Skip to content

Commit 3abd026

Browse files
committed
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
1 parent cbf9f06 commit 3abd026

File tree

7 files changed

+221
-13
lines changed

7 files changed

+221
-13
lines changed

targets/TARGET_NUVOTON/TARGET_M2351/analogin_api.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,40 @@ void analogin_init(analogin_t *obj, PinName pin)
9292
eadc_modinit_mask |= 1 << chn;
9393
}
9494

95+
void analogin_free(analogin_t *obj)
96+
{
97+
const struct nu_modinit_s *modinit = get_modinit(obj->adc, adc_modinit_tab);
98+
MBED_ASSERT(modinit->modname == (int) obj->adc);
99+
100+
/* Module subindex (aka channel) */
101+
uint32_t chn = NU_MODSUBINDEX(obj->adc);
102+
103+
EADC_T *eadc_base = (EADC_T *) NU_MODBASE(obj->adc);
104+
105+
/* Channel-level windup from here */
106+
107+
/* Mark channel free */
108+
eadc_modinit_mask &= ~(1 << chn);
109+
110+
/* Module-level windup from here */
111+
112+
/* See analogin_init() for reason */
113+
if (! eadc_modinit_mask) {
114+
/* Disable EADC module */
115+
EADC_Close(eadc_base);
116+
117+
/* Disable IP clock
118+
*
119+
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
120+
*/
121+
CLK_DisableModuleClock_S(modinit->clkidx);
122+
}
123+
124+
/* Free up pins */
125+
gpio_set(obj->pin);
126+
obj->pin = NC;
127+
}
128+
95129
uint16_t analogin_read_u16(analogin_t *obj)
96130
{
97131
EADC_T *eadc_base = (EADC_T *) NU_MODBASE(obj->adc);

targets/TARGET_NUVOTON/TARGET_M251/analogin_api.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,37 @@ void analogin_init(analogin_t *obj, PinName pin)
9393
eadc_modinit_mask |= 1 << chn;
9494
}
9595

96+
void analogin_free(analogin_t *obj)
97+
{
98+
const struct nu_modinit_s *modinit = get_modinit(obj->adc, adc_modinit_tab);
99+
MBED_ASSERT(modinit->modname == (int) obj->adc);
100+
101+
/* Module subindex (aka channel) */
102+
uint32_t chn = NU_MODSUBINDEX(obj->adc);
103+
104+
EADC_T *eadc_base = (EADC_T *) NU_MODBASE(obj->adc);
105+
106+
/* Channel-level windup from here */
107+
108+
/* Mark channel free */
109+
eadc_modinit_mask &= ~(1 << chn);
110+
111+
/* Module-level windup from here */
112+
113+
/* See analogin_init() for reason */
114+
if (! eadc_modinit_mask) {
115+
/* Disable EADC module */
116+
EADC_Close(eadc_base);
117+
118+
/* Disable IP clock */
119+
CLK_DisableModuleClock(modinit->clkidx);
120+
}
121+
122+
/* Free up pins */
123+
gpio_set(obj->pin);
124+
obj->pin = NC;
125+
}
126+
96127
uint16_t analogin_read_u16(analogin_t *obj)
97128
{
98129
EADC_T *eadc_base = (EADC_T *) NU_MODBASE(obj->adc);

targets/TARGET_NUVOTON/TARGET_M261/analogin_api.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,37 @@ void analogin_init(analogin_t *obj, PinName pin)
8484
eadc_modinit_mask |= 1 << chn;
8585
}
8686

