diff --git a/.gitignore b/.gitignore
index a3b2312da..a15d34c63 100644
--- a/.gitignore
+++ b/.gitignore
@@ -42,3 +42,8 @@ Listings/
*.axfdump
/crypto/lib
+Firmware License (Crypto).rtf
+License (Crypto).rtf
+PKCryptoWelcome.rtf
+REDIST_CRYPTO.TXT
+ReleaseNotesCrypto.txt
diff --git a/DeviceCode/Targets/Native/STM32F4/DeviceCode/STM32F4_Bootstrap/STM32F4_bootstrap.cpp b/DeviceCode/Targets/Native/STM32F4/DeviceCode/STM32F4_Bootstrap/STM32F4_bootstrap.cpp
index 779e4dab8..a6cfde5d6 100644
--- a/DeviceCode/Targets/Native/STM32F4/DeviceCode/STM32F4_Bootstrap/STM32F4_bootstrap.cpp
+++ b/DeviceCode/Targets/Native/STM32F4/DeviceCode/STM32F4_Bootstrap/STM32F4_bootstrap.cpp
@@ -19,6 +19,8 @@
#include "..\stm32f2xx.h"
#endif
+#include "..\..\..\..\..\pal\time\Time_driver.h"
+
#ifndef FLASH
#define FLASH ((FLASH_TypeDef *) FLASH_R_BASE)
#endif
@@ -276,8 +278,9 @@ void __section("SectionForBootstrapOperations") STM32F4_BootstrapCode()
// remove Flash remap to Boot area to avoid problems with Monitor_Execute
SYSCFG->MEMRMP = 1; // map System memory to Boot area
-#ifdef STM32F4_Enable_RTC
- STM32F4_RTC_Initialize(); // enable RTC
+#ifdef STM32F4_RTC_ENABLE
+ Time_Uninitialize();
+ Time_Initialize();
#endif
}
diff --git a/DeviceCode/Targets/Native/STM32F4/DeviceCode/STM32F4_RTC/RTC_decl.h b/DeviceCode/Targets/Native/STM32F4/DeviceCode/STM32F4_RTC/RTC_decl.h
index 98c2bb0f1..440af3414 100644
--- a/DeviceCode/Targets/Native/STM32F4/DeviceCode/STM32F4_RTC/RTC_decl.h
+++ b/DeviceCode/Targets/Native/STM32F4/DeviceCode/STM32F4_RTC/RTC_decl.h
@@ -10,9 +10,10 @@
BOOL RTC_Initialize ( );
INT64 RTC_GetTime ( );
void RTC_SetTime ( INT64 time );
+#ifndef STM32F4_RTC_ENABLE
INT32 RTC_GetOffset ( );
void RTC_SetOffset ( INT32 offset );
-
+#endif
//--//
#endif // _DRIVERS_RTC_DECL_H_
diff --git a/DeviceCode/Targets/Native/STM32F4/DeviceCode/STM32F4_RTC/STM32F4_RTC_functions.cpp b/DeviceCode/Targets/Native/STM32F4/DeviceCode/STM32F4_RTC/STM32F4_RTC_functions.cpp
index 42d8bbdfb..58cd78e3f 100644
--- a/DeviceCode/Targets/Native/STM32F4/DeviceCode/STM32F4_RTC/STM32F4_RTC_functions.cpp
+++ b/DeviceCode/Targets/Native/STM32F4/DeviceCode/STM32F4_RTC/STM32F4_RTC_functions.cpp
@@ -21,12 +21,149 @@
#include "..\stm32f2xx.h"
#endif
+#define RCC_LSE_TIMEOUT_VALUE ((uint32_t)6000) // 6000 ms
+#define LSI_TIMEOUT_VALUE ((uint32_t)100) // 100 ms
BOOL RTC_Initialize()
{
+#ifndef STM32F4_RTC_ENABLE
+
PWR->CR |= PWR_CR_DBP; // enable RTC access
RCC->BDCR |= RCC_BDCR_RTCSEL_0 | RCC_BDCR_LSEON | RCC_BDCR_RTCEN; // RTC & LSE on
+#else
+
+ UINT64 ticksStart;
+ uint32_t tmpreg1 = 0;
+
+ // enable power clock
+ RCC->APB1ENR |= RCC_APB1ENR_PWREN;
+ // also on sleep mode
+ RCC->APB1LPENR |= RCC_APB1LPENR_PWRLPEN;
+
+ // enable access to the backup domain allowing access to RTC
+ PWR->CR |= PWR_CR_DBP;
+
+#if defined(STM32F4_RTC_LSE)
+ // enable LSE
+
+ if((RCC->BDCR & RCC_BDCR_RTCSEL) != RCC_BDCR_RTCSEL_LSE)
+ {
+ // Store the content of BDCR register before the reset of Backup Domain
+ // and clear RTC clock source
+ tmpreg1 = (RCC->BDCR & ~(RCC_BDCR_RTCSEL));
+ // RTC Clock selection can be changed only if the Backup Domain is reset
+ RCC->BDCR |= RCC_BDCR_BDRST;
+ RCC->BDCR &= ~RCC_BDCR_BDRST;
+ // Restore the Content of BDCR register
+ RCC->BDCR = tmpreg1;
+ }
+
+ // Set LSEON bit
+ RCC->BDCR = RCC_BDCR_LSEON;
+
+ // Get Start Tick
+ ticksStart = HAL_Time_CurrentTicks();
+
+ // wait for external low-speed oscillator valid
+ while(!(RCC->BDCR & RCC_BDCR_LSERDY))
+ {
+ if((HAL_Time_CurrentTicks()-ticksStart) > CPU_MillisecondsToTicks((UINT32)RCC_LSE_TIMEOUT_VALUE))
+ {
+ // external low-speed oscillator is not working or not fitted
+ return FALSE;
+ }
+ }
+
+ // Select the RTC Clock Source
+ RCC->BDCR |= RCC_BDCR_RTCSEL_LSE;
+
+#elif defined(STM32F4_RTC_LSE_BYPASS)
+ // enable LSE and bypass oscillator
+
+ // Set LSEBYP and LSEON bits
+ RCC->BDCR = RCC_BDCR_LSEBYP | RCC_BDCR_LSEON;
+
+ // Get Start Tick
+ ticksStart = HAL_Time_CurrentTicks();
+
+ // wait for external low-speed oscillator valid
+ while(!(RCC->BDCR & RCC_BDCR_LSERDY))
+ {
+ if((HAL_Time_CurrentTicks()-ticksStart) > CPU_MillisecondsToTicks((UINT32)RCC_LSE_TIMEOUT_VALUE))
+ {
+ // external low-speed oscillator is not working or not fitted
+ return FALSE;
+ }
+ }
+
+ // Select the RTC Clock Source
+ RCC->BDCR |= RCC_BDCR_RTCSEL_LSE;
+
+#elif defined(STM32F4_RTC_LSI)
+ // enable LSI
+
+ // enable internal low-power oscillator
+ RCC->CSR |= (uint32_t)RCC_CSR_LSION
+
+ // Get Start Tick
+ ticksStart = HAL_Time_CurrentTicks();
+
+ // Wait till LSI is ready
+ while(!(RCC->CSR & RCC_CSR_LSIRDY))
+ {
+ if((HAL_Time_CurrentTicks()-ticksStart) > CPU_MillisecondsToTicks((UINT32)LSI_TIMEOUT_VALUE))
+ {
+ // external low-speed oscillator is not working
+ return FALSE;
+ }
+ }
+
+ // Select the RTC Clock Source
+ RCC->BDCR |= RCC_BDCR_RTCSEL_LSI;
+
+#else
+// sanity check for RTC enabled but no selection of clock source
+#error RTC is enabled in configuration but there is no RTC clock source selected
+#endif
+
+ // Enable the RTC Clock
+ RCC->BDCR |= RCC_BDCR_RTCEN;
+
+ // Disable the write protection for RTC registers
+ RTC->WPR = 0xCA;
+ RTC->WPR = 0x53;
+
+ // Check if the Initialization mode is set
+ if (!(RTC->ISR & RTC_ISR_INITF))
+ {
+ // Set the Initialization mode
+ RTC->ISR |= (uint32_t)RTC_ISR_INIT;
+
+ // Wait till RTC is in INIT state and if Time out is reached exit
+ // according to the STM32 manual it's OK to wait without a timeout as it takes from 1 to 2 RTCCLK clock cycles to enter Initialization mode
+ while(!(RTC->ISR & RTC_ISR_INITF));
+ }
+
+ // can be read from the shadow registers only if APB clock is at least 7 times the frequency of the RTC
+ // to avoid adding another check on this, RTC will always be read directly from registers
+ RTC->CR |= RTC_CR_BYPSHAD;
+
+ // Configure the RTC PRER
+ RTC->PRER = (uint32_t)0xFF;
+ RTC->PRER |= ((uint32_t)0x7F << 16);
+
+ // Exit Initialization mode
+ RTC->ISR &= ~RTC_ISR_INIT;
+
+ // Enable the write protection for RTC registers
+ RTC->WPR = 0xFF;
+
+ // disable access to the backup domain
+ PWR->CR &= ~PWR_CR_DBP;
+
+#endif
+
return TRUE;
}
@@ -42,12 +179,18 @@ UINT32 RTC_BinToBcd(UINT32 bin)
INT64 RTC_GetTime()
{
- if (!(RTC->ISR & RTC_ISR_INITS)) { // RTC not set up
+ if (!(RTC->ISR & RTC_ISR_INITS))
+ {
+ // RTC not set up
return 0;
}
-
+
+#ifndef STM32F4_RTC_ENABLE
+
while (!(RTC->ISR & RTC_ISR_RSF)); // wait for shadow register ready
+#endif
+
UINT32 ss = ~RTC->SSR & 255; // sub seconds [s/256]
UINT32 tr = RTC->TR; // time
UINT32 dr = RTC->DR; // date
@@ -65,6 +208,8 @@ INT64 RTC_GetTime()
void RTC_SetTime( INT64 time )
{
+#ifndef STM32F4_RTC_ENABLE
+
RTC->WPR = 0xCA; // disable write protection
RTC->WPR = 0x53;
RTC->ISR = 0xFFFFFFFF; // enter Init mode
@@ -97,8 +242,53 @@ void RTC_SetTime( INT64 time )
RTC->ISR = 0xFFFFFFFF & ~RTC_ISR_INIT; // exit Init mode
RTC->WPR = 0xFF; // enable write protection
+
+#else
+
+ // enable access to the backup domain allowing access to RTC
+ PWR->CR |= PWR_CR_DBP;
+
+ RTC->WPR = 0xCA; // disable write protection
+ RTC->WPR = 0x53;
+
+ // Set the Initialization mode
+ RTC->ISR |= (uint32_t)RTC_ISR_INIT;
+
+ SYSTEMTIME sysTime;
+ Time_ToSystemTime(time, &sysTime);
+ UINT32 tr = RTC_BinToBcd(sysTime.wSecond)
+ | RTC_BinToBcd(sysTime.wMinute) << 8
+ | RTC_BinToBcd(sysTime.wHour) << 16;
+ UINT32 dr = RTC_BinToBcd(sysTime.wDay)
+ | RTC_BinToBcd(sysTime.wMonth) << 8
+ | (sysTime.wDayOfWeek ? sysTime.wDayOfWeek : 7) << 13
+ | RTC_BinToBcd(sysTime.wYear % 100) << 16;
+
+ // Wait till RTC is in INIT state and if Time out is reached exit
+ // according to the STM32 manual it's OK to wait without a timeout as it takes from 1 to 2 RTCCLK clock cycles to enter Initialization mode
+ while(!(RTC->ISR & RTC_ISR_INITF));
+
+ // 24h format
+ RTC->CR &= ~(RTC_CR_FMT);
+ // set time register
+ RTC->TR = tr;
+ // set date register
+ RTC->DR = dr;
+
+ // Exit Initialization mode
+ RTC->ISR &= ~RTC_ISR_INIT;
+
+ // Enable the write protection for RTC registers
+ RTC->WPR = 0xFF;
+
+ // disable access to the backup domain
+ PWR->CR &= ~PWR_CR_DBP;
+
+#endif
}
+#ifndef STM32F4_RTC_ENABLE
+
INT32 RTC_GetOffset()
{
return RTC->BKP0R;
@@ -111,3 +301,5 @@ void RTC_SetOffset(INT32 offset)
RTC->BKP0R = offset;
RTC->WPR = 0xFF; // enable write protection
}
+
+#endif
diff --git a/DeviceCode/Targets/Native/STM32F4/DeviceCode/STM32F4_RTC/Time_Pal_Rtc/time_functions_rtc.cpp b/DeviceCode/Targets/Native/STM32F4/DeviceCode/STM32F4_RTC/Time_Pal_Rtc/time_functions_rtc.cpp
index d020d6caf..ac2e0973c 100644
--- a/DeviceCode/Targets/Native/STM32F4/DeviceCode/STM32F4_RTC/Time_Pal_Rtc/time_functions_rtc.cpp
+++ b/DeviceCode/Targets/Native/STM32F4/DeviceCode/STM32F4_RTC/Time_Pal_Rtc/time_functions_rtc.cpp
@@ -24,11 +24,32 @@ HRESULT Time_Initialize()
RTC_Initialize();
HRESULT res = g_TimeDriver.Initialize();
INT64 time = RTC_GetTime();
+
+#ifndef STM32F4_RTC_ENABLE
+
if (time != 0) {
g_TimeDriver.SetUtcTime(time, FALSE);
INT32 offset = RTC_GetOffset();
g_TimeDriver.SetTimeZoneOffset(offset);
}
+
+#else
+
+ if (time >= 0x10000000)
+ {
+ // RCT value seems to be valid
+ // set time driver value with time from RCT
+ g_TimeDriver.SetUtcTime(time, FALSE);
+ }
+ else
+ {
+ // invalid time from RCT probably because it hasn't been initialized yet
+ // set RTC with time driver value
+ RTC_SetTime(g_TimeDriver.GetUtcTime());
+ }
+
+#endif
+
return res;
}
@@ -41,7 +62,9 @@ INT64 Time_SetUtcTime( INT64 UtcTime, bool calibrate )
INT32 Time_SetTimeZoneOffset(INT32 offset)
{
// offset in minutes
+#ifndef STM32F4_RTC_ENABLE
RTC_SetOffset(offset);
+#endif
return g_TimeDriver.SetTimeZoneOffset(offset);
}
@@ -55,12 +78,21 @@ HRESULT Time_Uninitialize()
INT64 Time_GetUtcTime()
{
+#ifndef STM32F4_RTC_ENABLE
return g_TimeDriver.GetUtcTime();
+#else
+ return RTC_GetTime();
+#endif
}
INT64 Time_GetLocalTime()
{
+#ifndef STM32F4_RTC_ENABLE
return g_TimeDriver.GetLocalTime();
+#else
+ // GetTimeZoneOffset() returns the offset in minutes so we need to convert it back to TIMEUNIT_TO_MINUTES
+ return RTC_GetTime() + (g_TimeDriver.GetTimeZoneOffset() * 600000000);
+#endif
}
INT32 Time_GetTimeZoneOffset()
@@ -137,6 +169,3 @@ LPCSTR Time_CurrentDateTimeToString()
{
return g_TimeDriver.DateTimeToString(Time_GetLocalTime());
}
-
-
-
diff --git a/Solutions/MCBSTM32F400/TinyBooter/TinyBooter.proj b/Solutions/MCBSTM32F400/TinyBooter/TinyBooter.proj
index d9d1375cf..5b5e66862 100644
--- a/Solutions/MCBSTM32F400/TinyBooter/TinyBooter.proj
+++ b/Solutions/MCBSTM32F400/TinyBooter/TinyBooter.proj
@@ -194,8 +194,16 @@
-
-
+
+
+
+
+
+
+
+
+
+
diff --git a/Solutions/MCBSTM32F400/TinyCLR/TinyCLR.proj b/Solutions/MCBSTM32F400/TinyCLR/TinyCLR.proj
index 2869bc261..2775a7024 100644
--- a/Solutions/MCBSTM32F400/TinyCLR/TinyCLR.proj
+++ b/Solutions/MCBSTM32F400/TinyCLR/TinyCLR.proj
@@ -31,6 +31,7 @@
TinyClr_Dat_Start
g_ConfigurationSector
true
+ false
@@ -247,8 +248,16 @@
-
-
+
+
+
+
+
+
+
+
+
+
diff --git a/Solutions/MCBSTM32F400/TinyCLR_NONET/TinyCLR_NONET.proj b/Solutions/MCBSTM32F400/TinyCLR_NONET/TinyCLR_NONET.proj
index 868d7a2c6..99c43c11d 100644
--- a/Solutions/MCBSTM32F400/TinyCLR_NONET/TinyCLR_NONET.proj
+++ b/Solutions/MCBSTM32F400/TinyCLR_NONET/TinyCLR_NONET.proj
@@ -30,6 +30,7 @@
EntryPoint
TinyClr_Dat_Start
g_ConfigurationSector
+ false
@@ -215,8 +216,16 @@
-
-
+
+
+
+
+
+
+
+
+
+
diff --git a/Solutions/MCBSTM32F400/platform_selector.h b/Solutions/MCBSTM32F400/platform_selector.h
index aa4f4f418..d287da611 100644
--- a/Solutions/MCBSTM32F400/platform_selector.h
+++ b/Solutions/MCBSTM32F400/platform_selector.h
@@ -66,6 +66,12 @@
#define SLOW_CLOCKS_TEN_MHZ_GCD 1000000 // GCD(SLOW_CLOCKS_PER_SECOND, 10M)
#define SLOW_CLOCKS_MILLISECOND_GCD 1000 // GCD(SLOW_CLOCKS_PER_SECOND, 1k)
+// RTC clock selection, required when solution has USE_RTC property set to TRUE
+//#define STM32F4_RTC_ENABLE // STM32F4 RTC enabled
+//#define STM32F4_RTC_LSE // STM32F4 RTC clocked by external low power oscilator
+//#define STM32F4_RTC_LSE_BYPASS // STM32F4 RTC bypass LSE oscilator
+//#define STM32F4_RTC_LSI // STM32F4 RTC clocked by internal low-speed internal RC
+
#define FLASH_MEMORY_Base 0x08000000
#define FLASH_MEMORY_Size 0x00100000
#define SRAM1_MEMORY_Base 0x68000000
diff --git a/Solutions/STM32F4DISCOVERY/TinyBooter/TinyBooter.proj b/Solutions/STM32F4DISCOVERY/TinyBooter/TinyBooter.proj
index d8c4f5188..b41e5812f 100644
--- a/Solutions/STM32F4DISCOVERY/TinyBooter/TinyBooter.proj
+++ b/Solutions/STM32F4DISCOVERY/TinyBooter/TinyBooter.proj
@@ -23,6 +23,7 @@
$(ExtraTargets);CompressBin
scatterfile_bootloader_$(COMPILER_TOOL).$(SCATTER_EXT)
scatterfile_bootloader_$(COMPILER_TOOL).$(SCATTER_EXT)
+ false
@@ -194,8 +195,16 @@
-
-
+
+
+
+
+
+
+
+
+
+
diff --git a/Solutions/STM32F4DISCOVERY/TinyCLR/TinyCLR.proj b/Solutions/STM32F4DISCOVERY/TinyCLR/TinyCLR.proj
index bb8254842..06dc83632 100644
--- a/Solutions/STM32F4DISCOVERY/TinyCLR/TinyCLR.proj
+++ b/Solutions/STM32F4DISCOVERY/TinyCLR/TinyCLR.proj
@@ -32,6 +32,7 @@
g_ConfigurationSector
false
+ false
@@ -217,8 +218,16 @@
-
-
+
+
+
+
+
+
+
+
+
+
diff --git a/Solutions/STM32F4DISCOVERY/platform_selector.h b/Solutions/STM32F4DISCOVERY/platform_selector.h
index e1cf20592..39f07a38b 100644
--- a/Solutions/STM32F4DISCOVERY/platform_selector.h
+++ b/Solutions/STM32F4DISCOVERY/platform_selector.h
@@ -65,6 +65,12 @@
#define SLOW_CLOCKS_TEN_MHZ_GCD 1000000 // GCD(SLOW_CLOCKS_PER_SECOND, 10M)
#define SLOW_CLOCKS_MILLISECOND_GCD 1000 // GCD(SLOW_CLOCKS_PER_SECOND, 1k)
+// RTC clock selection, required when solution has USE_RTC property set to TRUE
+//#define STM32F4_RTC_ENABLE // STM32F4 RTC enabled
+//#define STM32F4_RTC_LSE // STM32F4 RTC clocked by external low power oscilator
+//#define STM32F4_RTC_LSE_BYPASS // STM32F4 RTC bypass LSE oscilator
+//#define STM32F4_RTC_LSI // STM32F4 RTC clocked by internal low-speed internal RC
+
#define FLASH_MEMORY_Base 0x08000000
#define FLASH_MEMORY_Size 0x00100000
#define SRAM1_MEMORY_Base 0x20000000