📄 printfuart.h
字号:
/*
* "Copyright (c) 2008 The Regents of the University of California.
* All rights reserved."
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
* CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
*
*/
/*
* Copyright (c) 2005
* The President and Fellows of Harvard College.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Writes printf like output to the UART.
* This works only on the AVR and MSP430 Microcontrollers!
* <p>
* Note: For AVR we explicitly place the print statements in ROM; for
* MSP430 this is done by default! For AVR, if we don't place it
* explicitely in ROM, the statements will go in RAM, which will
* quickly cause a descent size program to run out of RAM. By default
* it doesn't disable the interupts; disabling the interupts when
* writing to the UART, slows down/makes the mote quite unresponsive,
* and can lead to problems! If you wish to disable all printfs to
* the UART, then comment the flag: <code>PRINTFUART_ENABLED</code>.
* <p> <pre>
* How to use:
* // (0) In your Makefile, define PRINTFUART_ENABLED
* CFLAGS += -DPRINTFUART_ENABLED
* // (1) Call printfUART_init() from your initialization function
* // to initialize the UART
* printfUART_init();
* // (2) Set your UART client to the correct baud rate. Look at
* // the comments in printfUART_init(), to figure out what
* // baud to use for your particular mote
*
* // (3) Send printf statements like this:
* printfUART("Hello World, we are in year= %u\n", 2004);
* printfUART("Printing uint32_t variable, value= %lu\n", 4294967295);
*
* Examples and caveats:
* // (1) - Must use curly braces in single section statements.
* (Look in the app.c to see why -- hint: it's a macro)
* if (x < 3)
* {printfUART("The value of x is %i\n", x);}
* // (2) - Otherwise it more or less works like regular printf
* printfUART("\nThe value of x=%u, and y=%u\n", x, y);
* </pre>
* <pre>URL: http://www.eecs.harvard.edu/~konrad/projects/motetrack</pre>
* @author Konrad Lorincz
* @version 2.0, January 5, 2005
*/
#ifndef PRINTFUART_H
#define PRINTFUART_H
#include <stdarg.h>
#include <stdio.h>
// -------------------------------------------------------------------
#ifdef PRINTFUART_ENABLED
#define DEBUGBUF_SIZE 256
char debugbuf[DEBUGBUF_SIZE];
char debugbufROMtoRAM[DEBUGBUF_SIZE];
#if defined(PLATFORM_MICAZ) || defined(PLATFORM_MICA2) || defined(PLATFORM_MICA2DOT)
#define printfUART(__format...) { \
static const char strROM[] PROGMEM = __format; \
strcpy_P((char*) &debugbufROMtoRAM, (PGM_P) &strROM); \
sprintf(debugbuf, debugbufROMtoRAM); \
writedebug(); \
}
#else // assume MSP430 architecture (e.g. TelosA, TelosB, etc.)
#define printfUART(__format...) { \
sprintf(debugbuf, __format); \
writedebug(); \
}
#endif
#else
#define printfUART(X, args...) dbg("printf", X, ## args)
// #define printfUART(__format...) {}
void printfUART_init() {}
#endif
#define NOprintfUART(__format...)
// -------------------------------------------------------------------
#ifdef PRINTFUART_ENABLED
/**
* Initialize the UART port. Call this from your startup routine.
*/
#define printfUART_init() {atomic printfUART_init_private();}
void printfUART_init_private()
{
#if defined(PLATFORM_MICAZ) || defined(PLATFORM_MICA2)
// 56K baud
outp(0,UBRR0H);
outp(15, UBRR0L); //set baud rate
outp((1<<U2X),UCSR0A); // Set UART double speed
outp(((1 << UCSZ1) | (1 << UCSZ0)) , UCSR0C); // Set frame format: 8 data-bits, 1 stop-bit
inp(UDR0);
outp((1 << TXEN) ,UCSR0B); // Enable uart reciever and transmitter
#else
#if defined(PLATFORM_MICA2DOT)
// 19.2K baud
outp(0,UBRR0H); // Set baudrate to 19.2 KBps
outp(12, UBRR0L);
outp(0,UCSR0A); // Disable U2X and MPCM
outp(((1 << UCSZ1) | (1 << UCSZ0)) , UCSR0C);
inp(UDR0);
outp((1 << TXEN) ,UCSR0B);
#else
#if defined(PLATFORM_IMOTE2)
//async command result_t UART.init() {
/***
need to configure the ST UART pins for the correct functionality
GPIO<46> = STDRXD = ALT2(in)
GPIO<47> = STDTXD = ALT1(out)
*********/
//atomic{
//configure the GPIO Alt functions and directions
_GPIO_setaltfn(46,2); // STD_RXD
_GPIO_setaltfn(47,1); // STD_TXD
_GPDR(46) &= ~_GPIO_bit(46); // input
_GPDR(47) |= _GPIO_bit(47); // output
STLCR |=LCR_DLAB; //turn on DLAB so we can change the divisor
STDLL = 8; //configure to 115200;
STDLH = 0;
STLCR &= ~(LCR_DLAB); //turn off DLAB
STLCR |= 0x3; //configure to 8 bits
STMCR &= ~MCR_LOOP;
STMCR |= MCR_OUT2;
STIER |= IER_RAVIE;
STIER |= IER_TIE;
STIER |= IER_UUE; //enable the UART
//STMCR |= MCR_AFE; //Auto flow control enabled;
//STMCR |= MCR_RTS;
STFCR |= FCR_TRFIFOE; //enable the fifos
// call Interrupt.allocate();
// call Interrupt.enable();
//configure all the interrupt stuff
//make sure that the interrupt causes an IRQ not an FIQ
// __REG(0x40D00008) &= ~(1<<21);
//configure the priority as IPR1
//__REG(0x40D00020) = (1<<31 | 21);
//unmask the interrupt
//__REG(0x40D00004) |= (1<<21);
CKEN |= CKEN5_STUART; //enable the UART's clk
#else // assume TelosA, TelosB, etc.
// Variabel baud
// To change the baud rate, see /tos/platform/msp430/msp430baudrates.h
uint8_t source = SSEL_SMCLK;
uint16_t baudrate = 0x0012; // UBR_SMCLK_57600=0x0012
uint8_t mctl = 0x84; // UMCTL_SMCLK_57600=0x84
//uint16_t baudrate = 0x0009; // UBR_SMCLK_115200=0x0009
//uint8_t mctl = 0x10; // UMCTL_SMCLK_115200=0x10
uint16_t l_br = 0;
uint8_t l_mctl = 0;
uint8_t l_ssel = 0;
TOSH_SEL_UTXD1_MODFUNC();
TOSH_SEL_URXD1_MODFUNC();
UCTL1 = SWRST;
UCTL1 |= CHAR; // 8-bit char, UART-mode
U1RCTL &= ~URXEIE; // even erroneous characters trigger interrupts
UCTL1 = SWRST;
UCTL1 |= CHAR; // 8-bit char, UART-mode
if (l_ssel & 0x80) {
U1TCTL &= ~(SSEL_0 | SSEL_1 | SSEL_2 | SSEL_3);
U1TCTL |= (l_ssel & 0x7F);
}
else {
U1TCTL &= ~(SSEL_0 | SSEL_1 | SSEL_2 | SSEL_3);
U1TCTL |= SSEL_ACLK; // use ACLK, assuming 32khz
}
if ((l_mctl != 0) || (l_br != 0)) {
U1BR0 = l_br & 0x0FF;
U1BR1 = (l_br >> 8) & 0x0FF;
U1MCTL = l_mctl;
}
else {
U1BR0 = 0x03; // 9600 baud
U1BR1 = 0x00;
U1MCTL = 0x4A;
}
ME2 &= ~USPIE1; // USART1 SPI module disable
ME2 |= (UTXE1 | URXE1); // USART1 UART module enable
U1CTL &= ~SWRST;
IFG2 &= ~(UTXIFG1 | URXIFG1);
IE2 &= ~(UTXIE1 | URXIE1); // interrupt disabled
//async command void USARTControl.setClockSource(uint8_t source) {
// atomic {
l_ssel = source | 0x80;
U1TCTL &= ~(SSEL_0 | SSEL_1 | SSEL_2 | SSEL_3);
U1TCTL |= (l_ssel & 0x7F);
// }
//}
//async command void USARTControl.setClockRate(uint16_t baudrate, uint8_t mctl) {
//atomic {
l_br = baudrate;
l_mctl = mctl;
U1BR0 = baudrate & 0x0FF;
U1BR1 = (baudrate >> 8) & 0x0FF;
U1MCTL = mctl;
//}
//}
//async command result_t USARTControl.enableRxIntr(){
//atomic {
IFG2 &= ~URXIFG1;
IE2 |= URXIE1;
//}
//return SUCCESS;
//}
//async command result_t USARTControl.enableTxIntr(){
//atomic {
IFG2 &= ~UTXIFG1;
IE2 |= UTXIE1;
//}
//return SUCCESS;
//}
#endif
#endif
#endif
}
#if defined(PLATFORM_MICAZ) || defined(PLATFORM_MICA2) || defined(PLATFORM_MICA2DOT)
#else
#if defined(PLATFORM_IMOTE2)
#else // assume AVR architecture (e.g. TelosA, TelosB)
bool isTxIntrPending()
{
if (U1TCTL & TXEPT) {
return TRUE;
}
return FALSE;
}
#endif
#endif
/**
* Outputs a char to the UART.
*/
void UARTPutChar(char c)
{
if (c == '\n')
UARTPutChar('\r');
#if defined(PLATFORM_MICAZ) || defined(PLATFORM_MICA2) || defined(PLATFORM_MICA2DOT)
loop_until_bit_is_set(UCSR0A, UDRE);
outb(UDR0,c);
#else
#if defined(PLATFORM_IMOTE2)
STTHR = c;
#else // assume AVR architecture (e.g. TelosA, TelosB)
U1TXBUF = c;
while( !isTxIntrPending() )
continue;
#endif
#endif
}
/**
* Outputs the entire debugbuf to the UART, or until it encounters '\0'.
*/
void writedebug()
{
uint16_t i = 0;
while (debugbuf[i] != '\0' && i < DEBUGBUF_SIZE)
UARTPutChar(debugbuf[i++]);
}
#endif // PRINTFUART_ENABLED
// -------------------------------------------------------------------
#if 0
// --------------------------------------------------------------
#define assertUART(x) if (!(x)) { __assertUART(__FILE__, __LINE__); }
void __assertUART(const char* file, int line)
{
printfUART("ASSERT FAILED: file= %s, lineNbr= %i\n", file, line);
// for some reason, CLR means on
TOSH_MAKE_RED_LED_OUTPUT();
TOSH_MAKE_YELLOW_LED_OUTPUT();
TOSH_MAKE_GREEN_LED_OUTPUT();
TOSH_CLR_RED_LED_PIN();
TOSH_CLR_YELLOW_LED_PIN();
TOSH_CLR_GREEN_LED_PIN();
exit(1);
}
// --------------------------------------------------------------
#endif
#endif // PRINTFUART_H
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -