| 
 
| /***************************************************************************** //  MSP-FET430P140 Demo - Bootstrap Loader (BSL) Replicator
 //
 //  Description: This program implements the BSL protocol used to download
 //  a MSP430 program to a target MSP430 device. The program is stored locally
 //  in Flash in array CodeArray[]. Pressing SW1 downloads the program to the
 //  target device and pressing SW2 starts program execution on the target
 //  device.
 //  ACLK = LFXT1 = 32768Hz,  MCLK = SMCLK = BRCLK = DCOCLK = 1048576Hz
 //  Baud rate divider with 1048576Hz = 1048576/9600 ~109.23 (06Dh)
 //  //* An external 32kHz watch crystal btw XIN & XOUT is required for ACLK *//
 //
 //
 //                    MSP430F149
 //                -----------------
 //            /|\|              XIN|-
 //             | |                 | 32768Hz
 //              --|RST          XOUT|-
 //               |                 |
 //               |       P3.4/UTXD0|------------> (BOOTST pin 3)
 //               |                 | 9600 - 8N1
 //               |       P3.5/URXD0|<------------ (BOOTST pin 1)
 //               |                 |
 //               |             P1.5|--> RST/NMI   (BOOTST pin 4)
 //               |             P1.6|--> TEST      (BOOTST pin 7)
 //  BSL PATCH -->|P1.1         P1.7|--> TCK       (BOOTST pin 2)
 //    BSL SEQ -->|P1.2             |
 //        SW1 -->|P1.3         P1.0|--> LED (DCO Calibration/Timer)
 //        SW2 -->|P1.4             |
 //               |             P5.4|--> Status LED 1 (BSL ACK/BSL RX MSG DONE)
 //               |             P5.3|--> Status LED 2 (BSL TX MSG)
 //               |             P5.2|--> Status LED 3 (BSL NACK/FAILURE)
 //               |             P5.1|--> Status LED 4 (SUCCESS)
 //
 //
 //    NOTE: 1. Grounding pin P1.2 selects BSL entry sequence for MSP430
 //             devices having shared JTAG pins.
 //          2. Connecting pin P1.2 to Vcc selects BSL entry sequence for
 //             MSP430 devices having dedicated JTAG pins.
 //
 //
 //  G. Morton
 //  Texas Instruments Inc.
 //  April 2005
 //  Built with IAR Embedded Workbench Version: 3.21A
 //*****************************************************************************
 
 #include  <msp430x14x.h>
 
 
 //
 // Events
 //
 typedef enum
 {
 EVENT_SW1     = 0x0001,                   // Pushbutton 1 event
 EVENT_SW2     = 0x0002                    // Pushbutton 2 event
 } Event;
 
 
 //
 // BSL Message Structure
 //
 typedef struct _bslMsg
 {
 unsigned char reply;                      // BSL reply type - ACK, MSG, None
 unsigned char hdr[8];                     // Header
 unsigned char data[256];                  // Data
 unsigned char chksum[2];                  // Checksum
 } BslMsg;
 
 
 //
 // ERRORS
 //
 #define TIMEOUT_ERROR   -101                // Timeout error
 #define NACK_ERROR      -102                // NACK error
 
 //
 // External, momentary pushbutton switches
 //
 #define SW1             0x08                // P1.3
 #define SW2             0x10                // P1.4
 
 //
 // DCO frequency
 //
 #define DCO_FREQ       1048576              // 1048576 MHz
 
 //
 // Timer Values
 //
 #define TIMERLEDPORT    P1OUT               // Timer Status LED port
 #define TIMER_LED       0x01                // Timer Status LED pin
 #define DELAY_10_MSEC   10486               // ~10 msec delay
 #define DELAY_20_MSEC   20972               // ~20 msec delay
 #define BSL_DELAY_CNT   1259                // ~1.2 msec
 #define CHAR_DELAY      1259                // ~1.2 msec
 #define SYNC_DELAY      50000               // Wait for SYNC ACK reply delay
 #define ACK_DELAY       DELAY_10_MSEC       // Wait for ACK/NACK reply delay
 #define MSG_DELAY       DELAY_10_MSEC       // Wait for msg reply delay
 #define SW_DELAY        DELAY_10_MSEC       // Switch debounce delay
 #define TIMEOUT_LOOP    100                 // Number of delay loops
 
 //
 // BSL Connections
 //
 #define BSLPATCHIN      P1IN                // BSL patch option port
 #define BSL_PATCH_PIN   0x02                // BSL patch option pin
 #define BSLSEQIN        P1IN                // BSL entry sequence option port
 #define BSL_SEQ_PIN     0x04                // BSL entry sequence option pin
 #define BSLOUT          P1OUT               // BSL port output
 #define BSLDIR          P1DIR               // BSL port direction
 #define RESET_NMI_PORT  BSLOUT              // RST/NMI port output
 #define TEST_TCK_PORT   BSLOUT              // TEST/TCK port output
 #define RESET_NMI_PIN   0x20                // RST/NMI pin (P1.5)
 #define TEST_PIN        0x40                // TEST pin    (P1.6)
 #define TCK_PIN         0x80                // TCK pin     (P1.7)
 #define BSL_PINS        (RESET_NMI_PIN+TEST_PIN+TCK_PIN)
 
 //
 // Status LEDs
 //
 #define DCO_STATUS_LED  0x01
 #define LED1            0x10
 #define LED2            0x08
 #define LED3            0x04
 #define LED4            0x02
 #define STATUS_LEDS     (LED1+LED2+LED3+LED4)
 #define LEDPORTOUT      P5OUT
 #define LEDPORTDIR      P5DIR
 #define DCOLEDPORTOUT   P1OUT
 #define DCOLEDPORTDIR   P1DIR
 
 //
 // State Flags
 //
 unsigned char flags = 0;
 #define TIMER_FLAG      0x01                // Timer flag
 #define ACK_FLAG        0x02                // ACK flag
 #define NACK_FLAG       0x04                // NACK flag
 #define REPLY_FLAG      0x08                // REPLY flag
 #define DONE_FLAG       0x10                // DONE flag
 #define DOWNLOAD_FLAG   0x20                // DOWNLOAD flag
 #define PATCH_FLAG      0x80                // PATCH flag
 #define BSL_FLAGS       (ACK_FLAG + NACK_FLAG + REPLY_FLAG + DONE_FLAG)
 
 //
 // BSL Characters
 //
 #define SYNC_CHAR       0x80                // SYNC char to BSL
 #define ACK_CHAR        0x90                // ACK char from BSL
 #define NACK_CHAR       0xA0                // NACK char from BSL
 
 //
 // BSL Message Reply Types
 //
 #define BSL_ACK_REPLY   0x01                // Wait for ACK from BSL
 #define BSL_MSG_REPLY   0x02                // Wait for msg from BSL
 
 //
 // Block size for downloads to target BSL
 //
 #define TX_BLK_SIZE     0x10                // BSL Tx data block size
 
 
 //
 // Function prototypes
 //
 void configUart0(void);
 void configTimer_A(void);
 void setDCO(unsigned long freq);
 void delay(unsigned int val);
 void timer(unsigned int val);
 void cancelTimer(void);
 int  strncompare(const char* str1, const char* str2, unsigned char len);
 
 
 //
 // BSL Function Prototypes
 //
 void bslEntrySeq(void);
 void bslChecksum(BslMsg* pMsg);
 int  bslTxMsg(BslMsg* pMsg);
 int  bslTxSync(void);
 void bslSendChar(unsigned char val);
 int  bslWaitForReply(unsigned char type);
 void bslStateReset(void);
 int  bslDownloadCode(unsigned int* pCodeArray, unsigned char patchFlag);
 int  bslDownloadProgram(void);
 int  bslInstallPatch(void);
 
 
 //
 // BSL Message Function Prototypes
 //
 void bslMsgRxDataBlk(BslMsg* pMsg, int addr, int len, unsigned int* pData);
 void bslMsgRxPassword(BslMsg* pMsg);
 void bslMsgEraseSeg(BslMsg* pMsg, int addr, int len);
 void bslMsgErase(BslMsg* pMsg);
 void bslMsgEraseChk(BslMsg* pMsg, int addr, int len);
 void bslMsgBaudRate(BslMsg* pMsg, int dco, int bcs, int baudRate);
 void bslMsgLoadPC(BslMsg* pMsg, int addr);
 void bslMsgTxDataBlk(BslMsg* pMsg, int addr, int bytes);
 void bslMsgVer(BslMsg* pMsg);
 
 
 //
 // Global Variables
 //
 extern unsigned int PatchArray[];           // Holds the BSL patch for
 // version 1.10
 
 extern unsigned int CodeArray[];            // Holds the target program code
 
 unsigned char PatchFlag = 0;                // Patch flag
 
 unsigned int eventFlag = 0;                 // Event Flag
 
 unsigned int StartAddr = 0;                 // Start Address
 
 BslMsg bslMsg;                              // BSL message
 
 char BslRxMsg[256];                         // Stores message from target BSL
 unsigned char bslRxIndex = 0;               // BSL Rx msg array index
 unsigned char bslReplyLen = 0;              // Length of msg from target BSL
 
 //
 // BSL Password - initialized to default password for erased device
 //
 unsigned char BslPassword[32] =
 {
 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
 };
 
 
 //
 //  Low-level System Initialization - called prior to main()
 //
 int __low_level_init(void)
 {
 WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
 return (1);                               // Force initialization of RAM
 //  return (0);                           // Skip initialization of RAM
 }
 
 
 //
 // Set DCO Frequency
 //
 void setDCO(unsigned long freq)
 {
 unsigned char old_BCSCTL1;
 unsigned int old_TACCTL2;
 unsigned int old_TACTL;
 unsigned int clkCnt;
 unsigned int numDcoClks;
 unsigned int prevCnt = 0;
 
 // PUC value for DCOx = 3
 // PUC value for RSELx = 4
 
 old_BCSCTL1 = BCSCTL1;                    // Save current BCSCTL1 setting
 old_TACCTL2 = TACCTL2;                    // Save current TACCTL2 setting
 old_TACTL   = TACTL;                      // Save current TACTL setting
 
 
 // Basic Clock System Control Register 1
 BCSCTL1 |= DIVA_3;                        // ACLK = LFXT1CLK/8 = 4096 Hz
 
 numDcoClks = freq/4096;                   // Number of DCO clocks in one
 // ACLK/8 period
 
 // Timer_A Capture/Compare Control Register
 TACCTL2 = CM_1 + CCIS_1 + CAP;            // Capture on rising Edge
 // Capture input is CCI2B = ACLK
 // Async capture
 // Capture mode
 // Output mode is OUT bit
 // Interrupt disabled
 // OUT bit is 0
 // Clear capture overflow bit (COV)
 // Clear interrupt flag (CCIFG)
 
 // Timer A Control Register
 TACTL = TASSEL_2 + MC_2 + TACLR;          // Clk src is SMCLK
 // Input clock divider is 1
 // Continuous mode
 // Reset
 // Interrupt is disabled
 // Clear interrupt flag (TAIFG)
 
 while(1)
 {
 while( !(TACCTL2 & CCIFG) );            // Wait for capture event
 
 TACCTL2 &= ~CCIFG;                      // Capture occured, clear flag
 
 clkCnt = TACCR2 - prevCnt;              // Num of clks since last capture
 
 prevCnt = TACCR2;                       // Save current clock count
 
 if( (numDcoClks <= (clkCnt + 2)) && (numDcoClks >= (clkCnt - 2))  )
 {
 DCOLEDPORTOUT |= DCO_STATUS_LED;      // Set DCO Status LED
 break;
 }
 else if( clkCnt > numDcoClks )          // DCO is too fast, slow it down
 {
 DCOCTL--;
 
 if( DCOCTL == 0xFF )
 {
 if( BCSCTL1 & 0x07 )
 {
 BCSCTL1--;                        // DCO role under?, dec RSEL
 }
 else
 {
 break;                            // Error condition, break loop
 }
 }
 }
 else                                    // DCO is too slow, speed it up
 {
 DCOCTL++;
 
 if( DCOCTL == 0x00 )
 {
 if( (BCSCTL1 & 0x07) != 0x07 )
 {
 BCSCTL1++;                        // DCO role over? higher RSEL
 }
 else
 {
 break;                            // Error condition, break loop
 }
 }
 }
 }
 
 // Stop Timer_A
 TACTL = 0;
 TACCTL2 = 0;
 
 // Restore original values
 BCSCTL1 = old_BCSCTL1;
 TACCTL2 = old_TACCTL2;
 TACTL = old_TACTL;
 }
 
 
 //
 //  System Initialization
 //
 void sysInit(void)
 {
 BSLOUT &= ~BSL_PINS;                      // Clear BSL outputs
 BSLDIR |= BSL_PINS;                       // Set BSL outputs
 
 DCOLEDPORTOUT &= ~DCO_STATUS_LED;         // Clear DCO Status LED
 DCOLEDPORTDIR |= DCO_STATUS_LED;          // Set DCO Status LED output
 
 LEDPORTOUT &= ~STATUS_LEDS;               // Clear Status LED outputs
 LEDPORTDIR |= STATUS_LEDS;                // Set Status LED outputs
 
 P1IES |= (SW1+SW2);                       // Set P1.4,3 for 1->0 interrupt
 P1IFG  = 0x00;                            // Clear P1 interrupts
 P1IE  |= (SW1+SW2);                       // Enable P1.4,3 interrupts
 
 setDCO(DCO_FREQ);                         // Set DCO frequency
 
 configUart0();                            // Configure UART0
 
 configTimer_A();                          // Configure Timer_A
 }
 
 
 //
 // Configure USART0 for UART mode
 //
 void configUart0(void)
 {
 P3SEL |= 0x30;                            // P3.4,5 = UTXD0/URXD0
 ME1 |= UTXE0 + URXE0;                     // Enable USART0 TXD/RXD
 U0CTL |= (CHAR + PENA + PEV + SWRST);     // 8-bit char, even parity, reset
 U0TCTL |= SSEL1;                          // BRCLK = SMCLK
 U0BR0 = 0x6d;                             // 9600 from 1MHz
 U0BR1 = 0x00;                             //
 U0MCTL = 0x03;                            // Modulation
 U0CTL &= ~SWRST;                          // Initialize USART state machine
 IE1 |= URXIE0;                            // Enable USART0 RX interrupt
 }
 
 
 //
 // Configure Timer_A
 //
 void configTimer_A(void)
 {
 TACCTL1 = 0;
 TACCTL2 = 0;
 TACTL = TASSEL_2 + MC_2 + TACLR;          // SMCLK, continuous mode, clear
 }
 
 
 //
 // Main Program Loop
 //
 void main(void)
 {
 int retVal;
 
 // Initialize System
 sysInit();
 
 // Event Loop
 for(;;)
 {
 if( eventFlag == 0 )                    // No events to handle?
 {
 // Enter low-power mode 0 with interrupts enabled
 _BIS_SR(LPM0_bits + GIE);
 }
 
 if( eventFlag & EVENT_SW1 )
 {
 eventFlag &= ~EVENT_SW1;              // Clear event flag
 
 LEDPORTOUT &= ~(LED3+LED4);           // Ensure LED3 and LED4 are off
 
 retVal = 0;                           // Clear return value variable
 
 bslEntrySeq();                        // BSL entry sequence
 
 if( BSLPATCHIN & BSL_PATCH_PIN )      // Install patch option selected?
 {
 flags |= PATCH_FLAG;                // Set patch flag
 retVal = bslInstallPatch();         // Install BSL patch
 }
 else
 {
 flags &= ~PATCH_FLAG;               // Clear patch flag
 }
 
 if( retVal == 0 )
 {
 retVal = bslDownloadProgram();      // Download program to target BSL
 }
 
 if( retVal < 0 )                      // Check result
 {
 LEDPORTOUT |= LED3;                 // Set LED3 to indicate an error
 }
 else
 {
 LEDPORTOUT |= LED4;                 // Set LED4 to indicate success
 }
 }
 
 if( eventFlag & EVENT_SW2 )
 {
 eventFlag &= ~EVENT_SW2;              // Clear event flag
 
 LEDPORTOUT &= ~(LED3+LED4);           // Ensure LED3 and LED4 are off
 
 bslMsgLoadPC(&bslMsg, StartAddr);     // Jump to start address msg
 
 if( bslTxMsg(&bslMsg) < 0 )           // Send msg to BSL
 {
 LEDPORTOUT |= LED3;                 // Set LED3 to indicate an error
 }
 else
 {
 LEDPORTOUT |= LED4;                 // Set LED4 to indicate success
 }
 }
 }
 }
 
 
 
 
 
 | 
 |