@@ -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
123142uint16_t analogin_read_u16 (analogin_t * obj )
0 commit comments