SLAAEC7 September 2024
This application makes use of the TI System Configuration tool (SysConfig) graphical interface to generate the configuration code for the device peripherals. Using a graphical interface to configure the device peripherals streamlines the application prototyping process.
There are a few key variables that
this example uses: the number of rows, the column mask value, the display period
duration, and a counter to track the number of interrupts. The number of rows is a
defined value that is used to build the memory table array. The column mask is
equivalent to the bitwise OR of the GPIO values of all of the column pins used. The
column mask is used with the memory table to determine which column pins need to be
on or off per row at a given time. The display period variable is multiplied by the
duration of time per timer interrupt to determine the amount of time that a single
memory table write is used. For this example, the display period value is defined as
100 which equates to a display period time of half a second. The counter, or
gLedState
, is used to track the number of interrupts in
relation to the display period value. This makes sure that the memory table is
written to every display
period.
#define NUMBER_OF_ROWS 3
#define COL_MASK 0x38
#define LED_DISPLAY_PERIOD 100 /* timer period = 5 ms, so display period = 500 ms */
volatile uint32_t gLedState = 0;
void LED_updateTable(uint8_t rowNumber, uint8_t LEDs);
The next
snippet of code shows the enumeration table as well as the timer Interrupt Request
(IRQ). The enumeration table defines the row states that the
rowState
switch cycles through in the timer IRQ. For each
rowState
(or row pin), the current row is turned on, the
previous row is turned off, and the columns are set by comparing the column mask
value with the memory table value. The next rowState
is then set.
This example cycles sequentially from row one to row N and back to one. Before
leaving the timer IRQ, gLedState
is incremented to track the number
of interrupts for each display
period.
typedef enum {
ROW_1,
ROW_2,
ROW_3
}rowNumber;
rowNumber rowState = ROW_1;
void LED_STATE_INST_IRQHandler(void) {
switch (DL_TimerG_getPendingInterrupt(LED_STATE_INST)){
case DL_TIMER_IIDX_ZERO:
/* State machine to auto cycle from row 1 to row N and repeat */
switch (rowState){
case ROW_1:
/* Turn on ROW_1, Turn off ROW_3 */
DL_GPIO_clearPins(ROW_PORT, ROW_ROW_1_PIN);
DL_GPIO_setPins(ROW_PORT, ROW_ROW_3_PIN);
/* Set COLUMN values */
DL_GPIO_writePinsVal(COLUMN_PORT, COL_MASK, gLedMemoryTable[0]);
rowState = ROW_2;
break;
case ROW_2:
/* Turn on ROW_2, Turn off ROW_1 */
DL_GPIO_clearPins(ROW_PORT, ROW_ROW_2_PIN);
DL_GPIO_setPins(ROW_PORT, ROW_ROW_1_PIN);
/* Set COLUMN values */
DL_GPIO_writePinsVal(COLUMN_PORT, COL_MASK, gLedMemoryTable[1]);
rowState = ROW_3;
break;
case ROW_3:
/* Turn on ROW_3, Turn off ROW_2 */
DL_GPIO_clearPins(ROW_PORT, ROW_ROW_3_PIN);
DL_GPIO_setPins(ROW_PORT, ROW_ROW_2_PIN);
/* Set COLUMN values */
DL_GPIO_writePinsVal(COLUMN_PORT, COL_MASK, gLedMemoryTable[2]);
rowState = ROW_1;
break;
}
/* Increment LED_STATE */
gLedState++;
break;
default:
break;
}
}
In the main code, all that is done is to write to the memory table every display period. This repeats indefinitely. This particular code uses binary to make determining which LED is on easier as the layout of 1s and 0s mimics the matrix layout. The binary value is 1 if an LED is on and 0 if an LED is off.
while(1){
__WFI();
/* Flash TI on repeat in half second increments */
if (gLedState == LED_DISPLAY_PERIOD){ /* Display "T" for one display period */
LED_updateTable(1, 0b111);
LED_updateTable(2, 0b010);
LED_updateTable(3, 0b010);
} else if (gLedState == LED_DISPLAY_PERIOD*2){ /* Blank for one display period */
LED_updateTable(1, 0b000);
LED_updateTable(2, 0b000);
LED_updateTable(3, 0b000);
} else if (gLedState == LED_DISPLAY_PERIOD*3){ /* Display "I" for one display period */
LED_updateTable(1, 0b111);
LED_updateTable(2, 0b010);
LED_updateTable(3, 0b111);
} else if (gLedState == LED_DISPLAY_PERIOD*4){ /* Blank for one display period */
LED_updateTable(1, 0b000);
LED_updateTable(2, 0b000);
LED_updateTable(3, 0b000);
} else if (gLedState > LED_DISPLAY_PERIOD*4){ /* Reset gLedState and start over */
gLedState = 0;
}
}