// // BlimpBot // CSE 466 final project // Josh Green, Baron Oldenburg, Henry Baba-Weiss // #include "bsp.h" #include "mrfi.h" #include "nwk_types.h" #include "nwk_api.h" #include "bsp_leds.h" #include "bsp_buttons.h" #include "../virtual_com_cmds.h" #include "app_remap_led.h" // Uncomment to display the menu as a CLI over UART //#define USE_CLI /* for when I want to debug the link, make the base station wait */ //#define debuglink #define SPIN_ABOUT_A_SECOND NWK_DELAY(1000) /* Rx callback handler */ static uint8_t sRxCallback(linkID_t); /* set up the static link */ static void setupLink(void); /* UART RX ISR */ __interrupt void USCI0RX_ISR(void); /* terminal bootup splash text */ const char splashart[] = "\r\n ,_~\"\"\"~-,\r\n .---------,\r\n .\'------(_)--`\r\n ,--------------`.\r\n |===============|\r\n \'---------------;\r\n `,-----------,\'\r\n .---------,\r\n ~.___.~\r\n\r\n\r\n"; const char menu[] = "WELCOME TO THE DEATH STAR CONTROL MENU\r\n (a)ctivate the blimp\r\n (d)eactivate the blimp\r\n control (m)otors\r\n read IR pro(x)imity sensors\r\n read (e)-field sensors\r\n read (c)ompass\r\n read (b)attery state\r\n"; /* link ID */ static linkID_t sLinkID1 = 0; /* command buffer */ static char cmdbuf[10] = {0}; static int cmdbufsize = 0; static char UART_MODE = 0; static char motor_buf[6] = {0}; static int motor_index = 0; static char motor_dir = 0; void main (void) { BSP_Init(); /* initialize UART */ COM_Init(); #ifdef USE_CLI TXString((char *)splashart, sizeof splashart); TXString((char *)menu, sizeof menu ); #endif /* This call will fail because the join will fail since there is no Access Point * in this scenario. But we don't care -- just use the default link token later. * We supply a callback pointer to handle the message returned by the peer. */ SMPL_Init(sRxCallback); /* set up static radio link. */ setupLink(); #ifdef debuglink /* wait for a button press. */ do { if (BSP_BUTTON1() || BSP_BUTTON2()) { break; } } while (1); #endif // main program loop while (1) { if (BSP_LED1_IS_ON()) BSP_TOGGLE_LED1(); if (BSP_LED2_IS_ON()) BSP_TOGGLE_LED2(); // spin until we get a command (UART ISR will fire) if (cmdbufsize > 0) { #ifdef USE_CLI TXString("sending packet\r\n", 16); #endif // transmit (wireless) packet based on command while (SMPL_SendOpt(sLinkID1, (uint8_t *)cmdbuf, cmdbufsize, SMPL_TXOPTION_ACKREQ) != SMPL_SUCCESS); #ifdef USE_CLI TXString("send successful\r\n", 17); TXString((char *)menu, sizeof menu); #endif UART_MODE = 0; cmdbufsize = 0; } __delay_cycles(1000); } } static void setupLink() { addr_t blimpAddr; blimpAddr.addr[0] = 0x42; blimpAddr.addr[1] = 0x42; blimpAddr.addr[2] = 0x42; blimpAddr.addr[3] = 0x42; while (SMPL_Commission(&blimpAddr, 0x3E, 0x3E, &sLinkID1) != SMPL_SUCCESS) ; /* turn on RX. default is RX off. */ SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXON, 0 ); } /* handle received messages. */ static uint8_t sRxCallback(linkID_t port) { uint8_t msg[10], len; /* is the callback for the link ID we want to handle? */ if (port == sLinkID1) { /* yes. go get the frame. we know this call will succeed. */ if ((SMPL_Receive(sLinkID1, msg, &len) == SMPL_SUCCESS) && len) { if (!BSP_LED1_IS_ON()) BSP_TOGGLE_LED1(); switch ((packetType)*msg) { case IR_RESPONSE: // unsafe --------- make better msg[len-1] = '\n'; TXString((char *)msg, len); break; case EFIELD_RESPONSE: //TXString("efield response\r\n", 17); break; case COMPASS_RESPONSE: //TXString("compass response\r\n", 18); break; case BATTERY_RESPONSE: //TXString("battery response\r\n", 18); break; case ACTIVATE_RESPONSE: //TXString("activate response\r\n", 19); break; case DEACTIVATE_RESPONSE: //TXString("deactivate response\r\n", 21); break; default: return 0; } return 1; } } /* keep frame for later handling. */ return 0; } /*------------------------------------------------------------------------------ * USCIA interrupt service routine ------------------------------------------------------------------------------*/ #pragma vector=USCIAB0RX_VECTOR __interrupt void USCI0RX_ISR(void) { // Turn on red LED to indicate we've received a command over UART if (!BSP_LED2_IS_ON()) BSP_TOGGLE_LED2(); char rx = UCA0RXBUF; cmdbufsize = 0; if (UART_MODE == 0) { switch (rx) { case 'm': // control motors UART_MODE = 'm'; break; case 'x': // read IR sensors UART_MODE = 'x'; break; case 'a': // toggle altitude control *cmdbuf = TOGGLE_AUTOHEIGHT_RESPONSE; cmdbufsize++; break; case 's': // toggle altitude control *cmdbuf = SET_AUTOHEIGHT_RESPONSE; cmdbufsize++; break; case 'p': // toggle altitude control *cmdbuf = SONG_PLAY_ONCE_RESPONSE; cmdbufsize++; break; case 'L': // toggle altitude control *cmdbuf = SONG_TOGGLE_LOOP_RESPONSE; cmdbufsize++; break; /*case 'e': // set elevation UART_MODE = 'e'; break;*/ case '+': // activate the blimp *cmdbuf = ACTIVATE_RESPONSE; cmdbufsize++; break; case '-': // deactivate the blimp *cmdbuf = DEACTIVATE_RESPONSE; cmdbufsize++; break; //////////// not used //////////////// case 'E': // read E-field sensors *cmdbuf = EFIELD_RESPONSE; cmdbufsize++; break; case 'c': // read compass *cmdbuf = COMPASS_RESPONSE; cmdbufsize++; break; case 'b': // read battery state *cmdbuf = BATTERY_RESPONSE; cmdbufsize++; break; default: TXString("invalid command\r\n\r\n", 18); //TXString((char *)menu, sizeof menu); return; } } else if (UART_MODE == 'm') { // control motors if (motor_index == 0) { if (rx == 'z') { cmdbuf[0] = MOTOR_RESPONSE; cmdbuf[1] = rx; cmdbufsize = 2; UART_MODE = '!'; motor_index = 0; motor_dir = 0; } else { motor_dir = rx; motor_index++; } } else { //motor_buf[motor_index-1] = rx; //motor_index++; cmdbuf[0] = MOTOR_RESPONSE; cmdbuf[1] = motor_dir; cmdbuf[2] = rx; cmdbufsize = 3;//motor_index+1; // index includes motor_dir, +1 for MOTOR_RESPONSE UART_MODE = '!'; motor_index = 0; motor_dir = 0; } } else if (UART_MODE == 'x') { // read IR sensors cmdbuf[0] = IR_RESPONSE; cmdbuf[1] = rx; cmdbufsize = 2; UART_MODE = 0; } /*else if(UART_MODE == 'a') { elevation_buf[elevation_index] = rx; elevation_index++; if (rx == '\n') { cmdbuf[0] = SET_ALTITUDE_RESPONSE; int k; for(k = 0; k < elevation_index; k++) { cmdbuf[k+1] = elevation_buf[k]; } cmdbufsize = elevation_index + 1; elevation_index = 0; UART_MODE = 0; } }*/ #ifdef USE_CLI TXString("enqueued command\r\n", 18); #endif }