main.c 4.32 KB
/*
 * ============ Platform Configuration ============
 */

#include <msp430.h>

#define LED_ON()                (P1OUT |= BIT6)
#define LED_OFF()               (P1OUT &= ~BIT6)
#define LED_READ()              (P1OUT & BIT6)
#define LED_TOGGLE()            (P1OUT ^= BIT6)

#define CONNECTED_LED_ON()      (P1OUT |= BIT0)
#define CONNECTED_LED_OFF()     (P1OUT &= ~BIT0)

#define EAP_RX_BUF              UCA0RXBUF
#define EAP_TX_BUF              UCA0TXBUF

#define EAP_RX_VECTOR           USCIAB0RX_VECTOR
#define EAP_TX_VECTOR           PORT2_VECTOR

#define EAP_RX_ACK_CONFIG()     (P2DIR |= BIT0)
#define EAP_RX_ACK_SET()        (P2OUT |= BIT0)
#define EAP_RX_ACK_CLR()        (P2OUT &= ~BIT0)

#define EAP_TX_INT_CONFIG()     (P2DIR &= ~BIT1, P2IES |= BIT1, P2IFG &= BIT1, P2IE |= BIT1)
#define EAP_TX_INT_TST()        (P2IFG & BIT1)
#define EAP_TX_INT_CLR()        (P2IFG &= ~BIT1)

void init(void) {
    
    WDTCTL = WDTPW + WDTHOLD;
    BCSCTL2 = SELM_0 + DIVM_0 + DIVS_0;
    if (CALBC1_1MHZ != 0xFF) {
        DCOCTL = 0x00;
        BCSCTL1 = CALBC1_1MHZ;      /* Set DCO to 1MHz */
        DCOCTL = CALDCO_1MHZ;
    }
    BCSCTL1 |= XT2OFF + DIVA_0;
    BCSCTL3 = XT2S_0 + LFXT1S_2 + XCAP_1;

    P1DIR |= BIT0;  /* LED */
    LED_OFF();
    P1DIR |= BIT6;  /* CONNECTED_LED */
    CONNECTED_LED_OFF();

    UCA0CTL1 |= UCSWRST;

    P1SEL |= BIT1 + BIT2;
    P1SEL2 |= BIT1 + BIT2;
    
    EAP_RX_ACK_CONFIG();
    EAP_RX_ACK_SET();
    
    EAP_TX_INT_CONFIG();

    UCA0CTL1 = UCSSEL_2 + UCSWRST;
    UCA0MCTL = UCBRF_0 + UCBRS_6;
    UCA0BR0 = 8;
    UCA0CTL1 &= ~UCSWRST;
    
    IFG2 &= ~(UCA0RXIFG);
    IE2 |= UCA0RXIE;

    TA1CCTL0 = CM_0 + CCIS_0 + OUTMOD_0 + CCIE;
    TA1CCR0 = 1200;
    TA1CTL = TASSEL_1 + ID_0 + MC_1;

    __enable_interrupt();
}

/*
 * ============ Serial Driver ============
 */

#include <Em_Message.h>

__attribute__((interrupt(EAP_RX_VECTOR)))
static void rxHandler(void) {
    uint8_t b = EAP_RX_BUF;
    if (Em_Message_addByte(b)) {
        Em_Message_dispatch();
    }
    EAP_RX_ACK_CLR();
    EAP_RX_ACK_SET();
}

__attribute__((interrupt(EAP_TX_VECTOR)))
static void txHandler(void) {
    if (EAP_TX_INT_TST()) {
        uint8_t b;
        if (Em_Message_getByte(&b)) {
            EAP_TX_BUF = b;
        }
        EAP_TX_INT_CLR();
    }
}

void Em_Message_startSend() {
    uint8_t b;
    if (Em_Message_getByte(&b)) {
        UCA0TXBUF = b;
    }
}

uint8_t Em_Message_lock() {
    uint8_t key;
    asm ("MOV r2, %0": "=r" (key));
    key &= 0x8;
    asm ("DINT");
    return key;
}

void Em_Message_unlock(uint8_t key) {
    if (key) {
        asm ("EINT");
    }
    else {
        asm ("DINT");
    }
}

/*
 * ============ Application Program ============
 */

#include <Blinker.h>

#define COUNT_DEFAULT 5

volatile Blinker_cmd_t cmdRes = Blinker_STOP_CMD;
volatile Blinker_count_t countRes = COUNT_DEFAULT;
volatile Blinker_delay_t delayRes = Blinker_delay_min;

volatile Blinker_count_t curCount;
volatile Blinker_delay_t curTime;

__attribute__((interrupt(TIMER1_A0_VECTOR)))
void tickHandler(void) {
    if (cmdRes == Blinker_STOP_CMD) {
        return;
    }
    if (curTime < delayRes) {
        curTime += Blinker_delay_step;
        return;
    }
    else {
        curTime = 0;
    }
    if (curCount-- > 0) {
        LED_TOGGLE();
    }
    else {
        cmdRes = Blinker_STOP_CMD;
        LED_OFF();
    }
    Blinker_ledState_indicate();
}

int main(int argc, char *argv[]) {
    volatile int dummy = 0;
    init();
    Blinker_run();
    while (dummy == 0) {
        /* idle */
    }
    return 0;
}

void Blinker_connectHandler(void) {
    CONNECTED_LED_ON();
}

void Blinker_disconnectHandler(void) {
    CONNECTED_LED_OFF();
}

void Blinker_cmd_store(Blinker_cmd_t* input) {
    cmdRes = *input;
    switch (cmdRes) {
        case Blinker_START_CMD:
            curCount = countRes * 2;
            curTime = 0;
            break;
        case Blinker_STOP_CMD:
            LED_OFF();
            break;
    }
}

void Blinker_count_fetch(Blinker_count_t* output) {
    *output = countRes;
}

void Blinker_count_store(Blinker_count_t* input) {
    countRes = *input;
}

void Blinker_delay_fetch(Blinker_delay_t* output) {
    *output = delayRes;
}

void Blinker_delay_store(Blinker_delay_t* input) {
    delayRes = *input;
}

void Blinker_ledState_fetch(Blinker_ledState_t* output) {
    *output = LED_READ() ? Blinker_LED_ON : Blinker_LED_OFF;
}