Browse Source

Дополнил IAP проверками и защитой от сбоев передачи.

TelenkovDmitry 8 months ago
parent
commit
16e1cc9465

+ 0 - 1
fw/user/main.cpp

@@ -42,7 +42,6 @@ extern "C" {
 #include <string.h>
 
 
-
 void init_task(void *argument);
 void test_hw_task(void *argument);
 void soft_wdt(void *params);

+ 191 - 0
fw/user/system_at32f403a_407.c

@@ -0,0 +1,191 @@
+/**
+  **************************************************************************
+  * @file     system_at32f403a_407.c
+  * @brief    contains all the functions for cmsis cortex-m4 system source 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.
+  *
+  **************************************************************************
+  */
+
+/** @addtogroup CMSIS
+  * @{
+  */
+
+/** @addtogroup AT32F403A_407_system
+  * @{
+  */
+
+#include "at32f403a_407.h"
+
+/** @addtogroup AT32F403A_407_system_private_defines
+  * @{
+  */
+#define VECT_TAB_OFFSET                  0x21000 /*!< vector table base offset field. this value must be a multiple of 0x200. */
+/**
+  * @}
+  */
+
+/** @addtogroup AT32F403A_407_system_private_variables
+  * @{
+  */
+unsigned int system_core_clock           = HICK_VALUE; /*!< system clock frequency (core clock) */
+/**
+  * @}
+  */
+
+/** @addtogroup AT32F403A_407_system_private_functions
+  * @{
+  */
+
+/**
+  * @brief  setup the microcontroller system
+  *         initialize the flash interface.
+  * @note   this function should be used only after reset.
+  * @param  none
+  * @retval none
+  */
+void SystemInit (void)
+{
+#if defined (__FPU_USED) && (__FPU_USED == 1U)
+  SCB->CPACR |= ((3U << 10U * 2U) |         /* set cp10 full access */
+                 (3U << 11U * 2U)  );       /* set cp11 full access */
+#endif
+
+  /* reset the crm clock configuration to the default reset state(for debug purpose) */
+  /* set hicken bit */
+  CRM->ctrl_bit.hicken = TRUE;
+
+  /* wait hick stable */
+  while(CRM->ctrl_bit.hickstbl != SET);
+
+  /* hick used as system clock */
+  CRM->cfg_bit.sclksel = CRM_SCLK_HICK;
+
+  /* wait sclk switch status */
+  while(CRM->cfg_bit.sclksts != CRM_SCLK_HICK);
+
+  /* reset hexten, hextbyps, cfden and pllen bits */
+  CRM->ctrl &= ~(0x010D0000U);
+
+  /* reset cfg register, include sclk switch, ahbdiv, apb1div, apb2div, adcdiv,
+     clkout pllrcs, pllhextdiv, pllmult, usbdiv and pllrange bits */
+  CRM->cfg = 0; 
+
+  /* reset clkout[3], usbbufs, hickdiv, clkoutdiv */
+  CRM->misc1 = 0;
+
+  /* disable all interrupts enable and clear pending bits  */
+  CRM->clkint = 0x009F0000;
+
+#ifdef VECT_TAB_SRAM
+  SCB->VTOR = SRAM_BASE  | VECT_TAB_OFFSET;  /* vector table relocation in internal sram. */
+#else
+  SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET;  /* vector table relocation in internal flash. */
+#endif
+}
+
+/**
+  * @brief  update system_core_clock variable according to clock register values.
+  *         the system_core_clock variable contains the core clock (hclk), it can
+  *         be used by the user application to setup the systick timer or configure
+  *         other parameters.
+  * @param  none
+  * @retval none
+  */
+void system_core_clock_update(void)
+{
+  uint32_t hext_prediv = 0, pll_mult = 0, pll_mult_h = 0, pll_clock_source = 0, temp = 0, div_value = 0;
+  crm_sclk_type sclk_source;
+
+  static const uint8_t sys_ahb_div_table[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
+
+  /* get sclk source */
+  sclk_source = crm_sysclk_switch_status_get();
+
+  switch(sclk_source)
+  {
+    case CRM_SCLK_HICK:
+      if(((CRM->misc3_bit.hick_to_sclk) != RESET) && ((CRM->misc1_bit.hickdiv) != RESET))
+        system_core_clock = HICK_VALUE * 6;
+      else
+        system_core_clock = HICK_VALUE;
+      break;
+    case CRM_SCLK_HEXT:
+      system_core_clock = HEXT_VALUE;
+      break;
+    case CRM_SCLK_PLL:
+      pll_clock_source = CRM->cfg_bit.pllrcs;
+      {
+        /* get multiplication factor */
+        pll_mult = CRM->cfg_bit.pllmult_l;
+        pll_mult_h = CRM->cfg_bit.pllmult_h;
+        /* process high bits */
+        if((pll_mult_h != 0U) || (pll_mult == 15U)){
+            pll_mult += ((16U * pll_mult_h) + 1U);
+        }
+        else
+        {
+            pll_mult += 2U;
+        }
+
+        if (pll_clock_source == 0x00)
+        {
+          /* hick divided by 2 selected as pll clock entry */
+          system_core_clock = (HICK_VALUE >> 1) * pll_mult;
+        }
+        else
+        {
+          /* hext selected as pll clock entry */
+          if (CRM->cfg_bit.pllhextdiv != RESET)
+          {
+            hext_prediv = CRM->misc3_bit.hextdiv;
+
+            /* hext clock divided by 2 */
+            system_core_clock = (HEXT_VALUE / (hext_prediv + 2)) * pll_mult;
+          }
+          else
+          {
+            system_core_clock = HEXT_VALUE * pll_mult;
+          }
+        }
+      }
+      break;
+    default:
+      system_core_clock = HICK_VALUE;
+      break;
+  }
+
+  /* compute sclk, ahbclk frequency */
+  /* get ahb division */
+  temp = CRM->cfg_bit.ahbdiv;
+  div_value = sys_ahb_div_table[temp];
+  /* ahbclk frequency */
+  system_core_clock = system_core_clock >> div_value;
+}
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+

+ 0 - 0
libs/artery/cmsis/cm4/device_support/system_at32f403a_407.h → fw/user/system_at32f403a_407.h


+ 393 - 382
iap/modules/iap/iap.c

@@ -1,382 +1,393 @@
-#include "at32f403a_407.h"
-#include "iap.h"
-#include "common_config.h"
-#include "FreeRTOS.h"
-#include "task.h"
-#include "semphr.h"
-#include "fr_timers.h"
-#include "event_groups.h"
-#include "mb.h"
-#include "mbport.h"
-#include "mbrtu.h"
-#include <stdio.h>
-#include <string.h>
-
-
-EventGroupHandle_t event;
-SemaphoreHandle_t buf_sem;
-SemaphoreHandle_t flash_sem;
-TimerHandle_t led_timer_handle;
-
-uint32_t fw_size;   // Размер FW (передается в первом пакете)
-static uint16_t i_big_package;
-static uint16_t i_short_package;
-uint8_t fw_buf_1[FW_BUF_SIZE];
-uint8_t fw_buf_2[FW_BUF_SIZE];
-bool flash_err_flag = false;
-
-void led_timer(TimerHandle_t timer);
-void iap_task(void *params);
-
-
-//
-void iap_init(void)
-{
-    flash_sem = xSemaphoreCreateBinary();
-    
-    led_timer_handle = xTimerCreate("led_timer", 500, pdTRUE, (void *)0, led_timer);
-    xTimerStart(led_timer_handle, 0);
-    
-    xTaskCreate(iap_task, "iap_task", 4*configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL);
-}
-
-//
-void iap_task(void *params)
-{
-    (void)(params);
-    unsigned int ev;
-
-    event = xEventGroupCreate();
-    buf_sem = xSemaphoreCreateBinary();
-    xSemaphoreGive(buf_sem);
-    
-    if (ev = xEventGroupWaitBits(event, IAP_START | IAP_RETURN, pdTRUE, pdFALSE, 60000) != IAP_START)
-    {
-        printf("IAP: switch to FW!\r\n");
-        bpr_data_write(BPR_DATA1, 0);
-        NVIC_SystemReset();
-    }
-    
-    if (ev == IAP_RETURN)
-    {
-        printf("IAP: return to FW\r\n");
-        bpr_data_write(BPR_DATA1, 0);
-        vTaskDelay(200);
-        NVIC_SystemReset();
-    }
-    
-    for (;;)
-    {
-        ev = xEventGroupWaitBits(event, 
-                                 IAP_BLOCK | IAP_FINISH | IAP_RETURN | 
-                                 IAP_FLASH_ERROR | IAP_RESET,
-                                 pdTRUE, pdFALSE, portMAX_DELAY);
-
-        switch (ev)
-        {
-            case IAP_BLOCK :
-              
-                write_buf();
-                
-            break;
-            
-            // Запись завершена. Нужно провести проверку CRC.
-            case IAP_FINISH :
-              
-                flash_lock();
-                DBG printf("IAP: finish\r\n");
-                bpr_data_write(BPR_DATA1, 0);
-                vTaskDelay(100);
-                NVIC_SystemReset();
-                
-            break;
-            
-            // Возврат в основное ПО
-            case IAP_RETURN :
-              
-                DBG printf("IAP: return to FW\r\n");
-                bpr_data_write(BPR_DATA1, 0);
-                vTaskDelay(100);
-                NVIC_SystemReset();
-            
-            break;
-            
-            // Ошибка работы с flash
-            case IAP_FLASH_ERROR :
-              
-                DBG printf("IAP: flash error");
-                vTaskDelay(100);
-                NVIC_SystemReset();
-              
-            break;
-            
-            // Общая ошибка (что-то пошло не так)
-            case IAP_RESET :
-            
-                DBG printf("IAP: common error");
-                vTaskDelay(100);
-                NVIC_SystemReset();
-              
-            break;
-              
-            default : break;
-        }  
-	}
-}
-
-// Обработчик приема первого пакета с ключом и размером
-mb_err_code_t iap_start(uint8_t *data, uint8_t len)
-{
-    // Проверка контрольного слова
-	if (data[0] != 0xEF || data[1] != 0xBE || data[2] != 0xAD || data[3] != 0xDE)
-		return MB_BOOT_ERR_WRONG_CONTENT;
-
-	swap((uint8_t*)&data[4], (uint8_t*)&fw_size, 4);
-    
-    DBG printf("FW size: %u\r\n", fw_size);
-    
-    erase_flash();
-    
-/*
-   // Проверка размера загружаемого файла
-	if (fw_size != FW_SIZE) 
-    {
-        DBG printf("ERR: wrong FW size! Size should be: %u\r\n", (uint32_t)FW_SIZE);
-        xEventGroupSetBits(event, IAP_RETURN);
-		return MB_BOOT_ERR_WRONG_FW_SIZE;
-    }
-*/
-	i_big_package = 0;
-	i_short_package = 0;
-
-	xEventGroupSetBits(event, IAP_START);
-
-	return MB_BOOT_ERR_NO;
-}
-
-// Обработчик приема блока прошивки
-mb_err_code_t iap_block(uint8_t *data, uint8_t len)
-{
-	uint16_t pack_num;
-    static uint16_t pack_index = 0;
-
-    // Проверка номера пакета
-	swap(data, (uint8_t*)&pack_num, 2);
-    if (pack_num != pack_index) {
-        xEventGroupSetBits(event, IAP_RESET);
-        return MB_BOOT_WRONG_PACK_INDEX;
-    }
-    pack_index++;
-        
-	memcpy(&fw_buf_1[BLOCK_SIZE*i_short_package++], &data[2], BLOCK_SIZE);
-    
-	// Когда буфер заполняется нужно писать во флеш
-	if  (i_short_package == (FLASH_PAGE_SIZE / BLOCK_SIZE)) 
-	{
-		i_short_package = 0;
-		i_big_package++;
-		
-		if (i_big_package != 1) 
-		{
-			memcpy(fw_buf_2, fw_buf_1, FLASH_PAGE_SIZE);
-			xEventGroupSetBits(event, IAP_BLOCK);
-            return MB_BOOT_ERR_NO;
-		}
-	}
-
-	// Собрали данные для первой станицы. Нужно проверить ключ прошивки.
-	if ((i_big_package == 1) && (i_short_package == 0))
-	{
-		memcpy(fw_buf_2, fw_buf_1, FLASH_PAGE_SIZE);
-        xEventGroupSetBits(event, IAP_BLOCK);
-		return MB_BOOT_ERR_NO;			
-#if 0      
-        if (memcmp(&fw_buf_1[KEY_FW_SHIFT], HW_REW, strlen(HW_REW))) 
-        {
-            DBG printf("ERR: wrong fw key! Should be: %s\r\n", HW_REW);
-            xEventGroupSetBits(event, IAP_RETURN);
-            return MB_BOOT_ERR_WRONG_KEY;
-		}
-		else
-		{
-			memcpy(fw_buf_2, fw_buf_1, FLASH_PAGE_SIZE);
-			xEventGroupSetBits(event, IAP_BLOCK);
-			return MB_BOOT_ERR_NO;			
-		}
-#endif        
-	}
-
-    xSemaphoreGive(flash_sem);
-	return MB_BOOT_ERR_NO;
-}
-
-//
-bool write_buf(void)
-{
-	uint32_t *ptr = (uint32_t*)fw_buf_2;
-	uint32_t addr = FW_BEGIN_ADDRESS + FLASH_PAGE_SIZE*(i_big_package - 1);
-    
-	// Когда принят и проверен первый блок данных (2кБт) нужно очистить память
-	if (i_big_package == 1)
-	{
-/*      
-        if (!erase_flash())
-        {
-            flash_err_flag = true;  // ошибка flash
-            xSemaphoreGive(flash_sem);
-            return false;
-        }
-*/
-    }  
-    
-    flash_unlock();
-    
-    for (uint32_t i = 0; i < 512; i++)
-    {
-        if (flash_word_program(addr, *ptr) != FLASH_OPERATE_DONE)
-        {
-            flash_lock();
-            flash_err_flag = true;  // ошибка flash
-        }
-        ptr++;
-		addr += 4;
-    }  
-    
-#if 0
-	for (uint32_t i = 0; i < 256; i++)
-	{
-		if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, addr, (uint64_t)*ptr) != HAL_OK)
-		{
-            HAL_FLASH_Lock();
-            flash_err_flag = true;  // ошибка flash
-		}
-		ptr++;
-		addr += 8;
-	}
-#endif        
-    
-    xSemaphoreGive(flash_sem);
-	
-	return true;
-}
-
-// Нужно определить количество секторов для записи FW
-bool erase_flash(void)
-{
-    uint32_t sector = FW_BEGIN_ADDRESS;
-    int sector_number = fw_size/FLASH_PAGE_SIZE + 1;
-      
-    //DBG printf("Need to erase %u sectros\r\n", sector_number);
-    
-    flash_unlock();
-    
-    for (int i = 0; i < sector_number; i++)
-    {
-        if (flash_sector_erase(sector) != FLASH_OPERATE_DONE) {
-            return false;
-        }
-        //DBG printf("Sector %X erased\r\n", sector);
-        sector += FLASH_PAGE_SIZE;
-    }
-    
-    flash_lock();
-    
-    return true;
-}
-
-// 
-mb_err_code_t check_crc(void)
-{
-    uint32_t calc_crc;
-    uint32_t read_crc;
-#if 0    
-    cortex_crc_init();
-    read_crc = (*(uint32_t*)FW_CRC_ADDRESS);
-    calc_crc = cortex_crc((uint8_t*)FW_BEGIN_ADDRESS, (FW_SIZE - 4));
-    
-    if (read_crc != calc_crc)
-        return MB_BOOT_ERR_WRONG_FW_CRC;
-#endif    
-    return MB_BOOT_ERR_NO;
-}
-
-//
-void iap_finish(void)
-{
-	xEventGroupSetBits(event, IAP_BLOCK | IAP_FINISH);
-}
-
-//
-void led_timer(TimerHandle_t timer)
-{
-    
-}
-
-//
-// 65 (0x41) Read Input Registers	 
-eMBErrorCode
-eMBUpdateCB( UCHAR * pucFrame, USHORT * usLen)
-{
-	int res;
-				
-	switch (pucFrame[1]) 
-	{
-		case 1:
-
-			pucFrame[1] = iap_start(&pucFrame[2], *usLen);
-			*usLen = 2;
-			return MB_ENOERR;
-
-        break;
-
-		case 2:
-#if 1			
-            res = iap_block(&pucFrame[2], *usLen);
-            
-            xSemaphoreTake(flash_sem, 500);
-            
-            if (flash_err_flag) {
-                pucFrame[1] = MB_BOOT_FLASH_ERR;
-                xEventGroupSetBits(event, IAP_FLASH_ERROR);
-            }
-            else if (res == MB_BOOT_ERR_NO)
-                pucFrame[1] = WRITE_BLOCK_COM;
-            else if (res == MB_BOOT_ERR_WRONG_KEY)
-                pucFrame[1] = MB_BOOT_ERR_WRONG_KEY;
-            else if (res == MB_BOOT_WRONG_PACK_INDEX)
-                pucFrame[1] = MB_BOOT_WRONG_PACK_INDEX;
-            
-			*usLen = 2;
-#endif
-			return MB_ENOERR;
-
-        break;
-
-		case 3:
-#if 1
-            res = check_crc();
-          
-            if (res == MB_BOOT_ERR_WRONG_FW_CRC)
-                pucFrame[1] = WRITE_BLOCK_COM;
-            else 
-                iap_finish();
-            
-			*usLen = 2;
-#endif            
-			return MB_ENOERR;
-			
-		break;
-
-		default:
-			return MB_EPORTERR;
-	}
-}
-
-
-//
-void swap(uint8_t *in_buf, uint8_t *out_buf,  uint8_t size)
-{
-	for (uint8_t i = 0; i < size; i++) 
-		out_buf[size - i - 1] = in_buf[i];
-}
-
+#include "at32f403a_407.h"
+#include "iap.h"
+#include "common_config.h"
+#include "FreeRTOS.h"
+#include "task.h"
+#include "semphr.h"
+#include "fr_timers.h"
+#include "event_groups.h"
+#include "mb.h"
+#include "mbport.h"
+#include "mbrtu.h"
+#include "model_cfg.h"
+#include <stdio.h>
+#include <string.h>
+
+
+EventGroupHandle_t event;
+SemaphoreHandle_t buf_sem;
+SemaphoreHandle_t flash_sem;
+TimerHandle_t led_timer_handle;
+TimerHandle_t iap_timeout_handle;
+
+uint32_t fw_size;   // Размер FW (передается в первом пакете)
+static uint16_t i_big_package;
+static uint16_t i_short_package;
+uint8_t fw_buf_1[FW_BUF_SIZE];
+uint8_t fw_buf_2[FW_BUF_SIZE];
+bool flash_err_flag = false;
+
+void led_timer(TimerHandle_t timer);
+void iap_timeout(TimerHandle_t timer);
+void iap_task(void *params);
+
+
+//
+void iap_init(void)
+{
+    flash_sem = xSemaphoreCreateBinary();
+    
+    led_timer_handle = xTimerCreate("led_timer", 500, pdTRUE, (void *)0, led_timer);
+    xTimerStart(led_timer_handle, 0);
+    
+    iap_timeout_handle = xTimerCreate("iap_timer", 100000, pdTRUE, (void *)0, iap_timeout);
+        
+    xTaskCreate(iap_task, "iap_task", 4*configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL);
+}
+
+//
+void iap_task(void *params)
+{
+    (void)(params);
+    unsigned int ev;
+
+    event = xEventGroupCreate();
+    buf_sem = xSemaphoreCreateBinary();
+    xSemaphoreGive(buf_sem);
+    
+    if (ev = xEventGroupWaitBits(event, IAP_START | IAP_RETURN, pdTRUE, pdFALSE, 60000) != IAP_START)
+    {
+        printf("IAP: switch to FW!\r\n");
+        bpr_data_write(BPR_DATA1, 0);
+        NVIC_SystemReset();
+    }
+    
+    if (ev == IAP_RETURN)
+    {
+        printf("IAP: return to FW\r\n");
+        bpr_data_write(BPR_DATA1, 0);
+        vTaskDelay(200);
+        NVIC_SystemReset();
+    }
+    
+    for (;;)
+    {
+        ev = xEventGroupWaitBits(event, 
+                                 IAP_BLOCK | IAP_FINISH | IAP_RETURN | 
+                                 IAP_FLASH_ERROR | IAP_RESET,
+                                 pdTRUE, pdFALSE, portMAX_DELAY);
+
+        switch (ev)
+        {
+            case IAP_BLOCK :
+              
+                write_buf();
+                
+            break;
+            
+            // Запись завершена. Нужно провести проверку CRC.
+            case IAP_FINISH :
+              
+                flash_lock();
+                DBG printf("IAP: finish\r\n");
+                bpr_data_write(BPR_DATA1, 0);
+                vTaskDelay(100);
+                NVIC_SystemReset();
+                
+            break;
+            
+            // Возврат в основное ПО
+            case IAP_RETURN :
+              
+                DBG printf("IAP: return to FW\r\n");
+                bpr_data_write(BPR_DATA1, 0);
+                vTaskDelay(100);
+                NVIC_SystemReset();
+            
+            break;
+            
+            // Ошибка работы с flash
+            case IAP_FLASH_ERROR :
+              
+                DBG printf("IAP: flash error");
+                vTaskDelay(100);
+                NVIC_SystemReset();
+              
+            break;
+            
+            // Общая ошибка (что-то пошло не так)
+            case IAP_RESET :
+            
+                DBG printf("IAP: common error");
+                vTaskDelay(100);
+                NVIC_SystemReset();
+              
+            break;
+              
+            default : break;
+        }  
+	}
+}
+
+// Обработчик приема первого пакета с ключом и размером
+mb_err_code_t iap_start(uint8_t *data, uint8_t len)
+{
+    char model[MODEL_LEN] = {0};
+    char new_model[MODEL_LEN] = {0};
+    
+    // Проверка контрольного слова
+	if (data[0] != 0xEF || data[1] != 0xBE || data[2] != 0xAD || data[3] != 0xDE)
+		return MB_BOOT_ERR_WRONG_CONTENT;
+
+    // Проверка модели выполняется если флеш не пустая.
+    // Если флеш пуста, то можно залить прошивку от любой модели
+    memcpy(model, (void const*)MODEL_ADDR, MODEL_LEN);
+    
+    if ((model[0] != 0xFF) && (model[1] != 0xFF) && (model[2] != 0xFF) && (model[3] != 0xFF)) 
+    {
+        memcpy(new_model, &data[8], MODEL_LEN);
+        printf("Current model: %s\r\n", model);
+        printf("New model: %s\r\n", new_model);
+        printf("Model size: %u\r\n", strlen(new_model));
+        if (memcmp(new_model, model, strlen(new_model)) != 0)
+        {
+            DBG printf("Model error!\r\n");
+            return MB_BOOT_ERR_WRONG_CONTENT;
+        }
+    }
+    
+	swap((uint8_t*)&data[4], (uint8_t*)&fw_size, 4);
+    
+    DBG printf("FW size: %u\r\n", fw_size);
+    
+    erase_flash();
+
+	i_big_package = 0;
+	i_short_package = 0;
+
+    // Запуск таймера для отсчета timeout
+    xTimerStart(iap_timeout_handle, 0);
+    
+	xEventGroupSetBits(event, IAP_START);
+
+	return MB_BOOT_ERR_NO;
+}
+
+// Обработчик приема блока прошивки
+mb_err_code_t iap_block(uint8_t *data, uint8_t len)
+{
+	uint16_t pack_num;
+    static uint16_t pack_index = 0;
+    
+    // Проверка номера пакета
+	swap(data, (uint8_t*)&pack_num, 2);
+    if (pack_num != pack_index) {
+        xEventGroupSetBits(event, IAP_RESET);
+        return MB_BOOT_WRONG_PACK_INDEX;
+    }
+    pack_index++;
+	
+    memcpy(&fw_buf_1[BLOCK_SIZE*i_short_package++], &data[2], len - 4);
+    
+	// Когда буфер заполняется нужно писать во флеш.
+    // Файл может быть не кратен размеру блока!
+    if  ((i_short_package == (FLASH_PAGE_SIZE / BLOCK_SIZE)) || (len != (BLOCK_SIZE + 4))) 
+	{
+		i_short_package = 0;
+		i_big_package++;
+		
+		if (i_big_package != 1) 
+		{
+			memcpy(fw_buf_2, fw_buf_1, FLASH_PAGE_SIZE);
+			xEventGroupSetBits(event, IAP_BLOCK);
+            return MB_BOOT_ERR_NO;
+		}
+	}
+
+	// Собрали данные для первой станицы. Нужно проверить ключ прошивки.
+	if ((i_big_package == 1) && (i_short_package == 0))
+	{
+		memcpy(fw_buf_2, fw_buf_1, FLASH_PAGE_SIZE);
+        xEventGroupSetBits(event, IAP_BLOCK);
+		return MB_BOOT_ERR_NO;			
+	}
+
+    xSemaphoreGive(flash_sem);
+	return MB_BOOT_ERR_NO;
+}
+
+//
+bool write_buf(void)
+{
+	uint32_t *ptr = (uint32_t*)fw_buf_2;
+	uint32_t addr = FW_BEGIN_ADDRESS + FLASH_PAGE_SIZE*(i_big_package - 1);
+    
+	// Когда принят и проверен первый блок данных (2кБт) нужно очистить память
+	if (i_big_package == 1)
+	{
+/*      
+        if (!erase_flash())
+        {
+            flash_err_flag = true;  // ошибка flash
+            xSemaphoreGive(flash_sem);
+            return false;
+        }
+*/
+    }  
+    
+    flash_unlock();
+    
+    for (uint32_t i = 0; i < 512; i++)
+    {
+        if (flash_word_program(addr, *ptr) != FLASH_OPERATE_DONE)
+        {
+            flash_lock();
+            flash_err_flag = true;  // ошибка flash
+        }
+        ptr++;
+		addr += 4;
+    }        
+    
+    xSemaphoreGive(flash_sem);
+	
+	return true;
+}
+
+// Нужно определить количество секторов для записи FW
+bool erase_flash(void)
+{
+    uint32_t sector = FW_BEGIN_ADDRESS;
+    int sector_number = fw_size/FLASH_PAGE_SIZE + 1;
+      
+    //DBG printf("Need to erase %u sectros\r\n", sector_number);
+    
+    flash_unlock();
+    
+    for (int i = 0; i < sector_number; i++)
+    {
+        if (flash_sector_erase(sector) != FLASH_OPERATE_DONE) {
+            return false;
+        }
+        //DBG printf("Sector %X erased\r\n", sector);
+        sector += FLASH_PAGE_SIZE;
+    }
+    
+    flash_lock();
+    
+    return true;
+}
+
+// 
+mb_err_code_t check_crc(void)
+{
+    uint32_t calc_crc;
+    uint32_t read_crc;
+    
+    
+    read_crc = *(uint32_t*)(FW_BEGIN_ADDRESS + fw_size - 4);
+    DBG printf("Read CRC: %X\r\n", read_crc);
+    
+    crm_periph_clock_enable(CRM_CRC_PERIPH_CLOCK, TRUE);
+    crc_data_reset();
+      
+    for (uint32_t* ptr = (uint32_t*)FW_BEGIN_ADDRESS; ptr != (uint32_t*)(FW_BEGIN_ADDRESS + fw_size - 4); ptr++)
+        crc_one_word_calculate(*ptr); // добавляем всю прошивку в CRC
+        
+    calc_crc = crc_data_get();
+    
+    DBG printf("Calc CRC: %X\r\n", calc_crc);
+    
+    if (read_crc != calc_crc)
+        return MB_BOOT_ERR_WRONG_FW_CRC;
+    
+    return MB_BOOT_ERR_NO;
+}
+
+//
+void iap_finish(void)
+{
+	xEventGroupSetBits(event, IAP_BLOCK | IAP_FINISH);
+}
+
+//
+void led_timer(TimerHandle_t timer)
+{
+    
+}
+
+//
+// 65 (0x41) Read Input Registers	 
+eMBErrorCode
+eMBUpdateCB( UCHAR * pucFrame, USHORT * usLen)
+{
+	int res;
+				
+	switch (pucFrame[1]) 
+	{
+		case 1:
+
+			pucFrame[1] = iap_start(&pucFrame[2], *usLen);
+			*usLen = 2;
+			return MB_ENOERR;
+
+        break;
+
+		case 2:
+			
+            res = iap_block(&pucFrame[2], *usLen);
+            
+            xSemaphoreTake(flash_sem, 500);
+            
+            if (flash_err_flag) {
+                pucFrame[1] = MB_BOOT_FLASH_ERR;
+                xEventGroupSetBits(event, IAP_FLASH_ERROR);
+            }
+            else if (res == MB_BOOT_ERR_NO)
+                pucFrame[1] = WRITE_BLOCK_COM;
+            else if (res == MB_BOOT_ERR_WRONG_KEY)
+                pucFrame[1] = MB_BOOT_ERR_WRONG_KEY;
+            else if (res == MB_BOOT_WRONG_PACK_INDEX)
+                pucFrame[1] = MB_BOOT_WRONG_PACK_INDEX;
+            
+			*usLen = 2;
+
+			return MB_ENOERR;
+
+        break;
+
+		case 3:
+
+            res = check_crc();
+          
+            if (res == MB_BOOT_ERR_WRONG_FW_CRC)
+                pucFrame[1] = WRITE_BLOCK_COM;
+            else 
+                iap_finish();
+            
+			*usLen = 2;
+
+			return MB_ENOERR;
+			
+		break;
+
+		default:
+			return MB_EPORTERR;
+	}
+}
+
+
+//
+void swap(uint8_t *in_buf, uint8_t *out_buf,  uint8_t size)
+{
+	for (uint8_t i = 0; i < size; i++) 
+		out_buf[size - i - 1] = in_buf[i];
+}
+
+//
+void iap_timeout(TimerHandle_t timer)
+{
+    DBG printf("IAP timeout callback\r\nReset...");
+    vTaskDelay(1000);
+    flash_lock();
+    NVIC_SystemReset();
+}

