1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00
RIOT/msb-430-common/board_init.c

225 lines
6.4 KiB
C
Raw Normal View History

#include "cpu.h"
#include "board.h"
#include "kernel_internal.h"
#include "msp430.h"
#include "debug.h"
static volatile uint32_t __msp430_cpu_speed = MSP430_INITIAL_CPU_SPEED;
/*---------------------------------------------------------------------------*/
static uint8_t calc_umctl(uint16_t br)
{
// from TI slaa049
register uint8_t CMOD = 256 * br - 256 * (br + 1) / 2;
register uint8_t c = 0;
register int i = 0;
register uint8_t a = CMOD;
a <<= 1;
do {
if (a & 0x80) { // Overflow to integer?
a = a - 128 + CMOD; // Yes, subtract 1.000000
c |= 0x80;
}
else {
a += CMOD; // No, add fraction
}
if (i == 7) {
return c;
}
i++;
c >>= 1;
}
while (1);
}
static void msb_ports_init(void)
{
// Port 1: Free port, for energy saving all outputs are set to zero.
P1SEL = 0x00; // Port1 Zweitfunktion
P1OUT = 0x00; // Port1 Ausgangsregister: 00000000 = 0x00
P1DIR = 0xFF; // Port1 Direction: 11111111 = 0xFF
P2SEL = 0x20; // Port2 Zweitfunktion
P2OUT = 0x00; // Port2 Ausgangsregister: 00000000 = 0x00
P2DIR = 0x1C; // Port2 Direction: 00011010 = 0x1C
// 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 ] - SD-KARTE Protect
// 0 - P2.7 [IN ] - SD-KARTE Detect
P3SEL = 0xC0; // Port3 Zweitfunktion
P3OUT = 0x09; // Port3 Ausgangsregister: 00001001 = 0x09
P3DIR = 0x2B; // Port3 Direction
// 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
// 0 - P3.7 [2-Funktion] - RS232_TxD
// Port 4: Free port, for energy saving all outputs are set to zero.
P4SEL = 0x00; // Port4 Zweitfunktion
P4OUT = 0x00; // Port4 Ausgangsregister: 00000000 = 0x00
P4DIR = 0xFF; // Port4 Direction: 11111111 = 0xFF
// 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
P5SEL = 0x00; // Port5 Zweitfunktion: 00000000 = 0x00
P5OUT = 0x80; // Port5 Ausgangsregister: 00001001 = 0x09
P5DIR = 0xFF; // Port5 Direction: 11111011 = 0xFB
// 1 - P5.0 [OUT] - SD-KARTE /CS
// 1 - P5.1 [OUT] - SD-KARTE DI
// 0 - P5.2 [IN ] - SD-KARTE DO
// 1 - P5.3 [OUT] - SD-KARTE DCLK
// 1 - P5.4 [OUT] - MMA GS1
// 1 - P5.5 [OUT] - MMA GS2
// 1 - P5.6 [OUT] - MMA /SLEEP
// 1 - P5.7 [OUT] - LED_ROT 0-an, 1-aus
P6SEL = 0x00; // Port6 Zweitfunktion = 0x07
P6OUT = 0x00; // Port6 Ausgangsregister: 00000000 = 0x00
P6DIR = 0xFF; // Port6 Direction: 11111000 = 0xF8
// 0 - P6.0 [AD-IN] - MMA X-Achse
// 0 - P6.1 [AD-IN] - MMA Y-Achse
// 0 - P6.2 [AD-IN] - MMA Z-Achse
// 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
}
void msp430_set_cpu_speed(uint32_t speed)
{
dint();
__msp430_cpu_speed = speed;
msp430_init_dco();
uint16_t br;
UCTL1 = SWRST | CHAR; // 8-bit character
UTCTL1 |= SSEL1 | URXSE; // UCLK = MCLK
// activate
U1ME |= UTXE1 | URXE1; // Enable USART1 TXD/RXD
br = (uint16_t)(__msp430_cpu_speed / 115200uL);
UBR01 = br; // set baudrate
UBR11 = br >> 8;
UMCTL1 = calc_umctl(br); // set modulation
UCTL1 &= ~SWRST;
//clock_init();
eint();
}
/*---------------------------------------------------------------------------*/
void
msp430_init_dco()
{
#if MSP430_HAS_EXTERNAL_CRYSTAL
/*------------------ use external oszillator -----------------------*/
uint16_t i;
// Stop watchdog
WDTCTL = WDTPW + WDTHOLD;
//Init crystal for mclk
//XT2 = HF XTAL
BCSCTL1 = RSEL2;
// Wait for xtal to stabilize
do {
IFG1 &= ~OFIFG; // Clear oscillator fault flag
for (i = 0xFF; i > 0; i--); // Time for flag to set
}
while ((IFG1 & OFIFG) != 0); // Oscillator fault flag still set?
BCSCTL2 = SELM_2 + SELS; // MCLK und SMCLK = XT2 (safe)
#else
/* Thdeltais code taken from the FU Berlin sources and reformatted. */
int delta = __msp430_cpu_speed >> 12;
//#define DELTA 600
unsigned int compare, oldcapture = 0;
unsigned int i;
BCSCTL1 = 0xa4; /* ACLK is devided by 4. RSEL=6 no division for MCLK
and SSMCLK. XT2 is off. */
// Init FLL to desired frequency using the 32762Hz crystal
#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 */
CCTL2 = CCIS0 + CM0 + CAP; // Define CCR2, CAP, ACLK
TACTL = TASSEL1 + TACLR + MC1; // SMCLK, continous mode
while (1) {
while ((CCTL2 & CCIFG) != CCIFG); /* Wait until capture occured! */
CCTL2 &= ~CCIFG; /* Capture occured, clear flag */
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 */
}
}
CCTL2 = 0; /* Stop CCR2 function */
TACTL = 0; /* Stop Timer_A */
BCSCTL1 &= ~(DIVA1 + DIVA0); /* remove /8 divisor from ACLK again */
#endif
}
void board_init()
{
msp430_cpu_init();
msb_ports_init();
LED_RED_ON;
msp430_set_cpu_speed(7372800uL);
}