Add other

This commit is contained in:
Степанов Станислав 2025-09-25 15:59:22 +03:00
parent 61e8faba80
commit 96ed36382e
45 changed files with 3273 additions and 0 deletions

191
APP/AT32F403AxG_FLASH.ld Normal file
View File

@ -0,0 +1,191 @@
/*
*****************************************************************************
**
** File : AT32F403AxG_FLASH.ld
**
** Abstract : Linker script for AT32F403AxG Device with
** 1000KByte FLASH, 96KByte RAM
**
** Set heap size, stack size and stack location according
** to application requirements.
**
** Set memory bank area and size if external memory is used.
**
** Target : Artery Tek AT32
**
** Environment : Arm gcc toolchain
**
*****************************************************************************
*/
/* Entry Point */
ENTRY(Reset_Handler)
/* Highest address of the user mode stack */
_estack = 0x20038000; /* end of RAM */
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x200; /* required amount of heap */
_Min_Stack_Size = 0x400; /* required amount of stack */
_FirmwareBegin = 0x08000000;
_FullFirmwareSize = 400K ;
_MetadataSize = 256 ;
_FullStorageSize = 16K ;
_FirmwareSize = _FullFirmwareSize - _MetadataSize ;
/* Specify the memory areas */
MEMORY
{
FLASH (rx) : ORIGIN = _FirmwareBegin, LENGTH = _FirmwareSize
META (rx) : ORIGIN = _FirmwareBegin + _FirmwareSize, LENGTH = _MetadataSize
STORAGE_A (rx) : ORIGIN = 0x080E8000, LENGTH = _FullStorageSize
STORAGE_B (rx) : ORIGIN = 0x080EC000, LENGTH = _FullStorageSize
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 96K+128K
/*SPIM (rx) : ORIGIN = 0x08400000, LENGTH = 16384K*/
}
/* Define output sections */
SECTIONS
{
/* The startup code goes first into FLASH */
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} >FLASH
.metaaaa : SUBALIGN(1)
{
KEEP(*(.meta_fw_crc))
LONG(_FirmwareSize) ; /* word with firmware_size */
KEEP(*(.meta_fw_name_size))
KEEP(*(.meta_fw_name))
KEEP(*(.meta_hw_name_size))
KEEP(*(.meta_hw_name))
. = ALIGN(256);
} >META
/* The program code and other data goes into FLASH */
.text :
{
. = ALIGN(4);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.glue_7) /* glue arm to thumb code */
*(.glue_7t) /* glue thumb to arm code */
*(.eh_frame)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
_etext = .; /* define a global symbols at end of code */
} >FLASH
/* Constant data goes into FLASH */
.rodata :
{
. = ALIGN(4);
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
. = ALIGN(4);
} >FLASH
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
.ARM : {
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} >FLASH
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >FLASH
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
} >FLASH
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array*))
PROVIDE_HIDDEN (__fini_array_end = .);
} >FLASH
/* used by the startup to initialize data */
_sidata = LOADADDR(.data);
/* Initialized data sections goes into RAM, load LMA copy after code */
.data :
{
. = ALIGN(4);
_sdata = .; /* create a global symbol at data start */
*(.data) /* .data sections */
*(.data*) /* .data* sections */
. = ALIGN(4);
_edata = .; /* define a global symbol at data end */
} >RAM AT> FLASH
_spim_init_base = LOADADDR(.spim);
_spim_init_length = SIZEOF(.spim);
.spim :
{
. = ALIGN(4);
_spim_start = .; /* create a global symbol at spim start */
*(.spim) /* .spim sections */
*(.spim*) /* .spim* sections */
. = ALIGN(4);
_spim_end = .; /* define a global symbols at end of spim */
} >SPIM
/* Uninitialized data section */
. = ALIGN(4);
.bss :
{
/* This is used by the startup in order to initialize the .bss secion */
_sbss = .; /* define a global symbol at bss start */
__bss_start__ = _sbss;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .; /* define a global symbol at bss end */
__bss_end__ = _ebss;
} >RAM
/* User_heap_stack section, used to check that there is enough RAM left */
._user_heap_stack :
{
. = ALIGN(8);
PROVIDE ( end = . );
PROVIDE ( _end = . );
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(8);
} >RAM
/* Remove information from the standard libraries */
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
.ARM.attributes 0 : { *(.ARM.attributes) }
}

138
APP/ChargerConfig.h Normal file
View File

@ -0,0 +1,138 @@
//
// Created by villuton on 25.08.2025.
//
#ifndef CHARGER_CHARGERCONFIG_H
#define CHARGER_CHARGERCONFIG_H
/**
* Нумерация каналов
* для формирования массивов значений
* и пинов управления
*/
typedef enum {
CHRG_Ch1 = 0,
CHRG_Ch2,
CHRG_Ch3,
CHRG_Ch4,
CHRG_Ch5,
CHRG_Ch6,
CHRG_Ch7,
CHRG_Ch8,
CHRG_Ch9,
CHRG_Ch10,
}eChargerChannels;
/**
* Количество каналов
*/
#define CHARGER_CH_NUM 10
/**
* ADCS
*/
#define ADCS_ADCx ADC1
#define ADCS_ADC_BUFF_SIZE CHARGER_CH_NUM
#define ADCS_CRM_ADCx_PERIPH_CLOCK CRM_ADC1_PERIPH_CLOCK
#define ADCS_ADCx_ORDINARY_TRIG_SOFTWARE ADC12_ORDINARY_TRIG_SOFTWARE
#define ADCS_ADC_DMAx_CHANNELx DMA1_CHANNEL1
#define ADCS_ADC_DMAx_Channelx_IRQn DMA1_Channel1_IRQn
#define ADCS_ADC_CRM_DMAx_PERIPH_CLOCK CRM_DMA1_PERIPH_CLOCK
/**
* GPIOS
*/
#define GPIOS_NUM CHARGER_CH_NUM
/**
* SERIAL
*/
/**
* INDICATION
*/
#define INDICATION_CHANEL_NUM CHARGER_CH_NUM
#define INDICATION_MOD_NUM 4
#define INDICATION_THREAD_DELAY_MS 20
/**
* STORAGE FLASH AND RUNTIME VARIABLES
*/
/**
* Про расчет напряжения аккумулятора
* И приведения значения АЦП к реальному напряжению на входе
*
* V_in (04 В) R1R2 GND
*
* к АЦП (V_adc = 03,3 В)
*
* Приведение данных ацп к напряжению
* V_adc = adc_data * 3.3f / 4095.0f
*
* Формула соотношения входного напряжения к выходному
* на делителях
* V_adc = V_in * R1 / (R1 + R2)
* V_in = V_adc * (R1 + R2) / R1
*
* Вариант с пересчетом коэффициента и калибровки
* K = V_in_cal / ADC
* V_in_cal = ADC * K
*
* Для расчета будут два варианта, по умолчанию
* будет пересчет на делителях, для этого будем использовать посчитанный коэффициент,
* в нашем случае
* V_adc = adc_data * 3.3f / 4095.0f
* R1 = 51KOm R2 = 51KOm =>
* V_in = V_adc * (51 + 51)/51 =>
* V_in = V_adc * 2
* То есть коэффициент на делителях будет 2
* По умолчанию будут
*
* Второй вариант - расчет калибровочного коэффициента
* с выставленным напряжением на входе АКБ
* По умолчанию будет 4 Вольта, значение
* А калибровочные коэффициенты 0, чтобы брать в расчет
* Соотношение делителя и приведение от данных ацп к напряжению
*/
/// Количество значений калибровочных коэффициентов для каналов в стореде
#define STORAGE_CALIB_CHANEL_NUM CHARGER_CH_NUM
/// Напряжение, которое подаем для калибровки
#define STORAGE_V_REFERENCE_DEFAULT 4.0
/// Калибровочный коэффициент по умолчанию, если значение 0, то расчет ведется по соотношению делителя напряжения
#define STORAGE_CALIBRATION_FACTOR_DEFAULT 0.0
/// Напряжение на входе АКБ относится как два напряжения на входе ADC
#define STORAGE_V_DIVIDER_RATIO_DEFAULT 2.0
/// Напряжение, при котором считаем, что аккумулятор подключен
#define STORAGE_V_BAT_CONNECT 0.5
/// Напряжение, при котором считаем, что аккумулятор заряжен
#define STORAGE_V_BAT_LOADED 4.0
/// Верхнее значение напряжение на АЦП
#define STORAGE_V_ADC_THRESHOLD 3.3f
/// Верхнее значение 12 разрядов АЦП
#define STORAGE_ADC_THRESHOLD 4095.0f
/// Время проверки значения напряжения на каналах АЦП во время зарядки
#define STORAGE_VERIFICATION_TIME 100
/// Время зарядки, напряжение проверяется только на факт отключения АКБ
#define STORAGE_CHARGE_TIME 1000
/**
* MAIN
*/
/// Задержка основного потока
#define MAIN_THREAD_DELAY_MS 10
#endif //CHARGER_CHARGERCONFIG_H

89
APP/delay_sec.c Normal file
View File

@ -0,0 +1,89 @@
#include "at32f403a_407_clock.h"
#include "at32f403a_407.h"
/* delay macros */
#define STEP_DELAY_MS 50
/* delay variable */
static __IO uint32_t fac_us;
static __IO uint32_t fac_ms;
/**
* @brief initialize delay function
* @param none
* @retval none
*/
void delay_init()
{
/* configure systick */
systick_clock_source_config(SYSTICK_CLOCK_SOURCE_AHBCLK_NODIV);
fac_us = system_core_clock / (1000000U);
fac_ms = fac_us * (1000U);
}
/**
* @brief inserts a delay time.
* @param nus: specifies the delay time length, in microsecond.
* @retval none
*/
void delay_us(uint32_t nus)
{
uint32_t temp = 0;
SysTick->LOAD = (uint32_t)(nus * fac_us);
SysTick->VAL = 0x00;
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk ;
do
{
temp = SysTick->CTRL;
}while((temp & 0x01) && !(temp & (1 << 16)));
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
SysTick->VAL = 0x00;
}
/**
* @brief inserts a delay time.
* @param nms: specifies the delay time length, in milliseconds.
* @retval none
*/
void delay_ms(uint16_t nms)
{
uint32_t temp = 0;
while(nms)
{
if(nms > STEP_DELAY_MS)
{
SysTick->LOAD = (uint32_t)(STEP_DELAY_MS * fac_ms);
nms -= STEP_DELAY_MS;
}
else
{
SysTick->LOAD = (uint32_t)(nms * fac_ms);
nms = 0;
}
SysTick->VAL = 0x00;
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
do
{
temp = SysTick->CTRL;
}while((temp & 0x01) && !(temp & (1 << 16)));
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
SysTick->VAL = 0x00;
}
}
/**
* @brief inserts a delay time.
* @param sec: specifies the delay time, in seconds.
* @retval none
*/
void delay_sec(uint16_t sec)
{
uint16_t index;
for(index = 0; index < sec; index++)
{
delay_ms(500);
delay_ms(500);
}
}

11
APP/delay_sec.h Normal file
View File

@ -0,0 +1,11 @@
#ifndef DELAY_SEC_H
#define DELAY_SEC_H
#include "inttypes.h"
void delay_init();
void delay_ms(uint16_t nms);
void delay_us(uint32_t nus);
#endif //DELAY_SEC_H

176
APP/inc/FreeRTOSConfig.h Normal file
View File