+ 144 - 174
iap/modules/io/mux.c

@@ -1,174 +1,144 @@
-#include "at32f403a_407.h"
-#include "mux.h"
-#include "FreeRTOS.h"
-#include "task.h"
-#include <stdbool.h>
-
-
-mux_channel_t leds[LED_NUMBER] = {
-                                  {INP_1, {0, 0, 0}, LED_OFF, 0},
-                                  {INP_2, {0, 0, 0}, LED_OFF, 0},
-                                  {INP_3, {0, 0, 0}, LED_OFF, 0},
-                                  {INP_4, {0, 0, 0}, LED_OFF, 0},
-
-                                  {INP_5, {0, 1, 1}, LED_OFF, 0},
-                                  {INP_6, {0, 1, 1}, LED_OFF, 0},
-                                  {INP_7, {0, 1, 1}, LED_OFF, 0},
-                                  {INP_8, {0, 1, 1}, LED_OFF, 0},
-                                  
-                                  {OUT_1_G, {1, 0, 0}, LED_OFF, 0},
-                                  {OUT_2_G, {1, 0, 0}, LED_OFF, 0},
-                                  {OUT_3_G, {1, 0, 0}, LED_OFF, 0},
-                                  {OUT_4_G, {1, 0, 0}, LED_OFF, 0},
-                                  
-                                  {OUT_1_R, {0, 1, 0}, LED_OFF, 0},
-                                  {OUT_2_R, {0, 1, 0}, LED_OFF, 0},
-                                  {OUT_3_R, {0, 1, 0}, LED_OFF, 0},
-                                  {OUT_4_R, {0, 1, 0}, LED_OFF, 0},
-
-                                  {STATUS_G, {1, 1, 0}, LED_OFF, 0},
-                                  {STATUS_R, {1, 1, 0}, LED_OFF, 0},
-                                  {RX_G, {1, 1, 0}, LED_OFF, 0},
-                                  {TX_R, {1, 1, 0}, LED_OFF, 0},
-                                  
-                                  {OUT_5_R, {0, 0, 1}, LED_OFF, 0},
-                                  {OUT_6_R, {0, 0, 1}, LED_OFF, 0},
-                                  {OUT_7_R, {0, 0, 1}, LED_OFF, 0},
-                                  {OUT_8_R, {0, 0, 1}, LED_OFF, 0},
-
-                                  {OUT_5_G, {1, 0, 1}, LED_OFF, 0},
-                                  {OUT_6_G, {1, 0, 1}, LED_OFF, 0},
-                                  {OUT_7_G, {1, 0, 1}, LED_OFF, 0},
-                                  {OUT_8_G, {1, 0, 1}, LED_OFF, 0}
-                                 };
-
-
-
-//
-void mux_led_init(mux_channel_t *ch)
-{
-}
-
-
-//
-void mux_gpio_init(void)
-{
-    gpio_init_type gpio_initstructure;
-  
-    
-    crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);
-    crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);
-    crm_periph_clock_enable(CRM_GPIOE_PERIPH_CLOCK, TRUE);
-    
-    // LED_COL
-    //      COL_1 - PD6
-    //      COL_2 - PD7
-    //      COL_3 - PB6
-    //      COL_4 - PB7
-    gpio_initstructure.gpio_out_type       = GPIO_OUTPUT_PUSH_PULL;  
-    gpio_initstructure.gpio_pull           = GPIO_PULL_NONE;  
-    gpio_initstructure.gpio_mode           = GPIO_MODE_OUTPUT;  
-    gpio_initstructure.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
-    gpio_initstructure.gpio_pins           = GPIO_PINS_6 | GPIO_PINS_7;
-    gpio_init(GPIOB, &gpio_initstructure); 
-
-    gpio_initstructure.gpio_pins           = GPIO_PINS_6 | GPIO_PINS_7;
-    gpio_init(GPIOD, &gpio_initstructure); 
-    
-    gpio_bits_reset(GPIOB, GPIO_PINS_6 | GPIO_PINS_7);
-    gpio_bits_reset(GPIOD, GPIO_PINS_6 | GPIO_PINS_7);
-    
-    // LED_LINE (низкий уровень на пине = высокий уровень на входе MUX)
-    //      LINE_0 - PE3
-    //      LINE_1 - PE2
-    //      LINE_2 - PB9
-    gpio_initstructure.gpio_out_type       = GPIO_OUTPUT_PUSH_PULL;  
-    gpio_initstructure.gpio_pull           = GPIO_PULL_NONE;  
-    gpio_initstructure.gpio_mode           = GPIO_MODE_OUTPUT;  
-    gpio_initstructure.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
-    gpio_initstructure.gpio_pins           = GPIO_PINS_2 | GPIO_PINS_3;
-    gpio_init(GPIOE, &gpio_initstructure); 
-
-    gpio_initstructure.gpio_pins           = GPIO_PINS_9;
-    gpio_init(GPIOB, &gpio_initstructure);
-    
-    gpio_bits_reset(GPIOE, GPIO_PINS_2 | GPIO_PINS_3);
-    gpio_bits_reset(GPIOB, GPIO_PINS_9);
-}
-
-
-//
-void mux_led_proc(void)
-{
-    uint8_t shift = 0;
-    
-    for (uint8_t i = 0; i < LED_NUMBER/4; i++)
-    {
-        leds[shift].line[0] ? (LINE_0_RESET) : (LINE_0_SET);
-        leds[shift].line[1] ? (LINE_1_RESET) : (LINE_1_SET);
-        leds[shift].line[2] ? (LINE_2_RESET) : (LINE_2_SET);
-        
-        leds[i*4].state     == LED_ON ? (COL_1_SET) : (COL_1_RESET);
-        leds[i*4 + 1].state == LED_ON ? (COL_2_SET) : (COL_2_RESET);
-        leds[i*4 + 2].state == LED_ON ? (COL_3_SET) : (COL_3_RESET);
-        leds[i*4 + 3].state == LED_ON ? (COL_4_SET) : (COL_4_RESET);
-        
-        if (leds[i*4].state == LED_ON || leds[i*4 + 1].state == LED_ON || 
-            leds[i*4 + 2].state == LED_ON || leds[i*4 + 3].state == LED_ON) 
-        {
-            vTaskDelay(1);
-        }
-        
-        shift += 4;
-    }
-}
-
-//
-void mux_led_test_init(void)
-{
-    LINE_0_SET;
-    LINE_1_SET;
-    LINE_2_SET;
-}
-
-//
-void mux_led_test_toggle(void)
-{
-    static bool flag = false;
-    
-    if (!flag) {
-        COL_1_SET;
-        flag = true;
-    }
-    else {
-        COL_1_RESET;
-        flag = false;
-    }
-}
-
-//
-void mux_led_blink(void)
-{
-    for (int i = 0; i < LED_NUMBER; i++)
-    {
-        leds[i].state = LED_ON;
-        
-        vTaskDelay(100);
-        
-        leds[i].state = LED_OFF;
-    }
-}
-
-// true - normal
-// false - alarm
-void mux_led_status(bool state)
-{
-    if (state) {
-        leds[STATUS_G].state = LED_ON;
-        leds[STATUS_R].state = LED_OFF;
-    }
-    else {
-        leds[STATUS_G].state = LED_OFF;
-        leds[STATUS_R].state = LED_ON;
-    }
-}
+#include "at32f403a_407.h"
+#include "mux.h"
+#include "FreeRTOS.h"
+#include "task.h"
+#include <stdbool.h>
+
+
+mux_channel_t leds[LED_NUMBER] = {
+                                  {STATUS_G, {1, 1, 0}, LED_OFF, 0},
+                                  {STATUS_R, {1, 1, 0}, LED_OFF, 0},
+                                  {RX_G, {1, 1, 0}, LED_OFF, 0},
+                                  {TX_R, {1, 1, 0}, LED_OFF, 0},
+                                 };
+
+
+
+//
+void mux_led_init(mux_channel_t *ch)
+{
+}
+
+
+//
+void mux_gpio_init(void)
+{
+    gpio_init_type gpio_initstructure;
+  
+    
+    crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);
+    crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);
+    crm_periph_clock_enable(CRM_GPIOE_PERIPH_CLOCK, TRUE);
+    
+    // LED_COL
+    //      COL_1 - PD6
+    //      COL_2 - PD7
+    //      COL_3 - PB6
+    //      COL_4 - PB7
+    gpio_initstructure.gpio_out_type       = GPIO_OUTPUT_PUSH_PULL;  
+    gpio_initstructure.gpio_pull           = GPIO_PULL_NONE;  
+    gpio_initstructure.gpio_mode           = GPIO_MODE_OUTPUT;  
+    gpio_initstructure.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
+    gpio_initstructure.gpio_pins           = GPIO_PINS_6 | GPIO_PINS_7;
+    gpio_init(GPIOB, &gpio_initstructure); 
+
+    gpio_initstructure.gpio_pins           = GPIO_PINS_6 | GPIO_PINS_7;
+    gpio_init(GPIOD, &gpio_initstructure); 
+    
+    gpio_bits_reset(GPIOB, GPIO_PINS_6 | GPIO_PINS_7);
+    gpio_bits_reset(GPIOD, GPIO_PINS_6 | GPIO_PINS_7);
+    
+    // LED_LINE (низкий уровень на пине = высокий уровень на входе MUX)
+    //      LINE_0 - PE3
+    //      LINE_1 - PE2
+    //      LINE_2 - PB9
+    gpio_initstructure.gpio_out_type       = GPIO_OUTPUT_PUSH_PULL;  
+    gpio_initstructure.gpio_pull           = GPIO_PULL_NONE;  
+    gpio_initstructure.gpio_mode           = GPIO_MODE_OUTPUT;  
+    gpio_initstructure.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
+    gpio_initstructure.gpio_pins           = GPIO_PINS_2 | GPIO_PINS_3;
+    gpio_init(GPIOE, &gpio_initstructure); 
+
+    gpio_initstructure.gpio_pins           = GPIO_PINS_9;
+    gpio_init(GPIOB, &gpio_initstructure);
+    
+    gpio_bits_reset(GPIOE, GPIO_PINS_2 | GPIO_PINS_3);
+    gpio_bits_reset(GPIOB, GPIO_PINS_9);
+}
+
+
+//
+void mux_led_proc(void)
+{
+    uint8_t shift = 0;
+    
+    for (uint8_t i = 0; i < LED_NUMBER/4; i++)
+    {
+        leds[shift].line[0] ? (LINE_0_RESET) : (LINE_0_SET);
+        leds[shift].line[1] ? (LINE_1_RESET) : (LINE_1_SET);
+        leds[shift].line[2] ? (LINE_2_RESET) : (LINE_2_SET);
+        
+        leds[i*4].state     == LED_ON ? (COL_1_SET) : (COL_1_RESET);
+        leds[i*4 + 1].state == LED_ON ? (COL_2_SET) : (COL_2_RESET);
+        leds[i*4 + 2].state == LED_ON ? (COL_3_SET) : (COL_3_RESET);
+        leds[i*4 + 3].state == LED_ON ? (COL_4_SET) : (COL_4_RESET);
+        
+        if (leds[i*4].state == LED_ON || leds[i*4 + 1].state == LED_ON || 
+            leds[i*4 + 2].state == LED_ON || leds[i*4 + 3].state == LED_ON) 
+        {
+            vTaskDelay(1);
+        }
+        
+        shift += 4;
+    }
+}
+
+//
+void mux_led_test_init(void)
+{
+    LINE_0_SET;
+    LINE_1_SET;
+    LINE_2_SET;
+}
+
+//
+void mux_led_test_toggle(void)
+{
+    static bool flag = false;
+    
+    if (!flag) {
+        COL_1_SET;
+        flag = true;
+    }
+    else {
+        COL_1_RESET;
+        flag = false;
+    }
+}
+
+//
+void mux_led_blink(void)
+{
+    for (int i = 0; i < LED_NUMBER; i++)
+    {
+        leds[i].state = LED_ON;
+        
+        vTaskDelay(100);
+        
+        leds[i].state = LED_OFF;
+    }
+}
+
+// true - normal
+// false - alarm
+void mux_led_status(bool state)
+{
+    if (state) {
+        leds[STATUS_G].state = LED_ON;
+        leds[STATUS_R].state = LED_OFF;
+    }
+    else {
+        leds[STATUS_G].state = LED_OFF;
+        leds[STATUS_R].state = LED_ON;
+    }
+}

+ 85 - 115
iap/modules/io/mux.h

@@ -1,115 +1,85 @@
-#ifndef __MUX_H
-#define __MUX_H
-
-#include <stdbool.h>
-
-//
-#define LED_NUMBER      28
-
-#define LINE_0_SET      GPIOE->scr = GPIO_PINS_3
-#define LINE_0_RESET    GPIOE->clr = GPIO_PINS_3
-
-#define LINE_1_SET      GPIOE->scr = GPIO_PINS_2
-#define LINE_1_RESET    GPIOE->clr = GPIO_PINS_2
-
-#define LINE_2_SET      GPIOB->scr = GPIO_PINS_9
-#define LINE_2_RESET    GPIOB->clr = GPIO_PINS_9
-
-#define COL_1_SET      GPIOD->scr = GPIO_PINS_6
-#define COL_1_RESET    GPIOD->clr = GPIO_PINS_6
-
-#define COL_2_SET      GPIOD->scr = GPIO_PINS_7
-#define COL_2_RESET    GPIOD->clr = GPIO_PINS_7
-
-#define COL_3_SET      GPIOB->scr = GPIO_PINS_6
-#define COL_3_RESET    GPIOB->clr = GPIO_PINS_6
-
-#define COL_4_SET      GPIOB->scr = GPIO_PINS_7
-#define COL_4_RESET    GPIOB->clr = GPIO_PINS_7
-
-
-typedef enum
-{
-    INP_1 = 0, 
-    INP_2, 
-    INP_3, 
-    INP_4,
-    
-    INP_5, 
-    INP_6, 
-    INP_7, 
-    INP_8,
-    
-    OUT_1_G,
-    OUT_2_G,
-    OUT_3_G,
-    OUT_4_G,
-    
-    OUT_1_R,
-    OUT_2_R,
-    OUT_3_R,
-    OUT_4_R,
-    
-    STATUS_G,
-    STATUS_R,
-    RX_G,
-    TX_R,
-    
-    OUT_5_R,
-    OUT_6_R,
-    OUT_7_R,
-    OUT_8_R,
-    
-    OUT_5_G,
-    OUT_6_G,
-    OUT_7_G,
-    OUT_8_G,
-      
-} led_t;
-
-
-typedef enum
-{
-    LED_OFF = 0, 
-    LED_ON,
-    LED_BLINK,
-    
-} led_state_t;
-
-
-typedef struct 
-{
-    led_t           name;
-    uint8_t         line[3];    // [line_0, line_1, line_2]
-    led_state_t     state;
-    uint32_t        cnt;
-    
-} mux_channel_t;
-
-
-//
-void mux_led_init(mux_channel_t *ch);
-
-//
-void mux_gpio_init(void);
-
-//
-void mux_led_proc(void);
-
-//
-void mux_led_blink(void);
-
-//
-void mux_led_test_init(void);
-
-//
-void mux_led_test_toggle(void);
-
-//
-void mux_led_status(bool state);
-
-
-extern mux_channel_t leds[];
-
-#endif  // __MUX_H
-
+#ifndef __MUX_H
+#define __MUX_H
+
+#include <stdbool.h>
+
+//
+#define LED_NUMBER      4
+
+#define LINE_0_SET      GPIOE->scr = GPIO_PINS_3
+#define LINE_0_RESET    GPIOE->clr = GPIO_PINS_3
+
+#define LINE_1_SET      GPIOE->scr = GPIO_PINS_2
+#define LINE_1_RESET    GPIOE->clr = GPIO_PINS_2
+
+#define LINE_2_SET      GPIOB->scr = GPIO_PINS_9
+#define LINE_2_RESET    GPIOB->clr = GPIO_PINS_9
+
+#define COL_1_SET      GPIOD->scr = GPIO_PINS_6
+#define COL_1_RESET    GPIOD->clr = GPIO_PINS_6
+
+#define COL_2_SET      GPIOD->scr = GPIO_PINS_7
+#define COL_2_RESET    GPIOD->clr = GPIO_PINS_7
+
+#define COL_3_SET      GPIOB->scr = GPIO_PINS_6
+#define COL_3_RESET    GPIOB->clr = GPIO_PINS_6
+
+#define COL_4_SET      GPIOB->scr = GPIO_PINS_7
+#define COL_4_RESET    GPIOB->clr = GPIO_PINS_7
+
+
+typedef enum
+{
+    STATUS_G = 0,
+    STATUS_R,
+    RX_G,
+    TX_R,
+      
+} led_t;
+
+
+typedef enum
+{
+    LED_OFF = 0, 
+    LED_ON,
+    LED_BLINK,
+    
+} led_state_t;
+
+
+typedef struct 
+{
+    led_t           name;
+    uint8_t         line[3];    // [line_0, line_1, line_2]
+    led_state_t     state;
+    uint32_t        cnt;
+    
+} mux_channel_t;
+
+
+//
+void mux_led_init(mux_channel_t *ch);
+
+//
+void mux_gpio_init(void);
+
+//
+void mux_led_proc(void);
+
+//
+void mux_led_blink(void);
+
+//
+void mux_led_test_init(void);
+
+//
+void mux_led_test_toggle(void);
+
+//
+void mux_led_status(bool state);
+
+
+extern mux_channel_t leds[];
+
+#endif  // __MUX_H
+

+ 8 - 11
iap/modules/modbus/modbus.c

@@ -11,6 +11,7 @@
 #include "settings_api.h"
 #include "iap.h"
 #include "common_gpio.h"
+#include "fr_timers.h"
 #include <stdio.h>
 #include <string.h>
 #include <stdbool.h>
@@ -67,10 +68,8 @@ void mb_init(void)
     xTaskCreate(modbus_task, "modbus_task", 2*configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL);
     
     xTaskCreate(modbus_params, "modbus_params", 4*configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL);
-    
-    settings_timer_handle = xTimerCreate("reset_timer", 10000, 
-                                        pdFALSE, (void *)0, cb_settings_timer);
-    
+   
+
 #if 0    
 	osTimerDef(vResetTimer, modbus_reset);
 	reset_timer_handle = osTimerCreate(osTimer(vResetTimer), osTimerOnce, NULL);
@@ -382,10 +381,8 @@ eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegi
 }
 
 
-//
-void cb_settings_timer(TimerHandle_t timer)
-{
-    printf("Settings timer callback\r\n");
-    psw_ok = false;
-}
-
+eMBException    
+eMBFuncReadFileRecordCB( UCHAR * pucFrame, USHORT * usLen )
+{        
+    return MB_EX_NONE;
+}

+ 32 - 2
iap/user/main.c

@@ -3,6 +3,7 @@
 
 void soft_wdt(void *params);
 void init_task(void *params);
+void led_task(void *params);
 bool jump_to_app(uint32_t address);
 void (*pftarget)(void);
 
@@ -42,7 +43,7 @@ int main()
     boot_try = bpr_data_read(BPR_DATA2);
     
     DBG printf("[IAP] load_mode: %u, boot_try: %u\r\n", load_mode, boot_try);
-#if 1    
+
     // Если есть попытки, то пытаемся загрузить FW.
 	// Используем ограниченное число попыток загрузить основное FW.
     if (boot_try > 1)
@@ -76,10 +77,15 @@ int main()
         DBG printf("Go to main FW...\r\n");
         jump_to_app(USER_FLASH_FIRST_PAGE_ADDRESS);
     }
-#endif    
         
     DBG printf("IAP starting...\r\n");
 
+    // -------------------------------------------------------------------------- //    
+    // Мультиплексор
+    
+    mux_gpio_init();
+
+    
 #if 0    
     // -------------------------------------------------------------------------
     // Для теста. Сброс.
@@ -97,6 +103,8 @@ int main()
     
     xTaskCreate(init_task, "init_task", 10*configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL);
     
+    xTaskCreate(led_task, "led_task", 2*configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL);
+    
     taskEXIT_CRITICAL();
     
     vTaskStartScheduler();
@@ -152,4 +160,26 @@ void init_task(void *params)
       
         vTaskDelay(500);
     }
+}
+
+//
+void led_task(void *params)
+{
+    for (;;) {
+        mux_led_proc();
+    }
+}
+
+//
+void USART1_IRQHandler(void)
+{
+    char data = 0;
+      
+    if (USART1->ctrl1_bit.rdbfien == SET)
+    {
+        if (usart_flag_get(USART1, USART_RDBF_FLAG) == SET) 
+        {
+            data = usart_data_receive(USART1);
+        }
+    }  
 }

+ 22 - 22
iap/user/main.h

@@ -1,23 +1,23 @@
-#ifndef __MAIN_H
-#define __MAIN_H
-
-#include "at32f403a_407.h"
-#include "at32f403a_407_board.h"
-#include "at32f403a_407_clock.h"
-#include "common_config.h"
-#include "FreeRTOS.h"
-#include "task.h"
-#include "queue.h"
-#include "semphr.h"
-//#include "extended_sram.h"
-#include "modbus.h"
-#include "common_gpio.h"
-#include "settings_api.h"
-#include <stdio.h>
-#include <stdbool.h>
-#include <string.h>
-
-
-
-
+#ifndef __MAIN_H
+#define __MAIN_H
+
+#include "at32f403a_407.h"
+#include "at32f403a_407_board.h"
+#include "at32f403a_407_clock.h"
+#include "common_config.h"
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+#include "semphr.h"
+#include "modbus.h"
+#include "common_gpio.h"
+#include "settings_api.h"
+#include "mux.h"
+#include <stdio.h>
+#include <stdbool.h>
+#include <string.h>
+
+
+
+
 #endif

+ 191 - 191
libs/artery/cmsis/cm4/device_support/system_at32f403a_407.c → iap/user/system_at32f403a_407.c

