Description
I have been using a fork of the DMA code here and find it works well.
The exception is that my application involves reading from two chained PWM counters in A B A B A order. To do this, I am chaining one DMA channel to another. To decrease the size of the control blocks, I am using the aliases of the DMA control registers which is pretty awkward in the current API.
To help with his, I have added the following code that allows me to get any alias of any register from a DMA channel as a volatile.Register32
. This lets me use the bit banging capabilities of a register to easily manipulate these values. I also have a related function that gives me the address of each register as a uint32
using a parallel API which is important for chaining. I think that this additional function is pretty much orthogonal to the other stuff you have in the package.
I can package this as a proper pull request, but I am unsure how you guys are running tests on code that is hardware dependent. Advice would be appreciated.
type dmaRegisterOffset uint32
// register offsets for DMA channels
//
//goland:noinspection GoSnakeCaseUsage
const (
DMA_READ_ADDR = dmaRegisterOffset(4 * iota)
DMA_WRITE_ADDR
DMA_TRANS_COUNT
DMA_CTRL_TRIG
DMA_AL1_CTRL
DMA_AL1_READ_ADDR
DMA_AL1_WRITE_ADDR
DMA_AL1_TRANS_COUNT_TRIG
DMA_AL2_CTRL
DMA_AL2_TRANS_COUNT
DMA_AL2_READ_ADDR
DMA_AL2_WRITE_ADDR_TRIG
DMA_AL3_CTRL
DMA_AL3_WRITE_ADDR
DMA_AL3_TRANS_COUNT
DMA_AL3_READ_ADDR_TRIG
DMA_END_MARKER = uint32(DMA_AL3_READ_ADDR_TRIG) + 4
)
func (ch DmaChannel) DmaRegisterAddress(register dmaRegisterOffset) uintptr {
base := uintptr(unsafe.Pointer(rp.DMA))
return (base + uintptr(ch.ChannelIndex())*uintptr(DMA_END_MARKER) + uintptr(register))
}
func (ch DmaChannel) DmaRegister(register dmaRegisterOffset) *volatile.Register32 {
//goland:noinspection GoVetUnsafePointer
return (*volatile.Register32)(unsafe.Pointer(ch.DmaRegisterAddress(register)))
}
Activity