@ -0,0 +1,176 @@
/* USER CODE BEGIN Header */
/*
* FreeRTOS Kernel V10.3.1
* Portion Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* Portion Copyright (C) 2019 StMicroelectronics, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* http://www.FreeRTOS.org
* http://aws.amazon.com/freertos
*
* 1 tab == 4 spaces!
*/
/* USER CODE END Header */
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
/*-----------------------------------------------------------
* Application specific definitions.
*
* These definitions should be adjusted for your particular hardware and
* application requirements.
*
* These parameters and more are described within the 'configuration' section of the
* FreeRTOS API documentation available on the FreeRTOS.org web site.
*
* See http://www.freertos.org/a00110.html
*----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* Section where include file can be added */
/* USER CODE END Includes */
/* Ensure definitions are only used by the compiler, and not by the assembler. */
#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)
#include <stdint.h>
extern unsigned int SystemCoreClock;
#endif
#ifndef CMSIS_device_header
//#define CMSIS_device_header "niietcm4.h"
#define CMSIS_device_header "at32f435_437.h"
#endif /* CMSIS_device_header */
//#include "niietcm4.h"
#include "at32f403a_407.h"
#define configCHECK_FOR_STACK_OVERFLOW 1
#define configENABLE_FPU 1
#define configENABLE_MPU 0
#define configUSE_PREEMPTION 1
#define configSUPPORT_STATIC_ALLOCATION 1
#define configSUPPORT_DYNAMIC_ALLOCATION 1
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 0
#define configCPU_CLOCK_HZ ( ( unsigned long ) system_core_clock )
#define configTICK_RATE_HZ ((TickType_t)1000)
#define configMAX_PRIORITIES ( 56 )
#define configMINIMAL_STACK_SIZE ((uint16_t)64)
#define configTOTAL_HEAP_SIZE ((size_t)40000)
#define configMAX_TASK_NAME_LEN ( 16 )
#define configUSE_TRACE_FACILITY 1
#define configUSE_16_BIT_TICKS 0
#define configUSE_MUTEXES 1
#define configQUEUE_REGISTRY_SIZE 8
#define configUSE_RECURSIVE_MUTEXES 1
#define configUSE_COUNTING_SEMAPHORES 1
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
/* USER CODE BEGIN MESSAGE_BUFFER_LENGTH_TYPE */
/* Defaults to size_t for backward compatibility, but can be changed
if lengths will always be less than the number of bytes in a size_t. */
#define configMESSAGE_BUFFER_LENGTH_TYPE size_t
/* USER CODE END MESSAGE_BUFFER_LENGTH_TYPE */
/* Co-routine definitions. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
/* Software timer definitions. */
#define configUSE_TIMERS 1
#define configTIMER_TASK_PRIORITY ( 2 )
#define configTIMER_QUEUE_LENGTH 10
#define configTIMER_TASK_STACK_DEPTH 128
/* CMSIS-RTOS V2 flags */
#define configUSE_OS2_THREAD_SUSPEND_RESUME 1
#define configUSE_OS2_THREAD_ENUMERATE 1
#define configUSE_OS2_EVENTFLAGS_FROM_ISR 1
#define configUSE_OS2_THREAD_FLAGS 1
#define configUSE_OS2_TIMER 1
#define configUSE_OS2_MUTEX 1
/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */
#define INCLUDE_vTaskPrioritySet 1
#define INCLUDE_uxTaskPriorityGet 1
#define INCLUDE_vTaskDelete 1
#define INCLUDE_vTaskCleanUpResources 0
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
#define INCLUDE_xTaskGetSchedulerState 1
#define INCLUDE_xTimerPendFunctionCall 1
#define INCLUDE_xQueueGetMutexHolder 1
#define INCLUDE_uxTaskGetStackHighWaterMark 1
#define INCLUDE_xTaskGetCurrentTaskHandle 1
#define INCLUDE_eTaskGetState 1
/*
* The CMSIS-RTOS V2 FreeRTOS wrapper is dependent on the heap implementation used
* by the application thus the correct define need to be enabled below
*/
#define USE_FreeRTOS_HEAP_4
/* Cortex-M specific definitions. */
#ifdef __NVIC_PRIO_BITS
/* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */
#define configPRIO_BITS __NVIC_PRIO_BITS
#else
#define configPRIO_BITS 4
#endif
/* The lowest interrupt priority that can be used in a call to a "set priority"
function. */
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15
/* The highest interrupt priority that can be used by any interrupt service
routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL
INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
PRIORITY THAN THIS! (higher priorities are lower numeric values. */
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5
/* Interrupt priorities used by the kernel port layer itself. These are generic
to all Cortex-M ports, and do not rely on any particular library functions. */
#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
/* Normal assert() semantics without relying on the provision of an assert.h
header file. */
/* USER CODE BEGIN 1 */
#define configASSERT(x) if ((x) == 0) {taskDISABLE_INTERRUPTS(); for( ;; );}
/* USER CODE END 1 */
/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
standard names. */
#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
/* IMPORTANT: After 10.3.1 update, Systick_Handler comes from NVIC (if SYS timebase = systick), otherwise from cmsis_os2.c */
#define USE_CUSTOM_SYSTICK_HANDLER_IMPLEMENTATION 0
#endif /* FREERTOS_CONFIG_H */

View File

@ -0,0 +1,44 @@
/**
**************************************************************************
* @file at32f403a_407_clock.h
* @brief header file of clock program
**************************************************************************
* Copyright notice & Disclaimer
*
* The software Board Support Package (BSP) that is made available to
* download from Artery official website is the copyrighted work of Artery.
* Artery authorizes customers to use, copy, and distribute the BSP
* software and its related documentation for the purpose of design and
* development in conjunction with Artery microcontrollers. Use of the
* software is governed by this copyright notice and the following disclaimer.
*
* THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
* GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
* TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
* STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
* INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
*
**************************************************************************
*/
/* define to prevent recursive inclusion -------------------------------------*/
#ifndef __AT32F403A_407_CLOCK_H
#define __AT32F403A_407_CLOCK_H
#ifdef __cplusplus
extern "C" {
#endif
/* includes ------------------------------------------------------------------*/
#include "at32f403a_407.h"
/* exported functions ------------------------------------------------------- */
void system_clock_config(void);
#ifdef __cplusplus
}
#endif
#endif /* __AT32F403A_407_CLOCK_H */

View File

@ -0,0 +1,161 @@
/**
**************************************************************************
* @file at32f403a_407_conf.h
* @brief at32f403a_407 config header file
**************************************************************************
* Copyright notice & Disclaimer
*
* The software Board Support Package (BSP) that is made available to
* download from Artery official website is the copyrighted work of Artery.
* Artery authorizes customers to use, copy, and distribute the BSP
* software and its related documentation for the purpose of design and
* development in conjunction with Artery microcontrollers. Use of the
* software is governed by this copyright notice and the following disclaimer.
*
* THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
* GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
* TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
* STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
* INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
*
**************************************************************************
*/
/* define to prevent recursive inclusion -------------------------------------*/
#ifndef __AT32F403A_407_CONF_H
#define __AT32F403A_407_CONF_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief in the following line adjust the value of high speed exernal crystal (hext)
* used in your application
*
* tip: to avoid modifying this file each time you need to use different hext, you
* can define the hext value in your toolchain compiler preprocessor.
*
*/
#if !defined HEXT_VALUE
#define HEXT_VALUE ((uint32_t)8000000) /*!< value of the high speed exernal crystal in hz */
#endif
/**
* @brief in the following line adjust the high speed exernal crystal (hext) startup
* timeout value
*/
#define HEXT_STARTUP_TIMEOUT ((uint16_t)0x3000) /*!< time out for hext start up */
#define HICK_VALUE ((uint32_t)16000000) /*!< value of the high speed internal clock in hz */
#define LEXT_VALUE ((uint32_t)32768) /*!< value of the low speed exernal clock in hz */
/* module define -------------------------------------------------------------*/
#define CRM_MODULE_ENABLED
#define TMR_MODULE_ENABLED
#define RTC_MODULE_ENABLED
#define BPR_MODULE_ENABLED
#define GPIO_MODULE_ENABLED
#define I2C_MODULE_ENABLED
#define USART_MODULE_ENABLED
#define PWC_MODULE_ENABLED
#define CAN_MODULE_ENABLED
#define ADC_MODULE_ENABLED
#define DAC_MODULE_ENABLED
#define SPI_MODULE_ENABLED
#define DMA_MODULE_ENABLED
#define DEBUG_MODULE_ENABLED
#define FLASH_MODULE_ENABLED
#define CRC_MODULE_ENABLED
#define WWDT_MODULE_ENABLED
#define WDT_MODULE_ENABLED
#define EXINT_MODULE_ENABLED
#define SDIO_MODULE_ENABLED
#define XMC_MODULE_ENABLED
#define USB_MODULE_ENABLED
#define ACC_MODULE_ENABLED
#define MISC_MODULE_ENABLED
#define EMAC_MODULE_ENABLED
/* includes ------------------------------------------------------------------*/
#ifdef CRM_MODULE_ENABLED
#include "at32f403a_407_crm.h"
#endif
#ifdef TMR_MODULE_ENABLED
#include "at32f403a_407_tmr.h"
#endif
#ifdef RTC_MODULE_ENABLED
#include "at32f403a_407_rtc.h"
#endif
#ifdef BPR_MODULE_ENABLED
#include "at32f403a_407_bpr.h"
#endif
#ifdef GPIO_MODULE_ENABLED
#include "at32f403a_407_gpio.h"
#endif
#ifdef I2C_MODULE_ENABLED
#include "at32f403a_407_i2c.h"
#endif
#ifdef USART_MODULE_ENABLED
#include "at32f403a_407_usart.h"
#endif
#ifdef PWC_MODULE_ENABLED
#include "at32f403a_407_pwc.h"
#endif
#ifdef CAN_MODULE_ENABLED
#include "at32f403a_407_can.h"
#endif
#ifdef ADC_MODULE_ENABLED
#include "at32f403a_407_adc.h"
#endif
#ifdef DAC_MODULE_ENABLED
#include "at32f403a_407_dac.h"
#endif
#ifdef SPI_MODULE_ENABLED
#include "at32f403a_407_spi.h"
#endif
#ifdef DMA_MODULE_ENABLED
#include "at32f403a_407_dma.h"
#endif
#ifdef DEBUG_MODULE_ENABLED
#include "at32f403a_407_debug.h"
#endif
#ifdef FLASH_MODULE_ENABLED
#include "at32f403a_407_flash.h"
#endif
#ifdef CRC_MODULE_ENABLED
#include "at32f403a_407_crc.h"
#endif
#ifdef WWDT_MODULE_ENABLED
#include "at32f403a_407_wwdt.h"
#endif
#ifdef WDT_MODULE_ENABLED
#include "at32f403a_407_wdt.h"
#endif
#ifdef EXINT_MODULE_ENABLED
#include "at32f403a_407_exint.h"
#endif
#ifdef SDIO_MODULE_ENABLED
#include "at32f403a_407_sdio.h"
#endif
#ifdef XMC_MODULE_ENABLED
#include "at32f403a_407_xmc.h"
#endif
#ifdef ACC_MODULE_ENABLED
#include "at32f403a_407_acc.h"
#endif
#ifdef MISC_MODULE_ENABLED
#include "at32f403a_407_misc.h"
#endif
#ifdef USB_MODULE_ENABLED
#include "at32f403a_407_usb.h"
#endif
#ifdef EMAC_MODULE_ENABLED
#include "at32f403a_407_emac.h"
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,56 @@
/**
**************************************************************************
* @file at32f403a_407_int.h
* @brief header file of main interrupt service routines.
**************************************************************************
* Copyright notice & Disclaimer
*
* The software Board Support Package (BSP) that is made available to
* download from Artery official website is the copyrighted work of Artery.
* Artery authorizes customers to use, copy, and distribute the BSP
* software and its related documentation for the purpose of design and
* development in conjunction with Artery microcontrollers. Use of the
* software is governed by this copyright notice and the following disclaimer.
*
* THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
* GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
* TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
* STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
* INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
*
**************************************************************************
*/
/* define to prevent recursive inclusion -------------------------------------*/
#ifndef __AT32F403A_407_INT_H
#define __AT32F403A_407_INT_H
#ifdef __cplusplus
extern "C" {
#endif
/* includes ------------------------------------------------------------------*/
#include "at32f403a_407.h"
/* exported types ------------------------------------------------------------*/
/* exported constants --------------------------------------------------------*/
/* exported macro ------------------------------------------------------------*/
/* exported functions ------------------------------------------------------- */
void NMI_Handler(void);
void HardFault_Handler(void);
void MemManage_Handler(void);
void BusFault_Handler(void);
void UsageFault_Handler(void);
void SVC_Handler(void);
void DebugMon_Handler(void);
void PendSV_Handler(void);
void SysTick_Handler(void);
#ifdef __cplusplus
}
#endif
#endif

83
APP/main.c Normal file
View File

@ -0,0 +1,83 @@
#include <at32f403a_407_clock.h>
#include <SystemDelayInterface.h>
#include <stdio.h>
#include "cmsis_os.h"
#include "CmsisRtosThreadUtils.h"
#include "delay_sec.h"
#define EXTEND_SRAM 0xFE
extern void MAIN_INIT();
extern void MAIN_START();
__WEAK void MAIN_INIT()
{
/**
* MAIN_INIT() not defined
*/
asm("nop");
}
__WEAK void MAIN_START()
{
/**
* MAIN_START() not defined
*/
asm("nop");
}
/**
* @brief to extend sram size
* @param none
* @retval none
*/
void extend_sram(void)
{
/* check if ram has been set to expectant size, if not, change eopb0 */
if (((USD->eopb0) & 0xFF) != EXTEND_SRAM) {
flash_unlock();
/* erase user system data bytes */
flash_user_system_data_erase();
/* change sram size */
flash_user_system_data_program((uint32_t) &USD->eopb0, EXTEND_SRAM);
/* system reset */
nvic_system_reset();
}
}
/**
* Stack Overflow
*/
_Noreturn void stop()
{
while (1) {
asm("nop");
}
}
#define STOP stop();
void vApplicationStackOverflowHook(TaskHandle_t xTask, signed char *pcTaskName)
{
STOP
}
int main(void)
{
system_clock_config();
delay_init();
osKernelInitialize();
MAIN_INIT();
MAIN_START();
osKernelStart();
STOP
}

13
APP/modular.json Normal file
View File

@ -0,0 +1,13 @@
{
"cmake": {
"inc_dirs": [
"./",
"./inc"
],
"srcs": [
"./src/**.c",
"./src/**.s",
"./**.c"
]
}
}

View File

