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