# RP2W RP2350 PicoMite troubleshooting

**URL:** <https://forum.clockworkpi.com/t/rp2w-rp2350-picomite-troubleshooting/19972>\
**Category:** PicoCalc\
**Created:** [October 5, 2025, 9:15pm UTC](https://forum.clockworkpi.com/t/rp2w-rp2350-picomite-troubleshooting/19972 "2025-10-05T21:15:23Z")\
**Posts on this page:** 4\
**Page:** 2

<div class="post-metadata">

**Author:** ![Toml\_12953](https://yyz1.discourse-cdn.com/flex029/user_avatar/forum.clockworkpi.com/toml_12953/32/11925_2.png) [@Toml\_12953](https://forum.clockworkpi.com/u/Toml_12953)\
**Post date:** [December 11, 2025, 6:08pm UTC](https://forum.clockworkpi.com/t/rp2w-rp2350-picomite-troubleshooting/19972/21 "2025-12-11T18:08:43Z")

</div>

I’m just wondering why it works for some people and not others. I have the keyboard and an RTC working OK on one of my PicoCalcs. The other PicoCalc doesn’t have an RTC yet.

---

<div class="post-metadata">

**Author:** ![ernst](https://avatars.discourse-cdn.com/v4/letter/e/9f8e36/32.png) [@ernst](https://forum.clockworkpi.com/u/ernst)\
**Post date:** [December 11, 2025, 7:38pm UTC](https://forum.clockworkpi.com/t/rp2w-rp2350-picomite-troubleshooting/19972/22 "2025-12-11T19:38:53Z")

</div>

The PicoCalc has uses a loop to activate internal services. The keyboard routine is called every 16 iterations, once for write and another 16 later iterations for read, that means there a 16 iterations between write and read. The keyboard routine uses MM.I2C internally to return the status. This all happens in the background, unnoticeable to the user. When the user interacts with I2C devices the MM.I2C status is used to return the result of the operation. If the user enters an I2C command on the console and then displays MM.I2C to see the result there will have been many keyboard transactions (using MM.I2C). Getting the correct result can be low, if not impossible. But this is only the beginning ….

Please download and read the following (8 pages):

[https://www.ti.com/lit/an/slva704/slva704.pdf](https://www.ti.com/lit/an/slva704/slva704.pdf)

Under 3.2 the following can be read:

_Reading from a slave is very similar to writing, but with some extra steps. In order to read from a slave, the master must first instruct the slave which register it wishes to read from. This is done by the master starting off the transmission in a similar fashion as the write, by sending the address with the R/W bit equal to 0 (signifying a write), followed by the register address it wishes to read from. Once the slave acknowledges this register address, the master will send a START condition again, followed by the slave address with the R/W bit set to 1 (signifying a read). This time, the slave will acknowledge the read request, and **the master releases the SDA bus, but will continue supplying the clock to the slave**. During this part of the transaction, the master will become the master-receiver, and the slave will become the slave-transmitter. The master will continue sending out the clock pulses, but will release the SDA line, so that the slave can transmit data. At the end of every byte of data, the master will send an ACK to the slave, letting the slave know that it is ready for more data. Once the master has received the number of bytes it is expecting, it will send a NACK, signaling to the slave to halt communications and release the bus. The master will follow this up with a STOP condition._

The keyboard is accessed through I2C by sending the value 0x09 to the keyboard bios to obtain a character from the FIFO maintained by the STM32. On the next read the keyboard bios will return what ever is available or none, every 32 ticks a keyboard write is send with a read 16 ticks later. In between any other I2C transaction can occur, such as keyboard backlight check. Or a stupid user (me) does a I2C scan (typing on the console) and wonders why phantom devices are being reported. Below is an example of what might happen: (based on i2c sniffer traces).

```auto
s=start p=stop a=ack n=nack 3E=write 0x1f 3F=read 0x1xf 
01: s3Ea0Bap => write keyboard Battery status request
02: s3Fa0Ba64np => read keyboard Battery status (see 01:)                                                            
03: s3Ea09ap => write keyboard FIFO request                                                              
04: s3Ea05ap => write keyboard LCD backlight status request 
05: s3Fa05a2Anp => read keyboard LCD backlight status (see 04:)                                                      
06: s3Fa00a00np => read keyboard FIFO data (see 03:) ???
07: s3Ea09ap => write keyboard FIFO request                                                         
08: s3Fa00a00np => read keyboard FIFO data (see 08)
09: s3Ea09ap => write keyboard FIFO request                                                         
10: s3Ea0Aap => write KBD backlight status request
11: s3Fa0Aa78np => read keyboard KBD backlight status (see 10)
12: s3Fa00a00np => read keyboard FIFO (see 09) ???

```

The proper method to interrogate the keyboard is to send the value x09 to the bios while holding the I2C bus, immediately followed with a read request. The following shows the proper way to use I2C: (real data from I2C sniffer using my RC25).

```auto
s=start p=stop a=ack n=nack 3E=write 0x1f 3F=read 0x1xf
s3Ea09as3Fa00a00np => write/read keyboard FIFO                                                      
s3Ea09as3Fa00a00np => write/read keyboard FIFO                                                    
s3Ea09as3Fa00a00np => write/read keyboard FIFO                                                            
s3Ea0Bas3Fa0Ba64np => write/read keyboard Battery status                                                             
s3Ea09as3Fa00a00np => write/read keyboard FIFO                                                             
s3Ea05as3Fa05a2Anp => write/read keyboard LCD backlight status                                                             
s3Ea09as3Fa00a00np => write/read keyboard FIFO                                                             
s3Ea0Aas3Fa0Aa78np => write/read keyboard KBD backlight status                                                             
s3Ea09as3Fa00a00np => write/read keyboard FIFO                                                             
s3Ea09as3Fa00a00np => write/read keyboard FIFO                                                              
s3Ea09as3Fa00a00np => write/read keyboard FIFO                                                             

```

This describes one part of the problem, there is more. In the keyboard service routines there are several error messages possible (like I2C not responding), unfortunately under many conditions the error message display is interrupted and the message “IIIIIIIIIIIIIIIIIII…” is displayed instead. This also the reason why my keyboard service routines does not report errors instead returns no keys.

---

<div class="post-metadata">

**Author:** ![Toml\_12953](https://yyz1.discourse-cdn.com/flex029/user_avatar/forum.clockworkpi.com/toml_12953/32/11925_2.png) [@Toml\_12953](https://forum.clockworkpi.com/u/Toml_12953)\
**Post date:** [December 11, 2025, 10:49pm UTC](https://forum.clockworkpi.com/t/rp2w-rp2350-picomite-troubleshooting/19972/23 "2025-12-11T22:49:37Z")

</div>

I can’t even list devices at all. I get this:

```auto
list system i2c
 HEX 0 1 2 3 4 5 6 7 8 9 A B C D E F
 00: -- -- -- -- -- -- --
[LIBRARY] IF MM.INFO(SYSTEM I2C)="I2C" THEN I2C check _ad ELSE I2C2 check _ad
Error : I2C Keyboard not responding
>

```

---

<div class="post-metadata">

**Author:** ![ernst](https://avatars.discourse-cdn.com/v4/letter/e/9f8e36/32.png) [@ernst](https://forum.clockworkpi.com/u/ernst)\
**Post date:** [December 12, 2025, 6:30am UTC](https://forum.clockworkpi.com/t/rp2w-rp2350-picomite-troubleshooting/19972/24 "2025-12-12T06:30:02Z")

</div>

I am not surprised ;-), that is what caused me to rewrite the keyboard routines. I used your RC23 source and ran the test on a pico 2:

```auto
> list system i2c                                                               
 HEX 0 1 2 3 4 5 6 7 8 9 A B C D E F                            
 00: -- -- -- -- -- -- --                                                       
[LIBRARY] If MM.Info(SYSTEM I2C)="I2C" Then I2C check _ad Else I2C2 check _ad   
Error : I2C Keyboard not responding       

```

The most likely reason is that the keyboard service was called and got the result of the scan in MM.I2C (timeout) instead of the keyboard read/write.

This is the [I2C sniffer](https://github.com/jjsch-dev/pico_i2c_sniffer) trace:

```auto
s3Ea09ap
s3Fa00a00np
s3Ea09ap
s3Fa00a00np
s3Ea09ap
s3Fa00a00np
s3Ea09ap
s3Fa00a00np
s3Ea09ap
s3Fa00a00np
s01np <= test address 0
s03np <= test address 1
s05np <= test address 2
s07np <= test address 3
s09np <= test address 4
s0Bnp <= test address 5
s0Dnp <= test address 6
s0Fnp <= test address 7
s3Ea09ap
s3Fa00a00np
s3Ea09ap
s3Fa00a00np
s3Ea09ap
s3Fa00a00np
s3Ea09ap
s3Fa00a00np

```

As you can see above the trace stops after address 7, but there is more wrong in this example because address 0 - 7 should never be tested because these are reserved! [https://i2cdevices.org/addresses](https://i2cdevices.org/addresses)

I used my RC25 build with my keyboard routines to do the same test and this is the result:

```auto
> list system i2c                                                               
 HEX 0 1 2 3 4 5 6 7 8 9 A B C D E F                            
 00: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --                            
 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 1F                            
 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --                            
 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --                            
 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --                            
 50: -- -- -- -- -- -- -- 57 -- -- -- -- -- -- -- --                            
 60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- --                           
 70: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --  
>

```

and the I2C sniffer trace:

```auto
s3Ea09as3Fa00a00np
s3Ea09as3Fa00a00np
s3Ea09as3Fa00a00np
s3Ea09as3Fa00a00np
s01np
s03np
s05np
s07np
s09np
s0Bnp
s0Dnp
s0Fnp
s11np
s13np
s15np
s17np
s19np
s1Bnp
s3Ea09as3Fa00a00np <= keyboard 
s1Dnp
s1Fnp
s21np
s23np
s25np
s27np
s29np
s2Bnp
s2Dnp
s2Fnp
s31np
s33np
s35np
s37np
s39np
s3Bnp
s3Dnp
s3Fa00np <= address 1f = bios reply
s41np
s43np
s45np
s47np
s49np
s4Bnp
s3Ea09as3Fa00a00np <== keyboard
s4Dnp
s4Fnp
s51np
s53np
s55np
s57np
s59np
s5Bnp
s5Dnp
s5Fnp
s61np
s63np
s65np
s67np
s69np
s6Bnp
s6Dnp
s6Fnp
s71np
s73np
s75np
s77np
s79np
s7Bnp
s3Ea09as3Fa00a00np <== keyboard
s7Dnp
s7Fnp
s81np
s83np
s85np
s87np
s89np
s8Bnp
s8Dnp
s8Fnp
s91np
s93np
s95np
s97np
s99np
s9Bnp
s9Dnp
s9Fnp
sA1np
sA3np
sA5np
s3Ea09as3Fa00a00np <== keyboard
sA7np
sA9np
sABnp
sADnp
sAFaFFnp <== address 57 = RTC
sB1np
sB3np
sB5np
sB7np
sB9np
sBBnp
sBDnp
sBFnp
sC1np
sC3np
sC5np
sC7np
sC9np
sCBnp
sCDnp
sCFnp
sD1a00np <== address 68 = EEPROM reply
sD3np
sD5np
sD7np
s3Ea09as3Fa00a00np <== keyboard
sD9np
sDBnp
sDDnp
sDFnp
sE1np
sE3np
sE5np
sE7np
sE9np
sEBnp
sEDnp
sEFnp
sF1np
sF3np
sF5np
sF7np
sF9np
sFBnp
sFDnp
sFFnp
s3Ea09as3Fa00a00np <== keyboard
s3Ea09as3Fa00a00np
s3Ea09as3Fa00a00np
s3Ea09as3Fa00a00np
s3Ea09as3Fa00a00np

```

As can be seen above the keyboard scan and the I2C check share the I2C bus, but in the “normal” version also the MM.I2C variable.

Note to the other readers: my modifications will be made available with the final release of MMBasic 6.1 which will be RSN.

[Previous page](https://forum.clockworkpi.com/t/rp2w-rp2350-picomite-troubleshooting/19972.md?page=1)
