2014-02-02 16:48:18 +01:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2014 INRIA
|
|
|
|
*
|
2014-07-31 20:15:03 +02:00
|
|
|
* This file is subject to the terms and conditions of the GNU Lesser
|
|
|
|
* General Public License v2.1. See the file LICENSE in the top level
|
|
|
|
* directory for more details.
|
2014-02-02 16:48:18 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @ingroup boards
|
|
|
|
* @{
|
|
|
|
* @file
|
|
|
|
* @brief msb-430 common board initialization
|
|
|
|
*
|
2014-02-03 00:47:38 +01:00
|
|
|
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
2014-02-02 16:48:18 +01:00
|
|
|
* @author Kaspar Schleiser <kaspar@schleiser.de>
|
|
|
|
*
|
2017-11-30 23:35:34 +01:00
|
|
|
* @}
|
2014-02-02 16:48:18 +01:00
|
|
|
*/
|
|
|
|
|
2010-09-22 15:10:42 +02:00
|
|
|
#include "cpu.h"
|
2015-09-02 16:30:18 +02:00
|
|
|
#include "irq.h"
|
2010-09-22 15:10:42 +02:00
|
|
|
#include "board.h"
|
2018-07-05 14:09:08 +02:00
|
|
|
#include "stdio_base.h"
|
2015-08-27 14:20:20 +02:00
|
|
|
#include "periph_conf.h"
|
2010-09-22 15:10:42 +02:00
|
|
|
#include "msp430.h"
|
|
|
|
#include "debug.h"
|
|
|
|
|
2013-07-18 16:06:02 +02:00
|
|
|
static volatile uint32_t __msp430_cpu_speed = MSP430_INITIAL_CPU_SPEED;
|
2010-09-22 15:10:42 +02:00
|
|
|
|
2013-08-14 23:48:01 +02:00
|
|
|
void msp430_init_dco(void);
|
|
|
|
|
2010-09-22 15:10:42 +02:00
|
|
|
static void msb_ports_init(void)
|
|
|
|
{
|
2013-08-13 10:41:50 +02:00
|
|
|
/* Port 1: Free port, for energy saving all outputs are set to zero. */
|
2014-02-03 00:47:38 +01:00
|
|
|
P1SEL = 0x00; /* Port1 I/O Function */
|
|
|
|
P1OUT = 0x00; /* Port1 Output register: 00000000 = 0x00 */
|
|
|
|
P1DIR = 0xFF; /* Port1 Direction: 11111111 = 0xFF */
|
2013-08-13 10:41:50 +02:00
|
|
|
|
2014-02-03 00:47:38 +01:00
|
|
|
P2SEL = 0x20; /* Port2 I/O Function */
|
|
|
|
P2OUT = 0x00; /* Port2 Output register: 00000000 = 0x00 */
|
|
|
|
P2DIR = 0x1C; /* Port2 Direction: 00011010 = 0x1C */
|
2013-08-13 10:41:50 +02:00
|
|
|
/* 0 - P2.0 [IN ] - */
|
|
|
|
/* 0 - P2.1 [OUT] - */
|
|
|
|
/* 1 - P2.2 [IN ] - */
|
|
|
|
/* 1 - P2.3 [OUT] - */
|
|
|
|
/* 1 - P2.4 [OUT] - */
|
|
|
|
/* 0 - P2.5 [IN ] - */
|
|
|
|
/* 0 - P2.6 [IN ] - SDC Protect */
|
|
|
|
/* 0 - P2.7 [IN ] - SDC Detect */
|
|
|
|
|
2015-08-27 14:20:20 +02:00
|
|
|
P3SEL = 0x00; /* Port3 Pins 6 & 7 for USART */
|
|
|
|
P3OUT = 0x00; /* Port3 Output register: 01001001: 0x49 */
|
|
|
|
P3DIR = 0xFF; /* Port3 Direction: 10101011: 0xAB */
|
2013-08-13 10:41:50 +02:00
|
|
|
/* 1 - P3.0 */
|
|
|
|
/* 1 - P3.1 */
|
|
|
|
/* 0 - P3.2 */
|
|
|
|
/* 1 - P3.3 */
|
|
|
|
/* 0 - P3.4 [IN ] - SHT 11 DATA (OUT/IN) */
|
|
|
|
/* 1 - P3.5 [OUT] - SHT 11 CLK */
|
|
|
|
/* 0 - P3.6 [2-Funktion] - RS232_RxD */
|
|
|
|
/* 1 - P3.7 [2-Funktion] - RS232_TxD */
|
|
|
|
|
|
|
|
/* Port 4: Free port, for energy saving all outputs are set to zero. */
|
2014-02-03 00:47:38 +01:00
|
|
|
P4SEL = 0x00; /* Port4 I/O Function */
|
|
|
|
P4OUT = 0x00; /* Port4 Output register: 00000000 = 0x00 */
|
|
|
|
P4DIR = 0xFF; /* Port4 Direction: 11111111 = 0xFF */
|
2013-08-13 10:41:50 +02:00
|
|
|
/* 1 - P4.0 [OUT] - unused */
|
|
|
|
/* 1 - P4.1 [OUT] - unused */
|
|
|
|
/* 1 - P4.2 [OUT] - unused */
|
|
|
|
/* 1 - P4.3 [OUT] - unused */
|
|
|
|
/* 1 - P4.4 [OUT] - unused */
|
|
|
|
/* 1 - P4.5 [OUT] - unused */
|
|
|
|
/* 1 - P4.6 [OUT] - unused */
|
|
|
|
/* 1 - P4.7 [OUT] - unused */
|
|
|
|
|
2014-02-03 00:47:38 +01:00
|
|
|
P5SEL = 0x00; /* Port5 I/O Function: 00000000 = 0x00 */
|
|
|
|
P5OUT = 0x80; /* Port5 Output register: 00001001 = 0x09 */
|
|
|
|
P5DIR = 0xFF; /* Port5 Direction: 11111011 = 0xFB */
|
2013-08-13 10:41:50 +02:00
|
|
|
/* 1 - P5.0 [OUT] - SDC /CS */
|
|
|
|
/* 1 - P5.1 [OUT] - SDC DI */
|
|
|
|
/* 0 - P5.2 [IN ] - SDC DO */
|
|
|
|
/* 1 - P5.3 [OUT] - SDC DCLK */
|
|
|
|
/* 1 - P5.4 [OUT] - MMA GS1 */
|
|
|
|
/* 1 - P5.5 [OUT] - MMA GS2 */
|
|
|
|
/* 1 - P5.6 [OUT] - MMA /SLEEP */
|
|
|
|
/* 1 - P5.7 [OUT] - LED_RED 0-on, 1-off */
|
|
|
|
|
2014-02-03 00:47:38 +01:00
|
|
|
P6SEL = 0x00; /* Port6 I/O Function = 0x07 */
|
|
|
|
P6OUT = 0x00; /* Port6 Output register: 00000000 = 0x00 */
|
|
|
|
P6DIR = 0xFF; /* Port6 Direction: 11111000 = 0xF8 */
|
2013-08-13 10:41:50 +02:00
|
|
|
/* 0 - P6.0 [AD-IN] - MMA X-Axis */
|
|
|
|
/* 0 - P6.1 [AD-IN] - MMA Y-Axis */
|
|
|
|
/* 0 - P6.2 [AD-IN] - MMA Z-Axis */
|
|
|
|
/* 1 - P6.3 [OUT] - unused */
|
|
|
|
/* 1 - P6.4 [OUT] - unused */
|
|
|
|
/* 1 - P6.5 [OUT] - unused */
|
|
|
|
/* 1 - P6.6 [OUT] - unused */
|
|
|
|
/* 1 - P6.7 [OUT] - unused */
|
2010-09-22 15:10:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void msp430_set_cpu_speed(uint32_t speed)
|
|
|
|
{
|
2016-03-19 09:25:47 +01:00
|
|
|
irq_disable();
|
2013-07-29 16:41:43 +02:00
|
|
|
__msp430_cpu_speed = speed;
|
|
|
|
msp430_init_dco();
|
2016-03-19 09:25:47 +01:00
|
|
|
irq_enable();
|
2010-09-22 15:10:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*---------------------------------------------------------------------------*/
|
2013-08-14 23:48:01 +02:00
|
|
|
void msp430_init_dco(void)
|
2010-09-22 15:10:42 +02:00
|
|
|
{
|
2013-07-29 16:41:43 +02:00
|
|
|
#if MSP430_HAS_EXTERNAL_CRYSTAL
|
|
|
|
/*------------------ use external oszillator -----------------------*/
|
|
|
|
uint16_t i;
|
|
|
|
|
2013-08-13 10:41:50 +02:00
|
|
|
/* Stop watchdog */
|
2013-07-29 16:41:43 +02:00
|
|
|
WDTCTL = WDTPW + WDTHOLD;
|
|
|
|
|
2018-02-05 11:39:08 +01:00
|
|
|
/* Init crystal for mclk */
|
|
|
|
/* XT2 = HF XTAL */
|
2013-07-29 16:41:43 +02:00
|
|
|
BCSCTL1 = RSEL2;
|
|
|
|
|
2013-08-13 10:41:50 +02:00
|
|
|
/* Wait for xtal to stabilize */
|
2013-07-29 16:41:43 +02:00
|
|
|
do {
|
2014-02-03 00:47:38 +01:00
|
|
|
IFG1 &= ~OFIFG; /* Clear oscillator fault flag */
|
2013-07-29 16:41:43 +02:00
|
|
|
|
2013-08-13 10:41:50 +02:00
|
|
|
for (i = 0xFF; i > 0; i--); /* Time for flag to set */
|
2013-07-29 16:41:43 +02:00
|
|
|
}
|
2014-02-03 00:47:38 +01:00
|
|
|
while ((IFG1 & OFIFG) != 0); /* Oscillator fault flag still set? */
|
2013-07-29 16:41:43 +02:00
|
|
|
|
2014-02-03 00:47:38 +01:00
|
|
|
BCSCTL2 = SELM_2 + SELS; /* MCLK und SMCLK = XT2 (safe) */
|
2013-07-29 16:41:43 +02:00
|
|
|
#else
|
make: fix sign-compare errors
cpu, nrf5x_common: fix sign-compare in periph/flashpage
drivers, periph_common: fix sign-compare in flashpage
cpu, sam0_common: fix sign-compare error in periph/gpio
cpu, cc2538: fix sign-compare in periph/timer
cpu, sam3: fix sign-compare in periph/gpio
cpu, stm32_common: fix sign-compare in periph/pwm
cpu, stm32_common: fix sign-compare in periph/timer
cpu, stm32_common: fix sign-compare in periph/flashpage
cpu, nrf5x_common: fix sign-compare in radio/nrfmin
cpu, samd21: fix sign-compare in periph/pwm
cpu, ezr32wg: fix sign-compare in periph/gpio
cpu, ezr32wg: fix sign-compare in periph/timer
drivers, ethos: fix sign-compare
sys, net: fix sign-compare
cpu, atmega_common: fix sign-compare error
cpu, msp430fxyz: fix sign-compare in periph/gpio
boards, msb-430-common: fix sign-compare in board_init
driver, cc2420: fix sign-compared
sys/net: fix sign-compare in gnrc_tftp
driver, pcd8544: fix sign-compare
driver, pn532: fix sign-compare
driver, sdcard_spi: fix sign-compare
tests: fix sign_compare
sys/net, lwmac: fix sign_compare
pkg, lwip: fix sign-compare
boards, waspmote: make CORECLOCK unsigned long to fix sign_compare error
tests, sock_ip: fix sign compare
tests, msg_avail: fix sign compare
tests, sock_udp: fix sign compare
boards: fix sign-compare for calliope and microbit matrix
2017-10-31 11:57:40 +01:00
|
|
|
unsigned int delta = __msp430_cpu_speed >> 12;
|
2014-08-11 19:51:23 +02:00
|
|
|
unsigned int oldcapture = 0;
|
2013-07-29 16:41:43 +02:00
|
|
|
unsigned int i;
|
|
|
|
|
2019-10-23 21:13:10 +02:00
|
|
|
BCSCTL1 = 0xa4; /* ACLK is divided by 4. RSEL=6 no division for MCLK
|
2014-02-03 00:47:38 +01:00
|
|
|
and SSMCLK. XT2 is off. */
|
2010-09-22 15:10:42 +02:00
|
|
|
|
2013-08-13 10:41:50 +02:00
|
|
|
/* Init FLL to desired frequency using the 32762Hz crystal */
|
2013-07-29 16:41:43 +02:00
|
|
|
#if MSP430_HAS_DCOR
|
|
|
|
BCSCTL2 = 0x01;
|
|
|
|
#else
|
|
|
|
BCSCTL2 = 0x00;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
WDTCTL = WDTPW + WDTHOLD; /* Stop WDT */
|
|
|
|
BCSCTL1 |= DIVA1 + DIVA0; /* ACLK = LFXT1CLK/8 */
|
|
|
|
|
|
|
|
for (i = 0xffff; i > 0; i--); /* Delay for XTAL to settle */
|
|
|
|
|
2013-08-13 10:41:50 +02:00
|
|
|
CCTL2 = CCIS0 + CM0 + CAP; /* Define CCR2, CAP, ACLK */
|
2019-10-23 21:13:10 +02:00
|
|
|
TACTL = TASSEL1 + TACLR + MC1; /* SMCLK, continuous mode */
|
2013-07-29 16:41:43 +02:00
|
|
|
|
|
|
|
while (1) {
|
2014-08-11 19:51:23 +02:00
|
|
|
unsigned int compare;
|
|
|
|
|
2019-10-23 21:13:10 +02:00
|
|
|
while ((CCTL2 & CCIFG) != CCIFG); /* Wait until capture occurred! */
|
2013-07-29 16:41:43 +02:00
|
|
|
|
2019-10-23 21:13:10 +02:00
|
|
|
CCTL2 &= ~CCIFG; /* Capture occurred, clear flag */
|
2013-07-29 16:41:43 +02:00
|
|
|
compare = CCR2; /* Get current captured SMCLK */
|
|
|
|
compare = compare - oldcapture; /* SMCLK difference */
|
|
|
|
oldcapture = CCR2; /* Save current captured SMCLK */
|
|
|
|
|
|
|
|
if (delta == compare) {
|
|
|
|
break; /* if equal, leave "while(1)" */
|
|
|
|
}
|
|
|
|
else if (delta < compare) { /* DCO is too fast, slow it down */
|
|
|
|
DCOCTL--;
|
|
|
|
|
|
|
|
if (DCOCTL == 0xFF) { /* Did DCO role under? */
|
|
|
|
BCSCTL1--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else { /* -> Select next lower RSEL */
|
|
|
|
DCOCTL++;
|
|
|
|
|
|
|
|
if (DCOCTL == 0x00) { /* Did DCO role over? */
|
|
|
|
BCSCTL1++;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* -> Select next higher RSEL */
|
|
|
|
}
|
2010-09-22 15:10:42 +02:00
|
|
|
}
|
|
|
|
|
2013-07-29 16:41:43 +02:00
|
|
|
CCTL2 = 0; /* Stop CCR2 function */
|
|
|
|
TACTL = 0; /* Stop Timer_A */
|
2010-09-22 15:10:42 +02:00
|
|
|
|
2013-07-29 16:41:43 +02:00
|
|
|
BCSCTL1 &= ~(DIVA1 + DIVA0); /* remove /8 divisor from ACLK again */
|
|
|
|
#endif
|
2010-09-22 15:10:42 +02:00
|
|
|
}
|
|
|
|
|
2014-05-07 12:36:32 +02:00
|
|
|
void board_init(void)
|
2013-07-29 16:41:43 +02:00
|
|
|
{
|
2010-09-22 15:10:42 +02:00
|
|
|
msb_ports_init();
|
2013-07-29 16:41:43 +02:00
|
|
|
|
2015-08-27 14:20:20 +02:00
|
|
|
msp430_set_cpu_speed(CLOCK_CORECLOCK);
|
2010-09-22 15:10:42 +02:00
|
|
|
}
|