CS428 Embedded Systems Lab


Assignment 2: Digital Clock

The goal of this assignment is to help you understand timers, interrupts, and introduce you to using the display (LCD) and sound via the corresponding communication protocols/peripherals. 

1. Get a lego kit from the lab!

Return the components you have used for the previous assignment. For this assignment you will need the lego nxt controller, the charger for the controller battery, and a usb cable. Follow the same procedure as for the previous assignments.

Please refer
to the Assignments page for information about forking the assignment repo. Create a file as2_readme.txt that will contain answers to any questions below and your remarks about your implementation. 

2. Display time as HH:MM:SS

Modify display.[ch] from the previous assignment to provide a call 

   

printtime(UBYTE hh, UBYTE mm, UBYTE ss); 

    


that displays time in the format HH:MM:SS (you can always make it more fancy if you want). 

2.1 Via which communication protocol/peripheral does data and commands get writtent to the LCD? 

2.2 Does updating the LCD require using interrupts at all? 

2.3 Does updating the LCD occupy the CPU significantly? Does it require waiting on certain events? If yes is this high overhead? If no, how is this achived?


3. Setup and use the PIT

Read from the appropriate manual how the PIT works.
Note that the PIT runs at master clock (MSC) / 16.
Find the appropriate definitions in AT91SAM7S256.h. Implement the following calls of the pit.h interface. 

 

    void    PITEnable(void); 

    void    PITDisable(void);

    ULONG   PITRead(void);

    


These calls require reading or writing a single memory mapped location. Next, implement the following calls.

 

    UWORD   PITTicks2ms(ULONG ticks);

    UWORD   PITTicks2s(ULONG ticks);

    void    spindelayms(ULONG ms);

    


These calls simply perform support functions. The first two convert a number of PIT ticks to milliseconds or seconds. The last one simply delays for ms milliseconds by spining on the PIT value.

3.1 Implement a main function that prints the time and udpates the display every second. 

3.2 What is the maximum value that can be read from the PIT? How many milliseconds is this?


4. Setup and use the AIC

Read from the appropriate manual how the AIC works. Implement the interface aic.h to the advanced interrupt controller. This interface allows you to enable or disable specific interrupts in the AIC. Initializing the AIC is merely disabling all interrupts. Enabling an interrupt in the AIC requires setting up the mode of the interrupts (e.g. edge or level triggered and priority), setting up an interrupt handler, and enabling the corresponding interrupt ID. Disabling the interrupt requires clearing the interrupt, reseting the interrupt handler, and disabling the interrupt. At this point you can make all interrupts in the AIC use the lowest priority.

4.1 What is the difference between edge- vs. level-triggered interrupts? Which ones will you choose to use and why? 

5. Setup and use PIT interrupts

Next implement the rest of the pit.h cals:

    ULONG     PITReadReset(void);

    void      PITInterruptEnable(ULONG period, void (*handler)(void));

    void      PITInterruptDisable(void);

    void      PITAckInterrupt(void);

    


To enable or disable the PIT interrupt you need to enable the corresponding interrupt in the AIC, setup the period in the PIT, and enable the interrupt itself in the PIT. Disabling the interrupt involves the "inverse" steps. 


5.1 Implement main using the PIT interrupts to update the time every second. 

5.2 What is the minimum frequency of PIT interrupts (max period)?


6. Clock beeps every 10 seconds

Now we need to make the clock sound a simple beep every 10 seconds. For this you need to implement the interface sound.h.

Read from the appropriate manual how the serial synchronous controller (SSC) works. Function SoundSync() is already provided. This function makes a sound depending on the parameters used. Calling it with a pattern[]={0xFF00FF00}, rate=100, and duration=10 should make a simple beep sound. This funciton is synchronous in the sense that it waits until the sound is complete and then it returns to the caller. Your goal is to implement the asynchronous version. For implementing SoundAsync you will need to use SSC interrupts (and an interrupt handler). SoundAsync will merely initiate the sound sequence and then, the handler will ensure that it outputs the sound pattern via the SSC. You will see that you need to also implement some help functions in sound.c that are not part of the sound.h interface.

6.1 Implement the rest of the sound.h interface.
6.2 Experiment with longer patterns and different rate and duration parameters using sync and async calls.
6.3 Modify you main function to beep every 10 seconds.
6.4 Try generating a beep every 1 minute and every 1 second as well. Does everything still work fine? 

7. Extra Credit

7.1 Measure the accuracy of your digital clock over a longer period. What is its accuracy? Why is it what it is (low or high)?
7.2 Is it possible that interrupts are lost while your program is running? How can this happen and what does it mean for each peripheral you use?
7.3 Is it possible that you receive nested interrupts? Explain?
7.4 How does the sound get generated after we send data via the SSC?
7.5 Can you control the volume of the sound? Modify the sound interface to do so.
7.6 Can you generate specific tones? 

8. Submit

Submit all files required to run the assignment, including your documentation file as2_readme.txt with all your answers and remarks. Please refer to the policies for information about the submission process. Also, follow the procedure outlined in class for returning the components you used in this assignment. 

___________________________________________________________________________________________________________________________________
(c) Copyright University of Crete, Greece, Last Modified: 07-Feb-2022