[EDIT] Go to post#2 to see what the problem now...
Hi.
I'm making a library to use DUE analog sequencer and ADC interrupt for precise sampling.
It use a ring buffer of 256 sample * number of channel active sequencer channels on a 2 dimension array.
value[256][numChannels]
Main 256 buffer are control with counter; countOutterFront and countOutterRear;
front increment after each ENDRX interrupt and data transfer to buffer.
on void loop, I read the data using for each conversion array with value[countOutterRear], that return the array of conversion.
If Rear==front, while loop exit and try the next loop if there's is new data (Rear!=front).
I had a print statement to monitor, set enough fast, rear and front, rear, after catching up after boot, follow front.
Now the strange behavior, it take a whole iteration of 256 sample before see a change in the printed data.
Timing, ADC and interrupt seem to work properly...
here the git repo for all the code:
the the main function I think are involve...
void ADC_Sampler::bufferConfig() {
ADC->ADC_IER = ADC_IDR_ENDRX; // interrupt enable register, enables only ENDRX
// following are the DMA controller registers for this peripheral
// "receive buffer address"
ADC->ADC_RPR = (uint32_t)bufferArray->value[bufferArray->countOutterFront]; // DMA receive pointer register points to beginning of global_ADCount
// "receive count"
ADC->ADC_RCR = numChannels; // receive counter set
// "next-buffer address"
ADC->ADC_RNPR = (uint32_t)bufferArray->value[bufferArray->countOutterFront]; // next receive pointer register DMA global_ADCounts_Arrayfer points to second set of data
// and "next count"
ADC->ADC_RNCR = numChannels; // and next counter is set
// "transmit control register"
ADC->ADC_PTCR = ADC_PTCR_RXTEN; // transfer control register for the DMA is set to enable receiver channel requests
}
uint16_t* ADC_Sampler::data() {
uint16_t* arr = bufferArray->data();
return arr;
}
bool ADC_Sampler::available() {
if (bufferArray->countOutterRear != bufferArray->countOutterFront) return true;
return false;
}
void ADC_Sampler::ADC_Handler() { // for the ATOD: re-initialize DMA pointers and count
// read the interrupt status register
if (ADC->ADC_ISR & ADC_ISR_ENDRX){ /// check the bit "endrx" in the status register /// ADC_IDR_ENDRX correction
/// set up the "next pointer register"
ADC->ADC_RNPR =(uint32_t)bufferArray->value[bufferArray->countOutterFront]; // "receive next pointer" register set to global_ADCounts_Array
// set up the "next count"
ADC->ADC_RNCR = numChannels; // "receive next" counter
bufferArray->countOutterFront++;
}
}
#ifdef __cplusplus
extern "C"
{
#endif
void ADC_Handler (void)
{
ADC_Sampler::ADC_Handler();
}
#ifdef __cplusplus
}
#endif
///ADCuffer
AdcBuffer::AdcBuffer(uint8_t innerSize) : countInnerFront(0), countInnerRear(0), countOutterFront(0), countOutterRear(0) {
value = new uint16_t*[BUFFER_SIZE];
for ( int i = 0; i < BUFFER_SIZE; i++) {
value[i] = new uint16_t[innerSize] {0};
}
}
uint16_t* AdcBuffer::data() volatile {
uint16_t *arr = value[countOutterRear];
countOutterRear++;
return arr;
}
bool AdcBuffer::available() {
if (countOutterRear != countOutterFront) return true;
return false;
}
//main sketch
void loop() {
String output;
if(ADC_Sampler::available()) Serial.println("A7,A6,A5,A4,A3,A2,A0,A1,A9,A10,A11");
while ( ADC_Sampler::available() ) {
uint16_t* x = ADC_Sampler::data();
for (int i = 0; i < ADC_sequencer_size; i++) {
output += String(x[i]);
output += ",";
}
output += " rear ";
output += String(ADC_Sampler::bufferArray->countOutterRear);
output += " front ";
uint8_t fr = ADC_Sampler::bufferArray->countOutterFront;
output += String(fr);
Serial.println(output);
output = String();//RESET
}
delay(1);
}
Regards.
Nitrof