Author Topic: STM32 SPI Code Advice  (Read 2281 times)

0 Members and 1 Guest are viewing this topic.

Offline 1310_nanometersTopic starter

  • Newbie
  • Posts: 2
  • Country: us
STM32 SPI Code Advice
« on: December 27, 2021, 06:15:16 pm »
I apologize in advance but this might be a bit of a long post. I'm new to embedded software development, but not the realm of software development itself. I believe I might be encoutering an issue with Endianness but I'm hoping someone more experienced with embedded systems and C could provide some guidance on how to verify my concerns.

I have an idea on how to resolve the issue already, but the project so far has been very ardious. I'm working with a STM32WB55 Nucleo Board and a MAX35103 Time of Flight Eval Kit. According to the MAX35103's Datasheet (Link Here refer to Table 20 on page 51) chip if I send opcode 0xC2 I can read Calibration and Control register.

If I send Opcode 0x42 followed by 16 bytes of data MSB first (this is explained on page 27 and 28) I can write the register.

So I wrote some code to perform these simple tests using STM's HAL here. I had some grounding issues that caused CS pin spikes. In my troubleshooting I thought it was possibly related to the slewing of the pin, which is why there's a 750 delay between the writes. In the end it was a bad ground wire:

Code: [Select]
  uint8_t opCode = 0xC2;
  uint8_t txBuf[] = { opCode };
  uint8_t rxBuf[2] = {0};
  //uint16_t buf = 0x00;

  HAL_GPIO_WritePin(SPI1_CS_GPIO_Port, SPI1_CS_Pin, GPIO_PIN_RESET);
  HAL_SPI_Transmit(&hspi1, txBuf, sizeof(txBuf), HAL_MAX_DELAY);
  HAL_SPI_Receive(&hspi1, rxBuf, 2, HAL_MAX_DELAY);
  HAL_GPIO_WritePin(SPI1_CS_GPIO_Port, SPI1_CS_Pin, GPIO_PIN_SET);

  HAL_Delay(750);

  opCode = 0x42;
  uint8_t txBuf2[] = { opCode, 0xAB, 0x01 };
  HAL_GPIO_WritePin(SPI1_CS_GPIO_Port, SPI1_CS_Pin, GPIO_PIN_RESET);
  HAL_SPI_Transmit(&hspi1, txBuf2, sizeof(txBuf2), HAL_MAX_DELAY);
  HAL_GPIO_WritePin(SPI1_CS_GPIO_Port, SPI1_CS_Pin, GPIO_PIN_SET);

  HAL_Delay(750);

  rxBuf[0] = 0x0;
  rxBuf[1] = 0x0;

  HAL_GPIO_WritePin(SPI1_CS_GPIO_Port, SPI1_CS_Pin, GPIO_PIN_RESET);
  HAL_SPI_Transmit(&hspi1, txBuf, sizeof(txBuf), HAL_MAX_DELAY);
  HAL_SPI_Receive(&hspi1, rxBuf, 2, HAL_MAX_DELAY);
  HAL_GPIO_WritePin(SPI1_CS_GPIO_Port, SPI1_CS_Pin, GPIO_PIN_SET);

The SPI write goes perfectly



But when I perform the second read my results are shifted weirdly



The waveforms for the capture don't lead me to believe anything's wrong with the capture. The way the data is shifted from the read, a 1 is added at the front otherwise everything else is fine, makes me think it's something with endianness possibly. But it's weird, not an exact mirror. I'm unsure. Here's a link to the full Saleae capture file if anyone wants to take a look at it: Dropbox Link

Any advice on what else to look at it would be very much appreciated. Thank you for your time reading this.
 

Offline jnz

  • Frequent Contributor
  • **
  • Posts: 593
Re: STM32 SPI Code Advice
« Reply #1 on: December 27, 2021, 07:02:39 pm »
IDK. I’m in a car and can’t really process what you are doing or look at code… but a couple of SPI gotchas I have run into…

1. IIRC there is a bit order or endianness on STM32 SPI peripherals. Endianness is easy to detect if you look at the binary though. Same with inversion or CLK/CPOL being wrong (see the four SPI modes).

2. Be careful of when you are releasing/asserting the chip select line. Don’t assert and read too quickly, don’t forget to release, certainly don’t forget to assert, be careful of writing and then expecting a change before you release the line as some devices just store in a buffer only receive or process when the line is released (this held me up one time for longer than I’ll ever admit to).

3. Get a scope. Use a scope.
 

Offline DavidAlfa

  • Super Contributor
  • ***
  • Posts: 6226
  • Country: es
Re: STM32 SPI Code Advice
« Reply #2 on: December 27, 2021, 07:57:09 pm »
Spi will send the data in this order:
uint8_t txBuf2[] = { opCode, 0xAB, 0x01 };

If the data is shifted 1 bit, that's not the endianness, but clock loss/missaligment.
Check the spi clock and polarity settings.
« Last Edit: December 27, 2021, 08:00:47 pm by DavidAlfa »
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 
The following users thanked this post: 1310_nanometers

Offline 1310_nanometersTopic starter

  • Newbie
  • Posts: 2
  • Country: us
Re: STM32 SPI Code Advice
« Reply #3 on: December 27, 2021, 08:10:35 pm »
Spi will send the data in this order:
uint8_t txBuf2[] = { opCode, 0xAB, 0x01 };

If the data is shifted 1 bit, that's not the endianness, but clock loss/missaligment.
Check the spi clock and polarity settings.


Well I feel like a dunce now, that was it.

Re-reading the datasheet for the MAX35103 it's DIN is latched on falling edge of SCK and of course I was simply using the default configuration for CPHA. Changed this around, and readjusted my Saleae. Worked. Thank you guys so much for pointing out I should have RTFMed a little harder.

 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf