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

#include <msp430.h> 

#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 + BIT6;  /* LED */
    P1OUT &= ~BIT0;

    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;

    __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");
    }
}

/*
 * Extra code and interrupts
 */

void led0_toggle(void)
{
	P1OUT ^= BIT0;
}

void led1_toggle(void)
{
	P1OUT ^= BIT6;
}

void led0_on(void)
{
	P1OUT |= BIT0;
}

void led0_off(void)
{
	P1OUT &= ~BIT0;
}

void led1_on(void)
{
	P1OUT |= BIT6;
}

void led1_off(void)
{
	P1OUT &= ~BIT6;
}

__attribute__((interrupt(TIMER0_A0_VECTOR)))
static void Timer_A (void)
{
	led0_toggle();					// Toggle LED
	//led1_toggle();
}

void initTimer(void)
{
	CCTL0 = CCIE;						// CCR0 interrupt enabled
	CCR0 = 2048;						// 32kHz/8/4096 -> 1 sec
	TACTL = TASSEL_1 + ID_3 + MC_1;		// ACLK, /8, upmode
	led1_off();
}

void stopTimer(void)
{
	CCTL0 ^= CCTL0 ;
}

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

#include <DUREX.h>
#include <string.h>

DUREX_numBytes_t			numBytes = 0;
DUREX_data_t				data = "";
DUREX_numPackets_t 			numPackets = 0;
DUREX_messageAvailable_t 	messageAvailable = 0;
uint8_t						lastMessageAck = 1;

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

void DUREX_connectHandler(void)
{
	stopTimer();
	led0_on();
	led1_off();
}

void DUREX_disconnectHandler(void)
{
	led0_off();
	led1_off();
    initTimer();
}

void DUREX_numBytes_fetch(DUREX_numBytes_t* const output)
{
    *output = numBytes;
}

void DUREX_numBytes_store(DUREX_numBytes_t* const input)
{
	numBytes = *input;
}

void DUREX_data_fetch(DUREX_data_t* const output)
{
	memcpy(output,data,numBytes);
}

void DUREX_data_store(DUREX_data_t* const input)
{
	memcpy(data,input,numBytes);
}

void DUREX_numPackets_fetch(DUREX_numPackets_t* const output)
{
	*output = numPackets;
}

void DUREX_numPackets_store(DUREX_numPackets_t* const input)
{
    numPackets = *input;
}

void DUREX_messageAvailable_fetch(DUREX_messageAvailable_t* const output)
{
    *output = messageAvailable;
}

void DUREX_messageAvailable_store(DUREX_messageAvailable_t* const input)
{
	messageAvailable = *input;
	if(messageAvailable == DUREX_TRUE)
	{
		led1_on();
		lastMessageAck = 0;
		messageAvailable = DUREX_FALSE;
		DUREX_messageAvailable_indicate();
		memcpy(data,"ACK",4);
		numPackets = 1;
		numBytes = 4;
		messageAvailable = DUREX_TRUE;
		DUREX_messageAvailable_indicate();
	}
	else if(messageAvailable == DUREX_FALSE)
	{
		led1_off();
		lastMessageAck = 1;
	}
}