STM32F4 discovery RNG problems - Page 1
Forum section: electronics / general

author: djacobow
author_rank: Super Contributor
timestamp: June 04, 2014, 03:28:41 am
content: I've got an STM32F4 discovery board and am trying to get the RNG to work. It's giving me clock errors, presumably because the 48MHz clock is not configured correctly. Examples I can find don't seem to have any special configuration of the clock, other than turning it on. What am I missing?Seems so easy, and yet....Code:#include "stm32f4xx.h"#include "stm32f4xx_rng.h"#include <stdint.h>int main(void) {volatile int i = 0;uint32_t j;RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_RNG, ENABLE);// RCC_AHB2PeriphResetCmd(RCC_AHB2Periph_RNG, ENABLE); // doesn't make a differenceRNG_DeInit();RNG_Cmd(ENABLE);RNG_ClearFlag(RNG_FLAG_CECS);while (RNG_GetFlagStatus(RNG_FLAG_DRDY == RESET)) {}while(1) {i++;j = RNG_GetRandomNumber();Delay(0x0fffff);}}void Delay(uint32_t nC) {while (nC--) {}}

author: HackedFridgeMagnet
author_rank: Super Contributor
timestamp: June 04, 2014, 03:36:23 am
content: RNG_DeInit(); ? What is that for?maybe something like.RNG_Config();

author: HackedFridgeMagnet
author_rank: Super Contributor
timestamp: June 04, 2014, 03:43:43 am
content: I guess if you don't know where you are setting up your clocks then you may not actually be setting them up.Better check that out.Can you attach a debugger?Here is some code for an STM32 eval board via atollic.Code:/********************************************************************************* @file RNG/RNG_MultiRNG/main.c* @author MCD Application Team* @version V1.0.1* @date 13-April-2012* @brief Main program body******************************************************************************* @attention** <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>** Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");* You may not use this file except in compliance with the License.* You may obtain a copy of the License at:** http://www.st.com/software_license_agreement_liberty_v2** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.********************************************************************************//* Includes ------------------------------------------------------------------*/#include "stm32f4xx.h"#include "stm324xg_eval.h"#include "stm324xg_eval_lcd.h"#include <stdio.h>/** @addtogroup STM32F4xx_StdPeriph_Examples* @{*//** @addtogroup RNG_MultiRNG* @{*//* Private typedef -----------------------------------------------------------*///#define PRINT_ON_USART#define PRINT_ON_LCD/* Private define ------------------------------------------------------------*//* Private macro -------------------------------------------------------------*//* Private variables ---------------------------------------------------------*//* Private function prototypes -----------------------------------------------*/void RNG_Config(void);void Display_Init(void);void Display(uint32_t rng, uint8_t line);#ifdef __GNUC__/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printfset to 'Yes') calls __io_putchar() */#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)#else#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)#endif /* __GNUC__ *//* Private functions ---------------------------------------------------------*//*** @brief Main program* @param None* @retval None*/int main(void){uint32_t random32bit = 0;uint8_t Counter = 0;/*!< At this stage the microcontroller clock setting is already configured,this is done through SystemInit() function which is called from startupfile (startup_stm32f4xx.s) before to branch to application main.To reconfigure the default setting of SystemInit() function, refer tosystem_stm32f4xx.c file*//* Display init (LCD or/and USART)*/Display_Init();/* Key Button configuration */STM_EVAL_PBInit(BUTTON_KEY, BUTTON_MODE_GPIO);/* RNG configuration */RNG_Config();while (1){/* Wait until Key button is pressed */while(STM_EVAL_PBGetState(BUTTON_KEY) != RESET){}/* Loop while Key button is maintained pressed */while(STM_EVAL_PBGetState(BUTTON_KEY) == RESET){}for(Counter = 0; Counter < 8; Counter++){/* Wait until one RNG number is ready */while(RNG_GetFlagStatus(RNG_FLAG_DRDY)== RESET){}/* Get a 32bit Random number */random32bit = RNG_GetRandomNumber();/* Display the Random number value on the LCD or/and USART */Display(random32bit, Counter+1);}}}/*** @brief RNG configuration* @param None* @retval None*/void RNG_Config(void){/* Enable RNG clock source */RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_RNG, ENABLE);/* RNG Peripheral enable */RNG_Cmd(ENABLE);}/*** @brief Display Init (LCD or/and USART)* @param None* @retval None*/void Display_Init(void){#ifdef PRINT_ON_USARTUSART_InitTypeDef USART_InitStructure;/* USARTx configured as follow:- BaudRate = 115200 baud- Word Length = 8 Bits- One Stop Bit- No parity- Hardware flow control disabled (RTS and CTS signals)- Receive and transmit enabled*/USART_InitStructure.USART_BaudRate = 115200;USART_InitStructure.USART_WordLength = USART_WordLength_8b;USART_InitStructure.USART_StopBits = USART_StopBits_1;USART_InitStructure.USART_Parity = USART_Parity_No;USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;STM_EVAL_COMInit(COM1, &USART_InitStructure);printf("\n\r ========================================\n");printf("\n\r ==== Multiple RNG Generator Example ====\n");printf("\n\r ======================================== \n\n\r");printf("\n\r Press key button to generate 8 x 32bit random number\n");#endif#ifdef PRINT_ON_LCD/* Initialize the LCD */STM324xG_LCD_Init();/* Clear the LCD */LCD_Clear(White);/* Set the LCD Text size */LCD_SetFont(&Font8x12);/* Set the LCD Back Color and Text Color*/LCD_SetBackColor(Blue);LCD_SetTextColor(White);LCD_DisplayStringLine(LINE(0x13), " To generate 8x32bit RNG, Press Key >>");/* Set the LCD Text size */LCD_SetFont(&Font16x24);LCD_DisplayStringLine(LINE(0), "*** RNG Example ***");/* Set the LCD Back Color and Text Color*/LCD_SetBackColor(White);LCD_SetTextColor(Blue);LCD_DisplayStringLine(LINE(3)," Press KEY button ");LCD_DisplayStringLine(LINE(5)," to START ");#endif}/*** @brief Display the Random number value on LCD or/and USART* @param rnumber: random number to display* @param line: LCD line number* @retval None*/void Display(uint32_t rnumber, uint8_t line){#ifdef PRINT_ON_LCDuint8_t text;#endif#ifdef PRINT_ON_USARTprintf("\r [ 0x%08x ]\n", rnumber);if (line == 8){printf("\n\r Press key button to generate 8 x 32bit random number\n");}#endif#ifdef PRINT_ON_LCDsprintf((char*)text," [ 0x%08X ] ", rnumber);LCD_DisplayStringLine(LINE(line),text);#endif}/*** @brief Retargets the C library printf function to the USART.* @param None* @retval None*/PUTCHAR_PROTOTYPE{/* Place your implementation of fputc here *//* e.g. write a character to the USART */USART_SendData(EVAL_COM1, (uint8_t) ch);/* Loop until the end of transmission */while (USART_GetFlagStatus(EVAL_COM1, USART_FLAG_TC) == RESET){}return ch;}#ifdef USE_FULL_ASSERT/*** @brief Reports the name of the source file and the source line number* where the assert_param error has occurred.* @param file: pointer to the source file name* @param line: assert_param error line source number* @retval None*/void assert_failed(uint8_t* file, uint32_t line){/* User can add his own implementation to report the file name and line number,ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) *//* Infinite loop */while (1){}}#endif/*** @}*//*** @}*//************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

