AnsweredAssumed Answered

stm32f4 SPI Busy flag seems to not work

Question asked by shiveley.spencer on Aug 6, 2015
Latest reply on Aug 7, 2015 by shiveley.spencer
Hello all,
I'm trying to communicate with a nokia 5110 LCD. The nokia 5110 has a slave select bit that I am setting using a GPIO pin (because I'm not entirely sure how the NSS bit for SPI works). My problem is that when I send a transmission I wait for the busy flag to go down before I reset this slave select, the problem is the busy flag never sets so the slave select is being reset immediately and the nokia 5110 doesn't get the data.

here's my initialization code:
    SPI_InitTypeDef SPI_InitDef;
    GPIO_InitTypeDef GPIO_InitDef;
    //Initialization of gpio port A for SPI
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
    GPIO_InitDef.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
    GPIO_InitDef.GPIO_Mode = GPIO_Mode_AF; //using alternative function
    GPIO_InitDef.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_InitDef.GPIO_OType = GPIO_OType_PP;
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1); //set PA5 to SPI1_Sclk
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1); //set PA6 to MISO (won't be used though, data only flows to Nokia5110)
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1); //set PA7 to MOSI
    GPIO_Init(GPIOA, &GPIO_InitDef);
    //Initiazation of gpio port C PC4 -> used for Data/Command (D/C) to Nokia 5110
    //Data: PC4 is high
    //Command: PC4 is low
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
    GPIO_InitDef.GPIO_Pin = GPIO_Pin_2| GPIO_Pin_4 | GPIO_Pin_5; //Pin 2 is Reset, Pin 4 is D/C, Pin 5 is CS
    GPIO_InitDef.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitDef.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_InitDef.GPIO_OType = GPIO_OType_PP;
    GPIO_InitDef.GPIO_PuPd = GPIO_PuPd_DOWN;
//Initialization of SPI1
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); //enable clock for SPI1
    SPI_InitDef.SPI_Direction = SPI_Direction_1Line_Tx;//only using Tx
    SPI_InitDef.SPI_Mode = SPI_Mode_Master;//STM32f4 is master
    SPI_InitDef.SPI_DataSize = SPI_DataSize_8b;
    SPI_InitDef.SPI_CPOL = SPI_CPOL_Low; //Sclk is low in between transmissions
    SPI_InitDef.SPI_CPHA = SPI_CPHA_1Edge;//clock data in on rising edge
    SPI_InitDef.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32;// clk frequency  = APB2/32 = 84MHz/32 = 2.625MHz
    SPI_InitDef.SPI_FirstBit = SPI_FirstBit_LSB; //data is transmitted LSB first
    SPI_InitDef.SPI_NSS = SPI_NSS_Soft;
    SPI_Init(SPI1, &SPI_InitDef);//initialize spi1
    SPI_Cmd(SPI1, ENABLE);//enable spi1

and here is my SPI transmission:
void static lcdwrite(enum typeOfWrite type, char message){
//SPI isn't quite working yet, Busy flag never seems to go high.  Possibly because of NSS pin
  if(type == COMMAND){
            // wait until SSI0 not busy/transmit FIFO empty
    while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)){};
        GPIO_ResetBits(GPIOC, GPIO_Pin_4|GPIO_Pin_5);
    SPI1->DR = message;                // command out, wait until SSI0 not busy/transmit FIFO empty
    while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY)){};
        GPIOC->ODR |= (0x1<<5);
  } else{
    while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)){}; // wait until transmit FIFO not full
            GPIO_ResetBits(GPIOC,GPIO_Pin_5); //Chip select is active low
            GPIO_SetBits(GPIOC, GPIO_Pin_4);
            SPI1->DR = message;   
            while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY)){}; //wait until transmission complete (not working)
            GPIOC->ODR |= (0x1<<5);         // bring chip select high

Any help would be greatly appreciated. the function SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) keeps returning 0 so the while loop is skipped.