Fast AnalogIn module which asks for a single non blocking reading and causes and interrupt when done.

Committer:
dontknowhow
Date:
Mon Apr 03 10:59:17 2017 +0000
Revision:
2:336af413f75c
Parent:
1:2666729acca1
Child:
3:d4f99bc10643
Multiple channels, custom interrupt;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dontknowhow 0:058d32b78e5d 1 #include "NbAnalogIn.h"
dontknowhow 0:058d32b78e5d 2
dontknowhow 1:2666729acca1 3 static inline int pos_inc(int i) {
dontknowhow 1:2666729acca1 4
dontknowhow 1:2666729acca1 5 if (i < ADC_BUF_SIZE - 1) {
dontknowhow 1:2666729acca1 6 i++;
dontknowhow 1:2666729acca1 7 } else {
dontknowhow 1:2666729acca1 8 i = 0;
dontknowhow 1:2666729acca1 9 }
dontknowhow 1:2666729acca1 10 return i;
dontknowhow 1:2666729acca1 11 }
dontknowhow 1:2666729acca1 12
dontknowhow 2:336af413f75c 13 static const PinMap PinMap_ADC[] = {
dontknowhow 2:336af413f75c 14 P0_23, ADC0_0, 1,
dontknowhow 2:336af413f75c 15 P0_24, ADC0_1, 1,
dontknowhow 2:336af413f75c 16 P0_25, ADC0_2, 1,
dontknowhow 2:336af413f75c 17 P0_26, ADC0_3, 1,
dontknowhow 2:336af413f75c 18 P1_30, ADC0_4, 3,
dontknowhow 2:336af413f75c 19 P1_31, ADC0_5, 3,
dontknowhow 2:336af413f75c 20 P0_2, ADC0_7, 2,
dontknowhow 2:336af413f75c 21 P0_3, ADC0_6, 2,
dontknowhow 2:336af413f75c 22 NC, NC, 0
dontknowhow 2:336af413f75c 23 };
dontknowhow 1:2666729acca1 24
dontknowhow 2:336af413f75c 25 //set the static handlers array to 0
dontknowhow 2:336af413f75c 26 NbAnalogIn* NbAnalogIn::handlers[ADC_CHANNELS] = {0};
dontknowhow 2:336af413f75c 27 volatile bool NbAnalogIn::converting = false;
dontknowhow 2:336af413f75c 28
dontknowhow 2:336af413f75c 29 NbAnalogIn::NbAnalogIn( PinName pin, void (*irqfunc)() ) {
dontknowhow 0:058d32b78e5d 30
dontknowhow 0:058d32b78e5d 31 NVIC_EnableIRQ(ADC_IRQn);
dontknowhow 1:2666729acca1 32 NVIC_SetVector(ADC_IRQn, (uint32_t)irq);
dontknowhow 1:2666729acca1 33
dontknowhow 2:336af413f75c 34 cirq = irqfunc;
dontknowhow 2:336af413f75c 35
dontknowhow 2:336af413f75c 36 channel = (ADCName)pinmap_peripheral(pin, PinMap_ADC);
dontknowhow 2:336af413f75c 37 if (channel == (uint32_t)NC)
dontknowhow 2:336af413f75c 38 error("ADC pin mapping failed");
dontknowhow 2:336af413f75c 39
dontknowhow 2:336af413f75c 40
dontknowhow 1:2666729acca1 41 write_pos = 0; // next position to be written to
dontknowhow 1:2666729acca1 42 read_pos = 0; // next position to be read from
dontknowhow 1:2666729acca1 43
dontknowhow 2:336af413f75c 44 handlers[channel] = this; // put a pointer to this object into the handlers array
dontknowhow 0:058d32b78e5d 45
dontknowhow 0:058d32b78e5d 46 LPC_SC->PCONP |= (1 << 12); // turn power for ADC on
dontknowhow 0:058d32b78e5d 47
dontknowhow 2:336af413f75c 48
dontknowhow 0:058d32b78e5d 49 // set peripheral clock registers to provide clock for ADC (bits 24 & 25)
dontknowhow 0:058d32b78e5d 50 // set to 00 for PCLK = CCLK
dontknowhow 0:058d32b78e5d 51 LPC_SC->PCLKSEL0 &= ~(0x3 << 24); // clear bits
dontknowhow 0:058d32b78e5d 52 LPC_SC->PCLKSEL0 |= (0x1 << 24); // set bits
dontknowhow 2:336af413f75c 53
dontknowhow 0:058d32b78e5d 54
dontknowhow 2:336af413f75c 55 //Map pins
dontknowhow 2:336af413f75c 56 pinmap_pinout(pin, PinMap_ADC);
dontknowhow 0:058d32b78e5d 57
dontknowhow 0:058d32b78e5d 58 /* set the A/D control register */
dontknowhow 0:058d32b78e5d 59
dontknowhow 2:336af413f75c 60 // select clkdiv = 7, enable, don't start yet
dontknowhow 2:336af413f75c 61 LPC_ADC->ADCR |= (7 << 8) // set CLKDIV=7 (the fastest)
dontknowhow 2:336af413f75c 62 | (1 << 21) // Power On
dontknowhow 2:336af413f75c 63 | (0 << 24) ; // Don't Start yet
dontknowhow 2:336af413f75c 64
dontknowhow 2:336af413f75c 65 LPC_ADC->ADINTEN |= (1 << 8);
dontknowhow 0:058d32b78e5d 66 }
dontknowhow 0:058d32b78e5d 67
dontknowhow 0:058d32b78e5d 68
dontknowhow 2:336af413f75c 69 int NbAnalogIn::readBl() {
dontknowhow 0:058d32b78e5d 70
dontknowhow 2:336af413f75c 71 /* disable interrupt */
dontknowhow 2:336af413f75c 72 NVIC_EnableIRQ(ADC_IRQn);
dontknowhow 0:058d32b78e5d 73
dontknowhow 2:336af413f75c 74 LPC_ADC->ADCR &= ~( 0xff ); // disable all other channels
dontknowhow 2:336af413f75c 75 LPC_ADC->ADCR |= (1 << channel)
dontknowhow 2:336af413f75c 76 | (1 << 24) ; // start conversion
dontknowhow 2:336af413f75c 77
dontknowhow 0:058d32b78e5d 78
dontknowhow 2:336af413f75c 79 while((LPC_ADC->ADSTAT & (1 << channel)) == 0);
dontknowhow 0:058d32b78e5d 80
dontknowhow 2:336af413f75c 81 int adc_result = (int)( (LPC_ADC->ADGDR >> 4) & 0xFFF );
dontknowhow 2:336af413f75c 82
dontknowhow 2:336af413f75c 83 NVIC_EnableIRQ(ADC_IRQn);
dontknowhow 2:336af413f75c 84 return adc_result;
dontknowhow 0:058d32b78e5d 85 }
dontknowhow 0:058d32b78e5d 86
dontknowhow 2:336af413f75c 87 void NbAnalogIn::triggerConv( bool wait) {
dontknowhow 2:336af413f75c 88
dontknowhow 2:336af413f75c 89 if(wait) {
dontknowhow 2:336af413f75c 90 while(converting);
dontknowhow 2:336af413f75c 91 }
dontknowhow 0:058d32b78e5d 92
dontknowhow 2:336af413f75c 93 converting = true;
dontknowhow 2:336af413f75c 94 LPC_ADC->ADCR &= ~( 0xff ); // disable all other channels
dontknowhow 2:336af413f75c 95 LPC_ADC->ADCR |= (1 << channel)
dontknowhow 2:336af413f75c 96 | (1 << 24) ; // start conversion
dontknowhow 2:336af413f75c 97
dontknowhow 2:336af413f75c 98
dontknowhow 1:2666729acca1 99 }
dontknowhow 1:2666729acca1 100
dontknowhow 1:2666729acca1 101 // static interrupt handler
dontknowhow 1:2666729acca1 102 void NbAnalogIn::irq() {
dontknowhow 1:2666729acca1 103
dontknowhow 2:336af413f75c 104
dontknowhow 1:2666729acca1 105 int adc_result = (int)((LPC_ADC->ADGDR >> 4) & 0xFFF);
dontknowhow 2:336af413f75c 106 uint8_t adc_channel = (uint8_t)((LPC_ADC->ADGDR >> 24) & 0x7);
dontknowhow 1:2666729acca1 107
dontknowhow 2:336af413f75c 108 converting = false;
dontknowhow 2:336af413f75c 109
dontknowhow 2:336af413f75c 110 /** for debug
dontknowhow 1:2666729acca1 111 static int count = 0;
dontknowhow 1:2666729acca1 112 adc_result = count++;
dontknowhow 2:336af413f75c 113 printf("NbAnalogIn::irq(): channel %d, result %d \n",adc_channel, adc_result);
dontknowhow 2:336af413f75c 114 */
dontknowhow 1:2666729acca1 115
dontknowhow 1:2666729acca1 116 // call the right channel's handler
dontknowhow 2:336af413f75c 117 handlers[adc_channel]->handler(adc_result);
dontknowhow 1:2666729acca1 118
dontknowhow 1:2666729acca1 119 }
dontknowhow 1:2666729acca1 120
dontknowhow 1:2666729acca1 121 void NbAnalogIn::handler( int adc_result ) {
dontknowhow 1:2666729acca1 122
dontknowhow 1:2666729acca1 123
dontknowhow 1:2666729acca1 124 buffer[write_pos] = adc_result;
dontknowhow 1:2666729acca1 125
dontknowhow 2:336af413f75c 126 //printf("NbAnalogIn::handler(c%d): %d written into pos %d \n", channel,adc_result, write_pos);
dontknowhow 1:2666729acca1 127 write_pos = pos_inc( write_pos );
dontknowhow 1:2666729acca1 128
dontknowhow 1:2666729acca1 129 // loop around
dontknowhow 1:2666729acca1 130 if( write_pos == read_pos ) {
dontknowhow 1:2666729acca1 131 read_pos = pos_inc( read_pos ); // keep read position ahead of write position
dontknowhow 2:336af413f75c 132 //printf("NbAnalogIn::handler(c%d): LOOP AROUND!!! incremented r \n", channel);
dontknowhow 1:2666729acca1 133 }
dontknowhow 2:336af413f75c 134 //printf("NbAnalogIn::handler(c%d): w=%d, r=%d \n", channel, write_pos, read_pos);
dontknowhow 1:2666729acca1 135
dontknowhow 2:336af413f75c 136 // call custom irq handler if set
dontknowhow 2:336af413f75c 137 if (cirq)
dontknowhow 2:336af413f75c 138 cirq();
dontknowhow 1:2666729acca1 139 }
dontknowhow 1:2666729acca1 140
dontknowhow 1:2666729acca1 141 bool NbAnalogIn::readable() {
dontknowhow 1:2666729acca1 142 return write_pos != read_pos;
dontknowhow 1:2666729acca1 143 }
dontknowhow 1:2666729acca1 144
dontknowhow 2:336af413f75c 145 int NbAnalogIn::read() {
dontknowhow 1:2666729acca1 146
dontknowhow 1:2666729acca1 147 while(write_pos == read_pos);
dontknowhow 1:2666729acca1 148
dontknowhow 1:2666729acca1 149 int result = buffer[read_pos];
dontknowhow 1:2666729acca1 150
dontknowhow 2:336af413f75c 151 //printf("NbAnalogIn::readNb(c%d): read %d from pos %d\n", channel, buffer[read_pos], read_pos );
dontknowhow 1:2666729acca1 152
dontknowhow 1:2666729acca1 153 read_pos = pos_inc( read_pos ); // increment reading position
dontknowhow 1:2666729acca1 154
dontknowhow 1:2666729acca1 155 return result;
dontknowhow 0:058d32b78e5d 156 }