![Page 1: Handling multiple input signals Version #2 – co-operative scheduler Version #3 – pre-emptive scheduler](https://reader036.vdocuments.mx/reader036/viewer/2022062519/5697c0261a28abf838cd59be/html5/thumbnails/1.jpg)
Handling multiple input signals
Version #2 – co-operative scheduler
Version #3 – pre-emptive scheduler
![Page 2: Handling multiple input signals Version #2 – co-operative scheduler Version #3 – pre-emptive scheduler](https://reader036.vdocuments.mx/reader036/viewer/2022062519/5697c0261a28abf838cd59be/html5/thumbnails/2.jpg)
Midterm question
Light sensor is in front of the door Light signs on light sensor If person blocking light – light
sensor output is low -- Active low logic
Output of light sensor connected to PF5
Program stops “immediately” when owner pushes and releases a button. Button connected to PF6 line
Show the count of the people on the LCD using WriteLCD( int count).
10k resistor
+5V
GROUND
PF6
GROUND
![Page 3: Handling multiple input signals Version #2 – co-operative scheduler Version #3 – pre-emptive scheduler](https://reader036.vdocuments.mx/reader036/viewer/2022062519/5697c0261a28abf838cd59be/html5/thumbnails/3.jpg)
Design component
Key part of the design – Neither action must block the other action
Light sensor If high – nobody has ever blocked the sensor, or somebody has blocked
the sensor at moved on If low – somebody is still blocking the sensor Must count “1 person enter or leave” as the signal goes from low to
high
Button If high – owner has not pressed the button or else has pressed the button
and released it. If low – is pressing the button – people can still be entering and leaving
store. Must stop the program as the signal goes from low to high
![Page 4: Handling multiple input signals Version #2 – co-operative scheduler Version #3 – pre-emptive scheduler](https://reader036.vdocuments.mx/reader036/viewer/2022062519/5697c0261a28abf838cd59be/html5/thumbnails/4.jpg)
Approach #1 – Superloop approach based on Lab. 1 ideasWhile (loop is not stopped) {
Read GPIO Flags
4 possible things possible
At least 2 true at the same time1. Light sensor PF 5 is high
2. Light sensor PF 5 is low
3. Button PF 6 is high
4. Button PF 6 is low
We want to take action – on the “edge of the signal”. We don’t want to take action on the “level of the signal”
}
![Page 5: Handling multiple input signals Version #2 – co-operative scheduler Version #3 – pre-emptive scheduler](https://reader036.vdocuments.mx/reader036/viewer/2022062519/5697c0261a28abf838cd59be/html5/thumbnails/5.jpg)
One solution for the codeint count = 0;
int stop = 0;
#define PF5Mask 0x20
int oldPF5state = 0;
int Midterm(void) {
InitAllInterFaces( );
oldPF5State = ReadGPIOASM( ) & PF5Mask ;
While (stop != 1) {
int newPF5State = ReadGPIOASM( ) & PF5Mask ; If PF5 was high before and high now – do nothing If PF5 was low before and low now – do nothing If PF5 was high before and low now – do nothing If PF5 was low before and high now – ACT
if ( (oldPF5State == 0) && (newPF5State == PF5Mask) ) count++; WriteLCD(count);oldPF5State = newPF5State
You write the other code for the button
}
return count;
}
![Page 6: Handling multiple input signals Version #2 – co-operative scheduler Version #3 – pre-emptive scheduler](https://reader036.vdocuments.mx/reader036/viewer/2022062519/5697c0261a28abf838cd59be/html5/thumbnails/6.jpg)
Using Lab. 2 ideasCo-operative SchedulerTTCOS_Init_Scheduler( ); // Assume Ticks occur every 1 ms – which is faster than people move or
press buttons
TTCOS_Add_Task(InitInterfaces, 0, 0)
TTCOS_Add_Task(WriteToLCD, 50, 100); // Update LCD every 1/10 second – faster than the eye
// These tasks ONLY work if no task waits, and no task causes an interrupt
TTCOS_Add_Task(Count_People, 5, 10); // Worry about people moving
TTCOS_Add_Task(CheckButton, 6, 10); // Worry about the button being pressed
TTCOS_Add_Task(Stop_System, 7, 10); // Do we need to stop the system
TTCOS_Star_Scheduler( );
While (1) {
TTCOS_GoToSleep( );
TTCOS_DispatchTasks( );
}
![Page 7: Handling multiple input signals Version #2 – co-operative scheduler Version #3 – pre-emptive scheduler](https://reader036.vdocuments.mx/reader036/viewer/2022062519/5697c0261a28abf838cd59be/html5/thumbnails/7.jpg)
Using Lab. 2 ideasCo-operative Schedulerint count_G = 0;
int stop_G = 0;
int oldState_G = 0;
void InitInterfaces(void) {
InitAllInterfaces( );
oldState_G = ReadGPIO( ) & PEOPLEMASK;
}
void WriteToLCD(void) { WriteLCD(count_G); 50, 100); }
void Count_People(void) {
int newstate = ReadGPIO( ) & PEOPLEMASK;
if ( (oldstate == 0) && (newState == PEOPLEMASK) ) count_G++;
oldState = newState;
}
void StopSystem(void) {
static systemStopped = 0;
if (systemStopped == 1) return;
if (stop_G == 1) { TTCOS_Stop(WriteToLCD); TTCOS_Stop(CountPeople); TTCOS_Stop(CheckButton)
systemStopped = 1;
}
}
FINAL EXAM HINT
You write the code forCheckButton( )and convert into assembly code
![Page 8: Handling multiple input signals Version #2 – co-operative scheduler Version #3 – pre-emptive scheduler](https://reader036.vdocuments.mx/reader036/viewer/2022062519/5697c0261a28abf838cd59be/html5/thumbnails/8.jpg)
Using Lab. 2 ideasEvent Driven Using Interrupts
InitAllInterfaces( );
SetUpPFInterrupts( );
StartPFInterrupts( );
while (1) {
/* Wait for interrupts to occur in the background */
idle( ); -- Low power mode
}
![Page 9: Handling multiple input signals Version #2 – co-operative scheduler Version #3 – pre-emptive scheduler](https://reader036.vdocuments.mx/reader036/viewer/2022062519/5697c0261a28abf838cd59be/html5/thumbnails/9.jpg)
void InitAllInterfaces(void) { InitLEDs( );
InitLCDScreen( );
// Init GPIO using C/C++*pFIO_DIR = 0; // Do properly with AND and OR
*pFIO_MASKA_D = 0; // All interrupts off – channel 1*pFIO_MASKB_D = 0; // All Interrupts off – channel 2
*pFIO_POLAR = 0;
*pFIO_EDGE = 0; // Will become very important*pFIO_BOTH = 0; // Will become important
*pFIO_INEN = 0x0600; need PF5 (0x20) and PF6 (0x40);
}
![Page 10: Handling multiple input signals Version #2 – co-operative scheduler Version #3 – pre-emptive scheduler](https://reader036.vdocuments.mx/reader036/viewer/2022062519/5697c0261a28abf838cd59be/html5/thumbnails/10.jpg)
04/21/23 Thermal Arm Wrestling, Copyright M. Smith, ECE, University of
Calgary, Canada
10 / 24 + extras
PF registers
Direction, Data, Polarity and Enable all the same from Lab. 1
Flag Mask registers – 14-11Flag mask Interrupt data register – basically which
PF pins have been set to allow to cause interruptFlag mask Interrupt Set register – sets PF pin that is allowed to
cause an interrupt, without the need for a read – or mask – write operation
Flag Mask Interrupt Clear register – which PF pin is no longer allowed to cause an interrupt without the need for a read – and mask – write operation
Flag interrupt Sensitivity register (FIO_EDGE) – set for edge-sensitive
FIO_BOTH allows you to cause interrupts on “both” leading and trailing edges of PF signals
![Page 11: Handling multiple input signals Version #2 – co-operative scheduler Version #3 – pre-emptive scheduler](https://reader036.vdocuments.mx/reader036/viewer/2022062519/5697c0261a28abf838cd59be/html5/thumbnails/11.jpg)
EX_INTERRUPT_HANDLER(PFInter)
All PF interrupts are multiplexed. That means any interrupt on PF line gets to same ISR
We get here ifPF5 line goes from low to highPF6 line goes from low to high
How do we know which one interruptedIf PF5 interrupt then FIO_FLAG bit 5 is highIf PF6 interrupt then FIO_FLAG bit 6 is high
![Page 12: Handling multiple input signals Version #2 – co-operative scheduler Version #3 – pre-emptive scheduler](https://reader036.vdocuments.mx/reader036/viewer/2022062519/5697c0261a28abf838cd59be/html5/thumbnails/12.jpg)
Interrupt routine looks like this#define BIT5 0x20
#define BIT6 0x40
extern volatile int count;
extern volatile int stop;
EX_INTERRUPT_HANDLER(PFInterrupt) {
short int whichInterrupt = *pFIO_FLAG_D & (BIT6 | BIT5); // Brackets around (BIT6 | BIT5); very important in Quiz 3
if ( (whichInterrupt & BIT5) == BIT5) { // Brackets important in Quiz 3
count++; *pFIO_FLAG_D &= ~BIT5; // Clear interrupt bit or *pFIO_FLAG_C = BIT5; // Clear interrupt bit
}
if ( (whichInterrupt & BIT6) == BIT6) { // Brackets important in Quiz 3
stop = 1; *pFIO_FLAG_D &= ~BIT6; // Clear interrupt bit or *pFIO_FLAG_C = BIT6; // Clear interrupt bit
}
} // Can you translate this into assembly code for post-lab quiz 3
![Page 13: Handling multiple input signals Version #2 – co-operative scheduler Version #3 – pre-emptive scheduler](https://reader036.vdocuments.mx/reader036/viewer/2022062519/5697c0261a28abf838cd59be/html5/thumbnails/13.jpg)
Getting interrupts to work
void SetUpInterrupts( ) {
// SetUp_VectorTable( ); Lab. 3
// SetUp_IMASK( ); Lab. 3
register_handler(ik_ivg12, PFInterrupt);
SetUp_SIC_MASK( ); Lab. 3 SetUp_PFLinesForInterrupts( ); Lab. 3
}
![Page 14: Handling multiple input signals Version #2 – co-operative scheduler Version #3 – pre-emptive scheduler](https://reader036.vdocuments.mx/reader036/viewer/2022062519/5697c0261a28abf838cd59be/html5/thumbnails/14.jpg)
Getting interrupts to workvoid SetUpInterrupts( ) {// SetUp_VectorTable( );
Lab. 2
// SetUp_IMASK( ); Lab. 2
register_handler(ik_ivg12, PFInterrupt);
// SetUp_SIC_MASK( ); Lab. 2 *pSIC_IMASK = 0x00100000
// SetUp_PFLinesForInterrupts( );
*pFIO_FLAG_D = 0; // In case interrupt waiting
*pFIO_MASKA_S = (BIT5 | BIT 6);
}
![Page 15: Handling multiple input signals Version #2 – co-operative scheduler Version #3 – pre-emptive scheduler](https://reader036.vdocuments.mx/reader036/viewer/2022062519/5697c0261a28abf838cd59be/html5/thumbnails/15.jpg)
void StartInterrupts( ) { *pFIO_FLAG_C = (BIT4 | BIT5); // Waiting
*pFIO_MASKA_D = (BIT4 | BIT5); Lab. 2
}
![Page 16: Handling multiple input signals Version #2 – co-operative scheduler Version #3 – pre-emptive scheduler](https://reader036.vdocuments.mx/reader036/viewer/2022062519/5697c0261a28abf838cd59be/html5/thumbnails/16.jpg)
Other approaches
We could
Use PF Interrupt A for PF5 line
and PF Interrupt B for PF6 line
Writing 2 ISR’s
![Page 17: Handling multiple input signals Version #2 – co-operative scheduler Version #3 – pre-emptive scheduler](https://reader036.vdocuments.mx/reader036/viewer/2022062519/5697c0261a28abf838cd59be/html5/thumbnails/17.jpg)
Example interrupt routine In assembly codeDesign the codeStart the special ISR instructionsWrite “the subroutine” part of the ISRFinish the special ISR instructionsTest the codeOptimize for FAST ISR
ISR routines are marked for efficiency
![Page 18: Handling multiple input signals Version #2 – co-operative scheduler Version #3 – pre-emptive scheduler](https://reader036.vdocuments.mx/reader036/viewer/2022062519/5697c0261a28abf838cd59be/html5/thumbnails/18.jpg)
Design the code
![Page 19: Handling multiple input signals Version #2 – co-operative scheduler Version #3 – pre-emptive scheduler](https://reader036.vdocuments.mx/reader036/viewer/2022062519/5697c0261a28abf838cd59be/html5/thumbnails/19.jpg)
Fix the easy bits-- Unoptimized code okay at this point
![Page 20: Handling multiple input signals Version #2 – co-operative scheduler Version #3 – pre-emptive scheduler](https://reader036.vdocuments.mx/reader036/viewer/2022062519/5697c0261a28abf838cd59be/html5/thumbnails/20.jpg)
Add in the code
HINT:Easier to optimizeif use higher registers first
![Page 21: Handling multiple input signals Version #2 – co-operative scheduler Version #3 – pre-emptive scheduler](https://reader036.vdocuments.mx/reader036/viewer/2022062519/5697c0261a28abf838cd59be/html5/thumbnails/21.jpg)
Optimize the code – save ONLY the registers used
ENTER 10 cyles205 1+206 1+207 6+209 2 + 4210 1+211 12121214 1215 1 ?216 2217 2 + 4218 1
224 5 jumpMissing ssync( )236 RTI 10 cycles