Satellite Observers Workbench. NOT yet complete, just published for forum posters to \"cherry pick\" pieces of code as requiered as an example.
debug/debug.c@0:0a841b89d614, 2010-10-11 (annotated)
- Committer:
- AjK
- Date:
- Mon Oct 11 10:34:55 2010 +0000
- Revision:
- 0:0a841b89d614
Totally Alpha quality as this project isn\t completed. Just publishing it as it answers many questions asked in the forums
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
AjK | 0:0a841b89d614 | 1 | /**************************************************************************** |
AjK | 0:0a841b89d614 | 2 | * Copyright 2010 Andy Kirkham, Stellar Technologies Ltd |
AjK | 0:0a841b89d614 | 3 | * |
AjK | 0:0a841b89d614 | 4 | * This file is part of the Satellite Observers Workbench (SOWB). |
AjK | 0:0a841b89d614 | 5 | * |
AjK | 0:0a841b89d614 | 6 | * SOWB is free software: you can redistribute it and/or modify |
AjK | 0:0a841b89d614 | 7 | * it under the terms of the GNU General Public License as published by |
AjK | 0:0a841b89d614 | 8 | * the Free Software Foundation, either version 3 of the License, or |
AjK | 0:0a841b89d614 | 9 | * (at your option) any later version. |
AjK | 0:0a841b89d614 | 10 | * |
AjK | 0:0a841b89d614 | 11 | * SOWB is distributed in the hope that it will be useful, |
AjK | 0:0a841b89d614 | 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
AjK | 0:0a841b89d614 | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
AjK | 0:0a841b89d614 | 14 | * GNU General Public License for more details. |
AjK | 0:0a841b89d614 | 15 | * |
AjK | 0:0a841b89d614 | 16 | * You should have received a copy of the GNU General Public License |
AjK | 0:0a841b89d614 | 17 | * along with SOWB. If not, see <http://www.gnu.org/licenses/>. |
AjK | 0:0a841b89d614 | 18 | * |
AjK | 0:0a841b89d614 | 19 | * $Id: main.cpp 5 2010-07-12 20:51:11Z ajk $ |
AjK | 0:0a841b89d614 | 20 | * |
AjK | 0:0a841b89d614 | 21 | ***************************************************************************/ |
AjK | 0:0a841b89d614 | 22 | |
AjK | 0:0a841b89d614 | 23 | #include "sowb.h" |
AjK | 0:0a841b89d614 | 24 | #include "debug.h" |
AjK | 0:0a841b89d614 | 25 | |
AjK | 0:0a841b89d614 | 26 | /* Design note. We do not use a txBufferOverflow flag like we |
AjK | 0:0a841b89d614 | 27 | do with the RX buffer as all calls to Uart0_putc() will |
AjK | 0:0a841b89d614 | 28 | block if there isn't room to send. It's up to the designer |
AjK | 0:0a841b89d614 | 29 | to either ensure they don't flood the TX buffer with too |
AjK | 0:0a841b89d614 | 30 | many debug strings or alternatively increase the buffer |
AjK | 0:0a841b89d614 | 31 | size to handle the higher amounts of traffic. */ |
AjK | 0:0a841b89d614 | 32 | |
AjK | 0:0a841b89d614 | 33 | volatile char txBuffer[UART0_TX_BUFFER_SIZE]; |
AjK | 0:0a841b89d614 | 34 | volatile char rxBuffer[UART0_RX_BUFFER_SIZE]; |
AjK | 0:0a841b89d614 | 35 | volatile unsigned char txBufferIn, txBufferOut; |
AjK | 0:0a841b89d614 | 36 | volatile unsigned char rxBufferIn, rxBufferOut; |
AjK | 0:0a841b89d614 | 37 | volatile bool txBufferFull, rxBufferFull, rxBufferOverflow; |
AjK | 0:0a841b89d614 | 38 | |
AjK | 0:0a841b89d614 | 39 | /** UART0_IRQHandler |
AjK | 0:0a841b89d614 | 40 | */ |
AjK | 0:0a841b89d614 | 41 | extern "C" void UART0_IRQHandler(void) __irq { |
AjK | 0:0a841b89d614 | 42 | uint32_t iir; |
AjK | 0:0a841b89d614 | 43 | |
AjK | 0:0a841b89d614 | 44 | iir = LPC_UART0->IIR; |
AjK | 0:0a841b89d614 | 45 | |
AjK | 0:0a841b89d614 | 46 | if (iir & 1) return; |
AjK | 0:0a841b89d614 | 47 | |
AjK | 0:0a841b89d614 | 48 | iir = (iir >> 1) & 0x3; |
AjK | 0:0a841b89d614 | 49 | |
AjK | 0:0a841b89d614 | 50 | if (iir == 2) { |
AjK | 0:0a841b89d614 | 51 | if (rxBufferIn == rxBufferOut && rxBufferFull) { |
AjK | 0:0a841b89d614 | 52 | char c __attribute__((unused)); /* oh dear, no room, send to /dev/null */ |
AjK | 0:0a841b89d614 | 53 | c = LPC_UART0->RBR; |
AjK | 0:0a841b89d614 | 54 | rxBufferOverflow = true; |
AjK | 0:0a841b89d614 | 55 | } |
AjK | 0:0a841b89d614 | 56 | else { |
AjK | 0:0a841b89d614 | 57 | rxBuffer[rxBufferIn++] = LPC_UART0->RBR; |
AjK | 0:0a841b89d614 | 58 | rxBufferIn &= (UART0_RX_BUFFER_SIZE - 1); |
AjK | 0:0a841b89d614 | 59 | if (rxBufferIn == rxBufferOut) rxBufferFull = true; |
AjK | 0:0a841b89d614 | 60 | } |
AjK | 0:0a841b89d614 | 61 | } |
AjK | 0:0a841b89d614 | 62 | |
AjK | 0:0a841b89d614 | 63 | if (iir == 1) { |
AjK | 0:0a841b89d614 | 64 | if (txBufferIn != txBufferOut || txBufferFull) { |
AjK | 0:0a841b89d614 | 65 | LPC_UART0->THR = (uint8_t)(txBuffer[txBufferOut++]); |
AjK | 0:0a841b89d614 | 66 | txBufferOut &= (UART0_TX_BUFFER_SIZE - 1); |
AjK | 0:0a841b89d614 | 67 | txBufferFull = false; |
AjK | 0:0a841b89d614 | 68 | } |
AjK | 0:0a841b89d614 | 69 | else { |
AjK | 0:0a841b89d614 | 70 | LPC_UART0->IER = 0x1; |
AjK | 0:0a841b89d614 | 71 | } |
AjK | 0:0a841b89d614 | 72 | } |
AjK | 0:0a841b89d614 | 73 | } |
AjK | 0:0a841b89d614 | 74 | |
AjK | 0:0a841b89d614 | 75 | /** Uart0_init |
AjK | 0:0a841b89d614 | 76 | */ |
AjK | 0:0a841b89d614 | 77 | void Uart0_init(void) { |
AjK | 0:0a841b89d614 | 78 | volatile char c __attribute__((unused)); |
AjK | 0:0a841b89d614 | 79 | |
AjK | 0:0a841b89d614 | 80 | LPC_SC->PCONP |= (1UL << 3); |
AjK | 0:0a841b89d614 | 81 | LPC_SC->PCLKSEL0 &= ~(3UL << 6); |
AjK | 0:0a841b89d614 | 82 | LPC_SC->PCLKSEL0 |= (1UL << 6); |
AjK | 0:0a841b89d614 | 83 | LPC_PINCON->PINSEL0 &= ~((1UL << 4) | (1UL << 6)); |
AjK | 0:0a841b89d614 | 84 | LPC_PINCON->PINSEL0 |= ((1UL << 4) | (1UL << 6)); |
AjK | 0:0a841b89d614 | 85 | LPC_UART0->LCR = 0x80; |
AjK | 0:0a841b89d614 | 86 | LPC_UART0->DLM = 0x0; // 0x00 for 115200 baud, for 9600 use 0x2; |
AjK | 0:0a841b89d614 | 87 | LPC_UART0->DLL = 0x34; // 0x34 for 115200 baud, for 9600 use 0x71; |
AjK | 0:0a841b89d614 | 88 | LPC_UART0->LCR = 0x3; |
AjK | 0:0a841b89d614 | 89 | LPC_UART0->FCR = 0x7; |
AjK | 0:0a841b89d614 | 90 | |
AjK | 0:0a841b89d614 | 91 | NVIC_SetVector(UART0_IRQn, (uint32_t)UART0_IRQHandler); |
AjK | 0:0a841b89d614 | 92 | NVIC_EnableIRQ(UART0_IRQn); |
AjK | 0:0a841b89d614 | 93 | |
AjK | 0:0a841b89d614 | 94 | /* Enable UART0 RX interrupt only. */ |
AjK | 0:0a841b89d614 | 95 | LPC_UART0->IER = 0x1; |
AjK | 0:0a841b89d614 | 96 | } |
AjK | 0:0a841b89d614 | 97 | |
AjK | 0:0a841b89d614 | 98 | /** debug_init |
AjK | 0:0a841b89d614 | 99 | */ |
AjK | 0:0a841b89d614 | 100 | void debug_init(void) { |
AjK | 0:0a841b89d614 | 101 | txBufferIn = txBufferOut = 0; |
AjK | 0:0a841b89d614 | 102 | memset((char *)txBuffer, 0, UART0_TX_BUFFER_SIZE); |
AjK | 0:0a841b89d614 | 103 | rxBufferIn = rxBufferOut = 0; |
AjK | 0:0a841b89d614 | 104 | memset((char *)txBuffer, 0, UART0_RX_BUFFER_SIZE); |
AjK | 0:0a841b89d614 | 105 | txBufferFull = rxBufferFull = false; |
AjK | 0:0a841b89d614 | 106 | rxBufferOverflow = false; |
AjK | 0:0a841b89d614 | 107 | Uart0_init(); |
AjK | 0:0a841b89d614 | 108 | } |
AjK | 0:0a841b89d614 | 109 | |
AjK | 0:0a841b89d614 | 110 | #ifdef DEBUG_USE_UART0 |
AjK | 0:0a841b89d614 | 111 | |
AjK | 0:0a841b89d614 | 112 | /** debug_string |
AjK | 0:0a841b89d614 | 113 | * |
AjK | 0:0a841b89d614 | 114 | * Print a null termimnated string to UART0. |
AjK | 0:0a841b89d614 | 115 | * |
AjK | 0:0a841b89d614 | 116 | * @param char *s A pointer to the null terminated string. |
AjK | 0:0a841b89d614 | 117 | */ |
AjK | 0:0a841b89d614 | 118 | void debug_string(char *s) { |
AjK | 0:0a841b89d614 | 119 | while (*(s)) { |
AjK | 0:0a841b89d614 | 120 | Uart0_putc(*s++); |
AjK | 0:0a841b89d614 | 121 | } |
AjK | 0:0a841b89d614 | 122 | } |
AjK | 0:0a841b89d614 | 123 | |
AjK | 0:0a841b89d614 | 124 | /** debug_stringl |
AjK | 0:0a841b89d614 | 125 | * |
AjK | 0:0a841b89d614 | 126 | * Print a string of specified length to UART0. |
AjK | 0:0a841b89d614 | 127 | * |
AjK | 0:0a841b89d614 | 128 | * @param char *s A pointer to the null terminated string. |
AjK | 0:0a841b89d614 | 129 | * @param int length The length of the string to print. |
AjK | 0:0a841b89d614 | 130 | */ |
AjK | 0:0a841b89d614 | 131 | void debug_stringl(char *s, int length) { |
AjK | 0:0a841b89d614 | 132 | while (length--) { |
AjK | 0:0a841b89d614 | 133 | Uart0_putc(*s++); |
AjK | 0:0a841b89d614 | 134 | } |
AjK | 0:0a841b89d614 | 135 | } |
AjK | 0:0a841b89d614 | 136 | |
AjK | 0:0a841b89d614 | 137 | /* Local function prototype for _init(). */ |
AjK | 0:0a841b89d614 | 138 | void Uart0_init(void); |
AjK | 0:0a841b89d614 | 139 | |
AjK | 0:0a841b89d614 | 140 | /** Uart0_putc |
AjK | 0:0a841b89d614 | 141 | * |
AjK | 0:0a841b89d614 | 142 | * Put a character out the UART0 serial port. |
AjK | 0:0a841b89d614 | 143 | * Note, if the THR register is not empty AND the output buffer is not empty |
AjK | 0:0a841b89d614 | 144 | * then place the character into the output buffer and enable interrupt to |
AjK | 0:0a841b89d614 | 145 | * flush the buffer. |
AjK | 0:0a841b89d614 | 146 | * |
AjK | 0:0a841b89d614 | 147 | * Additionally, if the TX buffer is full this function will BLOCK! |
AjK | 0:0a841b89d614 | 148 | * If you have lots of debugging messages to spit out then it may be |
AjK | 0:0a841b89d614 | 149 | * wise to either "slimeline" what you need to print out or alternatively |
AjK | 0:0a841b89d614 | 150 | * increase the size of the txBuffer to cope with the increased traffic. |
AjK | 0:0a841b89d614 | 151 | * Be aware of this blocking! |
AjK | 0:0a841b89d614 | 152 | * |
AjK | 0:0a841b89d614 | 153 | * @param char c The character to send out of UART0. |
AjK | 0:0a841b89d614 | 154 | */ |
AjK | 0:0a841b89d614 | 155 | void Uart0_putc(char c) { |
AjK | 0:0a841b89d614 | 156 | if ((LPC_UART0->LSR & 0x20) && (txBufferIn == txBufferOut && !txBufferFull)) { |
AjK | 0:0a841b89d614 | 157 | LPC_UART0->THR = (uint8_t)c; |
AjK | 0:0a841b89d614 | 158 | } |
AjK | 0:0a841b89d614 | 159 | else { |
AjK | 0:0a841b89d614 | 160 | while (txBufferFull) ; /* Blocks!!! */ |
AjK | 0:0a841b89d614 | 161 | txBuffer[txBufferIn++] = c; |
AjK | 0:0a841b89d614 | 162 | txBufferIn &= (UART0_TX_BUFFER_SIZE - 1); |
AjK | 0:0a841b89d614 | 163 | if (txBufferIn == txBufferOut && !txBufferFull) txBufferFull = true; |
AjK | 0:0a841b89d614 | 164 | LPC_UART0->IER = 0x3; |
AjK | 0:0a841b89d614 | 165 | } |
AjK | 0:0a841b89d614 | 166 | } |
AjK | 0:0a841b89d614 | 167 | |
AjK | 0:0a841b89d614 | 168 | /** Uart0_getc |
AjK | 0:0a841b89d614 | 169 | * |
AjK | 0:0a841b89d614 | 170 | * Used to get a character from Uart0. If the passed arg "block" is non-zero |
AjK | 0:0a841b89d614 | 171 | * then this function will block (wait) for user input. Otherwise if a char |
AjK | 0:0a841b89d614 | 172 | * is available return it, otherwise return -1 to show buffer was empty. |
AjK | 0:0a841b89d614 | 173 | * |
AjK | 0:0a841b89d614 | 174 | * @param int block Should we block? |
AjK | 0:0a841b89d614 | 175 | * @return int Cast char to int for char or -1 if non-blocking and no char. |
AjK | 0:0a841b89d614 | 176 | */ |
AjK | 0:0a841b89d614 | 177 | int Uart0_getc(int block) { |
AjK | 0:0a841b89d614 | 178 | char c; |
AjK | 0:0a841b89d614 | 179 | |
AjK | 0:0a841b89d614 | 180 | if (block) while (rxBufferOut == rxBufferIn && !rxBufferFull) ; /* Blocks! */ |
AjK | 0:0a841b89d614 | 181 | else if (rxBufferIn == rxBufferOut && !rxBufferFull) return -1; |
AjK | 0:0a841b89d614 | 182 | |
AjK | 0:0a841b89d614 | 183 | c = rxBuffer[rxBufferOut++]; |
AjK | 0:0a841b89d614 | 184 | rxBufferOut &= (UART0_RX_BUFFER_SIZE - 1); |
AjK | 0:0a841b89d614 | 185 | if (rxBufferFull) rxBufferFull = false; |
AjK | 0:0a841b89d614 | 186 | return (int)c; |
AjK | 0:0a841b89d614 | 187 | } |
AjK | 0:0a841b89d614 | 188 | |
AjK | 0:0a841b89d614 | 189 | /* end of #ifdef DEBUG_USE_UART0 */ |
AjK | 0:0a841b89d614 | 190 | #endif |
AjK | 0:0a841b89d614 | 191 | |
AjK | 0:0a841b89d614 | 192 | |
AjK | 0:0a841b89d614 | 193 |