Controller Selection and Design

For the purposes of this project, a microprocessor built for real-time control (optimised for sensing, processing, and system actuation with minimal latency) should be used. The controller used is the Texas Instruments TMS320F28377S (C2000 MCU Family, Delfino Series). This is used on the Texas Instruments F28377S LaunchPad development board. The LaunchPad uses the 100 pin PZP version of the TMS320F28377S (rather than the 176 pin PTP version or the 337 ball ZWT version). Although it is a little limited (only 2 ADCs, and only a subset of pins available, ADC references already configured for 12 bit mode, etc.) it is easy to implement as there is no need to build the control circuitry around the microcontroller. If we were to move away from the LaunchPad, we would use the 176 pin PTP version, as it gives more flexibility than the 100 pin PZP version and doesn’t add the PCB design complexity associated with the 337 ball ZWT version. Extra flexibility with the 176 pin version includes: 20 vs. 14 ADC input pins, 4 vs. 2 ADCs, 24 vs. 15 ePWM channels, 16 vs. 9 HRPWM channels, 8 vs. 6 SDFM channels, etc.

Powerful processing (CLA real-time coprocessor), advanced actuation (HRPWM), etc.

LaunchPad pin allocation (

  • SCI: To use SCI over USB on LaunchPad, need to assign GPIO84 (pin 85) to SCITXDA , and GPIO85 (pin 86) to SCIRXDA
  • CAN: To use CAN on LaunchPad, need to assign GPIO70 (pin 76) to CANRXA, and GPIO71 (pin 77) to CANTXA
  • GPIO: To use GPIO to drive LEDs on LaunchPad, need to assign GPIO 12 (pin 3) for red LED, and GPIO13 (pin 4) for blue LED
    • Should also assign GPIO for relay driver
    • Possibly also use GPIO for parallel reading from octa sensing ADC
  • SDFM
  • ADC
  • SPI x 2:
    • One for quad DAC to oscilloscope
    • One for octa ADC for sensing
  • PWM x as many as possible

Real-Time Control

A real-time control system is one that must process information and produce a response within a specified time. The input corresponds to an event in the physical world and so the output must relate to that same event.

Real-time system design involves four main responsibilities:

  • Task management and scheduling. Tasks must be allocated priorities. Watchdog timers should be used to see if a task is taking too long, then trigger a restoring task and provide debugging information.
  • (deferred) interrupt servicing. ISR (interrupt service routines) should be fast, otherwise other tasks are delayed. Try to avoid interrupt priorities (adds complexity and problems/opportunities known in task scheduling to the interrupt handling), and interrupt nesting.
  • Inter-process communication and synchronisation
  • Memory management

Look into TI-RTOS, SYS/BIOS, DSP/BIOS! This is a good lecture series from TI:

My design:

  • PWM at 5kHz
  • Interrupts at zero and mid-point of PWM (10kHz)
    • These interrupts trigger synchronous ADC sampling
      • End of ADC sampling triggers an interrupt which starts PLL code, then control code (can this happen on the CLA coprocessor?)
  • Fault checking (DC bus voltage too high, output current too high, voltage spike on grid) should be an asynchronous highest priority interrupt (trip zone?)
  • Interrupts at lower frequencies (periods of 1ms, 10ms, 200ms, 1s, etc.) for things like state checking (has the PLL locked? can the relay be closed? is the DC bus voltage within range?), and comms.
  • Higher frequency tasks should generally be higher priority
    • Nest all higher frequency interrupts in each interrupt? This means as soon you get into an ISR, you need to modify interrupt enable regs for whichever interrupts you want enabled, then re-enable global interrupts. This way, if another interrupt comes along during the ISR then it will be serviced. Read more here. FULL INSTRUCTIONS HERE.
    • Alternatively, I could simply use the ISR to enable a flag, then leave the ISR, and the main process can check for the flag, and act upon it. If multiple flags are set then it will act upon the highest one. The problem is that if it’s in a long low priority task, even if a higher priority interrupt comes along and sets a flag, it won’t be addressed until after the low priority task has finished.
  • Excellent example HERE (chapter 9)!