Satellite Observers Workbench. NOT yet complete, just published for forum posters to \"cherry pick\" pieces of code as requiered as an example.

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers debug.c Source File

debug.c

00001 /****************************************************************************
00002  *    Copyright 2010 Andy Kirkham, Stellar Technologies Ltd
00003  *    
00004  *    This file is part of the Satellite Observers Workbench (SOWB).
00005  *
00006  *    SOWB is free software: you can redistribute it and/or modify
00007  *    it under the terms of the GNU General Public License as published by
00008  *    the Free Software Foundation, either version 3 of the License, or
00009  *    (at your option) any later version.
00010  *
00011  *    SOWB is distributed in the hope that it will be useful,
00012  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *    GNU General Public License for more details.
00015  *
00016  *    You should have received a copy of the GNU General Public License
00017  *    along with SOWB.  If not, see <http://www.gnu.org/licenses/>.
00018  *
00019  *    $Id: main.cpp 5 2010-07-12 20:51:11Z ajk $
00020  *    
00021  ***************************************************************************/
00022 
00023 #include "sowb.h"
00024 #include "debug.h"
00025 
00026 /* Design note. We do not use a txBufferOverflow flag like we
00027    do with the RX buffer as all calls to Uart0_putc() will 
00028    block if there isn't room to send. It's up to the designer
00029    to either ensure they don't flood the TX buffer with too
00030    many debug strings or alternatively increase the buffer
00031    size to handle the higher amounts of traffic. */
00032 
00033 volatile char txBuffer[UART0_TX_BUFFER_SIZE];
00034 volatile char rxBuffer[UART0_RX_BUFFER_SIZE];
00035 volatile unsigned char txBufferIn, txBufferOut;
00036 volatile unsigned char rxBufferIn, rxBufferOut;
00037 volatile bool txBufferFull, rxBufferFull, rxBufferOverflow;
00038 
00039 /** UART0_IRQHandler
00040  */
00041 extern "C" void UART0_IRQHandler(void) __irq {
00042     uint32_t iir;
00043     
00044     iir = LPC_UART0->IIR;
00045     
00046     if (iir & 1) return;
00047     
00048     iir = (iir >> 1) & 0x3;
00049     
00050     if (iir == 2) {
00051         if (rxBufferIn == rxBufferOut && rxBufferFull) {            
00052             char c __attribute__((unused)); /* oh dear, no room, send to /dev/null */
00053             c = LPC_UART0->RBR;
00054             rxBufferOverflow = true;
00055         }
00056         else {
00057             rxBuffer[rxBufferIn++] = LPC_UART0->RBR;
00058             rxBufferIn &= (UART0_RX_BUFFER_SIZE - 1);
00059             if (rxBufferIn == rxBufferOut) rxBufferFull = true;
00060         }
00061     }
00062     
00063     if (iir == 1) {
00064         if (txBufferIn != txBufferOut || txBufferFull) {
00065             LPC_UART0->THR = (uint8_t)(txBuffer[txBufferOut++]);
00066             txBufferOut &= (UART0_TX_BUFFER_SIZE - 1);
00067             txBufferFull = false;
00068         }
00069         else {
00070             LPC_UART0->IER = 0x1;
00071         }
00072     } 
00073 }
00074 
00075 /** Uart0_init
00076  */
00077 void Uart0_init(void) {
00078     volatile char c __attribute__((unused));
00079     
00080     LPC_SC->PCONP       |=  (1UL << 3);
00081     LPC_SC->PCLKSEL0    &= ~(3UL << 6);
00082     LPC_SC->PCLKSEL0    |=  (1UL << 6);
00083     LPC_PINCON->PINSEL0 &= ~((1UL << 4) | (1UL << 6));
00084     LPC_PINCON->PINSEL0 |=  ((1UL << 4) | (1UL << 6));
00085     LPC_UART0->LCR       = 0x80;
00086     LPC_UART0->DLM       = 0x0;  // 0x00 for 115200 baud, for 9600 use 0x2;
00087     LPC_UART0->DLL       = 0x34; // 0x34 for 115200 baud, for 9600 use 0x71;
00088     LPC_UART0->LCR       = 0x3;
00089     LPC_UART0->FCR       = 0x7;
00090     
00091     NVIC_SetVector(UART0_IRQn, (uint32_t)UART0_IRQHandler);
00092     NVIC_EnableIRQ(UART0_IRQn);
00093     
00094     /* Enable UART0 RX interrupt only. */
00095     LPC_UART0->IER = 0x1;
00096 }
00097 
00098 /** debug_init
00099  */
00100 void debug_init(void) {
00101     txBufferIn = txBufferOut = 0;
00102     memset((char *)txBuffer, 0, UART0_TX_BUFFER_SIZE);
00103     rxBufferIn = rxBufferOut = 0;
00104     memset((char *)txBuffer, 0, UART0_RX_BUFFER_SIZE);
00105     txBufferFull = rxBufferFull = false;
00106     rxBufferOverflow = false;
00107     Uart0_init();
00108 }
00109 
00110 #ifdef DEBUG_USE_UART0
00111 
00112 /** debug_string
00113  *
00114  * Print a null termimnated string to UART0.
00115  *
00116  * @param char *s A pointer to the null terminated string. 
00117  */
00118 void debug_string(char *s) {
00119     while (*(s)) {
00120         Uart0_putc(*s++);
00121     }
00122 }
00123 
00124 /** debug_stringl
00125  *
00126  * Print a string of specified length to UART0.
00127  *
00128  * @param char *s A pointer to the null terminated string. 
00129  * @param int length The length of the string to print.
00130  */
00131 void debug_stringl(char *s, int length) {
00132     while (length--) {
00133         Uart0_putc(*s++);
00134     }
00135 }
00136 
00137 /* Local function prototype for _init(). */
00138 void Uart0_init(void);
00139 
00140 /** Uart0_putc
00141  *
00142  * Put a character out the UART0 serial port. 
00143  * Note, if the THR register is not empty AND the output buffer is not empty
00144  * then place the character into the output buffer and enable interrupt to
00145  * flush the buffer.
00146  *
00147  * Additionally, if the TX buffer is full this function will BLOCK!
00148  * If you have lots of debugging messages to spit out then it may be
00149  * wise to either "slimeline" what you need to print out or alternatively
00150  * increase the size of the txBuffer to cope with the increased traffic.
00151  * Be aware of this blocking!
00152  *
00153  * @param char c The character to send out of UART0.
00154  */
00155 void Uart0_putc(char c) {
00156     if ((LPC_UART0->LSR & 0x20) && (txBufferIn == txBufferOut && !txBufferFull)) {
00157         LPC_UART0->THR = (uint8_t)c;
00158     }
00159     else {  
00160         while (txBufferFull) ; /* Blocks!!! */    
00161         txBuffer[txBufferIn++] = c;
00162         txBufferIn &= (UART0_TX_BUFFER_SIZE - 1);
00163         if (txBufferIn == txBufferOut && !txBufferFull) txBufferFull = true;
00164         LPC_UART0->IER = 0x3;
00165     }
00166 }
00167 
00168 /** Uart0_getc
00169  *
00170  * Used to get a character from Uart0. If the passed arg "block" is non-zero
00171  * then this function will block (wait) for user input. Otherwise if a char
00172  * is available return it, otherwise return -1 to show buffer was empty.
00173  *
00174  * @param int block Should we block?
00175  * @return int Cast char to int for char or -1 if non-blocking and no char.
00176  */
00177 int Uart0_getc(int block) {
00178     char c;
00179     
00180     if (block) while (rxBufferOut == rxBufferIn && !rxBufferFull) ; /* Blocks! */    
00181     else if (rxBufferIn == rxBufferOut && !rxBufferFull) return -1;
00182     
00183     c = rxBuffer[rxBufferOut++];
00184     rxBufferOut &= (UART0_RX_BUFFER_SIZE - 1);
00185     if (rxBufferFull) rxBufferFull = false;     
00186     return (int)c;   
00187 }
00188 
00189 /* end of #ifdef DEBUG_USE_UART0 */
00190 #endif
00191 
00192 
00193