Skip to content

Commit f2236d2

Browse files
author
Seppo Takalo
authored
Merge pull request #11131 from lrusinowicz/serial_free_fix
FUTURE_SEQUANA: Add missing serial_free() implementation
2 parents e69a7c9 + 16372f3 commit f2236d2

File tree

1 file changed

+56
-7
lines changed

1 file changed

+56
-7
lines changed

targets/TARGET_Cypress/TARGET_PSOC6_FUTURE/serial_api.c

Lines changed: 56 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -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-
206199
static 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+
449498
void serial_baud(serial_t *obj_in, int baudrate)
450499
{
451500
serial_obj_t *obj = OBJ_P(obj_in);

0 commit comments

Comments
 (0)