author: Harvs
author_rank: Super Contributor
timestamp: June 04, 2014, 04:09:13 am
content: If you haven't yet download the packageSTM32F4xx_DSP_StdPeriph_Lib_VxxxWhile the STM32_Discovery package contains all the same libraries as this package (maybe not the DSP stuff, I'm not sure.) This package under /project/examples has at least double the number of peripheral examples. Further the examples aren't tied to several layers of pin and peripheral register renaming that occurs in the discovery board examples (I personally hate this with a passion, makes learning significantly harder.)In that package you'll find a simple yet complete example of how to setup and use the RNG.

author: djacobow
author_rank: Super Contributor
timestamp: June 04, 2014, 04:13:40 am
content: Oh, I had a debugger attached (CoIDE's) and it was showing me the RNG was not happy.The problem was with AHB2 clock. It was apparently too slow. I haven't quite plumbed the clock configuration calls in RCC yet, but it looks to change the clocks, I need to switch the clock source, disable the PLL, set the multipliers and dividers how I want, then reenable the PLL, and switch it back. Easier to just change the way they're set up the first time.What I did that did work was edit some file called stm32f4xx_StdFrameWorkConfig.h and set a macro SET_SYS_MAX_SPEED=1. That macro is used in the reset handlers to set up the PLL to maximum speed.And it started working. :-)Two hours of my life I'm not getting back.Quote from: HackedFridgeMagnet on June 04, 2014, 03:43:43 am

author: HackedFridgeMagnet
author_rank: Super Contributor
timestamp: June 04, 2014, 04:25:10 am
content: QuoteSituation normal for embedded programming.

author: djacobow
author_rank: Super Contributor
timestamp: June 04, 2014, 04:34:59 am
content: Thanks. I'm pretty new to STM32, and am in the steep part of the learning curve. It sort of bugs me that so much of the documentation is in the form of examples. I'd love to see a doc that went peripheral-by-peripheral, through all the registers and control bits and also showed an annotated example or two.I've been trying to work with CoIDE. As near as I can tell, there are "repositories" you can add to your project that have overlapping but very similar functionality. For example, 20 minutes ago, I had a checkbox checked called "STM32F4 Standard Framework." I had no idea what I was doing, but that seemed like something reasonable to include. But it included a file with a reset vector that did some initialization and that initialization was set up such that unless a certain macro was set, would not do anything with the PLLs. OK.But I unchecked that box and instead checked a box called "CMSIS BOOT". This included a different reset handler file. This one was very minimal, clearing registers, setting the SP, and calling main. Interestingly, it also pulled in files called system_stm32f4xx. which included a routine called SystemInit() which did the full PLL setup thing. Except that the reset handler did not call this function. But if I add it at the top of my main, it works, and the RNG works.Nothing of this says anything bad or wrong with STM32 or ARM, but it does say quite a bit about the fragmented nature of these tools, repositories, libraries, examples, and docs. I even find the ST website to be totally inscrutable. If you buy an F4 discovery board, it has a web address silkscreened onto it. If you type it in to your browser, you might expect it takes you to a "get started here" type of site. But no, just some F4 related page you can click on some links, poke around, scroll down, maybe get a doc here, a tool there, some random zip file, etc.Honestly, if there were a programmers reference manual type of doc for the F4 chips, that included all the peripherals, in detail, I'd be inclined to work from scratch and dispense with a lot of this "help."Quote from: Harvs on June 04, 2014, 04:09:13 am

author: HackedFridgeMagnet
author_rank: Super Contributor
timestamp: June 04, 2014, 04:45:06 am
content: QuoteYour not the only one.That's why I often start out with demo code provided by the toolmakers, it's easier to find. The ST forum was quite useful, and just about any post by that Clive guy.

author: dannyf
author_rank: Super Contributor
timestamp: June 04, 2014, 11:34:32 am
content: QuoteHow about rcc?Your code shouldn't run - if it did, it would end up in hard fault isr.

author: djacobow
author_rank: Super Contributor
timestamp: June 04, 2014, 07:05:50 pm
content: Not only was this post unhelpful, it is wrong. First, an ISR would not be called because I did not have the RNG clock error interrupt enabled. Second, the configuration error -- which you unhelpfully allude do but do not point out -- was not that the clock was not running, but that it was not running fast enough. Not perfectly obvious, at least to me, the original poster, or else I would not have asked the question. Finally, the issue had already been resolved, as per the thread.Let me ask, what purpose did you have in writing the post below?Quote from: dannyf on June 04, 2014, 11:34:32 am

author: westfw
author_rank: Super Contributor
timestamp: June 05, 2014, 06:40:16 am
content: QuoteI didn't find anything that says that the RNG clock has a minimum clock speed that must be exceeded, and that wouldn't match my expectations of modern microcontrollers. Why do you think that that was the problem?

author: djacobow
author_rank: Super Contributor
timestamp: June 05, 2014, 06:20:24 pm
content: Because of a comment on line 225 of this filehttps://code.google.com/p/stm32f4-discovery-freertos/source/browse/Drivers/ST/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_rng.c?r=f292ed54da1e328fd129e87bf8dbb73a5b150783Code:or3. In the case of a clock error : the PLL48CLK (RNG peripheral clock source)was not correctly detected (fPLL48CLK< fHCLK/16).This interrupt source is cleared using RNG_ClearITPendingBit(RNG_IT_CEI)function.@note In this case, User have to check that the clock controller iscorrectly configured to provide the RNG clock.Which could mean that the PLL48CLK is not running, or that it is not running fast enough relative to HCLK.The section on the RNG in the reference manual gives a hint why:http://www.st.com/st-web-ui/static/active/en/resource/technical/document/reference_manual/CD00225773.pdf,page 530:One of the features of the RNG is:"40 periods of the PLL48CLK clock signal between two consecutive random numbers"Clearly they do not need all those clocks for the LFSR portion of the RNG; I suspect they need that time in order to make sure that there is sufficient entropy from the noise source to seed the LFSR adequately to get a high quality rand.And finally, there is this from the following page of the RM:"Status bits(in the RNG_SR register) indicate when an abnormal sequence occurs on the seed or whenthe frequency of the PLL48CLK clock is too low. An interrupt can be generated when anerror is detected."Quote from: westfw on June 05, 2014, 06:40:16 am

author: westfw
author_rank: Super Contributor
timestamp: June 06, 2014, 09:41:00 am
content: Thanks! I saw the "40 periods" thing, but missed the other two "clues."