Electronics > Microcontrollers

STM32F4 SPI read problem

(1/3) > >>

Ulfberth:
Hi  :)

I got problem with receiving data from nrf24l01+
First I thought that this is hardware issue, and slave device doesn't send right data, so I plugged logic analyzer which showed me that hardware is ok.
After that I launched debugger and found out that this is software issue, but I still didn't managed to find the mistake  :scared:

So what I'm trying to do is:
1) Write register of slave.
2) Read that register.

so steps to write address are:

1) Select NRF 2) Send register address + write cmd 3) Send register value 4) Release device

And for read:

1) Select NRF 2) Send register address + read cmd 3) Send 5 dummy bytes 4) save data to array 5) Release device

The problem is, 1st byte in array always wrong, the rest is right, but they are shifted by 1. And after 1 cycle 1st data in array is actually the one which should be last  :-//
It's on screenshot below, instead of rxBuf[0]=0x51 I get 1C then after cycle its 0x55...

I assume mistake is in read function, but I can't figure it out  :-[

Code and screenshots is below

SPI settings

--- Code: ---void spi1_init(void)
{
    // Enable clock for SPI2
    RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;

    // Configure SPI2
    SPI1->CR1 = 0; // Reset CR1 register
    SPI1->CR1 |= SPI_CR1_BR_0;  // Baud rate prescaler = 4 => 16/4=4mhz
    SPI1->CR1 |= SPI_CR1_MSTR; // Master mode
    SPI1->CR1 |= SPI_CR1_SSM | SPI_CR1_SSI; // Software slave management
    SPI1->CR1 |= SPI_CR1_SPE; // Enable SPI2
}

void spi1_gpio_init(void) // PA4 - SPI1_NSS | PA5-SPI1_SCK | PA6-SPI1_MISO| PA7-SPI1_MOSI
{
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN; //Enable GPIOA Clock

GPIOA->MODER |= GPIO_MODER_MODER4_0;  //PA4 GPIO OUT mode
GPIOA->MODER |= GPIO_MODER_MODER5_1;  //Enable Alternate function mode for GPIOA PA5
GPIOA->MODER |= GPIO_MODER_MODER6_1;  //Enable Alternate function mode for GPIOA PA6
GPIOA->MODER |= GPIO_MODER_MODER7_1;  //Enable Alternate function mode for GPIOA PA7

GPIOA->AFR[0] |= 0x5UL<<GPIO_AFRL_AFSEL5_Pos;  //GPIO alternate function set 0101 AF5 SPI PA5
GPIOA->AFR[0] |= 0x5UL<<GPIO_AFRL_AFSEL6_Pos;  //GPIO alternate function set 0101 AF5 SPI PA6
GPIOA->AFR[0] |= 0x5UL<<GPIO_AFRL_AFSEL7_Pos;  //GPIO alternate function set 0101 AF5 SPI PA7
}

--- End code ---

code for read and write functions


--- Code: ---void test_read(void)
{

uint8_t rxBuf[5]={0};



GPIOA->BSRR = GPIO_BSRR_BR4;

    while (!(SPI1->SR & SPI_SR_TXE));
    SPI1->DR = NRF24_REG_TX_ADDR | NRF24_CMD_R_REGISTER;

    while (!(SPI1->SR & SPI_SR_TXE));
    SPI1->DR = 0xFF;
    while (!(SPI1->SR & SPI_SR_RXNE));
    rxBuf[0]=SPI1->DR;
    while (!(SPI1->SR & SPI_SR_TXE));
    SPI1->DR = 0xFF;
    while (!(SPI1->SR & SPI_SR_RXNE));
    rxBuf[1]=SPI1->DR;
    while (!(SPI1->SR & SPI_SR_TXE));
    SPI1->DR = 0xFF;
    while (!(SPI1->SR & SPI_SR_RXNE));
    rxBuf[2]=SPI1->DR;
    while (!(SPI1->SR & SPI_SR_TXE));
    SPI1->DR = 0xFF;
    while (!(SPI1->SR & SPI_SR_RXNE));
    rxBuf[3]=SPI1->DR;
    while (!(SPI1->SR & SPI_SR_TXE));
    SPI1->DR = 0xFF;
    while (!(SPI1->SR & SPI_SR_RXNE));
    rxBuf[4]=SPI1->DR;

    while (!(SPI1->SR & SPI_SR_TXE));
    while (SPI1->SR & SPI_SR_BSY);


    GPIOA->BSRR = GPIO_BSRR_BS4;

}

void test_write(void)
{
GPIOA->BSRR = GPIO_BSRR_BR4;

    while (!(SPI1->SR & SPI_SR_TXE));
    SPI1->DR = NRF24_REG_TX_ADDR | NRF24_CMD_W_REGISTER;

    while (!(SPI1->SR & SPI_SR_TXE));
    SPI1->DR = 0x51;

    while (!(SPI1->SR & SPI_SR_TXE));
    SPI1->DR = 0x52;

    while (!(SPI1->SR & SPI_SR_TXE));
    SPI1->DR = 0x53;

    while (!(SPI1->SR & SPI_SR_TXE));
    SPI1->DR = 0x54;

    while (!(SPI1->SR & SPI_SR_TXE));
    SPI1->DR = 0x55;

    while (!(SPI1->SR & SPI_SR_TXE));
    while (SPI1->SR & SPI_SR_BSY);


    GPIOA->BSRR = GPIO_BSRR_BS4;
}

--- End code ---

wek:
Basically, after *each* Tx you should wait for RXNE and read out the received byte.

JW

Ulfberth:
Is my sequence wrong?

My steps when I read from spi:
1) I wait for TXE ( transmit buffer empty)
2) I put data into tx DR
3) I wait for RXE (Receive buffer not empty)
4) I take data from rx DR and put it into array

langwadt:

--- Quote from: Ulfberth on February 02, 2023, 01:28:35 pm ---Is my sequence wrong?

My steps when I read from spi:
1) I wait for TXE ( transmit buffer empty)
2) I put data into tx DR
3) I wait for RXE (Receive buffer not empty)
4) I take data from rx DR and put it into array

--- End quote ---

remember that every transmit is also a receive

try waiting for RXE and doing a dummy read of DR after sending the read command


Sherlock Holmes:

--- Quote from: Ulfberth on February 02, 2023, 01:28:35 pm ---Is my sequence wrong?

My steps when I read from spi:
1) I wait for TXE ( transmit buffer empty)
2) I put data into tx DR
3) I wait for RXE (Receive buffer not empty)
4) I take data from rx DR and put it into array

--- End quote ---

I wrote this last year, the SPI to NRF code works correctly.

https://github.com/Steadsoft/embedded/tree/main/NucleoF446RE/NRF24

These are just apps, using the API I created, this is for testing RX functionality, all STM32

https://github.com/Steadsoft/embedded/blob/main/NucleoF446RE/NRF24/Receiver/nrf_hal_rx_project.c

So focus on the API libraries I created, that's where the real effort went.

Navigation

[0] Message Index

[#] Next page

There was an error while thanking
Thanking...
Go to full version
Powered by SMFPacks Advanced Attachments Uploader Mod