Simple mbed library with macros
Dependents: SimpleTimer SimpleUART SimpleTimer Stoppuhr1
serial.h@21:ce11d7ff88af, 2010-11-27 (annotated)
- Committer:
- Alkorin
- Date:
- Sat Nov 27 19:08:38 2010 +0000
- Revision:
- 21:ce11d7ff88af
- Parent:
- 18:aa026d9f7fc0
Added some Ethernet/IP structures
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Alkorin | 8:f8b47457fdcf | 1 | /* |
Alkorin | 8:f8b47457fdcf | 2 | * Copyright or © or Copr. 2010, Thomas SOETE |
Alkorin | 8:f8b47457fdcf | 3 | * |
Alkorin | 8:f8b47457fdcf | 4 | * Author e-mail: thomas@soete.org |
Alkorin | 14:23c6d41cb377 | 5 | * Library website : http://mbed.org/users/Alkorin/libraries/SimpleLib/ |
Alkorin | 8:f8b47457fdcf | 6 | * |
Alkorin | 8:f8b47457fdcf | 7 | * This software is governed by the CeCILL license under French law and |
Alkorin | 8:f8b47457fdcf | 8 | * abiding by the rules of distribution of free software. You can use, |
Alkorin | 8:f8b47457fdcf | 9 | * modify and/ or redistribute the software under the terms of the CeCILL |
Alkorin | 8:f8b47457fdcf | 10 | * license as circulated by CEA, CNRS and INRIA at the following URL |
Alkorin | 8:f8b47457fdcf | 11 | * "http://www.cecill.info". |
Alkorin | 8:f8b47457fdcf | 12 | * |
Alkorin | 8:f8b47457fdcf | 13 | * As a counterpart to the access to the source code and rights to copy, |
Alkorin | 8:f8b47457fdcf | 14 | * modify and redistribute granted by the license, users are provided only |
Alkorin | 8:f8b47457fdcf | 15 | * with a limited warranty and the software's author, the holder of the |
Alkorin | 8:f8b47457fdcf | 16 | * economic rights, and the successive licensors have only limited |
Alkorin | 8:f8b47457fdcf | 17 | * liability. |
Alkorin | 8:f8b47457fdcf | 18 | * |
Alkorin | 8:f8b47457fdcf | 19 | * In this respect, the user's attention is drawn to the risks associated |
Alkorin | 8:f8b47457fdcf | 20 | * with loading, using, modifying and/or developing or reproducing the |
Alkorin | 8:f8b47457fdcf | 21 | * software by the user in light of its specific status of free software, |
Alkorin | 8:f8b47457fdcf | 22 | * that may mean that it is complicated to manipulate, and that also |
Alkorin | 8:f8b47457fdcf | 23 | * therefore means that it is reserved for developers and experienced |
Alkorin | 8:f8b47457fdcf | 24 | * professionals having in-depth computer knowledge. Users are therefore |
Alkorin | 8:f8b47457fdcf | 25 | * encouraged to load and test the software's suitability as regards their |
Alkorin | 8:f8b47457fdcf | 26 | * requirements in conditions enabling the security of their systems and/or |
Alkorin | 8:f8b47457fdcf | 27 | * data to be ensured and, more generally, to use and operate it in the |
Alkorin | 8:f8b47457fdcf | 28 | * same conditions as regards security. |
Alkorin | 8:f8b47457fdcf | 29 | * |
Alkorin | 8:f8b47457fdcf | 30 | * The fact that you are presently reading this means that you have had |
Alkorin | 8:f8b47457fdcf | 31 | * knowledge of the CeCILL license and that you accept its terms. |
Alkorin | 8:f8b47457fdcf | 32 | */ |
Alkorin | 8:f8b47457fdcf | 33 | |
Alkorin | 18:aa026d9f7fc0 | 34 | #ifndef __SIMPLELIB_SERIAL_H__ |
Alkorin | 18:aa026d9f7fc0 | 35 | #define __SIMPLELIB_SERIAL_H__ |
Alkorin | 4:afddc4848b6c | 36 | |
Alkorin | 4:afddc4848b6c | 37 | #include "mbed_globals.h" |
Alkorin | 5:b3aa0a49e21f | 38 | #include "interrupts.h" |
Alkorin | 4:afddc4848b6c | 39 | |
Alkorin | 15:66150de7876b | 40 | /********************************** |
Alkorin | 15:66150de7876b | 41 | * Simple Serial Managment * |
Alkorin | 15:66150de7876b | 42 | ********************************** |
Alkorin | 5:b3aa0a49e21f | 43 | * The interrupt handler is : * |
Alkorin | 7:8443cecf62d1 | 44 | * SERIAL_INTERRUPT_HANDLER(void) * |
Alkorin | 7:8443cecf62d1 | 45 | * UART0 : Serial over USB * |
Alkorin | 7:8443cecf62d1 | 46 | * UART1 : TX p13, RX p14 * |
Alkorin | 7:8443cecf62d1 | 47 | * UART2 : TX p28, RX p27 * |
Alkorin | 15:66150de7876b | 48 | * UART3 : TX p9, RX p10 * |
Alkorin | 15:66150de7876b | 49 | **********************************/ |
Alkorin | 5:b3aa0a49e21f | 50 | |
Alkorin | 15:66150de7876b | 51 | /** Registers **/ |
Alkorin | 7:8443cecf62d1 | 52 | // Serial port (Choose UARTn (0,1,2,3)) |
Alkorin | 5:b3aa0a49e21f | 53 | #define UART_NUMBER UART0 |
Alkorin | 5:b3aa0a49e21f | 54 | #define UART_BASE TOKENPASTE2(LPC_,UART_NUMBER) |
Alkorin | 5:b3aa0a49e21f | 55 | |
Alkorin | 5:b3aa0a49e21f | 56 | // Peripheral Clock Selection registers (See 4.7.3 p56) |
Alkorin | 7:8443cecf62d1 | 57 | #define UART0_PCLK_REG (LPC_SC->PCLKSEL0) |
Alkorin | 7:8443cecf62d1 | 58 | #define UART1_PCLK_REG (LPC_SC->PCLKSEL0) |
Alkorin | 7:8443cecf62d1 | 59 | #define UART2_PCLK_REG (LPC_SC->PCLKSEL1) |
Alkorin | 7:8443cecf62d1 | 60 | #define UART3_PCLK_REG (LPC_SC->PCLKSEL1) |
Alkorin | 7:8443cecf62d1 | 61 | #define UART_PCLK_REG TOKENPASTE2(UART_NUMBER,_PCLK_REG) |
Alkorin | 7:8443cecf62d1 | 62 | |
Alkorin | 7:8443cecf62d1 | 63 | #define UART0_PCLK_OFFSET 6 |
Alkorin | 7:8443cecf62d1 | 64 | #define UART1_PCLK_OFFSET 8 |
Alkorin | 7:8443cecf62d1 | 65 | #define UART2_PCLK_OFFSET 16 |
Alkorin | 7:8443cecf62d1 | 66 | #define UART3_PCLK_OFFSET 18 |
Alkorin | 7:8443cecf62d1 | 67 | #define UART_PCLK_OFFSET TOKENPASTE2(UART_NUMBER,_PCLK_OFFSET) |
Alkorin | 7:8443cecf62d1 | 68 | |
Alkorin | 5:b3aa0a49e21f | 69 | #define UART0_PCLK ((LPC_SC->PCLKSEL0 >> 6) & 0x03) |
Alkorin | 7:8443cecf62d1 | 70 | #define UART1_PCLK ((LPC_SC->PCLKSEL0 >> 8) & 0x03) |
Alkorin | 5:b3aa0a49e21f | 71 | #define UART2_PCLK ((LPC_SC->PCLKSEL1 >> 16) & 0x03) |
Alkorin | 5:b3aa0a49e21f | 72 | #define UART3_PCLK ((LPC_SC->PCLKSEL1 >> 18) & 0x03) |
Alkorin | 5:b3aa0a49e21f | 73 | #define UART_PCLK TOKENPASTE2(UART_NUMBER,_PCLK) |
Alkorin | 5:b3aa0a49e21f | 74 | |
Alkorin | 7:8443cecf62d1 | 75 | // Pin Function Select register (See 8.5.1-8 p108) |
Alkorin | 7:8443cecf62d1 | 76 | #define UART0RX_PINSEL_REG (LPC_PINCON->PINSEL0) |
Alkorin | 7:8443cecf62d1 | 77 | #define UART1RX_PINSEL_REG (LPC_PINCON->PINSEL1) |
Alkorin | 7:8443cecf62d1 | 78 | #define UART2RX_PINSEL_REG (LPC_PINCON->PINSEL0) |
Alkorin | 7:8443cecf62d1 | 79 | #define UART3RX_PINSEL_REG (LPC_PINCON->PINSEL0) |
Alkorin | 7:8443cecf62d1 | 80 | #define UARTRX_PINSEL_REG TOKENPASTE2(UART_NUMBER,RX_PINSEL_REG) |
Alkorin | 7:8443cecf62d1 | 81 | |
Alkorin | 7:8443cecf62d1 | 82 | #define UART0TX_PINSEL_REG (LPC_PINCON->PINSEL0) |
Alkorin | 7:8443cecf62d1 | 83 | #define UART1TX_PINSEL_REG (LPC_PINCON->PINSEL0) |
Alkorin | 7:8443cecf62d1 | 84 | #define UART2TX_PINSEL_REG (LPC_PINCON->PINSEL0) |
Alkorin | 7:8443cecf62d1 | 85 | #define UART3TX_PINSEL_REG (LPC_PINCON->PINSEL0) |
Alkorin | 7:8443cecf62d1 | 86 | #define UARTTX_PINSEL_REG TOKENPASTE2(UART_NUMBER,TX_PINSEL_REG) |
Alkorin | 7:8443cecf62d1 | 87 | |
Alkorin | 7:8443cecf62d1 | 88 | #define UART0RX_PINSEL_OFFSET 6 |
Alkorin | 7:8443cecf62d1 | 89 | #define UART1RX_PINSEL_OFFSET 0 |
Alkorin | 7:8443cecf62d1 | 90 | #define UART2RX_PINSEL_OFFSET 22 |
Alkorin | 7:8443cecf62d1 | 91 | #define UART3RX_PINSEL_OFFSET 2 |
Alkorin | 7:8443cecf62d1 | 92 | #define UARTRX_PINSEL_OFFSET TOKENPASTE2(UART_NUMBER,RX_PINSEL_OFFSET) |
Alkorin | 7:8443cecf62d1 | 93 | |
Alkorin | 7:8443cecf62d1 | 94 | #define UART0TX_PINSEL_OFFSET 4 |
Alkorin | 7:8443cecf62d1 | 95 | #define UART1TX_PINSEL_OFFSET 30 |
Alkorin | 7:8443cecf62d1 | 96 | #define UART2TX_PINSEL_OFFSET 20 |
Alkorin | 7:8443cecf62d1 | 97 | #define UART3TX_PINSEL_OFFSET 0 |
Alkorin | 7:8443cecf62d1 | 98 | #define UARTTX_PINSEL_OFFSET TOKENPASTE2(UART_NUMBER,TX_PINSEL_OFFSET) |
Alkorin | 7:8443cecf62d1 | 99 | |
Alkorin | 15:66150de7876b | 100 | #define UART0_PINSEL_VALUE 1U |
Alkorin | 15:66150de7876b | 101 | #define UART1_PINSEL_VALUE 1U |
Alkorin | 15:66150de7876b | 102 | #define UART2_PINSEL_VALUE 1U |
Alkorin | 15:66150de7876b | 103 | #define UART3_PINSEL_VALUE 2U |
Alkorin | 7:8443cecf62d1 | 104 | #define UART_PINSEL_VALUE TOKENPASTE2(UART_NUMBER,_PINSEL_VALUE) |
Alkorin | 7:8443cecf62d1 | 105 | |
Alkorin | 15:66150de7876b | 106 | /** Interrupt handlers **/ |
Alkorin | 11:20e2539b6c2b | 107 | #define SERIAL_INTERRUPT_HANDLER EXTERN_C void __IRQ TOKENPASTE2(UART_NUMBER,_IRQHandler) |
Alkorin | 4:afddc4848b6c | 108 | |
Alkorin | 4:afddc4848b6c | 109 | /** Bits **/ |
Alkorin | 4:afddc4848b6c | 110 | // RBR Interrupt Enable (UnIER, 14.4.4 p302) |
Alkorin | 4:afddc4848b6c | 111 | #define RBR_INT_BIT 0 |
Alkorin | 4:afddc4848b6c | 112 | // Receiver Data Ready (UnLSR, 14.4.8 p306) |
Alkorin | 4:afddc4848b6c | 113 | #define RDR_BIT 0 |
Alkorin | 4:afddc4848b6c | 114 | // Transmitter Holding Register Empty (UnLSR, 14.4.8 p306) |
Alkorin | 4:afddc4848b6c | 115 | #define THRE_BIT 5 |
Alkorin | 5:b3aa0a49e21f | 116 | // RBR Interrupt Enable (UnIER, 14.4.4 p302) |
Alkorin | 5:b3aa0a49e21f | 117 | #define SERIAL_INT_RX 1 |
Alkorin | 5:b3aa0a49e21f | 118 | // THRE Interrupt Enable (UnIER, 14.4.4 p302) |
Alkorin | 5:b3aa0a49e21f | 119 | #define SERIAL_INT_TX 2 |
Alkorin | 5:b3aa0a49e21f | 120 | // Divisor Latch Access Bit (UnLCR, 14.4.7 p306) |
Alkorin | 5:b3aa0a49e21f | 121 | #define DLA_BIT 7 |
Alkorin | 7:8443cecf62d1 | 122 | // Power Control for Peripherals (PCONP, 4.8.7.1 p63) |
Alkorin | 7:8443cecf62d1 | 123 | #define UART0_PCONP_BIT 3 |
Alkorin | 7:8443cecf62d1 | 124 | #define UART1_PCONP_BIT 4 |
Alkorin | 7:8443cecf62d1 | 125 | #define UART2_PCONP_BIT 24 |
Alkorin | 7:8443cecf62d1 | 126 | #define UART3_PCONP_BIT 25 |
Alkorin | 4:afddc4848b6c | 127 | |
Alkorin | 4:afddc4848b6c | 128 | /** Macros **/ |
Alkorin | 15:66150de7876b | 129 | #define SERIAL_PUTCHAR(c) do { \ |
Alkorin | 15:66150de7876b | 130 | while (GET_BIT_VALUE(UART_BASE->LSR, THRE_BIT) == 0); \ |
Alkorin | 15:66150de7876b | 131 | UART_BASE->THR = c; \ |
Alkorin | 16:73f0f5d18800 | 132 | } while(0) |
Alkorin | 5:b3aa0a49e21f | 133 | |
Alkorin | 5:b3aa0a49e21f | 134 | #define SERIAL_DATA_TO_READ() (GET_BIT_VALUE(UART_BASE->LSR, RDR_BIT) == 1) |
Alkorin | 5:b3aa0a49e21f | 135 | |
Alkorin | 5:b3aa0a49e21f | 136 | #define SERIAL_GETCHAR() (UART_BASE->RBR) |
Alkorin | 4:afddc4848b6c | 137 | |
Alkorin | 5:b3aa0a49e21f | 138 | // Enable interrupt for RX or TX (SERIAL_INT_RX and SERIAL_INT_TX) |
Alkorin | 15:66150de7876b | 139 | #define SERIAL_ENABLE_INTERRUPT(value) do { \ |
Alkorin | 15:66150de7876b | 140 | UART_BASE->IER = value; \ |
Alkorin | 15:66150de7876b | 141 | ENABLE_INTERRUPT(TOKENPASTE2(UART_NUMBER,_IRQn)); \ |
Alkorin | 15:66150de7876b | 142 | } while(0) |
Alkorin | 6:9e1310782abf | 143 | |
Alkorin | 13:89420fa6f561 | 144 | extern __INLINE void SERIAL_INIT() |
Alkorin | 7:8443cecf62d1 | 145 | { |
Alkorin | 7:8443cecf62d1 | 146 | // Enable UARTn |
Alkorin | 7:8443cecf62d1 | 147 | SET_BIT_VALUE(LPC_SC->PCONP, TOKENPASTE2(UART_NUMBER,_PCONP_BIT) , 1); |
Alkorin | 7:8443cecf62d1 | 148 | // Enable FIFO and reset RX/TX FIFO (See 14.4.6 p305) |
Alkorin | 7:8443cecf62d1 | 149 | UART_BASE->FCR = 0x07; |
Alkorin | 7:8443cecf62d1 | 150 | // 8-bits, No Parity, 1 stop bit (See 14.4.7 p306) |
Alkorin | 7:8443cecf62d1 | 151 | UART_BASE->LCR = 0x03; |
Alkorin | 7:8443cecf62d1 | 152 | // Set CCLK as Peripheral Clock for UART (96MHz with mbed library) |
Alkorin | 15:66150de7876b | 153 | UART_PCLK_REG = (UART_PCLK_REG & (~(3UL << UART_PCLK_OFFSET))) | (1U << UART_PCLK_OFFSET); |
Alkorin | 7:8443cecf62d1 | 154 | // Define Pin's functions as UART |
Alkorin | 15:66150de7876b | 155 | UARTRX_PINSEL_REG = (UARTRX_PINSEL_REG & (~(3U << UARTRX_PINSEL_OFFSET))) | (UART_PINSEL_VALUE << UARTRX_PINSEL_OFFSET); |
Alkorin | 15:66150de7876b | 156 | UARTTX_PINSEL_REG = (UARTTX_PINSEL_REG & (~(3U << UARTTX_PINSEL_OFFSET))) | (UART_PINSEL_VALUE << UARTTX_PINSEL_OFFSET); |
Alkorin | 7:8443cecf62d1 | 157 | } |
Alkorin | 4:afddc4848b6c | 158 | |
Alkorin | 4:afddc4848b6c | 159 | // See 14.4.5 p303 |
Alkorin | 13:89420fa6f561 | 160 | extern __INLINE int SERIAL_CHECK_INTERRUPT(void) { |
Alkorin | 4:afddc4848b6c | 161 | uint32_t serialStatus = UART_BASE->IIR; |
Alkorin | 4:afddc4848b6c | 162 | |
Alkorin | 4:afddc4848b6c | 163 | if (serialStatus & 1) // IntStatus, 1 = No Interrupt is pending. |
Alkorin | 4:afddc4848b6c | 164 | return 0; |
Alkorin | 4:afddc4848b6c | 165 | |
Alkorin | 4:afddc4848b6c | 166 | serialStatus = (serialStatus >> 1) & 0x3; // IntId, 2 = More than threshold data to read, 6 = Some caracters to read |
Alkorin | 4:afddc4848b6c | 167 | if (serialStatus != 2 && serialStatus != 6) |
Alkorin | 4:afddc4848b6c | 168 | return 0; |
Alkorin | 4:afddc4848b6c | 169 | |
Alkorin | 4:afddc4848b6c | 170 | return 1; |
Alkorin | 4:afddc4848b6c | 171 | } |
Alkorin | 4:afddc4848b6c | 172 | |
Alkorin | 13:89420fa6f561 | 173 | extern __INLINE void SERIAL_SETBAUD(unsigned int baud) { |
Alkorin | 5:b3aa0a49e21f | 174 | // Peripheral Clock Selection register bit values (See Table 42, p57) |
Alkorin | 8:f8b47457fdcf | 175 | uint16_t divisorValue = (SystemCoreClock / 16 / baud); |
Alkorin | 8:f8b47457fdcf | 176 | #if 0 |
Alkorin | 8:f8b47457fdcf | 177 | // Peripheral Clock for UART is set to CCLK in SERIAL_INIT. Divisor is then 1. |
Alkorin | 8:f8b47457fdcf | 178 | // Else, use code below |
Alkorin | 8:f8b47457fdcf | 179 | static int divisors[4] = { 4, 1, 2, 8 }; |
Alkorin | 8:f8b47457fdcf | 180 | uint16_t divisorValue = ((SystemCoreClock / 16 / baud) / divisors[UART_PCLK]); |
Alkorin | 8:f8b47457fdcf | 181 | #endif |
Alkorin | 5:b3aa0a49e21f | 182 | |
Alkorin | 6:9e1310782abf | 183 | UART_BASE->LCR |= (1 << DLA_BIT); |
Alkorin | 5:b3aa0a49e21f | 184 | UART_BASE->DLM = (uint8_t) (divisorValue >> 8); |
Alkorin | 5:b3aa0a49e21f | 185 | UART_BASE->DLL = (uint8_t) divisorValue; |
Alkorin | 6:9e1310782abf | 186 | UART_BASE->LCR &= ~(1 << DLA_BIT); |
Alkorin | 5:b3aa0a49e21f | 187 | } |
Alkorin | 4:afddc4848b6c | 188 | |
Alkorin | 0:aa3c3d1a5918 | 189 | #endif |