This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC2564MODN: Interfacing with MSP430F6779A

Part Number: CC2564MODN
Other Parts Discussed in Thread: MSP430F6779A, , CC2564, MSP430F5438, MSP430F6779

Hello TI/StoneStreet,

I am trying to interface CC2564MODN with MSP430F6779A and using the sample code provided in MSP430_EXP5438, SPPLEDemo_Lite.

I have changed the hardware configurations as per the MSP430 Hardware porting guidelines.

When I run the code I see that BSC_Initialize(HCI_DriverInformation, 0); is returning -4 which is BTPS_ERROR_HCI_INITIALIZATION_ERROR.

I have configured the UART port, CTS, RTS as per the guidelines. Also I can see slow clock on the pin.

Attached is the signal capture of UART and flow control pins.

1777.HAL.c
/*****< HARDWARE.c >**********************************************************/
/*      Copyright 2010 - 2014 Stonestreet One.                               */
/*      All Rights Reserved.                                                 */
/*                                                                           */
/*  HARDWARE - Hardware API for MSP430 Experimentor Board                    */
/*                                                                           */
/*  Author:  Tim Cook                                                        */
/*                                                                           */
/*** MODIFICATION HISTORY ****************************************************/
/*                                                                           */
/*   mm/dd/yy  F. Lastname    Description of Modification                    */
/*   --------  -----------    -----------------------------------------------*/
/*   07/07/10  Tim Cook       Initial creation.                              */
/*****************************************************************************/
#include <msp430.h>
#include <string.h>
#include "HAL.h"                 /* MSP430 Hardware Abstraction API.         */
#include "HRDWCFG.h"             /* SS1 MSP430 Hardware Configuration Header.*/
#include "BTPSKRNL.h"

#define LED_WHITE               BIT0    /* Status LED */  // LED_BLUE
#define LED_GREEN_B_R           BIT1    /* Status LED */  // LED_GREEN_bottom_right
#define LED_GREEN_T_R           BIT2    /* Status LED */  // LED_GREEN_top_right
#define LED_GREEN_T_L           BIT3    /* Status LED */  // LED_GREEN_top_left
#define LED_GREEN_B_L           BIT4    /* Status LED */  // LED_GREEN_bottom_left
#define LED_GREEN               (LED_GREEN_T_L | LED_GREEN_T_R | LED_GREEN_B_R | LED_GREEN_B_L)
#define LED_GREEN_BOTTOM        (LED_GREEN_B_R | LED_GREEN_B_L)
#define LED_ORANGE              BIT5    /* Status LED */  // LED_ORANGE
#define MCU_P6_6_BIT            BIT6    /* Not used */
#define MCU_P6_7_BIT            BIT7    /* Not used */

 #define P6DIR_INIT      ( LED_WHITE | LED_GREEN_B_R | LED_GREEN_T_R | LED_GREEN_T_L | \
 LED_GREEN_B_L | LED_ORANGE | MCU_P6_6_BIT | MCU_P6_7_BIT )
 #define P6OUT_INIT      (0)

#define BTPS_MSP430_DEFAULT_BAUD           115200L  /* Default UART Baud Rate*/
                                                    /* used in baud rate     */
                                                    /* given to this module  */
                                                    /* is invalid.           */

   /* The following are some defines that we will define to be 0 if they*/
   /* are not define in the device header.                              */

#ifndef XT1LFOFFG

   #define XT1LFOFFG   0

#endif

#ifndef XT1HFOFFG

   #define XT1HFOFFG   0

#endif

#ifndef XT2OFFG

   #define XT2OFFG     0

#endif

   /* Auxilary clock frequency                                          */
#define ACLK_FREQUENCY_HZ  ((unsigned int)32768)

   /* Macro to stop the OS Scheduler.                                   */
#define STOP_SCHEDULER()   (TA1CTL &= (~(MC_3)))

   /* Instruction to start the Scheduler Tick ISR.                      */
#define START_SCHEDULER()  (TA1CTL |= MC_1)

   /* The following structure represents the data that is stored to     */
   /* allow us to table drive the CPU setup for each of the Clock       */
   /* Frequencies that we allow.                                        */
typedef struct _tagFrequency_Settings_t
{
   unsigned char VCORE_Level;
   unsigned int  DCO_Multiplier;
} Frequency_Settings_t;

   /* Internal Variables to this Module (Remember that all variables    */
   /* declared static are initialized to 0 automatically by the         */
   /* compiler as part of standard C/C++).                              */

                              /* The following variable is used to hold */
                              /* a system tick count for the Bluetopia  */
                              /* No-OS stack.                           */
static volatile unsigned long MSP430Ticks;

                              /* The following function is provided to  */
                              /* keep track of the number of peripherals*/
                              /* that have requested that the SMCLK stay*/
                              /* active. When this decrements to ZERO,  */
                              /* the clock will be turned off.          */
static volatile unsigned char ClockRequestedPeripherals;

                              /* The following is used to buffer        */
                              /* characters read from the Debug UART.   */
//static unsigned char RecvBuffer[BT_DEBUG_UART_RX_BUFFER_SIZE];

                              /* The following are used to track the    */
                              /* Receive circular buffer.               */
static unsigned int  RxInIndex;
static unsigned int  RxOutIndex;
//static unsigned int  RxBytesFree = BT_DEBUG_UART_RX_BUFFER_SIZE;

   /* If no buffer is specified, the this will result in a Blocking     */
   /* Write.                                                            */
#if BT_DEBUG_UART_TX_BUFFER_SIZE > 0

                              /* The following is used to buffer        */
                              /* characters sent to the Debug UART.     */
static unsigned char TransBuffer[BT_DEBUG_UART_TX_BUFFER_SIZE];

                              /* The following are used to track the    */
                              /* Transmir circular buffer.              */
static unsigned int TxInIndex;
static unsigned int TxOutIndex;
static unsigned int TxBytesFree = BT_DEBUG_UART_TX_BUFFER_SIZE;

#endif

   /* The following represents the table that we use to table drive the */
   /* CPU Frequency setup.                                              */
static BTPSCONST Frequency_Settings_t Frequency_Settings[] =
{
   {PMMCOREV_0, 244},  /* cf8MHZ_t.                          */
   {PMMCOREV_1, 488},  /* cf16MHZ_t.                         */
   {PMMCOREV_2, 610},  /* cf20MHZ_t.                         */
   {PMMCOREV_3, 675}   /* cf22.1184MHZ_t.                    */
};

   /* External functions called by this module.  These are neccessary   */
   /* for UART operation and reside in HCITRANS.c                       */

   /* Called upon reception of a CTS Interrupt. Must toggle Interrupt   */
   /* Edge Polarity and flag Tx Flow Enabled State.                     */
extern int CtsInterrupt(void);

   /* Local Function Prototypes.                                        */
static Boolean_t DetermineProcessorType(void);
static void ConfigureBoardDefaults(void);
static void ConfigureLEDs(void);
static void ToggleLED(int LEDID);
static void SetLED(int LED_ID, int State);
static void ConfigureTimer(void);
static unsigned char IncrementVCORE(unsigned char Level);
static unsigned char DecrementVCORE(unsigned char Level);
static void ConfigureVCore(unsigned char Level);
static void StartCrystalOscillator(void);
static void SetSystemClock(Cpu_Frequency_t CPU_Frequency);

   /* The following function is responsible for determining if we are   */
   /* running on the MSP430F5438 or the MSP430F5438A processor.  This   */
   /* function returns TRUE if we are on the MSP430F5438A or FALSE      */
   /* otherwise.                                                        */
static Boolean_t DetermineProcessorType(void)
{
   Boolean_t ret_val = FALSE;

  /* Read the TLV descriptors to determine the device type.             */
  // if ((*((char *)0x1A04) == 0x05) && (*((char *)0x1A05) == 0x80))
     ret_val = TRUE;

  return(ret_val);
}

   /* The following function is used to configure all unused pins to    */
   /* their board default values.                                       */
static void ConfigureBoardDefaults(void)
{
   P1DIR = P1DIR_INIT;
     P1OUT = P1OUT_INIT;
     P1SEL0 = P1SEL0_INIT;
     P1SEL1 = P1SEL1_INIT;

     P2DIR = P2DIR_INIT;
     P2OUT = P2OUT_INIT;
     P2SEL0 = P2SEL0_INIT;

     P3DIR = P3DIR_INIT;
     P3OUT = P3OUT_INIT;
     P3SEL0 = P3SEL0_INIT;

     P4DIR = P4DIR_INIT;
     P4OUT = P4OUT_INIT;
     P4SEL0 = 0x00;

     P5DIR = P5DIR_INIT;
     P5OUT = P5OUT_INIT;
     P5SEL0 = 0x00;

     P6DIR = P6DIR_INIT;
     P6OUT = P6OUT_INIT;
     P6SEL0 = 0x00;

     P7DIR = P7DIR_INIT;
     P7OUT = P7OUT_INIT;
     P7SEL0 = 0x00;

     P8DIR = P8DIR_INIT;
     P8OUT = P8OUT_INIT;
     P8SEL0 = 0x00;

     PJOUT  = 0;
     PJDIR  = 0xFF;
}


   /* The following function is used to configure the board LEDs.       */
static void ConfigureLEDs(void)
{
  P6DIR = P6DIR_INIT;
  P6OUT = P6OUT_INIT;
  P6SEL0 = 0x00;
  //P6SEL &= ~(BIT0 | BIT1);
   //P6DIR |= (BIT0 | BIT1);
}

   /* The following function is a utility function used to toggle an    */
   /* LED.                                                              */
static void ToggleLED(int LEDID)
{
   if(P6OUT & BIT1)
   {
      P6OUT &= ~BIT1;
      P6OUT |= BIT0;
   }
   else
   {
      P6OUT |= BIT1;
      P6OUT &= ~BIT0;
   }
}

   /* The following function is a utility function that is used to set  */
   /* the state of a specified LED.                                     */
static void SetLED(int LED_ID, int State)
{
   Byte_t Mask;

  if(LED_ID)
     Mask = BIT1;
  else
     Mask = BIT0;

  if(State)
     P6OUT |= Mask;
  else
     P6OUT &= ~Mask;
}

   /* This function is called to configure the System Timer, i.e TA1.   */
   /* This timer is used for all system time scheduling.                */
static void ConfigureTimer(void)
{
   /* Ensure the timer is stopped.                                      */
   TA1CTL = 0;

   /* Run the timer off of the ACLK.                                    */
   TA1CTL = TASSEL_1 | ID_0;

   /* Clear everything to start with.                                   */
   TA1CTL |= TACLR;

   /* Set the compare match value according to the tick rate we want.   */
   TA1CCR0 = ( ACLK_FREQUENCY_HZ / MSP430_TICK_RATE_HZ ) + 1;

   /* Enable the interrupts.                                            */
   TA1CCTL0 = CCIE;

   /* Start up clean.                                                   */
   TA1CTL |= TACLR;

   /* Up mode.                                                          */
   TA1CTL |= TASSEL_1 | MC_1 | ID_0;
}

   /* The following function is a utility function the is used to       */
   /* increment the VCore setting to the specified value.               */
