Computer Science 230 Assignment 1 to 4 solutions

$90.00

Original Work ?

Download Details:

  • Name: assignments-wd5a6i.zip
  • Type: zip
  • Size: 939.89 KB

Category: You will Instantly receive a download link upon Payment||Click Original Work Button for Custom work

Description

5/5 - (1 vote)

Computer Science 230 Assignment 1

Objectives of this assignment

β€’ Understand short problem descriptions for which an assembly-language
solution is required.
β€’ Use AVR assembly language to write solutions to three such small problems.
β€’ Use AVR Studio to implement, simulate and test your solution. (We will not
need to use the Arduino mega2560 boards for this assignment.)
β€’ Hand draw a flowchart corresponding to your solution to the second problem.
β€’ You are not to use AVR functions in this assignment.

Part (a): Edit distance

One specialization in computer science and mathematics is information theory,
invented in the 1940s when the possibilities for the digital representation of data and
signals were first deeply investigated. An example of a concept in information theory
is edit distance, which describes how much one data string differs from another data
string.

If we examine binary numbers instead of data strings, we can see an edit
distance more clearly. For example, consider the 8-bit binary equivalents of 198 and
81:
11000110
01010001

The numbers are clearly different, and one measure of this is found by determining
the number of bit positions in which the two binary numbers differ. Shown below are
these two numbers again but with the different bits noted in bold:
11000110
01010001

That is, if we denote bit 7 as the left-most bit of each number, then bits 7, 4, 2, 1 and 0
(i.e., five bits) are different between each number. The edit distance of these two
binary numbers is therefore five (5).

Your task for part (a) is to complete the code in edit-distance.asm within the
project csc230-a1-part-a provided to you. Please read this file for more details on
what is required.

β€’ The values for which you will find the edit distance will be registers r16 and
r17
β€’ The computed edit distance must be stored in r25.
Some test cases are provided to you in the provided assembly file.

Part (b): Resetting the right-most contiguous sequence of bits

Another common task when working with bit sequences is to identify and work with
contiguous set bits. For example, consider the bit sequence shown below, with several
of the set bits shown in a bold font:
01011100

We say that the bolded set bits constitute the right-most contiguous set bits. That is,
bits 4, 3, and 2 are set. If we reset the right-most contiguous set bits of the example just
given, the result is:
01000000

Your task for part (b) is to complete the code in reset-rightmost.asm in the project
csc230-a1-part-b provided to you. Please read this file for more details on what is
required.

β€’ The bit sequence for which the right-most contiguous set bits must be reset is
in r16.
β€’ The result must be stored in r25.

Some test cases are provided to you in the provided assembly file.
You must also draw by hand the flowchart of your solution and submit a scan or
smartphone photo of the diagram as part of your assignment submission; please
ensure this is a JPEG or PDF named β€œreset-rightmost-flowchart.jpg” or β€œresetrightmost-flowchart.pdf” depending on the file format you have chosen. (Please:
No BMPs or Word files! We beg of you!)

Part (c): Addition of two packed BCDs numbers

In lectures we have seen that a number such as 7210 may be represented as an eightbit two’s complement number: 0b01001000. Another form for representing decimal
numbers that was once popular is called binary-coded decimal (BCD). For a given
number, each decimal digit (from 0 to 9) was encoded in a four-bit field. The BCD
representation of 7210 is 0b01110010, i.e., where the left nibble (0111) represents 7
and the right nibble (0010) represents

2. A larger decimal number would therefore
require more groups of four bits, that is, four bits per decimal digit.
Put differently, one result of BCD is that the hexadecimal version of the number
appears identical to the decimal, even though they are in different bases. That is, 0x72
in a BCD encoding has the same meaning as 7210.

Performing arithmetic with BCD numbers is, however, definitely not the same as with
the ordinary two’s-complement encoding we have examined in class! For example,
adding together 0x35 (5310) and 0x49 (7310) as two’s complement numbers results in
0x6E (12610).

However, as BCD, the addition 0x35 and 0x49 is 0x84. This also suggest
that the largest number which can be represented in a byte using BCD is 0x99. (We
will only concern ourselves in this assignment with positive numbers.)

Your task for part (c) is to complete the code in bcd-addition.asm in the project
csc230-a1-part-c provided to you. The code is to add two numbers represented in
BCD.
β€’ The BCD operands for addition are in r16 and r17.
β€’ The right-most two BCD digits of addition result must be in r25.
β€’ The carry (either 0 or 1) resulting from the addition must be in r24.

Please read the ASM file for more detail on what is required. In your solution you will
wish to make use of the cbr and swap instructions (amongst others).

What you must submit

β€’ Your completed work in the three source code files (edit-distance.asm,
reset-rightmost.asm, bcd-addition.asm). Do not change the names of
these files! Please do not submit any other AVR 7 Studio project files.
Please do not submit ZIP files.

β€’ Your work must use the provided skeleton files. Any other kinds of solutions
will not be accepted. (Again: Do not submit ZIP files containing the Microchip
projects!)
β€’ The scan / smartphone photo of your hand-drawn flowchart with the name
of β€œreset-rightmost-flowchart.jpg” or β€œresetrightmost-flowchart.pdf” depending on the format you have chosen.

Evaluation
β€’ 3 marks: Edit Distance solution is correct for a variety of byte pairs values
(part a).
β€’ 3 marks: Reset Rightmost is correct for different byte values (part b).
β€’ 1 mark: Hand-drawn flowchart for Rest-rightmost solution is correctly
prepared (part a).

β€’ 2 marks: BCD addition solution is correct for different pairs of BCD values
(part c).
β€’ 1 mark: All submitted code is properly formatted (i.e., indenting and
comments are suitably used), and files correctly named.
Total marks: 10

Computer Science 230 Assignment 2

Objectives of this assignment

β€’ Write and use functions.
β€’ Implement parameter passing using registers and stack.
β€’ Implement return values using registers.
β€’ Use stack frames where needed for parameter passing.
β€’ Use the Arduino mega2560 board in the course lab to implement a text
signaling display.

Semaphore signaling

One form of visually communicating a message involves transforming each letter of
the message into a visible signal. That signal may be in the form of flags (as is used in
naval flag signaling). Another is to configure a set of lights into suitably different
patterns, and this is something we will do for this assignment using the six LEDs on
the lab’s Arduino Mega boards.
A video has been prepared demonstrating some working code for all five parts of this
assignment:

The video starts, however, with a demonstration of a complete working assignment
that is flashing the message HELLOWORLD. For each of the ten letters in this message
you will see is a pattern of six LEDs (some on, some off). Even more subtly, there is
also the possibility of changing the duration of the light pattern. Breaking this down
even further, and representing an LED that is on by using β€œo” and an LEDS that is off
by using β€œ.”, you will notice the following in that opening sequence of the video:
β€’ β€œH”: ..oo.. (short duration)
β€’ β€œE”: oooooo (long duration)
β€’ β€œL”: o.o.o. (long duration)
β€’ β€œL”: o.o.o. (long duration)
β€’ β€œO”: .oooo. (long duration)
β€’ β€œW”: o.o… (short duration)
β€’ β€œO”: .oooo. (long duration)
β€’ β€œR”: oo..oo (long duration)
β€’ β€œL”: o.o.o. (long duration)
β€’ β€œD”: …..o (long duration)

Note again that letters β€œH” and β€œW” have a short duration. The encoding for all 26
letters of the alphabet can be found at the end of the starter file provided to you for
this assignment (a2-signalling.asm).

There is only one file for this assignment. Your work will be in five parts made up
of six functions, ordered from easy to more difficult, with the assumption that you will
complete earlier parts before attempting later parts. Although you do not need to
write any functions above and beyond those listed below, you are not forbidden from
doing so.

a) Write the function set_leds
b) Write the functions fast_leds and slow_leds
c) Write the function leds_with_speed
d) Write the function encode_letter
e) Write the function display_message

Part (a): Write function set_leds

set_leds:
parameters: one in r16, pass-by-value
return value: none
The parameter to set_leds determines which of the Arduino board’s six LEDs to turn
on (i.e., the ones which you would have used during some lab exercises this semester).
For some of what appears below, you may find it helpful to review once again the
materials provided for Lab #3.

Interpretation of the parameter’s value by the function is quite straightforward. You’ll
notice that the six-LED board itself on the Arduino has numbers underneath each of
the LEDs.

β€’ bit 5 of r16 controls the leftmost LED (i.e. LED 01) – if the bit is set, the light
is to be turned on, otherwise turned off …
β€’ bit 4 of r16 controls the second-to-left LED (i.e. LED 02) in a manner similar
to that above …

β€’ bit 3 of r16 controls the third-to-left LED (i.e. LED 03) …
β€’ bit 2 of r16 controls the third-to-right LED (i.e. LED 04) …
β€’ bit 1 of r16 controls the second-to-right LED (i.e. LED 05) …
β€’ bit 0 of r16 controls the rightmost LED (i.e. LED 06) …
β€’ and finally, bits 7 and 6 of r16 is ignored, regardless of value.

For example, a value in r16 that would turn on the leftmost and rightmost LEDs is
0x21 (i.e 0b00100001). A value of 0x00 would turn off all LEDs.
Also please note that this function is meant to turn on/off the LEDs regardless
of any duration for this action. LEDs will stay on or stay off until changed by
another call to set_leds with a suitably different parameter value. To obtain
effects such as turning LEDs on for a fixed period of time, you will need to use extra
code, and this you will write written later.

Some code is provided for you at the label test_a which you may use to try out your
work after writing code for the function. The video described earlier in this document
shows expected behavior of test_a. (Note that the delay functions used in this code
are provided to you already: delay_long is about one second long, and delay_short
is about one-quarter of a second long.)

Part (b): Write the functions fast_leds and slow_leds

fast_leds:
parameters: one in r16 r17, pass-by-value
return value: none
slow_leds:
parameters: one in r16 r17, pass-by-value
return value: none

The fast_leds function will turn on LEDs using the same pattern as described in part
(a) but will leave them on for about one-quarter of a second before turning them off.
Amongst other things, you must call your code for set_leds and use the various delay
functions in the provided code (e.g., delay_short).

The slow_leds function will turn on the LEDs using the same pattern as described in
part (b) but will leave them on for about one second before turning them off. Amongst
other things, you must call your code for set_leds and use the various delay
functions in the provided code (e.g., delay_long).

Some code is provided for you at the label test_b which you may use to try out your
work after writing code for these two functions. The video described earlier in this
document shows expected behavior of test_b.
Part (c): Write the function leds_with_speed
leds_with_speed:
parameters: one byte, pushed onto the stack by the caller, pass-by-value
return value: none

In the functions described within the previous two parts of the assignment, the byte
provided as a parameter encoded the LEDs to be turned on or off. This is indicated by
the way bits 5 through 0 of the parameter are set or unset. Bits 7 and 6 have been
ignored until now. In this function, we’ll begin to make use of those two left-over bits.

β€’ If the two top-most bits are set, the LED pattern is to be on for about one
second.
β€’ If the two top-most bits are unset, the LED pattern is to be on for about onequarter of a second.
As an example, to turn on all LEDs for one second, the value pushed onto the stack
would be 0xFF (i.e., 0b11111111). However, to turn them all on for one-quarter of a
second, the value pushed would be 0x3F (0b00111111). Do not worry about the other
two possible patterns for the left-most two bits as those patterns may be ignored.

Call your code for fast_leds and slow_leds as part of the implementation of this
function.
Some code is provided for you at the label test_c which you may use to try out your
work after writing code for these two functions. The video described earlier in this
document shows the expected behavior of test_c.

Part (d): Write the function encode_letter

encode_letter:
parameters: one byte, pushed onto the stack by the caller, pass-by-value
return value: r25
This document began by describing a way of encoding letters as LED light patterns,
with the example of β€œHELLOWORLD” given. Although you’re not yet ready to display the
whole message, your task for this part is to take a single upper-case letter and to
convert it into the correct pattern (lights and duration).

Towards the bottom of a2-signalling.asm you will find the label PATTERNS,
followed by an upper-case alphabet – one letter per line – with information on
LED/duration encodings. For example, the first non-comment line below PATTERNS
is:
.db “A”, “..oo..”, 1
which is to be interpreted as follows:
β€’ This line is for the letter β€œA”;
β€’ LEDS 01, 02, 05 and 06 are off in this pattern;
β€’ LEDS 03 and 04 are on in this pattern;
β€’ The lighting pattern is to appear for about one second.
Right below appears this line:
.db “B”, “.o..o.”, 2
which is to be interpreted as follows:
β€’ This line is for the letter β€œB”;
β€’ LEDS 01, 03, 04, and 06 are off in this pattern;
β€’ LEDS 02 and 04 05 are on in this pattern;

β€’ The lighting pattern is to appear for about one-quarter of a second.
So on and so forth.
The only other entry that requires some special explanation is the very last. It appears
here as something which you may choose to check – i.e. if you are looking for a letter,
Page 6 of 7
but find the dash (β€œ-β€œ) then something has gone wrong with the parameter value.
(When testing your code, the evaluators will only use upper-case letters. However,
you cannot be sure how you yourself will accidentally test your code!)

Given the letter pushed onto the stack, your function is to determine the encoding for
the letter as would be given to leds_with_speed (i.e. a byte value), and this returned
in register r25. (That is, you are not to call leds_with_speed from within
encode_letter) Make use the functions you have written earlier in this assignment
to complete the function, as well as other operations. For example, the value returned
in r25 for β€œA” would be 0b11001100 or 0xcc; the value returned in r25 for β€œB” would
be 0b00010010 or 0x12.

Some code is provided for you at the label test_d which you may use to try out your
work after writing code for these two functions. The video described earlier in this
document shows the expected behavior of test_d.

Part (e): Write the function display_message

display_message:
parameters: byte address of message in program memory which is to be
displayed; high byte of address in r25; low byte of address in r24;
messages have no spaces and contain only upper-case letters;
messages are terminated with null (ASCII code 0).
return value: none

This last function of the assignment is meant to tie together all your work so far.
Again, towards the bottom of the assembly file provided to you are a few other labels.
For example, there is this line:
WORD07: .db “THE”, 0
where WORD07 can be provided to the assembler as the address within program
memory to the string β€œTHE”. Your function will move from letter to letter, encoding
each in turn by calling encode_letter and using the return value as the parameter
to call leds_with_speed.

Some code is provided for you at the label test_e which you may use to try out your
work after writing code for these two functions. The video described earlier in this
document shows the expected behavior of test_e.

What you must submit
β€’ Your completed work in the single source code file (a2-signalling.asm);
do not change the name of this file!
β€’ Your work must use the provided skeleton a2-signalling.asm. Any other
kinds of solutions will not be accepted.

β€’ Nothing else is to be submitted – no ZIP files, no project files, no manifestos,
no video rants, nothing else!
Evaluation
β€’ 3 marks: Solution for set_leds
β€’ 2 marks: Solution for fast_leds for slow_leds
β€’ 4 marks: Solution for leds_with_speed
β€’ 6 marks: Solution for encode_letter
β€’ 5 marks: Solution for display_message

Therefore, the total mark for this assignment is 20.
Some of the evaluations above will also take into account whether or not submitted
code is properly formatted (i.e., indenting and commenting are suitably used), and
the file correctly named.

Computer Science 230 Assignment 3

Objectives of this assignment

β€’ Use multiple AVR 16-bit timers.
β€’ Write interrupt handlers for two timers.
β€’ Output a representation of program state onto the Arduino mega2560
board’s 2×16 LCD display.
β€’ Practice with writing code the implements (and using functions that depend
upon) the parameter-passing mechanism based on stack frames.

Interrupts, LCD panel

In this assignment you will use two features of the Arduino boards that have been
introduced recently in lab: interrupts and the use of the 2×16 LCD display. The
handlers required for the assignment will not be particularly complex, but they
must work precisely. (Their execution will be triggered by several of the board’s
timers.) The LCD panel will finally allow you to create board behavior that is richer
than simply turning LEDs on and off; the labs earlier this semester introduced you
to the LCD panel and to interrupts.

A big challenge of this assignment, however, is that you are now moving into an area
of programming where our debugger is of very little help. When handlers are not
correctly coded or configured, the result is a mute board. Hence it is crucial you not
only complete this assignment in the order of the four parts listed, but also build
upon each of the completed parts by coding with successive projects folders. The
idea here is that even if you struggled with part D, your success with parts A, B and C
will be in those completed project folders for those parts (i.e., the code for those
earlier parts can still run successfully).

A brief demonstration illustrating the behavior for each of the parts can be seen in
this video:

As stated earlier, this assignment is in four parts, ordered from easier to more
difficult, with each later part building upon the work of the previous parts.

A. Write code to show on the LCD panel whether or not a button is currently
being pressed.
B. Write code to show on the LCD panel which of four buttons (left, up, down,
right) is either being pressed, or if there is no button being pressed, which
button was last pressed.

C. Write code to permit the use of the β€œup” and β€œdown” buttons to set a
hexadecimal digit at the top-left of the LCD display.
D. Write code to extend your work in Part C such that using the β€œright” and β€œleft”
buttons will permit the β€œup”/”down” buttons to work in a different part of
the display’s top row.

The ZIP file distributed with this assignment contains four directories, each
consisting of a Microchip Studio project. Directory a3part-A/ is meant for part A,
a3part-B/ is for part B, etc. In directory is an A#3 starter file in which you are to
write your solution for that particular part of the assignment. (Note every directory
starts out with exactly the same file contents.) The idea is that as your work
progresses from part to part, you can copy working code from one Microchip Studio
project to the next. In that way, if a later part is not finished or does not work, it will
not interfere with your working solution to an earlier part.

Part A: Button press

After completing this part, your Arduino board’s LCD display will appear have the
following display when no button is being pressed:
and the following display when any button is being pressed:
and this behavior continues as long as the Arduino runs your program.

This semester in lab 4 you examined the way an Analog-to-Digital Converter (ADC)
is used to read buttons on the Arduino board. The ADC obtains a value from 0 to
1023 from the buttons – if the value is greater than 900, then no button on the LCD
shield is being pushed. Code from lab 4 helped you explore how you might write
code to detect which button is pressed; polling loops were an important part of your
solutions.

Interrupts could help us here to detect ADC events, but not necessarily in the way
we expect. It would be tempting to have a solution where a button press itself
results causes an interrupt. However, in practice this is rarely done because of an
electrical phenomenon known bouncing.

Consider the figure below (found at https://bit.ly/2IdyYRg):
This is a screengrab from an oscilloscope (if you’ve never heard of these, visit
https://bit.ly/1RXdkgw for a description) showing the electrical behavior of a
button being pressed.

The signal does not clearly go from voltage low to voltage
high, but goes up and down quickly before settling to a high voltage; we say that the
voltage bounces (i.e., like a rubber ball being bounced by a schoolchild on a
playground). The diagram shows that in the space of two milliseconds, a button
being pressed actually appears to the computer as if the button were rapidly
pressed a dozen or so times.

Therefore, if we used an interrupt to detect when a
button caused the voltage to go high, then we would have too many interrupts for a
single button press. So, in practice designers implement debouncing, usually in
hardware. Our Arduino boards already perform some debouncing on the buttons,
but still not enough for our purposes.

What we will use instead is a timer to sample the value of the ADC at specific
intervals (in our case, timer1 set at 10 milliseconds). Every time the interrupt
handler for timer1 is executed, its code must determine whether or not a button is
currently being pressed. If this is the case, then a value of 1 is stored in
BUTTON_IS_PRESSED (i.e., see the .dseg at the end of the assembler file); otherwise
a value of 0 is stored in this location.

So far this description indicates the need for one timer (i.e., one with a duration of
0.01 seconds). But how then is the LCD panel updated to reflect the button state (i.e.
either a β€œ-” or β€œ*” character at the lower-left corner)? Unfortunately, the interrupt
handler for timer1 itself must never call the LCD routines! In fact, no interrupt
handler is able to call LCD code. So, if the handler is not permitted1 to call
lcd_gotoxy and lcd_putchar, how do we update the display?

The answer: Use another timer in main program but make use of it via a polling
technique. This additional timer (timer3 in your program) goes off every 100
milliseconds. When the polling loop detects timer3 has reached its TOP value (i.e.,
100 ms has occurred), then the code for updating the LCD display can be executed.
The latter code will determine whether β€œ-” or β€œ*” or should appear in the area of the
LCD to indicate the button-press state. It is perfectly legitimate to re-write repeatedly
the same characters in the same locations on the LCD!

Reminder: timer3 does not use an interrupt handler!

1 My use of the phrase β€œis not permitted” is a bit strong. In fact, the assembler will
not forbid us from calling the LCD routines from an interrupt handler. However,
once the program calls such routines from a handler, the whole program will simply
stop working. In general, it is a Very Bad Idea for an interrupt handler to call other
routines, especially because we cannot always be guaranteed those routines
themselves do not depend upon interrupts. The one exception here is the code I’ve
provided to you in a function named compare_words.

Part B: β€œWhat button was pressed?”

(This part will be based on your solution to part A. That is, the code within your
a3part-B.asm will use code you have copied-and-pasted from a3part-A.asm).
In lab 4 you may have done a little bit more with buttons – in fact, you may have
even had an opportunity to write code to determine precisely which button is
pressed.

The ADC obtains a value from 0 to 1023 from that represent button states –
if the value is greater than 900, then definitely no button is being pushed. (All of the
comments earlier in part A regarding β€œnoise” and β€œbouncing” are especially
important here.) The ranges for all buttons on our LCD/button shields are
maddingly inexact and may require a bit of tweaking and tuning, but they can be
described roughly as follows:

β€’ from 0 to around 50: β€œright” button2
β€’ from around 50 to around 176: β€œup” button
β€’ from around 176 to around 352: β€œdown” button
β€’ from around 352 to around 555: β€œleft” button
β€’ from around 555 to around 800: β€œselect” button
β€’ above 900: no button is pressed

For this assignment we will use β€œleft”, β€œdown”, β€œup”, and β€œright” buttons (i.e. we’ll
ignore β€œselect”). The LCD will display along the bottom row either the current
button being pressed, or if no button is being pressed, the last button to be pressed.

Button-letter-to-LCD mappings are to be as shown below:
Although the diagram above shows all button letters, in practice only one letter will
be shown at any one time. (At the start of the program, no letter needs appear as no
button will have yet be pressed; this will be the only situation where no letter
appears in the lower-left area of the display.)

Therefore, in order to complete this part of the assignment you will need to modify
both the handler for timer1 and also the LCD-update loop that is in your code
driven by timer3. The button pressed must be stored in LAST_BUTTON_PRESSED (in
the .dseg area at the bottom of the assembly file); that is, timer1 will
β€œcommunicate” with the timer3 loop via sharing this region of memory.

And do not be too disturbed by the β€œbouncing” you see when you write your code.
Sometimes a button press will result in some other letter showing up on the display.
This can be avoided either by shorter presses or longer presses. You may be able to
reduce the occurrence of this by tweaking the range values given above for buttons
2 There is a typo on many of the boards in the lab that spells this as β€œRIGTH”.

and the ACD reading. Regardless, if such β€œbouncing” is the exception and not the
norm, then you are on the right track with your work. Perfection is hard to achieve
here and is not expected.

Part C: Setting a hexadecimal digit on the LCD top row

(This part will be based on code you have written for parts A and B. That is, the code
within your a3part3-C.asm will use code you wrote for a3part2-B.asm).
Now that you can determine which of the directional letters has been pressed, you
will use this for setting a hexadecimal digit that appears at the upper-left hand
corner of the LCD display:

To do this, the β€œup” and β€œdown” buttons will be used – β€œup” to move from a smaller
hex digit to a larger, and β€œdown” to move from larger hex digit to a smaller. At the
bottom of the assembly file you will see:
AVAILABLE_CHARSET: .db “0123456789abcdef_”, 0
which you must use to move β€œup” (i.e. from left-to-right in the sequence) and β€œdown”
(i.e. from right-to-left in the sequence”).

Notice too that there is a special character
at the end that is not a digit (β€œ_”) and that the sequence is actually a string as it is
null terminated. Your code must not hard-code the length of the sequence
string – that is, it must be possible to place a difference sequence in the assembly
code (i.e. some other sequence of letters / numbers / characters), such that this
different set of characters can be selected when the program is re-assembled and rerun.

The rate at which the letter can be changed needs to be controlled, however, and
that is accomplished by using timer4 which raises an interrupt twice a second (i.e.
every 500 milliseconds). That is, this handler will use other state maintained by the
other handlers / loops to update these three memory areas in .dseg:
β€’ TOP_LINE_CONTENT which is 16 bytes in length and is to be read by the
timer3 loop (i.e. calls to lcd_putchar for the top row, amongst other calls).
This must be initialized with space characters.

β€’ CURRENT_CHARSET_INDEX which is 16 bytes in length and where its first
location will hold the index/offset into AVAILABLE_CHARSET that resulted
from the last up/down button press. For example, if the digit β€˜d’ appears in
the top-left corner of the display, then the byte at CURRENT_CHARSET_INDEX
will hold the value 13 as a result of your implementation.

β€’ CURRENT_CHAR_INDEX can be ignored for this Part C, but its implied value
here is zero (0).
Remember that the timer3 loop is the only code permitted to call LCD routines.

Part D: Setting other hexadecimal digits on the LCD top row

(This part will be based on the code you have written for the previous parts. That is,
the code within your a3part-D.asm will use code you wrote for a3part-C.asm).
The last part of this assignment is to add behavior to the β€œright” and β€œleft” buttons so
that other hex digits on the LCD’s top row may be set.

This will involve adding extra functionality to the timer4 handler, and hopefully will
require only minimal modifications to your timer3 polling loop. The memory
regions introduced in Part C must be used for these purposes (i.e. there are 16 chars
on the top row of the LCD, there are 16 byte locations in both TOP_LINE_CONTENT
and there are 16 byte locations CURRENT_CHARSET_INDEX).

You may find that pressing the β€œright” and β€œleft” buttons result in top-row spots
being missed. In the same spirit as what was mentioned above regarding the effects
of β€œbouncing” for Part B, as long as this behavior is the exception and not the norm,
you’re on the right track with your programming.

Summing up …
By the time you are completed work for all parts of this assignment, you will have –
in essence3 – accomplished the following:
β€’ For timer1: The handler will examine the ADC for button-presses every 10
milliseconds, writing correct values into the BUTTON_IS_PRESSED and
LAST_BUTTON_PRESSED memory areas.

β€’ For timer4: The handler will examine the values in BUTTON_IS_PRESSED
and LAST_BUTTON_PRESSED every 0.5 seconds in order read and write
memory areas CURRENT_CHARSET_INDEX, CURRENT_CHAR_INDEX, and
possibly TOP_LINE_CONTENT.
β€’ For timer3: The polling loop will examine the values in the five memory
areas (listed in the two bullet points above) every 100 milliseconds. The

code in this loop will make the appropriate calls to lcd_gotoxy and
lcd_putchar to ensure the LCD display represents that state of the program.
You may simply β€œredraw” the entire LCD display every 100 milliseconds; and
that frequency, there is very little (if any) flicker.

What you must submit
β€’ Your four completed parts: a3part-A.asm, a3part-B.asm, a3part-C.asm
and a3part-D.asm. Do not change the name of these files! Do not submit
the LCD files. Submit only the .asm files listed above!

β€’ Your work must use the provided skeleton files. Any other kinds of solutions
will not be accepted.
Evaluation
β€’ 6 marks: Solution for part A
β€’ 5 marks: solution for part B
β€’ 5 marks: solution for part C
β€’ 4 marks: solution for part D

Therefore, the total mark for this assignment is 20.
Some of the evaluations above will also take into account whether or not submitted
code is properly formatted (i.e., indenting and commenting are suitably used), and
the file correctly named.

In contrast to previous assignments, Assignment #3 will be assessed
through a live code demonstration. In this process, each student will have
the opportunity to meet with a member of the teaching team. These
instructors will review the code submitted by the student and engage in a
discussion about their work during the lab session scheduled for the week
following the Assignment #3 deadline.

Computer Science 230 Assignment 4

Objectives of this assignment

β€’ Work with timers, interrupts and the LEDs using the C programming
language.

C programming language

In this assignment you will write several functions for a C language program. This
programs uses the LEDs on the lab boards (i.e., to keep this assignment simple, you
will not need to use the LCD panel, and therefore need only work with a single C
source file).

The code given to you has already configured two of the mega2560
timers (timers 1 and 3). Interrupt handlers for these timers are already provided
(i.e., you are not being asked to implement interrupt handlers). A brief
demonstration illustrating the behavior for each of the parts can be seen in this
video:

The assignment is in four parts, ordered from easier to more difficult, each part
building upon your confidence in completing the previous part.
A. Write the code for lcd_state().
B. Write the code for SOS() which uses both your completed lcd_state() plus
arrays with LED and duration data.
C. Write the code for glow().
D. Write the code for pulse_glow().

There is also a bonus available for those who have successfully completed all four
parts. It is called light_show() and is to implement the LED pattern shown on the
YouTube video (link above).

The ZIP file distributed with this assignment contains a single directory consisting
of an Micochip Studio C-language project. The skeleton file a4.c is also contained
within this project directory. I have set the configuration of the project such that
paths for both the compiler and build tools are correctly set for machines in the lab.

Part A: lcd_state()

This part of the assignment does not involve interrupts.
In assignment #2 you wrote an assembly-language function named leds_on. For
this part you will write a function that accepts two parameters:
1. The number of an LCD; and
2. A number indicating the state to which that LCD must be put (with a zero
value meaning β€œoff”, and all other values meaning β€œon”).

The function is therefore to turn an LED on or off and immediately return.
To simply your work, your function need only deal with PORTL LEDs as numbered
in the following diagram.

You can also take advantage of notational convenience when writing to I/O registers
in AVR C. Assuming the DDR register for the port has been properly configured,
turning on LED #0 can be accomplished via:
PORTL |= 0b10000000;
while turning off LED #0 can be performed by:
PORTL &= 0b01111111;
which is equivalent to:
PORTL &= ~(0b10000000);
(Hint: This function might be a good candidate for including the use of a switch
statement.)

Part B: SOS()

This part of the assignment does not directly involve the use interrupts.
By now you are familiar with Morse code, specifically that for SOS (dot dot dot, dash
dash dash, dot dot dot). We can implement dots and dashes by calls to led_state()
and _delay_ms().

You are to write a function to cause SOS to be displayed, but there is a twist here. In
the SOS() function are three variables:
1. uint8_t light[]: an array of 8-bit values indicate the LED pattern. An array
value indicates LEDs on or off by bits set or cleared, with bit 0 the state for
LED #0, bit 1 the state for LED #1, etc.

2. int duration[]: an array of ints (i.e., 16-bit values) representating the
duration in milliseconds for an LED pattern.
3. int length: the number of elements in light[] and the number of
elements in duration[].

For example, at index 6 the bit pattern indicates LED #0 is turned on for 100
milliseconds).
So the twist is that you must cause the LEDs to flash appropriately for SOS by using
these arrays: they already contain the patterns and durations required for SOS. You
can use the arrays by writing a loop in which defined/declared appropriate counter
variables, plus calls to led_state() and _delay_ms(). (A for-loop is perhaps a
better choice here than a while-loop).

Part C: glow()

This part of the assignment must use the program-scope variable named count that
is incremented by the timer 1 interrupt handler. When testing your solution, we will
evaluate glow() separately from pulse_glow(), i.e., we will call one or the other
function not both in the same test run.

Our current LEDs can be either on or off. There is, however, no easy way to set their
relative brightness. Put differently, we control LED brightness by adjusting current
through the LED, but we cannot adjust the current on our boards.
There is, however, another way to get something like a brightness control that
exploits something called pulse-width modulation. In essence it means turning an
LED on and off, doing so very rapidly, and in a way that gives the appearance of
brightness or dimness.

Suppose we wish to have a somewhat dim LED. Consider the following diagram.
This shows that every 500 microseconds, the LED is turned on for 75 microseconds
and then turned off for 425 microseconds. This cycle of 500 microseconds goes on
for as long as dimmer LED intensity is needed.
And suppose we want a brighter LED, but not as bright as the fully-on LED. Consider
the next diagram.

Now for 500 microseconds, the LED is turned on for 250 microseconds and then
turned off for 250 microseconds.
So when the LED is on, we say the signal is high, and the time for which is the signal
is high is called the on time.

Given than our period here is 500 microseconds, our
first diagram shows an on time of 75 microseconds, and the percentage of on time to
the overall period is called the duty cycle (i.e., 75/500 = 0.15 = 15% duty cycle). For
our second diagram, the duty cycle is 50% (i.e., 250/500 = 0.5 = 50% duty cycle).
Going further, a duty cycle of 0% would be an LED that is completely off, while a
duty cycle of 100% would be an LED that is completely on.

You are to implement this notion of a duty cycle. Function glow() takes two
parameters:
1. The number of an LCD; and
2. The duty cycle for that LCD expressed as a floating-point value between 0.0
and 1.0.

In order to implement this function, you must use an infinite loop, and therefore you
will only be able to ever set the glow for a single LED. The infinite loop will take
advantage of the fact that the global variable count is incremented once a
microsecond.

The loop’s form will most likely need to be somewhat similar to:
threshold = PWM_PERIOD * given duty cycle
do forever {
if (count < threshold and LED is not already on) {
turn the LED on;
} else if (count < PWM_PERIOD and LED is not already off) {
turn the LED off;
} else { /* count must be greater than PWM_PERIOD */
count = 0;
turn the LED on;
}
}

Note that PWM_PERIOD is given in the top-most β€œDO NO TOUCH” section of a4.c.
Warning: Even though we might expect the LEDs to respond in a visually linear
fashion as we change the duty cycle, unfortunately our own visual systems do not
respond in a similar way. That is, the differences in brightness that we see as
increase the duty cycle from 10% to 20% to 30% to 40% etc. will not β€œappear” as
evenly-spaced changes to our eyes and brains. Don’t worry about this (or if you
insist on worrying about this, please spend some time at https://bit.ly/2pGn61A
after you have finished the assignment).

Part D: pulse_glow()

This part of the assignment must use the program-scope variables named count
and slow_count that are incremented by the timer 1 and timer 3 interrupt handlers
respectively. When testing your solution, we will evaluate pulse_glow() separately
from glow(), i.e., we will call one or the other function but not both in the same test
run.

Once you have completed glow(), you might have some intuition of how to
implement code to mimic those glowing LEDs appearing on some devices. That is, to
increase and decrease the brightness over time, we need to increase and decrease the
duty cycle over time. As our proxy for duty time in Part C was the value assigned to
the variable threshold, this means changing the value of threshold over time.

As with Part C, in order to implement Part D you must use an infinite loop, and
therefore you will only be able to have one LED pulsing. The infinite loop will take
advantage of the fact that the global variables count and slow_count are
incremented once a microsecond and once ever 10 milliseconds respectively. Your
loop will need to modify threshold by increasing it to PWM_PERIOD or decreasing it
to 0 in some way related to changes in slow_count. While your solution need not
mimic exactly the rate of pulsing that is shown in the YouTube video, it must be very
similar.

Bonus: light_show()

(This part of the assignment does not involve interrupts.)
Using the array idea from Part B, implement the light-show pattern using a loop that
iterates through your own versions of light[] and duration[] to produce the
pattern in the YouTube video.

What you must submit
β€’ Your completed a4.c. Do not change the name of this file! Do not submit
any other project files.
β€’ Your work must use the provided skeleton files. Any other kinds of solutions
will not be accepted.

Evaluation
β€’ 4 marks: Solution for part A
β€’ 4 marks: solution for part B
β€’ 6 marks: solution for part C
β€’ 6 marks: solution for part D
β€’ 2 marks: solution for the bonus

The total mark for this assignment is 20 (i.e., if full marks are given for parts A, B, C
and D, and the bonus is correctly implemented, the mark will be 22/20).

Some of the evaluation will also take into account whether or not submitted code is
properly formatted (i.e., indenting and commenting are suitably used), and the file
correctly named.