mirror of https://github.com/noisymime/Arduino.git
Fix issue on SPI RDRF
This commit is contained in:
parent
ca9415ba25
commit
bdc4d0ab22
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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", \
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue