Simple mbed library with macros

Dependents:   SimpleTimer SimpleUART SimpleTimer Stoppuhr1

Committer:
Alkorin
Date:
Sat Nov 13 21:33:11 2010 +0000
Revision:
7:8443cecf62d1
Parent:
6:9e1310782abf
Child:
8:f8b47457fdcf
All UARTs should now work

Who changed what in which revision?

UserRevisionLine numberNew 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 7:8443cecf62d1 9 * SERIAL_INTERRUPT_HANDLER(void) *
Alkorin 7:8443cecf62d1 10 * UART0 : Serial over USB *
Alkorin 7:8443cecf62d1 11 * UART1 : TX p13, RX p14 *
Alkorin 7:8443cecf62d1 12 * UART2 : TX p28, RX p27 *
Alkorin 7:8443cecf62d1 13 * UART3 : TX p9, RX p10 */
Alkorin 5:b3aa0a49e21f 14
Alkorin 7:8443cecf62d1 15 // Serial port (Choose UARTn (0,1,2,3))
Alkorin 5:b3aa0a49e21f 16 #define UART_NUMBER UART0
Alkorin 5:b3aa0a49e21f 17 #define UART_BASE TOKENPASTE2(LPC_,UART_NUMBER)
Alkorin 5:b3aa0a49e21f 18
Alkorin 5:b3aa0a49e21f 19 // Peripheral Clock Selection registers (See 4.7.3 p56)
Alkorin 7:8443cecf62d1 20 #define UART0_PCLK_REG (LPC_SC->PCLKSEL0)
Alkorin 7:8443cecf62d1 21 #define UART1_PCLK_REG (LPC_SC->PCLKSEL0)
Alkorin 7:8443cecf62d1 22 #define UART2_PCLK_REG (LPC_SC->PCLKSEL1)
Alkorin 7:8443cecf62d1 23 #define UART3_PCLK_REG (LPC_SC->PCLKSEL1)
Alkorin 7:8443cecf62d1 24 #define UART_PCLK_REG TOKENPASTE2(UART_NUMBER,_PCLK_REG)
Alkorin 7:8443cecf62d1 25
Alkorin 7:8443cecf62d1 26 #define UART0_PCLK_OFFSET 6
Alkorin 7:8443cecf62d1 27 #define UART1_PCLK_OFFSET 8
Alkorin 7:8443cecf62d1 28 #define UART2_PCLK_OFFSET 16
Alkorin 7:8443cecf62d1 29 #define UART3_PCLK_OFFSET 18
Alkorin 7:8443cecf62d1 30 #define UART_PCLK_OFFSET TOKENPASTE2(UART_NUMBER,_PCLK_OFFSET)
Alkorin 7:8443cecf62d1 31
Alkorin 5:b3aa0a49e21f 32 #define UART0_PCLK ((LPC_SC->PCLKSEL0 >> 6) & 0x03)
Alkorin 7:8443cecf62d1 33 #define UART1_PCLK ((LPC_SC->PCLKSEL0 >> 8) & 0x03)
Alkorin 5:b3aa0a49e21f 34 #define UART2_PCLK ((LPC_SC->PCLKSEL1 >> 16) & 0x03)
Alkorin 5:b3aa0a49e21f 35 #define UART3_PCLK ((LPC_SC->PCLKSEL1 >> 18) & 0x03)
Alkorin 5:b3aa0a49e21f 36 #define UART_PCLK TOKENPASTE2(UART_NUMBER,_PCLK)
Alkorin 5:b3aa0a49e21f 37
Alkorin 7:8443cecf62d1 38 // Pin Function Select register (See 8.5.1-8 p108)
Alkorin 7:8443cecf62d1 39 #define UART0RX_PINSEL_REG (LPC_PINCON->PINSEL0)
Alkorin 7:8443cecf62d1 40 #define UART1RX_PINSEL_REG (LPC_PINCON->PINSEL1)
Alkorin 7:8443cecf62d1 41 #define UART2RX_PINSEL_REG (LPC_PINCON->PINSEL0)
Alkorin 7:8443cecf62d1 42 #define UART3RX_PINSEL_REG (LPC_PINCON->PINSEL0)
Alkorin 7:8443cecf62d1 43 #define UARTRX_PINSEL_REG TOKENPASTE2(UART_NUMBER,RX_PINSEL_REG)
Alkorin 7:8443cecf62d1 44
Alkorin 7:8443cecf62d1 45 #define UART0TX_PINSEL_REG (LPC_PINCON->PINSEL0)
Alkorin 7:8443cecf62d1 46 #define UART1TX_PINSEL_REG (LPC_PINCON->PINSEL0)
Alkorin 7:8443cecf62d1 47 #define UART2TX_PINSEL_REG (LPC_PINCON->PINSEL0)
Alkorin 7:8443cecf62d1 48 #define UART3TX_PINSEL_REG (LPC_PINCON->PINSEL0)
Alkorin 7:8443cecf62d1 49 #define UARTTX_PINSEL_REG TOKENPASTE2(UART_NUMBER,TX_PINSEL_REG)
Alkorin 7:8443cecf62d1 50
Alkorin 7:8443cecf62d1 51 #define UART0RX_PINSEL_OFFSET 6
Alkorin 7:8443cecf62d1 52 #define UART1RX_PINSEL_OFFSET 0
Alkorin 7:8443cecf62d1 53 #define UART2RX_PINSEL_OFFSET 22
Alkorin 7:8443cecf62d1 54 #define UART3RX_PINSEL_OFFSET 2
Alkorin 7:8443cecf62d1 55 #define UARTRX_PINSEL_OFFSET TOKENPASTE2(UART_NUMBER,RX_PINSEL_OFFSET)
Alkorin 7:8443cecf62d1 56
Alkorin 7:8443cecf62d1 57 #define UART0TX_PINSEL_OFFSET 4
Alkorin 7:8443cecf62d1 58 #define UART1TX_PINSEL_OFFSET 30
Alkorin 7:8443cecf62d1 59 #define UART2TX_PINSEL_OFFSET 20
Alkorin 7:8443cecf62d1 60 #define UART3TX_PINSEL_OFFSET 0
Alkorin 7:8443cecf62d1 61 #define UARTTX_PINSEL_OFFSET TOKENPASTE2(UART_NUMBER,TX_PINSEL_OFFSET)
Alkorin 7:8443cecf62d1 62
Alkorin 7:8443cecf62d1 63 #define UART0_PINSEL_VALUE 1UL
Alkorin 7:8443cecf62d1 64 #define UART1_PINSEL_VALUE 1UL
Alkorin 7:8443cecf62d1 65 #define UART2_PINSEL_VALUE 1UL
Alkorin 7:8443cecf62d1 66 #define UART3_PINSEL_VALUE 2UL
Alkorin 7:8443cecf62d1 67 #define UART_PINSEL_VALUE TOKENPASTE2(UART_NUMBER,_PINSEL_VALUE)
Alkorin 7:8443cecf62d1 68
Alkorin 5:b3aa0a49e21f 69 // Interrupt handlers
Alkorin 5:b3aa0a49e21f 70 #define SERIAL_INTERRUPT_HANDLER extern "C" void __irq TOKENPASTE2(UART_NUMBER,_IRQHandler)
Alkorin 4:afddc4848b6c 71
Alkorin 4:afddc4848b6c 72 /** Bits **/
Alkorin 4:afddc4848b6c 73 // RBR Interrupt Enable (UnIER, 14.4.4 p302)
Alkorin 4:afddc4848b6c 74 #define RBR_INT_BIT 0
Alkorin 4:afddc4848b6c 75 // Receiver Data Ready (UnLSR, 14.4.8 p306)
Alkorin 4:afddc4848b6c 76 #define RDR_BIT 0
Alkorin 4:afddc4848b6c 77 // Transmitter Holding Register Empty (UnLSR, 14.4.8 p306)
Alkorin 4:afddc4848b6c 78 #define THRE_BIT 5
Alkorin 5:b3aa0a49e21f 79 // RBR Interrupt Enable (UnIER, 14.4.4 p302)
Alkorin 5:b3aa0a49e21f 80 #define SERIAL_INT_RX 1
Alkorin 5:b3aa0a49e21f 81 // THRE Interrupt Enable (UnIER, 14.4.4 p302)
Alkorin 5:b3aa0a49e21f 82 #define SERIAL_INT_TX 2
Alkorin 5:b3aa0a49e21f 83 // Divisor Latch Access Bit (UnLCR, 14.4.7 p306)
Alkorin 5:b3aa0a49e21f 84 #define DLA_BIT 7
Alkorin 7:8443cecf62d1 85 // Power Control for Peripherals (PCONP, 4.8.7.1 p63)
Alkorin 7:8443cecf62d1 86 #define UART0_PCONP_BIT 3
Alkorin 7:8443cecf62d1 87 #define UART1_PCONP_BIT 4
Alkorin 7:8443cecf62d1 88 #define UART2_PCONP_BIT 24
Alkorin 7:8443cecf62d1 89 #define UART3_PCONP_BIT 25
Alkorin 4:afddc4848b6c 90
Alkorin 4:afddc4848b6c 91 /** Macros **/
Alkorin 5:b3aa0a49e21f 92 #define SERIAL_PUTCHAR(c) while (GET_BIT_VALUE(UART_BASE->LSR, THRE_BIT) == 0); \
Alkorin 5:b3aa0a49e21f 93 UART_BASE->THR = c;
Alkorin 5:b3aa0a49e21f 94
Alkorin 5:b3aa0a49e21f 95 #define SERIAL_DATA_TO_READ() (GET_BIT_VALUE(UART_BASE->LSR, RDR_BIT) == 1)
Alkorin 5:b3aa0a49e21f 96
Alkorin 5:b3aa0a49e21f 97 #define SERIAL_GETCHAR() (UART_BASE->RBR)
Alkorin 4:afddc4848b6c 98
Alkorin 5:b3aa0a49e21f 99 // Enable interrupt for RX or TX (SERIAL_INT_RX and SERIAL_INT_TX)
Alkorin 5:b3aa0a49e21f 100 #define SERIAL_ENABLE_INTERRUPT(value) UART_BASE->IER = value; \
Alkorin 5:b3aa0a49e21f 101 ENABLE_INTERRUPT(TOKENPASTE2(UART_NUMBER,_IRQn));
Alkorin 6:9e1310782abf 102
Alkorin 7:8443cecf62d1 103 inline void SERIAL_INIT()
Alkorin 7:8443cecf62d1 104 {
Alkorin 7:8443cecf62d1 105 // Enable UARTn
Alkorin 7:8443cecf62d1 106 SET_BIT_VALUE(LPC_SC->PCONP, TOKENPASTE2(UART_NUMBER,_PCONP_BIT) , 1);
Alkorin 7:8443cecf62d1 107 // Enable FIFO and reset RX/TX FIFO (See 14.4.6 p305)
Alkorin 7:8443cecf62d1 108 UART_BASE->FCR = 0x07;
Alkorin 7:8443cecf62d1 109 // 8-bits, No Parity, 1 stop bit (See 14.4.7 p306)
Alkorin 7:8443cecf62d1 110 UART_BASE->LCR = 0x03;
Alkorin 7:8443cecf62d1 111 // Set CCLK as Peripheral Clock for UART (96MHz with mbed library)
Alkorin 7:8443cecf62d1 112 UART_PCLK_REG = UART_PCLK_REG & ~(3UL << UART_PCLK_OFFSET) | (1UL << UART_PCLK_OFFSET);
Alkorin 7:8443cecf62d1 113 // Define Pin's functions as UART
Alkorin 7:8443cecf62d1 114 UARTRX_PINSEL_REG = UARTRX_PINSEL_REG & ~(3UL << UARTRX_PINSEL_OFFSET) | (UART_PINSEL_VALUE << UARTRX_PINSEL_OFFSET);
Alkorin 7:8443cecf62d1 115 UARTTX_PINSEL_REG = UARTTX_PINSEL_REG & ~(3UL << UARTTX_PINSEL_OFFSET) | (UART_PINSEL_VALUE << UARTTX_PINSEL_OFFSET);
Alkorin 7:8443cecf62d1 116 }
Alkorin 4:afddc4848b6c 117
Alkorin 4:afddc4848b6c 118 // See 14.4.5 p303
Alkorin 4:afddc4848b6c 119 inline int SERIAL_CHECK_INTERRUPT(void) {
Alkorin 4:afddc4848b6c 120 uint32_t serialStatus = UART_BASE->IIR;
Alkorin 4:afddc4848b6c 121
Alkorin 4:afddc4848b6c 122 if (serialStatus & 1) // IntStatus, 1 = No Interrupt is pending.
Alkorin 4:afddc4848b6c 123 return 0;
Alkorin 4:afddc4848b6c 124
Alkorin 4:afddc4848b6c 125 serialStatus = (serialStatus >> 1) & 0x3; // IntId, 2 = More than threshold data to read, 6 = Some caracters to read
Alkorin 4:afddc4848b6c 126 if (serialStatus != 2 && serialStatus != 6)
Alkorin 4:afddc4848b6c 127 return 0;
Alkorin 4:afddc4848b6c 128
Alkorin 4:afddc4848b6c 129 return 1;
Alkorin 4:afddc4848b6c 130 }
Alkorin 4:afddc4848b6c 131
Alkorin 5:b3aa0a49e21f 132 inline void SERIAL_SETBAUD(unsigned int baud) {
Alkorin 5:b3aa0a49e21f 133 // Peripheral Clock Selection register bit values (See Table 42, p57)
Alkorin 5:b3aa0a49e21f 134 static int divisors[4] = { 4, 1, 2, 8 };
Alkorin 5:b3aa0a49e21f 135
Alkorin 5:b3aa0a49e21f 136 uint16_t divisorValue = ((SystemCoreClock / 16 / baud) * divisors[UART_PCLK]);
Alkorin 5:b3aa0a49e21f 137
Alkorin 6:9e1310782abf 138 UART_BASE->LCR |= (1 << DLA_BIT);
Alkorin 5:b3aa0a49e21f 139 UART_BASE->DLM = (uint8_t) (divisorValue >> 8);
Alkorin 5:b3aa0a49e21f 140 UART_BASE->DLL = (uint8_t) divisorValue;
Alkorin 6:9e1310782abf 141 UART_BASE->LCR &= ~(1 << DLA_BIT);
Alkorin 5:b3aa0a49e21f 142 }
Alkorin 4:afddc4848b6c 143
Alkorin 0:aa3c3d1a5918 144 #endif