Created
April 10, 2012 03:20
-
-
Save RickKimball/2348134 to your computer and use it in GitHub Desktop.
msp430 port of tlv data dump
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* tlv_data dumper - msp430-gcc port | |
* | |
* see: http://www.43oh.com/forum/viewtopic.php?f=10&t=2547 | |
* | |
*/ | |
#include <msp430.h> | |
#include <stdint.h> | |
volatile unsigned ta0txbuf = 0; // Timer0_A0 Transmit buffer pseudo register | |
static const uint16_t CYCLES_PER_BIT = 1000000/9600; | |
void TIMER0_A0_ISR(void) __attribute__((interrupt(TIMER0_A0_VECTOR))); | |
void init_serial() { | |
TACCTL0 = OUTMOD_0 | OUT; // immediately sets TA0.0 (P1.1) high | |
TACTL = TASSEL_2 | MC_2; // Use SMCLK, Continuous Up Mode | |
P1SEL |= BIT1; | |
P1DIR |= BIT1; | |
} | |
/** | |
* TIMER0_A0_ISR() - XMIT 10 bits in LSB order from TA0TXBUF | |
* | |
* Use TimerA0 CCR0 to send the data from TA0TXBUF. ISR assumes that | |
* TA0TXBUF 10 bits of data, 1 Start Bit + 8 Data Bits + 1 Stop bit. | |
* | |
*/ | |
void TIMER0_A0_ISR(void) { | |
if ( ta0txbuf ) { // have we sent all 10 bits? | |
if (ta0txbuf & BIT0) { | |
// OUTMOD_1-(1) Set | |
TACCTL0 &= ~(OUTMOD_5) | OUTMOD_1; | |
} | |
else { | |
// OUTMOD_5-(0) Reset | |
TACCTL0 |= OUTMOD_5; | |
} | |
ta0txbuf >>= 1; // shift next bit to send into BIT0 | |
TACCR0 += CYCLES_PER_BIT; // Set future time to send next bit | |
} | |
else { | |
TACCTL0 &= ~CCIE; // we are done, disable interrupt | |
} | |
} | |
void putchar(const uint8_t c) { | |
while (TACCTL0 & CCIE); // wait for previous xmit to finish | |
ta0txbuf = 0x0200 | (c << 1); // start bit + data + stop bit | |
TACCR0 = TAR + 16; // start slightly in the future | |
TACCTL0 = OUTMOD_1 | CCIE; // P1.1 set high, enable interrupt | |
} | |
void print(const char *s) { | |
while (*s) | |
putchar(*s++); | |
} | |
void print_hex_digit(unsigned n) { | |
putchar("0123456789ABCDEF"[n & 0x0F]); | |
} | |
void print_hex_byte(unsigned n) { | |
print_hex_digit(n >> 4); | |
print_hex_digit(n); | |
} | |
void print_hex_word(unsigned n) { | |
print_hex_digit(n >> 12); | |
print_hex_digit(n >> 8); | |
print_hex_digit(n >> 4); | |
print_hex_digit(n); | |
} | |
// TLV tags | |
static const char * const tag_checksum[] = { "Checksum", 0 }; | |
static const char * const tag_empty[] = { "TAG_EMPTY", 0 }; | |
static const char * const tag_unknown[] = { "Unknown Tag", 0 }; | |
static const char * const tag_dco[] = { | |
"TAG_DCO_30", | |
"CALBC1_16MHZ CALDCO_16MHZ", | |
"CALBC1_12MHZ CALDCO_12MHZ", | |
"CALBC1_8MHZ CALDCO_8MHZ", | |
"CALBC1_1MHZ CALDCO_1MHZ", | |
0 | |
}; | |
static const char * const tag_adc[] = { | |
"TAG_ADC1x_1", | |
"CAL_ADC_GAIN_FACTOR", | |
"CAL_ADC_OFFSET", | |
"CAL_ADC_15VREF_FACTOR", | |
"CAL_ADC_15T30", | |
"CAL_ADC_15T85", | |
"CAL_ADC_25VREF_FACTOR", | |
"CAL_ADC_25T30", | |
"CAL_ADC_25T85", | |
0 | |
}; | |
void dump_tlv_segment(const unsigned a, const unsigned n) | |
{ | |
const unsigned * const s = (unsigned *)a; // Start of info segment | |
const unsigned * const e = s + n; // End of info segment | |
const char * const *tag = tag_checksum; // Segment begins with checksum | |
unsigned len = 2; // Length of checksum | |
unsigned chk = 0; // Init checksum | |
const unsigned *p; | |
for(p = s; p < e; ++p, len -= 2) { // Do segment | |
const unsigned d = *p; // Get a word | |
chk ^= d; // Update checksum | |
if(!len) { // Next tag? | |
len = 2 + (d >> 8); // Setup length of tag | |
switch(d & 0xFF) { // Setup for tag type | |
case 0x01: tag = tag_dco; break; // DCO cal | |
case 0x08: tag = tag_adc; break; // ADC cal | |
case 0xFE: tag = tag_empty; break; // Empty | |
default: tag = tag_unknown; break; // Unknown | |
} | |
} | |
print_hex_word((unsigned)p); // Address | |
print(" "); | |
print_hex_word(d); // Data | |
if(*tag) { // Tag | |
print(" "); print(*tag); ++tag; | |
} | |
print("\r\n"); | |
} | |
chk ^= *s; // Fixup and validate checksum | |
chk += *s; | |
//print_hex_word(chk); | |
print("Checksum is "); | |
if(chk) print("IN"); | |
print("valid\r\n"); | |
} | |
int main(void) { | |
WDTCTL = WDTPW | WDTHOLD; | |
DCOCTL = 0; | |
BCSCTL1 = CALBC1_1MHZ; | |
DCOCTL = CALDCO_1MHZ; | |
__delay_cycles(0xffff); // let DCO stabilize for ~65ms | |
init_serial(); | |
__enable_interrupt(); | |
print("Tag Length Value entries in Info Segment A\r\n"); | |
dump_tlv_segment(0x10C0, 32); | |
for (;;); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment