Jump to content

MSP430Andy

Members
  • Content Count

    26
  • Joined

  • Last visited

  • Days Won

    1
  1. From the TI CCS Cloud FAQ ... Which devices and boards are supported? A: Support for more boards is continually being added. Currently the following LaunchPads are supported: "MSP-EXP432P401R", MSP-EXP430G2, MSP-EXP430FR5969 and MSP-EXP430F5529LP. Q: Is there any debug functionality? A: Currently the only debug functionality provided is printf() via UART. I was hoping, at least, to use the Launchpad debugger on Energia.
  2. Cannot import Energia v15 sketch into CCS I have installed the latest "whole" CCS download from TI - CCS version 6.1.0.00104 I have also installed the latest Energia Version 0101E0015. (Platform: PC/Windows 8.1/64 bit) Under CCS "file"/ "import"/ "Energia sketch or example" the device target dropdown does not show the MSP432 or the board dropdown does not show "launchpad" MSP-EXP432P401R (48 MHZ)? Any help is appreciated
  3. Read page 26 of Launchpad 5969 user manual. The 5969 is only 2k SRAM device. The calculation shows more than 2k for the 128x128 display. Now if only Energia could dynamically partition or allocate this device's FRAM?
  4. Got any Energia demo code for The Terminal using the 2553? ;-)
  5. @@grahamf72 the library file format from the zip file folders are not in the proper Arduino/Energia file/folder format? aka examples files and header files... running the test files fails compile due to Energia not finding the header files? I am using ver 10 on windows /xp/sp3 on a 2553
  6. I am using Zipgenius and on each folder extract requires a password? I will try another unzipper.
  7. Here is my updated Command Line Interface with parameters. (Beta) :ugeek: /*********************************************************************************/ /*! THIS SOFTWARE IS PROVIDED BY THE THE HOLDERS 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 INSTITUTE 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. THERE ARE BUGS IN ANY SOFTWARE. THERE COULD EVEN BE BUGS IN THIS SOFTWARE??? IF THERE WAS A TIME TO CALL THE BUG EXTERMINATOR, NOW WOULD BE THE TIME TO CALL 1-800-ORKIN. COLONIES OF BUGS ARE HARD TO EXTERMINATE IF YOU LET THEM BREED. IF YOU CAN'T CALL ORKIN JUST FIRE UP THE CCS DEBUGGER AND EXTERMINATE THEM YOURSELF! IF YOU USE THIS SOFTWARE AND YOUR HOUSE BURNS DOWN AND YOUR WIFE AND CHILDREN BECOMES HOMELESS AND WORST OF ALL YOUR DOG DIES, DON'T HOLD ME RESPONSIBLE! YOU CAN USE THIS CODE BUT PLEASE GIVE CREDIT TO THOSE WHO CONTRIBUTED TO IT. PLEASE INCLUDE ALL COPYWRITES HEADERS/FOOTERS IN YOUR SOFTWARE! */ /*********************************************************************************/ /*********************************************************************************/ /*! Author: MSP430Andy Description: LP_2553_Cmd_Line - command line interface or shell or interpreter. Program Revision: 1.0b (beta) Date: 1/30/12 PC Platform: Windows PC/SP3 Development platform: LaunchPad revision 2 firmware. PC compiler used: Eclipse with CCS 4.1 & 5 Configuration setup I/O generated by: GRACE Device used: MSP430G2553 Pin DIP Software Module: USCI_A0 at 9600, 8 N 1 Bugs: 1. Syntax warnings in function printf()? - routine works but there were no errors in CCS 4.1? Code size: 2553 Device: 16K flash, 512 bytes RAM Flash used: xxx k RAM used: xxx bytes (without printf_Test() Program status OK */ /*********************************************************************************/ /*********************************************************************************/ /*! [includes] */ /*********************************************************************************/ #include // GRACE Include #include // Support Include #include // for printF #include /*********************************************************************************/ /*! [Defines] */ /*********************************************************************************/ #ifdef MSP430 static void __inline__ __delay_cycles(register uint16_t n) { // 2553 @ 1 Mhz = 1 usec __delay_cycles(1000); = 1 msec __asm__ __volatile__ ( "1: \n" " dec %[n] \n" " jne 1b \n" : [n] "+r"(n)); } #else #endif // Red LED - on board on LaunchPad #define RED_LED_OFF() P1OUT &= ~BIT0 #define RED_LED_ON() P1OUT |= BIT0 #define RED_LED_FLIP() P1OUT ^= BIT0 // Green LED - on board on LaunchPad #define GRN_LED_OFF() P1OUT &= ~BIT6 #define GRN_LED_ON() P1OUT |= BIT6 #define GRN_LED_FLIP() P1OUT ^= BIT6 #define TX_RX_DIAG 0 // [1 = Toggles LP LEDs rx = grn & tx = red] [0 = all off] - careful for testing only #define SYNC_BYTE 0x7E // 127 dec #define ESCAPE_BYTE 0x7D // 128 dec // Command Line Interface #define PARSE_BUFFER_MAX 16 #define COMMAND_LINE_STYLE 1 // <---<<<< 0 = CLI NO PARAMETERS 1 = CLI with PARAMETERS static char value; static char stack[PARSE_BUFFER_MAX]; static char top; /*********************************************************************************/ /*! [Rx Ring Buffer] */ /*********************************************************************************/ //Ring Buffer #define RING_BUFFER_SIZE 32 char ring_buffer[RING_BUFFER_SIZE]; // usci_A0 rx ring buffer /* Size of RX ring buffer */ #define RING_BUFFER_MASK ( RING_BUFFER_SIZE - 1) #if ( RING_BUFFER_SIZE & RING_BUFFER_MASK ) #error RX ring buffer size is not a power of 2 #endif // Ring Buffer Global Variables int ring_buffer_data_size = 0; // number of chars in buffer int ring_buffer_read_pointer = 0; // indice number of last read char int ring_buffer_write_pointer = 0; // indice number of last written char /*********************************************************************************/ /*! [Printf] */ /*********************************************************************************/ //Printf Functions void printf_putc (unsigned char c); void printf_puts(char *s); void printf(char *, ...); void printf_Test(void); /*********************************************************************************/ /*! [Rx Receive Callback] */ /*********************************************************************************/ // Callbacks static uint8_t dummy_callback( uint8_t ); // default ring buffer callback // Holds pointers to all callback functions for USCI_AO rx buffer static uint8_t (*uart_rx_callback)( uint8_t ) = dummy_callback; /*********************************************************************************/ /*! [Flash Structure] The MSP430G2553 the flash memory is organized as follow: 4 * 64 BYTE BLOCKS = 256 BYTES Flash_ptrA = (char *) 0x10C0; // 10C0-10FF Initialize Flash segment A pointer but never touch this! (calibration constants) Flash_ptrB = (char *) 0x1080; // 1080-10BF Initialize Flash segment B pointer Flash_ptrC = (char *) 0x1040; // 1040-107F Initialize Flash segment C pointer Flash_ptrD = (char *) 0x1000; // 1000-103F Initialize Flash segment D pointer */ /*********************************************************************************/ // We store all the MSPNode RFM12B RF node config data in a structure so that // we can save it in the flash memory. (MSPNode is JeeNode protocol compatible) struct MSPNode { // MSPNode Group ID (1-254) unsigned char grp; // MSPNode Node ID (1-30) unsigned char id; // RFM12B ISM Freq. Band <--- Marked On RFM12B chip! //RF12_433MHZ 1 //RF12_868MHZ 2 //RF12_915MHZ 3 unsigned char band; // RFM12B Central Node ID unsigned char dest; } mspnode = {1,8,3,20}; // <---- init values to write to protected flash segment D (64 bytes total) // ref. only //mspnode.grp //mspnode.id //mspnode.band //mspnode.dest /*********************************************************************************/ /*! [Function Prototypes] */ /*********************************************************************************/ // rx ring buffer prototypes int ring_buffer_full(void); int ring_buffer_empty(void); void ring_buffer_push_char(char c); // to ring buffer unsigned char ring_buffer_pull_char(void); // from ring buffer <------<<<< for rx void flush_ring_buffer(void); // clear ring buffer with spaces 0x20 // usci_a0 uart prototypes void uart_put_char( uint8_t ); // <-------<<<<< for tx void uart_write_buffer( uint8_t*, uint16_t ); void uart_write_buffer_escaped( uint8_t*, uint16_t ); uint8_t hex_to_string( uint8_t* , uint8_t*, uint8_t ); // cmd line with parameters prototypes void cmd_show_help(void); void poll_cmd(void); // cmd line with parameters prototypes void poll_cmd_1(void); void cmd_show_help_1(void); static void parse_Input(char c); // protected flash prototypes // *******DO NOT LOOP THE WRITE FUNCTION - WILL CAUSE FLASH WEAR FAILURES!!!!! ******* void write_P_D_Flash(void); // uses MSPNode data structure (above) void read_P_D_Flash(void); // uses MSPNode data structure (above) void FF_SegD (void); // put FF in all of segment D /*********************************************************************************/ /*! [Main] */ /*********************************************************************************/ void main(void) { CSL_init(); // Activate Grace-generated configuration __enable_interrupt(); // Set global interrupt enable flush_ring_buffer(); // clear receive ring buffer with spaces 0x20 //_________________________________________________________________________________ RED_LED_OFF(); GRN_LED_OFF(); if (COMMAND_LINE_STYLE == 0){ { } cmd_show_help(); // CLI test no parameters } else { cmd_show_help_1(); // CLI test with parameters printf("Cmd >> "); } while(1){ if (COMMAND_LINE_STYLE == 0){ poll_cmd(); // CLI test no parameters } else { poll_cmd_1(); // CLI test with parameters } } } // end of main /*********************************************************************************/ /*! [uART_USCI_A0_RX_ISR] */ /*********************************************************************************/ void UART_USCI_A0_RX_ISR(void){ // Process incoming byte from USART if( IFG2 & UCA0RXIFG ) { // Call rx callback function (default - dummy) or // ring_buffer_callback if selected if( uart_rx_callback( UCA0RXBUF ) ) { // If function returns something nonzero, wakeup the processor //__bic_SR_register_on_exit(LPM1_bits); _nop(); } } } /*********************************************************************************/ /*! [user Application Functions] */ /*********************************************************************************/ /*********************************************************************************/ /*! [uART Functions] */ /*********************************************************************************/ /*********************************************************************************/ /*! @fn uart_put_char( uint8_t character ) @brief transmit single character */ /*********************************************************************************/ void uart_put_char( uint8_t character ) { while (!(IFG2&UCA0TXIFG)); // USCI_A0 TX buffer ready? UCA0TXBUF = character; if (TX_RX_DIAG){ RED_LED_FLIP(); } } /*********************************************************************************/ /*! @fn uart_write_buffer( uint8_t character ) @brief transmit whole buffer */ /*********************************************************************************/ void uart_write_buffer( uint8_t* buffer, uint16_t length ) { uint16_t buffer_index; for( buffer_index = 0; buffer_index < length; buffer_index++ ) { while (!(IFG2&UCA0TXIFG)); // USCI_A0 TX buffer ready? UCA0TXBUF = buffer[buffer_index]; } } /*********************************************************************************/ /*! @fn uart_write_buffer_escaped( uint8_t character ) @brief transmit whole buffer while escaping characters The uart_write_buffer_escaped() is more for sending whole packets through the serial peripheral to the computer. Normally you just send a stream of bytes. Unfortunately, there is no way for the computer to know when a stream of data begins or ends. This function uses the 0x7E byte as a start and end of packets. This way, the receiver knows when to begin and end capturing data. If your data contains a 0x7E, that might confuse the receiver, so you must escape it by preceding it with a 0x7D and modifying it. The receiver must be aware of this to process it accordingly. */ /*********************************************************************************/ void uart_write_buffer_escaped( uint8_t* buffer, uint16_t length ) { uint16_t buffer_index; while (!(IFG2&UCA0TXIFG)); // USCI_A0 TX buffer ready? UCA0TXBUF = SYNC_BYTE; for( buffer_index = 0; buffer_index < length; buffer_index++ ) { if( (buffer[buffer_index] == SYNC_BYTE) | (buffer[buffer_index] == ESCAPE_BYTE) ) { while (!(IFG2&UCA0TXIFG)); // USCI_A0 TX buffer ready? UCA0TXBUF = ESCAPE_BYTE; while (!(IFG2&UCA0TXIFG)); // USCI_A0 TX buffer ready? UCA0TXBUF = buffer[buffer_index] ^ 0x20; } else { while (!(IFG2&UCA0TXIFG)); // USCI_A0 TX buffer ready? UCA0TXBUF = buffer[buffer_index]; } } while (!(IFG2&UCA0TXIFG)); // USCI_A0 TX buffer ready? UCA0TXBUF = SYNC_BYTE; } /*********************************************************************************/ /*! @fn void dummy_callback( uint8_t rx_char ) @brief empty function works as default callback */ /*********************************************************************************/ static uint8_t dummy_callback( uint8_t rx_char ) { if (TX_RX_DIAG){ GRN_LED_FLIP(); } //uart_put_char(rx_char); // turnaround echo to tx <----- for test only ring_buffer_push_char(rx_char); // Put/push char into ring buffer return 0; } /*********************************************************************************/ /*! @fn uint8_t hex_to_string( uint8_t* buffer_out, uint8_t* buffer_in, uint8_t buffer_in_size ) @brief DEBUG function used to convert hex values to [hex]string format The hex_to_string function was just for debugging. When you want to display a value, you usually use printf(). Unfortunately, printf takes a lot of cycles to format the data, and if you're doing time-sensitive stuff, you can't afford the delay. In cases where you don't have full debugging capability, you might want to print out the values of some registers or variables. the hex_to_string() function converts a value to a hexadecimal string. */ /*********************************************************************************/ uint8_t hex_to_string( uint8_t* buffer_out, uint8_t* buffer_in, uint8_t buffer_in_size ) { static const uint8_t hex_char[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; uint8_t counter = 0; while( counter < buffer_in_size * 2 ) { buffer_out[counter] = hex_char[((buffer_in[(counter>>1)]>>4) & 0xF)]; counter++; buffer_out[counter] = hex_char[(buffer_in[(counter>>1)] & 0xF)]; counter++; } // Terminate string with null character buffer_out[counter++] = 0; return counter; } /*********************************************************************************/ /*! [Printf Functions] */ /*********************************************************************************/ /*********************************************************************************/ /*! @fn void printf_putc (unsigned char c) @brief put char into tx buffer */ /*********************************************************************************/ void printf_putc (unsigned char c) { _nop(); while (!(IFG2&UCA0TXIFG)); // USCI_A0 TX buffer ready? UCA0TXBUF = c; // TX <-- c } /*********************************************************************************/ /*! @fn void printf_puts(char *s) { while(*s) printf_putc(*s++); @brief put string chars into into tx buffer */ /*********************************************************************************/ void printf_puts(char *s) { while(*s) printf_putc(*s++); } /*********************************************************************************/ /*! @fn @brief */ /*********************************************************************************/ static const unsigned long dv[] = { // 4294967296 // 32 bit unsigned max 1000000000, // +0 100000000, // +1 10000000, // +2 1000000, // +3 100000, // +4 // 65535 // 16 bit unsigned max 10000, // +5 1000, // +6 100, // +7 10, // +8 1, // +9 }; /*********************************************************************************/ /*! @fn @brief */ /*********************************************************************************/ static void xtoa(unsigned long x, const unsigned long *dp) { char c; unsigned long d; if(x) { while(x < *dp) ++dp; do { d = *dp++; c = '0'; while(x >= d) ++c, x -= d; printf_putc(c); } while(!(d & 1)); } else printf_putc('0'); } /*********************************************************************************/ /*! @fn @brief */ /*********************************************************************************/ static void puth(unsigned n) { static const char hex[16] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; printf_putc(hex[n & 15]); } /***********************************************************************************/ /*! @fn @brief */ /***********************************************************************************/ void printf(char *format, ...) { char c; int i; long n; va_list a; va_start(a, format); while(c = *format++) { if(c == '%') { switch(c = *format++) { case 's': // String printf_puts(va_arg(a, char*)); break; case 'c': // Char printf_putc(va_arg(a, char)); break; case 'i': // 16 bit Integer case 'u': // 16 bit Unsigned i = va_arg(a, int); if(c == 'i' && i < 0) i = -i, printf_putc('-'); xtoa((unsigned)i, dv + 5); break; case 'l': // 32 bit Long case 'n': // 32 bit uNsigned loNg n = va_arg(a, long); if(c == 'l' && n < 0) n = -n, printf_putc('-'); xtoa((unsigned long)n, dv); break; case 'x': // 16 bit heXadecimal i = va_arg(a, int); puth(i >> 12); puth(i >> 8); puth(i >> 4); puth(i); break; case 0: return; default: goto bad_fmt; } } else bad_fmt: printf_putc(c); } va_end(a); } /***********************************************************************************/ /*! @fn @brief */ /***********************************************************************************/ void printf_Test(void){ /* ================= Printf() for 2553 ================= There are 7 format specifiers: %c - Character %s - String %i - signed Integer (16 bit) %u - Unsigned integer (16 bit) %l - signed Long (32 bit) %n - uNsigned loNg (32 bit) %x - heXadecimal (16 bit) Field width, floating point and other standard printf() features are not supported. */ const char *s = "test"; const char c = 'X'; const int i = -12345; const unsigned u = 12345; const long int l = -1234567890; const long unsigned n = 1234567890; const unsigned x = 0xABCD ; //hex printf("%s", "\r\n*** printf() test ***\r\n"); printf("String %s\r\n", s); printf("Char %c\r\n", c); printf("Integer %i\r\n", i); printf("Unsigned %u\r\n", u); printf("Long %l\r\n", l); printf("uNsigned loNg %n\r\n", n); printf("heX %x\r\n", x); printf("multiple args %s %c %i %u %l %n %x\r\n", s, c, i, u, l, n, x); printf("\r\n*** Done ***\r\n"); // printf_Test result .... /* *** printf() test *** String test Char X Integer -12345 Unsigned 12345 Long -1234567890 uNsigned loNg 1234567890 heX ABCD multiple args test X -12345 12345 -1234567890 1234567890 ABCD *** Done *** */ } /*********************************************************************************/ /*! [Ring Buffer Functions] */ /*********************************************************************************/ /*********************************************************************************/ /*! @fn void ring_buffer_push_char(char c) @brief adds a char */ /*********************************************************************************/ void ring_buffer_push_char(char c) { // increase ring_buffer_write_pointer, check if at end of array if (++ring_buffer_write_pointer >= RING_BUFFER_SIZE) ring_buffer_write_pointer = 0; ring_buffer[ring_buffer_write_pointer] = c; ring_buffer_data_size++; } /*********************************************************************************/ /*! @fn int ring_buffer_full(void) @brief returns 1 if buffer is full, 0 if buffer is not full */ /*********************************************************************************/ int ring_buffer_full(void) { return ring_buffer_read_pointer == ring_buffer_write_pointer && ring_buffer_data_size == RING_BUFFER_SIZE; } /*********************************************************************************/ /*! @fn int ring_buffer_empty(void) @brief returns 1 if buffer is empty, 0 if buffer is not empty */ /*********************************************************************************/ int ring_buffer_empty(void) { return ring_buffer_read_pointer == ring_buffer_write_pointer && ring_buffer_data_size == 0; } /*********************************************************************************/ /*! @fn void ring_buffer_pull_char(void) @brief pull char from queue */ /*********************************************************************************/ unsigned char ring_buffer_pull_char(void) { char rx; // added - also above unsigned char if (++ring_buffer_read_pointer >= RING_BUFFER_SIZE) ring_buffer_read_pointer = 0; rx = ring_buffer[ring_buffer_read_pointer]; // added // enter space on place of read char so we can see it is removed ring_buffer[ring_buffer_read_pointer] = 0x20; ring_buffer_data_size--; return rx; // added } /*********************************************************************************/ /*! @fn void flush_ring_buffer(void) @brief flushes ring buffer */ /*********************************************************************************/ void flush_ring_buffer(void){ // make sure there are no random chars in array, all spaces int i; for (i = 0; i < RING_BUFFER_SIZE; i++) ring_buffer[i] = 0x20; // spaces } /*********************************************************************************/ /*! [Command Line Functions] */ /*********************************************************************************/ /*********************************************************************************/ /*! @fn void cmd_show_help(void) @brief show cmd line help menu */ /*********************************************************************************/ void cmd_show_help(void) { const char *m0 = "<<--COMMAND LINE MENU-->>"; const char *m1 = "[A] LP Red LED ON"; const char *m2 = "[b] LP Red LED OFF"; const char *m3 = "[C] LP Green LED ON"; const char *m4 = "[D] LP Green LED OFF"; const char *m5 = "[E] Wr Data --> Prot. Flash Seg. D "; const char *m6 = "[F] Rd Data <-- Prot. Flash Seg. D "; const char *m7 = "[G] Wr / CLR Prot. Flash Seg. D with 0xFF"; const char *m8 = "[H] Show Help"; const char *prompt = "Cmd >> "; printf("\r\n"); printf("\r\n"); printf("%s\r\n",m0); printf("\r\n"); printf("%s\r\n",m1); printf("%s\r\n",m2); printf("%s\r\n",m3); printf("%s\r\n",m4); printf("%s\r\n",m5); printf("%s\r\n",m6); printf("%s\r\n",m7); printf("%s\r\n",m8); printf("\r\n"); printf("%s",prompt); } /*********************************************************************************/ /*! @fn void cmd_show_help_1(void) @brief show cmd line help menu */ /*********************************************************************************/ void cmd_show_help_1(void) { const char *m0 = "<<--COMMAND LINE MENU-->>"; const char *m1 = "[A] LP Red LED ON"; const char *m2 = "[b] LP Red LED OFF"; const char *m3 = "[C] Toggle Red & Grn LEDs"; const char *m4 = "[C] P1=1 Red LED ON"; const char *m5 = "[C] P2=2 Grn LED ON"; const char *m6 = "[C] P2=3 Red & Grn LEDs OFF"; const char *m7 = "[H] Show Help"; printf("\r\n"); printf("\r\n"); printf("%s\r\n",m0); printf("\r\n"); printf("%s\r\n",m1); printf("%s\r\n",m2); printf("%s\r\n",m3); printf("%s\r\n",m4); printf("%s\r\n",m5); printf("%s\r\n",m6); printf("%s\r\n",m7); } /*********************************************************************************/ /*! @fn poll_cmd(void) @brief Polls case/switch for keypress */ /*********************************************************************************/ void poll_cmd(void) { const char *FW = " Wr --> prot. flash seg. D ..."; const char *FR = " Rd <-- prot. flash seg. D ..."; const char *FC = " Wr --> prot. flash seg. D with 0xFF ..."; while(1){ char x; if (ring_buffer_data_size > 0){ x = ring_buffer_pull_char(); uart_put_char(x); // return/echo cmd char to uart screen } switch (x){ case 'A': case 'a': _nop(); RED_LED_ON(); _nop(); cmd_show_help(); break; case 'B': case 'b': _nop(); RED_LED_OFF(); _nop(); cmd_show_help(); break; case 'C': case 'c': GRN_LED_ON(); cmd_show_help(); break; case 'D': case 'd': GRN_LED_OFF(); cmd_show_help(); break; case 'E': case 'e': //MSPNode structure ref. only // write flash with MSPNode data mspnode.grp = 1; mspnode.id = 8; mspnode.band = 3; mspnode.dest = 20; write_P_D_Flash(); // uses flash MSPNode data structure (above) printf("%s\r\n", FW ); cmd_show_help(); break; case 'F': case 'f': read_P_D_Flash(); // uses flash MSPNode data structure (above) //MSPNode structure ref. only //mspnode.grp //mspnode.id //mspnode.band //mspnode.dest printf("%s\r\n", FR); printf(" Group ID = %x\r\n", mspnode.grp); printf(" Node ID = %x\r\n", mspnode.id); printf(" Band = %x\r\n", mspnode.band); printf(" Dest ID = %x\r\n", mspnode.dest); printf(" 10 Second Delay ... Please wait ... \r\n"); __delay_cycles(10000000); // 10 secs cmd_show_help(); break; case 'G': case 'g': FF_SegD (); // write 0xFF in all of seg D printf("%s\r\n", FC ); cmd_show_help(); break; case 'H': case 'h': cmd_show_help(); break; //default: } // end of case x = 0x20; // clear case char _nop(); } // end of while } /*********************************************************************************/ /*! @fn parse_Input(char c) @brief parses the user input char(s) and executes the case/switch command Cmd Format: p1,p2,p3,...cCR p1,p2,p3 = 0-255 Max, c is the cmd, chars 'a/A' - 'z/Z' & CR = enter/carriage return Examples: Cmd >> cCR --> will toggle both LEDs (stack[0]) with no other commands Cmd >> 1,0,0,cCR --> will turn on the red LED (stack[0]) Cmd >> 0,2,0,cCR --> will turn on the green LED (stack[1]) Cmd >> 0,0,3,cCR --> will turn off both red / green LEDs (stack[2]) */ /*********************************************************************************/ static void parse_Input(char c){ const char *status0 = "Toggle Red & Green LEDs "; const char *status1 = "Red LED ON "; const char *status2 = "Green LED ON "; const char *status3 = "Red & Green LEDs OFF "; char cr = NULL; uart_put_char(c); // return/echo char to uart screen if ('0' <= c && c <= '9') value = 10 * value + c - '0'; else if (c == ',') { if (top < sizeof stack) stack[top++] = value; value = 0; _nop(); } else if (('a' <= c && c <='z') || ('A' <= c && c <='Z')) { stack[top++] = c; // store command on stack while (!(cr == 0x0D)){ // wait for CR 0x0D if (ring_buffer_data_size > 0) // data available cr = ring_buffer_pull_char(); __delay_cycles(1000); // 1 ms } stack[top++] = cr; // store CR on stack stack[top--] = c; // get and process command from stack switch (c) { default: printf(" Cmd >> "); break; case 'A': case 'a': _nop(); RED_LED_ON(); printf( "\r\nRed LED ON\r\n"); _nop(); break; case 'B': case 'b': _nop(); RED_LED_OFF(); printf( "\r\nRed LED OFF\r\n"); break; case 'C': // command line parameter test case 'c': _nop(); // Process command only _nop(); if ((stack[0] == 'c') || (stack[0] == 'C')){ // stack buffer begins stack[0] // toggle both red and green LEDs RED_LED_FLIP(); GRN_LED_FLIP(); printf("\r\n%s\r\n",status0); break; // No parameters were entered - just the command was entered } // Process parameters // Parameter input values of 0-255 _nop(); if (stack[0] == 0x01){ // first parameter // Turn Red LED ON RED_LED_ON(); _nop(); printf("%\r\n%s\r\n",status1); _nop(); } if (stack[1] == 0x02){ // second parameter // Turn Green LED ON GRN_LED_ON(); _nop(); printf("%\r\n%s\r\n",status2); _nop(); } if (stack[2] == 0x03){ // third parameter // Turn both LEDs off RED_LED_OFF(); GRN_LED_OFF(); printf("\r\n%s\r\n",status3); _nop(); } break; case 'H': case 'h': _nop(); cmd_show_help_1(); //status = "Show Help"; break; } // end of case _nop(); printf("\r\nCmd >> "); value = top = 0; memset(stack, 0, sizeof stack); } else if (c > ' '){ // greater than 'space' value = top = 0; } if (c == 0x0D){ // exit on CR value = top = 0; memset(stack, 0, sizeof stack); printf("\r\nCmd >> "); } } // eof /*********************************************************************************/ /*! @fn poll_cmd_1(void) @brief */ /*********************************************************************************/ void poll_cmd_1(void) { if (ring_buffer_data_size > 0) // data available parse_Input(ring_buffer_pull_char()); } /*********************************************************************************/ /*! PROTECTED FLASH FUNCTIONS WARNING ...DO NOT LOOP THE WRITE FUNCTION - WILL CAUSE FLASH WEAR FAILURES!!!! */ /*********************************************************************************/ /*********************************************************************************/ /*! @fn write_P_D_Flash() @brief Writes flash structure to protected flash segment D - 2553 only WARNING ...DO NOT LOOP THE WRITE FUNCTION - WILL CAUSE FLASH WEAR FAILURES!!!! */ /*********************************************************************************/ void write_P_D_Flash(void) { char *Flash_ptr; char *p = (char *)&mspnode; unsigned int i; //WARNING ...DO NOT LOOP THE WRITE FUNCTION - WILL CAUSE FLASH WEAR FAILURES!!!! // uses flash MSPNode data structure (above) Flash_ptr = (char *) 0x1000; // was 0x103F; Flash pointer, to segment D FCTL1 = FWKEY + ERASE; // Set Erase bit FCTL3 = FWKEY; // Clear Lock bit *Flash_ptr = 0; // Dummy write to erase Flash segment FCTL1 = FWKEY + WRT; // Set WRT bit for write operation for (i=0; i { *Flash_ptr++ = *p++; // Write value to flash } FCTL1 = FWKEY; // Clear WRT bit FCTL3 = FWKEY + LOCK; // Set LOCK bit } /*********************************************************************************/ /*! @fn read_P_D_Flash() @brief Reads flash structure to protected flash segment D - 2553 only WARNING ...DO NOT LOOP THE WRITE FUNCTION - WILL CAUSE FLASH WEAR FAILURES!!!! */ /*********************************************************************************/ void read_P_D_Flash(void) { char *Flash_ptr; char *p = (char *)&mspnode; unsigned int i; // uses flash MSPNode data structure (above) Flash_ptr = (char *)0x1000; // was 0x103F; Flash pointer to segment D for (i=0; i { *p++ = *Flash_ptr++; } } /*********************************************************************************/ /*! @fn FF_SegD (void) @brief Writes 0xFF to all of segment D. WARNING ...DO NOT LOOP THE WRITE FUNCTION - WILL CAUSE FLASH WEAR FAILURES!!!! */ /*********************************************************************************/ void FF_SegD (void) { char *Flash_ptr; // Flash pointer unsigned int i; Flash_ptr = (char *) 0x1000; // Initialize Flash pointer FCTL1 = FWKEY + ERASE; // Set Erase bit FCTL3 = FWKEY; // Clear Lock bit *Flash_ptr = 0; // Dummy write to erase Flash segment FCTL1 = FWKEY + WRT; // Set WRT bit for write operation for (i=0; i<64; i++) { *Flash_ptr++ = 0xFF; // Write value to flash } FCTL1 = FWKEY; // Clear WRT bit FCTL3 = FWKEY + LOCK; // Set LOCK bit } //================================================================================= //================================================================================= // The End LP_2553_Cmd_Line_Test_R6.zip (Beta) :ugeek:
  8. Hardware and Software Application Notes Using the Command Line Interface: The "Poor Mans Command Line" interface is a simple shell that can be run on an MSP430G2553. It's nothing fancy and its main purpose is to allow users to easily call their functions on a running MSP430G2553 via a simple serial terminal. It also allows users to pass in arguments from the command line into the functions they wrote so they can easily toggle pins, set blinking speed, set pwm duty cycles, or whatever else might need command line user input. For software, you'll need to use a serial terminal program to access the MSP430G2553 Hw serial port. For Windows, I'd recommend using a free program like "Tera term" Pro or RealTerm . For Linux, I'd recommend Picocom . And for Mac, you can simply use the "screen" command built into Mac OSX. Of course, there is a terminal program, built in program, into Ti's CCS which can be used to debug the serial data streams by the emulator electronics. The maximum speed setup for this terminal program is 9600 8 N 1 and don't forget to cris-cross the tx/rx on the "old" Launchpad header! This same serial communications data stream can also be viewed on the USB/VCP port, by using a PC and any of the above terminal programs. For hardware, if you are NOT using the LauchPads emulator electronics or USB/VCP port, you'll also need to use a separate USB to TTL converter module to convert the LaunchPad's TX and RX signals to USB.(You need to pull the header jumpers on the launchpad!) Make sure the signals are set for 3.3 VDC operation only!!!! Sparkfun, Modern Device and Adafruit has the USB/TTL modules. BTW ... Since the PC can communicate with the LanuchPad's serial port on the "2553" via USB/VCP then it could be very possible to have the LaunchPad connected to an Android device and have the Android device change the I/O on the LaunchPad! That's another future project. :ugeek:
  9. Breaking news ... The Poor Man's Command Line Shell WITH PARAMETERS is now in beta testing! The format will be comma separated variables with the last character being the command. Typing in 123,100,25,a will execute case/switch 'a' command with buf[0}, = 123, buf[1] = 100 and buf[2] = 25. Up the 12 character parameters can be entered. (0-255) Having the ability to communicate serially to the "2553" and setting up internal parameters in protected flash will alter the operation of the microcontroller without using the development IDE to re-program the chip. Your application code would be protected and the user would use a serial terminal to configure the microcontroller settings. Now the question arises "what can you do with it?" Setting up RF nodes, networking nodes, testing devices or almost anything that needs to alter program execution with a change in program variables or settings. :ugeek: Stay tuned ...
  10. Oops... I forgot to include my example code snippets for reading, writing, and clearing protected flash segment D for my RFM12B ISM RF node setup configuration parameters. Enjoy /*********************************************************************************/ /*! THIS SOFTWARE IS PROVIDED BY THE THE HOLDERS 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 INSTITUTE 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. THERE ARE BUGS IN ANY SOFTWARE. THERE COULD EVEN BE BUGS IN THIS SOFTWARE??? IF THERE WAS A TIME TO CALL THE BUG EXTERMINATOR, NOW WOULD BE THE TIME TO CALL 1-800-ORKIN. COLONIES OF BUGS ARE HARD TO EXTERMINATE IF YOU LET THEM BREED. IF YOU CAN'T CALL ORKIN JUST FIRE UP THE CCS DEBUGGER AND EXTERMINATE THEM YOURSELF! IF YOU USE THIS SOFTWARE AND YOUR HOUSE BURNS DOWN AND YOUR WIFE AND CHILDREN BECOMES HOMELESS AND WORST OF ALL YOUR DOG DIES, DON'T HOLD ME RESPONSIBLE! YOU CAN USE THIS CODE BUT PLEASE GIVE CREDIT TO THOSE WHO CONTRIBUTED TO IT. PLEASE INCLUDE ALL COPYWRITES HEADERS/FOOTERS IN YOUR SOFTWARE! */ /*********************************************************************************/ /*********************************************************************************/ /*! [Flash Structure] The MSP430G2553 the flash memory is organized as follow: 4 * 64 BYTE BLOCKS = 256 BYTES Flash_ptrA = (char *) 0x10C0; // 10C0-10FF Initialize Flash segment A pointer but never touch this! (calibration constants) Flash_ptrB = (char *) 0x1080; // 1080-10BF Initialize Flash segment B pointer Flash_ptrC = (char *) 0x1040; // 1040-107F Initialize Flash segment C pointer Flash_ptrD = (char *) 0x1000; // 1000-103F Initialize Flash segment D pointer */ /*********************************************************************************/ // We store all the MSPNode RFM12B RF node config data in a structure so that // we can save it in the flash memory. (MSPNode is JeeNode protocol compatible) struct MSPNode { // MSPNode Group ID (1-254) unsigned char grp; // MSPNode Node ID (1-30) unsigned char id; // RFM12B ISM Freq. Band <--- Marked On RFM12B chip! //RF12_433MHZ 1 //RF12_868MHZ 2 //RF12_915MHZ 3 unsigned char band; // RFM12B Central Node ID unsigned char dest; } mspnode = {1,8,3,20}; // <---- init values to write to protected flash segment D (64 bytes total) // ref. only //mspnode.grp //mspnode.id //mspnode.band //mspnode.dest // protected flash prototypes // *******DO NOT LOOP THE WRITE FUNCTION - WILL CAUSE FLASH WEAR FAILURES!!!!! ******* void write_P_D_Flash(void); // uses MSPNode data structure (above) void read_P_D_Flash(void); // uses MSPNode data structure (above) void FF_SegD (void); // put FF in all of segment D /*********************************************************************************/ /*! PROTECTED FLASH FUNCTIONS WARNING ...DO NOT LOOP THE WRITE FUNCTION - WILL CAUSE FLASH WEAR FAILURES!!!! */ /*********************************************************************************/ /*********************************************************************************/ /*! @fn write_P_D_Flash() @brief Writes flash structure to protected flash segment D - 2553 only WARNING ...DO NOT LOOP THE WRITE FUNCTION - WILL CAUSE FLASH WEAR FAILURES!!!! */ /*********************************************************************************/ void write_P_D_Flash(void) { char *Flash_ptr; char *p = (char *)&mspnode; unsigned int i; //WARNING ...DO NOT LOOP THE WRITE FUNCTION - WILL CAUSE FLASH WEAR FAILURES!!!! // uses flash MSPNode data structure (above) Flash_ptr = (char *) 0x1000; // was 0x103F; Flash pointer, to segment D FCTL1 = FWKEY + ERASE; // Set Erase bit FCTL3 = FWKEY; // Clear Lock bit *Flash_ptr = 0; // Dummy write to erase Flash segment FCTL1 = FWKEY + WRT; // Set WRT bit for write operation for (i=0; i { *Flash_ptr++ = *p++; // Write value to flash } FCTL1 = FWKEY; // Clear WRT bit FCTL3 = FWKEY + LOCK; // Set LOCK bit } /*********************************************************************************/ /*! @fn read_P_D_Flash() @brief Reads flash structure to protected flash segment D - 2553 only WARNING ...DO NOT LOOP THE WRITE FUNCTION - WILL CAUSE FLASH WEAR FAILURES!!!! */ /*********************************************************************************/ void read_P_D_Flash(void) { char *Flash_ptr; char *p = (char *)&mspnode; unsigned int i; // uses flash MSPNode data structure (above) Flash_ptr = (char *)0x1000; // was 0x103F; Flash pointer to segment D for (i=0; i { *p++ = *Flash_ptr++; } } /*********************************************************************************/ /*! @fn FF_SegD (void) @brief Writes 0xFF to all of segment D. WARNING ...DO NOT LOOP THE WRITE FUNCTION - WILL CAUSE FLASH WEAR FAILURES!!!! */ /*********************************************************************************/ void FF_SegD (void) { char *Flash_ptr; // Flash pointer unsigned int i; Flash_ptr = (char *) 0x1000; // Initialize Flash pointer FCTL1 = FWKEY + ERASE; // Set Erase bit FCTL3 = FWKEY; // Clear Lock bit *Flash_ptr = 0; // Dummy write to erase Flash segment FCTL1 = FWKEY + WRT; // Set WRT bit for write operation for (i=0; i<64; i++) { *Flash_ptr++ = 0xFF; // Write value to flash } FCTL1 = FWKEY; // Clear WRT bit FCTL3 = FWKEY + LOCK; // Set LOCK bit } //end
  11. The "2553" with 16 K of flash provides plenty for extra program space in flash memory but TI should try to increase the size of RAM from 512 bytes to 2K. :ugeek:
  12. WARNING ... After importing the project into your workspace, do the following FIRST. Click on the main.cfg file (GRACE) to edit and wait ... wait until all processing is done! (see bottom right progress bar). After you can see the GRACE overview screen then rebuild the project. This would stop any compile problems with the project files. Project compiles best with CCS v 4.1. Poor_Mans_Command_Line_Shell.zip
  13. Why did I call this program a Poor Man's Command Line Shell? :?: Using the case/switch command only allows one command (char letter) per menu selection to run the user defined code snippet. There is also a "Rich Man's Command Line Shell" that can be seen by the following link tutorial: http://freaklabs.org/index.php/Tutorials/Software/Tutorial-Using-CmdArduino.html From this tutorial, a user can type in a pre-defined function name with parameter(s) at the command prompt. For instance, PWM 50 would tell the microcontroller to output PWM at 50%. The user function would then parse/decode the list of parameters by the command line shell. For user applications, which uses multiple parameters, like RF Node setup/configuration, this shell would be very flexiable and useful. By inputting multiple parameters, at the command prompt, the RF node variables could be sent to "protected flash" to be used for RF node configuration. Also, using this "parameter command shell", networking of "2553"s would be extremely easy. I tried to hack/patch this "freaklabs" command line shell on the "2553" but the complex command handlers, parsers and tables caused total failure. Only a "professional programmer" could probably make this code functional on the MSP430G2553. I will post my hacked code, on this board for others to fix and debug, if requested.
  14. I needed to serially input data in my "2553" LaunchPad using the hardware Uart. I hacked together some code which has Printf(), a receive ring buffer, Uart routines, and the case/switch Poor Man's Command Line Shell. You need to criss-cross the tx/rx on the LP header and use the terminal program in CCS 4.1. Please Note: CCS 5 does not have the terminal program installed ! :evil: Note: GRACE was used to setup the USCI_A0 hw UART at 9600 8 N 1 Enjoy Edited. 1/27/12 Ti took out the terminal program in CCS v 5 but you can add it back into the software. http://processors.wiki.ti.com/index.php/How_to_install_the_terminal_plugin_in_CCSv5 /*********************************************************************************/ /*! THIS SOFTWARE IS PROVIDED BY THE THE HOLDERS 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 INSTITUTE 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. IF YOU USE THIS SOFTWARE AND YOUR HOUSE BURNS DOWN AND YOUR WIFE AND CHILDREN BECOMES HOMELESS AND WORST OF ALL YOUR DOG DIES, DON'T HOLD ME RESPONSIBLE! YOU CAN USE THIS CODE BUT PLEASE GIVE CREDIT TO THOSE WHO CONTRIBUTED TO IT. PLEASE INCLUDE ALL COPYWRITES HEADERS/FOOTERS IN YOUR SOFTWARE. */ /*********************************************************************************/ /*********************************************************************************/ /*! Author: MSP430Andy Description: LP_2553_Cmd_Line - command line shell or interpreter. Program Revision: 1.0b (beta) Date: 2/1/12 PC Platform: Windows PC/SP3 Development platform: LaunchPad revision 2 firmware. PC compiler used: Eclipse with CCS 4.1 & 5 <--- Missing terminal program in 5 !!!!! Configuration setup I/O generated by: GRACE Device used: MSP430G2553 Pin DIP Software Module: USCI_A0 at 9600, 8 N 1 Bugs: 1. Syntax warnings in function printf()? - routine works but there were no errors in CCS 4.1? Code size: 2553 Device: 16K flash, 512 bytes RAM Flash used: xxx k RAM used: xxx bytes (without printf_Test() Program status OK */ /*********************************************************************************/ /*********************************************************************************/ /*! [includes] */ /*********************************************************************************/ #include // GRACE Include #include // Support Include #include // for printF #include /*********************************************************************************/ /*! [Defines] */ /*********************************************************************************/ // Red LED - on board on LaunchPad #define RED_LED_OFF() P1OUT &= ~BIT0 #define RED_LED_ON() P1OUT |= BIT0 #define RED_LED_FLIP() P1OUT ^= BIT0 // Green LED - on board on LaunchPad #define GRN_LED_OFF() P1OUT &= ~BIT6 #define GRN_LED_ON() P1OUT |= BIT6 #define GRN_LED_FLIP() P1OUT ^= BIT6 #define TX_RX_DIAG 0 // [1 = Toggles LP LEDs rx = grn & tx = red] [0 = all off] #define SYNC_BYTE 0x7E // 127 dec #define ESCAPE_BYTE 0x7D // 128 dec /*********************************************************************************/ /*! [Rx Ring Buffer] */ /*********************************************************************************/ //Ring Buffer #define RING_BUFFER_SIZE 32 char ring_buffer[RING_BUFFER_SIZE]; // usci_A0 rx ring buffer /* Size of RX ring buffer */ #define RING_BUFFER_MASK ( RING_BUFFER_SIZE - 1) #if ( RING_BUFFER_SIZE & RING_BUFFER_MASK ) #error RX ring buffer size is not a power of 2 #endif // Ring Buffer Global Variables int ring_buffer_data_size = 0; // number of chars in buffer int ring_buffer_read_pointer = 0; // indice number of last read char int ring_buffer_write_pointer = 0; // indice number of last written char /*********************************************************************************/ /*! [Printf] */ /*********************************************************************************/ //Printf Functions void printf_putc (unsigned char c); void printf_puts(char *s); void printf(char *, ...); void printf_Test(void); /*********************************************************************************/ /*! [Rx Receive Callback] */ /*********************************************************************************/ // Callbacks static uint8_t dummy_callback( uint8_t ); // default ring buffer callback // Holds pointers to all callback functions for USCI_AO rx buffer static uint8_t (*uart_rx_callback)( uint8_t ) = dummy_callback; /*********************************************************************************/ /*! [Function Prototypes] */ /*********************************************************************************/ // rx ring buffer prototypes int ring_buffer_full(void); int ring_buffer_empty(void); void ring_buffer_push_char(char c); // to ring buffer unsigned char ring_buffer_pull_char(void); // from ring buffer <------<<<< for rx void flush_ring_buffer(void); // clear ring buffer with spaces 0x20 // usci_a0 uart prototypes void uart_put_char( uint8_t ); // <-------<<<<< for tx void uart_write_buffer( uint8_t*, uint16_t ); void uart_write_buffer_escaped( uint8_t*, uint16_t ); uint8_t hex_to_string( uint8_t* , uint8_t*, uint8_t ); // cmd line prototypes void cmd_show_help(void); void poll_cmd(void); /*********************************************************************************/ /*! [Main] */ /*********************************************************************************/ void main(void) { CSL_init(); // Activate Grace-generated configuration __enable_interrupt(); // Set global interrupt enable flush_ring_buffer(); // clear receive ring buffer with spaces 0x20 //_________________________________________________________________________________ RED_LED_OFF(); GRN_LED_OFF(); //printf_Test(); cmd_show_help(); while(1){ poll_cmd(); } } // end of main /*********************************************************************************/ /*! [uART_USCI_A0_RX_ISR] */ /*********************************************************************************/ void UART_USCI_A0_RX_ISR(void){ // Process incoming byte from USART if( IFG2 & UCA0RXIFG ) { // Call rx callback function (default - dummy) or // ring_buffer_callback if selected if( uart_rx_callback( UCA0RXBUF ) ) { // If function returns something nonzero, wakeup the processor //__bic_SR_register_on_exit(LPM1_bits); _nop(); } } } /*********************************************************************************/ /*! [user Application Functions] */ /*********************************************************************************/ /*********************************************************************************/ /*! [uART Functions] */ /*********************************************************************************/ /*********************************************************************************/ /*! @fn uart_put_char( uint8_t character ) @brief transmit single character */ /*********************************************************************************/ void uart_put_char( uint8_t character ) { while (!(IFG2&UCA0TXIFG)); // USCI_A0 TX buffer ready? UCA0TXBUF = character; if (TX_RX_DIAG){ RED_LED_FLIP(); } } /*********************************************************************************/ /*! @fn uart_write_buffer( uint8_t character ) @brief transmit whole buffer */ /*********************************************************************************/ void uart_write_buffer( uint8_t* buffer, uint16_t length ) { uint16_t buffer_index; for( buffer_index = 0; buffer_index < length; buffer_index++ ) { while (!(IFG2&UCA0TXIFG)); // USCI_A0 TX buffer ready? UCA0TXBUF = buffer[buffer_index]; } } /*********************************************************************************/ /*! @fn uart_write_buffer_escaped( uint8_t character ) @brief transmit whole buffer while escaping characters The uart_write_buffer_escaped() is more for sending whole packets through the serial peripheral to the computer. Normally you just send a stream of bytes. Unfortunately, there is no way for the computer to know when a stream of data begins or ends. This function uses the 0x7E byte as a start and end of packets. This way, the receiver knows when to begin and end capturing data. If your data contains a 0x7E, that might confuse the receiver, so you must escape it by preceding it with a 0x7D and modifying it. The receiver must be aware of this to process it accordingly. */ /*********************************************************************************/ void uart_write_buffer_escaped( uint8_t* buffer, uint16_t length ) { uint16_t buffer_index; while (!(IFG2&UCA0TXIFG)); // USCI_A0 TX buffer ready? UCA0TXBUF = SYNC_BYTE; for( buffer_index = 0; buffer_index < length; buffer_index++ ) { if( (buffer[buffer_index] == SYNC_BYTE) | (buffer[buffer_index] == ESCAPE_BYTE) ) { while (!(IFG2&UCA0TXIFG)); // USCI_A0 TX buffer ready? UCA0TXBUF = ESCAPE_BYTE; while (!(IFG2&UCA0TXIFG)); // USCI_A0 TX buffer ready? UCA0TXBUF = buffer[buffer_index] ^ 0x20; } else { while (!(IFG2&UCA0TXIFG)); // USCI_A0 TX buffer ready? UCA0TXBUF = buffer[buffer_index]; } } while (!(IFG2&UCA0TXIFG)); // USCI_A0 TX buffer ready? UCA0TXBUF = SYNC_BYTE; } /*********************************************************************************/ /*! @fn void dummy_callback( uint8_t rx_char ) @brief empty function works as default callback */ /*********************************************************************************/ static uint8_t dummy_callback( uint8_t rx_char ) { if (TX_RX_DIAG){ GRN_LED_FLIP(); } //uart_put_char(rx_char); // turnaround echo to tx <----- for test only ring_buffer_push_char(rx_char); // Put/push char into ring buffer return 0; } /*********************************************************************************/ /*! @fn uint8_t hex_to_string( uint8_t* buffer_out, uint8_t* buffer_in, uint8_t buffer_in_size ) @brief DEBUG function used to convert hex values to [hex]string format The hex_to_string function was just for debugging. When you want to display a value, you usually use printf(). Unfortunately, printf takes a lot of cycles to format the data, and if you're doing time-sensitive stuff, you can't afford the delay. In cases where you don't have full debugging capability, you might want to print out the values of some registers or variables. the hex_to_string() function converts a value to a hexadecimal string. */ /*********************************************************************************/ uint8_t hex_to_string( uint8_t* buffer_out, uint8_t* buffer_in, uint8_t buffer_in_size ) { static const uint8_t hex_char[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; uint8_t counter = 0; while( counter < buffer_in_size * 2 ) { buffer_out[counter] = hex_char[((buffer_in[(counter>>1)]>>4) & 0xF)]; counter++; buffer_out[counter] = hex_char[(buffer_in[(counter>>1)] & 0xF)]; counter++; } // Terminate string with null character buffer_out[counter++] = 0; return counter; } /*********************************************************************************/ /*! [Printf Functions] */ /*********************************************************************************/ /*********************************************************************************/ /*! @fn void printf_putc (unsigned char c) @brief put char into tx buffer */ /*********************************************************************************/ void printf_putc (unsigned char c) { _nop(); while (!(IFG2&UCA0TXIFG)); // USCI_A0 TX buffer ready? UCA0TXBUF = c; // TX <-- c } /*********************************************************************************/ /*! @fn void printf_puts(char *s) { while(*s) printf_putc(*s++); @brief put string chars into into tx buffer */ /*********************************************************************************/ void printf_puts(char *s) { while(*s) printf_putc(*s++); } /*********************************************************************************/ /*! @fn @brief */ /*********************************************************************************/ static const unsigned long dv[] = { // 4294967296 // 32 bit unsigned max 1000000000, // +0 100000000, // +1 10000000, // +2 1000000, // +3 100000, // +4 // 65535 // 16 bit unsigned max 10000, // +5 1000, // +6 100, // +7 10, // +8 1, // +9 }; /*********************************************************************************/ /*! @fn @brief */ /*********************************************************************************/ static void xtoa(unsigned long x, const unsigned long *dp) { char c; unsigned long d; if(x) { while(x < *dp) ++dp; do { d = *dp++; c = '0'; while(x >= d) ++c, x -= d; printf_putc(c); } while(!(d & 1)); } else printf_putc('0'); } /*********************************************************************************/ /*! @fn @brief */ /*********************************************************************************/ static void puth(unsigned n) { static const char hex[16] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; printf_putc(hex[n & 15]); } /***********************************************************************************/ /*! @fn @brief */ /***********************************************************************************/ void printf(char *format, ...) { char c; int i; long n; va_list a; va_start(a, format); while(c = *format++) { if(c == '%') { switch(c = *format++) { case 's': // String printf_puts(va_arg(a, char*)); break; case 'c': // Char printf_putc(va_arg(a, char)); break; case 'i': // 16 bit Integer case 'u': // 16 bit Unsigned i = va_arg(a, int); if(c == 'i' && i < 0) i = -i, printf_putc('-'); xtoa((unsigned)i, dv + 5); break; case 'l': // 32 bit Long case 'n': // 32 bit uNsigned loNg n = va_arg(a, long); if(c == 'l' && n < 0) n = -n, printf_putc('-'); xtoa((unsigned long)n, dv); break; case 'x': // 16 bit heXadecimal i = va_arg(a, int); puth(i >> 12); puth(i >> 8); puth(i >> 4); puth(i); break; case 0: return; default: goto bad_fmt; } } else bad_fmt: printf_putc(c); } va_end(a); } /***********************************************************************************/ /*! @fn @brief */ /***********************************************************************************/ void printf_Test(void){ /* ================= Printf() for 2553 ================= There are 7 format specifiers: %c - Character %s - String %i - signed Integer (16 bit) %u - Unsigned integer (16 bit) %l - signed Long (32 bit) %n - uNsigned loNg (32 bit) %x - heXadecimal (16 bit) Field width, floating point and other standard printf() features are not supported. */ const char *s = "test"; const char c = 'X'; const int i = -12345; const unsigned u = 12345; const long int l = -1234567890; const long unsigned n = 1234567890; const unsigned x = 0xABCD ; //hex printf("%s", "\r\n*** printf() test ***\r\n"); printf("String %s\r\n", s); printf("Char %c\r\n", c); printf("Integer %i\r\n", i); printf("Unsigned %u\r\n", u); printf("Long %l\r\n", l); printf("uNsigned loNg %n\r\n", n); printf("heX %x\r\n", x); printf("multiple args %s %c %i %u %l %n %x\r\n", s, c, i, u, l, n, x); printf("\r\n*** Done ***\r\n"); // printf_Test result .... /* *** printf() test *** String test Char X Integer -12345 Unsigned 12345 Long -1234567890 uNsigned loNg 1234567890 heX ABCD multiple args test X -12345 12345 -1234567890 1234567890 ABCD *** Done *** */ } /*********************************************************************************/ /*! [Ring Buffer Functions] */ /*********************************************************************************/ /*********************************************************************************/ /*! @fn void ring_buffer_push_char(char c) @brief adds a char */ /*********************************************************************************/ void ring_buffer_push_char(char c) { // increase ring_buffer_write_pointer, check if at end of array if (++ring_buffer_write_pointer >= RING_BUFFER_SIZE) ring_buffer_write_pointer = 0; ring_buffer[ring_buffer_write_pointer] = c; ring_buffer_data_size++; } /*********************************************************************************/ /*! @fn int ring_buffer_full(void) @brief returns 1 if buffer is full, 0 if buffer is not full */ /*********************************************************************************/ int ring_buffer_full(void) { return ring_buffer_read_pointer == ring_buffer_write_pointer && ring_buffer_data_size == RING_BUFFER_SIZE; } /*********************************************************************************/ /*! @fn int ring_buffer_empty(void) @brief returns 1 if buffer is empty, 0 if buffer is not empty */ /*********************************************************************************/ int ring_buffer_empty(void) { return ring_buffer_read_pointer == ring_buffer_write_pointer && ring_buffer_data_size == 0; } /*********************************************************************************/ /*! @fn void ring_buffer_pull_char(void) @brief pull char from queue */ /*********************************************************************************/ unsigned char ring_buffer_pull_char(void) { char rx; // added - also above unsigned char if (++ring_buffer_read_pointer >= RING_BUFFER_SIZE) ring_buffer_read_pointer = 0; rx = ring_buffer[ring_buffer_read_pointer]; // added // enter space on place of read char so we can see it is removed ring_buffer[ring_buffer_read_pointer] = 0x20; ring_buffer_data_size--; return rx; // added } /*********************************************************************************/ /*! @fn void flush_ring_buffer(void) @brief flushes ring buffer */ /*********************************************************************************/ void flush_ring_buffer(void){ // make sure there are no random chars in array, all spaces int i; for (i = 0; i < RING_BUFFER_SIZE; i++) ring_buffer[i] = 0x20; // spaces } /*********************************************************************************/ /*! [Command Line Functions] */ /*********************************************************************************/ /*********************************************************************************/ /*! @fn void cmd_show_help(void) @brief show cmd line help menu */ /*********************************************************************************/ void cmd_show_help(void) { const char *m0 = "<<--COMMAND LINE MENU-->>"; const char *m1 = "[A] LP Red LED ON"; const char *m2 = "[b] LP Red LED OFF"; const char *m3 = "[C] LP Green LED ON"; const char *m4 = "[D] LP Green LED OFF"; const char *m5 = "[E] Command #5 Spare Text"; const char *m6 = "[F] Command #6 Spare Text"; const char *m7 = "[G] Command #7 Spare Text"; const char *m8 = "[?] Show Help"; const char *prompt = "Cmd >> "; printf("\r\n"); printf("\r\n"); printf("%s\r\n",m0); printf("\r\n"); printf("%s\r\n",m1); printf("%s\r\n",m2); printf("%s\r\n",m3); printf("%s\r\n",m4); printf("%s\r\n",m5); printf("%s\r\n",m6); printf("%s\r\n",m7); printf("%s\r\n",m8); printf("\r\n"); printf("%s",prompt); } /*********************************************************************************/ /*! @fn @brief */ /*********************************************************************************/ void poll_cmd(void) { while(1){ char x; if (ring_buffer_data_size > 0){ x = ring_buffer_pull_char(); uart_put_char(x); // return/echo cmd char to uart screen } switch (x){ case 'A': case 'a': _nop(); RED_LED_ON(); _nop(); cmd_show_help(); break; case 'B': case 'b': _nop(); RED_LED_OFF(); _nop(); cmd_show_help(); break; case 'C': case 'c': GRN_LED_ON(); cmd_show_help(); break; case 'D': case 'd': GRN_LED_OFF(); cmd_show_help(); break; case 'E': case 'e': cmd_show_help(); break; case 'F': case 'f': cmd_show_help(); break; case 'G': case 'g': cmd_show_help(); break; case '?': cmd_show_help(); break; //default: } // end of case x = 0x20; // clear case char _nop(); } // end of while } //================================================================================= //================================================================================= // The End
×
×
  • Create New...