Hello there~
I've recently picked up an Arduino Due and I'm currently trying to make it work as a gamecube controller (so it writes the controller outputs rather than the more common reading inputs). According to the timing of the GC. I need to be able to send data pulses over 4 microseconds, but each pulse is only high for either 1us or 3us, which is a little easier to time with than, say, the Uno.
However, in order to minimize any possible timing issues, I'm planning on using asm to properly time the pulses. At the moment, I have a fair idea of how to do this (basing off of this wonderful piece of code), but I'm not sure how to write to a pin in ARM without cbi.
As a side note, I apologize if the solution obvious- I've only found out about asm a few days ago, so I'm not sure if this is even the proper route to go (as the Due had a higher learning curve than I thought with less examples to learn from). Currently, my plan is to take digitalwritedirect (found here and here), compile it, and then check the assembly to see the exact timing then to use the assembly itself. However, I'm not even sure if that's applicable here at all with asm.
Finally, I did this digitalWrite for the SAMD core, and the relevant parts with the pull-up resistor worries me. Is a pull-up resistor relevant at all to the Due's SAM38XE CPU and - I apologize for throwing this here on top of everything else - is a pull-up resistor necessary at all for this application? I don't see how it's exactly relevant for the application and timing (then again, I've never really understood entirely the purpose of pull-up resistors).
Thanks for at least reading this post through! This is the one key obstacle I've been having trouble getting over, and I appreciate any and all help!
Edit:
I apologize about the pull-up resistor question, that was a terrible question. First off, I shouldn't need the pull-up resistor as I can choose the line to be high (and I don't need to care about the line before setup() runs). Furthermore, the SAM38XE spec states (section 31.5.6 Multi Drive Control (Open Drain)) that it is possible by writing to the PIO_MDER register, but it shouldn't be necessary (albeit I'll need to look into that separately).
(Edit2: In case anyone is curious, I was incorrect as the communication is bidirectional over a single line, so it needs to be open drain and I need to access the PIO_MDER register for the pin)
As for the primary topic, I found this beautiful question. Thus, I should be able to use the following to enable port 13:
asm volatile("mov r0, %[val]"::[val] "r" (®_PIOB_SODR));
asm volatile("mov r1, #1, lsl #27");
asm volatile("str r1, [r0]");
Two questions:
- Can I access all registers via REG_(REGNAME) (such as %REG_PIO_MDER)? And in the spec I found PIO_SODR instead of PIOB_SODR- I'm not sure where this discrepancy comes from at all or where to find out how it applies to the Due.
- Why is the 1 left shifted by 27 instead of, say, 12?
Thank you!