Fix issue on SPI RDRF

This commit is contained in:
Mimmo La Fauci 2012-06-16 19:05:42 +02:00
parent ca9415ba25
commit bdc4d0ab22
4 changed files with 59 additions and 104 deletions

View File

@ -110,6 +110,7 @@ typedef struct sStatSpi
int txErr; int txErr;
int rxErr; int rxErr;
int wrongFrame; int wrongFrame;
int frameDisalign;
int lastCmd; int lastCmd;
int lastError; int lastError;
unsigned long status; unsigned long status;
@ -127,6 +128,7 @@ void initStatSpi()
statSpi.timeoutErr= 0; statSpi.timeoutErr= 0;
statSpi.timeoutIntErr= 0; statSpi.timeoutIntErr= 0;
statSpi.wrongFrame = 0; statSpi.wrongFrame = 0;
statSpi.frameDisalign = 0;
} }
void printStatSpi() void printStatSpi()
@ -139,6 +141,7 @@ void printStatSpi()
printk("spiTmoErr\t: 0x%x\n", statSpi.timeoutErr); printk("spiTmoErr\t: 0x%x\n", statSpi.timeoutErr);
printk("spiTmoIntErr\t: 0x%x\n", statSpi.timeoutIntErr); printk("spiTmoIntErr\t: 0x%x\n", statSpi.timeoutIntErr);
printk("wrongFrame\t: 0x%x\n", statSpi.wrongFrame); printk("wrongFrame\t: 0x%x\n", statSpi.wrongFrame);
printk("disalFrame\t: 0x%x\n", statSpi.frameDisalign);
} }
cmd_state_t cmd_state_t
@ -259,30 +262,6 @@ void showTTCPstatus()
tcp_debug_print_pcbs(); tcp_debug_print_pcbs();
} }
inline spi_status_t myspi_read(volatile avr32_spi_t *spi, unsigned short *data)
{
if (spi->sr & AVR32_SPI_SR_RDRF_MASK)
*data = spi->rdr >> AVR32_SPI_RDR_RD_OFFSET;
return SPI_OK;
}
inline spi_status_t myspi_write(volatile avr32_spi_t *spi, unsigned short data)
{
unsigned int timeout = SPI_TIMEOUT;
while (!(spi->sr & AVR32_SPI_SR_TDRE_MASK)) {
if (!timeout--) {
return SPI_ERROR_TIMEOUT;
}
}
spi->tdr = data << AVR32_SPI_TDR_TD_OFFSET;
return SPI_OK;
}
int write_stream(volatile avr32_spi_t *spi, const char *stream, uint16_t len) int write_stream(volatile avr32_spi_t *spi, const char *stream, uint16_t len)
{ {
uint16_t _len = 0; uint16_t _len = 0;
@ -307,44 +286,19 @@ int write_stream(volatile avr32_spi_t *spi, const char *stream, uint16_t len)
else else
{ {
stream++; stream++;
unsigned long data = ARD_SPI->rdr; spi_read(spi,&dummy);
data = data;
} }
//SIGN1_UP(); //SIGN1_UP();
// if (myspi_read(spi, &dummy) == SPI_ERROR_TIMEOUT)
// {
// statSpi.timeoutErr++;
// statSpi.rxErr++;
// statSpi.lastError = SPI_ERROR_TIMEOUT;
// statSpi.status = spi_getStatus(spi);
// return SPI_ERROR_TIMEOUT;
// }
}while ((!streamExit)&&(_len++ <= len)); }while ((!streamExit)&&(_len++ <= len));
end_write=true;
//while (spi_readRegisterFullCheck(spi)); if (!streamExit)
spi_read(spi,&dummy); {
if ((ARD_SPI->sr & AVR32_SPI_SR_RDRF_MASK) != 0)
{
int a = 0;
if ((ARD_SPI->sr & AVR32_SPI_SR_RDRF_MASK) != 0)
a = rand();
a=a+5;
}
if (!streamExit)
{
#ifdef _SPI_STATS_ #ifdef _SPI_STATS_
statSpi.wrongFrame++; statSpi.wrongFrame++;
statSpi.lastError = SPI_ERROR_ARGUMENT; statSpi.lastError = SPI_ERROR_ARGUMENT;
#endif #endif
return SPI_ERROR_ARGUMENT; return SPI_ERROR_ARGUMENT;
} }
if ((ARD_SPI->sr & AVR32_SPI_SR_RDRF_MASK) != 0)
{
//SIGN1_DN();
}
return SPI_OK; return SPI_OK;
} }
@ -357,21 +311,23 @@ void sendError()
while(!spi_writeRegisterEmptyCheck(&AVR32_SPI)); while(!spi_writeRegisterEmptyCheck(&AVR32_SPI));
} }
BUSY_FOR_SPI(); BUSY_FOR_SPI();
WARN("Send SPI error!"); WARN("Send SPI error!\n");
} }
#define ENABLE_SPI_INT() do { \ #define ENABLE_SPI_INT() do { \
volatile avr32_spi_t *spi = ARD_SPI; \
Bool global_interrupt_enabled = Is_global_interrupt_enabled(); \ Bool global_interrupt_enabled = Is_global_interrupt_enabled(); \
if (global_interrupt_enabled) Disable_global_interrupt(); \ if (global_interrupt_enabled) Disable_global_interrupt(); \
ARD_SPI->IER.rdrf = 1; \ spi->IER.rdrf = 1; \
ARD_SPI->IER.rxbuff = 1; ARD_SPI->IER.endrx = 1; \ spi->IER.rxbuff = 1; spi->IER.endrx = 1; \
if (global_interrupt_enabled) Enable_global_interrupt(); \ if (global_interrupt_enabled) Enable_global_interrupt(); \
}while(0); }while(0);
#define DISABLE_SPI_INT() do { \ #define DISABLE_SPI_INT() do { \
volatile avr32_spi_t *spi = ARD_SPI; \
Bool global_interrupt_enabled = Is_global_interrupt_enabled(); \ Bool global_interrupt_enabled = Is_global_interrupt_enabled(); \
if (global_interrupt_enabled) Disable_global_interrupt(); \ if (global_interrupt_enabled) Disable_global_interrupt(); \
ARD_SPI->IDR.rdrf = 1; ARD_SPI->IDR.rxbuff = 1; ARD_SPI->IDR.endrx = 1; \ spi->IDR.rdrf = 1; spi->IDR.rxbuff = 1; spi->IDR.endrx = 1; \
if (global_interrupt_enabled) Enable_global_interrupt(); \ if (global_interrupt_enabled) Enable_global_interrupt(); \
}while(0); }while(0);
@ -1494,6 +1450,8 @@ bool checkMsgFormat(uint8_t* _recv, int len, int* offset)
if ((enableDebug & INFO_WARN_FLAG)&&(len < 20)) //TODO stamp only short messages wrong if ((enableDebug & INFO_WARN_FLAG)&&(len < 20)) //TODO stamp only short messages wrong
dump((char*)_recv, len); dump((char*)_recv, len);
STATSPI_DISALIGN_ERROR();
if (recv == NULL) if (recv == NULL)
return false; return false;
} }
@ -1552,15 +1510,6 @@ void spi_poll(struct netif* netif) {
receivedChars = 0; receivedChars = 0;
count = 0; count = 0;
state = SPI_CMD_IDLE; state = SPI_CMD_IDLE;
if ((ARD_SPI->sr & AVR32_SPI_SR_RDRF_MASK) != 0)
{
unsigned long data = ARD_SPI->rdr;
data = data;
if ((ARD_SPI->sr & AVR32_SPI_SR_RDRF_MASK) != 0)
{
//SIGN1_DN();
}
}
} }
else else
{ {
@ -1577,9 +1526,18 @@ void spi_poll(struct netif* netif) {
//Available for receiving a new spi data //Available for receiving a new spi data
AVAIL_FOR_SPI(); AVAIL_FOR_SPI();
} }
#ifdef _SPI_STATS_
if (statSpi.lastError != 0)
{
WARN("[E(0x%x) spiStatus:0x%x]\n", statSpi.lastError, statSpi.status);
statSpi.lastError = 0;
}
#endif
} }
inline int spi_slaveReceiveInt(volatile avr32_spi_t *spi, bool startRecvd) // ****TEMPORARY
/*inline*/ int spi_slaveReceiveInt(volatile avr32_spi_t *spi, bool startRecvd)
{ {
receivedChars=0; receivedChars=0;
int index = 0; int index = 0;
@ -1595,20 +1553,15 @@ inline int spi_slaveReceiveInt(volatile avr32_spi_t *spi, bool startRecvd)
} }
do { do {
err = SPI_OK; err = SPI_OK;
//SIGN1_DN();
//spi->tdr = DUMMY_DATA << AVR32_SPI_TDR_TD_OFFSET;
while ((spi->sr & (AVR32_SPI_SR_RDRF_MASK | AVR32_SPI_SR_TXEMPTY_MASK)) != while ((spi->sr & (AVR32_SPI_SR_RDRF_MASK | AVR32_SPI_SR_TXEMPTY_MASK)) !=
(AVR32_SPI_SR_RDRF_MASK | AVR32_SPI_SR_TXEMPTY_MASK)) { (AVR32_SPI_SR_RDRF_MASK | AVR32_SPI_SR_TXEMPTY_MASK)) {
if (!timeout--) { if ((timeout--)==0) {
err=SPI_ERROR_TIMEOUT; err=SPI_ERROR_TIMEOUT;
break; break;
} }
} }
_receiveBuffer[index] = (spi->rdr >> AVR32_SPI_RDR_RD_OFFSET) & 0x00ff; _receiveBuffer[index] = (spi->rdr >> AVR32_SPI_RDR_RD_OFFSET) & 0x00ff;
if (_receiveBuffer[index] == START_CMD){
TOGGLE_SIG0();
//SIGN1_UP();
}
if (err == SPI_OK) { if (err == SPI_OK) {
++index; ++index;
++receivedChars; ++receivedChars;
@ -1629,10 +1582,6 @@ inline int spi_slaveReceiveInt(volatile avr32_spi_t *spi, bool startRecvd)
return err; return err;
} }
uint32_t data = 0;
uint32_t status_register = 0;
#if defined (__GNUC__) #if defined (__GNUC__)
__attribute__((__interrupt__)) __attribute__((__interrupt__))
#elif defined (__ICCAVR32__) #elif defined (__ICCAVR32__)
@ -1640,40 +1589,28 @@ __interrupt
#endif #endif
static void spi_int_handler(void) static void spi_int_handler(void)
{ {
//SIGN2_DN(); volatile avr32_spi_t *spi = ARD_SPI;
//DEB_PIN_DN();
//eic_clear_interrupt_line(&AVR32_EIC, AVR32_SPI0_IRQ); //eic_clear_interrupt_line(&AVR32_EIC, AVR32_SPI0_IRQ);
AVAIL_FOR_SPI(); AVAIL_FOR_SPI();
DISABLE_SPI_INT(); DISABLE_SPI_INT();
//TODO verify why after the reply write the RDRF is set
unsigned short dummy = 0; unsigned short dummy = 0;
if ((end_write)&&((ARD_SPI->sr & AVR32_SPI_SR_RDRF_MASK) != 0)) {
end_write=false;
//SIGN1_UP();
spi_read(ARD_SPI, &dummy);
}
if (((ARD_SPI->sr & AVR32_SPI_SR_RDRF_MASK) != 0)||(dummy==START_CMD)) if (((spi->sr & AVR32_SPI_SR_RDRF_MASK) != 0)||(dummy==START_CMD))
{ {
int err = spi_slaveReceiveInt(ARD_SPI, dummy==START_CMD); int err = spi_slaveReceiveInt(ARD_SPI, dummy==START_CMD);
if (err != SPI_OK) if (err == SPI_OK)
{ {
#ifdef _SPI_STATS_
//TODO verify why at the end of cmd cycle RDF bit is high without any data recv.
if (statSpi.lastError != SPI_ERROR_TIMEOUT)
INFO_SPI("[E(0x%x):%d spiStatus:%d]\n", statSpi.lastError, err, statSpi.status);
#endif
}else{
BUSY_FOR_SPI(); BUSY_FOR_SPI();
startReply=true; startReply=true;
//maintain disable interrupt to send the reply command //maintain disable interrupt to send the reply command
//SIGN2_UP(); //DEB_PIN_UP();
return; return;
} }
} }
ENABLE_SPI_INT(); ENABLE_SPI_INT();
//SIGN2_UP(); //DEB_PIN_UP();
} }
inline spi_status_t spi_read8(volatile avr32_spi_t *spi, unsigned char *data) inline spi_status_t spi_read8(volatile avr32_spi_t *spi, unsigned char *data)

View File

@ -37,9 +37,9 @@ typedef enum {
CMD_IMM_SET_FLAG = 0x04, CMD_IMM_SET_FLAG = 0x04,
}cmd_flags; }cmd_flags;
#define TIMEOUT_SPI 200 #define TIMEOUT_SPI 200
//#define TIMEOUT_SENT_REPLY 1000 #define SPI_ALIGN_ERROR 0xF0
#define DUMMY_DATA 0xFF #define DUMMY_DATA 0xFF
typedef int (*cmd_spi_cb_t)(int numParam, char* buf, void* ctx); typedef int (*cmd_spi_cb_t)(int numParam, char* buf, void* ctx);
typedef cmd_spi_state_t (*cmd_spi_rcb_t)(char* recv, char* reply, void* ctx, uint16_t* _count); typedef cmd_spi_state_t (*cmd_spi_rcb_t)(char* recv, char* reply, void* ctx, uint16_t* _count);

View File

@ -197,17 +197,29 @@
GET_PARAM_##TYPE(PARAM, DATA) \ GET_PARAM_##TYPE(PARAM, DATA) \
NEXT_PARAM(PARAM) NEXT_PARAM(PARAM)
#ifdef _SPI_STATS_
#define STATSPI_TIMEOUT_ERROR() \ #define STATSPI_TIMEOUT_ERROR() \
statSpi.timeoutIntErr++; \ statSpi.timeoutIntErr++; \
statSpi.rxErr++; \ statSpi.rxErr++; \
statSpi.lastError = err; \ statSpi.lastError = err; \
statSpi.status = spi_getStatus(ARD_SPI); statSpi.status = spi_getStatus(ARD_SPI);
#define STATSPI_DISALIGN_ERROR() \
statSpi.frameDisalign++; \
statSpi.rxErr++; \
statSpi.lastError = SPI_ALIGN_ERROR; \
statSpi.status = spi_getStatus(ARD_SPI);
#define STATSPI_TX_TIMEOUT_ERROR() \ #define STATSPI_TX_TIMEOUT_ERROR() \
statSpi.timeoutErr++; \ statSpi.timeoutErr++; \
statSpi.txErr++; \ statSpi.txErr++; \
statSpi.lastError = SPI_ERROR_TIMEOUT; \ statSpi.lastError = SPI_ERROR_TIMEOUT; \
statSpi.status = spi_getStatus(ARD_SPI); statSpi.status = spi_getStatus(ARD_SPI);
#else
#define STATSPI_TIMEOUT_ERROR()
#define STATSPI_TX_TIMEOUT_ERROR()
#define STATSPI_DISALIGN_ERROR()
#endif
#define DUMP_TCP_STATE(TTCP) \ #define DUMP_TCP_STATE(TTCP) \
INFO_TCP("ttcp:%p tpcb:%p state:%d lpcb:%p state:%d\n", \ INFO_TCP("ttcp:%p tpcb:%p state:%d lpcb:%p state:%d\n", \

View File

@ -89,8 +89,14 @@ bool scanNetCompleted = false;
static bool initSpiComplete = false; static bool initSpiComplete = false;
// variable used as enable flag for debug prints // variable used as enable flag for debug prints
#ifdef _DEBUG_
uint16_t enableDebug = DEFAULT_INFO_FLAG | INFO_WARN_FLAG;// | INFO_SPI_FLAG;
uint16_t verboseDebug = 0;
#else
uint16_t enableDebug = DEFAULT_INFO_FLAG; uint16_t enableDebug = DEFAULT_INFO_FLAG;
uint16_t verboseDebug = 0; uint16_t verboseDebug = 0;
#endif
/** /**
* *
@ -294,7 +300,7 @@ void initShell()
console_add_cmd("wpass", cmd_setpass, NULL); console_add_cmd("wpass", cmd_setpass, NULL);
console_add_cmd("dpass", cmd_delpass, NULL); console_add_cmd("dpass", cmd_delpass, NULL);
#endif #endif
#ifdef STAT_SPI #ifdef _SPI_STATS_
console_add_cmd("spiStat", cmd_statSpi, NULL); console_add_cmd("spiStat", cmd_statSpi, NULL);
console_add_cmd("resetSpiStat", cmd_resetStatSpi, NULL); console_add_cmd("resetSpiStat", cmd_resetStatSpi, NULL);
#endif #endif