This commit is contained in:
Mysteo
2023-06-29 19:23:00 +03:00
commit bebfc1b5ab
415 changed files with 294688 additions and 0 deletions

View File

@@ -0,0 +1,56 @@
/************************************************************************************//**
* \file Source/ARMCM0_STM32G0/GCC/cpu_comp.c
* \brief Bootloader cpu module source file.
* \ingroup Target_ARMCM0_STM32G0
* \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 "boot.h" /* bootloader generic header */
/************************************************************************************//**
** \brief Disable global interrupts.
** \return none.
**
****************************************************************************************/
void CpuIrqDisable(void)
{
__asm volatile ("cpsid i");
} /*** end of CpuIrqDisable ***/
/************************************************************************************//**
** \brief Enable global interrupts.
** \return none.
**
****************************************************************************************/
void CpuIrqEnable(void)
{
__asm volatile ("cpsie i");
} /*** end of CpuIrqEnable ***/
/*********************************** end of cpu_comp.c *********************************/

View File

@@ -0,0 +1,57 @@
/************************************************************************************//**
* \file Source/ARMCM0_STM32G0/IAR/cpu_comp.c
* \brief Bootloader cpu module source file.
* \ingroup Target_ARMCM0_STM32G0
* \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 "boot.h" /* bootloader generic header */
#include <intrinsics.h> /* IAR intrinsics */
/************************************************************************************//**
** \brief Disable global interrupts.
** \return none.
**
****************************************************************************************/
void CpuIrqDisable(void)
{
__disable_interrupt();
} /*** end of CpuIrqDisable ***/
/************************************************************************************//**
** \brief Enable global interrupts.
** \return none.
**
****************************************************************************************/
void CpuIrqEnable(void)
{
__enable_interrupt();
} /*** end of CpuIrqEnable ***/
/*********************************** end of cpu_comp.c *********************************/

View File

@@ -0,0 +1,56 @@
/************************************************************************************//**
* \file Source/ARMCM0_STM32G0/Keil/cpu_comp.c
* \brief Bootloader cpu module source file.
* \ingroup Target_ARMCM0_STM32G0
* \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 "boot.h" /* bootloader generic header */
/************************************************************************************//**
** \brief Disable global interrupts.
** \return none.
**
****************************************************************************************/
void CpuIrqDisable(void)
{
__asm volatile ("cpsid i");
} /*** end of CpuIrqDisable ***/
/************************************************************************************//**
** \brief Enable global interrupts.
** \return none.
**
****************************************************************************************/
void CpuIrqEnable(void)
{
__asm volatile ("cpsie i");
} /*** end of CpuIrqEnable ***/
/*********************************** end of cpu_comp.c *********************************/

387
Boot/ARMCM0_STM32G0/can.c Normal file
View File

@@ -0,0 +1,387 @@
/************************************************************************************//**
* \file Source/ARMCM0_STM32G0/can.c
* \brief Bootloader CAN communication interface source file.
* \ingroup Target_ARMCM0_STM32G0
* \internal
*----------------------------------------------------------------------------------------
* C O P Y R I G H T
*----------------------------------------------------------------------------------------
* Copyright (c) 2021 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 "boot.h" /* bootloader generic header */
#if (BOOT_COM_CAN_ENABLE > 0)
#include "stm32g0xx.h" /* STM32 CPU and HAL header */
#include "stm32g0xx_ll_rcc.h" /* STM32 LL RCC header */
/****************************************************************************************
* Macro definitions
****************************************************************************************/
/** \brief Timeout for transmitting a CAN message in milliseconds. */
#define CAN_MSG_TX_TIMEOUT_MS (50u)
/* map the configured CAN channel index to the STM32's CAN peripheral */
#if (BOOT_COM_CAN_CHANNEL_INDEX == 0)
/** \brief Set CAN base address to CAN1. */
#define CAN_CHANNEL FDCAN1
#elif (BOOT_COM_CAN_CHANNEL_INDEX == 1)
/** \brief Set CAN base address to CAN2. */
#define CAN_CHANNEL FDCAN2
#endif
/****************************************************************************************
* Type definitions
****************************************************************************************/
/** \brief Structure type for grouping CAN bus timing related information. */
typedef struct t_can_bus_timing
{
blt_int8u tseg1; /**< CAN time segment 1 */
blt_int8u tseg2; /**< CAN time segment 2 */
} tCanBusTiming;
/****************************************************************************************
* Local constant declarations
****************************************************************************************/
/** \brief CAN bittiming table for dynamically calculating the bittiming settings.
* \details According to the CAN protocol 1 bit-time can be made up of between 8..25
* time quanta (TQ). The total TQ in a bit is SYNC + TSEG1 + TSEG2 with SYNC
* always being 1. The sample point is (SYNC + TSEG1) / (SYNC + TSEG1 + SEG2) *
* 100%. This array contains possible and valid time quanta configurations with
* a sample point between 68..78%.
*/
static const tCanBusTiming canTiming[] =
{
/* TQ | TSEG1 | TSEG2 | SP */
/* ------------------------- */
{ 5, 2 }, /* 8 | 5 | 2 | 75% */
{ 6, 2 }, /* 9 | 6 | 2 | 78% */
{ 6, 3 }, /* 10 | 6 | 3 | 70% */
{ 7, 3 }, /* 11 | 7 | 3 | 73% */
{ 8, 3 }, /* 12 | 8 | 3 | 75% */
{ 9, 3 }, /* 13 | 9 | 3 | 77% */
{ 9, 4 }, /* 14 | 9 | 4 | 71% */
{ 10, 4 }, /* 15 | 10 | 4 | 73% */
{ 11, 4 }, /* 16 | 11 | 4 | 75% */
{ 12, 4 }, /* 17 | 12 | 4 | 76% */
{ 12, 5 }, /* 18 | 12 | 5 | 72% */
{ 13, 5 }, /* 19 | 13 | 5 | 74% */
{ 14, 5 }, /* 20 | 14 | 5 | 75% */
{ 15, 5 }, /* 21 | 15 | 5 | 76% */
{ 15, 6 }, /* 22 | 15 | 6 | 73% */
{ 16, 6 }, /* 23 | 16 | 6 | 74% */
{ 16, 7 }, /* 24 | 16 | 7 | 71% */
{ 16, 8 } /* 25 | 16 | 8 | 68% */
};
/****************************************************************************************
* Local data declarations
****************************************************************************************/
/** \brief CAN handle to be used in API calls. */
static FDCAN_HandleTypeDef canHandle;
/************************************************************************************//**
** \brief Search algorithm to match the desired baudrate to a possible bus
** timing configuration.
** \param baud The desired baudrate in kbps. Valid values are 10..1000.
** \param prescaler Pointer to where the value for the prescaler will be stored.
** \param tseg1 Pointer to where the value for TSEG2 will be stored.
** \param tseg2 Pointer to where the value for TSEG2 will be stored.
** \return BLT_TRUE if the CAN bustiming register values were found, BLT_FALSE
** otherwise.
**
****************************************************************************************/
static blt_bool CanGetSpeedConfig(blt_int16u baud, blt_int16u *prescaler,
blt_int8u *tseg1, blt_int8u *tseg2)
{
blt_int8u cnt;
blt_int32u canClockFreqkHz;
/* obtain the CAN peripheral clock frequency in kHz. note that it is up to the user
* to configure the desired CAN clock source. By default it is PCLK1. Alternatives
* are HSE or PLLQ. To meet the clock tolerance requirement of CAN 2.0B, an external
* crystal oscillator (HSE) is recommended.
* whichever CAN clock source is selected, make sure that it is not higher than 48 MHz.
* a multiple of 8 MHz gives the best support for most commonly used CAN baudrates, so
* that is recommended.
*/
canClockFreqkHz = LL_RCC_GetFDCANClockFreq(LL_RCC_FDCAN_CLKSOURCE) / 1000u;
/* the CAN clock source should not be higher than 48 MHz. so only continue if this is
* the case.
*/
if (canClockFreqkHz <= 48000u)
{
/* loop through all possible time quanta configurations to find a match */
for (cnt=0; cnt < sizeof(canTiming)/sizeof(canTiming[0]); cnt++)
{
if ((canClockFreqkHz % (baud*(canTiming[cnt].tseg1+canTiming[cnt].tseg2+1))) == 0)
{
/* compute the prescaler that goes with this TQ configuration */
*prescaler = canClockFreqkHz/(baud*(canTiming[cnt].tseg1+canTiming[cnt].tseg2+1));
/* make sure the prescaler is valid */
if ((*prescaler > 0) && (*prescaler <= 512))
{
/* store the bustiming configuration */
*tseg1 = canTiming[cnt].tseg1;
*tseg2 = canTiming[cnt].tseg2;
/* found a good bus timing configuration */
return BLT_TRUE;
}
}
}
}
/* could not find a good bus timing configuration */
return BLT_FALSE;
} /*** end of CanGetSpeedConfig ***/
/************************************************************************************//**
** \brief Initializes the CAN controller and synchronizes it to the CAN bus.
** \return none.
**
****************************************************************************************/
void CanInit(void)
{
blt_int16u prescaler = 0;
blt_int8u tseg1 = 0, tseg2 = 0;
blt_int32u rxMsgId = BOOT_COM_CAN_RX_MSG_ID;
FDCAN_FilterTypeDef filterConfig;
/* the current implementation supports CAN1, 2 and 3. throw an assertion error in case
* a different CAN channel is configured.
*/
ASSERT_CT((BOOT_COM_CAN_CHANNEL_INDEX == 0) ||
(BOOT_COM_CAN_CHANNEL_INDEX == 1));
/* obtain bittiming configuration information. */
if (CanGetSpeedConfig(BOOT_COM_CAN_BAUDRATE/1000, &prescaler, &tseg1, &tseg2) == BLT_FALSE)
{
/* Incorrect configuration. The specified baudrate is not supported for the given
* clock configuration. Verify the following settings in blt_conf.h:
* - BOOT_COM_CAN_BAUDRATE
* - BOOT_CPU_XTAL_SPEED_KHZ
* - BOOT_CPU_SYSTEM_SPEED_KHZ
*/
ASSERT_RT(BLT_FALSE);
}
/* set the CAN controller configuration. */
canHandle.Instance = CAN_CHANNEL;
canHandle.Init.ClockDivider = FDCAN_CLOCK_DIV1;
canHandle.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
canHandle.Init.Mode = FDCAN_MODE_NORMAL;
canHandle.Init.AutoRetransmission = ENABLE;
canHandle.Init.TransmitPause = DISABLE;
canHandle.Init.ProtocolException = DISABLE;
canHandle.Init.NominalPrescaler = prescaler;
canHandle.Init.NominalSyncJumpWidth = 1;
canHandle.Init.NominalTimeSeg1 = tseg1;
canHandle.Init.NominalTimeSeg2 = tseg2;
/* FD mode is not used by this driver, so the .Init.DataXxx values are don't care. */
canHandle.Init.DataPrescaler = 1;
canHandle.Init.DataSyncJumpWidth = 1;
canHandle.Init.DataTimeSeg1 = 1;
canHandle.Init.DataTimeSeg2 = 1;
/* does the message to be received have a standard 11-bit CAN identifier? */
if ((rxMsgId & 0x80000000) == 0)
{
canHandle.Init.StdFiltersNbr = 1;
canHandle.Init.ExtFiltersNbr = 0;
}
else
{
canHandle.Init.StdFiltersNbr = 0;
canHandle.Init.ExtFiltersNbr = 1;
}
canHandle.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
/* initialize the CAN controller. this only fails if the CAN controller hardware is
* faulty. no need to evaluate the return value as there is nothing we can do about
* a faulty CAN controller.
*/
(void)HAL_FDCAN_Init(&canHandle);
/* configure the reception filter. note that the implementation of this function
* always returns HAL_OK as long as the CAN controller is initialized, so no need to
* evaluate the return value.
*/
if ((rxMsgId & 0x80000000) == 0)
{
filterConfig.IdType = FDCAN_STANDARD_ID;
}
else
{
filterConfig.IdType = FDCAN_EXTENDED_ID;
/* negate the ID-type bit */
rxMsgId &= ~0x80000000;
}
filterConfig.FilterIndex = 0;
filterConfig.FilterType = FDCAN_FILTER_DUAL;
filterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
filterConfig.FilterID1 = rxMsgId;
filterConfig.FilterID2 = rxMsgId;
(void)HAL_FDCAN_ConfigFilter(&canHandle, &filterConfig);
/* configure global filter to reject all non-matching frames. */
HAL_FDCAN_ConfigGlobalFilter(&canHandle, FDCAN_REJECT, FDCAN_REJECT,
FDCAN_REJECT_REMOTE, FDCAN_REJECT_REMOTE);
/* start the CAN peripheral. no need to evaluate the return value as there is nothing
* we can do about a faulty CAN controller. */
(void)HAL_FDCAN_Start(&canHandle);
} /*** end of CanInit ***/
/************************************************************************************//**
** \brief Transmits a packet formatted for the communication interface.
** \param data Pointer to byte array with data that it to be transmitted.
** \param len Number of bytes that are to be transmitted.
** \return none.
**
****************************************************************************************/
void CanTransmitPacket(blt_int8u *data, blt_int8u len)
{
blt_int32u txMsgId = BOOT_COM_CAN_TX_MSG_ID;
FDCAN_TxHeaderTypeDef txMsgHeader;
blt_int32u timeout;
HAL_StatusTypeDef status;
blt_int32u txMsgBuffer;
/* configure the message that should be transmitted. */
if ((txMsgId & 0x80000000) == 0)
{
/* set the 11-bit CAN identifier. */
txMsgHeader.Identifier = txMsgId;
txMsgHeader.IdType = FDCAN_STANDARD_ID;
}
else
{
/* negate the ID-type bit. */
txMsgId &= ~0x80000000;
/* set the 29-bit CAN identifier. */
txMsgHeader.Identifier = txMsgId;
txMsgHeader.IdType = FDCAN_EXTENDED_ID;
}
txMsgHeader.TxFrameType = FDCAN_DATA_FRAME;
txMsgHeader.DataLength = len << 16U;
txMsgHeader.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
txMsgHeader.BitRateSwitch = FDCAN_BRS_OFF;
txMsgHeader.FDFormat = FDCAN_CLASSIC_CAN;
txMsgHeader.TxEventFifoControl = FDCAN_NO_TX_EVENTS;
txMsgHeader.MessageMarker = 0x52;
/* add the message to the transmit FIFO to request its transmission. */
status = HAL_FDCAN_AddMessageToTxFifoQ(&canHandle, &txMsgHeader, data);
/* read out which FIFO buffer was used for the last transmit request. */
txMsgBuffer = HAL_FDCAN_GetLatestTxFifoQRequestBuffer(&canHandle);
/* only continue with polling for transmit completion if the message transmit request
* could be submitted to a valid FIFO buffer.
*/
if ((status == HAL_OK) && (txMsgBuffer != 0))
{
/* determine timeout time for the transmit completion. */
timeout = TimerGet() + CAN_MSG_TX_TIMEOUT_MS;
/* poll for completion of the transmit operation. */
while (HAL_FDCAN_IsTxBufferMessagePending(&canHandle, txMsgBuffer) != 0)
{
/* service the watchdog. */
CopService();
/* break loop upon timeout. this would indicate a hardware failure or no other
* nodes connected to the bus.
*/
if (TimerGet() > timeout)
{
break;
}
}
}
} /*** end of CanTransmitPacket ***/
/************************************************************************************//**
** \brief Receives a communication interface packet if one is present.
** \param data Pointer to byte array where the data is to be stored.
** \param len Pointer where the length of the packet is to be stored.
** \return BLT_TRUE is a packet was received, BLT_FALSE otherwise.
**
****************************************************************************************/
blt_bool CanReceivePacket(blt_int8u *data, blt_int8u *len)
{
blt_bool result = BLT_FALSE;
blt_int32u rxMsgId = BOOT_COM_CAN_RX_MSG_ID;
FDCAN_RxHeaderTypeDef rxMsgHeader;
HAL_StatusTypeDef rxStatus = HAL_ERROR;
/* check if the expected CAN message was received? */
if (HAL_FDCAN_GetRxFifoFillLevel(&canHandle, FDCAN_RX_FIFO0) > 0)
{
/* attempt to read the newly received CAN message from its buffer. */
rxStatus = HAL_FDCAN_GetRxMessage(&canHandle, FDCAN_RX_FIFO0, &rxMsgHeader, data);
}
/* only continue processing the CAN message if something was received. */
if (rxStatus == HAL_OK)
{
/* check if this message has the configured CAN packet identifier. */
if ((rxMsgId & 0x80000000) == 0)
{
/* was an 11-bit CAN message received that matches? */
if ( (rxMsgHeader.Identifier == rxMsgId) &&
(rxMsgHeader.IdType == FDCAN_STANDARD_ID) )
{
/* set flag that a packet with a matching CAN identifier was received. */
result = BLT_TRUE;
}
}
else
{
/* negate the ID-type bit. */
rxMsgId &= ~0x80000000;
/* was an 29-bit CAN message received that matches? */
if ( (rxMsgHeader.Identifier == rxMsgId) &&
(rxMsgHeader.IdType == FDCAN_EXTENDED_ID) )
{
/* set flag that a packet with a matching CAN identifier was received. */
result = BLT_TRUE;
}
}
/* store the data length. */
if (result == BLT_TRUE)
{
*len = (blt_int8u)(rxMsgHeader.DataLength >> 16U);
}
}
/* give the result back to the caller. */
return result;
} /*** end of CanReceivePacket ***/
#endif /* BOOT_COM_CAN_ENABLE > 0 */
/*********************************** end of can.c **************************************/

196
Boot/ARMCM0_STM32G0/cpu.c Normal file
View File

@@ -0,0 +1,196 @@
/************************************************************************************//**
* \file Source/ARMCM0_STM32G0/cpu.c
* \brief Bootloader cpu module source file.
* \ingroup Target_ARMCM0_STM32G0
* \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 "boot.h" /* bootloader generic header */
#include "stm32g0xx.h" /* STM32 CPU and HAL header */
#include "stm32g0xx_ll_bus.h" /* STM32 LL BUS header */
#include "stm32g0xx_ll_system.h" /* STM32 LL SYSTEM header */
/****************************************************************************************
* Macro definitions
****************************************************************************************/
/** \brief Pointer to the user program's reset vector. */
#define CPU_USER_PROGRAM_STARTADDR_PTR ((blt_addr)(NvmGetUserProgBaseAddress() + 0x00000004))
/** \brief Pointer to the user program's vector table. */
#define CPU_USER_PROGRAM_VECTABLE_OFFSET ((blt_int32u)NvmGetUserProgBaseAddress())
/****************************************************************************************
* Hook functions
****************************************************************************************/
#if (BOOT_CPU_USER_PROGRAM_START_HOOK > 0)
extern blt_bool CpuUserProgramStartHook(void);
#endif
/************************************************************************************//**
** \brief Initializes the CPU module.
** \return none.
**
****************************************************************************************/
void CpuInit(void)
{
/* bootloader runs in polling mode so disable the global interrupts. this is done for
* safety reasons. if the bootloader was started from a running user program, it could
* be that the user program did not properly disable the interrupt generation of
* peripherals. */
CpuIrqDisable();
} /*** end of CpuInit ***/
/************************************************************************************//**
** \brief Starts the user program, if one is present. In this case this function
** does not return.
** \return none.
**
****************************************************************************************/
void CpuStartUserProgram(void)
{
void (*pProgResetHandler)(void);
/* check if a user program is present by verifying the checksum */
if (NvmVerifyChecksum() == BLT_FALSE)
{
#if (BOOT_COM_DEFERRED_INIT_ENABLE > 0) && (BOOT_COM_ENABLE > 0)
/* bootloader will stay active so perform deferred initialization to make sure
* the communication interface that were not yet initialized are now initialized.
* this is needed to make sure firmware updates via these communication interfaces
* will be possible.
*/
ComDeferredInit();
#endif
/* not a valid user program so it cannot be started */
return;
}
#if (BOOT_CPU_USER_PROGRAM_START_HOOK > 0)
/* invoke callback */
if (CpuUserProgramStartHook() == BLT_FALSE)
{
#if (BOOT_COM_DEFERRED_INIT_ENABLE > 0) && (BOOT_COM_ENABLE > 0)
/* bootloader will stay active so perform deferred initialization to make sure
* the communication interface that were not yet initialized are now initialized.
* this is needed to make sure firmware updates via these communication interfaces
* will be possible.
*/
ComDeferredInit();
#endif
/* callback requests the user program to not be started */
return;
}
#endif
#if (BOOT_COM_ENABLE > 0)
/* release the communication interface */
ComFree();
#endif
/* reset the HAL */
HAL_DeInit();
/* reset the timer */
TimerReset();
/* remap user program's vector table */
SCB->VTOR = CPU_USER_PROGRAM_VECTABLE_OFFSET & (blt_int32u)0x1FFFFF80;
/* set the address where the bootloader needs to jump to. this is the address of
* the 2nd entry in the user program's vector table. this address points to the
* user program's reset handler.
*/
pProgResetHandler = (void(*)(void))(*((blt_addr *)CPU_USER_PROGRAM_STARTADDR_PTR));
/* the Cortex-M0+ core has interrupts enabled out of reset. the bootloader
* explicitly disables these for security reasons. Enable them here again, so it does
* not have to be done by the user program.
*/
CpuIrqEnable();
/* start the user program by activating its reset interrupt service routine */
pProgResetHandler();
#if (BOOT_COM_DEFERRED_INIT_ENABLE > 0) && (BOOT_COM_ENABLE > 0)
/* theoretically, the code never gets here because the user program should now be
* running and the previous function call should not return. In case it did return
* for whatever reason, make sure all communication interfaces are initialized so that
* firmware updates can be started.
*/
ComDeferredInit();
#endif
} /*** end of CpuStartUserProgram ***/
/************************************************************************************//**
** \brief Copies data from the source to the destination address.
** \param dest Destination address for the data.
** \param src Source address of the data.
** \param len length of the data in bytes.
** \return none.
**
****************************************************************************************/
void CpuMemCopy(blt_addr dest, blt_addr src, blt_int16u len)
{
blt_int8u *from, *to;
/* set casted pointers */
from = (blt_int8u *)src;
to = (blt_int8u *)dest;
/* copy all bytes from source address to destination address */
while (len-- > 0)
{
/* store byte value from source to destination */
*to++ = *from++;
/* keep the watchdog happy */
CopService();
}
} /*** end of CpuMemCopy ***/
/************************************************************************************//**
** \brief Sets the bytes at the destination address to the specified value.
** \param dest Destination address for the data.
** \param value Value to write.
** \param len Number of bytes to write.
** \return none.
**
****************************************************************************************/
void CpuMemSet(blt_addr dest, blt_int8u value, blt_int16u len)
{
blt_int8u *to;
/* set casted pointer */
to = (blt_int8u *)dest;
/* set all bytes at the destination address to the specified value */
while (len-- > 0)
{
/* set byte value */
*to++ = value;
/* keep the watchdog happy */
CopService();
}
} /*** end of CpuMemSet ***/
/*********************************** end of cpu.c **************************************/

1008
Boot/ARMCM0_STM32G0/flash.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,45 @@
/************************************************************************************//**
* \file Source/ARMCM0_STM32G0/flash.h
* \brief Bootloader flash driver header file.
* \ingroup Target_ARMCM0_STM32G0
* \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
****************************************************************************************/
#ifndef FLASH_H
#define FLASH_H
/****************************************************************************************
* Function prototypes
****************************************************************************************/
void FlashInit(void);
void FlashReinit(void);
blt_bool FlashWrite(blt_addr addr, blt_int32u len, blt_int8u *data);
blt_bool FlashErase(blt_addr addr, blt_int32u len);
blt_bool FlashWriteChecksum(void);
blt_bool FlashVerifyChecksum(void);
blt_bool FlashDone(void);
blt_addr FlashGetUserProgBaseAddress(void);
#endif /* FLASH_H */
/*********************************** end of flash.h ************************************/

245
Boot/ARMCM0_STM32G0/nvm.c Normal file
View File

@@ -0,0 +1,245 @@
/************************************************************************************//**
* \file Source/ARMCM0_STM32G0/nvm.c
* \brief Bootloader non-volatile memory driver source file.
* \ingroup Target_ARMCM0_STM32G0
* \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 "boot.h" /* bootloader generic header */
#include "flash.h"
/****************************************************************************************
* Hook functions
****************************************************************************************/
#if (BOOT_NVM_HOOKS_ENABLE > 0)
extern void NvmInitHook(void);
extern void NvmReinitHook(void);
extern blt_int8u NvmWriteHook(blt_addr addr, blt_int32u len, blt_int8u *data);
extern blt_int8u NvmEraseHook(blt_addr addr, blt_int32u len);
extern blt_bool NvmDoneHook(void);
#endif
#if (BOOT_NVM_CHECKSUM_HOOKS_ENABLE > 0)
extern blt_bool NvmWriteChecksumHook(void);
extern blt_bool NvmVerifyChecksumHook(void);
#endif
/************************************************************************************//**
** \brief Initializes the NVM driver.
** \return none.
**
****************************************************************************************/
void NvmInit(void)
{
#if (BOOT_NVM_HOOKS_ENABLE > 0)
/* give the application a chance to initialize a driver for operating on NVM
* that is not by default supported by this driver.
*/
NvmInitHook();
#endif
/* init the internal driver */
FlashInit();
} /*** end of NvmInit ***/
/************************************************************************************//**
** \brief Reinitializes the NVM driver. This function is called at the start of each
** firmware update as opposed to NvmInit, which is only called once during
** power on.
** \return none.
**
****************************************************************************************/
void NvmReinit(void)
{
#if (BOOT_NVM_HOOKS_ENABLE > 0)
/* give the application a chance to re-initialize a driver for operating on NVM
* that is not by default supported by this driver.
*/
NvmReinitHook();
#endif
/* reinitialize the internal driver */
FlashReinit();
} /*** end of NvmReinit ***/
/************************************************************************************//**
** \brief Programs the non-volatile memory.
** \param addr Start address.
** \param len Length in bytes.
** \param data Pointer to the data buffer.
** \return BLT_TRUE if successful, BLT_FALSE otherwise.
**
****************************************************************************************/
blt_bool NvmWrite(blt_addr addr, blt_int32u len, blt_int8u *data)
{
#if (BOOT_NVM_HOOKS_ENABLE > 0)
blt_int8u result = BLT_NVM_NOT_IN_RANGE;
#endif
#if (BOOT_NVM_HOOKS_ENABLE > 0)
/* give the application a chance to operate on memory that is not by default supported
* by this driver.
*/
result = NvmWriteHook(addr, len, data);
/* process the return code */
if (result == BLT_NVM_OKAY)
{
/* data was within range of the additionally supported memory and succesfully
* programmed, so we are all done.
*/
return BLT_TRUE;
}
else if (result == BLT_NVM_ERROR)
{
/* data was within range of the additionally supported memory and attempted to be
* programmed, but an error occurred, so we can't continue.
*/
return BLT_FALSE;
}
#endif
/* still here so the internal driver should try and perform the program operation */
return FlashWrite(addr, len, data);
} /*** end of NvmWrite ***/
/************************************************************************************//**
** \brief Erases the non-volatile memory.
** \param addr Start address.
** \param len Length in bytes.
** \return BLT_TRUE if successful, BLT_FALSE otherwise.
**
****************************************************************************************/
blt_bool NvmErase(blt_addr addr, blt_int32u len)
{
#if (BOOT_NVM_HOOKS_ENABLE > 0)
blt_int8u result = BLT_NVM_NOT_IN_RANGE;
#endif
#if (BOOT_NVM_HOOKS_ENABLE > 0)
/* give the application a chance to operate on memory that is not by default supported
* by this driver.
*/
result = NvmEraseHook(addr, len);
/* process the return code */
if (result == BLT_NVM_OKAY)
{
/* address was within range of the additionally supported memory and succesfully
* erased, so we are all done.
*/
return BLT_TRUE;
}
else if (result == BLT_NVM_ERROR)
{
/* address was within range of the additionally supported memory and attempted to be
* erased, but an error occurred, so we can't continue.
*/
return BLT_FALSE;
}
#endif
/* still here so the internal driver should try and perform the erase operation */
return FlashErase(addr, len);
} /*** end of NvmErase ***/
/************************************************************************************//**
** \brief Verifies the checksum, which indicates that a valid user program is
** present and can be started.
** \return BLT_TRUE if successful, BLT_FALSE otherwise.
**
****************************************************************************************/
blt_bool NvmVerifyChecksum(void)
{
#if (BOOT_NVM_CHECKSUM_HOOKS_ENABLE > 0)
/* check checksum using the application specific method. */
return NvmVerifyChecksumHook();
#else
/* check checksum using the interally supported method. */
return FlashVerifyChecksum();
#endif
} /*** end of NvmVerifyChecksum ***/
/************************************************************************************//**
** \brief Obtains the base address of the non-volatile memory available to the user
** program. This is typically that start of the vector table.
** \return Base address.
**
****************************************************************************************/
blt_addr NvmGetUserProgBaseAddress(void)
{
return FlashGetUserProgBaseAddress();
} /*** end of NvmGetUserProgBaseAddress ***/
/************************************************************************************//**
** \brief Once all erase and programming operations are completed, this
** function is called, so at the end of the programming session and
** right before a software reset is performed. It is used to calculate
** a checksum and program this into flash. This checksum is later used
** to determine if a valid user program is present in flash.
** \return BLT_TRUE if successful, BLT_FALSE otherwise.
**
****************************************************************************************/
blt_bool NvmDone(void)
{
#if (BOOT_NVM_HOOKS_ENABLE > 0)
/* give the application's NVM driver a chance to finish up */
if (NvmDoneHook() == BLT_FALSE)
{
/* error so no need to continue */
return BLT_FALSE;
}
#endif
#if (BOOT_NVM_CHECKSUM_HOOKS_ENABLE > 0)
/* compute and write checksum, using the application specific method. */
if (NvmWriteChecksumHook() == BLT_FALSE)
{
return BLT_FALSE;
}
#else
/* compute and write checksum, which is programmed by the internal driver. */
if (FlashWriteChecksum() == BLT_FALSE)
{
return BLT_FALSE;
}
#endif
/* finish up internal driver operations */
return FlashDone();
} /*** end of NvmDone ***/
/*********************************** end of nvm.c **************************************/

257
Boot/ARMCM0_STM32G0/rs232.c Normal file
View File

@@ -0,0 +1,257 @@
/************************************************************************************//**
* \file Source/ARMCM0_STM32G0/rs232.c
* \brief Bootloader RS232 communication interface source file.
* \ingroup Target_ARMCM0_STM32G0
* \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 "boot.h" /* bootloader generic header */
#if (BOOT_COM_RS232_ENABLE > 0)
#include "stm32g0xx.h" /* STM32 CPU and HAL header */
#include "stm32g0xx_ll_usart.h" /* STM32 LL USART header */
/****************************************************************************************
* 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)
/** \brief Timeout for transmitting a byte in milliseconds. */
#define RS232_BYTE_TX_TIMEOUT_MS (10u)
/* map the configured UART channel index to the STM32's USART peripheral */
#if (BOOT_COM_RS232_CHANNEL_INDEX == 0)
/** \brief Set UART base address to USART1. */
#define USART_CHANNEL USART1
#elif (BOOT_COM_RS232_CHANNEL_INDEX == 1)
/** \brief Set UART base address to USART2. */
#define USART_CHANNEL USART2
#elif (BOOT_COM_RS232_CHANNEL_INDEX == 2)
/** \brief Set UART base address to USART3. */
#define USART_CHANNEL USART3
#elif (BOOT_COM_RS232_CHANNEL_INDEX == 3)
/** \brief Set UART base address to USART4. */
#define USART_CHANNEL USART4
#endif
/****************************************************************************************
* Function prototypes
****************************************************************************************/
static blt_bool Rs232ReceiveByte(blt_int8u *data);
static void Rs232TransmitByte(blt_int8u data);
/************************************************************************************//**
** \brief Initializes the RS232 communication interface.
** \return none.
**
****************************************************************************************/
void Rs232Init(void)
{
LL_USART_InitTypeDef USART_InitStruct;
/* the current implementation supports USART1 - USART4. throw an assertion error in
* case a different UART channel is configured.
*/
ASSERT_CT((BOOT_COM_RS232_CHANNEL_INDEX == 0) ||
(BOOT_COM_RS232_CHANNEL_INDEX == 1) ||
(BOOT_COM_RS232_CHANNEL_INDEX == 2) ||
(BOOT_COM_RS232_CHANNEL_INDEX == 3));
/* disable the UART peripheral */
LL_USART_Disable(USART_CHANNEL);
/* configure UART peripheral */
USART_InitStruct.BaudRate = BOOT_COM_RS232_BAUDRATE;
USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B;
USART_InitStruct.StopBits = LL_USART_STOPBITS_1;
USART_InitStruct.Parity = LL_USART_PARITY_NONE;
USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX;
USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE;
USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16;
USART_InitStruct.PrescalerValue = LL_USART_PRESCALER_DIV1;
/* initialize the UART peripheral */
LL_USART_Init(USART_CHANNEL, &USART_InitStruct);
LL_USART_Enable(USART_CHANNEL);
} /*** end of Rs232Init ***/
/************************************************************************************//**
** \brief Transmits a packet formatted for the communication interface.
** \param data Pointer to byte array with data that it to be transmitted.
** \param len Number of bytes that are to be transmitted.
** \return none.
**
****************************************************************************************/
void Rs232TransmitPacket(blt_int8u *data, blt_int8u len)
{
blt_int16u data_index;
/* verify validity of the len-paramenter */
ASSERT_RT(len <= BOOT_COM_RS232_TX_MAX_DATA);
/* first transmit the length of the packet */
Rs232TransmitByte(len);
/* transmit all the packet bytes one-by-one */
for (data_index = 0; data_index < len; data_index++)
{
/* keep the watchdog happy */
CopService();
/* write byte */
Rs232TransmitByte(data[data_index]);
}
} /*** end of Rs232TransmitPacket ***/
/************************************************************************************//**
** \brief Receives a communication interface packet if one is present.
** \param data Pointer to byte array where the data is to be stored.
** \param len Pointer where the length of the packet is to be stored.
** \return BLT_TRUE if a packet was received, BLT_FALSE otherwise.
**
****************************************************************************************/
blt_bool Rs232ReceivePacket(blt_int8u *data, blt_int8u *len)
{
static blt_int8u xcpCtoReqPacket[BOOT_COM_RS232_RX_MAX_DATA+1]; /* one extra for length */
static blt_int8u xcpCtoRxLength;
static blt_bool xcpCtoRxInProgress = BLT_FALSE;
static blt_int32u xcpCtoRxStartTime = 0;
/* start of cto packet received? */
if (xcpCtoRxInProgress == BLT_FALSE)
{
/* store the message length when received */
if (Rs232ReceiveByte(&xcpCtoReqPacket[0]) == BLT_TRUE)
{
if ( (xcpCtoReqPacket[0] > 0) &&
(xcpCtoReqPacket[0] <= BOOT_COM_RS232_RX_MAX_DATA) )
{
/* store the start time */
xcpCtoRxStartTime = TimerGet();
/* reset packet data count */
xcpCtoRxLength = 0;
/* indicate that a cto packet is being received */
xcpCtoRxInProgress = BLT_TRUE;
}
}
}
else
{
/* store the next packet byte */
if (Rs232ReceiveByte(&xcpCtoReqPacket[xcpCtoRxLength+1]) == BLT_TRUE)
{
/* increment the packet data count */
xcpCtoRxLength++;
/* check to see if the entire packet was received */
if (xcpCtoRxLength == xcpCtoReqPacket[0])
{
/* copy the packet data */
CpuMemCopy((blt_int32u)data, (blt_int32u)&xcpCtoReqPacket[1], xcpCtoRxLength);
/* done with cto packet reception */
xcpCtoRxInProgress = BLT_FALSE;
/* set the packet length */
*len = xcpCtoRxLength;
/* packet reception complete */
return BLT_TRUE;
}
}
else
{
/* check packet reception timeout */
if (TimerGet() > (xcpCtoRxStartTime + RS232_CTO_RX_PACKET_TIMEOUT_MS))
{
/* cancel cto packet reception due to timeout. note that that automaticaly
* discards the already received packet bytes, allowing the host to retry.
*/
xcpCtoRxInProgress = BLT_FALSE;
}
}
}
/* packet reception not yet complete */
return BLT_FALSE;
} /*** end of Rs232ReceivePacket ***/
/************************************************************************************//**
** \brief Receives a communication interface byte if one is present.
** \param data Pointer to byte where the data is to be stored.
** \return BLT_TRUE if a byte was received, BLT_FALSE otherwise.
**
****************************************************************************************/
static blt_bool Rs232ReceiveByte(blt_int8u *data)
{
blt_bool result = BLT_FALSE;
/* check flag to see if a byte was received */
if (LL_USART_IsActiveFlag_RXNE(USART_CHANNEL) != 0)
{
/* retrieve and store the newly received byte */
*data = LL_USART_ReceiveData8(USART_CHANNEL);
/* update the result for success */
result = BLT_TRUE;
}
/* give the result back to the caller */
return result;
} /*** end of Rs232ReceiveByte ***/
/************************************************************************************//**
** \brief Transmits a communication interface byte.
** \param data Value of byte that is to be transmitted.
** \return none.
**
****************************************************************************************/
static void Rs232TransmitByte(blt_int8u data)
{
blt_int32u timeout;
/* write byte to transmit holding register */
LL_USART_TransmitData8(USART_CHANNEL, data);
/* set timeout time to wait for transmit completion. */
timeout = TimerGet() + RS232_BYTE_TX_TIMEOUT_MS;
/* wait for tx holding register to be empty */
while (LL_USART_IsActiveFlag_TXE(USART_CHANNEL) == 0)
{
/* keep the watchdog happy */
CopService();
/* break loop upon timeout. this would indicate a hardware failure. */
if (TimerGet() > timeout)
{
break;
}
}
} /*** end of Rs232TransmitByte ***/
#endif /* BOOT_COM_RS232_ENABLE > 0 */
/*********************************** end of rs232.c ************************************/

View File

@@ -0,0 +1,9 @@
/**
\defgroup Target_ARMCM0_STM32G0 Target ARMCM0 STM32G0
\ingroup Ports
\brief Target dependent code for the ARMCM0 STM32G0 microcontroller family.
\details This module implements the bootloader's target dependent part for the
ARMCM0 STM32G0 microcontroller family.
*/

128
Boot/ARMCM0_STM32G0/timer.c Normal file
View File

@@ -0,0 +1,128 @@
/************************************************************************************//**
* \file Source/ARMCM0_STM32G0/timer.c
* \brief Bootloader timer driver source file.
* \ingroup Target_ARMCM0_STM32G0
* \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 "boot.h" /* bootloader generic header */
#include "stm32g0xx.h" /* STM32 CPU and HAL header */
/****************************************************************************************
* Local data declarations
****************************************************************************************/
/** \brief Local variable for storing the number of milliseconds that have elapsed since
* startup.
*/
static blt_int32u millisecond_counter;
/************************************************************************************//**
** \brief Initializes the polling based millisecond timer driver.
** \return none.
**
****************************************************************************************/
void TimerInit(void)
{
/* Reset the timer configuration. */
TimerReset();
/* configure the systick frequency as a 1 ms event generator */
SysTick->LOAD = BOOT_CPU_SYSTEM_SPEED_KHZ - 1;
/* reset the current counter value */
SysTick->VAL = 0;
/* select core clock as source and enable the timer */
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;
/* reset the millisecond counter value */
millisecond_counter = 0;
} /*** end of TimerInit ***/
/************************************************************************************//**
** \brief Reset the timer by placing the timer back into it's default reset
** configuration.
** \return none.
**
****************************************************************************************/
void TimerReset(void)
{
/* set the systick's registers back into the default reset value. */
SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL = 0;
} /* end of TimerReset */
/************************************************************************************//**
** \brief Updates the millisecond timer.
** \return none.
**
****************************************************************************************/
void TimerUpdate(void)
{
/* check if the millisecond event occurred */
if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) != 0)
{
/* Increment the millisecond counter. */
millisecond_counter++;
}
} /*** end of TimerUpdate ***/
/************************************************************************************//**
** \brief Obtains the counter value of the millisecond timer.
** \return Current value of the millisecond timer.
**
****************************************************************************************/
blt_int32u TimerGet(void)
{
/* Updating timer here allows this function to be called in a loop with timeout
* detection.
*/
TimerUpdate();
/* Read and return the amount of milliseconds that passed since initialization. */
return millisecond_counter;
} /*** end of TimerGet ***/
/************************************************************************************//**
** \brief Override for the HAL driver's GetTick() functionality. This is needed
** because the bootloader doesn't use interrupts, but the HAL's tick
** functionality assumes that it does. This will cause the HAL_Delay()
** function to not work properly. As a result of this override, the HAL's
** tick functionality works in polling mode.
** \return Current value of the millisecond timer.
**
****************************************************************************************/
uint32_t HAL_GetTick(void)
{
/* Link to the bootloader's 1ms timer. */
return TimerGet();
} /*** end of HAL_GetTick ***/
/*********************************** end of timer.c ************************************/

View File

@@ -0,0 +1,59 @@
/************************************************************************************//**
* \file Source/ARMCM0_STM32G0/types.h
* \brief Bootloader types header file.
* \ingroup Target_ARMCM0_STM32G0
* \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
****************************************************************************************/
#ifndef TYPES_H
#define TYPES_H
/****************************************************************************************
* Macro definitions
****************************************************************************************/
/** \brief Boolean true value. */
#define BLT_TRUE (1)
/** \brief Boolean false value. */
#define BLT_FALSE (0)
/** \brief NULL pointer value. */
#define BLT_NULL ((void *)0)
/****************************************************************************************
* Type definitions
****************************************************************************************/
typedef unsigned char blt_bool; /**< boolean type */
typedef char blt_char; /**< character type */
typedef unsigned long blt_addr; /**< memory address type */
typedef unsigned char blt_int8u; /**< 8-bit unsigned integer */
typedef signed char blt_int8s; /**< 8-bit signed integer */
typedef unsigned short blt_int16u; /**< 16-bit unsigned integer */
typedef signed short blt_int16s; /**< 16-bit signed integer */
typedef unsigned int blt_int32u; /**< 32-bit unsigned integer */
typedef signed int blt_int32s; /**< 32-bit signed integer */
typedef unsigned long long blt_int64u; /**< 64-bit unsigned integer */
typedef signed long long blt_int64s; /**< 64-bit signed integer */
#endif /* TYPES_H */
/*********************************** end of types.h ************************************/