static unsigned char IncrementVCORE(unsigned char Level)
{
   unsigned char Result;
   unsigned char PMMRIE_backup;
   unsigned char SVSMHCTL_backup;
   unsigned char SVSMLCTL_backup;

   /* The code flow for increasing the Vcore has been altered to work   */
   /* around the erratum FLASH37.  Please refer to the Errata sheet to  */
   /* know if a specific device is affected DO NOT ALTER THIS FUNCTION  */

   /* Open PMM registers for write access.                              */
   PMMCTL0_H     = 0xA5;

   /* Disable dedicated Interrupts and backup all registers.            */
   PMMRIE_backup    = PMMRIE;
   PMMRIE          &= ~(SVMHVLRPE | SVSHPE | SVMLVLRPE | SVSLPE | SVMHVLRIE | SVMHIE | SVSMHDLYIE | SVMLVLRIE | SVMLIE | SVSMLDLYIE );
   SVSMHCTL_backup  = SVSMHCTL;
   SVSMLCTL_backup  = SVSMLCTL;

   /* Clear flags.                                                      */
   PMMIFG           = 0;

   /* Set SVM highside to new level and check if a VCore increase is    */
   /* possible.                                                         */
   SVSMHCTL = SVMHE | SVSHE | (SVSMHRRL0 * Level);

   /* Wait until SVM highside is settled.                               */
   while ((PMMIFG & SVSMHDLYIFG) == 0);

   /* Clear flag.                                                       */
   PMMIFG &= ~SVSMHDLYIFG;

   /* Check if a VCore increase is possible.                            */
   if((PMMIFG & SVMHIFG) == SVMHIFG)
   {
      /* Vcc is too low for a Vcore increase so we will recover the     */
      /* previous settings                                              */
      PMMIFG &= ~SVSMHDLYIFG;
      SVSMHCTL = SVSMHCTL_backup;

      /* Wait until SVM highside is settled.                            */
      while ((PMMIFG & SVSMHDLYIFG) == 0)
         ;

      /* Return that the value was not set.                             */
      Result = 1;
   }
   else
   {
      /* Set also SVS highside to new level Vcc is high enough for a    */
      /* Vcore increase                                                 */
      SVSMHCTL |= (SVSHRVL0 * Level);

      /* Wait until SVM highside is settled.                            */
      while ((PMMIFG & SVSMHDLYIFG) == 0)
         ;

      /* Clear flags.                                                   */
      PMMIFG &= ~SVSMHDLYIFG;

      /* Set VCore to new level.                                        */
      PMMCTL0_L = PMMCOREV0 * Level;

      /* Set SVM, SVS low side to new level.                            */
      SVSMLCTL = SVMLE | (SVSMLRRL0 * Level) | SVSLE | (SVSLRVL0 * Level);

      /* Wait until SVM, SVS low side is settled.                       */
      while ((PMMIFG & SVSMLDLYIFG) == 0)
         ;

      /* Clear flag.                                                    */
      PMMIFG &= ~SVSMLDLYIFG;

      /* SVS, SVM core and high side are now set to protect for the new */
      /* core level.  Restore Low side settings Clear all other bits    */
      /* _except_ level settings                                        */
      SVSMLCTL &= (SVSLRVL0+SVSLRVL1+SVSMLRRL0+SVSMLRRL1+SVSMLRRL2);

      /* Clear level settings in the backup register,keep all other     */
      /* bits.                                                          */
      SVSMLCTL_backup &= ~(SVSLRVL0+SVSLRVL1+SVSMLRRL0+SVSMLRRL1+SVSMLRRL2);

      /* Restore low-side SVS monitor settings.                         */
      SVSMLCTL |= SVSMLCTL_backup;

      /* Restore High side settings.  Clear all other bits except level */
      /* settings                                                       */
      SVSMHCTL &= (SVSHRVL0+SVSHRVL1+SVSMHRRL0+SVSMHRRL1+SVSMHRRL2);

      /* Clear level settings in the backup register,keep all other     */
      /* bits.                                                          */
      SVSMHCTL_backup &= ~(SVSHRVL0+SVSHRVL1+SVSMHRRL0+SVSMHRRL1+SVSMHRRL2);

      /* Restore backup.                                                */
      SVSMHCTL |= SVSMHCTL_backup;

      /* Wait until high side, low side settled.                        */
      while(((PMMIFG & SVSMLDLYIFG) == 0) && ((PMMIFG & SVSMHDLYIFG) == 0))
         ;

      /* Return that the value was set.                                 */
      Result = 0;
   }

   /* Clear all Flags.                                                  */
   PMMIFG &= ~(SVMHVLRIFG | SVMHIFG | SVSMHDLYIFG | SVMLVLRIFG | SVMLIFG | SVSMLDLYIFG);

   /* Restore PMM interrupt enable register.                            */
   PMMRIE = PMMRIE_backup;

   /* Lock PMM registers for write access.                              */
   PMMCTL0_H = 0x00;

   return(Result);
}

   /* The following function is a utility function the is used to       */
   /* decrement the VCore setting to the specified value.               */
