Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronic Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Register Log in

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
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.
 

horace1

Advanced Member level 5
Joined
Nov 18, 2008
Messages
2,123
Helped
596
Reputation
1,188
Reaction score
573
Trophy points
1,393
Location
Norwich, UK
Activity points
13,071
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;
}
 

sabra88

Newbie level 2
Joined
Aug 1, 2014
Messages
2
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
121
thank u that was helpfull :)
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Top