87+
void analogin_free(analogin_t *obj)
88+
{
89+
const struct nu_modinit_s *modinit = get_modinit(obj->adc, adc_modinit_tab);
90+
MBED_ASSERT(modinit->modname == (int) obj->adc);
91+
92+
/* Module subindex (aka channel) */
93+
uint32_t chn = NU_MODSUBINDEX(obj->adc);
94+
95+
EADC_T *eadc_base = (EADC_T *) NU_MODBASE(obj->adc);
96+
97+
/* Channel-level windup from here */
98+
99+
/* Mark channel free */
100+
eadc_modinit_mask &= ~(1 << chn);
101+
102+
/* Module-level windup from here */
103+
104+
/* See analogin_init() for reason */
105+
if (! eadc_modinit_mask) {
106+
/* Disable EADC module */
107+
EADC_Close(eadc_base);
108+
109+
/* Disable IP clock */
110+
CLK_DisableModuleClock(modinit->clkidx);
111+
}
112+
113+
/* Free up pins */
114+
gpio_set(obj->pin);
115+
obj->pin = NC;
116+
}
117+
87118
uint16_t analogin_read_u16(analogin_t *obj)
88119
{
89120
EADC_T *eadc_base = (EADC_T *) NU_MODBASE(obj->adc);

targets/TARGET_NUVOTON/TARGET_M451/analogin_api.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,37 @@ void analogin_init(analogin_t *obj, PinName pin)
8484
eadc_modinit_mask |= 1 << chn;
8585
}
8686

87+
void analogin_free(analogin_t *obj)
88+
{
89+
const struct nu_modinit_s *modinit = get_modinit(obj->adc, adc_modinit_tab);
90+
MBED_ASSERT(modinit->modname == (int) obj->adc);
91+
92+
/* Module subindex (aka channel) */
93+
uint32_t chn = NU_MODSUBINDEX(obj->adc);
94+
95+
EADC_T *eadc_base = (EADC_T *) NU_MODBASE(obj->adc);
96+
97+
/* Channel-level windup from here */
98+
99+
/* Mark channel free */
100+
eadc_modinit_mask &= ~(1 << chn);
101+
102+
/* Module-level windup from here */
103+
104+
/* See analogin_init() for reason */
105+
if (! eadc_modinit_mask) {
106+
/* Disable EADC module */
107+
EADC_Close(eadc_base);
108+
109+
/* Disable IP clock */
110+
CLK_DisableModuleClock(modinit->clkidx);
111+
}
112+
113+
/* Free up pins */
114+
gpio_set(obj->pin);
115+
obj->pin = NC;
116+
}
117+
87118
uint16_t analogin_read_u16(analogin_t *obj)
88119
{
89120
EADC_T *eadc_base = (EADC_T *) NU_MODBASE(obj->adc);

targets/TARGET_NUVOTON/TARGET_M480/analogin_api.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,37 @@ void analogin_init(analogin_t *obj, PinName pin)
8383
eadc_modinit_mask |= 1 << chn;
8484
}
8585

86+
void analogin_free(analogin_t *obj)
87+
{
88+
const struct nu_modinit_s *modinit = get_modinit(obj->adc, adc_modinit_tab);
89+
MBED_ASSERT(modinit->modname == (int) obj->adc);
90+
91+
/* Module subindex (aka channel) */
92+
uint32_t chn = NU_MODSUBINDEX(obj->adc);
93+
94+
EADC_T *eadc_base = (EADC_T *) NU_MODBASE(obj->adc);
95+
96+
/* Channel-level windup from here */
97+
98+
/* Mark channel free */
99+
eadc_modinit_mask &= ~(1 << chn);
100+
101+
/* Module-level windup from here */
102+
103+
/* See analogin_init() for reason */
104+
if (! eadc_modinit_mask) {
105+
/* Disable EADC module */
106+
EADC_Close(eadc_base);
107+
108+
/* Disable IP clock */
109+
CLK_DisableModuleClock(modinit->clkidx);
110+
}
111+
112+
/* Free up pins */
113+
gpio_set(obj->pin);
114+
obj->pin = NC;
115+
}
116+
86117
uint16_t analogin_read_u16(analogin_t *obj)
87118
{
88119
EADC_T *eadc_base = (EADC_T *) NU_MODBASE(obj->adc);

targets/TARGET_NUVOTON/TARGET_NANO100/analogin_api.c

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -94,30 +94,49 @@ void analogin_init(analogin_t *obj, PinName pin)
9494
adc_busy_flag = 0;
9595
}
9696

