Link Search Menu Expand Document

Clocks, Timers, and Watchdogs

Prelab due 10/02/22 at 11:00 am

Writeup due 10/16/22 at 11:00 am

Note that there is no lab next week: you have two weeks for this writeup.

About

In this lab, you will familiarize yourself with the clocks on your chip, learn to use an automatic timer/counter to create a square waveform of a custom frequency, and get practice setting up a watchdog timer. You will also learn how to use a Piezo speaker and go through the process of running a suite of tests before writing up your circuit.

Lab 4 Rubric

Resources

Materials

Included in your kits:

  • Arduino MKR1000 and USB cable
  • Breadboard
  • 1 passive piezo speaker
  • 1 resistor (1kΩ)
  • Jumpers/wires

Provided:

  • None necessary

Steps

A note on the lab: please try to be mindful of the noise you are creating when testing your code. If at all possible, use the test functions provided and Serial output when debugging.

  1. Download and extract the starter code. Open song_player.ino in your IDE. Also enable line numbers in your IDE if you haven’t already, under File > Preferences.

  2. As alluded to in the pre-lab, your job in this lab will be to use a Timer/Counter to toggle a pin at a certain frequency, to play certain notes on your piezo speaker. Scroll through the starter code and discuss it with your partner. We will implement and test the TC functionality first, so we do not have to configure the Piezo pin or WDT, nor pay attention to the song parser, yet.

    Read the testNote function in note_tests.ino and make sure you understand how it works. In particular, note that in order for the test to work, you must include the

     intcount += 1;
    

    line in the TC3_Handler() interrupt ISR (which counts the number of times TC3_Handler has been run).

  3. The lines you will have to change in the code have been annotated with comments. For example, the line you will change for this step has a comment with LAB STEP 3 above it. Set the CLOCKFREQ constant on that line to the pre-scaled frequency you determined using the values from Q3.3 and Q5.1 of the prelab.

  4. In the code, configure the GCLK according to the register bits you determined in Q4.1-4.3 of the prelab. Remember that you need to wait for the SYNCBUSY bit of the STATUS register to clear after writing to GENDIV and GENCTRL. GENDIV has been done for you.

  5. Have your code check the relevant PM bit(s) printing them to Serial. Similar to Prelab 3, the bit(s) for TC3 can be found in 16.8.10 of the datasheet.

  6. Disable the TC by zeroing the bits you determined in prelab Q4.4. Disable the TC3 interrupts for now, since you’re not playing any notes yet. Make sure this code is done before the lines that set up the NVIC (if you write the code directly under the LAB STEP 6 comment, you’ll be set). Comments in the code tell you how to reference the TC registers.

    Similar to lab 3, you can hard-code the values of the bits shifted to the relevant locations, or use the macros defined in tc.h (SAM D21 peripheral header files)

    Remember that you need to wait for the SYNCBUSY bit to clear after writing to some of the registers, described in 30.6.6.

  7. Fill out the playNote, stopPlay, and playNoteDuration functions, referencing Q5 of the prelab for the register configurations. playNoteDuration is a blocking function and is allowed to use delay. Remember to enable and disable interrupts as needed, using the bits you determined in Q4.4 of the prelab and the counter value you determinded in Q2.1 of the prelab.

    1. Remember to clear the interrupt register flag in the TC3_Handler()

    2. There shouldn’t be anything in the loop() function yet. Open the Serial Monitor in your IDE and upload and run your code on the Arduino (without any circuits). This will run the testAllNotes() function in the setup(). If you get the result that “All tests passed!”, get this checked off with a TA. Otherwise, debug your code. Have your prelab available, which will help the TAs help you.

  8. Now make the code play a song on the piezo! Wire up the following circuit:

    L04D01

    Note that the new kits include two piezo speakers – one active and one passive. You should use the passive one (the one that doesn’t have the sticker that says “remove after washing.” It also has some exposed metal on the underside, whereas the active one is covered in black plastic). Take heed to orient the “+” leg so that it is connected to the Arduino.

    1. Using the MKR1000 schematic, determine the port pin number that corresponds to pin 4 on the arduino, and set the PB_PIN variable accordingly. Referencing the registers (aka without using digitalWrite(...) pinMode(...)), configure this pin as an output and make the TC3_Handler() toggle it every time it is called (instead of using a register that ends in SET or CLR, try using the one that ends in TGL to toggle a bit!). Also remember to make stopPlay() turn the pin off.

    2. Remove the line with testAllNotes() from the setup() function and uncomment the song parsing (under the LAB STEP 8b comment).

    3. Modify the loop() function to play the song, note by note, and then pause for two seconds before playing it again.

    4. Upload, run, and debug your code. When you think it works, get it checked off by a TA.

  9. Now you will configure a watchdog timer to reset the board if the watchdog timer hasn’t been petted for 4 seconds, and to warn you after two seconds.

    1. Pet the watchdog once every iteration of the loop() function, according to your answer in prelab Q6.1.

    2. Uncomment the four lines starting with NVIC_ under the LAB STEP 9 comment.

    3. Configure and enable the WDT GCLK according to your answer in prelab Q6.2.-6.3. Remember about the SYNCBUSY bit! GENDIV has been done for you (uncomment it).

    4. Configure and enable the WDT and early warning interrupt according to your answer in prelab Q6.4. Remember to enable the early warning interrupt, and remember to wait for the SYNCBUSY bit for any registers described in 18.6.5.

    5. Complete WDT_Handler(), the early warning ISR, according to the documentation in the code.

    6. Run your code and observe the Serial monitor. What happened? Did the song play to completion? If your song did not play to completion, modify your loop() function code such that it calls play_note_duration(...) only once per execution of the loop() function (hint: you may need to define a new global variable.) Does it play to completion now? If so, increase the delay between replays of the song, and see if you can trigger the watchdog reset. Note: it is fine to shorten the song itself (e.g. "spooky:d=4,o=6,b=127:8c,f,8a,f,8c"') for ease of testing. Get this checked off by a TA.

  10. Turn in your work:

    1. Save your code as “song_player.ino”. Upload this to the “Lab 4 Code” assignment on Gradescope (include all partner(s) on the submission). You do not have to upload the three helper files that we gave you.

    2. INDIVIDUALLY, complete the Lab 4 writeup assignment on Gradescope.