/************************************************************************************//** * \file Demo/ARMCM0_STM32G0_Nucleo_G071RB_Keil/Prog/boot.c * \brief Demo program bootloader interface source file. * \ingroup Prog_ARMCM0_STM32G0_Nucleo_G071RB_Keil * \internal *---------------------------------------------------------------------------------------- * C O P Y R I G H T *---------------------------------------------------------------------------------------- * Copyright (c) 2019 by Feaser http://www.feaser.com All rights reserved * *---------------------------------------------------------------------------------------- * L I C E N S E *---------------------------------------------------------------------------------------- * This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any later * version. * * OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You have received a copy of the GNU General Public License along with OpenBLT. It * should be located in ".\Doc\license.html". If not, contact Feaser to obtain a copy. * * \endinternal ****************************************************************************************/ /**************************************************************************************** * Include files ****************************************************************************************/ #include "header.h" /* generic header */ /**************************************************************************************** * Function prototypes ****************************************************************************************/ #if (BOOT_COM_RS232_ENABLE > 0) static void BootComRs232Init(void); static void BootComRs232CheckActivationRequest(void); #endif /************************************************************************************//** ** \brief Initializes the communication interface. ** \return none. ** ****************************************************************************************/ void BootComInit(void) { #if (BOOT_COM_RS232_ENABLE > 0) BootComRs232Init(); #endif } /*** end of BootComInit ***/ /************************************************************************************//** ** \brief Receives the CONNECT request from the host, which indicates that the ** bootloader should be activated and, if so, activates it. ** \return none. ** ****************************************************************************************/ void BootComCheckActivationRequest(void) { #if (BOOT_COM_RS232_ENABLE > 0) BootComRs232CheckActivationRequest(); #endif } /*** end of BootComCheckActivationRequest ***/ /************************************************************************************//** ** \brief Bootloader activation function. ** \return none. ** ****************************************************************************************/ void BootActivate(void) { /* perform software reset to activate the bootoader again */ NVIC_SystemReset(); } /*** end of BootActivate ***/ #if (BOOT_COM_RS232_ENABLE > 0) /**************************************************************************************** * U N I V E R S A L A S Y N C H R O N O U S R X T X I N T E R F A C E ****************************************************************************************/ /**************************************************************************************** * Macro definitions ****************************************************************************************/ /** \brief Timeout time for the reception of a CTO packet. The timer is started upon * reception of the first packet byte. */ #define RS232_CTO_RX_PACKET_TIMEOUT_MS (100u) /**************************************************************************************** * Local data declarations ****************************************************************************************/ /** \brief UART handle to be used in API calls. */ static UART_HandleTypeDef rs232Handle; /**************************************************************************************** * Function prototypes ****************************************************************************************/ static unsigned char Rs232ReceiveByte(unsigned char *data); /************************************************************************************//** ** \brief Initializes the UART communication interface. ** \return none. ** ****************************************************************************************/ static void BootComRs232Init(void) { /* Configure UART peripheral. */ rs232Handle.Instance = USART2; rs232Handle.Init.BaudRate = BOOT_COM_RS232_BAUDRATE; rs232Handle.Init.WordLength = UART_WORDLENGTH_8B; rs232Handle.Init.StopBits = UART_STOPBITS_1; rs232Handle.Init.Parity = UART_PARITY_NONE; rs232Handle.Init.HwFlowCtl = UART_HWCONTROL_NONE; rs232Handle.Init.Mode = UART_MODE_TX_RX; rs232Handle.Init.OverSampling = UART_OVERSAMPLING_16; rs232Handle.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_ENABLE; rs232Handle.Init.ClockPrescaler = UART_PRESCALER_DIV1; /* Initialize the UART peripheral. */ HAL_UART_Init(&rs232Handle); } /*** end of BootComRs232Init ***/ /************************************************************************************//** ** \brief Receives the CONNECT request from the host, which indicates that the ** bootloader should be activated and, if so, activates it. ** \return none. ** ****************************************************************************************/ static void BootComRs232CheckActivationRequest(void) { static unsigned char xcpCtoReqPacket[BOOT_COM_RS232_RX_MAX_DATA+1]; static unsigned char xcpCtoRxLength; static unsigned char xcpCtoRxInProgress = 0; static unsigned long xcpCtoRxStartTime = 0; /* start of cto packet received? */ if (xcpCtoRxInProgress == 0) { /* store the message length when received */ if (Rs232ReceiveByte(&xcpCtoReqPacket[0]) == 1) { /* check that the length has a valid value. it should not be 0 */ if ( (xcpCtoReqPacket[0] > 0) && (xcpCtoReqPacket[0] <= BOOT_COM_RS232_RX_MAX_DATA) ) { /* store the start time */ xcpCtoRxStartTime = TimerGet(); /* indicate that a cto packet is being received */ xcpCtoRxInProgress = 1; /* reset packet data count */ xcpCtoRxLength = 0; } } } else { /* store the next packet byte */ if (Rs232ReceiveByte(&xcpCtoReqPacket[xcpCtoRxLength+1]) == 1) { /* increment the packet data count */ xcpCtoRxLength++; /* check to see if the entire packet was received */ if (xcpCtoRxLength == xcpCtoReqPacket[0]) { /* done with cto packet reception */ xcpCtoRxInProgress = 0; /* check if this was an XCP CONNECT command */ if ((xcpCtoReqPacket[1] == 0xff) && (xcpCtoRxLength == 2)) { /* connection request received so start the bootloader */ BootActivate(); } } } else { /* check packet reception timeout */ if (TimerGet() > (xcpCtoRxStartTime + RS232_CTO_RX_PACKET_TIMEOUT_MS)) { /* cancel cto packet reception due to timeout. note that this automatically * discards the already received packet bytes, allowing the host to retry. */ xcpCtoRxInProgress = 0; } } } } /*** end of BootComRs232CheckActivationRequest ***/ /************************************************************************************//** ** \brief Receives a communication interface byte if one is present. ** \param data Pointer to byte where the data is to be stored. ** \return 1 if a byte was received, 0 otherwise. ** ****************************************************************************************/ static unsigned char Rs232ReceiveByte(unsigned char *data) { HAL_StatusTypeDef result; /* receive a byte in a non-blocking manner */ result = HAL_UART_Receive(&rs232Handle, data, 1, 0); /* process the result */ if (result == HAL_OK) { /* success */ return 1; } /* error occurred */ return 0; } /*** end of Rs232ReceiveByte ***/ #endif /* BOOT_COM_RS232_ENABLE > 0 */ /*********************************** end of boot.c *************************************/