my implementation of mbed-like classes using the LPC1768 register access.
Dependents: registers-example RedWireBridge
This is just to satisfy my curiosity on how the mbed libraries work. I put it here just in case others are too. Every time I learn how another internal register works, I'll keep it here to save myself from future coding headaches.
working
- DigitalIn
- DigitalOut
- wait()
mostly working
- Serial
- Timer
- Ticker
- Timeout
Serial doesn't have all the methods that mbed had, but it works for me. (only UART0, so only over USB to the pc for now) Timer has the same limitations of mbed for default resolution (30 min limit), and if you start at the end of resolution and stop after it rolls back to 0, it doesn't take that into account. But I added the option to change resolution, so I can have longer timers.
For Ticker, I used a 100 microsecond timer instead of a 1 microsecond Timer, so the smallest interval in between function calls is 100 microseconds. (10KHz) However, this means that the maximum interval in between function calls is 59 hours. (untested)
The Timeout class, simply uses a Ticker, but then marks it as nonactive after the first function call. Automatically calls the detach() function when attaching it again, so no don't need to worry about it.
Serial.cpp@2:276fb0fe230c, 2013-01-03 (annotated)
- Committer:
- elevatorguy
- Date:
- Thu Jan 03 05:25:18 2013 +0000
- Revision:
- 2:276fb0fe230c
- Parent:
- 0:d2d9baa1a6d8
fix
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
elevatorguy | 0:d2d9baa1a6d8 | 1 | #include "Serial.h" |
elevatorguy | 0:d2d9baa1a6d8 | 2 | |
elevatorguy | 0:d2d9baa1a6d8 | 3 | void Serial::initUART0() |
elevatorguy | 0:d2d9baa1a6d8 | 4 | { |
elevatorguy | 0:d2d9baa1a6d8 | 5 | int pclk; |
elevatorguy | 0:d2d9baa1a6d8 | 6 | unsigned long int Fdiv; |
elevatorguy | 0:d2d9baa1a6d8 | 7 | |
elevatorguy | 0:d2d9baa1a6d8 | 8 | // PCLK_UART0 is being set to 1/4 of SystemCoreClock |
elevatorguy | 0:d2d9baa1a6d8 | 9 | pclk = SystemCoreClock / 4; |
elevatorguy | 0:d2d9baa1a6d8 | 10 | |
elevatorguy | 0:d2d9baa1a6d8 | 11 | // Turn on power to UART0 |
elevatorguy | 0:d2d9baa1a6d8 | 12 | LPC_SC->PCONP |= (1 << 3); |
elevatorguy | 0:d2d9baa1a6d8 | 13 | |
elevatorguy | 0:d2d9baa1a6d8 | 14 | // Turn on UART0 peripheral clock |
elevatorguy | 0:d2d9baa1a6d8 | 15 | LPC_SC->PCLKSEL0 &= ~(3 << 6); // mask |
elevatorguy | 0:d2d9baa1a6d8 | 16 | LPC_SC->PCLKSEL0 |= (0 << 6); // PCLK_periph = CCLK/4 ,, 6 is pclk for uart0 |
elevatorguy | 0:d2d9baa1a6d8 | 17 | |
elevatorguy | 0:d2d9baa1a6d8 | 18 | // Set PINSEL0 so that P0.2 = TXD0, P0.3 = RXD0 |
elevatorguy | 0:d2d9baa1a6d8 | 19 | LPC_PINCON->PINSEL0 &= ~0xf0; |
elevatorguy | 0:d2d9baa1a6d8 | 20 | LPC_PINCON->PINSEL0 |= ((1 << 4) | (1 << 6)); |
elevatorguy | 0:d2d9baa1a6d8 | 21 | |
elevatorguy | 0:d2d9baa1a6d8 | 22 | LPC_UART0->LCR = 0x83; // 8 bits, no Parity, 1 Stop bit, DLAB=1 |
elevatorguy | 0:d2d9baa1a6d8 | 23 | Fdiv = ( pclk / 16 ) / baudrate ; // Set baud rate |
elevatorguy | 0:d2d9baa1a6d8 | 24 | LPC_UART0->DLM = Fdiv / 256; |
elevatorguy | 0:d2d9baa1a6d8 | 25 | LPC_UART0->DLL = Fdiv % 256; |
elevatorguy | 0:d2d9baa1a6d8 | 26 | LPC_UART0->LCR = 0x03; // 8 bits, no Parity, 1 Stop bit DLAB = 0 |
elevatorguy | 0:d2d9baa1a6d8 | 27 | LPC_UART0->FCR = 0x07; // Enable and reset TX and RX FIFO |
elevatorguy | 0:d2d9baa1a6d8 | 28 | } |
elevatorguy | 0:d2d9baa1a6d8 | 29 | |
elevatorguy | 0:d2d9baa1a6d8 | 30 | Serial::Serial() |
elevatorguy | 0:d2d9baa1a6d8 | 31 | { |
elevatorguy | 0:d2d9baa1a6d8 | 32 | baudrate = 9600; |
elevatorguy | 0:d2d9baa1a6d8 | 33 | initUART0(); |
elevatorguy | 0:d2d9baa1a6d8 | 34 | } |
elevatorguy | 0:d2d9baa1a6d8 | 35 | |
elevatorguy | 0:d2d9baa1a6d8 | 36 | Serial::Serial(int br) |
elevatorguy | 0:d2d9baa1a6d8 | 37 | { |
elevatorguy | 0:d2d9baa1a6d8 | 38 | baudrate = br; |
elevatorguy | 0:d2d9baa1a6d8 | 39 | initUART0(); |
elevatorguy | 0:d2d9baa1a6d8 | 40 | } |
elevatorguy | 0:d2d9baa1a6d8 | 41 | |
elevatorguy | 0:d2d9baa1a6d8 | 42 | void Serial::putc(char c) |
elevatorguy | 0:d2d9baa1a6d8 | 43 | { |
elevatorguy | 0:d2d9baa1a6d8 | 44 | while( !(LPC_UART0->LSR & 0x20) ); // Block until tx empty |
elevatorguy | 0:d2d9baa1a6d8 | 45 | |
elevatorguy | 0:d2d9baa1a6d8 | 46 | LPC_UART0->THR = c; |
elevatorguy | 0:d2d9baa1a6d8 | 47 | } |
elevatorguy | 0:d2d9baa1a6d8 | 48 | |
elevatorguy | 0:d2d9baa1a6d8 | 49 | char Serial::getc() |
elevatorguy | 0:d2d9baa1a6d8 | 50 | { |
elevatorguy | 0:d2d9baa1a6d8 | 51 | char c; |
elevatorguy | 0:d2d9baa1a6d8 | 52 | while( !(LPC_UART0->LSR & 0x01) ); // wait until something received |
elevatorguy | 0:d2d9baa1a6d8 | 53 | c = LPC_UART0->RBR; // Read Receiver buffer register |
elevatorguy | 0:d2d9baa1a6d8 | 54 | return c; |
elevatorguy | 0:d2d9baa1a6d8 | 55 | } |
elevatorguy | 0:d2d9baa1a6d8 | 56 | |
elevatorguy | 0:d2d9baa1a6d8 | 57 | void Serial::printf(char* sendstring) |
elevatorguy | 0:d2d9baa1a6d8 | 58 | { |
elevatorguy | 0:d2d9baa1a6d8 | 59 | int i = 0; |
elevatorguy | 0:d2d9baa1a6d8 | 60 | // loop through until reach string's zero terminator |
elevatorguy | 0:d2d9baa1a6d8 | 61 | while (sendstring[i] != '\0') |
elevatorguy | 0:d2d9baa1a6d8 | 62 | { |
elevatorguy | 0:d2d9baa1a6d8 | 63 | putc(sendstring[i]); // print each character |
elevatorguy | 0:d2d9baa1a6d8 | 64 | i++; |
elevatorguy | 0:d2d9baa1a6d8 | 65 | } |
elevatorguy | 0:d2d9baa1a6d8 | 66 | } |
elevatorguy | 0:d2d9baa1a6d8 | 67 | |
elevatorguy | 0:d2d9baa1a6d8 | 68 | void Serial::printf(double number) |
elevatorguy | 0:d2d9baa1a6d8 | 69 | { |
elevatorguy | 0:d2d9baa1a6d8 | 70 | int numberAsInt = number; //truncates right of decimal point |
elevatorguy | 0:d2d9baa1a6d8 | 71 | printf(numberAsInt); |
elevatorguy | 0:d2d9baa1a6d8 | 72 | putc('.'); |
elevatorguy | 0:d2d9baa1a6d8 | 73 | int rightOfDecimal = (number-numberAsInt)*1000000000; //truncating smaller than 10^(-9) |
elevatorguy | 0:d2d9baa1a6d8 | 74 | printf(rightOfDecimal); |
elevatorguy | 0:d2d9baa1a6d8 | 75 | } |
elevatorguy | 0:d2d9baa1a6d8 | 76 | |
elevatorguy | 0:d2d9baa1a6d8 | 77 | void Serial::printf(double number, int res) |
elevatorguy | 0:d2d9baa1a6d8 | 78 | { |
elevatorguy | 0:d2d9baa1a6d8 | 79 | int numberAsInt = number; //truncates right of decimal point |
elevatorguy | 0:d2d9baa1a6d8 | 80 | printf(numberAsInt); |
elevatorguy | 0:d2d9baa1a6d8 | 81 | putc('.'); |
elevatorguy | 0:d2d9baa1a6d8 | 82 | int rightOfDecimal = (number-numberAsInt)*res; |
elevatorguy | 0:d2d9baa1a6d8 | 83 | printf(rightOfDecimal); |
elevatorguy | 0:d2d9baa1a6d8 | 84 | } |
elevatorguy | 0:d2d9baa1a6d8 | 85 | |
elevatorguy | 0:d2d9baa1a6d8 | 86 | void Serial::printf(int number) |
elevatorguy | 0:d2d9baa1a6d8 | 87 | { |
elevatorguy | 0:d2d9baa1a6d8 | 88 | //we go from left to right |
elevatorguy | 0:d2d9baa1a6d8 | 89 | int numofdigits = 0; |
elevatorguy | 0:d2d9baa1a6d8 | 90 | int temp2 = number; |
elevatorguy | 0:d2d9baa1a6d8 | 91 | while(temp2 > 0) |
elevatorguy | 0:d2d9baa1a6d8 | 92 | { |
elevatorguy | 0:d2d9baa1a6d8 | 93 | numofdigits = numofdigits + 1; |
elevatorguy | 0:d2d9baa1a6d8 | 94 | temp2 = temp2 / 10; |
elevatorguy | 0:d2d9baa1a6d8 | 95 | } |
elevatorguy | 0:d2d9baa1a6d8 | 96 | |
elevatorguy | 0:d2d9baa1a6d8 | 97 | while(numofdigits > 0) |
elevatorguy | 0:d2d9baa1a6d8 | 98 | { |
elevatorguy | 0:d2d9baa1a6d8 | 99 | int temp = numofdigits; |
elevatorguy | 0:d2d9baa1a6d8 | 100 | int position = 1; |
elevatorguy | 0:d2d9baa1a6d8 | 101 | while(temp > 1) |
elevatorguy | 0:d2d9baa1a6d8 | 102 | { |
elevatorguy | 0:d2d9baa1a6d8 | 103 | position = position * 10; |
elevatorguy | 0:d2d9baa1a6d8 | 104 | temp = temp - 1; |
elevatorguy | 0:d2d9baa1a6d8 | 105 | } |
elevatorguy | 0:d2d9baa1a6d8 | 106 | |
elevatorguy | 0:d2d9baa1a6d8 | 107 | int digit = (number / position) % 10; |
elevatorguy | 0:d2d9baa1a6d8 | 108 | |
elevatorguy | 0:d2d9baa1a6d8 | 109 | char character = tochar(digit); |
elevatorguy | 0:d2d9baa1a6d8 | 110 | putc(character); |
elevatorguy | 0:d2d9baa1a6d8 | 111 | numofdigits = numofdigits - 1; // |
elevatorguy | 0:d2d9baa1a6d8 | 112 | } |
elevatorguy | 0:d2d9baa1a6d8 | 113 | } |
elevatorguy | 0:d2d9baa1a6d8 | 114 | |
elevatorguy | 0:d2d9baa1a6d8 | 115 | // converts an individual digit into a character |
elevatorguy | 0:d2d9baa1a6d8 | 116 | char Serial::tochar(int digit) |
elevatorguy | 0:d2d9baa1a6d8 | 117 | { |
elevatorguy | 0:d2d9baa1a6d8 | 118 | int character = '0'; |
elevatorguy | 0:d2d9baa1a6d8 | 119 | switch (digit) |
elevatorguy | 0:d2d9baa1a6d8 | 120 | { |
elevatorguy | 0:d2d9baa1a6d8 | 121 | case 0 : |
elevatorguy | 0:d2d9baa1a6d8 | 122 | character = '0'; |
elevatorguy | 0:d2d9baa1a6d8 | 123 | break; |
elevatorguy | 0:d2d9baa1a6d8 | 124 | case 1 : |
elevatorguy | 0:d2d9baa1a6d8 | 125 | character = '1'; |
elevatorguy | 0:d2d9baa1a6d8 | 126 | break; |
elevatorguy | 0:d2d9baa1a6d8 | 127 | case 2 : |
elevatorguy | 0:d2d9baa1a6d8 | 128 | character = '2'; |
elevatorguy | 0:d2d9baa1a6d8 | 129 | break; |
elevatorguy | 0:d2d9baa1a6d8 | 130 | case 3 : |
elevatorguy | 0:d2d9baa1a6d8 | 131 | character = '3'; |
elevatorguy | 0:d2d9baa1a6d8 | 132 | break; |
elevatorguy | 0:d2d9baa1a6d8 | 133 | case 4 : |
elevatorguy | 0:d2d9baa1a6d8 | 134 | character = '4'; |
elevatorguy | 0:d2d9baa1a6d8 | 135 | break; |
elevatorguy | 0:d2d9baa1a6d8 | 136 | case 5 : |
elevatorguy | 0:d2d9baa1a6d8 | 137 | character = '5'; |
elevatorguy | 0:d2d9baa1a6d8 | 138 | break; |
elevatorguy | 0:d2d9baa1a6d8 | 139 | case 6 : |
elevatorguy | 0:d2d9baa1a6d8 | 140 | character = '6'; |
elevatorguy | 0:d2d9baa1a6d8 | 141 | break; |
elevatorguy | 0:d2d9baa1a6d8 | 142 | case 7 : |
elevatorguy | 0:d2d9baa1a6d8 | 143 | character = '7'; |
elevatorguy | 0:d2d9baa1a6d8 | 144 | break; |
elevatorguy | 0:d2d9baa1a6d8 | 145 | case 8 : |
elevatorguy | 0:d2d9baa1a6d8 | 146 | character = '8'; |
elevatorguy | 0:d2d9baa1a6d8 | 147 | break; |
elevatorguy | 0:d2d9baa1a6d8 | 148 | case 9 : |
elevatorguy | 0:d2d9baa1a6d8 | 149 | character = '9'; |
elevatorguy | 0:d2d9baa1a6d8 | 150 | break; |
elevatorguy | 0:d2d9baa1a6d8 | 151 | } |
elevatorguy | 0:d2d9baa1a6d8 | 152 | |
elevatorguy | 0:d2d9baa1a6d8 | 153 | return character; |
elevatorguy | 0:d2d9baa1a6d8 | 154 | } |