SPI FRAM driver_problem in reading data or status register content

Status
Not open for further replies.

sabra88

Newbie level 2
Joined
Aug 1, 2014
Messages
2
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Visit site
Activity points
121
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 !!!

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.
 

this is the code for a Ramtron FM33256 which has similar registers etc to the FM25CL64
although it is for a PIC24FJ256GB110 it may give you some ideas
Code:
#include "FM33256.h"

#define WREN 0x06
#define WRDI 0x04
#define RDSR 0x05
#define WRSR 0x01
#define READ 0x03
#define WRITE 0x02
#define RDPC 0x13
#define WRPC 0x12

#define FM33256_CS_TRIS      TRISEbits.TRISE9        // chip select port
#define FM33256_CS_PORT      PORTEbits.RE9               // set CS port output

#define oneHz					// define to output a 1 Hz signal


// send one byte of data and receive one back at the same time
static unsigned char writeSPI2( unsigned char i )
{
    SPI1BUF = i;                                        // write to buffer for TX
    while(!SPI1STATbits.SPIRBF);        // wait for transfer to complete
    return SPI1BUF;                    // read the received value
}//writeSPI1



/************************************************************************
* Structure STATREG and union _EEPROMStatus_                            *
*                                                                       *
* Overview: Provide a bits and byte access to EEPROM status value.      *
*                                                                       *
************************************************************************/
struct  STATREG{
        unsigned    WIP:1;
        unsigned    WEL:1;
        unsigned    BP0:1;
        unsigned    BP1:1;
        unsigned    RESERVED:3;
        unsigned    WPEN:1;
};

union _EEPROMStatus_{
        struct  STATREG Bits;
        unsigned char   Char;
};

// extract a low byte from a 2 byte word.          
#define Lo(X)   (unsigned char)(X&0x00ff)

// extract a high byte from a 2 byte word.        
#define Hi(X)   (unsigned char)((X>>8)&0x00ff)



// enable writeing to EEPROM
void EEPROMWriteEnable()
{
        unsigned char Local_8;
    FM33256_CS_PORT = 0;    // CS enabled
    Local_8 = writeSPI2(WREN);
    FM33256_CS_PORT = 1;    // CS disabled
}

void EEPROMWriteDisable()
{
        unsigned char Local_8;
    FM33256_CS_PORT = 0;    // CS enabled
    Local_8 = writeSPI2(WRDI);
    FM33256_CS_PORT = 1;    // CS disabled
}


// read status register
union _EEPROMStatus_ FM33256readStatus()
{
    unsigned char Local_8;
    FM33256_CS_PORT = 0;    // CS enabled
    Local_8 = writeSPI2(RDSR);
    Local_8 = writeSPI2(0);
    FM33256_CS_PORT = 1;    // CS disabled
    //printf("status %x\n",  Local_8);
    return (union _EEPROMStatus_)Local_8;
}

// write a byte to address (16 bits)
void FM33256write8(unsigned char Data, unsigned int Address)
{
        unsigned char Local_8;
    EEPROMWriteEnable();
    FM33256_CS_PORT = 0;    // CS enabled
    Local_8 = writeSPI2(WRITE);
    Local_8 = writeSPI2(Hi(Address));
    Local_8 = writeSPI2(Lo(Address));
    Local_8 = writeSPI2(Data);
    FM33256_CS_PORT = 1;    // CS disabled
    // wait for completion of previous write operation
    while(FM33256readStatus().Bits.WIP);  
    EEPROMWriteDisable();
}

// read a byte from address (16 bit)
unsigned char FM33256read8(unsigned int Address)
{
        unsigned char Local_8;
    FM33256_CS_PORT = 0;    // CS enabled
    Local_8 = writeSPI2(READ);
    Local_8 = writeSPI2(Hi(Address));
    Local_8 = writeSPI2(Lo(Address));
    Local_8 = writeSPI2(0);
    FM33256_CS_PORT = 1;    // CS disabled
    return Local_8;
}
 

Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…