PORT=/dev/ttyUSB0
BSL=msp430-bsl --invert-reset --invert-test -c $(PORT) --speed=38400
-#mcu=msp430x1611
+#mcu=msp430x2618
mcu=msp430x1612
-#ldscript is wonky
-GCCINC=-T ldscripts/161x.x
+
+#N.B., gcc WILL NOT BITCH if this file doesn't exist.
+#GCCINC=-T ldscripts/161x.x
+GCCINC=-T ldscripts/$(mcu).x
CC=msp430-gcc -Wall -g -mmcu=$(mcu) -DGCC $(GCCINC) -I include
apps= apps/monitor/monitor.o apps/spi/spi.o apps/i2c/i2c.o apps/chipcon/chipcon.o apps/jtag/jtag.o apps/jtag/jtag430.o
-libs= lib/msp430f1612.o lib/command.o apps/jtag/jtag430asm.o
+libs= lib/$(mcu).o lib/command.o apps/jtag/jtag430asm.o
app=goodfet
all: $(app).hex
--- /dev/null
+GoodFET Firmware
+by Travis Goodspeed
+<travis at radiantmachines.com>
+
+Requires MSPGCC and msp430-bsl.
+
+Assumes MSP430F161x by default. Call for others by
+mcu=msp430x2618 make -e
+
+++ /dev/null
-/* Default linker script, for normal executables */
-OUTPUT_FORMAT("elf32-msp430","elf32-msp430","elf32-msp430")
-OUTPUT_ARCH(msp:16)
-MEMORY
-{
- text (rx) : ORIGIN = 0x4000, LENGTH = 0xbfe0
- data (rwx) : ORIGIN = 0x1100, LENGTH = 0x1400
- vectors (rw) : ORIGIN = 0xffe0, LENGTH = 32
- bootloader(rx) : ORIGIN = 0x0c00, LENGTH = 1K
- infomem(rx) : ORIGIN = 0x1000, LENGTH = 256
- infomemnobits(rx) : ORIGIN = 0x1000, LENGTH = 256
-}
-SECTIONS
-{
- /* Read-only sections, merged into text segment. */
- .hash : { *(.hash) }
- .dynsym : { *(.dynsym) }
- .dynstr : { *(.dynstr) }
- .gnu.version : { *(.gnu.version) }
- .gnu.version_d : { *(.gnu.version_d) }
- .gnu.version_r : { *(.gnu.version_r) }
- .rel.init : { *(.rel.init) }
- .rela.init : { *(.rela.init) }
- .rel.text :
- {
- *(.rel.text)
- *(.rel.text.*)
- *(.rel.gnu.linkonce.t*)
- }
- .rela.text :
- {
- *(.rela.text)
- *(.rela.text.*)
- *(.rela.gnu.linkonce.t*)
- }
- .rel.fini : { *(.rel.fini) }
- .rela.fini : { *(.rela.fini) }
- .rel.rodata :
- {
- *(.rel.rodata)
- *(.rel.rodata.*)
- *(.rel.gnu.linkonce.r*)
- }
- .rela.rodata :
- {
- *(.rela.rodata)
- *(.rela.rodata.*)
- *(.rela.gnu.linkonce.r*)
- }
- .rel.data :
- {
- *(.rel.data)
- *(.rel.data.*)
- *(.rel.gnu.linkonce.d*)
- }
- .rela.data :
- {
- *(.rela.data)
- *(.rela.data.*)
- *(.rela.gnu.linkonce.d*)
- }
- .rel.ctors : { *(.rel.ctors) }
- .rela.ctors : { *(.rela.ctors) }
- .rel.dtors : { *(.rel.dtors) }
- .rela.dtors : { *(.rela.dtors) }
- .rel.got : { *(.rel.got) }
- .rela.got : { *(.rela.got) }
- .rel.bss : { *(.rel.bss) }
- .rela.bss : { *(.rela.bss) }
- .rel.plt : { *(.rel.plt) }
- .rela.plt : { *(.rela.plt) }
- /* Internal text space. */
- .text :
- {
- . = ALIGN(2);
- *(.init)
- KEEP(*(.init))
- *(.init0) /* Start here after reset. */
- KEEP(*(.init0))
- *(.init1) /* User definable. */
- KEEP(*(.init1))
- *(.init2) /* Initialize stack. */
- KEEP(*(.init2))
- *(.init3) /* Initialize hardware, user definable. */
- KEEP(*(.init3))
- *(.init4) /* Copy data to .data, clear bss. */
- KEEP(*(.init4))
- *(.init5) /* User definable. */
- KEEP(*(.init5))
- *(.init6) /* C++ constructors. */
- KEEP(*(.init6))
- *(.init7) /* User definable. */
- KEEP(*(.init7))
- *(.init8) /* User definable. */
- KEEP(*(.init8))
- *(.init9) /* Call main(). */
- KEEP(*(.init9))
- __ctors_start = . ;
- *(.ctors)
- KEEP(*(.ctors))
- __ctors_end = . ;
- __dtors_start = . ;
- *(.dtors)
- KEEP(*(.dtors))
- __dtors_end = . ;
- . = ALIGN(2);
- *(.text)
- . = ALIGN(2);
- *(.text.*)
- . = ALIGN(2);
- *(.fini9) /* Jumps here after main(). User definable. */
- KEEP(*(.fini9))
- *(.fini8) /* User definable. */
- KEEP(*(.fini8))
- *(.fini7) /* User definable. */
- KEEP(*(.fini7))
- *(.fini6) /* C++ destructors. */
- KEEP(*(.fini6))
- *(.fini5) /* User definable. */
- KEEP(*(.fini5))
- *(.fini4) /* User definable. */
- KEEP(*(.fini4))
- *(.fini3) /* User definable. */
- KEEP(*(.fini3))
- *(.fini2) /* User definable. */
- KEEP(*(.fini2))
- *(.fini1) /* User definable. */
- KEEP(*(.fini1))
- *(.fini0) /* Infinite loop after program termination. */
- KEEP(*(.fini0))
- *(.fini)
- KEEP(*(.fini))
- _etext = .;
- } > text
- .data :
- {
- PROVIDE (__data_start = .) ;
- . = ALIGN(2);
- *(.data)
- *(SORT_BY_ALIGNMENT(.data.*))
- . = ALIGN(2);
- *(.gnu.linkonce.d*)
- . = ALIGN(2);
- _edata = . ;
- } > data AT > text
- PROVIDE (__data_load_start = LOADADDR(.data) );
- PROVIDE (__data_size = SIZEOF(.data) );
- /* Bootloader. */
- .bootloader :
- {
- PROVIDE (__boot_start = .) ;
- *(.bootloader)
- . = ALIGN(2);
- *(.bootloader.*)
- } > bootloader
- /* Information memory. */
- .infomem :
- {
- *(.infomem)
- . = ALIGN(2);
- *(.infomem.*)
- } > infomem
- /* Information memory (not loaded into MPU). */
- .infomemnobits :
- {
- *(.infomemnobits)
- . = ALIGN(2);
- *(.infomemnobits.*)
- } > infomemnobits
- .bss :
- {
- PROVIDE (__bss_start = .) ;
- *(.bss)
- *(SORT_BY_ALIGNMENT(.bss.*))
- *(COMMON)
- PROVIDE (__bss_end = .) ;
- _end = . ;
- } > data
- PROVIDE (__bss_size = SIZEOF(.bss) );
- .noinit :
- {
- PROVIDE (__noinit_start = .) ;
- *(.noinit)
- *(.noinit.*)
- *(COMMON)
- PROVIDE (__noinit_end = .) ;
- _end = . ;
- } > data
- .vectors :
- {
- PROVIDE (__vectors_start = .) ;
- *(.vectors*)
- KEEP(*(.vectors*))
- _vectors_end = . ;
- } > vectors
- /* Stabs for profiling information*/
- .profiler 0 : { *(.profiler) }
- /* Stabs debugging sections. */
- .stab 0 : { *(.stab) }
- .stabstr 0 : { *(.stabstr) }
- .stab.excl 0 : { *(.stab.excl) }
- .stab.exclstr 0 : { *(.stab.exclstr) }
- .stab.index 0 : { *(.stab.index) }
- .stab.indexstr 0 : { *(.stab.indexstr) }
- .comment 0 : { *(.comment) }
- /* DWARF debug sections.
- Symbols in the DWARF debugging sections are relative to the beginning
- of the section so we begin them at 0. */
- /* DWARF 1 */
- .debug 0 : { *(.debug) }
- .line 0 : { *(.line) }
- /* GNU DWARF 1 extensions */
- .debug_srcinfo 0 : { *(.debug_srcinfo) }
- .debug_sfnames 0 : { *(.debug_sfnames) }
- /* DWARF 1.1 and DWARF 2 */
- .debug_aranges 0 : { *(.debug_aranges) }
- .debug_pubnames 0 : { *(.debug_pubnames) }
- /* DWARF 2 */
- .debug_info 0 : { *(.debug_info) *(.gnu.linkonce.wi.*) }
- .debug_abbrev 0 : { *(.debug_abbrev) }
- .debug_line 0 : { *(.debug_line) }
- .debug_frame 0 : { *(.debug_frame) }
- .debug_str 0 : { *(.debug_str) }
- .debug_loc 0 : { *(.debug_loc) }
- .debug_macinfo 0 : { *(.debug_macinfo) }
- /* DWARF 3 */
- .debug_pubtypes 0 : { *(.debug_pubtypes) }
- .debug_ranges 0 : { *(.debug_ranges) }
- PROVIDE (__stack = 0x2500) ;
- PROVIDE (__data_start_rom = _etext) ;
- PROVIDE (__data_end_rom = _etext + SIZEOF (.data)) ;
- PROVIDE (__noinit_start_rom = _etext + SIZEOF (.data)) ;
- PROVIDE (__noinit_end_rom = _etext + SIZEOF (.data) + SIZEOF (.noinit)) ;
- PROVIDE (__subdevice_has_heap = 0) ;
-}
--- /dev/null
+Linking script notes, by Travis Goodspeed.
+
+msp430f1612.x is a neighborly little linking script, the purpose of which is to
+link an application for use on an MSP430F1611 or MSP430F1612. These
+chips differ in that five kilobytes at 0x2500 are RAM in the 1611,
+Flash in the 1612. All other scripts in this directory should be
+similarly modified, but the GCC script seems to be used by default if not.
+
+
+
+
--- /dev/null
+/* Default linker script, for normal executables */
+OUTPUT_FORMAT("elf32-msp430","elf32-msp430","elf32-msp430")
+OUTPUT_ARCH(msp:16)
+MEMORY
+{
+ text (rx) : ORIGIN = 0x4000, LENGTH = 0xbfe0
+ data (rwx) : ORIGIN = 0x1100, LENGTH = 0x1400
+ vectors (rw) : ORIGIN = 0xffe0, LENGTH = 32
+ bootloader(rx) : ORIGIN = 0x0c00, LENGTH = 1K
+ infomem(rx) : ORIGIN = 0x1000, LENGTH = 256
+ infomemnobits(rx) : ORIGIN = 0x1000, LENGTH = 256
+}
+SECTIONS
+{
+ /* Read-only sections, merged into text segment. */
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .gnu.version : { *(.gnu.version) }
+ .gnu.version_d : { *(.gnu.version_d) }
+ .gnu.version_r : { *(.gnu.version_r) }
+ .rel.init : { *(.rel.init) }
+ .rela.init : { *(.rela.init) }
+ .rel.text :
+ {
+ *(.rel.text)
+ *(.rel.text.*)
+ *(.rel.gnu.linkonce.t*)
+ }
+ .rela.text :
+ {
+ *(.rela.text)
+ *(.rela.text.*)
+ *(.rela.gnu.linkonce.t*)
+ }
+ .rel.fini : { *(.rel.fini) }
+ .rela.fini : { *(.rela.fini) }
+ .rel.rodata :
+ {
+ *(.rel.rodata)
+ *(.rel.rodata.*)
+ *(.rel.gnu.linkonce.r*)
+ }
+ .rela.rodata :
+ {
+ *(.rela.rodata)
+ *(.rela.rodata.*)
+ *(.rela.gnu.linkonce.r*)
+ }
+ .rel.data :
+ {
+ *(.rel.data)
+ *(.rel.data.*)
+ *(.rel.gnu.linkonce.d*)
+ }
+ .rela.data :
+ {
+ *(.rela.data)
+ *(.rela.data.*)
+ *(.rela.gnu.linkonce.d*)
+ }
+ .rel.ctors : { *(.rel.ctors) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rel.dtors : { *(.rel.dtors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rel.got : { *(.rel.got) }
+ .rela.got : { *(.rela.got) }
+ .rel.bss : { *(.rel.bss) }
+ .rela.bss : { *(.rela.bss) }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ /* Internal text space. */
+ .text :
+ {
+ . = ALIGN(2);
+ *(.init)
+ KEEP(*(.init))
+ *(.init0) /* Start here after reset. */
+ KEEP(*(.init0))
+ *(.init1) /* User definable. */
+ KEEP(*(.init1))
+ *(.init2) /* Initialize stack. */
+ KEEP(*(.init2))
+ *(.init3) /* Initialize hardware, user definable. */
+ KEEP(*(.init3))
+ *(.init4) /* Copy data to .data, clear bss. */
+ KEEP(*(.init4))
+ *(.init5) /* User definable. */
+ KEEP(*(.init5))
+ *(.init6) /* C++ constructors. */
+ KEEP(*(.init6))
+ *(.init7) /* User definable. */
+ KEEP(*(.init7))
+ *(.init8) /* User definable. */
+ KEEP(*(.init8))
+ *(.init9) /* Call main(). */
+ KEEP(*(.init9))
+ __ctors_start = . ;
+ *(.ctors)
+ KEEP(*(.ctors))
+ __ctors_end = . ;
+ __dtors_start = . ;
+ *(.dtors)
+ KEEP(*(.dtors))
+ __dtors_end = . ;
+ . = ALIGN(2);
+ *(.text)
+ . = ALIGN(2);
+ *(.text.*)
+ . = ALIGN(2);
+ *(.fini9) /* Jumps here after main(). User definable. */
+ KEEP(*(.fini9))
+ *(.fini8) /* User definable. */
+ KEEP(*(.fini8))
+ *(.fini7) /* User definable. */
+ KEEP(*(.fini7))
+ *(.fini6) /* C++ destructors. */
+ KEEP(*(.fini6))
+ *(.fini5) /* User definable. */
+ KEEP(*(.fini5))
+ *(.fini4) /* User definable. */
+ KEEP(*(.fini4))
+ *(.fini3) /* User definable. */
+ KEEP(*(.fini3))
+ *(.fini2) /* User definable. */
+ KEEP(*(.fini2))
+ *(.fini1) /* User definable. */
+ KEEP(*(.fini1))
+ *(.fini0) /* Infinite loop after program termination. */
+ KEEP(*(.fini0))
+ *(.fini)
+ KEEP(*(.fini))
+ _etext = .;
+ } > text
+ .data :
+ {
+ PROVIDE (__data_start = .) ;
+ . = ALIGN(2);
+ *(.data)
+ *(SORT_BY_ALIGNMENT(.data.*))
+ . = ALIGN(2);
+ *(.gnu.linkonce.d*)
+ . = ALIGN(2);
+ _edata = . ;
+ } > data AT > text
+ PROVIDE (__data_load_start = LOADADDR(.data) );
+ PROVIDE (__data_size = SIZEOF(.data) );
+ /* Bootloader. */
+ .bootloader :
+ {
+ PROVIDE (__boot_start = .) ;
+ *(.bootloader)
+ . = ALIGN(2);
+ *(.bootloader.*)
+ } > bootloader
+ /* Information memory. */
+ .infomem :
+ {
+ *(.infomem)
+ . = ALIGN(2);
+ *(.infomem.*)
+ } > infomem
+ /* Information memory (not loaded into MPU). */
+ .infomemnobits :
+ {
+ *(.infomemnobits)
+ . = ALIGN(2);
+ *(.infomemnobits.*)
+ } > infomemnobits
+ .bss :
+ {
+ PROVIDE (__bss_start = .) ;
+ *(.bss)
+ *(SORT_BY_ALIGNMENT(.bss.*))
+ *(COMMON)
+ PROVIDE (__bss_end = .) ;
+ _end = . ;
+ } > data
+ PROVIDE (__bss_size = SIZEOF(.bss) );
+ .noinit :
+ {
+ PROVIDE (__noinit_start = .) ;
+ *(.noinit)
+ *(.noinit.*)
+ *(COMMON)
+ PROVIDE (__noinit_end = .) ;
+ _end = . ;
+ } > data
+ .vectors :
+ {
+ PROVIDE (__vectors_start = .) ;
+ *(.vectors*)
+ KEEP(*(.vectors*))
+ _vectors_end = . ;
+ } > vectors
+ /* Stabs for profiling information*/
+ .profiler 0 : { *(.profiler) }
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+ /* DWARF debug sections.
+ Symbols in the DWARF debugging sections are relative to the beginning
+ of the section so we begin them at 0. */
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info) *(.gnu.linkonce.wi.*) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ /* DWARF 3 */
+ .debug_pubtypes 0 : { *(.debug_pubtypes) }
+ .debug_ranges 0 : { *(.debug_ranges) }
+ PROVIDE (__stack = 0x2500) ;
+ PROVIDE (__data_start_rom = _etext) ;
+ PROVIDE (__data_end_rom = _etext + SIZEOF (.data)) ;
+ PROVIDE (__noinit_start_rom = _etext + SIZEOF (.data)) ;
+ PROVIDE (__noinit_end_rom = _etext + SIZEOF (.data) + SIZEOF (.noinit)) ;
+ PROVIDE (__subdevice_has_heap = 0) ;
+}
+++ /dev/null
-//! MSP430F1612/1611 clock and I/O definitions
-
-#include "platform.h"
-
-#include <signal.h>
-#include <io.h>
-#include <iomacros.h>
-
-
-//! Receive a byte.
-unsigned char serial_rx(){
- char c;
-
- while(!(IFG1&URXIFG0));//wait for a byte
- c = RXBUF0;
- IFG1&=~URXIFG0;
- U0TCTL &= ~URXSE;
-
- return c;
-}
-
-//! Receive a byte.
-unsigned char serial1_rx(){
- char c;
-
- while(!(IFG2&URXIFG1));//wait for a byte
- c = RXBUF1;
- IFG2&=~URXIFG1;
- U1TCTL &= ~URXSE;
-
- return c;
-}
-
-
-//! Transmit a byte.
-void serial_tx(unsigned char x){
- while ((IFG1 & UTXIFG0) == 0); //loop until buffer is free
- TXBUF0 = x;
-}
-
-//! Transmit a byte on the second UART.
-void serial1_tx(unsigned char x){
- while ((IFG2 & UTXIFG1) == 0); //loop until buffer is free
- TXBUF1 = x;
-}
-
-//! Set the baud rate.
-void setbaud(unsigned char rate){
-
- //http://mspgcc.sourceforge.net/baudrate.html
- switch(rate){
- case 1://9600 baud
- UBR00=0x7F; UBR10=0x01; UMCTL0=0x5B; /* uart0 3683400Hz 9599bps */
- break;
- case 2://19200 baud
- UBR00=0xBF; UBR10=0x00; UMCTL0=0xF7; /* uart0 3683400Hz 19194bps */
- break;
- case 3://38400 baud
- UBR00=0x5F; UBR10=0x00; UMCTL0=0xBF; /* uart0 3683400Hz 38408bps */
- break;
- case 4://57600 baud
- UBR00=0x40; UBR10=0x00; UMCTL0=0x00; /* uart0 3683400Hz 57553bps */
- break;
- default:
- case 5://115200 baud
- UBR00=0x20; UBR10=0x00; UMCTL0=0x00; /* uart0 3683400Hz 115106bps */
- break;
- }
-}
-
-//! Set the baud rate of the second uart.
-void setbaud1(unsigned char rate){
-
- //http://mspgcc.sourceforge.net/baudrate.html
- switch(rate){
- case 1://9600 baud
- UBR01=0x7F; UBR11=0x01; UMCTL1=0x5B; /* uart0 3683400Hz 9599bps */
- break;
- case 2://19200 baud
- UBR01=0xBF; UBR11=0x00; UMCTL1=0xF7; /* uart0 3683400Hz 19194bps */
- break;
- case 3://38400 baud
- UBR01=0x5F; UBR11=0x00; UMCTL1=0xBF; /* uart0 3683400Hz 38408bps */
- break;
- case 4://57600 baud
- UBR01=0x40; UBR11=0x00; UMCTL1=0x00; /* uart0 3683400Hz 57553bps */
- break;
- default:
- case 5://115200 baud
- UBR01=0x20; UBR11=0x00; UMCTL1=0x00; /* uart0 3683400Hz 115106bps */
- break;
- }
-}
-
-
-void msp430_init_uart(){
-
- P3SEL |= BIT4|BIT5; // P3.4,5 = USART0 TXD/RXD
- P3DIR |= BIT4;
-
- UCTL0 = SWRST | CHAR; /* 8-bit character, UART mode */
- UTCTL0 = SSEL1; /* UCLK = MCLK */
-
- setbaud(0);
-
- //Necessary for bit-banging, switch to hardware for performance.
- ME1 &= ~USPIE0; /* USART1 SPI module disable */
- ME1 |= (UTXE0 | URXE0); /* Enable USART1 TXD/RXD */
-
- UCTL0 &= ~SWRST;
-
- /* XXX Clear pending interrupts before enable!!! */
- U0TCTL |= URXSE;
-
-
- //IE1 |= URXIE1; /* Enable USART1 RX interrupt */
-}
-
-
-void msp430_init_dco() {
- /* This code taken from the FU Berlin sources and reformatted. */
- //
-
-//Works well.
-//#define MSP430_CPU_SPEED 2457600UL
-
-//Too fast for internal resistor.
-//#define MSP430_CPU_SPEED 4915200UL
-
-//Max speed.
-//#deefine MSP430_CPU_SPEED 4500000UL
-
-//baud rate speed
-#define MSP430_CPU_SPEED 3683400UL
-#define DELTA ((MSP430_CPU_SPEED) / (32768 / 8))
- unsigned int compare, oldcapture = 0;
- unsigned int i;
-
- WDTCTL = WDTPW + WDTHOLD; //stop WDT
-
-
- DCOCTL=0xF0;
- //a4
- //1100
-
- /* ACLK is devided by 4. RSEL=6 no division for MCLK
- and SSMCLK. XT2 is off. */
- //BCSCTL1 = 0xa8;
-
- BCSCTL2 = 0x00; /* Init FLL to desired frequency using the 32762Hz
- crystal DCO frquenzy = 2,4576 MHz */
-
- P1OUT|=1;
-
- BCSCTL1 |= DIVA1 + DIVA0; /* ACLK = LFXT1CLK/8 */
- for(i = 0xffff; i > 0; i--) { /* Delay for XTAL to settle */
- asm("nop");
- }
-
- 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 */
-
- P1OUT=0;
-}
-
--- /dev/null
+//! MSP430F1612/1611 clock and I/O definitions
+
+#include "platform.h"
+
+#include <signal.h>
+#include <io.h>
+#include <iomacros.h>
+
+
+//! Receive a byte.
+unsigned char serial_rx(){
+ char c;
+
+ while(!(IFG1&URXIFG0));//wait for a byte
+ c = RXBUF0;
+ IFG1&=~URXIFG0;
+ U0TCTL &= ~URXSE;
+
+ return c;
+}
+
+//! Receive a byte.
+unsigned char serial1_rx(){
+ char c;
+
+ while(!(IFG2&URXIFG1));//wait for a byte
+ c = RXBUF1;
+ IFG2&=~URXIFG1;
+ U1TCTL &= ~URXSE;
+
+ return c;
+}
+
+
+//! Transmit a byte.
+void serial_tx(unsigned char x){
+ while ((IFG1 & UTXIFG0) == 0); //loop until buffer is free
+ TXBUF0 = x;
+}
+
+//! Transmit a byte on the second UART.
+void serial1_tx(unsigned char x){
+ while ((IFG2 & UTXIFG1) == 0); //loop until buffer is free
+ TXBUF1 = x;
+}
+
+//! Set the baud rate.
+void setbaud(unsigned char rate){
+
+ //http://mspgcc.sourceforge.net/baudrate.html
+ switch(rate){
+ case 1://9600 baud
+ UBR00=0x7F; UBR10=0x01; UMCTL0=0x5B; /* uart0 3683400Hz 9599bps */
+ break;
+ case 2://19200 baud
+ UBR00=0xBF; UBR10=0x00; UMCTL0=0xF7; /* uart0 3683400Hz 19194bps */
+ break;
+ case 3://38400 baud
+ UBR00=0x5F; UBR10=0x00; UMCTL0=0xBF; /* uart0 3683400Hz 38408bps */
+ break;
+ case 4://57600 baud
+ UBR00=0x40; UBR10=0x00; UMCTL0=0x00; /* uart0 3683400Hz 57553bps */
+ break;
+ default:
+ case 5://115200 baud
+ UBR00=0x20; UBR10=0x00; UMCTL0=0x00; /* uart0 3683400Hz 115106bps */
+ break;
+ }
+}
+
+//! Set the baud rate of the second uart.
+void setbaud1(unsigned char rate){
+
+ //http://mspgcc.sourceforge.net/baudrate.html
+ switch(rate){
+ case 1://9600 baud
+ UBR01=0x7F; UBR11=0x01; UMCTL1=0x5B; /* uart0 3683400Hz 9599bps */
+ break;
+ case 2://19200 baud
+ UBR01=0xBF; UBR11=0x00; UMCTL1=0xF7; /* uart0 3683400Hz 19194bps */
+ break;
+ case 3://38400 baud
+ UBR01=0x5F; UBR11=0x00; UMCTL1=0xBF; /* uart0 3683400Hz 38408bps */
+ break;
+ case 4://57600 baud
+ UBR01=0x40; UBR11=0x00; UMCTL1=0x00; /* uart0 3683400Hz 57553bps */
+ break;
+ default:
+ case 5://115200 baud
+ UBR01=0x20; UBR11=0x00; UMCTL1=0x00; /* uart0 3683400Hz 115106bps */
+ break;
+ }
+}
+
+
+void msp430_init_uart(){
+
+ P3SEL |= BIT4|BIT5; // P3.4,5 = USART0 TXD/RXD
+ P3DIR |= BIT4;
+
+ UCTL0 = SWRST | CHAR; /* 8-bit character, UART mode */
+ UTCTL0 = SSEL1; /* UCLK = MCLK */
+
+ setbaud(0);
+
+ //Necessary for bit-banging, switch to hardware for performance.
+ ME1 &= ~USPIE0; /* USART1 SPI module disable */
+ ME1 |= (UTXE0 | URXE0); /* Enable USART1 TXD/RXD */
+
+ UCTL0 &= ~SWRST;
+
+ /* XXX Clear pending interrupts before enable!!! */
+ U0TCTL |= URXSE;
+
+
+ //IE1 |= URXIE1; /* Enable USART1 RX interrupt */
+}
+
+
+void msp430_init_dco() {
+ /* This code taken from the FU Berlin sources and reformatted. */
+ //
+
+//Works well.
+//#define MSP430_CPU_SPEED 2457600UL
+
+//Too fast for internal resistor.
+//#define MSP430_CPU_SPEED 4915200UL
+
+//Max speed.
+//#deefine MSP430_CPU_SPEED 4500000UL
+
+//baud rate speed
+#define MSP430_CPU_SPEED 3683400UL
+#define DELTA ((MSP430_CPU_SPEED) / (32768 / 8))
+ unsigned int compare, oldcapture = 0;
+ unsigned int i;
+
+ WDTCTL = WDTPW + WDTHOLD; //stop WDT
+
+
+ DCOCTL=0xF0;
+ //a4
+ //1100
+
+ /* ACLK is devided by 4. RSEL=6 no division for MCLK
+ and SSMCLK. XT2 is off. */
+ //BCSCTL1 = 0xa8;
+
+ BCSCTL2 = 0x00; /* Init FLL to desired frequency using the 32762Hz
+ crystal DCO frquenzy = 2,4576 MHz */
+
+ P1OUT|=1;
+
+ BCSCTL1 |= DIVA1 + DIVA0; /* ACLK = LFXT1CLK/8 */
+ for(i = 0xffff; i > 0; i--) { /* Delay for XTAL to settle */
+ asm("nop");
+ }
+
+ 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 */
+
+ P1OUT=0;
+}
+