Clark Lin
/
BX-car_s
QQQ
Fork of BX-car_s by
bx-adc.cpp@23:d6d4e8adf7fe, 2014-07-02 (annotated)
- Committer:
- physicsgood
- Date:
- Wed Jul 02 13:33:49 2014 +0000
- Revision:
- 23:d6d4e8adf7fe
- Parent:
- 1:82bc25a7b68b
QQQQ
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
backman | 1:82bc25a7b68b | 1 | #include "bx-adc.h" |
backman | 1:82bc25a7b68b | 2 | #include "clk_freqs.h" |
backman | 1:82bc25a7b68b | 3 | |
backman | 1:82bc25a7b68b | 4 | #define MAX_FADC 6000000 |
backman | 1:82bc25a7b68b | 5 | #define CHANNELS_A_SHIFT 5 |
backman | 1:82bc25a7b68b | 6 | |
backman | 1:82bc25a7b68b | 7 | FastAnalogIn::FastAnalogIn(PinName pin, bool enabled) |
backman | 1:82bc25a7b68b | 8 | { |
backman | 1:82bc25a7b68b | 9 | ADCnumber = (ADCName)pinmap_peripheral(pin, PinMap_ADC); |
backman | 1:82bc25a7b68b | 10 | if (ADCnumber == (ADCName)NC) { |
backman | 1:82bc25a7b68b | 11 | error("ADC pin mapping failed"); |
backman | 1:82bc25a7b68b | 12 | } |
backman | 1:82bc25a7b68b | 13 | |
backman | 1:82bc25a7b68b | 14 | SIM->SCGC6 |= SIM_SCGC6_ADC0_MASK; |
backman | 1:82bc25a7b68b | 15 | //----------------------------------------------------- |
backman | 1:82bc25a7b68b | 16 | uint32_t port = (uint32_t)pin >> PORT_SHIFT; |
backman | 1:82bc25a7b68b | 17 | SIM->SCGC5 |= 1 << (SIM_SCGC5_PORTA_SHIFT + port); |
backman | 1:82bc25a7b68b | 18 | |
backman | 1:82bc25a7b68b | 19 | uint32_t cfg2_muxsel = ADC_CFG2_MUXSEL_MASK; |
backman | 1:82bc25a7b68b | 20 | if (ADCnumber & (1 << CHANNELS_A_SHIFT)) { |
backman | 1:82bc25a7b68b | 21 | cfg2_muxsel = 0; |
backman | 1:82bc25a7b68b | 22 | } |
backman | 1:82bc25a7b68b | 23 | //------------------------------------------------------ |
backman | 1:82bc25a7b68b | 24 | // bus clk |
backman | 1:82bc25a7b68b | 25 | uint32_t PCLK = bus_frequency(); |
backman | 1:82bc25a7b68b | 26 | uint32_t clkdiv; |
backman | 1:82bc25a7b68b | 27 | for (clkdiv = 0; clkdiv < 4; clkdiv++) { |
backman | 1:82bc25a7b68b | 28 | if ((PCLK >> clkdiv) <= MAX_FADC) |
backman | 1:82bc25a7b68b | 29 | break; |
backman | 1:82bc25a7b68b | 30 | } |
backman | 1:82bc25a7b68b | 31 | if (clkdiv == 4) //Set max div |
backman | 1:82bc25a7b68b | 32 | clkdiv = 0x7; |
backman | 1:82bc25a7b68b | 33 | |
backman | 1:82bc25a7b68b | 34 | ADC0->SC1[1] = ADC_SC1_ADCH(ADCnumber & ~(1 << CHANNELS_A_SHIFT)); |
backman | 1:82bc25a7b68b | 35 | |
backman | 1:82bc25a7b68b | 36 | ADC0->CFG1 = ADC_CFG1_ADIV(clkdiv & 0x3) // Clock Divide Select: (Input Clock)/8 |
backman | 1:82bc25a7b68b | 37 | | ADC_CFG1_MODE(3) // (16)bits Resolution |
backman | 1:82bc25a7b68b | 38 | | ADC_CFG1_ADICLK(clkdiv >> 2); // Input Clock: (Bus Clock)/2 |
backman | 1:82bc25a7b68b | 39 | |
backman | 1:82bc25a7b68b | 40 | ADC0->CFG2 = cfg2_muxsel // ADxxb or ADxxa channels |
backman | 1:82bc25a7b68b | 41 | | ADC_CFG2_ADACKEN_MASK // Asynchronous Clock Output Enable |
backman | 1:82bc25a7b68b | 42 | | ADC_CFG2_ADHSC_MASK; // High-Speed Configuration |
backman | 1:82bc25a7b68b | 43 | |
backman | 1:82bc25a7b68b | 44 | ADC0->SC2 = ADC_SC2_REFSEL(0); // Default Voltage Reference |
backman | 1:82bc25a7b68b | 45 | |
backman | 1:82bc25a7b68b | 46 | pinmap_pinout(pin, PinMap_ADC); |
backman | 1:82bc25a7b68b | 47 | |
backman | 1:82bc25a7b68b | 48 | //Enable channel |
backman | 1:82bc25a7b68b | 49 | running = false; |
backman | 1:82bc25a7b68b | 50 | enable(enabled); |
backman | 1:82bc25a7b68b | 51 | } |
backman | 1:82bc25a7b68b | 52 | |
backman | 1:82bc25a7b68b | 53 | void FastAnalogIn::enable(bool enabled) |
backman | 1:82bc25a7b68b | 54 | { |
backman | 1:82bc25a7b68b | 55 | //If currently not running |
backman | 1:82bc25a7b68b | 56 | if (!running) { |
backman | 1:82bc25a7b68b | 57 | if (enabled) { |
backman | 1:82bc25a7b68b | 58 | //Enable the ADC channel |
backman | 1:82bc25a7b68b | 59 | ADC0->SC3 |= ADC_SC3_ADCO_MASK; // Enable continuous conversion |
backman | 1:82bc25a7b68b | 60 | ADC0->SC1[0] = ADC_SC1_ADCH(ADCnumber & ~(1 << CHANNELS_A_SHIFT)); //Start conversion |
backman | 1:82bc25a7b68b | 61 | running = true; |
backman | 1:82bc25a7b68b | 62 | } else |
backman | 1:82bc25a7b68b | 63 | disable(); |
backman | 1:82bc25a7b68b | 64 | } |
backman | 1:82bc25a7b68b | 65 | } |
backman | 1:82bc25a7b68b | 66 | |
backman | 1:82bc25a7b68b | 67 | void FastAnalogIn::disable( void ) |
backman | 1:82bc25a7b68b | 68 | { |
backman | 1:82bc25a7b68b | 69 | //If currently running |
backman | 1:82bc25a7b68b | 70 | if (running) { |
backman | 1:82bc25a7b68b | 71 | ADC0->SC3 &= ~ADC_SC3_ADCO_MASK; // Disable continuous conversion |
backman | 1:82bc25a7b68b | 72 | } |
backman | 1:82bc25a7b68b | 73 | running = false; |
backman | 1:82bc25a7b68b | 74 | } |
backman | 1:82bc25a7b68b | 75 | |
backman | 1:82bc25a7b68b | 76 | uint16_t FastAnalogIn::read_u16() |
backman | 1:82bc25a7b68b | 77 | { |
backman | 1:82bc25a7b68b | 78 | if (!running) |
backman | 1:82bc25a7b68b | 79 | { |
backman | 1:82bc25a7b68b | 80 | // start conversion |
backman | 1:82bc25a7b68b | 81 | ADC0->SC1[0] = ADC_SC1_ADCH(ADCnumber & ~(1 << CHANNELS_A_SHIFT)); |
backman | 1:82bc25a7b68b | 82 | // Wait Conversion Complete |
backman | 1:82bc25a7b68b | 83 | while ((ADC0->SC1[0] & ADC_SC1_COCO_MASK) != ADC_SC1_COCO_MASK); |
backman | 1:82bc25a7b68b | 84 | } |
backman | 1:82bc25a7b68b | 85 | if(running && ((ADC0->SC1[0]&ADC_SC1_ADCH_MASK) != (ADC_SC1_ADCH(ADCnumber & ~(1 << CHANNELS_A_SHIFT))))) |
backman | 1:82bc25a7b68b | 86 | { |
backman | 1:82bc25a7b68b | 87 | running = false; |
backman | 1:82bc25a7b68b | 88 | enable(); |
backman | 1:82bc25a7b68b | 89 | while ((ADC0->SC1[0] & ADC_SC1_COCO_MASK) != ADC_SC1_COCO_MASK); |
backman | 1:82bc25a7b68b | 90 | } |
backman | 1:82bc25a7b68b | 91 | // Return value |
backman | 1:82bc25a7b68b | 92 | return (uint16_t)ADC0->R[0]; |
backman | 1:82bc25a7b68b | 93 | } |
backman | 1:82bc25a7b68b | 94 |