static unsigned char DecrementVCORE(unsigned char Level)
{
   unsigned char Result;
   unsigned char PMMRIE_backup;
   unsigned char SVSMHCTL_backup;
   unsigned char SVSMLCTL_backup;

   /* The code flow for decreasing the Vcore has been altered to work   */
   /* around the erratum FLASH37.  Please refer to the Errata sheet to  */
   /* know if a specific device is affected DO NOT ALTER THIS FUNCTION  */

   /* Open PMM registers for write access.                              */
   PMMCTL0_H        = 0xA5;

   /* Disable dedicated Interrupts Backup all registers                 */
   PMMRIE_backup    = PMMRIE;
   PMMRIE          &= ~(SVMHVLRPE | SVSHPE | SVMLVLRPE | SVSLPE | SVMHVLRIE | SVMHIE | SVSMHDLYIE | SVMLVLRIE | SVMLIE | SVSMLDLYIE );
   SVSMHCTL_backup  = SVSMHCTL;
   SVSMLCTL_backup  = SVSMLCTL;

   /* Clear flags.                                                      */
   PMMIFG &= ~(SVMHIFG | SVSMHDLYIFG | SVMLIFG | SVSMLDLYIFG);

   /* Set SVM, SVS high & low side to new settings in normal mode.      */
   SVSMHCTL = SVMHE | (SVSMHRRL0 * Level) | SVSHE | (SVSHRVL0 * Level);
   SVSMLCTL = SVMLE | (SVSMLRRL0 * Level) | SVSLE | (SVSLRVL0 * Level);

   /* Wait until SVM high side and SVM low side is settled.             */
   while (((PMMIFG & SVSMHDLYIFG) == 0) || ((PMMIFG & SVSMLDLYIFG) == 0))
      ;

   /* Clear flags.                                                      */
   PMMIFG &= ~(SVSMHDLYIFG + SVSMLDLYIFG);

   /* SVS, SVM core and high side are now set to protect for the new    */
   /* core level.                                                       */

   /* Set VCore to new level.                                           */
   PMMCTL0_L = PMMCOREV0 * Level;

   /* Restore Low side settings Clear all other bits _except_ level     */
   /* settings                                                          */
   SVSMLCTL &= (SVSLRVL0+SVSLRVL1+SVSMLRRL0+SVSMLRRL1+SVSMLRRL2);

   /* Clear level settings in the backup register,keep all other bits.  */
   SVSMLCTL_backup &= ~(SVSLRVL0+SVSLRVL1+SVSMLRRL0+SVSMLRRL1+SVSMLRRL2);

   /* Restore low-side SVS monitor settings.                            */
   SVSMLCTL |= SVSMLCTL_backup;

   /* Restore High side settings Clear all other bits except level      */
   /* settings                                                          */
   SVSMHCTL &= (SVSHRVL0+SVSHRVL1+SVSMHRRL0+SVSMHRRL1+SVSMHRRL2);

   /* Clear level settings in the backup register, keep all other bits. */
   SVSMHCTL_backup &= ~(SVSHRVL0+SVSHRVL1+SVSMHRRL0+SVSMHRRL1+SVSMHRRL2);

   /* Restore backup.                                                   */
   SVSMHCTL |= SVSMHCTL_backup;

   /* Wait until high side, low side settled.                           */
   while (((PMMIFG & SVSMLDLYIFG) == 0) && ((PMMIFG & SVSMHDLYIFG) == 0))
      ;

   /* Clear all Flags.                                                  */
   PMMIFG &= ~(SVMHVLRIFG | SVMHIFG | SVSMHDLYIFG | SVMLVLRIFG | SVMLIFG | SVSMLDLYIFG);

   /* Restore PMM interrupt enable register.                            */
   PMMRIE = PMMRIE_backup;

   /* Lock PMM registers for write access.                              */
   PMMCTL0_H = 0x00;

   /* Return success to the caller.                                     */
   Result    = 0;

   return(Result);
}

   /* The following function is responsible for setting the PMM core    */
   /* voltage to the specified level.                                   */
static void ConfigureVCore(unsigned char Level)
{
   unsigned int ActualLevel;
   unsigned int Status;

   /* Set Mask for Max.  level.                                         */
   Level       &= PMMCOREV_3;

   /* Get actual VCore.                                                 */
   ActualLevel  = (PMMCTL0 & PMMCOREV_3);

   /* Step by step increase or decrease the VCore setting.              */
   Status = 0;
   while (((Level != ActualLevel) && (Status == 0)) || (Level < ActualLevel))
   {
     if (Level > ActualLevel)
       Status = IncrementVCORE(++ActualLevel);
     else
       Status = DecrementVCORE(--ActualLevel);
   }
}

   /* The following function is responsible for starting XT1 in the     */
   /* MSP430 that is used to source the internal FLL that drives the    */
   /* MCLK and SMCLK.                                                   */
static void StartCrystalOscillator(void)
{
  	uint16_t srRegisterState = __get_SR_register() & (1 << 6);

	P1SEL0 = ACLK_OUT | MCLK_OUT;

	/* Enable XT1 and disable XT2, drive strength set to low current consumption */
	UCSCTL6 &= ~(1 << 0);
	// Internal load cap
	UCSCTL6 |= (3 << 2);		// XCAP = 3

	// Check for Oscillator Fault flags on XT1

	// Note from Sec 5.2.12 of Users guide SLAU208M:
	// The OFIFG oscillator-fault interrupt flag is set and latched at POR or
	// when any oscillator fault (XT1LFOFFG, XT1HFOFFG, XT2OFFG, or DCOFFG) is
	// detected. Once set, the fault bits remain set until reset in software,
	// regardless if the fault condition no longer exists. If the user clears the
	// fault bits and the fault condition still exists, the fault bits are
	// automatically set, otherwise they remain cleared.

	// Clear the flags once before starting; since doing this first time after
	// POR
	UCSCTL7 &= ~(1 << 1);				// XT1LFOFFG = 0

	// Loop until XT1 fault flag is cleared

	while (UCSCTL7 & (1 << 1))
	{
		// Clear XT1 fault flags
		UCSCTL7 &= ~(1 << 1);
		SFRIFG1 &= ~(1 << 1);
	}


	/*  Set the FLL reference source to XT1CLK. The FLL reference divider bits 2-0 are set
	    to 0, for divide by 1.
	*/
	UCSCTL3 = 0;				// SELREF = XT1CLK, FLLREFDIV = /1

	// set ACLK source to XT1CLK
	UCSCTL4 = 0;				// SELA = XT1CLK, SELS = XT1CLK, SELM = XT1CLK

	/* DCO Initialization to 16 MHz */

	// disable the FLL loop control loop
	__bic_SR_register(SCG0);

	UCSCTL0 = 0x1F00;            // Set DCO to lowest Tap  fDCO(4,31), DCOx=31, MODx=0
	UCSCTL2 &= ~(0x03FFu);        // Clear the FLLN (Multiplier) bits
	UCSCTL2 = 488;				// 16000000/32768 = 488

	UCSCTL1 = (4 << 4);			// DCORSEL = 4, DISMOD = 0

	/* Wait for DCO to Settle */
	UCSCTL7 &= ~(1 << 0);		// DCOFFG = 0
	while (UCSCTL7 & (1 << 0))
	{
		// Clear DCO fault flags
		UCSCTL7 &= ~(1 << 0);		// DCOFFG = 0
		SFRIFG1 &= ~(1 << 1);		// OFFIFG = 0
	}

	__bis_SR_register(srRegisterState);

	/*  This is part of system HW initialization and happens at the very beginning.Delay
	    as recommended in TI's reference driver lib
	*/
	__delay_cycles(10000);

	/* Check for Oscillator flag on XT2 */

	// Note from Sec 5.2.12 of Users guide SLAU208O:
	// The OFIFG oscillator-fault interrupt flag is set and latched at POR or
	// when any oscillator fault (XT1LFOFFG, XT1HFOFFG, XT2OFFG, or DCOFFG) is
	// detected. Once set, the fault bits remain set until reset in software,
	// regardless if the fault condition no longer exists. If the user clears the
	// fault bits and the fault condition still exists, the fault bits are
	// automatically set, otherwise they remain cleared.

	//  set both MCLK and SMCLK to DCOCLK as source, ACLK src is already set to XT1
	UCSCTL4 |= (3 << 4) | (3 << 0);

	// Clear the flags once before starting; since doing this first time after POR
	// workaround for Errata UCS11 - XT1HFOFFG not supported by this MCU
	UCSCTL7 &= ~((1 << 3) | (1 << 1) | (1 << 0));		// XT2OFFG = 0, XT1LFOFFG = 0, DCOFFG = 0

	SFRIFG1 &= ~(1 << 1);								// OFIFG = 0

	while (SFRIFG1 & (1 << 1))
	{
		UCSCTL7 &= ~((1 << 3) | (1 << 1) | (1 << 0));		// XT2OFFG = 0, XT1LFOFFG = 0, DCOFFG = 0
		SFRIFG1 &= ~(1 << 1);								// OFIFG = 0
	}

}

   /* The following function is responsible for setting up the system   */
   /* clock at a specified frequency.                                   */
