From cde105eaa5bb51621057743b7bc33dc503e5c94f Mon Sep 17 00:00:00 2001 From: Masao Hamanaka Date: Fri, 14 Nov 2014 21:20:46 +0900 Subject: [PATCH] Fixed a bug of serial interrupt I fixed a bug of serial interrupt as below. Serial TX/RX interrupt was not occur when TX/RX end. --- .../TARGET_RENESAS/TARGET_RZ_A1H/serial_api.c | 192 +++++++++++++++--- 1 file changed, 166 insertions(+), 26 deletions(-) diff --git a/libraries/mbed/targets/hal/TARGET_RENESAS/TARGET_RZ_A1H/serial_api.c b/libraries/mbed/targets/hal/TARGET_RENESAS/TARGET_RZ_A1H/serial_api.c index d738af2c41..4f219ff48c 100644 --- a/libraries/mbed/targets/hal/TARGET_RENESAS/TARGET_RZ_A1H/serial_api.c +++ b/libraries/mbed/targets/hal/TARGET_RENESAS/TARGET_RZ_A1H/serial_api.c @@ -142,7 +142,7 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) { b0 SPB2DT - Serial port break data : High-level */ //obj->uart->SCSPTR |= 0x0000u; - obj->uart->SCSCR = 0x0030; + obj->uart->SCSCR = 0x00F0; // pinout the chosen uart pinmap_pinout(tx, PinMap_UART_TX); @@ -156,10 +156,11 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) { case P_SCIF4: obj->index = 4; break; case P_SCIF5: obj->index = 5; break; case P_SCIF6: obj->index = 6; break; + case P_SCIF7: obj->index = 7; break; } uart_data[obj->index].sw_rts.pin = NC; uart_data[obj->index].sw_cts.pin = NC; - serial_set_flow_control(obj, FlowControlNone, NC, NC); +// serial_set_flow_control(obj, FlowControlNone, NC, NC); is_stdio_uart = (uart == STDIO_UART) ? (1) : (0); @@ -219,11 +220,105 @@ void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_b * INTERRUPTS HANDLING ******************************************************************************/ -void uart0_irq() {irq_handler(0, RxIrq);//dummy call +static void uart_tx_irq(IRQn_Type irq_num, uint32_t index) { + uint16_t dummy_read; + /* Clear TDFE */ + switch (index) { + case 0: + dummy_read = SCFSR_0; + SCFSR_0 = (dummy_read & ~0x0060); + break; + case 1: + dummy_read = SCFSR_1; + SCFSR_1 = (dummy_read & ~0x0060); + break; + case 2: + dummy_read = SCFSR_2; + SCFSR_2 = (dummy_read & ~0x0060); + break; + case 3: + dummy_read = SCFSR_3; + SCFSR_3 = (dummy_read & ~0x0060); + break; + case 4: + dummy_read = SCFSR_4; + SCFSR_4 = (dummy_read & ~0x0060); + break; + case 5: + dummy_read = SCFSR_5; + SCFSR_5 = (dummy_read & ~0x0060); + break; + case 6: + dummy_read = SCFSR_6; + SCFSR_6 = (dummy_read & ~0x0060); + break; + case 7: + dummy_read = SCFSR_7; + SCFSR_7 = (dummy_read & ~0x0060); + break; } -void uart1_irq() {/*uart_irq((LPC_UART1->IIR >> 1) & 0x7, 1, (LPC_UART_TypeDef*)LPC_UART1);*/} -void uart2_irq() {/*uart_irq((LPC_UART2->IIR >> 1) & 0x7, 2, (LPC_UART_TypeDef*)LPC_UART2);*/} -void uart3_irq() {/*uart_irq((LPC_UART3->IIR >> 1) & 0x7, 3, (LPC_UART_TypeDef*)LPC_UART3);*/} + irq_handler(uart_data[index].serial_irq_id, TxIrq); + GIC_EndInterrupt(irq_num); +} + +static void uart_rx_irq(IRQn_Type irq_num, uint32_t index) { + uint16_t dummy_read; + /* Clear RDF */ + switch (index) { + case 0: + dummy_read = SCFSR_0; + SCFSR_0 = (dummy_read & ~0x0003); + break; + case 1: + dummy_read = SCFSR_1; + SCFSR_1 = (dummy_read & ~0x0003); + break; + case 2: + dummy_read = SCFSR_2; + SCFSR_2 = (dummy_read & ~0x0003); + break; + case 3: + dummy_read = SCFSR_3; + SCFSR_3 = (dummy_read & ~0x0003); + break; + case 4: + dummy_read = SCFSR_4; + SCFSR_4 = (dummy_read & ~0x0003); + break; + case 5: + dummy_read = SCFSR_5; + SCFSR_5 = (dummy_read & ~0x0003); + break; + case 6: + dummy_read = SCFSR_6; + SCFSR_6 = (dummy_read & ~0x0003); + break; + case 7: + dummy_read = SCFSR_7; + SCFSR_7 = (dummy_read & ~0x0003); + break; + } + irq_handler(uart_data[index].serial_irq_id, RxIrq); + GIC_EndInterrupt(irq_num); +} +/* TX handler */ +void uart0_tx_irq() {uart_tx_irq(SCIFTXI0_IRQn, 0);} +void uart1_tx_irq() {uart_tx_irq(SCIFTXI1_IRQn, 1);} +void uart2_tx_irq() {uart_tx_irq(SCIFTXI2_IRQn, 2);} +void uart3_tx_irq() {uart_tx_irq(SCIFTXI3_IRQn, 3);} +void uart4_tx_irq() {uart_tx_irq(SCIFTXI4_IRQn, 4);} +void uart5_tx_irq() {uart_tx_irq(SCIFTXI5_IRQn, 5);} +void uart6_tx_irq() {uart_tx_irq(SCIFTXI6_IRQn, 6);} +void uart7_tx_irq() {uart_tx_irq(SCIFTXI7_IRQn, 7);} +/* RX handler */ +void uart0_rx_irq() {uart_rx_irq(SCIFRXI0_IRQn, 0);} +void uart1_rx_irq() {uart_rx_irq(SCIFRXI1_IRQn, 1);} +void uart2_rx_irq() {uart_rx_irq(SCIFRXI2_IRQn, 2);} +void uart3_rx_irq() {uart_rx_irq(SCIFRXI3_IRQn, 3);} +void uart4_rx_irq() {uart_rx_irq(SCIFRXI4_IRQn, 4);} +void uart5_rx_irq() {uart_rx_irq(SCIFRXI5_IRQn, 5);} +void uart6_rx_irq() {uart_rx_irq(SCIFRXI6_IRQn, 6);} +void uart7_rx_irq() {uart_rx_irq(SCIFRXI7_IRQn, 7);} void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) { irq_handler = handler; @@ -231,27 +326,72 @@ void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) { } static void serial_irq_set_internal(serial_t *obj, SerialIrq irq, uint32_t enable) { -/* IRQn_Type irq_n = (IRQn_Type)0; - uint32_t vector = 0; - switch ((int)obj->uart) { - case UART_0: irq_n=UART0_IRQn; vector = (uint32_t)&uart0_irq; break; - case UART_1: irq_n=UART1_IRQn; vector = (uint32_t)&uart1_irq; break; - case UART_2: irq_n=UART2_IRQn; vector = (uint32_t)&uart2_irq; break; - case UART_3: irq_n=UART3_IRQn; vector = (uint32_t)&uart3_irq; break; + switch (obj->index){ + case 0: + InterruptHandlerRegister(SCIFTXI0_IRQn, (void (*)(uint32_t))uart0_tx_irq); + InterruptHandlerRegister(SCIFRXI0_IRQn, (void (*)(uint32_t))uart0_rx_irq); + GIC_SetPriority(SCIFTXI0_IRQn, 5); + GIC_SetPriority(SCIFRXI0_IRQn, 5); + GIC_EnableIRQ(SCIFTXI0_IRQn); + GIC_EnableIRQ(SCIFRXI0_IRQn); + break; + case 1: + InterruptHandlerRegister(SCIFTXI1_IRQn, (void (*)(uint32_t))uart1_tx_irq); + InterruptHandlerRegister(SCIFRXI1_IRQn, (void (*)(uint32_t))uart1_rx_irq); + GIC_SetPriority(SCIFTXI1_IRQn, 5); + GIC_SetPriority(SCIFRXI1_IRQn, 5); + GIC_EnableIRQ(SCIFTXI1_IRQn); + GIC_EnableIRQ(SCIFRXI1_IRQn); + break; + case 2: + InterruptHandlerRegister(SCIFTXI2_IRQn, (void (*)(uint32_t))uart2_tx_irq); + InterruptHandlerRegister(SCIFRXI2_IRQn, (void (*)(uint32_t))uart2_rx_irq); + GIC_SetPriority(SCIFTXI2_IRQn, 5); + GIC_SetPriority(SCIFRXI2_IRQn, 5); + GIC_EnableIRQ(SCIFTXI2_IRQn); + GIC_EnableIRQ(SCIFRXI2_IRQn); + break; + case 3: + InterruptHandlerRegister(SCIFTXI3_IRQn, (void (*)(uint32_t))uart3_tx_irq); + InterruptHandlerRegister(SCIFRXI3_IRQn, (void (*)(uint32_t))uart3_rx_irq); + GIC_SetPriority(SCIFTXI3_IRQn, 5); + GIC_SetPriority(SCIFRXI3_IRQn, 5); + GIC_EnableIRQ(SCIFTXI3_IRQn); + GIC_EnableIRQ(SCIFRXI3_IRQn); + break; + case 4: + InterruptHandlerRegister(SCIFTXI4_IRQn, (void (*)(uint32_t))uart4_tx_irq); + InterruptHandlerRegister(SCIFRXI4_IRQn, (void (*)(uint32_t))uart4_rx_irq); + GIC_SetPriority(SCIFTXI4_IRQn, 5); + GIC_SetPriority(SCIFRXI4_IRQn, 5); + GIC_EnableIRQ(SCIFTXI4_IRQn); + GIC_EnableIRQ(SCIFRXI4_IRQn); + break; + case 5: + InterruptHandlerRegister(SCIFTXI5_IRQn, (void (*)(uint32_t))uart5_tx_irq); + InterruptHandlerRegister(SCIFRXI5_IRQn, (void (*)(uint32_t))uart5_rx_irq); + GIC_SetPriority(SCIFTXI5_IRQn, 5); + GIC_SetPriority(SCIFRXI5_IRQn, 5); + GIC_EnableIRQ(SCIFTXI5_IRQn); + GIC_EnableIRQ(SCIFRXI5_IRQn); + break; + case 6: + InterruptHandlerRegister(SCIFTXI6_IRQn, (void (*)(uint32_t))uart6_tx_irq); + InterruptHandlerRegister(SCIFRXI6_IRQn, (void (*)(uint32_t))uart6_rx_irq); + GIC_SetPriority(SCIFTXI6_IRQn, 5); + GIC_SetPriority(SCIFRXI6_IRQn, 5); + GIC_EnableIRQ(SCIFTXI6_IRQn); + GIC_EnableIRQ(SCIFRXI6_IRQn); + break; + case 7: + InterruptHandlerRegister(SCIFTXI7_IRQn, (void (*)(uint32_t))uart7_tx_irq); + InterruptHandlerRegister(SCIFRXI7_IRQn, (void (*)(uint32_t))uart7_rx_irq); + GIC_SetPriority(SCIFTXI7_IRQn, 5); + GIC_SetPriority(SCIFRXI7_IRQn, 5); + GIC_EnableIRQ(SCIFTXI7_IRQn); + GIC_EnableIRQ(SCIFRXI7_IRQn); + break; } - - if (enable) { - obj->uart->IER |= 1 << irq; - //NVIC_SetVector(irq_n, vector); - //NVIC_EnableIRQ(irq_n); - } else if ((TxIrq == irq) || (uart_data[obj->index].rx_irq_set_api + uart_data[obj->index].rx_irq_set_flow == 0)) { // disable - int all_disabled = 0; - SerialIrq other_irq = (irq == RxIrq) ? (TxIrq) : (RxIrq); - obj->uart->IER &= ~(1 << irq); - all_disabled = (obj->uart->IER & (1 << other_irq)) == 0; - if (all_disabled) ; - //NVIC_DisableIRQ(irq_n); - }*/ } void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) {