On the Hunt for a Serial Problem

We have a serial port problem in PicoMite. The PicoCalc can receive but not send through the onboard serial port (not the one on the Pico itself)

Here’s a hint for you if you’re going looking for it:
The problem doesn’t occur in WebMite, only the non-web version. Webmite’s serial response is just what it should be. This is a clue to the hunt for the serial bug. If you have any knowledge of C at all, Please help us find the bug! The more eyes on it, the faster it can be found.

1 Like

Hold your horses, I think I may have found the problem but I need a little bit of time to confirm.

1 Like

The analysis of this has taken many days/hours to understand the problem, getting into the problem with two debug (uart) probes on the UART0 and UART1, with dbg tracing the flow in the program, seeing the data go into the uart0 with evidence that the data was removed from uart0 but no output on pin1 as shown on my oscilloscope. While taking a walk I came to the conclusion that something is blocking the data on pin 1 but no idea where to start looking.

The problem is only shown on a PicoCalc using a Pico2, all other versions do not have this problem. The plain PicoMite (not PicoCalc) build has only a few options installed, so I removed all the options from the PicoCalc build and found that the following option causes the problem to appear:

OPTION LCDPANEL ST7796SP, PORTRAIT,GP14,GP15,GP13,,INVERT

The above information is created from the options as shown in FileIO.c:

    Option.DISPLAY_TYPE = ST7796SP;
    Option.SYSTEM_CLK = 14;
    Option.SYSTEM_MOSI = 15;
    Option.SYSTEM_MISO = 16;
    Option.DISPLAY_BL = 0; //stm32 control the backlight
    Option.LCD_CD = 19;
    Option.LCD_CS = 17;
    Option.LCD_Reset = 20;
    Option.DISPLAY_ORIENTATION = PORTRAIT;

With the visual inspection of the code I found the following in SPI-LCD.c that is used for PICOMITERP2350 only:

#if PICOMITERP2350
		if (Option.SYSTEM_CLK != Option.LCD_CLK)
		{ // configure the LCD SPI pins
			gpio_set_function(LCD_CLK_PIN, GPIO_FUNC_SPI);
			gpio_set_function(LCD_MOSI_PIN, GPIO_FUNC_SPI);
			gpio_set_function(LCD_MISO_PIN, GPIO_FUNC_SPI);
			gpio_set_drive_strength(LCD_MOSI_PIN, GPIO_DRIVE_STRENGTH_8MA);
			gpio_set_drive_strength(LCD_CLK_PIN, GPIO_DRIVE_STRENGTH_8MA);
			gpio_set_input_hysteresis_enabled(LCD_MISO_PIN, true);

When you look at the options in FileIO.c you can notice that Option.LCD_CLK is not included, iow this option is 0 (zero) and not equal to Option.SYSTEM_CLK. Please note that I mentioned Pin 1 above which GP0 (or the value zero). What happens next is killing the output on pin 1 = GP0 because value of Option.LCD_CLK_PIN is zero!

gpio_set_function(LCD_CLK_PIN, GPIO_FUNC_SPI);
.
.
gpio_set_drive_strength(LCD_CLK_PIN, GPIO_DRIVE_STRENGTH_8MA);

Please note that I do not know why this routine exists and I did not investigate further.

There are two solutions to this problem, the first solution would be to do additional checking in SPI-LCD.

#if PICOMITERP2350
		if ((Option.SYSTEM_CLK != Option.LCD_CLK)) && (Option.LCD_CLK != 0))

but this would require a change in the MMBasic.

The simpler solution is to add Option.LCD_CLK to the PicoCalc initial options in FileIO.c:

    Option.DISPLAY_TYPE = ST7796SP;
    Option.SYSTEM_CLK = 14;
    Option.SYSTEM_MOSI = 15;
    Option.SYSTEM_MISO = 16;
    Option.DISPLAY_BL = 0; //stm32 control the backlight
    Option.LCD_CLK = 14;
    Option.LCD_CD = 19;
    Option.LCD_CS = 17;
    Option.LCD_Reset = 20;
    Option.DISPLAY_ORIENTATION = PORTRAIT;