static void SetSystemClock(Cpu_Frequency_t CPU_Frequency)
{
   Boolean_t                       UseDCO;
   unsigned int                    Ratio;
   unsigned int                    DCODivBits;
   unsigned long                   SystemFrequency;
   volatile unsigned int           Counter;
   BTPSCONST Frequency_Settings_t *CPU_Settings;

   /* Verify that the CPU Frequency enumerated type is valid, if it is  */
   /* not then we will force it to a default.                           */
   if((CPU_Frequency != cf8MHZ_t) && (CPU_Frequency != cf16MHZ_t) && (CPU_Frequency != cf20MHZ_t) && (CPU_Frequency != cf25MHZ_t))
      CPU_Frequency = cf16MHZ_t;

   /* Do not allow improper settings (MSP430F5438 cannot run at 20MHz or*/
   /* 25 MHz).                                                          */
   if((!DetermineProcessorType()) && ((CPU_Frequency == cf20MHZ_t) || (CPU_Frequency == cf25MHZ_t)))
      CPU_Frequency = cf16MHZ_t;

   /* Get the CPU settings for the specified frequency.                 */
   CPU_Settings = &Frequency_Settings[CPU_Frequency - cf8MHZ_t];

   /* Configure the PMM core voltage.                                   */
   ConfigureVCore(CPU_Settings->VCORE_Level);

   /* Get the ratio of the system frequency to the source clock.        */
   Ratio           = CPU_Settings->DCO_Multiplier;

   /* Use a divider of at least 2 in the FLL control loop.              */
   DCODivBits      = FLLD__2;

   /* Get the system frequency that is configured.                      */
   SystemFrequency  = HAL_GetSystemSpeed();
   SystemFrequency /= 1000;

   /* If the requested frequency is above 16MHz we will use DCO as the  */
   /* source of the system clocks, otherwise we will use DCOCLKDIV.     */
   if(SystemFrequency > 16000)
   {
       Ratio  >>= 1;
       UseDCO   = TRUE;
   }
   else
   {
       SystemFrequency <<= 1;
       UseDCO            = FALSE;
   }

   /* While needed set next higher div level.                           */
   while (Ratio > 512)
   {
       DCODivBits   = DCODivBits + FLLD0;
       Ratio      >>= 1;
   }

   /* Disable the FLL.                                                  */
   __bis_SR_register(SCG0);

   /* Set DCO to lowest Tap.                                            */
   UCSCTL0 = 0x0000;

   /* Reset FN bits.                                                    */
   UCSCTL2 &= ~(0x03FF);
   UCSCTL2  = (DCODivBits | (Ratio - 1));

   /* Set the DCO Range.                                                */
   if(SystemFrequency <= 630)
   {
      /* Fsystem < 630KHz.                                              */
      UCSCTL1 = DCORSEL_0;
   }
   else if(SystemFrequency <  1250)
   {
      /* 0.63MHz < fsystem < 1.25MHz.                                   */
      UCSCTL1 = DCORSEL_1;
   }
   else if(SystemFrequency <  2500)
   {
      /* 1.25MHz < fsystem < 2.5MHz.                                    */
      UCSCTL1 = DCORSEL_2;
   }
   else if(SystemFrequency <  5000)
   {
      /* 2.5MHz < fsystem < 5MHz.                                       */
      UCSCTL1 = DCORSEL_3;
   }
   else if(SystemFrequency <  10000)
   {
      /* 5MHz < fsystem < 10MHz.                                        */
      UCSCTL1 = DCORSEL_4;
   }
   else if(SystemFrequency <  20000)
   {
      /* 10MHz < fsystem < 20MHz.                                       */
      UCSCTL1 = DCORSEL_5;
   }
   else if(SystemFrequency <  40000)
   {
      /* 20MHz < fsystem < 40MHz.                                       */
      UCSCTL1 = DCORSEL_6;
   }
   else
      UCSCTL1 = DCORSEL_7;

   /* Re-enable the FLL.                                                */
   __bic_SR_register(SCG0);

   /* Loop until the DCO is stabilized.                                 */
   while(UCSCTL7 & DCOFFG)
   {
       /* Clear DCO Fault Flag.                                         */
       UCSCTL7 &= ~DCOFFG;

       /* Clear OFIFG fault flag.                                       */
       SFRIFG1 &= ~OFIFG;
   }

   /* Enable the FLL control loop.                                      */
   __bic_SR_register(SCG0);

   /* Based on the frequency we will use either DCO or DCOCLKDIV as the */
   /* source of MCLK and SMCLK.                                         */
   if (UseDCO)
   {
      /* Select DCOCLK for MCLK and SMCLK.                              */
      UCSCTL4 &=  ~(SELM_7 | SELS_7);
      UCSCTL4 |= (SELM__DCOCLK | SELS__DCOCLK);
   }
   else
   {
      /* Select DCOCLKDIV for MCLK and SMCLK.                           */
       UCSCTL4 &=  ~(SELM_7 | SELS_7);
       UCSCTL4 |= (SELM__DCOCLKDIV | SELS__DCOCLKDIV);
   }

   /* Delay the appropriate amount of cycles for the clock to settle.   */
   Counter = Ratio * 32;
   while (Counter--)
       __delay_cycles(30);
}

   /* The following function is provided to allow a mechanism of        */
   /* configuring the MSP430 pins to their default state for the sample.*/