97-
void analogin_deinit(PinName pin)
97+
void analogin_free(analogin_t *obj)
9898
{
99-
analogin_t obj;
100-
obj.adc = (ADCName) pinmap_peripheral(pin, PinMap_ADC);
101-
MBED_ASSERT(obj.adc != (ADCName) NC);
99+
const struct nu_modinit_s *modinit = get_modinit(obj->adc, adc_modinit_tab);
100+
MBED_ASSERT(modinit->modname == (int) obj->adc);
101+
102+
/* Module subindex (aka channel) */
103+
uint32_t chn = NU_MODSUBINDEX(obj->adc);
104+
105+
ADC_T *adc_base = (ADC_T *) NU_MODBASE(obj->adc);
102106

103-
const struct nu_modinit_s *modinit = get_modinit(obj.adc, adc_modinit_tab);
104-
MBED_ASSERT(modinit != NULL);
105-
MBED_ASSERT((ADCName) modinit->modname == obj.adc);
106-
107-
ADC_T *adc_base = (ADC_T *) NU_MODBASE(obj.adc);
108-
uint32_t chn = NU_MODSUBINDEX(obj.adc);
109-
110107
// Wait for ADC is not busy, due to all ADC channels share the same module
111108
while (adc_busy_flag != 0) {
112109
wait_us(100);
113110
}
114111
adc_busy_flag = 1;
115-
116-
// Disable channel N
112+
113+
/* Channel-level windup from here */
114+
115+
/* Mark channel free */
116+
adc_modinit_mask &= ~(1 << chn);
117+
117118
adc_base->CHEN &= ~(1 << chn);
118119
adc_modinit_mask &= ~(1 << chn);
119120

121+
/* Module-level windup from here */
122+
123+
/* See analogin_init() for reason */
124+
if (! adc_modinit_mask) {
125+
/* Disable ADC module */
126+
ADC_Close(adc_base);
127+
128+
// Power off ADC
129+
ADC_POWER_DOWN(adc_base);
130+
131+
/* Disable IP clock */
132+
CLK_DisableModuleClock(modinit->clkidx);
133+
}
134+
120135
adc_busy_flag = 0;
136+
137+
/* Free up pins */
138+
gpio_set(obj->pin);
139+
obj->pin = NC;
121140
}
122141

123142
uint16_t analogin_read_u16(analogin_t *obj)

targets/TARGET_NUVOTON/TARGET_NUC472/analogin_api.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,37 @@ void analogin_init(analogin_t *obj, PinName pin)
8585
eadc_modinit_mask |= 1 << smp_mod;
8686
}
8787

88+
void analogin_free(analogin_t *obj)
89+
{
90+
const struct nu_modinit_s *modinit = get_modinit(obj->adc, adc_modinit_tab);
91+
MBED_ASSERT(modinit->modname == (int) obj->adc);
92+
93+
/* Module subindex (aka channel) */
94+
uint32_t chn = NU_MODSUBINDEX(obj->adc);
95+
96+
EADC_T *eadc_base = (EADC_T *) NU_MODBASE(obj->adc);
97+
98+
/* Channel-level windup from here */
99+
100+
/* Mark channel free */
101+
eadc_modinit_mask &= ~(1 << chn);
102+
103+
/* Module-level windup from here */
104+
105+
/* See analogin_init() for reason */
106+
if (! eadc_modinit_mask) {
107+
/* Disable EADC module */
108+
EADC_Close(eadc_base);
109+
110+
/* Disable IP clock */
111+
CLK_DisableModuleClock(modinit->clkidx);
112+
}
113+
114+
/* Free up pins */
115+
gpio_set(obj->pin);
116+
obj->pin = NC;
117+
}
118+
88119
uint16_t analogin_read_u16(analogin_t *obj)
89120
{
90121
EADC_T *eadc_base = (EADC_T *) NU_MODBASE(obj->adc);

0 commit comments

Comments
 (0)