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.
pull/703/head
Masao Hamanaka 2014-11-14 21:20:46 +09:00
parent e53ae9e840
commit cde105eaa5
1 changed files with 166 additions and 26 deletions

View File

@ -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) {