void HAL_ConfigureHardware(void)
{
   /* Configure the default board setup.                                */
   ConfigureBoardDefaults();

   /* Configure the LEDs for outputs                                    */
   ConfigureLEDs();

   /* Call the MSP430F5438 Experimentor Board Hardware Abstraction Layer*/
   /* to setup the system clock.                                        */
   StartCrystalOscillator();
   SetSystemClock(BT_CPU_FREQ);

   /* Configure the UART-USB Port for its default configuration         */
   //HAL_CommConfigure(BT_DEBUG_UART_BASE, BT_DEBUG_UART_BAUDRATE, 0);
   //GPIOPinTypeUART(BT_DEBUG_UART_PIN_BASE, BT_DEBUG_UART_PIN_TX_MASK, BT_DEBUG_UART_PIN_RX_MASK);

   /* Enable Debug UART Receive Interrupt.                              */
   //UARTIntEnableReceive(BT_DEBUG_UART_BASE);

   /* Configure the scheduler timer.                                    */
   ConfigureTimer();
}

   /* * NOTE * The following are the allowed flags for the flags        */
   /*          argument.                                                */
   /*  1.  UART_CONFIG_WLEN_8, UART_CONFIG_WLEN_7                       */
   /*  2.  UART_CONFIG_PAR_NONE,UART_CONFIG_PAR_ODD,UART_CONFIG_PAR_EVEN*/
   /*  3.  UART_CONFIG_STOP_ONE,UART_CONFIG_STOP_TWO                    */
   /*          The flags is a bitfield which may include one flag from  */
   /*          each of the three rows above                             */
void HAL_CommConfigure(unsigned char *UartBase, unsigned long BaudRate, unsigned char Flags)
{
   unsigned long Frequency;
   unsigned int  Divider;

   /* Since we allow access to register clear any invalid flags.        */
   Flags &= (UART_CONFIG_PAR_EVEN | UART_CONFIG_WLEN_7 | UART_CONFIG_STOP_TWO);

   /* set UCSWRST bit to hold UART module in reset while we configure   */
   /* it.                                                               */
   HWREG8(UartBase + MSP430_UART_CTL1_OFFSET) = MSP430_UART_CTL1_SWRST;

   /* Configure control register 0 by clearing and then setting the     */
   /* allowed user options we also ensure that UCSYNC = Asynchronous    */
   /* Mode, UCMODE = UART, UCMSB = LSB first and also ensure that the   */
   /* default 8N1 configuration is used if the flags argument is 0.     */
   HWREG8(UartBase + MSP430_UART_CTL0_OFFSET) = Flags;

   /* UART peripheral erroneous characters cause interrupts break       */
   /* characters cause interrupts on reception                          */
   HWREG8(UartBase + MSP430_UART_CTL1_OFFSET) |= (MSP430_UART_CTL1_RXIE | MSP430_UART_CTL1_BRKIE);

   /* clear UCA status register                                         */
   HWREG8(UartBase + MSP430_UART_STAT_OFFSET)  = 0x00;

   /* clear interrupt flags                                             */
   HWREG8(UartBase + MSP430_UART_IFG_OFFSET)  &= ~(MSP430_UART_TXIFG_mask | MSP430_UART_RXIFG_mask);

   /* If the baud rate is not valid, use the default.                   */
   if(!BaudRate)
      BaudRate = BTPS_MSP430_DEFAULT_BAUD;

   /* Use ACLK for Baud rates less than 9600 to allow us to still       */
   /* receive characters while in LPM3.                                 */
   if(BaudRate <= 9600)
   {
      HWREG8(UartBase + MSP430_UART_CTL1_OFFSET) |= MSP430_UART_CTL1_UCSSEL_ACLK_mask;
      Frequency = ACLK_FREQUENCY_HZ;
   }
   else
   {
      HWREG8(UartBase + MSP430_UART_CTL1_OFFSET) |= MSP430_UART_CTL1_UCSSEL_SMCLK_mask;
      Frequency = HAL_GetSystemSpeed();
   }

   /* Calculate the initial baud rate divisor. This value can be used   */
   /* for correct rounding for either the low frequency or oversampling */
   /* calculations.                                                     */
   Divider = (unsigned int)((Frequency * 16) / BaudRate);

   /* If the divider will be less than 32, use the low frequency        */
   /* calculation, otherwise use oversampling. Note that the current    */
   /* divider value is 16 times the actual divider.                     */
   if(Divider < (32 * 16))
   {
      /* For low frequency baud rates, first calculate the divider * 8, */
      /* rounded to the nearest integer. The lower 3 bits of the result */
      /* will be the fraction portion of the divider and the rest will  */
      /* be the integer portion of the divider.                         */
      Divider     = (Divider + 1) / 2;
      HWREG16(UartBase + MSP430_UART_BRW_OFFSET) = Divider / 8;
      HWREG8(UartBase + MSP430_UART_MCTL_OFFSET) = (Divider & 0x07) << MSP430_UART_MCTL_BRS_bit;
   }
   else
   {
      /* For oversamping mode, first calculate the divider * 16, rounded*/
      /* to the nearest integer. The lower 4 bits of the result will be */
      /* the fraction portion of the divider and the rest will be the   */
      /* integer portion of the divider.                                */
      Divider   = (Divider + 8) / 16;
      HWREG16(UartBase + MSP430_UART_BRW_OFFSET) = Divider / 16;
      HWREG8(UartBase + MSP430_UART_MCTL_OFFSET) = ((Divider & 0x0F) << MSP430_UART_MCTL_BRF_bit) | MSP430_UART_MCTL_UCOS16_mask;
   }

   /* now clear the UCA2 Software Reset bit                             */
   HWREG8(UartBase + MSP430_UART_CTL1_OFFSET) &= (~(MSP430_UART_CTL1_SWRST));
}

   /* Called to read from a UART port and returns the number of bytes   */
   /* read.                                                             */
