- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I am a newbie, working on PSoC 4 to communicate a sensor via SPI.
After reading and trying a lot of documents and example, I still cannot make one SPI example work. Without LCD, how could I test an SPI example?
To read register of my sensor, I need to select and deselect; write one byte address to MOSI, get one dumb byte from MISO, and the write one byte 0x00 to MOSI, the get my data back.
I set a GPIO as chip select pin, and connect MOSI to 3[1], MISO to 3[0], SCK to 0[6]; and wrote the corresponding firmware, however cannot get nothing.
Could anyone help me and have a look?
Thank you very much!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I got it working!
Added a delay between write to MOSI and read MISO.
SPI_Master_SpiUartWriteTxData((uint32)fixedAddress);
CyDelayUs(75);
uint32 readBuffer = SPI_Master_SpiUartReadRxData();
However, I don't know the smallest delay time. In Arduino, I could read MISO as long as the SPIF changes; could I write a "while" sentence that could help me do it? How should I write it?
Thank you!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You normally do not need a delay-function when reading from spi.
Imagine how SPI works: For every byte you send you receive a byte at the same time.
Writing a byte means: putting the byte into the transmit buffer, then return to caller.
The sending of the byte(s) will take some time, so the receiving seems to be delayed.
I would suggest you to divide your SPI accesses into "transactions", a given number of bytes to transmit and receive. Make the buffer as large as the largest transaction will take. When you sent your data check (wait for) the last byte transmitted (GetTxStatus() & SPI_DONE) then you have received all data and may access them.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Bob,
I like your suggestion, and will try it in my future application, although I don't understand much about (GetTxStatus() & SPI_DONE); but, thank you!
However, in this application, I have to do one byte at a time to visit my sensor, and two bytes together separately to read one register.
I have no idea why a delay is needed, but it turns out that at least 6 us is needed in order to get the right data.
The PSoC programming is quite different from Arduino, and lots of bottom layers' programming job needed to be done.
I am looking for a way to realize the sentences below, which was inside Arduino system,
Serial.available();
Serial.flush();
I tried a some sentences in PSoC Creator, however failed all the time, could you please help me?
Thank you very much!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Bob,
I used
SPI_Master_SpiUartClearTxBuffer() as Serial.Flush(),
and
uint8 UART_ReadAvailableCheck(void)
{
uint8 character=0;
if(SPI_Master_CHECK_RX_SW_BUFFER) character = 1;
else character = 0u;
return character;
}
But it seems like the UART_ReadAvailableCheck() function doesn't work.
Could you please help me fix this UART_ReadAvailableCheck() function?
Thank you!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
"Flush" usually means "write out (complete) outstanding device I/O" while "Clear" has the meaning of "abandon (stop) any outstanding I/O", so both are in nature different. I suggested you to wait for completion which would be similar to a "flush".
You should open the SPI datasheet and check the available APIs. There is a SPI_Master_GetTxInterruptSource() which delivers a bit-mask showing which conditions might generate an interrupt (when enabled). One bit stands for a completed transfer: SPI_Master_INTR_MASTER_SPI_DONE when that bit is set, the last byte from FIFO has been transmitted. Then you can read from your receive buffer or FIFO (is selected automatically).
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you! Your tips about flush is totally right.
But it is about UART control, not SPI; to communicate with PC, instead of sensor.
How do you think the UART_ReadAvailableCheck() function should be?
I am trying to detect a button press while continuously transferring data to PC, however never tested one button press; which means it failed to check the UART_ReadAvailable.
Could you please help me fix the function UART_ReadAvailableCheck() so that any button press could stop my communication?
Thank you!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
There is no API named SPI_Master_CHECK_RX_SW_BUFFER().
You should use instead SPI_Master_SpiUartGetRxBufferSize() which returns the number of bytes in the buffer (not the size of the buffer)
So your routine should look like this
uint8 UART_ReadAvailableCheck(void)
{
return (SPI_Master_SpiUartGetRxBufferSize() != 0) ;
}
Since this is a one-liner you even do not need a function for it, you may even write in your program
uint8 MyBuffer[10];
uint8 Index = 0;
while(SPI_Master_SpiUartGetRxBufferSize()) MyBuffer[Index++] = SPI_Master_SpiUartReadRxData();
and now you have got your data in your buffer.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Bob,
You are right!
I fixed it with
return (0u != UART_SpiUartGetRxBufferSize()) ;
Thank you so much! I cannot do it without you.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Keep calm 😉
Bob