Clarification on SCB SPI and DMA Settings

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

cross mob
peterq
Level 1
Level 1
10 sign-ins 5 questions asked First reply posted

Hi PSoC Community, I have several questions regarding a SCB in SPI slave (receiving data from a 32 bit ADC) and DMA transfer from the SPI slave RX fifo buffer to a double buffer setup on the PSoC. The data rate output from the ADC is 16.384 Mbps I am unsure about a few things:

 

1. Firstly, I am setting the 'Data Rate (kbps)' in the SCB in slave mode to be 16384. Shouldn't this be sufficient to determine the clock that operates the SCB? I dont understand why we need to specify another that drives the block. Also what value should I set the block clock to be? Currently this is set to be 100 MHz (the peripheral clock) which is derived from the FLL.

 

2. Can someone please confirm that setting the SCB SPI RX data width to be 16 is OK? As I mentioned above, the ADC generates 32 bit data, so the CS signal remains low for 32 bits of the transfer. Does the SCB in slave mode store the single 32 bits as two 16 bit values in the SCB RX fifo buffer if the CS signal remains low for the 32 bits of the transfer? (as the maximum RX data width for the SCB SPI block is 16). Unfortunately I am unable to control the SPI master CS line to drive high and then low again in the middle of the 32 bit transfer.

 

3. Finally when the SCB RX Fifo buffer is full, I have set up the SCB to trigger a DMA transfer. The issue I have here is that I am unsure what to set the 'Data transfer width' in the DMA descriptor to be. Intuitively I thought it should be Halfword (2 bytes) to Halfword, where the source is the SCB RX Fifo buffer which is set to have a data width of 16 bits, and the destination also halfword, as I have allocated uint16_t memory block (destination). However, it seems that the source (the SCB RX Fifo) must be set to be 'Word' for the program to compile and run. Can someone please explain why this is? Also there are Word to Word (masked) settings in the selection, can someone also explain what these are for? The documentation is really poor! P.S. I then combine two 16 bit values into a single 32 bit value after the DMA transfer to memory. Any help is appreciated.

0 Likes
3 Replies
Ekta
Moderator
Moderator
Moderator
750 replies posted First like given 250 solutions authored

Hi @peterq 

You can refer to the following application note which provides guidance regarding configuring DMA in PSoC 6:
PSoC™ 6 MCU usage of Direct Memory Access (DMA).

1. To get an accurate data rate (same as what you set in the data rate field) for the SCB (SPI in this case) it is important the clock that goes to this SCB clock is a multiple of the data rate provided.

If you take a look at the PSoC 6 clocking tree, you will notice that all the peripherals are clocked using CLK_PERI.
The CLK_PERI in turn has its parent clock as CLK_HF0. CLK_PERI must pass through one of the 8 bit peripheral clock dividers before reaching the SCB.

 

Ekta_0-1707328404314.png

The value of the 8 bit peripheral clock divider, that goes to the SCB must be set such that the desired data rate could be achieved. When this does not happen device configurator will prompt to set the divider correctly on saving the configuration as can be seen in the image below:

Ekta_1-1707328779029.png

2. Could you please help me understand how is the ADC generating 32 bit data?
PSoC 6 has a 12 bit ADC. Since the ADC output will be a maximum of 12 bits, you can easily set the SPI Data Width to 12 or more, say 16 to ensure you do not lose any bits.

3. All peripherals support 32-bit data width, if the source or destination of a transfer is a peripheral, the source or destination data width must be set to 32 bits.
Memory supports 8-bit, 16-bit, and 32-bit access. You can use larger data widths to increase throughputs, or use
smaller data widths to quantize the data size. For example, 8-bit data is being transferred from a
communication block to the memory, the source data width must be 32 bits (because the source is a
peripheral), but the destination can be 8 bits (because the destination is a memory location), which
automatically truncates the higher 24 bits. This will enable a smaller memory footprint.

In your case since the transfer is between ADC and SPI, i.e., peripheral to peripheral, you must set the data transfer width parameter as Word to Word.

Best Regards
Ekta

 

0 Likes
peterq
Level 1
Level 1
10 sign-ins 5 questions asked First reply posted

Hi Ekta,

Thanks for your response, but I still have several follow up questions.

