Simple mbed library with macros
Dependents: SimpleTimer SimpleUART SimpleTimer Stoppuhr1
serial.h@6:9e1310782abf, 2010-11-13 (annotated)
- Committer:
- Alkorin
- Date:
- Sat Nov 13 14:47:51 2010 +0000
- Revision:
- 6:9e1310782abf
- Parent:
- 5:b3aa0a49e21f
- Child:
- 7:8443cecf62d1
Fixed a bug in SERIAL_SETBAUD
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Alkorin | 4:afddc4848b6c | 1 | #ifndef __SERIAL_H__ |
Alkorin | 4:afddc4848b6c | 2 | #define __SERIAL_H__ |
Alkorin | 4:afddc4848b6c | 3 | |
Alkorin | 4:afddc4848b6c | 4 | #include "mbed_globals.h" |
Alkorin | 5:b3aa0a49e21f | 5 | #include "interrupts.h" |
Alkorin | 4:afddc4848b6c | 6 | |
Alkorin | 5:b3aa0a49e21f | 7 | /* Simple Serial Managment * |
Alkorin | 5:b3aa0a49e21f | 8 | * The interrupt handler is : * |
Alkorin | 5:b3aa0a49e21f | 9 | * SERIAL_INTERRUPT_HANDLER(void) */ |
Alkorin | 5:b3aa0a49e21f | 10 | |
Alkorin | 5:b3aa0a49e21f | 11 | // Serial port (Choose UARTn (0,2,3)) |
Alkorin | 5:b3aa0a49e21f | 12 | #define UART_NUMBER UART0 |
Alkorin | 5:b3aa0a49e21f | 13 | #define UART_BASE TOKENPASTE2(LPC_,UART_NUMBER) |
Alkorin | 5:b3aa0a49e21f | 14 | |
Alkorin | 5:b3aa0a49e21f | 15 | // Peripheral Clock Selection registers (See 4.7.3 p56) |
Alkorin | 5:b3aa0a49e21f | 16 | #define UART0_PCLK ((LPC_SC->PCLKSEL0 >> 6) & 0x03) |
Alkorin | 5:b3aa0a49e21f | 17 | #define UART2_PCLK ((LPC_SC->PCLKSEL1 >> 16) & 0x03) |
Alkorin | 5:b3aa0a49e21f | 18 | #define UART3_PCLK ((LPC_SC->PCLKSEL1 >> 18) & 0x03) |
Alkorin | 5:b3aa0a49e21f | 19 | #define UART_PCLK TOKENPASTE2(UART_NUMBER,_PCLK) |
Alkorin | 5:b3aa0a49e21f | 20 | |
Alkorin | 5:b3aa0a49e21f | 21 | // Interrupt handlers |
Alkorin | 5:b3aa0a49e21f | 22 | #define SERIAL_INTERRUPT_HANDLER extern "C" void __irq TOKENPASTE2(UART_NUMBER,_IRQHandler) |
Alkorin | 4:afddc4848b6c | 23 | |
Alkorin | 4:afddc4848b6c | 24 | /** Bits **/ |
Alkorin | 4:afddc4848b6c | 25 | // RBR Interrupt Enable (UnIER, 14.4.4 p302) |
Alkorin | 4:afddc4848b6c | 26 | #define RBR_INT_BIT 0 |
Alkorin | 4:afddc4848b6c | 27 | // Receiver Data Ready (UnLSR, 14.4.8 p306) |
Alkorin | 4:afddc4848b6c | 28 | #define RDR_BIT 0 |
Alkorin | 4:afddc4848b6c | 29 | // Transmitter Holding Register Empty (UnLSR, 14.4.8 p306) |
Alkorin | 4:afddc4848b6c | 30 | #define THRE_BIT 5 |
Alkorin | 5:b3aa0a49e21f | 31 | // RBR Interrupt Enable (UnIER, 14.4.4 p302) |
Alkorin | 5:b3aa0a49e21f | 32 | #define SERIAL_INT_RX 1 |
Alkorin | 5:b3aa0a49e21f | 33 | // THRE Interrupt Enable (UnIER, 14.4.4 p302) |
Alkorin | 5:b3aa0a49e21f | 34 | #define SERIAL_INT_TX 2 |
Alkorin | 5:b3aa0a49e21f | 35 | // Divisor Latch Access Bit (UnLCR, 14.4.7 p306) |
Alkorin | 5:b3aa0a49e21f | 36 | #define DLA_BIT 7 |
Alkorin | 4:afddc4848b6c | 37 | |
Alkorin | 4:afddc4848b6c | 38 | /** Macros **/ |
Alkorin | 5:b3aa0a49e21f | 39 | #define SERIAL_PUTCHAR(c) while (GET_BIT_VALUE(UART_BASE->LSR, THRE_BIT) == 0); \ |
Alkorin | 5:b3aa0a49e21f | 40 | UART_BASE->THR = c; |
Alkorin | 5:b3aa0a49e21f | 41 | |
Alkorin | 5:b3aa0a49e21f | 42 | #define SERIAL_DATA_TO_READ() (GET_BIT_VALUE(UART_BASE->LSR, RDR_BIT) == 1) |
Alkorin | 5:b3aa0a49e21f | 43 | |
Alkorin | 5:b3aa0a49e21f | 44 | #define SERIAL_GETCHAR() (UART_BASE->RBR) |
Alkorin | 4:afddc4848b6c | 45 | |
Alkorin | 5:b3aa0a49e21f | 46 | // Enable interrupt for RX or TX (SERIAL_INT_RX and SERIAL_INT_TX) |
Alkorin | 5:b3aa0a49e21f | 47 | #define SERIAL_ENABLE_INTERRUPT(value) UART_BASE->IER = value; \ |
Alkorin | 5:b3aa0a49e21f | 48 | ENABLE_INTERRUPT(TOKENPASTE2(UART_NUMBER,_IRQn)); |
Alkorin | 6:9e1310782abf | 49 | |
Alkorin | 6:9e1310782abf | 50 | // UART0 is enabled by default ? |
Alkorin | 5:b3aa0a49e21f | 51 | #define SERIAL_INIT() LPC_SC->PCONP |= (1UL << 3); \ |
Alkorin | 5:b3aa0a49e21f | 52 | UART_BASE->FCR = 0x07; \ |
Alkorin | 5:b3aa0a49e21f | 53 | UART_BASE->LCR = 0x03; \ |
Alkorin | 5:b3aa0a49e21f | 54 | LPC_SC->PCLKSEL0 &= ~(3UL << 6); \ |
Alkorin | 5:b3aa0a49e21f | 55 | LPC_SC->PCLKSEL0 |= (1UL << 6); \ |
Alkorin | 5:b3aa0a49e21f | 56 | LPC_PINCON->PINSEL0 &= ~(1UL << 4); \ |
Alkorin | 5:b3aa0a49e21f | 57 | LPC_PINCON->PINSEL0 |= (1UL << 4); \ |
Alkorin | 5:b3aa0a49e21f | 58 | LPC_PINCON->PINSEL0 &= ~(1UL << 6); \ |
Alkorin | 6:9e1310782abf | 59 | LPC_PINCON->PINSEL0 |= (1UL << 6); |
Alkorin | 4:afddc4848b6c | 60 | |
Alkorin | 4:afddc4848b6c | 61 | // See 14.4.5 p303 |
Alkorin | 4:afddc4848b6c | 62 | inline int SERIAL_CHECK_INTERRUPT(void) { |
Alkorin | 4:afddc4848b6c | 63 | uint32_t serialStatus = UART_BASE->IIR; |
Alkorin | 4:afddc4848b6c | 64 | |
Alkorin | 4:afddc4848b6c | 65 | if (serialStatus & 1) // IntStatus, 1 = No Interrupt is pending. |
Alkorin | 4:afddc4848b6c | 66 | return 0; |
Alkorin | 4:afddc4848b6c | 67 | |
Alkorin | 4:afddc4848b6c | 68 | serialStatus = (serialStatus >> 1) & 0x3; // IntId, 2 = More than threshold data to read, 6 = Some caracters to read |
Alkorin | 4:afddc4848b6c | 69 | if (serialStatus != 2 && serialStatus != 6) |
Alkorin | 4:afddc4848b6c | 70 | return 0; |
Alkorin | 4:afddc4848b6c | 71 | |
Alkorin | 4:afddc4848b6c | 72 | return 1; |
Alkorin | 4:afddc4848b6c | 73 | } |
Alkorin | 4:afddc4848b6c | 74 | |
Alkorin | 5:b3aa0a49e21f | 75 | inline void SERIAL_SETBAUD(unsigned int baud) { |
Alkorin | 5:b3aa0a49e21f | 76 | // Peripheral Clock Selection register bit values (See Table 42, p57) |
Alkorin | 5:b3aa0a49e21f | 77 | static int divisors[4] = { 4, 1, 2, 8 }; |
Alkorin | 5:b3aa0a49e21f | 78 | |
Alkorin | 5:b3aa0a49e21f | 79 | uint16_t divisorValue = ((SystemCoreClock / 16 / baud) * divisors[UART_PCLK]); |
Alkorin | 5:b3aa0a49e21f | 80 | |
Alkorin | 6:9e1310782abf | 81 | UART_BASE->LCR |= (1 << DLA_BIT); |
Alkorin | 5:b3aa0a49e21f | 82 | UART_BASE->DLM = (uint8_t) (divisorValue >> 8); |
Alkorin | 5:b3aa0a49e21f | 83 | UART_BASE->DLL = (uint8_t) divisorValue; |
Alkorin | 6:9e1310782abf | 84 | UART_BASE->LCR &= ~(1 << DLA_BIT); |
Alkorin | 5:b3aa0a49e21f | 85 | } |
Alkorin | 4:afddc4848b6c | 86 | |
Alkorin | 0:aa3c3d1a5918 | 87 | #endif |