aboutsummaryrefslogtreecommitdiff
path: root/example-fs-bb48/adc_kl27z.c
diff options
context:
space:
mode:
Diffstat (limited to 'example-fs-bb48/adc_kl27z.c')
-rw-r--r--example-fs-bb48/adc_kl27z.c320
1 files changed, 0 insertions, 320 deletions
diff --git a/example-fs-bb48/adc_kl27z.c b/example-fs-bb48/adc_kl27z.c
deleted file mode 100644
index de482bb..0000000
--- a/example-fs-bb48/adc_kl27z.c
+++ /dev/null
@@ -1,320 +0,0 @@
-/*
- * adc_kl27z.c - ADC driver for KL27Z
- * In this ADC driver, there are NeuG specific parts.
- * It only records lower 8-bit of 16-bit data.
- * You need to modify to use this as generic ADC driver.
- *
- * Copyright (C) 2016 Flying Stone Technology
- * Author: NIIBE Yutaka <gniibe@fsij.org>
- *
- * This file is a part of Chopstx, a thread library for embedded.
- *
- * Chopstx is free software: you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Chopstx is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * As additional permission under GNU GPL version 3 section 7, you may
- * distribute non-source form of the Program without the copy of the
- * GNU GPL normally required by section 4, provided you inform the
- * receipents of GNU GPL by a written offer.
- *
- */
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <chopstx.h>
-#include <mcu/kl_sim.h>
-
-struct DMAMUX {
- volatile uint32_t CHCFG0;
- volatile uint32_t CHCFG1;
- volatile uint32_t CHCFG2;
- volatile uint32_t CHCFG3;
-};
-static struct DMAMUX *const DMAMUX = (struct DMAMUX *const)0x40021000;
-
-#define INTR_REQ_DMA0 0
-
-struct DMA {
- volatile uint32_t SAR;
- volatile uint32_t DAR;
- volatile uint32_t DSR_BCR;
- volatile uint32_t DCR;
-};
-static struct DMA *const DMA0 = (struct DMA *const)0x40008100;
-static struct DMA *const DMA1 = (struct DMA *const)0x40008110;
-
-
-/* We don't use ADC interrupt. Just for reference. */
-#define INTR_REQ_ADC 15
-
-struct ADC {
- volatile uint32_t SC1[2];/* Status and Control Registers 1 */
- volatile uint32_t CFG1; /* Configuration Register 1 */
- volatile uint32_t CFG2; /* Configuration Register 2 */
- volatile uint32_t R[2]; /* Data Result Register */
-
- /* Compare Value Registers 1, 2 */
- volatile uint32_t CV1;
- volatile uint32_t CV2;
-
- volatile uint32_t SC2; /* Status and Control Register 2 */
- volatile uint32_t SC3; /* Status and Control Register 3 */
-
- volatile uint32_t OFS; /* Offset Correction Register */
- volatile uint32_t PG; /* Plus-Side Gain Register */
- volatile uint32_t MG; /* Minus-Side Gain Register */
-
- /* Plus-Side General Calibration Value Registers */
- volatile uint32_t CLPD;
- volatile uint32_t CLPS;
- volatile uint32_t CLP4;
- volatile uint32_t CLP3;
- volatile uint32_t CLP2;
- volatile uint32_t CLP1;
- volatile uint32_t CLP0;
- uint32_t rsvd0;
- /* Minus-Side General Calibration Value Registers */
- volatile uint32_t CLMD;
- volatile uint32_t CLMS;
- volatile uint32_t CLM4;
- volatile uint32_t CLM3;
- volatile uint32_t CLM2;
- volatile uint32_t CLM1;
- volatile uint32_t CLM0;
-};
-static struct ADC *const ADC0 = (struct ADC *const)0x4003B000;
-
-/* SC1 */
-#define ADC_SC1_DIFF (1 << 5)
-#define ADC_SC1_AIEN (1 << 6)
-#define ADC_SC1_COCO (1 << 7)
-#define ADC_SC1_TEMPSENSOR 26
-#define ADC_SC1_BANDGAP 27
-#define ADC_SC1_ADCSTOP 31
-
-/* CFG1 */
-#define ADC_CLOCK_SOURCE_ASYNCH (3 << 0)
-#define ADC_MODE_16BIT (3 << 2)
-#define ADC_ADLSMP_SHORT (0 << 4)
-#define ADC_ADLSMP_LONG (1 << 4)
-#define ADC_ADIV_1 (0 << 5)
-#define ADC_ADIV_8 (3 << 5)
-#define ADC_ADLPC_NORMAL (0 << 7)
-#define ADC_ADLPC_LOWPOWER (1 << 7)
-/**/
-#define ADC_CLOCK_SOURCE ADC_CLOCK_SOURCE_ASYNCH
-#define ADC_MODE ADC_MODE_16BIT
-#define ADC_ADLSMP ADC_ADLSMP_SHORT
-#define ADC_ADIV ADC_ADIV_1
-#define ADC_ADLPC ADC_ADLPC_LOWPOWER
-
-/* CFG2 */
-#define ADC_ADLSTS_DEFAULT 0 /* 24 cycles if CFG1.ADLSMP=1, 4 if not. */
-#define ADC_ADHSC_NORMAL (0 << 2)
-#define ADC_ADHSC_HIGHSPEED (1 << 2)
-#define ADC_ADACK_DISABLE (0 << 3)
-#define ADC_ADACK_ENABLE (1 << 3)
-#define ADC_MUXSEL_A (0 << 4)
-#define ADC_MUXSEL_B (1 << 4)
-/**/
-#define ADC_ADLSTS ADC_ADLSTS_DEFAULT
-#define ADC_ADHSC ADC_ADHSC_NORMAL
-#define ADC_ADACKEN ADC_ADACK_ENABLE
-#define ADC_MUXSEL ADC_MUXSEL_A
-
-/* SC2 */
-#define ADC_SC2_REFSEL_DEFAULT 1 /* Internal Voltage Reference??? */
-#define ADC_SC2_DMAEN (1 << 2)
-#define ADC_SC2_ACREN (1 << 3)
-#define ADC_SC2_ACFGT (1 << 4)
-#define ADC_SC2_ACFE (1 << 5)
-#define ADC_SC2_ADTRG (1 << 6) /* For hardware trigger */
-
-/* SC3 */
-#define ADC_SC3_AVGS11 0x03
-#define ADC_SC3_AVGE (1 << 2)
-#define ADC_SC3_ADCO (1 << 3)
-#define ADC_SC3_CALF (1 << 6)
-#define ADC_SC3_CAL (1 << 7)
-
-#define ADC_DMA_SLOT_NUM 40
-
-/*
- * Buffer to save ADC data.
- */
-uint32_t adc_buf[64];
-
-static const uint32_t adc0_sc1_setting = ADC_SC1_TEMPSENSOR;
-
-static chopstx_intr_t adc_intr;
-
-struct adc_internal {
- uint32_t buf[64];
- uint8_t *p;
- int phase : 8;
- int count : 8;
-};
-struct adc_internal adc;
-
-/*
- * Initialize ADC module, do calibration.
- *
- * This is called by MAIN, only once, hopefully before creating any
- * other threads (to be accurate).
- *
- * We configure ADC0 to kick DMA0, configure DMA0 to kick DMA1.
- * DMA0 records output of ADC0 to the ADC.BUF.
- * DMA1 kicks ADC0 again to get another value.
- *
- * ADC0 --[finish conversion]--> DMA0 --[Link channel 1]--> DMA1
- */
-int
-adc_init (void)
-{
- uint32_t v;
-
- /* Enable ADC0 and DMAMUX clock. */
- SIM->SCGC6 |= (1 << 27) | (1 << 1);
- /* Enable DMA clock. */
- SIM->SCGC7 |= (1 << 8);
-
- /* ADC0 setting for calibration. */
- ADC0->CFG1 = ADC_CLOCK_SOURCE | ADC_MODE | ADC_ADLSMP | ADC_ADIV | ADC_ADLPC;
- ADC0->CFG2 = ADC_ADLSTS | ADC_ADHSC | ADC_ADACKEN | ADC_MUXSEL;
- ADC0->SC2 = ADC_SC2_REFSEL_DEFAULT;
- ADC0->SC3 = ADC_SC3_CAL | ADC_SC3_CALF | ADC_SC3_AVGE | ADC_SC3_AVGS11;
-
- /* Wait ADC completion */
- while ((ADC0->SC1[0] & ADC_SC1_COCO) == 0)
- if ((ADC0->SC3 & ADC_SC3_CALF) != 0)
- /* Calibration failure */
- return -1;
-
- if ((ADC0->SC3 & ADC_SC3_CALF) != 0)
- /* Calibration failure */
- return -1;
-
- /* Configure PG by the calibration values. */
- v = ADC0->CLP0 + ADC0->CLP1 + ADC0->CLP2 + ADC0->CLP3 + ADC0->CLP4 + ADC0->CLPS;
- ADC0->PG = 0x8000 | (v >> 1);
-
- /* Configure MG by the calibration values. */
- v = ADC0->CLM0 + ADC0->CLM1 + ADC0->CLM2 + ADC0->CLM3 + ADC0->CLM4 + ADC0->CLMS;
- ADC0->MG = 0x8000 | (v >> 1);
-
- ADC0->SC1[0] = ADC_SC1_ADCSTOP;
-
- /* DMAMUX setting. */
- DMAMUX->CHCFG0 = (1 << 7) | ADC_DMA_SLOT_NUM;
-
- /* DMA0 initial setting. */
- DMA0->SAR = (uint32_t)&ADC0->R[0];
-
- /* DMA1 initial setting. */
- DMA1->SAR = (uint32_t)&adc0_sc1_setting;
- DMA1->DAR = (uint32_t)&ADC0->SC1[0];
-
- chopstx_claim_irq (&adc_intr, INTR_REQ_DMA0);
- return 0;
-}
-
-/*
- * Start using ADC.
- */
-void
-adc_start (void)
-{
- ADC0->CFG1 = ADC_CLOCK_SOURCE | ADC_MODE | ADC_ADLSMP | ADC_ADIV | ADC_ADLPC;
- ADC0->CFG2 = ADC_ADLSTS | ADC_ADHSC | ADC_ADACKEN | ADC_MUXSEL;
- ADC0->SC2 = ADC_SC2_REFSEL_DEFAULT | ADC_SC2_DMAEN;
- ADC0->SC3 = 0;
-}
-
-/*
- * Kick getting data for COUNT times.
- * Data will be saved in ADC_BUF starting at OFFSET.
- */
-static void
-adc_start_conversion_internal (int count)
-{
- /* DMA0 setting. */
- DMA0->DAR = (uint32_t)&adc.buf[0];
- DMA0->DSR_BCR = 4 * count;
- DMA0->DCR = (1 << 31) | (1 << 30) | (1 << 29) | (0 << 20) | (1 << 19)
- | (0 << 17) | (1 << 7) | (2 << 4) | (1 << 2);
-
- /* Kick DMA1. */
- DMA1->DSR_BCR = 4 * count;
- DMA1->DCR = (1 << 30) | (1 << 29) | (0 << 19) | (0 << 17) | (1 << 16) | (1 << 7);
-}
-
-
-/*
- * Kick getting data for COUNT times.
- * Data will be saved in ADC_BUF starting at OFFSET.
- */
-void
-adc_start_conversion (int offset, int count)
-{
- adc.p = (uint8_t *)&adc_buf[offset];
- adc.phase = 0;
- adc.count = count;
- adc_start_conversion_internal (count);
-}
-
-
-static void
-adc_stop_conversion (void)
-{
- ADC0->SC1[0] = ADC_SC1_ADCSTOP;
-}
-
-/*
- * Stop using ADC.
- */
-void
-adc_stop (void)
-{
- SIM->SCGC6 &= ~(1 << 27);
-}
-
-/*
- * Return 0 on success.
- * Return 1 on error.
- */
-int
-adc_wait_completion (void)
-{
- while (1)
- {
- int i;
-
- /* Wait DMA completion */
- chopstx_poll (NULL, 1, &adc_intr);
-
- DMA0->DSR_BCR = (1 << 24);
- DMA1->DSR_BCR = (1 << 24);
-
- adc_stop_conversion ();
-
- for (i = 0; i < adc.count; i++)
- *adc.p++ = (uint8_t)adc.buf[i];
-
- if (++adc.phase >= 4)
- break;
-
- adc_start_conversion_internal (adc.count);
- }
-
- return 0;
-}