⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lowlevelfunc430x.c

📁 msp430的jtag程序下载的源代码
💻 C
字号:
/*==========================================================================*\
|                                                                            |
| LowLevelFunc.c                                                             |
|                                                                            |
| Low Level Functions regarding user's Hardware                              |
|----------------------------------------------------------------------------|
| Project:              MSP430 Replicator                                    |
| Developed using:      IAR Embedded Workbench 3.40B [Kickstart]             |
|----------------------------------------------------------------------------|
| Author:               FRGR                                                 |
| Version:              1.5                                                  |
| Initial Version:      04-17-02                                             |
| Last Change:          09-21-05                                             |
|----------------------------------------------------------------------------|
| Version history:                                                           |
| 1.0 04/02 FRGR        Initial version.                                     |
| 1.1 04/02 FRGR        Included SPI mode to speed up shifting function by 2.|
| 1.2 06/02 ALB2        Formatting changes, added comments.                  |
| 1.3 08/02 ALB2        Initial code release with Lit# SLAA149.              |
| 1.4 09/05 SUN1        Software delays redesigned to use TimerA harware;    |
|                       see MsDelay() routine. Added TA setup                |
| 1.5 12/05 STO         Adapted for 2xx devices with SpyBiWire using 4JTAG   |
|----------------------------------------------------------------------------|
| Designed 2002 by Texas Instruments Germany                                 |
\*==========================================================================*/

#include "LowLevelFunc430X.h"

/****************************************************************************/
/* Function declarations which have to be programmed by the user for use    */
/* with hosts other than the MSP430F149.                                    */
/*                                                                          */
/* The following MSP430F149-specific code can be used as a reference as to  */
/* how to implement the required JTAG communication on additional hosts.    */
/****************************************************************************/

/*----------------------------------------------------------------------------
   Initialization of the Controller Board (Master or Host)
*/
void InitController(void)
{
	byte i;
	
	WDTCTL   = WDTPW + WDTHOLD;		// Stop watchdog timer
		
	// initialize MCLK = LFXT1 (external crystal)
	BCSCTL1 |= XTS;				    // ACLK = LFXT1 = HF XTAL
    do
    {
		IFG1 &= ~OFIFG;			    // Clear OSCFault flag
		for (i = 0xFF; i > 0; i--);	// Time for flag to set
	}
	while ((IFG1 & OFIFG) != 0);    // OSCFault flag still set?
	IFG1 &= ~OFIFG;				    // Clear OSCFault flag again
	BCSCTL2 |= SELM1+SELM0;			// MCLK = LFXT1 (safe)
	
    // Setup timer_A for hardware delay
	TACTL &= MC_0;				    // STOP Timer
    TACTL |= ID_3+TASSEL_1;  		// Timer_A source: ACLK/8 = 1MHz
	TACCR0 = ONEMS;				    // Load CCR0 with delay... (1ms delay)

	MsDelay(50);				    // debounce RST key
	
	// initialize the Status LEDs control port
	LEDSEL  &= ~(LEDGREEN | LEDRED);	// no special function, I/O
	LEDOUT  &= ~(LEDGREEN | LEDRED);	// LEDs are OFF
	LEDDIR  |=  (LEDGREEN | LEDRED);	// LED pins are outputs
	
#ifdef SPI_MODE
	// initialize the SPI
	UBR0  = SPI_DIV;			    // Load SPI frequency divider
	UBR1  = 0x00;
	UMCTL = 0x00;				    // Clear Modulation Register
	UTCTL = CKPL | SSEL0 | STC | TXEPT;	// Load TX control: ACLK (inactive high), no STE
	UCTL  = SYNC | MM | SWRST;		// Load USART Control: 7bit, SPI, Master
	UCTL &= ~SWRST;				    // Reset SWRST bit as last action
	ME   |= USPIE;				    // Enable SPI module
#endif
}

/*----------------------------------------------------------------------------
   This function switches TDO to Input, used for fuse blowing
*/
void TDOisInput(void)
{
	JTAGOUT &= ~TDICTRL1;		    // Release TDI pin on target
	MsDelay(5);				        // Settle MOS relay
	JTAGOUT |=  TDICTRL2;			// Switch TDI --> TDO	
	MsDelay(5);				        // Settle MOS relay
}

/*----------------------------------------------------------------------------
   Initialization of the Target Board (switch voltages on, preset JTAG pins)	
    for devices with normal 4wires JTAG  (JTAG4SBW=0)
    for devices with Spy-Bi-Wire to work in 4wires JTAG (JTAG4SBW=1)
*/
void InitTarget(void)
{
	JTAGSEL  = 0x00;			// Pins all I/Os except during SPI access
	JTAGOUT  = TEST | TDI | TMS | TCK | TCLK | TDICTRL1 | VCCTGT;
	JTAGDIR  = TEST | TDI | TMS | TCK | TCLK | TDICTRL1 | TDICTRL2 | VCCTGT;

    VPPSEL  &= ~(VPPONTDI | VPPONTEST | RESET);	// No special function, I/Os
	VPPOUT  &= ~(VPPONTDI | VPPONTEST);	        // VPPs are OFF
    VPPOUT |= RESET;                            // Release target reset
	VPPDIR  |=  (VPPONTDI | VPPONTEST | RESET);	// VPP pins are outputs
    MsDelay(50);	            // Settle MOS relays, target capacitor
}

