void GPIOPortB_Handler(void) { // handle port B0 interrupt if ((GPIO_PORTB_MIS_R&0x01) == 0x01) { GPIO_PORTB_ICR_R = 0x01; // handle rising edge if ((GPIO_PORTB_IEV_R&0x01) == 0x01) { Sensor0StartTime = OS_Time(); GPIO_PORTB_IEV_R &= ~0x01; // switch to falling edge } else { // handle falling edge Sensor0Reading = OS_TimeDifference(Sensor0StartTime, OS_Time()); GPIO_PORTB_IM_R &= ~0x01; // disable PB0 interrupts GPIO_PORTB_IEV_R |= 0x01; // switch to rising edge (for next time) GPIO_PORTB_DIR_R |= 0x01; // make PB0 out (for next time) OS_bSignal(&Sensor0DataAvailable); } } // handle port B1 interrupt if ((GPIO_PORTB_MIS_R&0x02) == 0x02) { GPIO_PORTB_ICR_R = 0x02; // handle rising edge if ((GPIO_PORTB_IEV_R&0x02) == 0x02) { Sensor1StartTime = OS_Time(); GPIO_PORTB_IEV_R &= ~0x02; // switch to falling edge } else { // handle falling edge Sensor1Reading = OS_TimeDifference(Sensor1StartTime, OS_Time()); GPIO_PORTB_IM_R &= ~0x02; // disable PB1 interrupts GPIO_PORTB_IEV_R |= 0x02; // switch to rising edge (for next time) GPIO_PORTB_DIR_R |= 0x02; // make PB1 out (for next time) OS_bSignal(&Sensor1DataAvailable); } } }
unsigned long Ping_GetDistance(int sensor) { unsigned long time; unsigned long distance = 0; if (sensor == 0) { OS_bWait(&Sensor0Free); TriggerSensor0(); OS_bWait(&Sensor0DataAvailable); time = Sensor0Reading; distance = SPEED_OF_SOUND * time / (2 * TIME_1S) + PING_OFFSET; OS_bSignal(&Sensor0Free); } else if (sensor == 1) { OS_bWait(&Sensor1Free); TriggerSensor1(); OS_bWait(&Sensor1DataAvailable); time = Sensor1Reading; distance = SPEED_OF_SOUND * time / (2 * TIME_1S) + PING_OFFSET; OS_bSignal(&Sensor1Free); } return distance; }
//***************************************************************************** // //! \internal //! //! Write a sequence of data bytes to the SSD1329 controller. //! //! The data is written in a polled fashion; this function will not return //! until the entire byte sequence has been written to the controller. //! //! \return None. // //***************************************************************************** static void RITWriteData(const unsigned char *pucBuffer, unsigned long ulCount) { OS_bWait(&oLEDFree); // // Return if SSI port is not enabled for RIT display. // if(!HWREGBITW(&g_ulSSIFlags, FLAG_SSI_ENABLED)) { OS_bSignal(&oLEDFree); return; } // // See if command mode is enabled. // if(!HWREGBITW(&g_ulSSIFlags, FLAG_DC_HIGH)) { // // Wait until the SSI is not busy, meaning that all previous commands // have been transmitted. // while(SSIBusy(SSI0_BASE)) { } // // Set the command/control bit to enable data mode. // GPIOPinWrite(GPIO_OLEDDC_BASE, GPIO_OLEDDC_PIN, GPIO_OLEDDC_PIN); HWREGBITW(&g_ulSSIFlags, FLAG_DC_HIGH) = 1; } // // Loop while there are more bytes left to be transferred. // while(ulCount != 0) { // // Write the next byte to the controller. // SSIDataPut(SSI0_BASE, *pucBuffer++); // // Decrement the BYTE counter. // ulCount--; } OS_bSignal(&oLEDFree); }
//int count2 = 0; void dummyTask2(void) { // int i; // unsigned long data; // #if PROFILING == 1 // int myPin = 0x02; // #endif while(1) { // OLED_Out(BOTTOM, "task 2 request"); OS_bWait(&binarySemaphore); OLED_Out(BOTTOM, "task 2 acquired"); // for(i = 0; i < 100000; i++) { // #if PROFILING == 1 // GPIO_PORTB_DATA_R ^= myPin; // #endif // } OS_Sleep(1000); OS_bSignal(&binarySemaphore); OLED_Out(BOTTOM, "task 2 released"); OS_Sleep(1000); // for(i = 0; i < 100000; i++) { // #if PROFILING == 1 // GPIO_PORTB_DATA_R ^= myPin; // #endif // } // data = OS_MailBox_Recv(); // OLED_Out(BOTTOM, "task 2 receive"); // OS_AddThread(&dummyTask1, 0, 1); // OLED_Out(BOTTOM, "task 2 dead"); // OS_Kill(); // OS_Sleep(2000); } }
//int count1 = 0; void dummyTask1(void) { // int i; // #if PROFILING == 1 // int myPin = 0x01; // #endif OS_InitSemaphore(&binarySemaphore, OS_BINARY_SEMAPHORE); while(1) { OS_bWait(&binarySemaphore); OLED_Out(TOP, "task 1 acquired"); // for(i = 0; i < 100000; i++) { // #if PROFILING == 1 // GPIO_PORTB_DATA_R ^= myPin; // #endif // } OS_Sleep(1000); OS_bSignal(&binarySemaphore); OLED_Out(TOP, "task 1 released"); OS_Sleep(1000); // for(i = 0; i < 100000; i++) { // #if PROFILING == 1 // GPIO_PORTB_DATA_R ^= myPin; // #endif // } // OLED_Out(TOP, "task 1 dead"); // OS_AddThread(&dummyTask2, 0 ,1); // OS_Kill(); } }
// ******** OS_Fifo_Size ************ // Check the status of the Fifo // Inputs: none // Outputs: returns the number of elements in the Fifo // greater than zero if a call to OS_Fifo_Get will return right away // zero or less than zero if the Fifo is empty // zero or less than zero if a call to OS_Fifo_Get will spin or block long OS_Fifo_Size(void) { OS_bWait(&mutex); long toReturn = (OS_TxPutI-OS_TxGetI); OS_bSignal(&mutex); return toReturn; }
// ******** OS_MailBox_Recv ************ // remove mail from the MailBox // Inputs: none // Outputs: data received // This function will be called from a foreground thread // It will spin/block if the MailBox is empty unsigned long OS_MailBox_Recv(void) { unsigned long toReturn; OS_bWait(&dataValid); toReturn = dataInMailBox; OS_bSignal(&mailBoxFree); return toReturn; }
// ******** OS_MailBox_Recv ************ // remove mail from the MailBox // Inputs: none // Outputs: data received // This function will be called from a foreground thread // It will spin/block if the MailBox is empty unsigned long OS_MailBox_Recv(void) { unsigned long mail; OS_bWait(&DataValid); mail = Mailbox; OS_bSignal(&BoxFree); return mail; }
// if receive data is ready, gets the data and returns true // if no receive data is ready, returns false int CAN0_GetMailNonBlock(uint8_t data[8]){ OS_bWait(&CAN0ReceiveFree); if(MailFlag){ data[0] = CAN0_Fifo_Get(); data[1] = CAN0_Fifo_Get(); data[2] = CAN0_Fifo_Get(); data[3] = CAN0_Fifo_Get(); data[4] = CAN0_Fifo_Get(); data[5] = CAN0_Fifo_Get(); data[6] = CAN0_Fifo_Get(); data[7] = CAN0_Fifo_Get(); MailFlag = false; OS_bSignal(&CAN0ReceiveFree); return true; } OS_bSignal(&CAN0ReceiveFree); return false; }
void BackgroundThread1d(void){ // called at 1000 Hz static int i=0; i++; if(i==500){ i = 0; //every 50 ms Count1++; OS_bSignal(&Readyd); } }
// ******** CAN0_Fifo_Get ************ // Remove one data sample from the Fifo // Called in foreground, will block if empty // Inputs: none // Outputs: data uint8_t CAN0_Fifo_Get(void){ int8_t returnValue; // holds the value poped off of fifo. OS_Wait(&CAN0CurrentSize); // block for data OS_bWait(&CAN0FifoMutex); // only one thread can access the fifo at any given time returnValue = *CAN0GetPt; // pop element off fifo CAN0GetPt++; if(CAN0GetPt == &CAN0Fifo[CAN_FIFOSIZE]){ CAN0GetPt = &CAN0Fifo[0]; // wrap around } OS_bSignal(&CAN0FifoMutex); //release the fifo return returnValue; }
unsigned long OS_Fifo_Get(void) { OS_Wait(&dataAvailable); OS_bWait(&mutex); unsigned long toReturn; toReturn = TxFifo[OS_TxGetI&(TXFIFOSIZE-1)]; OS_TxGetI++; // Success, update samplesConsumed++; OS_bSignal(&mutex); //OS_Signal(&roomLeft); return toReturn; }
// ******** OS_Fifo_Get ************ // Remove one data sample from the Fifo // Called in foreground, will spin/block if empty // Inputs: none // Outputs: data unsigned long OS_Fifo_Get(void) { unsigned long data; OS_Wait(&CurrentSize); OS_bWait(&FifoMutex); data = *(OS_GetPt++); if(OS_GetPt == &OS_Fifo[FIFOSIZE]) { OS_GetPt = &OS_Fifo[0]; } OS_bSignal(&FifoMutex); return data; }
/* Allow the use of two (logically) separate screens. * This function outputs a given string onto the specified * part of the OLED screen * param: int device, screen to output onto (TOP or BOTTOM) * param: const char * string, character array to be displayed * return: none */ void OLED_Out(int device, const char * string) { /* Marks function as critical */ // OS_CRITICAL_FUNCTION; /* Blank line */ char clear[OLED_COLUMNS + 2] = {0}; int offset = 0; OS_bWait(&OLED_Semaphore); ASSERT(line < 5 && device < 2 && device >= 0); /* Enter critical section */ // OS_ENTER_CRITICAL(); /* Initialize blank line */ memset(clear, ' ', OLED_COLUMNS + 1); /* Write string, wrapping as needed */ do { /* Row buffer */ char cur_row[OLED_COLUMNS + 1] = {0}; int num = 0, length; /* Copy next row, update offset */ length = OLED_MIN( /* length up until end of string/column */ OLED_MIN(strlen(&string[offset]), OLED_COLUMNS), /* location of '\n' */ _OLED_Find(&string[offset], '\n') + 1 ); memcpy(cur_row, &string[offset], length); offset += length; /* Roll screen back when max lines reached */ line[device] += num; if(line[device] >= OLED_LINES) { _OLED_Rollback(char_buff[device], device); line[device] = OLED_LINES - 1; } /* Write most recent row */ strcpy(char_buff[device][line[device]], cur_row); // char_buff[device][line[device]][OLED_COLUMNS-1] = 0; _OLED_Message(device, line[device]++, cur_row, OLED_Get_Color()); } while(string[offset]); /* End critical section */ // OS_EXIT_CRITICAL(); OS_bSignal(&OLED_Semaphore); }
// if receive data is ready, gets the data // if no receive data is ready, it waits until it is ready void CAN0_GetMail(uint8_t data[8]){ OS_bWait(&CAN0ReceiveFree); while(MailFlag==false){}; data[0] = CAN0_Fifo_Get(); data[1] = CAN0_Fifo_Get(); data[2] = CAN0_Fifo_Get(); data[3] = CAN0_Fifo_Get(); data[4] = CAN0_Fifo_Get(); data[5] = CAN0_Fifo_Get(); data[6] = CAN0_Fifo_Get(); data[7] = CAN0_Fifo_Get(); MailFlag = false; OS_bSignal(&CAN0ReceiveFree); }
// ******** OS_MailBox_Send ************ // enter mail into the MailBox // Inputs: data to be sent // Outputs: none // This function will be called from a foreground thread // It will spin/block if the MailBox contains data not yet received void OS_MailBox_Send(unsigned long data) { OS_bWait(&mailBoxFree); dataInMailBox = data; OS_bSignal(&dataValid); }
// ******** OS_MailBox_Send ************ // enter mail into the MailBox // Inputs: data to be sent // Outputs: none // This function will be called from a foreground thread // It will spin/block if the MailBox contains data not yet received void OS_MailBox_Send(unsigned long data) { OS_bWait(&BoxFree); Mailbox = data; OS_bSignal(&DataValid); return; }