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

Committer:
dontknowhow
Date:
Tue Apr 04 22:35:34 2017 +0000
Revision:
3:d4f99bc10643
Parent:
2:336af413f75c
set interrupt priority;

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 3:d4f99bc10643 29 NbAnalogIn::NbAnalogIn( PinName pin) {
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 3:d4f99bc10643 34
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 3:d4f99bc10643 68 void NbAnalogIn::setInterrupt(void (*irqfunc)() , int prio) {
dontknowhow 3:d4f99bc10643 69 cirq = irqfunc;
dontknowhow 3:d4f99bc10643 70
dontknowhow 3:d4f99bc10643 71 if( prio >=0 && prio <=32 ) {
dontknowhow 3:d4f99bc10643 72 NVIC_SetPriority(ADC_IRQn, prio); //set priority of these interrupts
dontknowhow 3:d4f99bc10643 73 }
dontknowhow 3:d4f99bc10643 74 }
dontknowhow 0:058d32b78e5d 75
dontknowhow 2:336af413f75c 76 int NbAnalogIn::readBl() {
dontknowhow 0:058d32b78e5d 77
dontknowhow 2:336af413f75c 78 /* disable interrupt */
dontknowhow 2:336af413f75c 79 NVIC_EnableIRQ(ADC_IRQn);
dontknowhow 0:058d32b78e5d 80
dontknowhow 2:336af413f75c 81 LPC_ADC->ADCR &= ~( 0xff ); // disable all other channels
dontknowhow 2:336af413f75c 82 LPC_ADC->ADCR |= (1 << channel)
dontknowhow 2:336af413f75c 83 | (1 << 24) ; // start conversion
dontknowhow 2:336af413f75c 84
dontknowhow 0:058d32b78e5d 85
dontknowhow 2:336af413f75c 86 while((LPC_ADC->ADSTAT & (1 << channel)) == 0);
dontknowhow 0:058d32b78e5d 87
dontknowhow 2:336af413f75c 88 int adc_result = (int)( (LPC_ADC->ADGDR >> 4) & 0xFFF );
dontknowhow 2:336af413f75c 89
dontknowhow 2:336af413f75c 90 NVIC_EnableIRQ(ADC_IRQn);
dontknowhow 2:336af413f75c 91 return adc_result;
dontknowhow 0:058d32b78e5d 92 }
dontknowhow 0:058d32b78e5d 93
dontknowhow 2:336af413f75c 94 void NbAnalogIn::triggerConv( bool wait) {
dontknowhow 2:336af413f75c 95
dontknowhow 2:336af413f75c 96 if(wait) {
dontknowhow 2:336af413f75c 97 while(converting);
dontknowhow 2:336af413f75c 98 }
dontknowhow 0:058d32b78e5d 99
dontknowhow 2:336af413f75c 100 converting = true;
dontknowhow 2:336af413f75c 101 LPC_ADC->ADCR &= ~( 0xff ); // disable all other channels
dontknowhow 2:336af413f75c 102 LPC_ADC->ADCR |= (1 << channel)
dontknowhow 2:336af413f75c 103 | (1 << 24) ; // start conversion
dontknowhow 2:336af413f75c 104
dontknowhow 2:336af413f75c 105
dontknowhow 1:2666729acca1 106 }
dontknowhow 1:2666729acca1 107
dontknowhow 1:2666729acca1 108 // static interrupt handler
dontknowhow 1:2666729acca1 109 void NbAnalogIn::irq() {
dontknowhow 1:2666729acca1 110
dontknowhow 2:336af413f75c 111
dontknowhow 1:2666729acca1 112 int adc_result = (int)((LPC_ADC->ADGDR >> 4) & 0xFFF);
dontknowhow 2:336af413f75c 113 uint8_t adc_channel = (uint8_t)((LPC_ADC->ADGDR >> 24) & 0x7);
dontknowhow 1:2666729acca1 114
dontknowhow 2:336af413f75c 115 converting = false;
dontknowhow 2:336af413f75c 116
dontknowhow 2:336af413f75c 117 /** for debug
dontknowhow 1:2666729acca1 118 static int count = 0;
dontknowhow 1:2666729acca1 119 adc_result = count++;
dontknowhow 2:336af413f75c 120 printf("NbAnalogIn::irq(): channel %d, result %d \n",adc_channel, adc_result);
dontknowhow 2:336af413f75c 121 */
dontknowhow 1:2666729acca1 122
dontknowhow 1:2666729acca1 123 // call the right channel's handler
dontknowhow 2:336af413f75c 124 handlers[adc_channel]->handler(adc_result);
dontknowhow 1:2666729acca1 125
dontknowhow 1:2666729acca1 126 }
dontknowhow 1:2666729acca1 127
dontknowhow 1:2666729acca1 128 void NbAnalogIn::handler( int adc_result ) {
dontknowhow 1:2666729acca1 129
dontknowhow 1:2666729acca1 130
dontknowhow 1:2666729acca1 131 buffer[write_pos] = adc_result;
dontknowhow 1:2666729acca1 132
dontknowhow 2:336af413f75c 133 //printf("NbAnalogIn::handler(c%d): %d written into pos %d \n", channel,adc_result, write_pos);
dontknowhow 1:2666729acca1 134 write_pos = pos_inc( write_pos );
dontknowhow 1:2666729acca1 135
dontknowhow 1:2666729acca1 136 // loop around
dontknowhow 1:2666729acca1 137 if( write_pos == read_pos ) {
dontknowhow 1:2666729acca1 138 read_pos = pos_inc( read_pos ); // keep read position ahead of write position
dontknowhow 2:336af413f75c 139 //printf("NbAnalogIn::handler(c%d): LOOP AROUND!!! incremented r \n", channel);
dontknowhow 1:2666729acca1 140 }
dontknowhow 2:336af413f75c 141 //printf("NbAnalogIn::handler(c%d): w=%d, r=%d \n", channel, write_pos, read_pos);
dontknowhow 1:2666729acca1 142
dontknowhow 2:336af413f75c 143 // call custom irq handler if set
dontknowhow 2:336af413f75c 144 if (cirq)
dontknowhow 2:336af413f75c 145 cirq();
dontknowhow 1:2666729acca1 146 }
dontknowhow 1:2666729acca1 147
dontknowhow 1:2666729acca1 148 bool NbAnalogIn::readable() {
dontknowhow 1:2666729acca1 149 return write_pos != read_pos;
dontknowhow 1:2666729acca1 150 }
dontknowhow 1:2666729acca1 151
dontknowhow 2:336af413f75c 152 int NbAnalogIn::read() {
dontknowhow 1:2666729acca1 153
dontknowhow 1:2666729acca1 154 while(write_pos == read_pos);
dontknowhow 1:2666729acca1 155
dontknowhow 1:2666729acca1 156 int result = buffer[read_pos];
dontknowhow 1:2666729acca1 157
dontknowhow 2:336af413f75c 158 //printf("NbAnalogIn::readNb(c%d): read %d from pos %d\n", channel, buffer[read_pos], read_pos );
dontknowhow 1:2666729acca1 159
dontknowhow 1:2666729acca1 160 read_pos = pos_inc( read_pos ); // increment reading position
dontknowhow 1:2666729acca1 161
dontknowhow 1:2666729acca1 162 return result;
dontknowhow 0:058d32b78e5d 163 }