int HAL_ConsoleRead(unsigned int Length, char *Buffer)
{
//   int Processed = 0;
//   int CopyLength;
//   int MaxRead;
//   int Count;
//
//   /* Make sure the passed in parameters seem valid.                    */
//   if((Buffer) && (Length))
//   {
//      /* Read the characters if neccessary.                             */
//      Processed = 0;
//      while((Length) && (RxBytesFree != BT_DEBUG_UART_RX_BUFFER_SIZE))
//      {
//         /* Determine the number of characters until the buffer wraps.  */
//         Count      = BT_DEBUG_UART_RX_BUFFER_SIZE - RxBytesFree;
//         MaxRead    = BT_DEBUG_UART_RX_BUFFER_SIZE - RxOutIndex;
//         CopyLength = (MaxRead < Count)?MaxRead:Count;
//
//         /* Process the number of characters till the buffer wraps or   */
//         /* maximum number that we can store in the passed in buffer.   */
//         CopyLength = (Length < CopyLength)?Length:CopyLength;
//
//         /* Copy the characters over.                                   */
//         BTPS_MemCopy(&Buffer[Processed], &RecvBuffer[RxOutIndex], CopyLength);
//
//         /* Update the counts.                                          */
//         Processed      += CopyLength;
//         Length         -= CopyLength;
//         RxOutIndex     += CopyLength;
//
//         /* Handle the case where the out index wraps.                  */
//         if(RxOutIndex >= BT_DEBUG_UART_RX_BUFFER_SIZE)
//            RxOutIndex = 0;
//
//         /* This is changed in an interrupt so we must protect this     */
//         /* section.                                                    */
//         __disable_interrupt();
//
//         RxBytesFree += CopyLength;
//
//         __enable_interrupt();
//      }
//   }
//
//   return(Processed);
}

   /* This function writes a fixed size string to the UART port         */
   /* specified by UartBase.                                            */
void HAL_ConsoleWrite(unsigned int Length, char *String)
{
//#if BT_DEBUG_UART_TX_BUFFER_SIZE
//
//   unsigned int Count;
//
//#endif
//
//   volatile int Flags;
//
//   /* First make sure the parameters seem semi valid.                   */
//   if((Length) && (String))
//   {
//      /* Loop and transmit all characters to the Debug UART.            */
//      while(Length)
//      {
//#if BT_DEBUG_UART_TX_BUFFER_SIZE
//
//         if(TxBytesFree)
//         {
//            /* Get the number of bytes till we reach the end of the     */
//            /* buffer.                                                  */
//            Count = (BT_DEBUG_UART_TX_BUFFER_SIZE-TxInIndex);
//
//            /* Limit this by the number of Byte that are available.     */
//            if(Count > TxBytesFree)
//               Count = TxBytesFree;
//
//            if(Count > Length)
//               Count = Length;
//
//            /* Copy as much data as we can.                             */
//            BTPS_MemCopy(&TransBuffer[TxInIndex], String, Count);
//
//            /* Adjust the number of Free Bytes.                         */
//            Flags = (__get_interrupt_state() & GIE);
//            __disable_interrupt();
//
//            TxBytesFree -= Count;
//
//            if(Flags)
//               __enable_interrupt();
//
//            /* Adjust the Index and Counts.                             */
//            TxInIndex += Count;
//            String    += Count;
//            Length    -= Count;
//            if(TxInIndex == BT_DEBUG_UART_TX_BUFFER_SIZE)
//               TxInIndex = 0;
//
//            /* Check to see if we need to prime the transmitter.        */
//            if(!UARTIntTransmitEnabled(BT_DEBUG_UART_BASE))
//            {
//               /* Send the next character out.                          */
//               UARTTransmitBufferReg(BT_DEBUG_UART_BASE) = TransBuffer[TxOutIndex++];
//
//               /* Decrement the number of characters that are in the    */
//               /* transmit buffer and adjust the out index.             */
//               TxBytesFree++;
//               if(TxOutIndex == BT_DEBUG_UART_TX_BUFFER_SIZE)
//                  TxOutIndex = 0;
//
//               UARTIntEnableTransmit(BT_DEBUG_UART_BASE);
//            }
//         }
//
//#else
//
//         /* Loop until the TXBUF is empty.                              */
//         while(!UARTTransmitBufferEmpty(BT_DEBUG_UART_BASE));
//
//         /* Now that the TXBUF is empty send the character.             */
//         UARTTransmitBufferReg(BT_DEBUG_UART_BASE) = *String;
//
//         String++;
//         Length--;
//
//#endif

//      }
//   }
}

   /* The following function is used to return the configured system    */
   /* clock speed in MHz.                                               */
