Files
yau07b-stm32/Core/Src/main.c
2025-12-09 15:58:08 +03:00

834 lines
25 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* Copyright (c) 2024 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 "lwip.h"
#include "lwip/udp.h"
#include "lwip/debug.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "pribors.h"
#include <FLASH_SECTOR_F4.h>
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* 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 ---------------------------------------------------------*/
TIM_HandleTypeDef htim3;
SRAM_HandleTypeDef hsram1;
/* USER CODE BEGIN PV */
// Счётчики которые висят на таймере
volatile uint32_t br_counter = 0;
volatile uint32_t rx_counter = 0;
volatile uint32_t flash_counter = 0;
volatile uint32_t pribor = 0; // Прибор в котором стоит ячейка
volatile pribor_type = 0; // Тип прибора в котором стоит ячейка
volatile rx_addr; // Адрес с которого принят пакет.
// Флаги загрузки ячеек ЭМС/КЭМС
volatile flag_load_ems_b0 = 0;
volatile _Bool flag_load_ems_b1 = 0;
volatile _Bool flag_load_kems_b = 0;
volatile _Bool flag_load_ems_g = 0;
// Структуры принятого и отправленного сообщения
volatile struct rcv_msg rx_msg;
volatile struct tsm_msg tx_msg;
volatile _Bool need_send_private = 0; // Флаг, что нужно отправить персональный ответ.
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_FMC_Init(void);
static void MX_TIM3_Init(void);
/* USER CODE BEGIN PFP */
void write_isa(uint16_t addr, uint16_t data);
uint16_t read_isa(uint16_t addr);
void sock_init(struct udp_pcb * pcb);
void udp_echo_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port);
void rcv_command(void);
uint16_t create_header(void);
void set_pbuf_params(struct pbuf *p, u16_t length);
_Bool load_flash_to_ems(uint32_t base_addr, uint16_t base_port);
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* 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();
HAL_Delay(100);
MX_LWIP_Init();
MX_FMC_Init();
MX_TIM3_Init();
/* USER CODE BEGIN 2 */
struct udp_pcb* pcb = udp_new();
sock_init(pcb);
memset(tx_msg.tx_buf, 0, sizeof tx_msg.tx_buf);
struct pbuf *p = pbuf_alloc(0, sizeof tx_msg.tx_buf, PBUF_RAM);
uint32_t br_addr = ipaddr_addr("10.1.1.255");
u16_t br_port = 50000U;
pribor = (((GPIOC->IDR) >> 6) & 0x7) | (((GPIOC->IDR) >> 9) & 0x18);
// timer start
if (HAL_TIM_Base_Start_IT(&htim3) != HAL_OK)
{
/* Starting Error */
Error_Handler();
}
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_14, GPIO_PIN_SET);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
MX_LWIP_Process();
if (need_send_private == 1)
{
need_send_private = 0;
set_pbuf_params(p, tx_msg.status_len + tx_msg.cmd_len);
err_t errok = udp_sendto(pcb, p, &rx_addr, rx_msg.port);
br_counter = 0;
}
if (br_counter > 99) // Широковещательный всётчик для отправки пакетов 100мс.
{
set_pbuf_params(p, create_header() + tx_msg.cmd_len);
err_t errok = udp_sendto(pcb, p, (ip_addr_t*)&br_addr, br_port);
br_counter = 0;
}
if (rx_msg.con_timeout > 1999) // Таймаут соединения 2с
{
rx_msg.clnt_con = 0;
}
if (rx_counter > 30) // Мигание светодиода на 30мс при приёме команды
{
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_14, GPIO_PIN_SET);
}
if (flash_counter > 100) // Таймер проверки загрежен ли флеш
{
flash_counter = 0;
switch(pribor_type)
{
case PRIBOR_TYPE_UF:
{
if (flag_load_kems_b == 0) flag_load_kems_b = load_flash_to_ems(FLASH_BASE_WR, BASE_ADDR_KEMS_B);
if (flag_load_ems_b0 == 0) flag_load_ems_b0 = load_flash_to_ems(FLASH_BASE_EMS_B0, BASE_ADDR_EMS_B0);
if (flag_load_ems_b1 == 0) flag_load_ems_b1 = load_flash_to_ems(FLASH_BASE_EMS_B1, BASE_ADDR_EMS_B1);
break;
}
}
}
}
/* USER CODE END WHILE */
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Configure the main internal regulator output voltage
*/
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3);
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLM = 8;
RCC_OscInitStruct.PLL.PLLN = 100;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 4;
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_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK)
{
Error_Handler();
}
}
/**
* @brief TIM3 Initialization Function
* @param None
* @retval None
*/
static void MX_TIM3_Init(void)
{
/* USER CODE BEGIN TIM3_Init 0 */
/* USER CODE END TIM3_Init 0 */
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
/* USER CODE BEGIN TIM3_Init 1 */
/* USER CODE END TIM3_Init 1 */
htim3.Instance = TIM3;
htim3.Init.Prescaler = 22;
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
htim3.Init.Period = 2170;
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
{
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN TIM3_Init 2 */
/* USER CODE END TIM3_Init 2 */
}
/* FMC initialization function */
static void MX_FMC_Init(void)
{
/* USER CODE BEGIN FMC_Init 0 */
/* USER CODE END FMC_Init 0 */
FMC_NORSRAM_TimingTypeDef Timing = {0};
/* USER CODE BEGIN FMC_Init 1 */
/* USER CODE END FMC_Init 1 */
/** Perform the SRAM1 memory initialization sequence
*/
hsram1.Instance = FMC_NORSRAM_DEVICE;
hsram1.Extended = FMC_NORSRAM_EXTENDED_DEVICE;
/* hsram1.Init */
hsram1.Init.NSBank = FMC_NORSRAM_BANK1;
hsram1.Init.DataAddressMux = FMC_DATA_ADDRESS_MUX_DISABLE;
hsram1.Init.MemoryType = FMC_MEMORY_TYPE_SRAM;
hsram1.Init.MemoryDataWidth = FMC_NORSRAM_MEM_BUS_WIDTH_16;
hsram1.Init.BurstAccessMode = FMC_BURST_ACCESS_MODE_DISABLE;
hsram1.Init.WaitSignalPolarity = FMC_WAIT_SIGNAL_POLARITY_LOW;
hsram1.Init.WrapMode = FMC_WRAP_MODE_DISABLE;
hsram1.Init.WaitSignalActive = FMC_WAIT_TIMING_BEFORE_WS;
hsram1.Init.WriteOperation = FMC_WRITE_OPERATION_ENABLE;
hsram1.Init.WaitSignal = FMC_WAIT_SIGNAL_DISABLE;
hsram1.Init.ExtendedMode = FMC_EXTENDED_MODE_DISABLE;
hsram1.Init.AsynchronousWait = FMC_ASYNCHRONOUS_WAIT_DISABLE;
hsram1.Init.WriteBurst = FMC_WRITE_BURST_DISABLE;
hsram1.Init.ContinuousClock = FMC_CONTINUOUS_CLOCK_SYNC_ONLY;
hsram1.Init.PageSize = FMC_PAGE_SIZE_NONE;
/* Timing */
Timing.AddressSetupTime = 10;
Timing.AddressHoldTime = 10;
Timing.DataSetupTime = 15;
Timing.BusTurnAroundDuration = 10;
Timing.CLKDivision = 10;
Timing.DataLatency = 10;
Timing.AccessMode = FMC_ACCESS_MODE_A;
if (HAL_SRAM_Init(&hsram1, &Timing, NULL) != HAL_OK)
{
Error_Handler( );
}
/* USER CODE BEGIN FMC_Init 2 */
/* USER CODE END FMC_Init 2 */
}
/**
* @brief GPIO Initialization Function
* @param None
* @retval None
*/
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOE_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOF_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOG_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_14, GPIO_PIN_RESET);
/*Configure GPIO pins : PC13 PC6 PC7 PC8
PC12 */
GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8
|GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/*Configure GPIO pin : PC14 */
GPIO_InitStruct.Pin = GPIO_PIN_14;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
}
/* USER CODE BEGIN 4 */
uint16_t create_header(void)
{
tx_msg.tx_buf[0] = 0;
tx_msg.tx_buf[1] = 0;
tx_msg.tx_buf[2] = rx_msg.rx_buf[2];
tx_msg.tx_buf[3] = rx_msg.rx_buf[3];
tx_msg.tx_buf[4] = 0;
tx_msg.tx_buf[5] = 0;
tx_msg.status_len = set_status(tx_msg.tx_buf, pribor) + 6;
return tx_msg.status_len;
}
void set_pbuf_params(struct pbuf *p, u16_t length)
{
p->len = length;
p->tot_len = p->len;
memcpy(p->payload, tx_msg.tx_buf, p->tot_len);
}
void sock_init(struct udp_pcb * pcb)
{
uint32_t ipaddr = get_ip();
u16_t port = get_port();
err_t errok = udp_bind(pcb, (ip_addr_t*)&ipaddr, port);
udp_recv(pcb, udp_echo_recv, NULL);
rx_msg.port = 0;
rx_msg.cmd_num = 0;
rx_msg.cmd_code = 0;
rx_msg.clnt_con = 0;
rx_msg.length = 0;
tx_msg.status_len = 0;
tx_msg.cmd_len = 0;
memset(rx_msg.rx_buf, 0, sizeof rx_msg.rx_buf);
return;
}
void udp_echo_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
{
if (!p) return;
if (p->tot_len >= sizeof rx_msg.rx_buf)
{
pbuf_free(p);
return;
}
if (p->tot_len < 6)
{
pbuf_free(p);
return;
}
memcpy(rx_msg.rx_buf, p->payload, p->tot_len);
if (rx_msg.clnt_con == 1)
{
if ((memcmp(&rx_addr, addr, sizeof rx_addr)!= 0) || (rx_msg.port != port))
{
pbuf_free(p);
return;
}
uint16_t cmd_num = rx_msg.rx_buf[2] | (rx_msg.rx_buf[3] << 8);
if (cmd_num != (rx_msg.cmd_num + 1))
{
pbuf_free(p);
return;
}
}
else
{
memcpy(&rx_addr, addr, sizeof rx_addr);
rx_msg.port = port;
}
rx_msg.con_timeout = 0;
rx_msg.clnt_con = 1;
rx_msg.length = p->tot_len;
rcv_command();
/* free the pbuf */
pbuf_free(p);
}
void rcv_command(void)
{
uint16_t ports_amount = 0;
uint16_t bytes_amount = 0;
uint16_t len_block = 0;
uint16_t i = 0;
rx_msg.cmd_num = rx_msg.rx_buf[2] | (rx_msg.rx_buf[3] << 8);
rx_msg.cmd_code = rx_msg.rx_buf[6];
tx_msg.status_len = create_header();
unsigned char *cmd_buf = &tx_msg.tx_buf[tx_msg.status_len];
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_14, GPIO_PIN_RESET);
rx_counter = 0;
switch(rx_msg.cmd_code) // код команды
{
case 0:
//-----------------------------------------------------------
// КОМАНДА №0
// ЧТЕНИЕ МАССИВА ПОРТОВ
//-----------------------------------------------------------
cmd_buf[0] = rx_msg.cmd_code; // - код команды
ports_amount = rx_msg.rx_buf[7];
// Проверка размера принятого буфера
if( rx_msg.length < (8 + ports_amount * 2))
{
// Размер принятого пакета меньше чем долно быть
// Установить ошибку
// КОД = 2
cmd_buf[1] = ERR_SIZE;
// Установить размер буфера = 2
tx_msg.cmd_len = 2;
}
else
{
// Установить ВЫПОЛНЕНО
cmd_buf[1] = NO_ERROR;
// Колличество прочитаных портов
cmd_buf[2] = rx_msg.rx_buf[7];
uint16_t port_data = 0xFFFF;
uint16_t port_addr = 0x0000;
for (i = 0; i < ports_amount; i ++)
{
port_addr = rx_msg.rx_buf[8 + i * 2] + (rx_msg.rx_buf[9 + i * 2] << 8);
cmd_buf[3 + (i*4)] = rx_msg.rx_buf[8 + i * 2];
cmd_buf[4 + (i*4)] = rx_msg.rx_buf[9 + i * 2];
port_data = read_isa(port_addr);
cmd_buf[5 + (i*4)] = port_data & 0xFF;
cmd_buf[6 + (i*4)] = port_data >> 8;
}
// Установить размер буфера
tx_msg.cmd_len = (ports_amount << 2) + 3;
}
break;
case 1:
//-----------------------------------------------------------
// КОМАНДА №1
// ЗАПИСЬ МАССИВА ПОРТОВ
//-----------------------------------------------------------
cmd_buf[0] = rx_msg.cmd_code; // - код команды
ports_amount = rx_msg.rx_buf[7];
// Проверка размера принятого буфера
if( rx_msg.length < (8 + ports_amount * 4))
{
// Размер принятого пакета меньше чем долно быть
// Установить ошибку
// КОД = 2
cmd_buf[1] = ERR_SIZE;
// Установить размер буфера = 2
tx_msg.cmd_len = 2;
}
else
{
// Установить ВЫПОЛНЕНО
cmd_buf[1] = NO_ERROR;
// Колличество записанных портов
cmd_buf[2] = rx_msg.rx_buf[7];
uint16_t port_data;
uint16_t port_addr;
for (i = 0; i<ports_amount; i++)
{
port_addr = rx_msg.rx_buf[8 + i * 4] + (rx_msg.rx_buf[9 + i * 4] << 8);
port_data = rx_msg.rx_buf[10 + i * 4] + (rx_msg.rx_buf[11 + i * 4] << 8);
cmd_buf[3 + (i*4)] = rx_msg.rx_buf[8 + i * 4];
cmd_buf[4 + (i*4)] = rx_msg.rx_buf[9 + i * 4];
write_isa(port_addr, port_data);
port_data = read_isa(port_addr);
cmd_buf[5 + (i*4)] = port_data & 0xFF;
cmd_buf[6 + (i*4)] = port_data >> 8;
}
// Установить размер буфера
tx_msg.cmd_len = (ports_amount << 2) + 3;
}
break;
case 55:
//-----------------------------------------------------------
// КОМАНДА №55
// ЗАПИСЬ МАССИВА В FLASH
//-----------------------------------------------------------
cmd_buf[0] = rx_msg.cmd_code; // - код команды
bytes_amount = rx_msg.rx_buf[10] + (rx_msg.rx_buf[11] << 8);
// Проверка размера принятого буфера
if( rx_msg.length < (10 + bytes_amount))
{
// Размер принятого пакета меньше чем долно быть
// Установить ошибку
// КОД = 2
cmd_buf[1] = ERR_SIZE;
// Установить размер буфера = 2
tx_msg.cmd_len = 2;
}
else
{
// Установить ВЫПОЛНЕНО
cmd_buf[1] = NO_ERROR;
uint32_t sector = FLASH_BASE_WR;
unsigned char flash_sector = rx_msg.rx_buf[7];
if (flash_sector == 1) sector = FLASH_BASE_EMS_B0;
if (flash_sector == 2) sector = FLASH_BASE_EMS_B1;
uint16_t flash_addr = rx_msg.rx_buf[8] + (rx_msg.rx_buf[9] << 8);
uint16_t numofwords = (bytes_amount / 4) + ((bytes_amount % 4) != 0);
Flash_Write_Data(sector + flash_addr, (uint32_t *)&rx_msg.rx_buf[12], numofwords);
// Установить размер буфера
tx_msg.cmd_len = 2;
}
break;
case 56:
//-----------------------------------------------------------
// КОМАНДА №56
// ЧТЕНИЕ МАССИВА ИЗ FLASH
//-----------------------------------------------------------
cmd_buf[0] = rx_msg.cmd_code; // - код команды
// Проверка размера принятого буфера
if( rx_msg.length < 8)
{
// Размер принятого пакета меньше чем долно быть
// Установить ошибку
// КОД = 2
cmd_buf[1] = ERR_SIZE;
// Установить размер буфера = 2
tx_msg.cmd_len = 2;
}
else
{
uint32_t sector = FLASH_BASE_WR;
unsigned char flash_sector = rx_msg.rx_buf[7];
if (flash_sector == 1) sector = FLASH_BASE_EMS_B0;
if (flash_sector == 2) sector = FLASH_BASE_EMS_B1;
bytes_amount = rx_msg.rx_buf[10] + (rx_msg.rx_buf[11] << 8);
// Установить ВЫПОЛНЕНО
cmd_buf[1] = NO_ERROR;
// Колличество записаных байт
cmd_buf[2] = rx_msg.rx_buf[7];
cmd_buf[3] = rx_msg.rx_buf[8];
cmd_buf[4] = rx_msg.rx_buf[9];
cmd_buf[5] = rx_msg.rx_buf[10];
cmd_buf[6] = rx_msg.rx_buf[11];
uint16_t flash_addr = rx_msg.rx_buf[8] + (rx_msg.rx_buf[9] << 8);
uint16_t numofwords = (bytes_amount / 4) + ((bytes_amount % 4) != 0);
Flash_Read_Data(sector + flash_addr, (uint32_t *)&cmd_buf[7], numofwords);
// Установить размер буфера
tx_msg.cmd_len = 7 + bytes_amount;
}
break;
case 60:
//-----------------------------------------------------------
// КОМАНДА №60
// ЗАПИСЬ МАССИВА В ПОРТ
//-----------------------------------------------------------
cmd_buf[0] = rx_msg.cmd_code; // - код команды
len_block = rx_msg.rx_buf[7] + (rx_msg.rx_buf[8] << 8); // - длинна блока данных в словах
// Проверка размера принятого буфера
if( rx_msg.length < (11 + len_block * 2))
{
// Размер принятого пакета меньше чем долно быть
// Установить ошибку
// КОД = 2
cmd_buf[1] = ERR_SIZE;
// Установить размер буфера = 2
tx_msg.cmd_len = 2;
}
else
{
// Установить ВЫПОЛНЕНО
cmd_buf[1] = NO_ERROR;
// Колличество записанных портов
cmd_buf[2] = rx_msg.rx_buf[7];
cmd_buf[3] = rx_msg.rx_buf[8];
cmd_buf[4] = rx_msg.rx_buf[9];
cmd_buf[5] = rx_msg.rx_buf[10];
uint16_t port_data;
uint16_t port_addr;
port_addr = rx_msg.rx_buf[9] + (rx_msg.rx_buf[10] << 8);
for (i = 0; i<len_block; i++)
{
port_data = rx_msg.rx_buf[11 + i * 2] + (rx_msg.rx_buf[12 + i * 2] << 8);
write_isa(port_addr, port_data);
}
// Установить размер буфера
tx_msg.cmd_len = 6;
}
break;
case 61:
//-----------------------------------------------------------
// КОМАНДА №61
// ЧТЕНИЕ МАССИВА ИЗ ПОРТА
//-----------------------------------------------------------
cmd_buf[0] = rx_msg.cmd_code; // - код команды
len_block = rx_msg.rx_buf[7] + (rx_msg.rx_buf[8] << 8); // - длинна блока данных в словах
// Проверка размера принятого буфера
if( rx_msg.length < 11 )
{
// Размер принятого пакета меньше чем долно быть
// Установить ошибку
// КОД = 2
cmd_buf[1] = ERR_SIZE;
// Установить размер буфера = 2
tx_msg.cmd_len = 2;
}
else
{
// Установить ВЫПОЛНЕНО
cmd_buf[1] = NO_ERROR;
// Колличество прочитаных портов
cmd_buf[2] = rx_msg.rx_buf[7];
cmd_buf[3] = rx_msg.rx_buf[8];
cmd_buf[4] = rx_msg.rx_buf[9];
cmd_buf[5] = rx_msg.rx_buf[10];
uint16_t port_addr = rx_msg.rx_buf[9] + (rx_msg.rx_buf[10] << 8);
for (i = 0; i < len_block; i++)
{
uint16_t port_data = read_isa(port_addr);
cmd_buf[6 + (i * 2)] = port_data & 0xFF;
cmd_buf[7 + (i * 2)] = port_data >> 8;
}
// Установить размер буфера
tx_msg.cmd_len = 6 + len_block * 2;
}
break;
case 70:
//-----------------------------------------------------------
// КОМАНДА №70
// КОМАНДА ЗАПИСИ ФЛАГА О ОКОНЧАНИИ ЗАГРУЗКИ ЭМС-Г
//-----------------------------------------------------------
cmd_buf[0] = rx_msg.cmd_code; // - код команды
// Проверка размера принятого буфера
if( rx_msg.length < 7)
{
// Размер принятого пакета меньше чем долно быть
// Установить ошибку
// КОД = 2
cmd_buf[1] = ERR_SIZE;
// Установить размер буфера = 2
tx_msg.cmd_len = 2;
}
else
{
// Установить ВЫПОЛНЕНО
cmd_buf[1] = NO_ERROR;
flag_load_ems_g = 1;
// Установить размер буфера
tx_msg.cmd_len = 2;
}
break;
default:
{
//-----------------------------------------------------------
// НЕИЗВЕСТНАЯ КОМАНДА
//-----------------------------------------------------------
cmd_buf[0] = rx_msg.cmd_code; // - код команды
cmd_buf[1] = ERR_UNKNOW_COMMAND;
tx_msg.cmd_len = 2;
}
break;
}
need_send_private = 1;
}
uint16_t read_isa(uint16_t addr)
{
return *(uint16_t*)(ISA_BASE_RD + (addr << 1));
}
void write_isa(uint16_t addr, uint16_t data)
{
*(uint16_t*)(ISA_BASE_WR + (addr << 1)) = data;
}
_Bool load_flash_to_ems(uint32_t base_addr, uint16_t base_port)
{
_Bool load_ok = 0;
uint16_t ports_data = 0, i = 0;
uint32_t flash_data[2] = {0,0};
write_isa(base_port + 0x2, 200);
ports_data = read_isa(base_port + 0x2);
if (ports_data != 200) return load_ok;
for (i = 0; i<=WORDS_TO_KEMS; i++)
{
Flash_Read_Data(base_addr + i * 10, (uint32_t *)&flash_data, 1);
write_isa(base_port + 0x2, flash_data[0]);
Flash_Read_Data(base_addr + i * 10 + 2, (uint32_t *)&flash_data, 1);
write_isa(base_port + 0x4, flash_data[0]);
Flash_Read_Data(base_addr + i * 10 + 4, (uint32_t *)&flash_data, 1);
write_isa(base_port + 0x6, flash_data[0]);
Flash_Read_Data(base_addr + i * 10 + 6, (uint32_t *)&flash_data, 1);
write_isa(base_port + 0x8, flash_data[0]);
Flash_Read_Data(base_addr + i * 10 + 8, (uint32_t *)&flash_data, 1);
write_isa(base_port + 0xa, flash_data[0]);
}
load_ok = 1;
return load_ok;
}
/* 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 */