/*----------------------------------------------------------------------------
   Release Target Board (switch voltages off, JTAG pins are HI-Z)	
*/
void ReleaseTarget(void)
{
	VPPoff();				// VPPs are off (safety)
	MsDelay(5);				// Settle MOS relays
	JTAGDIR  =  0x00;	    // VCC is off, all I/Os are HI-Z
	MsDelay(5);				// Settle MOS relays
}

//----------------------------------------------------------------------------
/*  Shift a value into TDI (MSB first) and simultaneously shift out a value
    from TDO (MSB first).
    Note:      When defining SPI_MODE the embedded SPI is used to speed up by 2.
    Arguments: word Format (number of bits shifted, 8 (F_BYTE) or 16 (F_WORD))
               word Data (data to be shifted into TDI)
    Result:    word (scanned TDO value)
*/
word Shift(word Format, word Data)
{
	word tclk = StoreTCLK();		// Store TCLK state;
	word TDOword = 0x0000;			// Initialize shifted-in word
	word MSB = 0x0000;
   	
#ifdef SPI_MODE					// Shift via SPI pins, entry: TCK=1, TMS=0
	JTAGSEL |= (TDI | TDO | TCK);		// Function select to SPI module
	// Process 8 MSBs if 16 bits
	if (Format == F_WORD)
	{
		UCTL |= CHAR;			// SPI: set 8bit mode
		UTXBUF = (byte)(Data >> 8);	// Write TX Buffer: 8 MSBs
		while ((UTCTL & TXEPT) == 0);
		MSB = (URXBUF << 8);		// Get RX Buffer: 8 MSBs
	}
	// Process higher 7 LSBs
	UCTL &= ~CHAR;				// SPI: set 7bit mode
	UTXBUF = (byte)(Data);			// Write TX Buffer: 7(+1) LSBs
	while ((UTCTL & TXEPT) == 0);
	TDOword = MSB + (URXBUF << 1);		// Combine 15 MSBs
	JTAGSEL &= ~(TDI | TDO | TCK);		// Function select back to ports
	// process LSB discretely due to TMS   	
	((Data & 0x01) == 0) ? ClrTDI() : SetTDI();
	SetTMS();				// Last bit requires TMS=1
	ClrTCK();
	SetTCK();
	if (ScanTDO() != 0)
		TDOword++;	 	   	

#else						// Shift via port pins, no coding necessary
	volatile word i;
	(Format == F_WORD) ? (MSB = 0x8000) : (MSB = 0x80);
	for (i = Format; i > 0; i--)
	{
		((Data & MSB) == 0) ? ClrTDI() : SetTDI();
		Data <<= 1;
		if (i == 1)			    // Last bit requires TMS=1
		   SetTMS();
		ClrTCK();
		SetTCK();
		TDOword <<= 1;			// TDO could be any port pin
		if (ScanTDO() != 0)
			TDOword++;	
	}
#endif

	// common exit
	RestoreTCLK(tclk);  		// restore TCLK state

    // JTAG FSM = Exit-DR
    ClrTCK();
    SetTCK();
    // JTAG FSM = Update-DR
    ClrTMS();
    ClrTCK();
    SetTCK();
    // JTAG FSM = Run-Test/Idle
	return(TDOword);
}

