FastAnalogIn
Fork of FastAnalogIn by
FastAnalogIn_LPC408X.cpp@7:965a2b0e477f, 2014-04-21 (annotated)
- Committer:
- Sissors
- Date:
- Mon Apr 21 10:26:49 2014 +0000
- Revision:
- 7:965a2b0e477f
- Parent:
- 5:55274430c8df
moved channel_usage to .cpp
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
humlet | 4:cd84739f7640 | 1 | #ifdef TARGET_LPC408X |
humlet | 4:cd84739f7640 | 2 | |
humlet | 4:cd84739f7640 | 3 | #include "FastAnalogIn.h" |
humlet | 4:cd84739f7640 | 4 | |
humlet | 4:cd84739f7640 | 5 | static inline int div_round_up(int x, int y) |
humlet | 4:cd84739f7640 | 6 | { |
humlet | 4:cd84739f7640 | 7 | return (x + (y - 1)) / y; |
humlet | 4:cd84739f7640 | 8 | } |
humlet | 4:cd84739f7640 | 9 | |
humlet | 4:cd84739f7640 | 10 | static const PinMap PinMap_ADC[] = { |
humlet | 4:cd84739f7640 | 11 | {P0_23, ADC0_0, 0x01}, |
humlet | 4:cd84739f7640 | 12 | {P0_24, ADC0_1, 0x01}, |
humlet | 4:cd84739f7640 | 13 | {P0_25, ADC0_2, 0x01}, |
humlet | 4:cd84739f7640 | 14 | {P0_26, ADC0_3, 0x01}, |
humlet | 4:cd84739f7640 | 15 | {P1_30, ADC0_4, 0x03}, |
humlet | 4:cd84739f7640 | 16 | {P1_31, ADC0_5, 0x03}, |
humlet | 4:cd84739f7640 | 17 | {P0_12, ADC0_6, 0x03}, |
humlet | 4:cd84739f7640 | 18 | {P0_13, ADC0_7, 0x03}, |
humlet | 4:cd84739f7640 | 19 | {NC , NC , 0 } |
humlet | 4:cd84739f7640 | 20 | }; |
humlet | 4:cd84739f7640 | 21 | |
Sissors | 7:965a2b0e477f | 22 | static int channel_usage[8] = {0,0,0,0,0,0,0,0}; |
humlet | 4:cd84739f7640 | 23 | |
humlet | 4:cd84739f7640 | 24 | FastAnalogIn::FastAnalogIn(PinName pin, bool enabled) |
humlet | 4:cd84739f7640 | 25 | { |
humlet | 4:cd84739f7640 | 26 | ADCnumber = (ADCName)pinmap_peripheral(pin, PinMap_ADC); |
humlet | 4:cd84739f7640 | 27 | if (ADCnumber == (uint32_t)NC) |
humlet | 4:cd84739f7640 | 28 | error("ADC pin mapping failed"); |
humlet | 4:cd84739f7640 | 29 | datareg = (uint32_t*) (&LPC_ADC->DR[ADCnumber]); |
humlet | 4:cd84739f7640 | 30 | |
humlet | 5:55274430c8df | 31 | wait_us(1000); // wait for a short while before trying to initialize the ADC afer a reset (needed for those global instantiations just before main) |
humlet | 4:cd84739f7640 | 32 | |
humlet | 4:cd84739f7640 | 33 | // ensure power is turned on |
humlet | 4:cd84739f7640 | 34 | LPC_SC->PCONP |= (1 << 12); |
humlet | 4:cd84739f7640 | 35 | |
humlet | 4:cd84739f7640 | 36 | uint32_t PCLK = PeripheralClock; |
humlet | 4:cd84739f7640 | 37 | |
humlet | 4:cd84739f7640 | 38 | // calculate minimum clock divider |
humlet | 4:cd84739f7640 | 39 | // clkdiv = divider - 1 |
humlet | 4:cd84739f7640 | 40 | uint32_t MAX_ADC_CLK = 12400000; |
humlet | 4:cd84739f7640 | 41 | uint32_t clkdiv = div_round_up(PCLK, MAX_ADC_CLK) - 1; |
humlet | 4:cd84739f7640 | 42 | // Set the clkdiv |
humlet | 4:cd84739f7640 | 43 | LPC_ADC->CR &= ~(255<<8); |
humlet | 4:cd84739f7640 | 44 | LPC_ADC->CR |= clkdiv<<8; |
humlet | 4:cd84739f7640 | 45 | |
humlet | 4:cd84739f7640 | 46 | //Enable ADC: |
humlet | 4:cd84739f7640 | 47 | LPC_ADC->CR |= 1<<21; |
humlet | 4:cd84739f7640 | 48 | |
humlet | 4:cd84739f7640 | 49 | //Enable burstmode, set start as zero |
humlet | 4:cd84739f7640 | 50 | LPC_ADC->CR |= 1<<16; |
humlet | 4:cd84739f7640 | 51 | LPC_ADC->CR &= ~(7<<24); |
humlet | 4:cd84739f7640 | 52 | |
humlet | 4:cd84739f7640 | 53 | // must enable analog mode (ADMODE = 0) ... ??? just copied from official LPC408X analogin_api.c |
humlet | 4:cd84739f7640 | 54 | __IO uint32_t *reg = (__IO uint32_t*) (LPC_IOCON_BASE + 4 * pin); |
humlet | 4:cd84739f7640 | 55 | *reg &= ~(1 << 7); |
humlet | 4:cd84739f7640 | 56 | |
humlet | 4:cd84739f7640 | 57 | //Map pins |
humlet | 4:cd84739f7640 | 58 | pinmap_pinout(pin, PinMap_ADC); |
humlet | 4:cd84739f7640 | 59 | |
humlet | 4:cd84739f7640 | 60 | //Enable channel |
humlet | 4:cd84739f7640 | 61 | running = false; |
humlet | 4:cd84739f7640 | 62 | enable(enabled); |
humlet | 4:cd84739f7640 | 63 | |
humlet | 4:cd84739f7640 | 64 | } |
humlet | 4:cd84739f7640 | 65 | |
humlet | 4:cd84739f7640 | 66 | void FastAnalogIn::enable(bool enabled) |
humlet | 4:cd84739f7640 | 67 | { |
humlet | 4:cd84739f7640 | 68 | //If currently not running |
humlet | 4:cd84739f7640 | 69 | if (!running) { |
humlet | 4:cd84739f7640 | 70 | if (enabled) { |
humlet | 4:cd84739f7640 | 71 | //Enable the ADC channel |
humlet | 4:cd84739f7640 | 72 | channel_usage[ADCnumber]++; |
humlet | 4:cd84739f7640 | 73 | LPC_ADC->CR |= (1<<ADCnumber); |
humlet | 4:cd84739f7640 | 74 | running = true; |
humlet | 4:cd84739f7640 | 75 | } else |
humlet | 4:cd84739f7640 | 76 | disable(); |
humlet | 4:cd84739f7640 | 77 | } |
humlet | 4:cd84739f7640 | 78 | } |
humlet | 4:cd84739f7640 | 79 | |
humlet | 4:cd84739f7640 | 80 | void FastAnalogIn::disable( void ) |
humlet | 4:cd84739f7640 | 81 | { |
humlet | 4:cd84739f7640 | 82 | //If currently running |
humlet | 4:cd84739f7640 | 83 | if (running) { |
humlet | 4:cd84739f7640 | 84 | channel_usage[ADCnumber]--; |
humlet | 4:cd84739f7640 | 85 | |
humlet | 4:cd84739f7640 | 86 | if (channel_usage[ADCnumber]==0) |
humlet | 4:cd84739f7640 | 87 | LPC_ADC->CR &= ~(1<<ADCnumber); |
humlet | 4:cd84739f7640 | 88 | } |
humlet | 4:cd84739f7640 | 89 | running = false; |
humlet | 4:cd84739f7640 | 90 | } |
humlet | 4:cd84739f7640 | 91 | |
humlet | 4:cd84739f7640 | 92 | unsigned short FastAnalogIn::read_u16( void ) |
humlet | 4:cd84739f7640 | 93 | { |
humlet | 4:cd84739f7640 | 94 | volatile unsigned int retval; |
humlet | 4:cd84739f7640 | 95 | //If object is enabled return current value of datareg |
humlet | 4:cd84739f7640 | 96 | if (running ){ |
humlet | 4:cd84739f7640 | 97 | retval = *datareg; |
humlet | 4:cd84739f7640 | 98 | //If it isn't running, enable it and wait until new value is written to datareg |
humlet | 4:cd84739f7640 | 99 | }else { |
humlet | 4:cd84739f7640 | 100 | //Force a read to clear done bit, enable the ADC channel |
humlet | 4:cd84739f7640 | 101 | retval = *datareg; |
humlet | 4:cd84739f7640 | 102 | enable(); |
humlet | 4:cd84739f7640 | 103 | //Wait until it is converted |
humlet | 4:cd84739f7640 | 104 | while(1) { |
humlet | 4:cd84739f7640 | 105 | wait_us(1); |
humlet | 4:cd84739f7640 | 106 | retval = *datareg; |
humlet | 4:cd84739f7640 | 107 | if ((retval>>31) == 1) |
humlet | 4:cd84739f7640 | 108 | break; |
humlet | 4:cd84739f7640 | 109 | } |
humlet | 4:cd84739f7640 | 110 | //Do a second conversion since first one always fails for some reason |
humlet | 4:cd84739f7640 | 111 | while(1) { |
humlet | 4:cd84739f7640 | 112 | wait_us(1); |
humlet | 4:cd84739f7640 | 113 | retval = *datareg; |
humlet | 4:cd84739f7640 | 114 | if ((retval>>31) == 1) |
humlet | 4:cd84739f7640 | 115 | break; |
humlet | 4:cd84739f7640 | 116 | } |
humlet | 4:cd84739f7640 | 117 | //Disable again |
humlet | 4:cd84739f7640 | 118 | disable(); |
humlet | 4:cd84739f7640 | 119 | } |
humlet | 4:cd84739f7640 | 120 | |
humlet | 4:cd84739f7640 | 121 | //Do same thing as standard mbed lib, unused bit 0-3, replicate 4-7 in it |
humlet | 4:cd84739f7640 | 122 | retval &= ~0xFFFF000F; |
humlet | 4:cd84739f7640 | 123 | retval |= (retval >> 8) & 0x000F; |
humlet | 4:cd84739f7640 | 124 | return retval; |
humlet | 4:cd84739f7640 | 125 | |
humlet | 4:cd84739f7640 | 126 | } |
humlet | 4:cd84739f7640 | 127 | #endif //defined TARGET_LPC408X |
Sissors | 7:965a2b0e477f | 128 |