Laboratory 1: Programming and Using the GPIO Lines Page |1 Lab 1 Block Diagram – Looking up from underneath the board :-) (Opportunities for a Quiz or Exam questions are obvious) Task 6.1: Demo using the TARD_OS super-loop and your GPIO driver You should now be able to go back and run this super-loop void main(void) { My_InitLED(USE_UTTCOS_GPIO); My_InitSwitches(USE_MY_GPIO); while (1) { // Activate TARD_OS Wait_Time_USeconds(WAIT_TIME ); Flash_LED6( ); // Modify the code you developed in Lab 0 for LED5 to flash LED 6 unsigned char switchBitValue = My_ReadSwitches(USE_MY_GPIO); My_WriteLEDs(USE_UTTCOS_GPIO, switchBitValue); } } Task 6.2: Developing a more controlled TARD_OS super-loop -- The MPG group use a similar format The code above just “RUNS” with no control. We need a better TARD_OS super-loop operating system to control things. So in the rest of Lab1 we will to. int main(void) { bool keepGoing_TASK1 = true; unsigned char switchBitValue = 0; // A variable shared between task My_Init_TARDOS( ); // What ever it takes – this line expresses an idea – may be code, may be a function while (keepGoing_TASK1 == true) { TIC_OneTwelvethSecond( ); Every 1/4 SECOND { DO LED6_Flash( ); } // Need to have a clock ticking 1 / 12 second is fast enough // In Lab. 10 – develop a low power mode // to make the project green – environmentally friendly Every SECOND { DO LED5_Flash( ); } Every 1/32 SECOND { switchBitValue = My_ReadSwitches(USE_MY_GPIO);} Every 1/32 SECOND BUT DELAYED A LITTLE { My_WriteLEDs(USE_UTTCOS_GPIO, switchBitValue);}; Every 1/2 SECOND { DO keepGoing_LOOP1 = ! Is_SW4_Pressed( ); } // Read -- if sw4 is pressed – quit loop if pressed } // End while Wait till SW4 released ( ); return 0; } Laboratory 1: Programming and Using the GPIO Lines Page |2 Task 6.3: Initial TARD-OS development Inside Lab1SuperLoop.h add a structure definition typedef struct TARD_OS_TASK_CONTROL { unsigned long int delay_TARD_OS; unsigned long int period_TARD_OS } TARD_OS; This allows us to rewrite our code as this Modify start of Lab 1 main Check for your typos and mine // Remember include files #define TARDOS_NO_DELAY 0x00 #define TARDOS_ONE_SECOND 0x0A #define SW4_BITMASK 0x08 int main(void) { My_Init_TARDOS( ); // What ever it takes – this line expresses an idea – may be code, may be a function TARD_OS everyQuarterSecond = { TARDOS_NO_DELAY, TARDOS_ONE_SECOND / 4}; TARD_OS everyHalfSecond = { TARDOS_NO_DELAY, TARDOS_ONE_SECOND / 2}; TARD_OS everySecond= { TARDOS_NO_DELAY, TARDOS_ONE_SECOND }; You handle the 1/32 second one with no delay, and the 1/32 one with a short delay – Just spotted a simple-to-fix DESIGN defect – look for it unsigned int keepGoing_TASK1 = ~SW4_BITMASK ; // Design change – will not use direct “Boolean” control of the loop Do a code review and the build Lab 1 main to check for typos. Want to find them now before they make a real mess of things later. I code review and build roughly every 10 lines (incremental coding) Task 6.6: Add in the Super-loop timing control for the tasks while ( (keepGoing_TASK1 & SW4_BITMASK != SW4_BITMASK)) { // Looking for SW4 to become high TIC_OneTwelvethSecond( ); // Wait in (pseudo) low power mode for 1/12 second // DESIGN REVIEW // Every 1/4 SECOND { DO LED6_Flash( ); } if (everyQuarterSecond.delay_TARD_OS == 0 ) { // Time to run the task LED6_Flash( ); everyQuarterSecond.delay_TARD_OS = everyQuarterSecond.period_TARD_OS; // Reset delay to make it start again in 3 TICS // or should it be everyQuarterSecond. delay_TARD_OS = everyQuarterSecond. period_TARD_OS - 1; // to get the LED6_Flash to go Every 1/4 SECOND // Work out the time diagram on square-lined paper and hand-in with Lab 1 report // See my Circuit Cellar article TTCOS explained part 1 on ENCM511 web page for examples } // end if (everyQuarterSecond. delay_TARD_OS == 0 ) At the bottom of the loop at the code to update the down-counter -everyQuarterSecond.delay_TARD_OS = everyQuarterSecond.delay_TARD_OS – 1; // Remove some delay // You complete the code -- Every SECOND { DO Flash_LED5( ); } // Every 1/2 SECOND{ DO keepGoing_LOOP1 = ! Is_SW4_Pressed( ); } if (everyHalfSecond. delay_TARD_OS == 0 ) { // Time to run the task keepGoing_ TASK1 = My_ReadSwitchesASM( ) & SW4_BITMASK ; // Make sure you have enough brackets to ensure operator precedence everyHalfSecond. delay_TARD_OS = everyHalfSecond. period_TARD_OS; } // end if (everyHalfSecond. delay_TARD_OS == 0 ) everyHalfSecond. delay_TARD_OS = everyHalfSecond. delay_TARD_OS – 1; // Remove some delay – Nasty syntax error here etc. } // end while (keepGoing_ TASK1 == SW4_BITMASK ) printf(“Loop 1 finished\n”); while (( My_ReadSwitches( ) & SW4_BITMASK ) == SW4_BITMASK) /* Wait for SW4 to be released */ Laboratory 1: Programming and Using the GPIO Lines Page |3 Task 6.8: Dr. Smith’s “Special Programming Tricks” Corner Every E-UNIT Test is actually a complex macro (try hovering over the word Test in a Lab1 Test) So I tried to find macros to allow me to code TARD_OS Tasks more easily OLD 1920 Story A “recently rich” person goes into a car sales-room looking for an expensive car. The person says to the salesman “How much does it cost?” The salesman replies “If you have to ask about the cost, then you can’t afford it” 2014 Story A “very busy” C++ developer goes on line to find out about C++ Macros. The person tweets “How long will take me to learn enough to be able use C++ macros in a useful way”. The answers go viral -- “If you have to ask about how much time – then you don’t have enough” These macros can’t be used during 511 Exams where I am testing that you understand the ideas of constructing superloops However, they would make perfect “documentation” of pseudo-your code when designing The macro definition code is at the end of the Lab report if you want more details