Nuvoton: Add analogin_free

1.  Deal with channel-wise and module-wise
2.  Disable IP clock
3.  Free up pin

Support targets:

-   NUMAKER_PFM_NANO130
-   NUMAKER_PFM_NUC472
-   NUMAKER_PFM_M453
-   NUMAKER_PFM_M487/NUMAKER_IOT_M487
-   NU_PFM_M2351*
-   NUMAKER_IOT_M263A
-   NUMAKER_M252KG
pull/11780/head
Chun-Chieh Li 2019-10-31 10:20:01 +08:00
parent cbf9f0650b
commit 3abd02614a
7 changed files with 221 additions and 13 deletions

View File

@ -92,6 +92,40 @@ void analogin_init(analogin_t *obj, PinName pin)
eadc_modinit_mask |= 1 << chn;
}
void analogin_free(analogin_t *obj)
{
const struct nu_modinit_s *modinit = get_modinit(obj->adc, adc_modinit_tab);
MBED_ASSERT(modinit->modname == (int) obj->adc);
/* Module subindex (aka channel) */
uint32_t chn = NU_MODSUBINDEX(obj->adc);
EADC_T *eadc_base = (EADC_T *) NU_MODBASE(obj->adc);
/* Channel-level windup from here */
/* Mark channel free */
eadc_modinit_mask &= ~(1 << chn);
/* Module-level windup from here */
/* See analogin_init() for reason */
if (! eadc_modinit_mask) {
/* Disable EADC module */
EADC_Close(eadc_base);
/* Disable IP clock
*
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
*/
CLK_DisableModuleClock_S(modinit->clkidx);
}
/* Free up pins */
gpio_set(obj->pin);
obj->pin = NC;
}
uint16_t analogin_read_u16(analogin_t *obj)
{
EADC_T *eadc_base = (EADC_T *) NU_MODBASE(obj->adc);

View File

@ -93,6 +93,37 @@ void analogin_init(analogin_t *obj, PinName pin)
eadc_modinit_mask |= 1 << chn;
}
void analogin_free(analogin_t *obj)
{
const struct nu_modinit_s *modinit = get_modinit(obj->adc, adc_modinit_tab);
MBED_ASSERT(modinit->modname == (int) obj->adc);
/* Module subindex (aka channel) */
uint32_t chn = NU_MODSUBINDEX(obj->adc);
EADC_T *eadc_base = (EADC_T *) NU_MODBASE(obj->adc);
/* Channel-level windup from here */
/* Mark channel free */
eadc_modinit_mask &= ~(1 << chn);
/* Module-level windup from here */
/* See analogin_init() for reason */
if (! eadc_modinit_mask) {
/* Disable EADC module */
EADC_Close(eadc_base);
/* Disable IP clock */
CLK_DisableModuleClock(modinit->clkidx);
}
/* Free up pins */
gpio_set(obj->pin);
obj->pin = NC;
}
uint16_t analogin_read_u16(analogin_t *obj)
{
EADC_T *eadc_base = (EADC_T *) NU_MODBASE(obj->adc);

View File

@ -84,6 +84,37 @@ void analogin_init(analogin_t *obj, PinName pin)
eadc_modinit_mask |= 1 << chn;
}
void analogin_free(analogin_t *obj)
{
const struct nu_modinit_s *modinit = get_modinit(obj->adc, adc_modinit_tab);
MBED_ASSERT(modinit->modname == (int) obj->adc);
/* Module subindex (aka channel) */
uint32_t chn = NU_MODSUBINDEX(obj->adc);
EADC_T *eadc_base = (EADC_T *) NU_MODBASE(obj->adc);
/* Channel-level windup from here */
/* Mark channel free */
eadc_modinit_mask &= ~(1 << chn);
/* Module-level windup from here */
/* See analogin_init() for reason */
if (! eadc_modinit_mask) {
/* Disable EADC module */
EADC_Close(eadc_base);
/* Disable IP clock */
CLK_DisableModuleClock(modinit->clkidx);
}
/* Free up pins */
gpio_set(obj->pin);
obj->pin = NC;
}
uint16_t analogin_read_u16(analogin_t *obj)
{
EADC_T *eadc_base = (EADC_T *) NU_MODBASE(obj->adc);

View File

@ -84,6 +84,37 @@ void analogin_init(analogin_t *obj, PinName pin)
eadc_modinit_mask |= 1 << chn;
}
void analogin_free(analogin_t *obj)
{
const struct nu_modinit_s *modinit = get_modinit(obj->adc, adc_modinit_tab);
MBED_ASSERT(modinit->modname == (int) obj->adc);
/* Module subindex (aka channel) */
uint32_t chn = NU_MODSUBINDEX(obj->adc);
EADC_T *eadc_base = (EADC_T *) NU_MODBASE(obj->adc);
/* Channel-level windup from here */
/* Mark channel free */
eadc_modinit_mask &= ~(1 << chn);
/* Module-level windup from here */
/* See analogin_init() for reason */
if (! eadc_modinit_mask) {
/* Disable EADC module */
EADC_Close(eadc_base);
/* Disable IP clock */
CLK_DisableModuleClock(modinit->clkidx);
}
/* Free up pins */
gpio_set(obj->pin);
obj->pin = NC;
}
uint16_t analogin_read_u16(analogin_t *obj)
{
EADC_T *eadc_base = (EADC_T *) NU_MODBASE(obj->adc);

View File

@ -83,6 +83,37 @@ void analogin_init(analogin_t *obj, PinName pin)
eadc_modinit_mask |= 1 << chn;
}
void analogin_free(analogin_t *obj)
{
const struct nu_modinit_s *modinit = get_modinit(obj->adc, adc_modinit_tab);
MBED_ASSERT(modinit->modname == (int) obj->adc);
/* Module subindex (aka channel) */
uint32_t chn = NU_MODSUBINDEX(obj->adc);
EADC_T *eadc_base = (EADC_T *) NU_MODBASE(obj->adc);
/* Channel-level windup from here */
/* Mark channel free */
eadc_modinit_mask &= ~(1 << chn);
/* Module-level windup from here */
/* See analogin_init() for reason */
if (! eadc_modinit_mask) {
/* Disable EADC module */
EADC_Close(eadc_base);
/* Disable IP clock */
CLK_DisableModuleClock(modinit->clkidx);
}
/* Free up pins */
gpio_set(obj->pin);
obj->pin = NC;
}
uint16_t analogin_read_u16(analogin_t *obj)
{
EADC_T *eadc_base = (EADC_T *) NU_MODBASE(obj->adc);

View File

@ -94,30 +94,49 @@ void analogin_init(analogin_t *obj, PinName pin)
adc_busy_flag = 0;
}
void analogin_deinit(PinName pin)
void analogin_free(analogin_t *obj)
{
analogin_t obj;
obj.adc = (ADCName) pinmap_peripheral(pin, PinMap_ADC);
MBED_ASSERT(obj.adc != (ADCName) NC);
const struct nu_modinit_s *modinit = get_modinit(obj->adc, adc_modinit_tab);
MBED_ASSERT(modinit->modname == (int) obj->adc);
/* Module subindex (aka channel) */
uint32_t chn = NU_MODSUBINDEX(obj->adc);
ADC_T *adc_base = (ADC_T *) NU_MODBASE(obj->adc);
const struct nu_modinit_s *modinit = get_modinit(obj.adc, adc_modinit_tab);
MBED_ASSERT(modinit != NULL);
MBED_ASSERT((ADCName) modinit->modname == obj.adc);
ADC_T *adc_base = (ADC_T *) NU_MODBASE(obj.adc);
uint32_t chn = NU_MODSUBINDEX(obj.adc);
// Wait for ADC is not busy, due to all ADC channels share the same module
while (adc_busy_flag != 0) {
wait_us(100);
}
adc_busy_flag = 1;
// Disable channel N
/* Channel-level windup from here */
/* Mark channel free */
adc_modinit_mask &= ~(1 << chn);
adc_base->CHEN &= ~(1 << chn);
adc_modinit_mask &= ~(1 << chn);
/* Module-level windup from here */
/* See analogin_init() for reason */
if (! adc_modinit_mask) {
/* Disable ADC module */
ADC_Close(adc_base);
// Power off ADC
ADC_POWER_DOWN(adc_base);
/* Disable IP clock */
CLK_DisableModuleClock(modinit->clkidx);
}
adc_busy_flag = 0;
/* Free up pins */
gpio_set(obj->pin);
obj->pin = NC;
}
uint16_t analogin_read_u16(analogin_t *obj)

View File

@ -85,6 +85,37 @@ void analogin_init(analogin_t *obj, PinName pin)
eadc_modinit_mask |= 1 << smp_mod;
}
void analogin_free(analogin_t *obj)
{
const struct nu_modinit_s *modinit = get_modinit(obj->adc, adc_modinit_tab);
MBED_ASSERT(modinit->modname == (int) obj->adc);
/* Module subindex (aka channel) */
uint32_t chn = NU_MODSUBINDEX(obj->adc);
EADC_T *eadc_base = (EADC_T *) NU_MODBASE(obj->adc);
/* Channel-level windup from here */
/* Mark channel free */
eadc_modinit_mask &= ~(1 << chn);
/* Module-level windup from here */
/* See analogin_init() for reason */
if (! eadc_modinit_mask) {
/* Disable EADC module */
EADC_Close(eadc_base);
/* Disable IP clock */
CLK_DisableModuleClock(modinit->clkidx);
}
/* Free up pins */
gpio_set(obj->pin);
obj->pin = NC;
}
uint16_t analogin_read_u16(analogin_t *obj)
{
EADC_T *eadc_base = (EADC_T *) NU_MODBASE(obj->adc);