PIC32 Uart Driver and Protocol
Uart Driver and Serial Protocol Project
Introduction
For UC Santa Cruz's Electrical Engineering program, a concentration of Communication Signals and Systems, or Electronics and Optics must be chosen and a respective design elective based of the concentration. I chose electronics and optics with the design elective ECE 121, Microcontroller System Design. The final project for this course was to create a UART driver and protocol parser for the PIC32 microcontroller. This involved understanding the hardware architecture of the PIC32, how to interpret the family reference manual, to design a UART driver that interfaces properly to the hardware, and parses the data into packages based on its message ID. This is done on the ChipKit uno32 development board by Diligent, coded and debugged using MPLab X IDE.
Block Diagram
The project can be broken up into two distinct layers, the physical layer, and the application layer. The block diagram is featured below, and detailed descriptions for each layer follow. The two layers can be easily thought of as the physical layer being interrupting code based on the tx and rx registers, and the normal running code which is the application layer.
Uart Driver and Protocol Block Diagram
Physical Layer
The physical layer consists of the UART bridge chip and is uart RX and TX registers (hardware components), the interrupt service routine functions, two instances of a circular buffer struct for rx and tx, and the Getchar and Putchar functions for adding or taking from the RX/TX buffers. This is necessary because of the limitations of the hardware register sizes.
Character and Packet Buffer Structs
The heart of the physical layer is the UartInit function and the interrupt service routine (ISR) function which triggers the ISR depending on the status of the hardware registers. The code for the Init function and ISR are featured below.
UartInit and Iterrupt Service Routine
Application layer
As for the application layer, this consists of a serial protocol that verifies and creates packages via a state machine from the incoming characters (head, length, payload, tail, checksum, end). The state machine also parses the packages based on various IDs remakes the package and sends it back to the physical layer to be transmitted back out of the Uno32 development board. The IDs of each packet determine how they are parsed, the debug ID returns the date and time. The Ping ID returns the Pong ID and the rest of the message (payload) is converted from big endian to little endian and returned. The last two ID cases are the Set and Get IDs which based on the rest of the message (payload) sets or gets the status of lit LEDS on the board. For packages without these IDs, the none-affected payload is returned. Together both layers of the program work to correctly satisfy the project requirements.
Conclusion
This project was my first true embedded project and provided valuable insights into the limitations of hardware, and its respective software solutions. The hardware registers provided on the PIC32 are only 9 bits wide (if remembered correctly), and without the use of interrupting code to enqueue and dequeue this data to larger software buffers, data would be overwritten and lost. The software techniques used such as interrupts and linked lists provide a real-world solution to these limitations. The GitHub repo includes a more descriptive report of the project and all C source files.