dblob 0 Posted April 1, 2014 Share Posted April 1, 2014 Hi all, I am trying to implement/edit an UART library (https://github.com/wendlers/msp430-softuart) on 2452 to run on MCLK 8MHz and SMCLK at 8MHz (by /8 divider). BCSCTL1 = CALBC1_1MHZ; DCOCTL = CALDCO_1MHZ; Then I changed the MCLK to 8MHz and divided the SMCLK to 1MHz, but even after some magic with USB ports (I am using debian) or restarts I can't get it working as in the initial version (which still works when I reflash the chip). The changed snippet in 2452_echo.c: BCSCTL1 = CALBC1_8MHZ; DCOCTL = CALDCO_8MHZ; /* set sub-main clock to 1MHz */ //BCSCTL2 = DIVS_3; BCSCTL2 = SELM_0 | DIVM_0 | DIVS_3; Any hints?Thank you, b Quote Link to post Share on other sites
dblob 0 Posted April 1, 2014 Author Share Posted April 1, 2014 Forgot to add the code.. 2452_code.c /* echos back received bytes */ #include <msp430g2452.h> #include <stdint.h> #include "uart.h" #define UART_TXD BIT1 #define UART_RXD BIT2 #define RED_LED BIT0 #define GRN_LED BIT6 uint16_t wdtCounter = 0; inline static void init_clock(void) { /* set main clock to 8MHz */ DCOCTL = 0x00; BCSCTL1 = CALBC1_8MHZ; DCOCTL = CALDCO_8MHZ; /* set sub-main clock to 1MHz */ //BCSCTL2 = DIVS_3; BCSCTL2 = SELM_0 | DIVM_0 | DIVS_3; // BCSCTL2 &= ~SELM0; // MCLK comes from DCO // BCSCTL2 &= ~SELM1; // BCSCTL2 &= ~SELS; // Sub main clock comes from DCO // BCSCTL2 |= DIVS0 + DIVS1; // SMCLK = 1 MHz (DC0/8) } inline static void init_timers(void) { /* watchdog */ WDTCTL = WDT_MDLY_32; /* set watchdog timer interval to 32ms */ IE1 |= WDTIE; /* enable interrupts for the watchdog timer */ } inline static void init_IO(void) { /* configure LED pins on port 1 as output pins */ P1DIR |= RED_LED | GRN_LED; /* make sure leds are turned on */ P1OUT |= RED_LED | GRN_LED; uart_init(); } int main(void) { uint8_t c; /* init */ __delay_cycles(128); init_timers(); init_IO(); __enable_interrupt(); for(; { /* infinite loop */ if (uart_getc(&c)) { if (c == '\r') { uart_putc('\n'); uart_putc('\r'); P1OUT ^= RED_LED; } else { uart_putc('-'); uart_putc(c); uart_putc('-'); P1OUT ^= GRN_LED; } } } } void watchdog_timer(void) __attribute__((interrupt(WDT_VECTOR))); void watchdog_timer(void) { wdtCounter++; if(wdtCounter == 20) { wdtCounter = 0; /* reset counter */ } } init_clock(); uart.c /****************************************************************************** * Software UART example for MSP430. * * Stefan Wendler * sw@kaltpost.de * http://gpio.kaltpost.de * * **************************************************************************** * The original code is taken form Nicholas J. Conn example: * * http://www.msp430launchpad.com/2010/08/half-duplex-software-uart-on-launchpad.html * * Origial Description from Nicholas: * * Half Duplex Software UART on the LaunchPad * * Description: This code provides a simple Bi-Directional Half Duplex * Software UART. The timing is dependant on SMCLK, which * is set to 1MHz. The transmit function is based off of * the example code provided by TI with the LaunchPad. * This code was originally created for "NJC's MSP430 * LaunchPad Blog". * * Author: Nicholas J. Conn - http://msp430launchpad.com * Email: webmaster at msp430launchpad.com * Date: 08-17-10 * **************************************************************************** * Includes also improvements from Joby Taffey and fixes from Colin Funnell * as posted here: * * http://blog.hodgepig.org/tag/msp430/ ******************************************************************************/ #include <msp430.h> #include <legacymsp430.h> #include <stdbool.h> #include "uart.h" /** * TXD on P1.1 */ #define TXD BIT1 /** * RXD on P1.2 */ #define RXD BIT2 /** * Clock freq. */ #define CLK_FREQ 1000000 /** * Baudrate */#define BAUDRATE 9600 /** * Bit time */ #define BIT_TIME (CLK_FREQ / BAUDRATE) /** * Half bit time */ #define HALF_BIT_TIME (BIT_TIME / 2) /** * Bit count, used when transmitting byte */ static volatile uint8_t bitCount; /** * Value sent over UART when uart_putc() is called */ static volatile unsigned int TXByte; /** * Value recieved once hasRecieved is set */ static volatile unsigned int RXByte; /** * Status for when the device is receiving */ static volatile bool isReceiving = false; /** * Lets the program know when a byte is received */ static volatile bool hasReceived = false; void uart_init(void) { P1SEL |= TXD; P1DIR |= TXD; P1IES |= RXD; // RXD Hi/lo edge interrupt P1IFG &= ~RXD; // Clear RXD (flag) before enabling interrupt P1IE |= RXD; // Enable RXD interrupt } bool uart_getc(uint8_t *c) { if (!hasReceived) { return false; } *c = RXByte; hasReceived = false; return true; } void uart_putc(uint8_t c) { TXByte = c; while (isReceiving) {} // Wait for RX completion TACCTL0 = OUT; // TXD Idle as Mark TACTL = TASSEL_2 | MC_2; // SMCLK, continuous mode bitCount = 0xA; // Load Bit counter, 8 bits + ST/SP TACCR0 = TAR; // Initialize compare register TACCR0 += BIT_TIME; // Set time till first bit TXByte |= 0x100; // Add stop bit to TXByte (which is logical 1) TXByte = TXByte << 1; // Add start bit (which is logical 0) TACCTL0 = CCIS_0 | OUTMOD_0 | CCIE | OUT; // Set signal, intial value, enable interrupts while (TACCTL0 & CCIE) {} // Wait for previous TX completion } void uart_puts(const char *str) { if (*str != 0) { uart_putc(*str++); } while (*str != 0) { uart_putc(*str++); } } /** * ISR for RXD */ interrupt(PORT1_VECTOR) PORT1_ISR(void) { isReceiving = true; P1IE &= ~RXD; // Disable RXD interrupt P1IFG &= ~RXD; // Clear RXD IFG (interrupt flag) TACTL = TASSEL_2 | MC_2; // SMCLK, continuous mode TACCR0 = TAR; // Initialize compare register TACCR0 += HALF_BIT_TIME; // Set time till first bit TACCTL0 = OUTMOD_1 | CCIE; // Disable TX and enable interrupts RXByte = 0; // Initialize RXByte bitCount = 9; // Load Bit counter, 8 bits + start bit } /** * ISR for TXD and RXD */ interrupt(TIMER0_A0_VECTOR) TIMERA0_ISR(void) { if (!isReceiving) { TACCR0 += BIT_TIME; // Add Offset to CCR0 if (bitCount == 0) { // If all bits TXed TACTL = 0; // SMCLK, timer off (for power consumption) TACCTL0 &= ~CCIE; // Disable interrupt } else { if (TXByte & 0x01) { TACCTL0 = ((TACCTL0 & ~OUTMOD_7) | OUTMOD_1); //OUTMOD_7 defines the 'window' of the field. } else { TACCTL0 = ((TACCTL0 & ~OUTMOD_7) | OUTMOD_5); //OUTMOD_7 defines the 'window' of the field. } TXByte = TXByte >> 1; bitCount--; } } else { TACCR0 += BIT_TIME; // Add Offset to CCR0 if (bitCount == 0) { TACTL = 0; // SMCLK, timer off (for power consumption) TACCTL0 &= ~ CCIE ; // Disable interrupt isReceiving = false; P1IFG &= ~RXD; // clear RXD IFG (interrupt flag) P1IE |= RXD; // enabled RXD interrupt if ((RXByte & 0x201) == 0x200) { // Validate the start and stop bits are correct RXByte = RXByte >> 1; // Remove start bit RXByte &= 0xFF; // Remove stop bit hasReceived = true; } } else { if ((P1IN & RXD) == RXD) { // If bit is set? RXByte |= 0x400; // Set the value in the RXByte } RXByte = RXByte >> 1; // Shift the bits down bitCount--; } } } uart.h is the same as in the linked library.. Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.