creata timeline con tempi in decimi
This commit is contained in:
@@ -27,3 +27,4 @@
|
||||
*** SESSION apr 27, 2026 18:08:05.110 ------------------------------------------
|
||||
*** SESSION apr 28, 2026 17:49:36.231 ------------------------------------------
|
||||
*** SESSION apr 28, 2026 22:13:13.508 ------------------------------------------
|
||||
*** SESSION apr 29, 2026 20:10:49.962 ------------------------------------------
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
22:27:58 **** Incremental Build of configuration Debug for project AUTOM10 ****
|
||||
13:01:40 **** Incremental Build of configuration Debug for project AUTOM10 ****
|
||||
make -j12 all
|
||||
arm-none-eabi-gcc "../Core/Src/cdc_int.c" -mcpu=cortex-m3 -std=gnu11 -g3 -DDEBUG -DUSE_HAL_DRIVER -DSTM32F103xB -c -I../Core/Inc -I../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy -I../Drivers/STM32F1xx_HAL_Driver/Inc -I../Drivers/CMSIS/Device/ST/STM32F1xx/Include -I../Drivers/CMSIS/Include -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -fcyclomatic-complexity -MMD -MP -MF"Core/Src/cdc_int.d" -MT"Core/Src/cdc_int.o" --specs=nano.specs -mfloat-abi=soft -mthumb -o "Core/Src/cdc_int.o"
|
||||
arm-none-eabi-gcc "../Core/Src/eeprom.c" -mcpu=cortex-m3 -std=gnu11 -g3 -DDEBUG -DUSE_HAL_DRIVER -DSTM32F103xB -c -I../Core/Inc -I../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy -I../Drivers/STM32F1xx_HAL_Driver/Inc -I../Drivers/CMSIS/Device/ST/STM32F1xx/Include -I../Drivers/CMSIS/Include -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -fcyclomatic-complexity -MMD -MP -MF"Core/Src/eeprom.d" -MT"Core/Src/eeprom.o" --specs=nano.specs -mfloat-abi=soft -mthumb -o "Core/Src/eeprom.o"
|
||||
arm-none-eabi-gcc "../Core/Src/main.c" -mcpu=cortex-m3 -std=gnu11 -g3 -DDEBUG -DUSE_HAL_DRIVER -DSTM32F103xB -c -I../Core/Inc -I../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy -I../Drivers/STM32F1xx_HAL_Driver/Inc -I../Drivers/CMSIS/Device/ST/STM32F1xx/Include -I../Drivers/CMSIS/Include -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -fcyclomatic-complexity -MMD -MP -MF"Core/Src/main.d" -MT"Core/Src/main.o" --specs=nano.specs -mfloat-abi=soft -mthumb -o "Core/Src/main.o"
|
||||
arm-none-eabi-gcc -o "AUTOM10.elf" @"objects.list" -mcpu=cortex-m3 -T"C:\progetti\AUTOM\workspace\AUTOM10\STM32F103C8TX_FLASH.ld" --specs=nosys.specs -Wl,-Map="AUTOM10.map" -Wl,--gc-sections -static --specs=nano.specs -mfloat-abi=soft -mthumb -Wl,--start-group -lc -lm -Wl,--end-group
|
||||
Finished building target: AUTOM10.elf
|
||||
|
||||
arm-none-eabi-size AUTOM10.elf
|
||||
arm-none-eabi-objdump -h -S AUTOM10.elf > "AUTOM10.list"
|
||||
text data bss dec hex filename
|
||||
57620 468 7336 65424 ff90 AUTOM10.elf
|
||||
59100 468 7360 66928 10570 AUTOM10.elf
|
||||
Finished building: default.size.stdout
|
||||
|
||||
Finished building: AUTOM10.list
|
||||
|
||||
|
||||
22:28:00 Build Finished. 0 errors, 0 warnings. (took 2s.613ms)
|
||||
13:01:40 Build Finished. 0 errors, 0 warnings. (took 816ms)
|
||||
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
22:27:58 **** Incremental Build of configuration Debug for project AUTOM10 ****
|
||||
13:01:40 **** Incremental Build of configuration Debug for project AUTOM10 ****
|
||||
make -j12 all
|
||||
arm-none-eabi-gcc "../Core/Src/cdc_int.c" -mcpu=cortex-m3 -std=gnu11 -g3 -DDEBUG -DUSE_HAL_DRIVER -DSTM32F103xB -c -I../Core/Inc -I../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy -I../Drivers/STM32F1xx_HAL_Driver/Inc -I../Drivers/CMSIS/Device/ST/STM32F1xx/Include -I../Drivers/CMSIS/Include -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -fcyclomatic-complexity -MMD -MP -MF"Core/Src/cdc_int.d" -MT"Core/Src/cdc_int.o" --specs=nano.specs -mfloat-abi=soft -mthumb -o "Core/Src/cdc_int.o"
|
||||
arm-none-eabi-gcc "../Core/Src/eeprom.c" -mcpu=cortex-m3 -std=gnu11 -g3 -DDEBUG -DUSE_HAL_DRIVER -DSTM32F103xB -c -I../Core/Inc -I../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy -I../Drivers/STM32F1xx_HAL_Driver/Inc -I../Drivers/CMSIS/Device/ST/STM32F1xx/Include -I../Drivers/CMSIS/Include -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -fcyclomatic-complexity -MMD -MP -MF"Core/Src/eeprom.d" -MT"Core/Src/eeprom.o" --specs=nano.specs -mfloat-abi=soft -mthumb -o "Core/Src/eeprom.o"
|
||||
arm-none-eabi-gcc "../Core/Src/main.c" -mcpu=cortex-m3 -std=gnu11 -g3 -DDEBUG -DUSE_HAL_DRIVER -DSTM32F103xB -c -I../Core/Inc -I../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy -I../Drivers/STM32F1xx_HAL_Driver/Inc -I../Drivers/CMSIS/Device/ST/STM32F1xx/Include -I../Drivers/CMSIS/Include -I../USB_DEVICE/App -I../USB_DEVICE/Target -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -fcyclomatic-complexity -MMD -MP -MF"Core/Src/main.d" -MT"Core/Src/main.o" --specs=nano.specs -mfloat-abi=soft -mthumb -o "Core/Src/main.o"
|
||||
arm-none-eabi-gcc -o "AUTOM10.elf" @"objects.list" -mcpu=cortex-m3 -T"C:\progetti\AUTOM\workspace\AUTOM10\STM32F103C8TX_FLASH.ld" --specs=nosys.specs -Wl,-Map="AUTOM10.map" -Wl,--gc-sections -static --specs=nano.specs -mfloat-abi=soft -mthumb -Wl,--start-group -lc -lm -Wl,--end-group
|
||||
Finished building target: AUTOM10.elf
|
||||
|
||||
arm-none-eabi-size AUTOM10.elf
|
||||
arm-none-eabi-objdump -h -S AUTOM10.elf > "AUTOM10.list"
|
||||
text data bss dec hex filename
|
||||
57620 468 7336 65424 ff90 AUTOM10.elf
|
||||
59100 468 7360 66928 10570 AUTOM10.elf
|
||||
Finished building: default.size.stdout
|
||||
|
||||
Finished building: AUTOM10.list
|
||||
|
||||
@@ -0,0 +1,482 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "eeprom.h"
|
||||
extern UART_HandleTypeDef huart1;
|
||||
/*
|
||||
* Record format (4 bytes):
|
||||
* [0] VirtAddress (uint16_t)
|
||||
* [2] Data (uint16_t)
|
||||
*
|
||||
* Page layout:
|
||||
* [0] PageStatus (uint16_t)
|
||||
* [2..] Records...
|
||||
*/
|
||||
|
||||
extern uint16_t m1pwmap;
|
||||
extern uint16_t m1pwmch;
|
||||
extern uint16_t m2pwmap;
|
||||
extern uint16_t m2pwmch;
|
||||
extern uint16_t m3pwmap;
|
||||
extern uint16_t m3pwmch;
|
||||
extern uint16_t m4pwmap;
|
||||
extern uint16_t m4pwmch;
|
||||
extern uint16_t m1TimeoutMan;
|
||||
extern uint16_t m2TimeoutMan;
|
||||
extern uint16_t m3TimeoutMan;
|
||||
extern uint16_t m4TimeoutMan;
|
||||
extern uint16_t twap;
|
||||
extern uint16_t tramp;
|
||||
extern uint16_t t1ch;
|
||||
extern uint16_t t2ch;
|
||||
extern uint16_t t3ch;
|
||||
extern uint16_t t4ch;
|
||||
extern uint16_t twch;
|
||||
extern uint16_t tramp1;
|
||||
extern uint16_t trampman;
|
||||
extern uint16_t m1pwmMan;
|
||||
extern uint16_t m2pwmMan;
|
||||
extern uint16_t m3pwmMan;
|
||||
extern uint16_t m4pwmMan;
|
||||
|
||||
|
||||
extern uint16_t apM1start;
|
||||
extern uint16_t apM1stop;
|
||||
extern uint16_t apM2start;
|
||||
extern uint16_t apM2stop;
|
||||
extern uint16_t apM3start;
|
||||
extern uint16_t apM3stop;
|
||||
extern uint16_t apM4start;
|
||||
extern uint16_t apM4stop;
|
||||
extern uint16_t chM1start;
|
||||
extern uint16_t chM1stop;
|
||||
extern uint16_t chM2start;
|
||||
extern uint16_t chM2stop;
|
||||
extern uint16_t chM3start;
|
||||
extern uint16_t chM3stop;
|
||||
extern uint16_t chM4start;
|
||||
extern uint16_t chM4stop;
|
||||
|
||||
const uint16_t deftab[EE_NUM_VIRTUAL_ADDR]={
|
||||
40, //m1pwmap
|
||||
60, //m1pwmch
|
||||
70, //m2pwmap
|
||||
70, //m2pwmch
|
||||
35, //m3pwmap
|
||||
40, //m3pwmch
|
||||
40, //m4pwmap
|
||||
40, //m4pwmch
|
||||
20, //m1rampstart
|
||||
20, //m2rampstart
|
||||
20, //m3rampstart
|
||||
20, //m4rampstart
|
||||
230,//m1timeoutman
|
||||
100,//m2timeoutman
|
||||
130,//m3timeoutman
|
||||
300,//m4timeoutman
|
||||
1, //twap
|
||||
27, //t1ch
|
||||
10, //t2ch
|
||||
30, //t3ch
|
||||
1, //t4ch
|
||||
1, //twch
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
100, //tramp1
|
||||
60, //m1pwmMan
|
||||
70, //m2pwmMan
|
||||
40, //m3pwmMan
|
||||
40, //m4pwmMan
|
||||
50, //trampman
|
||||
10, //tramp
|
||||
310, //apM1start;
|
||||
450, //apM1stop;
|
||||
30, //apM2start;
|
||||
310, //apM2stop;
|
||||
350, //apM3start;
|
||||
450, //apM3stop;
|
||||
450, //apM4start;
|
||||
850, //apM4stop;
|
||||
10, //chM1start;
|
||||
280, //chM1stop;
|
||||
280, //chM2start;
|
||||
580, //chM2stop;
|
||||
20, //chM3start;
|
||||
280, //chM3stop;
|
||||
280, //chM4start;
|
||||
680, //chM4stop;
|
||||
1,
|
||||
27,
|
||||
10,
|
||||
30,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
100,
|
||||
60,
|
||||
70,
|
||||
40,
|
||||
40,
|
||||
50,
|
||||
10,
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t VirtAddress;
|
||||
uint16_t Data;
|
||||
} EE_Record_t;
|
||||
|
||||
/* Active page base address (runtime selected in EE_Init) */
|
||||
static uint32_t EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
|
||||
/* 32 sequential virtual addresses */
|
||||
const uint16_t EE_VirtAddrs[EE_NUM_VIRTUAL_ADDR] =
|
||||
{
|
||||
0x0001, 0x0002, 0x0003, 0x0004,
|
||||
0x0005, 0x0006, 0x0007, 0x0008,
|
||||
0x0009, 0x000A, 0x000B, 0x000C,
|
||||
0x000D, 0x000E, 0x000F, 0x0010,
|
||||
0x0011, 0x0012, 0x0013, 0x0014,
|
||||
0x0015, 0x0016, 0x0017, 0x0018,
|
||||
0x0019, 0x001A, 0x001B, 0x001C,
|
||||
0x001D, 0x001E, 0x001F, 0x0020,
|
||||
|
||||
0x0021, 0x0022, 0x0023, 0x0024,
|
||||
0x0025, 0x0026, 0x0027, 0x0028,
|
||||
0x0029, 0x002A, 0x002B, 0x002C,
|
||||
0x002D, 0x002E, 0x002F, 0x0030,
|
||||
0x0031, 0x0032, 0x0033, 0x0034,
|
||||
0x0035, 0x0036, 0x0037, 0x0038,
|
||||
0x0039, 0x003A, 0x003B, 0x003C,
|
||||
0x003D, 0x003E, 0x003F, 0x0040
|
||||
};
|
||||
/* ========================================================================= */
|
||||
|
||||
/* --- Internal helpers ---------------------------------------------------- */
|
||||
|
||||
static uint16_t EE_GetPageStatus(uint32_t pageBase)
|
||||
{
|
||||
return *(__IO uint16_t *)pageBase;
|
||||
}
|
||||
|
||||
static HAL_StatusTypeDef EE_FlashProgramHalfWord(uint32_t Address, uint16_t Data)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
|
||||
HAL_FLASH_Unlock();
|
||||
status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, Address, Data);
|
||||
HAL_FLASH_Lock();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static HAL_StatusTypeDef EE_FlashErasePage(uint32_t PageAddress)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
FLASH_EraseInitTypeDef EraseInit;
|
||||
uint32_t PageError = 0;
|
||||
|
||||
HAL_FLASH_Unlock();
|
||||
|
||||
EraseInit.TypeErase = FLASH_TYPEERASE_PAGES;
|
||||
EraseInit.PageAddress = PageAddress;
|
||||
EraseInit.NbPages = 1;
|
||||
|
||||
status = HAL_FLASHEx_Erase(&EraseInit, &PageError);
|
||||
|
||||
HAL_FLASH_Lock();
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Find first free record address in given page (returns 0 if full) */
|
||||
static uint32_t EE_FindFreeAddress(uint32_t pageBase)
|
||||
{
|
||||
uint32_t addr = pageBase + 2U; /* Skip status word */
|
||||
uint32_t pageEnd = pageBase + EE_PAGE_SIZE;
|
||||
|
||||
while (addr < (pageEnd - sizeof(EE_Record_t) + 1U))
|
||||
{
|
||||
uint16_t vaddr = *(__IO uint16_t *)addr;
|
||||
|
||||
if (vaddr == 0xFFFFU)
|
||||
{
|
||||
/* Empty slot */
|
||||
return addr;
|
||||
}
|
||||
addr += sizeof(EE_Record_t);
|
||||
}
|
||||
|
||||
return 0U; /* No space */
|
||||
}
|
||||
|
||||
/* Find latest value of VirtAddress in a specific page (internal, uses EE_Status) */
|
||||
/* Find latest value of VirtAddress in a specific page (scan forward) */
|
||||
static EE_Status EE_FindInPage(uint32_t pageBase, uint16_t VirtAddress, uint16_t *Data)
|
||||
{
|
||||
uint32_t addr = pageBase + 2U; // skip status halfword
|
||||
uint32_t pageEnd = pageBase + EE_PAGE_SIZE;
|
||||
EE_Status result = EE_NOT_FOUND;
|
||||
uint16_t lastVal = 0;
|
||||
|
||||
if (Data == NULL)
|
||||
return EE_ERROR;
|
||||
|
||||
while (addr <= (pageEnd - sizeof(EE_Record_t)))
|
||||
{
|
||||
uint16_t vaddr = *(__IO uint16_t *)addr;
|
||||
|
||||
if (vaddr == 0xFFFFU)
|
||||
{
|
||||
// First empty slot => no more records in this page
|
||||
break;
|
||||
}
|
||||
|
||||
uint16_t value = *(__IO uint16_t *)(addr + 2U);
|
||||
|
||||
if (vaddr == VirtAddress)
|
||||
{
|
||||
lastVal = value; // keep most recent
|
||||
result = EE_OK;
|
||||
}
|
||||
|
||||
addr += sizeof(EE_Record_t); // move 4 bytes forward
|
||||
}
|
||||
|
||||
if (result == EE_OK)
|
||||
*Data = lastVal;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Format both pages: erase and set PAGE0 as VALID */
|
||||
static EE_Status EE_Format(void)
|
||||
{
|
||||
if (EE_FlashErasePage(EE_PAGE0_BASE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
if (EE_FlashErasePage(EE_PAGE1_BASE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
if (EE_FlashProgramHalfWord(EE_PAGE0_BASE, EE_PAGE_STATUS_VALID) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* PAGE1 will remain erased (status = 0xFFFF) */
|
||||
EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
|
||||
return EE_STATUS_OK;
|
||||
}
|
||||
|
||||
/* Get the base of the other page */
|
||||
static uint32_t EE_GetOtherPageBase(uint32_t pageBase)
|
||||
{
|
||||
return (pageBase == EE_PAGE0_BASE) ? EE_PAGE1_BASE : EE_PAGE0_BASE;
|
||||
}
|
||||
|
||||
/* Page transfer (garbage collection + new write) */
|
||||
static EE_Status EE_PageTransfer(uint16_t VirtAddress, uint16_t Data)
|
||||
{
|
||||
uint32_t oldBase = EE_ActivePageBase;
|
||||
uint32_t newBase = EE_GetOtherPageBase(oldBase);
|
||||
uint32_t addr;
|
||||
uint16_t value;
|
||||
EE_Status st;
|
||||
|
||||
/* Erase new page */
|
||||
if (EE_FlashErasePage(newBase) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Mark new page as RECEIVE */
|
||||
if (EE_FlashProgramHalfWord(newBase, EE_PAGE_STATUS_RECEIVE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Start writing records just after status */
|
||||
addr = newBase + 2U;
|
||||
|
||||
/* For each known virtual variable */
|
||||
for (uint16_t i = 0; i < EE_NUM_VIRTUAL_ADDR; i++)
|
||||
{
|
||||
uint16_t vaddr = EE_VirtAddrs[i];
|
||||
|
||||
if (vaddr == VirtAddress)
|
||||
{
|
||||
/* Use the new data passed into PageTransfer */
|
||||
value = Data;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Read latest value from old active page */
|
||||
st = EE_FindInPage(oldBase, vaddr, &value);
|
||||
if (st != EE_STATUS_OK)
|
||||
{
|
||||
/* Variable never written -> skip */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Write record to new page */
|
||||
if (EE_FlashProgramHalfWord(addr, vaddr) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
if (EE_FlashProgramHalfWord(addr + 2U, value) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
addr += sizeof(EE_Record_t);
|
||||
if (addr >= (newBase + EE_PAGE_SIZE))
|
||||
return EE_STATUS_NO_SPACE;
|
||||
}
|
||||
|
||||
/* Erase old page */
|
||||
if (EE_FlashErasePage(oldBase) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Mark new page as VALID */
|
||||
if (EE_FlashProgramHalfWord(newBase, EE_PAGE_STATUS_VALID) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Update active page */
|
||||
EE_ActivePageBase = newBase;
|
||||
|
||||
return EE_STATUS_OK;
|
||||
}
|
||||
|
||||
/* --- Public API ----------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* Initialize the EEPROM emulation.
|
||||
* - Checks page statuses and chooses the active page.
|
||||
* - If inconsistent or blank, formats pages.
|
||||
* PUBLIC RETURN TYPE: uint16_t (EE_OK / EE_ERROR / ...)
|
||||
*/
|
||||
uint16_t EE_Init(void)
|
||||
{
|
||||
uint16_t status0 = EE_GetPageStatus(EE_PAGE0_BASE);
|
||||
uint16_t status1 = EE_GetPageStatus(EE_PAGE1_BASE);
|
||||
|
||||
if ((status0 == EE_PAGE_STATUS_ERASED) && (status1 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
/* Fresh device -> format */
|
||||
return (uint16_t)EE_Format();
|
||||
}
|
||||
else if ((status0 == EE_PAGE_STATUS_VALID) && (status1 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
return EE_OK;
|
||||
}
|
||||
else if ((status1 == EE_PAGE_STATUS_VALID) && (status0 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
EE_ActivePageBase = EE_PAGE1_BASE;
|
||||
return EE_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Any weird or inconsistent state -> reformat */
|
||||
return (uint16_t)EE_Format();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a 16-bit variable by its virtual address.
|
||||
* PUBLIC RETURN: EE_OK / EE_NOT_FOUND / EE_ERROR (as uint16_t)
|
||||
*/
|
||||
uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t *Data)
|
||||
{
|
||||
EE_Status st;
|
||||
|
||||
if (Data == NULL)
|
||||
return EE_ERROR;
|
||||
|
||||
st = EE_FindInPage(EE_ActivePageBase, VirtAddress, Data);
|
||||
return (uint16_t)st;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write (append) a 16-bit variable.
|
||||
* - Writes a new record in the active page.
|
||||
* - If the page is full, triggers a page transfer (GC).
|
||||
* PUBLIC RETURN: EE_OK / EE_ERROR / EE_NO_SPACE (as uint16_t)
|
||||
*/
|
||||
uint16_t EE_WriteVariable(uint16_t VirtAddress, uint16_t Data)
|
||||
{
|
||||
uint32_t freeAddr;
|
||||
EE_Status st;
|
||||
|
||||
/* Find free space in active page */
|
||||
freeAddr = EE_FindFreeAddress(EE_ActivePageBase);
|
||||
if (freeAddr != 0U)
|
||||
{
|
||||
/* Write new record */
|
||||
if (EE_FlashProgramHalfWord(freeAddr, VirtAddress) != HAL_OK)
|
||||
return EE_ERROR;
|
||||
if (EE_FlashProgramHalfWord(freeAddr + 2U, Data) != HAL_OK)
|
||||
return EE_ERROR;
|
||||
|
||||
return EE_OK;
|
||||
}
|
||||
|
||||
/* No space -> page transfer */
|
||||
st = EE_PageTransfer(VirtAddress, Data);
|
||||
return (uint16_t)st;
|
||||
}
|
||||
|
||||
void loadEE(void){
|
||||
char s [200];
|
||||
EEW_Read(M1PWMAP, &m1pwmap);
|
||||
EEW_Read(M1PWMCH, &m1pwmch);
|
||||
EEW_Read(M2PWMAP, &m2pwmap);
|
||||
EEW_Read(M2PWMCH, &m2pwmch);
|
||||
EEW_Read(M3PWMAP, &m3pwmap);
|
||||
EEW_Read(M3PWMCH, &m3pwmch);
|
||||
EEW_Read(M4PWMAP, &m4pwmap);
|
||||
EEW_Read(M4PWMCH, &m4pwmch);
|
||||
EEW_Read(M1TIMEOUTMAN, &m1TimeoutMan);
|
||||
EEW_Read(M2TIMEOUTMAN, &m2TimeoutMan);
|
||||
EEW_Read(M3TIMEOUTMAN, &m3TimeoutMan);
|
||||
EEW_Read(M4TIMEOUTMAN, &m4TimeoutMan);
|
||||
EEW_Read(TWAP, &twap);
|
||||
EEW_Read(T1CH, &t1ch);
|
||||
EEW_Read(T2CH, &t2ch);
|
||||
EEW_Read(T3CH, &t3ch);
|
||||
EEW_Read(T4CH, &t4ch);
|
||||
EEW_Read(TWCH, &twch);
|
||||
EEW_Read(TRAMP1, &tramp1);
|
||||
EEW_Read(M1PWMMAN, &m1pwmMan);
|
||||
EEW_Read(M2PWMMAN, &m2pwmMan);
|
||||
EEW_Read(M3PWMMAN, &m3pwmMan);
|
||||
EEW_Read(M4PWMMAN, &m4pwmMan);
|
||||
EEW_Read(TRAMPMAN, &trampman);
|
||||
EEW_Read(TRAMP, &tramp);
|
||||
|
||||
EEW_Read(APM1START,&apM1start);
|
||||
EEW_Read(APM1STOP ,&apM1stop);
|
||||
EEW_Read(APM2START,&apM2start);
|
||||
EEW_Read(APM2STOP ,&apM2stop);
|
||||
EEW_Read(APM3START,&apM3start);
|
||||
EEW_Read(APM3STOP ,&apM3stop);
|
||||
EEW_Read(APM4START,&apM4start);
|
||||
EEW_Read(APM4STOP ,&apM4stop);
|
||||
EEW_Read(CHM1START,&chM1start);
|
||||
EEW_Read(CHM1STOP ,&chM1stop);
|
||||
EEW_Read(CHM2START,&chM2start);
|
||||
EEW_Read(CHM2STOP ,&chM2stop);
|
||||
EEW_Read(CHM3START,&chM3start);
|
||||
EEW_Read(CHM3STOP ,&chM3stop);
|
||||
EEW_Read(CHM4START,&chM4start);
|
||||
EEW_Read(CHM4STOP ,&chM4stop);
|
||||
|
||||
sprintf((char*)s,"LoadEE\n");
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
sprintf((char*)s,"\nm1pwmap=%d m1pwmch=%d m2pwmap=%d m2pwmch=%d m3pwmap=%d m3pwmch=%d m4pwmap=%d m4pwmch=%d",m1pwmap,m1pwmch,m2pwmap,m2pwmch,m3pwmap,m3pwmch,m4pwmap, m4pwmch);
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
sprintf((char*)s,"\nm1TimeoutMan=%d m2TimeoutMan=%d m3TimeoutMan=%d m4TimeoutMan=%d ",m1TimeoutMan,m2TimeoutMan,m3timeoutMan,m4TimeoutMan);
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
sprintf((char*)s,"\ntramp=%d trampman=%d",tramp,trampman);
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
sprintf((char*)s,"\nm1pwmMan=%d m2pwmMan=%d m3pwmMan=%d m4pwmMan=%d",m1pwmMan,m2pwmMan,m3pwmMan,m4pwmMan);
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,189 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file : main.h
|
||||
* @brief : Header for main.c file.
|
||||
* This file contains the common defines of the application.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2025 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __MAIN_H
|
||||
#define __MAIN_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32f1xx_hal.h"
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN ET */
|
||||
typedef enum{
|
||||
omchiuso,
|
||||
omM1fw1,
|
||||
omM1fw2,
|
||||
omM1bw1,
|
||||
omM1bw2,
|
||||
omM2fw1,
|
||||
omM2fw2,
|
||||
omM2bw1,
|
||||
omM2bw2,
|
||||
omM3fw1,
|
||||
omM3fw2,
|
||||
omM3bw1,
|
||||
omM3bw2,
|
||||
omM4fw1,
|
||||
omM4fw2,
|
||||
omM4bw1,
|
||||
omM4bw2,
|
||||
omStopMan,
|
||||
omapertura0,
|
||||
omapertura1,
|
||||
omapertura2,
|
||||
omapertura3,
|
||||
omapertura4,
|
||||
omapertura5,
|
||||
omapertura6,
|
||||
omapertura7,
|
||||
omapertura8,
|
||||
omapertura9,
|
||||
omapertura10,
|
||||
omapertura11,
|
||||
omapertura12,
|
||||
omapertura13,
|
||||
omapertura14,
|
||||
omstopapertura,
|
||||
omaperto,
|
||||
omchiusura1,
|
||||
omchiusura2,
|
||||
omchiusura3,
|
||||
omchiusura4,
|
||||
omchiusura5,
|
||||
omchiusura6,
|
||||
omchiusura7,
|
||||
omchiusura8,
|
||||
omchiusura9,
|
||||
omchiusura10,
|
||||
omchiusura11,
|
||||
omchiusura12,
|
||||
omchiusura13,
|
||||
omchiusura14,
|
||||
omstopchiusura,
|
||||
}omCiclo_st;
|
||||
/* USER CODE END ET */
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* USER CODE BEGIN EC */
|
||||
|
||||
/* USER CODE END EC */
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN EM */
|
||||
|
||||
/* USER CODE END EM */
|
||||
|
||||
void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim);
|
||||
|
||||
/* Exported functions prototypes ---------------------------------------------*/
|
||||
void Error_Handler(void);
|
||||
|
||||
/* USER CODE BEGIN EFP */
|
||||
|
||||
/* USER CODE END EFP */
|
||||
|
||||
/* Private defines -----------------------------------------------------------*/
|
||||
#define LED2_Pin GPIO_PIN_13
|
||||
#define LED2_GPIO_Port GPIOC
|
||||
#define P1_Pin GPIO_PIN_14
|
||||
#define P1_GPIO_Port GPIOC
|
||||
#define P2_Pin GPIO_PIN_15
|
||||
#define P2_GPIO_Port GPIOC
|
||||
#define IN1_Pin GPIO_PIN_0
|
||||
#define IN1_GPIO_Port GPIOA
|
||||
#define IN2_Pin GPIO_PIN_1
|
||||
#define IN2_GPIO_Port GPIOA
|
||||
#define IN3_Pin GPIO_PIN_2
|
||||
#define IN3_GPIO_Port GPIOA
|
||||
#define IN4_Pin GPIO_PIN_3
|
||||
#define IN4_GPIO_Port GPIOA
|
||||
#define AIN1_Pin GPIO_PIN_4
|
||||
#define AIN1_GPIO_Port GPIOA
|
||||
#define AIN2_Pin GPIO_PIN_5
|
||||
#define AIN2_GPIO_Port GPIOA
|
||||
#define AIN3_Pin GPIO_PIN_6
|
||||
#define AIN3_GPIO_Port GPIOA
|
||||
#define AIN4_Pin GPIO_PIN_7
|
||||
#define AIN4_GPIO_Port GPIOA
|
||||
#define ANEM_Pin GPIO_PIN_0
|
||||
#define ANEM_GPIO_Port GPIOB
|
||||
#define INH1_Pin GPIO_PIN_1
|
||||
#define INH1_GPIO_Port GPIOB
|
||||
#define INH2_Pin GPIO_PIN_2
|
||||
#define INH2_GPIO_Port GPIOB
|
||||
#define INH3_Pin GPIO_PIN_10
|
||||
#define INH3_GPIO_Port GPIOB
|
||||
#define INH4_Pin GPIO_PIN_11
|
||||
#define INH4_GPIO_Port GPIOB
|
||||
#define CH1_Pin GPIO_PIN_12
|
||||
#define CH1_GPIO_Port GPIOB
|
||||
#define CH2_Pin GPIO_PIN_13
|
||||
#define CH2_GPIO_Port GPIOB
|
||||
#define CH3_Pin GPIO_PIN_14
|
||||
#define CH3_GPIO_Port GPIOB
|
||||
#define CH4_Pin GPIO_PIN_15
|
||||
#define CH4_GPIO_Port GPIOB
|
||||
#define BUZ_Pin GPIO_PIN_8
|
||||
#define BUZ_GPIO_Port GPIOA
|
||||
#define SWIO_Pin GPIO_PIN_13
|
||||
#define SWIO_GPIO_Port GPIOA
|
||||
#define SWCLK_Pin GPIO_PIN_14
|
||||
#define SWCLK_GPIO_Port GPIOA
|
||||
#define LED1_Pin GPIO_PIN_15
|
||||
#define LED1_GPIO_Port GPIOA
|
||||
#define EXP1_Pin GPIO_PIN_3
|
||||
#define EXP1_GPIO_Port GPIOB
|
||||
#define EXP2_Pin GPIO_PIN_4
|
||||
#define EXP2_GPIO_Port GPIOB
|
||||
#define EXP3_Pin GPIO_PIN_5
|
||||
#define EXP3_GPIO_Port GPIOB
|
||||
#define IN5_Pin GPIO_PIN_6
|
||||
#define IN5_GPIO_Port GPIOB
|
||||
#define IN6_Pin GPIO_PIN_7
|
||||
#define IN6_GPIO_Port GPIOB
|
||||
#define IN7_Pin GPIO_PIN_8
|
||||
#define IN7_GPIO_Port GPIOB
|
||||
#define IN8_Pin GPIO_PIN_9
|
||||
#define IN8_GPIO_Port GPIOB
|
||||
|
||||
/* USER CODE BEGIN Private defines */
|
||||
#define INP1 1
|
||||
#define INP2 2
|
||||
#define INCH1 4
|
||||
#define INCH2 8
|
||||
#define INCH3 16
|
||||
#define INCH4 32
|
||||
/* USER CODE END Private defines */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __MAIN_H */
|
||||
@@ -0,0 +1,482 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "eeprom.h"
|
||||
extern UART_HandleTypeDef huart1;
|
||||
/*
|
||||
* Record format (4 bytes):
|
||||
* [0] VirtAddress (uint16_t)
|
||||
* [2] Data (uint16_t)
|
||||
*
|
||||
* Page layout:
|
||||
* [0] PageStatus (uint16_t)
|
||||
* [2..] Records...
|
||||
*/
|
||||
|
||||
extern uint16_t m1pwmap;
|
||||
extern uint16_t m1pwmch;
|
||||
extern uint16_t m2pwmap;
|
||||
extern uint16_t m2pwmch;
|
||||
extern uint16_t m3pwmap;
|
||||
extern uint16_t m3pwmch;
|
||||
extern uint16_t m4pwmap;
|
||||
extern uint16_t m4pwmch;
|
||||
extern uint16_t t1ap;
|
||||
extern uint16_t t2ap;
|
||||
extern uint16_t t3ap;
|
||||
extern uint16_t t4ap;
|
||||
extern uint16_t twap;
|
||||
extern uint16_t tramp;
|
||||
extern uint16_t t1ch;
|
||||
extern uint16_t t2ch;
|
||||
extern uint16_t t3ch;
|
||||
extern uint16_t t4ch;
|
||||
extern uint16_t twch;
|
||||
extern uint16_t tramp1;
|
||||
extern uint16_t trampman;
|
||||
extern uint16_t m1pwmMan;
|
||||
extern uint16_t m2pwmMan;
|
||||
extern uint16_t m3pwmMan;
|
||||
extern uint16_t m4pwmMan;
|
||||
|
||||
|
||||
extern uint16_t apM1start;
|
||||
extern uint16_t apM1stop;
|
||||
extern uint16_t apM2start;
|
||||
extern uint16_t apM2stop;
|
||||
extern uint16_t apM3start;
|
||||
extern uint16_t apM3stop;
|
||||
extern uint16_t apM4start;
|
||||
extern uint16_t apM4stop;
|
||||
extern uint16_t chM1start;
|
||||
extern uint16_t chM1stop;
|
||||
extern uint16_t chM2start;
|
||||
extern uint16_t chM2stop;
|
||||
extern uint16_t chM3start;
|
||||
extern uint16_t chM3stop;
|
||||
extern uint16_t chM4start;
|
||||
extern uint16_t chM4stop;
|
||||
|
||||
const uint16_t deftab[EE_NUM_VIRTUAL_ADDR]={
|
||||
40, //m1pwmap
|
||||
60, //m1pwmch
|
||||
70, //m2pwmap
|
||||
70, //m2pwmch
|
||||
35, //m3pwmap
|
||||
40, //m3pwmch
|
||||
40, //m4pwmap
|
||||
40, //m4pwmch
|
||||
20, //m1rampstart
|
||||
20, //m2rampstart
|
||||
20, //m3rampstart
|
||||
20, //m4rampstart
|
||||
230,//m1timeoutman
|
||||
100,//m2timeoutman
|
||||
130,//m3timeoutman
|
||||
300,//m4timeoutman
|
||||
1, //twap
|
||||
27, //t1ch
|
||||
10, //t2ch
|
||||
30, //t3ch
|
||||
1, //t4ch
|
||||
1, //twch
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
100, //tramp1
|
||||
60, //m1pwmMan
|
||||
70, //m2pwmMan
|
||||
40, //m3pwmMan
|
||||
40, //m4pwmMan
|
||||
50, //trampman
|
||||
10, //tramp
|
||||
310, //apM1start;
|
||||
450, //apM1stop;
|
||||
30, //apM2start;
|
||||
310, //apM2stop;
|
||||
350, //apM3start;
|
||||
450, //apM3stop;
|
||||
450, //apM4start;
|
||||
850, //apM4stop;
|
||||
10, //chM1start;
|
||||
280, //chM1stop;
|
||||
280, //chM2start;
|
||||
580, //chM2stop;
|
||||
20, //chM3start;
|
||||
280, //chM3stop;
|
||||
280, //chM4start;
|
||||
680, //chM4stop;
|
||||
1,
|
||||
27,
|
||||
10,
|
||||
30,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
100,
|
||||
60,
|
||||
70,
|
||||
40,
|
||||
40,
|
||||
50,
|
||||
10,
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t VirtAddress;
|
||||
uint16_t Data;
|
||||
} EE_Record_t;
|
||||
|
||||
/* Active page base address (runtime selected in EE_Init) */
|
||||
static uint32_t EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
|
||||
/* 32 sequential virtual addresses */
|
||||
const uint16_t EE_VirtAddrs[EE_NUM_VIRTUAL_ADDR] =
|
||||
{
|
||||
0x0001, 0x0002, 0x0003, 0x0004,
|
||||
0x0005, 0x0006, 0x0007, 0x0008,
|
||||
0x0009, 0x000A, 0x000B, 0x000C,
|
||||
0x000D, 0x000E, 0x000F, 0x0010,
|
||||
0x0011, 0x0012, 0x0013, 0x0014,
|
||||
0x0015, 0x0016, 0x0017, 0x0018,
|
||||
0x0019, 0x001A, 0x001B, 0x001C,
|
||||
0x001D, 0x001E, 0x001F, 0x0020,
|
||||
|
||||
0x0021, 0x0022, 0x0023, 0x0024,
|
||||
0x0025, 0x0026, 0x0027, 0x0028,
|
||||
0x0029, 0x002A, 0x002B, 0x002C,
|
||||
0x002D, 0x002E, 0x002F, 0x0030,
|
||||
0x0031, 0x0032, 0x0033, 0x0034,
|
||||
0x0035, 0x0036, 0x0037, 0x0038,
|
||||
0x0039, 0x003A, 0x003B, 0x003C,
|
||||
0x003D, 0x003E, 0x003F, 0x0040
|
||||
};
|
||||
/* ========================================================================= */
|
||||
|
||||
/* --- Internal helpers ---------------------------------------------------- */
|
||||
|
||||
static uint16_t EE_GetPageStatus(uint32_t pageBase)
|
||||
{
|
||||
return *(__IO uint16_t *)pageBase;
|
||||
}
|
||||
|
||||
static HAL_StatusTypeDef EE_FlashProgramHalfWord(uint32_t Address, uint16_t Data)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
|
||||
HAL_FLASH_Unlock();
|
||||
status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, Address, Data);
|
||||
HAL_FLASH_Lock();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static HAL_StatusTypeDef EE_FlashErasePage(uint32_t PageAddress)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
FLASH_EraseInitTypeDef EraseInit;
|
||||
uint32_t PageError = 0;
|
||||
|
||||
HAL_FLASH_Unlock();
|
||||
|
||||
EraseInit.TypeErase = FLASH_TYPEERASE_PAGES;
|
||||
EraseInit.PageAddress = PageAddress;
|
||||
EraseInit.NbPages = 1;
|
||||
|
||||
status = HAL_FLASHEx_Erase(&EraseInit, &PageError);
|
||||
|
||||
HAL_FLASH_Lock();
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Find first free record address in given page (returns 0 if full) */
|
||||
static uint32_t EE_FindFreeAddress(uint32_t pageBase)
|
||||
{
|
||||
uint32_t addr = pageBase + 2U; /* Skip status word */
|
||||
uint32_t pageEnd = pageBase + EE_PAGE_SIZE;
|
||||
|
||||
while (addr < (pageEnd - sizeof(EE_Record_t) + 1U))
|
||||
{
|
||||
uint16_t vaddr = *(__IO uint16_t *)addr;
|
||||
|
||||
if (vaddr == 0xFFFFU)
|
||||
{
|
||||
/* Empty slot */
|
||||
return addr;
|
||||
}
|
||||
addr += sizeof(EE_Record_t);
|
||||
}
|
||||
|
||||
return 0U; /* No space */
|
||||
}
|
||||
|
||||
/* Find latest value of VirtAddress in a specific page (internal, uses EE_Status) */
|
||||
/* Find latest value of VirtAddress in a specific page (scan forward) */
|
||||
static EE_Status EE_FindInPage(uint32_t pageBase, uint16_t VirtAddress, uint16_t *Data)
|
||||
{
|
||||
uint32_t addr = pageBase + 2U; // skip status halfword
|
||||
uint32_t pageEnd = pageBase + EE_PAGE_SIZE;
|
||||
EE_Status result = EE_NOT_FOUND;
|
||||
uint16_t lastVal = 0;
|
||||
|
||||
if (Data == NULL)
|
||||
return EE_ERROR;
|
||||
|
||||
while (addr <= (pageEnd - sizeof(EE_Record_t)))
|
||||
{
|
||||
uint16_t vaddr = *(__IO uint16_t *)addr;
|
||||
|
||||
if (vaddr == 0xFFFFU)
|
||||
{
|
||||
// First empty slot => no more records in this page
|
||||
break;
|
||||
}
|
||||
|
||||
uint16_t value = *(__IO uint16_t *)(addr + 2U);
|
||||
|
||||
if (vaddr == VirtAddress)
|
||||
{
|
||||
lastVal = value; // keep most recent
|
||||
result = EE_OK;
|
||||
}
|
||||
|
||||
addr += sizeof(EE_Record_t); // move 4 bytes forward
|
||||
}
|
||||
|
||||
if (result == EE_OK)
|
||||
*Data = lastVal;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Format both pages: erase and set PAGE0 as VALID */
|
||||
static EE_Status EE_Format(void)
|
||||
{
|
||||
if (EE_FlashErasePage(EE_PAGE0_BASE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
if (EE_FlashErasePage(EE_PAGE1_BASE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
if (EE_FlashProgramHalfWord(EE_PAGE0_BASE, EE_PAGE_STATUS_VALID) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* PAGE1 will remain erased (status = 0xFFFF) */
|
||||
EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
|
||||
return EE_STATUS_OK;
|
||||
}
|
||||
|
||||
/* Get the base of the other page */
|
||||
static uint32_t EE_GetOtherPageBase(uint32_t pageBase)
|
||||
{
|
||||
return (pageBase == EE_PAGE0_BASE) ? EE_PAGE1_BASE : EE_PAGE0_BASE;
|
||||
}
|
||||
|
||||
/* Page transfer (garbage collection + new write) */
|
||||
static EE_Status EE_PageTransfer(uint16_t VirtAddress, uint16_t Data)
|
||||
{
|
||||
uint32_t oldBase = EE_ActivePageBase;
|
||||
uint32_t newBase = EE_GetOtherPageBase(oldBase);
|
||||
uint32_t addr;
|
||||
uint16_t value;
|
||||
EE_Status st;
|
||||
|
||||
/* Erase new page */
|
||||
if (EE_FlashErasePage(newBase) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Mark new page as RECEIVE */
|
||||
if (EE_FlashProgramHalfWord(newBase, EE_PAGE_STATUS_RECEIVE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Start writing records just after status */
|
||||
addr = newBase + 2U;
|
||||
|
||||
/* For each known virtual variable */
|
||||
for (uint16_t i = 0; i < EE_NUM_VIRTUAL_ADDR; i++)
|
||||
{
|
||||
uint16_t vaddr = EE_VirtAddrs[i];
|
||||
|
||||
if (vaddr == VirtAddress)
|
||||
{
|
||||
/* Use the new data passed into PageTransfer */
|
||||
value = Data;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Read latest value from old active page */
|
||||
st = EE_FindInPage(oldBase, vaddr, &value);
|
||||
if (st != EE_STATUS_OK)
|
||||
{
|
||||
/* Variable never written -> skip */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Write record to new page */
|
||||
if (EE_FlashProgramHalfWord(addr, vaddr) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
if (EE_FlashProgramHalfWord(addr + 2U, value) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
addr += sizeof(EE_Record_t);
|
||||
if (addr >= (newBase + EE_PAGE_SIZE))
|
||||
return EE_STATUS_NO_SPACE;
|
||||
}
|
||||
|
||||
/* Erase old page */
|
||||
if (EE_FlashErasePage(oldBase) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Mark new page as VALID */
|
||||
if (EE_FlashProgramHalfWord(newBase, EE_PAGE_STATUS_VALID) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Update active page */
|
||||
EE_ActivePageBase = newBase;
|
||||
|
||||
return EE_STATUS_OK;
|
||||
}
|
||||
|
||||
/* --- Public API ----------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* Initialize the EEPROM emulation.
|
||||
* - Checks page statuses and chooses the active page.
|
||||
* - If inconsistent or blank, formats pages.
|
||||
* PUBLIC RETURN TYPE: uint16_t (EE_OK / EE_ERROR / ...)
|
||||
*/
|
||||
uint16_t EE_Init(void)
|
||||
{
|
||||
uint16_t status0 = EE_GetPageStatus(EE_PAGE0_BASE);
|
||||
uint16_t status1 = EE_GetPageStatus(EE_PAGE1_BASE);
|
||||
|
||||
if ((status0 == EE_PAGE_STATUS_ERASED) && (status1 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
/* Fresh device -> format */
|
||||
return (uint16_t)EE_Format();
|
||||
}
|
||||
else if ((status0 == EE_PAGE_STATUS_VALID) && (status1 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
return EE_OK;
|
||||
}
|
||||
else if ((status1 == EE_PAGE_STATUS_VALID) && (status0 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
EE_ActivePageBase = EE_PAGE1_BASE;
|
||||
return EE_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Any weird or inconsistent state -> reformat */
|
||||
return (uint16_t)EE_Format();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a 16-bit variable by its virtual address.
|
||||
* PUBLIC RETURN: EE_OK / EE_NOT_FOUND / EE_ERROR (as uint16_t)
|
||||
*/
|
||||
uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t *Data)
|
||||
{
|
||||
EE_Status st;
|
||||
|
||||
if (Data == NULL)
|
||||
return EE_ERROR;
|
||||
|
||||
st = EE_FindInPage(EE_ActivePageBase, VirtAddress, Data);
|
||||
return (uint16_t)st;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write (append) a 16-bit variable.
|
||||
* - Writes a new record in the active page.
|
||||
* - If the page is full, triggers a page transfer (GC).
|
||||
* PUBLIC RETURN: EE_OK / EE_ERROR / EE_NO_SPACE (as uint16_t)
|
||||
*/
|
||||
uint16_t EE_WriteVariable(uint16_t VirtAddress, uint16_t Data)
|
||||
{
|
||||
uint32_t freeAddr;
|
||||
EE_Status st;
|
||||
|
||||
/* Find free space in active page */
|
||||
freeAddr = EE_FindFreeAddress(EE_ActivePageBase);
|
||||
if (freeAddr != 0U)
|
||||
{
|
||||
/* Write new record */
|
||||
if (EE_FlashProgramHalfWord(freeAddr, VirtAddress) != HAL_OK)
|
||||
return EE_ERROR;
|
||||
if (EE_FlashProgramHalfWord(freeAddr + 2U, Data) != HAL_OK)
|
||||
return EE_ERROR;
|
||||
|
||||
return EE_OK;
|
||||
}
|
||||
|
||||
/* No space -> page transfer */
|
||||
st = EE_PageTransfer(VirtAddress, Data);
|
||||
return (uint16_t)st;
|
||||
}
|
||||
|
||||
void loadEE(void){
|
||||
char s [200];
|
||||
EEW_Read(M1PWMAP, &m1pwmap);
|
||||
EEW_Read(M1PWMCH, &m1pwmch);
|
||||
EEW_Read(M2PWMAP, &m2pwmap);
|
||||
EEW_Read(M2PWMCH, &m2pwmch);
|
||||
EEW_Read(M3PWMAP, &m3pwmap);
|
||||
EEW_Read(M3PWMCH, &m3pwmch);
|
||||
EEW_Read(M4PWMAP, &m4pwmap);
|
||||
EEW_Read(M4PWMCH, &m4pwmch);
|
||||
EEW_Read(M1TIMEOUTMAN, &m1TimeoutMan);
|
||||
EEW_Read(M2TIMEOUTMAN, &m2TimeoutMan);
|
||||
EEW_Read(M3TIMEOUTMAN, &m3TimeoutMan);
|
||||
EEW_Read(M4TIMEOUTMAN, &m4TimeoutMan);
|
||||
EEW_Read(TWAP, &twap);
|
||||
EEW_Read(T1CH, &t1ch);
|
||||
EEW_Read(T2CH, &t2ch);
|
||||
EEW_Read(T3CH, &t3ch);
|
||||
EEW_Read(T4CH, &t4ch);
|
||||
EEW_Read(TWCH, &twch);
|
||||
EEW_Read(TRAMP1, &tramp1);
|
||||
EEW_Read(M1PWMMAN, &m1pwmMan);
|
||||
EEW_Read(M2PWMMAN, &m2pwmMan);
|
||||
EEW_Read(M3PWMMAN, &m3pwmMan);
|
||||
EEW_Read(M4PWMMAN, &m4pwmMan);
|
||||
EEW_Read(TRAMPMAN, &trampman);
|
||||
EEW_Read(TRAMP, &tramp);
|
||||
|
||||
EEW_Read(APM1START,&apM1start);
|
||||
EEW_Read(APM1STOP ,&apM1stop);
|
||||
EEW_Read(APM2START,&apM2start);
|
||||
EEW_Read(APM2STOP ,&apM2stop);
|
||||
EEW_Read(APM3START,&apM3start);
|
||||
EEW_Read(APM3STOP ,&apM3stop);
|
||||
EEW_Read(APM4START,&apM4start);
|
||||
EEW_Read(APM4STOP ,&apM4stop);
|
||||
EEW_Read(CHM1START,&chM1start);
|
||||
EEW_Read(CHM1STOP ,&chM1stop);
|
||||
EEW_Read(CHM2START,&chM2start);
|
||||
EEW_Read(CHM2STOP ,&chM2stop);
|
||||
EEW_Read(CHM3START,&chM3start);
|
||||
EEW_Read(CHM3STOP ,&chM3stop);
|
||||
EEW_Read(CHM4START,&chM4start);
|
||||
EEW_Read(CHM4STOP ,&chM4stop);
|
||||
|
||||
sprintf((char*)s,"LoadEE\n");
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
sprintf((char*)s,"\nm1pwmap=%d m1pwmch=%d m2pwmap=%d m2pwmch=%d m3pwmap=%d m3pwmch=%d m4pwmap=%d m4pwmch=%d",m1pwmap,m1pwmch,m2pwmap,m2pwmch,m3pwmap,m3pwmch,m4pwmap, m4pwmch);
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
sprintf((char*)s,"\nm1TimeoutMan=%d m2TimeoutMan=%d m3TimeoutMan=%d m4TimeoutMan=%d ",m1TimeouMan,m2TimeoutMan,m3timeoutMan,m4TimeoutMan);
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
sprintf((char*)s,"\ntramp=%d trampman=%d",tramp,trampman);
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
sprintf((char*)s,"\nm1pwmMan=%d m2pwmMan=%d m3pwmMan=%d m4pwmMan=%d",m1pwmMan,m2pwmMan,m3pwmMan,m4pwmMan);
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* eeprom.h
|
||||
*
|
||||
* Created on: Dec 7, 2025
|
||||
* Author: user
|
||||
*/
|
||||
|
||||
#ifndef __EEPROM_H
|
||||
#define __EEPROM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "stm32f1xx_hal.h"
|
||||
|
||||
/*
|
||||
* Simple EEPROM emulation for STM32F103C8T6 (medium density).
|
||||
* - Uses 2 Flash pages (1 kB each) at the end of Flash.
|
||||
* - Stores variables as 16-bit values identified by 16-bit "virtual addresses".
|
||||
*
|
||||
* You must define the list of virtual addresses in eeprom.c: EE_VirtAddrs[].
|
||||
*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
EE_STATUS_OK = 0,
|
||||
EE_STATUS_ERROR,
|
||||
EE_STATUS_NOT_FOUND,
|
||||
EE_STATUS_NO_SPACE
|
||||
} EE_Status;
|
||||
|
||||
/* For compatibility with ST style uint16_t return codes */
|
||||
#define EE_OK ((uint16_t)EE_STATUS_OK)
|
||||
#define EE_ERROR ((uint16_t)EE_STATUS_ERROR)
|
||||
#define EE_NOT_FOUND ((uint16_t)EE_STATUS_NOT_FOUND)
|
||||
#define EE_NO_SPACE ((uint16_t)EE_STATUS_NO_SPACE)
|
||||
|
||||
/* Flash parameters for STM32F103C8T6 */
|
||||
#define EE_FLASH_BASE_ADDR 0x08000000U
|
||||
#define EE_PAGE_SIZE 0x400U /* 1 kB pages */
|
||||
|
||||
/*
|
||||
* Here we assume a 64 kB Flash device (STM32F103C8T6):
|
||||
* Flash range: 0x0800 0000 - 0x0800 FFFF
|
||||
* Pages: 0..63 (64 pages)
|
||||
* We use the last 2 pages for EEPROM:
|
||||
* - Page 62: 0x0800 F800
|
||||
* - Page 63: 0x0800 FC00
|
||||
*/
|
||||
#define EE_PAGE0_BASE (EE_FLASH_BASE_ADDR + (62U * EE_PAGE_SIZE))
|
||||
#define EE_PAGE1_BASE (EE_FLASH_BASE_ADDR + (63U * EE_PAGE_SIZE))
|
||||
|
||||
/* Page status markers (stored in the first halfword of each page) */
|
||||
#define EE_PAGE_STATUS_ERASED 0xFFFFU
|
||||
#define EE_PAGE_STATUS_VALID 0xAAAAU
|
||||
#define EE_PAGE_STATUS_RECEIVE 0x5555U
|
||||
|
||||
/*
|
||||
* Configure how many virtual variables you have.
|
||||
* Example: bytes, words, and array elements mapped to 16-bit variables.
|
||||
* Set EE_NUM_VIRTUAL_ADDR and define EE_VirtAddrs[] in eeprom.c.
|
||||
*/
|
||||
/* 32 virtual variables, sequential addresses */
|
||||
#define EE_NUM_VIRTUAL_ADDR 64U
|
||||
#define EEW_ADDR(i) ((uint16_t)(0x0001U + (uint16_t)(i))) // i = 0..63
|
||||
|
||||
|
||||
#define M1PWMAP 0 //m1pwmap
|
||||
#define M1PWMCH 1 //m1pwmch
|
||||
#define M2PWMAP 2 //m2pwmap
|
||||
#define M2PWMCH 3 //m2pwmch
|
||||
#define M3PWMAP 4 //m3pwmap
|
||||
#define M3PWMCH 5 //m3pwmch
|
||||
#define M4PWMAP 6 //m4pwmap
|
||||
#define M4PWMCH 7 //m4pwmch
|
||||
#define M1RAMPSTART 8 //m1rampstart
|
||||
#define M2RAMPSTART 9 //m2rampstart
|
||||
#define M3RAMPSTART 10 //m3rampstart
|
||||
#define M4RAMPSTART 11 //m4rampstart
|
||||
#define T1AP 12 //t1ap
|
||||
#define T2AP 13 //t2ap
|
||||
#define T3AP 14 //t3ap
|
||||
#define T4AP 15 //t4ap
|
||||
#define TWAP 16 //twap
|
||||
#define T1CH 17 //t1ch
|
||||
#define T2CH 18 //t2ch
|
||||
#define T3CH 19 //t3ch
|
||||
#define T4CH 20 //t4ch
|
||||
#define TWCH 21 //twch
|
||||
|
||||
#define TRAMP1 25 //tramp1
|
||||
#define M1PWMMAN 26 //m1pwmMan
|
||||
#define M2PWMMAN 27 //m2pwmMan
|
||||
#define M3PWMMAN 28 //m3pwmMan
|
||||
#define M4PWMMAN 29 //m4pwmMan
|
||||
#define TRAMPMAN 30 //trampman
|
||||
#define TRAMP 31 //tramp
|
||||
|
||||
|
||||
/* Virtual address table (defined in eeprom.c, can be customized) */
|
||||
extern const uint16_t EE_VirtAddrs[EE_NUM_VIRTUAL_ADDR];
|
||||
|
||||
/* Public API – now using uint16_t like ST examples */
|
||||
uint16_t EE_Init(void);
|
||||
uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t *Data);
|
||||
uint16_t EE_WriteVariable(uint16_t VirtAddress, uint16_t Data);
|
||||
void loadEE(void);
|
||||
/* Pseudo-array accessor EEW[idx] */
|
||||
static inline uint16_t EEW_Read(uint8_t idx, uint16_t *value)
|
||||
{
|
||||
return EE_ReadVariable(EEW_ADDR(idx), value);
|
||||
}
|
||||
|
||||
static inline uint16_t EEW_Write(uint8_t idx, uint16_t value)
|
||||
{
|
||||
return EE_WriteVariable(EEW_ADDR(idx), value);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __EEPROM_H */
|
||||
@@ -0,0 +1,304 @@
|
||||
/*
|
||||
* mot.c
|
||||
*
|
||||
* Created on: May 2, 2026
|
||||
* Author: user
|
||||
*/
|
||||
#include "mot.h"
|
||||
|
||||
|
||||
motMov_st m1ap(void){
|
||||
static motMov_st m1st;
|
||||
if(rtCiclo<apM1start)m1st=motWaiting;
|
||||
switch(m1st){
|
||||
case motWaiting:
|
||||
SetMotPerc(M1,FW,0);
|
||||
SetMotPerc(M1,BW,0);
|
||||
if(rtCiclo>=apM1start){
|
||||
(void)ramp(M1,BW,mrampstart[M1-1],m1pwmap,tramp,RAMPINIT);
|
||||
m1st=motStartRamp;
|
||||
}
|
||||
break;
|
||||
case motStartRamp:
|
||||
if(ramp(M1,BW,mrampstart[M1-1],m1pwmap,tramp,RAMPRUN)==DONE){
|
||||
m1st=motWaitingTime;
|
||||
}
|
||||
break;
|
||||
case motWaitingTime:
|
||||
if(rtCiclo>=apM1stop){
|
||||
(void)ramp(M1,BW,m1pwmap,0,tramp,RAMPINIT);
|
||||
m1st=motStopRamp;
|
||||
}
|
||||
break;
|
||||
case motStopRamp:
|
||||
if(ramp(M1,BW,m1pwmap,0,tramp,RAMPRUN)==DONE){
|
||||
m1st=motStop;
|
||||
}
|
||||
break;
|
||||
case motStop:
|
||||
default:
|
||||
SetMotPerc(M1,FW,0);
|
||||
SetMotPerc(M1,BW,0);
|
||||
break;
|
||||
}
|
||||
return m1st;
|
||||
}
|
||||
|
||||
motMov_st m2ap(void){
|
||||
static motMov_st m2st;
|
||||
if(rtCiclo<apM2start)m2st=motWaiting;
|
||||
switch(m2st){
|
||||
case motWaiting:
|
||||
SetMotPerc(M2,FW,0);
|
||||
SetMotPerc(M2,BW,0);
|
||||
if(rtCiclo>=apM2start){
|
||||
(void)ramp(M2,BW,mrampstart[M2-1],m2pwmap,tramp,RAMPINIT);
|
||||
m2st=motStartRamp;
|
||||
}
|
||||
break;
|
||||
case motStartRamp:
|
||||
if(ramp(M2,BW,mrampstart[M2-1],m2pwmap,tramp,RAMPRUN)==DONE){
|
||||
m2st=motWaitingTime;
|
||||
}
|
||||
break;
|
||||
case motWaitingTime:
|
||||
if(rtCiclo>=apM2stop){
|
||||
(void)ramp(M2,BW,m2pwmap,0,tramp,RAMPINIT);
|
||||
m2st=motStopRamp;
|
||||
}
|
||||
break;
|
||||
case motStopRamp:
|
||||
if(ramp(M2,BW,m2pwmap,0,tramp,RAMPRUN)==DONE){
|
||||
m2st=motStop;
|
||||
}
|
||||
break;
|
||||
case motStop:
|
||||
default:
|
||||
SetMotPerc(M2,FW,0);
|
||||
SetMotPerc(M2,BW,0);
|
||||
break;
|
||||
}
|
||||
return m2st;
|
||||
}
|
||||
|
||||
motMov_st m3ap(void){
|
||||
static motMov_st m3st;
|
||||
if(rtCiclo<apM3start)m3st=motWaiting;
|
||||
switch(m3st){
|
||||
case motWaiting:
|
||||
SetMotPerc(M3,FW,0);
|
||||
SetMotPerc(M3,BW,0);
|
||||
if(rtCiclo>=apM3start){
|
||||
(void)ramp(M3,BW,mrampstart[M3-1],m2pwmap,tramp,RAMPINIT);
|
||||
m3st=motStartRamp;
|
||||
}
|
||||
break;
|
||||
case motStartRamp:
|
||||
if(ramp(M3,BW,mrampstart[M3-1],m3pwmap,tramp,RAMPRUN)==DONE){
|
||||
m3st=motWaitingTime;
|
||||
}
|
||||
break;
|
||||
case motWaitingTime:
|
||||
if(rtCiclo>=apM3stop){
|
||||
(void)ramp(M3,BW,m3pwmap,0,tramp,RAMPINIT);
|
||||
m3st=motStopRamp;
|
||||
}
|
||||
break;
|
||||
case motStopRamp:
|
||||
if(ramp(M3,BW,m3pwmap,0,tramp,RAMPRUN)==DONE){
|
||||
m3st=motStop;
|
||||
}
|
||||
break;
|
||||
case motStop:
|
||||
default:
|
||||
SetMotPerc(M3,FW,0);
|
||||
SetMotPerc(M3,BW,0);
|
||||
break;
|
||||
}
|
||||
return m3st;
|
||||
}
|
||||
|
||||
motMov_st m4ap(void){
|
||||
static motMov_st m4st;
|
||||
if(rtCiclo<apM4start)m4st=motWaiting;
|
||||
switch(m4st){
|
||||
case motWaiting:
|
||||
SetMotPerc(M4,FW,0);
|
||||
SetMotPerc(M4,BW,0);
|
||||
if(rtCiclo>=apM4start){
|
||||
(void)ramp(M4,BW,mrampstart[M4-1],m2pwmap,tramp,RAMPINIT);
|
||||
m4st=motStartRamp;
|
||||
}
|
||||
break;
|
||||
case motStartRamp:
|
||||
if(ramp(M4,BW,mrampstart[M4-1],m4pwmap,tramp,RAMPRUN)==DONE){
|
||||
m4st=motWaitingTime;
|
||||
}
|
||||
break;
|
||||
case motWaitingTime:
|
||||
if(rtCiclo>=apM4stop){
|
||||
(void)ramp(M4,BW,m4pwmap,0,tramp,RAMPINIT);
|
||||
m4st=motStopRamp;
|
||||
}
|
||||
break;
|
||||
case motStopRamp:
|
||||
if(ramp(43,BW,m4pwmap,0,tramp,RAMPRUN)==DONE){
|
||||
m4st=motStop;
|
||||
}
|
||||
break;
|
||||
case motStop:
|
||||
default:
|
||||
SetMotPerc(M4,FW,0);
|
||||
SetMotPerc(M4,BW,0);
|
||||
break;
|
||||
}
|
||||
return m4st;
|
||||
}
|
||||
|
||||
motMov_st m1ch(void){
|
||||
static motMov_st m1st;
|
||||
if(rtCiclo<chM1start)m1st=motWaiting;
|
||||
switch(m1st){
|
||||
case motWaiting:
|
||||
SetMotPerc(M1,FW,0);
|
||||
SetMotPerc(M1,BW,0);
|
||||
if(rtCiclo>=chM1start){
|
||||
(void)ramp(M1,FW,mrampstart[M1-1],m1pwmch,tramp,RAMPINIT);
|
||||
m1st=motStartRamp;
|
||||
}
|
||||
break;
|
||||
case motStartRamp:
|
||||
if(ramp(M1,FW,mrampstart[M1-1],m1pwmch,tramp,RAMPRUN)==DONE){
|
||||
m1st=motWaitingTime;
|
||||
}
|
||||
break;
|
||||
case motWaitingTime:
|
||||
if(rtCiclo>=chM1stop){
|
||||
(void)ramp(M1,FW,m1pwmch,0,tramp,RAMPINIT);
|
||||
m1st=motStopRamp;
|
||||
}
|
||||
break;
|
||||
case motStopRamp:
|
||||
if(ramp(M1,FW,m1pwmch,0,tramp,RAMPRUN)==DONE){
|
||||
m1st=motStop;
|
||||
}
|
||||
break;
|
||||
case motStop:
|
||||
default:
|
||||
SetMotPerc(M1,FW,0);
|
||||
SetMotPerc(M1,BW,0);
|
||||
break;
|
||||
}
|
||||
return m1st;
|
||||
}
|
||||
|
||||
motMov_st m2ch(void){
|
||||
static motMov_st m2st;
|
||||
if(rtCiclo<chM2start)m2st=motWaiting;
|
||||
switch(m2st){
|
||||
case motWaiting:
|
||||
SetMotPerc(M2,FW,0);
|
||||
SetMotPerc(M2,BW,0);
|
||||
if(rtCiclo>=chM2start){
|
||||
(void)ramp(M2,FW,mrampstart[M2-1],m2pwmch,tramp,RAMPINIT);
|
||||
m2st=motStartRamp;
|
||||
}
|
||||
break;
|
||||
case motStartRamp:
|
||||
if(ramp(M2,FW,mrampstart[M2-1],m2pwmch,tramp,RAMPRUN)==DONE){
|
||||
m2st=motWaitingTime;
|
||||
}
|
||||
break;
|
||||
case motWaitingTime:
|
||||
if(rtCiclo>=chM2stop){
|
||||
(void)ramp(M2,FW,m2pwmch,0,tramp,RAMPINIT);
|
||||
m2st=motStopRamp;
|
||||
}
|
||||
break;
|
||||
case motStopRamp:
|
||||
if(ramp(M2,FW,m2pwmch,0,tramp,RAMPRUN)==DONE){
|
||||
m2st=motStop;
|
||||
}
|
||||
break;
|
||||
case motStop:
|
||||
default:
|
||||
SetMotPerc(M2,FW,0);
|
||||
SetMotPerc(M2,BW,0);
|
||||
break;
|
||||
}
|
||||
return m2st;
|
||||
}
|
||||
|
||||
motMov_st m3ch(void){
|
||||
static motMov_st m3st;
|
||||
if(rtCiclo<chM3start)m3st=motWaiting;
|
||||
switch(m3st){
|
||||
case motWaiting:
|
||||
SetMotPerc(M3,FW,0);
|
||||
SetMotPerc(M3,BW,0);
|
||||
if(rtCiclo>=chM3start){
|
||||
(void)ramp(M3,FW,mrampstart[M3-1],m2pwmch,tramp,RAMPINIT);
|
||||
m3st=motStartRamp;
|
||||
}
|
||||
break;
|
||||
case motStartRamp:
|
||||
if(ramp(M3,FW,mrampstart[M3-1],m3pwmch,tramp,RAMPRUN)==DONE){
|
||||
m3st=motWaitingTime;
|
||||
}
|
||||
break;
|
||||
case motWaitingTime:
|
||||
if(rtCiclo>=chM3stop){
|
||||
(void)ramp(M3,FW,m3pwmch,0,tramp,RAMPINIT);
|
||||
m3st=motStopRamp;
|
||||
}
|
||||
break;
|
||||
case motStopRamp:
|
||||
if(ramp(M3,FW,m3pwmch,0,tramp,RAMPRUN)==DONE){
|
||||
m3st=motStop;
|
||||
}
|
||||
break;
|
||||
case motStop:
|
||||
default:
|
||||
SetMotPerc(M3,FW,0);
|
||||
SetMotPerc(M3,BW,0);
|
||||
break;
|
||||
}
|
||||
return m3st;
|
||||
}
|
||||
|
||||
motMov_st m4ch(void){
|
||||
static motMov_st m4st;
|
||||
if(rtCiclo<chM4start)m4st=motWaiting;
|
||||
switch(m4st){
|
||||
case motWaiting:
|
||||
SetMotPerc(M4,FW,0);
|
||||
SetMotPerc(M4,BW,0);
|
||||
if(rtCiclo>=chM4start){
|
||||
(void)ramp(M4,FW,mrampstart[M4-1],m2pwmch,tramp,RAMPINIT);
|
||||
m4st=motStartRamp;
|
||||
}
|
||||
break;
|
||||
case motStartRamp:
|
||||
if(ramp(M4,FW,mrampstart[M4-1],m4pwmch,tramp,RAMPRUN)==DONE){
|
||||
m4st=motWaitingTime;
|
||||
}
|
||||
break;
|
||||
case motWaitingTime:
|
||||
if(rtCiclo>=chM4stop){
|
||||
(void)ramp(M4,FW,m4pwmch,0,tramp,RAMPINIT);
|
||||
m4st=motStopRamp;
|
||||
}
|
||||
break;
|
||||
case motStopRamp:
|
||||
if(ramp(43,FW,m4pwmch,0,tramp,RAMPRUN)==DONE){
|
||||
m4st=motStop;
|
||||
}
|
||||
break;
|
||||
case motStop:
|
||||
default:
|
||||
SetMotPerc(M4,FW,0);
|
||||
SetMotPerc(M4,BW,0);
|
||||
break;
|
||||
}
|
||||
return m4st;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,321 @@
|
||||
/*
|
||||
* mot.c
|
||||
*
|
||||
* Created on: May 2, 2026
|
||||
* Author: user
|
||||
*/
|
||||
#include "mot.h"
|
||||
|
||||
extern uint16_t apM1start;
|
||||
extern uint16_t apM1stop;
|
||||
extern uint16_t apM2start;
|
||||
extern uint16_t apM2stop;
|
||||
extern uint16_t apM3start;
|
||||
extern uint16_t apM3stop;
|
||||
extern uint16_t apM4start;
|
||||
extern uint16_t apM4stop;
|
||||
extern uint16_t chM1start;
|
||||
extern uint16_t chM1stop;
|
||||
extern uint16_t chM2start;
|
||||
extern uint16_t chM2stop;
|
||||
extern uint16_t chM3start;
|
||||
extern uint16_t chM3stop;
|
||||
extern uint16_t chM4start;
|
||||
extern uint16_t chM4stop;
|
||||
extern volatile uint16_t rtCiclo;
|
||||
|
||||
motMov_st m1ap(void){
|
||||
static motMov_st m1st;
|
||||
if(rtCiclo<apM1start)m1st=motWaiting;
|
||||
switch(m1st){
|
||||
case motWaiting:
|
||||
SetMotPerc(M1,FW,0);
|
||||
SetMotPerc(M1,BW,0);
|
||||
if(rtCiclo>=apM1start){
|
||||
(void)ramp(M1,BW,mrampstart[M1-1],m1pwmap,tramp,RAMPINIT);
|
||||
m1st=motStartRamp;
|
||||
}
|
||||
break;
|
||||
case motStartRamp:
|
||||
if(ramp(M1,BW,mrampstart[M1-1],m1pwmap,tramp,RAMPRUN)==DONE){
|
||||
m1st=motWaitingTime;
|
||||
}
|
||||
break;
|
||||
case motWaitingTime:
|
||||
if(rtCiclo>=apM1stop){
|
||||
(void)ramp(M1,BW,m1pwmap,0,tramp,RAMPINIT);
|
||||
m1st=motStopRamp;
|
||||
}
|
||||
break;
|
||||
case motStopRamp:
|
||||
if(ramp(M1,BW,m1pwmap,0,tramp,RAMPRUN)==DONE){
|
||||
m1st=motStop;
|
||||
}
|
||||
break;
|
||||
case motStop:
|
||||
default:
|
||||
SetMotPerc(M1,FW,0);
|
||||
SetMotPerc(M1,BW,0);
|
||||
break;
|
||||
}
|
||||
return m1st;
|
||||
}
|
||||
|
||||
motMov_st m2ap(void){
|
||||
static motMov_st m2st;
|
||||
if(rtCiclo<apM2start)m2st=motWaiting;
|
||||
switch(m2st){
|
||||
case motWaiting:
|
||||
SetMotPerc(M2,FW,0);
|
||||
SetMotPerc(M2,BW,0);
|
||||
if(rtCiclo>=apM2start){
|
||||
(void)ramp(M2,BW,mrampstart[M2-1],m2pwmap,tramp,RAMPINIT);
|
||||
m2st=motStartRamp;
|
||||
}
|
||||
break;
|
||||
case motStartRamp:
|
||||
if(ramp(M2,BW,mrampstart[M2-1],m2pwmap,tramp,RAMPRUN)==DONE){
|
||||
m2st=motWaitingTime;
|
||||
}
|
||||
break;
|
||||
case motWaitingTime:
|
||||
if(rtCiclo>=apM2stop){
|
||||
(void)ramp(M2,BW,m2pwmap,0,tramp,RAMPINIT);
|
||||
m2st=motStopRamp;
|
||||
}
|
||||
break;
|
||||
case motStopRamp:
|
||||
if(ramp(M2,BW,m2pwmap,0,tramp,RAMPRUN)==DONE){
|
||||
m2st=motStop;
|
||||
}
|
||||
break;
|
||||
case motStop:
|
||||
default:
|
||||
SetMotPerc(M2,FW,0);
|
||||
SetMotPerc(M2,BW,0);
|
||||
break;
|
||||
}
|
||||
return m2st;
|
||||
}
|
||||
|
||||
motMov_st m3ap(void){
|
||||
static motMov_st m3st;
|
||||
if(rtCiclo<apM3start)m3st=motWaiting;
|
||||
switch(m3st){
|
||||
case motWaiting:
|
||||
SetMotPerc(M3,FW,0);
|
||||
SetMotPerc(M3,BW,0);
|
||||
if(rtCiclo>=apM3start){
|
||||
(void)ramp(M3,BW,mrampstart[M3-1],m2pwmap,tramp,RAMPINIT);
|
||||
m3st=motStartRamp;
|
||||
}
|
||||
break;
|
||||
case motStartRamp:
|
||||
if(ramp(M3,BW,mrampstart[M3-1],m3pwmap,tramp,RAMPRUN)==DONE){
|
||||
m3st=motWaitingTime;
|
||||
}
|
||||
break;
|
||||
case motWaitingTime:
|
||||
if(rtCiclo>=apM3stop){
|
||||
(void)ramp(M3,BW,m3pwmap,0,tramp,RAMPINIT);
|
||||
m3st=motStopRamp;
|
||||
}
|
||||
break;
|
||||
case motStopRamp:
|
||||
if(ramp(M3,BW,m3pwmap,0,tramp,RAMPRUN)==DONE){
|
||||
m3st=motStop;
|
||||
}
|
||||
break;
|
||||
case motStop:
|
||||
default:
|
||||
SetMotPerc(M3,FW,0);
|
||||
SetMotPerc(M3,BW,0);
|
||||
break;
|
||||
}
|
||||
return m3st;
|
||||
}
|
||||
|
||||
motMov_st m4ap(void){
|
||||
static motMov_st m4st;
|
||||
if(rtCiclo<apM4start)m4st=motWaiting;
|
||||
switch(m4st){
|
||||
case motWaiting:
|
||||
SetMotPerc(M4,FW,0);
|
||||
SetMotPerc(M4,BW,0);
|
||||
if(rtCiclo>=apM4start){
|
||||
(void)ramp(M4,BW,mrampstart[M4-1],m2pwmap,tramp,RAMPINIT);
|
||||
m4st=motStartRamp;
|
||||
}
|
||||
break;
|
||||
case motStartRamp:
|
||||
if(ramp(M4,BW,mrampstart[M4-1],m4pwmap,tramp,RAMPRUN)==DONE){
|
||||
m4st=motWaitingTime;
|
||||
}
|
||||
break;
|
||||
case motWaitingTime:
|
||||
if(rtCiclo>=apM4stop){
|
||||
(void)ramp(M4,BW,m4pwmap,0,tramp,RAMPINIT);
|
||||
m4st=motStopRamp;
|
||||
}
|
||||
break;
|
||||
case motStopRamp:
|
||||
if(ramp(43,BW,m4pwmap,0,tramp,RAMPRUN)==DONE){
|
||||
m4st=motStop;
|
||||
}
|
||||
break;
|
||||
case motStop:
|
||||
default:
|
||||
SetMotPerc(M4,FW,0);
|
||||
SetMotPerc(M4,BW,0);
|
||||
break;
|
||||
}
|
||||
return m4st;
|
||||
}
|
||||
|
||||
motMov_st m1ch(void){
|
||||
static motMov_st m1st;
|
||||
if(rtCiclo<chM1start)m1st=motWaiting;
|
||||
switch(m1st){
|
||||
case motWaiting:
|
||||
SetMotPerc(M1,FW,0);
|
||||
SetMotPerc(M1,BW,0);
|
||||
if(rtCiclo>=chM1start){
|
||||
(void)ramp(M1,FW,mrampstart[M1-1],m1pwmch,tramp,RAMPINIT);
|
||||
m1st=motStartRamp;
|
||||
}
|
||||
break;
|
||||
case motStartRamp:
|
||||
if(ramp(M1,FW,mrampstart[M1-1],m1pwmch,tramp,RAMPRUN)==DONE){
|
||||
m1st=motWaitingTime;
|
||||
}
|
||||
break;
|
||||
case motWaitingTime:
|
||||
if(rtCiclo>=chM1stop){
|
||||
(void)ramp(M1,FW,m1pwmch,0,tramp,RAMPINIT);
|
||||
m1st=motStopRamp;
|
||||
}
|
||||
break;
|
||||
case motStopRamp:
|
||||
if(ramp(M1,FW,m1pwmch,0,tramp,RAMPRUN)==DONE){
|
||||
m1st=motStop;
|
||||
}
|
||||
break;
|
||||
case motStop:
|
||||
default:
|
||||
SetMotPerc(M1,FW,0);
|
||||
SetMotPerc(M1,BW,0);
|
||||
break;
|
||||
}
|
||||
return m1st;
|
||||
}
|
||||
|
||||
motMov_st m2ch(void){
|
||||
static motMov_st m2st;
|
||||
if(rtCiclo<chM2start)m2st=motWaiting;
|
||||
switch(m2st){
|
||||
case motWaiting:
|
||||
SetMotPerc(M2,FW,0);
|
||||
SetMotPerc(M2,BW,0);
|
||||
if(rtCiclo>=chM2start){
|
||||
(void)ramp(M2,FW,mrampstart[M2-1],m2pwmch,tramp,RAMPINIT);
|
||||
m2st=motStartRamp;
|
||||
}
|
||||
break;
|
||||
case motStartRamp:
|
||||
if(ramp(M2,FW,mrampstart[M2-1],m2pwmch,tramp,RAMPRUN)==DONE){
|
||||
m2st=motWaitingTime;
|
||||
}
|
||||
break;
|
||||
case motWaitingTime:
|
||||
if(rtCiclo>=chM2stop){
|
||||
(void)ramp(M2,FW,m2pwmch,0,tramp,RAMPINIT);
|
||||
m2st=motStopRamp;
|
||||
}
|
||||
break;
|
||||
case motStopRamp:
|
||||
if(ramp(M2,FW,m2pwmch,0,tramp,RAMPRUN)==DONE){
|
||||
m2st=motStop;
|
||||
}
|
||||
break;
|
||||
case motStop:
|
||||
default:
|
||||
SetMotPerc(M2,FW,0);
|
||||
SetMotPerc(M2,BW,0);
|
||||
break;
|
||||
}
|
||||
return m2st;
|
||||
}
|
||||
|
||||
motMov_st m3ch(void){
|
||||
static motMov_st m3st;
|
||||
if(rtCiclo<chM3start)m3st=motWaiting;
|
||||
switch(m3st){
|
||||
case motWaiting:
|
||||
SetMotPerc(M3,FW,0);
|
||||
SetMotPerc(M3,BW,0);
|
||||
if(rtCiclo>=chM3start){
|
||||
(void)ramp(M3,FW,mrampstart[M3-1],m2pwmch,tramp,RAMPINIT);
|
||||
m3st=motStartRamp;
|
||||
}
|
||||
break;
|
||||
case motStartRamp:
|
||||
if(ramp(M3,FW,mrampstart[M3-1],m3pwmch,tramp,RAMPRUN)==DONE){
|
||||
m3st=motWaitingTime;
|
||||
}
|
||||
break;
|
||||
case motWaitingTime:
|
||||
if(rtCiclo>=chM3stop){
|
||||
(void)ramp(M3,FW,m3pwmch,0,tramp,RAMPINIT);
|
||||
m3st=motStopRamp;
|
||||
}
|
||||
break;
|
||||
case motStopRamp:
|
||||
if(ramp(M3,FW,m3pwmch,0,tramp,RAMPRUN)==DONE){
|
||||
m3st=motStop;
|
||||
}
|
||||
break;
|
||||
case motStop:
|
||||
default:
|
||||
SetMotPerc(M3,FW,0);
|
||||
SetMotPerc(M3,BW,0);
|
||||
break;
|
||||
}
|
||||
return m3st;
|
||||
}
|
||||
|
||||
motMov_st m4ch(void){
|
||||
static motMov_st m4st;
|
||||
if(rtCiclo<chM4start)m4st=motWaiting;
|
||||
switch(m4st){
|
||||
case motWaiting:
|
||||
SetMotPerc(M4,FW,0);
|
||||
SetMotPerc(M4,BW,0);
|
||||
if(rtCiclo>=chM4start){
|
||||
(void)ramp(M4,FW,mrampstart[M4-1],m2pwmch,tramp,RAMPINIT);
|
||||
m4st=motStartRamp;
|
||||
}
|
||||
break;
|
||||
case motStartRamp:
|
||||
if(ramp(M4,FW,mrampstart[M4-1],m4pwmch,tramp,RAMPRUN)==DONE){
|
||||
m4st=motWaitingTime;
|
||||
}
|
||||
break;
|
||||
case motWaitingTime:
|
||||
if(rtCiclo>=chM4stop){
|
||||
(void)ramp(M4,FW,m4pwmch,0,tramp,RAMPINIT);
|
||||
m4st=motStopRamp;
|
||||
}
|
||||
break;
|
||||
case motStopRamp:
|
||||
if(ramp(43,FW,m4pwmch,0,tramp,RAMPRUN)==DONE){
|
||||
m4st=motStop;
|
||||
}
|
||||
break;
|
||||
case motStop:
|
||||
default:
|
||||
SetMotPerc(M4,FW,0);
|
||||
SetMotPerc(M4,BW,0);
|
||||
break;
|
||||
}
|
||||
return m4st;
|
||||
}
|
||||
@@ -0,0 +1,332 @@
|
||||
/*
|
||||
* mot.c
|
||||
*
|
||||
* Created on: May 2, 2026
|
||||
* Author: user
|
||||
*/
|
||||
#include "main.h"
|
||||
#include "mot.h"
|
||||
#include "pwm.h"
|
||||
|
||||
extern uint16_t apM1start;
|
||||
extern uint16_t apM1stop;
|
||||
extern uint16_t apM2start;
|
||||
extern uint16_t apM2stop;
|
||||
extern uint16_t apM3start;
|
||||
extern uint16_t apM3stop;
|
||||
extern uint16_t apM4start;
|
||||
extern uint16_t apM4stop;
|
||||
extern uint16_t chM1start;
|
||||
extern uint16_t chM1stop;
|
||||
extern uint16_t chM2start;
|
||||
extern uint16_t chM2stop;
|
||||
extern uint16_t chM3start;
|
||||
extern uint16_t chM3stop;
|
||||
extern uint16_t chM4start;
|
||||
extern uint16_t chM4stop;
|
||||
extern volatile uint16_t rtCiclo;
|
||||
extern uint16_t m1pwmap;
|
||||
extern uint16_t m1pwmch;
|
||||
extern uint16_t m2pwmap;
|
||||
extern uint16_t m2pwmch;
|
||||
extern uint16_t m3pwmap;
|
||||
extern uint16_t m3pwmch;
|
||||
extern uint16_t m4pwmap;
|
||||
extern uint16_t m4pwmch;
|
||||
extern uint16_t mrampstart[4];
|
||||
|
||||
motMov_st m1ap(void){
|
||||
static motMov_st m1st;
|
||||
if(rtCiclo<apM1start)m1st=motWaiting;
|
||||
switch(m1st){
|
||||
case motWaiting:
|
||||
SetMotPerc(M1,FW,0);
|
||||
SetMotPerc(M1,BW,0);
|
||||
if(rtCiclo>=apM1start){
|
||||
(void)ramp(M1,BW,mrampstart[M1-1],m1pwmap,tramp,RAMPINIT);
|
||||
m1st=motStartRamp;
|
||||
}
|
||||
break;
|
||||
case motStartRamp:
|
||||
if(ramp(M1,BW,mrampstart[M1-1],m1pwmap,tramp,RAMPRUN)==DONE){
|
||||
m1st=motWaitingTime;
|
||||
}
|
||||
break;
|
||||
case motWaitingTime:
|
||||
if(rtCiclo>=apM1stop){
|
||||
(void)ramp(M1,BW,m1pwmap,0,tramp,RAMPINIT);
|
||||
m1st=motStopRamp;
|
||||
}
|
||||
break;
|
||||
case motStopRamp:
|
||||
if(ramp(M1,BW,m1pwmap,0,tramp,RAMPRUN)==DONE){
|
||||
m1st=motStop;
|
||||
}
|
||||
break;
|
||||
case motStop:
|
||||
default:
|
||||
SetMotPerc(M1,FW,0);
|
||||
SetMotPerc(M1,BW,0);
|
||||
break;
|
||||
}
|
||||
return m1st;
|
||||
}
|
||||
|
||||
motMov_st m2ap(void){
|
||||
static motMov_st m2st;
|
||||
if(rtCiclo<apM2start)m2st=motWaiting;
|
||||
switch(m2st){
|
||||
case motWaiting:
|
||||
SetMotPerc(M2,FW,0);
|
||||
SetMotPerc(M2,BW,0);
|
||||
if(rtCiclo>=apM2start){
|
||||
(void)ramp(M2,BW,mrampstart[M2-1],m2pwmap,tramp,RAMPINIT);
|
||||
m2st=motStartRamp;
|
||||
}
|
||||
break;
|
||||
case motStartRamp:
|
||||
if(ramp(M2,BW,mrampstart[M2-1],m2pwmap,tramp,RAMPRUN)==DONE){
|
||||
m2st=motWaitingTime;
|
||||
}
|
||||
break;
|
||||
case motWaitingTime:
|
||||
if(rtCiclo>=apM2stop){
|
||||
(void)ramp(M2,BW,m2pwmap,0,tramp,RAMPINIT);
|
||||
m2st=motStopRamp;
|
||||
}
|
||||
break;
|
||||
case motStopRamp:
|
||||
if(ramp(M2,BW,m2pwmap,0,tramp,RAMPRUN)==DONE){
|
||||
m2st=motStop;
|
||||
}
|
||||
break;
|
||||
case motStop:
|
||||
default:
|
||||
SetMotPerc(M2,FW,0);
|
||||
SetMotPerc(M2,BW,0);
|
||||
break;
|
||||
}
|
||||
return m2st;
|
||||
}
|
||||
|
||||
motMov_st m3ap(void){
|
||||
static motMov_st m3st;
|
||||
if(rtCiclo<apM3start)m3st=motWaiting;
|
||||
switch(m3st){
|
||||
case motWaiting:
|
||||
SetMotPerc(M3,FW,0);
|
||||
SetMotPerc(M3,BW,0);
|
||||
if(rtCiclo>=apM3start){
|
||||
(void)ramp(M3,BW,mrampstart[M3-1],m2pwmap,tramp,RAMPINIT);
|
||||
m3st=motStartRamp;
|
||||
}
|
||||
break;
|
||||
case motStartRamp:
|
||||
if(ramp(M3,BW,mrampstart[M3-1],m3pwmap,tramp,RAMPRUN)==DONE){
|
||||
m3st=motWaitingTime;
|
||||
}
|
||||
break;
|
||||
case motWaitingTime:
|
||||
if(rtCiclo>=apM3stop){
|
||||
(void)ramp(M3,BW,m3pwmap,0,tramp,RAMPINIT);
|
||||
m3st=motStopRamp;
|
||||
}
|
||||
break;
|
||||
case motStopRamp:
|
||||
if(ramp(M3,BW,m3pwmap,0,tramp,RAMPRUN)==DONE){
|
||||
m3st=motStop;
|
||||
}
|
||||
break;
|
||||
case motStop:
|
||||
default:
|
||||
SetMotPerc(M3,FW,0);
|
||||
SetMotPerc(M3,BW,0);
|
||||
break;
|
||||
}
|
||||
return m3st;
|
||||
}
|
||||
|
||||
motMov_st m4ap(void){
|
||||
static motMov_st m4st;
|
||||
if(rtCiclo<apM4start)m4st=motWaiting;
|
||||
switch(m4st){
|
||||
case motWaiting:
|
||||
SetMotPerc(M4,FW,0);
|
||||
SetMotPerc(M4,BW,0);
|
||||
if(rtCiclo>=apM4start){
|
||||
(void)ramp(M4,BW,mrampstart[M4-1],m2pwmap,tramp,RAMPINIT);
|
||||
m4st=motStartRamp;
|
||||
}
|
||||
break;
|
||||
case motStartRamp:
|
||||
if(ramp(M4,BW,mrampstart[M4-1],m4pwmap,tramp,RAMPRUN)==DONE){
|
||||
m4st=motWaitingTime;
|
||||
}
|
||||
break;
|
||||
case motWaitingTime:
|
||||
if(rtCiclo>=apM4stop){
|
||||
(void)ramp(M4,BW,m4pwmap,0,tramp,RAMPINIT);
|
||||
m4st=motStopRamp;
|
||||
}
|
||||
break;
|
||||
case motStopRamp:
|
||||
if(ramp(43,BW,m4pwmap,0,tramp,RAMPRUN)==DONE){
|
||||
m4st=motStop;
|
||||
}
|
||||
break;
|
||||
case motStop:
|
||||
default:
|
||||
SetMotPerc(M4,FW,0);
|
||||
SetMotPerc(M4,BW,0);
|
||||
break;
|
||||
}
|
||||
return m4st;
|
||||
}
|
||||
|
||||
motMov_st m1ch(void){
|
||||
static motMov_st m1st;
|
||||
if(rtCiclo<chM1start)m1st=motWaiting;
|
||||
switch(m1st){
|
||||
case motWaiting:
|
||||
SetMotPerc(M1,FW,0);
|
||||
SetMotPerc(M1,BW,0);
|
||||
if(rtCiclo>=chM1start){
|
||||
(void)ramp(M1,FW,mrampstart[M1-1],m1pwmch,tramp,RAMPINIT);
|
||||
m1st=motStartRamp;
|
||||
}
|
||||
break;
|
||||
case motStartRamp:
|
||||
if(ramp(M1,FW,mrampstart[M1-1],m1pwmch,tramp,RAMPRUN)==DONE){
|
||||
m1st=motWaitingTime;
|
||||
}
|
||||
break;
|
||||
case motWaitingTime:
|
||||
if(rtCiclo>=chM1stop){
|
||||
(void)ramp(M1,FW,m1pwmch,0,tramp,RAMPINIT);
|
||||
m1st=motStopRamp;
|
||||
}
|
||||
break;
|
||||
case motStopRamp:
|
||||
if(ramp(M1,FW,m1pwmch,0,tramp,RAMPRUN)==DONE){
|
||||
m1st=motStop;
|
||||
}
|
||||
break;
|
||||
case motStop:
|
||||
default:
|
||||
SetMotPerc(M1,FW,0);
|
||||
SetMotPerc(M1,BW,0);
|
||||
break;
|
||||
}
|
||||
return m1st;
|
||||
}
|
||||
|
||||
motMov_st m2ch(void){
|
||||
static motMov_st m2st;
|
||||
if(rtCiclo<chM2start)m2st=motWaiting;
|
||||
switch(m2st){
|
||||
case motWaiting:
|
||||
SetMotPerc(M2,FW,0);
|
||||
SetMotPerc(M2,BW,0);
|
||||
if(rtCiclo>=chM2start){
|
||||
(void)ramp(M2,FW,mrampstart[M2-1],m2pwmch,tramp,RAMPINIT);
|
||||
m2st=motStartRamp;
|
||||
}
|
||||
break;
|
||||
case motStartRamp:
|
||||
if(ramp(M2,FW,mrampstart[M2-1],m2pwmch,tramp,RAMPRUN)==DONE){
|
||||
m2st=motWaitingTime;
|
||||
}
|
||||
break;
|
||||
case motWaitingTime:
|
||||
if(rtCiclo>=chM2stop){
|
||||
(void)ramp(M2,FW,m2pwmch,0,tramp,RAMPINIT);
|
||||
m2st=motStopRamp;
|
||||
}
|
||||
break;
|
||||
case motStopRamp:
|
||||
if(ramp(M2,FW,m2pwmch,0,tramp,RAMPRUN)==DONE){
|
||||
m2st=motStop;
|
||||
}
|
||||
break;
|
||||
case motStop:
|
||||
default:
|
||||
SetMotPerc(M2,FW,0);
|
||||
SetMotPerc(M2,BW,0);
|
||||
break;
|
||||
}
|
||||
return m2st;
|
||||
}
|
||||
|
||||
motMov_st m3ch(void){
|
||||
static motMov_st m3st;
|
||||
if(rtCiclo<chM3start)m3st=motWaiting;
|
||||
switch(m3st){
|
||||
case motWaiting:
|
||||
SetMotPerc(M3,FW,0);
|
||||
SetMotPerc(M3,BW,0);
|
||||
if(rtCiclo>=chM3start){
|
||||
(void)ramp(M3,FW,mrampstart[M3-1],m2pwmch,tramp,RAMPINIT);
|
||||
m3st=motStartRamp;
|
||||
}
|
||||
break;
|
||||
case motStartRamp:
|
||||
if(ramp(M3,FW,mrampstart[M3-1],m3pwmch,tramp,RAMPRUN)==DONE){
|
||||
m3st=motWaitingTime;
|
||||
}
|
||||
break;
|
||||
case motWaitingTime:
|
||||
if(rtCiclo>=chM3stop){
|
||||
(void)ramp(M3,FW,m3pwmch,0,tramp,RAMPINIT);
|
||||
m3st=motStopRamp;
|
||||
}
|
||||
break;
|
||||
case motStopRamp:
|
||||
if(ramp(M3,FW,m3pwmch,0,tramp,RAMPRUN)==DONE){
|
||||
m3st=motStop;
|
||||
}
|
||||
break;
|
||||
case motStop:
|
||||
default:
|
||||
SetMotPerc(M3,FW,0);
|
||||
SetMotPerc(M3,BW,0);
|
||||
break;
|
||||
}
|
||||
return m3st;
|
||||
}
|
||||
|
||||
motMov_st m4ch(void){
|
||||
static motMov_st m4st;
|
||||
if(rtCiclo<chM4start)m4st=motWaiting;
|
||||
switch(m4st){
|
||||
case motWaiting:
|
||||
SetMotPerc(M4,FW,0);
|
||||
SetMotPerc(M4,BW,0);
|
||||
if(rtCiclo>=chM4start){
|
||||
(void)ramp(M4,FW,mrampstart[M4-1],m2pwmch,tramp,RAMPINIT);
|
||||
m4st=motStartRamp;
|
||||
}
|
||||
break;
|
||||
case motStartRamp:
|
||||
if(ramp(M4,FW,mrampstart[M4-1],m4pwmch,tramp,RAMPRUN)==DONE){
|
||||
m4st=motWaitingTime;
|
||||
}
|
||||
break;
|
||||
case motWaitingTime:
|
||||
if(rtCiclo>=chM4stop){
|
||||
(void)ramp(M4,FW,m4pwmch,0,tramp,RAMPINIT);
|
||||
m4st=motStopRamp;
|
||||
}
|
||||
break;
|
||||
case motStopRamp:
|
||||
if(ramp(43,FW,m4pwmch,0,tramp,RAMPRUN)==DONE){
|
||||
m4st=motStop;
|
||||
}
|
||||
break;
|
||||
case motStop:
|
||||
default:
|
||||
SetMotPerc(M4,FW,0);
|
||||
SetMotPerc(M4,BW,0);
|
||||
break;
|
||||
}
|
||||
return m4st;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,175 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file : main.h
|
||||
* @brief : Header for main.c file.
|
||||
* This file contains the common defines of the application.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2025 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __MAIN_H
|
||||
#define __MAIN_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32f1xx_hal.h"
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN ET */
|
||||
typedef enum{
|
||||
omchiuso,
|
||||
omM1fw1,
|
||||
omM1fw2,
|
||||
omM1bw1,
|
||||
omM1bw2,
|
||||
omM2fw1,
|
||||
omM2fw2,
|
||||
omM2bw1,
|
||||
omM2bw2,
|
||||
omM3fw1,
|
||||
omM3fw2,
|
||||
omM3bw1,
|
||||
omM3bw2,
|
||||
omM4fw1,
|
||||
omM4fw2,
|
||||
omM4bw1,
|
||||
omM4bw2,
|
||||
omStopMan,
|
||||
omapertura0,
|
||||
omstopapertura,
|
||||
omaperto,
|
||||
omchiusura1,
|
||||
omchiusura2,
|
||||
omchiusura3,
|
||||
omchiusura4,
|
||||
omchiusura5,
|
||||
omchiusura6,
|
||||
omchiusura7,
|
||||
omchiusura8,
|
||||
omchiusura9,
|
||||
omchiusura10,
|
||||
omchiusura11,
|
||||
omchiusura12,
|
||||
omchiusura13,
|
||||
omchiusura14,
|
||||
omstopchiusura,
|
||||
}omCiclo_st;
|
||||
/* USER CODE END ET */
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* USER CODE BEGIN EC */
|
||||
|
||||
/* USER CODE END EC */
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN EM */
|
||||
|
||||
/* USER CODE END EM */
|
||||
|
||||
void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim);
|
||||
|
||||
/* Exported functions prototypes ---------------------------------------------*/
|
||||
void Error_Handler(void);
|
||||
|
||||
/* USER CODE BEGIN EFP */
|
||||
|
||||
/* USER CODE END EFP */
|
||||
|
||||
/* Private defines -----------------------------------------------------------*/
|
||||
#define LED2_Pin GPIO_PIN_13
|
||||
#define LED2_GPIO_Port GPIOC
|
||||
#define P1_Pin GPIO_PIN_14
|
||||
#define P1_GPIO_Port GPIOC
|
||||
#define P2_Pin GPIO_PIN_15
|
||||
#define P2_GPIO_Port GPIOC
|
||||
#define IN1_Pin GPIO_PIN_0
|
||||
#define IN1_GPIO_Port GPIOA
|
||||
#define IN2_Pin GPIO_PIN_1
|
||||
#define IN2_GPIO_Port GPIOA
|
||||
#define IN3_Pin GPIO_PIN_2
|
||||
#define IN3_GPIO_Port GPIOA
|
||||
#define IN4_Pin GPIO_PIN_3
|
||||
#define IN4_GPIO_Port GPIOA
|
||||
#define AIN1_Pin GPIO_PIN_4
|
||||
#define AIN1_GPIO_Port GPIOA
|
||||
#define AIN2_Pin GPIO_PIN_5
|
||||
#define AIN2_GPIO_Port GPIOA
|
||||
#define AIN3_Pin GPIO_PIN_6
|
||||
#define AIN3_GPIO_Port GPIOA
|
||||
#define AIN4_Pin GPIO_PIN_7
|
||||
#define AIN4_GPIO_Port GPIOA
|
||||
#define ANEM_Pin GPIO_PIN_0
|
||||
#define ANEM_GPIO_Port GPIOB
|
||||
#define INH1_Pin GPIO_PIN_1
|
||||
#define INH1_GPIO_Port GPIOB
|
||||
#define INH2_Pin GPIO_PIN_2
|
||||
#define INH2_GPIO_Port GPIOB
|
||||
#define INH3_Pin GPIO_PIN_10
|
||||
#define INH3_GPIO_Port GPIOB
|
||||
#define INH4_Pin GPIO_PIN_11
|
||||
#define INH4_GPIO_Port GPIOB
|
||||
#define CH1_Pin GPIO_PIN_12
|
||||
#define CH1_GPIO_Port GPIOB
|
||||
#define CH2_Pin GPIO_PIN_13
|
||||
#define CH2_GPIO_Port GPIOB
|
||||
#define CH3_Pin GPIO_PIN_14
|
||||
#define CH3_GPIO_Port GPIOB
|
||||
#define CH4_Pin GPIO_PIN_15
|
||||
#define CH4_GPIO_Port GPIOB
|
||||
#define BUZ_Pin GPIO_PIN_8
|
||||
#define BUZ_GPIO_Port GPIOA
|
||||
#define SWIO_Pin GPIO_PIN_13
|
||||
#define SWIO_GPIO_Port GPIOA
|
||||
#define SWCLK_Pin GPIO_PIN_14
|
||||
#define SWCLK_GPIO_Port GPIOA
|
||||
#define LED1_Pin GPIO_PIN_15
|
||||
#define LED1_GPIO_Port GPIOA
|
||||
#define EXP1_Pin GPIO_PIN_3
|
||||
#define EXP1_GPIO_Port GPIOB
|
||||
#define EXP2_Pin GPIO_PIN_4
|
||||
#define EXP2_GPIO_Port GPIOB
|
||||
#define EXP3_Pin GPIO_PIN_5
|
||||
#define EXP3_GPIO_Port GPIOB
|
||||
#define IN5_Pin GPIO_PIN_6
|
||||
#define IN5_GPIO_Port GPIOB
|
||||
#define IN6_Pin GPIO_PIN_7
|
||||
#define IN6_GPIO_Port GPIOB
|
||||
#define IN7_Pin GPIO_PIN_8
|
||||
#define IN7_GPIO_Port GPIOB
|
||||
#define IN8_Pin GPIO_PIN_9
|
||||
#define IN8_GPIO_Port GPIOB
|
||||
|
||||
/* USER CODE BEGIN Private defines */
|
||||
#define INP1 1
|
||||
#define INP2 2
|
||||
#define INCH1 4
|
||||
#define INCH2 8
|
||||
#define INCH3 16
|
||||
#define INCH4 32
|
||||
/* USER CODE END Private defines */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __MAIN_H */
|
||||
@@ -0,0 +1,480 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "eeprom.h"
|
||||
extern UART_HandleTypeDef huart1;
|
||||
/*
|
||||
* Record format (4 bytes):
|
||||
* [0] VirtAddress (uint16_t)
|
||||
* [2] Data (uint16_t)
|
||||
*
|
||||
* Page layout:
|
||||
* [0] PageStatus (uint16_t)
|
||||
* [2..] Records...
|
||||
*/
|
||||
|
||||
extern uint16_t m1pwmap;
|
||||
extern uint16_t m1pwmch;
|
||||
extern uint16_t m2pwmap;
|
||||
extern uint16_t m2pwmch;
|
||||
extern uint16_t m3pwmap;
|
||||
extern uint16_t m3pwmch;
|
||||
extern uint16_t m4pwmap;
|
||||
extern uint16_t m4pwmch;
|
||||
extern uint16_t t1ap;
|
||||
extern uint16_t t2ap;
|
||||
extern uint16_t t3ap;
|
||||
extern uint16_t t4ap;
|
||||
extern uint16_t twap;
|
||||
extern uint16_t tramp;
|
||||
extern uint16_t t1ch;
|
||||
extern uint16_t t2ch;
|
||||
extern uint16_t t3ch;
|
||||
extern uint16_t t4ch;
|
||||
extern uint16_t twch;
|
||||
extern uint16_t tramp1;
|
||||
extern uint16_t trampman;
|
||||
extern uint16_t m1pwmMan;
|
||||
extern uint16_t m2pwmMan;
|
||||
extern uint16_t m3pwmMan;
|
||||
extern uint16_t m4pwmMan;
|
||||
|
||||
|
||||
extern uint16_t apM1start;
|
||||
extern uint16_t apM1stop;
|
||||
extern uint16_t apM2start;
|
||||
extern uint16_t apM2stop;
|
||||
extern uint16_t apM3start;
|
||||
extern uint16_t apM3stop;
|
||||
extern uint16_t apM4start;
|
||||
extern uint16_t apM4stop;
|
||||
extern uint16_t chM1start;
|
||||
extern uint16_t chM1stop;
|
||||
extern uint16_t chM2start;
|
||||
extern uint16_t chM2stop;
|
||||
extern uint16_t chM3start;
|
||||
extern uint16_t chM3stop;
|
||||
extern uint16_t chM4start;
|
||||
extern uint16_t chM4stop;
|
||||
|
||||
const uint8_t deftab[EE_NUM_VIRTUAL_ADDR]={
|
||||
40, //m1pwmap
|
||||
60, //m1pwmch
|
||||
70, //m2pwmap
|
||||
70, //m2pwmch
|
||||
35, //m3pwmap
|
||||
40, //m3pwmch
|
||||
40, //m4pwmap
|
||||
40, //m4pwmch
|
||||
20, //m1rampstart
|
||||
20, //m2rampstart
|
||||
20, //m3rampstart
|
||||
20, //m4rampstart
|
||||
28, //t1ap
|
||||
4, //t2ap
|
||||
10, //t3ap
|
||||
40, //t4ap
|
||||
1, //twap
|
||||
27, //t1ch
|
||||
10, //t2ch
|
||||
30, //t3ch
|
||||
1, //t4ch
|
||||
1, //twch
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
100, //tramp1
|
||||
60, //m1pwmMan
|
||||
70, //m2pwmMan
|
||||
40, //m3pwmMan
|
||||
40, //m4pwmMan
|
||||
50, //trampman
|
||||
10, //tramp
|
||||
0, //apM1start;
|
||||
0, //apM1stop;
|
||||
0, //apM2start;
|
||||
0, //apM2stop;
|
||||
0, //apM3start;
|
||||
0, //apM3stop;
|
||||
0, //apM4start;
|
||||
0, //apM4stop;
|
||||
0, //chM1start;
|
||||
0, //chM1stop;
|
||||
0, //chM2start;
|
||||
0, //chM2stop;
|
||||
0, //chM3start;
|
||||
0, //chM3stop;
|
||||
0, //chM4start;
|
||||
0, //chM4stop;
|
||||
1,
|
||||
27,
|
||||
10,
|
||||
30,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
100,
|
||||
60,
|
||||
70,
|
||||
40,
|
||||
40,
|
||||
50,
|
||||
10,
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t VirtAddress;
|
||||
uint16_t Data;
|
||||
} EE_Record_t;
|
||||
|
||||
/* Active page base address (runtime selected in EE_Init) */
|
||||
static uint32_t EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
|
||||
/* 32 sequential virtual addresses */
|
||||
const uint16_t EE_VirtAddrs[EE_NUM_VIRTUAL_ADDR] =
|
||||
{
|
||||
0x0001, 0x0002, 0x0003, 0x0004,
|
||||
0x0005, 0x0006, 0x0007, 0x0008,
|
||||
0x0009, 0x000A, 0x000B, 0x000C,
|
||||
0x000D, 0x000E, 0x000F, 0x0010,
|
||||
0x0011, 0x0012, 0x0013, 0x0014,
|
||||
0x0015, 0x0016, 0x0017, 0x0018,
|
||||
0x0019, 0x001A, 0x001B, 0x001C,
|
||||
0x001D, 0x001E, 0x001F, 0x0020,
|
||||
|
||||
0x0021, 0x0022, 0x0023, 0x0024,
|
||||
0x0025, 0x0026, 0x0027, 0x0028,
|
||||
0x0029, 0x002A, 0x002B, 0x002C,
|
||||
0x002D, 0x002E, 0x002F, 0x0030,
|
||||
0x0031, 0x0032, 0x0033, 0x0034,
|
||||
0x0035, 0x0036, 0x0037, 0x0038,
|
||||
0x0039, 0x003A, 0x003B, 0x003C,
|
||||
0x003D, 0x003E, 0x003F, 0x0040
|
||||
};
|
||||
/* ========================================================================= */
|
||||
|
||||
/* --- Internal helpers ---------------------------------------------------- */
|
||||
|
||||
static uint16_t EE_GetPageStatus(uint32_t pageBase)
|
||||
{
|
||||
return *(__IO uint16_t *)pageBase;
|
||||
}
|
||||
|
||||
static HAL_StatusTypeDef EE_FlashProgramHalfWord(uint32_t Address, uint16_t Data)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
|
||||
HAL_FLASH_Unlock();
|
||||
status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, Address, Data);
|
||||
HAL_FLASH_Lock();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static HAL_StatusTypeDef EE_FlashErasePage(uint32_t PageAddress)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
FLASH_EraseInitTypeDef EraseInit;
|
||||
uint32_t PageError = 0;
|
||||
|
||||
HAL_FLASH_Unlock();
|
||||
|
||||
EraseInit.TypeErase = FLASH_TYPEERASE_PAGES;
|
||||
EraseInit.PageAddress = PageAddress;
|
||||
EraseInit.NbPages = 1;
|
||||
|
||||
status = HAL_FLASHEx_Erase(&EraseInit, &PageError);
|
||||
|
||||
HAL_FLASH_Lock();
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Find first free record address in given page (returns 0 if full) */
|
||||
static uint32_t EE_FindFreeAddress(uint32_t pageBase)
|
||||
{
|
||||
uint32_t addr = pageBase + 2U; /* Skip status word */
|
||||
uint32_t pageEnd = pageBase + EE_PAGE_SIZE;
|
||||
|
||||
while (addr < (pageEnd - sizeof(EE_Record_t) + 1U))
|
||||
{
|
||||
uint16_t vaddr = *(__IO uint16_t *)addr;
|
||||
|
||||
if (vaddr == 0xFFFFU)
|
||||
{
|
||||
/* Empty slot */
|
||||
return addr;
|
||||
}
|
||||
addr += sizeof(EE_Record_t);
|
||||
}
|
||||
|
||||
return 0U; /* No space */
|
||||
}
|
||||
|
||||
/* Find latest value of VirtAddress in a specific page (internal, uses EE_Status) */
|
||||
/* Find latest value of VirtAddress in a specific page (scan forward) */
|
||||
static EE_Status EE_FindInPage(uint32_t pageBase, uint16_t VirtAddress, uint16_t *Data)
|
||||
{
|
||||
uint32_t addr = pageBase + 2U; // skip status halfword
|
||||
uint32_t pageEnd = pageBase + EE_PAGE_SIZE;
|
||||
EE_Status result = EE_NOT_FOUND;
|
||||
uint16_t lastVal = 0;
|
||||
|
||||
if (Data == NULL)
|
||||
return EE_ERROR;
|
||||
|
||||
while (addr <= (pageEnd - sizeof(EE_Record_t)))
|
||||
{
|
||||
uint16_t vaddr = *(__IO uint16_t *)addr;
|
||||
|
||||
if (vaddr == 0xFFFFU)
|
||||
{
|
||||
// First empty slot => no more records in this page
|
||||
break;
|
||||
}
|
||||
|
||||
uint16_t value = *(__IO uint16_t *)(addr + 2U);
|
||||
|
||||
if (vaddr == VirtAddress)
|
||||
{
|
||||
lastVal = value; // keep most recent
|
||||
result = EE_OK;
|
||||
}
|
||||
|
||||
addr += sizeof(EE_Record_t); // move 4 bytes forward
|
||||
}
|
||||
|
||||
if (result == EE_OK)
|
||||
*Data = lastVal;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Format both pages: erase and set PAGE0 as VALID */
|
||||
static EE_Status EE_Format(void)
|
||||
{
|
||||
if (EE_FlashErasePage(EE_PAGE0_BASE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
if (EE_FlashErasePage(EE_PAGE1_BASE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
if (EE_FlashProgramHalfWord(EE_PAGE0_BASE, EE_PAGE_STATUS_VALID) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* PAGE1 will remain erased (status = 0xFFFF) */
|
||||
EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
|
||||
return EE_STATUS_OK;
|
||||
}
|
||||
|
||||
/* Get the base of the other page */
|
||||
static uint32_t EE_GetOtherPageBase(uint32_t pageBase)
|
||||
{
|
||||
return (pageBase == EE_PAGE0_BASE) ? EE_PAGE1_BASE : EE_PAGE0_BASE;
|
||||
}
|
||||
|
||||
/* Page transfer (garbage collection + new write) */
|
||||
static EE_Status EE_PageTransfer(uint16_t VirtAddress, uint16_t Data)
|
||||
{
|
||||
uint32_t oldBase = EE_ActivePageBase;
|
||||
uint32_t newBase = EE_GetOtherPageBase(oldBase);
|
||||
uint32_t addr;
|
||||
uint16_t value;
|
||||
EE_Status st;
|
||||
|
||||
/* Erase new page */
|
||||
if (EE_FlashErasePage(newBase) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Mark new page as RECEIVE */
|
||||
if (EE_FlashProgramHalfWord(newBase, EE_PAGE_STATUS_RECEIVE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Start writing records just after status */
|
||||
addr = newBase + 2U;
|
||||
|
||||
/* For each known virtual variable */
|
||||
for (uint16_t i = 0; i < EE_NUM_VIRTUAL_ADDR; i++)
|
||||
{
|
||||
uint16_t vaddr = EE_VirtAddrs[i];
|
||||
|
||||
if (vaddr == VirtAddress)
|
||||
{
|
||||
/* Use the new data passed into PageTransfer */
|
||||
value = Data;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Read latest value from old active page */
|
||||
st = EE_FindInPage(oldBase, vaddr, &value);
|
||||
if (st != EE_STATUS_OK)
|
||||
{
|
||||
/* Variable never written -> skip */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Write record to new page */
|
||||
if (EE_FlashProgramHalfWord(addr, vaddr) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
if (EE_FlashProgramHalfWord(addr + 2U, value) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
addr += sizeof(EE_Record_t);
|
||||
if (addr >= (newBase + EE_PAGE_SIZE))
|
||||
return EE_STATUS_NO_SPACE;
|
||||
}
|
||||
|
||||
/* Erase old page */
|
||||
if (EE_FlashErasePage(oldBase) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Mark new page as VALID */
|
||||
if (EE_FlashProgramHalfWord(newBase, EE_PAGE_STATUS_VALID) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Update active page */
|
||||
EE_ActivePageBase = newBase;
|
||||
|
||||
return EE_STATUS_OK;
|
||||
}
|
||||
|
||||
/* --- Public API ----------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* Initialize the EEPROM emulation.
|
||||
* - Checks page statuses and chooses the active page.
|
||||
* - If inconsistent or blank, formats pages.
|
||||
* PUBLIC RETURN TYPE: uint16_t (EE_OK / EE_ERROR / ...)
|
||||
*/
|
||||
uint16_t EE_Init(void)
|
||||
{
|
||||
uint16_t status0 = EE_GetPageStatus(EE_PAGE0_BASE);
|
||||
uint16_t status1 = EE_GetPageStatus(EE_PAGE1_BASE);
|
||||
|
||||
if ((status0 == EE_PAGE_STATUS_ERASED) && (status1 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
/* Fresh device -> format */
|
||||
return (uint16_t)EE_Format();
|
||||
}
|
||||
else if ((status0 == EE_PAGE_STATUS_VALID) && (status1 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
return EE_OK;
|
||||
}
|
||||
else if ((status1 == EE_PAGE_STATUS_VALID) && (status0 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
EE_ActivePageBase = EE_PAGE1_BASE;
|
||||
return EE_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Any weird or inconsistent state -> reformat */
|
||||
return (uint16_t)EE_Format();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a 16-bit variable by its virtual address.
|
||||
* PUBLIC RETURN: EE_OK / EE_NOT_FOUND / EE_ERROR (as uint16_t)
|
||||
*/
|
||||
uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t *Data)
|
||||
{
|
||||
EE_Status st;
|
||||
|
||||
if (Data == NULL)
|
||||
return EE_ERROR;
|
||||
|
||||
st = EE_FindInPage(EE_ActivePageBase, VirtAddress, Data);
|
||||
return (uint16_t)st;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write (append) a 16-bit variable.
|
||||
* - Writes a new record in the active page.
|
||||
* - If the page is full, triggers a page transfer (GC).
|
||||
* PUBLIC RETURN: EE_OK / EE_ERROR / EE_NO_SPACE (as uint16_t)
|
||||
*/
|
||||
uint16_t EE_WriteVariable(uint16_t VirtAddress, uint16_t Data)
|
||||
{
|
||||
uint32_t freeAddr;
|
||||
EE_Status st;
|
||||
|
||||
/* Find free space in active page */
|
||||
freeAddr = EE_FindFreeAddress(EE_ActivePageBase);
|
||||
if (freeAddr != 0U)
|
||||
{
|
||||
/* Write new record */
|
||||
if (EE_FlashProgramHalfWord(freeAddr, VirtAddress) != HAL_OK)
|
||||
return EE_ERROR;
|
||||
if (EE_FlashProgramHalfWord(freeAddr + 2U, Data) != HAL_OK)
|
||||
return EE_ERROR;
|
||||
|
||||
return EE_OK;
|
||||
}
|
||||
|
||||
/* No space -> page transfer */
|
||||
st = EE_PageTransfer(VirtAddress, Data);
|
||||
return (uint16_t)st;
|
||||
}
|
||||
|
||||
void loadEE(void){
|
||||
char s [200];
|
||||
EEW_Read(M1PWMAP, &m1pwmap);
|
||||
EEW_Read(M1PWMCH, &m1pwmch);
|
||||
EEW_Read(M2PWMAP, &m2pwmap);
|
||||
EEW_Read(M2PWMCH, &m2pwmch);
|
||||
EEW_Read(M3PWMAP, &m3pwmap);
|
||||
EEW_Read(M3PWMCH, &m3pwmch);
|
||||
EEW_Read(M4PWMAP, &m4pwmap);
|
||||
EEW_Read(M4PWMCH, &m4pwmch);
|
||||
EEW_Read(T1AP, &t1ap);
|
||||
EEW_Read(T2AP, &t2ap);
|
||||
EEW_Read(T3AP, &t3ap);
|
||||
EEW_Read(T4AP, &t4ap);
|
||||
EEW_Read(TWAP, &twap);
|
||||
EEW_Read(T1CH, &t1ch);
|
||||
EEW_Read(T2CH, &t2ch);
|
||||
EEW_Read(T3CH, &t3ch);
|
||||
EEW_Read(T4CH, &t4ch);
|
||||
EEW_Read(TWCH, &twch);
|
||||
EEW_Read(TRAMP1, &tramp1);
|
||||
EEW_Read(M1PWMMAN, &m1pwmMan);
|
||||
EEW_Read(M2PWMMAN, &m2pwmMan);
|
||||
EEW_Read(M3PWMMAN, &m3pwmMan);
|
||||
EEW_Read(M4PWMMAN, &m4pwmMan);
|
||||
EEW_Read(TRAMPMAN, &trampman);
|
||||
EEW_Read(TRAMP, &tramp);
|
||||
|
||||
EEW_Read(APM1START,&apM1start);
|
||||
EEW_Read(APM1STOP ,&apM1stop);
|
||||
EEW_Read(APM2START,&apM2start);
|
||||
EEW_Read(APM2STOP ,&apM2stop);
|
||||
EEW_Read(APM3START,&apM3start);
|
||||
EEW_Read(APM3STOP ,&apM3stop);
|
||||
EEW_Read(APM4START,&apM4start);
|
||||
EEW_Read(APM4STOP ,&apM4stop);
|
||||
EEW_Read(CHM1START,&chM1start);
|
||||
EEW_Read(CHM1STOP ,&chM1stop);
|
||||
EEW_Read(CHM2START,&chM2start);
|
||||
EEW_Read(CHM2STOP ,&chM2stop);
|
||||
EEW_Read(CHM3START,&chM3start);
|
||||
EEW_Read(CHM3STOP ,&chM3stop);
|
||||
EEW_Read(CHM4START,&chM4start);
|
||||
EEW_Read(CHM4STOP ,&chM4stop);
|
||||
|
||||
sprintf((char*)s,"LoadEE\n");
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
sprintf((char*)s,"\nm1pwmap=%d m1pwmch=%d m2pwmap=%d m2pwmch=%d m3pwmap=%d m3pwmch=%d m4pwmap=%d m4pwmch=%d",m1pwmap,m1pwmch,m2pwmap,m2pwmch,m3pwmap,m3pwmch,m4pwmap, m4pwmch);
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
sprintf((char*)s,"\ntramp=%d trampman=%d",tramp,trampman);
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
sprintf((char*)s,"\nm1pwmMan=%d m2pwmMan=%d m3pwmMan=%d m4pwmMan=%d",m1pwmMan,m2pwmMan,m3pwmMan,m4pwmMan);
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,470 @@
|
||||
#include "eeprom.h"
|
||||
|
||||
/*
|
||||
* Record format (4 bytes):
|
||||
* [0] VirtAddress (uint16_t)
|
||||
* [2] Data (uint16_t)
|
||||
*
|
||||
* Page layout:
|
||||
* [0] PageStatus (uint16_t)
|
||||
* [2..] Records...
|
||||
*/
|
||||
|
||||
extern uint16_t m1pwmap;
|
||||
extern uint16_t m1pwmch;
|
||||
extern uint16_t m2pwmap;
|
||||
extern uint16_t m2pwmch;
|
||||
extern uint16_t m3pwmap;
|
||||
extern uint16_t m3pwmch;
|
||||
extern uint16_t m4pwmap;
|
||||
extern uint16_t m4pwmch;
|
||||
extern uint16_t t1ap;
|
||||
extern uint16_t t2ap;
|
||||
extern uint16_t t3ap;
|
||||
extern uint16_t t4ap;
|
||||
extern uint16_t twap;
|
||||
extern uint16_t tramp;
|
||||
extern uint16_t t1ch;
|
||||
extern uint16_t t2ch;
|
||||
extern uint16_t t3ch;
|
||||
extern uint16_t t4ch;
|
||||
extern uint16_t twch;
|
||||
extern uint16_t tramp1;
|
||||
extern uint16_t trampman;
|
||||
extern uint16_t m1pwmMan;
|
||||
extern uint16_t m2pwmMan;
|
||||
extern uint16_t m3pwmMan;
|
||||
extern uint16_t m4pwmMan;
|
||||
|
||||
|
||||
extern uint16_t apM1start;
|
||||
extern uint16_t apM1stop;
|
||||
extern uint16_t apM2start;
|
||||
extern uint16_t apM2stop;
|
||||
extern uint16_t apM3start;
|
||||
extern uint16_t apM3stop;
|
||||
extern uint16_t apM4start;
|
||||
extern uint16_t apM4stop;
|
||||
extern uint16_t chM1start;
|
||||
extern uint16_t chM1stop;
|
||||
extern uint16_t chM2start;
|
||||
extern uint16_t chM2stop;
|
||||
extern uint16_t chM3start;
|
||||
extern uint16_t chM3stop;
|
||||
extern uint16_t chM4start;
|
||||
extern uint16_t chM4stop;
|
||||
|
||||
const uint8_t deftab[EE_NUM_VIRTUAL_ADDR]={
|
||||
40, //m1pwmap
|
||||
60, //m1pwmch
|
||||
70, //m2pwmap
|
||||
70, //m2pwmch
|
||||
35, //m3pwmap
|
||||
40, //m3pwmch
|
||||
40, //m4pwmap
|
||||
40, //m4pwmch
|
||||
20, //m1rampstart
|
||||
20, //m2rampstart
|
||||
20, //m3rampstart
|
||||
20, //m4rampstart
|
||||
28, //t1ap
|
||||
4, //t2ap
|
||||
10, //t3ap
|
||||
40, //t4ap
|
||||
1, //twap
|
||||
27, //t1ch
|
||||
10, //t2ch
|
||||
30, //t3ch
|
||||
1, //t4ch
|
||||
1, //twch
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
100, //tramp1
|
||||
60, //m1pwmMan
|
||||
70, //m2pwmMan
|
||||
40, //m3pwmMan
|
||||
40, //m4pwmMan
|
||||
50, //trampman
|
||||
10, //tramp
|
||||
0, //apM1start;
|
||||
0, //apM1stop;
|
||||
0, //apM2start;
|
||||
0, //apM2stop;
|
||||
0, //apM3start;
|
||||
0, //apM3stop;
|
||||
0, //apM4start;
|
||||
0, //apM4stop;
|
||||
0, //chM1start;
|
||||
0, //chM1stop;
|
||||
0, //chM2start;
|
||||
0, //chM2stop;
|
||||
0, //chM3start;
|
||||
0, //chM3stop;
|
||||
0, //chM4start;
|
||||
0, //chM4stop;
|
||||
1,
|
||||
27,
|
||||
10,
|
||||
30,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
100,
|
||||
60,
|
||||
70,
|
||||
40,
|
||||
40,
|
||||
50,
|
||||
10,
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t VirtAddress;
|
||||
uint16_t Data;
|
||||
} EE_Record_t;
|
||||
|
||||
/* Active page base address (runtime selected in EE_Init) */
|
||||
static uint32_t EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
|
||||
/* 32 sequential virtual addresses */
|
||||
const uint16_t EE_VirtAddrs[EE_NUM_VIRTUAL_ADDR] =
|
||||
{
|
||||
0x0001, 0x0002, 0x0003, 0x0004,
|
||||
0x0005, 0x0006, 0x0007, 0x0008,
|
||||
0x0009, 0x000A, 0x000B, 0x000C,
|
||||
0x000D, 0x000E, 0x000F, 0x0010,
|
||||
0x0011, 0x0012, 0x0013, 0x0014,
|
||||
0x0015, 0x0016, 0x0017, 0x0018,
|
||||
0x0019, 0x001A, 0x001B, 0x001C,
|
||||
0x001D, 0x001E, 0x001F, 0x0020,
|
||||
|
||||
0x0021, 0x0022, 0x0023, 0x0024,
|
||||
0x0025, 0x0026, 0x0027, 0x0028,
|
||||
0x0029, 0x002A, 0x002B, 0x002C,
|
||||
0x002D, 0x002E, 0x002F, 0x0030,
|
||||
0x0031, 0x0032, 0x0033, 0x0034,
|
||||
0x0035, 0x0036, 0x0037, 0x0038,
|
||||
0x0039, 0x003A, 0x003B, 0x003C,
|
||||
0x003D, 0x003E, 0x003F, 0x0040
|
||||
};
|
||||
/* ========================================================================= */
|
||||
|
||||
/* --- Internal helpers ---------------------------------------------------- */
|
||||
|
||||
static uint16_t EE_GetPageStatus(uint32_t pageBase)
|
||||
{
|
||||
return *(__IO uint16_t *)pageBase;
|
||||
}
|
||||
|
||||
static HAL_StatusTypeDef EE_FlashProgramHalfWord(uint32_t Address, uint16_t Data)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
|
||||
HAL_FLASH_Unlock();
|
||||
status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, Address, Data);
|
||||
HAL_FLASH_Lock();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static HAL_StatusTypeDef EE_FlashErasePage(uint32_t PageAddress)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
FLASH_EraseInitTypeDef EraseInit;
|
||||
uint32_t PageError = 0;
|
||||
|
||||
HAL_FLASH_Unlock();
|
||||
|
||||
EraseInit.TypeErase = FLASH_TYPEERASE_PAGES;
|
||||
EraseInit.PageAddress = PageAddress;
|
||||
EraseInit.NbPages = 1;
|
||||
|
||||
status = HAL_FLASHEx_Erase(&EraseInit, &PageError);
|
||||
|
||||
HAL_FLASH_Lock();
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Find first free record address in given page (returns 0 if full) */
|
||||
static uint32_t EE_FindFreeAddress(uint32_t pageBase)
|
||||
{
|
||||
uint32_t addr = pageBase + 2U; /* Skip status word */
|
||||
uint32_t pageEnd = pageBase + EE_PAGE_SIZE;
|
||||
|
||||
while (addr < (pageEnd - sizeof(EE_Record_t) + 1U))
|
||||
{
|
||||
uint16_t vaddr = *(__IO uint16_t *)addr;
|
||||
|
||||
if (vaddr == 0xFFFFU)
|
||||
{
|
||||
/* Empty slot */
|
||||
return addr;
|
||||
}
|
||||
addr += sizeof(EE_Record_t);
|
||||
}
|
||||
|
||||
return 0U; /* No space */
|
||||
}
|
||||
|
||||
/* Find latest value of VirtAddress in a specific page (internal, uses EE_Status) */
|
||||
/* Find latest value of VirtAddress in a specific page (scan forward) */
|
||||
static EE_Status EE_FindInPage(uint32_t pageBase, uint16_t VirtAddress, uint16_t *Data)
|
||||
{
|
||||
uint32_t addr = pageBase + 2U; // skip status halfword
|
||||
uint32_t pageEnd = pageBase + EE_PAGE_SIZE;
|
||||
EE_Status result = EE_NOT_FOUND;
|
||||
uint16_t lastVal = 0;
|
||||
|
||||
if (Data == NULL)
|
||||
return EE_ERROR;
|
||||
|
||||
while (addr <= (pageEnd - sizeof(EE_Record_t)))
|
||||
{
|
||||
uint16_t vaddr = *(__IO uint16_t *)addr;
|
||||
|
||||
if (vaddr == 0xFFFFU)
|
||||
{
|
||||
// First empty slot => no more records in this page
|
||||
break;
|
||||
}
|
||||
|
||||
uint16_t value = *(__IO uint16_t *)(addr + 2U);
|
||||
|
||||
if (vaddr == VirtAddress)
|
||||
{
|
||||
lastVal = value; // keep most recent
|
||||
result = EE_OK;
|
||||
}
|
||||
|
||||
addr += sizeof(EE_Record_t); // move 4 bytes forward
|
||||
}
|
||||
|
||||
if (result == EE_OK)
|
||||
*Data = lastVal;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Format both pages: erase and set PAGE0 as VALID */
|
||||
static EE_Status EE_Format(void)
|
||||
{
|
||||
if (EE_FlashErasePage(EE_PAGE0_BASE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
if (EE_FlashErasePage(EE_PAGE1_BASE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
if (EE_FlashProgramHalfWord(EE_PAGE0_BASE, EE_PAGE_STATUS_VALID) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* PAGE1 will remain erased (status = 0xFFFF) */
|
||||
EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
|
||||
return EE_STATUS_OK;
|
||||
}
|
||||
|
||||
/* Get the base of the other page */
|
||||
static uint32_t EE_GetOtherPageBase(uint32_t pageBase)
|
||||
{
|
||||
return (pageBase == EE_PAGE0_BASE) ? EE_PAGE1_BASE : EE_PAGE0_BASE;
|
||||
}
|
||||
|
||||
/* Page transfer (garbage collection + new write) */
|
||||
static EE_Status EE_PageTransfer(uint16_t VirtAddress, uint16_t Data)
|
||||
{
|
||||
uint32_t oldBase = EE_ActivePageBase;
|
||||
uint32_t newBase = EE_GetOtherPageBase(oldBase);
|
||||
uint32_t addr;
|
||||
uint16_t value;
|
||||
EE_Status st;
|
||||
|
||||
/* Erase new page */
|
||||
if (EE_FlashErasePage(newBase) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Mark new page as RECEIVE */
|
||||
if (EE_FlashProgramHalfWord(newBase, EE_PAGE_STATUS_RECEIVE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Start writing records just after status */
|
||||
addr = newBase + 2U;
|
||||
|
||||
/* For each known virtual variable */
|
||||
for (uint16_t i = 0; i < EE_NUM_VIRTUAL_ADDR; i++)
|
||||
{
|
||||
uint16_t vaddr = EE_VirtAddrs[i];
|
||||
|
||||
if (vaddr == VirtAddress)
|
||||
{
|
||||
/* Use the new data passed into PageTransfer */
|
||||
value = Data;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Read latest value from old active page */
|
||||
st = EE_FindInPage(oldBase, vaddr, &value);
|
||||
if (st != EE_STATUS_OK)
|
||||
{
|
||||
/* Variable never written -> skip */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Write record to new page */
|
||||
if (EE_FlashProgramHalfWord(addr, vaddr) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
if (EE_FlashProgramHalfWord(addr + 2U, value) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
addr += sizeof(EE_Record_t);
|
||||
if (addr >= (newBase + EE_PAGE_SIZE))
|
||||
return EE_STATUS_NO_SPACE;
|
||||
}
|
||||
|
||||
/* Erase old page */
|
||||
if (EE_FlashErasePage(oldBase) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Mark new page as VALID */
|
||||
if (EE_FlashProgramHalfWord(newBase, EE_PAGE_STATUS_VALID) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Update active page */
|
||||
EE_ActivePageBase = newBase;
|
||||
|
||||
return EE_STATUS_OK;
|
||||
}
|
||||
|
||||
/* --- Public API ----------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* Initialize the EEPROM emulation.
|
||||
* - Checks page statuses and chooses the active page.
|
||||
* - If inconsistent or blank, formats pages.
|
||||
* PUBLIC RETURN TYPE: uint16_t (EE_OK / EE_ERROR / ...)
|
||||
*/
|
||||
uint16_t EE_Init(void)
|
||||
{
|
||||
uint16_t status0 = EE_GetPageStatus(EE_PAGE0_BASE);
|
||||
uint16_t status1 = EE_GetPageStatus(EE_PAGE1_BASE);
|
||||
|
||||
if ((status0 == EE_PAGE_STATUS_ERASED) && (status1 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
/* Fresh device -> format */
|
||||
return (uint16_t)EE_Format();
|
||||
}
|
||||
else if ((status0 == EE_PAGE_STATUS_VALID) && (status1 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
return EE_OK;
|
||||
}
|
||||
else if ((status1 == EE_PAGE_STATUS_VALID) && (status0 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
EE_ActivePageBase = EE_PAGE1_BASE;
|
||||
return EE_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Any weird or inconsistent state -> reformat */
|
||||
return (uint16_t)EE_Format();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a 16-bit variable by its virtual address.
|
||||
* PUBLIC RETURN: EE_OK / EE_NOT_FOUND / EE_ERROR (as uint16_t)
|
||||
*/
|
||||
uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t *Data)
|
||||
{
|
||||
EE_Status st;
|
||||
|
||||
if (Data == NULL)
|
||||
return EE_ERROR;
|
||||
|
||||
st = EE_FindInPage(EE_ActivePageBase, VirtAddress, Data);
|
||||
return (uint16_t)st;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write (append) a 16-bit variable.
|
||||
* - Writes a new record in the active page.
|
||||
* - If the page is full, triggers a page transfer (GC).
|
||||
* PUBLIC RETURN: EE_OK / EE_ERROR / EE_NO_SPACE (as uint16_t)
|
||||
*/
|
||||
uint16_t EE_WriteVariable(uint16_t VirtAddress, uint16_t Data)
|
||||
{
|
||||
uint32_t freeAddr;
|
||||
EE_Status st;
|
||||
|
||||
/* Find free space in active page */
|
||||
freeAddr = EE_FindFreeAddress(EE_ActivePageBase);
|
||||
if (freeAddr != 0U)
|
||||
{
|
||||
/* Write new record */
|
||||
if (EE_FlashProgramHalfWord(freeAddr, VirtAddress) != HAL_OK)
|
||||
return EE_ERROR;
|
||||
if (EE_FlashProgramHalfWord(freeAddr + 2U, Data) != HAL_OK)
|
||||
return EE_ERROR;
|
||||
|
||||
return EE_OK;
|
||||
}
|
||||
|
||||
/* No space -> page transfer */
|
||||
st = EE_PageTransfer(VirtAddress, Data);
|
||||
return (uint16_t)st;
|
||||
}
|
||||
|
||||
void loadEE(void){
|
||||
char s [100];
|
||||
EEW_Read(M1PWMAP, &m1pwmap);
|
||||
EEW_Read(M1PWMCH, &m1pwmch);
|
||||
EEW_Read(M2PWMAP, &m2pwmap);
|
||||
EEW_Read(M2PWMCH, &m2pwmch);
|
||||
EEW_Read(M3PWMAP, &m3pwmap);
|
||||
EEW_Read(M3PWMCH, &m3pwmch);
|
||||
EEW_Read(M4PWMAP, &m4pwmap);
|
||||
EEW_Read(M4PWMCH, &m4pwmch);
|
||||
EEW_Read(T1AP, &t1ap);
|
||||
EEW_Read(T2AP, &t2ap);
|
||||
EEW_Read(T3AP, &t3ap);
|
||||
EEW_Read(T4AP, &t4ap);
|
||||
EEW_Read(TWAP, &twap);
|
||||
EEW_Read(T1CH, &t1ch);
|
||||
EEW_Read(T2CH, &t2ch);
|
||||
EEW_Read(T3CH, &t3ch);
|
||||
EEW_Read(T4CH, &t4ch);
|
||||
EEW_Read(TWCH, &twch);
|
||||
EEW_Read(TRAMP1, &tramp1);
|
||||
EEW_Read(M1PWMMAN, &m1pwmMan);
|
||||
EEW_Read(M2PWMMAN, &m2pwmMan);
|
||||
EEW_Read(M3PWMMAN, &m3pwmMan);
|
||||
EEW_Read(M4PWMMAN, &m4pwmMan);
|
||||
EEW_Read(TRAMPMAN, &trampman);
|
||||
EEW_Read(TRAMP, &tramp);
|
||||
|
||||
EEW_Read(APM1START,apM1start);
|
||||
EEW_Read(APM1STOP ,apM1stop);
|
||||
EEW_Read(APM2START,apM2start);
|
||||
EEW_Read(APM2STOP ,apM2stop);
|
||||
EEW_Read(APM3START,apM3start);
|
||||
EEW_Read(APM3STOP ,apM3stop);
|
||||
EEW_Read(APM4START,apM4start);
|
||||
EEW_Read(APM4STOP ,apM4stop);
|
||||
EEW_Read(CHM1START,chM1start);
|
||||
EEW_Read(CHM1STOP ,chM1stop);
|
||||
EEW_Read(CHM2START,chM2start);
|
||||
EEW_Read(CHM2STOP ,chM2stop);
|
||||
EEW_Read(CHM3START,chM3start);
|
||||
EEW_Read(CHM3STOP ,chM3stop);
|
||||
EEW_Read(CHM4START,chM4start);
|
||||
EEW_Read(CHM4STOP ,chM4stop);
|
||||
|
||||
sprintf((char*)s,"LoadEE\n");
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,475 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "eeprom.h"
|
||||
extern UART_HandleTypeDef huart1;
|
||||
/*
|
||||
* Record format (4 bytes):
|
||||
* [0] VirtAddress (uint16_t)
|
||||
* [2] Data (uint16_t)
|
||||
*
|
||||
* Page layout:
|
||||
* [0] PageStatus (uint16_t)
|
||||
* [2..] Records...
|
||||
*/
|
||||
|
||||
extern uint16_t m1pwmap;
|
||||
extern uint16_t m1pwmch;
|
||||
extern uint16_t m2pwmap;
|
||||
extern uint16_t m2pwmch;
|
||||
extern uint16_t m3pwmap;
|
||||
extern uint16_t m3pwmch;
|
||||
extern uint16_t m4pwmap;
|
||||
extern uint16_t m4pwmch;
|
||||
extern uint16_t t1ap;
|
||||
extern uint16_t t2ap;
|
||||
extern uint16_t t3ap;
|
||||
extern uint16_t t4ap;
|
||||
extern uint16_t twap;
|
||||
extern uint16_t tramp;
|
||||
extern uint16_t t1ch;
|
||||
extern uint16_t t2ch;
|
||||
extern uint16_t t3ch;
|
||||
extern uint16_t t4ch;
|
||||
extern uint16_t twch;
|
||||
extern uint16_t tramp1;
|
||||
extern uint16_t trampman;
|
||||
extern uint16_t m1pwmMan;
|
||||
extern uint16_t m2pwmMan;
|
||||
extern uint16_t m3pwmMan;
|
||||
extern uint16_t m4pwmMan;
|
||||
|
||||
|
||||
extern uint16_t apM1start;
|
||||
extern uint16_t apM1stop;
|
||||
extern uint16_t apM2start;
|
||||
extern uint16_t apM2stop;
|
||||
extern uint16_t apM3start;
|
||||
extern uint16_t apM3stop;
|
||||
extern uint16_t apM4start;
|
||||
extern uint16_t apM4stop;
|
||||
extern uint16_t chM1start;
|
||||
extern uint16_t chM1stop;
|
||||
extern uint16_t chM2start;
|
||||
extern uint16_t chM2stop;
|
||||
extern uint16_t chM3start;
|
||||
extern uint16_t chM3stop;
|
||||
extern uint16_t chM4start;
|
||||
extern uint16_t chM4stop;
|
||||
|
||||
const uint8_t deftab[EE_NUM_VIRTUAL_ADDR]={
|
||||
40, //m1pwmap
|
||||
60, //m1pwmch
|
||||
70, //m2pwmap
|
||||
70, //m2pwmch
|
||||
35, //m3pwmap
|
||||
40, //m3pwmch
|
||||
40, //m4pwmap
|
||||
40, //m4pwmch
|
||||
20, //m1rampstart
|
||||
20, //m2rampstart
|
||||
20, //m3rampstart
|
||||
20, //m4rampstart
|
||||
28, //t1ap
|
||||
4, //t2ap
|
||||
10, //t3ap
|
||||
40, //t4ap
|
||||
1, //twap
|
||||
27, //t1ch
|
||||
10, //t2ch
|
||||
30, //t3ch
|
||||
1, //t4ch
|
||||
1, //twch
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
100, //tramp1
|
||||
60, //m1pwmMan
|
||||
70, //m2pwmMan
|
||||
40, //m3pwmMan
|
||||
40, //m4pwmMan
|
||||
50, //trampman
|
||||
10, //tramp
|
||||
0, //apM1start;
|
||||
0, //apM1stop;
|
||||
0, //apM2start;
|
||||
0, //apM2stop;
|
||||
0, //apM3start;
|
||||
0, //apM3stop;
|
||||
0, //apM4start;
|
||||
0, //apM4stop;
|
||||
0, //chM1start;
|
||||
0, //chM1stop;
|
||||
0, //chM2start;
|
||||
0, //chM2stop;
|
||||
0, //chM3start;
|
||||
0, //chM3stop;
|
||||
0, //chM4start;
|
||||
0, //chM4stop;
|
||||
1,
|
||||
27,
|
||||
10,
|
||||
30,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
100,
|
||||
60,
|
||||
70,
|
||||
40,
|
||||
40,
|
||||
50,
|
||||
10,
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t VirtAddress;
|
||||
uint16_t Data;
|
||||
} EE_Record_t;
|
||||
|
||||
/* Active page base address (runtime selected in EE_Init) */
|
||||
static uint32_t EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
|
||||
/* 32 sequential virtual addresses */
|
||||
const uint16_t EE_VirtAddrs[EE_NUM_VIRTUAL_ADDR] =
|
||||
{
|
||||
0x0001, 0x0002, 0x0003, 0x0004,
|
||||
0x0005, 0x0006, 0x0007, 0x0008,
|
||||
0x0009, 0x000A, 0x000B, 0x000C,
|
||||
0x000D, 0x000E, 0x000F, 0x0010,
|
||||
0x0011, 0x0012, 0x0013, 0x0014,
|
||||
0x0015, 0x0016, 0x0017, 0x0018,
|
||||
0x0019, 0x001A, 0x001B, 0x001C,
|
||||
0x001D, 0x001E, 0x001F, 0x0020,
|
||||
|
||||
0x0021, 0x0022, 0x0023, 0x0024,
|
||||
0x0025, 0x0026, 0x0027, 0x0028,
|
||||
0x0029, 0x002A, 0x002B, 0x002C,
|
||||
0x002D, 0x002E, 0x002F, 0x0030,
|
||||
0x0031, 0x0032, 0x0033, 0x0034,
|
||||
0x0035, 0x0036, 0x0037, 0x0038,
|
||||
0x0039, 0x003A, 0x003B, 0x003C,
|
||||
0x003D, 0x003E, 0x003F, 0x0040
|
||||
};
|
||||
/* ========================================================================= */
|
||||
|
||||
/* --- Internal helpers ---------------------------------------------------- */
|
||||
|
||||
static uint16_t EE_GetPageStatus(uint32_t pageBase)
|
||||
{
|
||||
return *(__IO uint16_t *)pageBase;
|
||||
}
|
||||
|
||||
static HAL_StatusTypeDef EE_FlashProgramHalfWord(uint32_t Address, uint16_t Data)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
|
||||
HAL_FLASH_Unlock();
|
||||
status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, Address, Data);
|
||||
HAL_FLASH_Lock();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static HAL_StatusTypeDef EE_FlashErasePage(uint32_t PageAddress)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
FLASH_EraseInitTypeDef EraseInit;
|
||||
uint32_t PageError = 0;
|
||||
|
||||
HAL_FLASH_Unlock();
|
||||
|
||||
EraseInit.TypeErase = FLASH_TYPEERASE_PAGES;
|
||||
EraseInit.PageAddress = PageAddress;
|
||||
EraseInit.NbPages = 1;
|
||||
|
||||
status = HAL_FLASHEx_Erase(&EraseInit, &PageError);
|
||||
|
||||
HAL_FLASH_Lock();
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Find first free record address in given page (returns 0 if full) */
|
||||
static uint32_t EE_FindFreeAddress(uint32_t pageBase)
|
||||
{
|
||||
uint32_t addr = pageBase + 2U; /* Skip status word */
|
||||
uint32_t pageEnd = pageBase + EE_PAGE_SIZE;
|
||||
|
||||
while (addr < (pageEnd - sizeof(EE_Record_t) + 1U))
|
||||
{
|
||||
uint16_t vaddr = *(__IO uint16_t *)addr;
|
||||
|
||||
if (vaddr == 0xFFFFU)
|
||||
{
|
||||
/* Empty slot */
|
||||
return addr;
|
||||
}
|
||||
addr += sizeof(EE_Record_t);
|
||||
}
|
||||
|
||||
return 0U; /* No space */
|
||||
}
|
||||
|
||||
/* Find latest value of VirtAddress in a specific page (internal, uses EE_Status) */
|
||||
/* Find latest value of VirtAddress in a specific page (scan forward) */
|
||||
static EE_Status EE_FindInPage(uint32_t pageBase, uint16_t VirtAddress, uint16_t *Data)
|
||||
{
|
||||
uint32_t addr = pageBase + 2U; // skip status halfword
|
||||
uint32_t pageEnd = pageBase + EE_PAGE_SIZE;
|
||||
EE_Status result = EE_NOT_FOUND;
|
||||
uint16_t lastVal = 0;
|
||||
|
||||
if (Data == NULL)
|
||||
return EE_ERROR;
|
||||
|
||||
while (addr <= (pageEnd - sizeof(EE_Record_t)))
|
||||
{
|
||||
uint16_t vaddr = *(__IO uint16_t *)addr;
|
||||
|
||||
if (vaddr == 0xFFFFU)
|
||||
{
|
||||
// First empty slot => no more records in this page
|
||||
break;
|
||||
}
|
||||
|
||||
uint16_t value = *(__IO uint16_t *)(addr + 2U);
|
||||
|
||||
if (vaddr == VirtAddress)
|
||||
{
|
||||
lastVal = value; // keep most recent
|
||||
result = EE_OK;
|
||||
}
|
||||
|
||||
addr += sizeof(EE_Record_t); // move 4 bytes forward
|
||||
}
|
||||
|
||||
if (result == EE_OK)
|
||||
*Data = lastVal;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Format both pages: erase and set PAGE0 as VALID */
|
||||
static EE_Status EE_Format(void)
|
||||
{
|
||||
if (EE_FlashErasePage(EE_PAGE0_BASE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
if (EE_FlashErasePage(EE_PAGE1_BASE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
if (EE_FlashProgramHalfWord(EE_PAGE0_BASE, EE_PAGE_STATUS_VALID) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* PAGE1 will remain erased (status = 0xFFFF) */
|
||||
EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
|
||||
return EE_STATUS_OK;
|
||||
}
|
||||
|
||||
/* Get the base of the other page */
|
||||
static uint32_t EE_GetOtherPageBase(uint32_t pageBase)
|
||||
{
|
||||
return (pageBase == EE_PAGE0_BASE) ? EE_PAGE1_BASE : EE_PAGE0_BASE;
|
||||
}
|
||||
|
||||
/* Page transfer (garbage collection + new write) */
|
||||
static EE_Status EE_PageTransfer(uint16_t VirtAddress, uint16_t Data)
|
||||
{
|
||||
uint32_t oldBase = EE_ActivePageBase;
|
||||
uint32_t newBase = EE_GetOtherPageBase(oldBase);
|
||||
uint32_t addr;
|
||||
uint16_t value;
|
||||
EE_Status st;
|
||||
|
||||
/* Erase new page */
|
||||
if (EE_FlashErasePage(newBase) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Mark new page as RECEIVE */
|
||||
if (EE_FlashProgramHalfWord(newBase, EE_PAGE_STATUS_RECEIVE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Start writing records just after status */
|
||||
addr = newBase + 2U;
|
||||
|
||||
/* For each known virtual variable */
|
||||
for (uint16_t i = 0; i < EE_NUM_VIRTUAL_ADDR; i++)
|
||||
{
|
||||
uint16_t vaddr = EE_VirtAddrs[i];
|
||||
|
||||
if (vaddr == VirtAddress)
|
||||
{
|
||||
/* Use the new data passed into PageTransfer */
|
||||
value = Data;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Read latest value from old active page */
|
||||
st = EE_FindInPage(oldBase, vaddr, &value);
|
||||
if (st != EE_STATUS_OK)
|
||||
{
|
||||
/* Variable never written -> skip */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Write record to new page */
|
||||
if (EE_FlashProgramHalfWord(addr, vaddr) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
if (EE_FlashProgramHalfWord(addr + 2U, value) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
addr += sizeof(EE_Record_t);
|
||||
if (addr >= (newBase + EE_PAGE_SIZE))
|
||||
return EE_STATUS_NO_SPACE;
|
||||
}
|
||||
|
||||
/* Erase old page */
|
||||
if (EE_FlashErasePage(oldBase) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Mark new page as VALID */
|
||||
if (EE_FlashProgramHalfWord(newBase, EE_PAGE_STATUS_VALID) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Update active page */
|
||||
EE_ActivePageBase = newBase;
|
||||
|
||||
return EE_STATUS_OK;
|
||||
}
|
||||
|
||||
/* --- Public API ----------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* Initialize the EEPROM emulation.
|
||||
* - Checks page statuses and chooses the active page.
|
||||
* - If inconsistent or blank, formats pages.
|
||||
* PUBLIC RETURN TYPE: uint16_t (EE_OK / EE_ERROR / ...)
|
||||
*/
|
||||
uint16_t EE_Init(void)
|
||||
{
|
||||
uint16_t status0 = EE_GetPageStatus(EE_PAGE0_BASE);
|
||||
uint16_t status1 = EE_GetPageStatus(EE_PAGE1_BASE);
|
||||
|
||||
if ((status0 == EE_PAGE_STATUS_ERASED) && (status1 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
/* Fresh device -> format */
|
||||
return (uint16_t)EE_Format();
|
||||
}
|
||||
else if ((status0 == EE_PAGE_STATUS_VALID) && (status1 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
return EE_OK;
|
||||
}
|
||||
else if ((status1 == EE_PAGE_STATUS_VALID) && (status0 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
EE_ActivePageBase = EE_PAGE1_BASE;
|
||||
return EE_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Any weird or inconsistent state -> reformat */
|
||||
return (uint16_t)EE_Format();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a 16-bit variable by its virtual address.
|
||||
* PUBLIC RETURN: EE_OK / EE_NOT_FOUND / EE_ERROR (as uint16_t)
|
||||
*/
|
||||
uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t *Data)
|
||||
{
|
||||
EE_Status st;
|
||||
|
||||
if (Data == NULL)
|
||||
return EE_ERROR;
|
||||
|
||||
st = EE_FindInPage(EE_ActivePageBase, VirtAddress, Data);
|
||||
return (uint16_t)st;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write (append) a 16-bit variable.
|
||||
* - Writes a new record in the active page.
|
||||
* - If the page is full, triggers a page transfer (GC).
|
||||
* PUBLIC RETURN: EE_OK / EE_ERROR / EE_NO_SPACE (as uint16_t)
|
||||
*/
|
||||
uint16_t EE_WriteVariable(uint16_t VirtAddress, uint16_t Data)
|
||||
{
|
||||
uint32_t freeAddr;
|
||||
EE_Status st;
|
||||
|
||||
/* Find free space in active page */
|
||||
freeAddr = EE_FindFreeAddress(EE_ActivePageBase);
|
||||
if (freeAddr != 0U)
|
||||
{
|
||||
/* Write new record */
|
||||
if (EE_FlashProgramHalfWord(freeAddr, VirtAddress) != HAL_OK)
|
||||
return EE_ERROR;
|
||||
if (EE_FlashProgramHalfWord(freeAddr + 2U, Data) != HAL_OK)
|
||||
return EE_ERROR;
|
||||
|
||||
return EE_OK;
|
||||
}
|
||||
|
||||
/* No space -> page transfer */
|
||||
st = EE_PageTransfer(VirtAddress, Data);
|
||||
return (uint16_t)st;
|
||||
}
|
||||
|
||||
void loadEE(void){
|
||||
char s [200];
|
||||
EEW_Read(M1PWMAP, &m1pwmap);
|
||||
EEW_Read(M1PWMCH, &m1pwmch);
|
||||
EEW_Read(M2PWMAP, &m2pwmap);
|
||||
EEW_Read(M2PWMCH, &m2pwmch);
|
||||
EEW_Read(M3PWMAP, &m3pwmap);
|
||||
EEW_Read(M3PWMCH, &m3pwmch);
|
||||
EEW_Read(M4PWMAP, &m4pwmap);
|
||||
EEW_Read(M4PWMCH, &m4pwmch);
|
||||
EEW_Read(T1AP, &t1ap);
|
||||
EEW_Read(T2AP, &t2ap);
|
||||
EEW_Read(T3AP, &t3ap);
|
||||
EEW_Read(T4AP, &t4ap);
|
||||
EEW_Read(TWAP, &twap);
|
||||
EEW_Read(T1CH, &t1ch);
|
||||
EEW_Read(T2CH, &t2ch);
|
||||
EEW_Read(T3CH, &t3ch);
|
||||
EEW_Read(T4CH, &t4ch);
|
||||
EEW_Read(TWCH, &twch);
|
||||
EEW_Read(TRAMP1, &tramp1);
|
||||
EEW_Read(M1PWMMAN, &m1pwmMan);
|
||||
EEW_Read(M2PWMMAN, &m2pwmMan);
|
||||
EEW_Read(M3PWMMAN, &m3pwmMan);
|
||||
EEW_Read(M4PWMMAN, &m4pwmMan);
|
||||
EEW_Read(TRAMPMAN, &trampman);
|
||||
EEW_Read(TRAMP, &tramp);
|
||||
|
||||
EEW_Read(APM1START,&apM1start);
|
||||
EEW_Read(APM1STOP ,&apM1stop);
|
||||
EEW_Read(APM2START,&apM2start);
|
||||
EEW_Read(APM2STOP ,&apM2stop);
|
||||
EEW_Read(APM3START,&apM3start);
|
||||
EEW_Read(APM3STOP ,&apM3stop);
|
||||
EEW_Read(APM4START,&apM4start);
|
||||
EEW_Read(APM4STOP ,&apM4stop);
|
||||
EEW_Read(CHM1START,&chM1start);
|
||||
EEW_Read(CHM1STOP ,&chM1stop);
|
||||
EEW_Read(CHM2START,&chM2start);
|
||||
EEW_Read(CHM2STOP ,&chM2stop);
|
||||
EEW_Read(CHM3START,&chM3start);
|
||||
EEW_Read(CHM3STOP ,&chM3stop);
|
||||
EEW_Read(CHM4START,&chM4start);
|
||||
EEW_Read(CHM4STOP ,&chM4stop);
|
||||
|
||||
sprintf((char*)s,"LoadEE\n");
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
sprintf((char*)s,"\nm1pwmap=%d m1pwmch=%d m2pwmap=%d m2pwmch=%d m3pwmap=%d m3pwmch=%d m4pwmap=%d m4pwmch=%d",m1pwmap,m1pwmch,m2pwmap,m2pwmch,m3pwmap,m3pwmch,m4pwmap, m4pwmch);
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* eeprom.h
|
||||
*
|
||||
* Created on: Dec 7, 2025
|
||||
* Author: user
|
||||
*/
|
||||
|
||||
#ifndef __EEPROM_H
|
||||
#define __EEPROM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "stm32f1xx_hal.h"
|
||||
|
||||
/*
|
||||
* Simple EEPROM emulation for STM32F103C8T6 (medium density).
|
||||
* - Uses 2 Flash pages (1 kB each) at the end of Flash.
|
||||
* - Stores variables as 16-bit values identified by 16-bit "virtual addresses".
|
||||
*
|
||||
* You must define the list of virtual addresses in eeprom.c: EE_VirtAddrs[].
|
||||
*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
EE_STATUS_OK = 0,
|
||||
EE_STATUS_ERROR,
|
||||
EE_STATUS_NOT_FOUND,
|
||||
EE_STATUS_NO_SPACE
|
||||
} EE_Status;
|
||||
|
||||
/* For compatibility with ST style uint16_t return codes */
|
||||
#define EE_OK ((uint16_t)EE_STATUS_OK)
|
||||
#define EE_ERROR ((uint16_t)EE_STATUS_ERROR)
|
||||
#define EE_NOT_FOUND ((uint16_t)EE_STATUS_NOT_FOUND)
|
||||
#define EE_NO_SPACE ((uint16_t)EE_STATUS_NO_SPACE)
|
||||
|
||||
/* Flash parameters for STM32F103C8T6 */
|
||||
#define EE_FLASH_BASE_ADDR 0x08000000U
|
||||
#define EE_PAGE_SIZE 0x400U /* 1 kB pages */
|
||||
|
||||
/*
|
||||
* Here we assume a 64 kB Flash device (STM32F103C8T6):
|
||||
* Flash range: 0x0800 0000 - 0x0800 FFFF
|
||||
* Pages: 0..63 (64 pages)
|
||||
* We use the last 2 pages for EEPROM:
|
||||
* - Page 62: 0x0800 F800
|
||||
* - Page 63: 0x0800 FC00
|
||||
*/
|
||||
#define EE_PAGE0_BASE (EE_FLASH_BASE_ADDR + (62U * EE_PAGE_SIZE))
|
||||
#define EE_PAGE1_BASE (EE_FLASH_BASE_ADDR + (63U * EE_PAGE_SIZE))
|
||||
|
||||
/* Page status markers (stored in the first halfword of each page) */
|
||||
#define EE_PAGE_STATUS_ERASED 0xFFFFU
|
||||
#define EE_PAGE_STATUS_VALID 0xAAAAU
|
||||
#define EE_PAGE_STATUS_RECEIVE 0x5555U
|
||||
|
||||
/*
|
||||
* Configure how many virtual variables you have.
|
||||
* Example: bytes, words, and array elements mapped to 16-bit variables.
|
||||
* Set EE_NUM_VIRTUAL_ADDR and define EE_VirtAddrs[] in eeprom.c.
|
||||
*/
|
||||
/* 32 virtual variables, sequential addresses */
|
||||
#define EE_NUM_VIRTUAL_ADDR 64U
|
||||
#define EEW_ADDR(i) ((uint16_t)(0x0001U + (uint16_t)(i))) // i = 0..63
|
||||
|
||||
|
||||
#define M1PWMAP 0 //m1pwmap
|
||||
#define M1PWMCH 1 //m1pwmch
|
||||
#define M2PWMAP 2 //m2pwmap
|
||||
#define M2PWMCH 3 //m2pwmch
|
||||
#define M3PWMAP 4 //m3pwmap
|
||||
#define M3PWMCH 5 //m3pwmch
|
||||
#define M4PWMAP 6 //m4pwmap
|
||||
#define M4PWMCH 7 //m4pwmch
|
||||
#define M1RAMPSTART 8 //m1rampstart
|
||||
#define M2RAMPSTART 9 //m2rampstart
|
||||
#define M3RAMPSTART 10 //m3rampstart
|
||||
#define M4RAMPSTART 11 //m4rampstart
|
||||
#define T1AP 12 //t1ap
|
||||
#define T2AP 13 //t2ap
|
||||
#define T3AP 14 //t3ap
|
||||
#define T4AP 15 //t4ap
|
||||
#define TWAP 16 //twap
|
||||
#define T1CH 17 //t1ch
|
||||
#define T2CH 18 //t2ch
|
||||
#define T3CH 19 //t3ch
|
||||
#define T4CH 20 //t4ch
|
||||
#define TWCH 21 //twch
|
||||
|
||||
#define TRAMP1 25 //tramp1
|
||||
#define M1PWMMAN 26 //m1pwmMan
|
||||
#define M2PWMMAN 27 //m2pwmMan
|
||||
#define M3PWMMAN 28 //m3pwmMan
|
||||
#define M4PWMMAN 29 //m4pwmMan
|
||||
#define TRAMPMAN 30 //trampman
|
||||
#define TRAMP 31 //tramp
|
||||
|
||||
#define APM1START 32 //apM1start;
|
||||
#define APM1STOP 33 //apM1stop;
|
||||
#define APM2START 34 //apM2start;
|
||||
#define APM2STOP 35 //apM2stop;
|
||||
#define APM3START 36 //apM3start;
|
||||
#define APM3STOP 37 //apM3stop;
|
||||
#define APM4START 38 //apM4start;
|
||||
#define APM4STOP 39 //apM4stop;
|
||||
#define CHM1START 40 //chM1start;
|
||||
#define CHM1STOP 41 //chM1stop;
|
||||
#define CHM2START 42 //chM2start;
|
||||
#define CHM2STOP 43 //chM2stop;
|
||||
#define CHM3START 44 //chM3start;
|
||||
#define CHM3STOP 45 //chM3stop;
|
||||
#define CHM4START 46 //chM4start;
|
||||
#define CHM4STOP 47 //chM4stop;
|
||||
|
||||
|
||||
/* Virtual address table (defined in eeprom.c, can be customized) */
|
||||
extern const uint16_t EE_VirtAddrs[EE_NUM_VIRTUAL_ADDR];
|
||||
|
||||
/* Public API – now using uint16_t like ST examples */
|
||||
uint16_t EE_Init(void);
|
||||
uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t *Data);
|
||||
uint16_t EE_WriteVariable(uint16_t VirtAddress, uint16_t Data);
|
||||
void loadEE(void);
|
||||
/* Pseudo-array accessor EEW[idx] */
|
||||
static inline uint16_t EEW_Read(uint8_t idx, uint16_t *value)
|
||||
{
|
||||
return EE_ReadVariable(EEW_ADDR(idx), value);
|
||||
}
|
||||
|
||||
static inline uint16_t EEW_Write(uint8_t idx, uint16_t value)
|
||||
{
|
||||
return EE_WriteVariable(EEW_ADDR(idx), value);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __EEPROM_H */
|
||||
@@ -0,0 +1,481 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "eeprom.h"
|
||||
extern UART_HandleTypeDef huart1;
|
||||
/*
|
||||
* Record format (4 bytes):
|
||||
* [0] VirtAddress (uint16_t)
|
||||
* [2] Data (uint16_t)
|
||||
*
|
||||
* Page layout:
|
||||
* [0] PageStatus (uint16_t)
|
||||
* [2..] Records...
|
||||
*/
|
||||
|
||||
extern uint16_t m1pwmap;
|
||||
extern uint16_t m1pwmch;
|
||||
extern uint16_t m2pwmap;
|
||||
extern uint16_t m2pwmch;
|
||||
extern uint16_t m3pwmap;
|
||||
extern uint16_t m3pwmch;
|
||||
extern uint16_t m4pwmap;
|
||||
extern uint16_t m4pwmch;
|
||||
extern uint16_t t1ap;
|
||||
extern uint16_t t2ap;
|
||||
extern uint16_t t3ap;
|
||||
extern uint16_t t4ap;
|
||||
extern uint16_t twap;
|
||||
extern uint16_t tramp;
|
||||
extern uint16_t t1ch;
|
||||
extern uint16_t t2ch;
|
||||
extern uint16_t t3ch;
|
||||
extern uint16_t t4ch;
|
||||
extern uint16_t twch;
|
||||
extern uint16_t tramp1;
|
||||
extern uint16_t trampman;
|
||||
extern uint16_t m1pwmMan;
|
||||
extern uint16_t m2pwmMan;
|
||||
extern uint16_t m3pwmMan;
|
||||
extern uint16_t m4pwmMan;
|
||||
|
||||
|
||||
extern uint16_t apM1start;
|
||||
extern uint16_t apM1stop;
|
||||
extern uint16_t apM2start;
|
||||
extern uint16_t apM2stop;
|
||||
extern uint16_t apM3start;
|
||||
extern uint16_t apM3stop;
|
||||
extern uint16_t apM4start;
|
||||
extern uint16_t apM4stop;
|
||||
extern uint16_t chM1start;
|
||||
extern uint16_t chM1stop;
|
||||
extern uint16_t chM2start;
|
||||
extern uint16_t chM2stop;
|
||||
extern uint16_t chM3start;
|
||||
extern uint16_t chM3stop;
|
||||
extern uint16_t chM4start;
|
||||
extern uint16_t chM4stop;
|
||||
|
||||
const uint8_t deftab[EE_NUM_VIRTUAL_ADDR]={
|
||||
40, //m1pwmap
|
||||
60, //m1pwmch
|
||||
70, //m2pwmap
|
||||
70, //m2pwmch
|
||||
35, //m3pwmap
|
||||
40, //m3pwmch
|
||||
40, //m4pwmap
|
||||
40, //m4pwmch
|
||||
20, //m1rampstart
|
||||
20, //m2rampstart
|
||||
20, //m3rampstart
|
||||
20, //m4rampstart
|
||||
28, //t1ap
|
||||
4, //t2ap
|
||||
10, //t3ap
|
||||
40, //t4ap
|
||||
1, //twap
|
||||
27, //t1ch
|
||||
10, //t2ch
|
||||
30, //t3ch
|
||||
1, //t4ch
|
||||
1, //twch
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
100, //tramp1
|
||||
60, //m1pwmMan
|
||||
70, //m2pwmMan
|
||||
40, //m3pwmMan
|
||||
40, //m4pwmMan
|
||||
50, //trampman
|
||||
10, //tramp
|
||||
310, //apM1start;
|
||||
450, //apM1stop;
|
||||
30, //apM2start;
|
||||
310, //apM2stop;
|
||||
350, //apM3start;
|
||||
450, //apM3stop;
|
||||
450, //apM4start;
|
||||
850, //apM4stop;
|
||||
10, //chM1start;
|
||||
280, //chM1stop;
|
||||
280, //chM2start;
|
||||
580, //chM2stop;
|
||||
20, //chM3start;
|
||||
280, //chM3stop;
|
||||
280, //chM4start;
|
||||
680, //chM4stop;
|
||||
1,
|
||||
27,
|
||||
10,
|
||||
30,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
100,
|
||||
60,
|
||||
70,
|
||||
40,
|
||||
40,
|
||||
50,
|
||||
10,
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t VirtAddress;
|
||||
uint16_t Data;
|
||||
} EE_Record_t;
|
||||
|
||||
/* Active page base address (runtime selected in EE_Init) */
|
||||
static uint32_t EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
|
||||
/* 32 sequential virtual addresses */
|
||||
const uint16_t EE_VirtAddrs[EE_NUM_VIRTUAL_ADDR] =
|
||||
{
|
||||
0x0001, 0x0002, 0x0003, 0x0004,
|
||||
0x0005, 0x0006, 0x0007, 0x0008,
|
||||
0x0009, 0x000A, 0x000B, 0x000C,
|
||||
0x000D, 0x000E, 0x000F, 0x0010,
|
||||
0x0011, 0x0012, 0x0013, 0x0014,
|
||||
0x0015, 0x0016, 0x0017, 0x0018,
|
||||
0x0019, 0x001A, 0x001B, 0x001C,
|
||||
0x001D, 0x001E, 0x001F, 0x0020,
|
||||
|
||||
0x0021, 0x0022, 0x0023, 0x0024,
|
||||
0x0025, 0x0026, 0x0027, 0x0028,
|
||||
0x0029, 0x002A, 0x002B, 0x002C,
|
||||
0x002D, 0x002E, 0x002F, 0x0030,
|
||||
0x0031, 0x0032, 0x0033, 0x0034,
|
||||
0x0035, 0x0036, 0x0037, 0x0038,
|
||||
0x0039, 0x003A, 0x003B, 0x003C,
|
||||
0x003D, 0x003E, 0x003F, 0x0040
|
||||
};
|
||||
/* ========================================================================= */
|
||||
|
||||
/* --- Internal helpers ---------------------------------------------------- */
|
||||
|
||||
static uint16_t EE_GetPageStatus(uint32_t pageBase)
|
||||
{
|
||||
return *(__IO uint16_t *)pageBase;
|
||||
}
|
||||
|
||||
static HAL_StatusTypeDef EE_FlashProgramHalfWord(uint32_t Address, uint16_t Data)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
|
||||
HAL_FLASH_Unlock();
|
||||
status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, Address, Data);
|
||||
HAL_FLASH_Lock();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static HAL_StatusTypeDef EE_FlashErasePage(uint32_t PageAddress)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
FLASH_EraseInitTypeDef EraseInit;
|
||||
uint32_t PageError = 0;
|
||||
|
||||
HAL_FLASH_Unlock();
|
||||
|
||||
EraseInit.TypeErase = FLASH_TYPEERASE_PAGES;
|
||||
EraseInit.PageAddress = PageAddress;
|
||||
EraseInit.NbPages = 1;
|
||||
|
||||
status = HAL_FLASHEx_Erase(&EraseInit, &PageError);
|
||||
|
||||
HAL_FLASH_Lock();
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Find first free record address in given page (returns 0 if full) */
|
||||
static uint32_t EE_FindFreeAddress(uint32_t pageBase)
|
||||
{
|
||||
uint32_t addr = pageBase + 2U; /* Skip status word */
|
||||
uint32_t pageEnd = pageBase + EE_PAGE_SIZE;
|
||||
|
||||
while (addr < (pageEnd - sizeof(EE_Record_t) + 1U))
|
||||
{
|
||||
uint16_t vaddr = *(__IO uint16_t *)addr;
|
||||
|
||||
if (vaddr == 0xFFFFU)
|
||||
{
|
||||
/* Empty slot */
|
||||
return addr;
|
||||
}
|
||||
addr += sizeof(EE_Record_t);
|
||||
}
|
||||
|
||||
return 0U; /* No space */
|
||||
}
|
||||
|
||||
/* Find latest value of VirtAddress in a specific page (internal, uses EE_Status) */
|
||||
/* Find latest value of VirtAddress in a specific page (scan forward) */
|
||||
static EE_Status EE_FindInPage(uint32_t pageBase, uint16_t VirtAddress, uint16_t *Data)
|
||||
{
|
||||
uint32_t addr = pageBase + 2U; // skip status halfword
|
||||
uint32_t pageEnd = pageBase + EE_PAGE_SIZE;
|
||||
EE_Status result = EE_NOT_FOUND;
|
||||
uint16_t lastVal = 0;
|
||||
|
||||
if (Data == NULL)
|
||||
return EE_ERROR;
|
||||
|
||||
while (addr <= (pageEnd - sizeof(EE_Record_t)))
|
||||
{
|
||||
uint16_t vaddr = *(__IO uint16_t *)addr;
|
||||
|
||||
if (vaddr == 0xFFFFU)
|
||||
{
|
||||
// First empty slot => no more records in this page
|
||||
break;
|
||||
}
|
||||
|
||||
uint16_t value = *(__IO uint16_t *)(addr + 2U);
|
||||
|
||||
if (vaddr == VirtAddress)
|
||||
{
|
||||
lastVal = value; // keep most recent
|
||||
result = EE_OK;
|
||||
}
|
||||
|
||||
addr += sizeof(EE_Record_t); // move 4 bytes forward
|
||||
}
|
||||
|
||||
if (result == EE_OK)
|
||||
*Data = lastVal;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Format both pages: erase and set PAGE0 as VALID */
|
||||
static EE_Status EE_Format(void)
|
||||
{
|
||||
if (EE_FlashErasePage(EE_PAGE0_BASE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
if (EE_FlashErasePage(EE_PAGE1_BASE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
if (EE_FlashProgramHalfWord(EE_PAGE0_BASE, EE_PAGE_STATUS_VALID) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* PAGE1 will remain erased (status = 0xFFFF) */
|
||||
EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
|
||||
return EE_STATUS_OK;
|
||||
}
|
||||
|
||||
/* Get the base of the other page */
|
||||
static uint32_t EE_GetOtherPageBase(uint32_t pageBase)
|
||||
{
|
||||
return (pageBase == EE_PAGE0_BASE) ? EE_PAGE1_BASE : EE_PAGE0_BASE;
|
||||
}
|
||||
|
||||
/* Page transfer (garbage collection + new write) */
|
||||
static EE_Status EE_PageTransfer(uint16_t VirtAddress, uint16_t Data)
|
||||
{
|
||||
uint32_t oldBase = EE_ActivePageBase;
|
||||
uint32_t newBase = EE_GetOtherPageBase(oldBase);
|
||||
uint32_t addr;
|
||||
uint16_t value;
|
||||
EE_Status st;
|
||||
|
||||
/* Erase new page */
|
||||
if (EE_FlashErasePage(newBase) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Mark new page as RECEIVE */
|
||||
if (EE_FlashProgramHalfWord(newBase, EE_PAGE_STATUS_RECEIVE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Start writing records just after status */
|
||||
addr = newBase + 2U;
|
||||
|
||||
/* For each known virtual variable */
|
||||
for (uint16_t i = 0; i < EE_NUM_VIRTUAL_ADDR; i++)
|
||||
{
|
||||
uint16_t vaddr = EE_VirtAddrs[i];
|
||||
|
||||
if (vaddr == VirtAddress)
|
||||
{
|
||||
/* Use the new data passed into PageTransfer */
|
||||
value = Data;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Read latest value from old active page */
|
||||
st = EE_FindInPage(oldBase, vaddr, &value);
|
||||
if (st != EE_STATUS_OK)
|
||||
{
|
||||
/* Variable never written -> skip */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Write record to new page */
|
||||
if (EE_FlashProgramHalfWord(addr, vaddr) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
if (EE_FlashProgramHalfWord(addr + 2U, value) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
addr += sizeof(EE_Record_t);
|
||||
if (addr >= (newBase + EE_PAGE_SIZE))
|
||||
return EE_STATUS_NO_SPACE;
|
||||
}
|
||||
|
||||
/* Erase old page */
|
||||
if (EE_FlashErasePage(oldBase) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Mark new page as VALID */
|
||||
if (EE_FlashProgramHalfWord(newBase, EE_PAGE_STATUS_VALID) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Update active page */
|
||||
EE_ActivePageBase = newBase;
|
||||
|
||||
return EE_STATUS_OK;
|
||||
}
|
||||
|
||||
/* --- Public API ----------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* Initialize the EEPROM emulation.
|
||||
* - Checks page statuses and chooses the active page.
|
||||
* - If inconsistent or blank, formats pages.
|
||||
* PUBLIC RETURN TYPE: uint16_t (EE_OK / EE_ERROR / ...)
|
||||
*/
|
||||
uint16_t EE_Init(void)
|
||||
{
|
||||
uint16_t status0 = EE_GetPageStatus(EE_PAGE0_BASE);
|
||||
uint16_t status1 = EE_GetPageStatus(EE_PAGE1_BASE);
|
||||
|
||||
if ((status0 == EE_PAGE_STATUS_ERASED) && (status1 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
/* Fresh device -> format */
|
||||
return (uint16_t)EE_Format();
|
||||
}
|
||||
else if ((status0 == EE_PAGE_STATUS_VALID) && (status1 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
return EE_OK;
|
||||
}
|
||||
else if ((status1 == EE_PAGE_STATUS_VALID) && (status0 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
EE_ActivePageBase = EE_PAGE1_BASE;
|
||||
return EE_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Any weird or inconsistent state -> reformat */
|
||||
return (uint16_t)EE_Format();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a 16-bit variable by its virtual address.
|
||||
* PUBLIC RETURN: EE_OK / EE_NOT_FOUND / EE_ERROR (as uint16_t)
|
||||
*/
|
||||
uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t *Data)
|
||||
{
|
||||
EE_Status st;
|
||||
|
||||
if (Data == NULL)
|
||||
return EE_ERROR;
|
||||
|
||||
st = EE_FindInPage(EE_ActivePageBase, VirtAddress, Data);
|
||||
return (uint16_t)st;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write (append) a 16-bit variable.
|
||||
* - Writes a new record in the active page.
|
||||
* - If the page is full, triggers a page transfer (GC).
|
||||
* PUBLIC RETURN: EE_OK / EE_ERROR / EE_NO_SPACE (as uint16_t)
|
||||
*/
|
||||
uint16_t EE_WriteVariable(uint16_t VirtAddress, uint16_t Data)
|
||||
{
|
||||
uint32_t freeAddr;
|
||||
EE_Status st;
|
||||
|
||||
/* Find free space in active page */
|
||||
freeAddr = EE_FindFreeAddress(EE_ActivePageBase);
|
||||
if (freeAddr != 0U)
|
||||
{
|
||||
/* Write new record */
|
||||
if (EE_FlashProgramHalfWord(freeAddr, VirtAddress) != HAL_OK)
|
||||
return EE_ERROR;
|
||||
if (EE_FlashProgramHalfWord(freeAddr + 2U, Data) != HAL_OK)
|
||||
return EE_ERROR;
|
||||
|
||||
return EE_OK;
|
||||
}
|
||||
|
||||
/* No space -> page transfer */
|
||||
st = EE_PageTransfer(VirtAddress, Data);
|
||||
return (uint16_t)st;
|
||||
}
|
||||
|
||||
void loadEE(void){
|
||||
char s [200];
|
||||
EEW_Read(M1PWMAP, &m1pwmap);
|
||||
EEW_Read(M1PWMCH, &m1pwmch);
|
||||
EEW_Read(M2PWMAP, &m2pwmap);
|
||||
EEW_Read(M2PWMCH, &m2pwmch);
|
||||
EEW_Read(M3PWMAP, &m3pwmap);
|
||||
EEW_Read(M3PWMCH, &m3pwmch);
|
||||
EEW_Read(M4PWMAP, &m4pwmap);
|
||||
EEW_Read(M4PWMCH, &m4pwmch);
|
||||
EEW_Read(T1AP, &t1ap);
|
||||
EEW_Read(T2AP, &t2ap);
|
||||
EEW_Read(T3AP, &t3ap);
|
||||
EEW_Read(T4AP, &t4ap);
|
||||
EEW_Read(TWAP, &twap);
|
||||
EEW_Read(T1CH, &t1ch);
|
||||
EEW_Read(T2CH, &t2ch);
|
||||
EEW_Read(T3CH, &t3ch);
|
||||
EEW_Read(T4CH, &t4ch);
|
||||
EEW_Read(TWCH, &twch);
|
||||
EEW_Read(TRAMP1, &tramp1);
|
||||
EEW_Read(M1PWMMAN, &m1pwmMan);
|
||||
EEW_Read(M2PWMMAN, &m2pwmMan);
|
||||
EEW_Read(M3PWMMAN, &m3pwmMan);
|
||||
EEW_Read(M4PWMMAN, &m4pwmMan);
|
||||
EEW_Read(TRAMPMAN, &trampman);
|
||||
EEW_Read(TRAMP, &tramp);
|
||||
|
||||
EEW_Read(APM1START,&apM1start);
|
||||
EEW_Read(APM1STOP ,&apM1stop);
|
||||
EEW_Read(APM2START,&apM2start);
|
||||
EEW_Read(APM2STOP ,&apM2stop);
|
||||
EEW_Read(APM3START,&apM3start);
|
||||
EEW_Read(APM3STOP ,&apM3stop);
|
||||
EEW_Read(APM4START,&apM4start);
|
||||
EEW_Read(APM4STOP ,&apM4stop);
|
||||
EEW_Read(CHM1START,&chM1start);
|
||||
EEW_Read(CHM1STOP ,&chM1stop);
|
||||
EEW_Read(CHM2START,&chM2start);
|
||||
EEW_Read(CHM2STOP ,&chM2stop);
|
||||
EEW_Read(CHM3START,&chM3start);
|
||||
EEW_Read(CHM3STOP ,&chM3stop);
|
||||
EEW_Read(CHM4START,&chM4start);
|
||||
EEW_Read(CHM4STOP ,&chM4stop);
|
||||
|
||||
sprintf((char*)s,"LoadEE\n");
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
sprintf((char*)s,"\nm1pwmap=%d m1pwmch=%d m2pwmap=%d m2pwmch=%d m3pwmap=%d m3pwmch=%d m4pwmap=%d m4pwmch=%d",m1pwmap,m1pwmch,m2pwmap,m2pwmch,m3pwmap,m3pwmch,m4pwmap, m4pwmch);
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
|
||||
sprintf((char*)s,"\ntramp=%d trampman=%d",tramp,trampman);
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
sprintf((char*)s,"\nm1pwmMan=%d m2pwmMan=%d m3pwmMan=%d m4pwmMan=%d",m1pwmMan,m2pwmMan,m3pwmMan,m4pwmMan);
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,322 @@
|
||||
/*
|
||||
* mot.c
|
||||
*
|
||||
* Created on: May 2, 2026
|
||||
* Author: user
|
||||
*/
|
||||
#include "mot.h"
|
||||
#include "pwm.h"
|
||||
|
||||
extern uint16_t apM1start;
|
||||
extern uint16_t apM1stop;
|
||||
extern uint16_t apM2start;
|
||||
extern uint16_t apM2stop;
|
||||
extern uint16_t apM3start;
|
||||
extern uint16_t apM3stop;
|
||||
extern uint16_t apM4start;
|
||||
extern uint16_t apM4stop;
|
||||
extern uint16_t chM1start;
|
||||
extern uint16_t chM1stop;
|
||||
extern uint16_t chM2start;
|
||||
extern uint16_t chM2stop;
|
||||
extern uint16_t chM3start;
|
||||
extern uint16_t chM3stop;
|
||||
extern uint16_t chM4start;
|
||||
extern uint16_t chM4stop;
|
||||
extern volatile uint16_t rtCiclo;
|
||||
|
||||
motMov_st m1ap(void){
|
||||
static motMov_st m1st;
|
||||
if(rtCiclo<apM1start)m1st=motWaiting;
|
||||
switch(m1st){
|
||||
case motWaiting:
|
||||
SetMotPerc(M1,FW,0);
|
||||
SetMotPerc(M1,BW,0);
|
||||
if(rtCiclo>=apM1start){
|
||||
(void)ramp(M1,BW,mrampstart[M1-1],m1pwmap,tramp,RAMPINIT);
|
||||
m1st=motStartRamp;
|
||||
}
|
||||
break;
|
||||
case motStartRamp:
|
||||
if(ramp(M1,BW,mrampstart[M1-1],m1pwmap,tramp,RAMPRUN)==DONE){
|
||||
m1st=motWaitingTime;
|
||||
}
|
||||
break;
|
||||
case motWaitingTime:
|
||||
if(rtCiclo>=apM1stop){
|
||||
(void)ramp(M1,BW,m1pwmap,0,tramp,RAMPINIT);
|
||||
m1st=motStopRamp;
|
||||
}
|
||||
break;
|
||||
case motStopRamp:
|
||||
if(ramp(M1,BW,m1pwmap,0,tramp,RAMPRUN)==DONE){
|
||||
m1st=motStop;
|
||||
}
|
||||
break;
|
||||
case motStop:
|
||||
default:
|
||||
SetMotPerc(M1,FW,0);
|
||||
SetMotPerc(M1,BW,0);
|
||||
break;
|
||||
}
|
||||
return m1st;
|
||||
}
|
||||
|
||||
motMov_st m2ap(void){
|
||||
static motMov_st m2st;
|
||||
if(rtCiclo<apM2start)m2st=motWaiting;
|
||||
switch(m2st){
|
||||
case motWaiting:
|
||||
SetMotPerc(M2,FW,0);
|
||||
SetMotPerc(M2,BW,0);
|
||||
if(rtCiclo>=apM2start){
|
||||
(void)ramp(M2,BW,mrampstart[M2-1],m2pwmap,tramp,RAMPINIT);
|
||||
m2st=motStartRamp;
|
||||
}
|
||||
break;
|
||||
case motStartRamp:
|
||||
if(ramp(M2,BW,mrampstart[M2-1],m2pwmap,tramp,RAMPRUN)==DONE){
|
||||
m2st=motWaitingTime;
|
||||
}
|
||||
break;
|
||||
case motWaitingTime:
|
||||
if(rtCiclo>=apM2stop){
|
||||
(void)ramp(M2,BW,m2pwmap,0,tramp,RAMPINIT);
|
||||
m2st=motStopRamp;
|
||||
}
|
||||
break;
|
||||
case motStopRamp:
|
||||
if(ramp(M2,BW,m2pwmap,0,tramp,RAMPRUN)==DONE){
|
||||
m2st=motStop;
|
||||
}
|
||||
break;
|
||||
case motStop:
|
||||
default:
|
||||
SetMotPerc(M2,FW,0);
|
||||
SetMotPerc(M2,BW,0);
|
||||
break;
|
||||
}
|
||||
return m2st;
|
||||
}
|
||||
|
||||
motMov_st m3ap(void){
|
||||
static motMov_st m3st;
|
||||
if(rtCiclo<apM3start)m3st=motWaiting;
|
||||
switch(m3st){
|
||||
case motWaiting:
|
||||
SetMotPerc(M3,FW,0);
|
||||
SetMotPerc(M3,BW,0);
|
||||
if(rtCiclo>=apM3start){
|
||||
(void)ramp(M3,BW,mrampstart[M3-1],m2pwmap,tramp,RAMPINIT);
|
||||
m3st=motStartRamp;
|
||||
}
|
||||
break;
|
||||
case motStartRamp:
|
||||
if(ramp(M3,BW,mrampstart[M3-1],m3pwmap,tramp,RAMPRUN)==DONE){
|
||||
m3st=motWaitingTime;
|
||||
}
|
||||
break;
|
||||
case motWaitingTime:
|
||||
if(rtCiclo>=apM3stop){
|
||||
(void)ramp(M3,BW,m3pwmap,0,tramp,RAMPINIT);
|
||||
m3st=motStopRamp;
|
||||
}
|
||||
break;
|
||||
case motStopRamp:
|
||||
if(ramp(M3,BW,m3pwmap,0,tramp,RAMPRUN)==DONE){
|
||||
m3st=motStop;
|
||||
}
|
||||
break;
|
||||
case motStop:
|
||||
default:
|
||||
SetMotPerc(M3,FW,0);
|
||||
SetMotPerc(M3,BW,0);
|
||||
break;
|
||||
}
|
||||
return m3st;
|
||||
}
|
||||
|
||||
motMov_st m4ap(void){
|
||||
static motMov_st m4st;
|
||||
if(rtCiclo<apM4start)m4st=motWaiting;
|
||||
switch(m4st){
|
||||
case motWaiting:
|
||||
SetMotPerc(M4,FW,0);
|
||||
SetMotPerc(M4,BW,0);
|
||||
if(rtCiclo>=apM4start){
|
||||
(void)ramp(M4,BW,mrampstart[M4-1],m2pwmap,tramp,RAMPINIT);
|
||||
m4st=motStartRamp;
|
||||
}
|
||||
break;
|
||||
case motStartRamp:
|
||||
if(ramp(M4,BW,mrampstart[M4-1],m4pwmap,tramp,RAMPRUN)==DONE){
|
||||
m4st=motWaitingTime;
|
||||
}
|
||||
break;
|
||||
case motWaitingTime:
|
||||
if(rtCiclo>=apM4stop){
|
||||
(void)ramp(M4,BW,m4pwmap,0,tramp,RAMPINIT);
|
||||
m4st=motStopRamp;
|
||||
}
|
||||
break;
|
||||
case motStopRamp:
|
||||
if(ramp(43,BW,m4pwmap,0,tramp,RAMPRUN)==DONE){
|
||||
m4st=motStop;
|
||||
}
|
||||
break;
|
||||
case motStop:
|
||||
default:
|
||||
SetMotPerc(M4,FW,0);
|
||||
SetMotPerc(M4,BW,0);
|
||||
break;
|
||||
}
|
||||
return m4st;
|
||||
}
|
||||
|
||||
motMov_st m1ch(void){
|
||||
static motMov_st m1st;
|
||||
if(rtCiclo<chM1start)m1st=motWaiting;
|
||||
switch(m1st){
|
||||
case motWaiting:
|
||||
SetMotPerc(M1,FW,0);
|
||||
SetMotPerc(M1,BW,0);
|
||||
if(rtCiclo>=chM1start){
|
||||
(void)ramp(M1,FW,mrampstart[M1-1],m1pwmch,tramp,RAMPINIT);
|
||||
m1st=motStartRamp;
|
||||
}
|
||||
break;
|
||||
case motStartRamp:
|
||||
if(ramp(M1,FW,mrampstart[M1-1],m1pwmch,tramp,RAMPRUN)==DONE){
|
||||
m1st=motWaitingTime;
|
||||
}
|
||||
break;
|
||||
case motWaitingTime:
|
||||
if(rtCiclo>=chM1stop){
|
||||
(void)ramp(M1,FW,m1pwmch,0,tramp,RAMPINIT);
|
||||
m1st=motStopRamp;
|
||||
}
|
||||
break;
|
||||
case motStopRamp:
|
||||
if(ramp(M1,FW,m1pwmch,0,tramp,RAMPRUN)==DONE){
|
||||
m1st=motStop;
|
||||
}
|
||||
break;
|
||||
case motStop:
|
||||
default:
|
||||
SetMotPerc(M1,FW,0);
|
||||
SetMotPerc(M1,BW,0);
|
||||
break;
|
||||
}
|
||||
return m1st;
|
||||
}
|
||||
|
||||
motMov_st m2ch(void){
|
||||
static motMov_st m2st;
|
||||
if(rtCiclo<chM2start)m2st=motWaiting;
|
||||
switch(m2st){
|
||||
case motWaiting:
|
||||
SetMotPerc(M2,FW,0);
|
||||
SetMotPerc(M2,BW,0);
|
||||
if(rtCiclo>=chM2start){
|
||||
(void)ramp(M2,FW,mrampstart[M2-1],m2pwmch,tramp,RAMPINIT);
|
||||
m2st=motStartRamp;
|
||||
}
|
||||
break;
|
||||
case motStartRamp:
|
||||
if(ramp(M2,FW,mrampstart[M2-1],m2pwmch,tramp,RAMPRUN)==DONE){
|
||||
m2st=motWaitingTime;
|
||||
}
|
||||
break;
|
||||
case motWaitingTime:
|
||||
if(rtCiclo>=chM2stop){
|
||||
(void)ramp(M2,FW,m2pwmch,0,tramp,RAMPINIT);
|
||||
m2st=motStopRamp;
|
||||
}
|
||||
break;
|
||||
case motStopRamp:
|
||||
if(ramp(M2,FW,m2pwmch,0,tramp,RAMPRUN)==DONE){
|
||||
m2st=motStop;
|
||||
}
|
||||
break;
|
||||
case motStop:
|
||||
default:
|
||||
SetMotPerc(M2,FW,0);
|
||||
SetMotPerc(M2,BW,0);
|
||||
break;
|
||||
}
|
||||
return m2st;
|
||||
}
|
||||
|
||||
motMov_st m3ch(void){
|
||||
static motMov_st m3st;
|
||||
if(rtCiclo<chM3start)m3st=motWaiting;
|
||||
switch(m3st){
|
||||
case motWaiting:
|
||||
SetMotPerc(M3,FW,0);
|
||||
SetMotPerc(M3,BW,0);
|
||||
if(rtCiclo>=chM3start){
|
||||
(void)ramp(M3,FW,mrampstart[M3-1],m2pwmch,tramp,RAMPINIT);
|
||||
m3st=motStartRamp;
|
||||
}
|
||||
break;
|
||||
case motStartRamp:
|
||||
if(ramp(M3,FW,mrampstart[M3-1],m3pwmch,tramp,RAMPRUN)==DONE){
|
||||
m3st=motWaitingTime;
|
||||
}
|
||||
break;
|
||||
case motWaitingTime:
|
||||
if(rtCiclo>=chM3stop){
|
||||
(void)ramp(M3,FW,m3pwmch,0,tramp,RAMPINIT);
|
||||
m3st=motStopRamp;
|
||||
}
|
||||
break;
|
||||
case motStopRamp:
|
||||
if(ramp(M3,FW,m3pwmch,0,tramp,RAMPRUN)==DONE){
|
||||
m3st=motStop;
|
||||
}
|
||||
break;
|
||||
case motStop:
|
||||
default:
|
||||
SetMotPerc(M3,FW,0);
|
||||
SetMotPerc(M3,BW,0);
|
||||
break;
|
||||
}
|
||||
return m3st;
|
||||
}
|
||||
|
||||
motMov_st m4ch(void){
|
||||
static motMov_st m4st;
|
||||
if(rtCiclo<chM4start)m4st=motWaiting;
|
||||
switch(m4st){
|
||||
case motWaiting:
|
||||
SetMotPerc(M4,FW,0);
|
||||
SetMotPerc(M4,BW,0);
|
||||
if(rtCiclo>=chM4start){
|
||||
(void)ramp(M4,FW,mrampstart[M4-1],m2pwmch,tramp,RAMPINIT);
|
||||
m4st=motStartRamp;
|
||||
}
|
||||
break;
|
||||
case motStartRamp:
|
||||
if(ramp(M4,FW,mrampstart[M4-1],m4pwmch,tramp,RAMPRUN)==DONE){
|
||||
m4st=motWaitingTime;
|
||||
}
|
||||
break;
|
||||
case motWaitingTime:
|
||||
if(rtCiclo>=chM4stop){
|
||||
(void)ramp(M4,FW,m4pwmch,0,tramp,RAMPINIT);
|
||||
m4st=motStopRamp;
|
||||
}
|
||||
break;
|
||||
case motStopRamp:
|
||||
if(ramp(43,FW,m4pwmch,0,tramp,RAMPRUN)==DONE){
|
||||
m4st=motStop;
|
||||
}
|
||||
break;
|
||||
case motStop:
|
||||
default:
|
||||
SetMotPerc(M4,FW,0);
|
||||
SetMotPerc(M4,BW,0);
|
||||
break;
|
||||
}
|
||||
return m4st;
|
||||
}
|
||||
@@ -0,0 +1,978 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file : main.c
|
||||
* @brief : Main program body
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2025 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "main.h"
|
||||
#include "usb_device.h"
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
#include "usbd_cdc_if.h"
|
||||
#include "cdc_int.h"
|
||||
#include "eeprom.h"
|
||||
#include "pwm.h"
|
||||
#include "adc.h"
|
||||
#include "debug.h"
|
||||
#include "mot.h"
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PTD */
|
||||
|
||||
typedef enum{
|
||||
bzoff,
|
||||
bzmoving,
|
||||
bzwarning,
|
||||
}stBuz_st;
|
||||
|
||||
|
||||
/* USER CODE END PTD */
|
||||
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PD */
|
||||
|
||||
|
||||
/* USER CODE END PD */
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PM */
|
||||
|
||||
/* USER CODE END PM */
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
ADC_HandleTypeDef hadc1;
|
||||
DMA_HandleTypeDef hdma_adc1;
|
||||
|
||||
TIM_HandleTypeDef htim2;
|
||||
TIM_HandleTypeDef htim4;
|
||||
|
||||
UART_HandleTypeDef huart1;
|
||||
|
||||
/* USER CODE BEGIN PV */
|
||||
|
||||
extern volatile uint16_t adc_dma_buf[];
|
||||
extern uint16_t ch4 ;
|
||||
extern uint16_t ch5 ;
|
||||
extern uint16_t ch6 ;
|
||||
extern uint16_t ch7 ;
|
||||
extern uint16_t ch8 ;
|
||||
|
||||
uint8_t pulsanti=0;
|
||||
volatile uint8_t rtP1=200;
|
||||
volatile uint8_t rtP2=200;
|
||||
volatile uint8_t rtTLC=100;
|
||||
volatile uint16_t rtramp[4];
|
||||
volatile uint16_t rtCiclo;
|
||||
uint16_t m1pwmap;
|
||||
uint16_t m1pwmch;
|
||||
uint16_t m2pwmap;
|
||||
uint16_t m2pwmch;
|
||||
uint16_t m3pwmap;
|
||||
uint16_t m3pwmch;
|
||||
uint16_t m4pwmap;
|
||||
uint16_t m4pwmch;
|
||||
uint16_t t1ap;
|
||||
uint16_t t2ap;
|
||||
uint16_t t3ap;
|
||||
uint16_t t4ap;
|
||||
uint16_t twap;
|
||||
uint16_t t1ch;
|
||||
uint16_t t2ch;
|
||||
uint16_t t3ch;
|
||||
uint16_t t4ch;
|
||||
uint16_t twch;
|
||||
uint16_t tramp;
|
||||
uint16_t tramp1;
|
||||
uint16_t trampman;
|
||||
uint16_t m1pwmMan;
|
||||
uint16_t m2pwmMan;
|
||||
uint16_t m3pwmMan;
|
||||
uint16_t m4pwmMan;
|
||||
|
||||
uint16_t apM1start;
|
||||
uint16_t apM1stop;
|
||||
uint16_t apM2start;
|
||||
uint16_t apM2stop;
|
||||
uint16_t apM3start;
|
||||
uint16_t apM3stop;
|
||||
uint16_t apM4start;
|
||||
uint16_t apM4stop;
|
||||
uint16_t chM1start;
|
||||
uint16_t chM1stop;
|
||||
uint16_t chM2start;
|
||||
uint16_t chM2stop;
|
||||
uint16_t chM3start;
|
||||
uint16_t chM3stop;
|
||||
uint16_t chM4start;
|
||||
uint16_t chM4stop;
|
||||
|
||||
|
||||
uint16_t mrampstart[4];
|
||||
uint16_t stPulsanti=0;
|
||||
omCiclo_st stCiclo=omchiuso;
|
||||
omCiclo_st memstCiclo=omchiuso;
|
||||
volatile stBuz_st stBuz=bzoff;
|
||||
/* USER CODE END PV */
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
void SystemClock_Config(void);
|
||||
static void MX_GPIO_Init(void);
|
||||
static void MX_DMA_Init(void);
|
||||
static void MX_TIM2_Init(void);
|
||||
static void MX_TIM4_Init(void);
|
||||
static void MX_ADC1_Init(void);
|
||||
static void MX_USART1_UART_Init(void);
|
||||
/* USER CODE BEGIN PFP */
|
||||
|
||||
/* USER CODE END PFP */
|
||||
|
||||
/* Private user code ---------------------------------------------------------*/
|
||||
/* USER CODE BEGIN 0 */
|
||||
void HAL_SYSTICK_Callback(void){
|
||||
static unsigned char c10ms = 0;
|
||||
static uint8_t c100ms = 0;
|
||||
static uint8_t c1s = 0;
|
||||
static uint8_t inidx=0;
|
||||
static uint8_t inbuf[4];
|
||||
uint8_t i;
|
||||
|
||||
if (++c10ms >= 10) { // 10 ms
|
||||
c10ms = 0;
|
||||
if(rtP1)rtP1--;
|
||||
if(rtP2)rtP2--;
|
||||
if(rtTLC)rtTLC--;
|
||||
//**** legge i tasti********************************************************************************
|
||||
inidx++;
|
||||
inidx&=0x03;
|
||||
if(HAL_GPIO_ReadPin(P1_GPIO_Port, P1_Pin)==GPIO_PIN_RESET)inbuf[inidx]|=INP1;else inbuf[inidx]&=(~INP1);
|
||||
if(HAL_GPIO_ReadPin(P2_GPIO_Port, P2_Pin)==GPIO_PIN_RESET)inbuf[inidx]|=INP2;else inbuf[inidx]&=(~INP2);
|
||||
if(HAL_GPIO_ReadPin(CH1_GPIO_Port, CH1_Pin)==GPIO_PIN_RESET)inbuf[inidx]|=INCH1;else inbuf[inidx]&=(~INCH1);
|
||||
if(HAL_GPIO_ReadPin(CH2_GPIO_Port, CH2_Pin)==GPIO_PIN_RESET)inbuf[inidx]|=INCH2;else inbuf[inidx]&=(~INCH2);
|
||||
if(HAL_GPIO_ReadPin(CH3_GPIO_Port, CH3_Pin)==GPIO_PIN_RESET)inbuf[inidx]|=INCH3;else inbuf[inidx]&=(~INCH3);
|
||||
if(HAL_GPIO_ReadPin(CH4_GPIO_Port, CH4_Pin)==GPIO_PIN_RESET)inbuf[inidx]|=INCH4;else inbuf[inidx]&=(~INCH4);
|
||||
|
||||
pulsanti|=(inbuf[0]&inbuf[1]&inbuf[2]&inbuf[3]);
|
||||
pulsanti&=(inbuf[0]|inbuf[1]|inbuf[2]|inbuf[3]);
|
||||
//**** legge adc ***********************************************************************************
|
||||
readAdc();
|
||||
if (++c100ms >= 10) { // 10 ms
|
||||
c100ms = 0; //flag_10ms = 1; // set a flag; do real work in main loop
|
||||
for(i=0;i<4;i++){
|
||||
if(rtramp[i])rtramp[i]--;
|
||||
}
|
||||
if(rtCiclo<0xffff)rtCiclo++;
|
||||
|
||||
//**** gestione buzzer *****************************************************************************
|
||||
if(stBuz==bzmoving){
|
||||
if(c1s>=5)HAL_GPIO_WritePin(GPIOA, BUZ_Pin, GPIO_PIN_RESET);else HAL_GPIO_WritePin(GPIOA, BUZ_Pin, GPIO_PIN_SET);
|
||||
}else if(stBuz==bzwarning){
|
||||
if(c1s&2)HAL_GPIO_WritePin(GPIOA, BUZ_Pin, GPIO_PIN_RESET);else HAL_GPIO_WritePin(GPIOA, BUZ_Pin, GPIO_PIN_SET);
|
||||
}else{//bzoff
|
||||
HAL_GPIO_WritePin(GPIOA, BUZ_Pin, GPIO_PIN_RESET);
|
||||
}
|
||||
//**************************************************************************************************
|
||||
if (++c1s >= 10) { // 1 s
|
||||
c1s = 0;
|
||||
HAL_GPIO_TogglePin(LED2_GPIO_Port, LED2_Pin);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void managePulsanti(void){
|
||||
if(pulsanti&INP1){
|
||||
if(rtP1==0)stPulsanti|=P1START;
|
||||
}else{
|
||||
if(stPulsanti&P1START)stPulsanti&=(~P1START);
|
||||
else if(rtP1<=190){
|
||||
stPulsanti|=P1STOP;
|
||||
}
|
||||
rtP1=200;
|
||||
}
|
||||
if(pulsanti&INP2){
|
||||
if(rtP2==0)stPulsanti|=P2START;
|
||||
}else{
|
||||
if(stPulsanti&P2START)stPulsanti&=(~P2START);
|
||||
else if(rtP2<=190)stPulsanti|=P2STOP;
|
||||
rtP2=200;
|
||||
}
|
||||
stPulsanti&=(P1START|P1STOP|P2START|P2STOP);
|
||||
if(stPulsanti==0){
|
||||
switch(pulsanti&0x3c){
|
||||
case 0x00:
|
||||
rtTLC=100;
|
||||
stPulsanti&=(!(M1FW|M1BW|M3FW|M3BW|M4FW|M4BW));
|
||||
break;
|
||||
case 0x08://tlc1
|
||||
if(rtTLC==0)stPulsanti|=M1FW;
|
||||
break;
|
||||
case 0x10://tlc2
|
||||
if(rtTLC==0)stPulsanti|=M1BW;
|
||||
break;
|
||||
case 0x20://tlc3
|
||||
if(rtTLC==0)stPulsanti|=M3FW;
|
||||
break;
|
||||
case 0x04://tlc4
|
||||
if(rtTLC==0)stPulsanti|=M3BW;
|
||||
break;
|
||||
case 0x30://tlc5
|
||||
if(rtTLC==0)stPulsanti|=M4FW;
|
||||
break;
|
||||
case 0x0c://tlc6
|
||||
if(rtTLC==0)stPulsanti|=M4BW;
|
||||
break;
|
||||
default:
|
||||
rtTLC=100;
|
||||
stPulsanti&=(!(M1FW|M1BW|M3FW|M3BW|M4FW|M4BW));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void manageCiclo(void){
|
||||
|
||||
switch(stCiclo){
|
||||
case omchiuso:
|
||||
if(stPulsanti&P1START){
|
||||
stBuz=bzwarning;
|
||||
rtCiclo=0;
|
||||
stCiclo=omapertura0;
|
||||
(void)m1ap();(void)m2ap();(void)m3ap();(void)m4ap();
|
||||
}else if(stPulsanti&P1STOP)stCiclo=omstopapertura;
|
||||
// else if(stPulsanti&M1FW){
|
||||
// stBuz=bzmoving;
|
||||
// (void)ramp(M1,FW,mrampstart[M1-1],m1pwmMan,trampman,RAMPINIT);
|
||||
// stCiclo=omM1fw1;
|
||||
// }else if(stPulsanti&M1BW){
|
||||
// stBuz=bzmoving;
|
||||
// (void)ramp(M1,BW,mrampstart[M1-1],m1pwmMan,trampman,RAMPINIT);
|
||||
// stCiclo=omM1bw1;
|
||||
// }else if(stPulsanti&M2FW){
|
||||
// stBuz=bzmoving;
|
||||
// (void)ramp(M2,FW,mrampstart[M2-1],m2pwmMan,trampman,RAMPINIT);
|
||||
// stCiclo=omM2fw1;
|
||||
// }else if(stPulsanti&M2BW){
|
||||
// stBuz=bzmoving;
|
||||
// (void)ramp(M2,BW,mrampstart[M2-1],m2pwmMan,trampman,RAMPINIT);
|
||||
// stCiclo=omM2bw1;
|
||||
// }else if(stPulsanti&M3FW){
|
||||
// stBuz=bzmoving;
|
||||
// (void)ramp(M3,FW,mrampstart[M3-1],m3pwmMan,trampman,RAMPINIT);
|
||||
// stCiclo=omM3fw1;
|
||||
// }else if(stPulsanti&M3BW){
|
||||
// stBuz=bzmoving;
|
||||
// (void)ramp(M3,BW,mrampstart[M3-1],m3pwmMan,trampman,RAMPINIT);
|
||||
// stCiclo=omM3bw1;
|
||||
// }else if(stPulsanti&M4FW){
|
||||
// stBuz=bzmoving;
|
||||
// (void)ramp(M4,FW,mrampstart[M4-1],m3pwmMan,trampman,RAMPINIT);
|
||||
// stCiclo=omM4fw1;
|
||||
// }else if(stPulsanti&M4BW){
|
||||
// stBuz=bzmoving;
|
||||
// (void)ramp(M4,BW,mrampstart[M4-1],m3pwmMan,trampman,RAMPINIT);
|
||||
// stCiclo=omM4bw1;
|
||||
// }
|
||||
break;
|
||||
case omM1fw1:
|
||||
(void)ramp(M1,FW,mrampstart[M1-1],m1pwmMan,trampman,RAMPRUN);
|
||||
if(pulsanti==0)stCiclo=omM1fw2;
|
||||
break;
|
||||
case omM1fw2:
|
||||
(void)ramp(M1,FW,mrampstart[M1-1],m1pwmMan,trampman,RAMPRUN);
|
||||
if(pulsanti)stCiclo=omStopMan;
|
||||
break;
|
||||
case omM1bw1:
|
||||
(void)ramp(M1,BW,mrampstart[M1-1],m1pwmMan,trampman,RAMPRUN);
|
||||
if(pulsanti==0)stCiclo=omM1bw2;
|
||||
break;
|
||||
case omM1bw2:
|
||||
(void)ramp(M1,BW,mrampstart[M1-1],m1pwmMan,trampman,RAMPRUN);
|
||||
if(pulsanti)stCiclo=omStopMan;
|
||||
break;
|
||||
case omM2fw1:
|
||||
(void)ramp(M2,FW,mrampstart[M2-1],m2pwmMan,trampman,RAMPRUN);
|
||||
if(pulsanti==0)stCiclo=omM2fw2;
|
||||
break;
|
||||
case omM2fw2:
|
||||
(void)ramp(M2,FW,mrampstart[M2-1],m2pwmMan,trampman,RAMPRUN);
|
||||
if(pulsanti)stCiclo=omStopMan;
|
||||
break;
|
||||
case omM2bw1:
|
||||
(void)ramp(M2,BW,mrampstart[M2-1],m2pwmMan,trampman,RAMPRUN);
|
||||
if(pulsanti==0)stCiclo=omM2bw2;
|
||||
break;
|
||||
case omM2bw2:
|
||||
(void)ramp(M2,BW,mrampstart[M2-1],m2pwmMan,trampman,RAMPRUN);
|
||||
if(pulsanti)stCiclo=omStopMan;
|
||||
break;
|
||||
case omM3fw1:
|
||||
(void)ramp(M3,FW,mrampstart[M3-1],m3pwmMan,trampman,RAMPRUN);
|
||||
if(pulsanti==0)stCiclo=omM3fw2;
|
||||
break;
|
||||
case omM3fw2:
|
||||
(void)ramp(M3,FW,mrampstart[M3-1],m3pwmMan,trampman,RAMPRUN);
|
||||
if(pulsanti)stCiclo=omStopMan;
|
||||
break;
|
||||
case omM3bw1:
|
||||
(void)ramp(M3,BW,mrampstart[M3-1],m3pwmMan,trampman,RAMPRUN);
|
||||
if(pulsanti==0)stCiclo=omM3bw2;
|
||||
break;
|
||||
case omM3bw2:
|
||||
(void)ramp(M3,BW,mrampstart[M3-1],m3pwmMan,trampman,RAMPRUN);
|
||||
if(pulsanti)stCiclo=omStopMan;
|
||||
break;
|
||||
case omM4fw1:
|
||||
(void)ramp(M4,FW,mrampstart[M4-1],m4pwmMan,trampman,RAMPRUN);
|
||||
if(pulsanti==0)stCiclo=omM4fw2;
|
||||
break;
|
||||
case omM4fw2:
|
||||
(void)ramp(M4,FW,mrampstart[M4-1],m4pwmMan,trampman,RAMPRUN);
|
||||
if(pulsanti)stCiclo=omStopMan;
|
||||
break;
|
||||
case omM4bw1:
|
||||
(void)ramp(M4,BW,mrampstart[M4-1],m4pwmMan,trampman,RAMPRUN);
|
||||
if(pulsanti==0)stCiclo=omM4bw2;
|
||||
break;
|
||||
case omM4bw2:
|
||||
(void)ramp(M4,BW,mrampstart[M4-1],m4pwmMan,trampman,RAMPRUN);
|
||||
if(pulsanti)stCiclo=omStopMan;
|
||||
break;
|
||||
case omStopMan:
|
||||
SetMotPerc(M1,FW,0);
|
||||
SetMotPerc(M2,FW,0);
|
||||
SetMotPerc(M3,FW,0);
|
||||
SetMotPerc(M4,FW,0);
|
||||
SetMotPerc(M1,BW,0);
|
||||
SetMotPerc(M2,BW,0);
|
||||
SetMotPerc(M3,BW,0);
|
||||
SetMotPerc(M4,BW,0);
|
||||
if(pulsanti==0){
|
||||
stBuz=bzoff;
|
||||
stCiclo=omaperto;
|
||||
}
|
||||
break;
|
||||
case omapertura0:
|
||||
if(rtCiclo>=30){//doppo 3 secondi
|
||||
stBuz=bzmoving;
|
||||
if((m1ap()==motStop)&&(m2ap()==motStop)&&(m3ap()==motStop)&&(m4ap()==motStop)){
|
||||
stBuz=bzoff;
|
||||
stCiclo=omaperto;
|
||||
}
|
||||
}
|
||||
if(stPulsanti&P1STOP)stCiclo=omstopapertura;
|
||||
break;
|
||||
case omstopapertura:
|
||||
SetMotPerc(M1,FW,0);
|
||||
SetMotPerc(M2,FW,0);
|
||||
SetMotPerc(M3,FW,0);
|
||||
SetMotPerc(M4,FW,0);
|
||||
if(pulsanti==0){
|
||||
stBuz=bzoff;
|
||||
stCiclo=omchiuso;
|
||||
stPulsanti&=(~P1STOP);
|
||||
}
|
||||
break;
|
||||
case omaperto:
|
||||
if(stPulsanti&P1START){
|
||||
stBuz=bzmoving;
|
||||
(void)ramp(M1,BW,mrampstart[M1-1],m1pwmch,tramp,RAMPINIT);
|
||||
stCiclo=omchiusura1;
|
||||
rtCiclo=0;
|
||||
(void)m1ch();(void)m2ch();(void)m3ch();(void)m4ch();
|
||||
}
|
||||
if(stPulsanti&P1STOP)stCiclo=omstopchiusura;
|
||||
else if(stPulsanti&M1FW){
|
||||
stBuz=bzmoving;
|
||||
(void)ramp(M1,FW,mrampstart[M1-1],m1pwmMan,trampman,RAMPINIT);
|
||||
stCiclo=omM1fw1;
|
||||
}else if(stPulsanti&M1BW){
|
||||
stBuz=bzmoving;
|
||||
(void)ramp(M1,BW,mrampstart[M1-1],m1pwmMan,trampman,RAMPINIT);
|
||||
stCiclo=omM1bw1;
|
||||
}else if(stPulsanti&M2FW){
|
||||
stBuz=bzmoving;
|
||||
(void)ramp(M2,FW,mrampstart[M2-1],m2pwmMan,trampman,RAMPINIT);
|
||||
stCiclo=omM2fw1;
|
||||
}else if(stPulsanti&M2BW){
|
||||
stBuz=bzmoving;
|
||||
(void)ramp(M2,BW,mrampstart[M2-1],m2pwmMan,trampman,RAMPINIT);
|
||||
stCiclo=omM2bw1;
|
||||
}else if(stPulsanti&M3FW){
|
||||
stBuz=bzmoving;
|
||||
(void)ramp(M3,FW,mrampstart[M3-1],m3pwmMan,trampman,RAMPINIT);
|
||||
stCiclo=omM3fw1;
|
||||
}else if(stPulsanti&M3BW){
|
||||
stBuz=bzmoving;
|
||||
(void)ramp(M3,BW,mrampstart[M3-1],m3pwmMan,trampman,RAMPINIT);
|
||||
stCiclo=omM3bw1;
|
||||
}else if(stPulsanti&M4FW){
|
||||
stBuz=bzmoving;
|
||||
(void)ramp(M4,FW,mrampstart[M4-1],m3pwmMan,trampman,RAMPINIT);
|
||||
stCiclo=omM4fw1;
|
||||
}else if(stPulsanti&M4BW){
|
||||
stBuz=bzmoving;
|
||||
(void)ramp(M4,BW,mrampstart[M4-1],m3pwmMan,trampman,RAMPINIT);
|
||||
stCiclo=omM4bw1;
|
||||
}
|
||||
break;
|
||||
case omchiusura1:
|
||||
if(rtCiclo>=10){//doppo 1 secondi
|
||||
if((m1ch()==motStop)&&(m2ch()==motStop)&&(m3ch()==motStop)&&(m4ch()==motStop)){
|
||||
stBuz=bzoff;
|
||||
stCiclo=omchiuso;
|
||||
}
|
||||
}
|
||||
if(stPulsanti&P1STOP)stCiclo=omstopchiusura;
|
||||
break;
|
||||
|
||||
case omstopchiusura:
|
||||
SetMotPerc(M1,FW,0);
|
||||
SetMotPerc(M2,FW,0);
|
||||
SetMotPerc(M3,FW,0);
|
||||
SetMotPerc(M4,FW,0);
|
||||
if(pulsanti==0){
|
||||
stBuz=bzoff;
|
||||
stCiclo=omaperto;
|
||||
stPulsanti&=(~P1STOP);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* USER CODE END 0 */
|
||||
|
||||
/**
|
||||
* @brief The application entry point.
|
||||
* @retval int
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
/* USER CODE END 1 */
|
||||
|
||||
/* MCU Configuration--------------------------------------------------------*/
|
||||
|
||||
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
|
||||
HAL_Init();
|
||||
|
||||
/* USER CODE BEGIN Init */
|
||||
|
||||
/* USER CODE END Init */
|
||||
|
||||
/* Configure the system clock */
|
||||
SystemClock_Config();
|
||||
|
||||
/* USER CODE BEGIN SysInit */
|
||||
|
||||
/* USER CODE END SysInit */
|
||||
|
||||
/* Initialize all configured peripherals */
|
||||
MX_GPIO_Init();
|
||||
MX_DMA_Init();
|
||||
MX_USB_DEVICE_Init();
|
||||
MX_TIM2_Init();
|
||||
MX_TIM4_Init();
|
||||
MX_ADC1_Init();
|
||||
MX_USART1_UART_Init();
|
||||
/* USER CODE BEGIN 2 */
|
||||
HAL_ADC_Start_DMA(&hadc1, (uint32_t *)adc_dma_buf, ADC_NUM_CHANNELS);
|
||||
StopMot(timMot1,FWMot1);
|
||||
StopMot(timMot1,BWMot1);
|
||||
StopMot(timMot2,FWMot2);
|
||||
StopMot(timMot2,BWMot2);
|
||||
StopMot(timMot3,FWMot3);
|
||||
StopMot(timMot3,BWMot3);
|
||||
StopMot(timMot4,FWMot4);
|
||||
StopMot(timMot4,BWMot4);
|
||||
//CDC_Transmit_FS((uint8_t*)"Start\r\n", 7);
|
||||
//while (CDC_Transmit_FS((uint8_t*)"Start\r\n", 7) == USBD_BUSY);
|
||||
if (EE_Init() != EE_OK){
|
||||
for(;;);//errore eeprom
|
||||
}
|
||||
loadEE();
|
||||
/* USER CODE END 2 */
|
||||
|
||||
/* Infinite loop */
|
||||
/* USER CODE BEGIN WHILE */
|
||||
while (1){
|
||||
manageCDC();
|
||||
manageAdc();
|
||||
managePulsanti();
|
||||
manageCiclo();
|
||||
debug();
|
||||
// while (CDC_Available()) {
|
||||
// int c = CDC_ReadByte();
|
||||
//if (c < 0) break;
|
||||
|
||||
// uint8_t out = (uint8_t)c;
|
||||
// if (out >= 'a' && out <= 'z') out -= 32; // to upper
|
||||
|
||||
// unsigned char s[100];
|
||||
// sprintf((char*)s,"\nc=%03d",c);
|
||||
// while (CDC_Transmit_FS(s, 6) == USBD_BUSY) {
|
||||
// // tiny spin or yield
|
||||
// }
|
||||
// }
|
||||
|
||||
//HAL_Delay(1000);
|
||||
// CDC_Transmit_FS((uint8_t*)"Ping\r\n", 6);
|
||||
/* USER CODE END WHILE */
|
||||
|
||||
/* USER CODE BEGIN 3 */
|
||||
}
|
||||
/* USER CODE END 3 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief System Clock Configuration
|
||||
* @retval None
|
||||
*/
|
||||
void SystemClock_Config(void)
|
||||
{
|
||||
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
|
||||
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
|
||||
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
|
||||
|
||||
/** Initializes the RCC Oscillators according to the specified parameters
|
||||
* in the RCC_OscInitTypeDef structure.
|
||||
*/
|
||||
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
|
||||
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
|
||||
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
|
||||
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
|
||||
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
|
||||
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
|
||||
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL6;
|
||||
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/** Initializes the CPU, AHB and APB buses clocks
|
||||
*/
|
||||
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|
||||
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
|
||||
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
|
||||
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
|
||||
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
|
||||
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
|
||||
|
||||
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC|RCC_PERIPHCLK_USB;
|
||||
PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6;
|
||||
PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLL_DIV1_5;
|
||||
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ADC1 Initialization Function
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
static void MX_ADC1_Init(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN ADC1_Init 0 */
|
||||
|
||||
/* USER CODE END ADC1_Init 0 */
|
||||
|
||||
ADC_ChannelConfTypeDef sConfig = {0};
|
||||
|
||||
/* USER CODE BEGIN ADC1_Init 1 */
|
||||
|
||||
/* USER CODE END ADC1_Init 1 */
|
||||
|
||||
/** Common config
|
||||
*/
|
||||
hadc1.Instance = ADC1;
|
||||
hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
|
||||
hadc1.Init.ContinuousConvMode = ENABLE;
|
||||
hadc1.Init.DiscontinuousConvMode = DISABLE;
|
||||
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
|
||||
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
|
||||
hadc1.Init.NbrOfConversion = 5;
|
||||
if (HAL_ADC_Init(&hadc1) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/** Configure Regular Channel
|
||||
*/
|
||||
sConfig.Channel = ADC_CHANNEL_4;
|
||||
sConfig.Rank = ADC_REGULAR_RANK_1;
|
||||
sConfig.SamplingTime = ADC_SAMPLETIME_28CYCLES_5;
|
||||
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/** Configure Regular Channel
|
||||
*/
|
||||
sConfig.Channel = ADC_CHANNEL_5;
|
||||
sConfig.Rank = ADC_REGULAR_RANK_2;
|
||||
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/** Configure Regular Channel
|
||||
*/
|
||||
sConfig.Channel = ADC_CHANNEL_6;
|
||||
sConfig.Rank = ADC_REGULAR_RANK_3;
|
||||
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/** Configure Regular Channel
|
||||
*/
|
||||
sConfig.Channel = ADC_CHANNEL_7;
|
||||
sConfig.Rank = ADC_REGULAR_RANK_4;
|
||||
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/** Configure Regular Channel
|
||||
*/
|
||||
sConfig.Channel = ADC_CHANNEL_8;
|
||||
sConfig.Rank = ADC_REGULAR_RANK_5;
|
||||
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
/* USER CODE BEGIN ADC1_Init 2 */
|
||||
|
||||
/* USER CODE END ADC1_Init 2 */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief TIM2 Initialization Function
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
static void MX_TIM2_Init(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN TIM2_Init 0 */
|
||||
|
||||
/* USER CODE END TIM2_Init 0 */
|
||||
|
||||
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
|
||||
TIM_MasterConfigTypeDef sMasterConfig = {0};
|
||||
TIM_OC_InitTypeDef sConfigOC = {0};
|
||||
|
||||
/* USER CODE BEGIN TIM2_Init 1 */
|
||||
|
||||
/* USER CODE END TIM2_Init 1 */
|
||||
htim2.Instance = TIM2;
|
||||
htim2.Init.Prescaler = 0;
|
||||
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
|
||||
htim2.Init.Period = 17999;
|
||||
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
|
||||
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
|
||||
if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
|
||||
if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
if (HAL_TIM_PWM_Init(&htim2) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
|
||||
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
|
||||
if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
sConfigOC.OCMode = TIM_OCMODE_PWM1;
|
||||
sConfigOC.Pulse = 1000;
|
||||
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
|
||||
sConfigOC.OCFastMode = TIM_OCFAST_ENABLE;
|
||||
if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
sConfigOC.Pulse = 2000;
|
||||
if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
sConfigOC.Pulse = 3000;
|
||||
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
|
||||
if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
sConfigOC.Pulse = 4000;
|
||||
sConfigOC.OCFastMode = TIM_OCFAST_ENABLE;
|
||||
if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
/* USER CODE BEGIN TIM2_Init 2 */
|
||||
|
||||
/* USER CODE END TIM2_Init 2 */
|
||||
HAL_TIM_MspPostInit(&htim2);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief TIM4 Initialization Function
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
static void MX_TIM4_Init(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN TIM4_Init 0 */
|
||||
|
||||
/* USER CODE END TIM4_Init 0 */
|
||||
|
||||
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
|
||||
TIM_MasterConfigTypeDef sMasterConfig = {0};
|
||||
TIM_OC_InitTypeDef sConfigOC = {0};
|
||||
|
||||
/* USER CODE BEGIN TIM4_Init 1 */
|
||||
|
||||
/* USER CODE END TIM4_Init 1 */
|
||||
htim4.Instance = TIM4;
|
||||
htim4.Init.Prescaler = 0;
|
||||
htim4.Init.CounterMode = TIM_COUNTERMODE_UP;
|
||||
htim4.Init.Period = 17999;
|
||||
htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
|
||||
htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
|
||||
if (HAL_TIM_Base_Init(&htim4) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
|
||||
if (HAL_TIM_ConfigClockSource(&htim4, &sClockSourceConfig) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
if (HAL_TIM_PWM_Init(&htim4) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
|
||||
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
|
||||
if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
sConfigOC.OCMode = TIM_OCMODE_PWM1;
|
||||
sConfigOC.Pulse = 5000;
|
||||
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
|
||||
sConfigOC.OCFastMode = TIM_OCFAST_ENABLE;
|
||||
if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
sConfigOC.Pulse = 6000;
|
||||
if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
sConfigOC.Pulse = 7000;
|
||||
if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
sConfigOC.Pulse = 8000;
|
||||
if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
/* USER CODE BEGIN TIM4_Init 2 */
|
||||
|
||||
/* USER CODE END TIM4_Init 2 */
|
||||
HAL_TIM_MspPostInit(&htim4);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USART1 Initialization Function
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
static void MX_USART1_UART_Init(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN USART1_Init 0 */
|
||||
|
||||
/* USER CODE END USART1_Init 0 */
|
||||
|
||||
/* USER CODE BEGIN USART1_Init 1 */
|
||||
|
||||
/* USER CODE END USART1_Init 1 */
|
||||
huart1.Instance = USART1;
|
||||
huart1.Init.BaudRate = 115200;
|
||||
huart1.Init.WordLength = UART_WORDLENGTH_8B;
|
||||
huart1.Init.StopBits = UART_STOPBITS_1;
|
||||
huart1.Init.Parity = UART_PARITY_NONE;
|
||||
huart1.Init.Mode = UART_MODE_TX_RX;
|
||||
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
|
||||
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
|
||||
if (HAL_UART_Init(&huart1) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
/* USER CODE BEGIN USART1_Init 2 */
|
||||
|
||||
/* USER CODE END USART1_Init 2 */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable DMA controller clock
|
||||
*/
|
||||
static void MX_DMA_Init(void)
|
||||
{
|
||||
|
||||
/* DMA controller clock enable */
|
||||
__HAL_RCC_DMA1_CLK_ENABLE();
|
||||
|
||||
/* DMA interrupt init */
|
||||
/* DMA1_Channel1_IRQn interrupt configuration */
|
||||
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);
|
||||
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief GPIO Initialization Function
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
static void MX_GPIO_Init(void)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
/* USER CODE BEGIN MX_GPIO_Init_1 */
|
||||
|
||||
/* USER CODE END MX_GPIO_Init_1 */
|
||||
|
||||
/* GPIO Ports Clock Enable */
|
||||
__HAL_RCC_GPIOC_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOD_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
|
||||
/*Configure GPIO pin Output Level */
|
||||
HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_RESET);
|
||||
|
||||
/*Configure GPIO pin Output Level */
|
||||
HAL_GPIO_WritePin(GPIOB, INH1_Pin|INH2_Pin|INH3_Pin|INH4_Pin
|
||||
|EXP1_Pin|EXP2_Pin|EXP3_Pin, GPIO_PIN_RESET);
|
||||
|
||||
/*Configure GPIO pin Output Level */
|
||||
HAL_GPIO_WritePin(GPIOA, BUZ_Pin|LED1_Pin, GPIO_PIN_RESET);
|
||||
|
||||
/*Configure GPIO pin : LED2_Pin */
|
||||
GPIO_InitStruct.Pin = LED2_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
HAL_GPIO_Init(LED2_GPIO_Port, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pins : P1_Pin P2_Pin */
|
||||
GPIO_InitStruct.Pin = P1_Pin|P2_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pin : AIN1_Pin */
|
||||
GPIO_InitStruct.Pin = AIN1_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
|
||||
HAL_GPIO_Init(AIN1_GPIO_Port, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pins : INH1_Pin INH2_Pin INH3_Pin INH4_Pin
|
||||
EXP1_Pin EXP2_Pin EXP3_Pin */
|
||||
GPIO_InitStruct.Pin = INH1_Pin|INH2_Pin|INH3_Pin|INH4_Pin
|
||||
|EXP1_Pin|EXP2_Pin|EXP3_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pins : CH1_Pin CH2_Pin CH3_Pin CH4_Pin */
|
||||
GPIO_InitStruct.Pin = CH1_Pin|CH2_Pin|CH3_Pin|CH4_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pins : BUZ_Pin LED1_Pin */
|
||||
GPIO_InitStruct.Pin = BUZ_Pin|LED1_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
/* USER CODE BEGIN MX_GPIO_Init_2 */
|
||||
|
||||
/* USER CODE END MX_GPIO_Init_2 */
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 4 */
|
||||
|
||||
/* USER CODE END 4 */
|
||||
|
||||
/**
|
||||
* @brief This function is executed in case of error occurrence.
|
||||
* @retval None
|
||||
*/
|
||||
void Error_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN Error_Handler_Debug */
|
||||
/* User can add his own implementation to report the HAL error return state */
|
||||
__disable_irq();
|
||||
while (1)
|
||||
{
|
||||
}
|
||||
/* USER CODE END Error_Handler_Debug */
|
||||
}
|
||||
#ifdef USE_FULL_ASSERT
|
||||
/**
|
||||
* @brief Reports the name of the source file and the source line number
|
||||
* where the assert_param error has occurred.
|
||||
* @param file: pointer to the source file name
|
||||
* @param line: assert_param error line source number
|
||||
* @retval None
|
||||
*/
|
||||
void assert_failed(uint8_t *file, uint32_t line)
|
||||
{
|
||||
/* USER CODE BEGIN 6 */
|
||||
/* User can add his own implementation to report the file name and line number,
|
||||
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
|
||||
/* USER CODE END 6 */
|
||||
}
|
||||
#endif /* USE_FULL_ASSERT */
|
||||
@@ -0,0 +1,331 @@
|
||||
/*
|
||||
* mot.c
|
||||
*
|
||||
* Created on: May 2, 2026
|
||||
* Author: user
|
||||
*/
|
||||
#include "mot.h"
|
||||
#include "pwm.h"
|
||||
|
||||
extern uint16_t apM1start;
|
||||
extern uint16_t apM1stop;
|
||||
extern uint16_t apM2start;
|
||||
extern uint16_t apM2stop;
|
||||
extern uint16_t apM3start;
|
||||
extern uint16_t apM3stop;
|
||||
extern uint16_t apM4start;
|
||||
extern uint16_t apM4stop;
|
||||
extern uint16_t chM1start;
|
||||
extern uint16_t chM1stop;
|
||||
extern uint16_t chM2start;
|
||||
extern uint16_t chM2stop;
|
||||
extern uint16_t chM3start;
|
||||
extern uint16_t chM3stop;
|
||||
extern uint16_t chM4start;
|
||||
extern uint16_t chM4stop;
|
||||
extern volatile uint16_t rtCiclo;
|
||||
extern uint16_t m1pwmap;
|
||||
extern uint16_t m1pwmch;
|
||||
extern uint16_t m2pwmap;
|
||||
extern uint16_t m2pwmch;
|
||||
extern uint16_t m3pwmap;
|
||||
extern uint16_t m3pwmch;
|
||||
extern uint16_t m4pwmap;
|
||||
extern uint16_t m4pwmch;
|
||||
extern uint16_t mrampstart[4];
|
||||
|
||||
motMov_st m1ap(void){
|
||||
static motMov_st m1st;
|
||||
if(rtCiclo<apM1start)m1st=motWaiting;
|
||||
switch(m1st){
|
||||
case motWaiting:
|
||||
SetMotPerc(M1,FW,0);
|
||||
SetMotPerc(M1,BW,0);
|
||||
if(rtCiclo>=apM1start){
|
||||
(void)ramp(M1,BW,mrampstart[M1-1],m1pwmap,tramp,RAMPINIT);
|
||||
m1st=motStartRamp;
|
||||
}
|
||||
break;
|
||||
case motStartRamp:
|
||||
if(ramp(M1,BW,mrampstart[M1-1],m1pwmap,tramp,RAMPRUN)==DONE){
|
||||
m1st=motWaitingTime;
|
||||
}
|
||||
break;
|
||||
case motWaitingTime:
|
||||
if(rtCiclo>=apM1stop){
|
||||
(void)ramp(M1,BW,m1pwmap,0,tramp,RAMPINIT);
|
||||
m1st=motStopRamp;
|
||||
}
|
||||
break;
|
||||
case motStopRamp:
|
||||
if(ramp(M1,BW,m1pwmap,0,tramp,RAMPRUN)==DONE){
|
||||
m1st=motStop;
|
||||
}
|
||||
break;
|
||||
case motStop:
|
||||
default:
|
||||
SetMotPerc(M1,FW,0);
|
||||
SetMotPerc(M1,BW,0);
|
||||
break;
|
||||
}
|
||||
return m1st;
|
||||
}
|
||||
|
||||
motMov_st m2ap(void){
|
||||
static motMov_st m2st;
|
||||
if(rtCiclo<apM2start)m2st=motWaiting;
|
||||
switch(m2st){
|
||||
case motWaiting:
|
||||
SetMotPerc(M2,FW,0);
|
||||
SetMotPerc(M2,BW,0);
|
||||
if(rtCiclo>=apM2start){
|
||||
(void)ramp(M2,BW,mrampstart[M2-1],m2pwmap,tramp,RAMPINIT);
|
||||
m2st=motStartRamp;
|
||||
}
|
||||
break;
|
||||
case motStartRamp:
|
||||
if(ramp(M2,BW,mrampstart[M2-1],m2pwmap,tramp,RAMPRUN)==DONE){
|
||||
m2st=motWaitingTime;
|
||||
}
|
||||
break;
|
||||
case motWaitingTime:
|
||||
if(rtCiclo>=apM2stop){
|
||||
(void)ramp(M2,BW,m2pwmap,0,tramp,RAMPINIT);
|
||||
m2st=motStopRamp;
|
||||
}
|
||||
break;
|
||||
case motStopRamp:
|
||||
if(ramp(M2,BW,m2pwmap,0,tramp,RAMPRUN)==DONE){
|
||||
m2st=motStop;
|
||||
}
|
||||
break;
|
||||
case motStop:
|
||||
default:
|
||||
SetMotPerc(M2,FW,0);
|
||||
SetMotPerc(M2,BW,0);
|
||||
break;
|
||||
}
|
||||
return m2st;
|
||||
}
|
||||
|
||||
motMov_st m3ap(void){
|
||||
static motMov_st m3st;
|
||||
if(rtCiclo<apM3start)m3st=motWaiting;
|
||||
switch(m3st){
|
||||
case motWaiting:
|
||||
SetMotPerc(M3,FW,0);
|
||||
SetMotPerc(M3,BW,0);
|
||||
if(rtCiclo>=apM3start){
|
||||
(void)ramp(M3,BW,mrampstart[M3-1],m2pwmap,tramp,RAMPINIT);
|
||||
m3st=motStartRamp;
|
||||
}
|
||||
break;
|
||||
case motStartRamp:
|
||||
if(ramp(M3,BW,mrampstart[M3-1],m3pwmap,tramp,RAMPRUN)==DONE){
|
||||
m3st=motWaitingTime;
|
||||
}
|
||||
break;
|
||||
case motWaitingTime:
|
||||
if(rtCiclo>=apM3stop){
|
||||
(void)ramp(M3,BW,m3pwmap,0,tramp,RAMPINIT);
|
||||
m3st=motStopRamp;
|
||||
}
|
||||
break;
|
||||
case motStopRamp:
|
||||
if(ramp(M3,BW,m3pwmap,0,tramp,RAMPRUN)==DONE){
|
||||
m3st=motStop;
|
||||
}
|
||||
break;
|
||||
case motStop:
|
||||
default:
|
||||
SetMotPerc(M3,FW,0);
|
||||
SetMotPerc(M3,BW,0);
|
||||
break;
|
||||
}
|
||||
return m3st;
|
||||
}
|
||||
|
||||
motMov_st m4ap(void){
|
||||
static motMov_st m4st;
|
||||
if(rtCiclo<apM4start)m4st=motWaiting;
|
||||
switch(m4st){
|
||||
case motWaiting:
|
||||
SetMotPerc(M4,FW,0);
|
||||
SetMotPerc(M4,BW,0);
|
||||
if(rtCiclo>=apM4start){
|
||||
(void)ramp(M4,BW,mrampstart[M4-1],m2pwmap,tramp,RAMPINIT);
|
||||
m4st=motStartRamp;
|
||||
}
|
||||
break;
|
||||
case motStartRamp:
|
||||
if(ramp(M4,BW,mrampstart[M4-1],m4pwmap,tramp,RAMPRUN)==DONE){
|
||||
m4st=motWaitingTime;
|
||||
}
|
||||
break;
|
||||
case motWaitingTime:
|
||||
if(rtCiclo>=apM4stop){
|
||||
(void)ramp(M4,BW,m4pwmap,0,tramp,RAMPINIT);
|
||||
m4st=motStopRamp;
|
||||
}
|
||||
break;
|
||||
case motStopRamp:
|
||||
if(ramp(43,BW,m4pwmap,0,tramp,RAMPRUN)==DONE){
|
||||
m4st=motStop;
|
||||
}
|
||||
break;
|
||||
case motStop:
|
||||
default:
|
||||
SetMotPerc(M4,FW,0);
|
||||
SetMotPerc(M4,BW,0);
|
||||
break;
|
||||
}
|
||||
return m4st;
|
||||
}
|
||||
|
||||
motMov_st m1ch(void){
|
||||
static motMov_st m1st;
|
||||
if(rtCiclo<chM1start)m1st=motWaiting;
|
||||
switch(m1st){
|
||||
case motWaiting:
|
||||
SetMotPerc(M1,FW,0);
|
||||
SetMotPerc(M1,BW,0);
|
||||
if(rtCiclo>=chM1start){
|
||||
(void)ramp(M1,FW,mrampstart[M1-1],m1pwmch,tramp,RAMPINIT);
|
||||
m1st=motStartRamp;
|
||||
}
|
||||
break;
|
||||
case motStartRamp:
|
||||
if(ramp(M1,FW,mrampstart[M1-1],m1pwmch,tramp,RAMPRUN)==DONE){
|
||||
m1st=motWaitingTime;
|
||||
}
|
||||
break;
|
||||
case motWaitingTime:
|
||||
if(rtCiclo>=chM1stop){
|
||||
(void)ramp(M1,FW,m1pwmch,0,tramp,RAMPINIT);
|
||||
m1st=motStopRamp;
|
||||
}
|
||||
break;
|
||||
case motStopRamp:
|
||||
if(ramp(M1,FW,m1pwmch,0,tramp,RAMPRUN)==DONE){
|
||||
m1st=motStop;
|
||||
}
|
||||
break;
|
||||
case motStop:
|
||||
default:
|
||||
SetMotPerc(M1,FW,0);
|
||||
SetMotPerc(M1,BW,0);
|
||||
break;
|
||||
}
|
||||
return m1st;
|
||||
}
|
||||
|
||||
motMov_st m2ch(void){
|
||||
static motMov_st m2st;
|
||||
if(rtCiclo<chM2start)m2st=motWaiting;
|
||||
switch(m2st){
|
||||
case motWaiting:
|
||||
SetMotPerc(M2,FW,0);
|
||||
SetMotPerc(M2,BW,0);
|
||||
if(rtCiclo>=chM2start){
|
||||
(void)ramp(M2,FW,mrampstart[M2-1],m2pwmch,tramp,RAMPINIT);
|
||||
m2st=motStartRamp;
|
||||
}
|
||||
break;
|
||||
case motStartRamp:
|
||||
if(ramp(M2,FW,mrampstart[M2-1],m2pwmch,tramp,RAMPRUN)==DONE){
|
||||
m2st=motWaitingTime;
|
||||
}
|
||||
break;
|
||||
case motWaitingTime:
|
||||
if(rtCiclo>=chM2stop){
|
||||
(void)ramp(M2,FW,m2pwmch,0,tramp,RAMPINIT);
|
||||
m2st=motStopRamp;
|
||||
}
|
||||
break;
|
||||
case motStopRamp:
|
||||
if(ramp(M2,FW,m2pwmch,0,tramp,RAMPRUN)==DONE){
|
||||
m2st=motStop;
|
||||
}
|
||||
break;
|
||||
case motStop:
|
||||
default:
|
||||
SetMotPerc(M2,FW,0);
|
||||
SetMotPerc(M2,BW,0);
|
||||
break;
|
||||
}
|
||||
return m2st;
|
||||
}
|
||||
|
||||
motMov_st m3ch(void){
|
||||
static motMov_st m3st;
|
||||
if(rtCiclo<chM3start)m3st=motWaiting;
|
||||
switch(m3st){
|
||||
case motWaiting:
|
||||
SetMotPerc(M3,FW,0);
|
||||
SetMotPerc(M3,BW,0);
|
||||
if(rtCiclo>=chM3start){
|
||||
(void)ramp(M3,FW,mrampstart[M3-1],m2pwmch,tramp,RAMPINIT);
|
||||
m3st=motStartRamp;
|
||||
}
|
||||
break;
|
||||
case motStartRamp:
|
||||
if(ramp(M3,FW,mrampstart[M3-1],m3pwmch,tramp,RAMPRUN)==DONE){
|
||||
m3st=motWaitingTime;
|
||||
}
|
||||
break;
|
||||
case motWaitingTime:
|
||||
if(rtCiclo>=chM3stop){
|
||||
(void)ramp(M3,FW,m3pwmch,0,tramp,RAMPINIT);
|
||||
m3st=motStopRamp;
|
||||
}
|
||||
break;
|
||||
case motStopRamp:
|
||||
if(ramp(M3,FW,m3pwmch,0,tramp,RAMPRUN)==DONE){
|
||||
m3st=motStop;
|
||||
}
|
||||
break;
|
||||
case motStop:
|
||||
default:
|
||||
SetMotPerc(M3,FW,0);
|
||||
SetMotPerc(M3,BW,0);
|
||||
break;
|
||||
}
|
||||
return m3st;
|
||||
}
|
||||
|
||||
motMov_st m4ch(void){
|
||||
static motMov_st m4st;
|
||||
if(rtCiclo<chM4start)m4st=motWaiting;
|
||||
switch(m4st){
|
||||
case motWaiting:
|
||||
SetMotPerc(M4,FW,0);
|
||||
SetMotPerc(M4,BW,0);
|
||||
if(rtCiclo>=chM4start){
|
||||
(void)ramp(M4,FW,mrampstart[M4-1],m2pwmch,tramp,RAMPINIT);
|
||||
m4st=motStartRamp;
|
||||
}
|
||||
break;
|
||||
case motStartRamp:
|
||||
if(ramp(M4,FW,mrampstart[M4-1],m4pwmch,tramp,RAMPRUN)==DONE){
|
||||
m4st=motWaitingTime;
|
||||
}
|
||||
break;
|
||||
case motWaitingTime:
|
||||
if(rtCiclo>=chM4stop){
|
||||
(void)ramp(M4,FW,m4pwmch,0,tramp,RAMPINIT);
|
||||
m4st=motStopRamp;
|
||||
}
|
||||
break;
|
||||
case motStopRamp:
|
||||
if(ramp(43,FW,m4pwmch,0,tramp,RAMPRUN)==DONE){
|
||||
m4st=motStop;
|
||||
}
|
||||
break;
|
||||
case motStop:
|
||||
default:
|
||||
SetMotPerc(M4,FW,0);
|
||||
SetMotPerc(M4,BW,0);
|
||||
break;
|
||||
}
|
||||
return m4st;
|
||||
}
|
||||
@@ -0,0 +1,482 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "eeprom.h"
|
||||
extern UART_HandleTypeDef huart1;
|
||||
/*
|
||||
* Record format (4 bytes):
|
||||
* [0] VirtAddress (uint16_t)
|
||||
* [2] Data (uint16_t)
|
||||
*
|
||||
* Page layout:
|
||||
* [0] PageStatus (uint16_t)
|
||||
* [2..] Records...
|
||||
*/
|
||||
|
||||
extern uint16_t m1pwmap;
|
||||
extern uint16_t m1pwmch;
|
||||
extern uint16_t m2pwmap;
|
||||
extern uint16_t m2pwmch;
|
||||
extern uint16_t m3pwmap;
|
||||
extern uint16_t m3pwmch;
|
||||
extern uint16_t m4pwmap;
|
||||
extern uint16_t m4pwmch;
|
||||
extern uint16_t m1TimeoutMan;
|
||||
extern uint16_t m2TimeoutMan;
|
||||
extern uint16_t m3TimeoutMan;
|
||||
extern uint16_t m4TimeoutMan;
|
||||
extern uint16_t twap;
|
||||
extern uint16_t tramp;
|
||||
extern uint16_t t1ch;
|
||||
extern uint16_t t2ch;
|
||||
extern uint16_t t3ch;
|
||||
extern uint16_t t4ch;
|
||||
extern uint16_t twch;
|
||||
extern uint16_t tramp1;
|
||||
extern uint16_t trampman;
|
||||
extern uint16_t m1pwmMan;
|
||||
extern uint16_t m2pwmMan;
|
||||
extern uint16_t m3pwmMan;
|
||||
extern uint16_t m4pwmMan;
|
||||
|
||||
|
||||
extern uint16_t apM1start;
|
||||
extern uint16_t apM1stop;
|
||||
extern uint16_t apM2start;
|
||||
extern uint16_t apM2stop;
|
||||
extern uint16_t apM3start;
|
||||
extern uint16_t apM3stop;
|
||||
extern uint16_t apM4start;
|
||||
extern uint16_t apM4stop;
|
||||
extern uint16_t chM1start;
|
||||
extern uint16_t chM1stop;
|
||||
extern uint16_t chM2start;
|
||||
extern uint16_t chM2stop;
|
||||
extern uint16_t chM3start;
|
||||
extern uint16_t chM3stop;
|
||||
extern uint16_t chM4start;
|
||||
extern uint16_t chM4stop;
|
||||
|
||||
const uint16_t deftab[EE_NUM_VIRTUAL_ADDR]={
|
||||
40, //m1pwmap
|
||||
60, //m1pwmch
|
||||
70, //m2pwmap
|
||||
70, //m2pwmch
|
||||
35, //m3pwmap
|
||||
40, //m3pwmch
|
||||
40, //m4pwmap
|
||||
40, //m4pwmch
|
||||
20, //m1rampstart
|
||||
20, //m2rampstart
|
||||
20, //m3rampstart
|
||||
20, //m4rampstart
|
||||
230,//m1timeoutman
|
||||
100,//m2timeoutman
|
||||
130,//m3timeoutman
|
||||
300,//m4timeoutman
|
||||
1, //twap
|
||||
27, //t1ch
|
||||
10, //t2ch
|
||||
30, //t3ch
|
||||
1, //t4ch
|
||||
1, //twch
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
100, //tramp1
|
||||
60, //m1pwmMan
|
||||
70, //m2pwmMan
|
||||
40, //m3pwmMan
|
||||
40, //m4pwmMan
|
||||
50, //trampman
|
||||
10, //tramp
|
||||
310, //apM1start;
|
||||
450, //apM1stop;
|
||||
30, //apM2start;
|
||||
310, //apM2stop;
|
||||
350, //apM3start;
|
||||
450, //apM3stop;
|
||||
450, //apM4start;
|
||||
850, //apM4stop;
|
||||
10, //chM1start;
|
||||
280, //chM1stop;
|
||||
280, //chM2start;
|
||||
580, //chM2stop;
|
||||
20, //chM3start;
|
||||
280, //chM3stop;
|
||||
280, //chM4start;
|
||||
680, //chM4stop;
|
||||
1,
|
||||
27,
|
||||
10,
|
||||
30,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
100,
|
||||
60,
|
||||
70,
|
||||
40,
|
||||
40,
|
||||
50,
|
||||
10,
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t VirtAddress;
|
||||
uint16_t Data;
|
||||
} EE_Record_t;
|
||||
|
||||
/* Active page base address (runtime selected in EE_Init) */
|
||||
static uint32_t EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
|
||||
/* 32 sequential virtual addresses */
|
||||
const uint16_t EE_VirtAddrs[EE_NUM_VIRTUAL_ADDR] =
|
||||
{
|
||||
0x0001, 0x0002, 0x0003, 0x0004,
|
||||
0x0005, 0x0006, 0x0007, 0x0008,
|
||||
0x0009, 0x000A, 0x000B, 0x000C,
|
||||
0x000D, 0x000E, 0x000F, 0x0010,
|
||||
0x0011, 0x0012, 0x0013, 0x0014,
|
||||
0x0015, 0x0016, 0x0017, 0x0018,
|
||||
0x0019, 0x001A, 0x001B, 0x001C,
|
||||
0x001D, 0x001E, 0x001F, 0x0020,
|
||||
|
||||
0x0021, 0x0022, 0x0023, 0x0024,
|
||||
0x0025, 0x0026, 0x0027, 0x0028,
|
||||
0x0029, 0x002A, 0x002B, 0x002C,
|
||||
0x002D, 0x002E, 0x002F, 0x0030,
|
||||
0x0031, 0x0032, 0x0033, 0x0034,
|
||||
0x0035, 0x0036, 0x0037, 0x0038,
|
||||
0x0039, 0x003A, 0x003B, 0x003C,
|
||||
0x003D, 0x003E, 0x003F, 0x0040
|
||||
};
|
||||
/* ========================================================================= */
|
||||
|
||||
/* --- Internal helpers ---------------------------------------------------- */
|
||||
|
||||
static uint16_t EE_GetPageStatus(uint32_t pageBase)
|
||||
{
|
||||
return *(__IO uint16_t *)pageBase;
|
||||
}
|
||||
|
||||
static HAL_StatusTypeDef EE_FlashProgramHalfWord(uint32_t Address, uint16_t Data)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
|
||||
HAL_FLASH_Unlock();
|
||||
status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, Address, Data);
|
||||
HAL_FLASH_Lock();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static HAL_StatusTypeDef EE_FlashErasePage(uint32_t PageAddress)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
FLASH_EraseInitTypeDef EraseInit;
|
||||
uint32_t PageError = 0;
|
||||
|
||||
HAL_FLASH_Unlock();
|
||||
|
||||
EraseInit.TypeErase = FLASH_TYPEERASE_PAGES;
|
||||
EraseInit.PageAddress = PageAddress;
|
||||
EraseInit.NbPages = 1;
|
||||
|
||||
status = HAL_FLASHEx_Erase(&EraseInit, &PageError);
|
||||
|
||||
HAL_FLASH_Lock();
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Find first free record address in given page (returns 0 if full) */
|
||||
static uint32_t EE_FindFreeAddress(uint32_t pageBase)
|
||||
{
|
||||
uint32_t addr = pageBase + 2U; /* Skip status word */
|
||||
uint32_t pageEnd = pageBase + EE_PAGE_SIZE;
|
||||
|
||||
while (addr < (pageEnd - sizeof(EE_Record_t) + 1U))
|
||||
{
|
||||
uint16_t vaddr = *(__IO uint16_t *)addr;
|
||||
|
||||
if (vaddr == 0xFFFFU)
|
||||
{
|
||||
/* Empty slot */
|
||||
return addr;
|
||||
}
|
||||
addr += sizeof(EE_Record_t);
|
||||
}
|
||||
|
||||
return 0U; /* No space */
|
||||
}
|
||||
|
||||
/* Find latest value of VirtAddress in a specific page (internal, uses EE_Status) */
|
||||
/* Find latest value of VirtAddress in a specific page (scan forward) */
|
||||
static EE_Status EE_FindInPage(uint32_t pageBase, uint16_t VirtAddress, uint16_t *Data)
|
||||
{
|
||||
uint32_t addr = pageBase + 2U; // skip status halfword
|
||||
uint32_t pageEnd = pageBase + EE_PAGE_SIZE;
|
||||
EE_Status result = EE_NOT_FOUND;
|
||||
uint16_t lastVal = 0;
|
||||
|
||||
if (Data == NULL)
|
||||
return EE_ERROR;
|
||||
|
||||
while (addr <= (pageEnd - sizeof(EE_Record_t)))
|
||||
{
|
||||
uint16_t vaddr = *(__IO uint16_t *)addr;
|
||||
|
||||
if (vaddr == 0xFFFFU)
|
||||
{
|
||||
// First empty slot => no more records in this page
|
||||
break;
|
||||
}
|
||||
|
||||
uint16_t value = *(__IO uint16_t *)(addr + 2U);
|
||||
|
||||
if (vaddr == VirtAddress)
|
||||
{
|
||||
lastVal = value; // keep most recent
|
||||
result = EE_OK;
|
||||
}
|
||||
|
||||
addr += sizeof(EE_Record_t); // move 4 bytes forward
|
||||
}
|
||||
|
||||
if (result == EE_OK)
|
||||
*Data = lastVal;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Format both pages: erase and set PAGE0 as VALID */
|
||||
static EE_Status EE_Format(void)
|
||||
{
|
||||
if (EE_FlashErasePage(EE_PAGE0_BASE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
if (EE_FlashErasePage(EE_PAGE1_BASE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
if (EE_FlashProgramHalfWord(EE_PAGE0_BASE, EE_PAGE_STATUS_VALID) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* PAGE1 will remain erased (status = 0xFFFF) */
|
||||
EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
|
||||
return EE_STATUS_OK;
|
||||
}
|
||||
|
||||
/* Get the base of the other page */
|
||||
static uint32_t EE_GetOtherPageBase(uint32_t pageBase)
|
||||
{
|
||||
return (pageBase == EE_PAGE0_BASE) ? EE_PAGE1_BASE : EE_PAGE0_BASE;
|
||||
}
|
||||
|
||||
/* Page transfer (garbage collection + new write) */
|
||||
static EE_Status EE_PageTransfer(uint16_t VirtAddress, uint16_t Data)
|
||||
{
|
||||
uint32_t oldBase = EE_ActivePageBase;
|
||||
uint32_t newBase = EE_GetOtherPageBase(oldBase);
|
||||
uint32_t addr;
|
||||
uint16_t value;
|
||||
EE_Status st;
|
||||
|
||||
/* Erase new page */
|
||||
if (EE_FlashErasePage(newBase) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Mark new page as RECEIVE */
|
||||
if (EE_FlashProgramHalfWord(newBase, EE_PAGE_STATUS_RECEIVE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Start writing records just after status */
|
||||
addr = newBase + 2U;
|
||||
|
||||
/* For each known virtual variable */
|
||||
for (uint16_t i = 0; i < EE_NUM_VIRTUAL_ADDR; i++)
|
||||
{
|
||||
uint16_t vaddr = EE_VirtAddrs[i];
|
||||
|
||||
if (vaddr == VirtAddress)
|
||||
{
|
||||
/* Use the new data passed into PageTransfer */
|
||||
value = Data;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Read latest value from old active page */
|
||||
st = EE_FindInPage(oldBase, vaddr, &value);
|
||||
if (st != EE_STATUS_OK)
|
||||
{
|
||||
/* Variable never written -> skip */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Write record to new page */
|
||||
if (EE_FlashProgramHalfWord(addr, vaddr) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
if (EE_FlashProgramHalfWord(addr + 2U, value) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
addr += sizeof(EE_Record_t);
|
||||
if (addr >= (newBase + EE_PAGE_SIZE))
|
||||
return EE_STATUS_NO_SPACE;
|
||||
}
|
||||
|
||||
/* Erase old page */
|
||||
if (EE_FlashErasePage(oldBase) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Mark new page as VALID */
|
||||
if (EE_FlashProgramHalfWord(newBase, EE_PAGE_STATUS_VALID) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Update active page */
|
||||
EE_ActivePageBase = newBase;
|
||||
|
||||
return EE_STATUS_OK;
|
||||
}
|
||||
|
||||
/* --- Public API ----------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* Initialize the EEPROM emulation.
|
||||
* - Checks page statuses and chooses the active page.
|
||||
* - If inconsistent or blank, formats pages.
|
||||
* PUBLIC RETURN TYPE: uint16_t (EE_OK / EE_ERROR / ...)
|
||||
*/
|
||||
uint16_t EE_Init(void)
|
||||
{
|
||||
uint16_t status0 = EE_GetPageStatus(EE_PAGE0_BASE);
|
||||
uint16_t status1 = EE_GetPageStatus(EE_PAGE1_BASE);
|
||||
|
||||
if ((status0 == EE_PAGE_STATUS_ERASED) && (status1 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
/* Fresh device -> format */
|
||||
return (uint16_t)EE_Format();
|
||||
}
|
||||
else if ((status0 == EE_PAGE_STATUS_VALID) && (status1 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
return EE_OK;
|
||||
}
|
||||
else if ((status1 == EE_PAGE_STATUS_VALID) && (status0 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
EE_ActivePageBase = EE_PAGE1_BASE;
|
||||
return EE_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Any weird or inconsistent state -> reformat */
|
||||
return (uint16_t)EE_Format();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a 16-bit variable by its virtual address.
|
||||
* PUBLIC RETURN: EE_OK / EE_NOT_FOUND / EE_ERROR (as uint16_t)
|
||||
*/
|
||||
uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t *Data)
|
||||
{
|
||||
EE_Status st;
|
||||
|
||||
if (Data == NULL)
|
||||
return EE_ERROR;
|
||||
|
||||
st = EE_FindInPage(EE_ActivePageBase, VirtAddress, Data);
|
||||
return (uint16_t)st;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write (append) a 16-bit variable.
|
||||
* - Writes a new record in the active page.
|
||||
* - If the page is full, triggers a page transfer (GC).
|
||||
* PUBLIC RETURN: EE_OK / EE_ERROR / EE_NO_SPACE (as uint16_t)
|
||||
*/
|
||||
uint16_t EE_WriteVariable(uint16_t VirtAddress, uint16_t Data)
|
||||
{
|
||||
uint32_t freeAddr;
|
||||
EE_Status st;
|
||||
|
||||
/* Find free space in active page */
|
||||
freeAddr = EE_FindFreeAddress(EE_ActivePageBase);
|
||||
if (freeAddr != 0U)
|
||||
{
|
||||
/* Write new record */
|
||||
if (EE_FlashProgramHalfWord(freeAddr, VirtAddress) != HAL_OK)
|
||||
return EE_ERROR;
|
||||
if (EE_FlashProgramHalfWord(freeAddr + 2U, Data) != HAL_OK)
|
||||
return EE_ERROR;
|
||||
|
||||
return EE_OK;
|
||||
}
|
||||
|
||||
/* No space -> page transfer */
|
||||
st = EE_PageTransfer(VirtAddress, Data);
|
||||
return (uint16_t)st;
|
||||
}
|
||||
|
||||
void loadEE(void){
|
||||
char s [200];
|
||||
EEW_Read(M1PWMAP, &m1pwmap);
|
||||
EEW_Read(M1PWMCH, &m1pwmch);
|
||||
EEW_Read(M2PWMAP, &m2pwmap);
|
||||
EEW_Read(M2PWMCH, &m2pwmch);
|
||||
EEW_Read(M3PWMAP, &m3pwmap);
|
||||
EEW_Read(M3PWMCH, &m3pwmch);
|
||||
EEW_Read(M4PWMAP, &m4pwmap);
|
||||
EEW_Read(M4PWMCH, &m4pwmch);
|
||||
EEW_Read(M1TIMEOUTMAN, &m1TimeoutMan);
|
||||
EEW_Read(M2TIMEOUTMAN, &m2TimeoutMan);
|
||||
EEW_Read(M3TIMEOUTMAN, &m3TimeoutMan);
|
||||
EEW_Read(M4TIMEOUTMAN, &m4TimeoutMan);
|
||||
EEW_Read(TWAP, &twap);
|
||||
EEW_Read(T1CH, &t1ch);
|
||||
EEW_Read(T2CH, &t2ch);
|
||||
EEW_Read(T3CH, &t3ch);
|
||||
EEW_Read(T4CH, &t4ch);
|
||||
EEW_Read(TWCH, &twch);
|
||||
EEW_Read(TRAMP1, &tramp1);
|
||||
EEW_Read(M1PWMMAN, &m1pwmMan);
|
||||
EEW_Read(M2PWMMAN, &m2pwmMan);
|
||||
EEW_Read(M3PWMMAN, &m3pwmMan);
|
||||
EEW_Read(M4PWMMAN, &m4pwmMan);
|
||||
EEW_Read(TRAMPMAN, &trampman);
|
||||
EEW_Read(TRAMP, &tramp);
|
||||
|
||||
EEW_Read(APM1START,&apM1start);
|
||||
EEW_Read(APM1STOP ,&apM1stop);
|
||||
EEW_Read(APM2START,&apM2start);
|
||||
EEW_Read(APM2STOP ,&apM2stop);
|
||||
EEW_Read(APM3START,&apM3start);
|
||||
EEW_Read(APM3STOP ,&apM3stop);
|
||||
EEW_Read(APM4START,&apM4start);
|
||||
EEW_Read(APM4STOP ,&apM4stop);
|
||||
EEW_Read(CHM1START,&chM1start);
|
||||
EEW_Read(CHM1STOP ,&chM1stop);
|
||||
EEW_Read(CHM2START,&chM2start);
|
||||
EEW_Read(CHM2STOP ,&chM2stop);
|
||||
EEW_Read(CHM3START,&chM3start);
|
||||
EEW_Read(CHM3STOP ,&chM3stop);
|
||||
EEW_Read(CHM4START,&chM4start);
|
||||
EEW_Read(CHM4STOP ,&chM4stop);
|
||||
|
||||
sprintf((char*)s,"LoadEE\n");
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
sprintf((char*)s,"\nm1pwmap=%d m1pwmch=%d m2pwmap=%d m2pwmch=%d m3pwmap=%d m3pwmch=%d m4pwmap=%d m4pwmch=%d",m1pwmap,m1pwmch,m2pwmap,m2pwmch,m3pwmap,m3pwmch,m4pwmap, m4pwmch);
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
sprintf((char*)s,"\nm1TimeoutMan=%d m2TimeoutMan=%d m3TimeoutMan=%d m4TimeoutMan=%d ",m1TimeoutMan,m2TimeoutMan,m3TimeoutMan,m4TimeoutMan);
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
sprintf((char*)s,"\ntramp=%d trampman=%d",tramp,trampman);
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
sprintf((char*)s,"\nm1pwmMan=%d m2pwmMan=%d m3pwmMan=%d m4pwmMan=%d",m1pwmMan,m2pwmMan,m3pwmMan,m4pwmMan);
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,477 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "eeprom.h"
|
||||
extern UART_HandleTypeDef huart1;
|
||||
/*
|
||||
* Record format (4 bytes):
|
||||
* [0] VirtAddress (uint16_t)
|
||||
* [2] Data (uint16_t)
|
||||
*
|
||||
* Page layout:
|
||||
* [0] PageStatus (uint16_t)
|
||||
* [2..] Records...
|
||||
*/
|
||||
|
||||
extern uint16_t m1pwmap;
|
||||
extern uint16_t m1pwmch;
|
||||
extern uint16_t m2pwmap;
|
||||
extern uint16_t m2pwmch;
|
||||
extern uint16_t m3pwmap;
|
||||
extern uint16_t m3pwmch;
|
||||
extern uint16_t m4pwmap;
|
||||
extern uint16_t m4pwmch;
|
||||
extern uint16_t t1ap;
|
||||
extern uint16_t t2ap;
|
||||
extern uint16_t t3ap;
|
||||
extern uint16_t t4ap;
|
||||
extern uint16_t twap;
|
||||
extern uint16_t tramp;
|
||||
extern uint16_t t1ch;
|
||||
extern uint16_t t2ch;
|
||||
extern uint16_t t3ch;
|
||||
extern uint16_t t4ch;
|
||||
extern uint16_t twch;
|
||||
extern uint16_t tramp1;
|
||||
extern uint16_t trampman;
|
||||
extern uint16_t m1pwmMan;
|
||||
extern uint16_t m2pwmMan;
|
||||
extern uint16_t m3pwmMan;
|
||||
extern uint16_t m4pwmMan;
|
||||
|
||||
|
||||
extern uint16_t apM1start;
|
||||
extern uint16_t apM1stop;
|
||||
extern uint16_t apM2start;
|
||||
extern uint16_t apM2stop;
|
||||
extern uint16_t apM3start;
|
||||
extern uint16_t apM3stop;
|
||||
extern uint16_t apM4start;
|
||||
extern uint16_t apM4stop;
|
||||
extern uint16_t chM1start;
|
||||
extern uint16_t chM1stop;
|
||||
extern uint16_t chM2start;
|
||||
extern uint16_t chM2stop;
|
||||
extern uint16_t chM3start;
|
||||
extern uint16_t chM3stop;
|
||||
extern uint16_t chM4start;
|
||||
extern uint16_t chM4stop;
|
||||
|
||||
const uint8_t deftab[EE_NUM_VIRTUAL_ADDR]={
|
||||
40, //m1pwmap
|
||||
60, //m1pwmch
|
||||
70, //m2pwmap
|
||||
70, //m2pwmch
|
||||
35, //m3pwmap
|
||||
40, //m3pwmch
|
||||
40, //m4pwmap
|
||||
40, //m4pwmch
|
||||
20, //m1rampstart
|
||||
20, //m2rampstart
|
||||
20, //m3rampstart
|
||||
20, //m4rampstart
|
||||
28, //t1ap
|
||||
4, //t2ap
|
||||
10, //t3ap
|
||||
40, //t4ap
|
||||
1, //twap
|
||||
27, //t1ch
|
||||
10, //t2ch
|
||||
30, //t3ch
|
||||
1, //t4ch
|
||||
1, //twch
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
100, //tramp1
|
||||
60, //m1pwmMan
|
||||
70, //m2pwmMan
|
||||
40, //m3pwmMan
|
||||
40, //m4pwmMan
|
||||
50, //trampman
|
||||
10, //tramp
|
||||
0, //apM1start;
|
||||
0, //apM1stop;
|
||||
0, //apM2start;
|
||||
0, //apM2stop;
|
||||
0, //apM3start;
|
||||
0, //apM3stop;
|
||||
0, //apM4start;
|
||||
0, //apM4stop;
|
||||
0, //chM1start;
|
||||
0, //chM1stop;
|
||||
0, //chM2start;
|
||||
0, //chM2stop;
|
||||
0, //chM3start;
|
||||
0, //chM3stop;
|
||||
0, //chM4start;
|
||||
0, //chM4stop;
|
||||
1,
|
||||
27,
|
||||
10,
|
||||
30,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
100,
|
||||
60,
|
||||
70,
|
||||
40,
|
||||
40,
|
||||
50,
|
||||
10,
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t VirtAddress;
|
||||
uint16_t Data;
|
||||
} EE_Record_t;
|
||||
|
||||
/* Active page base address (runtime selected in EE_Init) */
|
||||
static uint32_t EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
|
||||
/* 32 sequential virtual addresses */
|
||||
const uint16_t EE_VirtAddrs[EE_NUM_VIRTUAL_ADDR] =
|
||||
{
|
||||
0x0001, 0x0002, 0x0003, 0x0004,
|
||||
0x0005, 0x0006, 0x0007, 0x0008,
|
||||
0x0009, 0x000A, 0x000B, 0x000C,
|
||||
0x000D, 0x000E, 0x000F, 0x0010,
|
||||
0x0011, 0x0012, 0x0013, 0x0014,
|
||||
0x0015, 0x0016, 0x0017, 0x0018,
|
||||
0x0019, 0x001A, 0x001B, 0x001C,
|
||||
0x001D, 0x001E, 0x001F, 0x0020,
|
||||
|
||||
0x0021, 0x0022, 0x0023, 0x0024,
|
||||
0x0025, 0x0026, 0x0027, 0x0028,
|
||||
0x0029, 0x002A, 0x002B, 0x002C,
|
||||
0x002D, 0x002E, 0x002F, 0x0030,
|
||||
0x0031, 0x0032, 0x0033, 0x0034,
|
||||
0x0035, 0x0036, 0x0037, 0x0038,
|
||||
0x0039, 0x003A, 0x003B, 0x003C,
|
||||
0x003D, 0x003E, 0x003F, 0x0040
|
||||
};
|
||||
/* ========================================================================= */
|
||||
|
||||
/* --- Internal helpers ---------------------------------------------------- */
|
||||
|
||||
static uint16_t EE_GetPageStatus(uint32_t pageBase)
|
||||
{
|
||||
return *(__IO uint16_t *)pageBase;
|
||||
}
|
||||
|
||||
static HAL_StatusTypeDef EE_FlashProgramHalfWord(uint32_t Address, uint16_t Data)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
|
||||
HAL_FLASH_Unlock();
|
||||
status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, Address, Data);
|
||||
HAL_FLASH_Lock();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static HAL_StatusTypeDef EE_FlashErasePage(uint32_t PageAddress)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
FLASH_EraseInitTypeDef EraseInit;
|
||||
uint32_t PageError = 0;
|
||||
|
||||
HAL_FLASH_Unlock();
|
||||
|
||||
EraseInit.TypeErase = FLASH_TYPEERASE_PAGES;
|
||||
EraseInit.PageAddress = PageAddress;
|
||||
EraseInit.NbPages = 1;
|
||||
|
||||
status = HAL_FLASHEx_Erase(&EraseInit, &PageError);
|
||||
|
||||
HAL_FLASH_Lock();
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Find first free record address in given page (returns 0 if full) */
|
||||
static uint32_t EE_FindFreeAddress(uint32_t pageBase)
|
||||
{
|
||||
uint32_t addr = pageBase + 2U; /* Skip status word */
|
||||
uint32_t pageEnd = pageBase + EE_PAGE_SIZE;
|
||||
|
||||
while (addr < (pageEnd - sizeof(EE_Record_t) + 1U))
|
||||
{
|
||||
uint16_t vaddr = *(__IO uint16_t *)addr;
|
||||
|
||||
if (vaddr == 0xFFFFU)
|
||||
{
|
||||
/* Empty slot */
|
||||
return addr;
|
||||
}
|
||||
addr += sizeof(EE_Record_t);
|
||||
}
|
||||
|
||||
return 0U; /* No space */
|
||||
}
|
||||
|
||||
/* Find latest value of VirtAddress in a specific page (internal, uses EE_Status) */
|
||||
/* Find latest value of VirtAddress in a specific page (scan forward) */
|
||||
static EE_Status EE_FindInPage(uint32_t pageBase, uint16_t VirtAddress, uint16_t *Data)
|
||||
{
|
||||
uint32_t addr = pageBase + 2U; // skip status halfword
|
||||
uint32_t pageEnd = pageBase + EE_PAGE_SIZE;
|
||||
EE_Status result = EE_NOT_FOUND;
|
||||
uint16_t lastVal = 0;
|
||||
|
||||
if (Data == NULL)
|
||||
return EE_ERROR;
|
||||
|
||||
while (addr <= (pageEnd - sizeof(EE_Record_t)))
|
||||
{
|
||||
uint16_t vaddr = *(__IO uint16_t *)addr;
|
||||
|
||||
if (vaddr == 0xFFFFU)
|
||||
{
|
||||
// First empty slot => no more records in this page
|
||||
break;
|
||||
}
|
||||
|
||||
uint16_t value = *(__IO uint16_t *)(addr + 2U);
|
||||
|
||||
if (vaddr == VirtAddress)
|
||||
{
|
||||
lastVal = value; // keep most recent
|
||||
result = EE_OK;
|
||||
}
|
||||
|
||||
addr += sizeof(EE_Record_t); // move 4 bytes forward
|
||||
}
|
||||
|
||||
if (result == EE_OK)
|
||||
*Data = lastVal;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Format both pages: erase and set PAGE0 as VALID */
|
||||
static EE_Status EE_Format(void)
|
||||
{
|
||||
if (EE_FlashErasePage(EE_PAGE0_BASE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
if (EE_FlashErasePage(EE_PAGE1_BASE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
if (EE_FlashProgramHalfWord(EE_PAGE0_BASE, EE_PAGE_STATUS_VALID) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* PAGE1 will remain erased (status = 0xFFFF) */
|
||||
EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
|
||||
return EE_STATUS_OK;
|
||||
}
|
||||
|
||||
/* Get the base of the other page */
|
||||
static uint32_t EE_GetOtherPageBase(uint32_t pageBase)
|
||||
{
|
||||
return (pageBase == EE_PAGE0_BASE) ? EE_PAGE1_BASE : EE_PAGE0_BASE;
|
||||
}
|
||||
|
||||
/* Page transfer (garbage collection + new write) */
|
||||
static EE_Status EE_PageTransfer(uint16_t VirtAddress, uint16_t Data)
|
||||
{
|
||||
uint32_t oldBase = EE_ActivePageBase;
|
||||
uint32_t newBase = EE_GetOtherPageBase(oldBase);
|
||||
uint32_t addr;
|
||||
uint16_t value;
|
||||
EE_Status st;
|
||||
|
||||
/* Erase new page */
|
||||
if (EE_FlashErasePage(newBase) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Mark new page as RECEIVE */
|
||||
if (EE_FlashProgramHalfWord(newBase, EE_PAGE_STATUS_RECEIVE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Start writing records just after status */
|
||||
addr = newBase + 2U;
|
||||
|
||||
/* For each known virtual variable */
|
||||
for (uint16_t i = 0; i < EE_NUM_VIRTUAL_ADDR; i++)
|
||||
{
|
||||
uint16_t vaddr = EE_VirtAddrs[i];
|
||||
|
||||
if (vaddr == VirtAddress)
|
||||
{
|
||||
/* Use the new data passed into PageTransfer */
|
||||
value = Data;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Read latest value from old active page */
|
||||
st = EE_FindInPage(oldBase, vaddr, &value);
|
||||
if (st != EE_STATUS_OK)
|
||||
{
|
||||
/* Variable never written -> skip */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Write record to new page */
|
||||
if (EE_FlashProgramHalfWord(addr, vaddr) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
if (EE_FlashProgramHalfWord(addr + 2U, value) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
addr += sizeof(EE_Record_t);
|
||||
if (addr >= (newBase + EE_PAGE_SIZE))
|
||||
return EE_STATUS_NO_SPACE;
|
||||
}
|
||||
|
||||
/* Erase old page */
|
||||
if (EE_FlashErasePage(oldBase) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Mark new page as VALID */
|
||||
if (EE_FlashProgramHalfWord(newBase, EE_PAGE_STATUS_VALID) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Update active page */
|
||||
EE_ActivePageBase = newBase;
|
||||
|
||||
return EE_STATUS_OK;
|
||||
}
|
||||
|
||||
/* --- Public API ----------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* Initialize the EEPROM emulation.
|
||||
* - Checks page statuses and chooses the active page.
|
||||
* - If inconsistent or blank, formats pages.
|
||||
* PUBLIC RETURN TYPE: uint16_t (EE_OK / EE_ERROR / ...)
|
||||
*/
|
||||
uint16_t EE_Init(void)
|
||||
{
|
||||
uint16_t status0 = EE_GetPageStatus(EE_PAGE0_BASE);
|
||||
uint16_t status1 = EE_GetPageStatus(EE_PAGE1_BASE);
|
||||
|
||||
if ((status0 == EE_PAGE_STATUS_ERASED) && (status1 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
/* Fresh device -> format */
|
||||
return (uint16_t)EE_Format();
|
||||
}
|
||||
else if ((status0 == EE_PAGE_STATUS_VALID) && (status1 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
return EE_OK;
|
||||
}
|
||||
else if ((status1 == EE_PAGE_STATUS_VALID) && (status0 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
EE_ActivePageBase = EE_PAGE1_BASE;
|
||||
return EE_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Any weird or inconsistent state -> reformat */
|
||||
return (uint16_t)EE_Format();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a 16-bit variable by its virtual address.
|
||||
* PUBLIC RETURN: EE_OK / EE_NOT_FOUND / EE_ERROR (as uint16_t)
|
||||
*/
|
||||
uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t *Data)
|
||||
{
|
||||
EE_Status st;
|
||||
|
||||
if (Data == NULL)
|
||||
return EE_ERROR;
|
||||
|
||||
st = EE_FindInPage(EE_ActivePageBase, VirtAddress, Data);
|
||||
return (uint16_t)st;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write (append) a 16-bit variable.
|
||||
* - Writes a new record in the active page.
|
||||
* - If the page is full, triggers a page transfer (GC).
|
||||
* PUBLIC RETURN: EE_OK / EE_ERROR / EE_NO_SPACE (as uint16_t)
|
||||
*/
|
||||
uint16_t EE_WriteVariable(uint16_t VirtAddress, uint16_t Data)
|
||||
{
|
||||
uint32_t freeAddr;
|
||||
EE_Status st;
|
||||
|
||||
/* Find free space in active page */
|
||||
freeAddr = EE_FindFreeAddress(EE_ActivePageBase);
|
||||
if (freeAddr != 0U)
|
||||
{
|
||||
/* Write new record */
|
||||
if (EE_FlashProgramHalfWord(freeAddr, VirtAddress) != HAL_OK)
|
||||
return EE_ERROR;
|
||||
if (EE_FlashProgramHalfWord(freeAddr + 2U, Data) != HAL_OK)
|
||||
return EE_ERROR;
|
||||
|
||||
return EE_OK;
|
||||
}
|
||||
|
||||
/* No space -> page transfer */
|
||||
st = EE_PageTransfer(VirtAddress, Data);
|
||||
return (uint16_t)st;
|
||||
}
|
||||
|
||||
void loadEE(void){
|
||||
char s [200];
|
||||
EEW_Read(M1PWMAP, &m1pwmap);
|
||||
EEW_Read(M1PWMCH, &m1pwmch);
|
||||
EEW_Read(M2PWMAP, &m2pwmap);
|
||||
EEW_Read(M2PWMCH, &m2pwmch);
|
||||
EEW_Read(M3PWMAP, &m3pwmap);
|
||||
EEW_Read(M3PWMCH, &m3pwmch);
|
||||
EEW_Read(M4PWMAP, &m4pwmap);
|
||||
EEW_Read(M4PWMCH, &m4pwmch);
|
||||
EEW_Read(T1AP, &t1ap);
|
||||
EEW_Read(T2AP, &t2ap);
|
||||
EEW_Read(T3AP, &t3ap);
|
||||
EEW_Read(T4AP, &t4ap);
|
||||
EEW_Read(TWAP, &twap);
|
||||
EEW_Read(T1CH, &t1ch);
|
||||
EEW_Read(T2CH, &t2ch);
|
||||
EEW_Read(T3CH, &t3ch);
|
||||
EEW_Read(T4CH, &t4ch);
|
||||
EEW_Read(TWCH, &twch);
|
||||
EEW_Read(TRAMP1, &tramp1);
|
||||
EEW_Read(M1PWMMAN, &m1pwmMan);
|
||||
EEW_Read(M2PWMMAN, &m2pwmMan);
|
||||
EEW_Read(M3PWMMAN, &m3pwmMan);
|
||||
EEW_Read(M4PWMMAN, &m4pwmMan);
|
||||
EEW_Read(TRAMPMAN, &trampman);
|
||||
EEW_Read(TRAMP, &tramp);
|
||||
|
||||
EEW_Read(APM1START,&apM1start);
|
||||
EEW_Read(APM1STOP ,&apM1stop);
|
||||
EEW_Read(APM2START,&apM2start);
|
||||
EEW_Read(APM2STOP ,&apM2stop);
|
||||
EEW_Read(APM3START,&apM3start);
|
||||
EEW_Read(APM3STOP ,&apM3stop);
|
||||
EEW_Read(APM4START,&apM4start);
|
||||
EEW_Read(APM4STOP ,&apM4stop);
|
||||
EEW_Read(CHM1START,&chM1start);
|
||||
EEW_Read(CHM1STOP ,&chM1stop);
|
||||
EEW_Read(CHM2START,&chM2start);
|
||||
EEW_Read(CHM2STOP ,&chM2stop);
|
||||
EEW_Read(CHM3START,&chM3start);
|
||||
EEW_Read(CHM3STOP ,&chM3stop);
|
||||
EEW_Read(CHM4START,&chM4start);
|
||||
EEW_Read(CHM4STOP ,&chM4stop);
|
||||
|
||||
sprintf((char*)s,"LoadEE\n");
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
sprintf((char*)s,"\nm1pwmap=%d m1pwmch=%d m2pwmap=%d m2pwmch=%d m3pwmap=%d m3pwmch=%d m4pwmap=%d m4pwmch=%d",m1pwmap,m1pwmch,m2pwmap,m2pwmch,m3pwmap,m3pwmch,m4pwmap, m4pwmch);
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
sprintf((char*)s,"\ntramp=%d trampman=%d",tramp,trampman);
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,481 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "eeprom.h"
|
||||
extern UART_HandleTypeDef huart1;
|
||||
/*
|
||||
* Record format (4 bytes):
|
||||
* [0] VirtAddress (uint16_t)
|
||||
* [2] Data (uint16_t)
|
||||
*
|
||||
* Page layout:
|
||||
* [0] PageStatus (uint16_t)
|
||||
* [2..] Records...
|
||||
*/
|
||||
|
||||
extern uint16_t m1pwmap;
|
||||
extern uint16_t m1pwmch;
|
||||
extern uint16_t m2pwmap;
|
||||
extern uint16_t m2pwmch;
|
||||
extern uint16_t m3pwmap;
|
||||
extern uint16_t m3pwmch;
|
||||
extern uint16_t m4pwmap;
|
||||
extern uint16_t m4pwmch;
|
||||
extern uint16_t t1ap;
|
||||
extern uint16_t t2ap;
|
||||
extern uint16_t t3ap;
|
||||
extern uint16_t t4ap;
|
||||
extern uint16_t twap;
|
||||
extern uint16_t tramp;
|
||||
extern uint16_t t1ch;
|
||||
extern uint16_t t2ch;
|
||||
extern uint16_t t3ch;
|
||||
extern uint16_t t4ch;
|
||||
extern uint16_t twch;
|
||||
extern uint16_t tramp1;
|
||||
extern uint16_t trampman;
|
||||
extern uint16_t m1pwmMan;
|
||||
extern uint16_t m2pwmMan;
|
||||
extern uint16_t m3pwmMan;
|
||||
extern uint16_t m4pwmMan;
|
||||
|
||||
|
||||
extern uint16_t apM1start;
|
||||
extern uint16_t apM1stop;
|
||||
extern uint16_t apM2start;
|
||||
extern uint16_t apM2stop;
|
||||
extern uint16_t apM3start;
|
||||
extern uint16_t apM3stop;
|
||||
extern uint16_t apM4start;
|
||||
extern uint16_t apM4stop;
|
||||
extern uint16_t chM1start;
|
||||
extern uint16_t chM1stop;
|
||||
extern uint16_t chM2start;
|
||||
extern uint16_t chM2stop;
|
||||
extern uint16_t chM3start;
|
||||
extern uint16_t chM3stop;
|
||||
extern uint16_t chM4start;
|
||||
extern uint16_t chM4stop;
|
||||
|
||||
const uint16_t deftab[EE_NUM_VIRTUAL_ADDR]={
|
||||
40, //m1pwmap
|
||||
60, //m1pwmch
|
||||
70, //m2pwmap
|
||||
70, //m2pwmch
|
||||
35, //m3pwmap
|
||||
40, //m3pwmch
|
||||
40, //m4pwmap
|
||||
40, //m4pwmch
|
||||
20, //m1rampstart
|
||||
20, //m2rampstart
|
||||
20, //m3rampstart
|
||||
20, //m4rampstart
|
||||
28, //t1ap
|
||||
4, //t2ap
|
||||
10, //t3ap
|
||||
40, //t4ap
|
||||
1, //twap
|
||||
27, //t1ch
|
||||
10, //t2ch
|
||||
30, //t3ch
|
||||
1, //t4ch
|
||||
1, //twch
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
100, //tramp1
|
||||
60, //m1pwmMan
|
||||
70, //m2pwmMan
|
||||
40, //m3pwmMan
|
||||
40, //m4pwmMan
|
||||
50, //trampman
|
||||
10, //tramp
|
||||
310, //apM1start;
|
||||
450, //apM1stop;
|
||||
30, //apM2start;
|
||||
310, //apM2stop;
|
||||
350, //apM3start;
|
||||
450, //apM3stop;
|
||||
450, //apM4start;
|
||||
850, //apM4stop;
|
||||
10, //chM1start;
|
||||
280, //chM1stop;
|
||||
280, //chM2start;
|
||||
580, //chM2stop;
|
||||
20, //chM3start;
|
||||
280, //chM3stop;
|
||||
280, //chM4start;
|
||||
680, //chM4stop;
|
||||
1,
|
||||
27,
|
||||
10,
|
||||
30,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
100,
|
||||
60,
|
||||
70,
|
||||
40,
|
||||
40,
|
||||
50,
|
||||
10,
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t VirtAddress;
|
||||
uint16_t Data;
|
||||
} EE_Record_t;
|
||||
|
||||
/* Active page base address (runtime selected in EE_Init) */
|
||||
static uint32_t EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
|
||||
/* 32 sequential virtual addresses */
|
||||
const uint16_t EE_VirtAddrs[EE_NUM_VIRTUAL_ADDR] =
|
||||
{
|
||||
0x0001, 0x0002, 0x0003, 0x0004,
|
||||
0x0005, 0x0006, 0x0007, 0x0008,
|
||||
0x0009, 0x000A, 0x000B, 0x000C,
|
||||
0x000D, 0x000E, 0x000F, 0x0010,
|
||||
0x0011, 0x0012, 0x0013, 0x0014,
|
||||
0x0015, 0x0016, 0x0017, 0x0018,
|
||||
0x0019, 0x001A, 0x001B, 0x001C,
|
||||
0x001D, 0x001E, 0x001F, 0x0020,
|
||||
|
||||
0x0021, 0x0022, 0x0023, 0x0024,
|
||||
0x0025, 0x0026, 0x0027, 0x0028,
|
||||
0x0029, 0x002A, 0x002B, 0x002C,
|
||||
0x002D, 0x002E, 0x002F, 0x0030,
|
||||
0x0031, 0x0032, 0x0033, 0x0034,
|
||||
0x0035, 0x0036, 0x0037, 0x0038,
|
||||
0x0039, 0x003A, 0x003B, 0x003C,
|
||||
0x003D, 0x003E, 0x003F, 0x0040
|
||||
};
|
||||
/* ========================================================================= */
|
||||
|
||||
/* --- Internal helpers ---------------------------------------------------- */
|
||||
|
||||
static uint16_t EE_GetPageStatus(uint32_t pageBase)
|
||||
{
|
||||
return *(__IO uint16_t *)pageBase;
|
||||
}
|
||||
|
||||
static HAL_StatusTypeDef EE_FlashProgramHalfWord(uint32_t Address, uint16_t Data)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
|
||||
HAL_FLASH_Unlock();
|
||||
status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, Address, Data);
|
||||
HAL_FLASH_Lock();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static HAL_StatusTypeDef EE_FlashErasePage(uint32_t PageAddress)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
FLASH_EraseInitTypeDef EraseInit;
|
||||
uint32_t PageError = 0;
|
||||
|
||||
HAL_FLASH_Unlock();
|
||||
|
||||
EraseInit.TypeErase = FLASH_TYPEERASE_PAGES;
|
||||
EraseInit.PageAddress = PageAddress;
|
||||
EraseInit.NbPages = 1;
|
||||
|
||||
status = HAL_FLASHEx_Erase(&EraseInit, &PageError);
|
||||
|
||||
HAL_FLASH_Lock();
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Find first free record address in given page (returns 0 if full) */
|
||||
static uint32_t EE_FindFreeAddress(uint32_t pageBase)
|
||||
{
|
||||
uint32_t addr = pageBase + 2U; /* Skip status word */
|
||||
uint32_t pageEnd = pageBase + EE_PAGE_SIZE;
|
||||
|
||||
while (addr < (pageEnd - sizeof(EE_Record_t) + 1U))
|
||||
{
|
||||
uint16_t vaddr = *(__IO uint16_t *)addr;
|
||||
|
||||
if (vaddr == 0xFFFFU)
|
||||
{
|
||||
/* Empty slot */
|
||||
return addr;
|
||||
}
|
||||
addr += sizeof(EE_Record_t);
|
||||
}
|
||||
|
||||
return 0U; /* No space */
|
||||
}
|
||||
|
||||
/* Find latest value of VirtAddress in a specific page (internal, uses EE_Status) */
|
||||
/* Find latest value of VirtAddress in a specific page (scan forward) */
|
||||
static EE_Status EE_FindInPage(uint32_t pageBase, uint16_t VirtAddress, uint16_t *Data)
|
||||
{
|
||||
uint32_t addr = pageBase + 2U; // skip status halfword
|
||||
uint32_t pageEnd = pageBase + EE_PAGE_SIZE;
|
||||
EE_Status result = EE_NOT_FOUND;
|
||||
uint16_t lastVal = 0;
|
||||
|
||||
if (Data == NULL)
|
||||
return EE_ERROR;
|
||||
|
||||
while (addr <= (pageEnd - sizeof(EE_Record_t)))
|
||||
{
|
||||
uint16_t vaddr = *(__IO uint16_t *)addr;
|
||||
|
||||
if (vaddr == 0xFFFFU)
|
||||
{
|
||||
// First empty slot => no more records in this page
|
||||
break;
|
||||
}
|
||||
|
||||
uint16_t value = *(__IO uint16_t *)(addr + 2U);
|
||||
|
||||
if (vaddr == VirtAddress)
|
||||
{
|
||||
lastVal = value; // keep most recent
|
||||
result = EE_OK;
|
||||
}
|
||||
|
||||
addr += sizeof(EE_Record_t); // move 4 bytes forward
|
||||
}
|
||||
|
||||
if (result == EE_OK)
|
||||
*Data = lastVal;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Format both pages: erase and set PAGE0 as VALID */
|
||||
static EE_Status EE_Format(void)
|
||||
{
|
||||
if (EE_FlashErasePage(EE_PAGE0_BASE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
if (EE_FlashErasePage(EE_PAGE1_BASE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
if (EE_FlashProgramHalfWord(EE_PAGE0_BASE, EE_PAGE_STATUS_VALID) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* PAGE1 will remain erased (status = 0xFFFF) */
|
||||
EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
|
||||
return EE_STATUS_OK;
|
||||
}
|
||||
|
||||
/* Get the base of the other page */
|
||||
static uint32_t EE_GetOtherPageBase(uint32_t pageBase)
|
||||
{
|
||||
return (pageBase == EE_PAGE0_BASE) ? EE_PAGE1_BASE : EE_PAGE0_BASE;
|
||||
}
|
||||
|
||||
/* Page transfer (garbage collection + new write) */
|
||||
static EE_Status EE_PageTransfer(uint16_t VirtAddress, uint16_t Data)
|
||||
{
|
||||
uint32_t oldBase = EE_ActivePageBase;
|
||||
uint32_t newBase = EE_GetOtherPageBase(oldBase);
|
||||
uint32_t addr;
|
||||
uint16_t value;
|
||||
EE_Status st;
|
||||
|
||||
/* Erase new page */
|
||||
if (EE_FlashErasePage(newBase) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Mark new page as RECEIVE */
|
||||
if (EE_FlashProgramHalfWord(newBase, EE_PAGE_STATUS_RECEIVE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Start writing records just after status */
|
||||
addr = newBase + 2U;
|
||||
|
||||
/* For each known virtual variable */
|
||||
for (uint16_t i = 0; i < EE_NUM_VIRTUAL_ADDR; i++)
|
||||
{
|
||||
uint16_t vaddr = EE_VirtAddrs[i];
|
||||
|
||||
if (vaddr == VirtAddress)
|
||||
{
|
||||
/* Use the new data passed into PageTransfer */
|
||||
value = Data;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Read latest value from old active page */
|
||||
st = EE_FindInPage(oldBase, vaddr, &value);
|
||||
if (st != EE_STATUS_OK)
|
||||
{
|
||||
/* Variable never written -> skip */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Write record to new page */
|
||||
if (EE_FlashProgramHalfWord(addr, vaddr) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
if (EE_FlashProgramHalfWord(addr + 2U, value) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
addr += sizeof(EE_Record_t);
|
||||
if (addr >= (newBase + EE_PAGE_SIZE))
|
||||
return EE_STATUS_NO_SPACE;
|
||||
}
|
||||
|
||||
/* Erase old page */
|
||||
if (EE_FlashErasePage(oldBase) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Mark new page as VALID */
|
||||
if (EE_FlashProgramHalfWord(newBase, EE_PAGE_STATUS_VALID) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Update active page */
|
||||
EE_ActivePageBase = newBase;
|
||||
|
||||
return EE_STATUS_OK;
|
||||
}
|
||||
|
||||
/* --- Public API ----------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* Initialize the EEPROM emulation.
|
||||
* - Checks page statuses and chooses the active page.
|
||||
* - If inconsistent or blank, formats pages.
|
||||
* PUBLIC RETURN TYPE: uint16_t (EE_OK / EE_ERROR / ...)
|
||||
*/
|
||||
uint16_t EE_Init(void)
|
||||
{
|
||||
uint16_t status0 = EE_GetPageStatus(EE_PAGE0_BASE);
|
||||
uint16_t status1 = EE_GetPageStatus(EE_PAGE1_BASE);
|
||||
|
||||
if ((status0 == EE_PAGE_STATUS_ERASED) && (status1 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
/* Fresh device -> format */
|
||||
return (uint16_t)EE_Format();
|
||||
}
|
||||
else if ((status0 == EE_PAGE_STATUS_VALID) && (status1 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
return EE_OK;
|
||||
}
|
||||
else if ((status1 == EE_PAGE_STATUS_VALID) && (status0 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
EE_ActivePageBase = EE_PAGE1_BASE;
|
||||
return EE_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Any weird or inconsistent state -> reformat */
|
||||
return (uint16_t)EE_Format();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a 16-bit variable by its virtual address.
|
||||
* PUBLIC RETURN: EE_OK / EE_NOT_FOUND / EE_ERROR (as uint16_t)
|
||||
*/
|
||||
uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t *Data)
|
||||
{
|
||||
EE_Status st;
|
||||
|
||||
if (Data == NULL)
|
||||
return EE_ERROR;
|
||||
|
||||
st = EE_FindInPage(EE_ActivePageBase, VirtAddress, Data);
|
||||
return (uint16_t)st;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write (append) a 16-bit variable.
|
||||
* - Writes a new record in the active page.
|
||||
* - If the page is full, triggers a page transfer (GC).
|
||||
* PUBLIC RETURN: EE_OK / EE_ERROR / EE_NO_SPACE (as uint16_t)
|
||||
*/
|
||||
uint16_t EE_WriteVariable(uint16_t VirtAddress, uint16_t Data)
|
||||
{
|
||||
uint32_t freeAddr;
|
||||
EE_Status st;
|
||||
|
||||
/* Find free space in active page */
|
||||
freeAddr = EE_FindFreeAddress(EE_ActivePageBase);
|
||||
if (freeAddr != 0U)
|
||||
{
|
||||
/* Write new record */
|
||||
if (EE_FlashProgramHalfWord(freeAddr, VirtAddress) != HAL_OK)
|
||||
return EE_ERROR;
|
||||
if (EE_FlashProgramHalfWord(freeAddr + 2U, Data) != HAL_OK)
|
||||
return EE_ERROR;
|
||||
|
||||
return EE_OK;
|
||||
}
|
||||
|
||||
/* No space -> page transfer */
|
||||
st = EE_PageTransfer(VirtAddress, Data);
|
||||
return (uint16_t)st;
|
||||
}
|
||||
|
||||
void loadEE(void){
|
||||
char s [200];
|
||||
EEW_Read(M1PWMAP, &m1pwmap);
|
||||
EEW_Read(M1PWMCH, &m1pwmch);
|
||||
EEW_Read(M2PWMAP, &m2pwmap);
|
||||
EEW_Read(M2PWMCH, &m2pwmch);
|
||||
EEW_Read(M3PWMAP, &m3pwmap);
|
||||
EEW_Read(M3PWMCH, &m3pwmch);
|
||||
EEW_Read(M4PWMAP, &m4pwmap);
|
||||
EEW_Read(M4PWMCH, &m4pwmch);
|
||||
EEW_Read(T1AP, &t1ap);
|
||||
EEW_Read(T2AP, &t2ap);
|
||||
EEW_Read(T3AP, &t3ap);
|
||||
EEW_Read(T4AP, &t4ap);
|
||||
EEW_Read(TWAP, &twap);
|
||||
EEW_Read(T1CH, &t1ch);
|
||||
EEW_Read(T2CH, &t2ch);
|
||||
EEW_Read(T3CH, &t3ch);
|
||||
EEW_Read(T4CH, &t4ch);
|
||||
EEW_Read(TWCH, &twch);
|
||||
EEW_Read(TRAMP1, &tramp1);
|
||||
EEW_Read(M1PWMMAN, &m1pwmMan);
|
||||
EEW_Read(M2PWMMAN, &m2pwmMan);
|
||||
EEW_Read(M3PWMMAN, &m3pwmMan);
|
||||
EEW_Read(M4PWMMAN, &m4pwmMan);
|
||||
EEW_Read(TRAMPMAN, &trampman);
|
||||
EEW_Read(TRAMP, &tramp);
|
||||
|
||||
EEW_Read(APM1START,&apM1start);
|
||||
EEW_Read(APM1STOP ,&apM1stop);
|
||||
EEW_Read(APM2START,&apM2start);
|
||||
EEW_Read(APM2STOP ,&apM2stop);
|
||||
EEW_Read(APM3START,&apM3start);
|
||||
EEW_Read(APM3STOP ,&apM3stop);
|
||||
EEW_Read(APM4START,&apM4start);
|
||||
EEW_Read(APM4STOP ,&apM4stop);
|
||||
EEW_Read(CHM1START,&chM1start);
|
||||
EEW_Read(CHM1STOP ,&chM1stop);
|
||||
EEW_Read(CHM2START,&chM2start);
|
||||
EEW_Read(CHM2STOP ,&chM2stop);
|
||||
EEW_Read(CHM3START,&chM3start);
|
||||
EEW_Read(CHM3STOP ,&chM3stop);
|
||||
EEW_Read(CHM4START,&chM4start);
|
||||
EEW_Read(CHM4STOP ,&chM4stop);
|
||||
|
||||
sprintf((char*)s,"LoadEE\n");
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
sprintf((char*)s,"\nm1pwmap=%d m1pwmch=%d m2pwmap=%d m2pwmch=%d m3pwmap=%d m3pwmch=%d m4pwmap=%d m4pwmch=%d",m1pwmap,m1pwmch,m2pwmap,m2pwmch,m3pwmap,m3pwmch,m4pwmap, m4pwmch);
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
|
||||
sprintf((char*)s,"\ntramp=%d trampman=%d",tramp,trampman);
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
sprintf((char*)s,"\nm1pwmMan=%d m2pwmMan=%d m3pwmMan=%d m4pwmMan=%d",m1pwmMan,m2pwmMan,m3pwmMan,m4pwmMan);
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,469 @@
|
||||
#include "eeprom.h"
|
||||
|
||||
/*
|
||||
* Record format (4 bytes):
|
||||
* [0] VirtAddress (uint16_t)
|
||||
* [2] Data (uint16_t)
|
||||
*
|
||||
* Page layout:
|
||||
* [0] PageStatus (uint16_t)
|
||||
* [2..] Records...
|
||||
*/
|
||||
|
||||
extern uint16_t m1pwmap;
|
||||
extern uint16_t m1pwmch;
|
||||
extern uint16_t m2pwmap;
|
||||
extern uint16_t m2pwmch;
|
||||
extern uint16_t m3pwmap;
|
||||
extern uint16_t m3pwmch;
|
||||
extern uint16_t m4pwmap;
|
||||
extern uint16_t m4pwmch;
|
||||
extern uint16_t t1ap;
|
||||
extern uint16_t t2ap;
|
||||
extern uint16_t t3ap;
|
||||
extern uint16_t t4ap;
|
||||
extern uint16_t twap;
|
||||
extern uint16_t tramp;
|
||||
extern uint16_t t1ch;
|
||||
extern uint16_t t2ch;
|
||||
extern uint16_t t3ch;
|
||||
extern uint16_t t4ch;
|
||||
extern uint16_t twch;
|
||||
extern uint16_t tramp1;
|
||||
extern uint16_t trampman;
|
||||
extern uint16_t m1pwmMan;
|
||||
extern uint16_t m2pwmMan;
|
||||
extern uint16_t m3pwmMan;
|
||||
extern uint16_t m4pwmMan;
|
||||
|
||||
|
||||
extern uint16_t apM1start;
|
||||
extern uint16_t apM1stop;
|
||||
extern uint16_t apM2start;
|
||||
extern uint16_t apM2stop;
|
||||
extern uint16_t apM3start;
|
||||
extern uint16_t apM3stop;
|
||||
extern uint16_t apM4start;
|
||||
extern uint16_t apM4stop;
|
||||
extern uint16_t chM1start;
|
||||
extern uint16_t chM1stop;
|
||||
extern uint16_t chM2start;
|
||||
extern uint16_t chM2stop;
|
||||
extern uint16_t chM3start;
|
||||
extern uint16_t chM3stop;
|
||||
extern uint16_t chM4start;
|
||||
extern uint16_t chM4stop;
|
||||
|
||||
const uint8_t deftab[EE_NUM_VIRTUAL_ADDR]={
|
||||
40, //m1pwmap
|
||||
60, //m1pwmch
|
||||
70, //m2pwmap
|
||||
70, //m2pwmch
|
||||
35, //m3pwmap
|
||||
40, //m3pwmch
|
||||
40, //m4pwmap
|
||||
40, //m4pwmch
|
||||
20, //m1rampstart
|
||||
20, //m2rampstart
|
||||
20, //m3rampstart
|
||||
20, //m4rampstart
|
||||
28, //t1ap
|
||||
4, //t2ap
|
||||
10, //t3ap
|
||||
40, //t4ap
|
||||
1, //twap
|
||||
27, //t1ch
|
||||
10, //t2ch
|
||||
30, //t3ch
|
||||
1, //t4ch
|
||||
1, //twch
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
100, //tramp1
|
||||
60, //m1pwmMan
|
||||
70, //m2pwmMan
|
||||
40, //m3pwmMan
|
||||
40, //m4pwmMan
|
||||
50, //trampman
|
||||
10, //tramp
|
||||
0, //apM1start;
|
||||
0, //apM1stop;
|
||||
0, //apM2start;
|
||||
0, //apM2stop;
|
||||
0, //apM3start;
|
||||
0, //apM3stop;
|
||||
0, //apM4start;
|
||||
0, //apM4stop;
|
||||
0, //chM1start;
|
||||
0, //chM1stop;
|
||||
0, //chM2start;
|
||||
0, //chM2stop;
|
||||
0, //chM3start;
|
||||
0, //chM3stop;
|
||||
0, //chM4start;
|
||||
0, //chM4stop;
|
||||
1,
|
||||
27,
|
||||
10,
|
||||
30,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
100,
|
||||
60,
|
||||
70,
|
||||
40,
|
||||
40,
|
||||
50,
|
||||
10,
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t VirtAddress;
|
||||
uint16_t Data;
|
||||
} EE_Record_t;
|
||||
|
||||
/* Active page base address (runtime selected in EE_Init) */
|
||||
static uint32_t EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
|
||||
/* 32 sequential virtual addresses */
|
||||
const uint16_t EE_VirtAddrs[EE_NUM_VIRTUAL_ADDR] =
|
||||
{
|
||||
0x0001, 0x0002, 0x0003, 0x0004,
|
||||
0x0005, 0x0006, 0x0007, 0x0008,
|
||||
0x0009, 0x000A, 0x000B, 0x000C,
|
||||
0x000D, 0x000E, 0x000F, 0x0010,
|
||||
0x0011, 0x0012, 0x0013, 0x0014,
|
||||
0x0015, 0x0016, 0x0017, 0x0018,
|
||||
0x0019, 0x001A, 0x001B, 0x001C,
|
||||
0x001D, 0x001E, 0x001F, 0x0020,
|
||||
|
||||
0x0021, 0x0022, 0x0023, 0x0024,
|
||||
0x0025, 0x0026, 0x0027, 0x0028,
|
||||
0x0029, 0x002A, 0x002B, 0x002C,
|
||||
0x002D, 0x002E, 0x002F, 0x0030,
|
||||
0x0031, 0x0032, 0x0033, 0x0034,
|
||||
0x0035, 0x0036, 0x0037, 0x0038,
|
||||
0x0039, 0x003A, 0x003B, 0x003C,
|
||||
0x003D, 0x003E, 0x003F, 0x0040
|
||||
};
|
||||
/* ========================================================================= */
|
||||
|
||||
/* --- Internal helpers ---------------------------------------------------- */
|
||||
|
||||
static uint16_t EE_GetPageStatus(uint32_t pageBase)
|
||||
{
|
||||
return *(__IO uint16_t *)pageBase;
|
||||
}
|
||||
|
||||
static HAL_StatusTypeDef EE_FlashProgramHalfWord(uint32_t Address, uint16_t Data)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
|
||||
HAL_FLASH_Unlock();
|
||||
status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, Address, Data);
|
||||
HAL_FLASH_Lock();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static HAL_StatusTypeDef EE_FlashErasePage(uint32_t PageAddress)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
FLASH_EraseInitTypeDef EraseInit;
|
||||
uint32_t PageError = 0;
|
||||
|
||||
HAL_FLASH_Unlock();
|
||||
|
||||
EraseInit.TypeErase = FLASH_TYPEERASE_PAGES;
|
||||
EraseInit.PageAddress = PageAddress;
|
||||
EraseInit.NbPages = 1;
|
||||
|
||||
status = HAL_FLASHEx_Erase(&EraseInit, &PageError);
|
||||
|
||||
HAL_FLASH_Lock();
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Find first free record address in given page (returns 0 if full) */
|
||||
static uint32_t EE_FindFreeAddress(uint32_t pageBase)
|
||||
{
|
||||
uint32_t addr = pageBase + 2U; /* Skip status word */
|
||||
uint32_t pageEnd = pageBase + EE_PAGE_SIZE;
|
||||
|
||||
while (addr < (pageEnd - sizeof(EE_Record_t) + 1U))
|
||||
{
|
||||
uint16_t vaddr = *(__IO uint16_t *)addr;
|
||||
|
||||
if (vaddr == 0xFFFFU)
|
||||
{
|
||||
/* Empty slot */
|
||||
return addr;
|
||||
}
|
||||
addr += sizeof(EE_Record_t);
|
||||
}
|
||||
|
||||
return 0U; /* No space */
|
||||
}
|
||||
|
||||
/* Find latest value of VirtAddress in a specific page (internal, uses EE_Status) */
|
||||
/* Find latest value of VirtAddress in a specific page (scan forward) */
|
||||
static EE_Status EE_FindInPage(uint32_t pageBase, uint16_t VirtAddress, uint16_t *Data)
|
||||
{
|
||||
uint32_t addr = pageBase + 2U; // skip status halfword
|
||||
uint32_t pageEnd = pageBase + EE_PAGE_SIZE;
|
||||
EE_Status result = EE_NOT_FOUND;
|
||||
uint16_t lastVal = 0;
|
||||
|
||||
if (Data == NULL)
|
||||
return EE_ERROR;
|
||||
|
||||
while (addr <= (pageEnd - sizeof(EE_Record_t)))
|
||||
{
|
||||
uint16_t vaddr = *(__IO uint16_t *)addr;
|
||||
|
||||
if (vaddr == 0xFFFFU)
|
||||
{
|
||||
// First empty slot => no more records in this page
|
||||
break;
|
||||
}
|
||||
|
||||
uint16_t value = *(__IO uint16_t *)(addr + 2U);
|
||||
|
||||
if (vaddr == VirtAddress)
|
||||
{
|
||||
lastVal = value; // keep most recent
|
||||
result = EE_OK;
|
||||
}
|
||||
|
||||
addr += sizeof(EE_Record_t); // move 4 bytes forward
|
||||
}
|
||||
|
||||
if (result == EE_OK)
|
||||
*Data = lastVal;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Format both pages: erase and set PAGE0 as VALID */
|
||||
static EE_Status EE_Format(void)
|
||||
{
|
||||
if (EE_FlashErasePage(EE_PAGE0_BASE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
if (EE_FlashErasePage(EE_PAGE1_BASE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
if (EE_FlashProgramHalfWord(EE_PAGE0_BASE, EE_PAGE_STATUS_VALID) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* PAGE1 will remain erased (status = 0xFFFF) */
|
||||
EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
|
||||
return EE_STATUS_OK;
|
||||
}
|
||||
|
||||
/* Get the base of the other page */
|
||||
static uint32_t EE_GetOtherPageBase(uint32_t pageBase)
|
||||
{
|
||||
return (pageBase == EE_PAGE0_BASE) ? EE_PAGE1_BASE : EE_PAGE0_BASE;
|
||||
}
|
||||
|
||||
/* Page transfer (garbage collection + new write) */
|
||||
static EE_Status EE_PageTransfer(uint16_t VirtAddress, uint16_t Data)
|
||||
{
|
||||
uint32_t oldBase = EE_ActivePageBase;
|
||||
uint32_t newBase = EE_GetOtherPageBase(oldBase);
|
||||
uint32_t addr;
|
||||
uint16_t value;
|
||||
EE_Status st;
|
||||
|
||||
/* Erase new page */
|
||||
if (EE_FlashErasePage(newBase) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Mark new page as RECEIVE */
|
||||
if (EE_FlashProgramHalfWord(newBase, EE_PAGE_STATUS_RECEIVE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Start writing records just after status */
|
||||
addr = newBase + 2U;
|
||||
|
||||
/* For each known virtual variable */
|
||||
for (uint16_t i = 0; i < EE_NUM_VIRTUAL_ADDR; i++)
|
||||
{
|
||||
uint16_t vaddr = EE_VirtAddrs[i];
|
||||
|
||||
if (vaddr == VirtAddress)
|
||||
{
|
||||
/* Use the new data passed into PageTransfer */
|
||||
value = Data;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Read latest value from old active page */
|
||||
st = EE_FindInPage(oldBase, vaddr, &value);
|
||||
if (st != EE_STATUS_OK)
|
||||
{
|
||||
/* Variable never written -> skip */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Write record to new page */
|
||||
if (EE_FlashProgramHalfWord(addr, vaddr) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
if (EE_FlashProgramHalfWord(addr + 2U, value) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
addr += sizeof(EE_Record_t);
|
||||
if (addr >= (newBase + EE_PAGE_SIZE))
|
||||
return EE_STATUS_NO_SPACE;
|
||||
}
|
||||
|
||||
/* Erase old page */
|
||||
if (EE_FlashErasePage(oldBase) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Mark new page as VALID */
|
||||
if (EE_FlashProgramHalfWord(newBase, EE_PAGE_STATUS_VALID) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Update active page */
|
||||
EE_ActivePageBase = newBase;
|
||||
|
||||
return EE_STATUS_OK;
|
||||
}
|
||||
|
||||
/* --- Public API ----------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* Initialize the EEPROM emulation.
|
||||
* - Checks page statuses and chooses the active page.
|
||||
* - If inconsistent or blank, formats pages.
|
||||
* PUBLIC RETURN TYPE: uint16_t (EE_OK / EE_ERROR / ...)
|
||||
*/
|
||||
uint16_t EE_Init(void)
|
||||
{
|
||||
uint16_t status0 = EE_GetPageStatus(EE_PAGE0_BASE);
|
||||
uint16_t status1 = EE_GetPageStatus(EE_PAGE1_BASE);
|
||||
|
||||
if ((status0 == EE_PAGE_STATUS_ERASED) && (status1 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
/* Fresh device -> format */
|
||||
return (uint16_t)EE_Format();
|
||||
}
|
||||
else if ((status0 == EE_PAGE_STATUS_VALID) && (status1 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
return EE_OK;
|
||||
}
|
||||
else if ((status1 == EE_PAGE_STATUS_VALID) && (status0 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
EE_ActivePageBase = EE_PAGE1_BASE;
|
||||
return EE_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Any weird or inconsistent state -> reformat */
|
||||
return (uint16_t)EE_Format();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a 16-bit variable by its virtual address.
|
||||
* PUBLIC RETURN: EE_OK / EE_NOT_FOUND / EE_ERROR (as uint16_t)
|
||||
*/
|
||||
uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t *Data)
|
||||
{
|
||||
EE_Status st;
|
||||
|
||||
if (Data == NULL)
|
||||
return EE_ERROR;
|
||||
|
||||
st = EE_FindInPage(EE_ActivePageBase, VirtAddress, Data);
|
||||
return (uint16_t)st;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write (append) a 16-bit variable.
|
||||
* - Writes a new record in the active page.
|
||||
* - If the page is full, triggers a page transfer (GC).
|
||||
* PUBLIC RETURN: EE_OK / EE_ERROR / EE_NO_SPACE (as uint16_t)
|
||||
*/
|
||||
uint16_t EE_WriteVariable(uint16_t VirtAddress, uint16_t Data)
|
||||
{
|
||||
uint32_t freeAddr;
|
||||
EE_Status st;
|
||||
|
||||
/* Find free space in active page */
|
||||
freeAddr = EE_FindFreeAddress(EE_ActivePageBase);
|
||||
if (freeAddr != 0U)
|
||||
{
|
||||
/* Write new record */
|
||||
if (EE_FlashProgramHalfWord(freeAddr, VirtAddress) != HAL_OK)
|
||||
return EE_ERROR;
|
||||
if (EE_FlashProgramHalfWord(freeAddr + 2U, Data) != HAL_OK)
|
||||
return EE_ERROR;
|
||||
|
||||
return EE_OK;
|
||||
}
|
||||
|
||||
/* No space -> page transfer */
|
||||
st = EE_PageTransfer(VirtAddress, Data);
|
||||
return (uint16_t)st;
|
||||
}
|
||||
|
||||
void loadEE(void){
|
||||
EEW_Read(M1PWMAP, &m1pwmap);
|
||||
EEW_Read(M1PWMCH, &m1pwmch);
|
||||
EEW_Read(M2PWMAP, &m2pwmap);
|
||||
EEW_Read(M2PWMCH, &m2pwmch);
|
||||
EEW_Read(M3PWMAP, &m3pwmap);
|
||||
EEW_Read(M3PWMCH, &m3pwmch);
|
||||
EEW_Read(M4PWMAP, &m4pwmap);
|
||||
EEW_Read(M4PWMCH, &m4pwmch);
|
||||
EEW_Read(T1AP, &t1ap);
|
||||
EEW_Read(T2AP, &t2ap);
|
||||
EEW_Read(T3AP, &t3ap);
|
||||
EEW_Read(T4AP, &t4ap);
|
||||
EEW_Read(TWAP, &twap);
|
||||
EEW_Read(T1CH, &t1ch);
|
||||
EEW_Read(T2CH, &t2ch);
|
||||
EEW_Read(T3CH, &t3ch);
|
||||
EEW_Read(T4CH, &t4ch);
|
||||
EEW_Read(TWCH, &twch);
|
||||
EEW_Read(TRAMP1, &tramp1);
|
||||
EEW_Read(M1PWMMAN, &m1pwmMan);
|
||||
EEW_Read(M2PWMMAN, &m2pwmMan);
|
||||
EEW_Read(M3PWMMAN, &m3pwmMan);
|
||||
EEW_Read(M4PWMMAN, &m4pwmMan);
|
||||
EEW_Read(TRAMPMAN, &trampman);
|
||||
EEW_Read(TRAMP, &tramp);
|
||||
|
||||
EEW_Read(APM1START,apM1start);
|
||||
EEW_Read(APM1STOP ,apM1stop);
|
||||
EEW_Read(APM2START,apM2start);
|
||||
EEW_Read(APM2STOP ,apM2stop);
|
||||
EEW_Read(APM3START,apM3start);
|
||||
EEW_Read(APM3STOP ,apM3stop);
|
||||
EEW_Read(APM4START,apM4start);
|
||||
EEW_Read(APM4STOP ,apM4stop);
|
||||
EEW_Read(CHM1START,chM1start);
|
||||
EEW_Read(CHM1STOP ,chM1stop);
|
||||
EEW_Read(CHM2START,chM2start);
|
||||
EEW_Read(CHM2STOP ,chM2stop);
|
||||
EEW_Read(CHM3START,chM3start);
|
||||
EEW_Read(CHM3STOP ,chM3stop);
|
||||
EEW_Read(CHM4START,chM4start);
|
||||
EEW_Read(CHM4STOP ,chM4stop);
|
||||
|
||||
sprintf((char*)s,"LoadEE\n");
|
||||
while (CDC_Transmit_FS(s, 6) == USBD_BUSY);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,480 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "eeprom.h"
|
||||
extern UART_HandleTypeDef huart1;
|
||||
/*
|
||||
* Record format (4 bytes):
|
||||
* [0] VirtAddress (uint16_t)
|
||||
* [2] Data (uint16_t)
|
||||
*
|
||||
* Page layout:
|
||||
* [0] PageStatus (uint16_t)
|
||||
* [2..] Records...
|
||||
*/
|
||||
|
||||
extern uint16_t m1pwmap;
|
||||
extern uint16_t m1pwmch;
|
||||
extern uint16_t m2pwmap;
|
||||
extern uint16_t m2pwmch;
|
||||
extern uint16_t m3pwmap;
|
||||
extern uint16_t m3pwmch;
|
||||
extern uint16_t m4pwmap;
|
||||
extern uint16_t m4pwmch;
|
||||
extern uint16_t t1ap;
|
||||
extern uint16_t t2ap;
|
||||
extern uint16_t t3ap;
|
||||
extern uint16_t t4ap;
|
||||
extern uint16_t twap;
|
||||
extern uint16_t tramp;
|
||||
extern uint16_t t1ch;
|
||||
extern uint16_t t2ch;
|
||||
extern uint16_t t3ch;
|
||||
extern uint16_t t4ch;
|
||||
extern uint16_t twch;
|
||||
extern uint16_t tramp1;
|
||||
extern uint16_t trampman;
|
||||
extern uint16_t m1pwmMan;
|
||||
extern uint16_t m2pwmMan;
|
||||
extern uint16_t m3pwmMan;
|
||||
extern uint16_t m4pwmMan;
|
||||
|
||||
|
||||
extern uint16_t apM1start;
|
||||
extern uint16_t apM1stop;
|
||||
extern uint16_t apM2start;
|
||||
extern uint16_t apM2stop;
|
||||
extern uint16_t apM3start;
|
||||
extern uint16_t apM3stop;
|
||||
extern uint16_t apM4start;
|
||||
extern uint16_t apM4stop;
|
||||
extern uint16_t chM1start;
|
||||
extern uint16_t chM1stop;
|
||||
extern uint16_t chM2start;
|
||||
extern uint16_t chM2stop;
|
||||
extern uint16_t chM3start;
|
||||
extern uint16_t chM3stop;
|
||||
extern uint16_t chM4start;
|
||||
extern uint16_t chM4stop;
|
||||
|
||||
const uint8_t deftab[EE_NUM_VIRTUAL_ADDR]={
|
||||
40, //m1pwmap
|
||||
60, //m1pwmch
|
||||
70, //m2pwmap
|
||||
70, //m2pwmch
|
||||
35, //m3pwmap
|
||||
40, //m3pwmch
|
||||
40, //m4pwmap
|
||||
40, //m4pwmch
|
||||
20, //m1rampstart
|
||||
20, //m2rampstart
|
||||
20, //m3rampstart
|
||||
20, //m4rampstart
|
||||
28, //t1ap
|
||||
4, //t2ap
|
||||
10, //t3ap
|
||||
40, //t4ap
|
||||
1, //twap
|
||||
27, //t1ch
|
||||
10, //t2ch
|
||||
30, //t3ch
|
||||
1, //t4ch
|
||||
1, //twch
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
100, //tramp1
|
||||
60, //m1pwmMan
|
||||
70, //m2pwmMan
|
||||
40, //m3pwmMan
|
||||
40, //m4pwmMan
|
||||
50, //trampman
|
||||
10, //tramp
|
||||
310, //apM1start;
|
||||
450, //apM1stop;
|
||||
30, //apM2start;
|
||||
310, //apM2stop;
|
||||
350, //apM3start;
|
||||
450, //apM3stop;
|
||||
450, //apM4start;
|
||||
850, //apM4stop;
|
||||
10, //chM1start;
|
||||
280, //chM1stop;
|
||||
0, //chM2start;
|
||||
0, //chM2stop;
|
||||
20, //chM3start;
|
||||
280, //chM3stop;
|
||||
0, //chM4start;
|
||||
0, //chM4stop;
|
||||
1,
|
||||
27,
|
||||
10,
|
||||
30,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
100,
|
||||
60,
|
||||
70,
|
||||
40,
|
||||
40,
|
||||
50,
|
||||
10,
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t VirtAddress;
|
||||
uint16_t Data;
|
||||
} EE_Record_t;
|
||||
|
||||
/* Active page base address (runtime selected in EE_Init) */
|
||||
static uint32_t EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
|
||||
/* 32 sequential virtual addresses */
|
||||
const uint16_t EE_VirtAddrs[EE_NUM_VIRTUAL_ADDR] =
|
||||
{
|
||||
0x0001, 0x0002, 0x0003, 0x0004,
|
||||
0x0005, 0x0006, 0x0007, 0x0008,
|
||||
0x0009, 0x000A, 0x000B, 0x000C,
|
||||
0x000D, 0x000E, 0x000F, 0x0010,
|
||||
0x0011, 0x0012, 0x0013, 0x0014,
|
||||
0x0015, 0x0016, 0x0017, 0x0018,
|
||||
0x0019, 0x001A, 0x001B, 0x001C,
|
||||
0x001D, 0x001E, 0x001F, 0x0020,
|
||||
|
||||
0x0021, 0x0022, 0x0023, 0x0024,
|
||||
0x0025, 0x0026, 0x0027, 0x0028,
|
||||
0x0029, 0x002A, 0x002B, 0x002C,
|
||||
0x002D, 0x002E, 0x002F, 0x0030,
|
||||
0x0031, 0x0032, 0x0033, 0x0034,
|
||||
0x0035, 0x0036, 0x0037, 0x0038,
|
||||
0x0039, 0x003A, 0x003B, 0x003C,
|
||||
0x003D, 0x003E, 0x003F, 0x0040
|
||||
};
|
||||
/* ========================================================================= */
|
||||
|
||||
/* --- Internal helpers ---------------------------------------------------- */
|
||||
|
||||
static uint16_t EE_GetPageStatus(uint32_t pageBase)
|
||||
{
|
||||
return *(__IO uint16_t *)pageBase;
|
||||
}
|
||||
|
||||
static HAL_StatusTypeDef EE_FlashProgramHalfWord(uint32_t Address, uint16_t Data)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
|
||||
HAL_FLASH_Unlock();
|
||||
status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, Address, Data);
|
||||
HAL_FLASH_Lock();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static HAL_StatusTypeDef EE_FlashErasePage(uint32_t PageAddress)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
FLASH_EraseInitTypeDef EraseInit;
|
||||
uint32_t PageError = 0;
|
||||
|
||||
HAL_FLASH_Unlock();
|
||||
|
||||
EraseInit.TypeErase = FLASH_TYPEERASE_PAGES;
|
||||
EraseInit.PageAddress = PageAddress;
|
||||
EraseInit.NbPages = 1;
|
||||
|
||||
status = HAL_FLASHEx_Erase(&EraseInit, &PageError);
|
||||
|
||||
HAL_FLASH_Lock();
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Find first free record address in given page (returns 0 if full) */
|
||||
static uint32_t EE_FindFreeAddress(uint32_t pageBase)
|
||||
{
|
||||
uint32_t addr = pageBase + 2U; /* Skip status word */
|
||||
uint32_t pageEnd = pageBase + EE_PAGE_SIZE;
|
||||
|
||||
while (addr < (pageEnd - sizeof(EE_Record_t) + 1U))
|
||||
{
|
||||
uint16_t vaddr = *(__IO uint16_t *)addr;
|
||||
|
||||
if (vaddr == 0xFFFFU)
|
||||
{
|
||||
/* Empty slot */
|
||||
return addr;
|
||||
}
|
||||
addr += sizeof(EE_Record_t);
|
||||
}
|
||||
|
||||
return 0U; /* No space */
|
||||
}
|
||||
|
||||
/* Find latest value of VirtAddress in a specific page (internal, uses EE_Status) */
|
||||
/* Find latest value of VirtAddress in a specific page (scan forward) */
|
||||
static EE_Status EE_FindInPage(uint32_t pageBase, uint16_t VirtAddress, uint16_t *Data)
|
||||
{
|
||||
uint32_t addr = pageBase + 2U; // skip status halfword
|
||||
uint32_t pageEnd = pageBase + EE_PAGE_SIZE;
|
||||
EE_Status result = EE_NOT_FOUND;
|
||||
uint16_t lastVal = 0;
|
||||
|
||||
if (Data == NULL)
|
||||
return EE_ERROR;
|
||||
|
||||
while (addr <= (pageEnd - sizeof(EE_Record_t)))
|
||||
{
|
||||
uint16_t vaddr = *(__IO uint16_t *)addr;
|
||||
|
||||
if (vaddr == 0xFFFFU)
|
||||
{
|
||||
// First empty slot => no more records in this page
|
||||
break;
|
||||
}
|
||||
|
||||
uint16_t value = *(__IO uint16_t *)(addr + 2U);
|
||||
|
||||
if (vaddr == VirtAddress)
|
||||
{
|
||||
lastVal = value; // keep most recent
|
||||
result = EE_OK;
|
||||
}
|
||||
|
||||
addr += sizeof(EE_Record_t); // move 4 bytes forward
|
||||
}
|
||||
|
||||
if (result == EE_OK)
|
||||
*Data = lastVal;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Format both pages: erase and set PAGE0 as VALID */
|
||||
static EE_Status EE_Format(void)
|
||||
{
|
||||
if (EE_FlashErasePage(EE_PAGE0_BASE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
if (EE_FlashErasePage(EE_PAGE1_BASE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
if (EE_FlashProgramHalfWord(EE_PAGE0_BASE, EE_PAGE_STATUS_VALID) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* PAGE1 will remain erased (status = 0xFFFF) */
|
||||
EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
|
||||
return EE_STATUS_OK;
|
||||
}
|
||||
|
||||
/* Get the base of the other page */
|
||||
static uint32_t EE_GetOtherPageBase(uint32_t pageBase)
|
||||
{
|
||||
return (pageBase == EE_PAGE0_BASE) ? EE_PAGE1_BASE : EE_PAGE0_BASE;
|
||||
}
|
||||
|
||||
/* Page transfer (garbage collection + new write) */
|
||||
static EE_Status EE_PageTransfer(uint16_t VirtAddress, uint16_t Data)
|
||||
{
|
||||
uint32_t oldBase = EE_ActivePageBase;
|
||||
uint32_t newBase = EE_GetOtherPageBase(oldBase);
|
||||
uint32_t addr;
|
||||
uint16_t value;
|
||||
EE_Status st;
|
||||
|
||||
/* Erase new page */
|
||||
if (EE_FlashErasePage(newBase) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Mark new page as RECEIVE */
|
||||
if (EE_FlashProgramHalfWord(newBase, EE_PAGE_STATUS_RECEIVE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Start writing records just after status */
|
||||
addr = newBase + 2U;
|
||||
|
||||
/* For each known virtual variable */
|
||||
for (uint16_t i = 0; i < EE_NUM_VIRTUAL_ADDR; i++)
|
||||
{
|
||||
uint16_t vaddr = EE_VirtAddrs[i];
|
||||
|
||||
if (vaddr == VirtAddress)
|
||||
{
|
||||
/* Use the new data passed into PageTransfer */
|
||||
value = Data;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Read latest value from old active page */
|
||||
st = EE_FindInPage(oldBase, vaddr, &value);
|
||||
if (st != EE_STATUS_OK)
|
||||
{
|
||||
/* Variable never written -> skip */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Write record to new page */
|
||||
if (EE_FlashProgramHalfWord(addr, vaddr) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
if (EE_FlashProgramHalfWord(addr + 2U, value) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
addr += sizeof(EE_Record_t);
|
||||
if (addr >= (newBase + EE_PAGE_SIZE))
|
||||
return EE_STATUS_NO_SPACE;
|
||||
}
|
||||
|
||||
/* Erase old page */
|
||||
if (EE_FlashErasePage(oldBase) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Mark new page as VALID */
|
||||
if (EE_FlashProgramHalfWord(newBase, EE_PAGE_STATUS_VALID) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Update active page */
|
||||
EE_ActivePageBase = newBase;
|
||||
|
||||
return EE_STATUS_OK;
|
||||
}
|
||||
|
||||
/* --- Public API ----------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* Initialize the EEPROM emulation.
|
||||
* - Checks page statuses and chooses the active page.
|
||||
* - If inconsistent or blank, formats pages.
|
||||
* PUBLIC RETURN TYPE: uint16_t (EE_OK / EE_ERROR / ...)
|
||||
*/
|
||||
uint16_t EE_Init(void)
|
||||
{
|
||||
uint16_t status0 = EE_GetPageStatus(EE_PAGE0_BASE);
|
||||
uint16_t status1 = EE_GetPageStatus(EE_PAGE1_BASE);
|
||||
|
||||
if ((status0 == EE_PAGE_STATUS_ERASED) && (status1 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
/* Fresh device -> format */
|
||||
return (uint16_t)EE_Format();
|
||||
}
|
||||
else if ((status0 == EE_PAGE_STATUS_VALID) && (status1 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
return EE_OK;
|
||||
}
|
||||
else if ((status1 == EE_PAGE_STATUS_VALID) && (status0 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
EE_ActivePageBase = EE_PAGE1_BASE;
|
||||
return EE_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Any weird or inconsistent state -> reformat */
|
||||
return (uint16_t)EE_Format();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a 16-bit variable by its virtual address.
|
||||
* PUBLIC RETURN: EE_OK / EE_NOT_FOUND / EE_ERROR (as uint16_t)
|
||||
*/
|
||||
uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t *Data)
|
||||
{
|
||||
EE_Status st;
|
||||
|
||||
if (Data == NULL)
|
||||
return EE_ERROR;
|
||||
|
||||
st = EE_FindInPage(EE_ActivePageBase, VirtAddress, Data);
|
||||
return (uint16_t)st;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write (append) a 16-bit variable.
|
||||
* - Writes a new record in the active page.
|
||||
* - If the page is full, triggers a page transfer (GC).
|
||||
* PUBLIC RETURN: EE_OK / EE_ERROR / EE_NO_SPACE (as uint16_t)
|
||||
*/
|
||||
uint16_t EE_WriteVariable(uint16_t VirtAddress, uint16_t Data)
|
||||
{
|
||||
uint32_t freeAddr;
|
||||
EE_Status st;
|
||||
|
||||
/* Find free space in active page */
|
||||
freeAddr = EE_FindFreeAddress(EE_ActivePageBase);
|
||||
if (freeAddr != 0U)
|
||||
{
|
||||
/* Write new record */
|
||||
if (EE_FlashProgramHalfWord(freeAddr, VirtAddress) != HAL_OK)
|
||||
return EE_ERROR;
|
||||
if (EE_FlashProgramHalfWord(freeAddr + 2U, Data) != HAL_OK)
|
||||
return EE_ERROR;
|
||||
|
||||
return EE_OK;
|
||||
}
|
||||
|
||||
/* No space -> page transfer */
|
||||
st = EE_PageTransfer(VirtAddress, Data);
|
||||
return (uint16_t)st;
|
||||
}
|
||||
|
||||
void loadEE(void){
|
||||
char s [200];
|
||||
EEW_Read(M1PWMAP, &m1pwmap);
|
||||
EEW_Read(M1PWMCH, &m1pwmch);
|
||||
EEW_Read(M2PWMAP, &m2pwmap);
|
||||
EEW_Read(M2PWMCH, &m2pwmch);
|
||||
EEW_Read(M3PWMAP, &m3pwmap);
|
||||
EEW_Read(M3PWMCH, &m3pwmch);
|
||||
EEW_Read(M4PWMAP, &m4pwmap);
|
||||
EEW_Read(M4PWMCH, &m4pwmch);
|
||||
EEW_Read(T1AP, &t1ap);
|
||||
EEW_Read(T2AP, &t2ap);
|
||||
EEW_Read(T3AP, &t3ap);
|
||||
EEW_Read(T4AP, &t4ap);
|
||||
EEW_Read(TWAP, &twap);
|
||||
EEW_Read(T1CH, &t1ch);
|
||||
EEW_Read(T2CH, &t2ch);
|
||||
EEW_Read(T3CH, &t3ch);
|
||||
EEW_Read(T4CH, &t4ch);
|
||||
EEW_Read(TWCH, &twch);
|
||||
EEW_Read(TRAMP1, &tramp1);
|
||||
EEW_Read(M1PWMMAN, &m1pwmMan);
|
||||
EEW_Read(M2PWMMAN, &m2pwmMan);
|
||||
EEW_Read(M3PWMMAN, &m3pwmMan);
|
||||
EEW_Read(M4PWMMAN, &m4pwmMan);
|
||||
EEW_Read(TRAMPMAN, &trampman);
|
||||
EEW_Read(TRAMP, &tramp);
|
||||
|
||||
EEW_Read(APM1START,&apM1start);
|
||||
EEW_Read(APM1STOP ,&apM1stop);
|
||||
EEW_Read(APM2START,&apM2start);
|
||||
EEW_Read(APM2STOP ,&apM2stop);
|
||||
EEW_Read(APM3START,&apM3start);
|
||||
EEW_Read(APM3STOP ,&apM3stop);
|
||||
EEW_Read(APM4START,&apM4start);
|
||||
EEW_Read(APM4STOP ,&apM4stop);
|
||||
EEW_Read(CHM1START,&chM1start);
|
||||
EEW_Read(CHM1STOP ,&chM1stop);
|
||||
EEW_Read(CHM2START,&chM2start);
|
||||
EEW_Read(CHM2STOP ,&chM2stop);
|
||||
EEW_Read(CHM3START,&chM3start);
|
||||
EEW_Read(CHM3STOP ,&chM3stop);
|
||||
EEW_Read(CHM4START,&chM4start);
|
||||
EEW_Read(CHM4STOP ,&chM4stop);
|
||||
|
||||
sprintf((char*)s,"LoadEE\n");
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
sprintf((char*)s,"\nm1pwmap=%d m1pwmch=%d m2pwmap=%d m2pwmch=%d m3pwmap=%d m3pwmch=%d m4pwmap=%d m4pwmch=%d",m1pwmap,m1pwmch,m2pwmap,m2pwmch,m3pwmap,m3pwmch,m4pwmap, m4pwmch);
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
sprintf((char*)s,"\ntramp=%d trampman=%d",tramp,trampman);
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
sprintf((char*)s,"\nm1pwmMan=%d m2pwmMan=%d m3pwmMan=%d m4pwmMan=%d",m1pwmMan,m2pwmMan,m3pwmMan,m4pwmMan);
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* pwm.h
|
||||
*
|
||||
* Created on: Dec 6, 2025
|
||||
* Author: user
|
||||
*/
|
||||
|
||||
#ifndef INC_PWM_H_
|
||||
#define INC_PWM_H_
|
||||
#include <stdbool.h>
|
||||
bool IsPwmRunning(TIM_HandleTypeDef *htim, uint32_t Channel);;
|
||||
void StopMot(TIM_HandleTypeDef *htim,uint32_t Channel);
|
||||
void StartMot(TIM_HandleTypeDef *htim,uint32_t Channel,uint16_t pwmval);
|
||||
void SetMotPwm(TIM_HandleTypeDef *htim,uint32_t Channel,uint16_t pwmval);
|
||||
void SetMot(uint8_t mot,uint8_t dir,uint16_t pwmval);
|
||||
void SetMotPerc(uint8_t mot,uint8_t dir,uint8_t perc);
|
||||
uint8_t ramp(uint8_t mot,uint8_t dir,uint8_t percStart,uint8_t percEnd,uint8_t tr,uint8_t mode);
|
||||
|
||||
#define timMot1 &htim2
|
||||
#define FWMot1 TIM_CHANNEL_1
|
||||
#define BWMot1 TIM_CHANNEL_2
|
||||
|
||||
#define timMot2 &htim2
|
||||
#define FWMot2 TIM_CHANNEL_3
|
||||
#define BWMot2 TIM_CHANNEL_4
|
||||
|
||||
#define timMot3 &htim4
|
||||
#define FWMot3 TIM_CHANNEL_1
|
||||
#define BWMot3 TIM_CHANNEL_2
|
||||
|
||||
#define timMot4 &htim4
|
||||
#define FWMot4 TIM_CHANNEL_3
|
||||
#define BWMot4 TIM_CHANNEL_4
|
||||
|
||||
#define FW 0
|
||||
#define BW 1
|
||||
|
||||
#define RAMPINIT 0
|
||||
#define RAMPRUN 10
|
||||
|
||||
#define DONE 0
|
||||
#define RUNNING 1
|
||||
|
||||
#endif /* INC_PWM_H_ */
|
||||
@@ -0,0 +1,480 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "eeprom.h"
|
||||
extern UART_HandleTypeDef huart1;
|
||||
/*
|
||||
* Record format (4 bytes):
|
||||
* [0] VirtAddress (uint16_t)
|
||||
* [2] Data (uint16_t)
|
||||
*
|
||||
* Page layout:
|
||||
* [0] PageStatus (uint16_t)
|
||||
* [2..] Records...
|
||||
*/
|
||||
|
||||
extern uint16_t m1pwmap;
|
||||
extern uint16_t m1pwmch;
|
||||
extern uint16_t m2pwmap;
|
||||
extern uint16_t m2pwmch;
|
||||
extern uint16_t m3pwmap;
|
||||
extern uint16_t m3pwmch;
|
||||
extern uint16_t m4pwmap;
|
||||
extern uint16_t m4pwmch;
|
||||
extern uint16_t t1ap;
|
||||
extern uint16_t t2ap;
|
||||
extern uint16_t t3ap;
|
||||
extern uint16_t t4ap;
|
||||
extern uint16_t twap;
|
||||
extern uint16_t tramp;
|
||||
extern uint16_t t1ch;
|
||||
extern uint16_t t2ch;
|
||||
extern uint16_t t3ch;
|
||||
extern uint16_t t4ch;
|
||||
extern uint16_t twch;
|
||||
extern uint16_t tramp1;
|
||||
extern uint16_t trampman;
|
||||
extern uint16_t m1pwmMan;
|
||||
extern uint16_t m2pwmMan;
|
||||
extern uint16_t m3pwmMan;
|
||||
extern uint16_t m4pwmMan;
|
||||
|
||||
|
||||
extern uint16_t apM1start;
|
||||
extern uint16_t apM1stop;
|
||||
extern uint16_t apM2start;
|
||||
extern uint16_t apM2stop;
|
||||
extern uint16_t apM3start;
|
||||
extern uint16_t apM3stop;
|
||||
extern uint16_t apM4start;
|
||||
extern uint16_t apM4stop;
|
||||
extern uint16_t chM1start;
|
||||
extern uint16_t chM1stop;
|
||||
extern uint16_t chM2start;
|
||||
extern uint16_t chM2stop;
|
||||
extern uint16_t chM3start;
|
||||
extern uint16_t chM3stop;
|
||||
extern uint16_t chM4start;
|
||||
extern uint16_t chM4stop;
|
||||
|
||||
const uint8_t deftab[EE_NUM_VIRTUAL_ADDR]={
|
||||
40, //m1pwmap
|
||||
60, //m1pwmch
|
||||
70, //m2pwmap
|
||||
70, //m2pwmch
|
||||
35, //m3pwmap
|
||||
40, //m3pwmch
|
||||
40, //m4pwmap
|
||||
40, //m4pwmch
|
||||
20, //m1rampstart
|
||||
20, //m2rampstart
|
||||
20, //m3rampstart
|
||||
20, //m4rampstart
|
||||
28, //t1ap
|
||||
4, //t2ap
|
||||
10, //t3ap
|
||||
40, //t4ap
|
||||
1, //twap
|
||||
27, //t1ch
|
||||
10, //t2ch
|
||||
30, //t3ch
|
||||
1, //t4ch
|
||||
1, //twch
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
100, //tramp1
|
||||
60, //m1pwmMan
|
||||
70, //m2pwmMan
|
||||
40, //m3pwmMan
|
||||
40, //m4pwmMan
|
||||
50, //trampman
|
||||
10, //tramp
|
||||
310, //apM1start;
|
||||
450, //apM1stop;
|
||||
30, //apM2start;
|
||||
310, //apM2stop;
|
||||
350, //apM3start;
|
||||
450, //apM3stop;
|
||||
450, //apM4start;
|
||||
850, //apM4stop;
|
||||
0, //chM1start;
|
||||
0, //chM1stop;
|
||||
0, //chM2start;
|
||||
0, //chM2stop;
|
||||
0, //chM3start;
|
||||
0, //chM3stop;
|
||||
0, //chM4start;
|
||||
0, //chM4stop;
|
||||
1,
|
||||
27,
|
||||
10,
|
||||
30,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
100,
|
||||
60,
|
||||
70,
|
||||
40,
|
||||
40,
|
||||
50,
|
||||
10,
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t VirtAddress;
|
||||
uint16_t Data;
|
||||
} EE_Record_t;
|
||||
|
||||
/* Active page base address (runtime selected in EE_Init) */
|
||||
static uint32_t EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
|
||||
/* 32 sequential virtual addresses */
|
||||
const uint16_t EE_VirtAddrs[EE_NUM_VIRTUAL_ADDR] =
|
||||
{
|
||||
0x0001, 0x0002, 0x0003, 0x0004,
|
||||
0x0005, 0x0006, 0x0007, 0x0008,
|
||||
0x0009, 0x000A, 0x000B, 0x000C,
|
||||
0x000D, 0x000E, 0x000F, 0x0010,
|
||||
0x0011, 0x0012, 0x0013, 0x0014,
|
||||
0x0015, 0x0016, 0x0017, 0x0018,
|
||||
0x0019, 0x001A, 0x001B, 0x001C,
|
||||
0x001D, 0x001E, 0x001F, 0x0020,
|
||||
|
||||
0x0021, 0x0022, 0x0023, 0x0024,
|
||||
0x0025, 0x0026, 0x0027, 0x0028,
|
||||
0x0029, 0x002A, 0x002B, 0x002C,
|
||||
0x002D, 0x002E, 0x002F, 0x0030,
|
||||
0x0031, 0x0032, 0x0033, 0x0034,
|
||||
0x0035, 0x0036, 0x0037, 0x0038,
|
||||
0x0039, 0x003A, 0x003B, 0x003C,
|
||||
0x003D, 0x003E, 0x003F, 0x0040
|
||||
};
|
||||
/* ========================================================================= */
|
||||
|
||||
/* --- Internal helpers ---------------------------------------------------- */
|
||||
|
||||
static uint16_t EE_GetPageStatus(uint32_t pageBase)
|
||||
{
|
||||
return *(__IO uint16_t *)pageBase;
|
||||
}
|
||||
|
||||
static HAL_StatusTypeDef EE_FlashProgramHalfWord(uint32_t Address, uint16_t Data)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
|
||||
HAL_FLASH_Unlock();
|
||||
status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, Address, Data);
|
||||
HAL_FLASH_Lock();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static HAL_StatusTypeDef EE_FlashErasePage(uint32_t PageAddress)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
FLASH_EraseInitTypeDef EraseInit;
|
||||
uint32_t PageError = 0;
|
||||
|
||||
HAL_FLASH_Unlock();
|
||||
|
||||
EraseInit.TypeErase = FLASH_TYPEERASE_PAGES;
|
||||
EraseInit.PageAddress = PageAddress;
|
||||
EraseInit.NbPages = 1;
|
||||
|
||||
status = HAL_FLASHEx_Erase(&EraseInit, &PageError);
|
||||
|
||||
HAL_FLASH_Lock();
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Find first free record address in given page (returns 0 if full) */
|
||||
static uint32_t EE_FindFreeAddress(uint32_t pageBase)
|
||||
{
|
||||
uint32_t addr = pageBase + 2U; /* Skip status word */
|
||||
uint32_t pageEnd = pageBase + EE_PAGE_SIZE;
|
||||
|
||||
while (addr < (pageEnd - sizeof(EE_Record_t) + 1U))
|
||||
{
|
||||
uint16_t vaddr = *(__IO uint16_t *)addr;
|
||||
|
||||
if (vaddr == 0xFFFFU)
|
||||
{
|
||||
/* Empty slot */
|
||||
return addr;
|
||||
}
|
||||
addr += sizeof(EE_Record_t);
|
||||
}
|
||||
|
||||
return 0U; /* No space */
|
||||
}
|
||||
|
||||
/* Find latest value of VirtAddress in a specific page (internal, uses EE_Status) */
|
||||
/* Find latest value of VirtAddress in a specific page (scan forward) */
|
||||
static EE_Status EE_FindInPage(uint32_t pageBase, uint16_t VirtAddress, uint16_t *Data)
|
||||
{
|
||||
uint32_t addr = pageBase + 2U; // skip status halfword
|
||||
uint32_t pageEnd = pageBase + EE_PAGE_SIZE;
|
||||
EE_Status result = EE_NOT_FOUND;
|
||||
uint16_t lastVal = 0;
|
||||
|
||||
if (Data == NULL)
|
||||
return EE_ERROR;
|
||||
|
||||
while (addr <= (pageEnd - sizeof(EE_Record_t)))
|
||||
{
|
||||
uint16_t vaddr = *(__IO uint16_t *)addr;
|
||||
|
||||
if (vaddr == 0xFFFFU)
|
||||
{
|
||||
// First empty slot => no more records in this page
|
||||
break;
|
||||
}
|
||||
|
||||
uint16_t value = *(__IO uint16_t *)(addr + 2U);
|
||||
|
||||
if (vaddr == VirtAddress)
|
||||
{
|
||||
lastVal = value; // keep most recent
|
||||
result = EE_OK;
|
||||
}
|
||||
|
||||
addr += sizeof(EE_Record_t); // move 4 bytes forward
|
||||
}
|
||||
|
||||
if (result == EE_OK)
|
||||
*Data = lastVal;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Format both pages: erase and set PAGE0 as VALID */
|
||||
static EE_Status EE_Format(void)
|
||||
{
|
||||
if (EE_FlashErasePage(EE_PAGE0_BASE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
if (EE_FlashErasePage(EE_PAGE1_BASE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
if (EE_FlashProgramHalfWord(EE_PAGE0_BASE, EE_PAGE_STATUS_VALID) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* PAGE1 will remain erased (status = 0xFFFF) */
|
||||
EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
|
||||
return EE_STATUS_OK;
|
||||
}
|
||||
|
||||
/* Get the base of the other page */
|
||||
static uint32_t EE_GetOtherPageBase(uint32_t pageBase)
|
||||
{
|
||||
return (pageBase == EE_PAGE0_BASE) ? EE_PAGE1_BASE : EE_PAGE0_BASE;
|
||||
}
|
||||
|
||||
/* Page transfer (garbage collection + new write) */
|
||||
static EE_Status EE_PageTransfer(uint16_t VirtAddress, uint16_t Data)
|
||||
{
|
||||
uint32_t oldBase = EE_ActivePageBase;
|
||||
uint32_t newBase = EE_GetOtherPageBase(oldBase);
|
||||
uint32_t addr;
|
||||
uint16_t value;
|
||||
EE_Status st;
|
||||
|
||||
/* Erase new page */
|
||||
if (EE_FlashErasePage(newBase) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Mark new page as RECEIVE */
|
||||
if (EE_FlashProgramHalfWord(newBase, EE_PAGE_STATUS_RECEIVE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Start writing records just after status */
|
||||
addr = newBase + 2U;
|
||||
|
||||
/* For each known virtual variable */
|
||||
for (uint16_t i = 0; i < EE_NUM_VIRTUAL_ADDR; i++)
|
||||
{
|
||||
uint16_t vaddr = EE_VirtAddrs[i];
|
||||
|
||||
if (vaddr == VirtAddress)
|
||||
{
|
||||
/* Use the new data passed into PageTransfer */
|
||||
value = Data;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Read latest value from old active page */
|
||||
st = EE_FindInPage(oldBase, vaddr, &value);
|
||||
if (st != EE_STATUS_OK)
|
||||
{
|
||||
/* Variable never written -> skip */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Write record to new page */
|
||||
if (EE_FlashProgramHalfWord(addr, vaddr) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
if (EE_FlashProgramHalfWord(addr + 2U, value) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
addr += sizeof(EE_Record_t);
|
||||
if (addr >= (newBase + EE_PAGE_SIZE))
|
||||
return EE_STATUS_NO_SPACE;
|
||||
}
|
||||
|
||||
/* Erase old page */
|
||||
if (EE_FlashErasePage(oldBase) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Mark new page as VALID */
|
||||
if (EE_FlashProgramHalfWord(newBase, EE_PAGE_STATUS_VALID) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Update active page */
|
||||
EE_ActivePageBase = newBase;
|
||||
|
||||
return EE_STATUS_OK;
|
||||
}
|
||||
|
||||
/* --- Public API ----------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* Initialize the EEPROM emulation.
|
||||
* - Checks page statuses and chooses the active page.
|
||||
* - If inconsistent or blank, formats pages.
|
||||
* PUBLIC RETURN TYPE: uint16_t (EE_OK / EE_ERROR / ...)
|
||||
*/
|
||||
uint16_t EE_Init(void)
|
||||
{
|
||||
uint16_t status0 = EE_GetPageStatus(EE_PAGE0_BASE);
|
||||
uint16_t status1 = EE_GetPageStatus(EE_PAGE1_BASE);
|
||||
|
||||
if ((status0 == EE_PAGE_STATUS_ERASED) && (status1 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
/* Fresh device -> format */
|
||||
return (uint16_t)EE_Format();
|
||||
}
|
||||
else if ((status0 == EE_PAGE_STATUS_VALID) && (status1 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
return EE_OK;
|
||||
}
|
||||
else if ((status1 == EE_PAGE_STATUS_VALID) && (status0 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
EE_ActivePageBase = EE_PAGE1_BASE;
|
||||
return EE_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Any weird or inconsistent state -> reformat */
|
||||
return (uint16_t)EE_Format();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a 16-bit variable by its virtual address.
|
||||
* PUBLIC RETURN: EE_OK / EE_NOT_FOUND / EE_ERROR (as uint16_t)
|
||||
*/
|
||||
uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t *Data)
|
||||
{
|
||||
EE_Status st;
|
||||
|
||||
if (Data == NULL)
|
||||
return EE_ERROR;
|
||||
|
||||
st = EE_FindInPage(EE_ActivePageBase, VirtAddress, Data);
|
||||
return (uint16_t)st;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write (append) a 16-bit variable.
|
||||
* - Writes a new record in the active page.
|
||||
* - If the page is full, triggers a page transfer (GC).
|
||||
* PUBLIC RETURN: EE_OK / EE_ERROR / EE_NO_SPACE (as uint16_t)
|
||||
*/
|
||||
uint16_t EE_WriteVariable(uint16_t VirtAddress, uint16_t Data)
|
||||
{
|
||||
uint32_t freeAddr;
|
||||
EE_Status st;
|
||||
|
||||
/* Find free space in active page */
|
||||
freeAddr = EE_FindFreeAddress(EE_ActivePageBase);
|
||||
if (freeAddr != 0U)
|
||||
{
|
||||
/* Write new record */
|
||||
if (EE_FlashProgramHalfWord(freeAddr, VirtAddress) != HAL_OK)
|
||||
return EE_ERROR;
|
||||
if (EE_FlashProgramHalfWord(freeAddr + 2U, Data) != HAL_OK)
|
||||
return EE_ERROR;
|
||||
|
||||
return EE_OK;
|
||||
}
|
||||
|
||||
/* No space -> page transfer */
|
||||
st = EE_PageTransfer(VirtAddress, Data);
|
||||
return (uint16_t)st;
|
||||
}
|
||||
|
||||
void loadEE(void){
|
||||
char s [200];
|
||||
EEW_Read(M1PWMAP, &m1pwmap);
|
||||
EEW_Read(M1PWMCH, &m1pwmch);
|
||||
EEW_Read(M2PWMAP, &m2pwmap);
|
||||
EEW_Read(M2PWMCH, &m2pwmch);
|
||||
EEW_Read(M3PWMAP, &m3pwmap);
|
||||
EEW_Read(M3PWMCH, &m3pwmch);
|
||||
EEW_Read(M4PWMAP, &m4pwmap);
|
||||
EEW_Read(M4PWMCH, &m4pwmch);
|
||||
EEW_Read(T1AP, &t1ap);
|
||||
EEW_Read(T2AP, &t2ap);
|
||||
EEW_Read(T3AP, &t3ap);
|
||||
EEW_Read(T4AP, &t4ap);
|
||||
EEW_Read(TWAP, &twap);
|
||||
EEW_Read(T1CH, &t1ch);
|
||||
EEW_Read(T2CH, &t2ch);
|
||||
EEW_Read(T3CH, &t3ch);
|
||||
EEW_Read(T4CH, &t4ch);
|
||||
EEW_Read(TWCH, &twch);
|
||||
EEW_Read(TRAMP1, &tramp1);
|
||||
EEW_Read(M1PWMMAN, &m1pwmMan);
|
||||
EEW_Read(M2PWMMAN, &m2pwmMan);
|
||||
EEW_Read(M3PWMMAN, &m3pwmMan);
|
||||
EEW_Read(M4PWMMAN, &m4pwmMan);
|
||||
EEW_Read(TRAMPMAN, &trampman);
|
||||
EEW_Read(TRAMP, &tramp);
|
||||
|
||||
EEW_Read(APM1START,&apM1start);
|
||||
EEW_Read(APM1STOP ,&apM1stop);
|
||||
EEW_Read(APM2START,&apM2start);
|
||||
EEW_Read(APM2STOP ,&apM2stop);
|
||||
EEW_Read(APM3START,&apM3start);
|
||||
EEW_Read(APM3STOP ,&apM3stop);
|
||||
EEW_Read(APM4START,&apM4start);
|
||||
EEW_Read(APM4STOP ,&apM4stop);
|
||||
EEW_Read(CHM1START,&chM1start);
|
||||
EEW_Read(CHM1STOP ,&chM1stop);
|
||||
EEW_Read(CHM2START,&chM2start);
|
||||
EEW_Read(CHM2STOP ,&chM2stop);
|
||||
EEW_Read(CHM3START,&chM3start);
|
||||
EEW_Read(CHM3STOP ,&chM3stop);
|
||||
EEW_Read(CHM4START,&chM4start);
|
||||
EEW_Read(CHM4STOP ,&chM4stop);
|
||||
|
||||
sprintf((char*)s,"LoadEE\n");
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
sprintf((char*)s,"\nm1pwmap=%d m1pwmch=%d m2pwmap=%d m2pwmch=%d m3pwmap=%d m3pwmch=%d m4pwmap=%d m4pwmch=%d",m1pwmap,m1pwmch,m2pwmap,m2pwmch,m3pwmap,m3pwmch,m4pwmap, m4pwmch);
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
sprintf((char*)s,"\ntramp=%d trampman=%d",tramp,trampman);
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
sprintf((char*)s,"\nm1pwmMan=%d m2pwmMan=%d m3pwmMan=%d m4pwmMan=%d",m1pwmMan,m2pwmMan,m3pwmMan,m4pwmMan);
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,470 @@
|
||||
#include "eeprom.h"
|
||||
extern UART_HandleTypeDef huart1;
|
||||
/*
|
||||
* Record format (4 bytes):
|
||||
* [0] VirtAddress (uint16_t)
|
||||
* [2] Data (uint16_t)
|
||||
*
|
||||
* Page layout:
|
||||
* [0] PageStatus (uint16_t)
|
||||
* [2..] Records...
|
||||
*/
|
||||
|
||||
extern uint16_t m1pwmap;
|
||||
extern uint16_t m1pwmch;
|
||||
extern uint16_t m2pwmap;
|
||||
extern uint16_t m2pwmch;
|
||||
extern uint16_t m3pwmap;
|
||||
extern uint16_t m3pwmch;
|
||||
extern uint16_t m4pwmap;
|
||||
extern uint16_t m4pwmch;
|
||||
extern uint16_t t1ap;
|
||||
extern uint16_t t2ap;
|
||||
extern uint16_t t3ap;
|
||||
extern uint16_t t4ap;
|
||||
extern uint16_t twap;
|
||||
extern uint16_t tramp;
|
||||
extern uint16_t t1ch;
|
||||
extern uint16_t t2ch;
|
||||
extern uint16_t t3ch;
|
||||
extern uint16_t t4ch;
|
||||
extern uint16_t twch;
|
||||
extern uint16_t tramp1;
|
||||
extern uint16_t trampman;
|
||||
extern uint16_t m1pwmMan;
|
||||
extern uint16_t m2pwmMan;
|
||||
extern uint16_t m3pwmMan;
|
||||
extern uint16_t m4pwmMan;
|
||||
|
||||
|
||||
extern uint16_t apM1start;
|
||||
extern uint16_t apM1stop;
|
||||
extern uint16_t apM2start;
|
||||
extern uint16_t apM2stop;
|
||||
extern uint16_t apM3start;
|
||||
extern uint16_t apM3stop;
|
||||
extern uint16_t apM4start;
|
||||
extern uint16_t apM4stop;
|
||||
extern uint16_t chM1start;
|
||||
extern uint16_t chM1stop;
|
||||
extern uint16_t chM2start;
|
||||
extern uint16_t chM2stop;
|
||||
extern uint16_t chM3start;
|
||||
extern uint16_t chM3stop;
|
||||
extern uint16_t chM4start;
|
||||
extern uint16_t chM4stop;
|
||||
|
||||
const uint8_t deftab[EE_NUM_VIRTUAL_ADDR]={
|
||||
40, //m1pwmap
|
||||
60, //m1pwmch
|
||||
70, //m2pwmap
|
||||
70, //m2pwmch
|
||||
35, //m3pwmap
|
||||
40, //m3pwmch
|
||||
40, //m4pwmap
|
||||
40, //m4pwmch
|
||||
20, //m1rampstart
|
||||
20, //m2rampstart
|
||||
20, //m3rampstart
|
||||
20, //m4rampstart
|
||||
28, //t1ap
|
||||
4, //t2ap
|
||||
10, //t3ap
|
||||
40, //t4ap
|
||||
1, //twap
|
||||
27, //t1ch
|
||||
10, //t2ch
|
||||
30, //t3ch
|
||||
1, //t4ch
|
||||
1, //twch
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
100, //tramp1
|
||||
60, //m1pwmMan
|
||||
70, //m2pwmMan
|
||||
40, //m3pwmMan
|
||||
40, //m4pwmMan
|
||||
50, //trampman
|
||||
10, //tramp
|
||||
0, //apM1start;
|
||||
0, //apM1stop;
|
||||
0, //apM2start;
|
||||
0, //apM2stop;
|
||||
0, //apM3start;
|
||||
0, //apM3stop;
|
||||
0, //apM4start;
|
||||
0, //apM4stop;
|
||||
0, //chM1start;
|
||||
0, //chM1stop;
|
||||
0, //chM2start;
|
||||
0, //chM2stop;
|
||||
0, //chM3start;
|
||||
0, //chM3stop;
|
||||
0, //chM4start;
|
||||
0, //chM4stop;
|
||||
1,
|
||||
27,
|
||||
10,
|
||||
30,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
100,
|
||||
60,
|
||||
70,
|
||||
40,
|
||||
40,
|
||||
50,
|
||||
10,
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t VirtAddress;
|
||||
uint16_t Data;
|
||||
} EE_Record_t;
|
||||
|
||||
/* Active page base address (runtime selected in EE_Init) */
|
||||
static uint32_t EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
|
||||
/* 32 sequential virtual addresses */
|
||||
const uint16_t EE_VirtAddrs[EE_NUM_VIRTUAL_ADDR] =
|
||||
{
|
||||
0x0001, 0x0002, 0x0003, 0x0004,
|
||||
0x0005, 0x0006, 0x0007, 0x0008,
|
||||
0x0009, 0x000A, 0x000B, 0x000C,
|
||||
0x000D, 0x000E, 0x000F, 0x0010,
|
||||
0x0011, 0x0012, 0x0013, 0x0014,
|
||||
0x0015, 0x0016, 0x0017, 0x0018,
|
||||
0x0019, 0x001A, 0x001B, 0x001C,
|
||||
0x001D, 0x001E, 0x001F, 0x0020,
|
||||
|
||||
0x0021, 0x0022, 0x0023, 0x0024,
|
||||
0x0025, 0x0026, 0x0027, 0x0028,
|
||||
0x0029, 0x002A, 0x002B, 0x002C,
|
||||
0x002D, 0x002E, 0x002F, 0x0030,
|
||||
0x0031, 0x0032, 0x0033, 0x0034,
|
||||
0x0035, 0x0036, 0x0037, 0x0038,
|
||||
0x0039, 0x003A, 0x003B, 0x003C,
|
||||
0x003D, 0x003E, 0x003F, 0x0040
|
||||
};
|
||||
/* ========================================================================= */
|
||||
|
||||
/* --- Internal helpers ---------------------------------------------------- */
|
||||
|
||||
static uint16_t EE_GetPageStatus(uint32_t pageBase)
|
||||
{
|
||||
return *(__IO uint16_t *)pageBase;
|
||||
}
|
||||
|
||||
static HAL_StatusTypeDef EE_FlashProgramHalfWord(uint32_t Address, uint16_t Data)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
|
||||
HAL_FLASH_Unlock();
|
||||
status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, Address, Data);
|
||||
HAL_FLASH_Lock();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static HAL_StatusTypeDef EE_FlashErasePage(uint32_t PageAddress)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
FLASH_EraseInitTypeDef EraseInit;
|
||||
uint32_t PageError = 0;
|
||||
|
||||
HAL_FLASH_Unlock();
|
||||
|
||||
EraseInit.TypeErase = FLASH_TYPEERASE_PAGES;
|
||||
EraseInit.PageAddress = PageAddress;
|
||||
EraseInit.NbPages = 1;
|
||||
|
||||
status = HAL_FLASHEx_Erase(&EraseInit, &PageError);
|
||||
|
||||
HAL_FLASH_Lock();
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Find first free record address in given page (returns 0 if full) */
|
||||
static uint32_t EE_FindFreeAddress(uint32_t pageBase)
|
||||
{
|
||||
uint32_t addr = pageBase + 2U; /* Skip status word */
|
||||
uint32_t pageEnd = pageBase + EE_PAGE_SIZE;
|
||||
|
||||
while (addr < (pageEnd - sizeof(EE_Record_t) + 1U))
|
||||
{
|
||||
uint16_t vaddr = *(__IO uint16_t *)addr;
|
||||
|
||||
if (vaddr == 0xFFFFU)
|
||||
{
|
||||
/* Empty slot */
|
||||
return addr;
|
||||
}
|
||||
addr += sizeof(EE_Record_t);
|
||||
}
|
||||
|
||||
return 0U; /* No space */
|
||||
}
|
||||
|
||||
/* Find latest value of VirtAddress in a specific page (internal, uses EE_Status) */
|
||||
/* Find latest value of VirtAddress in a specific page (scan forward) */
|
||||
static EE_Status EE_FindInPage(uint32_t pageBase, uint16_t VirtAddress, uint16_t *Data)
|
||||
{
|
||||
uint32_t addr = pageBase + 2U; // skip status halfword
|
||||
uint32_t pageEnd = pageBase + EE_PAGE_SIZE;
|
||||
EE_Status result = EE_NOT_FOUND;
|
||||
uint16_t lastVal = 0;
|
||||
|
||||
if (Data == NULL)
|
||||
return EE_ERROR;
|
||||
|
||||
while (addr <= (pageEnd - sizeof(EE_Record_t)))
|
||||
{
|
||||
uint16_t vaddr = *(__IO uint16_t *)addr;
|
||||
|
||||
if (vaddr == 0xFFFFU)
|
||||
{
|
||||
// First empty slot => no more records in this page
|
||||
break;
|
||||
}
|
||||
|
||||
uint16_t value = *(__IO uint16_t *)(addr + 2U);
|
||||
|
||||
if (vaddr == VirtAddress)
|
||||
{
|
||||
lastVal = value; // keep most recent
|
||||
result = EE_OK;
|
||||
}
|
||||
|
||||
addr += sizeof(EE_Record_t); // move 4 bytes forward
|
||||
}
|
||||
|
||||
if (result == EE_OK)
|
||||
*Data = lastVal;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Format both pages: erase and set PAGE0 as VALID */
|
||||
static EE_Status EE_Format(void)
|
||||
{
|
||||
if (EE_FlashErasePage(EE_PAGE0_BASE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
if (EE_FlashErasePage(EE_PAGE1_BASE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
if (EE_FlashProgramHalfWord(EE_PAGE0_BASE, EE_PAGE_STATUS_VALID) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* PAGE1 will remain erased (status = 0xFFFF) */
|
||||
EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
|
||||
return EE_STATUS_OK;
|
||||
}
|
||||
|
||||
/* Get the base of the other page */
|
||||
static uint32_t EE_GetOtherPageBase(uint32_t pageBase)
|
||||
{
|
||||
return (pageBase == EE_PAGE0_BASE) ? EE_PAGE1_BASE : EE_PAGE0_BASE;
|
||||
}
|
||||
|
||||
/* Page transfer (garbage collection + new write) */
|
||||
static EE_Status EE_PageTransfer(uint16_t VirtAddress, uint16_t Data)
|
||||
{
|
||||
uint32_t oldBase = EE_ActivePageBase;
|
||||
uint32_t newBase = EE_GetOtherPageBase(oldBase);
|
||||
uint32_t addr;
|
||||
uint16_t value;
|
||||
EE_Status st;
|
||||
|
||||
/* Erase new page */
|
||||
if (EE_FlashErasePage(newBase) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Mark new page as RECEIVE */
|
||||
if (EE_FlashProgramHalfWord(newBase, EE_PAGE_STATUS_RECEIVE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Start writing records just after status */
|
||||
addr = newBase + 2U;
|
||||
|
||||
/* For each known virtual variable */
|
||||
for (uint16_t i = 0; i < EE_NUM_VIRTUAL_ADDR; i++)
|
||||
{
|
||||
uint16_t vaddr = EE_VirtAddrs[i];
|
||||
|
||||
if (vaddr == VirtAddress)
|
||||
{
|
||||
/* Use the new data passed into PageTransfer */
|
||||
value = Data;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Read latest value from old active page */
|
||||
st = EE_FindInPage(oldBase, vaddr, &value);
|
||||
if (st != EE_STATUS_OK)
|
||||
{
|
||||
/* Variable never written -> skip */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Write record to new page */
|
||||
if (EE_FlashProgramHalfWord(addr, vaddr) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
if (EE_FlashProgramHalfWord(addr + 2U, value) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
addr += sizeof(EE_Record_t);
|
||||
if (addr >= (newBase + EE_PAGE_SIZE))
|
||||
return EE_STATUS_NO_SPACE;
|
||||
}
|
||||
|
||||
/* Erase old page */
|
||||
if (EE_FlashErasePage(oldBase) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Mark new page as VALID */
|
||||
if (EE_FlashProgramHalfWord(newBase, EE_PAGE_STATUS_VALID) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Update active page */
|
||||
EE_ActivePageBase = newBase;
|
||||
|
||||
return EE_STATUS_OK;
|
||||
}
|
||||
|
||||
/* --- Public API ----------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* Initialize the EEPROM emulation.
|
||||
* - Checks page statuses and chooses the active page.
|
||||
* - If inconsistent or blank, formats pages.
|
||||
* PUBLIC RETURN TYPE: uint16_t (EE_OK / EE_ERROR / ...)
|
||||
*/
|
||||
uint16_t EE_Init(void)
|
||||
{
|
||||
uint16_t status0 = EE_GetPageStatus(EE_PAGE0_BASE);
|
||||
uint16_t status1 = EE_GetPageStatus(EE_PAGE1_BASE);
|
||||
|
||||
if ((status0 == EE_PAGE_STATUS_ERASED) && (status1 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
/* Fresh device -> format */
|
||||
return (uint16_t)EE_Format();
|
||||
}
|
||||
else if ((status0 == EE_PAGE_STATUS_VALID) && (status1 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
return EE_OK;
|
||||
}
|
||||
else if ((status1 == EE_PAGE_STATUS_VALID) && (status0 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
EE_ActivePageBase = EE_PAGE1_BASE;
|
||||
return EE_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Any weird or inconsistent state -> reformat */
|
||||
return (uint16_t)EE_Format();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a 16-bit variable by its virtual address.
|
||||
* PUBLIC RETURN: EE_OK / EE_NOT_FOUND / EE_ERROR (as uint16_t)
|
||||
*/
|
||||
uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t *Data)
|
||||
{
|
||||
EE_Status st;
|
||||
|
||||
if (Data == NULL)
|
||||
return EE_ERROR;
|
||||
|
||||
st = EE_FindInPage(EE_ActivePageBase, VirtAddress, Data);
|
||||
return (uint16_t)st;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write (append) a 16-bit variable.
|
||||
* - Writes a new record in the active page.
|
||||
* - If the page is full, triggers a page transfer (GC).
|
||||
* PUBLIC RETURN: EE_OK / EE_ERROR / EE_NO_SPACE (as uint16_t)
|
||||
*/
|
||||
uint16_t EE_WriteVariable(uint16_t VirtAddress, uint16_t Data)
|
||||
{
|
||||
uint32_t freeAddr;
|
||||
EE_Status st;
|
||||
|
||||
/* Find free space in active page */
|
||||
freeAddr = EE_FindFreeAddress(EE_ActivePageBase);
|
||||
if (freeAddr != 0U)
|
||||
{
|
||||
/* Write new record */
|
||||
if (EE_FlashProgramHalfWord(freeAddr, VirtAddress) != HAL_OK)
|
||||
return EE_ERROR;
|
||||
if (EE_FlashProgramHalfWord(freeAddr + 2U, Data) != HAL_OK)
|
||||
return EE_ERROR;
|
||||
|
||||
return EE_OK;
|
||||
}
|
||||
|
||||
/* No space -> page transfer */
|
||||
st = EE_PageTransfer(VirtAddress, Data);
|
||||
return (uint16_t)st;
|
||||
}
|
||||
|
||||
void loadEE(void){
|
||||
char s [100];
|
||||
EEW_Read(M1PWMAP, &m1pwmap);
|
||||
EEW_Read(M1PWMCH, &m1pwmch);
|
||||
EEW_Read(M2PWMAP, &m2pwmap);
|
||||
EEW_Read(M2PWMCH, &m2pwmch);
|
||||
EEW_Read(M3PWMAP, &m3pwmap);
|
||||
EEW_Read(M3PWMCH, &m3pwmch);
|
||||
EEW_Read(M4PWMAP, &m4pwmap);
|
||||
EEW_Read(M4PWMCH, &m4pwmch);
|
||||
EEW_Read(T1AP, &t1ap);
|
||||
EEW_Read(T2AP, &t2ap);
|
||||
EEW_Read(T3AP, &t3ap);
|
||||
EEW_Read(T4AP, &t4ap);
|
||||
EEW_Read(TWAP, &twap);
|
||||
EEW_Read(T1CH, &t1ch);
|
||||
EEW_Read(T2CH, &t2ch);
|
||||
EEW_Read(T3CH, &t3ch);
|
||||
EEW_Read(T4CH, &t4ch);
|
||||
EEW_Read(TWCH, &twch);
|
||||
EEW_Read(TRAMP1, &tramp1);
|
||||
EEW_Read(M1PWMMAN, &m1pwmMan);
|
||||
EEW_Read(M2PWMMAN, &m2pwmMan);
|
||||
EEW_Read(M3PWMMAN, &m3pwmMan);
|
||||
EEW_Read(M4PWMMAN, &m4pwmMan);
|
||||
EEW_Read(TRAMPMAN, &trampman);
|
||||
EEW_Read(TRAMP, &tramp);
|
||||
|
||||
EEW_Read(APM1START,apM1start);
|
||||
EEW_Read(APM1STOP ,apM1stop);
|
||||
EEW_Read(APM2START,apM2start);
|
||||
EEW_Read(APM2STOP ,apM2stop);
|
||||
EEW_Read(APM3START,apM3start);
|
||||
EEW_Read(APM3STOP ,apM3stop);
|
||||
EEW_Read(APM4START,apM4start);
|
||||
EEW_Read(APM4STOP ,apM4stop);
|
||||
EEW_Read(CHM1START,chM1start);
|
||||
EEW_Read(CHM1STOP ,chM1stop);
|
||||
EEW_Read(CHM2START,chM2start);
|
||||
EEW_Read(CHM2STOP ,chM2stop);
|
||||
EEW_Read(CHM3START,chM3start);
|
||||
EEW_Read(CHM3STOP ,chM3stop);
|
||||
EEW_Read(CHM4START,chM4start);
|
||||
EEW_Read(CHM4STOP ,chM4stop);
|
||||
|
||||
sprintf((char*)s,"LoadEE\n");
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
}
|
||||
@@ -0,0 +1,961 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file : main.c
|
||||
* @brief : Main program body
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2025 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "main.h"
|
||||
#include "usb_device.h"
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
#include "usbd_cdc_if.h"
|
||||
#include "cdc_int.h"
|
||||
#include "eeprom.h"
|
||||
#include "pwm.h"
|
||||
#include "adc.h"
|
||||
#include "debug.h"
|
||||
#include "mot.h"
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PTD */
|
||||
|
||||
typedef enum{
|
||||
bzoff,
|
||||
bzmoving,
|
||||
bzwarning,
|
||||
}stBuz_st;
|
||||
|
||||
|
||||
/* USER CODE END PTD */
|
||||
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PD */
|
||||
|
||||
|
||||
/* USER CODE END PD */
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PM */
|
||||
|
||||
/* USER CODE END PM */
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
ADC_HandleTypeDef hadc1;
|
||||
DMA_HandleTypeDef hdma_adc1;
|
||||
|
||||
TIM_HandleTypeDef htim2;
|
||||
TIM_HandleTypeDef htim4;
|
||||
|
||||
UART_HandleTypeDef huart1;
|
||||
|
||||
/* USER CODE BEGIN PV */
|
||||
|
||||
extern volatile uint16_t adc_dma_buf[];
|
||||
extern uint16_t ch4 ;
|
||||
extern uint16_t ch5 ;
|
||||
extern uint16_t ch6 ;
|
||||
extern uint16_t ch7 ;
|
||||
extern uint16_t ch8 ;
|
||||
|
||||
uint8_t pulsanti=0;
|
||||
volatile uint8_t rtP1=200;
|
||||
volatile uint8_t rtP2=200;
|
||||
volatile uint8_t rtTLC=100;
|
||||
volatile uint16_t rtramp[4];
|
||||
volatile uint16_t rtCiclo;
|
||||
uint16_t m1pwmap;
|
||||
uint16_t m1pwmch;
|
||||
uint16_t m2pwmap;
|
||||
uint16_t m2pwmch;
|
||||
uint16_t m3pwmap;
|
||||
uint16_t m3pwmch;
|
||||
uint16_t m4pwmap;
|
||||
uint16_t m4pwmch;
|
||||
uint16_t t1ap;
|
||||
uint16_t t2ap;
|
||||
uint16_t t3ap;
|
||||
uint16_t t4ap;
|
||||
uint16_t twap;
|
||||
uint16_t t1ch;
|
||||
uint16_t t2ch;
|
||||
uint16_t t3ch;
|
||||
uint16_t t4ch;
|
||||
uint16_t twch;
|
||||
uint16_t tramp;
|
||||
uint16_t tramp1;
|
||||
uint16_t trampman;
|
||||
uint16_t m1pwmMan;
|
||||
uint16_t m2pwmMan;
|
||||
uint16_t m3pwmMan;
|
||||
uint16_t m4pwmMan;
|
||||
|
||||
uint16_t apM1start;
|
||||
uint16_t apM1stop;
|
||||
uint16_t apM2start;
|
||||
uint16_t apM2stop;
|
||||
uint16_t apM3start;
|
||||
uint16_t apM3stop;
|
||||
uint16_t apM4start;
|
||||
uint16_t apM4stop;
|
||||
uint16_t chM1start;
|
||||
uint16_t chM1stop;
|
||||
uint16_t chM2start;
|
||||
uint16_t chM2stop;
|
||||
uint16_t chM3start;
|
||||
uint16_t chM3stop;
|
||||
uint16_t chM4start;
|
||||
uint16_t chM4stop;
|
||||
|
||||
|
||||
uint16_t mrampstart[4];
|
||||
uint16_t stPulsanti=0;
|
||||
omCiclo_st stCiclo=omchiuso;
|
||||
omCiclo_st memstCiclo=omchiuso;
|
||||
volatile stBuz_st stBuz=bzoff;
|
||||
/* USER CODE END PV */
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
void SystemClock_Config(void);
|
||||
static void MX_GPIO_Init(void);
|
||||
static void MX_DMA_Init(void);
|
||||
static void MX_TIM2_Init(void);
|
||||
static void MX_TIM4_Init(void);
|
||||
static void MX_ADC1_Init(void);
|
||||
static void MX_USART1_UART_Init(void);
|
||||
/* USER CODE BEGIN PFP */
|
||||
|
||||
/* USER CODE END PFP */
|
||||
|
||||
/* Private user code ---------------------------------------------------------*/
|
||||
/* USER CODE BEGIN 0 */
|
||||
void HAL_SYSTICK_Callback(void){
|
||||
static unsigned char c10ms = 0;
|
||||
static uint8_t c100ms = 0;
|
||||
static uint8_t c1s = 0;
|
||||
static uint8_t inidx=0;
|
||||
static uint8_t inbuf[4];
|
||||
uint8_t i;
|
||||
|
||||
if (++c10ms >= 10) { // 10 ms
|
||||
c10ms = 0;
|
||||
if(rtP1)rtP1--;
|
||||
if(rtP2)rtP2--;
|
||||
if(rtTLC)rtTLC--;
|
||||
//**** legge i tasti********************************************************************************
|
||||
inidx++;
|
||||
inidx&=0x03;
|
||||
if(HAL_GPIO_ReadPin(P1_GPIO_Port, P1_Pin)==GPIO_PIN_RESET)inbuf[inidx]|=INP1;else inbuf[inidx]&=(~INP1);
|
||||
if(HAL_GPIO_ReadPin(P2_GPIO_Port, P2_Pin)==GPIO_PIN_RESET)inbuf[inidx]|=INP2;else inbuf[inidx]&=(~INP2);
|
||||
if(HAL_GPIO_ReadPin(CH1_GPIO_Port, CH1_Pin)==GPIO_PIN_RESET)inbuf[inidx]|=INCH1;else inbuf[inidx]&=(~INCH1);
|
||||
if(HAL_GPIO_ReadPin(CH2_GPIO_Port, CH2_Pin)==GPIO_PIN_RESET)inbuf[inidx]|=INCH2;else inbuf[inidx]&=(~INCH2);
|
||||
if(HAL_GPIO_ReadPin(CH3_GPIO_Port, CH3_Pin)==GPIO_PIN_RESET)inbuf[inidx]|=INCH3;else inbuf[inidx]&=(~INCH3);
|
||||
if(HAL_GPIO_ReadPin(CH4_GPIO_Port, CH4_Pin)==GPIO_PIN_RESET)inbuf[inidx]|=INCH4;else inbuf[inidx]&=(~INCH4);
|
||||
|
||||
pulsanti|=(inbuf[0]&inbuf[1]&inbuf[2]&inbuf[3]);
|
||||
pulsanti&=(inbuf[0]|inbuf[1]|inbuf[2]|inbuf[3]);
|
||||
//**** legge adc ***********************************************************************************
|
||||
readAdc();
|
||||
if (++c100ms >= 10) { // 10 ms
|
||||
c100ms = 0; //flag_10ms = 1; // set a flag; do real work in main loop
|
||||
for(i=0;i<4;i++){
|
||||
if(rtramp[i])rtramp[i]--;
|
||||
}
|
||||
if(rtCiclo<0xffff)rtCiclo++;
|
||||
|
||||
//**** gestione buzzer *****************************************************************************
|
||||
if(stBuz==bzmoving){
|
||||
if(c1s>=5)HAL_GPIO_WritePin(GPIOA, BUZ_Pin, GPIO_PIN_RESET);else HAL_GPIO_WritePin(GPIOA, BUZ_Pin, GPIO_PIN_SET);
|
||||
}else if(stBuz==bzwarning){
|
||||
if(c1s&2)HAL_GPIO_WritePin(GPIOA, BUZ_Pin, GPIO_PIN_RESET);else HAL_GPIO_WritePin(GPIOA, BUZ_Pin, GPIO_PIN_SET);
|
||||
}else{//bzoff
|
||||
HAL_GPIO_WritePin(GPIOA, BUZ_Pin, GPIO_PIN_RESET);
|
||||
}
|
||||
//**************************************************************************************************
|
||||
if (++c1s >= 10) { // 1 s
|
||||
c1s = 0;
|
||||
HAL_GPIO_TogglePin(LED2_GPIO_Port, LED2_Pin);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void managePulsanti(void){
|
||||
if(pulsanti&INP1){
|
||||
if(rtP1==0)stPulsanti|=P1START;
|
||||
}else{
|
||||
if(stPulsanti&P1START)stPulsanti&=(~P1START);
|
||||
else if(rtP1<=190){
|
||||
stPulsanti|=P1STOP;
|
||||
}
|
||||
rtP1=200;
|
||||
}
|
||||
if(pulsanti&INP2){
|
||||
if(rtP2==0)stPulsanti|=P2START;
|
||||
}else{
|
||||
if(stPulsanti&P2START)stPulsanti&=(~P2START);
|
||||
else if(rtP2<=190)stPulsanti|=P2STOP;
|
||||
rtP2=200;
|
||||
}
|
||||
stPulsanti&=(P1START|P1STOP|P2START|P2STOP);
|
||||
if(stPulsanti==0){
|
||||
switch(pulsanti&0x3c){
|
||||
case 0x00:
|
||||
rtTLC=100;
|
||||
stPulsanti&=(!(M1FW|M1BW|M3FW|M3BW|M4FW|M4BW));
|
||||
break;
|
||||
case 0x08://tlc1
|
||||
if(rtTLC==0)stPulsanti|=M1FW;
|
||||
break;
|
||||
case 0x10://tlc2
|
||||
if(rtTLC==0)stPulsanti|=M1BW;
|
||||
break;
|
||||
case 0x20://tlc3
|
||||
if(rtTLC==0)stPulsanti|=M3FW;
|
||||
break;
|
||||
case 0x04://tlc4
|
||||
if(rtTLC==0)stPulsanti|=M3BW;
|
||||
break;
|
||||
case 0x30://tlc5
|
||||
if(rtTLC==0)stPulsanti|=M4FW;
|
||||
break;
|
||||
case 0x0c://tlc6
|
||||
if(rtTLC==0)stPulsanti|=M4BW;
|
||||
break;
|
||||
default:
|
||||
rtTLC=100;
|
||||
stPulsanti&=(!(M1FW|M1BW|M3FW|M3BW|M4FW|M4BW));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void manageCiclo(void){
|
||||
|
||||
switch(stCiclo){
|
||||
case omchiuso:
|
||||
if(stPulsanti&P1START){
|
||||
stBuz=bzwarning;
|
||||
rtCiclo=0;
|
||||
stCiclo=omapertura0;
|
||||
(void)m1ap();(void)m2ap();(void)m3ap();(void)m4ap();
|
||||
}else if(stPulsanti&P1STOP)stCiclo=omstopapertura;
|
||||
break;
|
||||
case omM1fw1:
|
||||
(void)ramp(M1,FW,mrampstart[M1-1],m1pwmMan,trampman,RAMPRUN);
|
||||
if(rtCiclo>=m1TimeoutMan)stCiclo=omStopMan;
|
||||
if(pulsanti==0)stCiclo=omM1fw2;
|
||||
break;
|
||||
case omM1fw2:
|
||||
(void)ramp(M1,FW,mrampstart[M1-1],m1pwmMan,trampman,RAMPRUN);
|
||||
if(rtCiclo>=m1TimeoutMan)stCiclo=omStopMan;
|
||||
if(pulsanti)stCiclo=omStopMan;
|
||||
break;
|
||||
case omM1bw1:
|
||||
(void)ramp(M1,BW,mrampstart[M1-1],m1pwmMan,trampman,RAMPRUN);
|
||||
if(rtCiclo>=m1TimeoutMan)stCiclo=omStopMan;
|
||||
if(pulsanti==0)stCiclo=omM1bw2;
|
||||
break;
|
||||
case omM1bw2:
|
||||
(void)ramp(M1,BW,mrampstart[M1-1],m1pwmMan,trampman,RAMPRUN);
|
||||
if(rtCiclo>=m1TimeoutMan)stCiclo=omStopMan;
|
||||
if(pulsanti)stCiclo=omStopMan;
|
||||
break;
|
||||
case omM2fw1:
|
||||
(void)ramp(M2,FW,mrampstart[M2-1],m2pwmMan,trampman,RAMPRUN);
|
||||
if(rtCiclo>=m2TimeoutMan)stCiclo=omStopMan;
|
||||
if(pulsanti==0)stCiclo=omM2fw2;
|
||||
break;
|
||||
case omM2fw2:
|
||||
(void)ramp(M2,FW,mrampstart[M2-1],m2pwmMan,trampman,RAMPRUN);
|
||||
if(rtCiclo>=m2TimeoutMan)stCiclo=omStopMan;
|
||||
if(pulsanti)stCiclo=omStopMan;
|
||||
break;
|
||||
case omM2bw1:
|
||||
(void)ramp(M2,BW,mrampstart[M2-1],m2pwmMan,trampman,RAMPRUN);
|
||||
if(rtCiclo>=m2TimeoutMan)stCiclo=omStopMan;
|
||||
if(pulsanti==0)stCiclo=omM2bw2;
|
||||
break;
|
||||
case omM2bw2:
|
||||
(void)ramp(M2,BW,mrampstart[M2-1],m2pwmMan,trampman,RAMPRUN);
|
||||
if(rtCiclo>=m2TimeoutMan)stCiclo=omStopMan;
|
||||
if(pulsanti)stCiclo=omStopMan;
|
||||
break;
|
||||
case omM3fw1:
|
||||
(void)ramp(M3,FW,mrampstart[M3-1],m3pwmMan,trampman,RAMPRUN);
|
||||
if(rtCiclo>=m3TimeoutMan)stCiclo=omStopMan;
|
||||
if(pulsanti==0)stCiclo=omM3fw2;
|
||||
break;
|
||||
case omM3fw2:
|
||||
(void)ramp(M3,FW,mrampstart[M3-1],m3pwmMan,trampman,RAMPRUN);
|
||||
if(rtCiclo>=m3TimeoutMan)stCiclo=omStopMan;
|
||||
if(pulsanti)stCiclo=omStopMan;
|
||||
break;
|
||||
case omM3bw1:
|
||||
(void)ramp(M3,BW,mrampstart[M3-1],m3pwmMan,trampman,RAMPRUN);
|
||||
if(rtCiclo>=m3TimeoutMan)stCiclo=omStopMan;
|
||||
if(pulsanti==0)stCiclo=omM3bw2;
|
||||
break;
|
||||
case omM3bw2:
|
||||
(void)ramp(M3,BW,mrampstart[M3-1],m3pwmMan,trampman,RAMPRUN);
|
||||
if(rtCiclo>=m3TimeoutMan)stCiclo=omStopMan;
|
||||
if(pulsanti)stCiclo=omStopMan;
|
||||
break;
|
||||
case omM4fw1:
|
||||
(void)ramp(M4,FW,mrampstart[M4-1],m4pwmMan,trampman,RAMPRUN);
|
||||
if(rtCiclo>=m4TimeoutMan)stCiclo=omStopMan;
|
||||
if(pulsanti==0)stCiclo=omM4fw2;
|
||||
break;
|
||||
case omM4fw2:
|
||||
(void)ramp(M4,FW,mrampstart[M4-1],m4pwmMan,trampman,RAMPRUN);
|
||||
if(rtCiclo>=m4TimeoutMan)stCiclo=omStopMan;
|
||||
if(pulsanti)stCiclo=omStopMan;
|
||||
break;
|
||||
case omM4bw1:
|
||||
(void)ramp(M4,BW,mrampstart[M4-1],m4pwmMan,trampman,RAMPRUN);
|
||||
if(rtCiclo>=m4TimeoutMan)stCiclo=omStopMan;
|
||||
if(pulsanti==0)stCiclo=omM4bw2;
|
||||
break;
|
||||
case omM4bw2:
|
||||
(void)ramp(M4,BW,mrampstart[M4-1],m4pwmMan,trampman,RAMPRUN);
|
||||
if(rtCiclo>=m4TimeoutMan)stCiclo=omStopMan;
|
||||
if(pulsanti)stCiclo=omStopMan;
|
||||
break;
|
||||
case omStopMan:
|
||||
SetMotPerc(M1,FW,0);
|
||||
SetMotPerc(M2,FW,0);
|
||||
SetMotPerc(M3,FW,0);
|
||||
SetMotPerc(M4,FW,0);
|
||||
SetMotPerc(M1,BW,0);
|
||||
SetMotPerc(M2,BW,0);
|
||||
SetMotPerc(M3,BW,0);
|
||||
SetMotPerc(M4,BW,0);
|
||||
if(pulsanti==0){
|
||||
stBuz=bzoff;
|
||||
stCiclo=omaperto;
|
||||
}
|
||||
break;
|
||||
case omapertura0:
|
||||
if(rtCiclo>=30){//doppo 3 secondi
|
||||
stBuz=bzmoving;
|
||||
if((m1ap()==motStop)&&(m2ap()==motStop)&&(m3ap()==motStop)&&(m4ap()==motStop)){
|
||||
stBuz=bzoff;
|
||||
stCiclo=omaperto;
|
||||
}
|
||||
}
|
||||
if(stPulsanti&P1STOP)stCiclo=omstopapertura;
|
||||
break;
|
||||
case omstopapertura:
|
||||
SetMotPerc(M1,FW,0);
|
||||
SetMotPerc(M2,FW,0);
|
||||
SetMotPerc(M3,FW,0);
|
||||
SetMotPerc(M4,FW,0);
|
||||
if(pulsanti==0){
|
||||
stBuz=bzoff;
|
||||
stCiclo=omchiuso;
|
||||
stPulsanti&=(~P1STOP);
|
||||
}
|
||||
break;
|
||||
case omaperto:
|
||||
rtCiclo=0;
|
||||
if(stPulsanti&P1START){
|
||||
stBuz=bzmoving;
|
||||
(void)ramp(M1,BW,mrampstart[M1-1],m1pwmch,tramp,RAMPINIT);
|
||||
stCiclo=omchiusura1;
|
||||
(void)m1ch();(void)m2ch();(void)m3ch();(void)m4ch();
|
||||
}
|
||||
if(stPulsanti&P1STOP)stCiclo=omstopchiusura;
|
||||
else if(stPulsanti&M1FW){
|
||||
stBuz=bzmoving;
|
||||
(void)ramp(M1,FW,mrampstart[M1-1],m1pwmMan,trampman,RAMPINIT);
|
||||
stCiclo=omM1fw1;
|
||||
}else if(stPulsanti&M1BW){
|
||||
stBuz=bzmoving;
|
||||
(void)ramp(M1,BW,mrampstart[M1-1],m1pwmMan,trampman,RAMPINIT);
|
||||
stCiclo=omM1bw1;
|
||||
}else if(stPulsanti&M2FW){
|
||||
stBuz=bzmoving;
|
||||
(void)ramp(M2,FW,mrampstart[M2-1],m2pwmMan,trampman,RAMPINIT);
|
||||
stCiclo=omM2fw1;
|
||||
}else if(stPulsanti&M2BW){
|
||||
stBuz=bzmoving;
|
||||
(void)ramp(M2,BW,mrampstart[M2-1],m2pwmMan,trampman,RAMPINIT);
|
||||
stCiclo=omM2bw1;
|
||||
}else if(stPulsanti&M3FW){
|
||||
stBuz=bzmoving;
|
||||
(void)ramp(M3,FW,mrampstart[M3-1],m3pwmMan,trampman,RAMPINIT);
|
||||
stCiclo=omM3fw1;
|
||||
}else if(stPulsanti&M3BW){
|
||||
stBuz=bzmoving;
|
||||
(void)ramp(M3,BW,mrampstart[M3-1],m3pwmMan,trampman,RAMPINIT);
|
||||
stCiclo=omM3bw1;
|
||||
}else if(stPulsanti&M4FW){
|
||||
stBuz=bzmoving;
|
||||
(void)ramp(M4,FW,mrampstart[M4-1],m3pwmMan,trampman,RAMPINIT);
|
||||
stCiclo=omM4fw1;
|
||||
}else if(stPulsanti&M4BW){
|
||||
stBuz=bzmoving;
|
||||
(void)ramp(M4,BW,mrampstart[M4-1],m3pwmMan,trampman,RAMPINIT);
|
||||
stCiclo=omM4bw1;
|
||||
}
|
||||
break;
|
||||
case omchiusura1:
|
||||
if(rtCiclo>=10){//doppo 1 secondi
|
||||
if((m1ch()==motStop)&&(m2ch()==motStop)&&(m3ch()==motStop)&&(m4ch()==motStop)){
|
||||
stBuz=bzoff;
|
||||
stCiclo=omchiuso;
|
||||
}
|
||||
}
|
||||
if(stPulsanti&P1STOP)stCiclo=omstopchiusura;
|
||||
break;
|
||||
|
||||
case omstopchiusura:
|
||||
SetMotPerc(M1,FW,0);
|
||||
SetMotPerc(M2,FW,0);
|
||||
SetMotPerc(M3,FW,0);
|
||||
SetMotPerc(M4,FW,0);
|
||||
if(pulsanti==0){
|
||||
stBuz=bzoff;
|
||||
stCiclo=omaperto;
|
||||
stPulsanti&=(~P1STOP);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* USER CODE END 0 */
|
||||
|
||||
/**
|
||||
* @brief The application entry point.
|
||||
* @retval int
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
/* USER CODE END 1 */
|
||||
|
||||
/* MCU Configuration--------------------------------------------------------*/
|
||||
|
||||
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
|
||||
HAL_Init();
|
||||
|
||||
/* USER CODE BEGIN Init */
|
||||
|
||||
/* USER CODE END Init */
|
||||
|
||||
/* Configure the system clock */
|
||||
SystemClock_Config();
|
||||
|
||||
/* USER CODE BEGIN SysInit */
|
||||
|
||||
/* USER CODE END SysInit */
|
||||
|
||||
/* Initialize all configured peripherals */
|
||||
MX_GPIO_Init();
|
||||
MX_DMA_Init();
|
||||
MX_USB_DEVICE_Init();
|
||||
MX_TIM2_Init();
|
||||
MX_TIM4_Init();
|
||||
MX_ADC1_Init();
|
||||
MX_USART1_UART_Init();
|
||||
/* USER CODE BEGIN 2 */
|
||||
HAL_ADC_Start_DMA(&hadc1, (uint32_t *)adc_dma_buf, ADC_NUM_CHANNELS);
|
||||
StopMot(timMot1,FWMot1);
|
||||
StopMot(timMot1,BWMot1);
|
||||
StopMot(timMot2,FWMot2);
|
||||
StopMot(timMot2,BWMot2);
|
||||
StopMot(timMot3,FWMot3);
|
||||
StopMot(timMot3,BWMot3);
|
||||
StopMot(timMot4,FWMot4);
|
||||
StopMot(timMot4,BWMot4);
|
||||
//CDC_Transmit_FS((uint8_t*)"Start\r\n", 7);
|
||||
//while (CDC_Transmit_FS((uint8_t*)"Start\r\n", 7) == USBD_BUSY);
|
||||
if (EE_Init() != EE_OK){
|
||||
for(;;);//errore eeprom
|
||||
}
|
||||
loadEE();
|
||||
/* USER CODE END 2 */
|
||||
|
||||
/* Infinite loop */
|
||||
/* USER CODE BEGIN WHILE */
|
||||
while (1){
|
||||
manageCDC();
|
||||
manageAdc();
|
||||
managePulsanti();
|
||||
manageCiclo();
|
||||
debug();
|
||||
// while (CDC_Available()) {
|
||||
// int c = CDC_ReadByte();
|
||||
//if (c < 0) break;
|
||||
|
||||
// uint8_t out = (uint8_t)c;
|
||||
// if (out >= 'a' && out <= 'z') out -= 32; // to upper
|
||||
|
||||
// unsigned char s[100];
|
||||
// sprintf((char*)s,"\nc=%03d",c);
|
||||
// while (CDC_Transmit_FS(s, 6) == USBD_BUSY) {
|
||||
// // tiny spin or yield
|
||||
// }
|
||||
// }
|
||||
|
||||
//HAL_Delay(1000);
|
||||
// CDC_Transmit_FS((uint8_t*)"Ping\r\n", 6);
|
||||
/* USER CODE END WHILE */
|
||||
|
||||
/* USER CODE BEGIN 3 */
|
||||
}
|
||||
/* USER CODE END 3 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief System Clock Configuration
|
||||
* @retval None
|
||||
*/
|
||||
void SystemClock_Config(void)
|
||||
{
|
||||
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
|
||||
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
|
||||
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
|
||||
|
||||
/** Initializes the RCC Oscillators according to the specified parameters
|
||||
* in the RCC_OscInitTypeDef structure.
|
||||
*/
|
||||
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
|
||||
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
|
||||
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
|
||||
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
|
||||
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
|
||||
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
|
||||
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL6;
|
||||
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/** Initializes the CPU, AHB and APB buses clocks
|
||||
*/
|
||||
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|
||||
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
|
||||
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
|
||||
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
|
||||
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
|
||||
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
|
||||
|
||||
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC|RCC_PERIPHCLK_USB;
|
||||
PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6;
|
||||
PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLL_DIV1_5;
|
||||
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ADC1 Initialization Function
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
static void MX_ADC1_Init(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN ADC1_Init 0 */
|
||||
|
||||
/* USER CODE END ADC1_Init 0 */
|
||||
|
||||
ADC_ChannelConfTypeDef sConfig = {0};
|
||||
|
||||
/* USER CODE BEGIN ADC1_Init 1 */
|
||||
|
||||
/* USER CODE END ADC1_Init 1 */
|
||||
|
||||
/** Common config
|
||||
*/
|
||||
hadc1.Instance = ADC1;
|
||||
hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
|
||||
hadc1.Init.ContinuousConvMode = ENABLE;
|
||||
hadc1.Init.DiscontinuousConvMode = DISABLE;
|
||||
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
|
||||
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
|
||||
hadc1.Init.NbrOfConversion = 5;
|
||||
if (HAL_ADC_Init(&hadc1) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/** Configure Regular Channel
|
||||
*/
|
||||
sConfig.Channel = ADC_CHANNEL_4;
|
||||
sConfig.Rank = ADC_REGULAR_RANK_1;
|
||||
sConfig.SamplingTime = ADC_SAMPLETIME_28CYCLES_5;
|
||||
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/** Configure Regular Channel
|
||||
*/
|
||||
sConfig.Channel = ADC_CHANNEL_5;
|
||||
sConfig.Rank = ADC_REGULAR_RANK_2;
|
||||
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/** Configure Regular Channel
|
||||
*/
|
||||
sConfig.Channel = ADC_CHANNEL_6;
|
||||
sConfig.Rank = ADC_REGULAR_RANK_3;
|
||||
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/** Configure Regular Channel
|
||||
*/
|
||||
sConfig.Channel = ADC_CHANNEL_7;
|
||||
sConfig.Rank = ADC_REGULAR_RANK_4;
|
||||
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/** Configure Regular Channel
|
||||
*/
|
||||
sConfig.Channel = ADC_CHANNEL_8;
|
||||
sConfig.Rank = ADC_REGULAR_RANK_5;
|
||||
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
/* USER CODE BEGIN ADC1_Init 2 */
|
||||
|
||||
/* USER CODE END ADC1_Init 2 */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief TIM2 Initialization Function
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
static void MX_TIM2_Init(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN TIM2_Init 0 */
|
||||
|
||||
/* USER CODE END TIM2_Init 0 */
|
||||
|
||||
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
|
||||
TIM_MasterConfigTypeDef sMasterConfig = {0};
|
||||
TIM_OC_InitTypeDef sConfigOC = {0};
|
||||
|
||||
/* USER CODE BEGIN TIM2_Init 1 */
|
||||
|
||||
/* USER CODE END TIM2_Init 1 */
|
||||
htim2.Instance = TIM2;
|
||||
htim2.Init.Prescaler = 0;
|
||||
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
|
||||
htim2.Init.Period = 17999;
|
||||
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
|
||||
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
|
||||
if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
|
||||
if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
if (HAL_TIM_PWM_Init(&htim2) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
|
||||
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
|
||||
if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
sConfigOC.OCMode = TIM_OCMODE_PWM1;
|
||||
sConfigOC.Pulse = 1000;
|
||||
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
|
||||
sConfigOC.OCFastMode = TIM_OCFAST_ENABLE;
|
||||
if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
sConfigOC.Pulse = 2000;
|
||||
if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
sConfigOC.Pulse = 3000;
|
||||
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
|
||||
if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
sConfigOC.Pulse = 4000;
|
||||
sConfigOC.OCFastMode = TIM_OCFAST_ENABLE;
|
||||
if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
/* USER CODE BEGIN TIM2_Init 2 */
|
||||
|
||||
/* USER CODE END TIM2_Init 2 */
|
||||
HAL_TIM_MspPostInit(&htim2);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief TIM4 Initialization Function
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
static void MX_TIM4_Init(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN TIM4_Init 0 */
|
||||
|
||||
/* USER CODE END TIM4_Init 0 */
|
||||
|
||||
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
|
||||
TIM_MasterConfigTypeDef sMasterConfig = {0};
|
||||
TIM_OC_InitTypeDef sConfigOC = {0};
|
||||
|
||||
/* USER CODE BEGIN TIM4_Init 1 */
|
||||
|
||||
/* USER CODE END TIM4_Init 1 */
|
||||
htim4.Instance = TIM4;
|
||||
htim4.Init.Prescaler = 0;
|
||||
htim4.Init.CounterMode = TIM_COUNTERMODE_UP;
|
||||
htim4.Init.Period = 17999;
|
||||
htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
|
||||
htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
|
||||
if (HAL_TIM_Base_Init(&htim4) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
|
||||
if (HAL_TIM_ConfigClockSource(&htim4, &sClockSourceConfig) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
if (HAL_TIM_PWM_Init(&htim4) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
|
||||
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
|
||||
if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
sConfigOC.OCMode = TIM_OCMODE_PWM1;
|
||||
sConfigOC.Pulse = 5000;
|
||||
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
|
||||
sConfigOC.OCFastMode = TIM_OCFAST_ENABLE;
|
||||
if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
sConfigOC.Pulse = 6000;
|
||||
if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
sConfigOC.Pulse = 7000;
|
||||
if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
sConfigOC.Pulse = 8000;
|
||||
if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
/* USER CODE BEGIN TIM4_Init 2 */
|
||||
|
||||
/* USER CODE END TIM4_Init 2 */
|
||||
HAL_TIM_MspPostInit(&htim4);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USART1 Initialization Function
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
static void MX_USART1_UART_Init(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN USART1_Init 0 */
|
||||
|
||||
/* USER CODE END USART1_Init 0 */
|
||||
|
||||
/* USER CODE BEGIN USART1_Init 1 */
|
||||
|
||||
/* USER CODE END USART1_Init 1 */
|
||||
huart1.Instance = USART1;
|
||||
huart1.Init.BaudRate = 115200;
|
||||
huart1.Init.WordLength = UART_WORDLENGTH_8B;
|
||||
huart1.Init.StopBits = UART_STOPBITS_1;
|
||||
huart1.Init.Parity = UART_PARITY_NONE;
|
||||
huart1.Init.Mode = UART_MODE_TX_RX;
|
||||
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
|
||||
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
|
||||
if (HAL_UART_Init(&huart1) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
/* USER CODE BEGIN USART1_Init 2 */
|
||||
|
||||
/* USER CODE END USART1_Init 2 */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable DMA controller clock
|
||||
*/
|
||||
static void MX_DMA_Init(void)
|
||||
{
|
||||
|
||||
/* DMA controller clock enable */
|
||||
__HAL_RCC_DMA1_CLK_ENABLE();
|
||||
|
||||
/* DMA interrupt init */
|
||||
/* DMA1_Channel1_IRQn interrupt configuration */
|
||||
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);
|
||||
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief GPIO Initialization Function
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
static void MX_GPIO_Init(void)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
/* USER CODE BEGIN MX_GPIO_Init_1 */
|
||||
|
||||
/* USER CODE END MX_GPIO_Init_1 */
|
||||
|
||||
/* GPIO Ports Clock Enable */
|
||||
__HAL_RCC_GPIOC_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOD_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
|
||||
/*Configure GPIO pin Output Level */
|
||||
HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_RESET);
|
||||
|
||||
/*Configure GPIO pin Output Level */
|
||||
HAL_GPIO_WritePin(GPIOB, INH1_Pin|INH2_Pin|INH3_Pin|INH4_Pin
|
||||
|EXP1_Pin|EXP2_Pin|EXP3_Pin, GPIO_PIN_RESET);
|
||||
|
||||
/*Configure GPIO pin Output Level */
|
||||
HAL_GPIO_WritePin(GPIOA, BUZ_Pin|LED1_Pin, GPIO_PIN_RESET);
|
||||
|
||||
/*Configure GPIO pin : LED2_Pin */
|
||||
GPIO_InitStruct.Pin = LED2_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
HAL_GPIO_Init(LED2_GPIO_Port, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pins : P1_Pin P2_Pin */
|
||||
GPIO_InitStruct.Pin = P1_Pin|P2_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pin : AIN1_Pin */
|
||||
GPIO_InitStruct.Pin = AIN1_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
|
||||
HAL_GPIO_Init(AIN1_GPIO_Port, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pins : INH1_Pin INH2_Pin INH3_Pin INH4_Pin
|
||||
EXP1_Pin EXP2_Pin EXP3_Pin */
|
||||
GPIO_InitStruct.Pin = INH1_Pin|INH2_Pin|INH3_Pin|INH4_Pin
|
||||
|EXP1_Pin|EXP2_Pin|EXP3_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pins : CH1_Pin CH2_Pin CH3_Pin CH4_Pin */
|
||||
GPIO_InitStruct.Pin = CH1_Pin|CH2_Pin|CH3_Pin|CH4_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pins : BUZ_Pin LED1_Pin */
|
||||
GPIO_InitStruct.Pin = BUZ_Pin|LED1_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
/* USER CODE BEGIN MX_GPIO_Init_2 */
|
||||
|
||||
/* USER CODE END MX_GPIO_Init_2 */
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 4 */
|
||||
|
||||
/* USER CODE END 4 */
|
||||
|
||||
/**
|
||||
* @brief This function is executed in case of error occurrence.
|
||||
* @retval None
|
||||
*/
|
||||
void Error_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN Error_Handler_Debug */
|
||||
/* User can add his own implementation to report the HAL error return state */
|
||||
__disable_irq();
|
||||
while (1)
|
||||
{
|
||||
}
|
||||
/* USER CODE END Error_Handler_Debug */
|
||||
}
|
||||
#ifdef USE_FULL_ASSERT
|
||||
/**
|
||||
* @brief Reports the name of the source file and the source line number
|
||||
* where the assert_param error has occurred.
|
||||
* @param file: pointer to the source file name
|
||||
* @param line: assert_param error line source number
|
||||
* @retval None
|
||||
*/
|
||||
void assert_failed(uint8_t *file, uint32_t line)
|
||||
{
|
||||
/* USER CODE BEGIN 6 */
|
||||
/* User can add his own implementation to report the file name and line number,
|
||||
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
|
||||
/* USER CODE END 6 */
|
||||
}
|
||||
#endif /* USE_FULL_ASSERT */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,472 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "eeprom.h"
|
||||
extern UART_HandleTypeDef huart1;
|
||||
/*
|
||||
* Record format (4 bytes):
|
||||
* [0] VirtAddress (uint16_t)
|
||||
* [2] Data (uint16_t)
|
||||
*
|
||||
* Page layout:
|
||||
* [0] PageStatus (uint16_t)
|
||||
* [2..] Records...
|
||||
*/
|
||||
|
||||
extern uint16_t m1pwmap;
|
||||
extern uint16_t m1pwmch;
|
||||
extern uint16_t m2pwmap;
|
||||
extern uint16_t m2pwmch;
|
||||
extern uint16_t m3pwmap;
|
||||
extern uint16_t m3pwmch;
|
||||
extern uint16_t m4pwmap;
|
||||
extern uint16_t m4pwmch;
|
||||
extern uint16_t t1ap;
|
||||
extern uint16_t t2ap;
|
||||
extern uint16_t t3ap;
|
||||
extern uint16_t t4ap;
|
||||
extern uint16_t twap;
|
||||
extern uint16_t tramp;
|
||||
extern uint16_t t1ch;
|
||||
extern uint16_t t2ch;
|
||||
extern uint16_t t3ch;
|
||||
extern uint16_t t4ch;
|
||||
extern uint16_t twch;
|
||||
extern uint16_t tramp1;
|
||||
extern uint16_t trampman;
|
||||
extern uint16_t m1pwmMan;
|
||||
extern uint16_t m2pwmMan;
|
||||
extern uint16_t m3pwmMan;
|
||||
extern uint16_t m4pwmMan;
|
||||
|
||||
|
||||
extern uint16_t apM1start;
|
||||
extern uint16_t apM1stop;
|
||||
extern uint16_t apM2start;
|
||||
extern uint16_t apM2stop;
|
||||
extern uint16_t apM3start;
|
||||
extern uint16_t apM3stop;
|
||||
extern uint16_t apM4start;
|
||||
extern uint16_t apM4stop;
|
||||
extern uint16_t chM1start;
|
||||
extern uint16_t chM1stop;
|
||||
extern uint16_t chM2start;
|
||||
extern uint16_t chM2stop;
|
||||
extern uint16_t chM3start;
|
||||
extern uint16_t chM3stop;
|
||||
extern uint16_t chM4start;
|
||||
extern uint16_t chM4stop;
|
||||
|
||||
const uint8_t deftab[EE_NUM_VIRTUAL_ADDR]={
|
||||
40, //m1pwmap
|
||||
60, //m1pwmch
|
||||
70, //m2pwmap
|
||||
70, //m2pwmch
|
||||
35, //m3pwmap
|
||||
40, //m3pwmch
|
||||
40, //m4pwmap
|
||||
40, //m4pwmch
|
||||
20, //m1rampstart
|
||||
20, //m2rampstart
|
||||
20, //m3rampstart
|
||||
20, //m4rampstart
|
||||
28, //t1ap
|
||||
4, //t2ap
|
||||
10, //t3ap
|
||||
40, //t4ap
|
||||
1, //twap
|
||||
27, //t1ch
|
||||
10, //t2ch
|
||||
30, //t3ch
|
||||
1, //t4ch
|
||||
1, //twch
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
100, //tramp1
|
||||
60, //m1pwmMan
|
||||
70, //m2pwmMan
|
||||
40, //m3pwmMan
|
||||
40, //m4pwmMan
|
||||
50, //trampman
|
||||
10, //tramp
|
||||
0, //apM1start;
|
||||
0, //apM1stop;
|
||||
0, //apM2start;
|
||||
0, //apM2stop;
|
||||
0, //apM3start;
|
||||
0, //apM3stop;
|
||||
0, //apM4start;
|
||||
0, //apM4stop;
|
||||
0, //chM1start;
|
||||
0, //chM1stop;
|
||||
0, //chM2start;
|
||||
0, //chM2stop;
|
||||
0, //chM3start;
|
||||
0, //chM3stop;
|
||||
0, //chM4start;
|
||||
0, //chM4stop;
|
||||
1,
|
||||
27,
|
||||
10,
|
||||
30,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
100,
|
||||
60,
|
||||
70,
|
||||
40,
|
||||
40,
|
||||
50,
|
||||
10,
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t VirtAddress;
|
||||
uint16_t Data;
|
||||
} EE_Record_t;
|
||||
|
||||
/* Active page base address (runtime selected in EE_Init) */
|
||||
static uint32_t EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
|
||||
/* 32 sequential virtual addresses */
|
||||
const uint16_t EE_VirtAddrs[EE_NUM_VIRTUAL_ADDR] =
|
||||
{
|
||||
0x0001, 0x0002, 0x0003, 0x0004,
|
||||
0x0005, 0x0006, 0x0007, 0x0008,
|
||||
0x0009, 0x000A, 0x000B, 0x000C,
|
||||
0x000D, 0x000E, 0x000F, 0x0010,
|
||||
0x0011, 0x0012, 0x0013, 0x0014,
|
||||
0x0015, 0x0016, 0x0017, 0x0018,
|
||||
0x0019, 0x001A, 0x001B, 0x001C,
|
||||
0x001D, 0x001E, 0x001F, 0x0020,
|
||||
|
||||
0x0021, 0x0022, 0x0023, 0x0024,
|
||||
0x0025, 0x0026, 0x0027, 0x0028,
|
||||
0x0029, 0x002A, 0x002B, 0x002C,
|
||||
0x002D, 0x002E, 0x002F, 0x0030,
|
||||
0x0031, 0x0032, 0x0033, 0x0034,
|
||||
0x0035, 0x0036, 0x0037, 0x0038,
|
||||
0x0039, 0x003A, 0x003B, 0x003C,
|
||||
0x003D, 0x003E, 0x003F, 0x0040
|
||||
};
|
||||
/* ========================================================================= */
|
||||
|
||||
/* --- Internal helpers ---------------------------------------------------- */
|
||||
|
||||
static uint16_t EE_GetPageStatus(uint32_t pageBase)
|
||||
{
|
||||
return *(__IO uint16_t *)pageBase;
|
||||
}
|
||||
|
||||
static HAL_StatusTypeDef EE_FlashProgramHalfWord(uint32_t Address, uint16_t Data)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
|
||||
HAL_FLASH_Unlock();
|
||||
status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, Address, Data);
|
||||
HAL_FLASH_Lock();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static HAL_StatusTypeDef EE_FlashErasePage(uint32_t PageAddress)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
FLASH_EraseInitTypeDef EraseInit;
|
||||
uint32_t PageError = 0;
|
||||
|
||||
HAL_FLASH_Unlock();
|
||||
|
||||
EraseInit.TypeErase = FLASH_TYPEERASE_PAGES;
|
||||
EraseInit.PageAddress = PageAddress;
|
||||
EraseInit.NbPages = 1;
|
||||
|
||||
status = HAL_FLASHEx_Erase(&EraseInit, &PageError);
|
||||
|
||||
HAL_FLASH_Lock();
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Find first free record address in given page (returns 0 if full) */
|
||||
static uint32_t EE_FindFreeAddress(uint32_t pageBase)
|
||||
{
|
||||
uint32_t addr = pageBase + 2U; /* Skip status word */
|
||||
uint32_t pageEnd = pageBase + EE_PAGE_SIZE;
|
||||
|
||||
while (addr < (pageEnd - sizeof(EE_Record_t) + 1U))
|
||||
{
|
||||
uint16_t vaddr = *(__IO uint16_t *)addr;
|
||||
|
||||
if (vaddr == 0xFFFFU)
|
||||
{
|
||||
/* Empty slot */
|
||||
return addr;
|
||||
}
|
||||
addr += sizeof(EE_Record_t);
|
||||
}
|
||||
|
||||
return 0U; /* No space */
|
||||
}
|
||||
|
||||
/* Find latest value of VirtAddress in a specific page (internal, uses EE_Status) */
|
||||
/* Find latest value of VirtAddress in a specific page (scan forward) */
|
||||
static EE_Status EE_FindInPage(uint32_t pageBase, uint16_t VirtAddress, uint16_t *Data)
|
||||
{
|
||||
uint32_t addr = pageBase + 2U; // skip status halfword
|
||||
uint32_t pageEnd = pageBase + EE_PAGE_SIZE;
|
||||
EE_Status result = EE_NOT_FOUND;
|
||||
uint16_t lastVal = 0;
|
||||
|
||||
if (Data == NULL)
|
||||
return EE_ERROR;
|
||||
|
||||
while (addr <= (pageEnd - sizeof(EE_Record_t)))
|
||||
{
|
||||
uint16_t vaddr = *(__IO uint16_t *)addr;
|
||||
|
||||
if (vaddr == 0xFFFFU)
|
||||
{
|
||||
// First empty slot => no more records in this page
|
||||
break;
|
||||
}
|
||||
|
||||
uint16_t value = *(__IO uint16_t *)(addr + 2U);
|
||||
|
||||
if (vaddr == VirtAddress)
|
||||
{
|
||||
lastVal = value; // keep most recent
|
||||
result = EE_OK;
|
||||
}
|
||||
|
||||
addr += sizeof(EE_Record_t); // move 4 bytes forward
|
||||
}
|
||||
|
||||
if (result == EE_OK)
|
||||
*Data = lastVal;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Format both pages: erase and set PAGE0 as VALID */
|
||||
static EE_Status EE_Format(void)
|
||||
{
|
||||
if (EE_FlashErasePage(EE_PAGE0_BASE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
if (EE_FlashErasePage(EE_PAGE1_BASE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
if (EE_FlashProgramHalfWord(EE_PAGE0_BASE, EE_PAGE_STATUS_VALID) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* PAGE1 will remain erased (status = 0xFFFF) */
|
||||
EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
|
||||
return EE_STATUS_OK;
|
||||
}
|
||||
|
||||
/* Get the base of the other page */
|
||||
static uint32_t EE_GetOtherPageBase(uint32_t pageBase)
|
||||
{
|
||||
return (pageBase == EE_PAGE0_BASE) ? EE_PAGE1_BASE : EE_PAGE0_BASE;
|
||||
}
|
||||
|
||||
/* Page transfer (garbage collection + new write) */
|
||||
static EE_Status EE_PageTransfer(uint16_t VirtAddress, uint16_t Data)
|
||||
{
|
||||
uint32_t oldBase = EE_ActivePageBase;
|
||||
uint32_t newBase = EE_GetOtherPageBase(oldBase);
|
||||
uint32_t addr;
|
||||
uint16_t value;
|
||||
EE_Status st;
|
||||
|
||||
/* Erase new page */
|
||||
if (EE_FlashErasePage(newBase) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Mark new page as RECEIVE */
|
||||
if (EE_FlashProgramHalfWord(newBase, EE_PAGE_STATUS_RECEIVE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Start writing records just after status */
|
||||
addr = newBase + 2U;
|
||||
|
||||
/* For each known virtual variable */
|
||||
for (uint16_t i = 0; i < EE_NUM_VIRTUAL_ADDR; i++)
|
||||
{
|
||||
uint16_t vaddr = EE_VirtAddrs[i];
|
||||
|
||||
if (vaddr == VirtAddress)
|
||||
{
|
||||
/* Use the new data passed into PageTransfer */
|
||||
value = Data;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Read latest value from old active page */
|
||||
st = EE_FindInPage(oldBase, vaddr, &value);
|
||||
if (st != EE_STATUS_OK)
|
||||
{
|
||||
/* Variable never written -> skip */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Write record to new page */
|
||||
if (EE_FlashProgramHalfWord(addr, vaddr) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
if (EE_FlashProgramHalfWord(addr + 2U, value) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
addr += sizeof(EE_Record_t);
|
||||
if (addr >= (newBase + EE_PAGE_SIZE))
|
||||
return EE_STATUS_NO_SPACE;
|
||||
}
|
||||
|
||||
/* Erase old page */
|
||||
if (EE_FlashErasePage(oldBase) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Mark new page as VALID */
|
||||
if (EE_FlashProgramHalfWord(newBase, EE_PAGE_STATUS_VALID) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Update active page */
|
||||
EE_ActivePageBase = newBase;
|
||||
|
||||
return EE_STATUS_OK;
|
||||
}
|
||||
|
||||
/* --- Public API ----------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* Initialize the EEPROM emulation.
|
||||
* - Checks page statuses and chooses the active page.
|
||||
* - If inconsistent or blank, formats pages.
|
||||
* PUBLIC RETURN TYPE: uint16_t (EE_OK / EE_ERROR / ...)
|
||||
*/
|
||||
uint16_t EE_Init(void)
|
||||
{
|
||||
uint16_t status0 = EE_GetPageStatus(EE_PAGE0_BASE);
|
||||
uint16_t status1 = EE_GetPageStatus(EE_PAGE1_BASE);
|
||||
|
||||
if ((status0 == EE_PAGE_STATUS_ERASED) && (status1 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
/* Fresh device -> format */
|
||||
return (uint16_t)EE_Format();
|
||||
}
|
||||
else if ((status0 == EE_PAGE_STATUS_VALID) && (status1 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
return EE_OK;
|
||||
}
|
||||
else if ((status1 == EE_PAGE_STATUS_VALID) && (status0 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
EE_ActivePageBase = EE_PAGE1_BASE;
|
||||
return EE_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Any weird or inconsistent state -> reformat */
|
||||
return (uint16_t)EE_Format();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a 16-bit variable by its virtual address.
|
||||
* PUBLIC RETURN: EE_OK / EE_NOT_FOUND / EE_ERROR (as uint16_t)
|
||||
*/
|
||||
uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t *Data)
|
||||
{
|
||||
EE_Status st;
|
||||
|
||||
if (Data == NULL)
|
||||
return EE_ERROR;
|
||||
|
||||
st = EE_FindInPage(EE_ActivePageBase, VirtAddress, Data);
|
||||
return (uint16_t)st;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write (append) a 16-bit variable.
|
||||
* - Writes a new record in the active page.
|
||||
* - If the page is full, triggers a page transfer (GC).
|
||||
* PUBLIC RETURN: EE_OK / EE_ERROR / EE_NO_SPACE (as uint16_t)
|
||||
*/
|
||||
uint16_t EE_WriteVariable(uint16_t VirtAddress, uint16_t Data)
|
||||
{
|
||||
uint32_t freeAddr;
|
||||
EE_Status st;
|
||||
|
||||
/* Find free space in active page */
|
||||
freeAddr = EE_FindFreeAddress(EE_ActivePageBase);
|
||||
if (freeAddr != 0U)
|
||||
{
|
||||
/* Write new record */
|
||||
if (EE_FlashProgramHalfWord(freeAddr, VirtAddress) != HAL_OK)
|
||||
return EE_ERROR;
|
||||
if (EE_FlashProgramHalfWord(freeAddr + 2U, Data) != HAL_OK)
|
||||
return EE_ERROR;
|
||||
|
||||
return EE_OK;
|
||||
}
|
||||
|
||||
/* No space -> page transfer */
|
||||
st = EE_PageTransfer(VirtAddress, Data);
|
||||
return (uint16_t)st;
|
||||
}
|
||||
|
||||
void loadEE(void){
|
||||
char s [100];
|
||||
EEW_Read(M1PWMAP, &m1pwmap);
|
||||
EEW_Read(M1PWMCH, &m1pwmch);
|
||||
EEW_Read(M2PWMAP, &m2pwmap);
|
||||
EEW_Read(M2PWMCH, &m2pwmch);
|
||||
EEW_Read(M3PWMAP, &m3pwmap);
|
||||
EEW_Read(M3PWMCH, &m3pwmch);
|
||||
EEW_Read(M4PWMAP, &m4pwmap);
|
||||
EEW_Read(M4PWMCH, &m4pwmch);
|
||||
EEW_Read(T1AP, &t1ap);
|
||||
EEW_Read(T2AP, &t2ap);
|
||||
EEW_Read(T3AP, &t3ap);
|
||||
EEW_Read(T4AP, &t4ap);
|
||||
EEW_Read(TWAP, &twap);
|
||||
EEW_Read(T1CH, &t1ch);
|
||||
EEW_Read(T2CH, &t2ch);
|
||||
EEW_Read(T3CH, &t3ch);
|
||||
EEW_Read(T4CH, &t4ch);
|
||||
EEW_Read(TWCH, &twch);
|
||||
EEW_Read(TRAMP1, &tramp1);
|
||||
EEW_Read(M1PWMMAN, &m1pwmMan);
|
||||
EEW_Read(M2PWMMAN, &m2pwmMan);
|
||||
EEW_Read(M3PWMMAN, &m3pwmMan);
|
||||
EEW_Read(M4PWMMAN, &m4pwmMan);
|
||||
EEW_Read(TRAMPMAN, &trampman);
|
||||
EEW_Read(TRAMP, &tramp);
|
||||
|
||||
EEW_Read(APM1START,apM1start);
|
||||
EEW_Read(APM1STOP ,apM1stop);
|
||||
EEW_Read(APM2START,apM2start);
|
||||
EEW_Read(APM2STOP ,apM2stop);
|
||||
EEW_Read(APM3START,apM3start);
|
||||
EEW_Read(APM3STOP ,apM3stop);
|
||||
EEW_Read(APM4START,apM4start);
|
||||
EEW_Read(APM4STOP ,apM4stop);
|
||||
EEW_Read(CHM1START,chM1start);
|
||||
EEW_Read(CHM1STOP ,chM1stop);
|
||||
EEW_Read(CHM2START,chM2start);
|
||||
EEW_Read(CHM2STOP ,chM2stop);
|
||||
EEW_Read(CHM3START,chM3start);
|
||||
EEW_Read(CHM3STOP ,chM3stop);
|
||||
EEW_Read(CHM4START,chM4start);
|
||||
EEW_Read(CHM4STOP ,chM4stop);
|
||||
|
||||
sprintf((char*)s,"LoadEE\n");
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
}
|
||||
@@ -0,0 +1,431 @@
|
||||
#include "eeprom.h"
|
||||
|
||||
/*
|
||||
* Record format (4 bytes):
|
||||
* [0] VirtAddress (uint16_t)
|
||||
* [2] Data (uint16_t)
|
||||
*
|
||||
* Page layout:
|
||||
* [0] PageStatus (uint16_t)
|
||||
* [2..] Records...
|
||||
*/
|
||||
|
||||
extern uint16_t m1pwmap;
|
||||
extern uint16_t m1pwmch;
|
||||
extern uint16_t m2pwmap;
|
||||
extern uint16_t m2pwmch;
|
||||
extern uint16_t m3pwmap;
|
||||
extern uint16_t m3pwmch;
|
||||
extern uint16_t m4pwmap;
|
||||
extern uint16_t m4pwmch;
|
||||
extern uint16_t t1ap;
|
||||
extern uint16_t t2ap;
|
||||
extern uint16_t t3ap;
|
||||
extern uint16_t t4ap;
|
||||
extern uint16_t twap;
|
||||
extern uint16_t tramp;
|
||||
extern uint16_t t1ch;
|
||||
extern uint16_t t2ch;
|
||||
extern uint16_t t3ch;
|
||||
extern uint16_t t4ch;
|
||||
extern uint16_t twch;
|
||||
extern uint16_t tramp1;
|
||||
extern uint16_t trampman;
|
||||
extern uint16_t m1pwmMan;
|
||||
extern uint16_t m2pwmMan;
|
||||
extern uint16_t m3pwmMan;
|
||||
extern uint16_t m4pwmMan;
|
||||
|
||||
const uint8_t deftab[EE_NUM_VIRTUAL_ADDR]={
|
||||
40, //m1pwmap
|
||||
60, //m1pwmch
|
||||
70, //m2pwmap
|
||||
70, //m2pwmch
|
||||
35, //m3pwmap
|
||||
40, //m3pwmch
|
||||
40, //m4pwmap
|
||||
40, //m4pwmch
|
||||
20, //m1rampstart
|
||||
20, //m2rampstart
|
||||
20, //m3rampstart
|
||||
20, //m4rampstart
|
||||
28, //t1ap
|
||||
4, //t2ap
|
||||
10, //t3ap
|
||||
40, //t4ap
|
||||
1, //twap
|
||||
27, //t1ch
|
||||
10, //t2ch
|
||||
30, //t3ch
|
||||
1, //t4ch
|
||||
1, //twch
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
100, //tramp1
|
||||
60, //m1pwmMan
|
||||
70, //m2pwmMan
|
||||
40, //m3pwmMan
|
||||
40, //m4pwmMan
|
||||
50, //trampman
|
||||
10, //tramp
|
||||
40,
|
||||
60,
|
||||
70,
|
||||
70,
|
||||
35,
|
||||
40,
|
||||
40,
|
||||
40,
|
||||
20,
|
||||
20,
|
||||
20,
|
||||
20,
|
||||
28,
|
||||
4,
|
||||
10,
|
||||
40,
|
||||
1,
|
||||
27,
|
||||
10,
|
||||
30,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
100,
|
||||
60,
|
||||
70,
|
||||
40,
|
||||
40,
|
||||
50,
|
||||
10,
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t VirtAddress;
|
||||
uint16_t Data;
|
||||
} EE_Record_t;
|
||||
|
||||
/* Active page base address (runtime selected in EE_Init) */
|
||||
static uint32_t EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
|
||||
/* 32 sequential virtual addresses */
|
||||
const uint16_t EE_VirtAddrs[EE_NUM_VIRTUAL_ADDR] =
|
||||
{
|
||||
0x0001, 0x0002, 0x0003, 0x0004,
|
||||
0x0005, 0x0006, 0x0007, 0x0008,
|
||||
0x0009, 0x000A, 0x000B, 0x000C,
|
||||
0x000D, 0x000E, 0x000F, 0x0010,
|
||||
0x0011, 0x0012, 0x0013, 0x0014,
|
||||
0x0015, 0x0016, 0x0017, 0x0018,
|
||||
0x0019, 0x001A, 0x001B, 0x001C,
|
||||
0x001D, 0x001E, 0x001F, 0x0020,
|
||||
|
||||
0x0021, 0x0022, 0x0023, 0x0024,
|
||||
0x0025, 0x0026, 0x0027, 0x0028,
|
||||
0x0029, 0x002A, 0x002B, 0x002C,
|
||||
0x002D, 0x002E, 0x002F, 0x0030,
|
||||
0x0031, 0x0032, 0x0033, 0x0034,
|
||||
0x0035, 0x0036, 0x0037, 0x0038,
|
||||
0x0039, 0x003A, 0x003B, 0x003C,
|
||||
0x003D, 0x003E, 0x003F, 0x0040
|
||||
};
|
||||
/* ========================================================================= */
|
||||
|
||||
/* --- Internal helpers ---------------------------------------------------- */
|
||||
|
||||
static uint16_t EE_GetPageStatus(uint32_t pageBase)
|
||||
{
|
||||
return *(__IO uint16_t *)pageBase;
|
||||
}
|
||||
|
||||
static HAL_StatusTypeDef EE_FlashProgramHalfWord(uint32_t Address, uint16_t Data)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
|
||||
HAL_FLASH_Unlock();
|
||||
status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, Address, Data);
|
||||
HAL_FLASH_Lock();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static HAL_StatusTypeDef EE_FlashErasePage(uint32_t PageAddress)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
FLASH_EraseInitTypeDef EraseInit;
|
||||
uint32_t PageError = 0;
|
||||
|
||||
HAL_FLASH_Unlock();
|
||||
|
||||
EraseInit.TypeErase = FLASH_TYPEERASE_PAGES;
|
||||
EraseInit.PageAddress = PageAddress;
|
||||
EraseInit.NbPages = 1;
|
||||
|
||||
status = HAL_FLASHEx_Erase(&EraseInit, &PageError);
|
||||
|
||||
HAL_FLASH_Lock();
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Find first free record address in given page (returns 0 if full) */
|
||||
static uint32_t EE_FindFreeAddress(uint32_t pageBase)
|
||||
{
|
||||
uint32_t addr = pageBase + 2U; /* Skip status word */
|
||||
uint32_t pageEnd = pageBase + EE_PAGE_SIZE;
|
||||
|
||||
while (addr < (pageEnd - sizeof(EE_Record_t) + 1U))
|
||||
{
|
||||
uint16_t vaddr = *(__IO uint16_t *)addr;
|
||||
|
||||
if (vaddr == 0xFFFFU)
|
||||
{
|
||||
/* Empty slot */
|
||||
return addr;
|
||||
}
|
||||
addr += sizeof(EE_Record_t);
|
||||
}
|
||||
|
||||
return 0U; /* No space */
|
||||
}
|
||||
|
||||
/* Find latest value of VirtAddress in a specific page (internal, uses EE_Status) */
|
||||
/* Find latest value of VirtAddress in a specific page (scan forward) */
|
||||
static EE_Status EE_FindInPage(uint32_t pageBase, uint16_t VirtAddress, uint16_t *Data)
|
||||
{
|
||||
uint32_t addr = pageBase + 2U; // skip status halfword
|
||||
uint32_t pageEnd = pageBase + EE_PAGE_SIZE;
|
||||
EE_Status result = EE_NOT_FOUND;
|
||||
uint16_t lastVal = 0;
|
||||
|
||||
if (Data == NULL)
|
||||
return EE_ERROR;
|
||||
|
||||
while (addr <= (pageEnd - sizeof(EE_Record_t)))
|
||||
{
|
||||
uint16_t vaddr = *(__IO uint16_t *)addr;
|
||||
|
||||
if (vaddr == 0xFFFFU)
|
||||
{
|
||||
// First empty slot => no more records in this page
|
||||
break;
|
||||
}
|
||||
|
||||
uint16_t value = *(__IO uint16_t *)(addr + 2U);
|
||||
|
||||
if (vaddr == VirtAddress)
|
||||
{
|
||||
lastVal = value; // keep most recent
|
||||
result = EE_OK;
|
||||
}
|
||||
|
||||
addr += sizeof(EE_Record_t); // move 4 bytes forward
|
||||
}
|
||||
|
||||
if (result == EE_OK)
|
||||
*Data = lastVal;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Format both pages: erase and set PAGE0 as VALID */
|
||||
static EE_Status EE_Format(void)
|
||||
{
|
||||
if (EE_FlashErasePage(EE_PAGE0_BASE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
if (EE_FlashErasePage(EE_PAGE1_BASE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
if (EE_FlashProgramHalfWord(EE_PAGE0_BASE, EE_PAGE_STATUS_VALID) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* PAGE1 will remain erased (status = 0xFFFF) */
|
||||
EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
|
||||
return EE_STATUS_OK;
|
||||
}
|
||||
|
||||
/* Get the base of the other page */
|
||||
static uint32_t EE_GetOtherPageBase(uint32_t pageBase)
|
||||
{
|
||||
return (pageBase == EE_PAGE0_BASE) ? EE_PAGE1_BASE : EE_PAGE0_BASE;
|
||||
}
|
||||
|
||||
/* Page transfer (garbage collection + new write) */
|
||||
static EE_Status EE_PageTransfer(uint16_t VirtAddress, uint16_t Data)
|
||||
{
|
||||
uint32_t oldBase = EE_ActivePageBase;
|
||||
uint32_t newBase = EE_GetOtherPageBase(oldBase);
|
||||
uint32_t addr;
|
||||
uint16_t value;
|
||||
EE_Status st;
|
||||
|
||||
/* Erase new page */
|
||||
if (EE_FlashErasePage(newBase) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Mark new page as RECEIVE */
|
||||
if (EE_FlashProgramHalfWord(newBase, EE_PAGE_STATUS_RECEIVE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Start writing records just after status */
|
||||
addr = newBase + 2U;
|
||||
|
||||
/* For each known virtual variable */
|
||||
for (uint16_t i = 0; i < EE_NUM_VIRTUAL_ADDR; i++)
|
||||
{
|
||||
uint16_t vaddr = EE_VirtAddrs[i];
|
||||
|
||||
if (vaddr == VirtAddress)
|
||||
{
|
||||
/* Use the new data passed into PageTransfer */
|
||||
value = Data;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Read latest value from old active page */
|
||||
st = EE_FindInPage(oldBase, vaddr, &value);
|
||||
if (st != EE_STATUS_OK)
|
||||
{
|
||||
/* Variable never written -> skip */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Write record to new page */
|
||||
if (EE_FlashProgramHalfWord(addr, vaddr) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
if (EE_FlashProgramHalfWord(addr + 2U, value) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
addr += sizeof(EE_Record_t);
|
||||
if (addr >= (newBase + EE_PAGE_SIZE))
|
||||
return EE_STATUS_NO_SPACE;
|
||||
}
|
||||
|
||||
/* Erase old page */
|
||||
if (EE_FlashErasePage(oldBase) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Mark new page as VALID */
|
||||
if (EE_FlashProgramHalfWord(newBase, EE_PAGE_STATUS_VALID) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Update active page */
|
||||
EE_ActivePageBase = newBase;
|
||||
|
||||
return EE_STATUS_OK;
|
||||
}
|
||||
|
||||
/* --- Public API ----------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* Initialize the EEPROM emulation.
|
||||
* - Checks page statuses and chooses the active page.
|
||||
* - If inconsistent or blank, formats pages.
|
||||
* PUBLIC RETURN TYPE: uint16_t (EE_OK / EE_ERROR / ...)
|
||||
*/
|
||||
uint16_t EE_Init(void)
|
||||
{
|
||||
uint16_t status0 = EE_GetPageStatus(EE_PAGE0_BASE);
|
||||
uint16_t status1 = EE_GetPageStatus(EE_PAGE1_BASE);
|
||||
|
||||
if ((status0 == EE_PAGE_STATUS_ERASED) && (status1 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
/* Fresh device -> format */
|
||||
return (uint16_t)EE_Format();
|
||||
}
|
||||
else if ((status0 == EE_PAGE_STATUS_VALID) && (status1 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
return EE_OK;
|
||||
}
|
||||
else if ((status1 == EE_PAGE_STATUS_VALID) && (status0 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
EE_ActivePageBase = EE_PAGE1_BASE;
|
||||
return EE_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Any weird or inconsistent state -> reformat */
|
||||
return (uint16_t)EE_Format();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a 16-bit variable by its virtual address.
|
||||
* PUBLIC RETURN: EE_OK / EE_NOT_FOUND / EE_ERROR (as uint16_t)
|
||||
*/
|
||||
uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t *Data)
|
||||
{
|
||||
EE_Status st;
|
||||
|
||||
if (Data == NULL)
|
||||
return EE_ERROR;
|
||||
|
||||
st = EE_FindInPage(EE_ActivePageBase, VirtAddress, Data);
|
||||
return (uint16_t)st;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write (append) a 16-bit variable.
|
||||
* - Writes a new record in the active page.
|
||||
* - If the page is full, triggers a page transfer (GC).
|
||||
* PUBLIC RETURN: EE_OK / EE_ERROR / EE_NO_SPACE (as uint16_t)
|
||||
*/
|
||||
uint16_t EE_WriteVariable(uint16_t VirtAddress, uint16_t Data)
|
||||
{
|
||||
uint32_t freeAddr;
|
||||
EE_Status st;
|
||||
|
||||
/* Find free space in active page */
|
||||
freeAddr = EE_FindFreeAddress(EE_ActivePageBase);
|
||||
if (freeAddr != 0U)
|
||||
{
|
||||
/* Write new record */
|
||||
if (EE_FlashProgramHalfWord(freeAddr, VirtAddress) != HAL_OK)
|
||||
return EE_ERROR;
|
||||
if (EE_FlashProgramHalfWord(freeAddr + 2U, Data) != HAL_OK)
|
||||
return EE_ERROR;
|
||||
|
||||
return EE_OK;
|
||||
}
|
||||
|
||||
/* No space -> page transfer */
|
||||
st = EE_PageTransfer(VirtAddress, Data);
|
||||
return (uint16_t)st;
|
||||
}
|
||||
|
||||
void loadEE(void){
|
||||
EEW_Read(M1PWMAP, &m1pwmap);
|
||||
EEW_Read(M1PWMCH, &m1pwmch);
|
||||
EEW_Read(M2PWMAP, &m2pwmap);
|
||||
EEW_Read(M2PWMCH, &m2pwmch);
|
||||
EEW_Read(M3PWMAP, &m3pwmap);
|
||||
EEW_Read(M3PWMCH, &m3pwmch);
|
||||
EEW_Read(M4PWMAP, &m4pwmap);
|
||||
EEW_Read(M4PWMCH, &m4pwmch);
|
||||
EEW_Read(T1AP, &t1ap);
|
||||
EEW_Read(T2AP, &t2ap);
|
||||
EEW_Read(T3AP, &t3ap);
|
||||
EEW_Read(T4AP, &t4ap);
|
||||
EEW_Read(TWAP, &twap);
|
||||
EEW_Read(T1CH, &t1ch);
|
||||
EEW_Read(T2CH, &t2ch);
|
||||
EEW_Read(T3CH, &t3ch);
|
||||
EEW_Read(T4CH, &t4ch);
|
||||
EEW_Read(TWCH, &twch);
|
||||
EEW_Read(TRAMP1, &tramp1);
|
||||
EEW_Read(M1PWMMAN, &m1pwmMan);
|
||||
EEW_Read(M2PWMMAN, &m2pwmMan);
|
||||
EEW_Read(M3PWMMAN, &m3pwmMan);
|
||||
EEW_Read(M4PWMMAN, &m4pwmMan);
|
||||
EEW_Read(TRAMPMAN, &trampman);
|
||||
EEW_Read(TRAMP, &tramp);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
/*
|
||||
* mot.h
|
||||
*
|
||||
* Created on: May 2, 2026
|
||||
* Author: user
|
||||
*/
|
||||
|
||||
#ifndef SRC_MOT_H_
|
||||
#define SRC_MOT_H_
|
||||
|
||||
|
||||
|
||||
#endif /* SRC_MOT_H_ */
|
||||
@@ -0,0 +1,482 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "eeprom.h"
|
||||
extern UART_HandleTypeDef huart1;
|
||||
/*
|
||||
* Record format (4 bytes):
|
||||
* [0] VirtAddress (uint16_t)
|
||||
* [2] Data (uint16_t)
|
||||
*
|
||||
* Page layout:
|
||||
* [0] PageStatus (uint16_t)
|
||||
* [2..] Records...
|
||||
*/
|
||||
|
||||
extern uint16_t m1pwmap;
|
||||
extern uint16_t m1pwmch;
|
||||
extern uint16_t m2pwmap;
|
||||
extern uint16_t m2pwmch;
|
||||
extern uint16_t m3pwmap;
|
||||
extern uint16_t m3pwmch;
|
||||
extern uint16_t m4pwmap;
|
||||
extern uint16_t m4pwmch;
|
||||
extern uint16_t m1TimeoutMan;
|
||||
extern uint16_t m2TimeoutMan;
|
||||
extern uint16_t m3TimeoutMan;
|
||||
extern uint16_t m4TimeoutMan;
|
||||
extern uint16_t twap;
|
||||
extern uint16_t tramp;
|
||||
extern uint16_t t1ch;
|
||||
extern uint16_t t2ch;
|
||||
extern uint16_t t3ch;
|
||||
extern uint16_t t4ch;
|
||||
extern uint16_t twch;
|
||||
extern uint16_t tramp1;
|
||||
extern uint16_t trampman;
|
||||
extern uint16_t m1pwmMan;
|
||||
extern uint16_t m2pwmMan;
|
||||
extern uint16_t m3pwmMan;
|
||||
extern uint16_t m4pwmMan;
|
||||
|
||||
|
||||
extern uint16_t apM1start;
|
||||
extern uint16_t apM1stop;
|
||||
extern uint16_t apM2start;
|
||||
extern uint16_t apM2stop;
|
||||
extern uint16_t apM3start;
|
||||
extern uint16_t apM3stop;
|
||||
extern uint16_t apM4start;
|
||||
extern uint16_t apM4stop;
|
||||
extern uint16_t chM1start;
|
||||
extern uint16_t chM1stop;
|
||||
extern uint16_t chM2start;
|
||||
extern uint16_t chM2stop;
|
||||
extern uint16_t chM3start;
|
||||
extern uint16_t chM3stop;
|
||||
extern uint16_t chM4start;
|
||||
extern uint16_t chM4stop;
|
||||
|
||||
const uint16_t deftab[EE_NUM_VIRTUAL_ADDR]={
|
||||
40, //m1pwmap
|
||||
60, //m1pwmch
|
||||
70, //m2pwmap
|
||||
70, //m2pwmch
|
||||
35, //m3pwmap
|
||||
40, //m3pwmch
|
||||
40, //m4pwmap
|
||||
40, //m4pwmch
|
||||
20, //m1rampstart
|
||||
20, //m2rampstart
|
||||
20, //m3rampstart
|
||||
20, //m4rampstart
|
||||
230,//m1timeoutman
|
||||
100,//m2timeoutman
|
||||
130,//m3timeoutman
|
||||
300,//m4timeoutman
|
||||
1, //twap
|
||||
27, //t1ch
|
||||
10, //t2ch
|
||||
30, //t3ch
|
||||
1, //t4ch
|
||||
1, //twch
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
100, //tramp1
|
||||
60, //m1pwmMan
|
||||
70, //m2pwmMan
|
||||
40, //m3pwmMan
|
||||
40, //m4pwmMan
|
||||
50, //trampman
|
||||
10, //tramp
|
||||
310, //apM1start;
|
||||
450, //apM1stop;
|
||||
30, //apM2start;
|
||||
310, //apM2stop;
|
||||
350, //apM3start;
|
||||
450, //apM3stop;
|
||||
450, //apM4start;
|
||||
850, //apM4stop;
|
||||
10, //chM1start;
|
||||
280, //chM1stop;
|
||||
280, //chM2start;
|
||||
580, //chM2stop;
|
||||
20, //chM3start;
|
||||
280, //chM3stop;
|
||||
280, //chM4start;
|
||||
680, //chM4stop;
|
||||
1,
|
||||
27,
|
||||
10,
|
||||
30,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
100,
|
||||
60,
|
||||
70,
|
||||
40,
|
||||
40,
|
||||
50,
|
||||
10,
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t VirtAddress;
|
||||
uint16_t Data;
|
||||
} EE_Record_t;
|
||||
|
||||
/* Active page base address (runtime selected in EE_Init) */
|
||||
static uint32_t EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
|
||||
/* 32 sequential virtual addresses */
|
||||
const uint16_t EE_VirtAddrs[EE_NUM_VIRTUAL_ADDR] =
|
||||
{
|
||||
0x0001, 0x0002, 0x0003, 0x0004,
|
||||
0x0005, 0x0006, 0x0007, 0x0008,
|
||||
0x0009, 0x000A, 0x000B, 0x000C,
|
||||
0x000D, 0x000E, 0x000F, 0x0010,
|
||||
0x0011, 0x0012, 0x0013, 0x0014,
|
||||
0x0015, 0x0016, 0x0017, 0x0018,
|
||||
0x0019, 0x001A, 0x001B, 0x001C,
|
||||
0x001D, 0x001E, 0x001F, 0x0020,
|
||||
|
||||
0x0021, 0x0022, 0x0023, 0x0024,
|
||||
0x0025, 0x0026, 0x0027, 0x0028,
|
||||
0x0029, 0x002A, 0x002B, 0x002C,
|
||||
0x002D, 0x002E, 0x002F, 0x0030,
|
||||
0x0031, 0x0032, 0x0033, 0x0034,
|
||||
0x0035, 0x0036, 0x0037, 0x0038,
|
||||
0x0039, 0x003A, 0x003B, 0x003C,
|
||||
0x003D, 0x003E, 0x003F, 0x0040
|
||||
};
|
||||
/* ========================================================================= */
|
||||
|
||||
/* --- Internal helpers ---------------------------------------------------- */
|
||||
|
||||
static uint16_t EE_GetPageStatus(uint32_t pageBase)
|
||||
{
|
||||
return *(__IO uint16_t *)pageBase;
|
||||
}
|
||||
|
||||
static HAL_StatusTypeDef EE_FlashProgramHalfWord(uint32_t Address, uint16_t Data)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
|
||||
HAL_FLASH_Unlock();
|
||||
status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, Address, Data);
|
||||
HAL_FLASH_Lock();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static HAL_StatusTypeDef EE_FlashErasePage(uint32_t PageAddress)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
FLASH_EraseInitTypeDef EraseInit;
|
||||
uint32_t PageError = 0;
|
||||
|
||||
HAL_FLASH_Unlock();
|
||||
|
||||
EraseInit.TypeErase = FLASH_TYPEERASE_PAGES;
|
||||
EraseInit.PageAddress = PageAddress;
|
||||
EraseInit.NbPages = 1;
|
||||
|
||||
status = HAL_FLASHEx_Erase(&EraseInit, &PageError);
|
||||
|
||||
HAL_FLASH_Lock();
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Find first free record address in given page (returns 0 if full) */
|
||||
static uint32_t EE_FindFreeAddress(uint32_t pageBase)
|
||||
{
|
||||
uint32_t addr = pageBase + 2U; /* Skip status word */
|
||||
uint32_t pageEnd = pageBase + EE_PAGE_SIZE;
|
||||
|
||||
while (addr < (pageEnd - sizeof(EE_Record_t) + 1U))
|
||||
{
|
||||
uint16_t vaddr = *(__IO uint16_t *)addr;
|
||||
|
||||
if (vaddr == 0xFFFFU)
|
||||
{
|
||||
/* Empty slot */
|
||||
return addr;
|
||||
}
|
||||
addr += sizeof(EE_Record_t);
|
||||
}
|
||||
|
||||
return 0U; /* No space */
|
||||
}
|
||||
|
||||
/* Find latest value of VirtAddress in a specific page (internal, uses EE_Status) */
|
||||
/* Find latest value of VirtAddress in a specific page (scan forward) */
|
||||
static EE_Status EE_FindInPage(uint32_t pageBase, uint16_t VirtAddress, uint16_t *Data)
|
||||
{
|
||||
uint32_t addr = pageBase + 2U; // skip status halfword
|
||||
uint32_t pageEnd = pageBase + EE_PAGE_SIZE;
|
||||
EE_Status result = EE_NOT_FOUND;
|
||||
uint16_t lastVal = 0;
|
||||
|
||||
if (Data == NULL)
|
||||
return EE_ERROR;
|
||||
|
||||
while (addr <= (pageEnd - sizeof(EE_Record_t)))
|
||||
{
|
||||
uint16_t vaddr = *(__IO uint16_t *)addr;
|
||||
|
||||
if (vaddr == 0xFFFFU)
|
||||
{
|
||||
// First empty slot => no more records in this page
|
||||
break;
|
||||
}
|
||||
|
||||
uint16_t value = *(__IO uint16_t *)(addr + 2U);
|
||||
|
||||
if (vaddr == VirtAddress)
|
||||
{
|
||||
lastVal = value; // keep most recent
|
||||
result = EE_OK;
|
||||
}
|
||||
|
||||
addr += sizeof(EE_Record_t); // move 4 bytes forward
|
||||
}
|
||||
|
||||
if (result == EE_OK)
|
||||
*Data = lastVal;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Format both pages: erase and set PAGE0 as VALID */
|
||||
static EE_Status EE_Format(void)
|
||||
{
|
||||
if (EE_FlashErasePage(EE_PAGE0_BASE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
if (EE_FlashErasePage(EE_PAGE1_BASE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
if (EE_FlashProgramHalfWord(EE_PAGE0_BASE, EE_PAGE_STATUS_VALID) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* PAGE1 will remain erased (status = 0xFFFF) */
|
||||
EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
|
||||
return EE_STATUS_OK;
|
||||
}
|
||||
|
||||
/* Get the base of the other page */
|
||||
static uint32_t EE_GetOtherPageBase(uint32_t pageBase)
|
||||
{
|
||||
return (pageBase == EE_PAGE0_BASE) ? EE_PAGE1_BASE : EE_PAGE0_BASE;
|
||||
}
|
||||
|
||||
/* Page transfer (garbage collection + new write) */
|
||||
static EE_Status EE_PageTransfer(uint16_t VirtAddress, uint16_t Data)
|
||||
{
|
||||
uint32_t oldBase = EE_ActivePageBase;
|
||||
uint32_t newBase = EE_GetOtherPageBase(oldBase);
|
||||
uint32_t addr;
|
||||
uint16_t value;
|
||||
EE_Status st;
|
||||
|
||||
/* Erase new page */
|
||||
if (EE_FlashErasePage(newBase) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Mark new page as RECEIVE */
|
||||
if (EE_FlashProgramHalfWord(newBase, EE_PAGE_STATUS_RECEIVE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Start writing records just after status */
|
||||
addr = newBase + 2U;
|
||||
|
||||
/* For each known virtual variable */
|
||||
for (uint16_t i = 0; i < EE_NUM_VIRTUAL_ADDR; i++)
|
||||
{
|
||||
uint16_t vaddr = EE_VirtAddrs[i];
|
||||
|
||||
if (vaddr == VirtAddress)
|
||||
{
|
||||
/* Use the new data passed into PageTransfer */
|
||||
value = Data;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Read latest value from old active page */
|
||||
st = EE_FindInPage(oldBase, vaddr, &value);
|
||||
if (st != EE_STATUS_OK)
|
||||
{
|
||||
/* Variable never written -> skip */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Write record to new page */
|
||||
if (EE_FlashProgramHalfWord(addr, vaddr) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
if (EE_FlashProgramHalfWord(addr + 2U, value) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
addr += sizeof(EE_Record_t);
|
||||
if (addr >= (newBase + EE_PAGE_SIZE))
|
||||
return EE_STATUS_NO_SPACE;
|
||||
}
|
||||
|
||||
/* Erase old page */
|
||||
if (EE_FlashErasePage(oldBase) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Mark new page as VALID */
|
||||
if (EE_FlashProgramHalfWord(newBase, EE_PAGE_STATUS_VALID) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Update active page */
|
||||
EE_ActivePageBase = newBase;
|
||||
|
||||
return EE_STATUS_OK;
|
||||
}
|
||||
|
||||
/* --- Public API ----------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* Initialize the EEPROM emulation.
|
||||
* - Checks page statuses and chooses the active page.
|
||||
* - If inconsistent or blank, formats pages.
|
||||
* PUBLIC RETURN TYPE: uint16_t (EE_OK / EE_ERROR / ...)
|
||||
*/
|
||||
uint16_t EE_Init(void)
|
||||
{
|
||||
uint16_t status0 = EE_GetPageStatus(EE_PAGE0_BASE);
|
||||
uint16_t status1 = EE_GetPageStatus(EE_PAGE1_BASE);
|
||||
|
||||
if ((status0 == EE_PAGE_STATUS_ERASED) && (status1 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
/* Fresh device -> format */
|
||||
return (uint16_t)EE_Format();
|
||||
}
|
||||
else if ((status0 == EE_PAGE_STATUS_VALID) && (status1 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
return EE_OK;
|
||||
}
|
||||
else if ((status1 == EE_PAGE_STATUS_VALID) && (status0 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
EE_ActivePageBase = EE_PAGE1_BASE;
|
||||
return EE_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Any weird or inconsistent state -> reformat */
|
||||
return (uint16_t)EE_Format();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a 16-bit variable by its virtual address.
|
||||
* PUBLIC RETURN: EE_OK / EE_NOT_FOUND / EE_ERROR (as uint16_t)
|
||||
*/
|
||||
uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t *Data)
|
||||
{
|
||||
EE_Status st;
|
||||
|
||||
if (Data == NULL)
|
||||
return EE_ERROR;
|
||||
|
||||
st = EE_FindInPage(EE_ActivePageBase, VirtAddress, Data);
|
||||
return (uint16_t)st;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write (append) a 16-bit variable.
|
||||
* - Writes a new record in the active page.
|
||||
* - If the page is full, triggers a page transfer (GC).
|
||||
* PUBLIC RETURN: EE_OK / EE_ERROR / EE_NO_SPACE (as uint16_t)
|
||||
*/
|
||||
uint16_t EE_WriteVariable(uint16_t VirtAddress, uint16_t Data)
|
||||
{
|
||||
uint32_t freeAddr;
|
||||
EE_Status st;
|
||||
|
||||
/* Find free space in active page */
|
||||
freeAddr = EE_FindFreeAddress(EE_ActivePageBase);
|
||||
if (freeAddr != 0U)
|
||||
{
|
||||
/* Write new record */
|
||||
if (EE_FlashProgramHalfWord(freeAddr, VirtAddress) != HAL_OK)
|
||||
return EE_ERROR;
|
||||
if (EE_FlashProgramHalfWord(freeAddr + 2U, Data) != HAL_OK)
|
||||
return EE_ERROR;
|
||||
|
||||
return EE_OK;
|
||||
}
|
||||
|
||||
/* No space -> page transfer */
|
||||
st = EE_PageTransfer(VirtAddress, Data);
|
||||
return (uint16_t)st;
|
||||
}
|
||||
|
||||
void loadEE(void){
|
||||
char s [200];
|
||||
EEW_Read(M1PWMAP, &m1pwmap);
|
||||
EEW_Read(M1PWMCH, &m1pwmch);
|
||||
EEW_Read(M2PWMAP, &m2pwmap);
|
||||
EEW_Read(M2PWMCH, &m2pwmch);
|
||||
EEW_Read(M3PWMAP, &m3pwmap);
|
||||
EEW_Read(M3PWMCH, &m3pwmch);
|
||||
EEW_Read(M4PWMAP, &m4pwmap);
|
||||
EEW_Read(M4PWMCH, &m4pwmch);
|
||||
EEW_Read(M1TIMEOUTMAN, &m1TimeoutMan);
|
||||
EEW_Read(M2TIMEOUTMAN, &m2TimeoutMan);
|
||||
EEW_Read(M3TIMEOUTMAN, &m3TimeoutMan);
|
||||
EEW_Read(M4TIMEOUTMAN, &m4TimeoutMan);
|
||||
EEW_Read(TWAP, &twap);
|
||||
EEW_Read(T1CH, &t1ch);
|
||||
EEW_Read(T2CH, &t2ch);
|
||||
EEW_Read(T3CH, &t3ch);
|
||||
EEW_Read(T4CH, &t4ch);
|
||||
EEW_Read(TWCH, &twch);
|
||||
EEW_Read(TRAMP1, &tramp1);
|
||||
EEW_Read(M1PWMMAN, &m1pwmMan);
|
||||
EEW_Read(M2PWMMAN, &m2pwmMan);
|
||||
EEW_Read(M3PWMMAN, &m3pwmMan);
|
||||
EEW_Read(M4PWMMAN, &m4pwmMan);
|
||||
EEW_Read(TRAMPMAN, &trampman);
|
||||
EEW_Read(TRAMP, &tramp);
|
||||
|
||||
EEW_Read(APM1START,&apM1start);
|
||||
EEW_Read(APM1STOP ,&apM1stop);
|
||||
EEW_Read(APM2START,&apM2start);
|
||||
EEW_Read(APM2STOP ,&apM2stop);
|
||||
EEW_Read(APM3START,&apM3start);
|
||||
EEW_Read(APM3STOP ,&apM3stop);
|
||||
EEW_Read(APM4START,&apM4start);
|
||||
EEW_Read(APM4STOP ,&apM4stop);
|
||||
EEW_Read(CHM1START,&chM1start);
|
||||
EEW_Read(CHM1STOP ,&chM1stop);
|
||||
EEW_Read(CHM2START,&chM2start);
|
||||
EEW_Read(CHM2STOP ,&chM2stop);
|
||||
EEW_Read(CHM3START,&chM3start);
|
||||
EEW_Read(CHM3STOP ,&chM3stop);
|
||||
EEW_Read(CHM4START,&chM4start);
|
||||
EEW_Read(CHM4STOP ,&chM4stop);
|
||||
|
||||
sprintf((char*)s,"LoadEE\n");
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
sprintf((char*)s,"\nm1pwmap=%d m1pwmch=%d m2pwmap=%d m2pwmch=%d m3pwmap=%d m3pwmch=%d m4pwmap=%d m4pwmch=%d",m1pwmap,m1pwmch,m2pwmap,m2pwmch,m3pwmap,m3pwmch,m4pwmap, m4pwmch);
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
sprintf((char*)s,"\nm1TimeoutMan=%d m2TimeoutMan=%d m3TimeoutMan=%d m4TimeoutMan=%d ",m1TimeouMan,m2TimeoutMan,m3timeoutMan,m4TimeoutMan);
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
sprintf((char*)s,"\ntramp=%d trampman=%d",tramp,trampman);
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
sprintf((char*)s,"\nm1pwmMan=%d m2pwmMan=%d m3pwmMan=%d m4pwmMan=%d",m1pwmMan,m2pwmMan,m3pwmMan,m4pwmMan);
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,472 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "eeprom.h"
|
||||
extern UART_HandleTypeDef huart1;
|
||||
/*
|
||||
* Record format (4 bytes):
|
||||
* [0] VirtAddress (uint16_t)
|
||||
* [2] Data (uint16_t)
|
||||
*
|
||||
* Page layout:
|
||||
* [0] PageStatus (uint16_t)
|
||||
* [2..] Records...
|
||||
*/
|
||||
|
||||
extern uint16_t m1pwmap;
|
||||
extern uint16_t m1pwmch;
|
||||
extern uint16_t m2pwmap;
|
||||
extern uint16_t m2pwmch;
|
||||
extern uint16_t m3pwmap;
|
||||
extern uint16_t m3pwmch;
|
||||
extern uint16_t m4pwmap;
|
||||
extern uint16_t m4pwmch;
|
||||
extern uint16_t t1ap;
|
||||
extern uint16_t t2ap;
|
||||
extern uint16_t t3ap;
|
||||
extern uint16_t t4ap;
|
||||
extern uint16_t twap;
|
||||
extern uint16_t tramp;
|
||||
extern uint16_t t1ch;
|
||||
extern uint16_t t2ch;
|
||||
extern uint16_t t3ch;
|
||||
extern uint16_t t4ch;
|
||||
extern uint16_t twch;
|
||||
extern uint16_t tramp1;
|
||||
extern uint16_t trampman;
|
||||
extern uint16_t m1pwmMan;
|
||||
extern uint16_t m2pwmMan;
|
||||
extern uint16_t m3pwmMan;
|
||||
extern uint16_t m4pwmMan;
|
||||
|
||||
|
||||
extern uint16_t apM1start;
|
||||
extern uint16_t apM1stop;
|
||||
extern uint16_t apM2start;
|
||||
extern uint16_t apM2stop;
|
||||
extern uint16_t apM3start;
|
||||
extern uint16_t apM3stop;
|
||||
extern uint16_t apM4start;
|
||||
extern uint16_t apM4stop;
|
||||
extern uint16_t chM1start;
|
||||
extern uint16_t chM1stop;
|
||||
extern uint16_t chM2start;
|
||||
extern uint16_t chM2stop;
|
||||
extern uint16_t chM3start;
|
||||
extern uint16_t chM3stop;
|
||||
extern uint16_t chM4start;
|
||||
extern uint16_t chM4stop;
|
||||
|
||||
const uint8_t deftab[EE_NUM_VIRTUAL_ADDR]={
|
||||
40, //m1pwmap
|
||||
60, //m1pwmch
|
||||
70, //m2pwmap
|
||||
70, //m2pwmch
|
||||
35, //m3pwmap
|
||||
40, //m3pwmch
|
||||
40, //m4pwmap
|
||||
40, //m4pwmch
|
||||
20, //m1rampstart
|
||||
20, //m2rampstart
|
||||
20, //m3rampstart
|
||||
20, //m4rampstart
|
||||
28, //t1ap
|
||||
4, //t2ap
|
||||
10, //t3ap
|
||||
40, //t4ap
|
||||
1, //twap
|
||||
27, //t1ch
|
||||
10, //t2ch
|
||||
30, //t3ch
|
||||
1, //t4ch
|
||||
1, //twch
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
100, //tramp1
|
||||
60, //m1pwmMan
|
||||
70, //m2pwmMan
|
||||
40, //m3pwmMan
|
||||
40, //m4pwmMan
|
||||
50, //trampman
|
||||
10, //tramp
|
||||
0, //apM1start;
|
||||
0, //apM1stop;
|
||||
0, //apM2start;
|
||||
0, //apM2stop;
|
||||
0, //apM3start;
|
||||
0, //apM3stop;
|
||||
0, //apM4start;
|
||||
0, //apM4stop;
|
||||
0, //chM1start;
|
||||
0, //chM1stop;
|
||||
0, //chM2start;
|
||||
0, //chM2stop;
|
||||
0, //chM3start;
|
||||
0, //chM3stop;
|
||||
0, //chM4start;
|
||||
0, //chM4stop;
|
||||
1,
|
||||
27,
|
||||
10,
|
||||
30,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
100,
|
||||
60,
|
||||
70,
|
||||
40,
|
||||
40,
|
||||
50,
|
||||
10,
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t VirtAddress;
|
||||
uint16_t Data;
|
||||
} EE_Record_t;
|
||||
|
||||
/* Active page base address (runtime selected in EE_Init) */
|
||||
static uint32_t EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
|
||||
/* 32 sequential virtual addresses */
|
||||
const uint16_t EE_VirtAddrs[EE_NUM_VIRTUAL_ADDR] =
|
||||
{
|
||||
0x0001, 0x0002, 0x0003, 0x0004,
|
||||
0x0005, 0x0006, 0x0007, 0x0008,
|
||||
0x0009, 0x000A, 0x000B, 0x000C,
|
||||
0x000D, 0x000E, 0x000F, 0x0010,
|
||||
0x0011, 0x0012, 0x0013, 0x0014,
|
||||
0x0015, 0x0016, 0x0017, 0x0018,
|
||||
0x0019, 0x001A, 0x001B, 0x001C,
|
||||
0x001D, 0x001E, 0x001F, 0x0020,
|
||||
|
||||
0x0021, 0x0022, 0x0023, 0x0024,
|
||||
0x0025, 0x0026, 0x0027, 0x0028,
|
||||
0x0029, 0x002A, 0x002B, 0x002C,
|
||||
0x002D, 0x002E, 0x002F, 0x0030,
|
||||
0x0031, 0x0032, 0x0033, 0x0034,
|
||||
0x0035, 0x0036, 0x0037, 0x0038,
|
||||
0x0039, 0x003A, 0x003B, 0x003C,
|
||||
0x003D, 0x003E, 0x003F, 0x0040
|
||||
};
|
||||
/* ========================================================================= */
|
||||
|
||||
/* --- Internal helpers ---------------------------------------------------- */
|
||||
|
||||
static uint16_t EE_GetPageStatus(uint32_t pageBase)
|
||||
{
|
||||
return *(__IO uint16_t *)pageBase;
|
||||
}
|
||||
|
||||
static HAL_StatusTypeDef EE_FlashProgramHalfWord(uint32_t Address, uint16_t Data)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
|
||||
HAL_FLASH_Unlock();
|
||||
status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, Address, Data);
|
||||
HAL_FLASH_Lock();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static HAL_StatusTypeDef EE_FlashErasePage(uint32_t PageAddress)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
FLASH_EraseInitTypeDef EraseInit;
|
||||
uint32_t PageError = 0;
|
||||
|
||||
HAL_FLASH_Unlock();
|
||||
|
||||
EraseInit.TypeErase = FLASH_TYPEERASE_PAGES;
|
||||
EraseInit.PageAddress = PageAddress;
|
||||
EraseInit.NbPages = 1;
|
||||
|
||||
status = HAL_FLASHEx_Erase(&EraseInit, &PageError);
|
||||
|
||||
HAL_FLASH_Lock();
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Find first free record address in given page (returns 0 if full) */
|
||||
static uint32_t EE_FindFreeAddress(uint32_t pageBase)
|
||||
{
|
||||
uint32_t addr = pageBase + 2U; /* Skip status word */
|
||||
uint32_t pageEnd = pageBase + EE_PAGE_SIZE;
|
||||
|
||||
while (addr < (pageEnd - sizeof(EE_Record_t) + 1U))
|
||||
{
|
||||
uint16_t vaddr = *(__IO uint16_t *)addr;
|
||||
|
||||
if (vaddr == 0xFFFFU)
|
||||
{
|
||||
/* Empty slot */
|
||||
return addr;
|
||||
}
|
||||
addr += sizeof(EE_Record_t);
|
||||
}
|
||||
|
||||
return 0U; /* No space */
|
||||
}
|
||||
|
||||
/* Find latest value of VirtAddress in a specific page (internal, uses EE_Status) */
|
||||
/* Find latest value of VirtAddress in a specific page (scan forward) */
|
||||
static EE_Status EE_FindInPage(uint32_t pageBase, uint16_t VirtAddress, uint16_t *Data)
|
||||
{
|
||||
uint32_t addr = pageBase + 2U; // skip status halfword
|
||||
uint32_t pageEnd = pageBase + EE_PAGE_SIZE;
|
||||
EE_Status result = EE_NOT_FOUND;
|
||||
uint16_t lastVal = 0;
|
||||
|
||||
if (Data == NULL)
|
||||
return EE_ERROR;
|
||||
|
||||
while (addr <= (pageEnd - sizeof(EE_Record_t)))
|
||||
{
|
||||
uint16_t vaddr = *(__IO uint16_t *)addr;
|
||||
|
||||
if (vaddr == 0xFFFFU)
|
||||
{
|
||||
// First empty slot => no more records in this page
|
||||
break;
|
||||
}
|
||||
|
||||
uint16_t value = *(__IO uint16_t *)(addr + 2U);
|
||||
|
||||
if (vaddr == VirtAddress)
|
||||
{
|
||||
lastVal = value; // keep most recent
|
||||
result = EE_OK;
|
||||
}
|
||||
|
||||
addr += sizeof(EE_Record_t); // move 4 bytes forward
|
||||
}
|
||||
|
||||
if (result == EE_OK)
|
||||
*Data = lastVal;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Format both pages: erase and set PAGE0 as VALID */
|
||||
static EE_Status EE_Format(void)
|
||||
{
|
||||
if (EE_FlashErasePage(EE_PAGE0_BASE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
if (EE_FlashErasePage(EE_PAGE1_BASE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
if (EE_FlashProgramHalfWord(EE_PAGE0_BASE, EE_PAGE_STATUS_VALID) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* PAGE1 will remain erased (status = 0xFFFF) */
|
||||
EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
|
||||
return EE_STATUS_OK;
|
||||
}
|
||||
|
||||
/* Get the base of the other page */
|
||||
static uint32_t EE_GetOtherPageBase(uint32_t pageBase)
|
||||
{
|
||||
return (pageBase == EE_PAGE0_BASE) ? EE_PAGE1_BASE : EE_PAGE0_BASE;
|
||||
}
|
||||
|
||||
/* Page transfer (garbage collection + new write) */
|
||||
static EE_Status EE_PageTransfer(uint16_t VirtAddress, uint16_t Data)
|
||||
{
|
||||
uint32_t oldBase = EE_ActivePageBase;
|
||||
uint32_t newBase = EE_GetOtherPageBase(oldBase);
|
||||
uint32_t addr;
|
||||
uint16_t value;
|
||||
EE_Status st;
|
||||
|
||||
/* Erase new page */
|
||||
if (EE_FlashErasePage(newBase) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Mark new page as RECEIVE */
|
||||
if (EE_FlashProgramHalfWord(newBase, EE_PAGE_STATUS_RECEIVE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Start writing records just after status */
|
||||
addr = newBase + 2U;
|
||||
|
||||
/* For each known virtual variable */
|
||||
for (uint16_t i = 0; i < EE_NUM_VIRTUAL_ADDR; i++)
|
||||
{
|
||||
uint16_t vaddr = EE_VirtAddrs[i];
|
||||
|
||||
if (vaddr == VirtAddress)
|
||||
{
|
||||
/* Use the new data passed into PageTransfer */
|
||||
value = Data;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Read latest value from old active page */
|
||||
st = EE_FindInPage(oldBase, vaddr, &value);
|
||||
if (st != EE_STATUS_OK)
|
||||
{
|
||||
/* Variable never written -> skip */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Write record to new page */
|
||||
if (EE_FlashProgramHalfWord(addr, vaddr) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
if (EE_FlashProgramHalfWord(addr + 2U, value) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
addr += sizeof(EE_Record_t);
|
||||
if (addr >= (newBase + EE_PAGE_SIZE))
|
||||
return EE_STATUS_NO_SPACE;
|
||||
}
|
||||
|
||||
/* Erase old page */
|
||||
if (EE_FlashErasePage(oldBase) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Mark new page as VALID */
|
||||
if (EE_FlashProgramHalfWord(newBase, EE_PAGE_STATUS_VALID) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Update active page */
|
||||
EE_ActivePageBase = newBase;
|
||||
|
||||
return EE_STATUS_OK;
|
||||
}
|
||||
|
||||
/* --- Public API ----------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* Initialize the EEPROM emulation.
|
||||
* - Checks page statuses and chooses the active page.
|
||||
* - If inconsistent or blank, formats pages.
|
||||
* PUBLIC RETURN TYPE: uint16_t (EE_OK / EE_ERROR / ...)
|
||||
*/
|
||||
uint16_t EE_Init(void)
|
||||
{
|
||||
uint16_t status0 = EE_GetPageStatus(EE_PAGE0_BASE);
|
||||
uint16_t status1 = EE_GetPageStatus(EE_PAGE1_BASE);
|
||||
|
||||
if ((status0 == EE_PAGE_STATUS_ERASED) && (status1 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
/* Fresh device -> format */
|
||||
return (uint16_t)EE_Format();
|
||||
}
|
||||
else if ((status0 == EE_PAGE_STATUS_VALID) && (status1 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
return EE_OK;
|
||||
}
|
||||
else if ((status1 == EE_PAGE_STATUS_VALID) && (status0 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
EE_ActivePageBase = EE_PAGE1_BASE;
|
||||
return EE_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Any weird or inconsistent state -> reformat */
|
||||
return (uint16_t)EE_Format();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a 16-bit variable by its virtual address.
|
||||
* PUBLIC RETURN: EE_OK / EE_NOT_FOUND / EE_ERROR (as uint16_t)
|
||||
*/
|
||||
uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t *Data)
|
||||
{
|
||||
EE_Status st;
|
||||
|
||||
if (Data == NULL)
|
||||
return EE_ERROR;
|
||||
|
||||
st = EE_FindInPage(EE_ActivePageBase, VirtAddress, Data);
|
||||
return (uint16_t)st;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write (append) a 16-bit variable.
|
||||
* - Writes a new record in the active page.
|
||||
* - If the page is full, triggers a page transfer (GC).
|
||||
* PUBLIC RETURN: EE_OK / EE_ERROR / EE_NO_SPACE (as uint16_t)
|
||||
*/
|
||||
uint16_t EE_WriteVariable(uint16_t VirtAddress, uint16_t Data)
|
||||
{
|
||||
uint32_t freeAddr;
|
||||
EE_Status st;
|
||||
|
||||
/* Find free space in active page */
|
||||
freeAddr = EE_FindFreeAddress(EE_ActivePageBase);
|
||||
if (freeAddr != 0U)
|
||||
{
|
||||
/* Write new record */
|
||||
if (EE_FlashProgramHalfWord(freeAddr, VirtAddress) != HAL_OK)
|
||||
return EE_ERROR;
|
||||
if (EE_FlashProgramHalfWord(freeAddr + 2U, Data) != HAL_OK)
|
||||
return EE_ERROR;
|
||||
|
||||
return EE_OK;
|
||||
}
|
||||
|
||||
/* No space -> page transfer */
|
||||
st = EE_PageTransfer(VirtAddress, Data);
|
||||
return (uint16_t)st;
|
||||
}
|
||||
|
||||
void loadEE(void){
|
||||
char s [100];
|
||||
EEW_Read(M1PWMAP, &m1pwmap);
|
||||
EEW_Read(M1PWMCH, &m1pwmch);
|
||||
EEW_Read(M2PWMAP, &m2pwmap);
|
||||
EEW_Read(M2PWMCH, &m2pwmch);
|
||||
EEW_Read(M3PWMAP, &m3pwmap);
|
||||
EEW_Read(M3PWMCH, &m3pwmch);
|
||||
EEW_Read(M4PWMAP, &m4pwmap);
|
||||
EEW_Read(M4PWMCH, &m4pwmch);
|
||||
EEW_Read(T1AP, &t1ap);
|
||||
EEW_Read(T2AP, &t2ap);
|
||||
EEW_Read(T3AP, &t3ap);
|
||||
EEW_Read(T4AP, &t4ap);
|
||||
EEW_Read(TWAP, &twap);
|
||||
EEW_Read(T1CH, &t1ch);
|
||||
EEW_Read(T2CH, &t2ch);
|
||||
EEW_Read(T3CH, &t3ch);
|
||||
EEW_Read(T4CH, &t4ch);
|
||||
EEW_Read(TWCH, &twch);
|
||||
EEW_Read(TRAMP1, &tramp1);
|
||||
EEW_Read(M1PWMMAN, &m1pwmMan);
|
||||
EEW_Read(M2PWMMAN, &m2pwmMan);
|
||||
EEW_Read(M3PWMMAN, &m3pwmMan);
|
||||
EEW_Read(M4PWMMAN, &m4pwmMan);
|
||||
EEW_Read(TRAMPMAN, &trampman);
|
||||
EEW_Read(TRAMP, &tramp);
|
||||
|
||||
EEW_Read(APM1START,&apM1start);
|
||||
EEW_Read(APM1STOP ,&apM1stop);
|
||||
EEW_Read(APM2START,&apM2start);
|
||||
EEW_Read(APM2STOP ,&apM2stop);
|
||||
EEW_Read(APM3START,&apM3start);
|
||||
EEW_Read(APM3STOP ,&apM3stop);
|
||||
EEW_Read(APM4START,&apM4start);
|
||||
EEW_Read(APM4STOP ,&apM4stop);
|
||||
EEW_Read(CHM1START,&chM1start);
|
||||
EEW_Read(CHM1STOP ,&chM1stop);
|
||||
EEW_Read(CHM2START,&chM2start);
|
||||
EEW_Read(CHM2STOP ,&chM2stop);
|
||||
EEW_Read(CHM3START,&chM3start);
|
||||
EEW_Read(CHM3STOP ,&chM3stop);
|
||||
EEW_Read(CHM4START,&chM4start);
|
||||
EEW_Read(CHM4STOP ,&chM4stop);
|
||||
|
||||
sprintf((char*)s,"LoadEE\n");
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
}
|
||||
@@ -0,0 +1,330 @@
|
||||
/*
|
||||
* mot.c
|
||||
*
|
||||
* Created on: May 2, 2026
|
||||
* Author: user
|
||||
*/
|
||||
#include "mot.h"
|
||||
#include "pwm.h"
|
||||
|
||||
extern uint16_t apM1start;
|
||||
extern uint16_t apM1stop;
|
||||
extern uint16_t apM2start;
|
||||
extern uint16_t apM2stop;
|
||||
extern uint16_t apM3start;
|
||||
extern uint16_t apM3stop;
|
||||
extern uint16_t apM4start;
|
||||
extern uint16_t apM4stop;
|
||||
extern uint16_t chM1start;
|
||||
extern uint16_t chM1stop;
|
||||
extern uint16_t chM2start;
|
||||
extern uint16_t chM2stop;
|
||||
extern uint16_t chM3start;
|
||||
extern uint16_t chM3stop;
|
||||
extern uint16_t chM4start;
|
||||
extern uint16_t chM4stop;
|
||||
extern volatile uint16_t rtCiclo;
|
||||
extern uint16_t m1pwmap;
|
||||
extern uint16_t m1pwmch;
|
||||
extern uint16_t m2pwmap;
|
||||
extern uint16_t m2pwmch;
|
||||
extern uint16_t m3pwmap;
|
||||
extern uint16_t m3pwmch;
|
||||
extern uint16_t m4pwmap;
|
||||
extern uint16_t m4pwmch;
|
||||
|
||||
motMov_st m1ap(void){
|
||||
static motMov_st m1st;
|
||||
if(rtCiclo<apM1start)m1st=motWaiting;
|
||||
switch(m1st){
|
||||
case motWaiting:
|
||||
SetMotPerc(M1,FW,0);
|
||||
SetMotPerc(M1,BW,0);
|
||||
if(rtCiclo>=apM1start){
|
||||
(void)ramp(M1,BW,mrampstart[M1-1],m1pwmap,tramp,RAMPINIT);
|
||||
m1st=motStartRamp;
|
||||
}
|
||||
break;
|
||||
case motStartRamp:
|
||||
if(ramp(M1,BW,mrampstart[M1-1],m1pwmap,tramp,RAMPRUN)==DONE){
|
||||
m1st=motWaitingTime;
|
||||
}
|
||||
break;
|
||||
case motWaitingTime:
|
||||
if(rtCiclo>=apM1stop){
|
||||
(void)ramp(M1,BW,m1pwmap,0,tramp,RAMPINIT);
|
||||
m1st=motStopRamp;
|
||||
}
|
||||
break;
|
||||
case motStopRamp:
|
||||
if(ramp(M1,BW,m1pwmap,0,tramp,RAMPRUN)==DONE){
|
||||
m1st=motStop;
|
||||
}
|
||||
break;
|
||||
case motStop:
|
||||
default:
|
||||
SetMotPerc(M1,FW,0);
|
||||
SetMotPerc(M1,BW,0);
|
||||
break;
|
||||
}
|
||||
return m1st;
|
||||
}
|
||||
|
||||
motMov_st m2ap(void){
|
||||
static motMov_st m2st;
|
||||
if(rtCiclo<apM2start)m2st=motWaiting;
|
||||
switch(m2st){
|
||||
case motWaiting:
|
||||
SetMotPerc(M2,FW,0);
|
||||
SetMotPerc(M2,BW,0);
|
||||
if(rtCiclo>=apM2start){
|
||||
(void)ramp(M2,BW,mrampstart[M2-1],m2pwmap,tramp,RAMPINIT);
|
||||
m2st=motStartRamp;
|
||||
}
|
||||
break;
|
||||
case motStartRamp:
|
||||
if(ramp(M2,BW,mrampstart[M2-1],m2pwmap,tramp,RAMPRUN)==DONE){
|
||||
m2st=motWaitingTime;
|
||||
}
|
||||
break;
|
||||
case motWaitingTime:
|
||||
if(rtCiclo>=apM2stop){
|
||||
(void)ramp(M2,BW,m2pwmap,0,tramp,RAMPINIT);
|
||||
m2st=motStopRamp;
|
||||
}
|
||||
break;
|
||||
case motStopRamp:
|
||||
if(ramp(M2,BW,m2pwmap,0,tramp,RAMPRUN)==DONE){
|
||||
m2st=motStop;
|
||||
}
|
||||
break;
|
||||
case motStop:
|
||||
default:
|
||||
SetMotPerc(M2,FW,0);
|
||||
SetMotPerc(M2,BW,0);
|
||||
break;
|
||||
}
|
||||
return m2st;
|
||||
}
|
||||
|
||||
motMov_st m3ap(void){
|
||||
static motMov_st m3st;
|
||||
if(rtCiclo<apM3start)m3st=motWaiting;
|
||||
switch(m3st){
|
||||
case motWaiting:
|
||||
SetMotPerc(M3,FW,0);
|
||||
SetMotPerc(M3,BW,0);
|
||||
if(rtCiclo>=apM3start){
|
||||
(void)ramp(M3,BW,mrampstart[M3-1],m2pwmap,tramp,RAMPINIT);
|
||||
m3st=motStartRamp;
|
||||
}
|
||||
break;
|
||||
case motStartRamp:
|
||||
if(ramp(M3,BW,mrampstart[M3-1],m3pwmap,tramp,RAMPRUN)==DONE){
|
||||
m3st=motWaitingTime;
|
||||
}
|
||||
break;
|
||||
case motWaitingTime:
|
||||
if(rtCiclo>=apM3stop){
|
||||
(void)ramp(M3,BW,m3pwmap,0,tramp,RAMPINIT);
|
||||
m3st=motStopRamp;
|
||||
}
|
||||
break;
|
||||
case motStopRamp:
|
||||
if(ramp(M3,BW,m3pwmap,0,tramp,RAMPRUN)==DONE){
|
||||
m3st=motStop;
|
||||
}
|
||||
break;
|
||||
case motStop:
|
||||
default:
|
||||
SetMotPerc(M3,FW,0);
|
||||
SetMotPerc(M3,BW,0);
|
||||
break;
|
||||
}
|
||||
return m3st;
|
||||
}
|
||||
|
||||
motMov_st m4ap(void){
|
||||
static motMov_st m4st;
|
||||
if(rtCiclo<apM4start)m4st=motWaiting;
|
||||
switch(m4st){
|
||||
case motWaiting:
|
||||
SetMotPerc(M4,FW,0);
|
||||
SetMotPerc(M4,BW,0);
|
||||
if(rtCiclo>=apM4start){
|
||||
(void)ramp(M4,BW,mrampstart[M4-1],m2pwmap,tramp,RAMPINIT);
|
||||
m4st=motStartRamp;
|
||||
}
|
||||
break;
|
||||
case motStartRamp:
|
||||
if(ramp(M4,BW,mrampstart[M4-1],m4pwmap,tramp,RAMPRUN)==DONE){
|
||||
m4st=motWaitingTime;
|
||||
}
|
||||
break;
|
||||
case motWaitingTime:
|
||||
if(rtCiclo>=apM4stop){
|
||||
(void)ramp(M4,BW,m4pwmap,0,tramp,RAMPINIT);
|
||||
m4st=motStopRamp;
|
||||
}
|
||||
break;
|
||||
case motStopRamp:
|
||||
if(ramp(43,BW,m4pwmap,0,tramp,RAMPRUN)==DONE){
|
||||
m4st=motStop;
|
||||
}
|
||||
break;
|
||||
case motStop:
|
||||
default:
|
||||
SetMotPerc(M4,FW,0);
|
||||
SetMotPerc(M4,BW,0);
|
||||
break;
|
||||
}
|
||||
return m4st;
|
||||
}
|
||||
|
||||
motMov_st m1ch(void){
|
||||
static motMov_st m1st;
|
||||
if(rtCiclo<chM1start)m1st=motWaiting;
|
||||
switch(m1st){
|
||||
case motWaiting:
|
||||
SetMotPerc(M1,FW,0);
|
||||
SetMotPerc(M1,BW,0);
|
||||
if(rtCiclo>=chM1start){
|
||||
(void)ramp(M1,FW,mrampstart[M1-1],m1pwmch,tramp,RAMPINIT);
|
||||
m1st=motStartRamp;
|
||||
}
|
||||
break;
|
||||
case motStartRamp:
|
||||
if(ramp(M1,FW,mrampstart[M1-1],m1pwmch,tramp,RAMPRUN)==DONE){
|
||||
m1st=motWaitingTime;
|
||||
}
|
||||
break;
|
||||
case motWaitingTime:
|
||||
if(rtCiclo>=chM1stop){
|
||||
(void)ramp(M1,FW,m1pwmch,0,tramp,RAMPINIT);
|
||||
m1st=motStopRamp;
|
||||
}
|
||||
break;
|
||||
case motStopRamp:
|
||||
if(ramp(M1,FW,m1pwmch,0,tramp,RAMPRUN)==DONE){
|
||||
m1st=motStop;
|
||||
}
|
||||
break;
|
||||
case motStop:
|
||||
default:
|
||||
SetMotPerc(M1,FW,0);
|
||||
SetMotPerc(M1,BW,0);
|
||||
break;
|
||||
}
|
||||
return m1st;
|
||||
}
|
||||
|
||||
motMov_st m2ch(void){
|
||||
static motMov_st m2st;
|
||||
if(rtCiclo<chM2start)m2st=motWaiting;
|
||||
switch(m2st){
|
||||
case motWaiting:
|
||||
SetMotPerc(M2,FW,0);
|
||||
SetMotPerc(M2,BW,0);
|
||||
if(rtCiclo>=chM2start){
|
||||
(void)ramp(M2,FW,mrampstart[M2-1],m2pwmch,tramp,RAMPINIT);
|
||||
m2st=motStartRamp;
|
||||
}
|
||||
break;
|
||||
case motStartRamp:
|
||||
if(ramp(M2,FW,mrampstart[M2-1],m2pwmch,tramp,RAMPRUN)==DONE){
|
||||
m2st=motWaitingTime;
|
||||
}
|
||||
break;
|
||||
case motWaitingTime:
|
||||
if(rtCiclo>=chM2stop){
|
||||
(void)ramp(M2,FW,m2pwmch,0,tramp,RAMPINIT);
|
||||
m2st=motStopRamp;
|
||||
}
|
||||
break;
|
||||
case motStopRamp:
|
||||
if(ramp(M2,FW,m2pwmch,0,tramp,RAMPRUN)==DONE){
|
||||
m2st=motStop;
|
||||
}
|
||||
break;
|
||||
case motStop:
|
||||
default:
|
||||
SetMotPerc(M2,FW,0);
|
||||
SetMotPerc(M2,BW,0);
|
||||
break;
|
||||
}
|
||||
return m2st;
|
||||
}
|
||||
|
||||
motMov_st m3ch(void){
|
||||
static motMov_st m3st;
|
||||
if(rtCiclo<chM3start)m3st=motWaiting;
|
||||
switch(m3st){
|
||||
case motWaiting:
|
||||
SetMotPerc(M3,FW,0);
|
||||
SetMotPerc(M3,BW,0);
|
||||
if(rtCiclo>=chM3start){
|
||||
(void)ramp(M3,FW,mrampstart[M3-1],m2pwmch,tramp,RAMPINIT);
|
||||
m3st=motStartRamp;
|
||||
}
|
||||
break;
|
||||
case motStartRamp:
|
||||
if(ramp(M3,FW,mrampstart[M3-1],m3pwmch,tramp,RAMPRUN)==DONE){
|
||||
m3st=motWaitingTime;
|
||||
}
|
||||
break;
|
||||
case motWaitingTime:
|
||||
if(rtCiclo>=chM3stop){
|
||||
(void)ramp(M3,FW,m3pwmch,0,tramp,RAMPINIT);
|
||||
m3st=motStopRamp;
|
||||
}
|
||||
break;
|
||||
case motStopRamp:
|
||||
if(ramp(M3,FW,m3pwmch,0,tramp,RAMPRUN)==DONE){
|
||||
m3st=motStop;
|
||||
}
|
||||
break;
|
||||
case motStop:
|
||||
default:
|
||||
SetMotPerc(M3,FW,0);
|
||||
SetMotPerc(M3,BW,0);
|
||||
break;
|
||||
}
|
||||
return m3st;
|
||||
}
|
||||
|
||||
motMov_st m4ch(void){
|
||||
static motMov_st m4st;
|
||||
if(rtCiclo<chM4start)m4st=motWaiting;
|
||||
switch(m4st){
|
||||
case motWaiting:
|
||||
SetMotPerc(M4,FW,0);
|
||||
SetMotPerc(M4,BW,0);
|
||||
if(rtCiclo>=chM4start){
|
||||
(void)ramp(M4,FW,mrampstart[M4-1],m2pwmch,tramp,RAMPINIT);
|
||||
m4st=motStartRamp;
|
||||
}
|
||||
break;
|
||||
case motStartRamp:
|
||||
if(ramp(M4,FW,mrampstart[M4-1],m4pwmch,tramp,RAMPRUN)==DONE){
|
||||
m4st=motWaitingTime;
|
||||
}
|
||||
break;
|
||||
case motWaitingTime:
|
||||
if(rtCiclo>=chM4stop){
|
||||
(void)ramp(M4,FW,m4pwmch,0,tramp,RAMPINIT);
|
||||
m4st=motStopRamp;
|
||||
}
|
||||
break;
|
||||
case motStopRamp:
|
||||
if(ramp(43,FW,m4pwmch,0,tramp,RAMPRUN)==DONE){
|
||||
m4st=motStop;
|
||||
}
|
||||
break;
|
||||
case motStop:
|
||||
default:
|
||||
SetMotPerc(M4,FW,0);
|
||||
SetMotPerc(M4,BW,0);
|
||||
break;
|
||||
}
|
||||
return m4st;
|
||||
}
|
||||
@@ -0,0 +1,475 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "eeprom.h"
|
||||
extern UART_HandleTypeDef huart1;
|
||||
/*
|
||||
* Record format (4 bytes):
|
||||
* [0] VirtAddress (uint16_t)
|
||||
* [2] Data (uint16_t)
|
||||
*
|
||||
* Page layout:
|
||||
* [0] PageStatus (uint16_t)
|
||||
* [2..] Records...
|
||||
*/
|
||||
|
||||
extern uint16_t m1pwmap;
|
||||
extern uint16_t m1pwmch;
|
||||
extern uint16_t m2pwmap;
|
||||
extern uint16_t m2pwmch;
|
||||
extern uint16_t m3pwmap;
|
||||
extern uint16_t m3pwmch;
|
||||
extern uint16_t m4pwmap;
|
||||
extern uint16_t m4pwmch;
|
||||
extern uint16_t t1ap;
|
||||
extern uint16_t t2ap;
|
||||
extern uint16_t t3ap;
|
||||
extern uint16_t t4ap;
|
||||
extern uint16_t twap;
|
||||
extern uint16_t tramp;
|
||||
extern uint16_t t1ch;
|
||||
extern uint16_t t2ch;
|
||||
extern uint16_t t3ch;
|
||||
extern uint16_t t4ch;
|
||||
extern uint16_t twch;
|
||||
extern uint16_t tramp1;
|
||||
extern uint16_t trampman;
|
||||
extern uint16_t m1pwmMan;
|
||||
extern uint16_t m2pwmMan;
|
||||
extern uint16_t m3pwmMan;
|
||||
extern uint16_t m4pwmMan;
|
||||
|
||||
|
||||
extern uint16_t apM1start;
|
||||
extern uint16_t apM1stop;
|
||||
extern uint16_t apM2start;
|
||||
extern uint16_t apM2stop;
|
||||
extern uint16_t apM3start;
|
||||
extern uint16_t apM3stop;
|
||||
extern uint16_t apM4start;
|
||||
extern uint16_t apM4stop;
|
||||
extern uint16_t chM1start;
|
||||
extern uint16_t chM1stop;
|
||||
extern uint16_t chM2start;
|
||||
extern uint16_t chM2stop;
|
||||
extern uint16_t chM3start;
|
||||
extern uint16_t chM3stop;
|
||||
extern uint16_t chM4start;
|
||||
extern uint16_t chM4stop;
|
||||
|
||||
const uint8_t deftab[EE_NUM_VIRTUAL_ADDR]={
|
||||
40, //m1pwmap
|
||||
60, //m1pwmch
|
||||
70, //m2pwmap
|
||||
70, //m2pwmch
|
||||
35, //m3pwmap
|
||||
40, //m3pwmch
|
||||
40, //m4pwmap
|
||||
40, //m4pwmch
|
||||
20, //m1rampstart
|
||||
20, //m2rampstart
|
||||
20, //m3rampstart
|
||||
20, //m4rampstart
|
||||
28, //t1ap
|
||||
4, //t2ap
|
||||
10, //t3ap
|
||||
40, //t4ap
|
||||
1, //twap
|
||||
27, //t1ch
|
||||
10, //t2ch
|
||||
30, //t3ch
|
||||
1, //t4ch
|
||||
1, //twch
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
100, //tramp1
|
||||
60, //m1pwmMan
|
||||
70, //m2pwmMan
|
||||
40, //m3pwmMan
|
||||
40, //m4pwmMan
|
||||
50, //trampman
|
||||
10, //tramp
|
||||
0, //apM1start;
|
||||
0, //apM1stop;
|
||||
0, //apM2start;
|
||||
0, //apM2stop;
|
||||
0, //apM3start;
|
||||
0, //apM3stop;
|
||||
0, //apM4start;
|
||||
0, //apM4stop;
|
||||
0, //chM1start;
|
||||
0, //chM1stop;
|
||||
0, //chM2start;
|
||||
0, //chM2stop;
|
||||
0, //chM3start;
|
||||
0, //chM3stop;
|
||||
0, //chM4start;
|
||||
0, //chM4stop;
|
||||
1,
|
||||
27,
|
||||
10,
|
||||
30,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
100,
|
||||
60,
|
||||
70,
|
||||
40,
|
||||
40,
|
||||
50,
|
||||
10,
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t VirtAddress;
|
||||
uint16_t Data;
|
||||
} EE_Record_t;
|
||||
|
||||
/* Active page base address (runtime selected in EE_Init) */
|
||||
static uint32_t EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
|
||||
/* 32 sequential virtual addresses */
|
||||
const uint16_t EE_VirtAddrs[EE_NUM_VIRTUAL_ADDR] =
|
||||
{
|
||||
0x0001, 0x0002, 0x0003, 0x0004,
|
||||
0x0005, 0x0006, 0x0007, 0x0008,
|
||||
0x0009, 0x000A, 0x000B, 0x000C,
|
||||
0x000D, 0x000E, 0x000F, 0x0010,
|
||||
0x0011, 0x0012, 0x0013, 0x0014,
|
||||
0x0015, 0x0016, 0x0017, 0x0018,
|
||||
0x0019, 0x001A, 0x001B, 0x001C,
|
||||
0x001D, 0x001E, 0x001F, 0x0020,
|
||||
|
||||
0x0021, 0x0022, 0x0023, 0x0024,
|
||||
0x0025, 0x0026, 0x0027, 0x0028,
|
||||
0x0029, 0x002A, 0x002B, 0x002C,
|
||||
0x002D, 0x002E, 0x002F, 0x0030,
|
||||
0x0031, 0x0032, 0x0033, 0x0034,
|
||||
0x0035, 0x0036, 0x0037, 0x0038,
|
||||
0x0039, 0x003A, 0x003B, 0x003C,
|
||||
0x003D, 0x003E, 0x003F, 0x0040
|
||||
};
|
||||
/* ========================================================================= */
|
||||
|
||||
/* --- Internal helpers ---------------------------------------------------- */
|
||||
|
||||
static uint16_t EE_GetPageStatus(uint32_t pageBase)
|
||||
{
|
||||
return *(__IO uint16_t *)pageBase;
|
||||
}
|
||||
|
||||
static HAL_StatusTypeDef EE_FlashProgramHalfWord(uint32_t Address, uint16_t Data)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
|
||||
HAL_FLASH_Unlock();
|
||||
status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, Address, Data);
|
||||
HAL_FLASH_Lock();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static HAL_StatusTypeDef EE_FlashErasePage(uint32_t PageAddress)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
FLASH_EraseInitTypeDef EraseInit;
|
||||
uint32_t PageError = 0;
|
||||
|
||||
HAL_FLASH_Unlock();
|
||||
|
||||
EraseInit.TypeErase = FLASH_TYPEERASE_PAGES;
|
||||
EraseInit.PageAddress = PageAddress;
|
||||
EraseInit.NbPages = 1;
|
||||
|
||||
status = HAL_FLASHEx_Erase(&EraseInit, &PageError);
|
||||
|
||||
HAL_FLASH_Lock();
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Find first free record address in given page (returns 0 if full) */
|
||||
static uint32_t EE_FindFreeAddress(uint32_t pageBase)
|
||||
{
|
||||
uint32_t addr = pageBase + 2U; /* Skip status word */
|
||||
uint32_t pageEnd = pageBase + EE_PAGE_SIZE;
|
||||
|
||||
while (addr < (pageEnd - sizeof(EE_Record_t) + 1U))
|
||||
{
|
||||
uint16_t vaddr = *(__IO uint16_t *)addr;
|
||||
|
||||
if (vaddr == 0xFFFFU)
|
||||
{
|
||||
/* Empty slot */
|
||||
return addr;
|
||||
}
|
||||
addr += sizeof(EE_Record_t);
|
||||
}
|
||||
|
||||
return 0U; /* No space */
|
||||
}
|
||||
|
||||
/* Find latest value of VirtAddress in a specific page (internal, uses EE_Status) */
|
||||
/* Find latest value of VirtAddress in a specific page (scan forward) */
|
||||
static EE_Status EE_FindInPage(uint32_t pageBase, uint16_t VirtAddress, uint16_t *Data)
|
||||
{
|
||||
uint32_t addr = pageBase + 2U; // skip status halfword
|
||||
uint32_t pageEnd = pageBase + EE_PAGE_SIZE;
|
||||
EE_Status result = EE_NOT_FOUND;
|
||||
uint16_t lastVal = 0;
|
||||
|
||||
if (Data == NULL)
|
||||
return EE_ERROR;
|
||||
|
||||
while (addr <= (pageEnd - sizeof(EE_Record_t)))
|
||||
{
|
||||
uint16_t vaddr = *(__IO uint16_t *)addr;
|
||||
|
||||
if (vaddr == 0xFFFFU)
|
||||
{
|
||||
// First empty slot => no more records in this page
|
||||
break;
|
||||
}
|
||||
|
||||
uint16_t value = *(__IO uint16_t *)(addr + 2U);
|
||||
|
||||
if (vaddr == VirtAddress)
|
||||
{
|
||||
lastVal = value; // keep most recent
|
||||
result = EE_OK;
|
||||
}
|
||||
|
||||
addr += sizeof(EE_Record_t); // move 4 bytes forward
|
||||
}
|
||||
|
||||
if (result == EE_OK)
|
||||
*Data = lastVal;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Format both pages: erase and set PAGE0 as VALID */
|
||||
static EE_Status EE_Format(void)
|
||||
{
|
||||
if (EE_FlashErasePage(EE_PAGE0_BASE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
if (EE_FlashErasePage(EE_PAGE1_BASE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
if (EE_FlashProgramHalfWord(EE_PAGE0_BASE, EE_PAGE_STATUS_VALID) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* PAGE1 will remain erased (status = 0xFFFF) */
|
||||
EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
|
||||
return EE_STATUS_OK;
|
||||
}
|
||||
|
||||
/* Get the base of the other page */
|
||||
static uint32_t EE_GetOtherPageBase(uint32_t pageBase)
|
||||
{
|
||||
return (pageBase == EE_PAGE0_BASE) ? EE_PAGE1_BASE : EE_PAGE0_BASE;
|
||||
}
|
||||
|
||||
/* Page transfer (garbage collection + new write) */
|
||||
static EE_Status EE_PageTransfer(uint16_t VirtAddress, uint16_t Data)
|
||||
{
|
||||
uint32_t oldBase = EE_ActivePageBase;
|
||||
uint32_t newBase = EE_GetOtherPageBase(oldBase);
|
||||
uint32_t addr;
|
||||
uint16_t value;
|
||||
EE_Status st;
|
||||
|
||||
/* Erase new page */
|
||||
if (EE_FlashErasePage(newBase) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Mark new page as RECEIVE */
|
||||
if (EE_FlashProgramHalfWord(newBase, EE_PAGE_STATUS_RECEIVE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Start writing records just after status */
|
||||
addr = newBase + 2U;
|
||||
|
||||
/* For each known virtual variable */
|
||||
for (uint16_t i = 0; i < EE_NUM_VIRTUAL_ADDR; i++)
|
||||
{
|
||||
uint16_t vaddr = EE_VirtAddrs[i];
|
||||
|
||||
if (vaddr == VirtAddress)
|
||||
{
|
||||
/* Use the new data passed into PageTransfer */
|
||||
value = Data;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Read latest value from old active page */
|
||||
st = EE_FindInPage(oldBase, vaddr, &value);
|
||||
if (st != EE_STATUS_OK)
|
||||
{
|
||||
/* Variable never written -> skip */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Write record to new page */
|
||||
if (EE_FlashProgramHalfWord(addr, vaddr) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
if (EE_FlashProgramHalfWord(addr + 2U, value) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
addr += sizeof(EE_Record_t);
|
||||
if (addr >= (newBase + EE_PAGE_SIZE))
|
||||
return EE_STATUS_NO_SPACE;
|
||||
}
|
||||
|
||||
/* Erase old page */
|
||||
if (EE_FlashErasePage(oldBase) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Mark new page as VALID */
|
||||
if (EE_FlashProgramHalfWord(newBase, EE_PAGE_STATUS_VALID) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Update active page */
|
||||
EE_ActivePageBase = newBase;
|
||||
|
||||
return EE_STATUS_OK;
|
||||
}
|
||||
|
||||
/* --- Public API ----------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* Initialize the EEPROM emulation.
|
||||
* - Checks page statuses and chooses the active page.
|
||||
* - If inconsistent or blank, formats pages.
|
||||
* PUBLIC RETURN TYPE: uint16_t (EE_OK / EE_ERROR / ...)
|
||||
*/
|
||||
uint16_t EE_Init(void)
|
||||
{
|
||||
uint16_t status0 = EE_GetPageStatus(EE_PAGE0_BASE);
|
||||
uint16_t status1 = EE_GetPageStatus(EE_PAGE1_BASE);
|
||||
|
||||
if ((status0 == EE_PAGE_STATUS_ERASED) && (status1 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
/* Fresh device -> format */
|
||||
return (uint16_t)EE_Format();
|
||||
}
|
||||
else if ((status0 == EE_PAGE_STATUS_VALID) && (status1 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
return EE_OK;
|
||||
}
|
||||
else if ((status1 == EE_PAGE_STATUS_VALID) && (status0 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
EE_ActivePageBase = EE_PAGE1_BASE;
|
||||
return EE_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Any weird or inconsistent state -> reformat */
|
||||
return (uint16_t)EE_Format();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a 16-bit variable by its virtual address.
|
||||
* PUBLIC RETURN: EE_OK / EE_NOT_FOUND / EE_ERROR (as uint16_t)
|
||||
*/
|
||||
uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t *Data)
|
||||
{
|
||||
EE_Status st;
|
||||
|
||||
if (Data == NULL)
|
||||
return EE_ERROR;
|
||||
|
||||
st = EE_FindInPage(EE_ActivePageBase, VirtAddress, Data);
|
||||
return (uint16_t)st;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write (append) a 16-bit variable.
|
||||
* - Writes a new record in the active page.
|
||||
* - If the page is full, triggers a page transfer (GC).
|
||||
* PUBLIC RETURN: EE_OK / EE_ERROR / EE_NO_SPACE (as uint16_t)
|
||||
*/
|
||||
uint16_t EE_WriteVariable(uint16_t VirtAddress, uint16_t Data)
|
||||
{
|
||||
uint32_t freeAddr;
|
||||
EE_Status st;
|
||||
|
||||
/* Find free space in active page */
|
||||
freeAddr = EE_FindFreeAddress(EE_ActivePageBase);
|
||||
if (freeAddr != 0U)
|
||||
{
|
||||
/* Write new record */
|
||||
if (EE_FlashProgramHalfWord(freeAddr, VirtAddress) != HAL_OK)
|
||||
return EE_ERROR;
|
||||
if (EE_FlashProgramHalfWord(freeAddr + 2U, Data) != HAL_OK)
|
||||
return EE_ERROR;
|
||||
|
||||
return EE_OK;
|
||||
}
|
||||
|
||||
/* No space -> page transfer */
|
||||
st = EE_PageTransfer(VirtAddress, Data);
|
||||
return (uint16_t)st;
|
||||
}
|
||||
|
||||
void loadEE(void){
|
||||
char s [200];
|
||||
EEW_Read(M1PWMAP, &m1pwmap);
|
||||
EEW_Read(M1PWMCH, &m1pwmch);
|
||||
EEW_Read(M2PWMAP, &m2pwmap);
|
||||
EEW_Read(M2PWMCH, &m2pwmch);
|
||||
EEW_Read(M3PWMAP, &m3pwmap);
|
||||
EEW_Read(M3PWMCH, &m3pwmch);
|
||||
EEW_Read(M4PWMAP, &m4pwmap);
|
||||
EEW_Read(M4PWMCH, &m4pwmch);
|
||||
EEW_Read(T1AP, &t1ap);
|
||||
EEW_Read(T2AP, &t2ap);
|
||||
EEW_Read(T3AP, &t3ap);
|
||||
EEW_Read(T4AP, &t4ap);
|
||||
EEW_Read(TWAP, &twap);
|
||||
EEW_Read(T1CH, &t1ch);
|
||||
EEW_Read(T2CH, &t2ch);
|
||||
EEW_Read(T3CH, &t3ch);
|
||||
EEW_Read(T4CH, &t4ch);
|
||||
EEW_Read(TWCH, &twch);
|
||||
EEW_Read(TRAMP1, &tramp1);
|
||||
EEW_Read(M1PWMMAN, &m1pwmMan);
|
||||
EEW_Read(M2PWMMAN, &m2pwmMan);
|
||||
EEW_Read(M3PWMMAN, &m3pwmMan);
|
||||
EEW_Read(M4PWMMAN, &m4pwmMan);
|
||||
EEW_Read(TRAMPMAN, &trampman);
|
||||
EEW_Read(TRAMP, &tramp);
|
||||
|
||||
EEW_Read(APM1START,&apM1start);
|
||||
EEW_Read(APM1STOP ,&apM1stop);
|
||||
EEW_Read(APM2START,&apM2start);
|
||||
EEW_Read(APM2STOP ,&apM2stop);
|
||||
EEW_Read(APM3START,&apM3start);
|
||||
EEW_Read(APM3STOP ,&apM3stop);
|
||||
EEW_Read(APM4START,&apM4start);
|
||||
EEW_Read(APM4STOP ,&apM4stop);
|
||||
EEW_Read(CHM1START,&chM1start);
|
||||
EEW_Read(CHM1STOP ,&chM1stop);
|
||||
EEW_Read(CHM2START,&chM2start);
|
||||
EEW_Read(CHM2STOP ,&chM2stop);
|
||||
EEW_Read(CHM3START,&chM3start);
|
||||
EEW_Read(CHM3STOP ,&chM3stop);
|
||||
EEW_Read(CHM4START,&chM4start);
|
||||
EEW_Read(CHM4STOP ,&chM4stop);
|
||||
|
||||
sprintf((char*)s,"LoadEE\n");
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
sprintf((char*)s,"\nm1pwmap=%d m1pwmch=%d m2pwmap=%d m2pwmch=%d m3pwmap=%d m3pwmch=%d m4pwmap=%d m4pwmch=%d",m1pwmap,m1pwmch,m2pwmap,m2pwmch,m3pwmap,m3pwmch,m4pwma, m4pwmch);
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
* mot.c
|
||||
*
|
||||
* Created on: May 2, 2026
|
||||
* Author: user
|
||||
*/
|
||||
|
||||
|
||||
@@ -0,0 +1,481 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "eeprom.h"
|
||||
extern UART_HandleTypeDef huart1;
|
||||
/*
|
||||
* Record format (4 bytes):
|
||||
* [0] VirtAddress (uint16_t)
|
||||
* [2] Data (uint16_t)
|
||||
*
|
||||
* Page layout:
|
||||
* [0] PageStatus (uint16_t)
|
||||
* [2..] Records...
|
||||
*/
|
||||
|
||||
extern uint16_t m1pwmap;
|
||||
extern uint16_t m1pwmch;
|
||||
extern uint16_t m2pwmap;
|
||||
extern uint16_t m2pwmch;
|
||||
extern uint16_t m3pwmap;
|
||||
extern uint16_t m3pwmch;
|
||||
extern uint16_t m4pwmap;
|
||||
extern uint16_t m4pwmch;
|
||||
extern uint16_t t1ap;
|
||||
extern uint16_t t2ap;
|
||||
extern uint16_t t3ap;
|
||||
extern uint16_t t4ap;
|
||||
extern uint16_t twap;
|
||||
extern uint16_t tramp;
|
||||
extern uint16_t t1ch;
|
||||
extern uint16_t t2ch;
|
||||
extern uint16_t t3ch;
|
||||
extern uint16_t t4ch;
|
||||
extern uint16_t twch;
|
||||
extern uint16_t tramp1;
|
||||
extern uint16_t trampman;
|
||||
extern uint16_t m1pwmMan;
|
||||
extern uint16_t m2pwmMan;
|
||||
extern uint16_t m3pwmMan;
|
||||
extern uint16_t m4pwmMan;
|
||||
|
||||
|
||||
extern uint16_t apM1start;
|
||||
extern uint16_t apM1stop;
|
||||
extern uint16_t apM2start;
|
||||
extern uint16_t apM2stop;
|
||||
extern uint16_t apM3start;
|
||||
extern uint16_t apM3stop;
|
||||
extern uint16_t apM4start;
|
||||
extern uint16_t apM4stop;
|
||||
extern uint16_t chM1start;
|
||||
extern uint16_t chM1stop;
|
||||
extern uint16_t chM2start;
|
||||
extern uint16_t chM2stop;
|
||||
extern uint16_t chM3start;
|
||||
extern uint16_t chM3stop;
|
||||
extern uint16_t chM4start;
|
||||
extern uint16_t chM4stop;
|
||||
|
||||
const uint8_t deftab[EE_NUM_VIRTUAL_ADDR]={
|
||||
40, //m1pwmap
|
||||
60, //m1pwmch
|
||||
70, //m2pwmap
|
||||
70, //m2pwmch
|
||||
35, //m3pwmap
|
||||
40, //m3pwmch
|
||||
40, //m4pwmap
|
||||
40, //m4pwmch
|
||||
20, //m1rampstart
|
||||
20, //m2rampstart
|
||||
20, //m3rampstart
|
||||
20, //m4rampstart
|
||||
28, //t1ap
|
||||
4, //t2ap
|
||||
10, //t3ap
|
||||
40, //t4ap
|
||||
1, //twap
|
||||
27, //t1ch
|
||||
10, //t2ch
|
||||
30, //t3ch
|
||||
1, //t4ch
|
||||
1, //twch
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
100, //tramp1
|
||||
60, //m1pwmMan
|
||||
70, //m2pwmMan
|
||||
40, //m3pwmMan
|
||||
40, //m4pwmMan
|
||||
50, //trampman
|
||||
10, //tramp
|
||||
310, //apM1start;
|
||||
450, //apM1stop;
|
||||
30, //apM2start;
|
||||
310, //apM2stop;
|
||||
350, //apM3start;
|
||||
450, //apM3stop;
|
||||
450, //apM4start;
|
||||
850, //apM4stop;
|
||||
10, //chM1start;
|
||||
280, //chM1stop;
|
||||
0, //chM2start;
|
||||
0, //chM2stop;
|
||||
20, //chM3start;
|
||||
280, //chM3stop;
|
||||
0, //chM4start;
|
||||
0, //chM4stop;
|
||||
1,
|
||||
27,
|
||||
10,
|
||||
30,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
100,
|
||||
60,
|
||||
70,
|
||||
40,
|
||||
40,
|
||||
50,
|
||||
10,
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t VirtAddress;
|
||||
uint16_t Data;
|
||||
} EE_Record_t;
|
||||
|
||||
/* Active page base address (runtime selected in EE_Init) */
|
||||
static uint32_t EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
|
||||
/* 32 sequential virtual addresses */
|
||||
const uint16_t EE_VirtAddrs[EE_NUM_VIRTUAL_ADDR] =
|
||||
{
|
||||
0x0001, 0x0002, 0x0003, 0x0004,
|
||||
0x0005, 0x0006, 0x0007, 0x0008,
|
||||
0x0009, 0x000A, 0x000B, 0x000C,
|
||||
0x000D, 0x000E, 0x000F, 0x0010,
|
||||
0x0011, 0x0012, 0x0013, 0x0014,
|
||||
0x0015, 0x0016, 0x0017, 0x0018,
|
||||
0x0019, 0x001A, 0x001B, 0x001C,
|
||||
0x001D, 0x001E, 0x001F, 0x0020,
|
||||
|
||||
0x0021, 0x0022, 0x0023, 0x0024,
|
||||
0x0025, 0x0026, 0x0027, 0x0028,
|
||||
0x0029, 0x002A, 0x002B, 0x002C,
|
||||
0x002D, 0x002E, 0x002F, 0x0030,
|
||||
0x0031, 0x0032, 0x0033, 0x0034,
|
||||
0x0035, 0x0036, 0x0037, 0x0038,
|
||||
0x0039, 0x003A, 0x003B, 0x003C,
|
||||
0x003D, 0x003E, 0x003F, 0x0040
|
||||
};
|
||||
/* ========================================================================= */
|
||||
|
||||
/* --- Internal helpers ---------------------------------------------------- */
|
||||
|
||||
static uint16_t EE_GetPageStatus(uint32_t pageBase)
|
||||
{
|
||||
return *(__IO uint16_t *)pageBase;
|
||||
}
|
||||
|
||||
static HAL_StatusTypeDef EE_FlashProgramHalfWord(uint32_t Address, uint16_t Data)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
|
||||
HAL_FLASH_Unlock();
|
||||
status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, Address, Data);
|
||||
HAL_FLASH_Lock();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static HAL_StatusTypeDef EE_FlashErasePage(uint32_t PageAddress)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
FLASH_EraseInitTypeDef EraseInit;
|
||||
uint32_t PageError = 0;
|
||||
|
||||
HAL_FLASH_Unlock();
|
||||
|
||||
EraseInit.TypeErase = FLASH_TYPEERASE_PAGES;
|
||||
EraseInit.PageAddress = PageAddress;
|
||||
EraseInit.NbPages = 1;
|
||||
|
||||
status = HAL_FLASHEx_Erase(&EraseInit, &PageError);
|
||||
|
||||
HAL_FLASH_Lock();
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Find first free record address in given page (returns 0 if full) */
|
||||
static uint32_t EE_FindFreeAddress(uint32_t pageBase)
|
||||
{
|
||||
uint32_t addr = pageBase + 2U; /* Skip status word */
|
||||
uint32_t pageEnd = pageBase + EE_PAGE_SIZE;
|
||||
|
||||
while (addr < (pageEnd - sizeof(EE_Record_t) + 1U))
|
||||
{
|
||||
uint16_t vaddr = *(__IO uint16_t *)addr;
|
||||
|
||||
if (vaddr == 0xFFFFU)
|
||||
{
|
||||
/* Empty slot */
|
||||
return addr;
|
||||
}
|
||||
addr += sizeof(EE_Record_t);
|
||||
}
|
||||
|
||||
return 0U; /* No space */
|
||||
}
|
||||
|
||||
/* Find latest value of VirtAddress in a specific page (internal, uses EE_Status) */
|
||||
/* Find latest value of VirtAddress in a specific page (scan forward) */
|
||||
static EE_Status EE_FindInPage(uint32_t pageBase, uint16_t VirtAddress, uint16_t *Data)
|
||||
{
|
||||
uint32_t addr = pageBase + 2U; // skip status halfword
|
||||
uint32_t pageEnd = pageBase + EE_PAGE_SIZE;
|
||||
EE_Status result = EE_NOT_FOUND;
|
||||
uint16_t lastVal = 0;
|
||||
|
||||
if (Data == NULL)
|
||||
return EE_ERROR;
|
||||
|
||||
while (addr <= (pageEnd - sizeof(EE_Record_t)))
|
||||
{
|
||||
uint16_t vaddr = *(__IO uint16_t *)addr;
|
||||
|
||||
if (vaddr == 0xFFFFU)
|
||||
{
|
||||
// First empty slot => no more records in this page
|
||||
break;
|
||||
}
|
||||
|
||||
uint16_t value = *(__IO uint16_t *)(addr + 2U);
|
||||
|
||||
if (vaddr == VirtAddress)
|
||||
{
|
||||
lastVal = value; // keep most recent
|
||||
result = EE_OK;
|
||||
}
|
||||
|
||||
addr += sizeof(EE_Record_t); // move 4 bytes forward
|
||||
}
|
||||
|
||||
if (result == EE_OK)
|
||||
*Data = lastVal;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Format both pages: erase and set PAGE0 as VALID */
|
||||
static EE_Status EE_Format(void)
|
||||
{
|
||||
if (EE_FlashErasePage(EE_PAGE0_BASE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
if (EE_FlashErasePage(EE_PAGE1_BASE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
if (EE_FlashProgramHalfWord(EE_PAGE0_BASE, EE_PAGE_STATUS_VALID) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* PAGE1 will remain erased (status = 0xFFFF) */
|
||||
EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
|
||||
return EE_STATUS_OK;
|
||||
}
|
||||
|
||||
/* Get the base of the other page */
|
||||
static uint32_t EE_GetOtherPageBase(uint32_t pageBase)
|
||||
{
|
||||
return (pageBase == EE_PAGE0_BASE) ? EE_PAGE1_BASE : EE_PAGE0_BASE;
|
||||
}
|
||||
|
||||
/* Page transfer (garbage collection + new write) */
|
||||
static EE_Status EE_PageTransfer(uint16_t VirtAddress, uint16_t Data)
|
||||
{
|
||||
uint32_t oldBase = EE_ActivePageBase;
|
||||
uint32_t newBase = EE_GetOtherPageBase(oldBase);
|
||||
uint32_t addr;
|
||||
uint16_t value;
|
||||
EE_Status st;
|
||||
|
||||
/* Erase new page */
|
||||
if (EE_FlashErasePage(newBase) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Mark new page as RECEIVE */
|
||||
if (EE_FlashProgramHalfWord(newBase, EE_PAGE_STATUS_RECEIVE) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Start writing records just after status */
|
||||
addr = newBase + 2U;
|
||||
|
||||
/* For each known virtual variable */
|
||||
for (uint16_t i = 0; i < EE_NUM_VIRTUAL_ADDR; i++)
|
||||
{
|
||||
uint16_t vaddr = EE_VirtAddrs[i];
|
||||
|
||||
if (vaddr == VirtAddress)
|
||||
{
|
||||
/* Use the new data passed into PageTransfer */
|
||||
value = Data;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Read latest value from old active page */
|
||||
st = EE_FindInPage(oldBase, vaddr, &value);
|
||||
if (st != EE_STATUS_OK)
|
||||
{
|
||||
/* Variable never written -> skip */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Write record to new page */
|
||||
if (EE_FlashProgramHalfWord(addr, vaddr) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
if (EE_FlashProgramHalfWord(addr + 2U, value) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
addr += sizeof(EE_Record_t);
|
||||
if (addr >= (newBase + EE_PAGE_SIZE))
|
||||
return EE_STATUS_NO_SPACE;
|
||||
}
|
||||
|
||||
/* Erase old page */
|
||||
if (EE_FlashErasePage(oldBase) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Mark new page as VALID */
|
||||
if (EE_FlashProgramHalfWord(newBase, EE_PAGE_STATUS_VALID) != HAL_OK)
|
||||
return EE_STATUS_ERROR;
|
||||
|
||||
/* Update active page */
|
||||
EE_ActivePageBase = newBase;
|
||||
|
||||
return EE_STATUS_OK;
|
||||
}
|
||||
|
||||
/* --- Public API ----------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* Initialize the EEPROM emulation.
|
||||
* - Checks page statuses and chooses the active page.
|
||||
* - If inconsistent or blank, formats pages.
|
||||
* PUBLIC RETURN TYPE: uint16_t (EE_OK / EE_ERROR / ...)
|
||||
*/
|
||||
uint16_t EE_Init(void)
|
||||
{
|
||||
uint16_t status0 = EE_GetPageStatus(EE_PAGE0_BASE);
|
||||
uint16_t status1 = EE_GetPageStatus(EE_PAGE1_BASE);
|
||||
|
||||
if ((status0 == EE_PAGE_STATUS_ERASED) && (status1 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
/* Fresh device -> format */
|
||||
return (uint16_t)EE_Format();
|
||||
}
|
||||
else if ((status0 == EE_PAGE_STATUS_VALID) && (status1 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
EE_ActivePageBase = EE_PAGE0_BASE;
|
||||
return EE_OK;
|
||||
}
|
||||
else if ((status1 == EE_PAGE_STATUS_VALID) && (status0 == EE_PAGE_STATUS_ERASED))
|
||||
{
|
||||
EE_ActivePageBase = EE_PAGE1_BASE;
|
||||
return EE_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Any weird or inconsistent state -> reformat */
|
||||
return (uint16_t)EE_Format();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a 16-bit variable by its virtual address.
|
||||
* PUBLIC RETURN: EE_OK / EE_NOT_FOUND / EE_ERROR (as uint16_t)
|
||||
*/
|
||||
uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t *Data)
|
||||
{
|
||||
EE_Status st;
|
||||
|
||||
if (Data == NULL)
|
||||
return EE_ERROR;
|
||||
|
||||
st = EE_FindInPage(EE_ActivePageBase, VirtAddress, Data);
|
||||
return (uint16_t)st;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write (append) a 16-bit variable.
|
||||
* - Writes a new record in the active page.
|
||||
* - If the page is full, triggers a page transfer (GC).
|
||||
* PUBLIC RETURN: EE_OK / EE_ERROR / EE_NO_SPACE (as uint16_t)
|
||||
*/
|
||||
uint16_t EE_WriteVariable(uint16_t VirtAddress, uint16_t Data)
|
||||
{
|
||||
uint32_t freeAddr;
|
||||
EE_Status st;
|
||||
|
||||
/* Find free space in active page */
|
||||
freeAddr = EE_FindFreeAddress(EE_ActivePageBase);
|
||||
if (freeAddr != 0U)
|
||||
{
|
||||
/* Write new record */
|
||||
if (EE_FlashProgramHalfWord(freeAddr, VirtAddress) != HAL_OK)
|
||||
return EE_ERROR;
|
||||
if (EE_FlashProgramHalfWord(freeAddr + 2U, Data) != HAL_OK)
|
||||
return EE_ERROR;
|
||||
|
||||
return EE_OK;
|
||||
}
|
||||
|
||||
/* No space -> page transfer */
|
||||
st = EE_PageTransfer(VirtAddress, Data);
|
||||
return (uint16_t)st;
|
||||
}
|
||||
|
||||
void loadEE(void){
|
||||
char s [200];
|
||||
EEW_Read(M1PWMAP, &m1pwmap);
|
||||
EEW_Read(M1PWMCH, &m1pwmch);
|
||||
EEW_Read(M2PWMAP, &m2pwmap);
|
||||
EEW_Read(M2PWMCH, &m2pwmch);
|
||||
EEW_Read(M3PWMAP, &m3pwmap);
|
||||
EEW_Read(M3PWMCH, &m3pwmch);
|
||||
EEW_Read(M4PWMAP, &m4pwmap);
|
||||
EEW_Read(M4PWMCH, &m4pwmch);
|
||||
EEW_Read(T1AP, &t1ap);
|
||||
EEW_Read(T2AP, &t2ap);
|
||||
EEW_Read(T3AP, &t3ap);
|
||||
EEW_Read(T4AP, &t4ap);
|
||||
EEW_Read(TWAP, &twap);
|
||||
EEW_Read(T1CH, &t1ch);
|
||||
EEW_Read(T2CH, &t2ch);
|
||||
EEW_Read(T3CH, &t3ch);
|
||||
EEW_Read(T4CH, &t4ch);
|
||||
EEW_Read(TWCH, &twch);
|
||||
EEW_Read(TRAMP1, &tramp1);
|
||||
EEW_Read(M1PWMMAN, &m1pwmMan);
|
||||
EEW_Read(M2PWMMAN, &m2pwmMan);
|
||||
EEW_Read(M3PWMMAN, &m3pwmMan);
|
||||
EEW_Read(M4PWMMAN, &m4pwmMan);
|
||||
EEW_Read(TRAMPMAN, &trampman);
|
||||
EEW_Read(TRAMP, &tramp);
|
||||
|
||||
EEW_Read(APM1START,&apM1start);
|
||||
EEW_Read(APM1STOP ,&apM1stop);
|
||||
EEW_Read(APM2START,&apM2start);
|
||||
EEW_Read(APM2STOP ,&apM2stop);
|
||||
EEW_Read(APM3START,&apM3start);
|
||||
EEW_Read(APM3STOP ,&apM3stop);
|
||||
EEW_Read(APM4START,&apM4start);
|
||||
EEW_Read(APM4STOP ,&apM4stop);
|
||||
EEW_Read(CHM1START,&chM1start);
|
||||
EEW_Read(CHM1STOP ,&chM1stop);
|
||||
EEW_Read(CHM2START,&chM2start);
|
||||
EEW_Read(CHM2STOP ,&chM2stop);
|
||||
EEW_Read(CHM3START,&chM3start);
|
||||
EEW_Read(CHM3STOP ,&chM3stop);
|
||||
EEW_Read(CHM4START,&chM4start);
|
||||
EEW_Read(CHM4STOP ,&chM4stop);
|
||||
|
||||
sprintf((char*)s,"LoadEE\n");
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
sprintf((char*)s,"\nm1pwmap=%d m1pwmch=%d m2pwmap=%d m2pwmch=%d m3pwmap=%d m3pwmch=%d m4pwmap=%d m4pwmch=%d",m1pwmap,m1pwmch,m2pwmap,m2pwmch,m3pwmap,m3pwmch,m4pwmap, m4pwmch);
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
|
||||
sprintf((char*)s,"\ntramp=%d trampman=%d",tramp,trampman);
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
sprintf((char*)s,"\nm1pwmMan=%d m2pwmMan=%d m3pwmMan=%d m4pwmMan=%d",m1pwmMan,m2pwmMan,m3pwmMan,m4pwmMan);
|
||||
HAL_UART_Transmit(&huart1,(uint8_t*) s, strlen(s), HAL_MAX_DELAY);
|
||||
|
||||
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
workspace/.metadata/.plugins/org.eclipse.core.resources/30.snap
Normal file
BIN
workspace/.metadata/.plugins/org.eclipse.core.resources/30.snap
Normal file
Binary file not shown.
File diff suppressed because one or more lines are too long
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<session version="1.0">
<refactoring comment="Delete resource 'AUTOM10/Core/Src/mot'" deleteContents="false" description="Delete resource 'AUTOM10/Core/Src/mot'" element1="/AUTOM10/Core/Src/mot" flags="7" id="org.eclipse.ltk.core.refactoring.delete.resources" resources="1" stamp="1777717660180"/>
<refactoring comment="Delete resource 'AUTOM10/Core/Src/mot-c'" deleteContents="false" description="Delete resource 'AUTOM10/Core/Src/mot-c'" element1="/AUTOM10/Core/Src/mot-c" flags="7" id="org.eclipse.ltk.core.refactoring.delete.resources" resources="1" stamp="1777717695069"/>
|
||||
</session>
|
||||
@@ -0,0 +1,2 @@
|
||||
1777717660180 Delete resource 'AUTOM10/Core/Src/mot'
|
||||
1777717695069 Delete resource 'AUTOM10/Core/Src/mot-c'
|
||||
Reference in New Issue
Block a user