Presentation is loading. Please wait.

Presentation is loading. Please wait.

General purpose timers

Similar presentations


Presentation on theme: "General purpose timers"— Presentation transcript:

1 General purpose timers
Recap of Tasks of Lab.2 Second example of setting up timer interrupts – TIMER0 rather than CORE TIMER Mid-term review

2 To be tackled today Lab. 2 – Over View
Reminder about CORETIMER interrupts New example – General purpose timer interrupts Follows the same procedure as for the CORETIMER in Lab. 2 Needs essentially the same code, so use the Lab. 2 as a template to follow 1/18/2019 TDD-Core Timer Library, Copyright M. Smith, ECE, University of Calgary, Canada

3 Show understanding of what concepts?
How to write up a “valid” (working) “C++” interrupt service routine for the timers on a microcontroller. How to set up a timer to be able to cause an interrupt. How to set-up the “C++” to handle a new interrupt without crashing Demonstrate “multi-tasking” – a main program and a background “interrupt” routine Using a test driven development approach to demonstrate validation of the other concepts 1/18/2019 TDD-Core Timer Library, Copyright M. Smith, ECE, University of Calgary, Canada

4 Lab. 2 concept CORE TIMER MMR
Registers BELONG to the CORE TIMER not the processor The Core timer is a programmable interval timer which can generate periodic interrupts. Blackfin Hardware pages onwards. The Core timer runs at the core clock (CCLK) rate. The timer includes four core Memory-Mapped Registers (MMRs), the Timer Control register (TCNTL) p 15-47, the Timer Count register (TCOUNT) p 15-47, the Timer Period register (TPERIOD) p 15-48, and the Timer Scale register (TSCALE) p 1/18/2019 TDD-Core Timer Library, Copyright M. Smith, ECE, University of Calgary, Canada

5 Lab. 2 Task 3 -- TDD for TCOUNT
You build the assembly code to copy the in-coming function parameters (passed in R0, R1 and R2) into the timer memory mapped registers TCOUNT, TPERIOD and TSCALE. Tests are provided. Make sure you read the hardware manual to understand interaction between these MMR Meaning does changing one register cause changes in another? 1/18/2019 TDD-Core Timer Library, Copyright M. Smith, ECE, University of Calgary, Canada

6 Lab. 3 concept General purpose timer MMR -- 1
TIMER0_COUNTER -- timer counter register – p 15-9 ESSENTIALLY the same role as TCOUNT DIFFERENCE – when TIMER0 is running then the TIMER0 counter is R0 – stands for read only -- not register 0 TIMER0_PERIOD -- timer period register – p 15-10 ESSENTIALLY the same role as TPERIOD TIMER0_WIDTH -- timer pulse width register – p 15-10 TIMER0_PERIOD TIMER0_WIDTH 1/18/2019 TDD-Core Timer Library, Copyright M. Smith, ECE, University of Calgary, Canada

7 Lab. 3 concept General purpose timer MMR - 2
These four registers together play the same role as the single TCNTRL register in the CORE TIMER. More registers since these timers are “fancier” – more general purpose – and can do more than the CORE-TIMER TIMER0_CONFIG -- timer configuration register. Set IRQ_ENA bit to enable the timer interrupts. TIMER_ENABLE and TIMER_DISABLE -- registers to control whether the timer is running or stopped. Note that these registers control ALL three of the general purpose timers -- you just need to set the appropriate bit for GP timer 0 TIMER_STATUS  -- timer status. In any ISR make sure that the TIMIL0 latch (in register TIMER_STATUS) is cleared before the RTI instruction is executed to ensure that the interrupt is not reissued. If not done, then you re-enter the ISR the moment you leave it. 1/18/2019 TDD-Core Timer Library, Copyright M. Smith, ECE, University of Calgary, Canada

8 We could perform similar tests on GPT as we did in Lab. 2 on CORETIMER
#define PERIOD_VALUE 0x30000 #define WIDTH_VALUE 0x40000 TEST(GPTimerPERIOD, SMITH_TEST) { StopGPTimer0ASM(); WatchDataClass<unsigned long int> timer_access(1, (unsigned long int *) pTIMER0_PERIOD); WATCH_MEMORY_RANGE(timer_access, Init_GPTimer0ASM(PERIOD_VALUE, WIDTH_VALUE)); CHECK(timer_access.getFinalValue(0) == PERIOD_VALUE); } TEST(GPTimerWidth_1, DEVELOPER_TEST) { WatchDataClass<unsigned long int> timer_access(1, (unsigned long int *) pTIMER0_WIDTH); CHECK(timer_access.getFinalValue(0) == PERIOD_VALUE - 1); 1/18/2019 TDD-Core Timer Library, Copyright M. Smith, ECE, University of Calgary, Canada