After the above change the UART0 was able to transmit data :wink:

I am preparing a large number of changes to the code for the PicoCalc and this will be included.

5 Likes

Looking at the definition of the option structure in FileIO.h it appears it is arranged to be a packed structure that fits in 7 128 byte blocks. The added picocalc option

#ifdef PICOCALC
uint8_t KEYBOARDBL;
#endif

does not take the packing into account, potentially leaving the next (u)int16_t unaligned and will also cause the option structure to exceed the 896 bytes. I don’t know if this will cause problems but it doesn’t feel right.

I have already noted this and fixed in my changes. Also I removed the purpose of this byte and replaced it with a new function to manage/track the LCD and KBD backlight.

Small update, the Option.LCD_CLK is only used with PICOMITERP2350, for this reason an #if should be included:

#if PICOMITERP2350
    Option.LCD_CLK = 14;
#endif

Code like that also appears in MM-Misc.c. Does the change have to be made there as well?

Tom L

Yes, it has been done already.

1 Like

Not sure if this is relevant to this particular issue, before seeing this thread I tried hooking up a Flipper Zero to uart0 tx and rx and gnd and 3.3v (pico1 picomite v6.01.00b10) I didn’t change any settings and had 2 way comms working fine. I then changed the baudrate in Picocalc to 9600 and did the same on Flipper Zero and again all worked as expected. Then I tried hooking up a Psion 2 by way of a rs232 level shifter and Psion comms link, to uart0 on picocalc (9600 baud rate on both) and the Psion could receive from Picocalc but anything sent from Psion was not received on Picocalc. I tried changing various parameters on Psion but no success. With the same settings and setup I then tried Psion with Flipper Zero and two way comms worked.

I am scratching my head, what do I still know about the Psion 2, once upon a time I had the complete diagram and all the documentation but that is ages ago.

What surprises me is that you mentioned the rs232 level shifter, this could be very dangerous because the RS232 voltage levels can be in the range of +3 to +15 volts or -3 to -15 volts. The range between −3 and +3 volts is not a valid RS-232 level. https://en.wikipedia.org/wiki/RS-232

The PicoCalc/Pico does not use driver chips, the signals are directly connected to the RP2040/RP2350, which means max 3.3V (although according to some information also 5V).

I suspect that the Psion 2 / RS232 level shifter uses 5V levels, that means you may have destroyed the Pico, or you have been over driving the GPIO receive pin.

Your description makes it very difficult to identify the problem because afaik the Psion Coms Link was intended to be used with real RS232/PC equipment, meaning high voltage and then I have to question what a RS232 level shifter would do in this case.

It is very likely that the simple solution might be to connect the PicoCalc directly to the Psion interface, but I would not do so without access to the circuit diagrams. And I would use an oscilloscope to measure the signals.

The organizer II was an interesting device at the time, this is all I can contribute at the moment.

The level shifter converts RS232 to TTL so it is used to protect the Picocalc, it only outputs 3.3v so no chance of damage.

Time to do some measuring:

This may help you to find the problem.

But I think the strange thing is picocalc and flipper compatible, psion and flipper (using level shifter) compatible, picocalc and psion (using level shifter) only tx from picocalc works, rx not working. This is with same settings on all devices, level shifter powered from picocalc 3v3 and gnd when connecting to psion, flipper powering level shifter when connecting flipper to psion, no level shifter needed with picocalc connecting to flipper obviously due to both being 3v3 natively on gpio.

If the Flipper and Psion only worked one way same as picocalc I’d be less puzzled, I have tried multiple times and the results are the same, it isn’t something that I need to get working so I doubt that I will spend much time trying to get to the bottom of it, but I did think it interesting after reading this topic where the Picocalc was receiving but not sending, and my findings were the opposite with the Psion.

