Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suggestion about DMA interface #16

Open
tdunning opened this issue Jan 13, 2025 · 1 comment
Open

Suggestion about DMA interface #16

tdunning opened this issue Jan 13, 2025 · 1 comment

Comments

@tdunning
Copy link

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)))
}
@soypat
Copy link
Collaborator

soypat commented Feb 23, 2025

Hey @tdunning! Sorry about the long response time. Feel free to add the methods you detail here as is, they seem like a logical addition which would allow flexibility to users. That said I still am unsure of exporting the dmaChannel type since this package is not quite the ideal place to be pulling DMA logic from. Eventually when we do put the DMA logic in its final resting place (probably tinygo machine package) it will bring along these methods :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants