834 lines
25 KiB
C
834 lines
25 KiB
C
/* 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 */
|