@@ -196,13 +196,6 @@ static IRQn_Type serial_irq_allocate_channel(serial_obj_t *obj)
196
196
#endif // M0
197
197
}
198
198
199
- static void serial_irq_release_channel (IRQn_Type channel , uint32_t serial_id )
200
- {
201
- #if defined (TARGET_MCU_PSOC6_M0 )
202
- cy_m0_nvic_release_channel (channel , CY_SERIAL_IRQN_ID + serial_id );
203
- #endif //M0
204
- }
205
-
206
199
static int serial_irq_setup_channel (serial_obj_t * obj )
207
200
{
208
201
cy_stc_sysint_t irq_config ;
@@ -230,6 +223,23 @@ static int serial_irq_setup_channel(serial_obj_t *obj)
230
223
return 0 ;
231
224
}
232
225
226
+ static void serial_irq_release_channel (serial_obj_t * obj )
227
+ {
228
+ irq_info_t * info = & irq_info [obj -> serial_id ];
229
+
230
+ if (info -> irqn != unconnected_IRQn ) {
231
+ MBED_ASSERT (info -> serial_obj == obj );
232
+ NVIC_DisableIRQ (info -> irqn );
233
+
234
+ #if defined (TARGET_MCU_PSOC6_M0 )
235
+ cy_m0_nvic_release_channel (info -> irqn , CY_SERIAL_IRQN_ID + obj -> serial_id );
236
+ #endif //M0
237
+ info -> irqn = unconnected_IRQn ;
238
+ info -> serial_obj = NULL ;
239
+ info -> handler = NULL ;
240
+ }
241
+ }
242
+
233
243
/*
234
244
* Calculates fractional divider value.
235
245
*/
@@ -292,6 +302,12 @@ static cy_en_sysclk_status_t serial_init_clock(serial_obj_t *obj, uint32_t baudr
292
302
return status ;
293
303
}
294
304
305
+ static void serial_deinit_clock (serial_obj_t * obj )
306
+ {
307
+ Cy_SysClk_PeriphDisableDivider (obj -> div_type , obj -> div_num );
308
+ cy_clk_free_divider (obj -> div_type , obj -> div_num );
309
+ }
310
+
295
311
/*
296
312
* Initializes i/o pins for UART tx/rx.
297
313
*/
@@ -328,6 +344,21 @@ static void serial_init_flow_pins(serial_obj_t *obj)
328
344
}
329
345
}
330
346
347
+ static void serial_deinit_pins (serial_obj_t * obj )
348
+ {
349
+ if (obj -> pin_tx != NC ) {
350
+ pin_function (obj -> pin_tx , CY_PIN_FUNCTION (HSIOM_SEL_GPIO , 0 , PullDown , PIN_INPUT ));
351
+ }
352
+ if (obj -> pin_rx != NC ) {
353
+ pin_function (obj -> pin_rx , CY_PIN_FUNCTION (HSIOM_SEL_GPIO , 0 , PullDown , PIN_INPUT ));
354
+ }
355
+ if (obj -> pin_rts != NC ) {
356
+ pin_function (obj -> pin_rts , CY_PIN_FUNCTION (HSIOM_SEL_GPIO , 0 , PullDown , PIN_INPUT ));
357
+ }
358
+ if (obj -> pin_cts != NC ) {
359
+ pin_function (obj -> pin_cts , CY_PIN_FUNCTION (HSIOM_SEL_GPIO , 0 , PullDown , PIN_INPUT ));
360
+ }
361
+ }
331
362
332
363
/*
333
364
* Initializes and enables UART/SCB.
@@ -446,6 +477,24 @@ void serial_init(serial_t *obj_in, PinName tx, PinName rx)
446
477
}
447
478
}
448
479
480
+ void serial_free (serial_t * obj_in )
481
+ {
482
+ serial_obj_t * obj = OBJ_P (obj_in );
483
+ bool is_stdio = (obj -> pin_tx == CY_STDIO_UART_TX ) || (obj -> pin_rx == CY_STDIO_UART_RX );
484
+
485
+ if (is_stdio && stdio_uart_inited ) {
486
+ /* stdio_uart just can't be released */
487
+ return ;
488
+ }
489
+
490
+ Cy_SCB_UART_Disable (obj -> base , NULL );
491
+ Cy_SysPm_UnregisterCallback (& obj -> pm_callback_handler );
492
+ serial_irq_release_channel (obj );
493
+ serial_deinit_pins (obj );
494
+ Cy_SCB_UART_DeInit (obj -> base );
495
+ serial_deinit_clock (obj );
496
+ }
497
+
449
498
void serial_baud (serial_t * obj_in , int baudrate )
450
499
{
451
500
serial_obj_t * obj = OBJ_P (obj_in );
0 commit comments