This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Help on M25P80 SPI c code for debug viewer

Hi , i have tried to write some code for M25P80 SPI communication using c programing. i have defined GPIO pins and chip select pin SPI functions also. But i want to make sure what are the functions should i add? Can anybody help me to complete the code for M25P80? or if anybody has written already some code then please email me at pra20008dip@homtail.com thank you.

  • Complete the code?

    You haven't shown any "incomplete code".

    And I don't think your teacher wants us to hand over all the code you are expected to write yourself.

  • Per Westermark ....Here is my incomplete code...i have make transmit data and hold for 5 second then again transmit ...and for up to 3 KHz...

    #include <stm32f4xx.h>
    #include <stm32f4xx_conf.h>
    
    uint8_t received_val;
            uint8_t i;
    
    //static int i;
    void delay(uint32_t a)
    {
            while (a--);
    }
    void init_GPIO(void)
    {
            GPIO_InitTypeDef GPIO_InitStruct;
            RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
    
            GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;          //Select pin PA0 (User Button) to configure
            GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;       //Set pin to input
            GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;  //Set GPIO clock speed
            GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;     //Set pin type to push/pull
            GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_DOWN;     //Enable pulldown resistor to detect high level
            GPIO_Init(GPIOA, &GPIO_InitStruct);                                                                 //Initialise GPIOA
    }
    void INTTIM_Config(void)
    {
      NVIC_InitTypeDef NVIC_InitStructure;
      TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    
      NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
      NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
      NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
      NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
      NVIC_Init(&NVIC_InitStructure);
    
       /* TIM2 clock enable */
      RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
      /* Time base configuration */
            TIM_TimeBaseStructure.TIM_Period = 3000;  // Up to 3 KHz (3 ms)
      TIM_TimeBaseStructure.TIM_Prescaler = 84 - 1;
      TIM_TimeBaseStructure.TIM_ClockDivision = 0;
      TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
      TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
      /* TIM IT enable */
      TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
      /* TIM2 enable counter */
      TIM_Cmd(TIM2, ENABLE);
    }
    // this function initializes the SPI1 peripheral
    void init_SPI1(void){
    
            GPIO_InitTypeDef GPIO_InitStruct;
            SPI_InitTypeDef SPI_InitStruct;
            //DMA_InitTypeDef  DMA_InitStructure;
    
            // enable clock for used IO pins
            RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
    
            /* configure pins used by SPI2
             * PA5 = SCK
             * PA6 = MISO
             * PA7 = MOSI
             */
            GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_6 | GPIO_Pin_5;
            GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
            GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
            GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
            GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
            GPIO_Init(GPIOA, &GPIO_InitStruct);
    
            // connect SPI1 pins to SPI alternate function
            GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1);
            GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1);
            GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1);
    
            // enable clock for used IO pins
            RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
    
            /* Configure the chip select pin
               in this case we will use PE7 */
            GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7;
            GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
            GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
            GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
            GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
            GPIO_Init(GPIOE, &GPIO_InitStruct);
    
            GPIOE->BSRRL |= GPIO_Pin_7; // set PE7 high
    
            // enable peripheral clock
            RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
    
            SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
            SPI_InitStruct.SPI_Mode = SPI_Mode_Master;
            SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;
            SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low;
            SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge;
            SPI_InitStruct.SPI_NSS = SPI_NSS_Soft | SPI_NSSInternalSoft_Set;
            SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
            SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;
            SPI_Init(SPI2, &SPI_InitStruct);
    
            SPI_Cmd(SPI1, ENABLE); // enable SPI2
    
    }
    
    
    /*void mySPI_SendData(uint8_t adress, uint8_t data){
    
            GPIO_ResetBits(GPIOE, GPIO_Pin_7);
    
            while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE));
            SPI_I2S_SendData(SPI1, adress);
            while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE));
            SPI_I2S_ReceiveData(SPI1);
    
            while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE));
            SPI_I2S_SendData(SPI1, data);
            while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE));
            SPI_I2S_ReceiveData(SPI1);
    
            GPIO_SetBits(GPIOE, GPIO_Pin_7);
            }*/
    
    /*void my_SPI_Cmd(uint8_t *A, uint8_t length, uint8_t *B)
    {
            uint8_t local_count = 0;
            GPIO_SetBits(GPIOE, GPIO_Pin_7);  // disable SPI device
            GPIO_ResetBits(GPIOE, GPIO_Pin_7);  // enable SPI device
    
            while (local_count < length)
            {
            SPI_I2S_SendData(SPI1, *(A + local_count));
            while (SPI_I2S_GetFlagStatus(SPI1, SPI_FLAG_TXE) == RESET); // wait until TX done
            while (SPI_I2S_GetFlagStatus(SPI1, SPI_FLAG_RXNE) == RESET); // wait until RX done
            *(B + local_count) = SPI_I2S_ReceiveData(SPI1);
            local_count++;
            }
            while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET); // wait until BSY = 0
    
            GPIO_SetBits(GPIOE, GPIO_Pin_7);  // disable SPI device
    }*/
    
    uint8_t SPI1_send(uint8_t data)
    {
    GPIO_ResetBits(GPIOE, GPIO_Pin_7);
            SPI1->DR = data;
            while( !(SPI1->SR & SPI_I2S_FLAG_TXE) );
            while( !(SPI1->SR & SPI_I2S_FLAG_RXNE) );
            while( SPI1->SR & SPI_I2S_FLAG_BSY );
    GPIO_SetBits(GPIOE, GPIO_Pin_7);
            return SPI1->DR;
    
    }
    int main(void)
    {
            init_SPI1();
            INTTIM_Config();
    
            GPIOD->BSRRL = 0xF000;       //Set PD12 through PD15 (BSRRL = Bit Set/Reset Register Low)
    delay(0xf42400);        //Wait
    GPIOD->BSRRH = 0xF000;       //Reset PD12 through PD15 (BSRRH = Bit Set/Reset Register High)
    //uint16_t received_val=0;
    
    while(1)
    {
    GPIOE->BSRRH |= GPIO_Pin_7; // set PE7 (CS) low
                    SPI1_send(i);  // transmit data
                    received_val = SPI1_send(0x00); // transmit dummy byte and receive data
                    GPIOE->BSRRL |= GPIO_Pin_7; // set PE7 (CS) high
    i++;
    delay(0x3D0900);
            //Add delay to debounce the switch
    }
    }
    

  • Hey, I have posted my code...could you please help me what else should i need to implement more..?

  • You enable a timer interrupt, but there is no service routine.

    Your delay function may be optimized away. Figure out what purpose it has, ideally use a timer or systick based counter to mark actual time, rather than loop iterations.

    Your main() loop sends non-sense to the Serial NOR Flash device.

    Have you reviewed the manual/data-sheet for the M25P80?

    If you send an READ ID Command, does it return the data you expect, along with the unique id?

    You'd want to implement a command function. Use that to send READ STATUS REGISTER, READ DATA BYTES, SECTOR ERASE, WRITE ENABLE, WRITE DISABLE, PROGRAM PAGE, etc.

  • Thanks for your suggestion ... I did completed the program...it works nice....