@ -0,0 +1,98 @@
/**
**************************************************************************
* @file at32f403a_407_clock.c
* @brief system clock config program
**************************************************************************
* Copyright notice & Disclaimer
*
* The software Board Support Package (BSP) that is made available to
* download from Artery official website is the copyrighted work of Artery.
* Artery authorizes customers to use, copy, and distribute the BSP
* software and its related documentation for the purpose of design and
* development in conjunction with Artery microcontrollers. Use of the
* software is governed by this copyright notice and the following disclaimer.
*
* THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
* GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
* TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
* STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
* INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
*
**************************************************************************
*/
/* includes ------------------------------------------------------------------*/
#include "at32f403a_407_clock.h"
/**
* @brief system clock config program
* @note the system clock is configured as follow:
* - system clock = hext / 2 * pll_mult
* - system clock source = pll (hext)
* - hext = 8000000
* - sclk = 240000000
* - ahbdiv = 1
* - ahbclk = 240000000
* - apb2div = 2
* - apb2clk = 120000000
* - apb1div = 2
* - apb1clk = 120000000
* - pll_mult = 60
* - pll_range = GT72MHZ (greater than 72 mhz)
* @param none
* @retval none
*/
void system_clock_config(void)
{
/* reset crm */
crm_reset();
crm_clock_source_enable(CRM_CLOCK_SOURCE_HEXT, TRUE);
/* wait till hext is ready */
while(crm_hext_stable_wait() == ERROR)
{
}
/* config pll clock resource */
crm_pll_config(CRM_PLL_SOURCE_HEXT_DIV, CRM_PLL_MULT_30, CRM_PLL_OUTPUT_RANGE_GT72MHZ);
/* config hext division */
crm_hext_clock_div_set(CRM_HEXT_DIV_2);
/* enable pll */
crm_clock_source_enable(CRM_CLOCK_SOURCE_PLL, TRUE);
/* wait till pll is ready */
while(crm_flag_get(CRM_PLL_STABLE_FLAG) != SET)
{
}
/* config ahbclk */
crm_ahb_div_set(CRM_AHB_DIV_1);
/* config apb2clk, the maximum frequency of APB1/APB2 clock is 120 MHz */
crm_apb2_div_set(CRM_APB2_DIV_2);
/* config apb1clk, the maximum frequency of APB1/APB2 clock is 120 MHz */
crm_apb1_div_set(CRM_APB1_DIV_2);
/* enable auto step mode */
crm_auto_step_mode_enable(TRUE);
/* select pll as system clock source */
crm_sysclk_switch(CRM_SCLK_PLL);
/* wait till pll is used as system clock source */
while(crm_sysclk_switch_status_get() != CRM_SCLK_PLL)
{
}
/* disable auto step mode */
crm_auto_step_mode_enable(FALSE);
/* update system_core_clock global variable */
system_core_clock_update();
}

140
APP/src/at32f403a_407_int.c Normal file
View File

@ -0,0 +1,140 @@
/**
**************************************************************************
* @file at32f403a_407_int.c
* @brief main interrupt service routines.
**************************************************************************
* Copyright notice & Disclaimer
*
* The software Board Support Package (BSP) that is made available to
* download from Artery official website is the copyrighted work of Artery.
* Artery authorizes customers to use, copy, and distribute the BSP
* software and its related documentation for the purpose of design and
* development in conjunction with Artery microcontrollers. Use of the
* software is governed by this copyright notice and the following disclaimer.
*
* THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
* GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
* TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
* STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
* INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
*
**************************************************************************
*/
/* includes ------------------------------------------------------------------*/
#include "at32f403a_407_int.h"
/** @addtogroup AT32F403A_periph_examples
* @{
*/
/** @addtogroup 403A_GPIO_led_toggle
* @{
*/
/**
* @brief this function handles nmi exception.
* @param none
* @retval none
*/
void NMI_Handler(void)
{
}
/**
* @brief this function handles hard fault exception.
* @param none
* @retval none
*/
void HardFault_Handler(void)
{
/* go to infinite loop when hard fault exception occurs */
while(1)
{
}
}
/**
* @brief this function handles memory manage exception.
* @param none
* @retval none
*/
void MemManage_Handler(void)
{
/* go to infinite loop when memory manage exception occurs */
while(1)
{
}
}
/**
* @brief this function handles bus fault exception.
* @param none
* @retval none
*/
void BusFault_Handler(void)
{
/* go to infinite loop when bus fault exception occurs */
while(1)
{
}
}
/**
* @brief this function handles usage fault exception.
* @param none
* @retval none
*/
void UsageFault_Handler(void)
{
/* go to infinite loop when usage fault exception occurs */
while(1)
{
}
}
/**
* @brief this function handles svcall exception.
* @param none
* @retval none
*/
//void SVC_Handler(void)
//{
//}
/**
* @brief this function handles debug monitor exception.
* @param none
* @retval none
*/
void DebugMon_Handler(void)
{
}
/**
* @brief this function handles pendsv_handler exception.
* @param none
* @retval none
*/
//void PendSV_Handler(void)
//{
//}
/**
* @brief this function handles systick handler.
* @param none
* @retval none
*/
//void SysTick_Handler(void)
//{
//}
/**
* @}
*/
/**
* @}
*/

View File

@ -0,0 +1,480 @@
/**
******************************************************************************
* @file startup_at32f403a_407.s
* @brief at32f403a_407xx devices vector table for gcc toolchain.
* this module performs:
* - set the initial sp
* - set the initial pc == reset_handler,
* - set the vector table entries with the exceptions isr address
* - configure the clock system and the external sram to
* be used as data memory (optional, to be enabled by user)
* - branches to main in the c library (which eventually
* calls main()).
* after reset the cortex-m4 processor is in thread mode,
* priority is privileged, and the stack is set to main.
******************************************************************************
*/
.syntax unified
.cpu cortex-m4
.fpu softvfp
.thumb
.global g_pfnVectors
.global Default_Handler
/* start address for the initialization values of the .data section.
defined in linker script */
.word _sidata
/* start address for the .data section. defined in linker script */
.word _sdata
/* end address for the .data section. defined in linker script */
.word _edata
/* start address for the .bss section. defined in linker script */
.word _sbss
/* end address for the .bss section. defined in linker script */
.word _ebss
/* stack used for SystemInit_ExtMemCtl; always internal RAM used */
/**
* @brief This is the code that gets called when the processor first
* starts execution following a reset event. Only the absolutely
* necessary set is performed, after which the application
* supplied main() routine is called.
* @param None
* @retval None
*/
.section .text.Reset_Handler
.weak Reset_Handler
.type Reset_Handler, %function
Reset_Handler:
/* Copy the data segment initializers from flash to SRAM */
bl extend_sram
movs r1, #0
b LoopCopyDataInit
CopyDataInit:
ldr r3, =_sidata
ldr r3, [r3, r1]
str r3, [r0, r1]
adds r1, r1, #4
LoopCopyDataInit:
ldr r0, =_sdata
ldr r3, =_edata
adds r2, r0, r1
cmp r2, r3
bcc CopyDataInit
ldr r2, =_sbss
b LoopFillZerobss
/* Zero fill the bss segment. */
FillZerobss:
movs r3, #0
str r3, [r2], #4
LoopFillZerobss:
ldr r3, = _ebss
cmp r2, r3
bcc FillZerobss
/* Call the clock system intitialization function.*/
bl SystemInit
/* Call static constructors */
bl __libc_init_array
/* Call the application's entry point.*/
bl main
bx lr
.size Reset_Handler, .-Reset_Handler
/**
* @brief This is the code that gets called when the processor receives an
* unexpected interrupt. This simply enters an infinite loop, preserving
* the system state for examination by a debugger.
* @param None
* @retval None
*/
.section .text.Default_Handler,"ax",%progbits
Default_Handler:
Infinite_Loop:
b Infinite_Loop
.size Default_Handler, .-Default_Handler
/******************************************************************************
*
* The minimal vector table for a Cortex M3. Note that the proper constructs
* must be placed on this to ensure that it ends up at physical address
* 0x0000.0000.
*
*******************************************************************************/
.section .isr_vector,"a",%progbits
.type g_pfnVectors, %object
.size g_pfnVectors, .-g_pfnVectors
g_pfnVectors:
.word _estack
.word Reset_Handler
.word NMI_Handler
.word HardFault_Handler
.word MemManage_Handler
.word BusFault_Handler
.word UsageFault_Handler
.word 0
.word 0
.word 0
.word 0
.word SVC_Handler
.word DebugMon_Handler
.word 0
.word PendSV_Handler
.word SysTick_Handler
/* External Interrupts */
.word WWDT_IRQHandler /* Window Watchdog Timer */
.word PVM_IRQHandler /* PVM through EXINT Line detect */
.word TAMPER_IRQHandler /* Tamper */
.word RTC_IRQHandler /* RTC */
.word FLASH_IRQHandler /* Flash */
.word CRM_IRQHandler /* CRM */
.word EXINT0_IRQHandler /* EXINT Line 0 */
.word EXINT1_IRQHandler /* EXINT Line 1 */
.word EXINT2_IRQHandler /* EXINT Line 2 */
.word EXINT3_IRQHandler /* EXINT Line 3 */
.word EXINT4_IRQHandler /* EXINT Line 4 */
.word DMA1_Channel1_IRQHandler /* DMA1 Channel 1 */
.word DMA1_Channel2_IRQHandler /* DMA1 Channel 2 */
.word DMA1_Channel3_IRQHandler /* DMA1 Channel 3 */
.word DMA1_Channel4_IRQHandler /* DMA1 Channel 4 */
.word DMA1_Channel5_IRQHandler /* DMA1 Channel 5 */
.word DMA1_Channel6_IRQHandler /* DMA1 Channel 6 */
.word DMA1_Channel7_IRQHandler /* DMA1 Channel 7 */
.word ADC1_2_IRQHandler /* ADC1 & ADC2 */
.word USBFS_H_CAN1_TX_IRQHandler /* USB High Priority or CAN1 TX */
.word USBFS_L_CAN1_RX0_IRQHandler /* USB Low Priority or CAN1 RX0 */
.word CAN1_RX1_IRQHandler /* CAN1 RX1 */
.word CAN1_SE_IRQHandler /* CAN1 SE */
.word EXINT9_5_IRQHandler /* EXINT Line [9:5] */
.word TMR1_BRK_TMR9_IRQHandler /* TMR1 Brake and TMR9 */
.word TMR1_OVF_TMR10_IRQHandler /* TMR1 Overflow and TMR10 */
.word TMR1_TRG_HALL_TMR11_IRQHandler /* TMR1 Trigger and hall and TMR11 */
.word TMR1_CH_IRQHandler /* TMR1 Channel */
.word TMR2_GLOBAL_IRQHandler /* TMR2 */
.word TMR3_GLOBAL_IRQHandler /* TMR3 */
.word TMR4_GLOBAL_IRQHandler /* TMR4 */
.word I2C1_EVT_IRQHandler /* I2C1 Event */
.word I2C1_ERR_IRQHandler /* I2C1 Error */
.word I2C2_EVT_IRQHandler /* I2C2 Event */
.word I2C2_ERR_IRQHandler /* I2C2 Error */
.word SPI1_IRQHandler /* SPI1 */
.word SPI2_I2S2EXT_IRQHandler /* SPI2 & I2S2EXT */
.word USART1_IRQHandler /* USART1 */
.word USART2_IRQHandler /* USART2 */
.word USART3_IRQHandler /* USART3 */
.word EXINT15_10_IRQHandler /* EXINT Line [15:10] */
.word RTCAlarm_IRQHandler /* RTC Alarm through EXINT Line */
.word USBFSWakeUp_IRQHandler /* USB Wakeup from suspend */
.word TMR8_BRK_TMR12_IRQHandler /* TMR8 Brake and TMR12 */
.word TMR8_OVF_TMR13_IRQHandler /* TMR8 Overflow and TMR13 */
.word TMR8_TRG_HALL_TMR14_IRQHandler /* TMR8 Trigger and hall and TMR14 */
.word TMR8_CH_IRQHandler /* TMR8 Channel */
.word ADC3_IRQHandler /* ADC3 */
.word XMC_IRQHandler /* XMC */
.word SDIO1_IRQHandler /* SDIO1 */
.word TMR5_GLOBAL_IRQHandler /* TMR5 */
.word SPI3_I2S3EXT_IRQHandler /* SPI3 & I2S3EXT */
.word UART4_IRQHandler /* UART4 */
.word UART5_IRQHandler /* UART5 */
.word TMR6_GLOBAL_IRQHandler /* TMR6 */
.word TMR7_GLOBAL_IRQHandler /* TMR7 */
.word DMA2_Channel1_IRQHandler /* DMA2 Channel1 */
.word DMA2_Channel2_IRQHandler /* DMA2 Channel2 */
.word DMA2_Channel3_IRQHandler /* DMA2 Channel3 */
.word DMA2_Channel4_5_IRQHandler /* DMA2 Channel4 & Channel5 */
.word SDIO2_IRQHandler /* SDIO2 */
.word I2C3_EVT_IRQHandler /* I2C3 Event */
.word I2C3_ERR_IRQHandler /* I2C3 Error */
.word SPI4_IRQHandler /* SPI4 */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word CAN2_TX_IRQHandler /* CAN2 TX */
.word CAN2_RX0_IRQHandler /* CAN2 RX0 */
.word CAN2_RX1_IRQHandler /* CAN2 RX1 */
.word CAN2_SE_IRQHandler /* CAN2 SE */
.word ACC_IRQHandler /* ACC */
.word USBFS_MAPH_IRQHandler /* USB Map HP */
.word USBFS_MAPL_IRQHandler /* USB Map LP */
.word DMA2_Channel6_7_IRQHandler /* DMA2 Channel6 & Channel7 */
.word USART6_IRQHandler /* USART6 */
.word UART7_IRQHandler /* UART7 */
.word UART8_IRQHandler /* UART8 */
.word EMAC_IRQHandler /* EMAC */
.word EMAC_WKUP_IRQHandler /* EMAC Wakeup */
/*******************************************************************************
*
* Provide weak aliases for each Exception handler to the Default_Handler.
* As they are weak aliases, any function with the same name will override
* this definition.
*
*******************************************************************************/
.weak NMI_Handler
.thumb_set NMI_Handler,Default_Handler
.weak HardFault_Handler
.thumb_set HardFault_Handler,Default_Handler
.weak MemManage_Handler
.thumb_set MemManage_Handler,Default_Handler
.weak BusFault_Handler
.thumb_set BusFault_Handler,Default_Handler
.weak UsageFault_Handler
.thumb_set UsageFault_Handler,Default_Handler
.weak SVC_Handler
.thumb_set SVC_Handler,Default_Handler
.weak DebugMon_Handler
.thumb_set DebugMon_Handler,Default_Handler
.weak PendSV_Handler
.thumb_set PendSV_Handler,Default_Handler
.weak SysTick_Handler
.thumb_set SysTick_Handler,Default_Handler
.weak WWDT_IRQHandler
.thumb_set WWDT_IRQHandler,Default_Handler
.weak PVM_IRQHandler
.thumb_set PVM_IRQHandler,Default_Handler
.weak TAMPER_IRQHandler
.thumb_set TAMPER_IRQHandler,Default_Handler
.weak RTC_IRQHandler
.thumb_set RTC_IRQHandler,Default_Handler
.weak FLASH_IRQHandler
.thumb_set FLASH_IRQHandler,Default_Handler
.weak CRM_IRQHandler
.thumb_set CRM_IRQHandler,Default_Handler
.weak EXINT0_IRQHandler
.thumb_set EXINT0_IRQHandler,Default_Handler
.weak EXINT1_IRQHandler
.thumb_set EXINT1_IRQHandler,Default_Handler
.weak EXINT2_IRQHandler
.thumb_set EXINT2_IRQHandler,Default_Handler
.weak EXINT3_IRQHandler
.thumb_set EXINT3_IRQHandler,Default_Handler
.weak EXINT4_IRQHandler
.thumb_set EXINT4_IRQHandler,Default_Handler
.weak DMA1_Channel1_IRQHandler
.thumb_set DMA1_Channel1_IRQHandler,Default_Handler
.weak DMA1_Channel2_IRQHandler
.thumb_set DMA1_Channel2_IRQHandler,Default_Handler
.weak DMA1_Channel3_IRQHandler
.thumb_set DMA1_Channel3_IRQHandler,Default_Handler
.weak DMA1_Channel4_IRQHandler
.thumb_set DMA1_Channel4_IRQHandler,Default_Handler
.weak DMA1_Channel5_IRQHandler
.thumb_set DMA1_Channel5_IRQHandler,Default_Handler
.weak DMA1_Channel6_IRQHandler
.thumb_set DMA1_Channel6_IRQHandler,Default_Handler
.weak DMA1_Channel7_IRQHandler
.thumb_set DMA1_Channel7_IRQHandler,Default_Handler
.weak ADC1_2_IRQHandler
.thumb_set ADC1_2_IRQHandler,Default_Handler
.weak USBFS_H_CAN1_TX_IRQHandler
.thumb_set USBFS_H_CAN1_TX_IRQHandler,Default_Handler
.weak USBFS_L_CAN1_RX0_IRQHandler
.thumb_set USBFS_L_CAN1_RX0_IRQHandler,Default_Handler
.weak CAN1_RX1_IRQHandler
.thumb_set CAN1_RX1_IRQHandler,Default_Handler
.weak CAN1_SE_IRQHandler
.thumb_set CAN1_SE_IRQHandler,Default_Handler
.weak EXINT9_5_IRQHandler
.thumb_set EXINT9_5_IRQHandler,Default_Handler
.weak TMR1_BRK_TMR9_IRQHandler
.thumb_set TMR1_BRK_TMR9_IRQHandler,Default_Handler
.weak TMR1_OVF_TMR10_IRQHandler
.thumb_set TMR1_OVF_TMR10_IRQHandler,Default_Handler
.weak TMR1_TRG_HALL_TMR11_IRQHandler
.thumb_set TMR1_TRG_HALL_TMR11_IRQHandler,Default_Handler
.weak TMR1_CH_IRQHandler
.thumb_set TMR1_CH_IRQHandler,Default_Handler
.weak TMR2_GLOBAL_IRQHandler
.thumb_set TMR2_GLOBAL_IRQHandler,Default_Handler
.weak TMR3_GLOBAL_IRQHandler
.thumb_set TMR3_GLOBAL_IRQHandler,Default_Handler
.weak TMR4_GLOBAL_IRQHandler
.thumb_set TMR4_GLOBAL_IRQHandler,Default_Handler
.weak I2C1_EVT_IRQHandler
.thumb_set I2C1_EVT_IRQHandler,Default_Handler
.weak I2C1_ERR_IRQHandler
.thumb_set I2C1_ERR_IRQHandler,Default_Handler
.weak I2C2_EVT_IRQHandler
.thumb_set I2C2_EVT_IRQHandler,Default_Handler
.weak I2C2_ERR_IRQHandler
.thumb_set I2C2_ERR_IRQHandler,Default_Handler
.weak SPI1_IRQHandler
.thumb_set SPI1_IRQHandler,Default_Handler
.weak SPI2_I2S2EXT_IRQHandler
.thumb_set SPI2_I2S2EXT_IRQHandler,Default_Handler
.weak USART1_IRQHandler
.thumb_set USART1_IRQHandler,Default_Handler
.weak USART2_IRQHandler
.thumb_set USART2_IRQHandler,Default_Handler
.weak USART3_IRQHandler
.thumb_set USART3_IRQHandler,Default_Handler
.weak EXINT15_10_IRQHandler
.thumb_set EXINT15_10_IRQHandler,Default_Handler
.weak RTCAlarm_IRQHandler
.thumb_set RTCAlarm_IRQHandler,Default_Handler
.weak USBFSWakeUp_IRQHandler
.thumb_set USBFSWakeUp_IRQHandler,Default_Handler
.weak TMR8_BRK_TMR12_IRQHandler
.thumb_set TMR8_BRK_TMR12_IRQHandler,Default_Handler
.weak TMR8_OVF_TMR13_IRQHandler
.thumb_set TMR8_OVF_TMR13_IRQHandler,Default_Handler
.weak TMR8_TRG_HALL_TMR14_IRQHandler
.thumb_set TMR8_TRG_HALL_TMR14_IRQHandler,Default_Handler
.weak TMR8_CH_IRQHandler
.thumb_set TMR8_CH_IRQHandler,Default_Handler
.weak ADC3_IRQHandler
.thumb_set ADC3_IRQHandler,Default_Handler
.weak XMC_IRQHandler
.thumb_set XMC_IRQHandler,Default_Handler
.weak SDIO1_IRQHandler
.thumb_set SDIO1_IRQHandler,Default_Handler
.weak TMR5_GLOBAL_IRQHandler
.thumb_set TMR5_GLOBAL_IRQHandler,Default_Handler
.weak SPI3_I2S3EXT_IRQHandler
.thumb_set SPI3_I2S3EXT_IRQHandler,Default_Handler
.weak UART4_IRQHandler
.thumb_set UART4_IRQHandler,Default_Handler
.weak UART5_IRQHandler
.thumb_set UART5_IRQHandler,Default_Handler
.weak TMR6_GLOBAL_IRQHandler
.thumb_set TMR6_GLOBAL_IRQHandler,Default_Handler
.weak TMR7_GLOBAL_IRQHandler
.thumb_set TMR7_GLOBAL_IRQHandler,Default_Handler
.weak DMA2_Channel1_IRQHandler
.thumb_set DMA2_Channel1_IRQHandler,Default_Handler
.weak DMA2_Channel2_IRQHandler
.thumb_set DMA2_Channel2_IRQHandler,Default_Handler
.weak DMA2_Channel3_IRQHandler
.thumb_set DMA2_Channel3_IRQHandler,Default_Handler
.weak DMA2_Channel4_5_IRQHandler
.thumb_set DMA2_Channel4_5_IRQHandler,Default_Handler
.weak SDIO2_IRQHandler
.thumb_set SDIO2_IRQHandler,Default_Handler
.weak I2C3_EVT_IRQHandler
.thumb_set I2C3_EVT_IRQHandler,Default_Handler
.weak I2C3_ERR_IRQHandler
.thumb_set I2C3_ERR_IRQHandler,Default_Handler
.weak SPI4_IRQHandler
.thumb_set SPI4_IRQHandler,Default_Handler
.weak CAN2_TX_IRQHandler
.thumb_set CAN2_TX_IRQHandler,Default_Handler
.weak CAN2_RX0_IRQHandler
.thumb_set CAN2_RX0_IRQHandler ,Default_Handler
.weak CAN2_RX1_IRQHandler
.thumb_set CAN2_RX1_IRQHandler ,Default_Handler
.weak CAN2_SE_IRQHandler
.thumb_set CAN2_SE_IRQHandler,Default_Handler
.weak ACC_IRQHandler
.thumb_set ACC_IRQHandler,Default_Handler
.weak USBFS_MAPH_IRQHandler
.thumb_set USBFS_MAPH_IRQHandler,Default_Handler
.weak USBFS_MAPL_IRQHandler
.thumb_set USBFS_MAPL_IRQHandler,Default_Handler
.weak DMA2_Channel6_7_IRQHandler
.thumb_set DMA2_Channel6_7_IRQHandler,Default_Handler
.weak USART6_IRQHandler
.thumb_set USART6_IRQHandler,Default_Handler
.weak UART7_IRQHandler
.thumb_set UART7_IRQHandler,Default_Handler
.weak UART8_IRQHandler
.thumb_set UART8_IRQHandler,Default_Handler
.weak EMAC_IRQHandler
.thumb_set EMAC_IRQHandler,Default_Handler
.weak EMAC_WKUP_IRQHandler
.thumb_set EMAC_WKUP_IRQHandler,Default_Handler

