Assignment 3
ΕΛΛΗΝΙΚΗ ΔΗΜΟΚΡΑΤΙΑ
ΠΑΝΕΠΙΣΤΗΜΙΟ ΚΡΗΤΗΣ
CS428 - Embedded Systems Lab
Ενότητα: 3
Άγγελος Μπίλας
Τμήμα Επιστήμης Υπολογιστών
Assignment 3: Analog Clock
The goal of this assignment is to help you understand SPI and peripheral communication protcols and to more thoroughly familiarize yourself with the LCD and simple graphics on the LCD.
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.
Copy the files ~hy428/files/as3_aclock.tar.gz to your account. Create a file as3_readme.txt that will contain the answers to questions below.
2. Serial Peripheral Interface (SPI)
You are given the following interface for SPI.
void SPIInit(void);
unsigned int SPITxReady(void);
unsigned int SPIRxReady(void);
/* use PIO to write len bytes from buf to SPI */
void SPIWrite(UBYTE *, UBYTE);
/* use PIO to read len bytes from SPI into buf */
void SPIRead(UBYTE *buf, UBYTE len);
void SPIPIOSetData(void);
void SPIPIOClearData(void);
Functions SPIRead/SPIWrite will use programmed IO (PIO) to manage the SPI interface, rather than DMA.
2.1 Implement the above API.
2.2 Which ARM pins connect to the SPI? Which PIO registers are initialized and how, before using the SPI?
2.3 (extra credit) Implement DMA transfer functions SPIReadDMA/SPIWriteDMA using PDC (no need to use interrupts for handling DMA completions. Just check the appropriate bit in the SPI status register before initiating a fresh DMA).
3. LCD
The manual "03-dts-264 uc1601d.pdf" in the tar archive contains information about the LCD works. You will need parts of this manual for the next steps. You are given the following API for the LCD:
void DisplayInit(void);
void DisplayExit(void);
void DisplayUpdateSync(void);
void DisplaySetPixel(UBYTE X,UBYTE Y);
void DisplayClrPixel(UBYTE X,UBYTE Y);
void DisplayLineX(UBYTE X1,UBYTE X2,UBYTE Y);
void DisplayLineY(UBYTE X,UBYTE Y1,UBYTE Y2);
void DisplayErase(void);
void DisplayChar(UBYTE X,UBYTE Y,UBYTE Char);
void DisplayNum(UBYTE X,UBYTE Y,ULONG Num);
void DisplayString(UBYTE X,UBYTE Y,UBYTE *pString);
The LCD is connected to ARM via the SPI interface. Thus, all data to the LCD will be send using the SPIWrite function. Although we can read data from the LCD, in this assignment we will only be sending data to it.
Beyond actually dispalying data to the LCD, we need to maintain an internal (to the module) representation of what is displayed. To achieve this we will use represent the LCD as a 2-D array of 1-bit pixels (on/off). This data structure is called IOMapDisplay (in display.c).
3.1 Implement the functions DisplayInit, DisplayExit. DisplayInit should initiaize the SPI and any other internal data structures. DisplayExit does not need to do much at this point.
3.2 Implement the functions DisplaySetPixel/DisplayClrPixel that set/clear pixels in IOMapDisplay.
3.3 Implement the function DisplayWrite and DisplayUpdateSync that send IOMapDisplay to the LCD. DisplayWrite uses the SPI to send a sequence of bytes to the LCD. This sequence can either be a command or simply data to be displayed. DisplaySyncUpdate uses DisplayWrite to perform the following steps:
(i) send initialization commands to the LCD (the string DsiplayInitCommands).
(ii) send a command to set the current line to be displayed (our LCD is written as 8 lines of 8x100 pixels each).
(iii) send the data to be displayed to the current line on the LCD.
(iv) repeate steps (ii) and (iii) for each of the 6 LCD lines.
3.4 Implement the functions DisplayLineX, DisplayLineY that simply draw a line on the X or Y axis by setting the corresponding pixels in IOMapDisplay.
3.5 Implement the function DisplayChar that plots a specific character in IOMapDisplay. For this you need the shape of pixels that correspond to each character. This is a font. File display.c contains a definition of such a font that you can use. Each character is 6x8 pixels. Each byte in the given structure represents 8 Y pixels fo a character. Thus each character is represented with 6 bytes. To display a character on IOMapDisplay, you need to find the appropriate bytes in the font and copy them to the appropriate pixels in IOMapDisplay.
3.6 Implement the functions DisplayNum and DisplayString that simply use DisplayChar. DisplayNum should print number Num as a decimal number. (if you want, you can add an option to print as Hex and Binary).
3.7 Implement the function DisplayErase, that erases the full display.
Note that the only function that sends data to the LCD is DisplayUpdateSync. All other functions simply modify IOMapDisplay.
4. Draw an analog clock
To draw an analog clock, you may want to use the following API:
void AclockDisplayFrame(UBYTE cx, UBYTE cy, UBYTE r);
void AclockDisplayHand(UBYTE cx, UBYTE cy, UBYTE r, UWORD hh);
void AclockDisplayFrameSymbol(UBYTE cx, UBYTE cy, UBYTE r, UWORD hh);
The first function displays a circular clock frame of radius r pixels at location cx,cy. The second function displays a "hand" between (cx,cy) and the pixel at the clock frame at hh degrees from 12 o'clock. This function will be useful to draw all clock hands. You may want to extend the second function with a second parameter that will allow you to differentiate between clock hands. The third fucntion simply plots at location hh on the frame a symbol (let's say a fat dot) to indicate hour marks (or minutes as well if you wish). To perform various calculations (mainly trigonometric) you will need to use <math.h> and -lm.
4.1 Implement a module aclock.[hc] that can be used to display an analog clock.
4.2 Modify firmware.c to show both the digital clock from assignment 2 and the analog clock from assignment 3.
The goal of this assignment is to help you understand SPI and peripheral communication protcols and to more thoroughly familiarize yourself with the LCD and simple graphics on the LCD.
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.
Copy the files ~hy428/files/as3_aclock.tar.gz to your account. Create a file as3_readme.txt that will contain the answers to questions below.
2. Serial Peripheral Interface (SPI)
You are given the following interface for SPI.
void SPIInit(void);
unsigned int SPITxReady(void);
unsigned int SPIRxReady(void);
/* use PIO to write len bytes from buf to SPI */
void SPIWrite(UBYTE *, UBYTE);
/* use PIO to read len bytes from SPI into buf */
void SPIRead(UBYTE *buf, UBYTE len);
void SPIPIOSetData(void);
void SPIPIOClearData(void);
Functions SPIRead/SPIWrite will use programmed IO (PIO) to manage the SPI interface, rather than DMA.
2.1 Implement the above API.
2.2 Which ARM pins connect to the SPI? Which PIO registers are initialized and how, before using the SPI?
2.3 (extra credit) Implement DMA transfer functions SPIReadDMA/SPIWriteDMA using PDC (no need to use interrupts for handling DMA completions. Just check the appropriate bit in the SPI status register before initiating a fresh DMA).
3. LCD
The manual "03-dts-264 uc1601d.pdf" in the tar archive contains information about the LCD works. You will need parts of this manual for the next steps. You are given the following API for the LCD:
void DisplayInit(void);
void DisplayExit(void);
void DisplayUpdateSync(void);
void DisplaySetPixel(UBYTE X,UBYTE Y);
void DisplayClrPixel(UBYTE X,UBYTE Y);
void DisplayLineX(UBYTE X1,UBYTE X2,UBYTE Y);
void DisplayLineY(UBYTE X,UBYTE Y1,UBYTE Y2);
void DisplayErase(void);
void DisplayChar(UBYTE X,UBYTE Y,UBYTE Char);
void DisplayNum(UBYTE X,UBYTE Y,ULONG Num);
void DisplayString(UBYTE X,UBYTE Y,UBYTE *pString);
The LCD is connected to ARM via the SPI interface. Thus, all data to the LCD will be send using the SPIWrite function. Although we can read data from the LCD, in this assignment we will only be sending data to it.
Beyond actually dispalying data to the LCD, we need to maintain an internal (to the module) representation of what is displayed. To achieve this we will use represent the LCD as a 2-D array of 1-bit pixels (on/off). This data structure is called IOMapDisplay (in display.c).
3.1 Implement the functions DisplayInit, DisplayExit. DisplayInit should initiaize the SPI and any other internal data structures. DisplayExit does not need to do much at this point.
3.2 Implement the functions DisplaySetPixel/DisplayClrPixel that set/clear pixels in IOMapDisplay.
3.3 Implement the function DisplayWrite and DisplayUpdateSync that send IOMapDisplay to the LCD. DisplayWrite uses the SPI to send a sequence of bytes to the LCD. This sequence can either be a command or simply data to be displayed. DisplaySyncUpdate uses DisplayWrite to perform the following steps:
(i) send initialization commands to the LCD (the string DsiplayInitCommands).
(ii) send a command to set the current line to be displayed (our LCD is written as 8 lines of 8x100 pixels each).
(iii) send the data to be displayed to the current line on the LCD.
(iv) repeate steps (ii) and (iii) for each of the 6 LCD lines.
3.4 Implement the functions DisplayLineX, DisplayLineY that simply draw a line on the X or Y axis by setting the corresponding pixels in IOMapDisplay.
3.5 Implement the function DisplayChar that plots a specific character in IOMapDisplay. For this you need the shape of pixels that correspond to each character. This is a font. File display.c contains a definition of such a font that you can use. Each character is 6x8 pixels. Each byte in the given structure represents 8 Y pixels fo a character. Thus each character is represented with 6 bytes. To display a character on IOMapDisplay, you need to find the appropriate bytes in the font and copy them to the appropriate pixels in IOMapDisplay.
3.6 Implement the functions DisplayNum and DisplayString that simply use DisplayChar. DisplayNum should print number Num as a decimal number. (if you want, you can add an option to print as Hex and Binary).
3.7 Implement the function DisplayErase, that erases the full display.
Note that the only function that sends data to the LCD is DisplayUpdateSync. All other functions simply modify IOMapDisplay.
4. Draw an analog clock
To draw an analog clock, you may want to use the following API:
void AclockDisplayFrame(UBYTE cx, UBYTE cy, UBYTE r);
void AclockDisplayHand(UBYTE cx, UBYTE cy, UBYTE r, UWORD hh);
void AclockDisplayFrameSymbol(UBYTE cx, UBYTE cy, UBYTE r, UWORD hh);
The first function displays a circular clock frame of radius r pixels at location cx,cy. The second function displays a "hand" between (cx,cy) and the pixel at the clock frame at hh degrees from 12 o'clock. This function will be useful to draw all clock hands. You may want to extend the second function with a second parameter that will allow you to differentiate between clock hands. The third fucntion simply plots at location hh on the frame a symbol (let's say a fat dot) to indicate hour marks (or minutes as well if you wish). To perform various calculations (mainly trigonometric) you will need to use <math.h> and -lm.
4.1 Implement a module aclock.[hc] that can be used to display an analog clock.
4.2 Modify firmware.c to show both the digital clock from assignment 2 and the analog clock from assignment 3.
4.3 (extra credit) Make your clock as fancier.
5. Submit
Submit all files required to run the assignment as a single as3_aclock.tar.gz file, including all your answers using the submit procedure described in the policies section. Return the components you used for this assignment, following the procedure outlined in class.
5. Submit
Submit all files required to run the assignment as a single as3_aclock.tar.gz file, including all your answers using the submit procedure described in the policies section. Return the components you used for this assignment, following the procedure outlined in class.
Άδειες Χρήσης
•Το παρόν εκπαιδευτικό υλικό υπόκειται στην άδεια χρήσης Creative Commons και
ειδικότερα
Αναφορά - Μη εμπορική Χρήση - Όχι Παράγωγο Έργο 3.0 Ελλάδα
(Attribution - Non Commercial - Non-derivatives 3.0 Greece)
•Εξαιρείται από την ως άνω άδεια υλικό που περιλαμβάνεται στις διαφάνειες
του μαθήματος, και υπόκειται σε άλλου τύπου άδεια χρήσης. Η άδεια χρήσης
στην οποία υπόκειται το υλικό αυτό αναφέρεται ρητώς.
Χρηματοδότηση
•Το παρόν εκπαιδευτικό υλικό έχει αναπτυχθεί στα πλαίσια του εκπαιδευτικού έργου του διδάσκοντα.
•Το έργο «Ανοικτά Ακαδημαϊκά Μαθήματα στο Πανεπιστήμιο Κρήτης» έχει χρηματοδοτήσει μόνο τη αναδιαμόρφωση του εκπαιδευτικού υλικού.
•Το έργο υλοποιείται στο πλαίσιο του Επιχειρησιακού Προγράμματος «Εκπαίδευση και Δια Βίου Μάθηση» και συγχρηματοδοτείται από την Ευρωπαϊκή Ένωση (Ευρωπαϊκό Κοινωνικό Ταμείο) και από εθνικούς πόρους.
Τελευταία τροποποίηση: Τετάρτη, 1 Ιουλίου 2015, 7:55 PM