/* * File: player.c * Author: Nick Falco * Brandon Smith * Comments: Functions as a lpayer module as descirbed in attached documentation * receieves commands over UART to enter different states which change how the * I/O operates * * Revision history: Last Updated 12/13/15 */ // ***************************************************************************** // Section: Included Files // ***************************************************************************** #include "config.h" #include "tft_master.h" #include "tft_gfx.h" #include #include "adc_intf.h" //math library #include // threading library #include "pt_cornell_1_2.h" // standard library #include #include #include // ***************************************************************************** // Section: Global Data Definitions // ***************************************************************************** // config.h sets 40 MHz #define SYS_FREQ 40000000 #define ARRAY_SIZE 50 #define RPM5_TICKS 480000000 //seven segment display values #define TABLESIZE 10 uint8_t segmentTable[TABLESIZE] = {0xBE, 0x30, 0xAD, 0xB9, 0x33, 0x9B, 0x1F, 0xB0, 0xBF, 0xB3}; // UART command structure variables int target_address = 99; int sender_address = 99; char command = 'x'; int value = 0; //identification variables uint32_t playerID = 2; //score volatile int currentScore = 0; //the current state the controller is in volatile uint8_t currentState = 0; //State definitions #define NOT_PRESSED 0 #define LOCKED_OUT 1 #define PRESSED 2 #define FIRST 3 // ***************************************************************************** // Section: User Functions // ***************************************************************************** // === thread structures ============================================ // thread control structs static struct pt pt_input, pt_read, pt_seven_seg; // === UART Read Thread ================================================= // Reads a String from the UART channel into a buffer then Changes state acordingly static PT_THREAD (protothread_read(struct pt *pt)) { PT_BEGIN(pt); //Clear the reset on the chip PT_YIELD_TIME_msec(50) ; mPORTAClearBits(BIT_4); while(1) { PT_YIELD_TIME_msec(50) ; PT_SPAWN(pt, &pt_input, PT_GetSerialBuffer(&pt_input) ); // scans UART terminal for specified format target_address = 99; sender_address = 99; command = '?'; value = 0; sscanf( PT_term_buffer, "%i %i %c %i", &target_address, &sender_address ,&command, &value ); // printf("Player %i Found <%i> <%i> <%c> <%i> \r", playerID,target_address, sender_address ,command, value); //reprints when entered // sets state based on input if(target_address == playerID){ //add value to current score if(command == 'a'){ currentScore = currentScore + value; if(currentScore > 999) currentScore = 999; // printf("Player %d 's score has been set to %i \r", playerID, currentScore); } //subtract value to current score else if(command == 's'){ currentScore = currentScore - value; if(currentScore < -999) currentScore = -999; // printf("Player %d 's score has been set to %i \r", playerID, currentScore); } //clear the surrent state and reset it back to idle else if(command == 'c'){ //reset the state currentState = NOT_PRESSED; //Turn off buzzer LED mPORTBClearBits(BIT_15); //re-sync the timer WriteTimer23(0x00000000); } //enter the lock down state else if(command == 'l'){ //disable the interrupt mPORTBClearBits(BIT_15); currentState = LOCKED_OUT; } //this player buzzed in first else if(command == 'f'){ currentState = FIRST; //turn on the buzzer LED mPORTBSetBits(BIT_15); } //reset the player module for a new game else if(command == 'r'){ //reset the state currentState = NOT_PRESSED; //Turn off buzzer LED mPORTBClearBits(BIT_15); //re-sync the timer WriteTimer23(0x00000000); //reset the score currentScore = 0; } } // NEVER exit while } // END WHILE(1) PT_END(pt); } // thread // === Seven Segment Display thread ================================================= // Outputs current score to seven segment display static PT_THREAD (protothread_seven_seg(struct pt *pt)) { PT_BEGIN(pt); while(1) { //yield for time multiplex PT_YIELD_TIME_msec(8) ; //Minus sign if(currentScore < 0) mPORTBSetBits(BIT_14); else mPORTBClearBits(BIT_14); //First digit display mPORTASetBits(BIT_1 | BIT_2); //clear segments mPORTBClearBits(BIT_0 | BIT_1 | BIT_2 | BIT_3 | BIT_4 | BIT_5 | BIT_7); mPORTAClearBits(BIT_0); //use the table to decode the needed segment uint8_t onesDigit = abs(currentScore % 10); uint8_t segments = segmentTable[onesDigit]; mPORTBSetBits(segments); //yield for time multiplex PT_YIELD_TIME_msec(8) ; //Second digit transmision mPORTASetBits(BIT_0 | BIT_2); //clear segments mPORTBClearBits(BIT_0 | BIT_1 | BIT_2 | BIT_3 | BIT_4 | BIT_5 | BIT_7); mPORTAClearBits(BIT_1); //use the table to decode the needed segment uint8_t tensDigit = abs( (currentScore/10) % 10); segments = segmentTable[tensDigit]; mPORTBSetBits(segments); //yield for time multiplex PT_YIELD_TIME_msec(8) ; //Third digit transmision mPORTASetBits(BIT_0 | BIT_1); //clear segments mPORTBClearBits(BIT_0 | BIT_1 | BIT_2 | BIT_3 | BIT_4 | BIT_5 | BIT_7); mPORTAClearBits(BIT_2); //use the table to decode the needed segment uint8_t hundredsDigit = abs ((currentScore/100) % 10); segments = segmentTable[hundredsDigit]; mPORTBSetBits(segments); // NEVER exit while } // END WHILE(1) PT_END(pt); } // thread // === Interrupt Service Routine ================================= // Monitors the button and interrupts on a press void __ISR (_INPUT_CAPTURE_1_VECTOR, ipl2soft) InputCapture_Handler(void) { //only react if in the unpressed state if(currentState == NOT_PRESSED){ // Figure out when a button is pressed uint32_t buttonTime = mIC1ReadCapture(); //send out the pressed signal printf("0 %i p %d \r", playerID, buttonTime); mPORTBSetBits(BIT_15); //set the current state to pressed currentState = PRESSED; } else{ //needs to be done to clear interrupt mIC1ReadCapture(); } // clear interrupt flag mIC1ClearIntFlag(); } // ISR /** * initialize input capture for reading button presses` */ inline void initEverything(void) { OpenTimer23(T23_ON | T23_32BIT_MODE_ON, 0xffffffff); OpenCapture1(IC_ON | IC_CAP_32BIT | IC_TIMER2_SRC | IC_EVERY_RISE_EDGE); } /** * Main */ void main(void) { SYSTEMConfigPerformance(PBCLK); ANSELA = 0; ANSELB = 0; CM1CON = 0; CM2CON = 0; // === config threads ========== PT_setup(); // init the threads PT_INIT(&pt_read); PT_INIT(&pt_input); PT_INIT(&pt_seven_seg); //disable JTAG mJTAGPortEnable(0); TRISACLR = 1; initEverything(); PPSInput(3, IC1, RPB13); // enable IC interrupt mIC1IntEnable(1); mIC1SetIntPriority(2); INTEnableSystemMultiVectoredInt(); // UART Directive // printf("Player module %d is ready for communication \r", playerID); //Seven Segment and LED setup //anodes mPORTASetPinsDigitalOut(BIT_0 | BIT_1| BIT_2| BIT_4); //segments mPORTBSetPinsDigitalOut(BIT_0 | BIT_1 | BIT_2 | BIT_3 | BIT_4 | BIT_5 | BIT_7 | BIT_14| BIT_15); //initialize outputs mPORTASetBits(BIT_0 | BIT_1| BIT_2); mPORTBClearBits(BIT_0 | BIT_1 | BIT_2 | BIT_3 | BIT_4 | BIT_5 | BIT_7 | BIT_14 | BIT_15); //reset BLE chip mPORTASetBits(BIT_4); // round-robin scheduler for threads while (1){ PT_SCHEDULE(protothread_read(&pt_read)); PT_SCHEDULE(protothread_seven_seg(&pt_seven_seg)); } }