1

I need to communicate with an eeprom chip(25lc1024) via SPI. I can get the following code to work but have to resort to delays isntead of the flags alone. Otherwise I can see on the scope that it is not waiting for all the bits to be shifted out and proceeds. Any ideas why the flags are not stopping it?

void  Init_SPI(void){
    RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;   // enable SPI clock

    GPIOA->AFR[0] |= SET_AFL_A_FOR_SPI1;
    GPIOB->AFR[0] |= SET_AFL_B_FOR_SPI1;

    SPI1_NSS = DESELECT_CHIP;            // set the SS pin high
    
    // initialize the SPI configuration register
    SPI1->CR1  =  SPI_CR1_MSTR  // SPI master mode
                | SPI_CR1_BR_1; // 010 bit rate prescale /8 (60MHz/8 = 7.5MHz)
    SPI1->CR2  =    SPI_CR2_SSOE;
    
    SPI1->CR1  |= SPI_CR1_SPE;  // enable SPI
}

unsigned int eeprom_read(unsigned long address, unsigned int chars_to_read)
{
    char temp;
    unsigned int result = 0;


    SPI1_NSS = SELECT_CHIP;                         // set the SS pin low
    SPI1->DR = READ_FROM_SPI;                       // send data out SPI
    while( !(SPI1->SR & SPI_SR_TXE) );              // wait until transmit buffer empty

    SPI1->DR = (address & 0xFF0000) >> ADJ16;   // send data out SPI
    while( !(SPI1->SR & SPI_SR_TXE) );              // wait until transmit buffer empty
    SPI1->DR = (address & 0x00FF00) >> ADJ8;    // send data out SPI
    while( !(SPI1->SR & SPI_SR_TXE) );              // wait until transmit buffer empty
    SPI1->DR = (address & 0x0000FF);                    // send data out SPI
    while( !(SPI1->SR & SPI_SR_TXE) );              // wait until transmit buffer empty

    delay();
    temp = SPI1->DR;
    SPI1->DR = DUMMY_8BIT;                    // send dummy 8 bits to generate clock
    chars_to_read--;

    while( !(SPI1->SR & SPI_SR_RXNE) );             // wait until receive buffer is not empty
    
    //USART2->DR = SPI1->DR;
    result = SPI1->DR;
    
    if(chars_to_read != 0){
        while((SPI1->SR & SPI_SR_RXNE) );               // wait until receive buffer is empty
        delay();
        SPI1->DR = DUMMY_8BIT;                    // send dummy 8 bits to generate clock
        
        //delay();
        while( !(SPI1->SR & SPI_SR_TXE) );              // wait until transmit buffer is empty
        while( !(SPI1->SR & SPI_SR_RXNE) );             // wait until receive buffer is not empty
        temp = SPI1->DR;
        result = (result*256) + temp;
        chars_to_read--;
    }
    
    delay();
    SPI1_NSS = DESELECT_CHIP;                                   // set the SS pin high
    
    return result;
}

static void delay(void)
{
    unsigned int j = FALSE;
    for (j = 0; j < 25; j++) {
    }
}

qwazar
  • 11
  • 1
  • RXNE and TXE are flags regarding the state of the *buffer*. Once transmission of the first bit starts, TXE will go high as the buffer is already able to accept the next byte. This is good for reducing pauses between bytes. In certain cases, you will need to check the BSY flag instead. – Codo Feb 05 '21 at 09:00

0 Answers0