Skip to content

Conversation

stnolting
Copy link
Owner

  • ⚠️ DMA: remove FIRQ-triggered auto-mode; re-arrange control register bist
  • ⚠️ GPTMR: remove mode configuration bit; timer now always operate in "continuous" mode (interval timer)

@stnolting stnolting added HW Hardware-related cleanup Clean-up the codebase labels Mar 2, 2025
@stnolting stnolting self-assigned this Mar 2, 2025
@stnolting stnolting marked this pull request as ready for review March 2, 2025 09:01
@stnolting stnolting merged commit 449dd87 into main Mar 2, 2025
7 checks passed
@stnolting stnolting deleted the dev020325 branch March 2, 2025 14:32
@jpf91
Copy link
Contributor

jpf91 commented Mar 8, 2025

@stnolting Hmm any reason why the FIRQ trigger mode was removed? I was planning to use it :-)

@stnolting
Copy link
Owner Author

That was another completely over-engineered feature... 🙈

The DMA only has one channel, which also only has a single descriptor. Event-driven triggering therefore seems to make little sense.

In addition, it does not require much overhead to start the (pre-programmed) DMA from an interrupt-driven service routine.

I was planning to use it :-)

Can you give us a few details? Perhaps I was too hasty and there are actually real-word applications that would benefit greatly from this. 🤔

@jpf91
Copy link
Contributor

jpf91 commented Mar 9, 2025

The DMA only has one channel, which also only has a single descriptor. Event-driven triggering therefore seems to make little sense.

Indeed the 1 channel limitation is probably the biggest one. However, there still seem to be cases where one channel is already quite usedul.

In addition, it does not require much overhead to start the (pre-programmed) DMA from an interrupt-driven service routine

I guess that's true for most applications. We have some test software where we used FreeRTOS and SPI to read SD Cards and I think the interrupt load was an issue, but I don't have any real numbers to back that claim. A large part of that issue might also be that the SPI SD card protocol is just stupid: You have to poll the busy flag bit-by-bit if I remember correctly, so you can't really do large bulk transfers well

Can you give us a few details?

I was thinking of implementing a simple SD card hardware controller. (it's in specification phase and might take some time until it's actually implemented, so don't expect too much).

SD cards are usually transferring data in 512 byte sectors, but you can also do reads of consecutive sectors with a single command. As far as I can tell from the SD specifications, traditional controllers have a lot of memory and store a complete block in the controller. I'd like to provide a more lightweight implementation, where only a single 32 bit data register is required. Whenever 32 bit have been read, I'd make them available in a data register and issue an data ready interrupt. Then the controller is paused until the data register has been read. After the register was read, the controller continues transferring more data (as much as previously configured).

The idea for DMA would now be to configure it like this:

  • Transfer from fixed address: SD Data register
  • Transfer to destination in memory, increase address
  • Set count to 128 (or multiples of that)
  • Set up an DMA finished interrupt

This way the DMA would copy the whole SD card sector to memory without CPU interaction. Once the DMA finished interrupt triggers, the application can start processing the data and set up new SD card commands.

I'm not sure where I've seen this before, but I think it was with ADCs in some microcontrollers: I think there you could configure the DMA to run on conversion done and copy the value to some memory location. Then you can take N samples without CPU interaction and after N samples you could for example average the results.

A similar usage pattern would probably work for all bulk large data transfers, e.g. for SPI and UART as well (this would probably make the receive / send FIFOs somewhat obsolete). But I think on SPI and UART you usually don't have such large data transfers, so for that it's more of an artifical use case.

@stnolting
Copy link
Owner Author

Indeed the 1 channel limitation is probably the biggest one. However, there still seem to be cases where one channel is already quite usedul.

Right. Most of the time I use the DMA interrupt to configure the next transfer from a software-managed list. This basically implements some kind of channelization.

What's more, we now also have a dual-core option. I simply use the second core as a kind of DMA instead of the actual DMA hardware module.

I was thinking of implementing a simple SD card hardware controller.

Good point. The legacy SPI protocol is nice if you do not need much data at a high transfer speed. But I agree, an external dedicated SD-mode controller would be more efficient. I think there are some good ones here on GitHub, too.

I'd like to provide a more lightweight implementation, where only a single 32 bit data register is required. Whenever 32 bit have been read, I'd make them available in a data register and issue an data ready interrupt. Then the controller is paused until the data register has been read.

You could increase the default bus timeout to some 1000 cycles and use the bus interface's ACK signal to halt the DMA/CPU until a new word of SD-card data is actually available. We are using this concept for accessing the CRC module:

we_ack <= we_ack(we_ack'left-1 downto 0) & (bus_req_i.stb and bus_req_i.rw);

bus_rsp_o.ack <= we_ack(we_ack'left) or (bus_req_i.stb and (not bus_req_i.rw));

This way the DMA would copy the whole SD card sector to memory without CPU interaction. Once the DMA finished interrupt triggers, the application can start processing the data and set up new SD card commands.

Sounds good! Maybe you can use double-buffering - transfer SD card data to one memory block while processing the previous SD data in another memory block.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cleanup Clean-up the codebase HW Hardware-related
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants