cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 SPI data is sent the reverse way?

Hrishikesh
Senior
Posted on July 09, 2018 at 21:26

I've been experimenting with writing to an external

https://www.microchip.com/wwwproducts/en/93LC46B

using SPI and I've had mixed success. The data does get shifted out but in an opposite manner. The EEPROM requires a start bit and then an opcode which is essentially a 2-bit code for read, write and erase. Essentially the start bit and the opcode are combined into one byte. I'm creating a 32-bit unsigned int and then bit-shifting the values into it. When I transmit these I see that the actual data is being seen first and then the SB+opcode and then the memory address. How do I reverse this to see the opcode first then the memory address and then the actual data. As seen in the image below, the data is BCDE, SB+opcode is 07 and the memory address is 3F. The correct sequence should be 07, 3F and then BCDE (I think!).

Here is the code:

uint8_t mem_addr = 0x3F;
uint16_t data = 0xBCDE;
uint32_t write_package = (ERASE << 24 | mem_addr << 16 | data);
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
 HAL_SPI_Transmit(&hspi1, &write_package, 2, HAL_MAX_DELAY);
 HAL_Delay(10);
}
/* USER CODE END 3 */�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

Here it is on the scope:

0690X0000060LhcQAE.png #hal-spi #hal #spi #stm32f1 #external-eeprom
1 ACCEPTED SOLUTION

Accepted Solutions
Posted on July 10, 2018 at 00:52

It's called Most Significant Bit (MSB) first, at the word level, and then Little Endian in terms of how the bytes are arrayed in memory. You're mixing a couple of concepts, and getting it wrong. Review how data is stored in memory, review how you've configured SPI, ie 16-bit MSB first

If you are in fact writing two 16-bit words, use

uint16_t array[2];

array[0] = (cmd << 8) | addr;

array[1] = data;

HAL_SPI_Transmit(&hspi1, array, 2, HAL_MAX_DELAY);

In the 32-bit sense, little endian (most ARM, x86, etc)

uint32_t write_package = (ERASE << 8) | mem_addr | ((uint32_t)data << 16);

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

View solution in original post

2 REPLIES 2
Posted on July 10, 2018 at 00:52

It's called Most Significant Bit (MSB) first, at the word level, and then Little Endian in terms of how the bytes are arrayed in memory. You're mixing a couple of concepts, and getting it wrong. Review how data is stored in memory, review how you've configured SPI, ie 16-bit MSB first

If you are in fact writing two 16-bit words, use

uint16_t array[2];

array[0] = (cmd << 8) | addr;

array[1] = data;

HAL_SPI_Transmit(&hspi1, array, 2, HAL_MAX_DELAY);

In the 32-bit sense, little endian (most ARM, x86, etc)

uint32_t write_package = (ERASE << 8) | mem_addr | ((uint32_t)data << 16);

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on July 10, 2018 at 09:34

Thank you. This helped.