Fast AnalogIn module which asks for a single non blocking reading and causes and interrupt when done.
Diff: NbAnalogIn.cpp
- Revision:
- 1:2666729acca1
- Parent:
- 0:058d32b78e5d
- Child:
- 2:336af413f75c
--- a/NbAnalogIn.cpp Mon Mar 27 11:35:25 2017 +0000 +++ b/NbAnalogIn.cpp Sun Apr 02 11:16:24 2017 +0000 @@ -1,8 +1,26 @@ #include "NbAnalogIn.h" +static inline int pos_inc(int i) { + + if (i < ADC_BUF_SIZE - 1) { + i++; + } else { + i = 0; + } + return i; +} + +NbAnalogIn* NbAnalogIn::handlers[2] = {0}; + NbAnalogIn::NbAnalogIn(){ NVIC_EnableIRQ(ADC_IRQn); + NVIC_SetVector(ADC_IRQn, (uint32_t)irq); + + write_pos = 0; // next position to be written to + read_pos = 0; // next position to be read from + + handlers[0] = this; // put a pointer to this object into the handlers array LPC_SC->PCONP |= (1 << 12); // turn power for ADC on @@ -25,7 +43,8 @@ // select 4, clkdiv = 7, enable, don't start yet LPC_ADC->ADCR = (1 << 4) | (7 << 8) | (1 << 21) | (0 << 24) ; - printf("constructed \n"); + + } @@ -43,9 +62,66 @@ return (unsigned int)((LPC_ADC->ADGDR >> 4) & 0xFFF); } -void NbAnalogIn::readNb(){ +void NbAnalogIn::triggerConv() { /* enable interrupts */ LPC_ADC->ADINTEN = (1 << 4); LPC_ADC->ADCR |= (1 << 24) ; // start conversion +} + +// static interrupt handler +void NbAnalogIn::irq() { + + int adc_result = (int)((LPC_ADC->ADGDR >> 4) & 0xFFF); + uint8_t channel = (uint8_t)((LPC_ADC->ADGDR >> 24) & 0x7); + + /** for debug */// + static int count = 0; + adc_result = count++; + printf("NB! channel %d, result %d \n",channel, adc_result); + + + // call the right channel's handler + handlers[0]->handler(adc_result); + + + /* disable interrupt */ + LPC_ADC->ADINTEN &= ~(1 << channel); +} + +void NbAnalogIn::handler( int adc_result ) { + + + buffer[write_pos] = adc_result; + + printf("ADC: %d written into pos %d \n",adc_result, write_pos); + write_pos = pos_inc( write_pos ); + + // loop around + if( write_pos == read_pos ) { + read_pos = pos_inc( read_pos ); // keep read position ahead of write position + printf("ADC: LOOP AROUND!!! incremented r \n"); + } + printf("ADC: w=%d, r=%d \n", write_pos, read_pos); + + +} + +bool NbAnalogIn::readable() { + return write_pos != read_pos; +} + +int NbAnalogIn::readNb() { + + while(write_pos == read_pos); + + int result = buffer[read_pos]; + + printf("MAIN: read %d from pos %d\n",buffer[read_pos], read_pos ); + + read_pos = pos_inc( read_pos ); // increment reading position + + + + return result; } \ No newline at end of file