@@ -1,191 +1,191 @@
-/**
-  **************************************************************************
-  * @file     system_at32f403a_407.c
-  * @brief    contains all the functions for cmsis cortex-m4 system source 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.
-  *
-  **************************************************************************
-  */
-
-/** @addtogroup CMSIS
-  * @{
-  */
-
-/** @addtogroup AT32F403A_407_system
-  * @{
-  */
-
-#include "at32f403a_407.h"
-
-/** @addtogroup AT32F403A_407_system_private_defines
-  * @{
-  */
-#define VECT_TAB_OFFSET                  0x0 /*!< vector table base offset field. this value must be a multiple of 0x200. */
-/**
-  * @}
-  */
-
-/** @addtogroup AT32F403A_407_system_private_variables
-  * @{
-  */
-unsigned int system_core_clock           = HICK_VALUE; /*!< system clock frequency (core clock) */
-/**
-  * @}
-  */
-
-/** @addtogroup AT32F403A_407_system_private_functions
-  * @{
-  */
-
-/**
-  * @brief  setup the microcontroller system
-  *         initialize the flash interface.
-  * @note   this function should be used only after reset.
-  * @param  none
-  * @retval none
-  */
-void SystemInit (void)
-{
-#if defined (__FPU_USED) && (__FPU_USED == 1U)
-  SCB->CPACR |= ((3U << 10U * 2U) |         /* set cp10 full access */
-                 (3U << 11U * 2U)  );       /* set cp11 full access */
-#endif
-
-  /* reset the crm clock configuration to the default reset state(for debug purpose) */
-  /* set hicken bit */
-  CRM->ctrl_bit.hicken = TRUE;
-
-  /* wait hick stable */
-  while(CRM->ctrl_bit.hickstbl != SET);
-
-  /* hick used as system clock */
-  CRM->cfg_bit.sclksel = CRM_SCLK_HICK;
-
-  /* wait sclk switch status */
-  while(CRM->cfg_bit.sclksts != CRM_SCLK_HICK);
-
-  /* reset hexten, hextbyps, cfden and pllen bits */
-  CRM->ctrl &= ~(0x010D0000U);
-
-  /* reset cfg register, include sclk switch, ahbdiv, apb1div, apb2div, adcdiv,
-     clkout pllrcs, pllhextdiv, pllmult, usbdiv and pllrange bits */
-  CRM->cfg = 0; 
-
-  /* reset clkout[3], usbbufs, hickdiv, clkoutdiv */
-  CRM->misc1 = 0;
-
-  /* disable all interrupts enable and clear pending bits  */
-  CRM->clkint = 0x009F0000;
-
-#ifdef VECT_TAB_SRAM
-  SCB->VTOR = SRAM_BASE  | VECT_TAB_OFFSET;  /* vector table relocation in internal sram. */
-#else
-  SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET;  /* vector table relocation in internal flash. */
-#endif
-}
-
-/**
-  * @brief  update system_core_clock variable according to clock register values.
-  *         the system_core_clock variable contains the core clock (hclk), it can
-  *         be used by the user application to setup the systick timer or configure
-  *         other parameters.
-  * @param  none
-  * @retval none
-  */
-void system_core_clock_update(void)
-{
-  uint32_t hext_prediv = 0, pll_mult = 0, pll_mult_h = 0, pll_clock_source = 0, temp = 0, div_value = 0;
-  crm_sclk_type sclk_source;
-
-  static const uint8_t sys_ahb_div_table[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
-
-  /* get sclk source */
-  sclk_source = crm_sysclk_switch_status_get();
-
-  switch(sclk_source)
-  {
-    case CRM_SCLK_HICK:
-      if(((CRM->misc3_bit.hick_to_sclk) != RESET) && ((CRM->misc1_bit.hickdiv) != RESET))
-        system_core_clock = HICK_VALUE * 6;
-      else
-        system_core_clock = HICK_VALUE;
-      break;
-    case CRM_SCLK_HEXT:
-      system_core_clock = HEXT_VALUE;
-      break;
-    case CRM_SCLK_PLL:
-      pll_clock_source = CRM->cfg_bit.pllrcs;
-      {
-        /* get multiplication factor */
-        pll_mult = CRM->cfg_bit.pllmult_l;
-        pll_mult_h = CRM->cfg_bit.pllmult_h;
-        /* process high bits */
-        if((pll_mult_h != 0U) || (pll_mult == 15U)){
-            pll_mult += ((16U * pll_mult_h) + 1U);
-        }
-        else
-        {
-            pll_mult += 2U;
-        }
-
-        if (pll_clock_source == 0x00)
-        {
-          /* hick divided by 2 selected as pll clock entry */
-          system_core_clock = (HICK_VALUE >> 1) * pll_mult;
-        }
-        else
-        {
-          /* hext selected as pll clock entry */
-          if (CRM->cfg_bit.pllhextdiv != RESET)
-          {
-            hext_prediv = CRM->misc3_bit.hextdiv;
-
-            /* hext clock divided by 2 */
-            system_core_clock = (HEXT_VALUE / (hext_prediv + 2)) * pll_mult;
-          }
-          else
-          {
-            system_core_clock = HEXT_VALUE * pll_mult;
-          }
-        }
-      }
-      break;
-    default:
-      system_core_clock = HICK_VALUE;
-      break;
-  }
-
-  /* compute sclk, ahbclk frequency */
-  /* get ahb division */
-  temp = CRM->cfg_bit.ahbdiv;
-  div_value = sys_ahb_div_table[temp];
-  /* ahbclk frequency */
-  system_core_clock = system_core_clock >> div_value;
-}
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-
-/**
-  * @}
-  */
-
+/**
+  **************************************************************************
+  * @file     system_at32f403a_407.c
+  * @brief    contains all the functions for cmsis cortex-m4 system source 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.
+  *
+  **************************************************************************
+  */
+
+/** @addtogroup CMSIS
+  * @{
+  */
+
+/** @addtogroup AT32F403A_407_system
+  * @{
+  */
+
+#include "at32f403a_407.h"
+
+/** @addtogroup AT32F403A_407_system_private_defines
+  * @{
+  */
+#define VECT_TAB_OFFSET                  0x0 /*!< vector table base offset field. this value must be a multiple of 0x200. */
+/**
+  * @}
+  */
+
+/** @addtogroup AT32F403A_407_system_private_variables
+  * @{
+  */
+unsigned int system_core_clock           = HICK_VALUE; /*!< system clock frequency (core clock) */
+/**
+  * @}
+  */
+
+/** @addtogroup AT32F403A_407_system_private_functions
+  * @{
+  */
+
+/**
+  * @brief  setup the microcontroller system
+  *         initialize the flash interface.
+  * @note   this function should be used only after reset.
+  * @param  none
+  * @retval none
+  */
+void SystemInit (void)
+{
+#if defined (__FPU_USED) && (__FPU_USED == 1U)
+  SCB->CPACR |= ((3U << 10U * 2U) |         /* set cp10 full access */
+                 (3U << 11U * 2U)  );       /* set cp11 full access */
+#endif
+
+  /* reset the crm clock configuration to the default reset state(for debug purpose) */
+  /* set hicken bit */
+  CRM->ctrl_bit.hicken = TRUE;
+
+  /* wait hick stable */
+  while(CRM->ctrl_bit.hickstbl != SET);
+
+  /* hick used as system clock */
+  CRM->cfg_bit.sclksel = CRM_SCLK_HICK;
+
+  /* wait sclk switch status */
+  while(CRM->cfg_bit.sclksts != CRM_SCLK_HICK);
+
+  /* reset hexten, hextbyps, cfden and pllen bits */
+  CRM->ctrl &= ~(0x010D0000U);
+
+  /* reset cfg register, include sclk switch, ahbdiv, apb1div, apb2div, adcdiv,
+     clkout pllrcs, pllhextdiv, pllmult, usbdiv and pllrange bits */
+  CRM->cfg = 0; 
+
+  /* reset clkout[3], usbbufs, hickdiv, clkoutdiv */
+  CRM->misc1 = 0;
+
+  /* disable all interrupts enable and clear pending bits  */
+  CRM->clkint = 0x009F0000;
+
+#ifdef VECT_TAB_SRAM
+  SCB->VTOR = SRAM_BASE  | VECT_TAB_OFFSET;  /* vector table relocation in internal sram. */
+#else
+  SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET;  /* vector table relocation in internal flash. */
+#endif
+}
+
+/**
+  * @brief  update system_core_clock variable according to clock register values.
+  *         the system_core_clock variable contains the core clock (hclk), it can
+  *         be used by the user application to setup the systick timer or configure
+  *         other parameters.
+  * @param  none
+  * @retval none
+  */
+void system_core_clock_update(void)
+{
+  uint32_t hext_prediv = 0, pll_mult = 0, pll_mult_h = 0, pll_clock_source = 0, temp = 0, div_value = 0;
+  crm_sclk_type sclk_source;
+
+  static const uint8_t sys_ahb_div_table[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
+
+  /* get sclk source */
+  sclk_source = crm_sysclk_switch_status_get();
+
+  switch(sclk_source)
+  {
+    case CRM_SCLK_HICK:
+      if(((CRM->misc3_bit.hick_to_sclk) != RESET) && ((CRM->misc1_bit.hickdiv) != RESET))
+        system_core_clock = HICK_VALUE * 6;
+      else
+        system_core_clock = HICK_VALUE;
+      break;
+    case CRM_SCLK_HEXT:
+      system_core_clock = HEXT_VALUE;
+      break;
+    case CRM_SCLK_PLL:
+      pll_clock_source = CRM->cfg_bit.pllrcs;
+      {
+        /* get multiplication factor */
+        pll_mult = CRM->cfg_bit.pllmult_l;
+        pll_mult_h = CRM->cfg_bit.pllmult_h;
+        /* process high bits */
+        if((pll_mult_h != 0U) || (pll_mult == 15U)){
+            pll_mult += ((16U * pll_mult_h) + 1U);
+        }
+        else
+        {
+            pll_mult += 2U;
+        }
+
+        if (pll_clock_source == 0x00)
+        {
+          /* hick divided by 2 selected as pll clock entry */
+          system_core_clock = (HICK_VALUE >> 1) * pll_mult;
+        }
+        else
+        {
+          /* hext selected as pll clock entry */
+          if (CRM->cfg_bit.pllhextdiv != RESET)
+          {
+            hext_prediv = CRM->misc3_bit.hextdiv;
+
+            /* hext clock divided by 2 */
+            system_core_clock = (HEXT_VALUE / (hext_prediv + 2)) * pll_mult;
+          }
+          else
+          {
+            system_core_clock = HEXT_VALUE * pll_mult;
+          }
+        }
+      }
+      break;
+    default:
+      system_core_clock = HICK_VALUE;
+      break;
+  }
+
+  /* compute sclk, ahbclk frequency */
+  /* get ahb division */
+  temp = CRM->cfg_bit.ahbdiv;
+  div_value = sys_ahb_div_table[temp];
+  /* ahbclk frequency */
+  system_core_clock = system_core_clock >> div_value;
+}
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+

+ 89 - 0
iap/user/system_at32f403a_407.h

@@ -0,0 +1,89 @@
+/**
+  **************************************************************************
+  * @file     system_at32f403a_407.h
+  * @brief    cmsis cortex-m4 system 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.
+  *
+  **************************************************************************
+  */
+
+#ifndef __SYSTEM_AT32F403A_407_H
+#define __SYSTEM_AT32F403A_407_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @addtogroup CMSIS
+  * @{
+  */
+
+/** @addtogroup AT32F403A_407_system
+  * @{
+  */
+
+/** @defgroup AT32F403A_407_system_clock_stable_definition
+  * @{
+  */
+
+#define HEXT_STABLE_DELAY                (5000u)
+#define PLL_STABLE_DELAY                 (500u)
+#define SystemCoreClock                  system_core_clock
+#define DUMMY_NOP()                      {__NOP();__NOP();__NOP();__NOP();__NOP(); \
+                                          __NOP();__NOP();__NOP();__NOP();__NOP(); \
+                                          __NOP();__NOP();__NOP();__NOP();__NOP(); \
+                                          __NOP();__NOP();__NOP();__NOP();__NOP();}
+
+/**
+  * @}
+  */
+
+/** @defgroup AT32F403A_407_system_exported_variables
+  * @{
+  */
+
+extern unsigned int system_core_clock; /*!< system clock frequency (core clock) */
+
+/**
+  * @}
+  */
+
+/** @defgroup AT32F403A_407_system_exported_functions
+  * @{
+  */
+
+extern void SystemInit(void);
+extern void system_core_clock_update(void);
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

BIN
output/crc_ewarm.exe


BIN
output/fw.bin


File diff suppressed because it is too large
+ 468 - 688
project/ewarm/iap/iap.dep


+ 23 - 6
project/ewarm/iap/iap.ewp

@@ -370,6 +370,8 @@
                     <state>$PROJ_DIR$\..\..\..\shared\freemodbus\include</state>
                     <state>$PROJ_DIR$\..\..\..\shared\freemodbus\port</state>
                     <state>$PROJ_DIR$\..\..\..\shared\freemodbus\rtu</state>
+                    <state>$PROJ_DIR$\..\..\..\shared\model</state>
+                    <state>$PROJ_DIR$\..\..\..\shared\rtc</state>
                     <state>$PROJ_DIR$\..\..\..\iap\modules\modbus</state>
                     <state>$PROJ_DIR$\..\..\..\iap\modules\settings</state>
                     <state>$PROJ_DIR$\..\..\..\iap\modules\iap</state>
@@ -2146,6 +2148,9 @@
                     <name>$PROJ_DIR$\..\..\..\iap\modules\io\mux.c</name>
                 </file>
             </group>
+            <group>
+                <name>misc</name>
+            </group>
             <group>
                 <name>modbus</name>
                 <file>
@@ -2173,6 +2178,9 @@
             <file>
                 <name>$PROJ_DIR$\..\..\..\iap\user\main.c</name>
             </file>
+            <file>
+                <name>$PROJ_DIR$\..\..\..\iap\user\system_at32f403a_407.c</name>
+            </file>
         </group>
     </group>
     <group>
@@ -2187,12 +2195,6 @@
                 <file>
                     <name>$PROJ_DIR$\..\..\..\libs\artery\cmsis\cm4\device_support\startup\iar\startup_at32f403a_407.s</name>
                 </file>
-                <file>
-                    <name>$PROJ_DIR$\..\..\..\libs\artery\cmsis\cm4\device_support\system_at32f403a_407.c</name>
-                </file>
-                <file>
-                    <name>$PROJ_DIR$\..\..\..\libs\artery\cmsis\cm4\device_support\system_at32f403a_407.h</name>
-                </file>
             </group>
             <group>
                 <name>drivers</name>
@@ -2358,6 +2360,9 @@
                 <file>
                     <name>$PROJ_DIR$\..\..\..\shared\freemodbus\functions\mbfuncdisc.c</name>
                 </file>
+                <file>
+                    <name>$PROJ_DIR$\..\..\..\shared\freemodbus\functions\mbfuncfile.c</name>
+                </file>
                 <file>
                     <name>$PROJ_DIR$\..\..\..\shared\freemodbus\functions\mbfuncholding.c</name>
                 </file>
@@ -2432,12 +2437,24 @@
                 <name>$PROJ_DIR$\..\..\..\shared\freemodbus\mb.c</name>
             </file>
         </group>
+        <group>
+            <name>model</name>
+            <file>
+                <name>$PROJ_DIR$\..\..\..\shared\model\model_cfg.h</name>
+            </file>
+        </group>
         <group>
             <name>peripherals</name>
             <file>
                 <name>$PROJ_DIR$\..\..\..\shared\peripherals\src\common_gpio.c</name>
             </file>
         </group>
+        <group>
+            <name>rtc</name>
+            <file>
+                <name>$PROJ_DIR$\..\..\..\shared\rtc\rtc.c</name>
+            </file>
+        </group>
         <group>
             <name>sys</name>
             <file>

+ 21 - 6
project/ewarm/iap/iap.ewt

@@ -2385,6 +2385,9 @@
                     <name>$PROJ_DIR$\..\..\..\iap\modules\io\mux.c</name>
                 </file>
             </group>
+            <group>
+                <name>misc</name>
+            </group>
             <group>
                 <name>modbus</name>
                 <file>
@@ -2412,6 +2415,9 @@
             <file>
                 <name>$PROJ_DIR$\..\..\..\iap\user\main.c</name>
             </file>
+            <file>
+                <name>$PROJ_DIR$\..\..\..\iap\user\system_at32f403a_407.c</name>
+            </file>
         </group>
     </group>
     <group>
@@ -2426,12 +2432,6 @@
                 <file>
                     <name>$PROJ_DIR$\..\..\..\libs\artery\cmsis\cm4\device_support\startup\iar\startup_at32f403a_407.s</name>
                 </file>
-                <file>
-                    <name>$PROJ_DIR$\..\..\..\libs\artery\cmsis\cm4\device_support\system_at32f403a_407.c</name>
-                </file>
-                <file>
-                    <name>$PROJ_DIR$\..\..\..\libs\artery\cmsis\cm4\device_support\system_at32f403a_407.h</name>
-                </file>
             </group>
             <group>
                 <name>drivers</name>
@@ -2597,6 +2597,9 @@
                 <file>
                     <name>$PROJ_DIR$\..\..\..\shared\freemodbus\functions\mbfuncdisc.c</name>
                 </file>
+                <file>
+                    <name>$PROJ_DIR$\..\..\..\shared\freemodbus\functions\mbfuncfile.c</name>
+                </file>
                 <file>
                     <name>$PROJ_DIR$\..\..\..\shared\freemodbus\functions\mbfuncholding.c</name>
                 </file>
@@ -2671,12 +2674,24 @@
                 <name>$PROJ_DIR$\..\..\..\shared\freemodbus\mb.c</name>
             </file>
         </group>
+        <group>
+            <name>model</name>
+            <file>
+                <name>$PROJ_DIR$\..\..\..\shared\model\model_cfg.h</name>
+            </file>
+        </group>
         <group>
             <name>peripherals</name>
             <file>
                 <name>$PROJ_DIR$\..\..\..\shared\peripherals\src\common_gpio.c</name>
             </file>
         </group>
+        <group>
+            <name>rtc</name>
+            <file>
+                <name>$PROJ_DIR$\..\..\..\shared\rtc\rtc.c</name>
+            </file>
+        </group>
         <group>
             <name>sys</name>
             <file>

File diff suppressed because it is too large
+ 671 - 683
project/ewarm/module_universal_io.dep


+ 11 - 10
project/ewarm/module_universal_io.ewp

@@ -371,6 +371,7 @@
                     <state>$PROJ_DIR$\..\..\shared\freemodbus\port</state>
                     <state>$PROJ_DIR$\..\..\shared\freemodbus\rtu</state>
                     <state>$PROJ_DIR$\..\..\shared\sys</state>
+                    <state>$PROJ_DIR$\..\..\shared\rtc</state>
                     <state>$PROJ_DIR$\..\..\fw\modules\usb</state>
                     <state>$PROJ_DIR$\..\..\fw\modules\io</state>
                     <state>$PROJ_DIR$\..\..\fw\modules\misc</state>
@@ -887,7 +888,7 @@
                 </option>
                 <option>
                     <name>DoFill</name>
-                    <state>1</state>
+                    <state>0</state>
                 </option>
                 <option>
                     <name>FillerByte</name>
@@ -2218,9 +2219,6 @@
                 <file>
                     <name>$PROJ_DIR$\..\..\fw\modules\misc\misc.c</name>
                 </file>
-                <file>
-                    <name>$PROJ_DIR$\..\..\fw\modules\misc\rtc.c</name>
-                </file>
                 <file>
                     <name>$PROJ_DIR$\..\..\fw\modules\misc\swap.c</name>
                 </file>
@@ -2309,6 +2307,9 @@
             <file>
                 <name>$PROJ_DIR$\..\..\fw\user\MicroRLConfig.h</name>
             </file>
+            <file>
+                <name>$PROJ_DIR$\..\..\fw\user\system_at32f403a_407.c</name>
+            </file>
             <file>
                 <name>$PROJ_DIR$\..\..\fw\user\usb_conf.h</name>
             </file>
@@ -2326,12 +2327,6 @@
                 <file>
                     <name>$PROJ_DIR$\..\..\libs\artery\cmsis\cm4\device_support\startup\iar\startup_at32f403a_407.s</name>
                 </file>
-                <file>
-                    <name>$PROJ_DIR$\..\..\libs\artery\cmsis\cm4\device_support\system_at32f403a_407.c</name>
-                </file>
-                <file>
-                    <name>$PROJ_DIR$\..\..\libs\artery\cmsis\cm4\device_support\system_at32f403a_407.h</name>
-                </file>
             </group>
             <group>
                 <name>drivers</name>
@@ -2787,6 +2782,12 @@
                 <name>$PROJ_DIR$\..\..\shared\peripherals\src\usb.c</name>
             </file>
         </group>
+        <group>
+            <name>rtc</name>
+            <file>
+                <name>$PROJ_DIR$\..\..\shared\rtc\rtc.c</name>
+            </file>
+        </group>
         <group>
             <name>sys</name>
             <file>

+ 9 - 9
project/ewarm/module_universal_io.ewt

@@ -2429,9 +2429,6 @@
                 <file>
                     <name>$PROJ_DIR$\..\..\fw\modules\misc\misc.c</name>
                 </file>
-                <file>
-                    <name>$PROJ_DIR$\..\..\fw\modules\misc\rtc.c</name>
-                </file>
                 <file>
                     <name>$PROJ_DIR$\..\..\fw\modules\misc\swap.c</name>
                 </file>
@@ -2520,6 +2517,9 @@
             <file>
                 <name>$PROJ_DIR$\..\..\fw\user\MicroRLConfig.h</name>
             </file>
+            <file>
+                <name>$PROJ_DIR$\..\..\fw\user\system_at32f403a_407.c</name>
+            </file>
             <file>
                 <name>$PROJ_DIR$\..\..\fw\user\usb_conf.h</name>
             </file>
@@ -2537,12 +2537,6 @@
                 <file>
                     <name>$PROJ_DIR$\..\..\libs\artery\cmsis\cm4\device_support\startup\iar\startup_at32f403a_407.s</name>
                 </file>
-                <file>
-                    <name>$PROJ_DIR$\..\..\libs\artery\cmsis\cm4\device_support\system_at32f403a_407.c</name>
-                </file>
-                <file>
-                    <name>$PROJ_DIR$\..\..\libs\artery\cmsis\cm4\device_support\system_at32f403a_407.h</name>
-                </file>
             </group>
             <group>
                 <name>drivers</name>
@@ -2998,6 +2992,12 @@
                 <name>$PROJ_DIR$\..\..\shared\peripherals\src\usb.c</name>
             </file>
         </group>
+        <group>
+            <name>rtc</name>
+            <file>
+                <name>$PROJ_DIR$\..\..\shared\rtc\rtc.c</name>
+            </file>
+        </group>
         <group>
             <name>sys</name>
             <file>

+ 2 - 0
shared/model/model_cfg.h

@@ -22,6 +22,8 @@
 
 static const uint16_t model_code = MODEL_CODE;
 
+#define MODEL_ADDR          0x080211F0
+
 #define MODEL_LEN           16
 
 

+ 1 - 2
fw/modules/misc/rtc.c → shared/rtc/rtc.c

@@ -1,8 +1,7 @@
 #include "rtc.h"
-#include "lwip/apps/sntp.h"
 #include "settings_api.h"
 #include <string.h>
-
+#include <stdio.h>
 
 //TM_RTC_t calendar;
 

+ 0 - 0
fw/modules/misc/rtc.h → shared/rtc/rtc.h


BIN
tools/__pycache__/updater.cpython-310.pyc


+ 5 - 2
tools/digital_io.py

@@ -20,13 +20,13 @@ class IO_Digital(IO_Module):
 def main():
     colorama.init(autoreset=True)
     dev = IO_Digital('COM24', 115200, 15)
-    dev.MB_DEBUG = False
+    dev.MB_DEBUG = True
 
     '''Системные переменные и параметры'''
     dev.sys.get_system_vars()
 
     ''' Установить текущее время с учетом часового пояса'''
-    dev.sys.set_rtc()     
+    # dev.sys.set_rtc()     
     
 
     '''Лог и архив. Настройки лога.'''
@@ -37,6 +37,9 @@ def main():
 
     '''Сохранение настроек'''
     # dev.sys.save_sattings()
+
+    '''Обновление'''
+    # dev.updater.update('fw.bin', 'MDIO-88')
     
     
 if __name__ == '__main__':

BIN
tools/fw.bin


+ 13 - 0
tools/time_test.py

@@ -24,5 +24,18 @@ def main():
     
     print(f'RTC: {time.ctime(1722011409)}. Unix time stamp:')
 
+    model = "MDIO-88"
+    # model_bytes = bytearray()
+    model_bytes = model.ljust(16, '\n').encode('ascii')
+
+
+    for i in model:
+        print(hex(ord(i)))
+        # model_bytes.append(ord(i))
+        # model_bytes += ord(i)
+
+    print(model)
+    print(model_bytes)
+
 if __name__ == '__main__':
     main()

+ 6 - 5
tools/updater.py

@@ -13,11 +13,12 @@ class Updater:
         request = bytes((self.modbus.address, 0x41, 0x01))
         response = self.modbus.raw_communicate(request + self.modbus._crc(request))
 
-    def write_fw_start(self, size: int):
+    def write_fw_start(self, size: int, model: str):
         """Ask device to start update"""
         self.update_segment_number = 0
-        request = bytes((self.modbus.address, 0x41, 0x01, 0xEF, 0xBE, 0xAD, 0xDE)) + size.to_bytes(4, 'big')
-        response = self.modbus.raw_communicate(request + self._crc(request), 5)
+        # request = bytes((self.modbus.address, 0x41, 0x01, 0xEF, 0xBE, 0xAD, 0xDE)) + size.to_bytes(4, 'big')
+        request = bytes((self.modbus.address, 0x41, 0x01, 0xEF, 0xBE, 0xAD, 0xDE)) + size.to_bytes(4, 'big') + model.ljust(16, '\0').encode('ascii') 
+        response = self.modbus.raw_communicate(request + self.modbus._crc(request), 5)
         if len(response) == 0:
             raise NoResponseError('No response on WRITE_START command')
         if len(response) != 5:
@@ -46,14 +47,14 @@ class Updater:
         if response[:3] != header:
             raise MBError('Incorrect response')
 
-    def update(self, path):
+    def update(self, path, model):
         self.modbus.MB_TIMEOUT = 3
         size = os.path.getsize('fw.bin')
         print('Switch to IAP mode')
         self.iap_start()
         time.sleep(4)
         print(f'Start writing {size} bytes of FW')
-        self.write_fw_start(size)
+        self.write_fw_start(size, model)
         time.sleep(2)
         print(f'Open FW file "{path}"...')
         with open(path, 'rb') as f:

Some files were not shown because too many files changed in this diff