/** @file micro.c * @brief STM32W108 micro specific minimal HAL functions * * * */ #include PLATFORM_HEADER #include BOARD_HEADER #include "error.h" #include "hal/micro/micro-common.h" #include "hal/micro/cortexm3/micro-common.h" #include "micro/system-timer.h" #include "micro/adc.h" #include "micro/cortexm3/memmap.h" #include "micro/cortexm3/iap_bootloader.h" #include #include extern void halBoardInit(void); void halInit(void) { //Disable the REG_EN external regulator enable signal. Out of reset this //signal overrides PA7. By disabling it early, PA7 is reclaimed as a GPIO. //If an external regulator is required, the following line of code should //be deleted. GPIO_DBGCFG &= ~GPIO_EXTREGEN; halInternalSetRegTrim(FALSE); halBoardInit(); halPowerUp(); halInternalCalibrateFastRc(); #ifndef DISABLE_WATCHDOG halInternalEnableWatchDog(); #endif halInternalStartSystemTimer(); } void halReboot(void) { INTERRUPTS_OFF(); //FCLK must be 6MHz to allow the SYSRESETREQ signal to cleanly //propagate and reset the chip. Switch SYSCLK first since we need //the cycles used by switching FCLK to guarantee the SYSCLK is //stable and ready for SYSRESETREQ. OSC24M_CTRL = OSC24M_CTRL_RESET; //Guarantee SYSCLK is sourced from OSCHF CPU_CLKSEL = CPU_CLKSEL_RESET; //Guarantee FCLK is sourced from PCLK SCS_AIRCR = (0x05FA0000 | SCS_AIRCR_SYSRESETREQ); // trigger the reset //NOTE: SYSRESETREQ is not the same as nRESET. It will not do the debug //pieces: DWT, ITM, FPB, vector catch, etc } void halPowerDown(void) { halBoardPowerDown(); } void halPowerUp(void) { halInternalInitAdc(); halCommonCalibratePads(); halInternalSwitchToXtal(); halBoardPowerUp(); } static uint16_t seed0 = 0xbeef; static uint16_t seed1 = 0xface; void halCommonSeedRandom(uint32_t seed) { seed0 = (uint16_t) seed; if (seed0 == 0) seed0 = 0xbeef; seed1 = (uint16_t) (seed >> 16); if (seed1 == 0) seed1 = 0xface; } static uint16_t shift(uint16_t *val, uint16_t taps) { uint16_t newVal = *val; if (newVal & 0x8000) newVal ^= taps; *val = newVal << 1; return newVal; } uint16_t halCommonGetRandom(void) { return (shift(&seed0, 0x0062) ^ shift(&seed1, 0x100B)); } void halCommonMemCopy(void *dest, const void *source, uint8_t bytes) { memcpy(dest, source, bytes); } int8_t halCommonMemCompare(const void *source0, const void *source1, uint8_t bytes) { return memcmp(source0, source1, bytes); } void halCommonMemSet(void *dest, uint8_t val, uint16_t bytes) { memset(dest, val, bytes); } #pragma pack(1) typedef struct appSwitchStruct { uint32_t signature; uint8_t mode; uint8_t channel; union { uint16_t panID; uint16_t offset; } param; } appSwitchStructType; #pragma pack() static appSwitchStructType *appSwitch = (appSwitchStructType *) RAM_BOTTOM; StStatus halBootloaderStart(uint8_t mode, uint8_t channel, uint16_t panID) { if (mode == IAP_BOOTLOADER_MODE_UART) { uint8_t cut = *(volatile uint8_t *) 0x08040798; if (!( (halFixedAddressTable.baseTable.type == FIXED_ADDRESS_TABLE_TYPE) && ( ( (halFixedAddressTable.baseTable.version & FAT_MAJOR_VERSION_MASK) == 0x0000 ) && (halFixedAddressTable.baseTable.version == 0x0003) //checking presence of valid version ) && (cut >= 2) && (cut <= 3))) /* Cut not supported */ return ST_ERR_FATAL; } else { /* Check that OTA bootloader is at the base of the flash */ if (*((uint32_t *) (MFB_BOTTOM + 28)) == IAP_BOOTLOADER_APP_SWITCH_SIGNATURE) { appSwitch->channel = ((channel >= 11) && (channel <= 26)) ? channel :IAP_BOOTLOADER_DEFAULT_CHANNEL; appSwitch->param.panID = panID; } else { return ST_ERR_FATAL; } } appSwitch->signature = IAP_BOOTLOADER_APP_SWITCH_SIGNATURE; appSwitch->mode = mode; halReboot(); return (mode <= IAP_BOOTLOADER_MODE_OTA) ? ST_ERR_FATAL: ST_BAD_ARGUMENT; }