MSP430 USB Stick Development Tool Program #3

(If you find this page, you can use this Software. I'd appreciate it if you let me know.)

Back to MSP430 USB Stick Development Tool Page

Morse Code Power-Up counter is a program that uses Flash to keep track of the number of times the device is started. It blips the LED on P1.0 and sends a tone on P1.1 to send out this count. So, with a modification to the Development Stick that brings a wire out from the first discrete output pin, you can actually have audio. In my setup I used two resistors (1k & 330) to voltage divide the discrete output and feed the resultant signal into my computers AUX audio input. A filter cap might help, but the tone sounds pretty good to me.

Unlike the Morse Code thermometer I am using the PWM output for the audio output.




//******************************************************************************
//  MSP430F20xx Demo - Timer_A, Toggle P1.0, CCR0 Cont. Mode ISR, DCO SMCLK
//
//  Description: Clear the next bit in Segment C of Flash Memory every time
//  the program begins to execute.  This way it keeps track of each power up.
//  Form the power-up count into CW and send out by flashing LED on p1.0 and 
//  making a tone (via TA) on p1.1
//  By Bryon Wiscons
//     June, 2007
//******************************************************************************

#include <msp430x20x3.h>
//Place the Morse codes into constant memory
//  A Morse Code consists of one word allowing up to 8 dots and/or dashes
//  a dot/dash occupies two bits 11 indicates a dash, 01 is a dot,
//  00 indicates no-more-dot/dash
/*
0	-----	1111,1111,1100,0000	FFC0
1	.----	0111,1111,1100,0000	7FC0
2	..---	0101,1111,1100,0000	5FC0
3	...--	0101,0111,1100,0000	57C0
4	....-	0101,0101,1100,0000	55C0
5	.....	0101,0101,0100,0000	5540
6	-....	1101,0101,0100,0000	D540
7	--...	1111,0101,0100,0000	F540
8	---..	1111,1101,0100,0000	FD40
9	----.	1111,1111,0100,0000	FF40
*/
#define interval 0x0020C49B   // corresponds to 32.768
const unsigned int MorseDigit[10] = {0xFFC0,0x7FC0,0x5FC0,0x57C0,0x55C0,
                                0x5540,0xD540,0xF540,0xFD40,0xFF40};
int seccnt,PUcnt;
unsigned long lcnt;
unsigned int codeInProg;
int whichdig;

void write_SegC (char value,unsigned char adr);
void erase_SegC (int Val);
char refbit(int i);
void clrbit(int i);
unsigned int nextCode(void);
void main(void)
{
unsigned int i;

WDTCTL = WDTPW | WDTTMSEL;                // Puts in interval time mode
BCSCTL1=CALBC1_1MHZ;
DCOCTL=CALDCO_1MHZ;
P1DIR |= 0x03;                            // Set P1.0&P1.1 to output direction
P1OUT &= 0xFE;                            // Clear P1.0 LED off
IE1 |= WDTIE;                             //for F2013, WDTIE bit is in IE1
P1SEL |= 0x02;                            // P1.1 option select
CCTL0 = OUTMOD_4;                         // CCR0 toggle mode
CCR0 = 62;
TACTL = TASSEL_2;                         // SMCLK, off mode
FCTL2 = FWKEY + FSSEL0 + FN1;             // MCLK/3 for Flash Timing Generator
// Now determine the previous PUcnt (Power Up count) by scanning Flash Memory
//  for the first non-zero bit.
for (i=0; i<512; i++)
  if (refbit(i))
    {
    PUcnt=i;
    break;
    }
//Having found PUcnt, clear that bit for next time.
clrbit(PUcnt);

//whichdig = 100 indicates that the 100's digit should be returned first.
whichdig=100;

//nextCode will then set whichfig to 10 and eventually to 1
seccnt=PUcnt;
codeInProg=nextCode();
__bis_SR_register(LPM0_bits|GIE);        // CPU off so enter LPM0 w/ interrupt
}

unsigned int Pausecnt,soundON;
#pragma vector=WDT_VECTOR
__interrupt void inthandler_ (void)
{
lcnt +=interval;
if (soundON)
  {
  TACTL = TASSEL_2 + MC_3;                  // SMCLK, up-downmode
  P1OUT = 0x01;                            // Turn ON P1.0
  }
else
  {
  P1OUT = 0x00;                            // Turn OFF P1.0
  TACTL = TASSEL_2;                  // SMCLK, off mode
  }
if (lcnt > 0x00640000)        //corresponds to 100.0000
  {
  lcnt-=0x00640000;
  if (Pausecnt)
    {
    Pausecnt--;
    if (!codeInProg)
      __bis_SR_register(LPM4_bits);
    return;
    }
  }
else return;
if (codeInProg&0xC000)
  {
  soundON=codeInProg&0xC000;
  codeInProg=(codeInProg&0x3FFF)| ((codeInProg-0x4000)&0xC000);
  }
else
  {
  soundON=0;
  codeInProg=codeInProg<<2;
  if (!(codeInProg&0xC000))
    {
    Pausecnt=3;
    codeInProg=nextCode();
    }
  }
}


void write_SegC (char value,unsigned char adr)
{
  char *Flash_ptr;               // Flash pointer

  Flash_ptr = (char *) 0x1040;   // Initialize Flash pointer
  FCTL3 = FWKEY;                 // Clear Lock bit
  Flash_ptr += adr;              // Initialize Flash pointer
  FCTL1 = FWKEY + WRT;           // Set WRT bit for write operation
  *Flash_ptr = value;            // Write value to flash
  FCTL1 = FWKEY;                 // Clear WRT bit
  FCTL3 = FWKEY + LOCK;          // Set LOCK bit
}

void erase_SegC (int Val)
{
  char *Flash_ptr;                          // Flash pointer

  Flash_ptr = (char *) 0x1040;              // 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;                            // Clear WRT bit
  FCTL3 = FWKEY + LOCK;                     // Set LOCK bit
}

char refbit(int i)
{
char w,b;
char *Flash_ptr;               // Flash pointer
w=i >>3;
b=1<<(i-(w*8));
Flash_ptr = (char *) 0x1040+w; 
return *Flash_ptr&b;
}
void clrbit(int i)
{
char w,b;
w=i >>3;
b=0xFE<<(i-(w*8));
write_SegC(b,w);
}

unsigned int nextCode(void)
{
int stat,result=0;
if (whichdig==100)
  if (seccnt>=100)
    stat=1;
  else 
    if (seccnt>10)
      stat=2;
    else
      stat=3;
else
  if (whichdig==10)
    stat=2;
  else
    if (whichdig==1)
      stat=3;
switch (stat)
{case 1 :
  {
  whichdig=10;
  result= seccnt / 100;
  seccnt = seccnt-result*100;
  break;
  }
case 2:
  {
  whichdig=1;
  result=seccnt/10;
  seccnt=seccnt-result*10;
  break;
  }
case 3 :
  {
  whichdig=0;
  result=seccnt;
  seccnt=0;
  break;
  }
default :
  return 0;
}
return MorseDigit[result];
  
}