From bcdd7f46d1e19e832b2b5e1a8b18905aff54a6f2 Mon Sep 17 00:00:00 2001 From: Mark Burton Date: Sun, 9 Feb 2014 08:23:19 +0000 Subject: [PATCH 1/3] Add getclksfreq(), wfe(), wfi(), rnd.setup() and rnd.read() functions. wfe() and wfi() just call the underlying ARM functions. getclksfreq() returns a table containing these clock frequencies: SYSCLK, HCLK, PCLK1 and PCLK2. rnd.setup() initialises the random number generator. rnd.read() will call this anyway if the RNG hasn't been initialised before you read from it. If rng.read() ever returns nil to signify a problem, you can call rnd.setup() to re-initialise the RNG. rnd.read() returns a 32 bit random number or nil if the generator signals an error. --- src/platform/stm32f4/cpu.c | 77 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/src/platform/stm32f4/cpu.c b/src/platform/stm32f4/cpu.c index d721fc33..06d92cb4 100644 --- a/src/platform/stm32f4/cpu.c +++ b/src/platform/stm32f4/cpu.c @@ -11,6 +11,8 @@ #include "auxmods.h" #include "cpu.h" +#include "stm32f4xx.h" + //Lua: reset() static int cpu_reset( lua_State *L ) { @@ -19,13 +21,88 @@ static int cpu_reset( lua_State *L ) return 0; } +//Lua: freqtable = getclocksfreq() +static int cpu_getclocksfreq( lua_State *L ) +{ + RCC_ClocksTypeDef rcc_clocks; + RCC_GetClocksFreq( &rcc_clocks ); + lua_newtable( L ); + lua_pushinteger( L, rcc_clocks.SYSCLK_Frequency ); + lua_setfield( L , -2, "SYSCLK" ); + lua_pushinteger( L, rcc_clocks.HCLK_Frequency ); + lua_setfield( L , -2, "HCLK" ); + lua_pushinteger( L, rcc_clocks.PCLK1_Frequency ); + lua_setfield( L , -2, "PCLK1" ); + lua_pushinteger( L, rcc_clocks.PCLK2_Frequency ); + lua_setfield( L , -2, "PCLK2" ); + return 1; +} + +//Lua: wfe() +static int cpu_wfe( lua_State *L ) +{ + __WFE(); + return 0; +} + +//Lua: wfi() +static int cpu_wfi( lua_State *L ) +{ + __WFI(); + + return 0; +} + +static int rng_initialised = 0; + +static int cpu_rng_setup( lua_State *L ) +{ + RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_RNG, ENABLE); + RNG_DeInit(); + RNG_ClearFlag( RNG_FLAG_CECS | RNG_FLAG_SECS ); + RNG_Cmd(ENABLE); + rng_initialised = 1; + + return 0; +} + +static int cpu_rng_read( lua_State *L ) +{ + if( !rng_initialised ) + cpu_rng_setup( L ); + + while( RNG_GetFlagStatus( RNG_FLAG_DRDY ) == RESET ) { + if( RNG_GetFlagStatus( RNG_FLAG_CECS ) == SET || + RNG_GetFlagStatus( RNG_FLAG_SECS ) == SET ) + { + rng_initialised = 0; + lua_pushnil( L ); + return 1; + } + } + + lua_pushinteger( L, RNG_GetRandomNumber() ); + return 1; +} + #define MIN_OPT_LEVEL 2 #include "lrodefs.h" +const LUA_REG_TYPE stm32_cpu_rng_map[] = +{ + { LSTRKEY( "setup" ), LFUNCVAL( cpu_rng_setup ) }, + { LSTRKEY( "read" ), LFUNCVAL( cpu_rng_read ) }, + { LNILKEY, LNILVAL } +}; + // Module function map const LUA_REG_TYPE stm32_cpu_map[] = { + { LSTRKEY( "getclocksfreq" ), LFUNCVAL( cpu_getclocksfreq ) }, { LSTRKEY( "reset" ), LFUNCVAL( cpu_reset ) }, + { LSTRKEY( "wfe" ), LFUNCVAL( cpu_wfe ) }, + { LSTRKEY( "wfi" ), LFUNCVAL( cpu_wfi ) }, + { LSTRKEY( "rng" ), LROVAL( stm32_cpu_rng_map ) }, { LNILKEY, LNILVAL } }; From d217905667096af962992dfc7bc09c834d7b473f Mon Sep 17 00:00:00 2001 From: Mark Burton Date: Wed, 19 Feb 2014 15:05:56 +0000 Subject: [PATCH 2/3] Change stm32f4.cpu.rng.read() to return a number rather than an integer. This ensures the result is always positive when numbers are not 32 integers. --- src/platform/stm32f4/cpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/stm32f4/cpu.c b/src/platform/stm32f4/cpu.c index 06d92cb4..5c9f1ba4 100644 --- a/src/platform/stm32f4/cpu.c +++ b/src/platform/stm32f4/cpu.c @@ -81,7 +81,7 @@ static int cpu_rng_read( lua_State *L ) } } - lua_pushinteger( L, RNG_GetRandomNumber() ); + lua_pushnumber( L, RNG_GetRandomNumber() ); return 1; } From 4cfaeebe1d7e416c413ee5b3ea3fe067e3324a6e Mon Sep 17 00:00:00 2001 From: Mark Burton Date: Mon, 24 Feb 2014 17:30:36 +0000 Subject: [PATCH 3/3] Add functions to read STM32F4 MCU id and unique device id. stm32f4.cpu.read_mcu_device_id() returns a number containing the 32 bit id. stm32f4.cpu.read_unique_device_id() returns an array of 3 numbers. The first number contains bits 0-31, the second number contains bits 32-63 and the last number contains bits 64-95 of the unique device id. --- src/platform/stm32f4/cpu.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/platform/stm32f4/cpu.c b/src/platform/stm32f4/cpu.c index 5c9f1ba4..ce05250e 100644 --- a/src/platform/stm32f4/cpu.c +++ b/src/platform/stm32f4/cpu.c @@ -53,8 +53,29 @@ static int cpu_wfi( lua_State *L ) return 0; } +//Lua: string = read_mcu_device_id() +static int cpu_read_mcu_device_id( lua_State *L ) +{ + lua_pushnumber( L, *(uint32_t *)0xe0042000 ); + return 1; +} + +//Lua: string = read_unique_device_id() +static int cpu_read_unique_device_id( lua_State *L ) +{ + uint32_t *id_addr = (uint32_t *)0x1fff7a10; + lua_newtable( L ); + int i; + for( i = 1; i <= 3; ++i ) { + lua_pushnumber( L, *id_addr++ ); + lua_rawseti( L, -2, i ); + } + return 1; +} + static int rng_initialised = 0; +//Lua: rng.setup() static int cpu_rng_setup( lua_State *L ) { RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_RNG, ENABLE); @@ -66,6 +87,7 @@ static int cpu_rng_setup( lua_State *L ) return 0; } +//Lua: num = rng.read() static int cpu_rng_read( lua_State *L ) { if( !rng_initialised ) @@ -99,6 +121,8 @@ const LUA_REG_TYPE stm32_cpu_rng_map[] = const LUA_REG_TYPE stm32_cpu_map[] = { { LSTRKEY( "getclocksfreq" ), LFUNCVAL( cpu_getclocksfreq ) }, + { LSTRKEY( "read_mcu_device_id" ), LFUNCVAL( cpu_read_mcu_device_id ) }, + { LSTRKEY( "read_unique_device_id" ), LFUNCVAL( cpu_read_unique_device_id ) }, { LSTRKEY( "reset" ), LFUNCVAL( cpu_reset ) }, { LSTRKEY( "wfe" ), LFUNCVAL( cpu_wfe ) }, { LSTRKEY( "wfi" ), LFUNCVAL( cpu_wfi ) },