Other Parts Discussed in Thread: MSP430F2274, MSP-FET
Hello!
I am trying to program the LMX2694 PLL. I have the EVAL board for it as well as the EVAL board for the microcontroller MSP430F2274. I am using an N5181 signal generator as my reference oscillator signal. When building my project and loading the code to the microcontroller using the MSP-FET and TI code composer studio, the PLL does not seem to output the signal it is supposed to (nothing is seen on the spectrum analyzer); however, when I place breakpoints in the code and then run it, it seems like the PLL is able to output the signal (a locked signal is seen on the spectrum analyzer at the chosen frequency).
I'll describe the two procedures I used to get the PLL to not work and work. In both instances, I have a power supply supplying power to the PLL's EVAL board:
The PLL does not work with this procedure:
(1) Toggle the PLL power supply ON.
(2) Load the inserted code into the microcontroller. The microcontroller then goes on and performs the entirety of int main().
(3) The PLL does not display a signal on the spectrum analyzer.
The PLL works with this procedure:
(1) Load inserted code into microcontroller in debug mode.
(2) Press "Resume" once the inserted code has loaded, and int main() will run down to the breakpoint on line 261.
(3) By this point, the microcontroller should have finished initializing the CPU clock, the SPI buses, and the GPIO ports.
(4) Toggle the PLL power supply ON.
(5) Press "Resume."
(6) Code progresses until the breakpoint on line 266 which is the end of the code (return 0).
(7) The PLL is able to display a signal that is seen by the spectrum analyzer.
I have a feeling that the initialization routines while the PLL is powered on is somehow preventing it from being programmed properly. Is this the case? The PLL seems to work fine when I run the code specific only to the PLL. Maybe the microcontroller is outputting signals to the SPI bus that confuses the PLL when it is powered on? Is there anything I can do about this, or any advice someone may have? I don't think there will be an option to toggle the power of the PLL after the microcontroller comes on on the field. Thank you!!
#include <msp430.h>
#include <stdint.h>
int i;
unsigned int j;
unsigned int t;
volatile char dummy = 0;
volatile char probe1 = 0;
volatile char probe2 = 0;
volatile char probe3 = 0;
volatile char probe4 = 0;
volatile char probe5 = 0;
volatile char probe6 = 0;
volatile char probe7 = 0;
volatile char probe8 = 0;
uint8_t reg_matrix[80][3] =
{
{0x00, 0x21, 0x14},
{0x01, 0x08, 0x0C},
{0x02, 0x05, 0x00},
{0x03, 0x06, 0x42},
{0x04, 0x0E, 0x43},
{0x05, 0x03, 0xE8},
{0x06, 0x78, 0x02},
{0x07, 0x00, 0xB2},
{0x08, 0x20, 0x00},
{0x09, 0x16, 0x04},
{0x0A, 0x10, 0xD8},
{0x0B, 0x00, 0x18},
{0x0C, 0x50, 0x01},
{0x0D, 0x40, 0x00},
{0x0E, 0x1E, 0x70},
{0x0F, 0x06, 0x4F},
{0x10, 0x00, 0x80},
{0x11, 0x01, 0x2C},
{0x12, 0x00, 0x64},
{0x13, 0x27, 0xB7},
{0x14, 0xF8, 0x48},
{0x15, 0x04, 0x01},
{0x16, 0x00, 0x01},
{0x17, 0x00, 0x7C},
{0x18, 0x07, 0x1A},
{0x19, 0x06, 0x24},
{0x1A, 0x0D, 0xB0},
{0x1B, 0x00, 0x02},
{0x1C, 0x04, 0x88},
{0x1D, 0x31, 0x8C},
{0x1E, 0x31, 0x8C},
{0x1F, 0x43, 0xEC},
{0x20, 0x03, 0x93},
{0x21, 0x1E, 0x21},
{0x22, 0x00, 0x00},
{0x23, 0x00, 0x04},
{0x24, 0x00, 0x36},
{0x25, 0x84, 0x04},
{0x26, 0xFD, 0x51},
{0x27, 0xDA, 0x80},
{0x28, 0x00, 0x00},
{0x29, 0x00, 0x00},
{0x2A, 0x00, 0x00},
{0x2B, 0x00, 0x00},
{0x2C, 0x1F, 0x63},
{0x2D, 0xC8, 0xDF},
{0x2E, 0x07, 0xFD},
{0x2F, 0x03, 0x00},
{0x30, 0x03, 0x00},
{0x31, 0x41, 0x80},
{0x32, 0x00, 0x00},
{0x33, 0x00, 0x80},
{0x34, 0x04, 0x20},
{0x35, 0x00, 0x00},
{0x36, 0x00, 0x00},
{0x37, 0x00, 0x00},
{0x38, 0x00, 0x00},
{0x39, 0x00, 0x20},
{0x3A, 0x80, 0x01},
{0x3B, 0x00, 0x01},
{0x3C, 0x09, 0xC4},
{0x3D, 0x00, 0xA8},
{0x3E, 0x03, 0x22},
{0x3F, 0x00, 0x00},
{0x40, 0x13, 0x88},
{0x41, 0x00, 0x00},
{0x42, 0x01, 0xF4},
{0x43, 0x00, 0x00},
{0x44, 0x03, 0xE8},
{0x45, 0x00, 0x00},
{0x46, 0xC3, 0x50},
{0x47, 0x00, 0x80},
{0x48, 0x00, 0x01},
{0x49, 0x00, 0x3F},
{0x4A, 0x00, 0x00},
{0x4B, 0x08, 0x00},
{0x4C, 0x00, 0x0C},
{0x4D, 0x00, 0x00},
{0x4E, 0x00, 0x64},
{0x4F, 0x00, 0x00}
};
void delay(unsigned int count)
{
//P3OUT = 0x00;
for (t = 0; t<count; ++t)
{
}
//P3OUT = 0x08;
}
void initClockTo16MHz()
{
if (CALBC1_16MHZ==0xFF) // If calibration constant erased
{
while(1); // do not load, trap CPU!!
}
DCOCTL = 0; // Select lowest DCOx and MODx settings
BCSCTL1 = CALBC1_16MHZ; // Set DCO
DCOCTL = CALDCO_16MHZ;
}
void initSPI()
{
UCA0CTL1 |= UCSWRST; //Performs a software reset on A0.
UCA0CTL1 |= UCSSEL_2; //Using SMCLK.
UCA0BR0 = 0x0A; //Divide by 10 (both UCA0BR0 and UCA0BR1 on the next line set this).
UCA0BR1 = 0;
UCA0MCTL = 0; //Modulation not used in SPI mode. Clearing UCA0MCTL register.
UCA0CTL0 = 0xAB; //UCCKPH + !UCCKPL + UCMSB + !UC7BIT + UCMST + 4-pin SPI w. ACTIVE Master (2 bits) + Synchronous.
//UCA0CTL1 = 0x00; //Releases the module from being in reset mode and initializes the USCI state machine.
}
void initGPIO()
{
//initialize GPIO
P3OUT = 0x00; //Reset all channels on port 3.
P3OUT = 0x0C;
P3DIR = 0x0C; //Configures P3.2 and P3.3 channels to be outputs.
P3SEL = 0x11; //Configures channel 0 to be in UC0CLK mode, channel 4 to be in UC0SIMO mode, and all other channels to be in I/O mode.
ADC10AE0 = 0;
//Configure all unused ports to be reset, and configured as outputs in I/O mode to reduce power consumption.
P1OUT = 0x00;
P2OUT = 0x00;
P4OUT = 0x00;
P1DIR = 0xFF;
P2DIR = 0xFF;
P4DIR = 0xFF;
P1SEL = 0x00;
P2SEL = 0x00;
P4SEL = 0x00;
UCA0CTL1 &= ~UCSWRST; //Releases the module from being in reset mode and initializes the USCI state machine.
}
//void writeSPI(char addr, char value)
//{
// TI_CC_CSn_PxOUT &= ~TI_CC_CSn_PIN; // /CS enable
// while (TI_CC_SPI_USCIB0_PxIN&TI_CC_SPI_USCIB0_SOMI);// Wait for CCxxxx ready
// IFG2 &= ~UCB0RXIFG; // Clear flag
// UCB0TXBUF = addr; // Send address
// while (!(IFG2&UCB0RXIFG)); // Wait for TX to finish
// IFG2 &= ~UCB0RXIFG; // Clear flag
// UCB0TXBUF = value; // Send data
// while (!(IFG2&UCB0RXIFG)); // Wait for TX to finish
// TI_CC_CSn_PxOUT |= TI_CC_CSn_PIN; // /CS disable
//}
void init_mainPLL()
{
//Resets the PLL
P3OUT = 0x00; //Select main PLL
while (!(IFG2 & UCA0TXIFG)); // USCI_A0 TX buffer ready?
UCA0TXBUF = 0b00000000;
while (!(IFG2 & UCA0TXIFG));
UCA0TXBUF = 0b00100001;
while (!(IFG2 & UCA0TXIFG));
UCA0TXBUF = 0b00010110;
while (!(IFG2 & UCA0RXIFG)); //USCI_A0 RX Received?
dummy = UCA0RXBUF; //Read back from RXBuffer.
while (!(IFG2 & UCA0TXIFG)); //Ensure buffer is empty before unselecting main PLL
delay(7); //Delay to allow bits to transfer to PLL
P3OUT = 0x08; //Unselect main PLL
//Removes reset on PLL
P3OUT = 0x00; //Select main PLL
while (!(IFG2 & UCA0TXIFG)); //USCI_A0 TX buffer ready?
UCA0TXBUF = 0b00000000;
while (!(IFG2 & UCA0TXIFG));
UCA0TXBUF = 0b00100001;
while (!(IFG2 & UCA0TXIFG));
UCA0TXBUF = 0b00010100;
while (!(IFG2 & UCA0RXIFG)); //USCI_A0 RX Received?
dummy = UCA0RXBUF; //Read back from RXBuffer
while (!(IFG2 & UCA0TXIFG)); //Ensure buffer is empty before unselecting main PLL
delay(7); //Delay to allow bits to transfer to PLL
P3OUT = 0x08; //Unselect main PLL
}
void program_mainPLL()
{
for (i = 79; i>-1; --i)
{
P3OUT = 0x00; //Select main PLL
for (j = 0; j<3; ++j)
{
while (!(IFG2 & UCA0TXIFG)); // USCI_A0 TX buffer ready?
UCA0TXBUF = reg_matrix[i][j]; //Send byte
}
while (!(IFG2 & UCA0RXIFG)); //USCI_A0 RX Received?
dummy = UCA0RXBUF; //Read back from RXBuffer
while (!(IFG2 & UCA0TXIFG));
delay(7);
P3OUT = 0x08; //Unselect main PLL
}
}
void ready_mainPLL()
{
P3OUT = 0x00; //Select main PLL
while (!(IFG2 & UCA0TXIFG)); //USCI_A0 TX buffer ready?
UCA0TXBUF = 0x00;
while (!(IFG2 & UCA0TXIFG)); //USCI_A0 TX buffer ready?
UCA0TXBUF = 0x21;
while (!(IFG2 & UCA0TXIFG)); //USCI_A0 TX buffer ready?
UCA0TXBUF = 0x1C;
while (!(IFG2 & UCA0RXIFG)); //USCI_A0 RX Received?
dummy = UCA0RXBUF;
while (!(IFG2 & UCA0TXIFG));
delay(7);
P3OUT = 0x08; //Unselect main PLL
}
void testloop()
{
while(1)
{
while (!(IFG2 & UCA0TXIFG));
//IFG2 |= UCA0TXIFG;
probe1 = IFG2;
probe2 = !(IFG2 & UCA0TXIFG);
probe3 = UCA0TXBUF;
probe4 = UCA0RXBUF;
UCA0TXBUF = 0x4D;
//IFG2 |= UCA0TXIFG;
probe5 = IFG2;
probe6 = !(IFG2 & UCA0TXIFG);
probe7 = UCA0TXBUF;
probe8 = UCA0RXBUF;
}
}
int main(void)
{
WDTCTL = WDTPW | WDTHOLD; //Stop watchdog timer
initClockTo16MHz();
initSPI();
initGPIO();
//testloop();
init_mainPLL();
program_mainPLL();
delay(1500);
ready_mainPLL();
return 0;
}