SuperHouse / esp-open-rtos

Open source FreeRTOS-based ESP8266 software framework
BSD 3-Clause "New" or "Revised" License
1.53k stars 491 forks source link

spi read 1 bit off #550

Closed vortex314 closed 6 years ago

vortex314 commented 6 years ago

I'm already struggling for some time to use ESP8266 and DWM1000 for a local positioning system. Things worked fine , but the spi communication is difficult to make correct. When I send via SPI a command to the DWM1000 chip, the execution is correctly done by the DWM1000. So transmission MOSI looks correct, but the MISO is 1 bit off misaligned Example : sending 5 times 00 hex , should give the result of the chip id : 0x7F3001CADE ( DECA0130 ) however I receive FE600395BC, shifting this 1 bit to the right gives the expected answer 7F3001CADE. Setting the EUID to the external chip via a command hex : 81 01 02 03 04 05 06 07 08 , is executed correctly , but when asking the result it gets back with FE020406080A0C0E11 which shifting 1 bit to the right gives the correct answer. 7F 01 02 03 04 05 06 07 08 . So for one reason or another the first bit is lost. I'm using SPI_MODE0 and clock 125k to 4MHZ. result is always the same. So tried with changing the SPI_setup time, maybe the DWM1000 was polled too fast :
´´´ uint32_t spi_user=READ_PERI_REG(SPI_USER(1)); spi_user |= (SPI_USER0_CS_HOLD | SPI_USER0_CS_SETUP); WRITE_PERI_REG(SPI_USER(1), spi_user); ´´´ No change on the result. Any suggestions ?

Code used for initialization : ´´´ spi_settings_t settings ; ZERO(settings); settings.mode = ( spi_mode_t) _mode; settings.msb= ! _lsbFirst; if ( _clock == 1000000 ) settings.freq_divider = SPI_FREQ_DIV_1M; else if ( _clock == 4000000 ) settings.freq_divider = SPI_FREQ_DIV_4M; else if ( _clock == 2000000 ) settings.freq_divider = SPI_FREQ_DIV_2M; else if ( _clock == 125000 ) settings.freq_divider = SPI_FREQ_DIV_125K; else if ( _clock == 250000 ) settings.freq_divider = SPI_FREQ_DIV_250K; else settings.freq_divider = SPI_FREQ_DIV_1M; settings.endianness=SPI_LITTLE_ENDIAN; settings.minimal_pins=_hwSelect ? false:true; spi_set_settings(1,&settings); spi_clear_address(1); spi_clear_command(1); spi_clear_dummy(1); ´´´

vortex314 commented 6 years ago

Looking with an oscilloscope at the SPI traffic I notice that the ESP8266 is polling for an extra bit at the end, while the data coming from DWM1000 was ended. The data from the DW1000 changes at the raising edge of the clock, while it should be stable at that moment. So strange enough I write in SPI mode 0, read in in SPI mode 0 and shift 1 bit the result and everything works find. Just left this trace here if someone would encounter the same.

Philoul commented 5 years ago

Hello, I have exactly the same problem with an ESP8266 (Wemos D1 Mini) and an ESP32 (MH-et-LIVE) I try to communicate with a NFC Card (BM019). Initialisation is Ok, and when I receive data from the NFC card, the first bit is lost and all other bits à shifted left... The data sent by slave are ok with Logic Analyzer

SPI.setDataMode(SPI_MODE0);
SPI.setBitOrder(MSBFIRST);
SPI.setClockDivider(SPI_CLOCK_DIV128);
SPI.begin();

...... digitalWrite(SSPin, LOW); SPI.transfer(0x02); // SPI control byte for read
RXBuffer[0] = SPI.transfer(0); // response code : 0x80 on Logic Analizer, 0x00 on RXBuffer[0] RXBuffer[1] = SPI.transfer(0); // length of data : 0x0D on Logic Analizer, 0x1A on RXBuffer[1] digitalWrite(SSPin, HIGH); .....

Do you have solved the problem ?