472 lines
12 KiB
C
472 lines
12 KiB
C
/*=================================================================
|
|
File name : SPISE2PD.C
|
|
|
|
Originator : Settu Duraisamy
|
|
C2000 Applications Team
|
|
Texas Instruments
|
|
|
|
Description : This file contains the SPI bus Serial EEPROM driver
|
|
implemented using Virtual SPI driver
|
|
|
|
Date : 6/30/2003 (DD/MM/YYYY)
|
|
====================================================================*/
|
|
|
|
#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
|
|
|
|
#include "spise2p.h"
|
|
//#include "pins.h"
|
|
|
|
/* Instance the SPI bus serial EEPROM driver */
|
|
static SPISE2P_DRV se2p=SPISE2P_DRV_DEFAULTS;
|
|
|
|
/* Instance serial EEPROm data transfer structure */
|
|
static SE2P_DATA writeData, readData;
|
|
|
|
// Prototype statements for functions found within this file.
|
|
interrupt void PRD_TICK(void);
|
|
interrupt void cpu_timer2_isr(void);
|
|
|
|
int ccc=0;
|
|
|
|
/********************************************************************/
|
|
/******* SPI bus Serial EEPROM driver Initialization routine ********/
|
|
/********************************************************************/
|
|
|
|
void Seeprom_write( unsigned int adres,
|
|
unsigned int buf[],
|
|
unsigned int size)
|
|
{
|
|
unsigned int len;
|
|
|
|
// diod2_on();
|
|
|
|
CpuTimer2.InterruptCount=0;
|
|
CpuTimer2Regs.TCR.all = 0x4020; // Use write-only instruction to set TSS bit = 0
|
|
|
|
while(!spiSe2pFree(&se2p));
|
|
|
|
size = (size / WORD_LEN) + (size % WORD_LEN);
|
|
while(size)
|
|
{
|
|
len = PAGE_LEN - (adres % PAGE_LEN);
|
|
if(len > size) len=size;
|
|
|
|
writeData.dataPtr = buf;
|
|
writeData.nrData = len;
|
|
writeData.se2pAddr = adres * WORD_LEN;
|
|
|
|
spiSe2pWrite(&se2p, &writeData);
|
|
while(!spiSe2pFree(&se2p));
|
|
|
|
buf += len;
|
|
adres += len;
|
|
size -= len;
|
|
}
|
|
CpuTimer2Regs.TCR.all = 0x4010; // Use write-only instruction to set TSS bit = 1
|
|
// diod2_off();
|
|
|
|
}
|
|
|
|
void Seeprom_read( unsigned int adres,
|
|
unsigned int buf[],
|
|
unsigned int size)
|
|
{
|
|
unsigned int len;
|
|
|
|
// diod2_on();
|
|
CpuTimer2.InterruptCount=0;
|
|
CpuTimer2Regs.TCR.all = 0x4020; // Use write-only instruction to set TSS bit = 0
|
|
|
|
while(!spiSe2pFree(&se2p));
|
|
|
|
size = (size / WORD_LEN) + (size % WORD_LEN);
|
|
while(size)
|
|
{
|
|
len = PAGE_LEN - (adres % PAGE_LEN);
|
|
if(len > size) len=size;
|
|
|
|
readData.dataPtr = buf;
|
|
readData.nrData = len;
|
|
readData.se2pAddr = adres * WORD_LEN;
|
|
|
|
spiSe2pRead(&se2p, &readData);
|
|
while(!spiSe2pFree(&se2p));
|
|
|
|
buf += len;
|
|
adres += len;
|
|
size -= len;
|
|
}
|
|
CpuTimer2Regs.TCR.all = 0x4010; // Use write-only instruction to set TSS bit = 1
|
|
// diod2_off();
|
|
}
|
|
|
|
void Init_Seeprom()
|
|
{
|
|
se2p.init(&se2p);
|
|
|
|
EALLOW; // This is needed to write to EALLOW protected registers
|
|
PieVectTable.TINT2 = &cpu_timer2_isr;
|
|
EDIS; // This is needed to disable write to EALLOW protected registers
|
|
|
|
InitCpuTimers(); // For this example, only initialize the Cpu Timers
|
|
// ConfigCpuTimer(&CpuTimer2, (SYSCLKOUT/1000000), 100);
|
|
// ConfigCpuTimer(&CpuTimer2, (SYSCLKOUT/1000000), 10);
|
|
ConfigCpuTimer(&CpuTimer2, (SYSCLKOUT/1000000), 100);
|
|
|
|
IER |= M_INT14;
|
|
}
|
|
|
|
void SPISE2P_DRV_init(SPISE2P_DRV *eeprom)
|
|
{
|
|
/* Configure SPI-A pins using GPIO regs*/
|
|
// This specifies which of the possible GPIO pins will be SPI functional pins.
|
|
// Comment out other unwanted lines.
|
|
EALLOW;
|
|
GpioCtrlRegs.GPAMUX2.bit.GPIO16 = 1; // Configure GPIO16 as SPISIMOA
|
|
GpioCtrlRegs.GPAMUX2.bit.GPIO17 = 1; // Configure GPIO17 as SPISOMIA
|
|
GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 1; // Configure GPIO18 as SPICLKA
|
|
GpioCtrlRegs.GPAMUX2.bit.GPIO19 = 0; // General purpose I/O 19 (default) (I/O)
|
|
GpioCtrlRegs.GPADIR.bit.GPIO19 = 1; // Configures the GPIO pin as an output
|
|
GpioDataRegs.GPADAT.bit.GPIO19 = 0;
|
|
EDIS;
|
|
|
|
/* Configure the SPI: 8-bit, Rising edge with delay */
|
|
SpiaRegs.SPICCR.all=0x0007;
|
|
SpiaRegs.SPICTL.all=0x001F;
|
|
SpiaRegs.SPISTS.all=0x00;
|
|
|
|
SpiaRegs.SPIBRR = (LSPCLK / SPIBAUD_RATE) - 1;
|
|
|
|
SpiaRegs.SPIFFTX.all=0x8000;
|
|
SpiaRegs.SPIFFRX.all=0x0000;
|
|
SpiaRegs.SPIFFCT.all=0x00;
|
|
SpiaRegs.SPIPRI.all=0x0010;
|
|
|
|
/* Disable Chip Select of Serial EEPROM */
|
|
eeprom->csr=0;
|
|
eeprom->msgPtr=0;
|
|
|
|
SpiaRegs.SPICCR.bit.SPISWRESET=1; // Enable SCI
|
|
}
|
|
|
|
void SPISE2P_DRV_csset()
|
|
{
|
|
GpioDataRegs.GPADAT.bit.GPIO19 = 1;
|
|
}
|
|
|
|
void SPISE2P_DRV_csclr()
|
|
{
|
|
GpioDataRegs.GPADAT.bit.GPIO19 = 0;
|
|
}
|
|
|
|
unsigned int spiSe2pFree(SPISE2P_DRV *se2p)
|
|
{
|
|
if(se2p->csr&0x3) return(0);
|
|
else return(1);
|
|
}
|
|
|
|
void spiSe2pWrite(SPISE2P_DRV *se2p, SE2P_DATA *msgPtr)
|
|
{
|
|
se2p->msgPtr=msgPtr;
|
|
se2p->csr|=0x1;
|
|
}
|
|
|
|
void spiSe2pRead(SPISE2P_DRV *se2p, SE2P_DATA *msgPtr)
|
|
{
|
|
se2p->msgPtr=msgPtr;
|
|
se2p->csr|=0x2;
|
|
}
|
|
|
|
/********************************************************************/
|
|
/******* SPI bus Serial EEPROM driver Tick function *****************/
|
|
/********************************************************************/
|
|
|
|
interrupt void cpu_timer2_isr(void)
|
|
{ EALLOW;
|
|
CpuTimer2.InterruptCount++;
|
|
|
|
se2p.tick(&se2p);
|
|
|
|
// The CPU acknowledges the interrupt.
|
|
EDIS;
|
|
}
|
|
|
|
void SPISE2P_DRV_tick(SPISE2P_DRV *eeprom)
|
|
{
|
|
static unsigned int step=0;
|
|
static unsigned int dataCount=0;
|
|
static volatile unsigned int dummy=0;
|
|
|
|
switch(step)
|
|
{
|
|
case 0:
|
|
/* If write request is SET, then trigger the Write operation
|
|
If read request is SET, then trigger the Read operation
|
|
If Read request is also not SET, then continue to poll */
|
|
|
|
if(eeprom->csr&SPISE2P_WRRQ)
|
|
{ step=1;
|
|
eeprom->csr|=SPISE2P_WRIP; /* Set Write in progress*/
|
|
eeprom->csclr();
|
|
}
|
|
|
|
if(eeprom->csr&SPISE2P_RDRQ)
|
|
{ step=13;
|
|
eeprom->csr|=SPISE2P_RDIP; /* Set Read in progress */
|
|
eeprom->csclr();
|
|
}
|
|
break;
|
|
|
|
case 1:
|
|
/************************************************************
|
|
*********** SPI bus EEPROM Write Starts from here ***********
|
|
*************************************************************
|
|
Prier to any attempt to write data to SPI serial EEPROM
|
|
Write Enable Latch must be set by issuing the WREN command */
|
|
SpiaRegs.SPICCR.all=SPISE2P_TFR8BIT;
|
|
SpiaRegs.SPITXBUF=SPISE2P_WREN_CMD;
|
|
SpiaRegs.SPISTS.bit.BUFFULL_FLAG=1;
|
|
step=2;
|
|
break;
|
|
|
|
case 2:
|
|
/* Wait for VSPI State machine to send the WREN command and
|
|
serial EEPROM Chip Select must be brought to HIGH to set
|
|
the WREN latch */
|
|
|
|
if(SpiaRegs.SPISTS.bit.INT_FLAG) /* Check SPI INT FLAG */
|
|
{
|
|
dummy=SpiaRegs.SPIRXBUF; /* Reset SPI INT FLAG */
|
|
eeprom->csset();
|
|
|
|
step=3;
|
|
}
|
|
break;
|
|
|
|
case 3:
|
|
/* Assert CS of Serial EEPROM and send WRITE command */
|
|
|
|
eeprom->csclr();
|
|
SpiaRegs.SPICCR.all=SPISE2P_TFR8BIT;
|
|
SpiaRegs.SPITXBUF=SPISE2P_WRITE_CMD;
|
|
SpiaRegs.SPISTS.bit.BUFFULL_FLAG=1;
|
|
step=4;
|
|
break;
|
|
|
|
case 4:
|
|
/* Wait for VSPI State machine to send the WRITE command */
|
|
|
|
if(SpiaRegs.SPISTS.bit.INT_FLAG) /* Check SPI INT FLAG */
|
|
{ dummy=SpiaRegs.SPIRXBUF; /* Reset SPI INT FLAG */
|
|
step=5;
|
|
}
|
|
break;
|
|
|
|
case 5:
|
|
/* Send Address */
|
|
|
|
#if(SPISE2P_ADDR_WIDTH==SIXTEEN_BIT)
|
|
SpiaRegs.SPICCR.all= SPISE2P_TFR16BIT;
|
|
SpiaRegs.SPITXBUF=eeprom->msgPtr->se2pAddr;
|
|
#endif
|
|
#if(SPISE2P_ADDR_WIDTH==EIGHT_BIT)
|
|
SpiaRegs.SPICCR.all= SPISE2P_TFR8BIT;
|
|
SpiaRegs.SPITXBUF=eeprom->msgPtr->se2pAddr<<8;
|
|
#endif
|
|
|
|
SpiaRegs.SPISTS.bit.BUFFULL_FLAG=1; /* Set TXBUF FULL FLAG */
|
|
step=6;
|
|
break;
|
|
|
|
case 6:
|
|
/* Wait for VSPI State machine to send the Address */
|
|
|
|
if(SpiaRegs.SPISTS.bit.INT_FLAG) /* Check SPI INT FLAG */
|
|
{ dummy=SpiaRegs.SPIRXBUF; /* Reset SPI INT FLAG */
|
|
step=7;
|
|
}
|
|
break;
|
|
|
|
case 7:
|
|
/* Send Data */
|
|
|
|
#if(SPISE2P_DATA_WIDTH==SIXTEEN_BIT)
|
|
SpiaRegs.SPICCR.all=SPISE2P_TFR16BIT;
|
|
SpiaRegs.SPITXBUF=*(eeprom->msgPtr->dataPtr+dataCount);
|
|
#endif
|
|
|
|
#if(SPISE2P_DATA_WIDTH==EIGHT_BIT)
|
|
SpiaRegs.SPICCR.all=SPISE2P_TFR8BIT;
|
|
SpiaRegs.SPITXBUF=*(eeprom->msgPtr->dataPtr+dataCount)<<8;
|
|
#endif
|
|
|
|
dataCount++;
|
|
SpiaRegs.SPISTS.bit.BUFFULL_FLAG=1; /* Set TXBUF FULL FLAG */
|
|
step=8;
|
|
break;
|
|
|
|
case 8:
|
|
/* Wait for VSPI State machine to send the Data.
|
|
If all the data are sent, then set the CS pin to HIGH
|
|
to program or write the data in EEPROM array */
|
|
|
|
if(SpiaRegs.SPISTS.bit.INT_FLAG) /* Check SPI INT FLAG */
|
|
{ dummy=SpiaRegs.SPIRXBUF; /* Reset SPI INT FLAG */
|
|
|
|
if (dataCount==eeprom->msgPtr->nrData)
|
|
{ eeprom->csset();
|
|
step=9;}
|
|
else
|
|
step=7; /* Write next data */
|
|
}
|
|
break;
|
|
|
|
|
|
case 9:
|
|
/* Read the EEPROM status register to check whether the
|
|
data sent are indeed programmed to the EEPROM array.
|
|
Hence, send RDSR command to EEPROM to read status reg. */
|
|
|
|
eeprom->csclr();
|
|
SpiaRegs.SPICCR.all=SPISE2P_TFR8BIT;
|
|
SpiaRegs.SPITXBUF=SPISE2P_RDSR_CMD;
|
|
SpiaRegs.SPISTS.bit.BUFFULL_FLAG=1; /* Set TXBUF FULL FLAG */
|
|
step=10;
|
|
break;
|
|
|
|
case 10:
|
|
/* Wait for VSPI State machine to send RDSR command */
|
|
|
|
if(SpiaRegs.SPISTS.bit.INT_FLAG) /* Check SPI INT FLAG */
|
|
{ dummy=SpiaRegs.SPIRXBUF; /* Reset SPI INT FLAG */
|
|
step=11;
|
|
}
|
|
break;
|
|
|
|
case 11:
|
|
/* Send dummy Data to read Status reg. */
|
|
|
|
SpiaRegs.SPITXBUF=SPISE2P_DUMMY_DATA;
|
|
SpiaRegs.SPISTS.bit.BUFFULL_FLAG=1; /* Set TXBUF FULL FLAG */
|
|
step=12;
|
|
break;
|
|
|
|
case 12:
|
|
/* Wait for VSPI State machine to clock out status reg.
|
|
Check, whether the data are written to the EEPROM array,
|
|
If written, then reset the WRIP(write in progress) and
|
|
WRRQ(Write request bit) and go back to STATE0 */
|
|
|
|
if(SpiaRegs.SPISTS.bit.INT_FLAG) /* Check SPI INT FLAG */
|
|
{ eeprom->csset();
|
|
|
|
if (SpiaRegs.SPIRXBUF & SPISE2P_BUSY_MASK )
|
|
step=9;
|
|
else
|
|
{ eeprom->csr&=(~SPISE2P_WRIP);
|
|
eeprom->csr&=(~SPISE2P_WRRQ);
|
|
step=0;
|
|
dataCount=0;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 13:
|
|
/************************************************************
|
|
*********** SPI bus EEPROM Read Starts from here ***********
|
|
*************************************************************
|
|
Send READ Command to SPI bus serail EEPROM */
|
|
|
|
SpiaRegs.SPICCR.all=SPISE2P_TFR8BIT;
|
|
SpiaRegs.SPITXBUF=SPISE2P_READ_CMD;
|
|
SpiaRegs.SPISTS.bit.BUFFULL_FLAG=1; /* Set TXBUF FULL FLAG */
|
|
step=14;
|
|
break;
|
|
|
|
case 14:
|
|
/* Wait for VSPI State machine to send READ command */
|
|
|
|
if(SpiaRegs.SPISTS.bit.INT_FLAG) /* Check SPI INT FLAG */
|
|
{ dummy=SpiaRegs.SPIRXBUF; /* Reset SPI INT FLAG */
|
|
step=15;
|
|
}
|
|
break;
|
|
|
|
case 15:
|
|
/* Send Address */
|
|
|
|
#if(SPISE2P_ADDR_WIDTH==SIXTEEN_BIT)
|
|
SpiaRegs.SPICCR.all= SPISE2P_TFR16BIT;
|
|
SpiaRegs.SPITXBUF=eeprom->msgPtr->se2pAddr;
|
|
#endif
|
|
#if(SPISE2P_ADDR_WIDTH==EIGHT_BIT)
|
|
SpiaRegs.SPICCR.all= SPISE2P_TFR8BIT;
|
|
SpiaRegs.SPITXBUF=eeprom->msgPtr->se2pAddr<<8;
|
|
#endif
|
|
|
|
SpiaRegs.SPISTS.bit.BUFFULL_FLAG=1; /* Set TXBUF FULL FLAG */
|
|
step=16;
|
|
break;
|
|
|
|
case 16:
|
|
/* Wait for VSPI State machine to send Address */
|
|
|
|
if(SpiaRegs.SPISTS.bit.INT_FLAG) /* Check SPI INT FLAG */
|
|
{ dummy=SpiaRegs.SPIRXBUF; /* Reset SPI INT FLAG */
|
|
step=17;
|
|
}
|
|
break;
|
|
|
|
case 17:
|
|
/* Send Dummy value to clock out data from serial EEPROM */
|
|
|
|
#if(SPISE2P_DATA_WIDTH==SIXTEEN_BIT)
|
|
SpiaRegs.SPICCR.all= SPISE2P_TFR16BIT;
|
|
SpiaRegs.SPITXBUF=SPISE2P_DUMMY_DATA;
|
|
#endif
|
|
|
|
#if(SPISE2P_DATA_WIDTH==EIGHT_BIT)
|
|
SpiaRegs.SPICCR.all= SPISE2P_TFR8BIT;
|
|
SpiaRegs.SPITXBUF=SPISE2P_DUMMY_DATA<<8;
|
|
#endif
|
|
|
|
SpiaRegs.SPISTS.bit.BUFFULL_FLAG=1; /* Set TXBUF FULL FLAG */
|
|
step=18;
|
|
break;
|
|
|
|
case 18:
|
|
/* Wait for VSPI State machine to clk out data from EEPROM */
|
|
|
|
if(SpiaRegs.SPISTS.bit.INT_FLAG) /* Check SPI INT FLAG */
|
|
{
|
|
#if(SPISE2P_DATA_WIDTH==SIXTEEN_BIT)
|
|
*(eeprom->msgPtr->dataPtr+dataCount)=SpiaRegs.SPIRXBUF;
|
|
#endif
|
|
|
|
#if(SPISE2P_DATA_WIDTH==EIGHT_BIT)
|
|
*(eeprom->msgPtr->dataPtr+dataCount)=SpiaRegs.SPIRXBUF&0xFF;
|
|
#endif
|
|
dataCount++;
|
|
step=19;
|
|
}
|
|
break;
|
|
|
|
case 19:
|
|
/* If all the data are read, terminate the read operation by
|
|
rising the CS. Then reset the RDIP (Read in progress) bit
|
|
and reset the RDRQ(Read request) bit and go back to STATE0 */
|
|
|
|
if (dataCount==eeprom->msgPtr->nrData)
|
|
{ eeprom->csset();
|
|
step=0;
|
|
dataCount=0;
|
|
eeprom->csr&=(~SPISE2P_RDIP);
|
|
eeprom->csr&=(~SPISE2P_RDRQ);
|
|
}
|
|
else
|
|
step=17;
|
|
break;
|
|
}
|
|
}
|
|
|