I have a problem writing to a digital pin on Arduino Due while my ADC is running.
I have the following code:
#undef HID_ENABLED
// Arduino Due ADC->DMA->USB 1MSPS
// by stimmer
// from http://forum.arduino.cc/index.php?topic=137635.msg1136315#msg1136315
// Input: Analog in A0
// Output: Raw stream of uint16_t in range 0-4095 on Native USB Serial/ACM
// on linux, to stop the OS cooking your data:
// stty -F /dev/ttyACM0 raw -iexten -echo -echoe -echok -echoctl -echoke -onlcr
// source: https://gist.github.com/pklaus/5921022
// applied patch 1 from: http://forum.arduino.cc/index.php?topic=137635.msg2526475#msg2526475
// applied patch 2 from: https://gist.github.com/pklaus/5921022 comment on Apr 2, 2017 from borisbarbour
volatile int bufn,obufn;
uint16_t buf[4][256]; // 4 buffers of 256 readings
void ADC_Handler(){ // move DMA pointers to next buffer
int f=ADC->ADC_ISR;
if (f&(1<<27)){
bufn=(bufn+1)&3;
// patch 2 start
//ADC->ADC_RNPR=(uint32_t)buf[bufn];
ADC->ADC_RNPR=(uint32_t)buf[(bufn+1)&3];
// patch 2 end
ADC->ADC_RNCR=256;
}
}
void setup() {
SerialUSB.begin(0);
while(!SerialUSB);
pmc_enable_periph_clk(ID_ADC);
adc_init(ADC, SystemCoreClock, ADC_FREQ_MAX, ADC_STARTUP_FAST);
ADC->ADC_MR |=0x80; // free running
ADC->ADC_CHER=0x80;
NVIC_EnableIRQ(ADC_IRQn);
ADC->ADC_IDR=~(1<<27);
ADC->ADC_IER=1<<27;
ADC->ADC_RPR=(uint32_t)buf[0]; // DMA buffer
ADC->ADC_RCR=256;
ADC->ADC_RNPR=(uint32_t)buf[1]; // next DMA buffer
ADC->ADC_RNCR=256;
// patch 1.2 start
//bufn=obufn=1;
bufn=1;
obufn=0;
// patch 1.2 end
ADC->ADC_PTCR=1;
ADC->ADC_CR=2;
// this doesn't work:
pinMode(52, OUTPUT); //
digitalWrite(52, HIGH); //
}
void loop(){
// patch 1.1 start
while((obufn + 1)%4==bufn);// wait for buffer to be full
// patch 1.1 end
SerialUSB.write((uint8_t *)buf[obufn],512); // send it - 512 bytes = 256 uint16_t
obufn=(obufn+1)&3;
}
Pin 52 says 0 V.
With this function, I can pull the digital output voltage to 1.58 V:
void digitalWriteDirect(int pin, boolean val){
if(val) g_APinDescription[pin].pPort -> PIO_SODR = g_APinDescription[pin].ulPin;
else g_APinDescription[pin].pPort -> PIO_CODR = g_APinDescription[pin].ulPin;
}
Any ideas?
1 Answer 1
I found the problem: The Arduino had been waiting for the SerialUSB
Connection.
The Serial connection has not been established because I was running the Arduino without running the corresponding Python script. That script would have opened the Serial connection.
When running the Python script, the Arduino Due then works as expected.