rendered paste body// ARDUINO Compatibility layer by Jonathan Schemoul// Parts of code from:// - friendly Launchpad : http://github.com/chrishulbert/friendly_launchpad// - WIRING project// License: LGPL#include "Arduino.h"const uint8_t BITS[] = {BIT0, BIT1, BIT2, BIT3, BIT4, BIT5, BIT6, BIT7};int timer_cycles = 1024;int16_t P1VAL[8] = {-1,-1,-1,-1,-1,-1,-1,-1};int16_t P2VAL[8] = {-1,-1,-1,-1,-1,-1,-1,-1};int16_t P3VAL[8] = {-1,-1,-1,-1,-1,-1,-1,-1};int16_t P4VAL[8] = {-1,-1,-1,-1,-1,-1,-1,-1};int16_t P5VAL[8] = {-1,-1,-1,-1,-1,-1,-1,-1};int16_t P6VAL[8] = {-1,-1,-1,-1,-1,-1,-1,-1};int16_t P7VAL[8] = {-1,-1,-1,-1,-1,-1,-1,-1};int16_t P8VAL[8] = {-1,-1,-1,-1,-1,-1,-1,-1};int16_t P9VAL[8] = {-1,-1,-1,-1,-1,-1,-1,-1};int pwm_counter = 0;unsigned long RAND_NEXT = 1;#ifdef __MSP430_HAS_BC2__void msp430_init_dco() { BCSCTL1 = CALBC1_16MHZ; DCOCTL = CALDCO_16MHZ;}#endif#ifdef __MSP430_HAS_UCS__void msp430_init_dco() { // Increase Vcore setting to level3 to support fsystem=25MHz // NOTE: Change core voltage one level at a time.. SetVcoreUp (0x01); SetVcoreUp (0x02); SetVcoreUp (0x03); UCSCTL3 = SELREF_2; // Set DCO FLL reference = REFO UCSCTL4 |= SELA_2; // Set ACLK = REFO __bis_SR_register(SCG0); // Disable the FLL control loop UCSCTL0 = 0x0000; // Set lowest possible DCOx, MODx UCSCTL1 = DCORSEL_7; // Select DCO range 50MHz operation //UCSCTL2 = 762; UCSCTL2 = F_CPU / 32768; //UCSCTL2 = FLLD_1 + 732; //UCSCTL2 = FLLD_1 + 488; // Set DCO Multiplier for 25MHz // (N + 1) * FLLRef = Fdco // (762 + 1) * 32768 = 25MHz // Set FLL Div = fDCOCLK/2 __bic_SR_register(SCG0); // re-enable the FLL control loop // Worst-case settling time for the DCO when the DCO range bits have been // changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx // UG for optimization. // 32 x 32 x 25 MHz / 32,768 Hz ~ 780k MCLK cycles for DCO to settle //for (int i = 0; i < 16; i++) // __delay_cycles(48875); // Loop until XT1 & DCO stabilizes - In this case only DCO has to stabilize /*do { UCSCTL7 &= ~(XT1LFOFFG + XT1HFOFFG + DCOFFG); // Clear XT1,DCO fault flags SFRIFG1 &= ~OFIFG; // Clear fault flags }while (SFRIFG1&OFIFG); // Test oscillator fault flag*/}void SetVcoreUp (unsigned int level){ // Open PMM registers for write PMMCTL0_H = PMMPW_H; // Set SVS/SVM high side new level SVSMHCTL = SVSHE + SVSHRVL0 * level + SVMHE + SVSMHRRL0 * level; // Set SVM low side to new level SVSMLCTL = SVSLE + SVMLE + SVSMLRRL0 * level; // Wait till SVM is settled while ((PMMIFG & SVSMLDLYIFG) == 0); // Clear already set flags PMMIFG &= ~(SVMLVLRIFG + SVMLIFG); // Set VCore to new level PMMCTL0_L = PMMCOREV0 * level; // Wait till new level reached if ((PMMIFG & SVMLIFG)) while ((PMMIFG & SVMLVLRIFG) == 0); // Set SVS/SVM low side to new level SVSMLCTL = SVSLE + SVSLRVL0 * level + SVMLE + SVSMLRRL0 * level; // Lock PMM registers for write access PMMCTL0_H = 0x00;}#endif#define port_write(port, pin, mode) {if(mode){port|=pinBit(pin);} else {port&=~pinBit(pin);}}#define port_read(port, mode) (port & pinBit(pin) ? HIGH : LOW)void pinMode(int pin, int mode) { switch (pin/10) { case 1: port_write(P1DIR, pin-10, mode); break;#ifdef P2DIR case 2: port_write(P2DIR, pin-20, mode); break;#endif#ifdef P3DIR case 3: port_write(P3DIR, pin-30, mode); break;#endif#ifdef P4DIR case 4: port_write(P4DIR, pin-40, mode); break;#endif#ifdef P5DIR case 5: port_write(P5DIR, pin-50, mode); break;#endif#ifdef P6DIR case 6: port_write(P6DIR, pin-60, mode); break;#endif#ifdef P7DIR case 7: port_write(P7DIR, pin-70, mode); break;#endif#ifdef P8DIR case 8: port_write(P8DIR, pin-80, mode); break;#endif }}#ifndef FAST_PWMvoid digitalWrite(int pin, int mode) { switch (pin/10) { case 1: analogWrite(pin, -1); port_write(P1OUT, pin-10, mode); break;#ifdef P2OUT case 2: analogWrite(pin, -1); port_write(P2OUT, pin-20, mode); break;#endif#ifdef P3OUT case 3: analogWrite(pin, -1); port_write(P3OUT, pin-30, mode); break;#endif#ifdef P4OUT case 4: analogWrite(pin, -1); port_write(P4OUT, pin-40, mode); break;#endif#ifdef P5OUT case 5: analogWrite(pin, -1); port_write(P5OUT, pin-50, mode); break;#endif#ifdef P6OUT case 6: analogWrite(pin, -1); port_write(P6OUT, pin-60, mode); break;#endif#ifdef P7OUT case 7: analogWrite(pin, -1); port_write(P7OUT, pin-70, mode); break;#endif#ifdef P8OUT case 8: analogWrite(pin, -1); port_write(P8OUT, pin-80, mode); break;#endif }}#elsevoid digitalWrite(int pin, int mode) { analogWrite(pin, mode ? 255 : 0);}#endifint digitalRead(int pin) { int retval; switch (pin/10) { case 1: retval = port_read(P1IN, pin-10); break;#ifdef P2IN case 2: retval = port_read(P2IN, pin-50); break;#endif#ifdef P3IN case 3: retval = port_read(P3IN, pin-60); break;#endif#ifdef P4IN case 4: retval = port_read(P4IN, pin-40); break;#endif#ifdef P5IN case 5: retval = port_read(P5IN, pin-50); break;#endif#ifdef P6IN case 6: retval = port_read(P6IN, pin-60); break;#endif#ifdef P7IN case 7: retval = port_read(P7IN, pin-70); break;#endif#ifdef P8IN case 8: retval = port_read(P8IN, pin-80); break;#endif } return retval;}void start_timers() { TACCR0 = timer_cycles; // TimerA SMCLK in UP mode TACTL = TASSEL_2 | MC_1; // Enable interrupt for TACCR0 match TACCTL0 = CCIE; _BIS_SR(GIE);}void change_pwm_frequency(int new_value) { timer_cycles = new_value; TACCR0 = timer_cycles;}int main(void){ msp430_init_dco(); start_timers(); // Stop watchdog WDTCTL = WDTPW + WDTHOLD; // Todo maybe remove the defaults? // Not necessary as they default to input just like arduino //P1DIR = 0; // All input (arduino's default?) //P2DIR = 0; // All input P1SEL = 0; // All GPIO P2SEL = 0; // All GPIO setup(); for(;;) { loop(); } return 0;}#define analog_port_write(port, pin, value) {port[pin]=value;}void analogWrite(int pin, int value) { /*switch (pin/10) { case 1: analog_port_write(P1VAL, pin%10, value); break; case 2: analog_port_write(P2VAL, pin%10, value); break; case 3: analog_port_write(P3VAL, pin%10, value); break; case 4: analog_port_write(P4VAL, pin%10, value); break; case 5: analog_port_write(P5VAL, pin%10, value); break; case 6: analog_port_write(P6VAL, pin%10, value); break; case 7: analog_port_write(P7VAL, pin%10, value); break; case 8: analog_port_write(P8VAL, pin%10, value); break; }*/ P1VAL[pin-10] = value;}#ifndef FAST_PWM#define port_pwm_write(port, portval) {\ uint8_t bcm = port;\ int i;\ int pval;\ for (i=0; i<8; i++) {\ pval = portval[i];\ if (pval != -1) {\ if (pval > pwm_counter) {\ bcm |= BITS[i];\ } else {\ bcm &=~ BITS[i];\ };\ }\ }\ port = bcm; }#else#define port_pwm_write(port, portval) {\ uint8_t bcm = 0x00;\ if (portval[0] > pwm_counter) bcm |= BIT0;\ if (portval[1] > pwm_counter) bcm |= BIT1;\ if (portval[2] > pwm_counter) bcm |= BIT2;\ if (portval[3] > pwm_counter) bcm |= BIT3;\ if (portval[4] > pwm_counter) bcm |= BIT4;\ if (portval[5] > pwm_counter) bcm |= BIT5;\ if (portval[6] > pwm_counter) bcm |= BIT6;\ if (portval[7] > pwm_counter) bcm |= BIT7;\ port = bcm;\}#endif//CCR0 timer interrupt, which toggles the LEDs#ifdef TIMER0_A0_VECTORinterrupt(TIMER0_A0_VECTOR) TIMERA0_ISR() {#endif#ifdef TIMERA0_VECTORinterrupt(TIMERA0_VECTOR) TIMERA0_ISR() {#endif pwm_counter++; if (pwm_counter >= 255) pwm_counter = 0; // port_pwm_write(P1OUT, P1VAL); #ifdef P2OUT port_pwm_write(P2OUT, P2VAL); #endif #ifdef P3OUT port_pwm_write(P3OUT, P3VAL); #endif #ifdef P4OUT port_pwm_write(P4OUT, P4VAL); #endif #ifdef P5OUT port_pwm_write(P5OUT, P5VAL); #endif #ifdef P6OUT port_pwm_write(P6OUT, P6VAL); #endif #ifdef P7OUT port_pwm_write(P7OUT, P7VAL); #endif #ifdef P8OUT port_pwm_write(P8OUT, P8VAL); #endif // This implementation is much faster but dumber :) /*uint8_t bcm = 0x00; if (P1VAL[0] > pwm_counter) bcm |= BIT0; if (P1VAL[1] > pwm_counter) bcm |= BIT1; if (P1VAL[2] > pwm_counter) bcm |= BIT2; if (P1VAL[3] > pwm_counter) bcm |= BIT3; if (P1VAL[4] > pwm_counter) bcm |= BIT4; if (P1VAL[5] > pwm_counter) bcm |= BIT5; if (P1VAL[6] > pwm_counter) bcm |= BIT6; if (P1VAL[7] > pwm_counter) bcm |= BIT7;*/ // This one is slower, but doesn't step on other's toes /*uint8_t bcm = P1OUT; int i; int pval; for (i=0; i<8; i++) { pval = P1VAL[i]; if (pval != -1) { if (pval > pwm_counter) { bcm |= BITS[i]; } else { bcm &=~ BITS[i]; }; } } */ /*uint8_t bcm = 0x00; if (curval) bcm |= BIT0; if (curval) bcm |= BIT1; if (curval) bcm |= BIT2; curval = !curval;*/ //P1OUT = bcm;}void delay(unsigned int ms){ ms++; while (ms > 0) { ms--; __delay_cycles(F_CPU_MS); // 1000 for 1 Mhz }}void delayMicroseconds(unsigned int mcs){ mcs++; while (mcs > 0) { mcs--; __delay_cycles(F_CPU_MCS); // 1 for 1 Mhz }}int random(int32_t howsmall, int32_t howbig){ RAND_NEXT = RAND_NEXT * 1103515245 + 12345; return((unsigned)((RAND_NEXT%(howbig-howsmall))+howsmall));}int random(int32_t howbig) { return random(0, howbig);}void randomSeed(unsigned seed) { RAND_NEXT = seed;}int32_t map(int32_t x, int32_t in_min, int32_t in_max, int32_t out_min, int32_t out_max){ return (x - in_min) * (out_max - out_min + 1) / (in_max - in_min + 1) + out_min;}uint16_t makeWord(uint16_t w){ return w;}uint16_t makeWord(uint8_t highByte, uint8_t lowByte){ return (highByte << 8) | lowByte;}uint16_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t count, uint8_t delayTime){ uint16_t value = 0; for (uint8_t i = 0; i < count; ++i) { digitalWrite(clockPin, HIGH); delayMicroseconds(delayTime); if (bitOrder == LSBFIRST) value |= digitalRead(dataPin) << i; else value |= digitalRead(dataPin) << ((count - 1) - i); digitalWrite(clockPin, LOW); delayMicroseconds(delayTime); } return value;}void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint16_t val, uint8_t count, uint8_t delayTime){ int i; for (i = 0; i < count; ++i) { if (bitOrder == LSBFIRST) { digitalWrite(dataPin, !!(val & (1 << i))); } else { digitalWrite(dataPin, !!(val & (1 << ((count - 1) - i)))); } digitalWrite(clockPin, HIGH); delayMicroseconds(delayTime); digitalWrite(clockPin, LOW); delayMicroseconds(delayTime); }}