Showing changes from revision #2 to #3:
Added | Removed | Changed
Currently, only API versions 0 and 1 are defined.
struct dmachannel { /* Public interface */ struct device dev; uint32_t (*Features)(struct dmachannel *); dmacontroller *controller; void (*Abort)(struct dmachannel *); void (*SetOptions)(struct dmachannel *, uint32_t flags, uint32_t address); void (*SetCurrentTransfer)(struct dmachannel *, uint32_t address, uint32_t length, uint32_t flags); void (*SetNextTransfer)(struct dmachannel *, uint32_t address, uint32_t length, uint32_t flags); __value_in_regs struct { uint32_t address; uint32_t length; } (*TransferState)(struct dmachannel *); void (*IRQClear)(struct dmachannel *); uint32_t (*Status)(struct dmachannel *); void (*SetCurrentTransfer2)(struct dmachannel *, uint32_t srcaddress, uint32_t dstaddress, uint32_t length, uint32_t flags); void (*SetNextTransfer2)(struct dmachannel *, uint32_t srcaddress, uint32_t dstaddress, uint32_t length, uint32_t flags); __value_in_regs struct { uint32_t srcaddress; uint32_t dstaddress; uint32_t length; } (*TransferState2)(struct dmachannel *); }
dev is the standard HAL Device descriptor. The address field is not used. Channels are activated/deactivated around each transfer (and are deactivated when a transfer is suspended).
dev.Activate enables this physical DMA channel, so that it can generate interrupts (typically this involves unmasking the DMA request line and unmasking a bit in an interrupt control register). If this is an interrupt-generating channel (i.e. dev.devicenumber is not -1) then the channel must generate an interrupt if Activate is called when no data has been scheduled for transfer.
dev.Deactivate must block until the transfer on this channel can safely be interrupted (due to Service_PagesUnsafe or SWI DMA_SuspendTransfer), then disable DMA at the DMA request line and interrupt generation levels. After it returns, the values returned from TransferState and Status must reflect the true state of the hardware – ie they must be suitable to use for resumption of the transfer using SetCurrentTransfer.
dev.Reset is called by the DMAManager between transfers (but not on OS resets). After this call, Status must report an over/underrun condition.
Features returns a flag word. Defined bits are as followed:
Bit | Flag | Meaning when set |
---|---|---|
0 | DMAFeaturesFlag_DualAddress | Channel implements “dual address mode”, i.e. it can only be used for DMA accelerated copies of blocks of memory. |
Flag bits not mentioned are reserved and must be set to zero.
controller points to this channel’s DMA controller device
Abort should be considered a “forced” version of dev.Deactivate, and is only used for SWI DMA_TerminateTransfer. The call must not block, but the values subsequently returned from TransferState and Status are allowed to report inaccurate results, providing they underestimate the progress of the transfer.
SetOptions is used to control the behaviour of the channel. The flags parameter specifies a flags word; defined bits are as follows:
Bit(s) | Meaning |
---|---|
0 | Bit set => memory to device |
Bit clear => device to memory | |
(Ignored for memory-to-memory channel) | |
1-5 | Transfer unit width, typically 1, 2 or 4 bytes (16 bytes can also be used for IOMD) |
6-8 | Cycle speed, on an arbitrary scale from 0-7 (0-3 maps to A-D cycles on IOMD) |
9-12 | Minimum delay required after a DMA transfer before the same physical channel is reused (required for 7200 and 9200) |
13 | Bit set => Disable burst transfers for this channel |
14 | Bit set => Bypass synchronisation to clock before initiating transfer (for synchronous peripherals – currently 7200 only) |
Other bits are reserved and must be ignored.
The address parameter sets the physical address of the peripheral to DMA to/from (should be ignored by memory-to-memory channels)
SetCurrentTransfer sets up the first transfer to be executed for this channel. address provides the physical address to start transfer from. length is the number of bytes to transfer. flags provides a flags word:
Bit | Meaning |
---|---|
0 | Bit set => stop and raise the TC signal when this transfer completes (mandatory if the DMA controller has no interrupt of its own) |
address and length should be multiples of the transfer unit size, and must not cross a page boundary.
SetNextTransfer sets up the next transfer to be executed for this channel, using similar parameters to SetCurrentTransfer. This will only be called for double-buffered channels.
TransferState reads the progress of the current transfer on this channel. If the DMA controller will not report accurate progress, report values corresponding to a pessimistic amount of progress.
IRQClear clears the interrupt for this physical DMA channel (unless some other action carried out during or since TestIRQ has already done so).
Status returns status bits for the current channel:
Bit | Meaning |
---|---|
0 | Bit set => There are no transfers programmed but not yet started (for a double-buffered controller, this is set when interrupting or for a single-buffered controller, this is always set) |
1 | Bit set => Channel has not yet been used, or is in over/underrun state (set on every interrupt for single-buffered DMA controllers) |
2 | Bit set => Channel entered over/underrun state before last call to SetNextTransfer had effect (devices may determine this by monitoring any handle they may have on the physical double buffers, or failing this by calculating the final value of the current pointer of the current buffer, and comparing it to what would be expected from the last time the next buffer was programmed – but note that this latter algorithm will fail if a circular transfer from a single-entry scatter list is in use) so the DMA manager needs to program the same data again, but this time using SetCurrentTransfer. This bit must be clear if the last transfer was programmed using SetCurrentTransfer, or if bit 1 is clear. |
Other bits are reserved and should be zero.
SetCurrentTransfer2, SetNextTransfer2 and TransferState2 are the same as above but with two address arguments and one length argument. For use in memory-to-memory transfers only.
API version 1 extends the set of flags returned by Features:
Bit | Flag | Meaning when set |
---|---|---|
4 | DMAFeaturesFlag_NoInitIRQ | Channel doesn’t generate an IRQ if Activate is called when the channel has no pending transfers |
5 | DMAFeaturesFlag_DoubleBuffered | The channel implements SetNextTransfer in conjunction with DMAFeaturesFlag_NoInitIRQ |
HALDeviceSysPeri_DMAB is supported by the trunk branch version of the DMAManager module.DMAManager module.
Device ID | Description | Implemented in |
---|---|---|
HALDeviceID_DMAB_M1535 | Acer M1535+ legacy DMA channel <x> | HAL.Tungsten.s.M1535DMA |
HALDeviceID_DMAB_OMAP3 | OMAP3 system DMA channel <x> | HAL.OMAP3.s.SDMA |