From: Eugene Crosser Date: Mon, 14 Dec 2015 16:27:54 +0000 (+0300) Subject: move msp430 code in a dir X-Git-Url: http://www.average.org/gitweb/?p=pulsecounter.git;a=commitdiff_plain;h=02d2dc9e46149beb63a3dac83a9346232e2626da move msp430 code in a dir --- diff --git a/Hal/Hal.c b/Hal/Hal.c deleted file mode 100644 index 0cdcc29..0000000 --- a/Hal/Hal.c +++ /dev/null @@ -1,439 +0,0 @@ -/* - * ============ Hardware Abstraction Layer for MSP-EXP430G2 LaunchPad ============ - */ - -#include "Hal.h" -#include "Em_Message.h" - -#include - - -/* -------- INTERNAL FEATURES -------- */ - -#define GREEN_LED_CONFIG() (P1DIR |= BIT6) -#define GREEN_LED_ON() (P1OUT |= BIT6) -#define GREEN_LED_OFF() (P1OUT &= ~BIT6) -#define GREEN_LED_READ() (P1OUT & BIT6) -#define GREEN_LED_TOGGLE() (P1OUT ^= BIT6) - -#define RED_LED_CONFIG() (P1DIR |= BIT0) -#define RED_LED_ON() (P1OUT |= BIT0) -#define RED_LED_OFF() (P1OUT &= ~BIT0) -#define RED_LED_READ() (P1OUT & BIT0) -#define RED_LED_TOGGLE() (P1OUT ^= BIT0) - -#define GPIO_CONFIG(mask) (P1DIR &= ~mask, P1REN |= mask, P1OUT |= mask, P1IES |= mask); -#define GPIO_ENABLE(mask) (P1IFG &= ~mask, P1IE |= mask) -#define GPIO_DISABLE(mask) (P1IE &= ~mask, P1IFG &= ~mask) -#define GPIO_FIRED(mask) (P1IFG & mask) -#define GPIO_LOW(mask) (!(P1IN & mask)) -#define GPIO_DEBOUNCE_MSECS 100 - -#define DEBUG1_CONFIG() (P2DIR |= BIT3) -#define DEBUG1_ON() (P2OUT |= BIT3) -#define DEBUG1_OFF() (P2OUT &= ~BIT3) - -#define DEBUG2_CONFIG() (P2DIR |= BIT4) -#define DEBUG2_ON() (P2OUT |= BIT4) -#define DEBUG2_OFF() (P2OUT &= ~BIT4) - -#define EAP_RX_BUF UCA0RXBUF -#define EAP_TX_BUF UCA0TXBUF - -#define EAP_RX_VECTOR USCIAB0RX_VECTOR -#define EAP_TX_VECTOR USCIAB0TX_VECTOR -#define EAP_TX_ACK_VECTOR PORT2_VECTOR - -#define EAP_RX_ENABLE() (P1SEL |= BIT1, P1SEL2 |= BIT1) -#define EAP_RX_DISABLE() (P1SEL &= ~BIT1, P1SEL2 &= ~BIT1) -#define EAP_TX_ENABLE() (P1SEL |= BIT2, P1SEL2 |= BIT2) -#define EAP_TX_DISABLE() (P1SEL &= ~BIT2, P1SEL2 &= ~BIT2) - -#define EAP_RX_ACK_CONFIG() (P2DIR |= BIT0) -#define EAP_RX_ACK_SET() (P2OUT |= BIT0) -#define EAP_RX_ACK_CLR() (P2OUT &= ~BIT0) - -#define EAP_TX_ACK_CONFIG() (P2DIR &= ~BIT1, P2IES |= BIT1, P2IFG &= ~BIT1, P2IE |= BIT1) -#define EAP_TX_ACK_TST() (P2IFG & BIT1) -#define EAP_TX_ACK_CLR() (P2IFG &= ~BIT1) - -#define EAP_RX_INT_CLR() (IFG2 &= ~UCA0RXIFG) -#define EAP_RX_INT_ENABLE() (IE2 |= UCA0RXIE) -#define EAP_TX_INT_CLR() (IFG2 &= ~UCA0TXIFG) -#define EAP_TX_INT_DISABLE() (IE2 &= ~UCA0TXIE) -#define EAP_TX_INT_ENABLE() (IE2 |= UCA0TXIE) - -#define MCLK_TICKS_PER_MS 1000L -#define ACLK_TICKS_PER_SECOND 1500L /* was 12000L with divider /1 */ -#define UART_WATCHDOG_PERIOD (ACLK_TICKS_PER_SECOND * 250) / 1000 - -#define UART_WATCH_DISABLE() (TA1CCTL1 = 0) // Turn off CCR1 Interrupt -#define UART_WATCH_ENABLE() (TA1CCR1 = TA1R + UART_WATCHDOG_PERIOD, TA1CCTL1 = CCIE) // Set CCR1, and Enable CCR1 Interrupt - -#ifdef __GNUC__ -#define DINT() __disable_interrupt() -#define EINT() __enable_interrupt() -#define INTERRUPT -#define SLEEP() _BIS_SR(LPM3_bits + GIE) -#define WAKEUP() _BIC_SR_IRQ(LPM3_bits) -#endif - -#ifdef __TI_COMPILER_VERSION__ -#define DINT() (_disable_interrupt()) -#define EINT() (_enable_interrupt()) -#define INTERRUPT interrupt -#define SLEEP() (__bis_SR_register(LPM3_bits + GIE)) -#define WAKEUP() (__bic_SR_register_on_exit(LPM3_bits)) -#endif - -#define NUM_HANDLERS 5 - -#define EVENT3_HANDLER_ID 0 -#define EVENT4_HANDLER_ID 1 -#define EVENT5_HANDLER_ID 2 -#define TICK_HANDLER_ID 3 -#define DISPATCH_HANDLER_ID 4 - -static void gpioHandler(uint8_t id); -static void postEvent(uint8_t handlerId); - -static Hal_Handler appGpioHandler; -static volatile uint16_t handlerEvents = 0; -static uint16_t clockTick = 0; -static Hal_Handler handlerTab[NUM_HANDLERS]; - - -/* -------- APP-HAL INTERFACE -------- */ - -void Hal_gpioEnable(Hal_Handler handler) { - uint8_t id; - uint16_t mask; - - for (id = 0, mask = BIT3; id < 3; id++, mask <<= 1) { - handlerTab[id] = gpioHandler; - appGpioHandler = handler; - (P1DIR &= ~mask, P1REN |= mask, P1OUT |= mask, P1IES |= mask); - Hal_delay(100); - (P1IFG &= ~mask, P1IE |= mask); - } -} - -void Hal_connected(void) { -} - -void Hal_debugOn(uint8_t line) { - switch (line) { - case 1: - DEBUG1_ON(); - break; - case 2: - DEBUG2_ON(); - } -} - -void Hal_debugOff(uint8_t line) { - switch (line) { - case 1: - DEBUG1_OFF(); - break; - case 2: - DEBUG2_OFF(); - } -} - -void Hal_debugPulse(uint8_t line) { - switch (line) { - case 1: - DEBUG1_ON(); - DEBUG1_OFF(); - break; - case 2: - DEBUG2_ON(); - DEBUG2_OFF(); - } -} - -void Hal_delay(uint16_t msecs) { - while (msecs--) { - __delay_cycles(MCLK_TICKS_PER_MS); - } -} - -void Hal_disconnected(void) { -} - -void Hal_init(void) { - - /* setup clocks */ - - WDTCTL = WDTPW + WDTHOLD; - /* MCLK = DCOCLK */ - /* MCLK divider = /1 */ - /* SMCLK divider = /1 */ - BCSCTL2 = SELM_0 + DIVM_0 + DIVS_0; - if (CALBC1_1MHZ != 0xFF) { - DCOCTL = 0x00; - BCSCTL1 = CALBC1_1MHZ; /* Set DCO to 1MHz */ - DCOCTL = CALDCO_1MHZ; - } - /* XT2 is off (Not used for MCLK/SMCLK) */ - /* ACLK divider = /8 */ - BCSCTL1 |= XT2OFF + DIVA_3; - /* XT2 range = 0.4 - 1 MHz */ - /* LFXT1 range/VLO = VLOCLK (or 3-16 MHz if XTS=1) */ - /* Capacitor 6 pF */ - BCSCTL3 = XT2S_0 + LFXT1S_2 + XCAP_1; - - /* setup LEDs */ - - GREEN_LED_CONFIG(); - GREEN_LED_OFF(); - RED_LED_CONFIG(); - RED_LED_OFF(); - - /* setup debug pins */ - - DEBUG1_CONFIG(); DEBUG1_OFF(); - DEBUG2_CONFIG(); DEBUG2_OFF(); - - DEBUG1_ON(); DEBUG1_OFF(); - - /* setup TimerA1 */ - TA1CTL = TASSEL_1 + MC_2; // ACLK, Continuous mode - UART_WATCH_DISABLE(); - - /* setup UART */ - - UCA0CTL1 |= UCSWRST; - - EAP_RX_ENABLE(); - EAP_TX_ENABLE(); - - EAP_RX_ACK_CONFIG(); - EAP_RX_ACK_SET(); - - EAP_TX_ACK_CONFIG(); - - // suspend the MCM - EAP_RX_ACK_CLR(); - - UCA0CTL1 = UCSSEL_2 + UCSWRST; - UCA0MCTL = UCBRF_0 + UCBRS_6; - UCA0BR0 = 8; - UCA0CTL1 &= ~UCSWRST; - - handlerTab[DISPATCH_HANDLER_ID] = Em_Message_dispatch; -} - -void Hal_idleLoop(void) { - - EINT(); - for (;;) { - - // atomically read/clear all handlerEvents - DINT(); - uint16_t events = handlerEvents; - handlerEvents = 0; - - if (events) { // dispatch all current events - EINT(); - uint16_t mask; - uint8_t id; - for (id = 0, mask = 0x1; id < NUM_HANDLERS; id++, mask <<= 1) { - if ((events & mask) && handlerTab[id]) { - handlerTab[id](id); - } - } - } - else { // await more events - SLEEP(); - } - } -} - -void Hal_greenLedOn(void) { - GREEN_LED_ON(); -} - -void Hal_greenLedOff(void) { - GREEN_LED_OFF(); -} - -bool Hal_greenLedRead(void) { - return GREEN_LED_READ(); -} - -void Hal_greenLedToggle(void) { - GREEN_LED_TOGGLE(); -} - -void Hal_redLedOn(void) { - RED_LED_ON(); -} - -void Hal_redLedOff(void) { - RED_LED_OFF(); -} - -bool Hal_redLedRead(void) { - return RED_LED_READ(); -} - -void Hal_redLedToggle(void) { - RED_LED_TOGGLE(); -} - -void Hal_tickStart(uint16_t msecs, Hal_Handler handler) { - handlerTab[TICK_HANDLER_ID] = handler; - clockTick = (ACLK_TICKS_PER_SECOND * msecs) / 1000; - TA1CCR0 = TA1R + clockTick; // Set the CCR0 interrupt for msecs from now. - TA1CCTL0 = CCIE; // Enable the CCR0 interrupt -} - -void Hal_tickStop(void) { - handlerTab[TICK_HANDLER_ID] = 0; - TA1CCR0 = 0; - TA1CCTL0 = 0; -} - -/* -------- SRT-HAL INTERFACE -------- */ - -uint8_t Em_Hal_lock(void) { - uint8_t key = _get_interrupt_state(); - #ifdef __GNUC__ - __disable_interrupt(); - #endif - #ifdef __TI_COMPILER_VERSION__ - _disable_interrupt(); - #endif - return key; -} - -void Em_Hal_reset(void) { - uint8_t key = Em_Hal_lock(); - EAP_RX_ACK_CLR(); // suspend the MCM - Hal_delay(100); - EAP_RX_ACK_SET(); // reset the MCM - Hal_delay(500); - EAP_RX_INT_CLR(); - EAP_TX_INT_CLR(); - EAP_TX_ACK_CLR(); - EAP_RX_INT_ENABLE(); - Em_Hal_unlock(key); -} - -void Em_Hal_startSend() { - EAP_TX_BUF = Em_Message_startTx(); -} - -void Em_Hal_unlock(uint8_t key) { - _set_interrupt_state(key); -} - -void Em_Hal_watchOff(void) { - UART_WATCH_DISABLE(); -} - -void Em_Hal_watchOn(void) { - UART_WATCH_ENABLE(); -} - - -/* -------- INTERNAL FUNCTIONS -------- */ - -static void gpioHandler(uint8_t id) { - uint16_t mask = BIT3 << id; - - Hal_delay(GPIO_DEBOUNCE_MSECS); - if (GPIO_LOW(mask) && appGpioHandler) - appGpioHandler(id); - GPIO_ENABLE(mask); -} - -static void postEvent(uint8_t handlerId) { - uint8_t key = Em_Hal_lock(); - handlerEvents |= 1 << handlerId; - Em_Hal_unlock(key); -} - -/* -------- INTERRUPT SERVICE ROUTINES -------- */ - -#ifdef __GNUC__ - __attribute__((interrupt(PORT1_VECTOR))) -#endif -#ifdef __TI_COMPILER_VERSION__ - #pragma vector=PORT1_VECTOR -#endif -INTERRUPT void gpioIsr(void) { - uint8_t id; - uint16_t mask; - - for (id = 0, mask = BIT3; id < 3; id++, mask <<= 1) - if (GPIO_FIRED(mask)) { - postEvent(id); - GPIO_DISABLE(mask); - } - WAKEUP(); -} - -#ifdef __GNUC__ - __attribute__((interrupt(EAP_RX_VECTOR))) -#endif -#ifdef __TI_COMPILER_VERSION__ - #pragma vector=EAP_RX_VECTOR -#endif -INTERRUPT void rxIsr(void) { - uint8_t b = EAP_RX_BUF; - Em_Message_startRx(); - EAP_RX_ACK_CLR(); - EAP_RX_ACK_SET(); - if (Em_Message_addByte(b)) { - postEvent(DISPATCH_HANDLER_ID); - } - WAKEUP(); -} - -#ifdef __GNUC__ - __attribute__((interrupt(TIMER1_A0_VECTOR))) -#endif -#ifdef __TI_COMPILER_VERSION__ - #pragma vector=TIMER1_A0_VECTOR -#endif -INTERRUPT void timerIsr(void) { - TA1CCR0 += clockTick; - postEvent(TICK_HANDLER_ID); - WAKEUP(); -} - -#ifdef __GNUC__ - __attribute__((interrupt(EAP_TX_ACK_VECTOR))) -#endif -#ifdef __TI_COMPILER_VERSION__ - #pragma vector=EAP_TX_ACK_VECTOR -#endif -INTERRUPT void txAckIsr(void) { - if (EAP_TX_ACK_TST()) { - uint8_t b; - if (Em_Message_getByte(&b)) { - EAP_TX_BUF = b; - } - EAP_TX_ACK_CLR(); - } - WAKEUP(); -} - -#ifdef __GNUC__ - __attribute__((interrupt(TIMER1_A1_VECTOR))) -#endif -#ifdef __TI_COMPILER_VERSION__ - #pragma vector=TIMER1_A1_VECTOR -#endif -INTERRUPT void uartWatchdogIsr(void) { - switch (TA1IV) { - case 2: // CCR1 - UART_WATCH_DISABLE(); - Em_Message_restart(); - WAKEUP(); - break; - } -} diff --git a/Hal/Hal.h b/Hal/Hal.h deleted file mode 100644 index 0d57348..0000000 --- a/Hal/Hal.h +++ /dev/null @@ -1,301 +0,0 @@ -/** - * Hal.h -- HAL Interface Definitions - * - * This example HAL is intentionally simple. The implementation is limited to: - * - * BUTTON -- a single button that when pressed will cause an interrupt. - * DEBUG -- two debug GPIOs that are available as outputs from the EAP and under user control. - * DELAY -- a delay routine that can delay by n milliseconds. - * INIT -- set the hardware up to its initial state - * LED -- a user LED that is available for application control. - * TICK -- a timer that can be set to interrupt every n milliseconds - * IDLE LOOP -- an event driven idle loop for controlling the EAP - * - * For information on Hal implementations for specific target hardware platforms, - * visit the http://wiki.em-hub.com/display/ED. - * - **/ - -#ifndef Hal__H -#define Hal__H - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void (*Hal_Handler)(uint8_t id); - -/** - * --------- Hal_buttonEnable --------- - * - * Enable the button interrupt and connect it to the user's buttonHandler - * - * When the button is pressed, it will cause an interrupt that will cause BUTTON event - * to be entered into the event list. Once dispatched by the idle loop, the user's - * buttonHandler will be called. - * - * Inputs: - * buttonHandler - pointer to the user's handler to be called after interrupt - * - * Returns: - * None - * - * Side effects: - * BUTTON interrupt enabled - * - **/ -extern void Hal_gpioEnable(Hal_Handler handler); -/** - * --------- Hal_connected --------- - * - * Called whenever the MCM peripheral connects to a central. - * - * Could do other things associated with connection to the central. - * - * Inputs: - * None - * - * Returns: - * None - * - **/ -extern void Hal_connected(void); -/** - * --------- Hal_debugOff --------- - * - * Turns the selected DEBUG line off. - * - * The two DEBUG lines are output GPIOs that are available to the user for - * debug purposes. - * - * Inputs: - * line - the index value of the debug line to turn off - * - * Returns: - * None - * - * Side Effects: - * DEBUG line off. - * - **/ -extern void Hal_debugOff(uint8_t line); -/** - * --------- Hal_debugOn --------- - * - * Turns the selected DEBUG line on. - * - * The two DEBUG lines are output GPIOs that are available to the user for - * debug purposes. - * - * Inputs: - * line - the index value of the debug line to turn on - * - * Returns: - * None - * - * Side Effects: - * DEBUG line on. - * - **/ -extern void Hal_debugOn(uint8_t line); -/** - * --------- Hal_debugPulse --------- - * - * Emits a pulse on the selected DEBUG line. - * - * The two DEBUG lines are output GPIOs that are available to the user for - * debug purposes. - * - * Inputs: - * line - the index value of the debug line to emit a pulse - * - * Returns: - * None - * - * Side Effects: - * DEBUG line turns on then off. - * - **/ -extern void Hal_debugPulse(uint8_t line); -/** - * --------- Hal_delay --------- - * - * Delays for the specified number of milliseconds. - * - * In this example, delay is done with CPU spinning for simplicity's sake. - * This could easily use a timer interrupt for more power savings. - * - * Inputs: - * msecs - the number of milliseconds to delay - * - * Returns: - * None - * - * Side Effects: - * None - * - **/ -extern void Hal_delay(uint16_t msecs); -/** - * --------- Hal_disconnected --------- - * - * Called whenever the MCM peripheral disconnects from a central. - * - * Could do other things associated with connection to the central. - * - * Inputs: - * None - * - * Returns: - * None - * - **/ -extern void Hal_disconnected(void); -/** - * --------- Hal_idleLoop --------- - * - * The idle loop that controls EAP operations. - * - * The hal implements an event driven "idle loop" scheduler. - * When there are no events pending, the idle loop sleeps. - * When an event happens, the idle loop wakes up, and dispatches - * to the appropriate event handler. - * - * The dispatching is done through a handlerTab that has one entry for each type of event. - * Each handlerTab entry should be a handler of type hal_handler *. - * There are currently three types of events, i.e. entries in the handlerTab: - * BUTTON_HANDLER_ID: handler to call upon a button press - * TICK_HANDLER_ID: handler to call upon a timer interrupt - * DISPATCH_HANDLER_ID: handler to call upon a received message from the MCM - * - * Inputs: - * None - * - * Returns: - * None - * - * Side Effects: - * dispatches events as they come in - * - **/ -extern void Hal_idleLoop(void); -/** - * --------- Hal_init --------- - * - * Initialize the hardware - * - * Initializes the EAP and MCM into their reset state. Should be called first. - * Sets up the clock, ports, watchdog timer, etc. - * - * - * Inputs: - * None - * - * Returns: - * None - * - * Side Effects: - * EAP and MCM in their initial state. - * - **/ -extern void Hal_init(void); -/** - * --------- Hal_ledOff --------- - * - * Turns the user LED off. - * - * Inputs: - * None - * - * Returns: - * None - * - * Side Effects: - * User LED off. - * - **/ -extern void Hal_greenLedOff(void); -extern void Hal_redLedOff(void); -/** - * --------- Hal_ledOn --------- - * - * Turns the user LED on. - * - * Inputs: - * None - * - * Returns: - * None - * - * Side Effects: - * User LED on. - * - **/ -extern void Hal_greenLedOn(void); -extern void Hal_redLedOn(void); -/** - * --------- Hal_ledRead --------- - * - * Returns the user LED state. - * - * Inputs: - * None - * - * Returns: - * Bool - (true = user LED is on, false = user LED is off) - * - * Side Effects: - * None - * - **/ -extern bool Hal_greenLedRead(void); -extern bool Hal_redLedRead(void); -/** - * --------- Hal_ledToggle --------- - * - * Toggles the user LED. - * - * Inputs: - * None - * - * Returns: - * None - * - * Side Effects: - * User LED toggles state. - * - **/ -extern void Hal_greenLedToggle(void); -extern void Hal_redLedToggle(void); -/** - * --------- Hal_tickStart --------- - * - * Sets up the timer to interrupt every msecs milliseconds and the user's tickHandler - * that will be called upon interrupt. - * - * Enable a timer interrupt every msecs ms. The interrupt will cause a TICK event - * to be entered into the event list. Once dispatched by the idle loop, the user's - * tickHandler will be called. - * - * Inputs: - * msecs - the number of milliseconds between tick interrupts - * tickHandler - the address of the user's tick handler that will be called - * - * Returns: - * None - * - * Side Effects: - * tickhandler called by the idle loop - * - **/ -extern void Hal_tickStart(uint16_t msecs, Hal_Handler Handler); -extern void Hal_tickStop(void); - -#ifdef __cplusplus -} -#endif - -#endif /* Hal__H */ diff --git a/Makefile b/Makefile deleted file mode 100644 index 88ef651..0000000 --- a/Makefile +++ /dev/null @@ -1,48 +0,0 @@ -GCCARCH = msp430 -MCU = msp430g2553 -COMMAND_PREFIX = $(GCCARCH)- -CC = $(COMMAND_PREFIX)gcc -LD = $(COMMAND_PREFIX)ld -UPLOAD = mspdebug rf2500 -EMBUILDER = em-builder - -APPNAME = Pulsecounter -MAIN = $(APPNAME)-Prog -OUTFILE = $(MAIN).out -OBJECTS = $(MAIN).o $(APPNAME).o Hal.o - -COPTS = -mmcu=$(MCU) -LDOPTS = -mmcu=$(MCU) -Wl,-Map=$(MAIN).map,--gc-sections -CFLAGS = -std=gnu99 -O2 -w -ffunction-sections -fdata-sections \ - -fpack-struct=1 -fno-strict-aliasing -fomit-frame-pointer \ - -c -g -IHal -IEm $(COPTS) - -all: $(OUTFILE) - -load: $(OUTFILE) - $(UPLOAD) "prog $(OUTFILE)" - -clean: - rm -f $(OUTFILE) $(OBJECTS) - -em-clean: clean - rm -rf Em - -$(OUTFILE): $(OBJECTS) - $(CC) -o $(OUTFILE) $^ $(LDOPTS) - -#.c.o: -# $(CC) $< -o $@ $(CFLAGS) - -$(MAIN).o: $(MAIN).c Em/$(APPNAME).c - $(CC) $< -o $@ $(CFLAGS) - -$(APPNAME).o: Em/$(APPNAME).c - $(CC) $< -o $@ $(CFLAGS) - -Hal.o: Hal/Hal.c - $(CC) $< -o $@ $(CFLAGS) - -Em/$(APPNAME).c: $(APPNAME).ems - $(EMBUILDER) -v $< - diff --git a/Pulsecounter-Prog.c b/Pulsecounter-Prog.c deleted file mode 100644 index ced5632..0000000 --- a/Pulsecounter-Prog.c +++ /dev/null @@ -1,142 +0,0 @@ -#include "Pulsecounter.h" -#include "Hal.h" - -static void gpioHandler(uint8_t id); -static void tickHandler(void); -static int32_t cold = 0; -static int32_t hot = 0; -static bool connected = false; -static bool updatable = false; - -void main() { - Hal_init(); - Hal_gpioEnable(gpioHandler); - Pulsecounter_setDeviceName("PULS-CNTR"); - Pulsecounter_start(); - Hal_idleLoop(); -} - -static void gpioHandler(uint8_t id) { - uint8_t i; - - switch (id) { - case 0: - /* Pulsecounter_accept(true); */ - updatable = true; - if (connected) { - Pulsecounter_coldTick_indicate(); - Hal_delay(100); - Pulsecounter_hotTick_indicate(); - } - Hal_greenLedOn(); - Hal_redLedOn(); - Hal_delay(10); - Hal_greenLedOff(); - Hal_redLedOff(); - Hal_tickStart(15000, tickHandler); - break; - case 1: - cold++; - if (connected) - Pulsecounter_coldTick_indicate(); - Hal_greenLedOn(); - Hal_delay(10); - Hal_greenLedOff(); - break; - case 2: - hot++; - if (connected) - Pulsecounter_hotTick_indicate(); - Hal_redLedOn(); - Hal_delay(10); - Hal_redLedOff(); - break; - default: - for (i = 0; i < 5; i++) { - Hal_greenLedOn(); - Hal_redLedOn(); - Hal_delay(10); - Hal_greenLedOff(); - Hal_redLedOff(); - Hal_delay(10); - } - } -} - -static void tickHandler(void) { - uint8_t i; - - Hal_tickStop(); - if (connected) - return; - for (i = 0; i < 3; i++) { - Hal_greenLedOn(); - Hal_delay(50); - Hal_redLedOn(); - Hal_delay(50); - Hal_redLedOff(); - Hal_delay(50); - Hal_greenLedOff(); - } - updatable = false; - /* Pulsecounter_accept(false); */ -} - -/* -------- SCHEMA CALLBACKS -------- */ - -void Pulsecounter_connectHandler(void) { - connected = true; - Hal_tickStop(); - Hal_connected(); - Hal_redLedOn(); - Hal_delay(100); - Hal_redLedOff(); - Hal_greenLedOn(); - Hal_delay(100); - Hal_greenLedOff(); -} - -void Pulsecounter_disconnectHandler(void) { - connected = false; - updatable = false; - Hal_greenLedOn(); - Hal_delay(100); - Hal_greenLedOff(); - Hal_redLedOn(); - Hal_delay(100); - Hal_redLedOff(); - /* Hal_tickStart(15000, tickHandler); */ - Hal_disconnected(); -} - -void Pulsecounter_coldTick_fetch(Pulsecounter_coldTick_t* const output) { - *output = cold; -} - -void Pulsecounter_hotTick_fetch(Pulsecounter_hotTick_t* const output) { - *output = hot; -} - -void Pulsecounter_coldSet_store(Pulsecounter_coldSet_t* const input) { - Hal_greenLedOn(); - Hal_delay(100); - Hal_greenLedOff(); - Hal_delay(100); - Hal_greenLedOn(); - Hal_delay(100); - Hal_greenLedOff(); - // if (updatable) - cold = *input; -} - -void Pulsecounter_hotSet_store(Pulsecounter_hotSet_t* const input) { - Hal_redLedOn(); - Hal_delay(100); - Hal_redLedOff(); - Hal_delay(100); - Hal_redLedOn(); - Hal_delay(100); - Hal_redLedOff(); - // if (updatable) - hot = *input; -} diff --git a/Pulsecounter.ems b/Pulsecounter.ems deleted file mode 100644 index 2eaffad..0000000 --- a/Pulsecounter.ems +++ /dev/null @@ -1,22 +0,0 @@ -version = "1.0.0"; -description = "Pulsecounter"; - -schema Pulsecounter { - - int32 coldTick { - indicator - }; - - int32 hotTick { - indicator - }; - - int32 coldSet { - writeonly - }; - - int32 hotSet { - writeonly - }; - -}; diff --git a/msp430/Hal/Hal.c b/msp430/Hal/Hal.c new file mode 100644 index 0000000..0cdcc29 --- /dev/null +++ b/msp430/Hal/Hal.c @@ -0,0 +1,439 @@ +/* + * ============ Hardware Abstraction Layer for MSP-EXP430G2 LaunchPad ============ + */ + +#include "Hal.h" +#include "Em_Message.h" + +#include + + +/* -------- INTERNAL FEATURES -------- */ + +#define GREEN_LED_CONFIG() (P1DIR |= BIT6) +#define GREEN_LED_ON() (P1OUT |= BIT6) +#define GREEN_LED_OFF() (P1OUT &= ~BIT6) +#define GREEN_LED_READ() (P1OUT & BIT6) +#define GREEN_LED_TOGGLE() (P1OUT ^= BIT6) + +#define RED_LED_CONFIG() (P1DIR |= BIT0) +#define RED_LED_ON() (P1OUT |= BIT0) +#define RED_LED_OFF() (P1OUT &= ~BIT0) +#define RED_LED_READ() (P1OUT & BIT0) +#define RED_LED_TOGGLE() (P1OUT ^= BIT0) + +#define GPIO_CONFIG(mask) (P1DIR &= ~mask, P1REN |= mask, P1OUT |= mask, P1IES |= mask); +#define GPIO_ENABLE(mask) (P1IFG &= ~mask, P1IE |= mask) +#define GPIO_DISABLE(mask) (P1IE &= ~mask, P1IFG &= ~mask) +#define GPIO_FIRED(mask) (P1IFG & mask) +#define GPIO_LOW(mask) (!(P1IN & mask)) +#define GPIO_DEBOUNCE_MSECS 100 + +#define DEBUG1_CONFIG() (P2DIR |= BIT3) +#define DEBUG1_ON() (P2OUT |= BIT3) +#define DEBUG1_OFF() (P2OUT &= ~BIT3) + +#define DEBUG2_CONFIG() (P2DIR |= BIT4) +#define DEBUG2_ON() (P2OUT |= BIT4) +#define DEBUG2_OFF() (P2OUT &= ~BIT4) + +#define EAP_RX_BUF UCA0RXBUF +#define EAP_TX_BUF UCA0TXBUF + +#define EAP_RX_VECTOR USCIAB0RX_VECTOR +#define EAP_TX_VECTOR USCIAB0TX_VECTOR +#define EAP_TX_ACK_VECTOR PORT2_VECTOR + +#define EAP_RX_ENABLE() (P1SEL |= BIT1, P1SEL2 |= BIT1) +#define EAP_RX_DISABLE() (P1SEL &= ~BIT1, P1SEL2 &= ~BIT1) +#define EAP_TX_ENABLE() (P1SEL |= BIT2, P1SEL2 |= BIT2) +#define EAP_TX_DISABLE() (P1SEL &= ~BIT2, P1SEL2 &= ~BIT2) + +#define EAP_RX_ACK_CONFIG() (P2DIR |= BIT0) +#define EAP_RX_ACK_SET() (P2OUT |= BIT0) +#define EAP_RX_ACK_CLR() (P2OUT &= ~BIT0) + +#define EAP_TX_ACK_CONFIG() (P2DIR &= ~BIT1, P2IES |= BIT1, P2IFG &= ~BIT1, P2IE |= BIT1) +#define EAP_TX_ACK_TST() (P2IFG & BIT1) +#define EAP_TX_ACK_CLR() (P2IFG &= ~BIT1) + +#define EAP_RX_INT_CLR() (IFG2 &= ~UCA0RXIFG) +#define EAP_RX_INT_ENABLE() (IE2 |= UCA0RXIE) +#define EAP_TX_INT_CLR() (IFG2 &= ~UCA0TXIFG) +#define EAP_TX_INT_DISABLE() (IE2 &= ~UCA0TXIE) +#define EAP_TX_INT_ENABLE() (IE2 |= UCA0TXIE) + +#define MCLK_TICKS_PER_MS 1000L +#define ACLK_TICKS_PER_SECOND 1500L /* was 12000L with divider /1 */ +#define UART_WATCHDOG_PERIOD (ACLK_TICKS_PER_SECOND * 250) / 1000 + +#define UART_WATCH_DISABLE() (TA1CCTL1 = 0) // Turn off CCR1 Interrupt +#define UART_WATCH_ENABLE() (TA1CCR1 = TA1R + UART_WATCHDOG_PERIOD, TA1CCTL1 = CCIE) // Set CCR1, and Enable CCR1 Interrupt + +#ifdef __GNUC__ +#define DINT() __disable_interrupt() +#define EINT() __enable_interrupt() +#define INTERRUPT +#define SLEEP() _BIS_SR(LPM3_bits + GIE) +#define WAKEUP() _BIC_SR_IRQ(LPM3_bits) +#endif + +#ifdef __TI_COMPILER_VERSION__ +#define DINT() (_disable_interrupt()) +#define EINT() (_enable_interrupt()) +#define INTERRUPT interrupt +#define SLEEP() (__bis_SR_register(LPM3_bits + GIE)) +#define WAKEUP() (__bic_SR_register_on_exit(LPM3_bits)) +#endif + +#define NUM_HANDLERS 5 + +#define EVENT3_HANDLER_ID 0 +#define EVENT4_HANDLER_ID 1 +#define EVENT5_HANDLER_ID 2 +#define TICK_HANDLER_ID 3 +#define DISPATCH_HANDLER_ID 4 + +static void gpioHandler(uint8_t id); +static void postEvent(uint8_t handlerId); + +static Hal_Handler appGpioHandler; +static volatile uint16_t handlerEvents = 0; +static uint16_t clockTick = 0; +static Hal_Handler handlerTab[NUM_HANDLERS]; + + +/* -------- APP-HAL INTERFACE -------- */ + +void Hal_gpioEnable(Hal_Handler handler) { + uint8_t id; + uint16_t mask; + + for (id = 0, mask = BIT3; id < 3; id++, mask <<= 1) { + handlerTab[id] = gpioHandler; + appGpioHandler = handler; + (P1DIR &= ~mask, P1REN |= mask, P1OUT |= mask, P1IES |= mask); + Hal_delay(100); + (P1IFG &= ~mask, P1IE |= mask); + } +} + +void Hal_connected(void) { +} + +void Hal_debugOn(uint8_t line) { + switch (line) { + case 1: + DEBUG1_ON(); + break; + case 2: + DEBUG2_ON(); + } +} + +void Hal_debugOff(uint8_t line) { + switch (line) { + case 1: + DEBUG1_OFF(); + break; + case 2: + DEBUG2_OFF(); + } +} + +void Hal_debugPulse(uint8_t line) { + switch (line) { + case 1: + DEBUG1_ON(); + DEBUG1_OFF(); + break; + case 2: + DEBUG2_ON(); + DEBUG2_OFF(); + } +} + +void Hal_delay(uint16_t msecs) { + while (msecs--) { + __delay_cycles(MCLK_TICKS_PER_MS); + } +} + +void Hal_disconnected(void) { +} + +void Hal_init(void) { + + /* setup clocks */ + + WDTCTL = WDTPW + WDTHOLD; + /* MCLK = DCOCLK */ + /* MCLK divider = /1 */ + /* SMCLK divider = /1 */ + BCSCTL2 = SELM_0 + DIVM_0 + DIVS_0; + if (CALBC1_1MHZ != 0xFF) { + DCOCTL = 0x00; + BCSCTL1 = CALBC1_1MHZ; /* Set DCO to 1MHz */ + DCOCTL = CALDCO_1MHZ; + } + /* XT2 is off (Not used for MCLK/SMCLK) */ + /* ACLK divider = /8 */ + BCSCTL1 |= XT2OFF + DIVA_3; + /* XT2 range = 0.4 - 1 MHz */ + /* LFXT1 range/VLO = VLOCLK (or 3-16 MHz if XTS=1) */ + /* Capacitor 6 pF */ + BCSCTL3 = XT2S_0 + LFXT1S_2 + XCAP_1; + + /* setup LEDs */ + + GREEN_LED_CONFIG(); + GREEN_LED_OFF(); + RED_LED_CONFIG(); + RED_LED_OFF(); + + /* setup debug pins */ + + DEBUG1_CONFIG(); DEBUG1_OFF(); + DEBUG2_CONFIG(); DEBUG2_OFF(); + + DEBUG1_ON(); DEBUG1_OFF(); + + /* setup TimerA1 */ + TA1CTL = TASSEL_1 + MC_2; // ACLK, Continuous mode + UART_WATCH_DISABLE(); + + /* setup UART */ + + UCA0CTL1 |= UCSWRST; + + EAP_RX_ENABLE(); + EAP_TX_ENABLE(); + + EAP_RX_ACK_CONFIG(); + EAP_RX_ACK_SET(); + + EAP_TX_ACK_CONFIG(); + + // suspend the MCM + EAP_RX_ACK_CLR(); + + UCA0CTL1 = UCSSEL_2 + UCSWRST; + UCA0MCTL = UCBRF_0 + UCBRS_6; + UCA0BR0 = 8; + UCA0CTL1 &= ~UCSWRST; + + handlerTab[DISPATCH_HANDLER_ID] = Em_Message_dispatch; +} + +void Hal_idleLoop(void) { + + EINT(); + for (;;) { + + // atomically read/clear all handlerEvents + DINT(); + uint16_t events = handlerEvents; + handlerEvents = 0; + + if (events) { // dispatch all current events + EINT(); + uint16_t mask; + uint8_t id; + for (id = 0, mask = 0x1; id < NUM_HANDLERS; id++, mask <<= 1) { + if ((events & mask) && handlerTab[id]) { + handlerTab[id](id); + } + } + } + else { // await more events + SLEEP(); + } + } +} + +void Hal_greenLedOn(void) { + GREEN_LED_ON(); +} + +void Hal_greenLedOff(void) { + GREEN_LED_OFF(); +} + +bool Hal_greenLedRead(void) { + return GREEN_LED_READ(); +} + +void Hal_greenLedToggle(void) { + GREEN_LED_TOGGLE(); +} + +void Hal_redLedOn(void) { + RED_LED_ON(); +} + +void Hal_redLedOff(void) { + RED_LED_OFF(); +} + +bool Hal_redLedRead(void) { + return RED_LED_READ(); +} + +void Hal_redLedToggle(void) { + RED_LED_TOGGLE(); +} + +void Hal_tickStart(uint16_t msecs, Hal_Handler handler) { + handlerTab[TICK_HANDLER_ID] = handler; + clockTick = (ACLK_TICKS_PER_SECOND * msecs) / 1000; + TA1CCR0 = TA1R + clockTick; // Set the CCR0 interrupt for msecs from now. + TA1CCTL0 = CCIE; // Enable the CCR0 interrupt +} + +void Hal_tickStop(void) { + handlerTab[TICK_HANDLER_ID] = 0; + TA1CCR0 = 0; + TA1CCTL0 = 0; +} + +/* -------- SRT-HAL INTERFACE -------- */ + +uint8_t Em_Hal_lock(void) { + uint8_t key = _get_interrupt_state(); + #ifdef __GNUC__ + __disable_interrupt(); + #endif + #ifdef __TI_COMPILER_VERSION__ + _disable_interrupt(); + #endif + return key; +} + +void Em_Hal_reset(void) { + uint8_t key = Em_Hal_lock(); + EAP_RX_ACK_CLR(); // suspend the MCM + Hal_delay(100); + EAP_RX_ACK_SET(); // reset the MCM + Hal_delay(500); + EAP_RX_INT_CLR(); + EAP_TX_INT_CLR(); + EAP_TX_ACK_CLR(); + EAP_RX_INT_ENABLE(); + Em_Hal_unlock(key); +} + +void Em_Hal_startSend() { + EAP_TX_BUF = Em_Message_startTx(); +} + +void Em_Hal_unlock(uint8_t key) { + _set_interrupt_state(key); +} + +void Em_Hal_watchOff(void) { + UART_WATCH_DISABLE(); +} + +void Em_Hal_watchOn(void) { + UART_WATCH_ENABLE(); +} + + +/* -------- INTERNAL FUNCTIONS -------- */ + +static void gpioHandler(uint8_t id) { + uint16_t mask = BIT3 << id; + + Hal_delay(GPIO_DEBOUNCE_MSECS); + if (GPIO_LOW(mask) && appGpioHandler) + appGpioHandler(id); + GPIO_ENABLE(mask); +} + +static void postEvent(uint8_t handlerId) { + uint8_t key = Em_Hal_lock(); + handlerEvents |= 1 << handlerId; + Em_Hal_unlock(key); +} + +/* -------- INTERRUPT SERVICE ROUTINES -------- */ + +#ifdef __GNUC__ + __attribute__((interrupt(PORT1_VECTOR))) +#endif +#ifdef __TI_COMPILER_VERSION__ + #pragma vector=PORT1_VECTOR +#endif +INTERRUPT void gpioIsr(void) { + uint8_t id; + uint16_t mask; + + for (id = 0, mask = BIT3; id < 3; id++, mask <<= 1) + if (GPIO_FIRED(mask)) { + postEvent(id); + GPIO_DISABLE(mask); + } + WAKEUP(); +} + +#ifdef __GNUC__ + __attribute__((interrupt(EAP_RX_VECTOR))) +#endif +#ifdef __TI_COMPILER_VERSION__ + #pragma vector=EAP_RX_VECTOR +#endif +INTERRUPT void rxIsr(void) { + uint8_t b = EAP_RX_BUF; + Em_Message_startRx(); + EAP_RX_ACK_CLR(); + EAP_RX_ACK_SET(); + if (Em_Message_addByte(b)) { + postEvent(DISPATCH_HANDLER_ID); + } + WAKEUP(); +} + +#ifdef __GNUC__ + __attribute__((interrupt(TIMER1_A0_VECTOR))) +#endif +#ifdef __TI_COMPILER_VERSION__ + #pragma vector=TIMER1_A0_VECTOR +#endif +INTERRUPT void timerIsr(void) { + TA1CCR0 += clockTick; + postEvent(TICK_HANDLER_ID); + WAKEUP(); +} + +#ifdef __GNUC__ + __attribute__((interrupt(EAP_TX_ACK_VECTOR))) +#endif +#ifdef __TI_COMPILER_VERSION__ + #pragma vector=EAP_TX_ACK_VECTOR +#endif +INTERRUPT void txAckIsr(void) { + if (EAP_TX_ACK_TST()) { + uint8_t b; + if (Em_Message_getByte(&b)) { + EAP_TX_BUF = b; + } + EAP_TX_ACK_CLR(); + } + WAKEUP(); +} + +#ifdef __GNUC__ + __attribute__((interrupt(TIMER1_A1_VECTOR))) +#endif +#ifdef __TI_COMPILER_VERSION__ + #pragma vector=TIMER1_A1_VECTOR +#endif +INTERRUPT void uartWatchdogIsr(void) { + switch (TA1IV) { + case 2: // CCR1 + UART_WATCH_DISABLE(); + Em_Message_restart(); + WAKEUP(); + break; + } +} diff --git a/msp430/Hal/Hal.h b/msp430/Hal/Hal.h new file mode 100644 index 0000000..0d57348 --- /dev/null +++ b/msp430/Hal/Hal.h @@ -0,0 +1,301 @@ +/** + * Hal.h -- HAL Interface Definitions + * + * This example HAL is intentionally simple. The implementation is limited to: + * + * BUTTON -- a single button that when pressed will cause an interrupt. + * DEBUG -- two debug GPIOs that are available as outputs from the EAP and under user control. + * DELAY -- a delay routine that can delay by n milliseconds. + * INIT -- set the hardware up to its initial state + * LED -- a user LED that is available for application control. + * TICK -- a timer that can be set to interrupt every n milliseconds + * IDLE LOOP -- an event driven idle loop for controlling the EAP + * + * For information on Hal implementations for specific target hardware platforms, + * visit the http://wiki.em-hub.com/display/ED. + * + **/ + +#ifndef Hal__H +#define Hal__H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*Hal_Handler)(uint8_t id); + +/** + * --------- Hal_buttonEnable --------- + * + * Enable the button interrupt and connect it to the user's buttonHandler + * + * When the button is pressed, it will cause an interrupt that will cause BUTTON event + * to be entered into the event list. Once dispatched by the idle loop, the user's + * buttonHandler will be called. + * + * Inputs: + * buttonHandler - pointer to the user's handler to be called after interrupt + * + * Returns: + * None + * + * Side effects: + * BUTTON interrupt enabled + * + **/ +extern void Hal_gpioEnable(Hal_Handler handler); +/** + * --------- Hal_connected --------- + * + * Called whenever the MCM peripheral connects to a central. + * + * Could do other things associated with connection to the central. + * + * Inputs: + * None + * + * Returns: + * None + * + **/ +extern void Hal_connected(void); +/** + * --------- Hal_debugOff --------- + * + * Turns the selected DEBUG line off. + * + * The two DEBUG lines are output GPIOs that are available to the user for + * debug purposes. + * + * Inputs: + * line - the index value of the debug line to turn off + * + * Returns: + * None + * + * Side Effects: + * DEBUG line off. + * + **/ +extern void Hal_debugOff(uint8_t line); +/** + * --------- Hal_debugOn --------- + * + * Turns the selected DEBUG line on. + * + * The two DEBUG lines are output GPIOs that are available to the user for + * debug purposes. + * + * Inputs: + * line - the index value of the debug line to turn on + * + * Returns: + * None + * + * Side Effects: + * DEBUG line on. + * + **/ +extern void Hal_debugOn(uint8_t line); +/** + * --------- Hal_debugPulse --------- + * + * Emits a pulse on the selected DEBUG line. + * + * The two DEBUG lines are output GPIOs that are available to the user for + * debug purposes. + * + * Inputs: + * line - the index value of the debug line to emit a pulse + * + * Returns: + * None + * + * Side Effects: + * DEBUG line turns on then off. + * + **/ +extern void Hal_debugPulse(uint8_t line); +/** + * --------- Hal_delay --------- + * + * Delays for the specified number of milliseconds. + * + * In this example, delay is done with CPU spinning for simplicity's sake. + * This could easily use a timer interrupt for more power savings. + * + * Inputs: + * msecs - the number of milliseconds to delay + * + * Returns: + * None + * + * Side Effects: + * None + * + **/ +extern void Hal_delay(uint16_t msecs); +/** + * --------- Hal_disconnected --------- + * + * Called whenever the MCM peripheral disconnects from a central. + * + * Could do other things associated with connection to the central. + * + * Inputs: + * None + * + * Returns: + * None + * + **/ +extern void Hal_disconnected(void); +/** + * --------- Hal_idleLoop --------- + * + * The idle loop that controls EAP operations. + * + * The hal implements an event driven "idle loop" scheduler. + * When there are no events pending, the idle loop sleeps. + * When an event happens, the idle loop wakes up, and dispatches + * to the appropriate event handler. + * + * The dispatching is done through a handlerTab that has one entry for each type of event. + * Each handlerTab entry should be a handler of type hal_handler *. + * There are currently three types of events, i.e. entries in the handlerTab: + * BUTTON_HANDLER_ID: handler to call upon a button press + * TICK_HANDLER_ID: handler to call upon a timer interrupt + * DISPATCH_HANDLER_ID: handler to call upon a received message from the MCM + * + * Inputs: + * None + * + * Returns: + * None + * + * Side Effects: + * dispatches events as they come in + * + **/ +extern void Hal_idleLoop(void); +/** + * --------- Hal_init --------- + * + * Initialize the hardware + * + * Initializes the EAP and MCM into their reset state. Should be called first. + * Sets up the clock, ports, watchdog timer, etc. + * + * + * Inputs: + * None + * + * Returns: + * None + * + * Side Effects: + * EAP and MCM in their initial state. + * + **/ +extern void Hal_init(void); +/** + * --------- Hal_ledOff --------- + * + * Turns the user LED off. + * + * Inputs: + * None + * + * Returns: + * None + * + * Side Effects: + * User LED off. + * + **/ +extern void Hal_greenLedOff(void); +extern void Hal_redLedOff(void); +/** + * --------- Hal_ledOn --------- + * + * Turns the user LED on. + * + * Inputs: + * None + * + * Returns: + * None + * + * Side Effects: + * User LED on. + * + **/ +extern void Hal_greenLedOn(void); +extern void Hal_redLedOn(void); +/** + * --------- Hal_ledRead --------- + * + * Returns the user LED state. + * + * Inputs: + * None + * + * Returns: + * Bool - (true = user LED is on, false = user LED is off) + * + * Side Effects: + * None + * + **/ +extern bool Hal_greenLedRead(void); +extern bool Hal_redLedRead(void); +/** + * --------- Hal_ledToggle --------- + * + * Toggles the user LED. + * + * Inputs: + * None + * + * Returns: + * None + * + * Side Effects: + * User LED toggles state. + * + **/ +extern void Hal_greenLedToggle(void); +extern void Hal_redLedToggle(void); +/** + * --------- Hal_tickStart --------- + * + * Sets up the timer to interrupt every msecs milliseconds and the user's tickHandler + * that will be called upon interrupt. + * + * Enable a timer interrupt every msecs ms. The interrupt will cause a TICK event + * to be entered into the event list. Once dispatched by the idle loop, the user's + * tickHandler will be called. + * + * Inputs: + * msecs - the number of milliseconds between tick interrupts + * tickHandler - the address of the user's tick handler that will be called + * + * Returns: + * None + * + * Side Effects: + * tickhandler called by the idle loop + * + **/ +extern void Hal_tickStart(uint16_t msecs, Hal_Handler Handler); +extern void Hal_tickStop(void); + +#ifdef __cplusplus +} +#endif + +#endif /* Hal__H */ diff --git a/msp430/Makefile b/msp430/Makefile new file mode 100644 index 0000000..88ef651 --- /dev/null +++ b/msp430/Makefile @@ -0,0 +1,48 @@ +GCCARCH = msp430 +MCU = msp430g2553 +COMMAND_PREFIX = $(GCCARCH)- +CC = $(COMMAND_PREFIX)gcc +LD = $(COMMAND_PREFIX)ld +UPLOAD = mspdebug rf2500 +EMBUILDER = em-builder + +APPNAME = Pulsecounter +MAIN = $(APPNAME)-Prog +OUTFILE = $(MAIN).out +OBJECTS = $(MAIN).o $(APPNAME).o Hal.o + +COPTS = -mmcu=$(MCU) +LDOPTS = -mmcu=$(MCU) -Wl,-Map=$(MAIN).map,--gc-sections +CFLAGS = -std=gnu99 -O2 -w -ffunction-sections -fdata-sections \ + -fpack-struct=1 -fno-strict-aliasing -fomit-frame-pointer \ + -c -g -IHal -IEm $(COPTS) + +all: $(OUTFILE) + +load: $(OUTFILE) + $(UPLOAD) "prog $(OUTFILE)" + +clean: + rm -f $(OUTFILE) $(OBJECTS) + +em-clean: clean + rm -rf Em + +$(OUTFILE): $(OBJECTS) + $(CC) -o $(OUTFILE) $^ $(LDOPTS) + +#.c.o: +# $(CC) $< -o $@ $(CFLAGS) + +$(MAIN).o: $(MAIN).c Em/$(APPNAME).c + $(CC) $< -o $@ $(CFLAGS) + +$(APPNAME).o: Em/$(APPNAME).c + $(CC) $< -o $@ $(CFLAGS) + +Hal.o: Hal/Hal.c + $(CC) $< -o $@ $(CFLAGS) + +Em/$(APPNAME).c: $(APPNAME).ems + $(EMBUILDER) -v $< + diff --git a/msp430/Pulsecounter-Prog.c b/msp430/Pulsecounter-Prog.c new file mode 100644 index 0000000..ced5632 --- /dev/null +++ b/msp430/Pulsecounter-Prog.c @@ -0,0 +1,142 @@ +#include "Pulsecounter.h" +#include "Hal.h" + +static void gpioHandler(uint8_t id); +static void tickHandler(void); +static int32_t cold = 0; +static int32_t hot = 0; +static bool connected = false; +static bool updatable = false; + +void main() { + Hal_init(); + Hal_gpioEnable(gpioHandler); + Pulsecounter_setDeviceName("PULS-CNTR"); + Pulsecounter_start(); + Hal_idleLoop(); +} + +static void gpioHandler(uint8_t id) { + uint8_t i; + + switch (id) { + case 0: + /* Pulsecounter_accept(true); */ + updatable = true; + if (connected) { + Pulsecounter_coldTick_indicate(); + Hal_delay(100); + Pulsecounter_hotTick_indicate(); + } + Hal_greenLedOn(); + Hal_redLedOn(); + Hal_delay(10); + Hal_greenLedOff(); + Hal_redLedOff(); + Hal_tickStart(15000, tickHandler); + break; + case 1: + cold++; + if (connected) + Pulsecounter_coldTick_indicate(); + Hal_greenLedOn(); + Hal_delay(10); + Hal_greenLedOff(); + break; + case 2: + hot++; + if (connected) + Pulsecounter_hotTick_indicate(); + Hal_redLedOn(); + Hal_delay(10); + Hal_redLedOff(); + break; + default: + for (i = 0; i < 5; i++) { + Hal_greenLedOn(); + Hal_redLedOn(); + Hal_delay(10); + Hal_greenLedOff(); + Hal_redLedOff(); + Hal_delay(10); + } + } +} + +static void tickHandler(void) { + uint8_t i; + + Hal_tickStop(); + if (connected) + return; + for (i = 0; i < 3; i++) { + Hal_greenLedOn(); + Hal_delay(50); + Hal_redLedOn(); + Hal_delay(50); + Hal_redLedOff(); + Hal_delay(50); + Hal_greenLedOff(); + } + updatable = false; + /* Pulsecounter_accept(false); */ +} + +/* -------- SCHEMA CALLBACKS -------- */ + +void Pulsecounter_connectHandler(void) { + connected = true; + Hal_tickStop(); + Hal_connected(); + Hal_redLedOn(); + Hal_delay(100); + Hal_redLedOff(); + Hal_greenLedOn(); + Hal_delay(100); + Hal_greenLedOff(); +} + +void Pulsecounter_disconnectHandler(void) { + connected = false; + updatable = false; + Hal_greenLedOn(); + Hal_delay(100); + Hal_greenLedOff(); + Hal_redLedOn(); + Hal_delay(100); + Hal_redLedOff(); + /* Hal_tickStart(15000, tickHandler); */ + Hal_disconnected(); +} + +void Pulsecounter_coldTick_fetch(Pulsecounter_coldTick_t* const output) { + *output = cold; +} + +void Pulsecounter_hotTick_fetch(Pulsecounter_hotTick_t* const output) { + *output = hot; +} + +void Pulsecounter_coldSet_store(Pulsecounter_coldSet_t* const input) { + Hal_greenLedOn(); + Hal_delay(100); + Hal_greenLedOff(); + Hal_delay(100); + Hal_greenLedOn(); + Hal_delay(100); + Hal_greenLedOff(); + // if (updatable) + cold = *input; +} + +void Pulsecounter_hotSet_store(Pulsecounter_hotSet_t* const input) { + Hal_redLedOn(); + Hal_delay(100); + Hal_redLedOff(); + Hal_delay(100); + Hal_redLedOn(); + Hal_delay(100); + Hal_redLedOff(); + // if (updatable) + hot = *input; +} diff --git a/msp430/Pulsecounter.ems b/msp430/Pulsecounter.ems new file mode 100644 index 0000000..2eaffad --- /dev/null +++ b/msp430/Pulsecounter.ems @@ -0,0 +1,22 @@ +version = "1.0.0"; +description = "Pulsecounter"; + +schema Pulsecounter { + + int32 coldTick { + indicator + }; + + int32 hotTick { + indicator + }; + + int32 coldSet { + writeonly + }; + + int32 hotSet { + writeonly + }; + +};