//----------------------------------------------------------------------------
/*  Shift a 20 bit value into TDI (MSB first) and simultaneously shift out a
    value from TDO (swapped bit order (15:0)(19:16) will be rearranged to
    (19:0) before returning).
    Note:      When defining SPI_MODE the embedded SPI is used to speed up by 2.
    Arguments: unsigned long Address (data to be shifted into TDI)
    Result:    unsigned long TDOvalue (scanned TDO value)
*/
unsigned long Shift_430X(unsigned long Address)
{
	word tclk = StoreTCLK();		// Store TCLK state;
	unsigned long TDOvalue = 0;     // Initialize shifted-in word
    word i;

    union DataOut { byte b[4]; word w[2]; unsigned long l; } uDataOut;
    union DataIn  { byte b[4]; word w[2]; unsigned long l; } uDataIn;

    uDataIn.l = Address;
    uDataOut.l  = 0;

    ((uDataIn.b[2] & 0x08) == 0) ? ClrTDI() : SetTDI();	// prepare TDI
    ClrTCK(); SetTCK();
    if (ScanTDO() != 0) uDataOut.b[2] |= 0x08;
    ((uDataIn.b[2] & 0x04) == 0) ? ClrTDI() : SetTDI();	// prepare TDI
    ClrTCK(); SetTCK();
    if (ScanTDO() != 0) uDataOut.b[2] |= 0x04;
    ((uDataIn.b[2] & 0x02) == 0) ? ClrTDI() : SetTDI();	// prepare TDI
    ClrTCK(); SetTCK();
    if (ScanTDO() != 0) uDataOut.b[2] |= 0x02;
    ((uDataIn.b[2] & 0x01) == 0) ? ClrTDI() : SetTDI();	// prepare TDI
    ClrTCK(); SetTCK();
    if (ScanTDO() != 0) uDataOut.b[2] |= 0x01;

  // Shift via port pins, no coding necessary
	for (i = F_WORD; i > 0; i--)
	{
		((uDataIn.w[0] & 0x8000) == 0) ? ClrTDI() : SetTDI();
		uDataIn.w[0] <<= 1;
		if (i == 1)			        // Last bit requires TMS=1
		   SetTMS();
		ClrTCK();
		SetTCK();
		uDataOut.w[0] <<= 1;		// TDO could be any port pin
		if (ScanTDO() != 0)
			uDataOut.w[0]++;	
	}

	// common exit
	RestoreTCLK(tclk);  		    // restore TCLK state

    // JTAG FSM = Exit-DR
    ClrTCK();
    SetTCK();
    // JTAG FSM = Update-DR
    ClrTMS();
    ClrTCK();
    SetTCK();
    // JTAG FSM = Run-Test/Idle

    // now swap the upper nipple
    // uDataIn.l holds bit order (15:0)(19:16)
    // TDOvalue will be returned as (19:0)
    TDOvalue = (uDataOut.l >> 4) + ((uDataOut.l << 16) & 0xF0000);

	return(TDOvalue);
}

/*---------------------------------------------------------------------------
   Delay function (resolution is 1 ms)
   Arguments: word millisec (number of ms, max number is 0xFFFF)
*/
void MsDelay(word milliseconds)
{
   word i;
   for(i = milliseconds; i > 0; i--)
   {
        TACCTL0 &= ~CCIFG;		// Clear the interrupt flag
        TACTL |= TACLR+MC_1;	        // Clear & start timer
        while ((TACCTL0 & CCIFG)==0);	// Wait until the Timer elapses
		TACTL &= ~MC_1;			// Stop Timer	
	}
}

/*---------------------------------------------------------------------------
   Delay function (resolution is ~1 us at 8MHz clock)
   Arguments: word microeconds (number of ms, max number is 0xFFFF)
*/
void usDelay(word microeconds)
{
    do
    {
        _NOP();
        _NOP();
    }
    while (--microeconds > 0);
}

/*---------------------------------------------------------------------------
   This function generates Amount strobes with the Flash Timing Generator
   Frequency fFTG = 257..476kHz (t = 3.9..2.1us).
   User knows target frequency, instruction cycles, C implementation.
   Arguments: word Amount (number of strobes to be generated)
*/
#define	S_LOOPBODY		14		// 14 cycles/loop w/o NOPs
#define S_ADDNOPS	(word)((FREQUENCY * 2.1) / 1000 - S_LOOPBODY + 1)
						// S_ADDNOPS = 3..18
void TCLKstrobes(word Amount)
{
	volatile word i;
	
	for (i = Amount; i > 0; i--)		// This implementation has 14 body cycles!	
	{
		JTAGOUT |=  TCLK;		// Set TCLK
		_NOP();				    // Include NOPs if necessary (min. 3)
		_NOP();
		_NOP();
		JTAGOUT &= ~TCLK;		// Reset TCLK
	}
}

/*----------------------------------------------------------------------------
   This function controls the status LEDs depending on the status
   argument. It stops program in error case.
   Arguments: word status (4 stati possible for 2 LEDs)
              word index (additional number for detailed diagnostics or
                          watch variable during debugging phase)
*/
void ShowStatus(word status, word index)
{
	LEDOUT  &= ~(LEDGREEN | LEDRED);	// Both LEDs are off
	switch (status)
	{
		case STATUS_ERROR:					
			LEDOUT  |= LEDRED;	        // Switch red LED on			
			ReleaseTarget();	        // Voltages off, JTAG HI-Z			
			while(index);		        // Stop program, index must be > 0
		case STATUS_ACTIVE:;		    // Switch both LEDs on			
			LEDOUT  |= LEDRED;
		case STATUS_OK:			        // Switch green LED on
			LEDOUT  |= LEDGREEN;				
		case STATUS_IDLE:;		        // Keap both LEDs switched off				
	}
}						                // return if active, idle, ok

/*----------------------------------------------------------------------------
   This function performs a Trigger Pulse for test/development
*/
#ifdef DEBUG
void TriggerPulse(word mode)
{
	switch (mode)
	{
		case 1:	LEDOUT  |=  TRIGGER;	// mode = 1: set trigger
				break;
		case 2:	LEDOUT  |=  TRIGGER;	// mode = 2: set/reset trigger
		case 0:	LEDOUT  &= ~TRIGGER;	// mode = 0: reset trigger
	}		
}	
#endif

/****************************************************************************/
/*                         END OF SOURCE FILE                               */
/****************************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -