/* * ============ Platform Configuration ============ */ #include #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 __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 #include 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; } }