- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear community,
For a couple of days I'm trying to extract data from a sensor. I tried using the examples and application notes but could not get it working. I tried it with DMA and interrupts but quickly decided it was too difficult.
The waveforms look good and the Logic analyser displays the correct information. The image below shows a single read-transaction. I only need the second value 0xA800.
main loop
for(;;)
{
UART_PutString("Start Loop:\r\n");
clearErrors();
for( int i =0; i < 10; i++){
printf("%x\r\n", readSPIWord(0x24));
}
CyDelay(1000);
}
functions
void clearErrors(){
//Write bit + 1E address + 07 data
SPI_Write(0x1E07 & SPI_WRITE_BITMASK);
//Write bit + 1F address + 0x46 keycode
SPI_Write(0x1F46 & SPI_WRITE_BITMASK);
}
uint16 readSPIWord(uint8 address)
{
uint16 readword;
SPI_Write(address << 8);
while(SPI_IsBusBusy());
SPI_ClearRxFifo();
SPI_Write(0x0000);
while(SPI_IsBusBusy());
readword = SPI_Read();
return (uint16)readword;
}
(Wrong) Result
Could someone point me in the correct direction?
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Moto,
I have succeeded in getting (the correct) data with the following code. I needed to wait until the RX FIFO was cleared entirely. Then write the two words and wait until the FIFO contains them. It feels like a hack to me.
int main(void)
{
uint8 addresses[9] = {0x1E, 0x20, 0x22, 0x24, 0x26, 0x28, 0x2A, 0x34, 0x36};
__enable_irq();
UART_Start();
/* Also calls init, sets slave to 0 and calls enables */
SPI_Start();
UART_PutString("Hello");
for(;;)
{
UART_PutString("\r\nStart Loop:\r\n");
clearErrors();
for( int i =0; i < 9; i++){
readSPIWord(addresses);
}
CyDelay(1000);
}
}
void clearErrors(){
//Write bit + 1E address + 07 data
SPI_Write(0x1E07 | (SPI_WRITE_BITMASK << 8));
//Write bit + 1F address + 0x46 keycode
SPI_Write(0x1F46 | (SPI_WRITE_BITMASK << 8));
}
uint16 readSPIWord(uint8 address)
{
uint16 readword1 = 0xfffe;
uint16 readword2 = 0xfffe;
uint32 fifobuffer = 0;
SPI_ClearRxFifo();
while(SPI_GetNumInRxFifo() != 0);
SPI_Write(address << 8);
SPI_Write(0x0000);
//Don't like this while here
while(SPI_GetNumInRxFifo() != 2);
fifobuffer = SPI_GetNumInRxFifo();
if(fifobuffer){
readword1 = SPI_Read();
readword2 = SPI_Read();
}
printf("ADD: 0x%x BUFFER: %u - VALUES:0x%x 0x%x\r\n",address, fifobuffer, readword1, readword2);
CyDelay(3); //Needed for printf
return (uint16)readword1;
}
Logic Output:
Without the printf/UART the logic analyzer output is as follows:
This means the while-delay is not noticeable.
UART Output:
Problem:
The while loop on line 42 will wait forever when something goes wrong with the SPI bus.
Thanks for your help, I can go on with this. Any feedback is appreciated.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
A couple of things, I'd like to check
(1) Is the MISO signal connected to the right pin?
(2) What is the pin configuration of MISO pin?
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Moto,
My pins are correct I think. When I put random delays at places it returns 0x0000.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Getting 0x0000 and 0xFFFF sounds good news.
This means MISO is receiving both values (0 and 1).
Next things I would try are
(1) Put some delay between address write and data read.
(For this please refer to the datasheet of the sensor)
(2) Change ss0_m to GPIO (output) and keep it low during address write and data read.
(Same as (1), please check SPI protocol of the sensor)
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Moto,
I have succeeded in getting (the correct) data with the following code. I needed to wait until the RX FIFO was cleared entirely. Then write the two words and wait until the FIFO contains them. It feels like a hack to me.
int main(void)
{
uint8 addresses[9] = {0x1E, 0x20, 0x22, 0x24, 0x26, 0x28, 0x2A, 0x34, 0x36};
__enable_irq();
UART_Start();
/* Also calls init, sets slave to 0 and calls enables */
SPI_Start();
UART_PutString("Hello");
for(;;)
{
UART_PutString("\r\nStart Loop:\r\n");
clearErrors();
for( int i =0; i < 9; i++){
readSPIWord(addresses);
}
CyDelay(1000);
}
}
void clearErrors(){
//Write bit + 1E address + 07 data
SPI_Write(0x1E07 | (SPI_WRITE_BITMASK << 8));
//Write bit + 1F address + 0x46 keycode
SPI_Write(0x1F46 | (SPI_WRITE_BITMASK << 8));
}
uint16 readSPIWord(uint8 address)
{
uint16 readword1 = 0xfffe;
uint16 readword2 = 0xfffe;
uint32 fifobuffer = 0;
SPI_ClearRxFifo();
while(SPI_GetNumInRxFifo() != 0);
SPI_Write(address << 8);
SPI_Write(0x0000);
//Don't like this while here
while(SPI_GetNumInRxFifo() != 2);
fifobuffer = SPI_GetNumInRxFifo();
if(fifobuffer){
readword1 = SPI_Read();
readword2 = SPI_Read();
}
printf("ADD: 0x%x BUFFER: %u - VALUES:0x%x 0x%x\r\n",address, fifobuffer, readword1, readword2);
CyDelay(3); //Needed for printf
return (uint16)readword1;
}
Logic Output:
Without the printf/UART the logic analyzer output is as follows:
This means the while-delay is not noticeable.
UART Output:
Problem:
The while loop on line 42 will wait forever when something goes wrong with the SPI bus.
Thanks for your help, I can go on with this. Any feedback is appreciated.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Thank you for the good news!
BTW, for a mission-critical application usually, we need to apply a timeout to avoid deadlock.
something like
============
uint32_t timeout_limit = 20000 ; // you decide how long to wait till timeout
...
uint32_t timeout_count ;
timeout_count = 0 ;
while(SPI_GetNumInRxFifo() != 0) {
CyDelayUs(10) ; // please use appropriate delay function here
timeout_count++ ;
if (timeout_count >= timeout_limit) {
// timeout!
break ; // or return with error value
}
}
...
=============
moto