Hello,
I'm running a 2 channel spi configuration utilizing the SPIDEV kernel module. The first channel (CS0) sends out a 4 Bytes full duplex message as a heartbeat monitor and the 2nd channel is used to access a EEPROM for storage. I have found that the heartbeat channel when disabled still interferes with the EEPROM channel. The first read of the eeprom (256 byte) read returns nothing but 0s, but a second attempt at a 256 read at the same eeprom address yields valid results.
My initial thoughts is that maybe it was a read out of order described in the bcm2835-peripherals.pdf (pg7) because I have to manually toggle GPIOs (through mmap) but my tests showed that it wasn't the problem after I added the synchronization barriers and it still was not working the way it was expected. I tried doing reads guarded with spinlock mutexs when doing reads to the /dev/spidev0.0 and /dev/spidev0.1 devices and still get that same 256 read of 0s from memory. I would disable the thread so no monitor is running on spidev0.0 with the same result. My other thought is that since the heartbeat monitor is a full duplex operation the read buffer isn't being fully drained.
The nature of the heartbeat monitor is 16 bit full duplex command, followed by a 16bit half duplex read. All operations are through the the ioctrl method and I haven't found a "flush" operation in the the kernel module code either. Nothing for the kernel buffers or the hardware SPI FIFO.
The first code block is the first attempt at reading the eeprom with the spidev0.0 operations intact, and the resulting binaries after the first and second reads. The 2nd code block is the code that the heartbeat monitor uses to monitor the device on the CS0. The hexdump output is from the eeprom on CS1 and uses a different code path and is the more traditional half duplex, write read address and read operation.
Thoughts and prayers?
-Thanks.
I'm running a 2 channel spi configuration utilizing the SPIDEV kernel module. The first channel (CS0) sends out a 4 Bytes full duplex message as a heartbeat monitor and the 2nd channel is used to access a EEPROM for storage. I have found that the heartbeat channel when disabled still interferes with the EEPROM channel. The first read of the eeprom (256 byte) read returns nothing but 0s, but a second attempt at a 256 read at the same eeprom address yields valid results.
My initial thoughts is that maybe it was a read out of order described in the bcm2835-peripherals.pdf (pg7) because I have to manually toggle GPIOs (through mmap) but my tests showed that it wasn't the problem after I added the synchronization barriers and it still was not working the way it was expected. I tried doing reads guarded with spinlock mutexs when doing reads to the /dev/spidev0.0 and /dev/spidev0.1 devices and still get that same 256 read of 0s from memory. I would disable the thread so no monitor is running on spidev0.0 with the same result. My other thought is that since the heartbeat monitor is a full duplex operation the read buffer isn't being fully drained.
The nature of the heartbeat monitor is 16 bit full duplex command, followed by a 16bit half duplex read. All operations are through the the ioctrl method and I haven't found a "flush" operation in the the kernel module code either. Nothing for the kernel buffers or the hardware SPI FIFO.
The first code block is the first attempt at reading the eeprom with the spidev0.0 operations intact, and the resulting binaries after the first and second reads. The 2nd code block is the code that the heartbeat monitor uses to monitor the device on the CS0. The hexdump output is from the eeprom on CS1 and uses a different code path and is the more traditional half duplex, write read address and read operation.
Code:
hexdump -vn 512 testmain-main-2.bin0000000 0000 0000 0000 0000 0000 0000 0000 00000000010 0000 0000 0000 0000 0000 0000 0000 00000000020 0000 0000 0000 0000 0000 0000 0000 00000000030 0000 0000 0000 0000 0000 0000 0000 00000000040 0000 0000 0000 0000 0000 0000 0000 00000000050 0000 0000 0000 0000 0000 0000 0000 00000000060 0000 0000 0000 0000 0000 0000 0000 00000000070 0000 0000 0000 0000 0000 0000 0000 00000000080 0000 0000 0000 0000 0000 0000 0000 00000000090 0000 0000 0000 0000 0000 0000 0000 000000000a0 0000 0000 0000 0000 0000 0000 0000 000000000b0 0000 0000 0000 0000 0000 0000 0000 000000000c0 0000 0000 0000 0000 0000 0000 0000 000000000d0 0000 0000 0000 0000 0000 0000 0000 000000000e0 0000 0000 0000 0000 0000 0000 0000 000000000f0 0000 0000 0000 0000 0000 0000 0000 0000----0000100 6de0 8237 3ba2 a942 8214 2550 1b87 01060000110 e790 aa36 6fa4 d1a7 e84a 4faa de7d 86520000120 d4ba 1a34 5689 323a 676e d690 ec47 eafb0000130 f6eb 7607 0eea 467c 7c2c 18a3 9b0a 38c30000140 6a2a 6f0a aabd 1063 7266 b665 6e6f 75e70000150 d6a7 951e 75bb f74a ab52 4c8d c410 90870000160 2bea 72b7 5bce 7974 e152 d02e e4ee 574b0000170 145f 11ed bc82 0a4c bac7 8719 dab7 53540000180 4cf1 1b19 4413 7679 3366 ab3b d377 a1f80000190 f789 fc08 60df 2240 718d cdfa 786c f1a200001a0 9a53 810a 3a83 d299 a8c4 ce4d 800a 753a00001b0 f41e a2b0 05dc efed 323a 79ce 8209 8ad900001c0 e129 effe 911b df90 5a17 b6de a920 36bb00001d0 33ec e8d7 ba1e 56dc ad3f ada5 2674 6fd400001e0 2ff1 f252 c766 483e 04eb e85d 1900 8e8500001f0 27b5 53de 803c 8965 2620 cf8b c6f6 5019 hexdump -vn 512 testmain-main-3.bin0000000 ea7c 3444 e5e9 0911 fdf0 8534 ff57 7dd00000010 a104 aaed 5381 df0c 4637 c0fa 99df 099e0000020 3ef0 f86c 9305 9ecc f82f cc65 2072 ee860000030 f660 1c9c bfab 44b7 6205 c8f4 601f 4be50000040 0b40 8893 1397 27b7 0d8a d3f5 2848 5b940000050 1a51 8845 856a 2d91 fd2d bd40 8be6 b1450000060 a8e9 ffd0 f100 857d 333c 1f3f de86 10e20000070 b0cb 5f21 e41a 6bae 1ff8 5cbd 7407 e4570000080 9df7 5ca8 807a 7575 d763 052d 89dc f8dd0000090 8fbd 4f11 525b e8e6 6980 7a3f dd2b 8ea000000a0 b4eb 764f eac5 ba83 f709 a615 a00e 7be000000b0 9c60 55d0 bb67 313f 3d47 2b1f d017 5f8b00000c0 8305 383d 267a 1038 0c51 7e0c df9b 55d300000d0 8109 e37a 7a29 ab9f a24d ffc1 05bd e7b300000e0 5502 1e21 620b 17a9 324d 7a1b 4329 513c00000f0 cb53 d171 f0e5 63e9 20f8 6da7 a5a7 2a22---0000100 6de0 8237 3ba2 a942 8214 2550 1b87 01060000110 e790 aa36 6fa4 d1a7 e84a 4faa de7d 86520000120 d4ba 1a34 5689 323a 676e d690 ec47 eafb0000130 f6eb 7607 0eea 467c 7c2c 18a3 9b0a 38c30000140 6a2a 6f0a aabd 1063 7266 b665 6e6f 75e70000150 d6a7 951e 75bb f74a ab52 4c8d c410 90870000160 2bea 72b7 5bce 7974 e152 d02e e4ee 574b0000170 145f 11ed bc82 0a4c bac7 8719 dab7 53540000180 4cf1 1b19 4413 7679 3366 ab3b d377 a1f80000190 f789 fc08 60df 2240 718d cdfa 786c f1a200001a0 9a53 810a 3a83 d299 a8c4 ce4d 800a 753a00001b0 f41e a2b0 05dc efed 323a 79ce 8209 8ad900001c0 e129 effe 911b df90 5a17 b6de a920 36bb00001d0 33ec e8d7 ba1e 56dc ad3f ada5 2674 6fd400001e0 2ff1 f252 c766 483e 04eb e85d 1900 8e8500001f0 27b5 53de 803c 8965 2620 cf8b c6f6 5019
Code:
bool SpiIfc::ReadWrite16( uint16_t usData, uint16_t &usResp){ uint8_t spiBufTx [2]; uint8_t spiBufRx [2]; struct spi_ioc_transfer spi; lock(); // Global Mutex Lock memset (&spi, 0, sizeof(spi)); // clear struct to start spiBufTx[0] = (uint8_t)(usData >> 8); spiBufTx[1] = (uint8_t) (usData & 0xFF); spi.tx_buf =(unsigned long)spiBufTx; spi.rx_buf =(unsigned long)spiBufRx; spi.len = 2; spi.delay_usecs = 0; // delay from CS to transfer (in us) spi.speed_hz = 500000; // speed spi.bits_per_word = 8;// bytes in word __sync_synchronize(); //DMB ISH (disassembly) ioctl(spi_fd, SPI_IOC_MESSAGE(1), &spi); //spi_fd = /dev/spidev0.0 __sync_synchronize(); //DMB ISH (disassembly) usResp = spiBufRx[0]; usResp = (usResp << 8 ) | spiBufRx[1]; unlock(); // unlock access return(true);}
-Thanks.
Statistics: Posted by crimson4911 — Mon Mar 18, 2024 8:34 pm — Replies 1 — Views 11