unsigned long HAL_GetSystemSpeed(void)
{
   Cpu_Frequency_t Frequency;

   /* Verify that the CPU Frequency enumerated type is valid, if it is  */
   /* not then we will force it to a default.                           */
   if((BT_CPU_FREQ != cf8MHZ_t) && (BT_CPU_FREQ != cf16MHZ_t) && (BT_CPU_FREQ != cf20MHZ_t) && (BT_CPU_FREQ != cf25MHZ_t))
      Frequency = cf16MHZ_t;
   else
      Frequency = BT_CPU_FREQ;

   if((!DetermineProcessorType()) && ((Frequency == cf20MHZ_t) || (Frequency == cf25MHZ_t)))
      return(((unsigned long)Frequency_Settings[cf16MHZ_t - cf8MHZ_t].DCO_Multiplier) * 32768L);
   else
      return(((unsigned long)Frequency_Settings[Frequency - cf8MHZ_t].DCO_Multiplier) * 32768L);
}

   /* This function is called to get the system Tick Count.             */
unsigned long HAL_GetTickCount(void)
{
   return(MSP430Ticks);
}

   /* The following Toggles an LED at a passed in blink rate.           */
void HAL_LedToggle(int LED_ID)
{
   ToggleLED(0);
}

   /* The following function is used to set an LED to a specified state.*/
void HAL_SetLED(int LED_ID, int State)
{
   SetLED(LED_ID, State);
}

   /* The following function is called to enter LPM3 mode on the MSP    */
   /* with the OS Timer Tick Disabled.                                  */
void HAL_LowPowerMode(unsigned char DisableLED)
{
   /* Turn off Timer 1, which is used for the FreeRTOS and NoRTOS       */
   /* timers. The timer runs off of the Auxilary Clock (ACLK) thus      */
   /* without this the timer would continue to run, consuming power     */
   /* and waking up the processor every 1 ms. Enter a critical section  */
   /* to do so that we do get switched out by the OS in the middle of   */
   /* stopping the OS Scheduler.                                        */
   __disable_interrupt();

   STOP_SCHEDULER();

   /* Clear the count register.                                         */
   TA1R = 0;

   __enable_interrupt();

   /* Turn off the LEDs if requested.                                   */
   if(DisableLED)
   {
      SetLED(0, 0);
      SetLED(1, 0);
   }

   /* Enter LPM3.                                                       */
   LPM3;

   /* Re-start the OS scheduler.                                        */
   START_SCHEDULER();

   /* Set the interrupt trigger bit to trigger an interrupt.            */
   TA1CCTL0 |= 0x01;
}

   /* The following function is called to enable the SMCLK Peripheral   */
   /* on the MSP430.                                                    */
   /* * NOTE * This function should be called with interrupts disabled. */
void HAL_EnableSMCLK(unsigned char Peripheral)
{
   /* Note, we will only disable SMCLK Request if the Baud Rate for the */
   /* Debug Console is less than or equal to 9600 BAUD.                 */
#if BT_DEBUG_UART_BAUDRATE <= 9600

   UCSCTL8                   |= SMCLKREQEN;
   ClockRequestedPeripherals |= Peripheral;

#endif
}

   /* The following function is called to disable the SMCLK Peripheral  */
   /* on the MSP430.                                                    */
   /* * NOTE * This function should be called with interrupts disabled. */
void HAL_DisableSMCLK(unsigned char Peripheral)
{
   /* Note, we will only disable SMCLK Request if the Baud Rate for the */
   /* Debug Console is less than or equal to 9600 BAUD.                 */
#if BT_DEBUG_UART_BAUDRATE <= 9600

   ClockRequestedPeripherals &= ~Peripheral;

   if(!ClockRequestedPeripherals)
      UCSCTL8 &= ~SMCLKREQEN;

#endif
}

   /* Timer A Get Tick Count Function for BTPSKRNL Timer A Interrupt.   */
   /* Included for Non-OS builds                                        */
#pragma vector=TIMER1_A0_VECTOR
__interrupt void TIMER_INTERRUPT(void)
{
   ++MSP430Ticks;

   /* Exit from LPM if necessary (this statement will have no effect if */
   /* we are not currently in low power mode).                          */
   LPM3_EXIT;
}



   /* CTS Pin Interrupt. CtsInterrupt routine must change the polarity  */
   /* of the Cts Interrupt.                                             */
#pragma vector=BT_UART_CTS_IV
__interrupt void CTS_ISR(void)
{
   switch(BT_UART_CTS_IVR)
   {
      case BT_UART_CTS_INT_NUM:
         if(CtsInterrupt())
         {
            /* Exit LPM3 on interrupt exit (RETI).                      */
            LPM3_EXIT;
         }
         break;
   }
}

HAL.h2664.HRDWCFG.h

Also sending you the hardware configuration files.

It would be great if you can have look at the files and suggest me if I am missing on something and also the reasons behind returning -4.

Thanks,

Justin John

  • Hi justin,

    If it is new design, our advice is to move to a MSP432 or similar MCU. MSP430 Bluetopia stack is not being updated for several years now and there are no plans to release any update either.

    In your porting to MSP430F6779A, the issue appears to be UART interfacing with the BT controller. You may want to connect the BT FW logger and see, if the host is detected from the controller..

    https://www.ti.com/lit/pdf/swau058

    Thanks

  • Hi Hari,

    I procured MSP-EXP430F5438 and CC2564MODNEM boards.

    When I am trying to run the demo examples I am getting same BTPS_ERROR_HCI_INITIALIZATION_ERROR.

    I am using the demo examples for MSP430_EXP5438. 

    Are there any settings that I need to do on CC2564 board? I can see that CC2564 board is not responding to the RTS sent by MSP430 chip.

    Do I need to download any code to CC2564?

    Thanks,

    Justin

  • I do not have the MSP430 setup to check.. How are you connecting the CC2564MODNEM board to MSP430F5438? Can, you connect the FW logger to BT debug pin of CC2564, to see if it powered and booted correctly?

  • Thanks Hari for help.

    My issue is resolved. I had to change the offset of MSP430_UART_IFG_OFFSET for msp430f6779 chip.

    //#define MSP430_UART_IFG_OFFSET (0x1D)   //msp430f5438
    #define MSP430_UART_IFG_OFFSET (0x1C)    //msp430f6779a