Initial WIP ADC support.
Signed-off-by: Yilin Sun <imi415@imi.moe>
This commit is contained in:
parent
4bf56bf36c
commit
a2eb84f757
|
@ -65,6 +65,7 @@ set(TARGET_SOURCES
|
|||
"src/app_aux_ctrl.c"
|
||||
"src/app_mrb_repl.c"
|
||||
"src/app_syscalls.c"
|
||||
"src/mrb_machine_impl/mrb_machine_adc_impl.c"
|
||||
"src/mrb_machine_impl/mrb_machine_gpio_impl.c"
|
||||
"src/main.c"
|
||||
)
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 12b520e7873432d7135f9de86330c000f8464873
|
||||
Subproject commit 7f0aca015ec2bcad7d08d912163f135bdb238149
|
|
@ -0,0 +1,127 @@
|
|||
#include <stdio.h>
|
||||
|
||||
/* Board */
|
||||
#include "board.h"
|
||||
|
||||
/* SDK drivers */
|
||||
#include "fsl_anactrl.h"
|
||||
#include "fsl_clock.h"
|
||||
#include "fsl_gpio.h"
|
||||
#include "fsl_iocon.h"
|
||||
#include "fsl_lpadc.h"
|
||||
#include "fsl_power.h"
|
||||
|
||||
/* FreeRTOS */
|
||||
#include "FreeRTOS.h"
|
||||
#include "semphr.h"
|
||||
|
||||
/* Gem private */
|
||||
#include "machine-adc/src/adc.h"
|
||||
|
||||
#define ADC_IMPL_PORT(x) (x / 32)
|
||||
#define ADC_IMPL_PIN(x) (x % 32)
|
||||
|
||||
#define ADC_EXT_CHANNEL_COUNT 10
|
||||
#define ADC_TEMP_CHANNEL 26
|
||||
|
||||
/* CH0A, CH0B, CH1A, CH1B, ... CH4A, CH4B */
|
||||
const static uint32_t s_adc_pin_table[ADC_EXT_CHANNEL_COUNT] = {
|
||||
23, 16, 10, 11, 15, 12, 31, 32, 40, 41,
|
||||
};
|
||||
|
||||
static bool s_adc_initialized = false;
|
||||
static SemaphoreHandle_t s_adc_semaphore = NULL;
|
||||
|
||||
static void mrb_machine_adc_impl_init_peripheral(void) {
|
||||
CLOCK_SetClkDiv(kCLOCK_DivAdcAsyncClk, 8, true);
|
||||
CLOCK_AttachClk(kMAIN_CLK_to_ADC_CLK);
|
||||
|
||||
POWER_DisablePD(kPDRUNCFG_PD_LDOGPADC);
|
||||
|
||||
ANACTRL_Init(ANACTRL);
|
||||
ANACTRL_EnableVref1V(ANACTRL, true);
|
||||
|
||||
lpadc_config_t adc_cfg;
|
||||
LPADC_GetDefaultConfig(&adc_cfg);
|
||||
|
||||
adc_cfg.enableAnalogPreliminary = true;
|
||||
adc_cfg.referenceVoltageSource = kLPADC_ReferenceVoltageAlt2;
|
||||
adc_cfg.conversionAverageMode = kLPADC_ConversionAverage128;
|
||||
|
||||
LPADC_Init(ADC0, &adc_cfg);
|
||||
LPADC_DoOffsetCalibration(ADC0);
|
||||
LPADC_DoAutoCalibration(ADC0);
|
||||
}
|
||||
|
||||
int mrb_machine_adc_impl_config(uint32_t pin) {
|
||||
if (!s_adc_initialized) {
|
||||
mrb_machine_adc_impl_init_peripheral();
|
||||
|
||||
s_adc_semaphore = xSemaphoreCreateBinary();
|
||||
if (s_adc_semaphore == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
s_adc_initialized = true;
|
||||
}
|
||||
|
||||
uint32_t iocon_mode = IOCON_PIO_ASW(1);
|
||||
|
||||
/* Configure IOCON only if this is an external channel */
|
||||
if (pin < ADC_EXT_CHANNEL_COUNT) {
|
||||
IOCON_PinMuxSet(IOCON, ADC_IMPL_PORT(s_adc_pin_table[pin]), ADC_IMPL_PIN(s_adc_pin_table[pin]), iocon_mode);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mrb_machine_adc_impl_read(uint32_t pin) {
|
||||
lpadc_conv_command_config_t conv_cfg;
|
||||
lpadc_conv_trigger_config_t trig_cfg;
|
||||
|
||||
LPADC_GetDefaultConvCommandConfig(&conv_cfg);
|
||||
LPADC_GetDefaultConvTriggerConfig(&trig_cfg);
|
||||
|
||||
conv_cfg.conversionResolutionMode = kLPADC_ConversionResolutionHigh;
|
||||
|
||||
if (pin < ADC_EXT_CHANNEL_COUNT) {
|
||||
/* This is an external channel, Positive and negative pair shares the same channel */
|
||||
|
||||
lpadc_sample_channel_mode_t mode;
|
||||
if ((pin % 2) == 0) {
|
||||
mode = kLPADC_SampleChannelSingleEndSideA;
|
||||
} else {
|
||||
mode = kLPADC_SampleChannelSingleEndSideB;
|
||||
}
|
||||
|
||||
conv_cfg.channelNumber = pin / 2;
|
||||
conv_cfg.sampleChannelMode = mode;
|
||||
} else if (pin == ADC_TEMP_CHANNEL) { /* Temperature channel requires differential sampling */
|
||||
conv_cfg.channelNumber = pin;
|
||||
conv_cfg.sampleChannelMode = kLPADC_SampleChannelDiffBothSide;
|
||||
} else { /* Other internal channels */
|
||||
conv_cfg.channelNumber = pin;
|
||||
conv_cfg.sampleChannelMode = kLPADC_SampleChannelSingleEndSideA;
|
||||
}
|
||||
|
||||
trig_cfg.targetCommandId = 15;
|
||||
trig_cfg.enableHardwareTrigger = false;
|
||||
|
||||
LPADC_SetConvCommandConfig(ADC0, 15, &conv_cfg);
|
||||
LPADC_SetConvTriggerConfig(ADC0, 0U, &trig_cfg);
|
||||
|
||||
LPADC_EnableInterrupts(ADC0, kLPADC_FIFO0WatermarkInterruptEnable);
|
||||
EnableIRQ(ADC0_IRQn);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ADC0_IRQHandler(void) {
|
||||
BaseType_t higher_priority_woken = pdFALSE;
|
||||
|
||||
xSemaphoreGiveFromISR(s_adc_semaphore, &higher_priority_woken);
|
||||
|
||||
if (higher_priority_woken) {
|
||||
portYIELD_FROM_ISR(higher_priority_woken);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue