/* add user code begin Header */ /** ************************************************************************** * @file main.c * @brief main program ************************************************************************** * Copyright notice & Disclaimer * * The software Board Support Package (BSP) that is made available to * download from Artery official website is the copyrighted work of Artery. * Artery authorizes customers to use, copy, and distribute the BSP * software and its related documentation for the purpose of design and * development in conjunction with Artery microcontrollers. Use of the * software is governed by this copyright notice and the following disclaimer. * * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. * ************************************************************************** */ /* add user code end Header */ /* Includes ------------------------------------------------------------------*/ #include "at32f403a_407_wk_config.h" #include "wk_acc.h" #include "wk_debug.h" #include "wk_spi.h" #include "wk_usbfs.h" #include "usb_app.h" #include "wk_system.h" #include "includes.h" #include #include "W25Q128.h" #include "Drv_TM1617_RGB.h" #include "UI0902_Res_Addr.h" #include "drv_nvm.h" #include "boot_flash_mode_ink.h" /* private includes ----------------------------------------------------------*/ /* add user code begin private includes */ /* add user code end private includes */ /* private typedef -----------------------------------------------------------*/ /* add user code begin private typedef */ /* add user code end private typedef */ /* private define ------------------------------------------------------------*/ /* add user code begin private define */ // // Power Button // #define POWER_BUTTON_PIN GPIO_PINS_2 #define POWER_BUTTON_PORT GPIOD // // Main Power // #define S_PWR_ON_OFF_Pin GPIO_PINS_2 #define S_PWR_ON_OFF_GPIO_Port GPIOB #define FIRMWARE_START_ADDR 0x08008000 /* add user code end private define */ /* private macro -------------------------------------------------------------*/ /* add user code begin private macro */ /* add user code end private macro */ /* private variables ---------------------------------------------------------*/ /* add user code begin private variables */ /* add user code end private variables */ /* private function prototypes --------------------------------------------*/ /* add user code begin function prototypes */ /* add user code end function prototypes */ /* private user code ---------------------------------------------------------*/ /* add user code begin 0 */ void wk_gpio_config(void); void JumpToApplication(void); uint8_t TM1617KeyValue = 0; static uint32_t PowerKeyCount = 0; static uint8_t long_press_locked = 0; // ??????????????????? /* add user code end 0 */ static uint16_t Boot_NvmSum(const uint8_t *p, uint16_t len) { uint16_t sum = 0; while (len > 0) { sum = (uint16_t)(sum + *p++); len--; } return sum; } static uint8_t Boot_NvmUsbUpdateRequested(void) { const NvmData_Type *nvm = (const NvmData_Type *)INNER_FLASH_SAVE_ADDRESS; uint16_t s0 = Boot_NvmSum((const uint8_t *)&nvm->data, sizeof(NvmParam_Type)); if (s0 != nvm->sum[0] || (uint16_t)(~s0) != nvm->sum[1]) return 0; if (nvm->data.nvm_version != NVM_VERSION) return 0; return (nvm->data.param.UsbMode == NVM_USB_UPDATE) ? 1 : 0; } /* 外部图把字画成了页面底色,铺出来是黑屏。字行中间有接近白色的像素才采用它。 */ static uint8_t Boot_FlashModeHasLight(void) { uint8_t row[172]; uint16_t i; W25Q128_Read(row, UI0902_FLASH_MODE_ADDR + (158ul * 240ul + 78ul) * 2ul, (uint16_t)sizeof(row)); for (i = 0; i + 1u < sizeof(row); i += 2) { uint16_t c = (uint16_t)(((uint16_t)row[i] << 8) | row[i + 1]); if (c >= 0xC618) return 1; } return 0; } static void Boot_DrawFlashModeInk(void) { uint16_t row, col, stride; LCD_FillByColor(0, 0, 240, 320, 0x0042); stride = (uint16_t)((BOOT_FLASH_INK_W + 7u) >> 3); for (row = 0; row < BOOT_FLASH_INK_H; row++) { const uint8_t *p = boot_flash_ink + (uint32_t)row * stride; for (col = 0; col < BOOT_FLASH_INK_W; col++) { if (p[col >> 3] & (uint8_t)(0x80u >> (col & 7))) LCD_DrawPoint((uint16_t)(BOOT_FLASH_INK_X + col), (uint16_t)(BOOT_FLASH_INK_Y + row), WHITE); } } } static void Boot_NvmClearUsbUpdate(void) { NvmData_Type tmp; uint16_t s0; uint32_t i; uint32_t words; uint32_t buf[(sizeof(NvmData_Type) + 3) / 4]; memcpy(&tmp, (const void *)INNER_FLASH_SAVE_ADDRESS, sizeof(tmp)); if (tmp.data.param.UsbMode != NVM_USB_UPDATE) return; tmp.data.param.UsbMode = NVM_USB_MIDI; s0 = Boot_NvmSum((const uint8_t *)&tmp.data, sizeof(NvmParam_Type)); tmp.sum[0] = s0; tmp.sum[1] = (uint16_t)(~s0); memset(buf, 0xFF, sizeof(buf)); memcpy(buf, &tmp, sizeof(tmp)); words = (sizeof(tmp) + 3) / 4; flash_unlock(); flash_sector_erase(INNER_FLASH_SECTOR_ADDRESS); for (i = 0; i < words; i++) flash_word_program(INNER_FLASH_SAVE_ADDRESS + i * 4, buf[i]); flash_lock(); } flag_status BSP_GetPowerKey (void) { return gpio_input_data_bit_read(POWER_BUTTON_PORT, POWER_BUTTON_PIN); } void BSP_MainPowerEnable (uint8_t Enable) { if (Enable) gpio_bits_set(S_PWR_ON_OFF_GPIO_Port, S_PWR_ON_OFF_Pin); else gpio_bits_reset(S_PWR_ON_OFF_GPIO_Port, S_PWR_ON_OFF_Pin); } /** * @brief main function. * @param none * @retval none */ int main(void) { /* add user code begin 1 */ /* add user code end 1 */ /* system clock config. */ wk_system_clock_config(); /* config periph clock. */ wk_periph_clock_config(); /* gpio config */ wk_gpio_config(); /* init debug function. */ wk_debug_config(); /* nvic config. */ wk_nvic_config(); /* timebase config. */ wk_timebase_init(); TM1617_GPIO_Init(); /* 按住圆键 4(KEY_MAIN_A),或 App 确认了 USB 更新,都停在烧录。 * USB 更新有两处标志:Flash 里的 UsbMode,以及复位后仍在的备份寄存器。 * 没按键且两处都没有标志才跳进 App。 */ wk_delay_ms(50); TM1617KeyValue = TM1617_ScanFkey(); if (TM1617KeyValue != KEY_MAIN_A && !Boot_NvmUsbUpdateRequested() && !drv_nvm_usb_boot_armed()) { JumpToApplication(); } /* init spi1 function. */ BSP_MainPowerEnable(1); wk_spi1_init(); /* init spi2 function. */ /* init acc function. */ wk_acc_init(); /* add user code begin 2 */ W25Q128_Init(); LCD_Init(); wk_delay_ms(10); /* USER CODE BEGIN 2 */ LCD_BLK_Set(); /* ���???��?��UI0902_FLASH_MODE @ ���� Flash��?����??�??��� */ { uint8_t peek[4]; W25Q128_Read(peek, UI0902_FLASH_MODE_ADDR, 4); if (!(peek[0] == 0xFF && peek[1] == 0xFF && peek[2] == 0xFF && peek[3] == 0xFF) && Boot_FlashModeHasLight()) { LCD_WR_PIC_FROM_FLASH(0, 0, UI0902_FLASH_MODE_W, UI0902_FLASH_MODE_H, UI0902_FLASH_MODE_ADDR); } else { Boot_DrawFlashModeInk(); } } /* 画面出来后再清标志,避免还没进烧录就被下一次复位跳回 App。 * 擦写与 Boot 同在 Flash Bank1,期间关掉中断。 */ if (Boot_NvmUsbUpdateRequested() || drv_nvm_usb_boot_armed()) { __disable_irq(); if (Boot_NvmUsbUpdateRequested()) Boot_NvmClearUsbUpdate(); drv_nvm_clear_usb_boot_arm(); __enable_irq(); } wk_usbfs_init(); wk_usb_app_init(); /* add user code end 2 */ while(1) { /* add user code begin 3 */ if(BSP_GetPowerKey() == 0) { // ???????? if (PowerKeyCount < 200 && long_press_locked == 0) { PowerKeyCount++; } if (PowerKeyCount >= 150 && long_press_locked == 0) { LCD_BLK_Clr(); BSP_MainPowerEnable(0); wk_delay_ms(3000); } wk_delay_ms(10); } /* add user code end 3 */ } } /* add user code begin 4 */ void wk_gpio_config(void) { /* add user code begin gpio_config 0 */ /* add user code end gpio_config 0 */ gpio_init_type gpio_init_struct; gpio_default_para_init(&gpio_init_struct); /* add user code begin gpio_config 1 */ crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE); crm_periph_clock_enable(CRM_GPIOC_PERIPH_CLOCK, TRUE); /* add user code end gpio_config 1 */ /* gpio input config */ gpio_init_struct.gpio_mode = GPIO_MODE_INPUT; gpio_init_struct.gpio_pins = GPIO_PINS_2; gpio_init_struct.gpio_pull = GPIO_PULL_NONE; gpio_init(GPIOD, &gpio_init_struct); /* gpio output config */ gpio_bits_reset(GPIOB, GPIO_PINS_9 | GPIO_PINS_2); gpio_bits_set(GPIOC, GPIO_PINS_13); gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE; gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT; gpio_init_struct.gpio_pins = GPIO_PINS_13; gpio_init_struct.gpio_pull = GPIO_PULL_NONE; gpio_init(GPIOC, &gpio_init_struct); gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE; gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT; gpio_init_struct.gpio_pins = GPIO_PINS_2 | GPIO_PINS_9; gpio_init_struct.gpio_pull = GPIO_PULL_NONE; gpio_init(GPIOB, &gpio_init_struct); /* gpio analog config */ /* add user code begin gpio_config 2 */ /* add user code end gpio_config 2 */ } /* add user code end 4 */ void JumpToApplication(void) { typedef void (*pFunction)(void); pFunction Jump_To_Application; uint32_t JumpAddress; if (((*(__IO uint32_t*)FIRMWARE_START_ADDR) & 0x2FFE0000 ) == 0x20000000) { /* ???????????????? */ JumpAddress = *(__IO uint32_t*) (FIRMWARE_START_ADDR + 4); Jump_To_Application = (pFunction) JumpAddress; /* ??????????��????????? */ __set_MSP(*(__IO uint32_t*) FIRMWARE_START_ADDR); SCB->VTOR = FIRMWARE_START_ADDR; Jump_To_Application(); } }