t
Fork of mbed-dev by
Diff: targets/hal/TARGET_ARM_SSG/TARGET_MPS2/serial_api.c
- Revision:
- 80:bdf1132a57cf
- Parent:
- 0:9b334a45a8ff
- Child:
- 144:ef7eb2e8f9f7
diff -r 7f02dc905b68 -r bdf1132a57cf targets/hal/TARGET_ARM_SSG/TARGET_MPS2/serial_api.c --- a/targets/hal/TARGET_ARM_SSG/TARGET_MPS2/serial_api.c Wed Mar 02 10:15:13 2016 +0000 +++ b/targets/hal/TARGET_ARM_SSG/TARGET_MPS2/serial_api.c Wed Mar 02 14:30:11 2016 +0000 @@ -30,18 +30,22 @@ ******************************************************************************/ static const PinMap PinMap_UART_TX[] = { - {USBTX , UART_0, 0}, - {UART_TX1, UART_1, 0}, + {USBTX , UART_0, 0}, + {XB_TX , UART_1, 0}, + {SH0_TX , UART_2, 0}, + {SH1_TX , UART_3, 0}, {NC , NC , 0} }; static const PinMap PinMap_UART_RX[] = { - {USBRX , UART_0, 0}, - {UART_RX1, UART_1, 0}, - {NC , NC , 0} + {USBRX , UART_0, 0}, + {XB_RX , UART_1, 0}, + {SH0_RX , UART_2, 0}, + {SH1_RX , UART_3, 0}, + {NC , NC , 0} }; -#define UART_NUM 3 +#define UART_NUM 4 static uart_irq_handler irq_handler; @@ -69,13 +73,73 @@ obj->uart = (CMSDK_UART_TypeDef *)uart; //set baud rate and enable Uart in normarl mode (RX and TX enabled) - switch (uart) { - case UART_0: CMSDK_UART0->CTRL = 0; // Disable UART when changing configuration - CMSDK_UART0->CTRL = 0x3; // Normal mode - break; - case UART_1: CMSDK_UART1->CTRL = 0; // Disable UART when changing configuration - CMSDK_UART1->CTRL = 0x3; // Normal mode - break; + switch (uart) + { + case UART_0: + { + CMSDK_UART0->CTRL = 0x00; // Disable UART when changing configuration + if((int)uart_tx != NC) + { + CMSDK_UART0->CTRL |= 0x01; // TX enable + } else { + CMSDK_UART0->CTRL &= 0xFFFE; // TX disable + } + + + if((int)uart_rx != NC) + { + CMSDK_UART0->CTRL |= 0x02; // RX enable + } else { + CMSDK_UART0->CTRL &= 0xFFFD; // RX disable + } + + } + break; + case UART_1: //XBEE SOCKET UART + { + CMSDK_UART1->CTRL = 0x00; // Disable UART when changing configuration + if((int)tx != NC) + { + CMSDK_UART1->CTRL = 0x1; // TX enable + CMSDK_GPIO1->ALTFUNCSET |= 0x0100; + } + if((int)rx != NC) + { + CMSDK_UART1->CTRL |= 0x2; // RX enable + CMSDK_GPIO1->ALTFUNCSET |= 0x0080; + } + } + break; + case UART_2: //Sheild0 UART + { + CMSDK_UART3->CTRL = 0x00; // Disable UART when changing configuration + if((int)tx != NC) + { + CMSDK_UART3->CTRL = 0x1; // TX enable + CMSDK_GPIO0->ALTFUNCSET |= 0x0010; + } + if((int)rx != NC) + { + CMSDK_UART3->CTRL |= 0x2; // RX enable + CMSDK_GPIO0->ALTFUNCSET |= 0x0001; + } + } + break; + case UART_3: //Sheild1 UART + { + CMSDK_UART4->CTRL = 0x00; // Disable UART when changing configuration + if((int)tx != NC) + { + CMSDK_UART4->CTRL = 0x1; // TX enable + CMSDK_GPIO1->ALTFUNCSET |= 0x4000; + } + if((int)rx != NC) + { + CMSDK_UART4->CTRL |= 0x2; // RX enable + CMSDK_GPIO1->ALTFUNCSET |= 0x0400; + } + } + break; } // set default baud rate and format @@ -88,6 +152,8 @@ switch (uart) { case UART_0: obj->index = 0; break; case UART_1: obj->index = 1; break; + case UART_2: obj->index = 2; break; + case UART_3: obj->index = 3; break; } uart_data[obj->index].sw_rts.pin = NC; uart_data[obj->index].sw_cts.pin = NC; @@ -102,6 +168,7 @@ } void serial_free(serial_t *obj) { + uart_data[obj->index].serial_irq_id = 0; } // serial_baud @@ -110,24 +177,26 @@ // The MPS2 has a simple divider to control the baud rate. The formula is: // // Baudrate = PCLK / BAUDDIV - // - // PCLK = 25 Mhz - // so for a desired baud rate of 9600 - // 25000000 / 9600 = 2604 + // + // PCLK = 25 Mhz + // so for a desired baud rate of 9600 + // 25000000 / 9600 = 2604 // - //check to see if minimum baud value entered - int baudrate_div = 0; - baudrate_div = 25000000 / baudrate; - if(baudrate >= 16){ + //check to see if minimum baud value entered + int baudrate_div = 0; + baudrate_div = SystemCoreClock / baudrate; + if(baudrate >= 16){ switch ((int)obj->uart) { case UART_0: CMSDK_UART0->BAUDDIV = baudrate_div; break; case UART_1: CMSDK_UART1->BAUDDIV = baudrate_div; break; + case UART_2: CMSDK_UART3->BAUDDIV = baudrate_div; break; + case UART_3: CMSDK_UART4->BAUDDIV = baudrate_div; break; default: error("serial_baud"); break; } - } else { - error("serial_baud"); - } - + } else { + error("serial_baud"); + } + } void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) { @@ -138,24 +207,58 @@ ******************************************************************************/ static inline void uart_irq(uint32_t intstatus, uint32_t index, CMSDK_UART_TypeDef *puart) { SerialIrq irq_type; - switch (intstatus) { - case 1: irq_type = TxIrq; break; - case 2: irq_type = RxIrq; break; + switch (intstatus) + { + case 1: + { + irq_type = TxIrq; + } + break; + + case 2: + { + irq_type = RxIrq; + } + break; + default: return; - } - if ((RxIrq == irq_type) && (NC != uart_data[index].sw_rts.pin)) { + } /* End of Switch */ + + if ((RxIrq == irq_type) && (NC != uart_data[index].sw_rts.pin)) + { gpio_write(&uart_data[index].sw_rts, 1); // Disable interrupt if it wasn't enabled by other part of the application if (!uart_data[index].rx_irq_set_api) - puart->CTRL &= ~(1 << RxIrq); + { + /* Disable Rx interrupt */ + puart->CTRL &= ~(CMSDK_UART_CTRL_RXIRQEN_Msk); + } } + if (uart_data[index].serial_irq_id != 0) + { if ((irq_type != RxIrq) || (uart_data[index].rx_irq_set_api)) + { irq_handler(uart_data[index].serial_irq_id, irq_type); + } + } + + if( irq_type == TxIrq ) + { + /* Clear the TX interrupt Flag */ + puart->INTCLEAR |= 0x01; + } + else + { + /* Clear the Rx interupt Flag */ + puart->INTCLEAR |= 0x02; + } } void uart0_irq() {uart_irq(CMSDK_UART0->INTSTATUS & 0x3, 0, (CMSDK_UART_TypeDef*)CMSDK_UART0);} void uart1_irq() {uart_irq(CMSDK_UART1->INTSTATUS & 0x3, 1, (CMSDK_UART_TypeDef*)CMSDK_UART1);} +void uart2_irq() {uart_irq(CMSDK_UART3->INTSTATUS & 0x3, 2, (CMSDK_UART_TypeDef*)CMSDK_UART3);} +void uart3_irq() {uart_irq(CMSDK_UART4->INTSTATUS & 0x3, 3, (CMSDK_UART_TypeDef*)CMSDK_UART4);} void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) { irq_handler = handler; @@ -163,30 +266,66 @@ } static void serial_irq_set_internal(serial_t *obj, SerialIrq irq, uint32_t enable) { + /* Declare a variable of type IRQn, initialise to 0 */ IRQn_Type irq_n = (IRQn_Type)0; uint32_t vector = 0; - switch ((int)obj->uart) { - case UART_0: irq_n=((irq>> 2) ? UARTRX0_IRQn : UARTTX0_IRQn); vector = (uint32_t)&uart0_irq; break; - case UART_1: irq_n=((irq>> 2) ? UARTRX1_IRQn : UARTTX1_IRQn); vector = (uint32_t)&uart1_irq; break; + switch ((int)obj->uart) + { + case UART_0: + { + irq_n = (( irq == TxIrq ) ? UARTTX0_IRQn : UARTRX0_IRQn); + vector = (uint32_t)&uart0_irq; + } + break; + + case UART_1: + { + irq_n = (( irq == TxIrq ) ? UARTTX1_IRQn : UARTRX1_IRQn); + vector = (uint32_t)&uart1_irq; + } + break; + case UART_2: + { + irq_n = (( irq == TxIrq ) ? UARTTX3_IRQn : UARTRX3_IRQn); + vector = (uint32_t)&uart2_irq; + } + break; + case UART_3: + { + irq_n = (( irq == TxIrq ) ? UARTTX4_IRQn : UARTRX4_IRQn); + vector = (uint32_t)&uart3_irq; + } + break; } - - if (enable) { - obj->uart->CTRL |= 1 << irq; + + if (enable) + { + if( irq == TxIrq ) + { + /* Transmit IRQ, set appripriate enable */ + + /* set TX interrupt enable in CTRL REG */ + obj->uart->CTRL |= CMSDK_UART_CTRL_TXIRQEN_Msk; + } + else + { + /* set Rx interrupt on in CTRL REG */ + obj->uart->CTRL |= CMSDK_UART_CTRL_RXIRQEN_Msk; + } 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->CTRL &= ~(1 << irq); - all_disabled = (obj->uart->CTRL & (1 << other_irq)) == 0; - if (all_disabled) + + } + else + { /* Disable IRQ */ + + obj->uart->CTRL &= ~(1 << (irq + 2)); + NVIC_DisableIRQ(irq_n); } } void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) { - if (RxIrq == irq) - uart_data[obj->index].rx_irq_set_api = enable; serial_irq_set_internal(obj, irq, enable); } @@ -205,11 +344,11 @@ } int serial_readable(serial_t *obj) { - return obj->uart->STATE & 2; + return obj->uart->STATE & 0x2; } int serial_writable(serial_t *obj) { - return obj->uart->STATE & 1; + return obj->uart->STATE & 0x1; } void serial_clear(serial_t *obj) {