Фронты START/STOP обрабатываются при принятии командного слова CAN/RS, а окончание импульса обслуживается таймером. STOP имеет приоритет, перекрытие выходов исключено, сохранена защита от самопуска при включении. Загрузка параметров больше не подменяет живые команды нагрузки. Добавлены подробные русские комментарии во все собственные C-модули и основные заголовки, описание поведения и host-тест автомата. Обновлены файлы прошивки. Полная сборка TI 22.6.1.LTS и тесты пройдены; проверка на физической плате не выполнялась.
463 lines
12 KiB
C
463 lines
12 KiB
C
/* SPI EEPROM. Seeprom_read/write ðàçáèâàþò çàïðîñ íà ñòðàíèöû
|
|
* è ñèíõðîííî æäóò spiSe2pFree. SPI-àâòîìàò ïðîäâèãàåò òàéìåð 2
|
|
* êàæäûå 100 ìêñ. Ïðè çàïðåòå ýòîãî IRQ îæèäàíèå íå çàâåðøèòñÿ.
|
|
* Òàéì-àóò â ñòàðîì äðàéâåðå îòñóòñòâóåò. Äèñêðåòû ÑÈÔÓ òåïåðü
|
|
* íå çàâèñÿò îò òîãî, çàâåðøèëîñü ëè ýòî îæèäàíèå â main.
|
|
*/
|
|
#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 ********/
|
|
/********************************************************************/
|
|
|
|
/* Áëîêèðóåò main äî çàâåðøåíèÿ ñòðàíèö. Çàïðåò IRQ îñòàíîâèò
|
|
* SPI-àâòîìàò. CAN è òàéìåð ÑÈÔÓ äîëæíû ïðåðûâàòü ýòî îæèäàíèå.
|
|
*/
|
|
void Seeprom_write( unsigned int adres,
|
|
unsigned int buf[],
|
|
unsigned int size)
|
|
{
|
|
unsigned int len;
|
|
|
|
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
|
|
}
|
|
|
|
/* ×òåíèå òàêæå ñèíõðîííîå äëÿ main, òàéì-àóò íå ðåàëèçîâàí.
|
|
* Ïðè çàâèñàíèè ïðîâåðèòü step/SPI è ðàáîòó òàéìåðà 2.
|
|
*/
|
|
void Seeprom_read( unsigned int adres,
|
|
unsigned int buf[],
|
|
unsigned int size)
|
|
{
|
|
unsigned int len;
|
|
|
|
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
|
|
}
|
|
|
|
void InitSeeprom()
|
|
{
|
|
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);
|
|
|
|
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 = CLKMULT * 6;
|
|
|
|
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;
|
|
}
|
|
}
|
|
|