SPI Rx chunk size in DMA mode

powerbroker
Posts: 21
Joined: Sun May 19, 2024 12:58 pm

Re: SPI Rx chunk size in DMA mode

Postby powerbroker » Sat Jun 15, 2024 3:58 pm

eriksl wrote:
Tue Jun 11, 2024 9:50 am
Are you replying to what ESP_Sprite says? I think he was quite clear.

Anyway, I don't think it makes sense to start up DMA for just two (or four) bytes. The overhead will be huge and most of the handling will be done by the SPI module anyway. I remember having seen a table in the documentation with break-even points for amounts of data between handling the data directly from/to the module or using DMA and I also remember the break-even point wasn't very small, somehing around 128 bytes.
there are two things:
  1. DMA releases CPU core so thread can go to sleep and CPU proceed with another tasks. i use polling now at research-development phase, and later it will be redesigned: configure-IO-and-forget until data arrived.
  2. I need one reusable piece of code responsible for SPI IO, where all SPI related bugs reside and SPI I/O can fail or be broken. so even if single byte, tens of them or thousands - one code, one concept(with some overhead on short chunks - well, okay, reasonable price for easy code maintenance).
    and surprisingly: setting 'SPI_DMA_DISABLE' on invoking spi_bus_initialize(...) breaks everything: with DMA enabled i get from driver almost the same as see on oscilloscope screen; but with DMA disabled it naturally does sh@t, failing to acquire correctly even a single byte from the bus!(it probably requires some fine tuning... but just huck it - why doesn't it simply behave same way???)
eriksl wrote:
Tue Jun 11, 2024 9:50 am
Also ESP_sprite already said that malloc (and variants) already return aligned memory blocks. This is by concept a requirement of malloc. It's will always return an address aligned to the largest alignment requirement of the processor.

If you want a static or auto (stack) to be aligned, you should indeed use the alignment attributes OR use the dirty trick to declare a "large" type (like uint32_t) and cast it to a char or small char array [sizeof(uint32_t)].
yeah, malloc does the trick.
it looks like stack variables when their allocation left as is, are often aligned by default too... i had to include two local variables into one structure to illustrate nearby data damage by... seems to me, SPI driver in case of misaligned buffer.
BTW, since it's not DMA hardware(writing to it's hardware FIFO, as i understand) - it's probably a driver bug.

MicroController
Posts: 1383
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: SPI Rx chunk size in DMA mode

Postby MicroController » Sun Jun 16, 2024 6:08 pm

powerbroker wrote:
Sat Jun 15, 2024 3:24 pm
so where is the 9-th byte, which is hardware-processed too?
i think, it's getting lost somewhere inside static inline void spi_ll_read_buffer(...) of spi_ll.h near it's for(...) loop, isn't it?
Nope. The code of spi_ll_read_buffer() you quoted does handle all bitlens correctly. Take bitlen = 40 (5 bytes) for example, and mentally execute the code: It will do two iterations (with x=0 and x=32, respectively), copying 4 bytes in the first and 1 byte in the second iteration.
Saying that "this logic definitely cannot handle properly cases like 9-bytes(5-, 13-, etc.)" is incorrect.

powerbroker
Posts: 21
Joined: Sun May 19, 2024 12:58 pm

Re: SPI Rx chunk size in DMA mode

Postby powerbroker » Sun Jun 16, 2024 9:26 pm

MicroController wrote:
Sun Jun 16, 2024 6:08 pm
Nope. The code of spi_ll_read_buffer() you quoted does handle all bitlens correctly. Take bitlen = 40 (5 bytes) for example, and mentally execute the code: It will do two iterations (with x=0 and x=32, respectively), copying 4 bytes in the first and 1 byte in the second iteration.
Saying that "this logic definitely cannot handle properly cases like 9-bytes(5-, 13-, etc.)" is incorrect.
yes, you're right - it works correctly

and the question remains: where is the ninth byte?

there is void spi_hal_fetch_result(const spi_hal_context_t *hal) in spi_hal_iram.c, which calls that spi_ll_read_buffer(...):

Code: Select all

void spi_hal_fetch_result(const spi_hal_context_t *hal)
{
    const spi_hal_trans_config_t *trans = &hal->trans_config;

    if (trans->rcv_buffer && !hal->dma_enabled) {
        //Need to copy from SPI regs to result buffer.
        spi_ll_read_buffer(hal->hw, trans->rcv_buffer, trans->rx_bitlen);
    }
}
and it passes 'trans->rx_bitlen', which is 8 in my case. the thing is if SPI response of 'rx_bitlen' but not 'total_bitlen' is required, it is definitely required as 'rx_bitlen' from end, not from beginning - as sample behaves.

BTW, it checks if DMA is enabled in HAL here. so, maybe it is not the case - 'where is the ninth byte?' is still actual.

Who is online

Users browsing this forum: No registered users and 27 guests