@@ -196,13 +196,6 @@ static IRQn_Type serial_irq_allocate_channel(serial_obj_t *obj)
196196#endif // M0
197197}
198198
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-
206199static int serial_irq_setup_channel (serial_obj_t * obj )
207200{
208201 cy_stc_sysint_t irq_config ;
@@ -230,6 +223,23 @@ static int serial_irq_setup_channel(serial_obj_t *obj)
230223 return 0 ;
231224}
232225
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+
233243/*
234244 * Calculates fractional divider value.
235245 */
@@ -292,6 +302,12 @@ static cy_en_sysclk_status_t serial_init_clock(serial_obj_t *obj, uint32_t baudr
292302 return status ;
293303}
294304
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+
295311/*
296312 * Initializes i/o pins for UART tx/rx.
297313 */
@@ -328,6 +344,21 @@ static void serial_init_flow_pins(serial_obj_t *obj)
328344 }
329345}
330346
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+ }
331362
332363/*
333364 * Initializes and enables UART/SCB.
@@ -446,6 +477,24 @@ void serial_init(serial_t *obj_in, PinName tx, PinName rx)
446477 }
447478}
448479
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+
449498void serial_baud (serial_t * obj_in , int baudrate )
450499{
451500 serial_obj_t * obj = OBJ_P (obj_in );
0 commit comments