h6. [[Hardware Abstraction Layer]] h6(. » [[HAL Device API]] h6((. » [[List of HAL devices]] h6(((. » DMA channel - list type h5. (HALDeviceSysPeri_DMAL) h4. Device API Currently, only API versions 0 and 1 are defined. h5. API version 0 <pre> struct dmalistchannel { /* Public interface */ struct device dev; struct dmalistchannelfeatures *(*Features)(struct dmachannel *); dmacontroller *controller; void (*Abort)(struct dmachannel *); void (*SetOptions)(struct dmachannel *, uint32_t flags, uint32_t address); void (*SetListTransfer)(struct dmachannel *, uint32_t blockphy, void *blocklog, uint32_t nentries, uint32_t length); uint32_t (*ListTransferProgress)(struct dmachannel *); uint32_t (*ListTransferStatus)(struct dmachannel *); uint32_t (*CurtailListTransfer)(struct dmachannel *, uint32_t minimum); } </pre> _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). Interrupts are used to detect transfer termination, and to trigger sync callbacks. If the device provides no interrupt, the device is interrogated from a [[TickerV]] routine instead. _dev.Activate_, _dev.Deactivate_, and_dev.Reset_ are handled similarly to [[HALDeviceSysPeri_DMAB|buffer-type DMA channel]] _Features_ returns a pointer to the following data structure: <pre> struct dmalistchannelfeatures { uint32_t flags; uint32_t blocksize; uint32_t blockalign; uint32_t blockbound; uint32_t maxtransfers; uint32_t transferlimit; uint32_t transferbound; } </pre> Defined _flags_ bits are as followed: |_<. Bit |_<. Flag |_<. Meaning when set | |1 |DMAFeaturesFlag_NotCircular |Channel does not support circular transfers | |2 |DMAFeaturesFlag_NotInfinite |Channel does not support infinite transfers | |3 |DMAFeaturesFlag_NoSyncIRQs |Channel does not generate interrupts on completion of each entry in the transfer descriptors block, so there is no benefit to be gained by splitting descriptors at multiples of the sync gap (sync gap splitting is done when this bit is clear, to provide more accurate sync callbacks) | Flag bits not mentioned are reserved and must be set to zero. Other entries in the structure are as follows: * _blocksize_ is the amount of memory to allocate for transfer descriptors block. * _blockalign_ is the required alignment of the transfer descriptors block (0 if none). * _blocklimit_ is the boundary limitation of transfer descriptors block (0 if none). * _maxtransfers_ is the maximum number of entries to provide in the transfer descriptors block (note this may differe from blocksize/8 if postprocessing needs to be done before the block is presented to the hardware). * _transferlimit_ is the maximum amount of data that can be transferred by a single entry in the transfer descriptors block. * _transferbound_ is the boundary limitation of individual entries in the transfer descriptors block. _controller_ points to this channel's [[HALDeviceSysPeri_DMAC|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 the same as for [[HALDeviceSysPeri_DMAB|buffer-type DMA channel devices]], with the addition of one extra flag: |_<. Bit(s) |_<. Meaning | |15 |Bit set => Transfer is circular | _SetListTransfer_ initiates the transfer according t o the transfer descriptors block: * _blockphy_ is the physical address of the transfer descritpors block. * _blocklog_ is the logical address of the transfer descriptors block. * _nentries_ is the number of entries in the transfer descriptors block. * _length_ is the total length to transfer, or 0 for infinite transfer. _ListTransferProgress_ returns the number of bytes transferred since the transfer was initiated. If this cannot be determined exactly, an underestimate should be returned. _ListTransferStatus_ returns status flags for the current channel: |_<. Bit |_<. Meaning | |0 |Bit set => An error has occured accessing memory (e.g. bus abort) since the transfer was initiated. | |1 |Bit set => An error has occured accessing the device (e.g. transfer size mismatch) since the transfer was started. | Other bits are reserved and should be zero. _CurtailListTransfer_ requests that a transfer in progress be shortened as much as possible subject to normal termination conditions (e.g. raising the TC line). The call need not block. For infinite transfers, there is a minimum requirement that this makes the transfer finite. _minimum_ specifies the minimum number of bytes that must still be transferred (as returned from the DMASync callback). Returns the number of bytes that will have been transferred when the transfer terminates. h5. API version 1 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 | h4. Support in RISC OS HALDeviceSysPeri_DMAL is supported by the trunk version of the [[DMAManager]] module. h4. Known implementations |_<. Device ID |_<. Description |_<. Implemented in | |/2^. HALDeviceID_DMAL_M5229 |Acer M5229 ATA controller bus master primary channel |/2^. HAL.Tungsten.s.ATA | |Acer M5229 ATA controller bus master secondary channel | |/1^. HALDeviceID_DMAL_BCM2835 |BCM2835 DMA channel |/1^. HAL.BCM2835.s.DMA | h6. Information sources: Kernel.Hdr.HALDevice, HWSupport.DMA.HAL_DMAAPI, HWSupport.DMA.hdr.DMADevice in CVS