diff --git a/LPC804.mex b/LPC804.mex index 0e0d73a..ea98d30 100644 --- a/LPC804.mex +++ b/LPC804.mex @@ -32,6 +32,8 @@ + + @@ -132,7 +134,13 @@ - + + + + + + + @@ -160,7 +168,13 @@ - + + + + + + + diff --git a/board/pin_mux.c b/board/pin_mux.c index 7ef22c9..ff2cdbf 100644 --- a/board/pin_mux.c +++ b/board/pin_mux.c @@ -20,6 +20,8 @@ pin_labels: - {pin_num: '8', pin_signal: PIO0_11/ADC_6/WKTCLKIN, label: IO1, identifier: IO1} - {pin_num: '9', pin_signal: PIO0_10/ADC_7, label: IO2, identifier: IO2} - {pin_num: '15', pin_signal: PIO0_20, label: IO3, identifier: IO3} +- {pin_num: '25', pin_signal: PIO0_14/ACMP_I3/ADC_2, label: IOREF, identifier: ADC_IOREF;IOREF} +- {pin_num: '26', pin_signal: PIO0_19/DACOUT, label: DAC, identifier: DAC} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ @@ -157,7 +159,7 @@ void BOARD_InitLEDPins(void) BOARD_InitADCPins: - options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'} - pin_list: - - {pin_num: '25', peripheral: ADC0, signal: 'CH, 2', pin_signal: PIO0_14/ACMP_I3/ADC_2} + - {pin_num: '25', peripheral: ADC0, signal: 'CH, 2', pin_signal: PIO0_14/ACMP_I3/ADC_2, identifier: IOREF, mode: inactive, opendrain: disabled} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ @@ -171,9 +173,22 @@ BOARD_InitADCPins: /* Function assigned for the Cortex-M0P */ void BOARD_InitADCPins(void) { + /* Enables clock for IOCON.: enable */ + CLOCK_EnableClock(kCLOCK_Iocon); /* Enables clock for switch matrix.: enable */ CLOCK_EnableClock(kCLOCK_Swm); + IOCON->PIO[18] = ((IOCON->PIO[18] & + /* Mask bits to zero which are setting */ + (~(IOCON_PIO_MODE_MASK | IOCON_PIO_OD_MASK))) + + /* Selects function mode (on-chip pull-up/pull-down resistor control).: Inactive. Inactive (no + * pull-down/pull-up resistor enabled). */ + | IOCON_PIO_MODE(PIO0_14_MODE_INACTIVE) + + /* Open-drain mode.: Disable. */ + | IOCON_PIO_OD(PIO0_14_OD_DISABLE)); + /* ADC_CHN2 connect to P0_14 */ SWM_SetFixedPinSelect(SWM0, kSWM_ADC_CHN2, true); @@ -187,7 +202,7 @@ void BOARD_InitADCPins(void) BOARD_InitDACPins: - options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'} - pin_list: - - {pin_num: '26', peripheral: DAC0, signal: DACOUT0, pin_signal: PIO0_19/DACOUT} + - {pin_num: '26', peripheral: DAC0, signal: DACOUT0, pin_signal: PIO0_19/DACOUT, mode: inactive, opendrain: disabled, dacmode: enabled} * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** */ /* clang-format on */ @@ -201,9 +216,25 @@ BOARD_InitDACPins: /* Function assigned for the Cortex-M0P */ void BOARD_InitDACPins(void) { + /* Enables clock for IOCON.: enable */ + CLOCK_EnableClock(kCLOCK_Iocon); /* Enables clock for switch matrix.: enable */ CLOCK_EnableClock(kCLOCK_Swm); + IOCON->PIO[24] = ((IOCON->PIO[24] & + /* Mask bits to zero which are setting */ + (~(IOCON_PIO_MODE_MASK | IOCON_PIO_OD_MASK | IOCON_PIO_DACMODE_MASK))) + + /* Selects function mode (on-chip pull-up/pull-down resistor control).: Inactive. Inactive (no + * pull-down/pull-up resistor enabled). */ + | IOCON_PIO_MODE(PIO0_19_MODE_INACTIVE) + + /* Open-drain mode.: Disable. */ + | IOCON_PIO_OD(PIO0_19_OD_DISABLE) + + /* DAC mode enable.: Enable. */ + | IOCON_PIO_DACMODE(PIO0_19_DACMODE_ENABLE)); + /* DAC_OUT0 connect to P0_19 */ SWM_SetFixedPinSelect(SWM0, kSWM_DAC_OUT0, true); diff --git a/board/pin_mux.h b/board/pin_mux.h index 92a5fb5..4baa9bd 100644 --- a/board/pin_mux.h +++ b/board/pin_mux.h @@ -80,12 +80,51 @@ void BOARD_InitDbgUARTPins(void); /* Function assigned for the Cortex-M0P */ */ void BOARD_InitLEDPins(void); /* Function assigned for the Cortex-M0P */ +/*! + * @brief + * Selects function mode (on-chip pull-up/pull-down resistor control). + * : Inactive. + * Inactive (no pull-down/pull-up resistor enabled). + */ +#define PIO0_14_MODE_INACTIVE 0x00u +/*! + * @brief Open-drain mode.: Disable. */ +#define PIO0_14_OD_DISABLE 0x00u + +/*! @name ADC_2 (number 25), IOREF + @{ */ +#define BOARD_INITADCPINS_IOREF_PORT 0U /*!<@brief PORT device index: 0 */ +#define BOARD_INITADCPINS_IOREF_PIN 14U /*!<@brief PORT pin number */ +#define BOARD_INITADCPINS_IOREF_PIN_MASK (1U << 14U) /*!<@brief PORT pin mask */ + /* @} */ + /*! * @brief Configures pin routing and optionally pin electrical features. * */ void BOARD_InitADCPins(void); /* Function assigned for the Cortex-M0P */ +/*! + * @brief DAC mode enable.: Enable. */ +#define PIO0_19_DACMODE_ENABLE 0x01u +/*! + * @brief + * Selects function mode (on-chip pull-up/pull-down resistor control). + * : Inactive. + * Inactive (no pull-down/pull-up resistor enabled). + */ +#define PIO0_19_MODE_INACTIVE 0x00u +/*! + * @brief Open-drain mode.: Disable. */ +#define PIO0_19_OD_DISABLE 0x00u + +/*! @name DACOUT (number 26), DAC + @{ */ +#define BOARD_INITDACPINS_DAC_PORT 0U /*!<@brief PORT device index: 0 */ +#define BOARD_INITDACPINS_DAC_PIN 19U /*!<@brief PORT pin number */ +#define BOARD_INITDACPINS_DAC_PIN_MASK (1U << 19U) /*!<@brief PORT pin mask */ + /* @} */ + /*! * @brief Configures pin routing and optionally pin electrical features. * diff --git a/src/app_adc.c b/src/app_adc.c index 6082d91..b45c61c 100644 --- a/src/app_adc.c +++ b/src/app_adc.c @@ -1,12 +1,146 @@ +/* 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) { - return 0x0000U; + 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]; + } + } +} \ No newline at end of file