summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuillaume Knispel <gknispel@avencall.com>2012-11-08 15:54:15 +0100
committerGuillaume Knispel <gknispel@avencall.com>2012-11-08 15:54:15 +0100
commite90bedf1691cd010050876ca00f6359ba98e2b48 (patch)
tree1fe5b0d897803bea9db397fa1998194678413f83
parent6adf596faf350e9a7bb8cf0b33410826f166e3fe (diff)
switch MCLK and SMCLK to 2 MHz
I am hopeful that this will provide a better stability of the MSP430 in case of voltage drops.
-rw-r--r--main.c92
1 files changed, 63 insertions, 29 deletions
diff --git a/main.c b/main.c
index 16dbdb5..e0d783a 100644
--- a/main.c
+++ b/main.c
@@ -106,18 +106,27 @@ volatile u8 bVCC3 = true;
#ifdef TRACE_SERIAL
-// For UCOS16 = 1
-// BRCLK Baud Rate UCBRx UCBRSx UCBRFx Tx Error Rx Error
-// 12,000,000 115200 6 0 8 -1.8 0 -2.2 0.4
+// For UCOS16 = 0
+/*
+def baud_slow(freq, ucbr, ucbrs):
+ zeros = 8 - ucbrs
+ return 1. / ((zeros * ucbr + ucbrs * (ucbr + 1)) / float(freq) / 8.)
+
+>>> baud_slow(2000000, 17, 3)
+115107.91366906476
+*/
static void SerialInit(void)
{
+ // Configure the USCI as an UART @ 115200 bauds
+ // Precondition: SMCLK = 2MHz
+
UCA0CTL1_bit.UCSWRST = 1;
- UCA0CTL0 = 0;
+ UCA0CTL0 = 0; // select UART mode and framing
UCA0CTL1 = 0xC1; // UCSSEL=11b => SMCLK; (keep) UCSWRST = 1;
- UCA0BR0 = 6;
+ UCA0BR0 = 17;
UCA0BR1 = 0;
- UCA0MCTL = 0x81; // UCOS16 = 1; UCBRSx = 0; UCBRFx = 8;
+ UCA0MCTL = 0x06; // UCOS16 = 0; UCBRSx = 3; UCBRFx = 0 (dont care);
UCA0STAT = 0;
// Configure port for UART access
@@ -441,7 +450,7 @@ int main(void)
__interrupt void Timer_A(void)
{
#ifdef WATCHDOG
- /* ACLK (VLO) /64 => T belongs to [0.016; 0.0032] s */
+ /* ACLK (VLO) /64 => T belongs to [0.0032; 0.016] s */
WDTCTL = WDTPW | WDTCNTCL | WDTSSEL | WDTIS1 | WDTIS0;
#endif /* WATCHDOG */
@@ -505,19 +514,24 @@ static void GlobalInit(void)
{
/******** MCLK SMCLK ACLK Configuration ********/
- /* freq selection procedure compliant with errata BCL12
+ /* Freq selection procedure compliant with errata BCL12 at startup
* (potentially switching from RSEL < 12 to > 13)
+ * Note that we do not even need this workaround with an 8MHz freq
+ * for the DCO (RSEL == 13). However, we might return to a 12MHz freq
+ * on the v6.6 board, so this sequence shall not be changed.
*/
+ BCSCTL2 = DIVS_2 | DIVM_2; /* MCLK and SMCLK Divider: /4 */
DCOCTL = 0;
/* LFXT1 low freq (to allow for VLO), ACLK will be /1 */
- BCSCTL1 = CALBC1_12MHZ & ~(XTS | DIVA0 | DIVA1);
- DCOCTL = CALDCO_12MHZ;
+ BCSCTL1 = CALBC1_8MHZ & ~(XTS | DIVA0 | DIVA1);
+ DCOCTL = CALDCO_8MHZ;
BCSCTL3 = LFXT1S_2 /* VLO */;
/* Status here:
- * MCLK and SMCLK from DCO, 12MHz nominal.
- * ACLK from VLOCLK, 4 -> 20kHz.
+ * DCO: 8MHz nominal.
+ * MCLK and SMCLK: DCO/4 = 2MHz nominal.
+ * ACLK from VLOCLK: 4 -> 20kHz.
*/
@@ -535,24 +549,44 @@ static void GlobalInit(void)
/******** Timer A configuration ********/
- TACTL = TASSEL_2 | ID_3 | TACLR | TAIE | MC_1; // SMCLK | div by 8 | reset |
- // enable interrupt | UP
-
// Calibrated DCO Frequencies - Tolerance Over Temperature 0C to 85C
+ // Min Typ Max
+ // BCSCTL1 = CALBC1_8MHZ, 2.2 V 7.76 8 8.4
+ // fCAL(8MHz) DCOCTL = CALDCO_8MHZ, 3V 7.8 8 8.2 MHz
+ // Gating time: 5 ms 3.6 V 7.6 8 8.24
//
- // Min Typ Max
- // BCSCTL1 = CALBC1_12MHZ, 2.2 V 11.7 12 12.3
- // fCAL(12MHz) DCOCTL = CALDCO_12MHZ, 3 V 11.7 12 12.3 MHz
- // Gating time: 5 ms 3.6 V 11.7 12 12.3
+ // BCSCTL1 = CALBC1_12MHZ, 2.2 V 11.7 12 12.3
+ // fCAL(12MHz) DCOCTL = CALDCO_12MHZ, 3 V 11.7 12 12.3 MHz
+ // Gating time: 5 ms 3.6 V 11.7 12 12.3
- // Timer_A called every:
- //
- // >>> 1539 / 1500000. * .975
- // 0.00100035 1.000 ms min
- // >>> 1539 / 1500000.
- // 0.001026 1.026 ms nom
- // >>> 1539 / 1500000. * 1.025
- // 0.00105165 1.052 ms max
-
- TACCR0 = 1539 + 1; /* TA16 errata => + 1 => so T belongs to [1.000 ; 1.053] */
+ // Currently used values 7.6 -> 8.4 MHz = 8 MHz +/- 5%
+
+ // Timer_A count:
+ /* ===============
+from math import ceil
+
+def taccr0(min_freq, nom_freq, max_freq, divisor, min_target_period):
+ min_div_freq = float(min_freq) / divisor
+ nom_div_freq = float(nom_freq) / divisor
+ max_div_freq = float(max_freq) / divisor
+ count = ceil(max_div_freq * min_target_period)
+ print "count =", int(count)
+ print "NOTE: remember to use count+1 (TA16 errata)"
+ print "min period =", count / max_div_freq
+ print "nom period =", count / nom_div_freq
+ print "max period (with count incremented) =", count / min_div_freq
+
+===============
+ >>> taccr0(7600000, 8000000, 8400000, 4, 0.001)
+ count = 2100
+ NOTE: remember to use count+1 (TA16 errata)
+ min period = 0.001
+ nom period = 0.00105
+ max period (with count incremented) = 0.00110526315789
+ */
+
+ TACTL = TASSEL_2 | ID_0 | TACLR | TAIE | MC_1; // SMCLK | div by 1 | reset |
+ // enable interrupt | UP
+
+ TACCR0 = 2100 + 1; /* T belongs to [1.000 ; 1.106] */
}