Two full lessons for Lab 3! This doesn't mean that you've got some time to relax - this means that Lab 3 is a lot of work. I'll discuss it more at the end of the lesson, but you'll be interfacing with external hardware for the first time in this lab. To interface with the LCD, you need to use a protocol call SPI - the Serial Peripheral Interface. That's what we'll talk about today.
Everything we do today will prepare you for Lab 3.
Serial Communications typically involve using a single wire for data transmission as opposed to multiple wires in Parallel Communications.
Can anyone name any serial protocols?
Our MSP430 is very pin-limited. A serial protocol is beneficial in this circumstance because it uses less pins that could be devoted to other purposes. Attempting to drive a parallel interface would use up almost all of our available pins.
How many pins would we have left over for other stuff if we wanted to drive this LCD? Not many! So we've got to do something different.
In Lab 3, we're going to drive our LCD using the Serial Peripheral Interface (SPI).
SPI is probably the simplest peripheral interface there is. It involves chaining shift registers on two devices together along with a clock. With each clock cycle, a single bit transferred from the MSB of one shift register to the LSB of the other. After 8 clock cycles, an entire byte has been transferred between the chips.
Is this a half-duplex or full-duplex protocol?
It involves two devices - a master and a slave - and four signals:
There are other variants and naming conventions, but this is the standard.
It's the job of the master to provide the clock signal to the slave so that transmissions can be synchronized. The master sets all clock characteristics - frequency, phase, polarity - but must make sure they are within the slave parameters.
Here's a sample of how you might wire up a SPI interface:
The Slave Select signal allows the master to potentially use the same interface to potentially interact with multiple slaves. It's usually active low.
For some reason, TI names these signals differently:
TI's SPI subsystem also provides a Slave Transmit Enable (STE) bit - this reverses the typical functionality of SS. STE allows a slave to select from amongst multiple masters.
Hardware support for SPI on MCUs is usually very flexible. There are configuration bits in the SPI control registers that can control all of these characteristics. This is because peripherals use a wide range of SPI configurations - it's critical that you read the datasheet for the SPI component you're trying to interface with and match its expectations.
Talk about different configurable elements
On the MSP430:
Your MSP430G2553 comes configured with two Univeral Serial Communication Interfaces (USCI), A and B. These are essentially hardware state machines that can be used for multiple protocols - making it extremely easy to implement the protocols. Their function is configured using a couple of control registers.
A and B have slightly different capabilities - which you can read about in the datasheet - but they function identically for SPI. They are referred to as
UCB0. If there are multiple A and B interfaces, the numbers go up sequentially.
In the template code I provide you for Lab 3, you'll use
Open datasheet - talk about control registers (pp444)
In the MSP430 Family Users Guide, they offer a suggested SPI initialization sequence:
Setting the UCSWRST bit in the CTL1 register resets the subsystem into a known state until it is cleared. All the registers will hold their default values.
Set the appropriate bits in the control registers to configure our signal the way we want.
Remember, you've got to set UCSYNC for the system to function! Other settings are based on your particular application.
All the ports on our MSP430 are multiplexed! We need to set the PxSEL and PxSEL2 ports so that we have access to the SPI signals we need!
[Show device-specific datasheet.]
Clear the UCSWRST bit in the CTL1 register - releases the system to operate.
Use the subsystem!
To send a byte, just write to the TXBUF register. To read a received byte, read from the RXBUF register.
But you can't write to them whenever you want - there could be an ongoing transmission.
You've got to monitor the flags in the IFG2 register (pp 447) to know when it's safe the send.
An example of SPI configured and sending some characters:
bis.b #UCSWRST, &UCA0CTL1 bis.b #UCCKPL|UCMSB|UCMST|UCSYNC, &UCA0CTL0 ; don't forget UCSYNC! bis.b #UCSSEL1, &UCA0CTL1 ; select a clock to use! bis.b #UCLISTEN, &UCA0STAT ; enables internal loopback bis.b #BIT4, &P1SEL ; make UCA0CLK available on P1.4 bis.b #BIT4, &P1SEL2 bis.b #BIT2, &P1SEL ; make UCA0SSIMO available on P1.2 bis.b #BIT2, &P1SEL2 bis.b #BIT1, &P1SEL ; make UCA0SSOMI available on P1.1 bis.b #BIT1, &P1SEL2 bic.b #UCSWRST, &UCA0CTL1 ; enable subsystem send mov.b #0xBB, &UCA0TXBUF ; place a byte in the TX buffer wait bit.b #UCA0RXIFG, &IFG2 ; wait for receive flag to be set (operation complete) jz wait mov.b &UCA0RXBUF, r4 ; read RX buffer to clear flag jmp send ; send another byte
Here's what a single send of
0xBB looks like on the Logic Analyzer. Note how our clock is 912ns - because we chose the SMCLK to be our clock source. Note how the clock default state is high and data is read on the second clock edge - consistent with our settings.
Zoom out a little - and here's what it looks like to send
The MSP430 uses a double-buffered system to implement SPI - meaning you do not have direct access to the SPI shift registers.
The buffers you write to for transmission (TXBUF) are copied into the shift register when it's ready for the next byte. This does NOT mean that the transmission has completed - just that the buffer is ready to accept another byte.
The buffers you receive from (RXBUF) are copied from the shift register when a full byte has been received. This indicates that the full byte has been transmitted and received.
Their status can be monitored using flags TXIFG and RXIFG, both in IFG2. If you're trying to wait until the entire byte has been transmitted, you want to monitor the RXIFG flags, depending on the USCI you're using. If you don't care and just need to fill the TX buffer whenever it's ready for my data, you should monitor the TXIFG.
Lab 3 is your first opportunity to interface the MSP430 with external hardware - we'll be using pushbuttons and an LCD. It's a long lab. You'll need all the time, so make sure you don't fall behind.
You're going to be using push buttons to write a block to the LCD and move it around.
There is a lot of information on the lab handout and in the links included in the lab handout - you'll need it. Follow it closely.
Datasheets you'll need are on the course website.
Describe required functionality.
Describe A functionality.
Never forget to ground your logic analyzer.
If you know what to do, you don't have to listen and can work at your own pace.
Remember, the pins on our MSP430 are multiplexed because we don't have many. We need to write some code to make it available on one of our pins so we can measure it. Here's the MSP430G2553 pinout:
Looks like the SMCLK is available on P1.4 if I set the P1DIR, P1SEL, and P1SEL2 registers properly. To the Users Guide!
Using this, here's the code we need to get access to SMCLK:
mov.b #BIT4, &P1DIR mov.b #BIT4, &P1SEL forever jmp forever
After we program our device, we'll use the Logic Analyzer to look at the signal and do some measurements.
I'll hook up the black Ground wire on Pod 1 to ground on the MSP430. I'll hook up Pod 1 Wire 0 to P1.4 - the signal I'm trying to measure.
I'll go into the bus screen and select Pod 1 Wire 0 as the signal I'm trying to look at, then name the signal SMCLK.
Next, I'll go into the sampling setup screen and set the sampling speed to be the fastest possible (once every 2ns). Since this is a fast signal, I want to get the most accurate data possible.
Finally, I'll go into the Waveform screen and set the trigger on my signal to be falling edge. I'll push the Run Single button and the trigger should hit instantaneously.
Now, I can see the shape and period of the SMCLK signal. I'll drag my markers to measure falling edge to falling edge - and the distance between the markers will show at the top of my screen. That's the period of my SMCLK.
1/period = frequency - now I know the frequency of my SMCLK!
Your clock speed will most likely be slightly different from mine because there is variability across MSP430 chips - so you'll have to perform this process yourself and record your results. You'll also have to use this process to measure the length of your delays to ensure they satisfy the Lab requirements.
More information on using the Logic Analyzer is available here.