Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed FastIO FastPWM USBDevice
AltAnalogIn/AltAnalogIn_KL25Z.cpp@43:7a6364d82a41, 2016-02-06 (annotated)
- Committer:
- mjr
- Date:
- Sat Feb 06 20:21:48 2016 +0000
- Revision:
- 43:7a6364d82a41
- Child:
- 45:c42166b2878c
Before floating point plunger ranging
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| mjr | 43:7a6364d82a41 | 1 | #if defined(TARGET_KLXX) || defined(TARGET_K20D50M) |
| mjr | 43:7a6364d82a41 | 2 | |
| mjr | 43:7a6364d82a41 | 3 | #include "AltAnalogIn.h" |
| mjr | 43:7a6364d82a41 | 4 | #include "clk_freqs.h" |
| mjr | 43:7a6364d82a41 | 5 | |
| mjr | 43:7a6364d82a41 | 6 | // Maximum ADC clock for KL25Z in 12-bit mode. The data sheet says this is |
| mjr | 43:7a6364d82a41 | 7 | // limited to 18MHz, but we seem to get good results at higher rates. The |
| mjr | 43:7a6364d82a41 | 8 | // data sheet is actually slightly vague on this because it's only in the |
| mjr | 43:7a6364d82a41 | 9 | // table for the 16-bit ADC, even though the ADC we're using is a 12-bit ADC, |
| mjr | 43:7a6364d82a41 | 10 | // which seems to have slightly different properties. So there's room to |
| mjr | 43:7a6364d82a41 | 11 | // think the data sheet omits the data for the 12-bit ADC. |
| mjr | 43:7a6364d82a41 | 12 | #define MAX_FADC_12BIT 25000000 |
| mjr | 43:7a6364d82a41 | 13 | |
| mjr | 43:7a6364d82a41 | 14 | #define CHANNELS_A_SHIFT 5 // bit position in ADC channel number of A/B mux |
| mjr | 43:7a6364d82a41 | 15 | #define ADC_CFG1_ADLSMP 0x10 // long sample time mode |
| mjr | 43:7a6364d82a41 | 16 | #define ADC_SC2_ADLSTS(mode) (mode) // long sample time select - bits 1:0 of CFG2 |
| mjr | 43:7a6364d82a41 | 17 | |
| mjr | 43:7a6364d82a41 | 18 | #ifdef TARGET_K20D50M |
| mjr | 43:7a6364d82a41 | 19 | static const PinMap PinMap_ADC[] = { |
| mjr | 43:7a6364d82a41 | 20 | {PTC2, ADC0_SE4b, 0}, |
| mjr | 43:7a6364d82a41 | 21 | {PTD1, ADC0_SE5b, 0}, |
| mjr | 43:7a6364d82a41 | 22 | {PTD5, ADC0_SE6b, 0}, |
| mjr | 43:7a6364d82a41 | 23 | {PTD6, ADC0_SE7b, 0}, |
| mjr | 43:7a6364d82a41 | 24 | {PTB0, ADC0_SE8, 0}, |
| mjr | 43:7a6364d82a41 | 25 | {PTB1, ADC0_SE9, 0}, |
| mjr | 43:7a6364d82a41 | 26 | {PTB2, ADC0_SE12, 0}, |
| mjr | 43:7a6364d82a41 | 27 | {PTB3, ADC0_SE13, 0}, |
| mjr | 43:7a6364d82a41 | 28 | {PTC0, ADC0_SE14, 0}, |
| mjr | 43:7a6364d82a41 | 29 | {PTC1, ADC0_SE15, 0}, |
| mjr | 43:7a6364d82a41 | 30 | {NC, NC, 0} |
| mjr | 43:7a6364d82a41 | 31 | }; |
| mjr | 43:7a6364d82a41 | 32 | #endif |
| mjr | 43:7a6364d82a41 | 33 | |
| mjr | 43:7a6364d82a41 | 34 | AltAnalogIn::AltAnalogIn(PinName pin, bool enabled) |
| mjr | 43:7a6364d82a41 | 35 | { |
| mjr | 43:7a6364d82a41 | 36 | // do nothing if explicitly not connected |
| mjr | 43:7a6364d82a41 | 37 | if (pin == NC) |
| mjr | 43:7a6364d82a41 | 38 | return; |
| mjr | 43:7a6364d82a41 | 39 | |
| mjr | 43:7a6364d82a41 | 40 | // figure our ADC number |
| mjr | 43:7a6364d82a41 | 41 | ADCnumber = (ADCName)pinmap_peripheral(pin, PinMap_ADC); |
| mjr | 43:7a6364d82a41 | 42 | if (ADCnumber == (ADCName)NC) { |
| mjr | 43:7a6364d82a41 | 43 | error("ADC pin mapping failed"); |
| mjr | 43:7a6364d82a41 | 44 | } |
| mjr | 43:7a6364d82a41 | 45 | |
| mjr | 43:7a6364d82a41 | 46 | // figure our multiplexer channel (A or B) |
| mjr | 43:7a6364d82a41 | 47 | ADCmux = (ADCnumber >> CHANNELS_A_SHIFT) ^ 1; |
| mjr | 43:7a6364d82a41 | 48 | |
| mjr | 43:7a6364d82a41 | 49 | // enable the ADC0 clock in the system control module |
| mjr | 43:7a6364d82a41 | 50 | SIM->SCGC6 |= SIM_SCGC6_ADC0_MASK; |
| mjr | 43:7a6364d82a41 | 51 | |
| mjr | 43:7a6364d82a41 | 52 | // enable the port clock gate for the port containing our GPIO pin |
| mjr | 43:7a6364d82a41 | 53 | uint32_t port = (uint32_t)pin >> PORT_SHIFT; |
| mjr | 43:7a6364d82a41 | 54 | SIM->SCGC5 |= 1 << (SIM_SCGC5_PORTA_SHIFT + port); |
| mjr | 43:7a6364d82a41 | 55 | |
| mjr | 43:7a6364d82a41 | 56 | // Figure the maximum clock frequency. In 12-bit mode or less, we can |
| mjr | 43:7a6364d82a41 | 57 | // run the ADC at up to 18 MHz per the KL25Z data sheet. (16-bit mode |
| mjr | 43:7a6364d82a41 | 58 | // is limited to 12 MHz.) |
| mjr | 43:7a6364d82a41 | 59 | int clkdiv = 0; |
| mjr | 43:7a6364d82a41 | 60 | uint32_t ourfreq = bus_frequency(); |
| mjr | 43:7a6364d82a41 | 61 | for ( ; ourfreq > MAX_FADC_12BIT ; ourfreq /= 2, clkdiv += 1) ; |
| mjr | 43:7a6364d82a41 | 62 | |
| mjr | 43:7a6364d82a41 | 63 | // Set the "high speed" configuration only if we're right at the bus speed |
| mjr | 43:7a6364d82a41 | 64 | // limit. This bit is somewhat confusingly named, in that it actually |
| mjr | 43:7a6364d82a41 | 65 | // *slows down* the conversions. "High speed" means that the *other* |
| mjr | 43:7a6364d82a41 | 66 | // options are set right at the limits of the ADC, so this option adds |
| mjr | 43:7a6364d82a41 | 67 | // a few extra cycle delays to every conversion to compensate for living |
| mjr | 43:7a6364d82a41 | 68 | // on the edge. |
| mjr | 43:7a6364d82a41 | 69 | uint32_t adhsc_bit = (ourfreq == MAX_FADC_12BIT ? ADC_CFG2_ADHSC_MASK : 0); |
| mjr | 43:7a6364d82a41 | 70 | |
| mjr | 43:7a6364d82a41 | 71 | printf("ADCnumber=%d, cfg2_muxsel=%d, bus freq=%ld, clkdiv=%d\r\n", ADCnumber, ADCmux, bus_frequency(), clkdiv); |
| mjr | 43:7a6364d82a41 | 72 | |
| mjr | 43:7a6364d82a41 | 73 | // set up the ADC control registers |
| mjr | 43:7a6364d82a41 | 74 | |
| mjr | 43:7a6364d82a41 | 75 | ADC0->CFG1 = ADC_CFG1_ADIV(clkdiv) // Clock Divide Select (as calculated above) |
| mjr | 43:7a6364d82a41 | 76 | | ADC_CFG1_MODE(1) // Sample precision = 12-bit |
| mjr | 43:7a6364d82a41 | 77 | | ADC_CFG1_ADICLK(0); // Input Clock = bus clock |
| mjr | 43:7a6364d82a41 | 78 | |
| mjr | 43:7a6364d82a41 | 79 | ADC0->CFG2 = adhsc_bit // High-Speed Configuration, if needed |
| mjr | 43:7a6364d82a41 | 80 | | ADC_CFG2_ADLSTS(3); // Long sample time mode 3 -> 6 ADCK cycles total |
| mjr | 43:7a6364d82a41 | 81 | |
| mjr | 43:7a6364d82a41 | 82 | ADC0->SC2 = ADC_SC2_REFSEL(0); // Default Voltage Reference |
| mjr | 43:7a6364d82a41 | 83 | |
| mjr | 43:7a6364d82a41 | 84 | ADC0->SC3 = 0; // Calibration mode off, single sample, averaging disabled |
| mjr | 43:7a6364d82a41 | 85 | |
| mjr | 43:7a6364d82a41 | 86 | // map the GPIO pin in the system multiplexer to the ADC |
| mjr | 43:7a6364d82a41 | 87 | pinmap_pinout(pin, PinMap_ADC); |
| mjr | 43:7a6364d82a41 | 88 | |
| mjr | 43:7a6364d82a41 | 89 | // figure our 'start' mask - this is the value we write to the SC1A register |
| mjr | 43:7a6364d82a41 | 90 | // to initiate a new sample |
| mjr | 43:7a6364d82a41 | 91 | startMask = ADC_SC1_ADCH(ADCnumber & ~(1 << CHANNELS_A_SHIFT)); |
| mjr | 43:7a6364d82a41 | 92 | } |
| mjr | 43:7a6364d82a41 | 93 | |
| mjr | 43:7a6364d82a41 | 94 | #endif //defined TARGET_KLXX |