Created
January 3, 2012 20:59
-
-
Save RickKimball/1556906 to your computer and use it in GitHub Desktop.
msp430 serial tool kit software/usci/timera/spi implementations
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* main.cpp - swserial/timerserial/usciserial Serial Asynch test driver. | |
* | |
* To test: use putty and connect to /dev/ttyACM0 at 9600 Baud | |
* | |
*/ | |
#include <msp430.h> | |
#include <stdio.h> | |
#include "serial.h" | |
#define MCLK_FREQ 16000000UL /* run @16MHz */ | |
/** | |
* typedef Serial - start of a simple serial wrapper class | |
*/ | |
typedef struct { | |
/** | |
* begin() - initialize serial port, sets registers, port direction, and | |
* alternative port features as required by implementing serial routines. | |
* Depending on the implementing method, you may not be able to use | |
* arbitrary rx/tx pins the software only implementation is the only | |
* version capable of using any arbitrary pin. | |
* | |
* baudRate - bits/sec default: 9600 | |
* rxPin - receive pin default: 1 (P1.1) ( g2553 defaults ) | |
* txPin - transmit pin default: 2 (P1.2) | |
*/ | |
static void begin(uint32_t baud = 9600, int rxPin = 1, int txPin = 2) { | |
init_serial(1 << txPin, 1 << rxPin, MCLK_FREQ / baud, (MCLK_FREQ / baud) >> 8); | |
} | |
/** | |
* puts - writes the string s to the serial output stream without a trailing | |
* newline character. Note: this differs from the ISO standard puts() | |
* function which appends a newline character. | |
*/ | |
static void puts(register const char *s) { | |
while(*s) { | |
putchar(*s++); | |
} | |
} | |
} serial_t; | |
static serial_t Serial; | |
static void initMCLK() { | |
#ifdef __MSP430FR5739 | |
CSCTL0_H = 0xA5; // CS_KEY | |
CSCTL1 |= DCOFSEL0 + DCOFSEL1; // Set max. DCO setting | |
CSCTL2 = SELA_3 + SELS_3 + SELM_3; // set ACLK = MCLK = DCO | |
CSCTL3 = DIVA_0 + DIVS_0 + DIVM_0; // set all dividers | |
#else | |
// Use 16MHz DCO factory calibration | |
DCOCTL = 0; | |
BCSCTL1 = CALBC1_16MHZ; | |
DCOCTL = CALDCO_16MHZ; | |
#endif | |
} | |
int main(void) { | |
WDTCTL = WDTPW | WDTHOLD; /* Disable watchdog */ | |
initMCLK(); | |
// configure serial device using defaults | |
Serial.begin(9600); | |
__eint(); // we enable interrupts after user setup() to give them a chance to customize | |
// goof with people | |
// printf("\rWelcome to msp430 uNix! %s %s %d, %d:%d %s\r\nlogin: ", "Fri", "Oct", 9, 11, 25, "AM"); | |
Serial.puts("\r\n# "); | |
int c; | |
int nCharCnt = 0; | |
for (;;) { | |
c = getchar(); | |
// do some minimum line control to handle backspace | |
if ( c != 127 ) { | |
putchar(c); | |
nCharCnt++; | |
} else { | |
if (nCharCnt > 0) { | |
putchar(c); | |
--nCharCnt; | |
} | |
} | |
// append newline on CR | |
if ( c == '\r' ) { | |
Serial.puts("\n# "); | |
nCharCnt = 0; | |
} | |
// restart processor on CTRL-D | |
if ( c == 0x04 /*CTRL-D*/ ) { | |
WDTCTL = WDTHOLD; // restart by setting the WDTCTL without a password | |
} | |
} | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//------------------------------------------------------------------------ | |
// serial.h - function declarations for compact asm serial routines | |
//------------------------------------------------------------------------ | |
#ifdef __cplusplus | |
extern "C" { | |
#endif | |
void init_serial(int txPinMask, int rxPinMask, unsigned duration, unsigned durMod); | |
int getchar(void); | |
int putchar(int); | |
#ifdef __cplusplus | |
} /* extern "C" */ | |
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//------------------------------------------------------------------------------ | |
// serial_priv.inc - msp430 mcu common defines for use with gcc assembler | |
//------------------------------------------------------------------------------ | |
//------------------------------------------------------------------------------ | |
// define PC,SP,SR as gcc only uses the register names | |
// | |
#define PC r0 | |
#define SP r1 | |
#define SR r2 | |
//------------------------------------------------------------------------------ | |
// define argument registers | |
// C function arguments are passed in R15-R12 | |
// | |
// Note: these registers can be used without preservation | |
// | |
#define ARG1 R15 | |
#define ARG2 R14 | |
#define ARG3 R13 | |
#define ARG4 R12 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;------------------------------------------------------------------------ | |
; File: sw_serial.S - gcc port of serial.asm | |
; | |
; Desc: blocking implementations of putchar(), getchar(), and puts() | |
; uses cycle counting for delay timing. No timers are used. | |
; can be used with any PORT1 pin | |
; | |
; See Also: | |
; Detailed information available here: | |
; http://www.43oh.com/forum/viewtopic.php?f=10&t=1727 | |
;------------------------------------------------------------------------ | |
#include <msp430.h> | |
#include "serial_priv.inc" | |
.file "serial.S" | |
.lcomm in_bit_mask, 2 ; Serial in pin mask ( rx ) | |
.lcomm out_bit_mask, 2 ; Serial out pin mask ( tx ) | |
.lcomm bit_dur, 2 ; Bit duration in cycles | |
.lcomm half_dur, 2 ; Half bit duration in cycles | |
.text ; | |
.global init_serial ; void init_serial(unsigned out_mask, unsigned in_mask, unsigned bit_duration); | |
#if 0 | |
.global puts ; int puts(const char *s); note: no trailing newline | |
#endif | |
.global putchar ; int putchar(unsigned c); | |
.global getchar ; int getchar(void); | |
.p2align 1,0 ; align on a word boundary | |
;-------------------------------------------------------------------------------- | |
; void initSerial(int txPinMask, int rxPinMask, int bitDuration) | |
;-------------------------------------------------------------------------------- | |
.type init_serial,@function | |
init_serial: ; Setup serial I/O bitmasks and bit duration (32 minimum) | |
mov ARG1, &out_bit_mask ; Save serial output bitmask | |
mov ARG2, &in_bit_mask ; Save serial input bitmask | |
bis ARG1, &P1DIR ; set output pin | |
bis ARG1, &P1OUT | |
bic ARG2, &P1DIR ; clear input pin | |
bis ARG2, ARG1 | |
#ifdef __MSP430FR5739 | |
bic ARG1, &P1SEL0 ; force output pin to digial I/O no pullups | |
bic ARG1, &P1SEL1 ; force output pin to digial I/O no pullups | |
#else | |
bic ARG1, &P1SEL ; force output pin to digial I/O no pullups | |
#endif | |
mov ARG3, ARG1 | |
sub #16, ARG3 ; Adjust count for loop overhead | |
rla ARG3 ; Multiply by 2 because NOP is two bytes | |
mov ARG3, &bit_dur ; Save bit duration | |
sub #32, ARG1 ; Adjust count for loop overhead | |
mov ARG1, &half_dur ; Save half bit duration | |
ret ; Return | |
.Lfe1: | |
.size init_serial,.Lfe1-init_serial | |
;-------------------------------------------------------------------------------- | |
; int putchar(int c) - writes the character c, cast to an unsigned char to serial out | |
;-------------------------------------------------------------------------------- | |
.type putchar,@function | |
putchar: ; Char to tx in R15, R12, R13, R14, R15 trashed | |
mov &out_bit_mask, R12 ; Serial output bitmask | |
mov &bit_dur, R14 ; Bit duration | |
bis #0x0300, ARG1 ; Add Stop bit(s) to tx char | |
jmp bit_low ; Send start bit... | |
tx_bit: | |
mov R14, R13 ; Get bit duration | |
tx_delay: | |
nop ; 4 cycle loop | |
sub #8, R13 ; | |
jc tx_delay ; | |
subc R13, PC ; 0 to 3 cycle delay | |
nop ; 3 | |
nop ; 2 | |
nop ; 1 | |
rra ARG1 ; Get bit to tx, test for zero | |
jc bit_high ; If high... | |
bit_low: | |
bic.b R12, &P1OUT ; Send zero bit | |
jmp tx_bit ; Next bit... | |
bit_high: | |
bis.b R12, &P1OUT ; Send one bit | |
jnz tx_bit ; If tx data is not zero, then there are more bits to send... | |
ret ; Return when all bits sent | |
.Lfe2: | |
;-------------------------------------------------------------------------------- | |
; int getchar(void) - read one character (blocking) | |
;-------------------------------------------------------------------------------- | |
.type getchar,@function | |
getchar: | |
mov &bit_dur, R14 ; Bit duration | |
mov &in_bit_mask, R13 ; Input bitmask | |
mov #0x01FF, ARG1 ; 9 bits - 8 data + stop | |
rx_start: ; Wait for start bit | |
mov &P1IN, R12 ; Get serial input | |
and R13, R12 ; Mask and test bit | |
jc rx_start ; Wait for low... | |
mov &half_dur, R13 ; Wait for 1/2 bit time | |
rx_delay: | |
nop ; Bit delay | |
sub #8, R13 | |
jc rx_delay | |
subc R13, PC ; 0 to 3 cycle delay | |
nop ; 3 | |
nop ; 2 | |
nop ; 1 | |
mov &P1IN, R12 ; Get serial input | |
and &in_bit_mask, R12 ; | |
rrc ARG1 ; Shift in a bit | |
mov R14, R13 ; Setup bit timer | |
jc rx_delay ; Next bit... | |
rla ARG1 ; Move stop bit to carry | |
swpb ARG1 ; Move rx byte to lower byte, start bit in msb | |
ret ; Return with rx char and start bit in R15, stop bit in carry | |
.Lfe3: | |
.size getchar,.Lfe3-getchar | |
;-------------------------------------------------------------------------------- | |
#if 0 /* NOT USED, implemented in C externally */ | |
;-------------------------------------------------------------------------------- | |
.type puts,@function | |
;-------------------------------------------------------------------------------- | |
; int puts(const char *s) - writes the string s and a trailing newline to serial out. | |
;-------------------------------------------------------------------------------- | |
puts: | |
push R11 ; Tx string using putchar | |
mov ARG1, R11 ; String pointer in R15, copy to R11 | |
putsloop: | |
mov.b @R11+, ARG1 ; Get a byte, inc pointer | |
tst.b ARG1 ; Test if end of string | |
jz putsx ; Yes, exit... | |
call #putchar ; Call putchar | |
jmp putsloop | |
putsx: | |
pop R11 ; restore original R11 | |
ret ; | |
.Lfe4: | |
.size puts,.Lfe4-puts | |
;-------------------------------------------------------------------------------- | |
#endif /* NOT USED, implemented in C externally */ | |
;-------------------------------------------------------------------------------- |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment