In the final assignment, youll take the principles from the sequencer instrument you built in assignment 2 and make it network-aware, so that it can receive messages from the outside world. That means that instead of playing a sound with a function call in your program you do it by sending a message as a change in voltage (an electrical signal) on the GPIO pins. This is a live wireits your job to make sure these electrical signals are sent & received to successfully play the sound. To illustrate1, heres AC/DC live in Paris (1979) playing Live Wire:
As youve seen in several of the labs (e.g. the blinky lab and lab 9) the discoboards GPIO pins provide a lot of flexibility for transmitting data (0
s and 1
s) as low and high voltages. In those labs, the pins were connected to LEDs & joysticks, but you might have noticed there are also a bunch of little gold-coloured pins sticking up on your board connected to nothing in particular. Any of these which are marked PXY (where X is the port number from A to F and Y is the pin number from 0 to 15) are GPIO pins as well, and you can connect them up using jumper wires like so:
You have to be a little bit careful when configuring your GPIO pins as inputs and outputs like thisit is possible to fry your board with a short circuit.
This assignment has two parts: in Part 1, you need to implement the P2300 communication protocola specific way of sending the 1
s and 0
s over the wire and interpreting them at the other end. In Part 2, you get to design your own protocol for playing sounds over the wire.
The assignment 3 template repo contains the usual starter code, including the utility libraries which have been introduced in the labs over the last few weeks. These libraries are there so that you can skip over the stuff youve already done in the previous assignments and spend your energy on actually implementing the P2300 protocol. Its still crucial that you understand what this code does, though, so if youre not sure about anything then ask a question on the COMP2300 forum using the assignment3
tag.
Background: the P2300 protocol
This assignment requires a bit more explanation than the first two. Make sure you read this section carefully so that you understand the P2300 protocol.
The purpose of P2300 is to allow two devices to work together to play music (to generate a sound waveform). The overall goal is similar to the sequencer you wrote in assignment 2, except that this time the messages to trigger a new note are sent over a wire.
To communicate over a wire (a network) its not enough to just connect two GPIO pins together with a jumper wire. You need a protocol: a way of interpreting the signals on the wire so that the sender and the receiver can understand one another. In Part 1 of this assignment you need to implement the P2300 protocol.
Wires
The P2300 protocol (which from here well refer to as just P2300) describes the way that a sender device can control the playback of a sequence of notes on a receiver device. P2300 is a simplex 2-wire protocol, which means:
- the information flows in one direction: from the device acting as the sender to the device acting as the receiver
- it requires two physical connections between the sender & the receiver
Heres a high-level diagram of the information flow:
The two lines2 (wires) used in P2300 are:
- a note on/off line which the sender uses to tell the receiver to begin playing the sound at the current pitch (frequency); i.e. to turn the sequencer on or off
- a pitch change line which the sender uses to tell the receiver to change the current pitch of the note being played
Dont get confused between the terms pitch and frequency, in the context of the P2300 protocol they mean the same thing.
In principle the P2300 connections can be made on any pair of GPIO pins on your discoboard. However, so that we can test your program easily you must use these specific pins:
- connect the note on/off line from PE12 (sender) to PH0 (receiver)
- connect the pitch change line from PE13 (sender) to PH1 (receiver)
Sender
Here is the full list of P2300 messages the sender may send to the receiver:
- a rising edge on the on/off line tells the receiver to begin making a sound (the pitch of which is determined by the current pitch sequence index)
- a falling edge on the on/off line tells the receiver to immediately stop making any sound at all (i.e. to go quiet)
- a rising edge on the pitch change line tells the receiver to increment the current pitch sequence index by 1 (regardless of whether the receiver is currently playing sound or not)
- a falling edge on the pitch change line has no effect
The sender device doesnt generate the waveform itself (thats kinda the point). It expects that theres a receiver listening on the other end which will correctly interpret the messages (the voltage changes on the on/off and pitch change lines).
Receiver
The P2300 receiver is the device which actually makes the sound. The waveform must be a sawtooth wave (unlike in assignments 1 and 2 which were square waves).
As well as responding to the P2300 messages as described above, on startup the P2300 receiver device must:
- make no sound (as if the last note on/off message was an off message)
- initialise the starting pitch sequence index to 0 (i.e. the first element in the P2300 pitch sequence)
Finally, between messages3 the receiver must either:
- continue to play a sawtooth wave at the current pitch (if the last note on/off message was an on message)
- remain silent (if the last note on/off message was an off message)
P2300 pitch sequence
In P2300 a pitch change message does not specify an actual pitch (either in Hz or as a MIDI note number). Instead, P2300 specifies that the receiver will play a pitch from a pre-arranged sequence of pitches. Each pitch change message increments the pitch sequence index by 1 (wrapping back to 0 when it is asked to increment from 7), so that the receiver will play the next pitch in the sequence.
This means that P2300 is a stateful protocol; you cant look at any particular message and know what the receiver will do, you also need to know the current pitch sequence index.
Here is the P2300 pitch sequence (remember that on startup the pitch sequence index must be initialised to 0, i.e. the starting pitch is 220Hz):
pitch sequence index | pitch (Hz) |
---|---|
0 | 220.00 |
1 | 246.94 |
2 | 261.63 |
3 | 293.66 |
4 | 329.63 |
5 | 369.99 |
6 | 392.00 |
7 | 440.00 |
In Part 1 you cannot change the pitch sequencee.g. by adding new entries to the end of the table or shuffling the order. If you do this, youre changing the P2300 protocol, and you will lose marks accordingly.
If the current pitch sequence index is the last pitch in the pitch sequence (i.e. if the pitch sequence index is 7) and a rising edge is triggered on the pitch change line, then the receiver should set the current pitch back to the first entry in the table. In other words, the pitch sequence should loop back to the beginning.
In this way, the P2300 protocol can be used to play any sequence of pitches from the set in the above table4, e.g. to skip a note in the sequence the sender should send a note off messages, then send two pitch change messages, then send the next note on message.
P2300 example
Heres an example of the P2300 protocol in action.
The diagram shows an example communication timeline for the P2300 protocol. It shows the way the voltage (either 0
or 1
) on both the note on/off wire (blue) and the pitch change wire (green) changes over time. It also shows the resulting effects of the P2300 communication; both the sound output (in orangenot to scale!) and the current pitch sequence index (in the pink boxes).
There are a few other things worth noting here:
- the required starting state is satisfied
- pitch changes only happen on a rising edge; it doesnt matter when the subsequent falling edge happens
- between messages (i.e. when there are no voltage changes on either line) the receiver keeps on playing (or being silent)
Part 1
In this assignment, you need to program your discoboard to implement both the sender and the receiver parts of P2300. This means that the jumper wires will connect from your board to itself (as described above). If youre confused about how this works, see the FAQ.
In Part 1 you need to write an assembly program which uses P2300 to play the following song (the pitch sequence indexes that are shown come from the table above) and indicate what the current value of the pitch sequence index should be. As in assignment 2 a gap (silence) between notes is represented by a -
in the pitch and pitch sequence index columns. The song must loop: when it gets to the end, it must loop back to the beginning. You must stick to the P2300 protocol and pitch sequence exactly as described aboveyou cannot modify the receivers pitch sequence/table to play the sequence.
pitch sequence index | pitch (Hz) | duration (s) |
---|---|---|
0 | 220.00 | 0.25 |
0.25 | ||
2 | 261.63 | 0.25 |
0.25 | ||
1 | 246.94 | 0.25 |
0.25 | ||
3 | 293.66 | 0.25 |
0.25 | ||
2 | 261.63 | 0.25 |
0.25 | ||
4 | 329.63 | 0.25 |
0.25 | ||
3 | 293.66 | 0.25 |
0.25 | ||
5 | 369.99 | 0.25 |
0.25 | ||
4 | 329.63 | 0.25 |
0.25 | ||
6 | 392.00 | 0.25 |
0.25 | ||
5 | 369.99 | 0.25 |
0.25 | ||
7 | 440.00 | 0.25 |
0.25 | ||
6 | 392.00 | 0.25 |
0.25 | ||
5 | 369.99 | 0.25 |
0.25 | ||
4 | 329.63 | 0.25 |
0.25 | ||
3 | 293.66 | 0.25 |
0.25 | ||
2 | 261.63 | 0.25 |
0.25 | ||
1 | 246.94 | 0.25 |
0.25 | ||
0 | 220.00 | 0.25 |
0.25 |
If all goes well, it should sound like this:
Marks will be awarded for:
- playing the notes with the correct pitches (frequency)
- playing the notes at the correct tempo (timing)
- clean note transitions (i.e. no pitches other than those in the sequence above, even for a split second)
- code structure, readability & modularity (including comments & use of functions)
- to be eligible for full marks in part-1, you must use a hardware timer to control the timing of the sender.
For Part 1, you must play the sequence by sending messages over the wire using the P2300 protocol (we will test this). If you try and play the sequence some other way (e.g. by playing it directly similar to your sequencer from assignment 2) youll get zero!
To help you out, theres a bit more starter code in the assignment 3 template compared to assignments 1 and 2. In particular, have a look in src/libcomp2300/tim7.S
for some helper functions for using the tim7 timer (for the sender part), src/libcomp2300/wave.S
for some helper functions for playing the sawtooth wave (i.e. the receiver part).In addition to this there are plenty of useful macros and functions in the src/libcomp2300/macros.S
and src/libcomp2300/utils.S
files respectively (e.g. setting up gpio pins, interrupts, priorities etc.).Please do take the time to check them out.
There is a lot going on in this assignment, so its understandable that this may seem a little overwhelming. To accommodate for this, the FAQ for this assignment is quite extensive, please do take the time to read it all.However, for your convenience here is a few of the points wed like to highlight:understand that interrupts may not work as expected when debuggingfollowing from the above, you NEED to be resetting your board (click in the black stick to the left of the joystick) before stepping through a debugging sessionthink about how to traverse the table (up and down) without changing the pitch table in memoryensure that there is no implicit (or explicit) communication between sender and receiver outside of the protocol, (no shared register or memory usage).utilize the common interrupt pitfalls to check off possible issues with your code
Part 2
In part 2, you get to implement a more advanced network protocol for controlling the music over the wire. There are a few ways to do this:
- extend the P2300 protocol in a meaningful way
- implement a serial protocol using a simple serial protocol outlined below
- design an all-new protocol
- implement an existing protocol (e.g., an industry standard such as MIDI, or OSC)
- some combination of the above (e.g. modify P2300 using ideas from an existing industry-standard protocol)
You also no longer have to play the specific note sequence from Part 1, you can play whatever sequence you likeperhaps pick one which shows off the cool features of your new protocol.
If you decide to extend the P2300 protocol, youre free to change any aspect of it. However, there is one caveatif you make a really superficial change (e.g. changing only the pitch sequence, or only changing rising edge triggers to falling edge triggers or vice versa) then that will not be enough to pass (itd be difficult to write a good design document with such a superficial change anyway). If youre unsure, check with your tutor or ask on the COMP2300 forum.
Here are some ideas for Part 2:
- extend P2300 to allow the sender to:
- play multiple notes at once (i.e. harmony)
- change the timbre of the receivers waveform (e.g. square, triangle, sine)
- adjust the amplitude (or even amplitude envelope) of the notes played by the receiver
- design a protocol where the sender can specify any pitch (frequency) for playback (instead of just choosing from a pre-determined pitch sequence), either by:
- using a clock line or timing-based protocol to send a multi-bit packet over the wire one-bit-at-a-time (a serial protocol)
- using multiple wires to send all the bits of the packet simultaneously (a parallel protocol)
- implement a real-world protocol like 1-wire, I2C, SPI or another pre-existing protocol (some of these are pretty hardbut theyre a great challenge if you want to stretch yourself)
In part-2
you will have a new file called pins.yml
. This file contains the information about which pin connections you are using (what pins are wired together). This must be filled out correctly and up to date at the time of submission or you will lose marks.As mentioned above, you dont have to use a different wiring configuration. See the FAQ for more details.
Marks for Part 2 will be awarded for a design document describing what youre doing and how you implemented it in ARM assembly language. You need to explain the what, how and why (design, implementation, and analysis) of what you have done. Although its ok if you dont do something super-complex, we do take the sophistication of your protocol into account. Using images/diagrams is encouraged. Your design document must be in pdf format (2 pages content + appendix + references) with the filename design-document.pdf
in top-level folder on the part-2
branch.
The design document for Part 2 is based on the protocol you implement (what it is, why is it like that, how is it implemented). That means dont write about the sequence of notes you choose to play, or how frequency etc. is calculated.For more help on writing the design document, check out this page.
Rate this product
[youtube https://www.youtube.com/watch?v=6tdiMdj164w]
The audio setup here is the same as assignment 2, you still need to run bl init
once at the start of your program before you do anything else. If you fail to do this then you will lose marks.
In general the start of your program should look like this:
Reviews
There are no reviews yet.