Update repo

This commit is contained in:
hangpersonal committed 2026-09-05 14:12:10 -07:00
1 parent dfe8ec02bd
commit d343e06de2
4 files changed
+180 -12

No files matched your search

+149 -8
View File
@@ -3,6 +3,7 @@
#include <stdlib.h>
#include <assert.h>
#include <file.h>
#include <limits.h>
#include <string.h>
// Driverlib headers
@@ -13,6 +14,7 @@
// Customized headers
#include "uart_drv.h"
#include "at24cm02.h"
#include "sine_table.h"
// FreeRTOS headers
#include "FreeRTOS.h"
@@ -46,6 +48,18 @@ uint8_t ucHeap[configTOTAL_HEAP_SIZE];
#define SCI_RXDA_PIN 85U
#define SCI_TXDA_PIN 84U
#define EPWM6A_GPIO 10U
#define EPWM6A_FREQUENCY_HZ 50000UL // 50KHz
#define EPWM6A_DUTY_PERCENT 75U // 75%
#define EPWM_CLOCK_HZ (DEVICE_SYSCLK_FREQ / 2UL)
#define EPWM6A_PERIOD_COUNTS (EPWM_CLOCK_HZ / EPWM6A_FREQUENCY_HZ)
#define EPWM6A_PERIOD_TICKS (EPWM6A_PERIOD_COUNTS - 1UL)
#define EPWM6A_COMPARE_TICKS ((EPWM6A_PERIOD_COUNTS * EPWM6A_DUTY_PERCENT) / 100UL)
#define DAC_SINE_FREQUENCY_HZ 1000UL
#define DAC_SAMPLE_FREQUENCY_HZ (DAC_SINE_FREQUENCY_HZ * SINE_TABLE_LENGTH)
#define DAC_SAMPLE_PERIOD_TICKS ((EPWM_CLOCK_HZ / DAC_SAMPLE_FREQUENCY_HZ) - 1UL)
// UART: SCIA
void UartSetup(void);
void UartPutChar(uint16_t charToWrite);
@@ -54,12 +68,23 @@ void UartPutChar(uint16_t charToWrite);
void configCPUTimer(uint32_t cpuTimer, uint32_t period_us);
__interrupt void timer1_ISR(void);
// ePWM6A: GPIO10, 50KHz, 75% duty cycle
void initEPWM6A(void);
// DACOUTB sine output and ePWM7 supplies the sample interrupt
void initDACBSine(void);
__interrupt void dacUpdateISR(void);
static volatile uint16_t sineTableIndex = 0U;
// 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
// FreeRTOS
const char * volatile g_overflow_task_name = NULL;
TaskHandle_t volatile g_overflow_task_handle = NULL;
void RedLED_Task(void *pvParameters);
void BlueLED_Task(void *pvParameters);
void EEPROM_Task(void *pvParameters);
@@ -86,9 +111,6 @@ void main(void) {
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
@@ -124,8 +146,9 @@ void main(void) {
ERTM;
// Enable Global real-time interrupt DBGM
// ------------------------ Redirect STDOUT to SCI ------------------------
// ------------------------------------------------------------------------
// SCIA: GPIO84/GPIO85
// 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,
@@ -134,11 +157,21 @@ void main(void) {
// Assign stdout to be a UART device
assert(freopen("uart:", "w", stdout) != NULL);
// GPIO91/GPIO92 and I2CA are configured by the EEPROM driver
eepromInitStatus = EEPROM_init();
// GPIO10 outputs ePWM6A at 50KHz with a 75% duty cycle
initEPWM6A();
// Generate a 1 kHz sine wave on DACOUTB
initDACBSine();
// ------------------------------- FreeRTOS -------------------------------
xSemaphore = xSemaphoreCreateBinary();
// Create tasks dynamically
// 1 stack element = 1 * uint16_t = 16 bits = 2 conventional bytes
// 256 stack elements * 2 bytes = 512 conventional bytes
xTaskCreate(RedLED_Task,
(const char*) "RedLED_Task",
256,
@@ -168,12 +201,16 @@ void main(void) {
void RedLED_Task(void *pvParameters) {
(void)pvParameters;
int uart_count = 0;
UBaseType_t uxRemainingWords;
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);
printf("FreeRTOS running on the F28377S Coreboard V1.3, %d!\r\n", uart_count);
uxRemainingWords = uxTaskGetStackHighWaterMark(NULL);
printf("RedLED_Task unused stack: %d stack elements (%d bytes)\r\n",
(int)uxRemainingWords,
(int)(uxRemainingWords * sizeof(StackType_t) * (CHAR_BIT / 8U)));
}
}
}
@@ -240,6 +277,110 @@ void EEPROM_Task(void *pvParameters) {
vTaskDelete(NULL);
}
void vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName) {
g_overflow_task_handle = xTask;
g_overflow_task_name = pcTaskName; // points to the task name string
taskDISABLE_INTERRUPTS();
for (;;) {
__asm(" NOP"); // set breakpoint here and inspect g_overflow_task_name
}
}
void vApplicationMallocFailedHook(void) {
taskDISABLE_INTERRUPTS();
for(;;){}
}
// -----------------------------------------------------------------------------------------
void initEPWM6A(void) {
// Route ePWM6A to GPIO10
GPIO_setMasterCore(EPWM6A_GPIO, GPIO_CORE_CPU1);
GPIO_setPadConfig(EPWM6A_GPIO, GPIO_PIN_TYPE_STD);
GPIO_setPinConfig(GPIO_10_EPWM6A);
// The F28377S runs at 200 MHz. Divide EPWMCLK by two so TBCLK is
// 100 MHz, then freeze all ePWM time-base clocks during configuration
SysCtl_setEPWMClockDivider(SYSCTL_EPWMCLK_DIV_2);
SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
EPWM_setClockPrescaler(EPWM6_BASE,
EPWM_CLOCK_DIVIDER_1,
EPWM_HSCLOCK_DIVIDER_1);
EPWM_setTimeBaseCounterMode(EPWM6_BASE, EPWM_COUNTER_MODE_UP);
EPWM_setTimeBasePeriod(EPWM6_BASE, (uint16_t)EPWM6A_PERIOD_TICKS);
EPWM_setTimeBaseCounter(EPWM6_BASE, 0U);
EPWM_disablePhaseShiftLoad(EPWM6_BASE);
EPWM_setPhaseShift(EPWM6_BASE, 0U);
EPWM_setCounterCompareValue(EPWM6_BASE,
EPWM_COUNTER_COMPARE_A,
(uint16_t)EPWM6A_COMPARE_TICKS);
EPWM_setCounterCompareShadowLoadMode(EPWM6_BASE,
EPWM_COUNTER_COMPARE_A,
EPWM_COMP_LOAD_ON_CNTR_ZERO);
// Drive ePWM6A high at the start of each period and low at CMPA
EPWM_setActionQualifierAction(EPWM6_BASE,
EPWM_AQ_OUTPUT_A,
EPWM_AQ_OUTPUT_HIGH,
EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
EPWM_setActionQualifierAction(EPWM6_BASE,
EPWM_AQ_OUTPUT_A,
EPWM_AQ_OUTPUT_LOW,
EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
}
// -----------------------------------------------------------------------------------------
void initDACBSine(void) {
// Configure DACOUTB for 12-bit output referenced to ADC VREFHI.
DAC_setReferenceVoltage(DACB_BASE, DAC_REF_ADC_VREFHI);
DAC_setLoadMode(DACB_BASE, DAC_LOAD_SYSCLK);
DAC_setShadowValue(DACB_BASE, sineTable[0U]);
DAC_enableOutput(DACB_BASE);
DEVICE_DELAY_US(10U);
// Use ePWM7 only as a 100 kHz sample clock. With a 100 MHz TBCLK,
// up-count mode and TBPRD = 999 produce one interrupt every 10 us.
SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
SysCtl_setEPWMClockDivider(SYSCTL_EPWMCLK_DIV_2);
EPWM_setClockPrescaler(EPWM7_BASE,
EPWM_CLOCK_DIVIDER_1,
EPWM_HSCLOCK_DIVIDER_1);
EPWM_setTimeBaseCounterMode(EPWM7_BASE, EPWM_COUNTER_MODE_UP);
EPWM_setTimeBasePeriod(EPWM7_BASE,
(uint16_t)DAC_SAMPLE_PERIOD_TICKS);
EPWM_setTimeBaseCounter(EPWM7_BASE, 0U);
EPWM_disablePhaseShiftLoad(EPWM7_BASE);
EPWM_setPhaseShift(EPWM7_BASE, 0U);
EPWM_setInterruptSource(EPWM7_BASE, EPWM_INT_TBCTR_ZERO);
EPWM_setInterruptEventCount(EPWM7_BASE, 1U);
EPWM_clearEventTriggerInterruptFlag(EPWM7_BASE);
Interrupt_register(INT_EPWM7, &dacUpdateISR);
Interrupt_enable(INT_EPWM7);
EPWM_enableInterrupt(EPWM7_BASE);
sineTableIndex = 1U;
SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
}
__interrupt void dacUpdateISR(void) {
DAC_setShadowValue(DACB_BASE, sineTable[sineTableIndex]);
sineTableIndex++;
if (sineTableIndex >= SINE_TABLE_LENGTH) {
sineTableIndex = 0U;
}
EPWM_clearEventTriggerInterruptFlag(EPWM7_BASE);
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3);
}
// -----------------------------------------------------------------------------------------
// This function initializes the selected timer to the period specified