- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi
I have an accelerometer generating interrupts on a processor pin on a regular base. I use an SPI interface to communicate between a PSoC3 and the accelero. The routine to read the data from the accelero, using the function adxl362_ReadXYZ(), works fine under main(). But when the same function is placed in the interrupt vector, it just generates zero a output. When verifying the behaviour of the accelerometer output data with an ascilloscoop (on Miso, Mosi, SCLK and CS lines) , no differences in the signals can ben detected. Why is the configured SPI component behaving this way? Any ideas? (by the way there are no other SPI devices are on the SPI bus)
My code looks like:
CY_ISR(adxl_int)
{
static uint8 _mark = 0;
ADXL_Sync_ClearInterrupt();
ADC_DelSig_1_StartConvert();
adxl362_ReadXYZ(); // comment this line when reading the data from main()
_adxl_data_ready = 1;
}
void adxl362_ReadXYZ(void)
{
char msg[64];
uint8 ch;
int16 value;
L2C hl;
ADXL_ena_Write(0); // Assert CS
mySPI_ClearRxBuffer();
/* Send "Byte Write to Memory " instruction */
mySPI_WriteTxData(ADXL362_CMD_READ);
mySPI_WaitTxDone();
mySPI_WriteTxData(ADXL362_REG_XDATA_L);
mySPI_WaitTxDone();
// Erase all data in the Rx buffer
mySPI_ClearRxBuffer();
mySPI_WriteTxData(0); // Dummy write
mySPI_WaitTxDone();
mySPI_WriteTxData(0); // Dummy write
mySPI_WaitTxDone();
hl.c[1] = mySPI_ReadRxData();
hl.c[0] = mySPI_ReadRxData();
// axis = hl.i[0] & 0xC000;
value = ((int16)(hl.i[0] << 4)) >> 4;
// sprintf(msg,"\n[%d] x:%d ", _fifo_count, value);
// sendMsg(DEBUG, msg);
_fifo[0][_fifo_count] = value;
mySPI_WriteTxData(0); // Dummy write
mySPI_WaitTxDone();
mySPI_WriteTxData(0); // Dummy write
mySPI_WaitTxDone();
hl.c[1] = mySPI_ReadRxData();
hl.c[0] = mySPI_ReadRxData();
// axis = hl.i[0] & 0xC000;
value = ((int16)(hl.i[0] << 4)) >> 4;
// sprintf(msg,"y:%d ", value);
// sendMsg(DEBUG, msg);
_fifo[1][_fifo_count] = value;
mySPI_WriteTxData(0); // Dummy write
mySPI_WaitTxDone();
mySPI_WriteTxData(0); // Dummy write
mySPI_WaitTxDone();
hl.c[1] = mySPI_ReadRxData();
hl.c[0] = mySPI_ReadRxData();
// axis = hl.i[0] & 0xC000;
value = ((int16)(hl.i[0] << 4)) >> 4;
// sprintf(msg,"z:%d ", value);
// sendMsg(DEBUG, msg);
_fifo[2][_fifo_count] = value;
ADXL_ena_Write(1);
_fifo_count++;
if (_fifo_count >= MAX_FIFO_SIZE + FIFO_HEADROOM)
_fifo_count = MAX_FIFO_SIZE + FIFO_HEADROOM -1;
}
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for your efforts.
@Bob: Totally agree on your remarks, but in this application it's the only way, using a PSoC' to synchronize samples from the accelero and an analog input in combination with the data handling routines in non real time part..
The reason for the malfunctioning of the read operation under inteerupt is caused by the loop mySPI_WaitTxDone(); Under interrupt, the SPI status is always marked as "mySPI_STS_SPI_DONE", causing an early termination of the loop and hence the reading of non valid data.
This routine has following code:
void mySPI_WaitTxDone(void)
{
while(!(mySPI_ReadTxStatus() & mySPI_STS_SPI_DONE));
}
Putting some trace in software removed the issue:
void mySPI_WaitTxDone(void)
{
Pin1_Write(1);
while(!(mySPI_ReadTxStatus() & mySPI_STS_SPI_DONE));
Pin1_Write(0);
}
Removing the trace again, thus using the original code again, did not re-insert the problem... Possibly this is a compiler issue??
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I don't know how the structure L2C is defined. I suspect the issue in SPI data being stored in hl.c but the "value" uses hl.i.
-Rajiv
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Interrupt handlers should be kept small and fast. The pitfall might be to call SPI functions (write) which could use the interrupt which will not fire because already handled. Try removing the SPI functiond from the handler, the waits() will take too much time.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for your efforts.
@Bob: Totally agree on your remarks, but in this application it's the only way, using a PSoC' to synchronize samples from the accelero and an analog input in combination with the data handling routines in non real time part..
The reason for the malfunctioning of the read operation under inteerupt is caused by the loop mySPI_WaitTxDone(); Under interrupt, the SPI status is always marked as "mySPI_STS_SPI_DONE", causing an early termination of the loop and hence the reading of non valid data.
This routine has following code:
void mySPI_WaitTxDone(void)
{
while(!(mySPI_ReadTxStatus() & mySPI_STS_SPI_DONE));
}
Putting some trace in software removed the issue:
void mySPI_WaitTxDone(void)
{
Pin1_Write(1);
while(!(mySPI_ReadTxStatus() & mySPI_STS_SPI_DONE));
Pin1_Write(0);
}
Removing the trace again, thus using the original code again, did not re-insert the problem... Possibly this is a compiler issue??
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Try to run this on a PSoC5!!! There are things to observe with PSoC3 and interrupts. Got any compiler warnings?
Get a CY8CKIT-059 and try.<<<<<<<<<<
Bob