Fast AnalogIn module which asks for a single non blocking reading and causes and interrupt when done.
NbAnalogIn.cpp@1:2666729acca1, 2017-04-02 (annotated)
- Committer:
- dontknowhow
- Date:
- Sun Apr 02 11:16:24 2017 +0000
- Revision:
- 1:2666729acca1
- Parent:
- 0:058d32b78e5d
- Child:
- 2:336af413f75c
IRQ handlers in class
Who changed what in which revision?
User | Revision | Line number | New 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 | 1:2666729acca1 | 13 | NbAnalogIn* NbAnalogIn::handlers[2] = {0}; |
dontknowhow | 1:2666729acca1 | 14 | |
dontknowhow | 0:058d32b78e5d | 15 | NbAnalogIn::NbAnalogIn(){ |
dontknowhow | 0:058d32b78e5d | 16 | |
dontknowhow | 0:058d32b78e5d | 17 | NVIC_EnableIRQ(ADC_IRQn); |
dontknowhow | 1:2666729acca1 | 18 | NVIC_SetVector(ADC_IRQn, (uint32_t)irq); |
dontknowhow | 1:2666729acca1 | 19 | |
dontknowhow | 1:2666729acca1 | 20 | write_pos = 0; // next position to be written to |
dontknowhow | 1:2666729acca1 | 21 | read_pos = 0; // next position to be read from |
dontknowhow | 1:2666729acca1 | 22 | |
dontknowhow | 1:2666729acca1 | 23 | handlers[0] = this; // put a pointer to this object into the handlers array |
dontknowhow | 0:058d32b78e5d | 24 | |
dontknowhow | 0:058d32b78e5d | 25 | LPC_SC->PCONP |= (1 << 12); // turn power for ADC on |
dontknowhow | 0:058d32b78e5d | 26 | |
dontknowhow | 0:058d32b78e5d | 27 | // set peripheral clock registers to provide clock for ADC (bits 24 & 25) |
dontknowhow | 0:058d32b78e5d | 28 | // set to 00 for PCLK = CCLK |
dontknowhow | 0:058d32b78e5d | 29 | LPC_SC->PCLKSEL0 &= ~(0x3 << 24); // clear bits |
dontknowhow | 0:058d32b78e5d | 30 | LPC_SC->PCLKSEL0 |= (0x1 << 24); // set bits |
dontknowhow | 0:058d32b78e5d | 31 | |
dontknowhow | 0:058d32b78e5d | 32 | //set P1.30 as AD0.4 |
dontknowhow | 0:058d32b78e5d | 33 | LPC_PINCON->PINSEL3 |= (3<<28); |
dontknowhow | 0:058d32b78e5d | 34 | |
dontknowhow | 0:058d32b78e5d | 35 | |
dontknowhow | 0:058d32b78e5d | 36 | //Set PINMODE of AD0.4 as no pull-up/down resistors |
dontknowhow | 0:058d32b78e5d | 37 | LPC_PINCON->PINMODE3 &= ~(3<<28); |
dontknowhow | 0:058d32b78e5d | 38 | LPC_PINCON->PINMODE3 |= (2<<28); |
dontknowhow | 0:058d32b78e5d | 39 | |
dontknowhow | 0:058d32b78e5d | 40 | |
dontknowhow | 0:058d32b78e5d | 41 | /* set the A/D control register */ |
dontknowhow | 0:058d32b78e5d | 42 | |
dontknowhow | 0:058d32b78e5d | 43 | // select 4, clkdiv = 7, enable, don't start yet |
dontknowhow | 0:058d32b78e5d | 44 | LPC_ADC->ADCR = (1 << 4) | (7 << 8) | (1 << 21) | (0 << 24) ; |
dontknowhow | 0:058d32b78e5d | 45 | |
dontknowhow | 1:2666729acca1 | 46 | |
dontknowhow | 1:2666729acca1 | 47 | |
dontknowhow | 0:058d32b78e5d | 48 | |
dontknowhow | 0:058d32b78e5d | 49 | } |
dontknowhow | 0:058d32b78e5d | 50 | |
dontknowhow | 0:058d32b78e5d | 51 | |
dontknowhow | 0:058d32b78e5d | 52 | unsigned int NbAnalogIn::read() { |
dontknowhow | 0:058d32b78e5d | 53 | |
dontknowhow | 0:058d32b78e5d | 54 | /* disable interrupts */ |
dontknowhow | 0:058d32b78e5d | 55 | LPC_ADC->ADINTEN &= ~(1 << 4); |
dontknowhow | 0:058d32b78e5d | 56 | LPC_ADC->ADINTEN = 0; |
dontknowhow | 0:058d32b78e5d | 57 | |
dontknowhow | 0:058d32b78e5d | 58 | LPC_ADC->ADCR |= (1 << 24) ; // start conversion |
dontknowhow | 0:058d32b78e5d | 59 | |
dontknowhow | 0:058d32b78e5d | 60 | while((LPC_ADC->ADSTAT & (1<<4)) == 0); |
dontknowhow | 0:058d32b78e5d | 61 | |
dontknowhow | 0:058d32b78e5d | 62 | return (unsigned int)((LPC_ADC->ADGDR >> 4) & 0xFFF); |
dontknowhow | 0:058d32b78e5d | 63 | } |
dontknowhow | 0:058d32b78e5d | 64 | |
dontknowhow | 1:2666729acca1 | 65 | void NbAnalogIn::triggerConv() { |
dontknowhow | 0:058d32b78e5d | 66 | /* enable interrupts */ |
dontknowhow | 0:058d32b78e5d | 67 | LPC_ADC->ADINTEN = (1 << 4); |
dontknowhow | 0:058d32b78e5d | 68 | |
dontknowhow | 0:058d32b78e5d | 69 | LPC_ADC->ADCR |= (1 << 24) ; // start conversion |
dontknowhow | 1:2666729acca1 | 70 | } |
dontknowhow | 1:2666729acca1 | 71 | |
dontknowhow | 1:2666729acca1 | 72 | // static interrupt handler |
dontknowhow | 1:2666729acca1 | 73 | void NbAnalogIn::irq() { |
dontknowhow | 1:2666729acca1 | 74 | |
dontknowhow | 1:2666729acca1 | 75 | int adc_result = (int)((LPC_ADC->ADGDR >> 4) & 0xFFF); |
dontknowhow | 1:2666729acca1 | 76 | uint8_t channel = (uint8_t)((LPC_ADC->ADGDR >> 24) & 0x7); |
dontknowhow | 1:2666729acca1 | 77 | |
dontknowhow | 1:2666729acca1 | 78 | /** for debug */// |
dontknowhow | 1:2666729acca1 | 79 | static int count = 0; |
dontknowhow | 1:2666729acca1 | 80 | adc_result = count++; |
dontknowhow | 1:2666729acca1 | 81 | printf("NB! channel %d, result %d \n",channel, adc_result); |
dontknowhow | 1:2666729acca1 | 82 | |
dontknowhow | 1:2666729acca1 | 83 | |
dontknowhow | 1:2666729acca1 | 84 | // call the right channel's handler |
dontknowhow | 1:2666729acca1 | 85 | handlers[0]->handler(adc_result); |
dontknowhow | 1:2666729acca1 | 86 | |
dontknowhow | 1:2666729acca1 | 87 | |
dontknowhow | 1:2666729acca1 | 88 | /* disable interrupt */ |
dontknowhow | 1:2666729acca1 | 89 | LPC_ADC->ADINTEN &= ~(1 << channel); |
dontknowhow | 1:2666729acca1 | 90 | } |
dontknowhow | 1:2666729acca1 | 91 | |
dontknowhow | 1:2666729acca1 | 92 | void NbAnalogIn::handler( int adc_result ) { |
dontknowhow | 1:2666729acca1 | 93 | |
dontknowhow | 1:2666729acca1 | 94 | |
dontknowhow | 1:2666729acca1 | 95 | buffer[write_pos] = adc_result; |
dontknowhow | 1:2666729acca1 | 96 | |
dontknowhow | 1:2666729acca1 | 97 | printf("ADC: %d written into pos %d \n",adc_result, write_pos); |
dontknowhow | 1:2666729acca1 | 98 | write_pos = pos_inc( write_pos ); |
dontknowhow | 1:2666729acca1 | 99 | |
dontknowhow | 1:2666729acca1 | 100 | // loop around |
dontknowhow | 1:2666729acca1 | 101 | if( write_pos == read_pos ) { |
dontknowhow | 1:2666729acca1 | 102 | read_pos = pos_inc( read_pos ); // keep read position ahead of write position |
dontknowhow | 1:2666729acca1 | 103 | printf("ADC: LOOP AROUND!!! incremented r \n"); |
dontknowhow | 1:2666729acca1 | 104 | } |
dontknowhow | 1:2666729acca1 | 105 | printf("ADC: w=%d, r=%d \n", write_pos, read_pos); |
dontknowhow | 1:2666729acca1 | 106 | |
dontknowhow | 1:2666729acca1 | 107 | |
dontknowhow | 1:2666729acca1 | 108 | } |
dontknowhow | 1:2666729acca1 | 109 | |
dontknowhow | 1:2666729acca1 | 110 | bool NbAnalogIn::readable() { |
dontknowhow | 1:2666729acca1 | 111 | return write_pos != read_pos; |
dontknowhow | 1:2666729acca1 | 112 | } |
dontknowhow | 1:2666729acca1 | 113 | |
dontknowhow | 1:2666729acca1 | 114 | int NbAnalogIn::readNb() { |
dontknowhow | 1:2666729acca1 | 115 | |
dontknowhow | 1:2666729acca1 | 116 | while(write_pos == read_pos); |
dontknowhow | 1:2666729acca1 | 117 | |
dontknowhow | 1:2666729acca1 | 118 | int result = buffer[read_pos]; |
dontknowhow | 1:2666729acca1 | 119 | |
dontknowhow | 1:2666729acca1 | 120 | printf("MAIN: read %d from pos %d\n",buffer[read_pos], read_pos ); |
dontknowhow | 1:2666729acca1 | 121 | |
dontknowhow | 1:2666729acca1 | 122 | read_pos = pos_inc( read_pos ); // increment reading position |
dontknowhow | 1:2666729acca1 | 123 | |
dontknowhow | 1:2666729acca1 | 124 | |
dontknowhow | 1:2666729acca1 | 125 | |
dontknowhow | 1:2666729acca1 | 126 | return result; |
dontknowhow | 0:058d32b78e5d | 127 | } |