9 Lab. 2 Tasks 5 and 6 -- Concept Lab. 3 – Same idea – except using GPT
main( ) Set up LED and PF operation Set up Timer Interrupts and THEN activate them Change volatile variables start_next_picture and next_line using SW1 and SW2 manually Interrupt service routine in the background suspends operation of main( ) at certain time intervals When CORE-TIMER expires – unpredictable when it will occur Task 5 – flashes LED 5 – SMALLEST (UNSET) VCR Task 6 -- Change volatile variables start_next_picture and next_line very quickly and automatically SMALLEST TV AND VCR 1/18/2019 TDD-Core Timer Library, Copyright M. Smith, ECE, University of Calgary, Canada

10 Some ideas about controlling devices DIRECTLY from “C++”
C++ is derived from C, which was designed as a “processor independent” assembly language IF YOU KNEW EXACTLY WHAT YOU WERE DOING Big problem is making sure that your C code handled registeres correctly Byte operations – how? Need to use volatile operations (did you remember) I would always advise – write in C++ until you need to talk to the hardware – talk to the hardware in assembly code, and know how to handle C++ to assembly language calls 1/18/2019 TDD-Core Timer Library, Copyright M. Smith, ECE, University of Calgary, Canada

11 pTCOUNT – means what? You have already used this in Lab. 2
Blackfin C++ has a series of built in “extensions” that this C++ more reliable for accessing hardware. Example Blackfin Assembly code P0.L = lo(TCOUNT); P0.H = hi(TCOUNT); R0 = 6; [P0] = R0; ssync; Blackfin C++ code to do the same thing #include <cdefsbf533.h> *pTCOUNT = 6; Ssync( ); 1/18/2019 TDD-Core Timer Library, Copyright M. Smith, ECE, University of Calgary, Canada

12 Lab. 2 Build the C++ ISR routine -- TLD
NOT W1C -- Should this be unsigned long temp = *pTCNTL; // Hardware read unsigned long mask = ~TINT; // Flip all bits temp = temp & mask; // Zero only TINT *pTCNTL = temp; // WRITE to hardware 1/18/2019 TDD-Core Timer Library, Copyright M. Smith, ECE, University of Calgary, Canada

13 Solution for Testing ISR -- 1
Make sure that no CORETIMER interrupt can accidentally occur Tell the operating system that when the core timer causes the special core timer bit (related to ik_timer) in the ILAT register to be set then the ISR called TIMER_ISR (our chosen name) should be called NOTE: This just sets up the INTERRUPT VECTOR – it does not start the interrupt 1/18/2019 TDD-Core Timer Library, Copyright M. Smith, ECE, University of Calgary, Canada

14 Key components of C++ ISR -- 2
SPECIAL NAME THIS SPECIAL NAME IS DEFINED IN THE SPECIAL HEADER FILES MANY ERROR MESSAGES IF NOT INCLUDED 1/18/2019 TDD-Core Timer Library, Copyright M. Smith, ECE, University of Calgary, Canada

15 FOUR STEPS NEEDED for setting up and then activate the CORE TIMER ISR (main() )
Now back in Lab. 2 project and NOT in Lab2Tests – all the tests are automatically disconnected VCR light should now BLINK The four steps IN THIS ORDER AVOID RACE CONDITIONS interrupts going off when not expected 1/18/2019 TDD-Core Timer Library, Copyright M. Smith, ECE, University of Calgary, Canada

16 Since we now better understand interrupts -- can “build the tests first”
First test – can we link to the GPT ISR code? Need a stub C++ function for Timer0_ISR_CPP Need a stub asm function for Timer0_ISR_ASM When building the tests, the linker will inform you of the name-mangling you need to use in the ASM code TEST(LinkToISR, SMITH_TEST) { register_handler(ik_ivg11, Timer0_ISR_CPP); CHECK(true); register_handler(ik_ivg11, Timer0_ISR_ASM); register_handler(ik_ivg11, EX_INT_IGNORE); } CORETIMER used ik_timer 1/18/2019 TDD-Core Timer Library, Copyright M. Smith, ECE, University of Calgary, Canada

17 What is the ISR going to be doing
Uses many of the ideas from the smallest VCR and smallest Movie problem in Lab. 2 Means that will be re-using a lot of the code from Lab. 2 Interrupt service routine will be using WriteLEDASM( ) within 2 new functions DisplayTemperatureCPP( ) DisplayAverageTemperatureModeCPP( ); 1/18/2019 TDD-Core Timer Library, Copyright M. Smith, ECE, University of Calgary, Canada

18 DisplayTemperatureCPP( ) part of the GPT ISR
Use WriteLEDASM( ) to display the temperature in either Celsius or Fahrenheit volatile global short int variable temperature calculated as part of main( ) from reading from a thermal sensor – Analog Devices TMP03 For this test, set temperature to a known value Remember that short int requires R0 = W[Px] (X); type of operations in assembly code 1/18/2019 TDD-Core Timer Library, Copyright M. Smith, ECE, University of Calgary, Canada

19 Example Test – display Celsius
TEST(ISRCPP_temperature_display, DEVELOPER_TEST) { InitializeLEDInterfaceASM( ); ResetDisplay( ); WriteLEDASM(0); temperature_display_mode = true; centigrade = true; temperature = 24; register_handler(ik_ivg11, Timer0_ISR_CPP); raise(SIGIVG11); long int LEDdisplay = ReadLEDASM( ); CHECK(LEDdisplay & BIT5); CHECK( (LEDdisplay & BITS4to0) == 24); 1/18/2019 TDD-Core Timer Library, Copyright M. Smith, ECE, University of Calgary, Canada

20 Finish test – this time Fahrenheit
WriteLEDASM(0); temperature_display_mode = true; centigrade = false; temperature = 6; raise(SIGIVG11); LEDdisplay = ReadLEDASM( ); CHECK((LEDdisplay & BIT5) == 0); CHECK( (LEDdisplay & BITS4to0) == 3); } 1/18/2019 TDD-Core Timer Library, Copyright M. Smith, ECE, University of Calgary, Canada

21 DisplayAverageTemperatureModeCPP( ); part of the GPT ISR
Use WriteLEDASM( ) to display whether the average temperature (calculated in main( )) is increasing, decreasing or staying the same Sort of “temperature dancing lights” If the same – flash all lights on and off If increasing – race the lights to the left (0x00, 0x01, 0x02, 0x04, 0x08 etc) If decreasing – race the lights to the right (0x00, 0x20, 0x10, 0x08 etc) Basically more practice with left and right shift 1/18/2019 TDD-Core Timer Library, Copyright M. Smith, ECE, University of Calgary, Canada

22 Again write the Test Then write code to satisfy the test
TEST(StableTemperature_ISR_CPP, DEVELOPER_TEST) { InitializeLEDInterfaceASM( ); ResetDisplay( ); temperature_display_mode = false; temperature_change = 0; register_handler(ik_ivg11, Timer0_ISR_CPP); raise(SIGIVG11); long int first_value = ReadLEDASM( ); long int second_value = ReadLEDASM( ); CHECK( second_value == (0x3F - first_value)); 1/18/2019 TDD-Core Timer Library, Copyright M. Smith, ECE, University of Calgary, Canada

23 Stable temperature test – part 2
for (int count = 0; count < 6; count++) { raise(SIGIVG11); first_value = ReadLEDASM( ); second_value = ReadLEDASM( ); CHECK( second_value == (0x3F - first_value)); } // The ISR routine will turn all bits on (0x3F) and then all bits off (0x00) // However, we don’t know whether we started with 0x00 or started with // 0x3F – this form of the test means we don’t have to worry about it. 1/18/2019 TDD-Core Timer Library, Copyright M. Smith, ECE, University of Calgary, Canada

24 Test in a similar manner for increasing temperature
TEST(IncreasingTemperature_ISR_CPP, DEVELOPER_TEST) { InitializeLEDInterfaceASM( ); ResetDisplay( ); temperature_display_mode = false; temperature_change = 1; register_handler(ik_ivg11, Timer0_ISR_CPP); raise(SIGIVG11); long int first_value = ReadLEDASM( ); CHECK(first_value == 0x0); for (int count = 0; count < 6; count++) { first_value = ReadLEDASM( ); CHECK(first_value == (1 << count)); } 1/18/2019 TDD-Core Timer Library, Copyright M. Smith, ECE, University of Calgary, Canada

25 Main Task – not our Lab. 3 – same idea
int main( ) { // Initialize_ProgrammableFlagsASM( ); // InitializeLEDInterfaceASM( ); // Now use Init_GPTimer0ASM( ) to set the GPTimer register values; // Use register_handler( ) to point C++ towards Timer0_ISR_ASM ResetDisplay( ); // 2 lines of code needed to activate the timer and timer interrupts long int switch_result = 0; while (1) { switch_result = ReadProgrammableFlagBitsASM( ); // Read the switches // Later -- we will connect SW1 to the temperature sensor // and actually measure, rather than simulate, the temperature if ((switch_result & SW1) == SW1) temperature_change = 1; else temperature_change = 0; if ((switch_result & SW2) == SW2) temperature_display_mode = true; else temperature_display_mode = false; if ((switch_result & SW3) == SW3) temperature = 15; else temperature = 17; } 1/18/2019 TDD-Core Timer Library, Copyright M. Smith, ECE, University of Calgary, Canada

26 To be tackled today Lab. 2 – Over View
Reminding about CORETIMER interrupts New example – General purpose timer interrupts Follows the same procedure as for the CORETIMER in Lab. 2 Needs essentially the same code, so use the Lab. 2 as a template to follow 1/18/2019 TDD-Core Timer Library, Copyright M. Smith, ECE, University of Calgary, Canada


Download ppt "General purpose timers"

Similar presentations


Ads by Google