aboutsummaryrefslogtreecommitdiffstats
path: root/msp430/alee-msp430.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'msp430/alee-msp430.cpp')
-rw-r--r--msp430/alee-msp430.cpp168
1 files changed, 142 insertions, 26 deletions
diff --git a/msp430/alee-msp430.cpp b/msp430/alee-msp430.cpp
index 4bb82ef..fba9c6f 100644
--- a/msp430/alee-msp430.cpp
+++ b/msp430/alee-msp430.cpp
@@ -32,24 +32,18 @@ static void serput(int c);
static void serputs(const char *s);
static void printint(DoubleCell n, char *buf);
+static void initGPIO();
+static void initClock();
+static void initUART();
+static void Software_Trim();
+#define MCLK_FREQ_MHZ (8) // MCLK = 8MHz
+
int main()
{
WDTCTL = WDTPW | WDTHOLD;
- DCOCTL = 0;
- BCSCTL1 = CALBC1_16MHZ;
- DCOCTL = CALDCO_16MHZ;
-
- P1SEL |= BIT1 | BIT2;
- P1SEL2 |= BIT1 | BIT2;
-
- UCA0CTL1 = UCSWRST;
- UCA0CTL1 |= UCSSEL_2;
- UCA0BR0 = 139;
- UCA0BR1 = 0;
- UCA0MCTL = UCBRS0;
- UCA0CTL1 &= (uint8_t)~UCSWRST;
-
- __enable_interrupt();
+ initGPIO();
+ initClock();
+ initUART();
static SplitMemDict<alee_dat_len> dict (alee_dat);
State state (dict, readchar);
@@ -58,8 +52,8 @@ int main()
auto ptr = strbuf;
while (1) {
- if (IFG2 & UCA0RXIFG) {
- char c = UCA0RXBUF;
+ if (UCA0IFG & UCRXIFG) {
+ auto c = static_cast<char>(UCA0RXBUF);
serput(c);
if (c == '\r') {
@@ -95,13 +89,13 @@ int main()
}
}
-static void readchar(State& state)
+void readchar(State& state)
{
auto idx = state.dict.read(Dictionary::Input);
Addr addr = Dictionary::Input + sizeof(Cell) + idx;
- while (!(IFG2 & UCA0RXIFG));
- auto c = UCA0RXBUF;
+ while (!(UCA0IFG & UCRXIFG));
+ auto c = static_cast<uint8_t>(UCA0RXBUF);
if (isupper(c))
c += 32;
state.dict.writebyte(addr, c ? c : ' ');
@@ -109,8 +103,8 @@ static void readchar(State& state)
void serput(int c)
{
- while (!(IFG2 & UCA0TXIFG));
- UCA0TXBUF = (char)c;
+ while (!(UCA0IFG & UCTXIFG));
+ UCA0TXBUF = static_cast<char>(c);
}
void serputs(const char *s)
@@ -128,7 +122,7 @@ void printint(DoubleCell n, char *buf)
n = -n;
do {
- *ptr++ = (char)(n % 10) + '0';
+ *ptr++ = static_cast<char>((n % 10) + '0');
} while ((n /= 10));
if (neg)
@@ -164,6 +158,128 @@ void user_sys(State& state)
}
}
-extern "C" int atexit(void (*)()) { return 0; }
-void operator delete(void *) {}
-void operator delete(void *, std::size_t) {}
+void initGPIO()
+{
+ // Unnecessary, but done by TI example
+ P1DIR = 0xFF; P2DIR = 0xFF;
+ P1REN = 0xFF; P2REN = 0xFF;
+ P1OUT = 0x00; P2OUT = 0x00;
+
+ // Set LED pins to outputs
+ P6DIR |= BIT0 | BIT1 | BIT2;
+ P6OUT |= BIT0 | BIT1 | BIT2;
+ P5DIR |= BIT5 | BIT6 | BIT7;
+ P5OUT |= BIT5 | BIT6 | BIT7;
+
+ // Allow GPIO configurations to be applied
+ PM5CTL0 &= ~LOCKLPM5;
+
+ // Safety measure, prevent unwarranted interrupts
+ P5IFG = 0;
+ P6IFG = 0;
+}
+
+void initClock()
+{
+ __bis_SR_register(SCG0); // disable FLL
+ CSCTL3 |= SELREF__REFOCLK; // Set REFO as FLL reference source
+ CSCTL1 = DCOFTRIMEN_1 | DCOFTRIM0 | DCOFTRIM1 | DCORSEL_3;// DCOFTRIM=3, DCO Range = 8MHz
+ CSCTL2 = FLLD_0 + 243; // DCODIV = 8MHz
+ __delay_cycles(3);
+ __bic_SR_register(SCG0); // enable FLL
+ Software_Trim(); // Software Trim to get the best DCOFTRIM value
+
+ CSCTL4 = SELMS__DCOCLKDIV | SELA__REFOCLK; // set default REFO(~32768Hz) as ACLK source, ACLK = 32768Hz
+ // default DCODIV as MCLK and SMCLK source
+}
+
+void initUART()
+{
+ // Configure UART pins
+ P5SEL0 |= BIT1 | BIT2; // set 2-UART pin as second function
+ SYSCFG3|=USCIA0RMP; //Set the remapping source
+ // Configure UART
+ UCA0CTLW0 |= UCSWRST;
+ UCA0CTLW0 |= UCSSEL__SMCLK;
+
+ // Baud Rate calculation
+ // 8000000/(16*9600) = 52.083
+ // Fractional portion = 0.083
+ // User's Guide Table 17-4: UCBRSx = 0x49
+ // UCBRFx = int ( (52.083-52)*16) = 1
+ UCA0BR0 = 52; // 8000000/16/9600
+ UCA0BR1 = 0x00;
+ UCA0MCTLW = 0x4900 | UCOS16 | UCBRF_1;
+
+ UCA0CTLW0 &= ~UCSWRST; // Initialize eUSCI
+}
+
+void Software_Trim()
+{
+ unsigned int oldDcoTap = 0xffff;
+ unsigned int newDcoTap = 0xffff;
+ unsigned int newDcoDelta = 0xffff;
+ unsigned int bestDcoDelta = 0xffff;
+ unsigned int csCtl0Copy = 0;
+ unsigned int csCtl1Copy = 0;
+ unsigned int csCtl0Read = 0;
+ unsigned int csCtl1Read = 0;
+ unsigned int dcoFreqTrim = 3;
+ unsigned char endLoop = 0;
+
+ do
+ {
+ CSCTL0 = 0x100; // DCO Tap = 256
+ do
+ {
+ CSCTL7 &= ~DCOFFG; // Clear DCO fault flag
+ }while (CSCTL7 & DCOFFG); // Test DCO fault flag
+
+ __delay_cycles((unsigned int)3000 * MCLK_FREQ_MHZ);// Wait FLL lock status (FLLUNLOCK) to be stable
+ // Suggest to wait 24 cycles of divided FLL reference clock
+ while((CSCTL7 & (FLLUNLOCK0 | FLLUNLOCK1)) && ((CSCTL7 & DCOFFG) == 0));
+
+ csCtl0Read = CSCTL0; // Read CSCTL0
+ csCtl1Read = CSCTL1; // Read CSCTL1
+
+ oldDcoTap = newDcoTap; // Record DCOTAP value of last time
+ newDcoTap = csCtl0Read & 0x01ff; // Get DCOTAP value of this time
+ dcoFreqTrim = (csCtl1Read & 0x0070)>>4;// Get DCOFTRIM value
+
+ if(newDcoTap < 256) // DCOTAP < 256
+ {
+ newDcoDelta = 256 - newDcoTap; // Delta value between DCPTAP and 256
+ if((oldDcoTap != 0xffff) && (oldDcoTap >= 256)) // DCOTAP cross 256
+ endLoop = 1; // Stop while loop
+ else
+ {
+ dcoFreqTrim--;
+ CSCTL1 = (csCtl1Read & (~DCOFTRIM)) | (dcoFreqTrim<<4);
+ }
+ }
+ else // DCOTAP >= 256
+ {
+ newDcoDelta = newDcoTap - 256; // Delta value between DCPTAP and 256
+ if(oldDcoTap < 256) // DCOTAP cross 256
+ endLoop = 1; // Stop while loop
+ else
+ {
+ dcoFreqTrim++;
+ CSCTL1 = (csCtl1Read & (~DCOFTRIM)) | (dcoFreqTrim<<4);
+ }
+ }
+
+ if(newDcoDelta < bestDcoDelta) // Record DCOTAP closest to 256
+ {
+ csCtl0Copy = csCtl0Read;
+ csCtl1Copy = csCtl1Read;
+ bestDcoDelta = newDcoDelta;
+ }
+
+ }while(endLoop == 0); // Poll until endLoop == 1
+
+ CSCTL0 = csCtl0Copy; // Reload locked DCOTAP
+ CSCTL1 = csCtl1Copy; // Reload locked DCOFTRIM
+ while(CSCTL7 & (FLLUNLOCK0 | FLLUNLOCK1)); // Poll until FLL is locked
+}
+