323 lines
9.3 KiB
C
323 lines
9.3 KiB
C
// Standard includes
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <assert.h>
|
|
#include <file.h>
|
|
#include <string.h>
|
|
|
|
// Driverlib headers
|
|
#include "driverlib.h"
|
|
#include "device.h"
|
|
#include "sci.h"
|
|
|
|
// Customized headers
|
|
#include "uart_drv.h"
|
|
#include "at24cm02.h"
|
|
|
|
// FreeRTOS headers
|
|
#include "FreeRTOS.h"
|
|
#include "task.h"
|
|
#include "semphr.h"
|
|
#include "queue.h"
|
|
#include "timers.h"
|
|
|
|
#if defined (__TI_EABI__)
|
|
void* malloc(size_t xSize) {
|
|
(void) xSize;
|
|
taskDISABLE_INTERRUPTS();
|
|
for (;;) {
|
|
ESTOP0;
|
|
}
|
|
}
|
|
#pragma WEAK (malloc)
|
|
#endif
|
|
|
|
#if(configAPPLICATION_ALLOCATED_HEAP == 1)
|
|
uint8_t ucHeap[configTOTAL_HEAP_SIZE];
|
|
#pragma DATA_SECTION(ucHeap, ".freertosHeap")
|
|
#pragma DATA_ALIGN(ucHeap, portBYTE_ALIGNMENT)
|
|
#endif
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
#define LED_R 41U // Red LED
|
|
#define LED_B 58U // Blue LED
|
|
|
|
#define SCI_RXDA_PIN 85U
|
|
#define SCI_TXDA_PIN 84U
|
|
|
|
// UART: SCIA
|
|
void UartSetup(void);
|
|
void UartPutChar(uint16_t charToWrite);
|
|
|
|
// CPU Timer 1
|
|
void configCPUTimer(uint32_t cpuTimer, uint32_t period_us);
|
|
__interrupt void timer1_ISR(void);
|
|
|
|
// EEPROM: AT24CM02 (2Mbit)
|
|
static EEPROM_Status eepromInitStatus = EEPROM_STATUS_NOT_INITIALIZED;
|
|
static uint16_t eepromReadData[AT24CM02_PAGE_SIZE_BYTES];
|
|
static uint16_t eepromWriteData[AT24CM02_PAGE_SIZE_BYTES];
|
|
|
|
// FreeRTOS tasks
|
|
void RedLED_Task(void *pvParameters);
|
|
void BlueLED_Task(void *pvParameters);
|
|
void EEPROM_Task(void *pvParameters);
|
|
static SemaphoreHandle_t xSemaphore = NULL;
|
|
|
|
|
|
void main(void) {
|
|
|
|
// Initializes device clock and peripherals
|
|
Device_init();
|
|
|
|
// Initializes PIE and clears PIE registers. Disables CPU interrupts
|
|
Interrupt_initModule();
|
|
|
|
// --------------------------- Initializes GPIO ---------------------------
|
|
|
|
Device_initGPIO();
|
|
|
|
GPIO_setPadConfig(LED_R, GPIO_PIN_TYPE_STD);
|
|
GPIO_setDirectionMode(LED_R, GPIO_DIR_MODE_OUT);
|
|
GPIO_writePin(LED_R, 0);
|
|
|
|
GPIO_setPadConfig(LED_B, GPIO_PIN_TYPE_STD);
|
|
GPIO_setDirectionMode(LED_B, GPIO_DIR_MODE_OUT);
|
|
GPIO_writePin(LED_B, 0);
|
|
|
|
// GPIO91/GPIO92 and I2CA are configured by the EEPROM driver.
|
|
eepromInitStatus = EEPROM_init();
|
|
|
|
// ------------------------------------------------------------------------
|
|
|
|
// Clear all interrupts and initialize PIE vector table
|
|
// Disable CPU interrupts
|
|
DINT;
|
|
|
|
// Disable CPU interrupts and clear all CPU interrupt flags
|
|
IER = 0x0000;
|
|
IFR = 0x0000;
|
|
|
|
// Initializes the PIE vector table with pointers to the shell Interrupt
|
|
// Service Routines (ISR)
|
|
Interrupt_initVectorTable();
|
|
|
|
// ------------------------- Configure CPU Timer --------------------------
|
|
|
|
// ISR functions found within this project
|
|
Interrupt_register(INT_TIMER1, &timer1_ISR);
|
|
|
|
// Configure CPU timer 1 to interrupt every given period: 1000000 us
|
|
configCPUTimer(CPUTIMER1_BASE, 1000000);
|
|
CPUTimer_clearOverflowFlag(CPUTIMER1_BASE);
|
|
|
|
// Enable CPU timer 1 interrupt and start CPU timer 1
|
|
Interrupt_enable(INT_TIMER1);
|
|
CPUTimer_startTimer(CPUTIMER1_BASE);
|
|
|
|
// ------------------------------------------------------------------------
|
|
|
|
// Enable global Interrupts and higher priority real-time debug events
|
|
EINT;
|
|
// Enable Global interrupt INTM
|
|
ERTM;
|
|
// Enable Global real-time interrupt DBGM
|
|
|
|
// ------------------------ Redirect STDOUT to SCI ------------------------
|
|
|
|
// Add the UART device. When fopen is called with a filename that
|
|
// begins "uart:", the UART device will be used to handle the file
|
|
add_device("uart", _SSA, UART_open, UART_close, UART_read, UART_write,
|
|
UART_lseek, UART_unlink, UART_rename);
|
|
|
|
// Assign stdout to be a UART device
|
|
assert(freopen("uart:", "w", stdout) != NULL);
|
|
|
|
// ------------------------------- FreeRTOS -------------------------------
|
|
|
|
xSemaphore = xSemaphoreCreateBinary();
|
|
|
|
// Create tasks dynamically
|
|
xTaskCreate(RedLED_Task,
|
|
(const char*) "RedLED_Task",
|
|
256,
|
|
NULL,
|
|
1,
|
|
NULL);
|
|
|
|
xTaskCreate(BlueLED_Task,
|
|
(const char*) "BlueLED_Task",
|
|
256,
|
|
NULL,
|
|
1,
|
|
NULL);
|
|
|
|
xTaskCreate(EEPROM_Task,
|
|
(const char*) "EEPROM_Task",
|
|
384,
|
|
NULL,
|
|
2,
|
|
NULL);
|
|
|
|
// Start the scheduler. This should not return
|
|
vTaskStartScheduler();
|
|
|
|
}
|
|
|
|
void RedLED_Task(void *pvParameters) {
|
|
(void)pvParameters;
|
|
int uart_count = 0;
|
|
while (1) {
|
|
if (xSemaphoreTake(xSemaphore, portMAX_DELAY) == pdTRUE) {
|
|
GPIO_togglePin(LED_R);
|
|
uart_count++;
|
|
printf("Hello from FreeRTOS running on the F28377S Coreboard, %d!\r\n",
|
|
uart_count);
|
|
}
|
|
}
|
|
}
|
|
|
|
void BlueLED_Task(void *pvParameters) {
|
|
(void)pvParameters;
|
|
while (1) {
|
|
GPIO_togglePin(LED_B);
|
|
vTaskDelay(pdMS_TO_TICKS(500));
|
|
}
|
|
}
|
|
|
|
void EEPROM_Task(void *pvParameters) {
|
|
uint16_t i;
|
|
uint16_t mismatchCount = 0U;
|
|
EEPROM_Status status = eepromInitStatus;
|
|
const char *operation = "initialization";
|
|
|
|
(void)pvParameters;
|
|
|
|
// Allow the EEPROM supply and power-on reset to settle before the first
|
|
// command. The datasheet requires at least 100 us after VCC is stable.
|
|
vTaskDelay(pdMS_TO_TICKS(2U));
|
|
|
|
for (i = 0U; i < AT24CM02_PAGE_SIZE_BYTES; i++) {
|
|
eepromWriteData[i] = i;
|
|
eepromReadData[i] = 0U;
|
|
}
|
|
|
|
if (status == EEPROM_STATUS_SUCCESS) {
|
|
operation = "page write";
|
|
status = EEPROM_writePage(eepromWriteData,
|
|
AT24CM02_DEFAULT_ADDRESS,
|
|
AT24CM02_PAGE_COUNT,
|
|
AT24CM02_PAGE_SIZE_BYTES,
|
|
pdMS_TO_TICKS(50U));
|
|
}
|
|
|
|
if (status == EEPROM_STATUS_SUCCESS) {
|
|
operation = "page read";
|
|
status = EEPROM_readPage(eepromReadData,
|
|
AT24CM02_DEFAULT_ADDRESS,
|
|
AT24CM02_PAGE_COUNT,
|
|
AT24CM02_PAGE_SIZE_BYTES,
|
|
pdMS_TO_TICKS(50U));
|
|
}
|
|
|
|
if (status == EEPROM_STATUS_SUCCESS) {
|
|
for (i = 0U; i < AT24CM02_PAGE_SIZE_BYTES; i++) {
|
|
if (eepromReadData[i] != eepromWriteData[i]) {
|
|
mismatchCount++;
|
|
}
|
|
}
|
|
printf("AT24CM02 page %u test: %s (%u mismatches)\r\n",
|
|
AT24CM02_PAGE_COUNT,
|
|
(mismatchCount == 0U) ? "PASS" : "FAIL",
|
|
mismatchCount);
|
|
} else {
|
|
printf("AT24CM02 %s failed: %s\r\n",
|
|
operation,
|
|
EEPROM_statusString(status));
|
|
}
|
|
|
|
vTaskDelete(NULL);
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------------------
|
|
|
|
// This function initializes the selected timer to the period specified
|
|
// by the "freq" and "period" variables. The "freq" is CPU frequency
|
|
// in Hz and the period in us.
|
|
void configCPUTimer(uint32_t cpuTimer, uint32_t period_us) {
|
|
|
|
uint32_t periodCount, freq = DEVICE_SYSCLK_FREQ;
|
|
|
|
// Initialize timer period
|
|
periodCount = ((freq / 1000000) * period_us);
|
|
CPUTimer_setPeriod(cpuTimer, periodCount);
|
|
|
|
// Set pre-scale counter to divide by 1 (SYSCLKOUT)
|
|
CPUTimer_setPreScaler(cpuTimer, 0);
|
|
|
|
// Initializes timer control register
|
|
CPUTimer_stopTimer(cpuTimer);
|
|
CPUTimer_reloadTimerCounter(cpuTimer);
|
|
CPUTimer_setEmulationMode(cpuTimer,
|
|
CPUTIMER_EMULATIONMODE_STOPAFTERNEXTDECREMENT);
|
|
|
|
CPUTimer_enableInterrupt(cpuTimer);
|
|
|
|
}
|
|
|
|
// Timer 1 ISR function
|
|
__interrupt void timer1_ISR(void) {
|
|
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
|
if (xSemaphore != NULL) {
|
|
xSemaphoreGiveFromISR(xSemaphore, &xHigherPriorityTaskWoken);
|
|
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
|
}
|
|
CPUTimer_clearOverflowFlag(CPUTIMER1_BASE);
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------------------
|
|
|
|
// Configures SCIA, baud rate is 115200
|
|
void UartSetup(void) {
|
|
|
|
// SCIA RX: GPIO85
|
|
GPIO_setMasterCore(SCI_RXDA_PIN, GPIO_CORE_CPU1);
|
|
GPIO_setPinConfig(GPIO_85_SCIRXDA);
|
|
GPIO_setDirectionMode(SCI_RXDA_PIN, GPIO_DIR_MODE_IN);
|
|
GPIO_setPadConfig(SCI_RXDA_PIN, GPIO_PIN_TYPE_STD);
|
|
GPIO_setQualificationMode(SCI_RXDA_PIN, GPIO_QUAL_ASYNC);
|
|
|
|
// SCIA TX: GPIO84
|
|
GPIO_setMasterCore(SCI_TXDA_PIN, GPIO_CORE_CPU1);
|
|
GPIO_setPinConfig(GPIO_84_SCITXDA);
|
|
GPIO_setDirectionMode(SCI_TXDA_PIN, GPIO_DIR_MODE_OUT);
|
|
GPIO_setPadConfig(SCI_TXDA_PIN, GPIO_PIN_TYPE_STD);
|
|
GPIO_setQualificationMode(SCI_TXDA_PIN, GPIO_QUAL_ASYNC);
|
|
|
|
// Configure SCIA
|
|
SCI_performSoftwareReset(SCIA_BASE);
|
|
|
|
SCI_setConfig(SCIA_BASE,
|
|
DEVICE_LSPCLK_FREQ,
|
|
115200U,
|
|
SCI_CONFIG_WLEN_8 |
|
|
SCI_CONFIG_STOP_ONE | SCI_CONFIG_PAR_NONE);
|
|
|
|
SCI_resetChannels(SCIA_BASE);
|
|
SCI_resetRxFIFO(SCIA_BASE);
|
|
SCI_resetTxFIFO(SCIA_BASE);
|
|
|
|
// Recommended when using FIFO
|
|
SCI_clearInterruptStatus(SCIA_BASE, SCI_INT_TXFF | SCI_INT_RXFF);
|
|
|
|
SCI_enableFIFO(SCIA_BASE);
|
|
SCI_enableModule(SCIA_BASE);
|
|
SCI_performSoftwareReset(SCIA_BASE);
|
|
}
|
|
|
|
// Implements SCI based putchar()
|
|
void UartPutChar(uint16_t charToWrite) {
|
|
SCI_writeCharBlockingFIFO(SCIA_BASE, charToWrite);
|
|
}
|