stm32spieeprom

STM32F0x8 SPI with 25LC256 recieve problem [Peripheral Lib]


I use an STM32F0 discovery board. I am trying to program an EEPROM to save an QR-code and display it on an LCD. Right now I am working on getting the STM32 to receive the data from the EEPROM, my code works if I short MISO and MOSI (I changed it a bit but not much), but when I try to get it to work with the EEPROM, it doesnt work.

My code below. Header file:

#include "stm32f0xx_conf.h"
#include <string.h>

//Pin definitions
//#define NSSA GPIO_PinSource12
#define SCKA GPIO_PinSource13
#define MISOA GPIO_PinSource14
#define MOSIA GPIO_PinSource15
#define TXPINA GPIO_PinSource9
//#define NSS GPIO_Pin_12
#define CS GPIO_Pin_12
#define SCK GPIO_Pin_13
#define MISO GPIO_Pin_14
#define MOSI GPIO_Pin_15
#define TXPIN GPIO_Pin_9
#define HOLD GPIO_Pin_11
#define GreenLED_Pin GPIO_Pin_9
#define BlueLED_Pin GPIO_Pin_8

//EEPROM INSTRUCTIONS:
uint8_t READMEM  = 0x003;    //READ  -   0000 0011     Read data from memory array beginning at selected address
uint8_t WRITEMEM = 0x002;    //WRITE -   0000 0010     Write data to memory array beginning at selected address
uint8_t READSR   = 0x005;    //RDSR  -   0000 0101     Read STATUS register
uint8_t WRITESR  = 0x001;    //WRSR  -   0000 0001     Write STATUS register
uint8_t WRITEDI  = 0x004;    //WRDI  -   0000 0100     Reset the write enable latch (disable write operations)
uint8_t WRITEEN  = 0x006;    //WREN  -   0000 0110     Set the write enable latch (enable write operations)
uint8_t NULLBYTE = 0x000;

SPI initialization:

void SPI_EEPROM()

RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
GPIO_PinAFConfig(GPIOB,SCKA,GPIO_AF_0);
GPIO_PinAFConfig(GPIOB,MISOA,GPIO_AF_0);
GPIO_PinAFConfig(GPIOB,MOSIA,GPIO_AF_0);

GPIO_InitTypeDef SPIGPIO;
SPIGPIO.GPIO_Mode = GPIO_Mode_AF;
SPIGPIO.GPIO_OType = GPIO_OType_PP;
SPIGPIO.GPIO_PuPd = GPIO_PuPd_NOPULL;
SPIGPIO.GPIO_Speed = GPIO_Speed_50MHz;

SPIGPIO.GPIO_Pin = SCK;
GPIO_Init(GPIOB, &SPIGPIO);
SPIGPIO.GPIO_Pin = MISO;
GPIO_Init(GPIOB, &SPIGPIO);
SPIGPIO.GPIO_Pin = MOSI;
GPIO_Init(GPIOB, &SPIGPIO);
SPI_I2S_DeInit(SPI2);
SPI_InitTypeDef SPIEPR;
SPIEPR.SPI_Mode = SPI_Mode_Master;
SPIEPR.SPI_CPHA = SPI_CPHA_1Edge;
SPIEPR.SPI_CPOL = SPI_CPOL_Low;
SPIEPR.SPI_FirstBit = SPI_FirstBit_MSB;
SPIEPR.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32; //-> _16~3.2MHZ CLOCK | _32 ~1.6MHZ CLOCK
SPIEPR.SPI_NSS = SPI_NSS_Soft;
SPIEPR.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPIEPR.SPI_DataSize = SPI_DataSize_8b;
SPI_Init(SPI2, &SPIEPR);
SPI_NSSInternalSoftwareConfig(SPI2,SPI_NSSInternalSoft_Set);
//SPI2 -> CR2 |= SPI_CR2_FRXTH;
SPI_Cmd(SPI2,ENABLE);

GPIO initialization:

void GPIO()

GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
GPIO_InitStructure.GPIO_Pin = BlueLED_Pin|GreenLED_Pin;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_3;
GPIO_Init(GPIOC, &GPIO_InitStructure);

GPIO_InitTypeDef GPIO2_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);

GPIO2_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO2_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO2_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO2_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO2_InitStructure.GPIO_Pin = HOLD;
GPIO_Init(GPIOB, &GPIO2_InitStructure);
GPIO2_InitStructure.GPIO_Pin = CS;
GPIO_Init(GPIOB, &GPIO2_InitStructure);

The simple send and recieve function:

uint8_t SPISendByte(uint8_t data)

uint8_t databck;
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) != RESET);
SPI_SendData8(SPI2,data);                                                      
while(SPI_GetReceptionFIFOStatus(SPI2) != 0x0000)
  SPI_ReceiveData8(SPI2); //read RXFIFO until empty

while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET); //wait until TXFIFO is empty
SPI_SendData8(SPI2,NULLBYTE); //send 0-byte to recive answer from EEPROM
while(SPI_GetReceptionFIFOStatus(SPI2) != 0x0200); //wait until the RXFIFO is a quarter full (8bit)
return SPI_ReceiveData8(SPI2);

Main function:

SystemInit();
SPI_EEPROM();
GPIO();
    GPIO_ResetBits(GPIOB, CS); //CS low to enable the EEPROM
SPI_SendData8(SPI2,WRITEEN); //send the WREN instruction to set the write enable latch
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) != RESET);
GPIO_SetBits(GPIOB, CS); //Toggle on and off to set bit in the Status register
GPIO_ResetBits(GPIOB, CS);
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) != RESET);
USART_SendData(USART1, SPISendByte(READSR)); //Read Status Reg and print it to USART (should be ..0010)

I set up the EEPROM like its datasheet tells me to. Clock setup from the sheet(should be CPOL and CPHA 0):

Instructions, addresses or data present on the SI pin are latched on the rising edge of the clock input, while data on the SO pin is updated after the falling edge of the clock input.

This is not my entire code but what I use for testing. It should work; I double checked it with my scope (it returns ..0010 on MISO with the logic mode) and looked at the RXFIFO with the debugger if its empty and receives actual data: It does, but the code always returns 0. I also tried a lot of different Flags instead of reading the RXFIFO but it seemed to be the best solution.


Solution

  • So, after bashing my head against my table and my coworker stealing my oscilloscope, it worked, so i found out that the oscilloscope channels pulled my signal down bc i had the inputs in 50 Ohm mode and not 1MOhm. Switching that fixed it.