We made a retro gaming system out of an MSP432 and a matrix LED. The system can run any retro game, but to demonstrate a simple game we used Snake. Everything is coded in C on code composer studios. The entire project consisted of using UARt and I2C communication the ADC, configuring the clock and I/O pins to make the entire system work. Along with the Matrix LED we used a 16 by 2 LCD to display the score, and a haptic motor to provide haptic feedback. In addition we used a joystick to control the game play and an external power supply to power the whole system.
Project Scope:
The project is to build a classical game Snake, which uses the 32x32 RGB LED Matrix as a display, and an Analog 2-Axis Thumb Joystick as a controller. A 4xAA Battery Holder, with a switch, powers the matrix LED, and a USB connection to the MSP432 powers the rest of the project. The SparkFun 16x2 SerLCD displays the score of the game and uses UART to communicate with the MSP432. The game starts by moving any direction on the Joystick and ends when the snake touches itself or the edge of the display. The LRA vibrates once the game is over, and each time the snake eats an apple. The display will also present a start screen and game over screen at the beginning and end of each playthrough.
For this project we will be writing our own UART, ADC, Matrix LED, and LCD drivers, and snake game. We will be using a prewritten I2C driver, instead of writing our own in order to operate the DRV2605L and LRA. The joystick uses a potentiometer to determine the direction of the movement, and the DRV2605L uses pull up resistors for the I2C communication. The PCB will connect the MSP to all of the other components, and therefore will contain all of the traces between pins and all of the header pins for the components to attach to. Our PCB will be a custom layout PCB, where we create the schematic from scratch and then manually route all of the connections.
Functional Block Diagram:
This is a diagram of all the components of the project and how they connect to each other on a high level. All of the components will be connected through a PCB to limit the number of wires and to create a compact design.
Wiring Diagram:
Below is a wiring diagram, showing all of the pin connections between the MSP432, the PCB, and other components. We went very detailed with this diagram, including how many pins needed to be on the PCB and the locations of pins on the MSP432, so that we could have a better idea of the wiring before the parts arrived. This will hopefully allow us to start wiring and testing our parts quickly, and design our PCB with ease.
PCB:
This is the Schematic for our PCB we labeled all of the pins instead of drawing the wire connections between them. This includes the extra pins we needed to add so the logic analyzer can be used to test and debug our project.
We began the PCB design by figuring out the dimensions of the MSP432 pins, and their distance apart from each other by downloading the MSP432 Eagle files from the Texas Instruments website.
We also added an extra set of pins for each component so that we could isolate and debug components if they didn’t work.
Below is the completely fabricated PCB that we ordered from OSHPark. It was delivered in one week. It contains only header pins as populated components because its main function is to provide easy connections between components.
When we designed the PCB we had in mind that we wanted to power the whole game system through a battery case connected to the PCB. However, we realized that we should have included footprints for a voltage converter instead of a voltage divider. This is because the resistors that we had planned to put on the PCB could not handle the 0.1A of current that was required by the matrix LED. We also wired to the incorrect power pins on the MSP432. So the MSP432 would not turn on when connected to the battery case.
Power Supply:
Calculation of Power Supply and Consumption (P= IV)
Maximum Estimated Total Power Consumption:
5*0.1+5*1*10^(-3)+5*80*48*10^(-6)+3.6*60*10^(-3)+1*3.3+5.2*0.5*10^(-3)
- 5*0.1+5*1*10^(-3)+5*80*48*10^(-6)+3.6*60*10^(-3)+1*3.3+5.2*0.5*10^(-3)
4.04 Watts
- 4.04 Watts
Maximum Estimated Total Power Supplied
1.6*4*3
- 1.6*4*3
19.2 Watts
- 19.2 Watts
We calculated the max power that could be consumed, the actual power consumed was smaller because the Matrix LED only needed 0.1A if we are turning on all of the LED’s. Also the LRA would only require power when it is vibrating which will not be very often. So we meet our power budget without adding more power supplied. We originally thought the Matrix LED would need 4 Amps to turn on all the LED’s but this was incorrect, which allowed us to be well within our power budget. Also the ending project powered the MSP, LCD, and haptic motor off of a laptop and the matrix LED off of the battery pack further reducing the power consumption of the battery pack.
Our finalized power supply ended up consisting of a USB cable from our computer to the MSP432 in order to power all components except for the Matrix LED. The Matrix LED ended up being powered by only three batteries at a total voltage of 4.5V. The reason for this was because we had not correctly wired the power supply to the Vin pin on the MSP432 in our PCB design, and resistors we were using were unable to handle the required current for the Matrix LED.
Firmware Calculations:
ADC14: For the ADC, we used the sample and hold pulse mode with one sample per every 192 ADC14CLK cycles. The source clock for the ADC14CLK was MODCLK, and the selection of 192 for the sample and hold time was completely arbitrary. We did not need to sample at a certain amount of time because the samples were already occurring fast enough so that there was no delay in the movement of the joystick and the snake.
One part of the ADC that did require calculation was the memory conversion values. If the conversion was greater than 4000 or less than 100, the ADC14_ISR would either set the joystick direction to up/down or left/right. The range of conversion values was 0 to 4092 because of the 12-bit resolution setting. The reason for the choice of >= 4000 or <=100 was so that the joystick would not be sensitive to diagonal movements, which would make the game easier to play since the snake does not move diagonally.
UART: For the UART we decided to use the 9600 baud rate because that is the default for the LCD we bought. The clock source we used was SMCLK which was at 3MHz. To calculate the N value we divided 3MHz by 9600 to get 312.5, then we knew os16 had to be one because N was greater than 16. Then we took the integer of N/16 to get that UCBRx value to be 19. Then to find UCBRFx we took the INT(N/16-INT(N/16)*16) which gave us 0x08. Finally, we looked at a table in the technical reference manual to find UCBRSx to find that it equals 0xAA. Once we had all those values we set them in the A2 register which set up the correct baud rate.
Matrix LED: For the matrix LED, we figured out that we would have to set MCLK to 48MHz because otherwise it would not update fast enough. When we had MCLK set to its default value of 12MHz, the matrix would only update at a frequency of 28Hz, which caused the display to blink. In order to combat this problem, we set MCLK to 48MHz so that the MSP432 would be able to update the pins connected to the matrix LED fast enough. Once we completed this task, the Matrix LED was able to update at about 130Hz. (Code for configuring MCLK to 48MHz: https://e2echina.ti.com/question_answer/microcontrollers/other_mcu/f/23/p/139193/391432).
Code Explanation (See Github Link for code):
Joystick: adc.c
In the adc.c file, we incorporated five functions. The ADC14_GPIO_CONFIG() function is used to put pin 5.0 and 5.2 into analog input mode by using the SELx registers. The ADC14_INIT function is used to enable interrupts globally, in the NVIC module, and in ADC14’s IER register. This function also sets up two memory control registers and puts ADC14 into repeated autoscan mode so that the MSP432 can read two different analog inputs. This was needed because the joystick has two analog outputs for the X and Y directions. The ADC14_ISR_Xout and ADC14_ISR_Yout functions basically read the conversion result and print right and/or up if the conversion result is greater than or equal to 4000. It prints left and/or up if the conversion result is less than or equal to 100. The ADC14_IRQHandler function triggered whenever the joystick is moved. When the function is triggered it calls either ADC14_ISR_Xout or ADC14_ISR_Yout based on the highest priority interrupt in the ADC14IV register. The register view within CCS was very helpful for debugging this C file. It allowed me to see that the MEM[1] register was not being loaded with conversions. After further reading in the MSP432 datasheet, I found out that I would have to use the repeat autoscan mode or manually alter the CSTARTADDx bits in order for this register to be loaded with conversion results.
UART.c for LCD
Used UART to communicate with the LCD. Used the UART interrupts and created a circular buffer in order to put bytes in and out of the TXBUF and RXBUF in the UART. Has received and send string, but the only one used is send string because the LCD doesn’t send anything back. We created a structure called bufr_t to make the circular buffer, and manipulated this circular buffer using the remove and insert byte functions. The IRQ handler is what used those functions to actually make the UART work and have it send the information. In the config function we set up the UART and the baud rate to 9600 which we chose because it is the default baud rate of the LCD.
Matrix LED code:
The snake game now plays on the matrix LED. We have several several files that make this happen one for the snake game play and one for the updating of the matrix. We also change the master clock to run at 48MHz so that the game would be smooth and without glitches (The code for running MCLK at 48MHz was copied from Texas Instruments. The link to the code is in the Appendix).
Due to very limited documentation on the Matrix LED, this component was very difficult to get running. Through the process of writing a driver for the Matrix LED, we learned that the MCLK would have to run at 48MHz. This is because when we ran our snake game code on the Matrix LED, the display would update at only 28Hz. This caused blinking on the display while we were playing the game because human eyes can detect the change in light up until about 60Hz. The 48MHz MCLK brought the update frequency to about 130Hz, which got rid of the blinking.
We also ended up figuring out that the panel is only able to light up two rows of LEDs at a time. If the address sent to the display is 4’b0000, then the 1st and 17th row of LEDs light up. It takes 32 clock cycles before all LEDs light up, and the RGB pins on the matrix LED panel select which colors to send to the LED. After all 32 clock cycles, we latched the RGB values through the LAT pin, and then enabled outputs through the OE_n pin. After a short delay, we toggled the LAT pin again and then disabled outputs, and incremented the address to 4’b0001. We kept repeating this process in our code until it reached address 15. Upon reaching address 15, we reset the address to 4’b0000. The function that contains this code is called void read(uint8_t matrix[32][32]) and can be found in the matrixLED.c file through the Github link.
Snake Code:
The code for the actual snake game can be found in the snake.c file through the Github link, and consists of a variety of functions that manipulate matrices, that are then sent to the void read(uint8_t matrix[32][32]) function in order to actually be displayed as LED colors.
Project Conclusion:
Overall, we believe that our project was a success. We completed nearly all of our project requirements, aside from the 3D printed enclosure and the PCB power supply. The select button on the joystick did not work, but we were able to work around that issue by starting the game with a down movement on the joystick
Other than these small issues, our LRA vibrated when the snake ate apples, the joystick was able to be used to determine direction, and the LCD was able to display the score through UART. We were even able to change the color of the snake from green to blue to light blue based on the joystick’s direction in the start game screen.
If we had more time, we would have liked to redo our PCB, so that we could power our whole system off of the battery pack. We would have also altered the orientation of the components on the PCB so that the controller would be easier to handle, and we would have tried to 3D print an enclosure so that the user would not be able to see all of our components.
Comments