AnsweredAssumed Answered

SPI Status Flags Don't Update

Question asked by shiveley.spencer on Aug 9, 2015
Latest reply on Aug 11, 2015 by shiveley.spencer
I'm sitting here pulling my hair out because I can't figure out what's going on, I've tried everything I can think of. I'm using SPI to communicate with an offboard periph, When I write to the data register the TXE flag doesn't go low. Here's my code I'm hoping someone can give me some insight that the Reference Manual isn't. The manual says there are 2 APB2 cycles before busy goes high and that I must wait on TXE. I've tried this to no avail. 

void Nokia5110_Init(void)
{
    volatile unsigned long delay;
    volatile unsigned long tempReg=0;
    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_InitDef.GPIO_PuPd = GPIO_PuPd_NOPULL;
     
    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;
     
    GPIO_Init(GPIOC,&GPIO_InitDef);
     
    //Initialization of SPI1
/*
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); //enable clock for SPI1
     
    SPI_I2S_DeInit(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
*/
 
     //SPI1 HardCode Initialization
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); //enable clock for SPI1
     tempReg |= (BRR | CPOL | PHASE | FRAME_LENGTH
                            | LSB_FIRST | NSS_SOFT | MSTER_MODE | BIDIR
                                | BIDIR_MODE);
 
     SPI1_CR1 = 0;
     SPI1_CR2 = 0;
     SPI1_CR1 |= tempReg;
     SPI1_CR2 |= SS_OUT_EN;
     SPI1_CR1 |= (SPI_EN | (0x1<<8)); //enable SPI, SET SS high
    
    // initialize Nokia5110
     
    GPIO_ResetBits(GPIOC, GPIO_Pin_2); //reset Nokia5110
    delay = 50;
    while(delay!=0)
    {
        delay--;
    }
  GPIO_SetBits(GPIOC, GPIO_Pin_2);
     
    lcdwrite(COMMAND, 0x21);
    lcdwrite(COMMAND, CONTRAST);          // try 0xB1 (for 3.3V red SparkFun), 0xB8 (for 3.3V blue SparkFun), 0xBF if your display is too dark, or 0x80 to 0xFF if experimenting
  lcdwrite(COMMAND, 0x04);              // set temp coefficient
  lcdwrite(COMMAND, 0x14);              // LCD bias mode 1:48: try 0x13 or 0x14
 
  lcdwrite(COMMAND, 0x20);              // we must send 0x20 before modifying the display control mode
  lcdwrite(COMMAND, 0x0C);              // set display control to normal mode: 0x0D for inverse
     
}
 
I've tried using SPI 2 instead of SPI 1, I've tried manipulating the registers myself thinking something might be wrong with the ST library. Nothing seems to work. Below is my transmission code.

void static lcdwrite(enum typeOfWrite type, char message){ 
    //SPI isn't quite working yet, TXE flag never goes low and Busy flag never sseems to go high.
  if(type == COMMAND){
    while ((SPI1_SR & SPI1_BUSY) == 0x80 ) //Check for busy flag
        {}
    while( !(SPI1_SR & SPI_I2S_FLAG_TXE) )  // wait until SPI not busy/transmit FIFO empty
        {}
        GPIO_ResetBits(GPIOC, GPIO_Pin_4|GPIO_Pin_5); //Pull slave select low
    SPI1_DR = message;                // command out                                       // wait until SSI0 not busy/transmit FIFO empty
    while( !(SPI1_SR & SPI_FLAG_TXE) ){} //wait for TXE to go high
    while( (SPI1_SR & SPI_I2S_FLAG_BSY) ) //wait for SPI to not be busy
    {}
    GPIOC->ODR |= (0x1<<5); //Pull slave select high
             
  } else{
         
    while( !(SPI1_SR&SPI_I2S_FLAG_TXE) ) // wait until transmit FIFO not full
    {}
    GPIO_ResetBits(GPIOC,GPIO_Pin_5); //Pull slave select low
    GPIO_SetBits(GPIOC, GPIO_Pin_4);
    SPI1_DR = (unsigned long) message;                // command out                                    
    
    while( !(SPI1_SR&SPI_FLAG_TXE) ){} //wait for TXE flag to go high
    while( (SPI1_SR&SPI_I2S_FLAG_BSY) ) //wait for SPI to not be busy
    {}
    GPIOC->ODR |= (0x1<<5); //Pull Slave Select high
 }
}

Any help would be greatly appreciated. I can't find any posts regarding the same problem. Thank you in advance. 

Outcomes