Update repo
This commit is contained in:
1 parent
ef5f9a563e
commit
dfe8ec02bd
12 files changed
+723
-341
No files matched your search
@@ -42,7 +42,7 @@
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.ti.ccstudio.buildDefinitions.C2000_22.6.compilerID.INCLUDE_PATH.77573739" name="Add dir to #include search path (--include_path, -I)" superClass="com.ti.ccstudio.buildDefinitions.C2000_22.6.compilerID.INCLUDE_PATH" valueType="includePath">
|
||||
<listOptionValue builtIn="false" value="${PROJECT_ROOT}"/>
|
||||
<listOptionValue builtIn="false" value="${PROJECT_ROOT}/device"/>
|
||||
<listOptionValue builtIn="false" value="${PROJECT_ROOT}/print_support"/>
|
||||
<listOptionValue builtIn="false" value="${PROJECT_ROOT}/include"/>
|
||||
<listOptionValue builtIn="false" value="${PROJECT_ROOT}/../C2000Ware/driverlib/f2837xs/driverlib"/>
|
||||
<listOptionValue builtIn="false" value="${PROJECT_ROOT}/FreeRTOS/Source/portable/CCS/C2000_C28x"/>
|
||||
<listOptionValue builtIn="false" value="${PROJECT_ROOT}/FreeRTOS/Source/include"/>
|
||||
|
||||
@@ -9,8 +9,8 @@ encoding//CPU1_FLASH/device/subdir_rules.mk=UTF-8
|
||||
encoding//CPU1_FLASH/device/subdir_vars.mk=UTF-8
|
||||
encoding//CPU1_FLASH/makefile=UTF-8
|
||||
encoding//CPU1_FLASH/objects.mk=UTF-8
|
||||
encoding//CPU1_FLASH/print_support/subdir_rules.mk=UTF-8
|
||||
encoding//CPU1_FLASH/print_support/subdir_vars.mk=UTF-8
|
||||
encoding//CPU1_FLASH/source/subdir_rules.mk=UTF-8
|
||||
encoding//CPU1_FLASH/source/subdir_vars.mk=UTF-8
|
||||
encoding//CPU1_FLASH/sources.mk=UTF-8
|
||||
encoding//CPU1_FLASH/subdir_rules.mk=UTF-8
|
||||
encoding//CPU1_FLASH/subdir_vars.mk=UTF-8
|
||||
@@ -105,56 +105,36 @@ SECTIONS
|
||||
.bss:cio : > RAMM0
|
||||
.data : > RAMGSx
|
||||
.sysmem : > RAMLSxDxGSx
|
||||
/* Initalized sections go in Flash */
|
||||
.const : > FLASH5, ALIGN(8)
|
||||
#else
|
||||
.pinit : > FLASH1, ALIGN(8)
|
||||
.ebss : > RAMGSx
|
||||
.esysmem : > RAMLSxDxGSx
|
||||
.cio : > RAMM0
|
||||
/* Initalized sections go in Flash */
|
||||
.econst : >> FLASH4 | FLASH5, ALIGN(8)
|
||||
#endif
|
||||
|
||||
/*
|
||||
ramgs0 : > RAMGS0, type=NOINIT
|
||||
ramgs1 : > RAMGS1, type=NOINIT
|
||||
*/
|
||||
ramm0 : > RAMM0, type=NOINIT
|
||||
ramm1 : > RAMM1, type=NOINIT
|
||||
|
||||
|
||||
/* The following section definitions are for SDFM examples */
|
||||
/*
|
||||
Filter_RegsFile : > RAMGS0
|
||||
Filter1_RegsFile : > RAMGS1, fill=0x1111
|
||||
Filter2_RegsFile : > RAMGS2, fill=0x2222
|
||||
Filter3_RegsFile : > RAMGS3, fill=0x3333
|
||||
Filter4_RegsFile : > RAMGS4, fill=0x4444
|
||||
Difference_RegsFile : >RAMGS5, fill=0x3333
|
||||
*/
|
||||
|
||||
#if defined(__TI_EABI__)
|
||||
.TI.ramfunc : {} LOAD = FLASH3,
|
||||
RUN = RAMGSx,
|
||||
LOAD_START(RamfuncsLoadStart),
|
||||
LOAD_SIZE(RamfuncsLoadSize),
|
||||
LOAD_END(RamfuncsLoadEnd),
|
||||
RUN_START(RamfuncsRunStart),
|
||||
RUN_SIZE(RamfuncsRunSize),
|
||||
RUN_END(RamfuncsRunEnd),
|
||||
ALIGN(8)
|
||||
#else
|
||||
.TI.ramfunc : {} LOAD = FLASH3,
|
||||
RUN = RAMGSx,
|
||||
LOAD_START(_RamfuncsLoadStart),
|
||||
LOAD_SIZE(_RamfuncsLoadSize),
|
||||
LOAD_END(_RamfuncsLoadEnd),
|
||||
RUN_START(_RamfuncsRunStart),
|
||||
RUN_SIZE(_RamfuncsRunSize),
|
||||
RUN_END(_RamfuncsRunEnd),
|
||||
ALIGN(8)
|
||||
#endif
|
||||
#if defined(__TI_EABI__)
|
||||
.TI.ramfunc : {} LOAD = FLASH3,
|
||||
RUN = RAMGSx,
|
||||
LOAD_START(RamfuncsLoadStart),
|
||||
LOAD_SIZE(RamfuncsLoadSize),
|
||||
LOAD_END(RamfuncsLoadEnd),
|
||||
RUN_START(RamfuncsRunStart),
|
||||
RUN_SIZE(RamfuncsRunSize),
|
||||
RUN_END(RamfuncsRunEnd),
|
||||
ALIGN(8)
|
||||
#else
|
||||
.TI.ramfunc : {} LOAD = FLASH3,
|
||||
RUN = RAMGSx,
|
||||
LOAD_START(_RamfuncsLoadStart),
|
||||
LOAD_SIZE(_RamfuncsLoadSize),
|
||||
LOAD_END(_RamfuncsLoadEnd),
|
||||
RUN_START(_RamfuncsRunStart),
|
||||
RUN_SIZE(_RamfuncsRunSize),
|
||||
RUN_END(_RamfuncsRunEnd),
|
||||
ALIGN(8)
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,21 +1,6 @@
|
||||
#ifndef FREERTOS_CONFIG_H
|
||||
#define FREERTOS_CONFIG_H
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// Application specific definitions.
|
||||
//
|
||||
// These definitions should be adjusted for your particular hardware and
|
||||
// application requirements.
|
||||
//
|
||||
// THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
|
||||
// FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
|
||||
//
|
||||
// See http://www.freertos.org/a00110.html.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
// Constants provided for debugging and optimization assistance
|
||||
//void vMainAssertCalled( const char *pcFileName, uint32_t ulLineNumber );
|
||||
//#define configASSERT( x ) if ((x) == 0) { vMainAssertCalled( __FILE__, __LINE__ ); }
|
||||
#define configASSERT( x ) if ((x) == 0) { taskDISABLE_INTERRUPTS(); for( ;; ); }
|
||||
|
||||
// Constants related to the behavior or the scheduler
|
||||
@@ -50,7 +35,7 @@ supported, or if both static and dynamic allocation are supported.
|
||||
the first block of RAM on the LPC device. See the initialization of the heap
|
||||
in main.c.
|
||||
*/
|
||||
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 16 * 1024 ) )
|
||||
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 24 * 1024 ) )
|
||||
|
||||
|
||||
// Constants that build features in or out
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
#ifndef AT24CM02_H_
|
||||
#define AT24CM02_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define AT24CM02_CAPACITY_BYTES 262144UL
|
||||
#define AT24CM02_PAGE_SIZE_BYTES 256U
|
||||
#define AT24CM02_PAGE_COUNT 1024U
|
||||
#define AT24CM02_DEFAULT_ADDRESS 0x50U
|
||||
|
||||
typedef enum
|
||||
{
|
||||
EEPROM_STATUS_SUCCESS = 0,
|
||||
EEPROM_STATUS_NOT_INITIALIZED,
|
||||
EEPROM_STATUS_INVALID_ARGUMENT,
|
||||
EEPROM_STATUS_OUT_OF_RANGE,
|
||||
EEPROM_STATUS_NO_MEMORY,
|
||||
EEPROM_STATUS_MUTEX_TIMEOUT,
|
||||
EEPROM_STATUS_BUS_BUSY,
|
||||
EEPROM_STATUS_TIMEOUT,
|
||||
EEPROM_STATUS_NO_ACK,
|
||||
EEPROM_STATUS_ARBITRATION_LOST
|
||||
} EEPROM_Status;
|
||||
|
||||
// Configure GPIO91/GPIO92 and I2CA for 400-kHz operation. Call this once
|
||||
// after Device_init() and Device_initGPIO(), before starting the scheduler.
|
||||
EEPROM_Status EEPROM_init(void);
|
||||
|
||||
// Read or write an arbitrary byte range. A write that crosses a 256-byte page
|
||||
// boundary is automatically split into multiple page-write transactions.
|
||||
EEPROM_Status EEPROM_read(uint16_t *data, uint32_t address,
|
||||
uint16_t deviceAddress, uint32_t byteCount,
|
||||
TickType_t timeoutTicks);
|
||||
EEPROM_Status EEPROM_write(const uint16_t *data, uint32_t address,
|
||||
uint16_t deviceAddress, uint32_t byteCount,
|
||||
TickType_t timeoutTicks);
|
||||
|
||||
// Page numbers are one-based (1 through 1024), matching the original driver.
|
||||
EEPROM_Status EEPROM_pageNumberToAddress(uint16_t pageNumber,
|
||||
uint32_t *pageAddress);
|
||||
EEPROM_Status EEPROM_readPage(uint16_t *data, uint16_t deviceAddress,
|
||||
uint16_t pageNumber, uint16_t byteCount,
|
||||
TickType_t timeoutTicks);
|
||||
EEPROM_Status EEPROM_writePage(const uint16_t *data, uint16_t deviceAddress,
|
||||
uint16_t pageNumber, uint16_t byteCount,
|
||||
TickType_t timeoutTicks);
|
||||
|
||||
const char *EEPROM_statusString(EEPROM_Status status);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // AT24CM02_H_
|
||||
File renamed without changes.
+134
-117
@@ -8,6 +8,11 @@
|
||||
// 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"
|
||||
@@ -16,33 +21,15 @@
|
||||
#include "queue.h"
|
||||
#include "timers.h"
|
||||
|
||||
// STDOUT redirection specific
|
||||
#include "uart_drv.h"
|
||||
#include "sci.h"
|
||||
|
||||
#define LED_R 41U // Red LED
|
||||
#define LED_B 58U // Blue LED
|
||||
|
||||
#define SCI_RXDA_PIN 85U
|
||||
#define SCI_TXDA_PIN 84U
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#if defined (__TI_EABI__)
|
||||
void *malloc(size_t xSize);
|
||||
#pragma WEAK (malloc)
|
||||
#endif
|
||||
|
||||
#if defined (__TI_EABI__)
|
||||
// malloc - Traps malloc calls
|
||||
void *malloc(size_t xSize) {
|
||||
(void)xSize;
|
||||
// There should not be a heap defined, trap any attempts to call malloc()
|
||||
void* malloc(size_t xSize) {
|
||||
(void) xSize;
|
||||
taskDISABLE_INTERRUPTS();
|
||||
for(;;) {
|
||||
ESTOP0; // Optional: useful during CCS debug
|
||||
for (;;) {
|
||||
ESTOP0;
|
||||
}
|
||||
}
|
||||
#pragma WEAK (malloc)
|
||||
#endif
|
||||
|
||||
#if(configAPPLICATION_ALLOCATED_HEAP == 1)
|
||||
@@ -51,26 +38,36 @@ uint8_t ucHeap[configTOTAL_HEAP_SIZE];
|
||||
#pragma DATA_ALIGN(ucHeap, portBYTE_ALIGNMENT)
|
||||
#endif
|
||||
|
||||
// UART stdout redirection configuration related functions
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#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);
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
// Configuration of CPU timer 1
|
||||
// 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];
|
||||
|
||||
void LED_TaskRed(void * pvParameters);
|
||||
void LED_TaskBlue(void * pvParameters);
|
||||
// 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)
|
||||
{
|
||||
void main(void) {
|
||||
|
||||
// Initializes device clock and peripherals
|
||||
Device_init();
|
||||
|
||||
@@ -89,6 +86,9 @@ 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
|
||||
@@ -119,29 +119,17 @@ void main(void)
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
// Enable global Interrupts and higher priority real-time debug events
|
||||
EINT; // Enable Global interrupt INTM
|
||||
ERTM; // Enable Global real-time interrupt DBGM
|
||||
EINT;
|
||||
// Enable Global interrupt INTM
|
||||
ERTM;
|
||||
// Enable Global real-time interrupt DBGM
|
||||
|
||||
// ------------------------ Redirect STDOUT to SCI ------------------------
|
||||
|
||||
//**************************************************************************
|
||||
// NOTE: SCI Configuration for this example is done in UartSetup()
|
||||
// As an alternative, the user can configure SCI here in the main, and then
|
||||
// provide an empty UartSetup() function. UartSetup() must be defined, even
|
||||
// if it is empty.
|
||||
//**************************************************************************
|
||||
|
||||
// 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);
|
||||
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);
|
||||
@@ -149,72 +137,114 @@ void main(void)
|
||||
// ------------------------------- FreeRTOS -------------------------------
|
||||
|
||||
xSemaphore = xSemaphoreCreateBinary();
|
||||
if(xSemaphore == NULL) {
|
||||
while(1);
|
||||
}
|
||||
|
||||
// Create tasks dynamically
|
||||
if(xTaskCreate(LED_TaskRed,
|
||||
(const char *) "Red LED Task",
|
||||
256,
|
||||
NULL,
|
||||
tskIDLE_PRIORITY + 2,
|
||||
NULL) != pdPASS) {
|
||||
ESTOP0;
|
||||
}
|
||||
xTaskCreate(RedLED_Task,
|
||||
(const char*) "RedLED_Task",
|
||||
256,
|
||||
NULL,
|
||||
1,
|
||||
NULL);
|
||||
|
||||
if(xTaskCreate(LED_TaskBlue,
|
||||
(const char *) "Blue LED Task",
|
||||
256,
|
||||
NULL,
|
||||
tskIDLE_PRIORITY + 1,
|
||||
NULL) != pdPASS) {
|
||||
ESTOP0;
|
||||
}
|
||||
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();
|
||||
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------
|
||||
|
||||
// This is an event-driven task. It sits in a blocked state waiting for
|
||||
// xSemaphore to be available by calling xSemaphoreTake() with a timeout
|
||||
// of portMAX_DELAY. Because Timer 1 releases this semaphore every 100 ms,
|
||||
// the Red LED task will unblock and toggle the LED exactly every 100 ms.
|
||||
// It is created with a higher priority of tskIDLE_PRIORITY + 2.
|
||||
void LED_TaskRed(void * pvParameters) {
|
||||
void RedLED_Task(void *pvParameters) {
|
||||
(void)pvParameters;
|
||||
int uart_count = 0;
|
||||
while(1) {
|
||||
if(xSemaphoreTake(xSemaphore, portMAX_DELAY) == pdTRUE) {
|
||||
// Toggle red LED
|
||||
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("Hello from FreeRTOS running on the F28377S Coreboard, %d!\r\n",
|
||||
uart_count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// This is a time-driven task. It simply toggles the blue LED and then puts
|
||||
// itself to sleep using vTaskDelay(500 / portTICK_PERIOD_MS).
|
||||
// Based on the RTOS configuration, this creates a 500 ms delay cycle.
|
||||
// It runs at a lower priority of tskIDLE_PRIORITY + 1.
|
||||
void LED_TaskBlue(void * pvParameters) {
|
||||
while(1) {
|
||||
// Toggle blue LED
|
||||
void BlueLED_Task(void *pvParameters) {
|
||||
(void)pvParameters;
|
||||
while (1) {
|
||||
GPIO_togglePin(LED_B);
|
||||
vTaskDelay(500);
|
||||
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);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------
|
||||
|
||||
// configCPUTimer - 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 uSeconds. The timer is held in
|
||||
// the stopped state after configuration.
|
||||
// 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;
|
||||
@@ -226,29 +256,20 @@ void configCPUTimer(uint32_t cpuTimer, uint32_t period_us) {
|
||||
// Set pre-scale counter to divide by 1 (SYSCLKOUT)
|
||||
CPUTimer_setPreScaler(cpuTimer, 0);
|
||||
|
||||
// Initializes timer control register. The timer is stopped,
|
||||
// reloaded, free run disabled, and interrupt enabled.
|
||||
// Additionally, the free and soft bits are set
|
||||
// Initializes timer control register
|
||||
CPUTimer_stopTimer(cpuTimer);
|
||||
CPUTimer_reloadTimerCounter(cpuTimer);
|
||||
CPUTimer_setEmulationMode(
|
||||
cpuTimer,
|
||||
CPUTIMER_EMULATIONMODE_STOPAFTERNEXTDECREMENT
|
||||
);
|
||||
CPUTimer_setEmulationMode(cpuTimer,
|
||||
CPUTIMER_EMULATIONMODE_STOPAFTERNEXTDECREMENT);
|
||||
|
||||
CPUTimer_enableInterrupt(cpuTimer);
|
||||
|
||||
}
|
||||
|
||||
|
||||
// When Timer 1 fires, the Interrupt Service Routine executes
|
||||
// xSemaphoreGiveFromISR(). This unlocks the semaphore so a waiting task
|
||||
// can proceed. portYIELD_FROM_ISR() is then called to force an immediate
|
||||
// FreeRTOS context switch if the newly unblocked task has a higher priority
|
||||
// than the interrupted task.
|
||||
// Timer 1 ISR function
|
||||
__interrupt void timer1_ISR(void) {
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
if(xSemaphore != NULL) {
|
||||
if (xSemaphore != NULL) {
|
||||
xSemaphoreGiveFromISR(xSemaphore, &xHigherPriorityTaskWoken);
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
}
|
||||
@@ -257,7 +278,7 @@ __interrupt void timer1_ISR(void) {
|
||||
|
||||
// -----------------------------------------------------------------------------------------
|
||||
|
||||
// UartSetup - Configures SCIA
|
||||
// Configures SCIA, baud rate is 115200
|
||||
void UartSetup(void) {
|
||||
|
||||
// SCIA RX: GPIO85
|
||||
@@ -278,11 +299,10 @@ void UartSetup(void) {
|
||||
SCI_performSoftwareReset(SCIA_BASE);
|
||||
|
||||
SCI_setConfig(SCIA_BASE,
|
||||
DEVICE_LSPCLK_FREQ,
|
||||
DEVICE_LSPCLK_FREQ,
|
||||
115200U,
|
||||
SCI_CONFIG_WLEN_8 |
|
||||
SCI_CONFIG_STOP_ONE |
|
||||
SCI_CONFIG_PAR_NONE);
|
||||
SCI_CONFIG_STOP_ONE | SCI_CONFIG_PAR_NONE);
|
||||
|
||||
SCI_resetChannels(SCIA_BASE);
|
||||
SCI_resetRxFIFO(SCIA_BASE);
|
||||
@@ -296,10 +316,7 @@ void UartSetup(void) {
|
||||
SCI_performSoftwareReset(SCIA_BASE);
|
||||
}
|
||||
|
||||
// UartPutChar - Implements SCI based putchar()
|
||||
// Implements SCI based putchar()
|
||||
void UartPutChar(uint16_t charToWrite) {
|
||||
SCI_writeCharBlockingFIFO(SCIA_BASE, charToWrite);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------
|
||||
|
||||
@@ -0,0 +1,504 @@
|
||||
#include "at24cm02.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "driverlib.h"
|
||||
#include "device.h"
|
||||
#include "semphr.h"
|
||||
#include "task.h"
|
||||
|
||||
#define EEPROM_I2C_BASE I2CA_BASE
|
||||
#define EEPROM_I2C_BIT_RATE 400000UL
|
||||
#define EEPROM_SDA_PIN 91U
|
||||
#define EEPROM_SCL_PIN 92U
|
||||
#define EEPROM_STATUS_ERROR_MASK (I2C_STS_NO_ACK | I2C_STS_ARB_LOST)
|
||||
#define EEPROM_CLEARABLE_STATUS_MASK (I2C_STS_NO_ACK | I2C_STS_ARB_LOST | \
|
||||
I2C_STS_REG_ACCESS_RDY | \
|
||||
I2C_STS_STOP_CONDITION)
|
||||
// The AT24CM02 tWR maximum is 10 ms. Use 11 RTOS ticks at a 1-kHz tick rate
|
||||
// so the actual delay cannot be shortened below 10 ms by tick quantization.
|
||||
#define EEPROM_WRITE_CYCLE_MS 11U
|
||||
|
||||
static SemaphoreHandle_t eepromMutex = NULL;
|
||||
static bool eepromInitialized = false;
|
||||
|
||||
static bool EEPROM_hasTimedOut(TickType_t start, TickType_t timeoutTicks)
|
||||
{
|
||||
if(timeoutTicks == portMAX_DELAY)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return ((TickType_t)(xTaskGetTickCount() - start) >= timeoutTicks);
|
||||
}
|
||||
|
||||
static void EEPROM_yield(void)
|
||||
{
|
||||
if(xTaskGetSchedulerState() == taskSCHEDULER_RUNNING)
|
||||
{
|
||||
taskYIELD();
|
||||
}
|
||||
}
|
||||
|
||||
static EEPROM_Status EEPROM_statusToError(uint16_t i2cStatus)
|
||||
{
|
||||
if((i2cStatus & I2C_STS_ARB_LOST) != 0U)
|
||||
{
|
||||
return EEPROM_STATUS_ARBITRATION_LOST;
|
||||
}
|
||||
|
||||
if((i2cStatus & I2C_STS_NO_ACK) != 0U)
|
||||
{
|
||||
return EEPROM_STATUS_NO_ACK;
|
||||
}
|
||||
|
||||
return EEPROM_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void EEPROM_abortTransaction(void)
|
||||
{
|
||||
I2C_sendStopCondition(EEPROM_I2C_BASE);
|
||||
I2C_clearStatus(EEPROM_I2C_BASE, EEPROM_CLEARABLE_STATUS_MASK);
|
||||
}
|
||||
|
||||
static EEPROM_Status EEPROM_waitForStatus(uint16_t requestedStatus,
|
||||
TickType_t start,
|
||||
TickType_t timeoutTicks)
|
||||
{
|
||||
uint16_t status;
|
||||
EEPROM_Status error;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
status = I2C_getStatus(EEPROM_I2C_BASE);
|
||||
error = EEPROM_statusToError(status);
|
||||
if(error != EEPROM_STATUS_SUCCESS)
|
||||
{
|
||||
return error;
|
||||
}
|
||||
|
||||
if((status & requestedStatus) != 0U)
|
||||
{
|
||||
return EEPROM_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if(EEPROM_hasTimedOut(start, timeoutTicks))
|
||||
{
|
||||
return EEPROM_STATUS_TIMEOUT;
|
||||
}
|
||||
|
||||
EEPROM_yield();
|
||||
}
|
||||
}
|
||||
|
||||
static EEPROM_Status EEPROM_waitForBusIdle(TickType_t start,
|
||||
TickType_t timeoutTicks)
|
||||
{
|
||||
while(I2C_getStopConditionStatus(EEPROM_I2C_BASE) ||
|
||||
I2C_isBusBusy(EEPROM_I2C_BASE))
|
||||
{
|
||||
if(EEPROM_hasTimedOut(start, timeoutTicks))
|
||||
{
|
||||
return EEPROM_STATUS_BUS_BUSY;
|
||||
}
|
||||
|
||||
EEPROM_yield();
|
||||
}
|
||||
|
||||
return EEPROM_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static uint16_t EEPROM_targetAddress(uint16_t deviceAddress,
|
||||
uint32_t memoryAddress)
|
||||
{
|
||||
return (uint16_t)(deviceAddress | ((memoryAddress >> 16U) & 0x3U));
|
||||
}
|
||||
|
||||
static bool EEPROM_deviceAddressIsValid(uint16_t deviceAddress)
|
||||
{
|
||||
// Bits A17:A16 are supplied by the memory address for this device.
|
||||
return ((deviceAddress <= 0x7CU) && ((deviceAddress & 0x3U) == 0U));
|
||||
}
|
||||
|
||||
static EEPROM_Status EEPROM_writeChunk(const uint16_t *data,
|
||||
uint32_t address,
|
||||
uint16_t deviceAddress,
|
||||
uint16_t byteCount,
|
||||
TickType_t timeoutTicks)
|
||||
{
|
||||
uint16_t i;
|
||||
TickType_t start = xTaskGetTickCount();
|
||||
EEPROM_Status status;
|
||||
|
||||
status = EEPROM_waitForBusIdle(start, timeoutTicks);
|
||||
if(status != EEPROM_STATUS_SUCCESS)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
I2C_clearStatus(EEPROM_I2C_BASE, EEPROM_CLEARABLE_STATUS_MASK);
|
||||
I2C_setTargetAddress(EEPROM_I2C_BASE,
|
||||
EEPROM_targetAddress(deviceAddress, address));
|
||||
I2C_setDataCount(EEPROM_I2C_BASE, (uint16_t)(byteCount + 2U));
|
||||
I2C_setConfig(EEPROM_I2C_BASE, I2C_CONTROLLER_SEND_MODE);
|
||||
I2C_sendStartCondition(EEPROM_I2C_BASE);
|
||||
I2C_sendStopCondition(EEPROM_I2C_BASE);
|
||||
|
||||
status = EEPROM_waitForStatus(I2C_STS_TX_DATA_RDY, start, timeoutTicks);
|
||||
if(status == EEPROM_STATUS_SUCCESS)
|
||||
{
|
||||
I2C_putData(EEPROM_I2C_BASE, (uint16_t)((address >> 8U) & 0xFFU));
|
||||
}
|
||||
|
||||
if(status == EEPROM_STATUS_SUCCESS)
|
||||
{
|
||||
status = EEPROM_waitForStatus(I2C_STS_TX_DATA_RDY, start,
|
||||
timeoutTicks);
|
||||
}
|
||||
if(status == EEPROM_STATUS_SUCCESS)
|
||||
{
|
||||
I2C_putData(EEPROM_I2C_BASE, (uint16_t)(address & 0xFFU));
|
||||
}
|
||||
|
||||
for(i = 0U; (i < byteCount) && (status == EEPROM_STATUS_SUCCESS); i++)
|
||||
{
|
||||
status = EEPROM_waitForStatus(I2C_STS_TX_DATA_RDY, start,
|
||||
timeoutTicks);
|
||||
if(status == EEPROM_STATUS_SUCCESS)
|
||||
{
|
||||
I2C_putData(EEPROM_I2C_BASE, data[i] & 0xFFU);
|
||||
}
|
||||
}
|
||||
|
||||
if(status == EEPROM_STATUS_SUCCESS)
|
||||
{
|
||||
status = EEPROM_waitForStatus(I2C_STS_STOP_CONDITION, start,
|
||||
timeoutTicks);
|
||||
}
|
||||
|
||||
if(status != EEPROM_STATUS_SUCCESS)
|
||||
{
|
||||
EEPROM_abortTransaction();
|
||||
return status;
|
||||
}
|
||||
|
||||
I2C_clearStatus(EEPROM_I2C_BASE, I2C_STS_STOP_CONDITION);
|
||||
return EEPROM_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static EEPROM_Status EEPROM_readChunk(uint16_t *data, uint32_t address,
|
||||
uint16_t deviceAddress,
|
||||
uint16_t byteCount,
|
||||
TickType_t timeoutTicks)
|
||||
{
|
||||
uint16_t i;
|
||||
TickType_t start = xTaskGetTickCount();
|
||||
EEPROM_Status status;
|
||||
|
||||
status = EEPROM_waitForBusIdle(start, timeoutTicks);
|
||||
if(status != EEPROM_STATUS_SUCCESS)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
I2C_clearStatus(EEPROM_I2C_BASE, EEPROM_CLEARABLE_STATUS_MASK);
|
||||
I2C_setTargetAddress(EEPROM_I2C_BASE,
|
||||
EEPROM_targetAddress(deviceAddress, address));
|
||||
I2C_setDataCount(EEPROM_I2C_BASE, 2U);
|
||||
I2C_setConfig(EEPROM_I2C_BASE, I2C_CONTROLLER_SEND_MODE);
|
||||
I2C_sendStartCondition(EEPROM_I2C_BASE);
|
||||
|
||||
status = EEPROM_waitForStatus(I2C_STS_TX_DATA_RDY, start, timeoutTicks);
|
||||
if(status == EEPROM_STATUS_SUCCESS)
|
||||
{
|
||||
I2C_putData(EEPROM_I2C_BASE, (uint16_t)((address >> 8U) & 0xFFU));
|
||||
}
|
||||
|
||||
if(status == EEPROM_STATUS_SUCCESS)
|
||||
{
|
||||
status = EEPROM_waitForStatus(I2C_STS_TX_DATA_RDY, start,
|
||||
timeoutTicks);
|
||||
}
|
||||
if(status == EEPROM_STATUS_SUCCESS)
|
||||
{
|
||||
I2C_putData(EEPROM_I2C_BASE, (uint16_t)(address & 0xFFU));
|
||||
}
|
||||
|
||||
if(status == EEPROM_STATUS_SUCCESS)
|
||||
{
|
||||
status = EEPROM_waitForStatus(I2C_STS_REG_ACCESS_RDY, start,
|
||||
timeoutTicks);
|
||||
}
|
||||
|
||||
if(status == EEPROM_STATUS_SUCCESS)
|
||||
{
|
||||
I2C_clearStatus(EEPROM_I2C_BASE, I2C_STS_REG_ACCESS_RDY);
|
||||
I2C_setDataCount(EEPROM_I2C_BASE, byteCount);
|
||||
I2C_setConfig(EEPROM_I2C_BASE, I2C_CONTROLLER_RECEIVE_MODE);
|
||||
I2C_sendStartCondition(EEPROM_I2C_BASE);
|
||||
I2C_sendStopCondition(EEPROM_I2C_BASE);
|
||||
}
|
||||
|
||||
for(i = 0U; (i < byteCount) && (status == EEPROM_STATUS_SUCCESS); i++)
|
||||
{
|
||||
status = EEPROM_waitForStatus(I2C_STS_RX_DATA_RDY, start,
|
||||
timeoutTicks);
|
||||
if(status == EEPROM_STATUS_SUCCESS)
|
||||
{
|
||||
data[i] = I2C_getData(EEPROM_I2C_BASE) & 0xFFU;
|
||||
}
|
||||
}
|
||||
|
||||
if(status == EEPROM_STATUS_SUCCESS)
|
||||
{
|
||||
status = EEPROM_waitForStatus(I2C_STS_STOP_CONDITION, start,
|
||||
timeoutTicks);
|
||||
}
|
||||
|
||||
if(status != EEPROM_STATUS_SUCCESS)
|
||||
{
|
||||
EEPROM_abortTransaction();
|
||||
return status;
|
||||
}
|
||||
|
||||
I2C_clearStatus(EEPROM_I2C_BASE, I2C_STS_STOP_CONDITION);
|
||||
return EEPROM_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
EEPROM_Status EEPROM_init(void)
|
||||
{
|
||||
if(eepromMutex == NULL)
|
||||
{
|
||||
eepromMutex = xSemaphoreCreateMutex();
|
||||
if(eepromMutex == NULL)
|
||||
{
|
||||
return EEPROM_STATUS_NO_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
GPIO_setMasterCore(EEPROM_SDA_PIN, GPIO_CORE_CPU1);
|
||||
GPIO_setPinConfig(GPIO_91_SDAA);
|
||||
GPIO_setDirectionMode(EEPROM_SDA_PIN, GPIO_DIR_MODE_IN);
|
||||
GPIO_setPadConfig(EEPROM_SDA_PIN, GPIO_PIN_TYPE_PULLUP);
|
||||
GPIO_setQualificationMode(EEPROM_SDA_PIN, GPIO_QUAL_ASYNC);
|
||||
|
||||
GPIO_setMasterCore(EEPROM_SCL_PIN, GPIO_CORE_CPU1);
|
||||
GPIO_setPinConfig(GPIO_92_SCLA);
|
||||
GPIO_setDirectionMode(EEPROM_SCL_PIN, GPIO_DIR_MODE_IN);
|
||||
GPIO_setPadConfig(EEPROM_SCL_PIN, GPIO_PIN_TYPE_PULLUP);
|
||||
GPIO_setQualificationMode(EEPROM_SCL_PIN, GPIO_QUAL_ASYNC);
|
||||
|
||||
I2C_disableModule(EEPROM_I2C_BASE);
|
||||
I2C_initController(EEPROM_I2C_BASE, DEVICE_SYSCLK_FREQ,
|
||||
EEPROM_I2C_BIT_RATE, I2C_DUTYCYCLE_33);
|
||||
I2C_setBitCount(EEPROM_I2C_BASE, I2C_BITCOUNT_8);
|
||||
I2C_setAddressMode(EEPROM_I2C_BASE, I2C_ADDR_MODE_7BITS);
|
||||
I2C_setEmulationMode(EEPROM_I2C_BASE, I2C_EMULATION_FREE_RUN);
|
||||
I2C_disableFIFO(EEPROM_I2C_BASE);
|
||||
I2C_disableInterrupt(EEPROM_I2C_BASE, I2C_INT_ARB_LOST |
|
||||
I2C_INT_NO_ACK | I2C_INT_REG_ACCESS_RDY |
|
||||
I2C_INT_RX_DATA_RDY | I2C_INT_TX_DATA_RDY |
|
||||
I2C_INT_STOP_CONDITION | I2C_INT_ADDR_TARGET |
|
||||
I2C_INT_RXFF | I2C_INT_TXFF);
|
||||
I2C_clearStatus(EEPROM_I2C_BASE, EEPROM_CLEARABLE_STATUS_MASK);
|
||||
I2C_enableModule(EEPROM_I2C_BASE);
|
||||
|
||||
eepromInitialized = true;
|
||||
return EEPROM_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
EEPROM_Status EEPROM_read(uint16_t *data, uint32_t address,
|
||||
uint16_t deviceAddress, uint32_t byteCount,
|
||||
TickType_t timeoutTicks)
|
||||
{
|
||||
EEPROM_Status status;
|
||||
uint32_t chunkSize;
|
||||
|
||||
if(!eepromInitialized)
|
||||
{
|
||||
return EEPROM_STATUS_NOT_INITIALIZED;
|
||||
}
|
||||
if((data == NULL) || (byteCount == 0UL) ||
|
||||
!EEPROM_deviceAddressIsValid(deviceAddress))
|
||||
{
|
||||
return EEPROM_STATUS_INVALID_ARGUMENT;
|
||||
}
|
||||
if((address >= AT24CM02_CAPACITY_BYTES) ||
|
||||
(byteCount > (AT24CM02_CAPACITY_BYTES - address)))
|
||||
{
|
||||
return EEPROM_STATUS_OUT_OF_RANGE;
|
||||
}
|
||||
if(xSemaphoreTake(eepromMutex, timeoutTicks) != pdTRUE)
|
||||
{
|
||||
return EEPROM_STATUS_MUTEX_TIMEOUT;
|
||||
}
|
||||
|
||||
status = EEPROM_STATUS_SUCCESS;
|
||||
while((byteCount != 0UL) && (status == EEPROM_STATUS_SUCCESS))
|
||||
{
|
||||
// I2CCNT is 16-bit; keep chunks moderate and avoid a block-address
|
||||
// change in the middle of an I2C transaction.
|
||||
chunkSize = 0x10000UL - (address & 0xFFFFUL);
|
||||
if(chunkSize > byteCount)
|
||||
{
|
||||
chunkSize = byteCount;
|
||||
}
|
||||
if(chunkSize > 0xFFFFUL)
|
||||
{
|
||||
chunkSize = 0xFFFFUL;
|
||||
}
|
||||
|
||||
status = EEPROM_readChunk(data, address, deviceAddress,
|
||||
(uint16_t)chunkSize, timeoutTicks);
|
||||
address += chunkSize;
|
||||
data += chunkSize;
|
||||
byteCount -= chunkSize;
|
||||
}
|
||||
|
||||
xSemaphoreGive(eepromMutex);
|
||||
return status;
|
||||
}
|
||||
|
||||
EEPROM_Status EEPROM_write(const uint16_t *data, uint32_t address,
|
||||
uint16_t deviceAddress, uint32_t byteCount,
|
||||
TickType_t timeoutTicks)
|
||||
{
|
||||
EEPROM_Status status;
|
||||
uint32_t chunkSize;
|
||||
|
||||
if(!eepromInitialized)
|
||||
{
|
||||
return EEPROM_STATUS_NOT_INITIALIZED;
|
||||
}
|
||||
if((data == NULL) || (byteCount == 0UL) ||
|
||||
!EEPROM_deviceAddressIsValid(deviceAddress))
|
||||
{
|
||||
return EEPROM_STATUS_INVALID_ARGUMENT;
|
||||
}
|
||||
if((address >= AT24CM02_CAPACITY_BYTES) ||
|
||||
(byteCount > (AT24CM02_CAPACITY_BYTES - address)))
|
||||
{
|
||||
return EEPROM_STATUS_OUT_OF_RANGE;
|
||||
}
|
||||
if(xSemaphoreTake(eepromMutex, timeoutTicks) != pdTRUE)
|
||||
{
|
||||
return EEPROM_STATUS_MUTEX_TIMEOUT;
|
||||
}
|
||||
|
||||
status = EEPROM_STATUS_SUCCESS;
|
||||
while((byteCount != 0UL) && (status == EEPROM_STATUS_SUCCESS))
|
||||
{
|
||||
chunkSize = AT24CM02_PAGE_SIZE_BYTES -
|
||||
(address & (AT24CM02_PAGE_SIZE_BYTES - 1U));
|
||||
if(chunkSize > byteCount)
|
||||
{
|
||||
chunkSize = byteCount;
|
||||
}
|
||||
|
||||
status = EEPROM_writeChunk(data, address, deviceAddress,
|
||||
(uint16_t)chunkSize, timeoutTicks);
|
||||
if(status == EEPROM_STATUS_SUCCESS)
|
||||
{
|
||||
if(xTaskGetSchedulerState() == taskSCHEDULER_RUNNING)
|
||||
{
|
||||
vTaskDelay(pdMS_TO_TICKS(EEPROM_WRITE_CYCLE_MS));
|
||||
}
|
||||
else
|
||||
{
|
||||
DEVICE_DELAY_US((uint32_t)EEPROM_WRITE_CYCLE_MS * 1000UL);
|
||||
}
|
||||
}
|
||||
|
||||
address += chunkSize;
|
||||
data += chunkSize;
|
||||
byteCount -= chunkSize;
|
||||
}
|
||||
|
||||
xSemaphoreGive(eepromMutex);
|
||||
return status;
|
||||
}
|
||||
|
||||
EEPROM_Status EEPROM_pageNumberToAddress(uint16_t pageNumber,
|
||||
uint32_t *pageAddress)
|
||||
{
|
||||
if(pageAddress == NULL)
|
||||
{
|
||||
return EEPROM_STATUS_INVALID_ARGUMENT;
|
||||
}
|
||||
if((pageNumber == 0U) || (pageNumber > AT24CM02_PAGE_COUNT))
|
||||
{
|
||||
return EEPROM_STATUS_OUT_OF_RANGE;
|
||||
}
|
||||
|
||||
*pageAddress = ((uint32_t)pageNumber - 1UL) *
|
||||
AT24CM02_PAGE_SIZE_BYTES;
|
||||
return EEPROM_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
EEPROM_Status EEPROM_readPage(uint16_t *data, uint16_t deviceAddress,
|
||||
uint16_t pageNumber, uint16_t byteCount,
|
||||
TickType_t timeoutTicks)
|
||||
{
|
||||
uint32_t address;
|
||||
EEPROM_Status status;
|
||||
|
||||
if((byteCount == 0U) || (byteCount > AT24CM02_PAGE_SIZE_BYTES))
|
||||
{
|
||||
return EEPROM_STATUS_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
status = EEPROM_pageNumberToAddress(pageNumber, &address);
|
||||
if(status != EEPROM_STATUS_SUCCESS)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
return EEPROM_read(data, address, deviceAddress, byteCount, timeoutTicks);
|
||||
}
|
||||
|
||||
EEPROM_Status EEPROM_writePage(const uint16_t *data, uint16_t deviceAddress,
|
||||
uint16_t pageNumber, uint16_t byteCount,
|
||||
TickType_t timeoutTicks)
|
||||
{
|
||||
uint32_t address;
|
||||
EEPROM_Status status;
|
||||
|
||||
if((byteCount == 0U) || (byteCount > AT24CM02_PAGE_SIZE_BYTES))
|
||||
{
|
||||
return EEPROM_STATUS_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
status = EEPROM_pageNumberToAddress(pageNumber, &address);
|
||||
if(status != EEPROM_STATUS_SUCCESS)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
return EEPROM_write(data, address, deviceAddress, byteCount, timeoutTicks);
|
||||
}
|
||||
|
||||
const char *EEPROM_statusString(EEPROM_Status status)
|
||||
{
|
||||
static const char *const descriptions[] =
|
||||
{
|
||||
"success",
|
||||
"not initialized",
|
||||
"invalid argument",
|
||||
"address out of range",
|
||||
"FreeRTOS heap exhausted",
|
||||
"mutex timeout",
|
||||
"I2C bus busy",
|
||||
"I2C timeout",
|
||||
"I2C no acknowledgement",
|
||||
"I2C arbitration lost"
|
||||
};
|
||||
|
||||
if((uint16_t)status >=
|
||||
(uint16_t)(sizeof(descriptions) / sizeof(descriptions[0])))
|
||||
{
|
||||
return "unknown status";
|
||||
}
|
||||
|
||||
return descriptions[(uint16_t)status];
|
||||
}
|
||||
File renamed without changes.
File renamed without changes.
Reference in new issue
Block a user