sabra88
Newbie level 2
I wrote a C-code describing an SPI driver for a FM25CL64 ram memory to interface it with a EFM32GG330 microcontroller. But when debugging, i found a problem reading from status registers or from memory array. In fact, they always return zero even if i write something on them and then read it !!
U will find the code here.
can anyone help me please !!!
Added code tags.
U will find the code here.
can anyone help me please !!!
Code:
/*
* FM25CL64.c
*/
//Global includes
#include "CommonLib.h"
//Debug include
#include "OSConsole.h"
#include "Console.h"
#include "system_efm32gg.h"
#include "em_cmu.h"
#include "em_gpio.h"
#include "VirtualClock.h"
#include "em_usart.h"
#include "General_Config.h"
#include "FM25CL64.h"
#include "FM25CL64_M.h"
//set up SPI interface for FM25CL64, at HFPERCLK/3
// FM25CL64 up to 20MHz SPI
// return 0 if all ok
void FM25CL64_GpioConfig(void)
{
//SPI Pins INIT
GPIO_PinModeSet(gpioPortC, 2 , gpioModePushPull, 0);
GPIO_PinModeSet(gpioPortC, 3 , gpioModeInput, 1);//input with filter for protection
GPIO_PinModeSet(gpioPortC, 4 , gpioModePushPull, 0);
GPIO_PinModeSet(gpioPortC, 5 , gpioModePushPull, 1); //FLACH_CS//
GPIO_PinModeSet(gpioPortC, 11 , gpioModePushPull, 1);//HOLD pin//
}
void FM25CL64_SpiConfig(void)
{
/*INIT*/
CMU_ClockEnable(cmuClock_USART2, true);
CMU_ClockEnable(cmuClock_GPIO, true);
/* Configure SPI */
USART2->CLKDIV=0x1700; //(0x1700 for 1Mhz) , SPI interface at HFPERCLK/3 = (48MHZ/8) =6 MHZ
//use mode 0
USART2->CTRL=0x00401 | (0x1 << 12) | (1<<9); //no auto CS, master, syn, TXbuffer available, falling edge for sampling
USART2->ROUTE=0x00B;//LOC0,//no CS--->the CS risk to change when TX buffer is empty!! AutoCS should work together with DMA!!
USART2->FRAME=0x005;
USART2->CMD = 0x15; //master enable, TxEN, RxEN
/* Clearing old transfers/receptions, and disabling interrupts */
//SPI0->CMD = USART_CMD_CLEARRX | USART_CMD_CLEARTX;
SPI0->IEN = 0;
}
uint8_t FM25CL64_Init(void)
{
FM25CL64_GpioConfig();
FM25CL64_SpiConfig();
return 0;
}
// return 0 if all ok
uint8_t FM25CL64_STATUS_READ(uint8_t *STATUS_VALUE) //to verify the content of the status register
{
uint8_t header_buffer[1];
header_buffer[0]=FM25CL64_RDSR; //FM25CL64_WRSR command used to enable reading from the status register
//Reading the content of the STATUS register
FM25CL64_readfromspi(1, header_buffer, 1, STATUS_VALUE);
return 0;
}
// return 0 if all ok
uint8_t FM25CL64_STATUS_WRTIE(uint8_t *STATUS_VALUE)//select certain write protection features by writing a byte to the Status register
{
uint8_t header_buffer[2];
uint8_t data_buffer[1];
header_buffer[0]=FM25CL64_WREN; //FM25CL64_WREN command used to enable write in general
header_buffer[1]=FM25CL64_WRSR; //FM25CL64_WRSR command used to enable write to the status register
data_buffer[0]=*STATUS_VALUE;
//writing to the Status registers
FM25CL64_writetospi(2, header_buffer, 1, data_buffer);
return 0;
}
// return 0 if all ok
uint8_t FM25CL64_DATA_READ(uint16_t address, uint8_t *DATA_VALUE)
{
uint8_t Read_length=1;
uint8_t header_buffer[2];
header_buffer[0]=0x03; //FM25CL64_READ command used to enable reading the memory
header_buffer[1]=address;
FM25CL64_readfromspi(2, header_buffer, 1, DATA_VALUE);
return 0;
}
// return 0 if all ok
uint8_t FM25CL64_DATA_WRTIE(uint16_t address, uint8_t *DATA_VALUE)
{
uint8_t write_length=1;
uint8_t header_buffer[2];
uint8_t data_buffer[1];
DATA_VALUE = data_buffer[0];
header_buffer[0]=FM25CL64_WREN; //FM25CL64_WREN command used to enable write in general
header_buffer[1]=FM25CL64_WRITE; //FM25CL64_WRSR command used to enable write to the status register
header_buffer[2]=address;
FM25CL64_writetospi(2, header_buffer, write_length, data_buffer);
return 0;
}
int FM25CL64_writetospi(uint8_t headerLength, uint8_t *headerBuffer,uint8_t bodylength, uint8_t *bodyBuffer)
{
int iii;
// uint16 data;
USART2->CMD=0xC00; //clear RX TX buffer
USART2->CMD=0x004; //TX enable, RX disable
USART2->ROUTE=0xB; //NO CS
for(iii=0;iii<headerLength;iii++)
{
/* CS Low */
GPIO_PinOutClear(PORTC, 5);
/* Waiting for the usart2 to be ready */
for(; (USART2->STATUS & 0x40)==0x0;);
USART2->TXDATA = headerBuffer[iii];
/* CS High */
GPIO_PinOutSet(PORTC, 5);
}
for(iii=0;iii<bodylength;iii++)
{
/* CS Low */
GPIO_PinOutClear(PORTC, 5);
/* Waiting for the usart2 to be ready */
for(; (USART2->STATUS & 0x40)==0x0;);
USART2->TXDATA = bodyBuffer[iii];
}
/*Waiting for transmission of last byte */
for(; (USART2->STATUS & 0x20)==0x0;);
/* CS High */
GPIO_PinOutSet(PORTC, 5);
return 0 ;
}
int FM25CL64_readfromspi(uint8_t headerLength, uint8_t *headerBuffer,uint8_t readlength, uint8_t *readBuffer)
{
int iii, jjj, kkk;
uint32_t temp,temp32, n1portekoi;
USART2->CMD=0xC00; //clear TX and RX buffer
USART2->CMD=0x005; //RX enable, TX enable
USART2->ROUTE=0xB; //NO CS
/* CS Low */
GPIO_PinOutClear(PORTC, 5);
//VirtualClock_wait_us(0.01); //Chip Select Setup tCSU_min=10ns
for(iii=0,jjj=0,kkk=0;(jjj<readlength);)
{
temp32=USART2->STATUS;
if((temp32 & 0x40) ==0x40 ) //TX buffer available
{
if(iii<(headerLength+readlength))
{
if(iii<headerLength)
{
USART2->TXDATA = headerBuffer[iii++];
}
else
USART2->TXDATA = 0x00; //NOP cmd ads1248
}
}
if(( temp32 & 0x80)==0x80) // data ready
{
if (kkk>=headerLength)
readBuffer[jjj++]=USART2->RXDATA;
else
{
temp=USART2->RXDATA;kkk++;
}
}
}
/* CS High */
GPIO_PinOutSet(PORTC, 5);
return 0;
}
Added code tags.