//======================= Blink ========================= // // Blinks a circle on the screen at a rate of 1 blink per second static PT_THREAD (protothread_blink(struct pt *pt)) { PT_BEGIN(pt); while(1) { PT_YIELD_TIME_msec(1000); tft_drawCircle(10, 10, 10, ILI9340_WHITE); PT_YIELD_TIME_msec(1000); tft_drawCircle(10, 10, 10, ILI9340_BLACK); } PT_END(pt); } // blink
// This thread blinks a circle on the display every second as a heartbeat static PT_THREAD(protothread_blink(struct pt *pt)) { PT_BEGIN(pt); while(1) { //draw circle tft_fillCircle(xc, yc, 4, ILI9340_GREEN); //yield time 1 second PT_YIELD_TIME_msec(500); //erase circle tft_fillCircle(xc, yc, 4, ILI9340_BLACK); //yield time 1 second PT_YIELD_TIME_msec(500); } PT_END(pt); }
/** * The first protothread function. A protothread function must always * return an integer, but must NEVER explicitly return - returning is * performed inside the protothread statements. * * The protothread function is driven by the main loop further down in * the code. */ static PT_THREAD (protothread1(struct pt *pt)) { // mark beginning of thread PT_BEGIN(pt); /* We loop forever here. */ while(1) { //stop until thread 2 signals PT_SEM_WAIT(pt, &control_t1); // put a 2 microsec pulse on the debug pin with amplitude 3 PT_DEBUG_VALUE(3, 2) ; // toggle a port pin mPORTAToggleBits(BIT_0); // tell thread 2 to go PT_SEM_SIGNAL(pt, &control_t2); // Allow thread 3 to control blinking // thru command interface PT_YIELD_UNTIL(pt, cntl_blink) ; // This is a locally written macro using timer5 to count millisec // to program a yield time PT_YIELD_TIME_msec(wait_t1) ; // NEVER exit while } // END WHILE(1) // mark end the thread PT_END(pt); } // thread 1
//==================== Calculate ===================== // static PT_THREAD (protothread_calculate (struct pt *pt)) { PT_BEGIN(pt); while(1) { PT_YIELD_TIME_msec(refreshRate); struct Ball *ti = head; struct Ball *tj = head; while(ti !=NULL){ //Calculates the collisions between every ball while(tj != NULL) { signed short rij_x = ti->xpos - tj->xpos; signed short rij_y = ti->ypos - tj->ypos; signed short mag_rij = pow(rij_x,2) + pow(rij_y,2); //Checks if ti and tj are not pointing to the same ball, //If they close enough for a collision and there is no collision //delay. if(ti != tj && ti->delay + tj->delay == 0 && mag_rij < 4*pow(ballradius,2)) { signed short vij_x = ti->xvel - tj->xvel; signed short vij_y = ti->yvel - tj->yvel; signed short temp = pow(2*pow(ballradius,2),2); signed short deltaVi_x = -1*(rij_x * (rij_x * vij_x+ rij_y*vij_y))/temp; signed short deltaVi_y = -1*(rij_y * (rij_x * vij_x+ rij_y*vij_y))/temp; //Updates the velocity ti->xvel = ti->xvel + deltaVi_x; ti->yvel = ti->yvel + deltaVi_y; tj->xvel = tj->xvel - deltaVi_x; tj->yvel = tj->yvel - deltaVi_y; ti->delay = delay_master; tj->delay = delay_master; collisions++; } tj = tj->b; } //"Clears" the image of the last ball tft_fillCircle(ti->xpos,ti->ypos,ballradius,ILI9340_BLACK); //Updates the new position of the ball ti->xpos = ti->xpos + ti->xvel * refreshRate/10; ti->ypos = ti->ypos + ti->yvel * refreshRate/10; //checks for wall collisions if(ti->xpos > 240 || ti->xpos < 0) ti->xvel = -1*ti->xvel; if(ti->ypos > 320 || ti->ypos < 0) ti->yvel = -1*ti->yvel; //Decrement the collide delay if(ti->delay > 0) ti->delay = ti->delay -1; ti = ti->b; tj = head; } } PT_END(pt); }
// === Launching balls ================================================= static PT_THREAD (protothread_launch_balls(struct pt *pt)) { PT_BEGIN(pt); while(1){ //make sure we don't put in too many balls PT_WAIT_UNTIL(pt, current_balls < MAX_BALLS); while(current_balls < MAX_BALLS) { PT_YIELD_TIME_msec(200); //5 balls per second current_balls++; //increase ball count in field ball *new_ball = (ball*) malloc (sizeof(ball)); new_ball->xc = int2fix16(315); new_ball->yc = int2fix16(120); new_ball->vxc = int2fix16(-8 + (rand()>>28)); new_ball->vyc = int2fix16(-8 + (rand()>>27)); new_ball->next = NULL; new_ball->hit_counter = 0; if (initial_ball == NULL) { //if chain is empty, this ball is first ball initial_ball = new_ball; new_ball->prev = NULL; } else {//otherwise, put it at end end_ball->next = new_ball; new_ball->prev = end_ball; } end_ball = new_ball; } } PT_END(pt); } // end launch ball thread
//method to figure out what sound to play // === Timer Thread ================================================= static PT_THREAD (protothread_timer(struct pt *pt)) { PT_BEGIN(pt); tft_setCursor(100, 0); tft_setTextColor(ILI9340_WHITE); tft_setTextSize(1); tft_writeString("Elapsed time : \t Score"); while(1) { PT_YIELD_TIME_msec(1000) ; sys_time_seconds++ ; tft_fillRect(100, 10, 150, 8, ILI9340_BLACK);// x,y,w,h,radius,color tft_setCursor(100, 10); tft_setTextColor(ILI9340_YELLOW); tft_setTextSize(1); sprintf(buffer,"%*d %*d", 7, sys_time_seconds, 12, score); tft_writeString(buffer); tft_fillRect(175, 18, 2, 7, ILI9340_CYAN); tft_fillRect(248, 18, 2, 7, ILI9340_CYAN); tft_fillRect(175, 18, 75, 2, ILI9340_CYAN); tft_fillRect(175, 233, 2, 7, ILI9340_CYAN); tft_fillRect(248, 233, 2, 7, ILI9340_CYAN); tft_fillRect(175, 238, 75, 2, ILI9340_CYAN); if(score >= 50 && sys_time_seconds <= 60) { tft_setCursor(100, 90); tft_setTextColor(ILI9340_GREEN); tft_setTextSize(3); tft_writeString("You Win!"); } else if(score <= -50 || sys_time_seconds > 60) { tft_setCursor(100, 90); tft_setTextColor(ILI9340_RED); tft_setTextSize(3); tft_writeString("You Lose!"); } } PT_END(pt); } // timer thread
// === Color Thread ================================================= // draw 3 color patches for R,G,B from a random number //static int color ; //static int i; static PT_THREAD (protothread_color(struct pt *pt)) { PT_BEGIN(pt); static int color ; static int i; while(1) { // yield time 1 second PT_YIELD_TIME_msec(2000) ; // choose a random color color = rand() & 0xffff ; // draw color string tft_fillRoundRect(0,50, 150, 14, 1, ILI9340_BLACK);// x,y,w,h,radius,color tft_setCursor(0, 50); tft_setTextColor(ILI9340_WHITE); tft_setTextSize(1); sprintf(buffer," %04x %04x %04x %04x", color & 0x1f, color & 0x7e0, color & 0xf800, color); tft_writeString(buffer); // draw the actual color patches tft_fillRoundRect(5,70, 30, 30, 1, color & 0x1f);// x,y,w,h,radius,blues tft_fillRoundRect(40,70, 30, 30, 1, color & 0x7e0);// x,y,w,h,radius,greens tft_fillRoundRect(75,70, 30, 30, 1, color & 0xf800);// x,y,w,h,radius,reds // now draw the RGB mixed color tft_fillRoundRect(110,70, 30, 30, 1, color);// x,y,w,h,radius,mix color // NEVER exit while } // END WHILE(1) PT_END(pt); } // color thread
static PT_THREAD (protothread_key(struct pt *pt)) { PT_BEGIN(pt); static int keypad, i, pattern; // order is 0 thru 9 then * ==10 and # ==11 // no press = -1 // table is decoded to natural digit order (except for * and #) // 0x80 for col 1 ; 0x100 for col 2 ; 0x200 for col 3 // 0x01 for row 1 ; 0x02 for row 2; etc static int keytable[12]={0x108, 0x81, 0x101, 0x201, 0x82, 0x102, 0x202, 0x84, 0x104, 0x204, 0x88, 0x208}; // init the keypad pins A0-A3 and B7-B9 // PortA ports as digital outputs mPORTASetPinsDigitalOut(BIT_0 | BIT_1 | BIT_2 | BIT_3); //Set port as output // PortB as inputs mPORTBSetPinsDigitalIn(BIT_7 | BIT_8 | BIT_9); //Set port as input while(1) { // read each row sequentially mPORTAClearBits(BIT_0 | BIT_1 | BIT_2 | BIT_3); pattern = 1; mPORTASetBits(pattern); // yield time PT_YIELD_TIME_msec(30); //mPORTAClearBits(BIT_0 | BIT_1 | BIT_2 | BIT_3); //pattern = 1; mPORTASetBits(pattern); for (i=0; i<4; i++) { keypad = mPORTBReadBits(BIT_7 | BIT_8 | BIT_9); if(keypad!=0) {keypad |= pattern ; break;} mPORTAClearBits(pattern); pattern <<= 1; mPORTASetBits(pattern); } // search for keycode if (keypad > 0){ // then button is pushed for (i=0; i<12; i++){ if (keytable[i]==keypad) break; } } else i = -1; // no button pushed // draw key number tft_fillRoundRect(30,200, 100, 28, 1, ILI9340_BLACK);// x,y,w,h,radius,color tft_setCursor(30, 200); tft_setTextColor(ILI9340_YELLOW); tft_setTextSize(4); sprintf(buffer,"%d", i); if (i==10)sprintf(buffer,"*"); if (i==11)sprintf(buffer,"#"); tft_writeString(buffer); // NEVER exit while } // END WHILE(1) PT_END(pt); } // keypad thread
// === Thread 5 ====================================================== // update a 1 second tick counter static PT_THREAD (protothread5(struct pt *pt)) { PT_BEGIN(pt); while(1) { // yield time 1 second PT_YIELD_TIME_msec(1000) ; sys_time_seconds++ ; // NEVER exit while } // END WHILE(1) PT_END(pt); } // thread 4
//======================= Refresh ========================= // static PT_THREAD (protothread_refresh(struct pt *pt)) { PT_BEGIN(pt); while(1) { PT_YIELD_TIME_msec(10); struct Ball *ti = head; while(ti != NULL){ tft_fillCircle(ti->xpos, ti->ypos, ballradius, ILI9340_WHITE); ti = ti->b; } } PT_END(pt); } // blink
static PT_THREAD(protothread_anim(struct pt *pt)) { // runs the LCD and updates around 5/second PT_BEGIN(pt); //write to screen tft_fillRect(0,0, 50, 50, ILI9340_BLACK);//write black over previous message tft_setCursor(0, 0); tft_setTextColor(ILI9340_WHITE); tft_setTextSize(1);//smallest size sprintf(buffer,"%s%d", "time since startup:\n", PT_GET_TIME()/1000 ); tft_writeString(buffer); PT_YIELD_TIME_msec(30); PT_END(pt); } // animation thread
// This thread is responsible for all the code not involving the TFT Display, it handled discharging and charging the capacitor and calculating the // capacitance of the capacitor. static PT_THREAD(protothread_cap(struct pt *pt)){ PT_BEGIN(pt); while(1){ // Discharge Capacitor // Set pin as output mPORTBSetPinsDigitalOut(BIT_3); // Drive RB3 low so capacitor can discharge into the pin mPORTBClearBits(BIT_3); // Yield until discharge is complete PT_YIELD_TIME_msec(2); // 2ms is given for the capacitor to discharge and for the display to update if needed Comp1Setup(); // Charge Capacitor // Set RB3 as an input to detect capacitor's current charge mPORTBSetPinsDigitalIn(BIT_3); // Set up the timer for charging the capcitor capTimerSetup(); // Set up the input capture to capture when the capacitor voltage reaches the reference voltage IC1setup(); // Yield while waiting for event from comparator PT_YIELD_UNTIL(pt, charged); CloseTimer2(); // Reset thread wait variable charged = 0; // Calculate capacitance in nF capacitance = (((charge_time*-1)/1000000)/(log(1-(VREF / VDD)) * RESISTOR))*1000000000; CMP1Close(); PT_YIELD_TIME_msec(20); } PT_END(pt); }
//===================== Capture ==================== // // Discharges capacitor, displays and begins measurement of C1INA static PT_THREAD (protothread_capture(struct pt *pt)) { PT_BEGIN(pt); while(1) { // sets pin 7 to an output mPORTBSetPinsDigitalOut(BIT_3); mPORTBClearBits(BIT_3); tft_setCursor(10, 50); tft_setTextColor(ILI9340_YELLOW); tft_setTextSize(3); tft_writeString("Capacitance: "); //sets up for the capacitor reading char buffer[20]; tft_setCursor(10, 90); tft_fillRect(10,90, 300, 100, ILI9340_BLACK); sprintf(buffer,"%.1f nF",cap); tft_setTextColor(ILI9340_WHITE); //displays the capacitor value if it is above the threshold of 1 nF if(cap < 1.0*(1-ERROR)) tft_writeString("No capacitor"); else tft_writeString(buffer); cap = 0.0; PT_YIELD_TIME_msec(1); //Clear timer and sets pin 7 as input WriteTimer2(0); mPORTBSetPinsDigitalIn(BIT_3); PT_YIELD_TIME_msec(100); } PT_END(pt); } // capture
//static PT_THREAD(protothread_I2C(struct pt *pt)){ // PT_BEGIN(pt); // while(1){ // // PT_YIELD_TIME_msec(500); // } // PT_END(pt); //} static PT_THREAD(protothread_uart(struct pt *pt)) { // this thread interacts with the PC keyboard to take user input and set up PID parameters PT_BEGIN(pt); // send the prompt via DMA to serial sprintf(PT_send_buffer, "%s", "cmd>"); // by spawning a print thread PT_SPAWN(pt, &pt_DMA_output, PT_DMA_PutSerialBuffer(&pt_DMA_output));//send date and time while (1) { buffer[0] = RcvIMUData(BNO055_QUATERNION_DATA_W_LSB_ADDR); buffer[1] = RcvIMUData(BNO055_QUATERNION_DATA_X_LSB_ADDR); buffer[2] = RcvIMUData(BNO055_QUATERNION_DATA_Y_LSB_ADDR); buffer[3] = RcvIMUData(BNO055_QUATERNION_DATA_Z_LSB_ADDR); // temp = RcvIMUData(BNO055_ACCEL_DATA_X_LSB_ADDR); sprintf(PT_send_buffer, "%s %s%d, %s%d, %s%d, %s%d%s", "Accelerometer value: " , "W: ", buffer[0], "X: " , buffer[1], "Y: ", buffer[2], "Z: ", buffer[3],"\n\r"); // sprintf(PT_send_buffer, "%s %s%d, %s%d, %s%d%s", "Accelerometer value: " , "W: ", buffer[0], "X: " // , buffer[1], "Y: ", buffer[2],"\n\r"); // by spawning a print thread PT_SPAWN(pt, &pt_DMA_output, PT_DMA_PutSerialBuffer(&pt_DMA_output));//send date and time // //spawn a thread to handle terminal input // // the input thread waits for input // // -- BUT does NOT block other threads // // string is returned in "PT_term_buffer" // PT_SPAWN(pt, &pt_input, PT_GetSerialBuffer(&pt_input));//wait for input // sscanf(PT_term_buffer, "%s %f", cmd, &value); // // // echo // sprintf(PT_send_buffer,"%04x%s", rcv, "\n");//send original message // PT_SPAWN(pt, &pt_DMA_output, PT_DMA_PutSerialBuffer(&pt_DMA_output) ); // sprintf(PT_send_buffer,"\n");//next line // PT_SPAWN(pt, &pt_DMA_output, PT_DMA_PutSerialBuffer(&pt_DMA_output) ); // sprintf(PT_send_buffer,"\r");//carriage return // PT_SPAWN(pt, &pt_DMA_output, PT_DMA_PutSerialBuffer(&pt_DMA_output) ); PT_YIELD_TIME_msec(500); } // while(1) PT_END(pt); } // uart input thread
// === Thread 4 ====================================================== // just blinks static PT_THREAD (protothread4(struct pt *pt)) { PT_BEGIN(pt); while(1) { mPORTBToggleBits(BIT_0); // put a 10 microsec pulse on the debug pin with amplitude 1 PT_DEBUG_VALUE(1, 10) ; PT_YIELD_TIME_msec(wait_t2) ; // never exit while } // END WHILE(1) PT_END(pt); } // thread 4
// === Animation Thread ============================================= // move a disk static PT_THREAD (protothread_anim(struct pt *pt)) { PT_BEGIN(pt); static int xc=10, yc=150, vxc=2, vyc=0; while(1) { // yield time 1 second PT_YIELD_TIME_msec(32); // erase disk tft_fillCircle(xc, yc, 4, ILI9340_BLACK); //x, y, radius, color // compute new position xc = xc + vxc; if (xc<5 || xc>235) vxc = -vxc; // draw disk tft_fillCircle(xc, yc, 4, ILI9340_GREEN); //x, y, radius, color // NEVER exit while } // END WHILE(1) PT_END(pt); } // animation thread
// === ADC Thread ============================================= static PT_THREAD (protothread_adc(struct pt *pt)) { PT_BEGIN(pt); myPaddle = (paddle*) malloc(sizeof(paddle)); myPaddle->xc = 4; static int adc_10; while(1) { PT_YIELD_TIME_msec(2); // read the ADC from pin 24 (AN11) adc_10 = ReadADC10(0); // read the result of channel 9 conversion from the idle buffer AcquireADC10(); // not needed if ADC_AUTO_SAMPLING_ON below //READADC10 value is between 0-1020 tft_fillRect(myPaddle->xc, myPaddle->yc, 2, PADDLE_LEN, ILI9340_BLACK); if(adc_10 < 3) adc_10 = 0; else if (adc_10 > 920) adc_10 = 920; myPaddle->vyc = (adc_10 >> 2) - myPaddle->yc; myPaddle->yc = (adc_10 >> 2); tft_fillRect(myPaddle->xc, myPaddle->yc, 2, PADDLE_LEN, ILI9340_WHITE); } // END WHILE(1) PT_END(pt); } // ADC thread
// === Timer Thread ================================================= // update a 1 second tick counter static PT_THREAD (protothread_timer(struct pt *pt)) { PT_BEGIN(pt); tft_setCursor(0, 0); tft_setTextColor(ILI9340_WHITE); tft_setTextSize(1); tft_writeString("Time in seconds since boot\n"); while(1) { // yield time 1 second PT_YIELD_TIME_msec(1000) ; sys_time_seconds++ ; // draw sys_time tft_fillRoundRect(0,10, 100, 14, 1, ILI9340_BLACK);// x,y,w,h,radius,color tft_setCursor(0, 10); tft_setTextColor(ILI9340_YELLOW); tft_setTextSize(2); sprintf(buffer,"%d", sys_time_seconds); tft_writeString(buffer); // NEVER exit while } // END WHILE(1) PT_END(pt); } // timer thread
//static PT_THREAD(protothread_I2C(struct pt *pt)){ // PT_BEGIN(pt); // while(1){ // // PT_YIELD_TIME_msec(500); // } // PT_END(pt); //} static PT_THREAD(protothread_uart(struct pt *pt)) { // this thread interacts with the PC keyboard to take user input and set up PID parameters PT_BEGIN(pt); // send the prompt via DMA to serial sprintf(PT_send_buffer, "%s", "cmd>"); // by spawning a print thread PT_SPAWN(pt, &pt_DMA_output, PT_DMA_PutSerialBuffer(&pt_DMA_output));//send date and time while (1) { temp = RcvData2(addr); sprintf(PT_send_buffer, "%s%d%s", "Temperature value: " ,temp, "\n\r"); // by spawning a print thread PT_SPAWN(pt, &pt_DMA_output, PT_DMA_PutSerialBuffer(&pt_DMA_output));//send date and time // //spawn a thread to handle terminal input // // the input thread waits for input // // -- BUT does NOT block other threads // // string is returned in "PT_term_buffer" // PT_SPAWN(pt, &pt_input, PT_GetSerialBuffer(&pt_input));//wait for input // sscanf(PT_term_buffer, "%s %f", cmd, &value); // // // echo // sprintf(PT_send_buffer,"%04x%s", rcv, "\n");//send original message // PT_SPAWN(pt, &pt_DMA_output, PT_DMA_PutSerialBuffer(&pt_DMA_output) ); // sprintf(PT_send_buffer,"\n");//next line // PT_SPAWN(pt, &pt_DMA_output, PT_DMA_PutSerialBuffer(&pt_DMA_output) ); // sprintf(PT_send_buffer,"\r");//carriage return // PT_SPAWN(pt, &pt_DMA_output, PT_DMA_PutSerialBuffer(&pt_DMA_output) ); PT_YIELD_TIME_msec(500); } // while(1) PT_END(pt); } // uart input thread
// This thead displays the value of the capcitor if it is in the 1nF-100nF range // or diplays a message if the capacitor is out of range static PT_THREAD(protothread_cap_read(struct pt *pt)) { PT_BEGIN(pt); tft_setCursor(0,0); tft_setTextColor(ILI9340_WHITE); tft_setTextSize(2); tft_writeString("Measuring capacitance:"); while(1) { tft_setCursor(0,30); tft_setTextColor(ILI9340_YELLOW); tft_setTextSize(2); if (capacitance < 1 || capacitance > 99) { tft_fillRoundRect(0,30, 320, 40, 1, ILI9340_BLACK);// x,y,w,h,radius,color tft_writeString("Capacitor out of range!"); } else { tft_fillRoundRect(0,30, 320, 40, 1, ILI9340_BLACK);// x,y,w,h,radius,color sprintf(buffer, "%4.1f nF", capacitance); tft_writeString(buffer); } PT_YIELD_TIME_msec(200); } PT_END(pt); }
static PT_THREAD(protothread_cap_read(struct pt *pt)) { PT_BEGIN(pt); tft_setCursor(0,0); tft_setTextColor(ILI9340_WHITE); tft_setTextSize(3); tft_writeString("Measuring capacitance:\n"); while(1) { tft_setCursor(0,10); tft_setTextColor(ILI9340_YELLOW); tft_setTextSize(3); if (capacitance == 0) { tft_writeString("No capacitor detected"); } else if (capacitance == 999) { tft_writeString("Capacitor out of range!"); } else { sprintf(buffer, "%5.1f", capacitance); } tft_writeString(buffer); PT_YIELD_TIME_msec(200); } PT_END(pt); }
//======================= Refresh ========================= // //Does Ball calculations and Draws the necessary elements on the screen static PT_THREAD (protothread_refresh(struct pt *pt)) { PT_BEGIN(pt); PT_YIELD_TIME_msec(100); //waits for the scoreboard to be set up while(1) { while (timeElapsed <=60) { PT_YIELD_TIME_msec(10); DmaChnDisable(dmaChn); DmaChnDisable(dmaChn2); //Generates a new ball at a given interval if(ballgen >= 10) { int troll1 = -((rand()) % 2)-1; int troll2 = ((rand()) % 6) - 3; struct Ball *temp = Ball_create(320,120,troll1,troll2,(numBalls+1)*500,0,NULL); temp->b = head; head = temp; ballgen = 0; numBalls++; } else ballgen ++; //collision calculations struct Ball *ti = head; struct Ball *tj = NULL; if(ti != NULL) tj = ti->b; while(ti !=NULL){ //Calculates the collisions between every ball while(tj != NULL) { int rij_x = ti->xpos - tj->xpos; int rij_y = ti->ypos - tj->ypos; int mag_rij = pow(rij_x,2) + pow(rij_y,2); //Checks if ti and tj are not pointing to the same ball, //If they close enough for a collision and there is no collision //delay. if( ti->delay + tj->delay == 0 && mag_rij < dist) { int vij_x = ti->xvel - tj->xvel; int vij_y = ti->yvel - tj->yvel; if (mag_rij==0) { mag_rij=dist; } int deltaVi_x = (int)((-1*(rij_x) * ((((rij_x * vij_x)+ (rij_y*vij_y)) << 7)/mag_rij)) >> 7); int deltaVi_y = (int)((-1*(rij_y) * ((((rij_x * vij_x)+ (rij_y*vij_y)) << 7)/mag_rij)) >> 7); /* tft_fillRoundRect(0,30, 320, 14, 1, ILI9340_BLACK);// x,y,w,h,radius,color tft_setCursor(0, 30); tft_setTextColor(ILI9340_WHITE); tft_setTextSize(2); sprintf(buffer,"%d:%d", (-1*(rij_x)/128 * (128*((rij_x * vij_x)+ (rij_y*vij_y))/mag_rij)), mag_rij); tft_writeString(buffer); */ //Updates the velocity ti->xvel = ti->xvel + deltaVi_x; ti->yvel = ti->yvel + deltaVi_y; tj->xvel = tj->xvel - deltaVi_x; tj->yvel = tj->yvel - deltaVi_y; ti->delay = delay_master; tj->delay = delay_master; } tj = tj->b; } //checks for wall collisions if(ti->xpos >= 320*scale || ti->xpos <= 0) ti->xvel = -1*ti->xvel; if(ti->ypos >= 240*scale || ti->ypos <= 35*scale) { ti->yvel = -1*ti->yvel; if (ti->xpos > 120*scale && ti->xpos < 200*scale) { //check for catch bin ti->delay=-1; //set to -1 to indicate +1 point } } //calculates the drag if(ti->xvel > 0) ti->xvel = ti->xvel - ti->xvel/drag; else ti->xvel = ti->xvel + ti->xvel/drag; if(ti->yvel > 0) ti->yvel = ti->yvel - ti->yvel/drag; else ti->yvel = ti->yvel - ti->yvel/drag; // Check for paddle Collisions if(abs(paddle_xpos-ti->xpos/scale) <= ballradius && ti->delay == 0) if(ti->ypos/scale > paddle_ypos - half_paddle_length && ti->ypos/scale < paddle_ypos + half_paddle_length) { ti->xvel = -1*ti->xvel; ti->yvel = ti->yvel + paddle_drag*paddle_v; ti->delay=delay_master; } //Decrement the collide delay if(ti->delay > 0) ti->delay = ti->delay -1; //iterates through the next set ti = ti->b; if(ti != NULL) tj = ti->b; //removes the last element if the limit is reached if(numBalls > maxBalls && tj->b == NULL) { tft_fillCircle(tj->xpos/scale,tj->ypos/scale,ballradius,ILI9340_BLACK); //erases from the screen ti->b = NULL; numBalls--; score++; //free(tj); } } // Calculates position of the paddle and draw //TODO: Calculate paddle position tft_drawLine(paddle_xpos,paddle_ypos - half_paddle_length, paddle_xpos, paddle_ypos + half_paddle_length, ILI9340_BLACK); paddle_v=paddle_ypos; paddle_ypos=(adc_9*240)/1023; paddle_v=paddle_ypos-paddle_v; tft_drawLine(paddle_xpos,paddle_ypos - half_paddle_length, paddle_xpos, paddle_ypos + half_paddle_length, ILI9340_WHITE); // Now it calculates the new position ti = head; tj = head; while(ti != NULL){ //"Clears" the image of the last ball tft_fillCircle(ti->xpos/scale,ti->ypos/scale,ballradius,ILI9340_BLACK); //Updates the new position of the ball ti->xpos = ti->xpos + ti->xvel; ti->ypos = ti->ypos + ti->yvel; //ensures the positions are within bounds //If the pos is less than 0 then we remove it //delay must also not be -1 (ie >=0) if(ti->xpos > paddle_xpos && ti->delay != -1) { if(ti->xpos > 320*scale) ti->xpos = 320*scale; if(ti->ypos > 240*scale) ti->ypos = 240*scale; else if(ti->ypos < 35*scale) ti->ypos = 35*scale; if(ti->delay > 0) tft_fillCircle(ti->xpos/scale, ti->ypos/scale, ballradius, ILI9340_WHITE); else tft_fillCircle(ti->xpos/scale, ti->ypos/scale, ballradius, ti->color); } else { //REMOVES THE BALL IF IT CROSSES THE BOUNDARY if (ti->delay==-1) { //check if went into catch bins score++; DmaChnEnable(dmaChn2); } else { DmaChnEnable(dmaChn); score--; } if(ti == head) head = head->b; else tj->b = ti->b; numBalls--; //free(ti); } tj = ti;//what does this do? ti = ti->b; } frames ++; } tft_fillRoundRect(0,35, 320, 205, 1, ILI9340_BLACK);// x,y,w,h,radius,color DmaChnDisable(dmaChn); DmaChnDisable(dmaChn2); DmaChnEnable(dmaChn3); while (1) { tft_setCursor(20, 120); tft_setTextColor(ILI9340_WHITE); tft_setTextSize(4); sprintf(buffer,"Game Over!"); tft_writeString(buffer); } }
static PT_THREAD(protothread_CSense(struct pt *pt)) { PT_BEGIN(pt); while (1) { if (config1 & CUR_SENSE_EN) { if(Status2 & M7_CUR){ if(M7_LastDir != M7_Dir)//if direction has changed, lower CS flag, which enables PWM writing Status2 &= !M7_CUR; } if(Status2 & M6_CUR){ if(M6_LastDir != M6_Dir) Status2 &= !M6_CUR; } if(Status2 & M6_CUR){ if(M6_LastDir != M6_Dir) Status2 &= !M6_CUR; } if(Status2 & M5_CUR){ if(M5_LastDir != M5_Dir) Status2 &= !M5_CUR; } if(Status2 & M4_CUR){ if(M4_LastDir != M4_Dir) Status2 &= !M4_CUR; } if(Status2 & M3_CUR){ if(M3_LastDir != M3_Dir) Status2 &= !M3_CUR; } if (mPORTBReadBits(BIT_3)) {//CS triggered! M7_PWM = 0; SetDCOC1PWM(M7_PWM);//Halt motor Status2 |= M7_CUR;//set CS flag M7_LastDir = M7_Dir;//save direction } if (mPORTBReadBits(BIT_1)) { M6_PWM = 0; SetDCOC2PWM(M6_PWM); Status2 |= M6_CUR; M6_LastDir = M6_Dir; } if (mPORTAReadBits(BIT_3)) { M5_PWM = 0; SetDCOC3PWM(M5_PWM); Status2 |= M5_CUR; M5_LastDir = M5_Dir; } if (mPORTBReadBits(BIT_4)) { M4_PWM = 0; SetDCOC5PWM(M4_PWM); Status2 |= M4_CUR; M4_LastDir = M4_Dir; } if (mPORTAReadBits(BIT_4)) { M3_PWM = 0; SetDCOC4PWM(M3_PWM); Status2 |= M3_CUR; M3_LastDir = M3_Dir; } } PT_YIELD_TIME_msec(10); } PT_END(pt); }
// === Animation Thread ============================================= static PT_THREAD (protothread_anim_balls(struct pt *pt)) { PT_BEGIN(pt); while(1) { PT_YIELD_TIME_msec(20); iterator = initial_ball; while(iterator != NULL) { iterator2 = iterator->next; tft_fillCircle(fix2int16(iterator->xc), fix2int16(iterator->yc), RADIUS, ILI9340_BLACK); (iterator->xc) = (iterator->xc) + multfix16((iterator->vxc), drag); (iterator->yc) = (iterator->yc) + multfix16((iterator->vyc), drag); tft_fillCircle(fix2int16(iterator->xc), fix2int16(iterator->yc), RADIUS, ILI9340_WHITE); while(iterator2 != NULL) { if (balls_collide(iterator, iterator2) && (iterator->hit_counter <= 0) && (iterator2->hit_counter <= 0)) computeVelocityChange(iterator, iterator2); else if (balls_collide(iterator, iterator2)) { iterator->hit_counter = COUNTER; iterator2->hit_counter = COUNTER; } else{ iterator->hit_counter--; iterator2->hit_counter--; } iterator2 = iterator2->next; } // If the ball hits the paddle if ((myPaddle->xc+DIAMETER >= fix2int16(iterator->xc)) && (myPaddle->yc <= fix2int16(iterator->yc)) && ((myPaddle->yc+PADDLE_LEN) >= fix2int16(iterator->yc))){ iterator->vxc = -(iterator->vxc); iterator->vyc = iterator->vyc + multfix16(int2fix16(myPaddle->vyc),pdrag); //DmaChnSetTxfer(dmaChn, sine_table2, (void*)&CVRCON, sizeof(sine_table2), 1, 1); //DmaChnEnable(dmaChn); //PT_YIELD_TIME_msec(2); //DmaChnDisable(dmaChn); } // Else the ball went off the right edge else if (myPaddle->xc+DIAMETER >= fix2int16(iterator->xc)) { DmaChnSetTxfer(dmaChn, ball_scored, (void*)&CVRCON, sizeof(ball_scored), 1, 1); DmaChnEnable(dmaChn); PT_YIELD_TIME_msec(2); DmaChnDisable(dmaChn); deleteBall(iterator); score--; } // Calculate top bin else if ((iterator->xc) <= int2fix16(250+2) && iterator->xc >= int2fix16(175-2) && iterator->yc <= int2fix16(25+9)) { deleteBall(iterator); score++;} // Calculate bottom bin else if ((iterator->xc) <= int2fix16(250+2) && iterator->xc >= int2fix16(175-2) && iterator->yc >= int2fix16(233-2)) { deleteBall(iterator); score++;} // Bounce off right wall else if ((iterator->xc) >= int2fix16(315)) (iterator->vxc) = -(iterator->vxc); // Bounce off top or bottom wall else if ((iterator->yc) <= int2fix16(25) ||(iterator->yc) >= int2fix16(233)) (iterator->vyc) = -(iterator->vyc); iterator = iterator->next; } } // END WHILE(1) PT_END(pt); } // animation thread