Hello!
I've been playing around with the Metro M4 Grand Central, and I was wondering if it was possible to speed up the analogWrite(); function?
I was thinking about creating my own NTSC composite out with the DAC, but it seems far too slow. Based on the specs of 1 MSPS, I would think that it could run close to 1MHz, but that doesn't seem to be the case.
Any suggestions?
Thanks!
Fast analogWrite to DAC?
Moderators: adafruit_support_bill, adafruit
Please be positive and constructive with your questions and comments.
- adafruit_support_bill
- Posts: 88096
- Joined: Sat Feb 07, 2009 10:11 am
Re: Fast analogWrite to DAC?
The Arduino language in general is designed for portability and not optimized for speed. To get maximum analogWrite performance from the M4, you will probably need to do some in-line assembly code.
- dmoss
- Posts: 3
- Joined: Sun Nov 04, 2012 10:17 pm
Re: Fast analogWrite to DAC?
Thanks for the quick reply.
Is there any documentation/libraries for directly accessing registers for this board? It seems like the documentation on the microchip site assumes that you are using their C compiler MPLAB.
Is there any documentation/libraries for directly accessing registers for this board? It seems like the documentation on the microchip site assumes that you are using their C compiler MPLAB.
- adafruit_support_bill
- Posts: 88096
- Joined: Sat Feb 07, 2009 10:11 am
Re: Fast analogWrite to DAC?
Adding inline assembly statements to an Arduino sketch is pretty straightforward: https://forum.arduino.cc/t/inline-asm-in-arduino/644126
But I don't know of any examples offhand of assembly code for the SAMD51 (Cortex M4). You might find some in the SAMD51 core code-base here: https://github.com/ace22293/SAMD51
But I don't know of any examples offhand of assembly code for the SAMD51 (Cortex M4). You might find some in the SAMD51 core code-base here: https://github.com/ace22293/SAMD51
- dmoss
- Posts: 3
- Joined: Sun Nov 04, 2012 10:17 pm
Re: Fast analogWrite to DAC?
Hello!
I was able to find some code on-line that does the trick without any assembly. It just changes the setup by setting some registers. My guess is that there is something in the default Arduino code for this microcontroller that is slowing it down.
With the new setup below, I can run between 200kHz and 600kHz which is pretty good!
I hope that this is helpful to the community, and maybe somebody can attempt to improve the arduino code!
void setup() {
GCLK->GENCTRL[1].reg =
GCLK_GENCTRL_DIV(0) |
GCLK_GENCTRL_IDC |
GCLK_GENCTRL_GENEN |
GCLK_GENCTRL_SRC_XOSC0;
GCLK->PCHCTRL[42].reg =
GCLK_PCHCTRL_BANNED |
GCLK_PCHCTRL_GEN_GCLK1; //DAC BIT
MCLK->APBDMASK.bit.DAC_ = 1;
DAC->CTRLA.bit.SWRST = 1;
while(DAC->CTRLA.bit.SWRST);
DAC->DACCTRL[0].reg = DAC_DACCTRL_REFRESH(1) |
DAC_DACCTRL_CCTRL_CC12M |
DAC_DACCTRL_ENABLE ;
//DAC_DACCTRL_LEFTADJ;
DAC->CTRLB.reg = DAC_CTRLB_REFSEL_INTREF;
DAC->DBGCTRL.bit.DBGRUN = 1;
DAC->CTRLA.reg = DAC_CTRLA_ENABLE;
while(DAC->SYNCBUSY.bit.ENABLE);
while(!DAC->STATUS.bit.READY0);
PORT->Group[0].PMUX[2].bit.PMUXO = 1;
PORT->Group[0].PINCFG[5].reg = PORT_PINCFG_PMUXEN;
}
void loop() {
DAC->DATA[0].reg = 500; while(!DAC->STATUS.bit.EOC0);
DAC->DATA[0].reg = 0; while(!DAC->STATUS.bit.EOC0);
}
I was able to find some code on-line that does the trick without any assembly. It just changes the setup by setting some registers. My guess is that there is something in the default Arduino code for this microcontroller that is slowing it down.
With the new setup below, I can run between 200kHz and 600kHz which is pretty good!
I hope that this is helpful to the community, and maybe somebody can attempt to improve the arduino code!
void setup() {
GCLK->GENCTRL[1].reg =
GCLK_GENCTRL_DIV(0) |
GCLK_GENCTRL_IDC |
GCLK_GENCTRL_GENEN |
GCLK_GENCTRL_SRC_XOSC0;
GCLK->PCHCTRL[42].reg =
GCLK_PCHCTRL_BANNED |
GCLK_PCHCTRL_GEN_GCLK1; //DAC BIT
MCLK->APBDMASK.bit.DAC_ = 1;
DAC->CTRLA.bit.SWRST = 1;
while(DAC->CTRLA.bit.SWRST);
DAC->DACCTRL[0].reg = DAC_DACCTRL_REFRESH(1) |
DAC_DACCTRL_CCTRL_CC12M |
DAC_DACCTRL_ENABLE ;
//DAC_DACCTRL_LEFTADJ;
DAC->CTRLB.reg = DAC_CTRLB_REFSEL_INTREF;
DAC->DBGCTRL.bit.DBGRUN = 1;
DAC->CTRLA.reg = DAC_CTRLA_ENABLE;
while(DAC->SYNCBUSY.bit.ENABLE);
while(!DAC->STATUS.bit.READY0);
PORT->Group[0].PMUX[2].bit.PMUXO = 1;
PORT->Group[0].PINCFG[5].reg = PORT_PINCFG_PMUXEN;
}
void loop() {
DAC->DATA[0].reg = 500; while(!DAC->STATUS.bit.EOC0);
DAC->DATA[0].reg = 0; while(!DAC->STATUS.bit.EOC0);
}
- adafruit_support_bill
- Posts: 88096
- Joined: Sat Feb 07, 2009 10:11 am
Re: Fast analogWrite to DAC?
Thanks for posting that. The high-level Arduino implementation is fairly generic. Partly for portability but mostly to hide the gory details from the inexperienced coders the system was designed for.
There are lots of examples on-line of low-level optimizations to speed up I/O on older AVR-based Arduinos. It will take a while for the community to catch up with all of the new processor architectures out there.
There are lots of examples on-line of low-level optimizations to speed up I/O on older AVR-based Arduinos. It will take a while for the community to catch up with all of the new processor architectures out there.
Please be positive and constructive with your questions and comments.