// -------------------------- OS_AddThread --------------------------- int OS_AddThread(void(*task)(void), unsigned long stackSize, unsigned long priority){ long status; int i = 0; status = StartCritical(); while((thread[i].id != 0) && (i < NUMTHREADS)){ i++; }; if (thread[i].id != 0){ EndCritical(status); return 0; } SetInitialStack(i, task); thread[i].id = i + 1; thread[i].priority = priority; thread[i].blockSt = 0; thread[i].sleepSt = 0; linkTCB(&Actives, &thread[i]); EndCritical(status); return 1; //successfully added thread }
void Task_WindOut(void) { BSET(AWS_DDR, AWS_PIN); BeginCritical(); // Fast PWM 8 bit TCCR1A = BV(COM1A1) | BV(COM1B1) | BV(WGM10); TCCR1B = BV(WGM12) | BV(CS11); // Enable PWM pins AWA_DDR |= BV(AWA_DDR_COS) | BV(AWA_DDR_SIN); EndCritical(); for (;;) { delay_ms(80); // // Dimension for 5 ms pulses (100 Hz) at 60 Kts // 60 kts - 100 revs / if (Nav_AWS < 5) windPulse = 0; else windPulse = 2000 / Nav_AWS; register int deg = Nav_AWA/10; BeginCritical(); AWA_SIN = trigint_sin8u(deg * 45 + (deg * 51 / 100)); deg = (90 - deg + 360) % 360; AWA_COS = trigint_sin8u(deg * 45 + (deg * 51 / 100)); EndCritical(); } }
int OS_AddThread(void(*task)(void), unsigned long stackSize, unsigned long priority) { long status; int i; int index; status = StartCritical(); if(NumThreads == 0) { // First thread no TCBs yet tcbs[0].next = &tcbs[0]; tcbs[0].prev = &tcbs[0]; Head = &tcbs[0]; Tail = &tcbs[0]; index = 0; } else { // Look for open spot in tcbs array for(i = 0; i < MAXTHREADS; i++) { if(tcbs[i].valid == INVALID) { index = i; i = MAXTHREADS; // Exit loop } else { index = -1; // Sentinel to detect no invalid spots } } if(index == -1) { EndCritical(status); return FAILURE; // No space in tcbs } tcbs[index].next = Head; // New tcb points to head tcbs[index].prev = Tail; // Point back to current tail (*Tail).next = &tcbs[index]; // Tail now points to new tcb Tail = &tcbs[index]; // New tcb becomes the tail (*Head).prev = &tcbs[index]; // Head now points backwards to new tcb } // Initilizing the stack for debugging setInitialStack(index); // Set PC for stack to point to function to run tcbs[index].stack[STACKSIZE - 2] = (long) (task); // Set inital values for sleep status and id tcbs[index].sleepState = 0; tcbs[index].priority = priority; tcbs[index].blockedState = '\0'; tcbs[index].id = index; tcbs[index].valid = VALID; NumThreads++; EndCritical(status); return SUCCESS; }
uint8_t uartRx(uint8_t uartId, bool block) { uint8_t recvd = 0xFF; StartCritical(); while((cBufGetChar(&rxBuffer[uartId], (char *)&recvd) > 0) && block) { EndCritical(); //give the interrupt a chance to run StartCritical(); } EndCritical(); return recvd; }
// ----------------------- OS_InitSemaphore -------------------------- void OS_InitSemaphore(Sema4Type *semaPt, long value){ long status; status = StartCritical(); (*semaPt).Value = value; semaPt->Blocked = 0; EndCritical(status); }
//trigger a ping measurement. Returns distance in mm. unsigned long PingMeasure(){int i; unsigned short startTime; unsigned long iBit; iBit = StartCritical(); TIMER0_IMR_R &= ~TIMER_IMR_CAEIM; // disable capture match interrupt Done = 0; //enable output on PD4 and send a send 10us pulse GPIO_PORTD_DEN_R &= ~0x10; GPIO_PORTD_DIR_R |= 0x10; GPIO_PORTD_AFSEL_R &= ~0x10; GPIO_PORTD_DEN_R |= 0x10; PD4 = 1; for(i = 0; i < 140; i ++){} //wait approx.10 us PD4 = 0; //change PD4 to input capture (CCP0) GPIO_PORTD_DEN_R &= ~0x10; GPIO_PORTD_DIR_R &= ~0x10; GPIO_PORTD_AFSEL_R |= 0x10; GPIO_PORTD_DEN_R |= 0x10; TIMER0_IMR_R |= TIMER_IMR_CAEIM; //wait for echo start while(!Done){} Done = 0; while(!Done){} //wait for echo end EndCritical(iBit); // TIMER0_IMR_R &= ~TIMER_IMR_CAEIM; // disable capture match interrupt //distance in mm = #ticks (period) / Cinv*2. divide by 2 because sound has to travel to object and back return (Period/7400); }
void Timer5A_Handler(void){ unsigned long sr; TIMER5_ICR_R = TIMER_ICR_TATOCINT;// acknowledge timer2A timeout if(counter == 50) { counter = 1; sr = StartCritical(); // GPIO_PORTB_AFSEL_R &= ~0x40; // regular port function // GPIO_PORTB_DIR_R |= 0x40; // make PD3-0 out // GPIO_PORTB_PCTL_R = (GPIO_PORTB_PCTL_R&0xF0FFFFFF)+0x00000000; // PB7 = 0x00; // PB7 = 0x80; // Timer4A_Wait(800); // 10 us // PB7 = 0x00; PA0 = 0x00; PA0 = 0x40; Timer4A_Wait(800); // 10 us PA0 = 0x00; // GPIO_PORTB_DIR_R &= ~0x40; // make PB6 in // GPIO_PORTB_AFSEL_R |= 0x40; // enable alt funct on PB6 // GPIO_PORTB_PCTL_R = (GPIO_PORTB_PCTL_R&0xF0FFFFFF)+0x07000000; EndCritical(sr); } else { counter++; } }
void Init_Timer5A(uint32_t period) { long sr; volatile unsigned long delay; sr = StartCritical(); counter = 0; SYSCTL_RCGCTIMER_R |= 0x20; delay = SYSCTL_RCGCTIMER_R; delay = SYSCTL_RCGCTIMER_R; TIMER5_CTL_R &= ~TIMER_CTL_TAEN; // 1) disable timer1A during setup // 2) configure for 32-bit timer mode TIMER5_CFG_R = TIMER_CFG_32_BIT_TIMER; // 3) configure for periodic mode, default down-count settings TIMER5_TAMR_R = TIMER_TAMR_TAMR_PERIOD; TIMER5_TAILR_R = period - 1; // 4) reload value // 5) clear timer1A timeout flag TIMER5_ICR_R = TIMER_ICR_TATOCINT; TIMER5_IMR_R |= TIMER_IMR_TATOIM;// 6) arm timeout interrupt // 7) priority shifted to bits 31-29 for timer2A NVIC_PRI23_R = (NVIC_PRI23_R&0xFFFFFF00)|(1 << 5); NVIC_EN2_R = NVIC_EN2_INT92; // 8) enable interrupt 23 in NVIC TIMER5_TAPR_R = 0; TIMER5_CTL_R |= TIMER_CTL_TAEN; // 9) enable timer2A //page 155 //page 104 //interrupt number 92 = priority 23 EndCritical(sr); }
void linkTCB(tcbList* list, tcbPt target){ tcbPt head = *list; tcbPt current; long status; status = StartCritical(); if (head == 0){ *list = target; target->next = target; target->prev = target; } else { current = head; if (target->priority < head->priority){ *list = target; } else { current = current->next; while ((target->priority >= current->priority) && (current != head)){ current = current->next; } } (current->prev)->next = target; target->prev = current->prev; target->next = current; current->prev = target; } EndCritical(status); }
void TimerCapture_Init3(void){long sr; //Timer 3 (Clock thing) sr = StartCritical(); P10SEL0 |= 0x10; P10SEL1 &= ~0x10; // configure P10.4 as TA0CCP0 P10DIR &= ~0x10; // make P10.4 in P8SEL0 |= 0x04; P8SEL1 &= ~0x04; // configure 8.2 as TA0CCP P8DIR &= ~0x04; TA3CTL &= ~0x0030; // halt Timer A3 TA3CTL = 0x0200; TA3CCTL0 = 0x8910; TA3CCTL2 = 0x49C0; TA3EX0 &= ~0x0007; // configure for input clock divider /1 NVIC_IPR3 |= (NVIC_IPR3&0xFFFFFF00)|0x04040000; // priority 2 // interrupts enabled in the main program after all devices initialized NVIC_ISER0 |= 0x00006000; // enable interrupt 8 in NVIC TA3CTL |= 0x0024; // reset and start Timer A1 in continuous up mode EndCritical(sr); }
// ******** OS_ClearMsTime ************ // sets the system time to zero from Lab 1) // Inputs: none // Outputs: none // You are free to change how this works void OS_ClearMsTime(void){ int status; status=StartCritical(); TIMELORD=0; EndCritical(status); return; }
void TimerCapture_Init01(void(*task)(uint16_t time), void(*task2)(uint16_t time)){long sr; //Timer 1 (Wheel encoders) sr = StartCritical(); CaptureTask = task; // user function CaptureTask2 = task2; // user function P8SEL0 |= 0x01; P8SEL1 &= ~0x01; // configure P8.0 as TA0CCP0 P8DIR &= ~0x01; // make P8.0 in RIGHT? P7SEL0 |= 0x10; P7SEL1 &= ~0x10; // configure P7.4 as TA0CCP0 P7DIR &= ~0x10; // make P7.4 in LEFT? TA1CTL &= ~0x0030; // halt Timer A1 TA1CTL = 0x0200; TA1CCTL0 = 0x4910; TA1CCTL4 = 0x4910; TA1EX0 &= ~0x0003; // configure for input clock divider /1 NVIC_IPR2 |= (NVIC_IPR2&0xFFFFFF00)|0x04040000; // priority 2 // interrupts enabled in the main program after all devices initialized NVIC_ISER0 = 0x00000C00; // enable interrupt 8 in NVIC TA1CTL |= 0x0024; // reset and start Timer A1 in continuous up mode // these also work NVIC_IPR2 |= (NVIC_IPR2&0xFFFFFF00)|0x00000040; NVIC_ISER0 |= 0x00000100; EndCritical(sr); }
// ******** OS_bSignal ************ // set semaphore to 1, wakeup blocked thread if appropriate // input: pointer to a binary semaphore // output: none void OS_bSignal(Sema4Type *semaPt) { long status; tcbType (*tempPt); status = StartCritical(); if((*semaPt).Value != 1) { (*semaPt).Value++; if((*semaPt).Value <= 0) { tempPt = RunPt; while((*tempPt).blockedState != semaPt) { tempPt = (*tempPt).next; } (*tempPt).blockedState = '\0'; } } EndCritical(status); }
// Initialize CAN port void CAN0_Open(void){ uint32_t volatile delay; int32_t sr; sr = StartCritical(); MailFlag = false; SYSCTL_RCGCCAN_R |= 0x00000001; // CAN0 enable bit 0 SYSCTL_RCGCGPIO_R |= 0x00000010; // RCGC2 portE bit 4 for(delay=0; delay<10; delay++){}; GPIO_PORTE_AFSEL_R |= 0x30; //PORTE AFSEL bits 5,4 // PORTE PCTL 88 into fields for pins 5,4 GPIO_PORTE_PCTL_R = (GPIO_PORTE_PCTL_R&0xFF00FFFF)|0x00880000; GPIO_PORTE_DEN_R |= 0x30; GPIO_PORTE_DIR_R |= 0x20; CANInit(CAN0_BASE); CANBitRateSet(CAN0_BASE, 80000000, CAN_BITRATE); CANEnable(CAN0_BASE); // make sure to enable STATUS interrupts CANIntEnable(CAN0_BASE, CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS); // Set up filter to receive these IDs // in this case there is just one type, but you could accept multiple ID types CAN0_Setup_Message_Object(Ping1_ID, MSG_OBJ_RX_INT_ENABLE, 4, NULL, Ping1_ID, MSG_OBJ_TYPE_RX); CAN0_Setup_Message_Object(Ping2_ID, MSG_OBJ_RX_INT_ENABLE, 4, NULL, Ping2_ID, MSG_OBJ_TYPE_RX); CAN0_Setup_Message_Object(Ping3_ID, MSG_OBJ_RX_INT_ENABLE, 4, NULL, Ping3_ID, MSG_OBJ_TYPE_RX); CAN0_Setup_Message_Object(Ping4_ID, MSG_OBJ_RX_INT_ENABLE, 4, NULL, Ping4_ID, MSG_OBJ_TYPE_RX); CAN0_Setup_Message_Object(Button1_ID, MSG_OBJ_RX_INT_ENABLE, 4, NULL, Button1_ID, MSG_OBJ_TYPE_RX); CAN0_Setup_Message_Object(Button2_ID, MSG_OBJ_RX_INT_ENABLE, 4, NULL, Button2_ID, MSG_OBJ_TYPE_RX); CAN0_Setup_Message_Object(IR_ID, MSG_OBJ_RX_INT_ENABLE, 4, NULL, IR_ID, MSG_OBJ_TYPE_RX); NVIC_EN1_R = (1 << (INT_CAN0 - 48)); //IntEnable(INT_CAN0); EndCritical(sr); return; }
// ******** OS_Wait ************ // decrement semaphore and spin/block if less than zero // input: pointer to a counting semaphore // output: none void OS_Wait(Sema4Type *s){ //new way (Lab3) long status; //the i bit, used to save and reload it status=StartCritical(); //Save Ibit s->Value = s->Value-1; //Decriment semaphore counter if(s->Value < 0){ //If counter < 0 block //BLOCK!!! NUMBLOCKEDTHREADS++; RUNPT->blockedOn=s; //set in TCB what sema4 its blocked on (for debug info) if(s->blockedThreads[(s->bIndex+1)%NUMTHREADS]==EMPTY){ s->bIndex=(s->bIndex+1)%NUMTHREADS; s->blockedThreads[(s->bIndex)%NUMTHREADS]=RUNPT; //add thread to array of blocked threads NVIC_ST_CURRENT_R = 0; //EndCritical(status); OS_SysTick_Handler(); //trigger thread switch } } EndCritical(status); //Reenable I bit //old way (Lab2) /* DisableInterrupts() while( s->Value <= 0){ //TODO: implement Blocking EnableInterrupts(); DisableInterrupts(); } s->Value--; EnableInterrupts(); */ }
// ******** OS_Signal ************ // increment semaphore, wakeup blocked thread if appropriate // input: pointer to a counting semaphore // output: none void OS_Signal(Sema4Type *s){ long status; status=StartCritical(); s->Value++; EndCritical(status); //TODO: wakeup blocked thread }
void examineButtons(void) { StartCritical(); if(AlertDebounce) { AlertDebounce = false; // When you hold 300, portA->Data is 0xBF if((PortA->Data&0xFF) == 0xBF) { sw300Pressed = true; } // When you hold 301, portA->Data is 0x7F else if((PortA->Data&0xFF) == 0x7F) { sw301Pressed = true; } // When you hold 302, portD->Data is 0x7B else if((PortD->Data&0xFF) == 0x7B) { sw302Pressed = true; } // When you hold 303, portD->Data is 0x77 else if((PortD->Data&0xFF) == 0x77) { sw303Pressed = true; } else { sw300Pressed = false; sw301Pressed = false; sw302Pressed = false; sw303Pressed = false; } } EndCritical(); }
int OS_AddThread(void(*task)(void), unsigned long stackSize, unsigned long priority) { uint32_t status; status = StartCritical(); //we will take the first thread from the dead pool if(DeadPt == '\0') { OS_DisableInterrupts(); while(1){} } (DeadPt)->id = uniqueId; //unique id (DeadPt)->active = 1; (DeadPt)->sleepState = 0; //flag (DeadPt)->priority = priority; (DeadPt)->blockedState = 0; //flag (DeadPt)->needToWakeUp = 0; //flag SetInitialStack(DeadPt, stackSize); (DeadPt)->stack[stackSize - 2] = (uint32_t)task; //push PC uniqueId++; addDeadToScheduler(&DeadPt); if(higherPriorityAdded == 1) { OS_Suspend(); } EndCritical(status); return 1; }
// Inputs: channelNum - ADC channel input [0:11]. // freq - sample frequency. // task - function pointer that accepts the collected ADC values. // Output: none void ADC_InitHWTrigger1(uint8_t channelNum, uint32_t freq, void(*task)(unsigned long data)){ long sr = StartCritical(); uint32_t prescale = 80; // prescale and period used to determine freq. Currently set for f=400Hz. See pg 108 of textbook uint32_t period = 1000000/freq; // prescale and period used to determine freq. Currently set for f=400Hz. See pg 108 of textbook UserTask1 = task; // user function channelInit(channelNum); // initalize ADC channels SYSCTL_RCGCADC_R |= 0x01; // activate ADC0 SYSCTL_RCGCTIMER_R |= 0x01; // activate timer0 while((SYSCTL_PRADC_R&0x01) == 0){}; // allow time for clock to stabilize while((SYSCTL_PRTIMER_R&0x01) == 0){}; // allow time for clock to stabilize TIMER0_CTL_R = 0x00000000; // disable timer0A during setup TIMER0_CTL_R |= 0x00000020; // enable timer0A trigger to ADC TIMER0_CFG_R = 0x4; // configure for 16-bit timer mode TIMER0_TAMR_R = 0x00000002; // configure for periodic mode, default down-count settings TIMER0_TAPR_R = prescale-1; // prescale value for trigger TIMER0_TAILR_R = period-1; // start value for trigger TIMER0_IMR_R = 0x00000000; // disable all interrupts TIMER0_CTL_R |= 0x00000001; // enable timer0A 32-b, periodic, no interrupts ADC0_PC_R = 0x01; // configure for 125K samples/sec ADC0_SSPRI_R = 0x3210; // Sequencer 3 = lowest priority, 0 = highest priority ADC0_ACTSS_R &= ~0x08; // disable sample sequencer 3 ADC0_EMUX_R = (ADC0_EMUX_R&0xFFFF0FFF)+0x5000; // timer trigger event ADC0_SSMUX3_R = channelNum; ADC0_SSCTL3_R = 0x06; // set flag and end ADC0_IM_R |= 0x08; // enable SS3 interrupts ADC0_ACTSS_R |= 0x08; // enable sample sequencer 3 NVIC_PRI4_R &= 0xFFFF00FF; //priority 2 NVIC_PRI4_R |= 0x00004000; //priority 2 NVIC_EN0_R |= 1<<17; // enable interrupt 17 in NVIC EndCritical(sr); }
void UserInit(void){ StartCritical(); //println_W(startmessage);// All printfDEBUG functions do not need to be removed from code if debug is disabled //#if defined(DEBUG) // ConfigureUART(115200); // if(GetChannelMode(16)!=IS_UART_TX) // setMode(16,IS_UART_TX); //#endif setPrintLevelInfoPrint(); println_I(/*PSTR*/("\e[1;1H\e[2J ***Starting User initialization***")); InitFlagPins(); InitBankLEDs(); SetPowerState0(0,0); SetPowerState1(0,0); //_delay_ms(1); #if defined(WPIRBE) SPISlaveInit(); #endif //_delay_ms(100); println_I(/*PSTR*/("Starting Pin Functions")); InitPinFunction(); println_I(/*PSTR*/("Starting Pin Modes")); InitPinModes(); int i=0; //println_I(/*PSTR*/("Starting hardware modes")); for(i=0;i<GetNumberOfIOChannels();i++){ initPinState(i); configAdvancedAsyncNotEqual(i,10); setAsyncLocal(i,true) ; } //println_I(/*PSTR*/("DONE pin initialization")); //println_I(/*PSTR*/("Adding IO Initialization")); addNamespaceToList((NAMESPACE_LIST *)get_bcsIoNamespace()); //println_I(/*PSTR*/("Adding IO.SETMODE Initialization")); addNamespaceToList((NAMESPACE_LIST *)get_bcsIoSetmodeNamespace()); //println_I(/*PSTR*/("Adding Internal Initialization")); addNamespaceToList((NAMESPACE_LIST *)get_internalNamespace()); setNoAsyncMode(true); setIgnoreAddressing(true); //SetPinTris(0,OUTPUT); //SetDIO(0,OFF); #if defined(USE_AS_LIBRARY) InitializeUserCode(); #endif EndCritical(); println_I(/*PSTR*/("Starting Core")); // setMode(22,IS_DO); // setMode(23,IS_DI); // println_I(/*PSTR*/("Pin done")); }
// -------------------------- OS_Kill -------------------------------- void OS_Kill(void){ long status; status = StartCritical(); unlinkTCB(&Actives, RunPt); RunPt->id = 0; EndCritical(status); OS_Suspend(); }
// ******** OS_bSignal ************ // set semaphore to 1, wakeup blocked thread if appropriate // input: pointer to a binary semaphore // output: none void OS_bSignal(Sema4Type *semaPt){ long status; status=StartCritical(); semaPt->Value= 1; EndCritical(status); //TODO: wakeup blocked thread return; }
// **************SysTick_Init********************* // Initialize SysTick periodic interrupts // Input: interrupt period // Units of period are 12.5ns (assuming 80 MHz clock) // Maximum is 2^24-1 // Minimum is determined by length of ISR // Output: none void SysTick_Init(uint32_t period){long sr; sr = StartCritical(); NVIC_ST_CTRL_R = 0; // disable SysTick during setup NVIC_ST_RELOAD_R = period-1;// reload value NVIC_ST_CURRENT_R = 0; // any write to current clears it NVIC_SYS_PRI3_R = (NVIC_SYS_PRI3_R&0x00FFFFFF)|0x40000000; // priority 2 // enable SysTick with core clock and interrupts NVIC_ST_CTRL_R = 0x07; EndCritical(sr); }
//------------TimerCapture_Init------------ // Initialize Timer A1 in edge time mode to request interrupts on // the rising edge of P8.0 (TA1CCP0). The interrupt service routine // acknowledges the interrupt and calls a user function. // Input: task is a pointer to a user function called when edge occurs // parameter is 16-bit up-counting timer value when edge occurred // Output: none void TimerCapture1_Init(void (*task1) (uint16_t time), void (*task2) (uint16_t time)) { long sr; sr = StartCritical(); CaptureTask = task1; // user function CaptureTask2 = task2; // initialize P8.0 and P7.7 and make them input P8SEL0 |= 0x01; P8SEL1 &= ~0x01; // configure P8.0 as TA1CCP0 P8DIR &= ~0x01; // make P8.0 in P7SEL0 |= 0x80; P7SEL1 &= ~0x80; // configure P7.7 as TA1CCP1 P7DIR &= ~0x80; // make P7.7 in TA1CTL &= ~0x0030; // halt Timer A0 // bits15-10=XXXXXX, reserved // bits9-8=10, clock source to SMCLK // bits7-6=00, input clock divider /1 // bits5-4=00, stop mode // bit3=X, reserved // bit2=0, set this bit to clear // bit1=0, interrupt disable // bit0=0, clear interrupt pending TA1CTL = 0x0200; // bits15-14=01, capture on rising edge // bits13-12=00, capture/compare input on CCI0A // bit11=1, synchronous capture source // bit10=X, synchronized capture/compare input // bit9=X, reserved // bit8=1, capture mode // bits7-5=XXX, output mode // bit4=1, enable capture/compare interrupt // bit3=X, read capture/compare input from here // bit2=X, output this value in output mode 0 // bit1=X, capture overflow status // bit0=0, clear capture/compare interrupt pending TA1CCTL0 = 0x4910; TA1CCTL1 = 0x4910; TA1EX0 &= ~0x0007; // configure for input clock divider /1 NVIC_IPR2 = (NVIC_IPR2&0xFFFFFF00)|0x00000040; // priority 2 // interrupts enabled in the main program after all devices initialized NVIC_ISER0 = 0x00000c00; // enable interrupt 10 and 11 in NVIC TA1CTL |= 0x0024; // reset and start Timer A0 in continuous up mode // bits15-10=XXXXXX, reserved // bits9-8=10, clock source to SMCLK // bits7-6=00, input clock divider /1 // bits5-4=10, continuous count up mode // bit3=X, reserved // bit2=1, set this bit to clear // bit1=0, interrupt disable (no interrupt on rollover) // bit0=0, clear interrupt pending EndCritical(sr); }
void LEDsInit(void) { int32_t status = StartCritical(); SYSCTL_RCGCGPIO_R |= 0x20; // activate port F while((SYSCTL_PRGPIO_R&0x20) == 0){}; // allow time for clock to stabilize GPIO_PORTF_DIR_R |= 0x0E; // make PF3-1 output (PF3-1 built-in LEDs) GPIO_PORTF_AFSEL_R &= ~0x0E; // disable alt funct on PF3-1 GPIO_PORTF_DEN_R |= 0x0E; // enable digital I/O on PF3-1 GPIO_PORTF_PCTL_R &= ~0x0000FFF0; // configure PF3-1 as GPIO GPIO_PORTF_AMSEL_R &= ~0x0E; // disable analog functionality on PF3-1 EndCritical(status); }
// ******** OS_Signal ************ // increment semaphore, wakeup blocked thread if appropriate // input: pointer to a counting semaphore // output: none void OS_Signal(Sema4Type *s){ long status; //new way(Lab3) int i,j,k; status=StartCritical(); //save Ibit if(s->Value<0){ //WAKE UP BLOCKED if(RRSCHEDULER){ //ROUND ROBIN for(i=(s->bIndex+1)%NUMTHREADS ; s->blockedThreads[i]==0 ; i=++i%NUMTHREADS){;} //itterate through blocked list untill you find a pointer to a blocked thread s->blockedThreads[i]->blockedOn=NULL; //remove blocked pointer from TCB s->blockedThreads[i]=EMPTY; //remove from blocked list NUMBLOCKEDTHREADS--; }else if(PRIORITYSCHEDULER){ //PRIORITY for(i=0,j=7;i<NUMTHREADS;i++){ if(s->blockedThreads[i]!=NULL && s->blockedThreads[i]->workingPriority<=j){ //j holds highest priority thus far encountered j=s->blockedThreads[i]->workingPriority; k=i; //k holds the index of the highest priority thread } } if(s->blockedThreads[k]->workingPriority < RUNPT->workingPriority){ //if unblocked thread has higher priority than currently running thread // NEXTRUNPT=s->blockedThreads[k] //possible ERROR, dont think i need this, but i might s->blockedThreads[k]->blockedOn=NULL; //remove block from TCB s->blockedThreads[k]=EMPTY; //remove from sema4 blocked threads list NVIC_ST_CURRENT_R =0; NUMBLOCKEDTHREADS--; OS_SysTick_Handler(); // }else{ //just add it back into the currently running list s->blockedThreads[k]->blockedOn=NULL; //remove block from TCB s->blockedThreads[k]=EMPTY; //remove from sema4 blocked threads list NUMBLOCKEDTHREADS--; } } } if(s->Value<1){ s->Value = s->Value +1; //Incriment Counter }else{ s->Value=1; } EndCritical(status); //old way (Lab2) /* status=StartCritical(); s->Value++; EndCritical(status); */ }
//------------TimerCapture_Init------------ // Initialize Timer0A in edge time mode to request interrupts on // the rising edge of PB0 (CCP0). The interrupt service routine // acknowledges the interrupt and calls a user function. // Input: task is a pointer to a user function // Output: none void TimerCapture_Init(void(*task)(void)){long sr; /* sr = StartCritical(); SYSCTL_RCGC2_R |= SYSCTL_RCGC2_GPIOB; //activate port B PING_PeriodicTask = task; //user function GPIO_PORTB_DIR_R |= 0x40; //PB6 out GPIO_PORTB_AFSEL_R &= ~0x40; //disable alt funct on PB64 GPIO_PORTB_DEN_R |= 0x40; //enable digital I/O on PB6 //configure PF4 as GPIO GPIO_PORTB_PCTL_R = (GPIO_PORTB_PCTL_R&0xF0FFFFFF)+0x00000000; GPIO_PORTB_AMSEL_R = 0; //disable analog functionality on PB // GPIO_PORTB_PUR_R |= 0x40; // enable weak pull-up on PB6 GPIO_PORTB_PDR_R |= 0x40; // enable weak pull-down on PB6 GPIO_PORTB_IS_R &= ~0x40; // (d) PB64 is edge-sensitive //GPIO_PORTB_IBE_R &= ~0x40; // PB6 is not both edges GPIO_PORTB_IBE_R |= 0x40; // PB6 is both edges //GPIO_PORTB_IEV_R &= ~0x40; // PB6 falling edge event GPIO_PORTB_ICR_R = 0x40; // (e) clear flag6 GPIO_PORTB_IM_R |= 0x40; // (f) arm interrupt on PB6 //NVIC_PRI4_R = (NVIC_PRI4_R&0x00FFFFFF)|0x40000000; // top 3 bits NVIC_PRI0_R = (NVIC_PRI0_R&0xFFFF0FFF)|0x00004000; // top 3 bits //NVIC_EN0_R = NVIC_EN0_INT19; // enable interrupt 19 in NVIC NVIC_EN0_R = NVIC_EN0_INT1; // enable interrupt 1 in NVIC EndCritical(sr); */ sr = StartCritical(); SYSCTL_RCGC2_R |= SYSCTL_RCGC2_GPIOB; //activate port B PING_PeriodicTask = task; //user function GPIO_PORTB_DIR_R |= 0xF0; //PB6 out GPIO_PORTB_AFSEL_R &= ~0xF0; //disable alt funct on PB64 GPIO_PORTB_DEN_R |= 0xF0; //enable digital I/O on PB6 //configure PF4 as GPIO GPIO_PORTB_PCTL_R = (GPIO_PORTB_PCTL_R&0xF0FFFFFF)+0x00000000; GPIO_PORTB_AMSEL_R = 0; //disable analog functionality on PB // GPIO_PORTB_PUR_R |= 0x40; // enable weak pull-up on PB6 GPIO_PORTB_PDR_R |= 0xF0; // enable weak pull-down on PB6 GPIO_PORTB_IS_R &= ~0xF0; // (d) PB64 is edge-sensitive //GPIO_PORTB_IBE_R &= ~0x40; // PB6 is not both edges GPIO_PORTB_IBE_R |= 0xF0; // PB6 is both edges //GPIO_PORTB_IEV_R &= ~0x40; // PB6 falling edge event GPIO_PORTB_ICR_R = 0xF0; // (e) clear flag6 GPIO_PORTB_IM_R |= 0xF0; // (f) arm interrupt on PB6 //NVIC_PRI4_R = (NVIC_PRI4_R&0x00FFFFFF)|0x40000000; // top 3 bits NVIC_PRI0_R = (NVIC_PRI0_R&0xFFFF0FFF)|0x00004000; // top 3 bits //NVIC_EN0_R = NVIC_EN0_INT19; // enable interrupt 19 in NVIC NVIC_EN0_R = NVIC_EN0_INT1; // enable interrupt 1 in NVIC EndCritical(sr); }
void portBInit(void) { int32_t status = StartCritical(); SYSCTL_RCGCGPIO_R |= 0x02; // 1) activate clock for Port B while((SYSCTL_PRGPIO_R&0x02) == 0) {}; // ready? GPIO_PORTB_DIR_R &= ~0xFF; // PB1 is an input GPIO_PORTB_AFSEL_R &= ~0xFF; // regular port function GPIO_PORTB_AMSEL_R &= ~0xFF; // disable analog on PB1 GPIO_PORTB_PCTL_R &= ~0xFFFFFFFF; // PCTL GPIO on PB1 GPIO_PORTB_DEN_R |= 0xFF; // PB3-0 enabled as a digital port EndCritical(status); }
int OS_AddPeriodicThread(void(*task)(void), unsigned long period, unsigned long priority){ int32_t status; status = OS_StartCritical(); //now need to add to linked list if(DeadPeriodicPt == '\0') //cant add this thread { OS_DisableInterrupts(); while(1){}; } removeAndAddToSingleList(&DeadPeriodicPt, period, task, priority); EndCritical(status ); return 0; //added sucesfully }
// ******** OS_bSignal ************ // Lab2 spinlock, set to 1 // Lab3 wakeup blocked thread if appropriate // input: pointer to a binary semaphore // output: none void OS_bSignal(Sema4Type *semaPt) { int32_t status; status = OS_StartCritical(); (*semaPt).Value = 1; if((*semaPt).blockedThreads != '\0') { (*(*semaPt).blockedThreads).active = 1; (*(*semaPt).blockedThreads).blockedState = 0; addDeadToScheduler(&(*semaPt).blockedThreads); //addDead is similar to what we want to do. Just takes first element of linked list and adds to scheduler } EndCritical(status ); }