How do I call the CyU3PSpiTransferWords/CyU3PSpiTransmitWords/CyU3PSpiReceiveWords correctly?

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
user_4790841
Level 2
Level 2
10 replies posted 10 sign-ins 5 replies posted

Hello,

I'm using the Cypress example code projects to try to get data from an accelerometer (ADcmXL3021). I'm using the UsbSpiDmaMode project, where I've merged GPIO functionality into it.

When I'm trying to communicate with the accerlerometer, I'm using SPI communication. The UsbSpiDmaMode already has functions set up for this; CyFxSpiTransfer (programmer application), which uses the two functions CyU3PSpiTransmitWords and CyU3PSpiReceiveWords.

Currently, I've tried making my own functions to write and read data over the SPI interface. They look as follows:

pastedImage_2.png

with startSampling() and readData().

As you can see I pass in 0x3E, 0x08, 0x00 as my input, which you can also read in the datasheet for the accelerometer are the registers that start recording data. The datasheet can be found here:

https://www.analog.com/media/en/technical-documentation/data-sheets/ADcmXL3021.pdf#page=42&zoom=100,...

(where 0x3E is the address for GLOB_CMD and 0x08 (0x0800) is the address to start recording).

My output gives the same values, which implies that I'm using the functions incorrectly. Below, my data value (200 entries) are seen from the UART debugger:

pastedImage_4.png

It would obviously be best if I could use the given function, CyFxSpiTransfer, but I get stuck in the CyFxSpiWaitForStatus() function when I try using it with the call: CyFxSpiTransfer(0x003E, 0x0800, 4, CyFalse)

(I'm unsure what the 3rd parameter means (*buffer).

I've seen you're employee, juchong, has made a GitHub FX3 API which includes this accelerometer, but I can't seem to understand it and how it works (I'm new to this world). It's found here:

GitHub - analogdevicesinc/iSensor-FX3-API: A .NET API and firmware for the Cypress FX3 USB interface...

Moreover, can I use the CyU3PSpiTransferWords function to combine the two (transmit and recieve) into one? If so, that would be much better of course.

If you could tell me where I go wrong, in the calls of the given functions, it would help me out very much! I hope it's a simple fix. All I want to do is invoke the RTS mode (later the MFFT mode) of the ADcmXL3021 accelerometer, and get a single reading of the mode for each iteration call from the main function of my program (located in the AppThread_entry function). The AppThread_entry function looks like below:

pastedImage_13.png

Hope I've provided enough information, other please tell me if you need more information. I've also attached the C-file to this message.

Sincerely,

Søren

0 Likes
1 Solution

Hello Søren,

I have modified the file shared by you, please try using this and let me know if it works.

The following modifications are done:

- The startsampling() and readdata() are combined into readdata() API. Please refer to readdata API for more details

- The vendor command 0xC3 (CY_FX_RQT_SPI_FLASH_READ) is used to get the read data. You can read the data on the control center itself by passing the 0xC3 vendor command (Direction: IN)

Please replace this file in the your firmware and let me know if it helps

Regards,

Rashi

Regards,
Rashi

View solution in original post

0 Likes
9 Replies
Rashi_Vatsa
Moderator
Moderator
Moderator
5 likes given 500 solutions authored 1000 replies posted

Hello Søren,

From the firmware, I checked the SPI master configuration done in CyFxSpiInit()

The SPI slave supports 16 bit word length but SPI interface of FX3 is configured for 8 bit word length.

16_bit.PNG

*/ From CyFxSpiInit */

   spiConfig.wordLen    = 8; //16 is expected by SPI slave

Please configure the SPI master (Fx3) for 16 bit word length and probe the SPI lines  when the startSampling() is called to check if the register value and register address is sent properly or not and share the traces for us to check.

Please let us know if it is possible to read the (GLOB_CMD) register and check the value written to the register. With this we can confirm if the value written to register is proper or not.

For testing purpose you can call startSampling() and readData() only once i.e. outside/before the for loop (for{}) of AppThread_Entry function.

then in for loop the received data can be printed.

It would obviously be best if I could use the given function, CyFxSpiTransfer, but I get stuck in the CyFxSpiWaitForStatus() function when I try using it with the call: CyFxSpiTransfer(0x003E, 0x0800, 4, CyFalse)

>> The UsbSpiDMaMode example is designed for communicating with SPI Flash, so the custom functions startSampling() and readData() can be used for your application.

Moreover, can I use the CyU3PSpiTransferWords function to combine the two (transmit and recieve) into one? If so, that would be much better of course.

>> As there is a 12 ms delay between the writing to the register (GLOB_CMD) and reading back the data (figure 4 of the datasheet), it is good to use CyU3PSpiTransmitWords(startSampling) and CyU3PSpiReceiveWords (readData) with 12 ms delay.

Regards,

Rashi

Regards,
Rashi
0 Likes