@ernst Do you think it worth trying a different pins on picocalc, I have not delved deeply into this but I believe gpio pins can be configured as rx/tx in picomite basic - any pointers here would be appreciated. I assume com2 using gp4 for TX and gp5 for RX is the way to go?

That is a definite maybe. There are a few problems, one being the mainboard of the PicoCalc that makes UART0 available on GP0/GP1. UART1 can be configured with OPTION SERIAL CONSOLE GP8,GP9 but there are no connection points for these pins on the mainboard.

Btw, this is very helpful when testing:

The above allows you to use jumper cables.

OTOH, I had a quick look at the Flipper Zero circuit diagrams and it looks to me that this uses 5V TTL logic levels with Zener diode protection on all the IO ports. AFAIK The Psion also uses 5V TTL logic which implies that you do not need a level shift to directly connect to the Flipper Zero. But the PSION Comms-Link uses MAX232CWE to drive the lines, this might be sufficient without an additional RS232 level shifter but you will have to consider shifting down.

The PicoCalc uses 3.3V CMOS logic and you need to shift the output level down, this could be as simple as using two resistors if you use 5V TTL logic on the PSION.

My advice: don’t play around with this stuff before you have studied the details and before having the right equipment to confirm your findings.

RS232/V.24 levels can be dangerous to health of the PicoCalc, even so it does not cost much to replace the Pico. The Flipper Zero does have some protection build in, but still I would not use a proper RS232 level shifter because of the reason described under “RS232 signal levels”.

The voltage levels are one of the main items in the specification. For RS232 data signals a voltage of between -3V and -25V represents a logic 1. The logic 0 is represented by a voltage of between +3V and +25V.

I almost forgot to mention that the original problem was a problem with the software configuration of GP0 which is also Pin 0. A routine to configure the display used an unitialized value (= 0) overwriting the configuration of UART0 TX on Pin 0 causing the output to fail.

Thanks for tips @ernst Flipper Zero gpio is native 3.3v, the reason for me using the level shifter with Psion is because it is powered from the device being connected (Flipper or Picocalc) and this supply voltage ensures its pins output don’t exceed that voltage, so when used with Picocalc or Flipper Zero it was connected to 3.3v and ground on the respective device, so rather than risk the 5v from Psion my logic was that the level shifter in between will handle the conversion to 3.3v, but maybe it is wrong.

I tried the example from the manual

SETPIN G5, GP4, COM2

OPEN “COM1:9600” AS #5

PRINT #5, “Hello”

dat$ = INPUT$(20, #5)

Close #5

I then connected Flipper Zero, and again Picocalc sent “Hello” to Flipper, but would not receive from it using that example code, obviously I made sure I was connected to the correct pins on both devices, and attempted to send from Flipper, not sure if it is to do with the code example as it seems to expect an input of upto 20 characters before closing, but maybe I am misunderstanding.

If you connected to UART0_RX and UART0_TX on the PicoCalc, you have to make a small hardware change inside the machine. As it’s shipped, the RX line on PicoCalc is dedicated to the USB port. In order to use the RX serial line, you have to bend up pin 1 of the Pico so it make no contact with the socket and unsolder the line going to the external connector’s RX line, then connect the two. I’ve attached a photo.

You can not use GP4,GP5 because these pins are connected to the PicoCalc onboard PSRAM. For COM2 you can use GP8,GP9 but you have to connect the wires to the Pico.

You can use COM1 on GP0,GP1 but you must disable the serial console with “OPTION SERIAL CONSOLE DISABLE”.

Note: The “Manual” is the document for PicoMite and WebMite which support many different hardware configurations. The examples may need changes to adapt to the PicoCalc hardware.

I do not understand, according to the circuit diagram AND my multimeter Pin 0 (GP0,UART0_TX) and Pin 1 (GP1,UART0_RX) are connected to socket J702 pin 2 (UART0_RX) and pin 3 (UART0_TX).

All I know is that in my unmodified PicoCalc, I can send but not receive on COM1: (GP0,GP1) but when I make the hardware change, I can. I’m using a serial terminal on COM1: I haven’t tried with just data and turning off the serial console.