speeding up analogread() at the Arduino Zero
hello,
i use 0 , looking faster analog reading times. found articles due (link), nothing zero. since i'm not verry µc experienced, take me lot time transfer.
but, google found thread in japanese forum, , including code, come 436µs 21µs analog reading time. maybe use someone:
the datasheet of atmel sam d21e mentions readingspeed of 350ks, there might still room more optimisations reach ~3µs, making run in free running mode?
i found more code used example here.
i use 0 , looking faster analog reading times. found articles due (link), nothing zero. since i'm not verry µc experienced, take me lot time transfer.
but, google found thread in japanese forum, , including code, come 436µs 21µs analog reading time. maybe use someone:
code: [select]
void adcbooster()
{
adc->ctrla.bit.enable = 0; // disable adc
while( adc->status.bit.syncbusy == 1 ); // wait synchronization
adc->ctrlb.reg = adc_ctrlb_prescaler_div64 | // divide clock 64.
adc_ctrlb_ressel_12bit; // result on 12 bits
adc->avgctrl.reg = adc_avgctrl_samplenum_1 | // 1 sample
adc_avgctrl_adjres(0x00ul); // adjusting result 0
adc->sampctrl.reg = 0x00; // sampling time length = 0
adc->ctrla.bit.enable = 1; // enable adc
while( adc->status.bit.syncbusy == 1 ); // wait synchronization
} // adcbooster
int analogpin = 1;
unsigned long start_times[100];
unsigned long stop_times[100];
unsigned long values[100];
void setup() {
adcbooster(); //uncomment reading time without 'boost'
serial.begin(9600);
pinmode(analogpin, input);
}
void loop() {
analogreadresolution(12); //analog resolution 12bit
unsigned int i;
for(i=0;i<100;i++) {
start_times[i] = micros();
values[i] = analogread(analogpin);
stop_times[i] = micros();
}
// print out results
serial.println("\n\n--- results ---");
for(i=0;i<100;i++) {
serial.print(values[i]);
serial.print(" elapse = ");
serial.print(stop_times[i] - start_times[i]);
serial.print(" us\n");
}
}
the datasheet of atmel sam d21e mentions readingspeed of 350ks, there might still room more optimisations reach ~3µs, making run in free running mode?
i found more code used example here.
hi,
you can use adc dma fill buffer adc samples. method, takes around 2us measure 1 sample. depending of needs, useful.
check thread more information : https://forum.arduino.cc/index.php?topic=346761.0
you can use adc dma fill buffer adc samples. method, takes around 2us measure 1 sample. depending of needs, useful.
check thread more information : https://forum.arduino.cc/index.php?topic=346761.0
code: [select]
// adcdma
// analog a1
// could use dac provide input voltage a0
// http://www.atmel.com/images/atmel-42258-asf-manual-sam-d21_ap-note_at07627.pdf pg 73
#define adcpin a1
#define hwords 1024
uint16_t adcbuf[hwords];
typedef struct {
uint16_t btctrl;
uint16_t btcnt;
uint32_t srcaddr;
uint32_t dstaddr;
uint32_t descaddr;
} dmacdescriptor ;
volatile dmacdescriptor wrb[12] __attribute__ ((aligned (16)));
dmacdescriptor descriptor_section[12] __attribute__ ((aligned (16)));
dmacdescriptor descriptor __attribute__ ((aligned (16)));
static uint32_t chnl = 0; // dma channel
volatile uint32_t dmadone;
void dmac_handler() {
// interrupts dmac_chintenclr_terr dmac_chintenclr_tcmpl dmac_chintenclr_susp
uint8_t active_channel;
// disable irqs ?
__disable_irq();
active_channel = dmac->intpend.reg & dmac_intpend_id_msk; // channel number
dmac->chid.reg = dmac_chid_id(active_channel);
dmadone = dmac->chintflag.reg;
dmac->chintflag.reg = dmac_chintenclr_tcmpl; // clear
dmac->chintflag.reg = dmac_chintenclr_terr;
dmac->chintflag.reg = dmac_chintenclr_susp;
__enable_irq();
}
void dma_init() {
// on default
pm->ahbmask.reg |= pm_ahbmask_dmac ;
pm->apbbmask.reg |= pm_apbbmask_dmac ;
nvic_enableirq( dmac_irqn ) ;
dmac->baseaddr.reg = (uint32_t)descriptor_section;
dmac->wrbaddr.reg = (uint32_t)wrb;
dmac->ctrl.reg = dmac_ctrl_dmaenable | dmac_ctrl_lvlen(0xf);
}
void adc_dma(void *rxdata, size_t hwords) {
uint32_t temp_chctrlb_reg;
dmac->chid.reg = dmac_chid_id(chnl);
dmac->chctrla.reg &= ~dmac_chctrla_enable;
dmac->chctrla.reg = dmac_chctrla_swrst;
dmac->swtrigctrl.reg &= (uint32_t)(~(1 << chnl));
temp_chctrlb_reg = dmac_chctrlb_lvl(0) |
dmac_chctrlb_trigsrc(adc_dmac_id_resrdy) | dmac_chctrlb_trigact_beat;
dmac->chctrlb.reg = temp_chctrlb_reg;
dmac->chintenset.reg = dmac_chintenset_mask ; // enable 3 interrupts
dmadone = 0;
descriptor.descaddr = 0;
descriptor.srcaddr = (uint32_t) &adc->result.reg;
descriptor.btcnt = hwords;
descriptor.dstaddr = (uint32_t)rxdata + hwords*2; // end address
descriptor.btctrl = dmac_btctrl_beatsize_hword | dmac_btctrl_dstinc | dmac_btctrl_valid;
memcpy(&descriptor_section[chnl],&descriptor, sizeof(dmacdescriptor));
// start channel
dmac->chid.reg = dmac_chid_id(chnl);
dmac->chctrla.reg |= dmac_chctrla_enable;
}
static __inline__ void adcsync() __attribute__((always_inline, unused));
static void adcsync() {
while (adc->status.bit.syncbusy == 1); //just wait till adc free
}
void adc_init(){
analogread(adcpin); // pin init pinperipheral()
adc->ctrla.bit.enable = 0x00; // disable adc
adcsync();
//adc->refctrl.bit.refsel = adc_refctrl_refsel_intvcc0_val; // 2.2297 v supply vddana
//adc->inputctrl.bit.gain = adc_inputctrl_gain_1x_val; // gain select 1x
adc->inputctrl.bit.gain = adc_inputctrl_gain_div2_val; // default
adc->refctrl.bit.refsel = adc_refctrl_refsel_intvcc1_val;
adcsync(); // ref 31.6.16
adc->inputctrl.bit.muxpos = g_apindescription[adcpin].uladcchannelnumber;
adcsync();
adc->avgctrl.reg = 0x00 ; //no averaging
adc->sampctrl.reg = 0x00; ; //sample length in 1/2 clk_adc cycles
adcsync();
adc->ctrlb.reg = adc_ctrlb_prescaler_div16 | adc_ctrlb_freerun | adc_ctrlb_ressel_10bit;
adcsync();
adc->ctrla.bit.enable = 0x01;
adcsync();
}
void setup(){
serial.begin(9600);
analogwriteresolution(10);
analogwrite(a0,64); // test dac
adc_init();
dma_init();
}
void loop() {
uint32_t t;
t = micros();
adc_dma(adcbuf,hwords);
while(!dmadone); // await dma done isr
t = micros() - t;
serial.print(t); serial.print(" us ");
serial.println(adcbuf[0]);
delay(2000);
}
Arduino Forum > Products > Arduino Zero (Moderator: cmaglie) > speeding up analogread() at the Arduino Zero
arduino
Comments
Post a Comment