I've cleaned up a lot of the code based on what you've said (deleted all the unnecessary functions).

I've changed the word length to support 16 bit word lengths instead in the CyFxSpiInit function. This has caused some problems, where I get this error output, because the returned status is wrong:

pastedImage_0.png

How do I see what error code matches with 64? I assume it's one of the following errors from cyu3spi.h:

pastedImage_1.png

I have a feeling its the CY_U3P_ERROR_BAD_ARGUMENT error, but how can I fix this?

As you can see, I've also changed the "*data" input parameter to be uint16_t (from uint8_t).

Moreover I've changed the bits to 16 for the input array for the CyU3PSpiTransmitWords function.

pastedImage_2.png

Is there anything else that I need to change? I can't currently probe the signals, as my oscilloscope is at work (where I will be back the 4th of January).

I've attached the updated c-file.

0 Likes

Hello Søren,

When the wordlen is change to 16 you don't need to change the data buffer to uint16_t as CyFxSpiTransmitWords supports data buffer of uint8_t. So, the data needs to be padded to make the data 16 bits. The byte count should also be modified accordingly.

extern CyU3PReturnStatus_t

CyU3PSpiTransmitWords (

        uint8_t *data,                    /**< Source data pointer. This needs to be padded to nearest

                                                    byte if the word length is not byte aligned. */

        uint32_t byteCount              /**< This needs to be a multiple of the word length aligned to the next

                                                      byte. */

        );

I have modified the function you used (the data in the buffer is dummy - Please pad the data properly according to the datasheet of the slave). Please try this and let me know if the CyFxSpiTransmitWords returns success.

I have tested this at my end and CyFxSpiTransmitWords didn't return any failures

If the write to SPI slave doesn't work please let me know if the register can be read to check if the value written to the register is fine or else we can wait for oscilloscope

Regards,

Rashi

Regards,
Rashi
0 Likes

Updating the functions to yours made the CyFxSpiTransmitWords return success, so thats progress! Now I'm back to where I started, with getting invalid data, but perhaps its because I'm padding the data incorrectly.

Would you know how to pad the data correctly according to the datasheet? (If this is a question that is not relevant this forum, please let me know). I assumed 0x3E and 0x0800 needs to be sent to start recording a set of measurements. I will try again to try to figure out how to pad the data correctly.

Best regards,

Søren

0 Likes

Hi again,

I've tried looking at the Analog website (the company for the ADcmXL3021), and seen similar forums that ask the question of how to get data from the accelerometer. It seems their forums aren't very active, and thus have no responses.

They have provided an API which should use the FX3 to control SPI access, but I cannot seem where to look for what registers they write, in which order, and how I have to pad the data registers. It can be found here:

GitHub - analogdevicesinc/iSensor-FX3-API: A .NET API and firmware for the Cypress FX3 USB interface...

I've also read the datasheet through, but they do not provide many examples. If you can quickly spot how to run the most simple mode to record data (the RTS mode), it would be greatly appreciated, as I cannot seem to figure it out. The datasheet is linked below:

https://www.analog.com/media/en/technical-documentation/data-sheets/ADcmXL3021.pdf#page=21&zoom=100,...

I've struggled with this for hours without progress, so any help would go a long way to help me start up this device and get some data out of it.

Best regards,

Søren

0 Likes

Hello Søren,

I have modified the file shared by you, please try using this and let me know if it works.

The following modifications are done:

- The startsampling() and readdata() are combined into readdata() API. Please refer to readdata API for more details

- The vendor command 0xC3 (CY_FX_RQT_SPI_FLASH_READ) is used to get the read data. You can read the data on the control center itself by passing the 0xC3 vendor command (Direction: IN)

Please replace this file in the your firmware and let me know if it helps

Regards,

Rashi

Regards,
Rashi
0 Likes

Hi,

I still get an error. Am I supposed to specify the target, or am I using the Control Center wrong in any other way? I provided a screenshot of what I specify below:

pastedImage_1.png

It returns an error-code once it tries to execute the CyU3PDmaChannelWaitForCompletion function inside the readData API. I'm assuming this error is because the buffer is never "completed" after setting it up in the previous CyU3PDmaChannelSetupRecvBuffer function. Why could this be?

Best regards,

Søren

0 Likes
Rashi_Vatsa
Moderator
Moderator
Moderator
5 likes given 500 solutions authored 1000 replies posted

Hello Søren,

Can you please let me know the return value (error code) of CyU3PDmaChannelWaitForCompletion

Also, let me know if  CyU3PDmaChannelSetupRecvBuffer returns success (0) or not

 

Regards,
Rashi
0 Likes

Hi Rashi,

I figured out the reason why it wasn't working, and fixed the issue  (your code still had it on 8 bytes transfer, and I had to change it back to 16). It works now 🙂 Thank you very much for all the help!

Best regards,

Søren

0 Likes