generated from Embedded_Projects/MPyATE_Template
146 lines
4.1 KiB
C
146 lines
4.1 KiB
C
/* Board */
|
|
#include "clock_config.h"
|
|
#include "pin_mux.h"
|
|
|
|
/* SDK drivers */
|
|
#include "fsl_adc.h"
|
|
#include "fsl_clock.h"
|
|
#include "fsl_power.h"
|
|
|
|
/* App */
|
|
#include "app_adc.h"
|
|
|
|
#define APP_ADC_CHANNEL_COUNT (1U)
|
|
#define APP_ADC_SEQUENCE (0U)
|
|
|
|
#define APP_ADC_REG_OFFSET_CTRL (0x00U)
|
|
#define APP_ADC_REG_OFFSET_STAT (0x01U)
|
|
#define APP_ADC_REG_OFFSET_CH (0x02U)
|
|
|
|
#define APP_ADC_CTRL_CHN_Pos (0U)
|
|
#define APP_ADC_CTRL_CHN_Msk (((1 << APP_ADC_CHANNEL_COUNT) - 1) << APP_ADC_CTRL_CHN_Pos)
|
|
|
|
#define APP_ADC_CTRL_CONV_Pos (15U)
|
|
#define APP_ADC_CTRL_CONV_Msk (1U << APP_ADC_CTRL_CONV_Pos)
|
|
|
|
#define APP_ADC_STAT_DONE_Pos (0U)
|
|
#define APP_ADC_STAT_DONE_Msk (1U << APP_ADC_STAT_DONE_Pos)
|
|
|
|
static const uint8_t s_app_adc_channel_id_table[APP_ADC_CHANNEL_COUNT] = {
|
|
2U, // VDDIO channel
|
|
};
|
|
|
|
static inline uint16_t app_adc_read_reg_ctrl(void);
|
|
static inline uint16_t app_adc_read_reg_stat(void);
|
|
static inline uint16_t app_adc_read_reg_ch(uint8_t ch);
|
|
|
|
static inline void app_adc_write_reg_ctrl(uint16_t data);
|
|
static inline void app_adc_write_reg_stat(uint16_t data);
|
|
|
|
void app_adc_init(void) {
|
|
POWER_DisablePD(kPDRUNCFG_PD_ADC0);
|
|
|
|
CLOCK_Select(kADC_Clk_From_Fro);
|
|
CLOCK_SetClkDivider(kCLOCK_DivAdcClk, 5);
|
|
CLOCK_EnableClock(kCLOCK_Adc);
|
|
|
|
RESET_PeripheralReset(kADC_RST_N_SHIFT_RSTn);
|
|
|
|
ADC->CTRL = ADC_CTRL_LPWRMODE(1) | (1U << 8U); // Async mode, LP mode enabled
|
|
|
|
/* Continuous mode, interrupt after sequence is completed */
|
|
ADC->SEQ_CTRL[APP_ADC_SEQUENCE] = ADC_SEQ_CTRL_MODE(1);
|
|
ADC->INTEN |= ADC_INTEN_SEQA_INTEN(1);
|
|
}
|
|
|
|
uint16_t app_adc_module_reg_read(uint8_t addr) {
|
|
uint16_t ret = 0x5555;
|
|
|
|
switch (addr) {
|
|
case APP_ADC_REG_OFFSET_CTRL:
|
|
ret = app_adc_read_reg_ctrl();
|
|
break;
|
|
case APP_ADC_REG_OFFSET_STAT:
|
|
ret = app_adc_read_reg_stat();
|
|
break;
|
|
default:
|
|
if ((addr >= APP_ADC_REG_OFFSET_CH) && addr < (APP_ADC_REG_OFFSET_CH + APP_ADC_CHANNEL_COUNT)) {
|
|
ret = app_adc_read_reg_ch(addr - APP_ADC_REG_OFFSET_CH);
|
|
}
|
|
break;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
void app_adc_module_reg_write(uint8_t addr, uint16_t data) {
|
|
switch (addr) {
|
|
case APP_ADC_REG_OFFSET_CTRL:
|
|
app_adc_write_reg_ctrl(data);
|
|
break;
|
|
case APP_ADC_REG_OFFSET_STAT:
|
|
app_adc_write_reg_stat(data);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
static inline uint16_t app_adc_read_reg_ctrl(void) {
|
|
uint16_t ret = 0x0000U;
|
|
|
|
for (uint8_t i = 0; i < APP_ADC_CHANNEL_COUNT; i++) {
|
|
if (ADC->SEQ_CTRL[APP_ADC_SEQUENCE] & (1U << s_app_adc_channel_id_table[i])) {
|
|
ret |= (1U << i);
|
|
}
|
|
}
|
|
|
|
if (ADC->SEQ_CTRL[APP_ADC_SEQUENCE] & ADC_SEQ_CTRL_SEQ_ENA(1)) {
|
|
ret |= APP_ADC_CTRL_CONV_Msk;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static inline uint16_t app_adc_read_reg_stat(void) {
|
|
uint16_t ret = 0x0000U;
|
|
|
|
if (ADC->FLAGS & ADC_FLAGS_SEQA_INT(1)) {
|
|
ret |= APP_ADC_STAT_DONE_Msk;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static inline uint16_t app_adc_read_reg_ch(uint8_t ch) {
|
|
uint32_t dat = ADC->DAT[s_app_adc_channel_id_table[ch]];
|
|
|
|
return ((dat & ADC_DAT_RESULT_MASK) >> ADC_DAT_RESULT_SHIFT);
|
|
}
|
|
|
|
static inline void app_adc_write_reg_ctrl(uint16_t data) {
|
|
/* Channel configuration can only be changed when ADC is disabled */
|
|
if ((ADC->SEQ_CTRL[APP_ADC_SEQUENCE] & ADC_SEQ_CTRL_SEQ_ENA(1)) == 0) {
|
|
for (uint8_t i = 0; i < APP_ADC_CHANNEL_COUNT; i++) {
|
|
if (data & (1U << i)) {
|
|
ADC->SEQ_CTRL[APP_ADC_SEQUENCE] |= (1U << s_app_adc_channel_id_table[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (data & APP_ADC_CTRL_CONV_Msk) {
|
|
ADC->SEQ_CTRL[APP_ADC_SEQUENCE] |= ADC_SEQ_CTRL_SEQ_ENA(1) | ADC_SEQ_CTRL_BURST(1);
|
|
} else {
|
|
ADC->SEQ_CTRL[APP_ADC_SEQUENCE] &= ~(ADC_SEQ_CTRL_SEQ_ENA(1) | ADC_SEQ_CTRL_BURST(1));
|
|
}
|
|
}
|
|
|
|
static inline void app_adc_write_reg_stat(uint16_t data) {
|
|
if (data & APP_ADC_STAT_DONE_Msk) {
|
|
/* W1C DONE Msk */
|
|
if (ADC->FLAGS & ADC_FLAGS_SEQA_INT(1)) {
|
|
/* Read GDATn register to clear INT flag. */
|
|
(void)ADC->SEQ_GDAT[APP_ADC_SEQUENCE];
|
|
}
|
|
}
|
|
} |