Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
NbAnalogIn.cpp
- Committer:
- dontknowhow
- Date:
- 2017-04-03
- Revision:
- 2:336af413f75c
- Parent:
- 1:2666729acca1
- Child:
- 3:d4f99bc10643
File content as of revision 2:336af413f75c:
#include "NbAnalogIn.h"
static inline int pos_inc(int i) {
if (i < ADC_BUF_SIZE - 1) {
i++;
} else {
i = 0;
}
return i;
}
static const PinMap PinMap_ADC[] = {
P0_23, ADC0_0, 1,
P0_24, ADC0_1, 1,
P0_25, ADC0_2, 1,
P0_26, ADC0_3, 1,
P1_30, ADC0_4, 3,
P1_31, ADC0_5, 3,
P0_2, ADC0_7, 2,
P0_3, ADC0_6, 2,
NC, NC, 0
};
//set the static handlers array to 0
NbAnalogIn* NbAnalogIn::handlers[ADC_CHANNELS] = {0};
volatile bool NbAnalogIn::converting = false;
NbAnalogIn::NbAnalogIn( PinName pin, void (*irqfunc)() ) {
NVIC_EnableIRQ(ADC_IRQn);
NVIC_SetVector(ADC_IRQn, (uint32_t)irq);
cirq = irqfunc;
channel = (ADCName)pinmap_peripheral(pin, PinMap_ADC);
if (channel == (uint32_t)NC)
error("ADC pin mapping failed");
write_pos = 0; // next position to be written to
read_pos = 0; // next position to be read from
handlers[channel] = this; // put a pointer to this object into the handlers array
LPC_SC->PCONP |= (1 << 12); // turn power for ADC on
// set peripheral clock registers to provide clock for ADC (bits 24 & 25)
// set to 00 for PCLK = CCLK
LPC_SC->PCLKSEL0 &= ~(0x3 << 24); // clear bits
LPC_SC->PCLKSEL0 |= (0x1 << 24); // set bits
//Map pins
pinmap_pinout(pin, PinMap_ADC);
/* set the A/D control register */
// select clkdiv = 7, enable, don't start yet
LPC_ADC->ADCR |= (7 << 8) // set CLKDIV=7 (the fastest)
| (1 << 21) // Power On
| (0 << 24) ; // Don't Start yet
LPC_ADC->ADINTEN |= (1 << 8);
}
int NbAnalogIn::readBl() {
/* disable interrupt */
NVIC_EnableIRQ(ADC_IRQn);
LPC_ADC->ADCR &= ~( 0xff ); // disable all other channels
LPC_ADC->ADCR |= (1 << channel)
| (1 << 24) ; // start conversion
while((LPC_ADC->ADSTAT & (1 << channel)) == 0);
int adc_result = (int)( (LPC_ADC->ADGDR >> 4) & 0xFFF );
NVIC_EnableIRQ(ADC_IRQn);
return adc_result;
}
void NbAnalogIn::triggerConv( bool wait) {
if(wait) {
while(converting);
}
converting = true;
LPC_ADC->ADCR &= ~( 0xff ); // disable all other channels
LPC_ADC->ADCR |= (1 << channel)
| (1 << 24) ; // start conversion
}
// static interrupt handler
void NbAnalogIn::irq() {
int adc_result = (int)((LPC_ADC->ADGDR >> 4) & 0xFFF);
uint8_t adc_channel = (uint8_t)((LPC_ADC->ADGDR >> 24) & 0x7);
converting = false;
/** for debug
static int count = 0;
adc_result = count++;
printf("NbAnalogIn::irq(): channel %d, result %d \n",adc_channel, adc_result);
*/
// call the right channel's handler
handlers[adc_channel]->handler(adc_result);
}
void NbAnalogIn::handler( int adc_result ) {
buffer[write_pos] = adc_result;
//printf("NbAnalogIn::handler(c%d): %d written into pos %d \n", channel,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("NbAnalogIn::handler(c%d): LOOP AROUND!!! incremented r \n", channel);
}
//printf("NbAnalogIn::handler(c%d): w=%d, r=%d \n", channel, write_pos, read_pos);
// call custom irq handler if set
if (cirq)
cirq();
}
bool NbAnalogIn::readable() {
return write_pos != read_pos;
}
int NbAnalogIn::read() {
while(write_pos == read_pos);
int result = buffer[read_pos];
//printf("NbAnalogIn::readNb(c%d): read %d from pos %d\n", channel, buffer[read_pos], read_pos );
read_pos = pos_inc( read_pos ); // increment reading position
return result;
}