1. Thanks for the clarification that the clock must be a multiple of the data rate provided. I have seen that the configurator prompt to update the peripheral clock divider, however, in my instance where the data rate is 16384 kbps, it is not possible for the source IMO (8 MHz) -> FLL -> CLK_PERI to exactly divide into this frequency. I guess we would have to use an EXTCLK source of our own potentially?

Secondly, with integer data rate multiple would you suggest CLK_PERI to be? e.g. 5x the data rate? i.e. 81.92 MHz?

 

 

2. The ADC is an external ADC IC, model AD7768 from analog devices, it is a 24 bit ADC but has an associated 8 bit header for each data packet, resulting in 32 bits. This is the SPI master. The PSoC is the SPI slave receiving 4x 32 bits (from 4 channels, time multiplexed on one MOSI output), and the CS line stays low for the entirety of 128 bits. Therefore my question is, does the PSoC SCB which has a data with of 16, store these 128 bits as 8 individual 16 bit numbers in the RX FIFO buffer (8*16 = 128)?

 

3.

>> All peripherals support 32-bit data width, if the source or destination of a transfer is a peripheral, the source or destination data width must be set to 32 bits.

Ok fine I get this

>> Memory supports 8-bit, 16-bit, and 32-bit access. You can use larger data widths to increase throughputs, or use smaller data widths to quantize the data size. 

Please clarify this. If the RX FIFO of the SCB has a data width of 16 bits, and you specify the source data width in DMA to be 32 bits (because the source is a peripheral), then are you transferring one value in the RX FIFO buffer to the destination or two? My guess is that the DMA will cast one single 16 bit value in RX FIFO to a 32 bit number and then if the destination buffer (which in my case is memory on the PSoC) is a uint16_t type buffer, it will truncate the 16 MSB's of zeros that was casted by the DMA?

>>In your case since the transfer is between ADC and SPI, i.e., peripheral to peripheral, you must set the data transfer width parameter as Word to Word.

I think you are confused, the DMA does not move data from ADC to SPI RX FIFO, the DMA moves data from SPI RX FIFO to PSoC internal memory allocated buffer. Also does that mean my DMA setting should therefore be Word to Half Word (2 bytes, 16 bits)?

 

Many thanks Ekta!!!

 

0 Likes
Ekta
Moderator
Moderator
Moderator
750 replies posted First like given 250 solutions authored

Hi @peterq 

You are correct, I got confused. From your description of the problem, I thought that the DMA is being used for an internal transfer from ADC to SPI (within PSoC). Now I understand, that the ADC interacts with PSoC using SPI and DMA has to be used to transfer the data from the Rx FIFO to memory location.

Here are the answers to your follow-up questions: 

1. `I see that your clock path is IMO (8 MHz) -> FLL -> CLK_PERI. What is the configuration of FLL? I tried the following configuration and it worked for me for a data rate of 16384.


IMO (8 MHz) - > FLL (72MHz) ->CLK_HF0(72MHz)-> CLK_PERI (72MHz)
Say your CLK_PERI which is now 72MHz passes through clock "8-bit divider 2" which is then selected as the source of the SCB. Modustoolbox prompts me to select the value of "8-bit divider 2" as 5 so that the data rate desired by the SCB block is nearly achieved. I can save this configuration without any warnings or errors.

Ekta_0-1707815888207.png

2. Yes, if you select the width of the SPI as 16 bit and send a total of 8 16-bit data then PSoC will save the incoming data as 8 individual 16-bit data elements.

FYI : The SPI FIFO can be configured in two modes 8 bit * 128 or 16 bit *164. What I observed while configuring the SPI block is that based on you SPI data width the FIFO mode is automatically adjusted. Therefore if select the width from 4 to 8 the FIFO mode is 8* 128. If your SPI data width is 9 or more then the FIFO width is 16 *64.

This is also mentioned in SPI section of the PSoC 6 Architecture TRM.

3. You can set the data transfer width as Word (from SCB) to Halfword (in memory) in this case.

The following code example will provide you some idea on DMA and SCB configuration: mtb-example-psoc6-spi-master-dma.
This example demonstrates the use of the SPI Serial Communication Block (SCB) resource for PSoC™ 6 MCU in master mode using DMA. The SPI master is configured to send command packets to control a user LED on the slave. Both the master and slave can be on the same device or on different devices.

You might need to edit a few configurations like data width,  clock etc. based on our discussion in the thread.

Hope this helps

Best Regards
Ekta

 

0 Likes