//******** Display *************** // foreground thread, accepts data from consumer // displays calculated results on the LCD // inputs: none // outputs: none void Display(void){ unsigned long data,voltage; oLED_Message(0,0,"Run length is",(RUNLENGTH)/1000); // top half used for Display while(NumSamples < RUNLENGTH) { oLED_Message(0,1,"Time left is",(RUNLENGTH-NumSamples)/1000); // top half used for Display OS_Wait(&MailBoxFull); data = OS_MailBox_Recv(); OS_Signal(&MailBoxEmpty); voltage = 3000*data/1024; // calibrate your device so voltage is in mV oLED_Message(0,2,"v(mV) =",voltage); } OS_Kill(); // done }
// ******** CAN0_Fifo_Put ************ // Enter one data sample into the Fifo // Called from the background, so no waiting. // This function cannot enable/disable intterupts // since it will be called from interrupts. // Inputs: data // Outputs: true - when data is properly saved, // false - if data not saved, because fifo was full int CAN0_Fifo_Put(uint8_t data){ volatile uint8_t *nextPutPt; nextPutPt = CAN0PutPt + 1; if(nextPutPt == &CAN0Fifo[CAN_FIFOSIZE]){ nextPutPt = &CAN0Fifo[0]; // wrap around } if(nextPutPt == CAN0GetPt){ return 0; // cannot put since fifo is full. Results in lost data } else{ *(CAN0PutPt) = data; CAN0PutPt = nextPutPt; OS_Signal(&CAN0CurrentSize); } return 1; // data put in fifo successfully }
// ******** OS_Fifo_Put ************ // Enter one data sample into the Fifo // Called from the background, so no waiting // Inputs: data // Outputs: true if data is properly saved, // false if data not saved, because it was full // Since this is called by interrupt handlers // this function can not disable or enable interrupts int OS_Fifo_Put(unsigned long data) { unsigned long *nextPutPt; nextPutPt = OS_PutPt + 1; if(nextPutPt == &OS_Fifo[FIFOSIZE]) { nextPutPt = &OS_Fifo[0]; //Wrap } if(nextPutPt == OS_GetPt) { return FAILURE; } else { *(OS_PutPt) = data; OS_PutPt = nextPutPt; OS_Signal(&CurrentSize); return SUCCESS; } }
/* Device: Scheduling period = 1/frequency of sound. Parameter (l) = number of oscillations to produce. */ void Buzz(void) { int i,l; l = OS_GetParam(); /* Release the cpu each time the speaker bit is altered, to allow the device process period to determine the frequency. */ for(i = 0; i < l; i++) { Ports[M6811_PORTA] SET_BIT(BIT3); OS_Yield(); Ports[M6811_PORTA] CLR_BIT(BIT3); OS_Yield(); } OS_Signal(S_BUZZ); }
// ******** RxFifo_Put ************ // Enter one character into the RxFifo // Called from the background, so no wait // Inputs: 8 bit data // Outputs: true if data is properly saved, // false if data not saved, because it was full // Since this is called by interrupt handlers no sei,cli short RxFifo_Put(unsigned char data){ unsigned char *tempPt; tempPt = RxPutPt; *tempPt = data; // try to Put data into fifo tempPt++; // place to Put next if (tempPt==&RxFifo[RXFIFOSIZE]){ // need to wrap? tempPt = &RxFifo[0]; } if (tempPt == RxGetPt ){ return(0); // Failed, fifo was full } else { RxPutPt = tempPt; // Success, so update pointer OS_Signal(&RxAvailable); // increment only if data actually stored return(1); } }
void ReadLightSensors(void) { FIFO f = (FIFO)OS_GetParam(); int l, r; while (1) { l = 0; r = 0; OS_Wait(S_PORTE); /* Activate A/D Converter...makes pins on Port E analog. */ Ports[M6811_OPTION] SET_BIT(BIT7); /* Delay at least 100 microseconds */ OS_Yield(); /* Start converting the right photocell */ Ports[M6811_ADCTL] = 0; /* Wait for conversion to complete. */ while (!(Ports[M6811_ADCTL] & BIT7)) { OS_Yield(); } r = Ports[M6811_ADR1]; /* Start converting the left photocell */ Ports[M6811_ADCTL] = 1; /* Wait for conversion to complete. */ while (!(Ports[M6811_ADCTL] & BIT7)) { OS_Yield(); } l = Ports[M6811_ADR1]; OS_Signal(S_PORTE); if (l > 100) { OS_Wait(S_BUZZ_FIFO); OS_Write(f,'l'); } if (r > 100) { OS_Wait(S_BUZZ_FIFO); OS_Write(f,'r'); } OS_Yield(); } }
//******** OS_SendData *************** // enter 16-bit data into the DataFifo // called from background, so does not wait if full // inputs: 16-bit data // outputs: 0 if data is lost, 1 if successful short OS_SendData(unsigned short data){ // must be atomic if more than one producer // but since there is only one producer, there is no critical section unsigned short *tempPt; SETBIT(PTT,0); // for profiling tempPt = DataPutPt; *tempPt = data; // Try to Put data into fifo tempPt++; // place to Put next if(tempPt == &DataFifo[DATAFIFOSIZE]){ // need to wrap? tempPt = &DataFifo[0]; } if(tempPt == DataGetPt){ CLRBIT(PTT,0); // for profiling return(0); // Failed, fifo was full } DataPutPt = tempPt; // Success, so update pointer OS_Signal(&DataAvailable); // increment only if data actually stored CLRBIT(PTT,0); // for profiling return(1); }
SF_STATUS FIFOPutBlocking(FIFO* fifo, void* item) { int status = 0; ASSERT(fifo != NULL && fifo->fifoDataPtr != NULL); ASSERT(fifo->length < fifo->capacity); OS_Wait(&(fifo->fifoFree)); // copy in the item memcpy(((char*)fifo->fifoDataPtr) + fifo->tailIndex*fifo->itemSizeBytes, item, fifo->itemSizeBytes); // move the tail index up. wrap around if necessary fifo->tailIndex += 1; fifo->tailIndex %= fifo->capacity; fifo->length ++; OS_Signal(&(fifo->fifoFree)); return (SUCCESS); }
void CAN0_Handler(void) { unsigned char data[8]; unsigned long ulIntStatus, ulIDStatus; CANmsgType rxMsg; int i; tCANMsgObject xTempMsgObject; xTempMsgObject.pucMsgData = data; // rxMsg.timestamp = OS_getTime(); //timestamp the CAN message ulIntStatus = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE); if(ulIntStatus & CAN_INT_INTID_STATUS) { // receive? ulIDStatus = CANStatusGet(CAN0_BASE, CAN_STS_NEWDAT); for(i = 0; i < 32; i++) { //test every bit of the mask if( (0x1 << i) & ulIDStatus) { // if active, get data CANMessageGet(CAN0_BASE, (i+1), &xTempMsgObject, true); rxMsg.byte0 = data[0]; rxMsg.byte1 = data[1]; rxMsg.byte2 = data[2]; rxMsg.byte3 = data[3]; rxMsg.byte4 = data[4]; rxMsg.byte5 = data[5]; rxMsg.byte6 = data[6]; rxMsg.byte7 = data[7]; rxMsg.length = xTempMsgObject.ulMsgLen; rxMsg.ID = xTempMsgObject.ulMsgID; if(CAN_RX_FIFOFifo_Put(rxMsg) == CANFIFOFAIL); CAN_Data_lost++; OS_Signal(&CANmessagesReceived); break; } } } CANIntClear(CAN0_BASE, ulIntStatus); // acknowledge }
SF_STATUS FIFOGetBlocking(FIFO* fifo, void* destination) { int status = 0; ASSERT(fifo != NULL && fifo->fifoDataPtr != NULL); ASSERT(fifo->length > 0); OS_Wait(&(fifo->fifoFree)); // copy the item memcpy(destination, ((char*)fifo->fifoDataPtr) + fifo->headIndex*fifo->itemSizeBytes, fifo->itemSizeBytes); // move the head index up. wrap around if necesssary fifo->headIndex += 1; fifo->headIndex %= fifo->capacity; fifo->length --; OS_Signal(&(fifo->fifoFree)); return (SUCCESS); }
//******** Consumer *************** // foreground thread, accepts data from producer // calculates FFT, sends DC component to Display // inputs: none // outputs: none void Consumer(void){ unsigned long data,DCcomponent; // 10-bit raw ADC sample, 0 to 1023 unsigned long t; // time in ms unsigned long myId = OS_Id(); ADC_Collect(0, 1000, &Producer); // start ADC sampling, channel 0, 1000 Hz NumCreated += OS_AddThread(&Display,128,0); while(NumSamples < RUNLENGTH) { for(t = 0; t < 64; t++){ // collect 64 ADC samples OS_Fifo_Get(&data); // get from producer x[t] = data; // real part is 0 to 1023, imaginary part is 0 } cr4_fft_64_stm32(y,x,64); // complex FFT of last 64 ADC values DCcomponent = y[0]&0xFFFF; // Real part at frequency 0, imaginary part should be zero OS_Wait(&MailBoxEmpty); OS_MailBox_Send(DCcomponent); GPIO_B1 ^= 0x02; OS_Signal(&MailBoxFull); OS_Sleep(15); } OS_Kill(); // done }
/* * Adds an item to the FIFO * fifo - fifo structure that was initialized and created by FIFOCreate * item - a pointer to the item that is to be added to the FIFO * * returns - SUCCESS if putting is successful * FAILURE if putting is not successful (i.e. the structure is full) */ SF_STATUS FIFOPut(FIFO* fifo, void* item) { int status = 0; ASSERT(fifo != NULL && fifo->fifoDataPtr != NULL); ASSERT(fifo->length < fifo->capacity); ASSERT(fifo->fifoFree.count > 0); // Make sure FIFO is free before continuing OS_Wait(&(fifo->fifoFree)); //status = StartCritical(); // copy in the item memcpy(((char*)fifo->fifoDataPtr) + fifo->tailIndex*fifo->itemSizeBytes, item, fifo->itemSizeBytes); // move the tail index up. wrap around if necessary fifo->tailIndex += 1; fifo->tailIndex %= fifo->capacity; fifo->length ++; OS_Signal(&(fifo->fifoFree)); //EndCritical(status); return (SUCCESS); }
void PrintLogo(void) { FIFO f; OS_InitSem(S_LOGO,1); f = OS_InitFiFo(); /* Print JoelOS in a convoluted way. */ OS_Wait(S_LOGO); OS_Create(WriteA, (int)f, PERIODIC, 10); OS_Create(Write1, (int)f, PERIODIC, 20); OS_Create(PrintFIFO, (int)f, PERIODIC, 30); /* Buzz SOS */ dot(); dot(); dot(); dash(); dash(); dash(); dot(); dot(); dot(); OS_Signal(S_BUZZ_OUTPUT); }
void Signal1(void){ // called every 799us in background if(SignalCount1<MAXCOUNT){ OS_Signal(&s); SignalCount1++; } }
void BackgroundThread1c(void){ // called at 1000 Hz Count1++; OS_Signal(&Readyc); }
/* Device: > 500ms */ void FIFOBuzz(void) { FIFO f; int fi; unsigned int i; f = (FIFO)OS_GetParam(); while (1) { if(OS_Read(f,&fi)) { /* Fifo for charactar output */ OS_Wait(S_BUZZ_OUTPUT); switch((char)fi) { case 'a': dot(); dash(); break; case 'b': dash(); dot(); dot(); dot(); break; case 'c': dash(); dot(); dash(); dot(); break; case 'd': dash(); dot(); dot(); break; case 'e': dot(); break; case 'f': dot(); dot(); dash(); dot(); break; case 'g': dash(); dash(); dot(); break; case 'h': dot(); dot(); dot(); dot(); break; case 'i': dot(); dot(); break; case 'j': dot(); dash(); dash(); dash(); break; case 'k': dash(); dot(); dash(); break; case 'l': dot(); dash(); dot(); dot(); break; case 'm': dash(); dash(); break; case 'n': dash(); dot(); break; case 'o': dash(); dash(); dash(); break; case 'p': dot(); dash(); dash(); dot(); break; case 'q': dash(); dash(); dot(); dash(); break; case 'r': dot(); dash(); dot(); break; case 's': dot(); dot(); dot(); break; case 't': dash(); break; case 'u': dot(); dot(); dash(); break; case 'v': dot(); dot(); dot(); dash(); break; case 'w': dot(); dash(); dash(); break; case 'x': dash(); dot(); dot(); dash(); break; case 'y': dash(); dot(); dash(); dash(); break; case 'z': dash(); dash(); dot(); dot(); break; case '1': dot(); dash(); dash(); dash(); dash(); break; case '2': dot(); dot(); dash(); dash(); dash(); break; case '3': dot(); dot(); dot(); dash(); dash(); break; case '4': dot(); dot(); dot(); dot(); dash(); break; case '5': dot(); dot(); dot(); dot(); dot(); break; case '6': dash(); dot(); dot(); dot(); dot(); break; case '7': dash(); dash(); dot(); dot(); dot(); break; case '8': dash(); dash(); dash(); dot(); dot(); break; case '9': dash(); dash(); dash(); dash(); dot(); break; case '0': dash(); dash(); dash(); dash(); dash(); break; default: OS_Yield(); break; } OS_Signal(S_BUZZ_FIFO); /* Wait for the speaker to settle...prevents the microphone from hearing it. */ OS_Yield(); /* When all buzz processes have finished, signal that output is complete. */ OS_Wait(S_BUZZ); OS_Signal(S_BUZZ_OUTPUT); OS_Signal(S_BUZZ); } OS_Yield(); } }
void ReadBumpers(void) { FIFO f = (FIFO)OS_GetParam(); int b; while (1) { b = 0; OS_Wait(S_PORTE); /* Activate A/D Converter...makes pins on Port E analog. */ Ports[M6811_OPTION] SET_BIT(BIT7); /* Delay at least 100 microseconds */ OS_Yield(); /* Start converting the bumpers. */ Ports[M6811_ADCTL] = 3; /* Wait for conversion to complete. */ while (!(Ports[M6811_ADCTL] & BIT7)) { OS_Yield(); } b = Ports[M6811_ADR1]; OS_Signal(S_PORTE); /* Move based on the bumper values. (b) */ /* Turn Left */ if (b > 3 && b < 7) { Ports[M6811_DDRD] = 0xFF; Ports[M6811_PORTD] CLR_BIT(BIT5); // Reverse Right Ports[M6811_PORTA] CLR_BIT(BIT6); // Left Ports[M6811_PORTA] SET_BIT(BIT5); // Right //OS_Write(f,1); } /* Turn Right */ else if (b > 23 && b < 26) { Ports[M6811_DDRD] = 0xFF; Ports[M6811_PORTD] CLR_BIT(BIT4); // Reverse Left Ports[M6811_PORTA] SET_BIT(BIT6); // Left Ports[M6811_PORTA] CLR_BIT(BIT5); // Right //OS_Write(f,2); } /* Move Ahead */ else if (b > 67 && b < 70) { Ports[M6811_DDRD] = 0xFF; Ports[M6811_PORTD] = 0xFF; // Forward Ports[M6811_PORTA] SET_BIT(BIT6); // Left Ports[M6811_PORTA] SET_BIT(BIT5); // Right //OS_Write(f,3); } /* Stop */ else { Ports[M6811_PORTA] CLR_BIT(BIT6); Ports[M6811_PORTA] CLR_BIT(BIT5); //OS_Write(f,4); } OS_Yield(); } }