79
CMakeLists.txt Normal file
View File

@ -0,0 +1,79 @@
#-- Service --------------------------------------------------------------------
SET(CMAKE_TOOLCHAIN_FILE ${CMAKE_SOURCE_DIR}/MODULES/CmakeConfig_GCC_CortexM4/gcc_cm4f.cmake)
ENABLE_LANGUAGE(ASM)
CMAKE_MINIMUM_REQUIRED(VERSION 3.8.0)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0")
IF (${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
MESSAGE(
FATAL_ERROR
"In-source builds not allowed.
Please make a new directory (called a build directory) and run CMake from there.
You may need to remove CMakeCache.txt."
)
ENDIF ()
SET(CMAKE_EXPORT_COMPILE_COMMANDS ON)
#-- Project config -------------------------------------------------------------
PROJECT(Charger) # Project name
SET(HARDWARE_REVISION 1) # HW in servisProg
SET(VERSION \"1.0.0\") #
SET(HARDWARE_USER_NAME "WeActARTRY")
#SET(VECT_TAB_OFFSET "0x100000")
SET(VECT_TAB_OFFSET "0x000000")
SET(HEXT_VALUE "8000000")
SET(PLL_NS "144")
#-- Defines --------------------------------------------------------------------
ADD_DEFINITIONS(-DUART_DMA_SEND)
ADD_DEFINITIONS(-DDEBUG -DAT32F403ACGT7)
#ADD_DEFINITIONS(-DDEBUG -DAT32F403AVG7 -DAT_START_F403_V1)
#ADD_DEFINITIONS(-DDEBUG -DAT32F437ZMT7 -DAT_START_F435_V1)
ADD_DEFINITIONS(-DFIRMWARE_VERSION=${VERSION})
ADD_DEFINITIONS(-DHARDWARE_REVISION=\"${HARDWARE_REVISION}\")
ADD_DEFINITIONS(-DVECT_TAB_OFFSET=${VECT_TAB_OFFSET})
ADD_DEFINITIONS(-DHEXT_VALUE=${HEXT_VALUE})
ADD_DEFINITIONS(-DPLL_NS=${PLL_NS})
ADD_DEFINITIONS(-DCMSIS_device_header="at32f403a_407.h")
ADD_DEFINITIONS(-DFLASH_PAGE_SIZE=2048)
#-- Project paths, Include dirs, Sources list ---------------------------------
#ADD_FILES(SOURCES "MODULES/DeviceStartup_ARTERY_AT32F437ZMT7/ld/startup_at32f403a_407.s")
include(modular.cmake)
#-- Options --------------------------------------------------------------------
#IF (PRINTF_FLOAT STREQUAL "1")
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -u_printf_float")
#ENDIF ()
IF (SCANF_FLOAT STREQUAL "1")
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -u_scanf_float")
ENDIF ()
#-- Linker script --------------------------------------------------------------
SET(LDSCRIPT ${CMAKE_SOURCE_DIR}/APP/AT32F403AxG_FLASH.ld)
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -T ${LDSCRIPT} -Wl,-Map=${CMAKE_BINARY_DIR}/${PROJECT_NAME}.map -Wl,--print-memory-usage")
#-- Random BuildId Generation ------------------------------------------------------------
SET(RANDOM_BUILD_ID_GEN_FILE ${CMAKE_SOURCE_DIR}/MODULES/CmakeConfig_RandomBuildIdGenerator/version.cmake)
add_custom_target(GEN_RANDOM_BUILD_ID)
ADD_CUSTOM_COMMAND(TARGET GEN_RANDOM_BUILD_ID POST_BUILD
COMMAND ${CMAKE_COMMAND} -P ${RANDOM_BUILD_ID_GEN_FILE})
#-- Project linking ------------------------------------------------------------
ADD_EXECUTABLE(${PROJECT_NAME}.elf ${SOURCES})
TARGET_LINK_LIBRARIES(${PROJECT_NAME}.elf)
add_dependencies(${PROJECT_NAME}.elf GEN_RANDOM_BUILD_ID)
#-- Custom commands ------------------------------------------------------------
ADD_CUSTOM_COMMAND(TARGET ${PROJECT_NAME}.elf POST_BUILD
COMMAND ${CMAKE_OBJCOPY} "-Oihex" ${PROJECT_NAME}.elf ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.hex
COMMAND ${CMAKE_OBJCOPY} "-Obinary" ${PROJECT_NAME}.elf ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.bin
# COMMAND ${CMAKE_OBJDUMP} "-DS" ${PROJECT_NAME}.elf > ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.dasm
COMMAND ${CMAKE_SIZE} ${PROJECT_NAME}.elf)

BIN
DOC/Charger_1.pdf Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

15
LOCAL/Inc/Adcs.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef CHARGER_ADCS_H
#define CHARGER_ADCS_H
#include <stdint.h>
#include "ChargerConfig.h"
typedef struct {
///Таблица значений каналов ADC
uint16_t tab[ADCS_ADC_BUFF_SIZE];
}tAdcs;
void Adcs_Init(tAdcs *env);
void Adcs_UpdateTab(tAdcs *env);
#endif //CHARGER_ADCS_H

36
LOCAL/Inc/Gpios.h Normal file
View File

@ -0,0 +1,36 @@
#ifndef CHARGER_GPIOS_H
#define CHARGER_GPIOS_H
#include "ChargerConfig.h"
#include "GpioPinInterface.h"
///Пины включения зарядника
typedef struct {
tGpioPin tab[GPIOS_NUM];
}tChrgEnPins;
/// Пины включения батареи в цепь
typedef struct {
tGpioPin tab[GPIOS_NUM];
}tBatEnPins;
/// Пины индикации
typedef struct {
tGpioPin tab[GPIOS_NUM];
}tLedPins;
/// Пин RE DE RS485
typedef struct {
tGpioPin reDePin;
}tRS485DirectionPins;
typedef struct {
tChrgEnPins chrgEnPins;
tBatEnPins batEnPins;
tLedPins ledPins;
tRS485DirectionPins directionPins;
}tGpios;
void Gpios_Init(tGpios *env);
#endif //CHARGER_GPIOS_H

52
LOCAL/Inc/Indication.h Normal file
View File

@ -0,0 +1,52 @@
//
// Created by villuton on 01.09.2025.
//
#ifndef CHARGER_INDICATION_H
#define CHARGER_INDICATION_H
#include "ChargerConfig.h"
#include "Gpios.h"
#include "cmsis_os2.h"
#include "FreeRTOS.h"
///Перечисление режимов индикации
typedef enum {
MOD_CH_STARTUP = 0,
MOD_CH_ERROR,
MOD_CH_OK,
MOD_CH_CHARGE,
} eIndicationMod;
typedef struct {
uint32_t timer;
uint32_t timeOn;
uint32_t timeOff;
bool pinFlag;
bool isPermanent;
} tMod;
typedef struct {
tMod mod[INDICATION_MOD_NUM];
uint32_t iterationMs;
tLedPins *ledPins;
uint8_t chanel[INDICATION_CHANEL_NUM];
struct {
osThreadId_t id;
uint32_t stack[128];
StaticTask_t controlBlock;
osThreadAttr_t attr;
} thread;
} tIndication;
void Indication_Init(tIndication *env,
tLedPins *ledPins);
void Indication_StartThread(tIndication *env);
void Indication_ChanelSetMode(tIndication *env,
eIndicationMod indicationMod,
eChargerChannels channel);
#endif //CHARGER_INDICATION_H

7
LOCAL/Inc/Main_Private.h Normal file
View File

@ -0,0 +1,7 @@
#ifndef CHARGER_MAIN_PRIVATE_H
#define CHARGER_MAIN_PRIVATE_H
#include "Main_env.h"
void Main_Processing(tMain *env);
#endif //CHARGER_MAIN_PRIVATE_H

8
LOCAL/Inc/Main_Thread.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef CHARGER_MAIN_THREAD_H
#define CHARGER_MAIN_THREAD_H
#include "Main_env.h"
void Main_StartThread(tMain *env);
void Main_InitThread(tMain *env);
#endif //CHARGER_MAIN_THREAD_H

35
LOCAL/Inc/Main_env.h Normal file
View File

@ -0,0 +1,35 @@
#ifndef CHARGER_MAIN_ENV_H
#define CHARGER_MAIN_ENV_H
#include "Adcs.h"
#include "Gpios.h"
#include "Indication.h"
#include "SerialPorts.h"
#include "DeviceStorage.h"
#include "StorageOnFlash.h"
#include "LoggerToSerialPort.h"
typedef struct {
tAdcs adcs;
tGpios gpios;
tIndication indication;
tSerialPorts *serialPorts;
tDeviceStorage storage;
tStorageOnFlash *flash;
tLoggerToSerialPort slog;
struct {
osThreadId_t id;
uint32_t stack[2048];
StaticTask_t controlBlock;
osThreadAttr_t attr;
} thread;
struct {
uint32_t timer;
bool check;
float chanel_value;
eChargerChannels currentChanel;
}processing;
}tMain;
#endif //CHARGER_MAIN_ENV_H

28
LOCAL/Inc/SerialPorts.h Normal file
View File

@ -0,0 +1,28 @@
#ifndef CHARGER_SERIALPORTS_H
#define CHARGER_SERIALPORTS_H
#include "SerialPortIO.h"
#include "SerialPortP2p.h"
#include "SerialPortArtery.h"
#include "SerialPortHalfDuplexIO.h"
#include "Gpios.h"
typedef struct {
///Последовательный порт командного интерфейса
tSerialPortArtery comint;
tSerialPortIO comint_IO;
///Полудуплексный интерфейс RS485
tSerialPortHalfDuplex comInt_HD;
tSerialPortIO comint_HD_IO;
///Виртуальный интерфейс
tSerialPortP2p cliVirtualPort;
tSerialPortIO cliVirtualInIo;
tSerialPortIO cliVirtualOutIo;
}tSerialPorts;
extern tSerialPorts SERIAL_PORTS;
void SerialPorts_Init(tRS485DirectionPins *directionPins);
#endif //CHARGER_SERIALPORTS_H

140
LOCAL/Src/Adcs.c Normal file
View File

@ -0,0 +1,140 @@
//
// Created by villuton on 25.08.2025.
//
#include <string.h>
#include "Adcs.h"
#include "at32f403a_407_gpio.h"
///Таблица значений ADC DMA
__IO uint16_t adc_ordinary_valuetab[ADCS_ADC_BUFF_SIZE] = {0};
__IO uint16_t dma_trans_complete_flag = 0;
/**
* @brief gpio configuration.
* @param none
* @retval none
*/
static void adc_gpio_config(void) {
gpio_init_type gpio_initstructure;
crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
gpio_default_para_init(&gpio_initstructure);
gpio_initstructure.gpio_mode = GPIO_MODE_ANALOG;
/// Инициализация пинов ADC GPIOA
gpio_initstructure.gpio_pins =
GPIO_PINS_0 | GPIO_PINS_1 | GPIO_PINS_2 | GPIO_PINS_3 |
GPIO_PINS_4 | GPIO_PINS_5 | GPIO_PINS_6 | GPIO_PINS_7;
gpio_init(GPIOA, &gpio_initstructure);
/// Инициализация пинов ADC GPIOB
gpio_initstructure.gpio_pins = GPIO_PINS_0 | GPIO_PINS_1;
gpio_init(GPIOB, &gpio_initstructure);
}
/**
* @brief dma configuration.
* @param none
* @retval none
*/
static void adc_dma_config(void) {
dma_init_type dma_init_struct;
crm_periph_clock_enable(ADCS_ADC_CRM_DMAx_PERIPH_CLOCK, TRUE);
nvic_irq_enable(ADCS_ADC_DMAx_Channelx_IRQn, 0, 0);
dma_reset(ADCS_ADC_DMAx_CHANNELx);
dma_default_para_init(&dma_init_struct);
dma_init_struct.buffer_size = ADCS_ADC_BUFF_SIZE;
dma_init_struct.direction = DMA_DIR_PERIPHERAL_TO_MEMORY;
dma_init_struct.memory_base_addr = (uint32_t) adc_ordinary_valuetab;
dma_init_struct.memory_data_width = DMA_MEMORY_DATA_WIDTH_HALFWORD;
dma_init_struct.memory_inc_enable = TRUE;
dma_init_struct.peripheral_base_addr = (uint32_t) &(ADCS_ADCx->odt);
dma_init_struct.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_HALFWORD;
dma_init_struct.peripheral_inc_enable = FALSE;
dma_init_struct.priority = DMA_PRIORITY_HIGH;
dma_init_struct.loop_mode_enable = TRUE;
dma_init(ADCS_ADC_DMAx_CHANNELx, &dma_init_struct);
dma_interrupt_enable(ADCS_ADC_DMAx_CHANNELx, DMA_FDT_INT, TRUE);
dma_channel_enable(ADCS_ADC_DMAx_CHANNELx, TRUE);
}
/**
* @brief adc channel configuration.
* @param none
* @retval none
*/
static void adc_channel_config(void) {
for (int i = ADC_CHANNEL_0; i <= ADC_CHANNEL_9; i++) {
adc_ordinary_channel_set(ADCS_ADCx, i, i + 1, ADC_SAMPLETIME_239_5);
}
/**
adc_ordinary_channel_set(ADCS_ADCx, ADC_CHANNEL_0, 1, ADC_SAMPLETIME_239_5);
adc_ordinary_channel_set(ADCS_ADCx, ADC_CHANNEL_1, 2, ADC_SAMPLETIME_239_5);
adc_ordinary_channel_set(ADCS_ADCx, ADC_CHANNEL_2, 3, ADC_SAMPLETIME_239_5);
adc_ordinary_channel_set(ADCS_ADCx, ADC_CHANNEL_3, 4, ADC_SAMPLETIME_239_5);
adc_ordinary_channel_set(ADCS_ADCx, ADC_CHANNEL_4, 5, ADC_SAMPLETIME_239_5);
adc_ordinary_channel_set(ADCS_ADCx, ADC_CHANNEL_5, 6, ADC_SAMPLETIME_239_5);
adc_ordinary_channel_set(ADCS_ADCx, ADC_CHANNEL_6, 7, ADC_SAMPLETIME_239_5);
adc_ordinary_channel_set(ADCS_ADCx, ADC_CHANNEL_7, 8, ADC_SAMPLETIME_239_5);
adc_ordinary_channel_set(ADCS_ADCx, ADC_CHANNEL_8, 9, ADC_SAMPLETIME_239_5);
adc_ordinary_channel_set(ADCS_ADCx, ADC_CHANNEL_9, 10, ADC_SAMPLETIME_239_5);
*/
}
/**
* @brief adc configuration.
* @param none
* @retval none
*/
static void adc_config(void) {
adc_base_config_type adc_base_struct;
crm_periph_clock_enable(ADCS_CRM_ADCx_PERIPH_CLOCK, TRUE);
crm_adc_clock_div_set(CRM_ADC_DIV_6);
/* select combine mode */
adc_combine_mode_select(ADC_INDEPENDENT_MODE);
adc_base_default_para_init(&adc_base_struct);
adc_base_struct.sequence_mode = TRUE;
adc_base_struct.repeat_mode = TRUE;
adc_base_struct.data_align = ADC_RIGHT_ALIGNMENT;
adc_base_struct.ordinary_channel_length = ADCS_ADC_BUFF_SIZE;
adc_base_config(ADCS_ADCx, &adc_base_struct);
adc_channel_config();
adc_ordinary_conversion_trigger_set(
ADCS_ADCx,
ADCS_ADCx_ORDINARY_TRIG_SOFTWARE,
TRUE);
adc_dma_mode_enable(ADCS_ADCx, TRUE);
adc_enable(ADCS_ADCx, TRUE);
adc_calibration_init(ADCS_ADCx);
while (adc_calibration_init_status_get(ADCS_ADCx));
adc_calibration_start(ADCS_ADCx);
while (adc_calibration_status_get(ADCS_ADCx));
}
/**
* Инициализация ADC
* @param *env tAdcs
*/
void Adcs_Init(tAdcs *env) {
adc_gpio_config();
adc_dma_config();
adc_config();
memset(env->tab, 0, ADCS_ADC_BUFF_SIZE);
}
/**
* Обновление таблицы значений каналов ADC
* @param env
*/
void Adcs_UpdateTab(tAdcs *env) {
memcpy(env->tab, (void *) adc_ordinary_valuetab, ADCS_ADC_BUFF_SIZE);
}

95
LOCAL/Src/Gpios.c Normal file
View File

@ -0,0 +1,95 @@
//
// Created by villuton on 25.08.2025.
//
#include "Gpios.h"
#include "GpioPin.h"
#define GCHRG_PIN_MODE GPIO_MODE_OUTPUT
#define GCHRG_PIN_REV GPIO_PIN_NOREVERSE
/**
* Инициализация пинов включения микросхем зарядника
* @param env
*/
static void gpios_chrg(tChrgEnPins *env) {
///GPIOB
env->tab[CHRG_Ch1] = InitGpioPin(GPIOB, GPIO_PINS_2, GCHRG_PIN_MODE, GCHRG_PIN_REV);
env->tab[CHRG_Ch2] = InitGpioPin(GPIOB, GPIO_PINS_3, GCHRG_PIN_MODE, GCHRG_PIN_REV);
env->tab[CHRG_Ch3] = InitGpioPin(GPIOB, GPIO_PINS_4, GCHRG_PIN_MODE, GCHRG_PIN_REV);
env->tab[CHRG_Ch4] = InitGpioPin(GPIOB, GPIO_PINS_5, GCHRG_PIN_MODE, GCHRG_PIN_REV);
env->tab[CHRG_Ch5] = InitGpioPin(GPIOB, GPIO_PINS_6, GCHRG_PIN_MODE, GCHRG_PIN_REV);
env->tab[CHRG_Ch6] = InitGpioPin(GPIOB, GPIO_PINS_7, GCHRG_PIN_MODE, GCHRG_PIN_REV);
env->tab[CHRG_Ch7] = InitGpioPin(GPIOB, GPIO_PINS_8, GCHRG_PIN_MODE, GCHRG_PIN_REV);
env->tab[CHRG_Ch8] = InitGpioPin(GPIOB, GPIO_PINS_9, GCHRG_PIN_MODE, GCHRG_PIN_REV);
env->tab[CHRG_Ch9] = InitGpioPin(GPIOB, GPIO_PINS_10, GCHRG_PIN_MODE, GCHRG_PIN_REV);
env->tab[CHRG_Ch10] = InitGpioPin(GPIOB, GPIO_PINS_11, GCHRG_PIN_MODE, GCHRG_PIN_REV);
}
#define GBAT_PIN_MODE GPIO_MODE_OUTPUT
#define GBAT_PIN_REV GPIO_PIN_NOREVERSE
/**
* Инициализация пинов включения батареи в цепь
* @param env
*/
static void gpios_bat(tBatEnPins *env) {
///GPIOB
env->tab[CHRG_Ch1] = InitGpioPin(GPIOB, GPIO_PINS_12, GBAT_PIN_MODE, GBAT_PIN_REV);
env->tab[CHRG_Ch2] = InitGpioPin(GPIOB, GPIO_PINS_13, GBAT_PIN_MODE, GBAT_PIN_REV);
env->tab[CHRG_Ch3] = InitGpioPin(GPIOB, GPIO_PINS_14, GBAT_PIN_MODE, GBAT_PIN_REV);
env->tab[CHRG_Ch4] = InitGpioPin(GPIOB, GPIO_PINS_15, GBAT_PIN_MODE, GBAT_PIN_REV);
///GPIOC
env->tab[CHRG_Ch5] = InitGpioPin(GPIOC, GPIO_PINS_0, GBAT_PIN_MODE, GBAT_PIN_REV);
env->tab[CHRG_Ch6] = InitGpioPin(GPIOC, GPIO_PINS_1, GBAT_PIN_MODE, GBAT_PIN_REV);
env->tab[CHRG_Ch7] = InitGpioPin(GPIOC, GPIO_PINS_2, GBAT_PIN_MODE, GBAT_PIN_REV);
env->tab[CHRG_Ch8] = InitGpioPin(GPIOC, GPIO_PINS_3, GBAT_PIN_MODE, GBAT_PIN_REV);
env->tab[CHRG_Ch9] = InitGpioPin(GPIOC, GPIO_PINS_4, GBAT_PIN_MODE, GBAT_PIN_REV);
env->tab[CHRG_Ch10] = InitGpioPin(GPIOC, GPIO_PINS_5, GBAT_PIN_MODE, GBAT_PIN_REV);
}
#define GLED_PIN_MODE GPIO_MODE_OUTPUT
#define GLED_PIN_REV GPIO_PIN_NOREVERSE
/**
* Инициализация светодиодов
* @param env
*/
static void gpios_led(tLedPins *env) {
///GPIOC
env->tab[CHRG_Ch1] = InitGpioPin(GPIOC, GPIO_PINS_6, GLED_PIN_MODE, GLED_PIN_REV);
env->tab[CHRG_Ch2] = InitGpioPin(GPIOC, GPIO_PINS_7, GLED_PIN_MODE, GLED_PIN_REV);
env->tab[CHRG_Ch3] = InitGpioPin(GPIOC, GPIO_PINS_8, GLED_PIN_MODE, GLED_PIN_REV);
env->tab[CHRG_Ch4] = InitGpioPin(GPIOC, GPIO_PINS_9, GLED_PIN_MODE, GLED_PIN_REV);
env->tab[CHRG_Ch5] = InitGpioPin(GPIOC, GPIO_PINS_10, GLED_PIN_MODE, GLED_PIN_REV);
env->tab[CHRG_Ch6] = InitGpioPin(GPIOC, GPIO_PINS_11, GLED_PIN_MODE, GLED_PIN_REV);
env->tab[CHRG_Ch7] = InitGpioPin(GPIOC, GPIO_PINS_12, GLED_PIN_MODE, GLED_PIN_REV);
env->tab[CHRG_Ch8] = InitGpioPin(GPIOC, GPIO_PINS_13, GLED_PIN_MODE, GLED_PIN_REV);
///GPIOA
env->tab[CHRG_Ch9] = InitGpioPin(GPIOA, GPIO_PINS_11, GLED_PIN_MODE, GLED_PIN_REV);
env->tab[CHRG_Ch10] = InitGpioPin(GPIOA, GPIO_PINS_12, GLED_PIN_MODE, GLED_PIN_REV);
}
#define GRE_DE_PIN_MODE GPIO_MODE_OUTPUT
#define GRE_DE_PIN_REV GPIO_PIN_NOREVERSE
/**
* Инициализация пина RE/DE RS485
* @param env
*/
static void gpios_rs485(tRS485DirectionPins *env) {
env->reDePin = InitGpioPin(GPIOA, GPIO_PINS_8, GRE_DE_PIN_MODE, GRE_DE_PIN_REV);
}
/**
* Инициализация GPIOS
* @param *env tGpios
*/
void Gpios_Init(tGpios *env) {
gpios_chrg(&env->chrgEnPins);
gpios_bat(&env->batEnPins);
gpios_led(&env->ledPins);
gpios_rs485(&env->directionPins);
}

115
LOCAL/Src/Indication.c Normal file
View File

@ -0,0 +1,115 @@
//
// Created by villuton on 01.09.2025.
//
#include "Indication.h"
#include "SystemDelayInterface.h"
/**
* Инициализация паттерна индикации
* В случае, если режим предполагает постоянное положения пина индикации
* Выставляется флаг permanent и большее время для соответствующего состояния
* @param *ptr tMod
* @param timeOn uint32_t Время включенного состояния
* @param timeOff uint32_t Время выключенного состояния
* @param permanent bool Флаг неизменяемости состояния
*/
static void lIndication_ModInit(tMod *ptr, uint32_t timeOn, uint32_t timeOff, bool permanent) {
ptr->timer = 0;
ptr->timeOn = timeOn;
ptr->timeOff = timeOff;
ptr->isPermanent = permanent;
ptr->pinFlag = false;
if (permanent != false) {
if (timeOn > timeOff) {
ptr->pinFlag = true;
} else {
ptr->pinFlag = false;
}
}
}
/**
* Функция индикации светодиода, в соответствии с каналом,
* выставленном на нем режимом и таймером индикации
* @param *ptr tMod
* @param iterationMs uint32_t
* @param *ledPin tGpioPin
*/
static void lIndication_ModSet(tMod *ptr, uint32_t iterationMs, tGpioPin *ledPin) {
///Если установлен перманентный режим работы
if (ptr->isPermanent) {
GpioPinSet(ledPin, ptr->pinFlag);
return;
}
///Если таймер истек
///Изменить флаг, выставляемый на пин светодиода
///Переустановить таймер, в зависимости от предыдущего установленного таймера
if (ptr->timer < iterationMs) {
ptr->pinFlag = !ptr->pinFlag;
ptr->timer = ptr->pinFlag != false ? ptr->timer = iterationMs + ptr->timeOn : iterationMs + ptr->timeOff;
}
///Если вышеперечисленные условия не выполнились, выставить пин светодиода, в соответствии с флагом
GpioPinSet(ledPin, ptr->pinFlag);
}
/**
* Функция потока индикации
* @param *env tIndication
*/
static _Noreturn void Indication_Thread(tIndication *env) {
for (;;) {
env->iterationMs = SystemGetMs();
for (uint8_t i = CHRG_Ch1; i <= INDICATION_CHANEL_NUM; i++) {
lIndication_ModSet(&env->mod[env->chanel[i]], env->iterationMs, &env->ledPins->tab[i]);
}
SystemDelayMs(INDICATION_THREAD_DELAY_MS);
}
}
/**
* Инициализация модуля индикации
* @param *env tIndication
* @param *ledPins tLedPins
*/
void Indication_Init(tIndication *env,
tLedPins *ledPins) {
env->ledPins = ledPins;
for (uint8_t i = 0; i <= INDICATION_CHANEL_NUM; i++) {
env->chanel[i] = MOD_CH_STARTUP;
}
lIndication_ModInit(&env->mod[MOD_CH_STARTUP], 500, 100, false);
lIndication_ModInit(&env->mod[MOD_CH_ERROR], 200, 200, false);
lIndication_ModInit(&env->mod[MOD_CH_OK], 0, 999, true);
lIndication_ModInit(&env->mod[MOD_CH_CHARGE], 999, 0, true);
}
/**
* Запуск потока индикации
* @param *env tIndication
*/
void Indication_StartThread(tIndication *env) {
if (!env->thread.id) {
env->thread.id = osThreadNew((osThreadFunc_t) (Indication_Thread), (void *) (env), &env->thread.attr);
} else {
osThreadResume(env->thread.id);
}
}
/**
* Изменения режима индикации канала
* @param *env tIndication
* @param indicationMod eIndicationMod
* @param channel eChargerChannels
*/
void Indication_ChanelSetMode(tIndication *env,
eIndicationMod indicationMod,
eChargerChannels channel) {
env->chanel[channel] = indicationMod;
}

29
LOCAL/Src/Main_Init.c Normal file
View File

@ -0,0 +1,29 @@
//
// Created by villuton on 16.09.2025.
//
#include "Main_Private.h"
#include "Main_Thread.h"
#include "CmsisRtosThreadUtils.h"
#include "LoggerToSerialPort.h"
tMain env;
static void Main_PreInit (void){
//Передача указателей структур в env
env.serialPorts = &SERIAL_PORTS;
env.flash = &NVM_STORAGE;
//Инициализация внешних интерфесов
Gpios_Init(&env.gpios);
Adcs_Init(&env.adcs);
SerialPorts_Init(&env.gpios.directionPins);
// Инициализация потока MAIN
Main_InitThread(&env);
}
void MAIN_INIT(void){
Main_PreInit();
}
void MAIN_START(void){
Main_StartThread(&env);
}

177
LOCAL/Src/Main_Processing.c Normal file
View File

@ -0,0 +1,177 @@
//
// Created by villuton on 17.09.2025.
//
#include <stdio.h>
#include "Main_Private.h"
#define STORAGE_DEVICE(VAR) env->storage.nvm.device.VAR
#define ADC(CH) env->adcs.tab[CH]
#define INDICATION(CH) env->indication.chanel[CH]
#define LOGGER &env->slog.logger
#define LOG_SIGN "Main_Processing"
/**
* Установка пина зарядника по каналу
* @param env
* @param chanel
* @param value
*/
void ChargerChanelSet(tMain *env, uint8_t chanel, bool value){
GpioPinSet(&env->gpios.chrgEnPins.tab[chanel], value);
}
/**
* Установка пина включения акб в цепь по каналу
* @param env
* @param chanel
* @param value
*/
void BatteryChanelSet(tMain *env, uint8_t chanel, bool value){
GpioPinSet(&env->gpios.batEnPins.tab[chanel], value);
}
/**
* Процедура установки положения пинов,
* в зависимости от того, идет сейчас проверка напряжения акб или нет
* @param env
* @param chanel
* @param check
*/
void SetPinsModeCheck(tMain *env, uint8_t chanel, bool check){
if(check == false){
ChargerChanelSet(env,chanel,true);
BatteryChanelSet(env,chanel,true);
}
else{
ChargerChanelSet(env,chanel,false);
BatteryChanelSet(env,chanel,true);
}
}
/**
* Процедура приведения данных АЦП к напряжению
* С поправкой либо на делитель, либо на калибровочный коэффициент
* @param env
* @param chanel
* @return
*/
#undef LOG_SIGN
#define LOG_SIGN "AdcToVoltage"
static float AdcToVoltage(tMain *env, uint8_t chanel){
if(STORAGE_DEVICE(chanelCalibrationFactor[chanel]) != STORAGE_CALIBRATION_FACTOR_DEFAULT){
/// Расчет через калибровочный параметр
LoggerTraceStatic(LOGGER, LOG_SIGN, "Calculation via calibration parameter")
return (float ) ADC(chanel) *
STORAGE_DEVICE(chanelCalibrationFactor[chanel]);
}
/// Расчет через коэффициент делителя
LoggerTraceStatic(LOGGER, LOG_SIGN, "Calculation using the divisor coefficient")
return (float ) ADC(chanel) *
(STORAGE_V_ADC_THRESHOLD / STORAGE_ADC_THRESHOLD) *
STORAGE_DEVICE(dividerRatio);
}
/**
* Процедура обработки переходов режимов
* в зависимости от значений считанного напряжения
* @param env
* @param value
* @param isCheck
* @return
*/
static eIndicationMod AdcChanelModeProcessing(tMain *env,float value, bool isCheck){
if(value <= STORAGE_DEVICE(voltageBatteryConnectThreshold)){
LoggerTraceStatic(LOGGER, LOG_SIGN, "The voltage is lower Battery Connect Threshold")
LoggerTraceStatic(LOGGER, LOG_SIGN, "Set mode STARTUP")
return MOD_CH_STARTUP;
}
if(value <= STORAGE_DEVICE(voltageBatteryLoadedThreshold)){
LoggerTraceStatic(LOGGER, LOG_SIGN, "The voltage is lower Battery Loader Threshold")
LoggerTraceStatic(LOGGER, LOG_SIGN, "Set mode CHARGE")
return MOD_CH_CHARGE;
}
if(value > STORAGE_DEVICE(voltageBatteryLoadedThreshold)){
LoggerTraceStatic(LOGGER, LOG_SIGN, "The voltage is higher Battery Loader Threshold")
if(isCheck != false){
LoggerTraceStatic(LOGGER, LOG_SIGN, "Is check time")
LoggerTraceStatic(LOGGER, LOG_SIGN, "Set mode OK")
return MOD_CH_OK;
} else{
LoggerTraceStatic(LOGGER, LOG_SIGN, "Is not check time")
LoggerTraceStatic(LOGGER, LOG_SIGN, "Set mode CHARGE")
return MOD_CH_CHARGE;
}
}
return MOD_CH_ERROR;
}
/**
* Процедура Обработчика данным с АЦП, включения/отключения зарядки и выставление режимов индикации
* @param env
*/
#undef LOG_SIGN
#define LOG_SIGN "Main_Processing"
void Main_Processing(tMain *env){
///Обновление таблицы данных каналов АЦП
LoggerTraceStatic(LOGGER, LOG_SIGN, "Updating the ADC channel data table")
Adcs_UpdateTab(&env->adcs);
///Проходимся в цикле по всем каналам
for (int chanel = CHRG_Ch1; chanel < CHARGER_CH_NUM; chanel++) {
env->processing.currentChanel = chanel;
char msd_buff[30] = {0};
sprintf(msd_buff,"Current Chanel: %d \n\r", chanel+1);
LoggerCnTrace(LOGGER, LOG_SIGN, msd_buff, sizeof(msd_buff))
switch (INDICATION(chanel)) {
/**
* В режиме стартапа предполагаем, что ожидаем подключения аккумулятора
* Зарядник отключен, режим постоянной проверки
*/
case MOD_CH_STARTUP:
LoggerTraceStatic(LOGGER, LOG_SIGN, "Current mod STARTUP")
SetPinsModeCheck(env,chanel,true);
INDICATION(chanel) = AdcChanelModeProcessing(env,AdcToVoltage(env, chanel), true);
/**
* В режиме зарядника возможен переход в любое из состояний, но переход в состояние "Заряжен"
* Возможен только при флаге check = true
*/
case MOD_CH_CHARGE:
LoggerTraceStatic(LOGGER, LOG_SIGN, "Current mod CHARGE")
SetPinsModeCheck(env,chanel,env->processing.check);
INDICATION(chanel) = AdcChanelModeProcessing(env,AdcToVoltage(env, chanel), env->processing.check);
/**
* Это режим состояния, говорящий, что АКБ заряжен
*/
case MOD_CH_OK:
LoggerTraceStatic(LOGGER, LOG_SIGN, "Current mod OK")
SetPinsModeCheck(env,chanel,true);
INDICATION(chanel) = AdcChanelModeProcessing(env,AdcToVoltage(env, chanel), true);
/**
* Режим ошибки, по факту сейчас не используется
*/
case MOD_CH_ERROR:
LoggerTraceStatic(LOGGER, LOG_SIGN, "Current mod ERROR")
ChargerChanelSet(env,chanel,false);
BatteryChanelSet(env,chanel,false);
default:
break;
}
}
/// Переустановка таймера и флага для отключения зарядника и проверки на заряд
if(env->processing.timer < SystemGetMs()){
LoggerTraceStatic(LOGGER, LOG_SIGN, "Timer update")
env->processing.timer = SystemGetMs() + env->processing.check != false?
STORAGE_CHARGE_TIME :
STORAGE_VERIFICATION_TIME;
env->processing.check = !env->processing.check;
}
}

84
LOCAL/Src/Main_Thread.c Normal file
View File

@ -0,0 +1,84 @@
#include "Main_Thread.h"
#include "Main_Private.h"
#include "CmsisRtosThreadUtils.h"
#define LOGGER &env->slog.logger
#define LOG_SIGN "Main"
/**
* Процедура инициализации и запуска подсистем
* Логирование, хранилище, командный интерфейс
* @param env
*/
#undef LOG_SIGN
#define LOG_SIGN "Main_ISS"
static void MainThread_InitSubSystems(tMain *env){
/// Инициализация Логирования
LoggerToSerialPort_Init(
&env->slog,
0,
&SERIAL_PORTS.comint_IO, //Пока нет платы с 485
//&SERIAL_PORTS.comint_HD_IO, //485
NULL,
SERIAL_LOGGER_SHOW_AUTHOR | SERIAL_LOGGER_SHOW_LOG_LEVEL
);
LoggerInfoStatic(LOGGER, LOG_SIGN, "Start Logging")
/// Инициализация Индикации
Indication_Init(&env->indication,&env->gpios.ledPins);
LoggerInfoStatic(LOGGER, LOG_SIGN, "Indication Init Completed")
/// Передача интерфейса логирования в хранилище
env->storage.logger = &env->slog.logger;
/// Инициализация хранилища
StorageOnFlash_Init();
if(DeviceStorage_Init(&env->storage, &env->flash->interface) == false){
LoggerErrorStatic(LOGGER, LOG_SIGN, "Storage Init Error")
} else {
LoggerInfoStatic(LOGGER, LOG_SIGN, "Storage Init Completed")
}
/// Запуск потока дампера
VarsTabDumpObserver_StartThread(&env->storage.dumpObserver);
/// Запуск потока индикации
Indication_StartThread(&env->indication);
}
/**
* Процедура Потока MAIN
* @param env
*/
#undef LOG_SIGN
#define LOG_SIGN "Main_Thread"
_Noreturn void Main_Thread(tMain *env) {
MainThread_InitSubSystems(env);
LoggerInfoStatic(LOGGER, LOG_SIGN, "Start main loop")
while (1){
///Вызов процедуры обработчика
Main_Processing(env);
SystemDelayMs(MAIN_THREAD_DELAY_MS);
}
}
/**
* Процедура вызова запуска потока MAIN
* @param env
*/
void Main_StartThread(tMain *env){
if (!env->thread.id) {
env->thread.id = osThreadNew((osThreadFunc_t) (Main_Thread), (void *) (env), &env->thread.attr);
} else {
osThreadResume(env->thread.id);
}
}
/**
* Процедура инициализации потока MAIN
* @param env
*/
void Main_InitThread(tMain *env){
InitThreadAtrStatic(&env->thread.attr, "MAIN", env->thread.controlBlock, env->thread.stack, osPriorityNormal);
env->thread.id = 0;
}

109
LOCAL/Src/SerialPorts.c Normal file
View File

@ -0,0 +1,109 @@
//
// Created by villuton on 26.08.2025.
//
#include "SerialPorts.h"
#include "at32f403a_407.h"
tSerialPorts SERIAL_PORTS;
///начало----------------------------------Командный интерфейс----------------------------------------------------------
///начало----------------------------------Командный интерфейс----------------------------------------------------------
///начало----------------------------------Командный интерфейс----------------------------------------------------------
///Буфер порта
uint8_t buf_USART1_DMA[1024];
/// IDLE прерывание
void USART1_IRQHandler() {
// Смотрим idle прерывание
if (usart_flag_get(SERIAL_PORTS.comint.uart, USART_IDLEF_FLAG)) {
// Сброс прерывания
usart_data_receive(SERIAL_PORTS.comint.uart);
vSerialPortIrqProcessingDMAloop(&SERIAL_PORTS.comint, SERIAL_PORTS.comint.dma_init_struct.buffer_size -
SERIAL_PORTS.comint.dma_channel->dtcnt);
}
}
/// RX
void DMA1_Channel3_IRQHandler(void) {
if (dma_flag_get(DMA1_FDT3_FLAG)) {
vSerialPortIrqProcessingDMAloop(&SERIAL_PORTS.comint,
SERIAL_PORTS.comint.dma_init_struct.buffer_size);
SERIAL_PORTS.comint.offset = 0;
dma_flag_clear(DMA1_FDT3_FLAG);
}
}
/// TX
void DMA1_Channel4_IRQHandler(void) {
if (dma_flag_get(DMA1_FDT4_FLAG)) {
dma_flag_clear(DMA1_FDT4_FLAG);
}
}
/// Настройка порта
static void vSerialPort_InitUSART1(tSerialPortArtery *env) {
gpio_init_type GPIO_InitStruct;
gpio_default_para_init(&GPIO_InitStruct);
GPIO_InitStruct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
GPIO_InitStruct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
GPIO_InitStruct.gpio_mode = GPIO_MODE_MUX;
GPIO_InitStruct.gpio_pins = GPIO_PINS_9 | GPIO_PINS_10;
GPIO_InitStruct.gpio_pull = GPIO_PULL_NONE;
gpio_init(GPIOA, &GPIO_InitStruct);
vSerialPortInitDMA(env,
USART1,
DMA1,
DMA1_CHANNEL3,
FLEX_CHANNEL3,
DMA_FLEXIBLE_UART1_RX,
buf_USART1_DMA,
sizeof(buf_USART1_DMA),
DMA1_Channel3_IRQn,
false,
115200,
USART1_IRQn,
CRM_USART1_PERIPH_CLOCK,
0x59,
1024,
0
);
}
///конец-----------------------------------Командный интерфейс----------------------------------------------------------
///конец-----------------------------------Командный интерфейс----------------------------------------------------------
///конец-----------------------------------Командный интерфейс----------------------------------------------------------
/**
* Инициализация серийного порта, RS485
* @param *directionPins tRS485DirectionPins
*/
void SerialPorts_Init(tRS485DirectionPins *directionPins) {
tSerialPorts *env = &SERIAL_PORTS;
/// USART1 КОМАНДНЫЙ ИНТЕРФЕЙС
vSerialPort_InitUSART1(&env->comint);
SERIAL_PORTS.comint_IO = vSerialPortGetIo(&SERIAL_PORTS.comint);
/// Полудуплекс RS485
SERIAL_PORTS.comInt_HD = vSerialPortHalfDuplexInit(&SERIAL_PORTS.comint_IO,
&directionPins->reDePin,
&directionPins->reDePin);
SERIAL_PORTS.comint_HD_IO = vSerialPortHalfDuplexGetIo(&SERIAL_PORTS.comInt_HD);
/// TODO Удалить виртуальные порты, если не будет сервисной программы
/// Виртуальные порты для сервисной программы (потенциально)
SerialPortP2p_Init(&env->cliVirtualPort, 1 * 1024, 1024);
env->cliVirtualInIo = SerialPortP2p_GetIoFirst(&env->cliVirtualPort);
env->cliVirtualOutIo = SerialPortP2p_GetIoSecond(&env->cliVirtualPort);
}

View File

@ -0,0 +1,48 @@
//
// Created by villuton on 16.09.2025.
//
#ifndef CHARGER_DATAFLASH_H
#define CHARGER_DATAFLASH_H
#include "ChargerConfig.h"
#include <VariablesTable.h>
#include "BaseTypes/Strings.h"
#define DEVICE_DATA_NO_VOLATILE_VERSION 0x10
typedef struct {
struct {
tString16 value;
uint16_t writeAccess;
} serialNumber;
/// Значение напряжения, подаваемого на вход АКБ в момент калибровки канала
float vReference;
/// Массив калибровочных коэффициентов ждя расчета напряжения на канале
float chanelCalibrationFactor[STORAGE_CALIB_CHANEL_NUM];
/// Коэффициент соотношения делителя напряжения,
/// в случае, если калибровочного значения для канала нет, расчет ведется по нему
float dividerRatio;
/// Порог напряжения, при котором мы считаем, что аккумулятор отключен
float voltageBatteryConnectThreshold;
/// Порог напряжения, при котором мы считаем, что аккумулятор заряжен
float voltageBatteryLoadedThreshold;
} tDeviceSettings;
typedef struct {
uint32_t version;
tDeviceSettings device;
} tDeviceDataNonVolatile;
void DeviceDataNonVolatile_InitDefaults(tDeviceDataNonVolatile *env);
void DataFlash_AddToVarTab(
tDeviceDataNonVolatile *env,
tVariablesTable *variablesTable,
uint32_t group
);
#endif //CHARGER_DATAFLASH_H

View File

@ -0,0 +1,12 @@
//
// Created by villuton on 16.09.2025.
//
#ifndef CHARGER_DATAFLASHPRIVATE_H
#define CHARGER_DATAFLASHPRIVATE_H
#include "DataFlash.h"
void DeviceStorageInitDeviceSettings(tDeviceSettings *env);
#endif //CHARGER_DATAFLASHPRIVATE_H

View File

@ -0,0 +1,25 @@
//
// Created by villuton on 16.09.2025.
//
#ifndef CHARGER_DATARUNTIME_H
#define CHARGER_DATARUNTIME_H
#include <BaseTypes.h>
#include <stdbool.h>
#include <VariablesTable.h>
typedef struct {
uint16_t disallowWrite;
bool debugMode;
bool calibration;
} tDeviceDataRuntime;
void DataRuntime_InitDefaults(tDeviceDataRuntime *env);
void DataRuntime_AddToVarTab(
tDeviceDataRuntime *env,
tVariablesTable *variablesTable,
uint32_t VARIABLES_GROUP
);
#endif //CHARGER_DATARUNTIME_H

View File

@ -0,0 +1,35 @@
//
// Created by villuton on 16.09.2025.
//
#ifndef CHARGER_DEVICESTORAGE_H
#define CHARGER_DEVICESTORAGE_H
#include "DataFlash.h"
#include "DataRuntime.h"
#include "VarsTabDumpObserver.h"
typedef struct {
tLoggerInterface *logger;
tDeviceDataRuntime runtime;
tDeviceDataNonVolatile nvm;
tVariablesTable publicVariablesTable;
tVarsTabDumpObserver dumpObserver;
struct {
tVariableDescriptor vartab[64];
} mem;
} tDeviceStorage;
bool DeviceStorage_Init(tDeviceStorage *env, tStorageInterface *storageInterface);
//использоввать только для отладки
void DeviceStorage_InitDefaults(tDeviceStorage *env);
void DeviceStorage_ForceDump(tDeviceStorage *env);
#endif //CHARGER_DEVICESTORAGE_H

View File

@ -0,0 +1,20 @@
//
// Created by villuton on 16.09.2025.
//
#ifndef CHARGER_STORAGEONFLASH_H
#define CHARGER_STORAGEONFLASH_H
#include "StorageOnFlashArtery.h"
typedef struct {
tStorageOnFlashArtery nf_storage;
tStorageInterface interface;
} tStorageOnFlash;
extern tStorageOnFlash NVM_STORAGE;
void StorageOnFlash_Init();
#endif //CHARGER_STORAGEONFLASH_H

View File

@ -0,0 +1,14 @@
//
// Created by villuton on 16.09.2025.
//
#include "DataFlashPrivate.h"
void DeviceDataNonVolatile_InitDefaults(tDeviceDataNonVolatile *env) {
DeviceStorageInitDeviceSettings(&env->device);
//проверка соответствия версии хранилища
//позволяет принудительно сбросить хранилище
//к значениям по умолчанию вслучае установки
//значения большее чем в придыдущих прошивках
env->version = DEVICE_DATA_NO_VOLATILE_VERSION;
}

View File

@ -0,0 +1,53 @@
//
// Created by villuton on 16.09.2025.
//
#include "DataFlashPrivate.h"
#define ADD_VAR_SIZE(TYPE, NAME, VALUE, LEN, GROUP) \
VariablesTableAdd( \
variablesTable, \
#NAME, \
sizeof (#NAME)-1, \
VARIABLE_TYPE_##TYPE, \
(VALUE), \
(LEN), \
0, \
GROUP \
)
#define ADD_VAR(TYPE, NAME, VALUE) ADD_VAR_SIZE(TYPE, NAME, VALUE, 0, group)
#define ADD_VAR_STR_OBJ(TYPE, NAME, VALUE) ADD_VAR_SIZE(TYPE, NAME, &(VALUE).data, &(VALUE).length,group)
// Добавление переменных в таблицу
void DataFlash_AddToVarTab(
tDeviceDataNonVolatile *env,
tVariablesTable *variablesTable,
uint32_t group
) {
//Devices
ADD_VAR_STR_OBJ(STRING, DEVICE_ID, env->device.serialNumber.value);
VariablesTable_GetLast(variablesTable)->writeAttempts = &env->device.serialNumber.writeAccess;
ADD_VAR(FLOAT32, VOLTAGE_REFERENCE, &env->device.vReference);
ADD_VAR(FLOAT32, DEVIDER_RATIO, &env->device.dividerRatio);
ADD_VAR(FLOAT32, VOLTAGE_BAT_CONNECT, &env->device.voltageBatteryConnectThreshold);
ADD_VAR(FLOAT32, VOLTAGE_BAT_LOADED, &env->device.voltageBatteryLoadedThreshold);
ADD_VAR(FLOAT32, CALIBRAION_FACTOR_CH1, &env->device.chanelCalibrationFactor[CHRG_Ch1]);
ADD_VAR(FLOAT32, CALIBRAION_FACTOR_CH2, &env->device.chanelCalibrationFactor[CHRG_Ch2]);
ADD_VAR(FLOAT32, CALIBRAION_FACTOR_CH3, &env->device.chanelCalibrationFactor[CHRG_Ch3]);
ADD_VAR(FLOAT32, CALIBRAION_FACTOR_CH4, &env->device.chanelCalibrationFactor[CHRG_Ch4]);
ADD_VAR(FLOAT32, CALIBRAION_FACTOR_CH5, &env->device.chanelCalibrationFactor[CHRG_Ch5]);
ADD_VAR(FLOAT32, CALIBRAION_FACTOR_CH6, &env->device.chanelCalibrationFactor[CHRG_Ch6]);
ADD_VAR(FLOAT32, CALIBRAION_FACTOR_CH7, &env->device.chanelCalibrationFactor[CHRG_Ch7]);
ADD_VAR(FLOAT32, CALIBRAION_FACTOR_CH8, &env->device.chanelCalibrationFactor[CHRG_Ch8]);
ADD_VAR(FLOAT32, CALIBRAION_FACTOR_CH9, &env->device.chanelCalibrationFactor[CHRG_Ch9]);
ADD_VAR(FLOAT32, CALIBRAION_FACTOR_CH10, &env->device.chanelCalibrationFactor[CHRG_Ch10]);
}
#undef ADD_VAR_SIZE
#undef ADD_VAR
#undef ADD_VAR_STR_OBJ

View File

@ -0,0 +1,47 @@
//
// Created by villuton on 16.09.2025.
//
//
// Created by ilya on 18.10.23.
//
#include "DataRuntime.h"
#include "FirmwareMetadataSection.h"
void DataRuntime_InitDefaults(tDeviceDataRuntime *env) {
env->debugMode = false;
env->calibration = false;
env->disallowWrite = 0;
}
#define ADD_VAR_SIZE(TYPE, NAME, VALUE, LEN, GROUP) \
VariablesTableAdd( \
variablesTable, \
#NAME, \
sizeof (#NAME)-1, \
VARIABLE_TYPE_##TYPE, \
(VALUE), \
(LEN), \
0, \
GROUP \
)
#define ADD_VAR(TYPE, NAME, VALUE) ADD_VAR_SIZE(TYPE, NAME, VALUE, 0, VARIABLES_GROUP)
#define ADD_VAR_STR_OBJ(TYPE, NAME, VALUE) ADD_VAR_SIZE(TYPE, NAME, &(VALUE).data, &(VALUE).length,VARIABLES_GROUP)
// Добавление переменных в таблицу
void DataRuntime_AddToVarTab(
tDeviceDataRuntime *env,
tVariablesTable *variablesTable,
uint32_t VARIABLES_GROUP
) {
ADD_VAR(BOOL, DEBUG_MODE, &env->debugMode);
ADD_VAR(BOOL, DEBUG_MODE, &env->calibration);
VariablesTable_GetLast(variablesTable)->writeAttempts = &env->disallowWrite;
}
#undef ADD_VAR_SIZE
#undef ADD_VAR
#undef ADD_VAR_STR_OBJ

View File

@ -0,0 +1,73 @@
//
// Created by villuton on 16.09.2025.
//
#include "DeviceStorage.h"
//
// Created by ilya on 18.10.23.
//
#include <CmsisRtosThreadUtils.h>
#include "DeviceStorage.h"
#include "VersionRandID.h"
#define LOGGER env->logger
#define LOG_SIGN "Хран."
#define VARIABLE_GROUP_UNTRACKED 0
#define VARIABLE_GROUP_FLASH (1 << 0)
void DeviceStorage_InitVariablesTable(tDeviceStorage *env) {
VariablesTableInitStatic(&env->publicVariablesTable, env->mem.vartab);
DataRuntime_InitDefaults(&env->runtime);
DataFlash_AddToVarTab(&env->nvm, &env->publicVariablesTable, VARIABLE_GROUP_FLASH);
DataRuntime_AddToVarTab(&env->runtime, &env->publicVariablesTable, VARIABLE_GROUP_UNTRACKED);
}
bool DeviceStorage_LoadNonVolatile(tDeviceStorage *env) {
if (VarsTabDumpObserver_Load(&env->dumpObserver)) {
if (env->nvm.version == DEVICE_DATA_NO_VOLATILE_VERSION) {
return true;
}
}
DeviceDataNonVolatile_InitDefaults(&env->nvm);
return VarsTabDumpObserver_Dump(&env->dumpObserver);
}
void DeviceStorage_ForceDump(tDeviceStorage *env) {
VarsTabDumpObserver_Dump(&env->dumpObserver);
}
void DeviceStorage_InitCommon(tDeviceStorage *env, tStorageInterface *storageInterface) {
VarsTabDumpObserver_Init(
&env->dumpObserver,
storageInterface,
5000,
&env->nvm,
sizeof(env->nvm),
&env->publicVariablesTable,
VARIABLE_GROUP_FLASH
);
env->dumpObserver.logger = env->logger;
DeviceStorage_InitVariablesTable(env);
}
void DeviceStorage_InitDefaults(tDeviceStorage *env) {
DeviceStorage_InitCommon(env, NULL);
DeviceDataNonVolatile_InitDefaults(&env->nvm);
}
bool DeviceStorage_Init(tDeviceStorage *env, tStorageInterface *storageInterface) {
DeviceStorage_InitCommon(env, storageInterface);
return DeviceStorage_LoadNonVolatile(env);
}

View File

@ -0,0 +1,19 @@
//
// Created by villuton on 16.09.2025.
//
#include "DataFlashPrivate.h"
void DeviceStorageInitDeviceSettings(tDeviceSettings *env) {
String16CopyStatic(&env->serialNumber.value, "Нет ID!");
env->serialNumber.writeAccess = 1;
env->dividerRatio = STORAGE_V_DIVIDER_RATIO_DEFAULT;
env->vReference = STORAGE_V_REFERENCE_DEFAULT;
env->voltageBatteryConnectThreshold = STORAGE_V_BAT_CONNECT;
env->voltageBatteryLoadedThreshold = STORAGE_V_BAT_LOADED;
for(uint8_t i = CHRG_Ch1; i < STORAGE_CALIB_CHANEL_NUM; i++){
env->chanelCalibrationFactor[i] = STORAGE_CALIBRATION_FACTOR_DEFAULT;
}
}

View File

@ -0,0 +1,12 @@
//
// Created by villuton on 16.09.2025.
//
#include "StorageOnFlash.h"
tStorageOnFlash NVM_STORAGE;
void StorageOnFlash_Init() {
tStorageOnFlash *env = &NVM_STORAGE;
vStorageOnFlashArtery_Init(&env->nf_storage, 0x080E8000, 0x080EC000);
env->interface = xStorageOnFlashArtery_GetInterface(&env->nf_storage);
}

13
LOCAL/modular.json Normal file
View File

@ -0,0 +1,13 @@
{
"cmake": {
"inc_dirs": [
"./Inc",
"./Storage/Inc"
],
"srcs": [
"./Src/**.c",
"./**.c",
"./Storage/Src/**.c"
]
}
}

27
artery_f403a.cfg Normal file
View File

@ -0,0 +1,27 @@
#
# This is an STM32F429 discovery board with a single STM32F429ZI chip.
# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/PF259090
#
source [find interface/stlink.cfg]
transport select hla_swd
source [find target/at32f403axG.cfg]
#reset_config trst_only
#reset_config srst_only
#reset_config trst_and_srst
#reset_config srst_pulls_trst
#reset_config combined
#reset_config srst_gates_jtag
#reset_config trst_push_pull
#reset_config trst_push_pull
reset_config none
#reset_config [none|trst_only|srst_only|trst_and_srst]
#[srst_pulls_trst|trst_pulls_srst|combined|separate]
#[srst_gates_jtag|srst_nogate] [trst_push_pull|trst_open_drain]
#[srst_push_pull|srst_open_drain]
#[connect_deassert_srst|connect_assert_srst]

186
modular.json Normal file
View File

@ -0,0 +1,186 @@
{
"dep": [
{
"type": "git",
"provider": "ELEMENT",
"repo": "SerialPort"
},
{
"type": "git",
"provider": "ELEMENT",
"repo": "AsciiStringAssemblingUtils"
},
{
"type": "git",
"provider": "ELEMENT",
"repo": "AsciiStringParsingUtils"
},
{
"type": "git",
"provider": "ELEMENT",
"repo": "SystemSyncInterface"
},
{
"type": "git",
"provider": "ELEMENT",
"repo": "CmakeConfig_GCC_CortexM4"
},
{
"type": "git",
"provider": "ELEMENT",
"repo": "FreeRTOSHeap4_CM4_CMSIS"
},
{
"type": "git",
"provider": "ELEMENT",
"repo": "SystemDelay_CMSIS_RTOS"
},
{
"type": "git",
"provider": "ELEMENT",
"repo": "SystemDelayInterface"
},
{
"type": "git",
"provider": "ELEMENT",
"repo": "DeviceStartup_ARTERY_AT32F403A_407"
},
{
"type": "git",
"provider": "ELEMENT",
"repo": "CmsisRtosThreadUtils"
},
{
"type": "git",
"provider": "ELEMENT",
"repo": "PeripheralDriver_ARTERY_AT32F403A_407"
},
{
"type": "git",
"provider": "ELEMENT",
"repo": "SerialPort_ARTERY_AT32_F403A"
},
{
"type": "git",
"provider": "ELEMENT",
"repo": "CmsisCore5"
},
{
"type": "git",
"provider": "ELEMENT",
"repo": "GpioPin_ARTERY_AT32F435_437"
},
{
"type": "git",
"provider": "ELEMENT",
"repo": "SerialPort_P2P_CmsisRtos"
},
{
"type": "git",
"provider": "ELEMENT",
"repo": "GpioPinInterface"
},
{
"type": "local",
"dir": "CmakeConfig_RandomBuildIdGenerator"
},
{
"type": "git",
"provider": "ELEMENT",
"repo": "FirmwareMetadataSection"
},
{
"type": "git",
"provider": "ELEMENT",
"repo": "LoggerToSerialPort"
},
{
"type": "git",
"provider": "ELEMENT",
"repo": "SerialPortHalfDuplexInterface"
},
{
"type": "git",
"provider": "ELEMENT",
"repo": "StorageOnFlash_ARTERY_AT32"
},
{
"type": "git",
"provider": "ELEMENT",
"repo": "SpiPortInterface"
},
{
"type": "git",
"provider": "ELEMENT",
"repo": "SpiPort"
},
{
"type": "git",
"provider": "ELEMENT",
"repo": "SpiPort_ARTERY_AT32_F403A"
},
{
"type": "git",
"provider": "ELEMENT",
"repo": "Adc_ARTERY_AT32"
},
{
"type": "git",
"provider": "ELEMENT",
"repo": "Rtc_ARTERY_AT32F403A_407"
},
{
"type": "git",
"provider": "ELEMENT",
"repo": "VarTabDumpObserver"
},
{
"type": "git",
"provider": "ELEMENT",
"repo": "VersionsInfoTable"
},
{
"type": "git",
"provider": "ELEMENT",
"repo": "VariablesTable"
},
{
"type": "git",
"provider": "ELEMENT",
"repo": "StorageInterface"
},
{
"type": "local",
"dir": "APP"
},
{
"type": "local",
"dir": "LOCAL"
}
]
}