cancel
Showing results for 
Search instead for 
Did you mean: 

SPI Not Sending

Scott Dev
Senior
Posted on March 16, 2018 at 12:10

Hi

  I am still learning on the STM32, and currently working on the Nucleo-64 (STM32L073RZT6) board. I am currently trying to get the SPI to work, I am simply trying to send a byte out so I can capture it on my logic analyser to confirm its sending, just to confirm I have it correct, then can move onto proer communication with it.  I am using SPI1, with pins PA5-CLK  PA6-MISO  PA7-MOSI   PA8-CS. I have an SPI memory chip connected to these pins, which I use on another processor so I have used it for many years. My code is below, on my logic analyser I see the chip select drop , but there is nothing else, all other pins are low. Im not worried about timing at the moment, just want to see the output first...

Mnay thanks

Scott

void SPI()

{

RCC->IOPENR |= RCC_IOPENR_GPIOAEN;//enable GPIO port A clock

GPIOA->MODER &= ~GPIO_MODER_MODE8; //PA8 as output

GPIOA->MODER |= GPIO_MODER_MODE8_0;

GPIOA->BSRR |=GPIO_BSRR_BR_8;

 GPIOA->BRR|=GPIO_BRR_BR_8;

  GPIOA->ODR |= GPIO_ODR_OD8; //cs high

GPIOA->MODER &= ~GPIO_MODER_MODE5; //PA5 Alternate Function

GPIOA->MODER |= GPIO_MODER_MODE5_1;

GPIOA->MODER &= ~GPIO_MODER_MODE6; //PA6 Alternate Function

GPIOA->MODER |= GPIO_MODER_MODE6_1;

GPIOA->MODER &= ~GPIO_MODER_MODE7; //PA7 Alternate Function

GPIOA->MODER |= GPIO_MODER_MODE7_1;

  //set alternate function AF0

    GPIOB->AFR[1] &= ~GPIO_AFRL_AFRL5; //PA5-CLK

    GPIOB->AFR[1] &= ~GPIO_AFRL_AFRL6; //PA6-MISO

    GPIOB->AFR[1] &= ~GPIO_AFRL_AFRL7; //PA7-MOSI

    RCC->APB2ENR |=  RCC_APB2ENR_SPI1EN; //enable SPI1 clock

    RCC->APB2RSTR |= RCC_APB2RSTR_SPI1RST; //reset SPI1

    RCC->APB2RSTR &= ~RCC_APB2RSTR_SPI1RST; //reset SPI1

    SPI1->CR1 &= ~SPI_CR1_SPE;    //disable SPI

    SPI1->CR1 &= ~SPI_CR1_RXONLY; //full duplex

    SPI1->CR1 &= ~SPI_CR1_BIDIMODE; //bidirectional

    SPI1->CR1 &= ~SPI_CR1_BIDIOE; //output disabled , received mode only

    SPI1->CR1 &= ~SPI_CR1_DFF; //8 bit Data frame format

    SPI1->CR1 &= ~SPI_CR1_LSBFIRST; //lsb first

    SPI1->CR1 &= ~SPI_CR1_CPHA; //1st edge

    SPI1->CR1 &= ~SPI_CR1_CPOL; //polarity low

    SPI1->CR1 &= ~SPI_CR1_BR; //baud rate to clk/2

    SPI1->CR1 &= ~SPI_CR1_CRCEN;//crc disabled

    SPI1->CR2 &= ~SPI_CR2_FRF; //motorola mode

    SPI1->CR1 |= SPI_CR1_MSTR; //set as master

    SPI1->CR1 |= SPI_CR1_SPE;    //enable SPI

unsigned char Tmp[5];Tmp[0]=0x55;

SPI_Write(&Tmp[0],1); //send 1 byte only....

}

void SPI_Write(unsigned char *txBuffer,int Size)

{

    unsigned char dummy;

    int i;

    GPIOA->ODR &= ~GPIO_ODR_OD8; //cs low

    for(i=0;i<Size;i++)

    {

        //wait for txe

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

        SPI1->DR = txBuffer[i];

        //wait for rxne

        while((SPI1->SR & SPI_SR_RXNE) != SPI_SR_RXNE);

        dummy=SPI1->DR;

    }

    //wait for BSY flag cleared

    while((SPI1->SR & SPI_SR_BSY) != SPI_SR_BSY);  //<<sticks here

//delay

    GPIOA->ODR |= GPIO_ODR_OD8; //cs high

}
5 REPLIES 5
Posted on March 16, 2018 at 12:13

 //wait for BSY flag cleared

    while((SPI1->SR & SPI_SR_BSY) != SPI_SR_BSY);  //<<sticks here

This is waiting for BSY flag set.

JW

Posted on March 16, 2018 at 12:37

I never noticed that, should have been ==

It gets stuck wating for the character, placed the //<<sticks here in the wrong place, sorry...

gets stuck here..

    while((SPI1->SR & SPI_SR_RXNE) != SPI_SR_RXNE); <<<<

I only see the CS pin going low on my logic analyser, other pins dont change.

Scott

T J
Lead
Posted on March 16, 2018 at 13:55

This seems to work for me.

unsigned char SPI_t::transfer_receive(unsigned short data) {

    char RxSPI;

   // clear old data from receiver 

   while ((hspi1.Instance->SR  & SPI_FLAG_RXNE))

        RxSPI = hspi1.Instance->DR;

    Clear_SPI1_nSS_Out();

    while (!(hspi1.Instance->SR  & SPI_FLAG_TXE))

        ;

    *((__IO uint8_t *)&hspi1.Instance->DR) = data;                // force the SPI to transceive 8 bit

    while (!(hspi1.Instance->SR  & SPI_FLAG_TXE))

        ;

    while ((hspi1.Instance->SR  & SPI_FLAG_BSY))

        ;

    RxSPI = hspi1.Instance->DR;  take the byte.

    Set_SPI1_nSS_Out();        

        

    return RxSPI;

}
Posted on March 16, 2018 at 14:32

Hi TJ

  I dont use the NSS pin, I use a seperate IO (PA8). I dont understand why nothing is coming out of the SPI pins, is there something in the setup of IO I am doing wrong? I tried your extra lines, i.e read byte before sending, and waiting for the TXE to become empty, but still the same.

Scott

Scott Dev
Senior
Posted on March 16, 2018 at 17:07

Hi

 I managed to fix the issue. I had to add:

SPI1->CR1 |= SPI_CR1_SSI;// manage nss software

SPI1->CR1 |= SPI_CR1_SSM; //software slave management enabled

As I use an IO pin for CS, I originally had them set to 0.

Thanks for all your info.

Scott