ESP32-S2: fractional SPI byte in master mode: input not captured
Posted: Wed Mar 30, 2022 7:59 pm
Hi,
I'm trying to use SPI in full duplex mode on ESP32-S2 to transmit a number of bits into a shift register chain which needs to be shifted by a number of bits that is not a multiple of 8. I am using CPU-controlled master mode on SPI3.
It seems to work great on the output side, but I find is that the final fractional input byte is never written to the SPI data buffers; that byte simply retains the value previously in that byte.
How can one flush out these additional bits? Transmitting additional clock pulses seen by peripherals is not acceptable, and the data appears to be lost if one starts a second (dummy) transaction.
Is there a workaround, or am I setting it up wrong? Here is a register dump of the registers set up for a 31-bit transaction, and the resulting register values:
SPI: *** Before
SPI: reg 0x000 = 0x00000000 0
SPI: reg 0x004 = 0x00000000 0
SPI: reg 0x008 = 0x06000000 100663296
SPI: reg 0x00c = 0x00000010 16
SPI: reg 0x010 = 0x00000000 0
SPI: reg 0x014 = 0x063c1001 104599553
SPI: reg 0x018 = 0x18000001 402653185
SPI: reg 0x01c = 0x00000000 0
SPI: reg 0x020 = 0x70000000 1879048192
SPI: reg 0x024 = 0x0000001e 30
SPI: reg 0x028 = 0x0000001e 30
SPI: reg 0x02c = 0x00000000 0
SPI: reg 0x030 = 0x06800200 109052416
SPI: reg 0x034 = 0x00000000 0
SPI: reg 0x038 = 0xd8000000 3623878656
SPI: reg 0x03c = 0x00000000 0
SPI: reg 0x040 = 0x0a000000 167772160
SPI: reg 0x044 = 0x00000000 0
SPI: reg 0x048 = 0x00000000 0
SPI: reg 0x04c = 0x00000200 512
SPI: reg 0x050 = 0x00000000 0
SPI: reg 0x054 = 0x00100000 1048576
SPI: reg 0x058 = 0x00000000 0
SPI: reg 0x05c = 0x00000000 0
SPI: reg 0x060 = 0x00000000 0
SPI: reg 0x064 = 0x00000000 0
SPI: reg 0x068 = 0x00000000 0
SPI: reg 0x06c = 0x00000000 0
SPI: reg 0x070 = 0x00000000 0
SPI: reg 0x074 = 0x00000000 0
SPI: reg 0x078 = 0x00000000 0
SPI: reg 0x07c = 0x00000000 0
SPI: reg 0x080 = 0x00000000 0
SPI: reg 0x084 = 0x00000000 0
SPI: reg 0x088 = 0x00000000 0
SPI: reg 0x08c = 0x00000000 0
SPI: reg 0x090 = 0x80000000 2147483648
SPI: reg 0x094 = 0xc0000000 3221225472
SPI: reg 0x098 = 0x6c80ffff 1820393471
SPI: reg 0x09c = 0x02020202 33686018
SPI: reg 0x0a0 = 0x03030303 50529027
SPI: reg 0x0a4 = 0x04040404 67372036
SPI: reg 0x0a8 = 0x05050505 84215045
SPI: reg 0x0ac = 0x06060606 101058054
SPI: reg 0x0b0 = 0x07070707 117901063
SPI: reg 0x0b4 = 0x08080808 134744072
SPI: reg 0x0b8 = 0x09090909 151587081
SPI: reg 0x0bc = 0x0a0a0a0a 168430090
SPI: reg 0x0c0 = 0x0b0b0b0b 185273099
SPI: reg 0x0c4 = 0x0c0c0c0c 202116108
SPI: reg 0x0c8 = 0x0d0d0d0d 218959117
SPI: reg 0x0cc = 0x0e0e0e0e 235802126
SPI: reg 0x0d0 = 0x0f0f0f0f 252645135
SPI: reg 0x0d4 = 0x10101010 269488144
SPI: reg 0x0d8 = 0x11111111 286331153
SPI: reg 0x0dc = 0x12121212 303174162
SPI: reg 0x0e0 = 0x00000000 0
SPI: reg 0x0e4 = 0x00000000 0
SPI: reg 0x0e8 = 0x00000000 0
SPI: reg 0x0ec = 0x00000000 0
SPI: reg 0x0f0 = 0x00000000 0
SPI: reg 0x0f4 = 0x00000000 0
SPI: reg 0x0f8 = 0x00000000 0
SPI: reg 0x0fc = 0x00000000 0
SPI: reg 0x100 = 0x00000000 0
SPI: *** After
SPI: reg 0x000 = 0x00000000 0
SPI: reg 0x004 = 0x00000000 0
SPI: reg 0x008 = 0x06000000 100663296
SPI: reg 0x00c = 0x00000010 16
SPI: reg 0x010 = 0x00000000 0
SPI: reg 0x014 = 0x063c1001 104599553
SPI: reg 0x018 = 0x18000001 402653185
SPI: reg 0x01c = 0x00000000 0
SPI: reg 0x020 = 0x70000000 1879048192
SPI: reg 0x024 = 0x0000001e 30
SPI: reg 0x028 = 0x0000001e 30
SPI: reg 0x02c = 0x00000000 0
SPI: reg 0x030 = 0x07000200 117441024
SPI: reg 0x034 = 0x00000000 0
SPI: reg 0x038 = 0xd8000000 3623878656
SPI: reg 0x03c = 0x00000000 0
SPI: reg 0x040 = 0x0a000000 167772160
SPI: reg 0x044 = 0x00000000 0
SPI: reg 0x048 = 0x00000000 0
SPI: reg 0x04c = 0x00000200 512
SPI: reg 0x050 = 0x00000000 0
SPI: reg 0x054 = 0x00100000 1048576
SPI: reg 0x058 = 0x00000000 0
SPI: reg 0x05c = 0x00000000 0
SPI: reg 0x060 = 0x00000000 0
SPI: reg 0x064 = 0x00000000 0
SPI: reg 0x068 = 0x00000000 0
SPI: reg 0x06c = 0x00000000 0
SPI: reg 0x070 = 0x00000000 0
SPI: reg 0x074 = 0x00000000 0
SPI: reg 0x078 = 0x00000000 0
SPI: reg 0x07c = 0x00000000 0
SPI: reg 0x080 = 0x00000000 0
SPI: reg 0x084 = 0x00000000 0
SPI: reg 0x088 = 0x00000000 0
SPI: reg 0x08c = 0x00000000 0
SPI: reg 0x090 = 0x80000000 2147483648
SPI: reg 0x094 = 0xc0000000 3221225472
SPI: reg 0x098 = 0x6c0f20dd 1812930781
SPI: reg 0x09c = 0x02020202 33686018
SPI: reg 0x0a0 = 0x03030303 50529027
SPI: reg 0x0a4 = 0x04040404 67372036
SPI: reg 0x0a8 = 0x05050505 84215045
SPI: reg 0x0ac = 0x06060606 101058054
SPI: reg 0x0b0 = 0x07070707 117901063
SPI: reg 0x0b4 = 0x08080808 134744072
SPI: reg 0x0b8 = 0x09090909 151587081
SPI: reg 0x0bc = 0x0a0a0a0a 168430090
SPI: reg 0x0c0 = 0x0b0b0b0b 185273099
SPI: reg 0x0c4 = 0x0c0c0c0c 202116108
SPI: reg 0x0c8 = 0x0d0d0d0d 218959117
SPI: reg 0x0cc = 0x0e0e0e0e 235802126
SPI: reg 0x0d0 = 0x0f0f0f0f 252645135
SPI: reg 0x0d4 = 0x10101010 269488144
SPI: reg 0x0d8 = 0x11111111 286331153
SPI: reg 0x0dc = 0x12121212 303174162
SPI: reg 0x0e0 = 0x00000000 0
SPI: reg 0x0e4 = 0x00000000 0
SPI: reg 0x0e8 = 0x00000000 0
SPI: reg 0x0ec = 0x00000000 0
SPI: reg 0x0f0 = 0x00000000 0
SPI: reg 0x0f4 = 0x00000000 0
SPI: reg 0x0f8 = 0x00000000 0
SPI: reg 0x0fc = 0x00000000 0
SPI: reg 0x100 = 0x00000000 0
Note that the top byte of SPI_W0 (0x098) is 0x6c both before and after the transaction. The actual data transmitted (using littleendian bit order) is 0100000 and so one would expect this byte to contain 0x02, 0x04, 0x05, or 0x82 (with 0x02 being the preferred result, of course.)
I'm trying to use SPI in full duplex mode on ESP32-S2 to transmit a number of bits into a shift register chain which needs to be shifted by a number of bits that is not a multiple of 8. I am using CPU-controlled master mode on SPI3.
It seems to work great on the output side, but I find is that the final fractional input byte is never written to the SPI data buffers; that byte simply retains the value previously in that byte.
How can one flush out these additional bits? Transmitting additional clock pulses seen by peripherals is not acceptable, and the data appears to be lost if one starts a second (dummy) transaction.
Is there a workaround, or am I setting it up wrong? Here is a register dump of the registers set up for a 31-bit transaction, and the resulting register values:
SPI: *** Before
SPI: reg 0x000 = 0x00000000 0
SPI: reg 0x004 = 0x00000000 0
SPI: reg 0x008 = 0x06000000 100663296
SPI: reg 0x00c = 0x00000010 16
SPI: reg 0x010 = 0x00000000 0
SPI: reg 0x014 = 0x063c1001 104599553
SPI: reg 0x018 = 0x18000001 402653185
SPI: reg 0x01c = 0x00000000 0
SPI: reg 0x020 = 0x70000000 1879048192
SPI: reg 0x024 = 0x0000001e 30
SPI: reg 0x028 = 0x0000001e 30
SPI: reg 0x02c = 0x00000000 0
SPI: reg 0x030 = 0x06800200 109052416
SPI: reg 0x034 = 0x00000000 0
SPI: reg 0x038 = 0xd8000000 3623878656
SPI: reg 0x03c = 0x00000000 0
SPI: reg 0x040 = 0x0a000000 167772160
SPI: reg 0x044 = 0x00000000 0
SPI: reg 0x048 = 0x00000000 0
SPI: reg 0x04c = 0x00000200 512
SPI: reg 0x050 = 0x00000000 0
SPI: reg 0x054 = 0x00100000 1048576
SPI: reg 0x058 = 0x00000000 0
SPI: reg 0x05c = 0x00000000 0
SPI: reg 0x060 = 0x00000000 0
SPI: reg 0x064 = 0x00000000 0
SPI: reg 0x068 = 0x00000000 0
SPI: reg 0x06c = 0x00000000 0
SPI: reg 0x070 = 0x00000000 0
SPI: reg 0x074 = 0x00000000 0
SPI: reg 0x078 = 0x00000000 0
SPI: reg 0x07c = 0x00000000 0
SPI: reg 0x080 = 0x00000000 0
SPI: reg 0x084 = 0x00000000 0
SPI: reg 0x088 = 0x00000000 0
SPI: reg 0x08c = 0x00000000 0
SPI: reg 0x090 = 0x80000000 2147483648
SPI: reg 0x094 = 0xc0000000 3221225472
SPI: reg 0x098 = 0x6c80ffff 1820393471
SPI: reg 0x09c = 0x02020202 33686018
SPI: reg 0x0a0 = 0x03030303 50529027
SPI: reg 0x0a4 = 0x04040404 67372036
SPI: reg 0x0a8 = 0x05050505 84215045
SPI: reg 0x0ac = 0x06060606 101058054
SPI: reg 0x0b0 = 0x07070707 117901063
SPI: reg 0x0b4 = 0x08080808 134744072
SPI: reg 0x0b8 = 0x09090909 151587081
SPI: reg 0x0bc = 0x0a0a0a0a 168430090
SPI: reg 0x0c0 = 0x0b0b0b0b 185273099
SPI: reg 0x0c4 = 0x0c0c0c0c 202116108
SPI: reg 0x0c8 = 0x0d0d0d0d 218959117
SPI: reg 0x0cc = 0x0e0e0e0e 235802126
SPI: reg 0x0d0 = 0x0f0f0f0f 252645135
SPI: reg 0x0d4 = 0x10101010 269488144
SPI: reg 0x0d8 = 0x11111111 286331153
SPI: reg 0x0dc = 0x12121212 303174162
SPI: reg 0x0e0 = 0x00000000 0
SPI: reg 0x0e4 = 0x00000000 0
SPI: reg 0x0e8 = 0x00000000 0
SPI: reg 0x0ec = 0x00000000 0
SPI: reg 0x0f0 = 0x00000000 0
SPI: reg 0x0f4 = 0x00000000 0
SPI: reg 0x0f8 = 0x00000000 0
SPI: reg 0x0fc = 0x00000000 0
SPI: reg 0x100 = 0x00000000 0
SPI: *** After
SPI: reg 0x000 = 0x00000000 0
SPI: reg 0x004 = 0x00000000 0
SPI: reg 0x008 = 0x06000000 100663296
SPI: reg 0x00c = 0x00000010 16
SPI: reg 0x010 = 0x00000000 0
SPI: reg 0x014 = 0x063c1001 104599553
SPI: reg 0x018 = 0x18000001 402653185
SPI: reg 0x01c = 0x00000000 0
SPI: reg 0x020 = 0x70000000 1879048192
SPI: reg 0x024 = 0x0000001e 30
SPI: reg 0x028 = 0x0000001e 30
SPI: reg 0x02c = 0x00000000 0
SPI: reg 0x030 = 0x07000200 117441024
SPI: reg 0x034 = 0x00000000 0
SPI: reg 0x038 = 0xd8000000 3623878656
SPI: reg 0x03c = 0x00000000 0
SPI: reg 0x040 = 0x0a000000 167772160
SPI: reg 0x044 = 0x00000000 0
SPI: reg 0x048 = 0x00000000 0
SPI: reg 0x04c = 0x00000200 512
SPI: reg 0x050 = 0x00000000 0
SPI: reg 0x054 = 0x00100000 1048576
SPI: reg 0x058 = 0x00000000 0
SPI: reg 0x05c = 0x00000000 0
SPI: reg 0x060 = 0x00000000 0
SPI: reg 0x064 = 0x00000000 0
SPI: reg 0x068 = 0x00000000 0
SPI: reg 0x06c = 0x00000000 0
SPI: reg 0x070 = 0x00000000 0
SPI: reg 0x074 = 0x00000000 0
SPI: reg 0x078 = 0x00000000 0
SPI: reg 0x07c = 0x00000000 0
SPI: reg 0x080 = 0x00000000 0
SPI: reg 0x084 = 0x00000000 0
SPI: reg 0x088 = 0x00000000 0
SPI: reg 0x08c = 0x00000000 0
SPI: reg 0x090 = 0x80000000 2147483648
SPI: reg 0x094 = 0xc0000000 3221225472
SPI: reg 0x098 = 0x6c0f20dd 1812930781
SPI: reg 0x09c = 0x02020202 33686018
SPI: reg 0x0a0 = 0x03030303 50529027
SPI: reg 0x0a4 = 0x04040404 67372036
SPI: reg 0x0a8 = 0x05050505 84215045
SPI: reg 0x0ac = 0x06060606 101058054
SPI: reg 0x0b0 = 0x07070707 117901063
SPI: reg 0x0b4 = 0x08080808 134744072
SPI: reg 0x0b8 = 0x09090909 151587081
SPI: reg 0x0bc = 0x0a0a0a0a 168430090
SPI: reg 0x0c0 = 0x0b0b0b0b 185273099
SPI: reg 0x0c4 = 0x0c0c0c0c 202116108
SPI: reg 0x0c8 = 0x0d0d0d0d 218959117
SPI: reg 0x0cc = 0x0e0e0e0e 235802126
SPI: reg 0x0d0 = 0x0f0f0f0f 252645135
SPI: reg 0x0d4 = 0x10101010 269488144
SPI: reg 0x0d8 = 0x11111111 286331153
SPI: reg 0x0dc = 0x12121212 303174162
SPI: reg 0x0e0 = 0x00000000 0
SPI: reg 0x0e4 = 0x00000000 0
SPI: reg 0x0e8 = 0x00000000 0
SPI: reg 0x0ec = 0x00000000 0
SPI: reg 0x0f0 = 0x00000000 0
SPI: reg 0x0f4 = 0x00000000 0
SPI: reg 0x0f8 = 0x00000000 0
SPI: reg 0x0fc = 0x00000000 0
SPI: reg 0x100 = 0x00000000 0
Note that the top byte of SPI_W0 (0x098) is 0x6c both before and after the transaction. The actual data transmitted (using littleendian bit order) is 0100000 and so one would expect this byte to contain 0x02, 0x04, 0x05, or 0x82 (with 0x02 being the preferred result, of course.)