Presentation is loading. Please wait.

Presentation is loading. Please wait.

Handling multiple input signals Version #2 – co-operative scheduler Version #3 – pre-emptive scheduler.

Similar presentations


Presentation on theme: "Handling multiple input signals Version #2 – co-operative scheduler Version #3 – pre-emptive scheduler."— Presentation transcript:

1 Handling multiple input signals Version #2 – co-operative scheduler Version #3 – pre-emptive scheduler

2 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

3 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

4 Approach #1 – Superloop approach based on Lab. 1 ideas While (loop is not stopped) { Read GPIO Flags 4 possible things possible At least 2 true at the same time 1. 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” }

5 One solution for the code int 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; }

6 Using Lab. 2 ideas Co-operative Scheduler TTCOS_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( ); }

7 Using Lab. 2 ideas Co-operative Scheduler int 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 for CheckButton( ) and convert into assembly code

8 Using Lab. 2 ideas Event Driven Using Interrupts InitAllInterfaces( ); SetUpPFInterrupts( ); StartPFInterrupts( ); while (1) { /* Wait for interrupts to occur in the background */ idle( ); -- Low power mode }

9 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); }

10 1/11/2016Thermal 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-11  Flag mask Interrupt data register – basically which PF pins have been set to allow to cause interrupt Flag 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

11 EX_INTERRUPT_HANDLER(PFInter) All PF interrupts are multiplexed. That means any interrupt on PF line gets to same ISR We get here if  PF5 line goes from low to high  PF6 line goes from low to high How do we know which one interrupted  If PF5 interrupt then FIO_FLAG bit 5 is high  If PF6 interrupt then FIO_FLAG bit 6 is high

12 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

13 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 }

14 Getting interrupts to work void 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); }

15 void StartInterrupts( ) { *pFIO_FLAG_C = (BIT4 | BIT5); // Waiting *pFIO_MASKA_D = (BIT4 | BIT5); Lab. 2 }

16 Other approaches We could Use PF Interrupt A for PF5 line and PF Interrupt B for PF6 line Writing 2 ISR’s

17 Example interrupt routine In assembly code Design the code Start the special ISR instructions Write “the subroutine” part of the ISR Finish the special ISR instructions Test the code Optimize for FAST ISR  ISR routines are marked for efficiency

18 Design the code

19 Fix the easy bits -- Unoptimized code okay at this point

20 Add in the code HINT: Easier to optimize if use higher registers first

21 Optimize the code – save ONLY the registers used ENTER 10 cyles 205 1+ 206 1+ 207 6+ 209 2 + 4 210 1+ 211 1 2121 214 1 215 1 ? 216 2 217 2 + 4 218 1 224 5 jump Missing ssync( ) 236 RTI 10 cycles


Download ppt "Handling multiple input signals Version #2 – co-operative scheduler Version #3 – pre-emptive scheduler."

Similar presentations


Ads by Google