Hi,
I think that in rpm_fun you should get timestamps to compute the time between sparks instead of counting pulses.
Anither ideea would be to use pulseIn to get the duration ( measure both high and low pulses). This method will do measurements on differen pulses, but as the engine is a slow system compared to the microcontroller, this should not be a problem.
This is a simple voltage and current meter that uses the TI INA219 chip. Voltage measurement range is 0 to 26 volts with 4 mV resolution and current measurement range is -4 to +4 amps with 1 mV resolution (when using a 0.01 ohm shunt). The specs are inferior to a pair of quality multimeters, but it is a fraction of the price and shows wattage in addition to voltage and current. The Nokia 5110 display is used so the firmware could be enhanced to do simple graphing. Sending the measurements to a computer could also be done.
Using the INA219 makes for a very simple circuit.
The normal display is three lines with voltage, amperage and wattage.
Pressing the P1.3 switch will show the 6 registers in the INA219 in hex and signed decimal.
The code is written in C++ and uses templates for the LCD, IIC and INA219. Software SPI and IIC is used for maximum portability.
vam.zip
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
I was working on a GUI that would be able to control any and all functions on a particular MSP430 processor from a PC GUI. Only limitations a course would be P1.1 and P1.2 which are required for GUI communication. This is very very very much so a work in progress. Currently i'm writing it using WX Widgets libraries to simplify the GUI aspect of it. However, currently i'm not using a "form builder" so it is going to take a handy amount of time to write. Good c++ experience though....
This GUI would be very handy to have from a hardware/software test debug standpoint. For example, say I wanted to test out some SPI sensor I purchased, I could use a GUI such as this to send custom SPI packets to the device i'm testing and read/observe results live. That as opposed to having to write a micro.c file to do the communication and re write it every time something doesn't work.
Many thanks to rick and suggaraddict for assistance on c++ coding help
GUI Download Rev 0.5 : https://github.com/NateZimmer/MSP430-Ev ... I_EVAL.exe (windows.exe, click "view raw" to download)
(feedback on whether or not it works for you would be great. Gaurenteed to work with a FTDI RS232 -> USB. However, launchpad drivers suppperr flakey and crapey )
Remember to flash https://github.com/NateZimmer/MSP430-Ev ... er/GUI.cpp to your MSP430G2553
Source Code is now at https://github.com/NateZimmer/MSP430-Eval-Tool
(your going to need to download and BUILD the wx libraries to get this to work)
Main Connect tab: Implemented
Digital Output tab: Implemented
Digital Input tab: Implemented
SPI Tab: Implemented but not fully tested
Analog Input tab: In Progress
Connection Issue Debug
1. Make sure you got a Rev1.5 launchpad with a G2553 micro flashed with the proper code provided. Also, makesure your jumpers are set to hardware uart.
2. If that doesn't work... sadly, the TI RS232 <-> USB sucks hardcore compared to FTDI that always works. Once a connection is established, it works fine. However, getting that first connection can be a super pain. If your having connection issues, open up a terminal program(such as putty), connect to the com port of your msp430, and press the "1" key and ONLY the 1 key. If your msp430 is working properly you should receive "PING" back. At that point, close the terminal program and open up my .exe program. At that point, it should connect fine.