LeMoussel Posted October 20, 2014 Report Posted October 20, 2014 I tested the gfxSleepMilliseconds function with the following codeint main(void){ GPIO_Configuration(); /* SystemCoreClock is 72000000Hz (72MHz) */ /* Set the HCLK Clock as SysTick clock source (72MHz) and Setup SysTick Timer for 1 msec interrupts */ SysTick_Config(SystemCoreClock / 1000); // Initialize and clear the display gfxInit(); while(TRUE) { LED1 = 1; // Turn on LED 1. LED2 = 0; // Turn off LED 2. gfxSleepMilliseconds(1000); // Wait 1 Sec; LED1 = 0; // Turn off LED 1. LED2 = 1; // Turn on LED 2. gfxSleepMilliseconds(1000); }}/*** @brief Gets a "tick" time from the hardware.* @param None* @retval a "tick" time*/systemticks_t gfxSystemTicks(void){ return SysTick->VAL;}/*** @brief Converts a number of milliseconds to a number of ticks.* @param None* @retval number of ticks*/systemticks_t gfxMillisecondsToTicks(delaytime_t ms){ return ms;}No LED blinkingWith this code LED blinkingint main(void){ GPIO_Configuration(); while(TRUE) { LED1 = 1; // Turn on LED 1. LED2 = 0; // Turn off LED 2. Delay(5000); LED1 = 0; // Turn off LED 1. LED2 = 1; // Turn on LED 2. Delay(5000); }}void Delay(uint16_t time){ uint16_t i,j; for(i=time;i>0;i--) { for(j=500;j>0;j--); }}Do you have an idea why the LEDs do not blink with the use of gfxSleepMilliseconds()?
Joel Bodenmann Posted October 20, 2014 Report Posted October 20, 2014 Where does the Delay() function come from? Can you show us it's implementation? I haven't worked with the stdperiph library for a long time.~ Tectu
inmarket Posted October 20, 2014 Report Posted October 20, 2014 Delay () won't work as part of the implementation of gfxsleepmilliseconds () because it doesn't allow anything else to happen while sleeping. I suspect the tick timer has not been initialised correctly.As a simple test write a loop that gets the tick value and when it has increased by 1000 then it toggles the leds. Is the tick counter even updating?
LeMoussel Posted October 21, 2014 Author Report Posted October 21, 2014 inmarket, it seems that you are right when you say I suspect the tick timer has not been initialised correctly.I took the code of gfxSleepMilliseconds() in the following wayvoid TestgfxSleepMilliseconds(delaytime_t ms){ systemticks_t currenttm, starttm, delay; // Convert delay to ticks delay = gfxMillisecondsToTicks(ms); starttm = gfxSystemTicks(); do { currenttm = gfxSystemTicks(); } while (currenttm - starttm < delay);}I do not know why the value in currenttm is always less than the value in starttm !With this test that handle SysTick it's OK /* Includes ------------------------------------------------------------------*/#include "stm32f10x_conf.h"// https://bitbucket.org/Tectu/ugfx/src/a61b4a71159f?at=master#include "gfx.h"#include "hardware.h"/* Private function prototypes -----------------------------------------------*/systemticks_t gfxSystemTicks(void);systemticks_t gfxMillisecondsToTicks(delaytime_t ms);// LED Definitions#define LED1 PAout(2) // on the board corresponds to LED1#define LED2 PAout(3) // on the board corresponds to LED2void GPIO_Configuration(void);void TestgfxSleepMilliseconds(delaytime_t ms);void mygfxSleepMilliseconds(volatile uint32_t nTime);void SysTick_Handler(void);static volatile uint32_t TimingDelay;/*** @brief Main program.* @param None* @retval None*/int main(void){ coord_t width, height; /* SystemCoreClock is 72000000Hz (72MHz) */ /* Setup SysTick Timer for 1 msec interrupts */ while(SysTick_Config(SystemCoreClock / 1000)); GPIO_Configuration(); // Initialize and clear the display //gfxInit(); // Get the screen size //width = gdispGetWidth(); //height = gdispGetHeight(); //gdispClear(Green); while(TRUE) { LED1 = 1; // Turn on LED 1. LED2 = 0; // Turn off LED 2. // Wait 1 Sec mygfxSleepMilliseconds(1000); // OK //TestgfxSleepMilliseconds(1000); // KO LED1 = 0; // Turn off LED 1. LED2 = 1; // Turn on LED 2. mygfxSleepMilliseconds(1000); }}void TestgfxSleepMilliseconds(delaytime_t ms){ systemticks_t currenttm, starttm, delay; // Convert delay to ticks delay = gfxMillisecondsToTicks(ms); starttm = gfxSystemTicks(); do { currenttm = gfxSystemTicks(); } while (currenttm - starttm < delay); // Sick ! currenttm is always < starttm, Why ?}void mygfxSleepMilliseconds(volatile uint32_t nTime){ TimingDelay = nTime; while(TimingDelay != 0);}/** * @brief This function handles SysTick Handler. * @param None * @retval : None */void SysTick_Handler(void){ if (TimingDelay != 0x00) { TimingDelay--; }}/*** @brief Configure IO port.* @param None* @retval None*/void GPIO_Configuration(void){ GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // enable port, it is important! ! ! GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3; // Configure LED1, LED2 pin functions GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // universal push-pull output GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // maximum output frequency is 50MHz GPIO_Init (GPIOA, & GPIO_InitStructure); // initialization PA2, PA3}/*** @brief Gets a "tick" time from the hardware.* @param None* @retval a "tick" time*/systemticks_t gfxSystemTicks(void){ return SysTick->VAL;}/*** @brief Converts a number of milliseconds to a number of ticks.* @param None* @retval number of ticks*/systemticks_t gfxMillisecondsToTicks(delaytime_t ms){ return ms;}
inmarket Posted October 22, 2014 Report Posted October 22, 2014 Simple replacement method...In your systick_Config handler function just increment a volatile uint32_t variable.gfxSystemTicks should then just return that variable.gfxsleepmilliseconds should then work.
LeMoussel Posted October 22, 2014 Author Report Posted October 22, 2014 I do this/* Includes ------------------------------------------------------------------*/#include "stm32f10x_conf.h"// https://bitbucket.org/Tectu/ugfx/src/a61b4a71159f?at=master#include "gfx.h"#include "hardware.h"/* Private function prototypes -----------------------------------------------*/systemticks_t gfxSystemTicks(void);systemticks_t gfxMillisecondsToTicks(delaytime_t ms);// LED Definitions#define LED1 PAout(2) // on the board corresponds to LED1#define LED2 PAout(3) // on the board corresponds to LED2void GPIO_Configuration(void);void TestgfxSleepMilliseconds(delaytime_t ms);void SysTick_Handler(void);static volatile uint32_t TimingDelay = 0;/*** @brief Main program.* @param None* @retval None*/int main(void){ /* Setup STM32 system (clock, PLL and Flash configuration) */ SystemInit(); /* Enable port GPIOA, GPIOB, GPIOC, GPIOD, GPIOE, GPIOF, GPIOG and AFIO clocks */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_GPIOF | RCC_APB2Periph_GPIOG | RCC_APB2Periph_AFIO | RCC_APB2Periph_ADC1, ENABLE); /* DMA1 and DMA2 clock enable */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 | RCC_AHBPeriph_DMA2, ENABLE); /* SystemCoreClock is 72000000Hz (72MHz) */ /* Setup SysTick Timer for 1 msec interrupts */ while(SysTick_Config(SystemCoreClock / 1000)); GPIO_Configuration(); while(TRUE) { LED1 = 1; // Turn on LED 1. LED2 = 0; // Turn off LED 2. // Wait 1 Sec TestgfxSleepMilliseconds(1000); // OK gfxSleepMilliseconds(1000); // KO no Return LED1 = !LED1; // Turn off LED 1. LED2 = !LED2; // Turn on LED 2. TestgfxSleepMilliseconds(1000); }}void TestgfxSleepMilliseconds(delaytime_t ms){ systemticks_t currenttm, starttm, delay; // Convert delay to ticks delay = gfxMillisecondsToTicks(ms); starttm = gfxSystemTicks(); do { currenttm = gfxSystemTicks(); } while (currenttm - starttm < delay);}/** * @brief This function handles SysTick Handler. * @param None * @retval : None */void SysTick_Handler(void){ TimingDelay++;}/*** @brief Configure IO port.* @param None* @retval None*/void GPIO_Configuration(void){ GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3; // Configure LED1, LED2 pin functions GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // universal push-pull output GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // maximum output frequency is 50MHz GPIO_Init (GPIOA, & GPIO_InitStructure); // initialization PA2, PA3}/*** @brief Gets a "tick" time from the hardware.* @param None* @retval a "tick" time*/systemticks_t gfxSystemTicks(void){ return TimingDelay;}/*** @brief Converts a number of milliseconds to a number of ticks.* @param None* @retval number of ticks*/systemticks_t gfxMillisecondsToTicks(delaytime_t ms){ return ms;}It's OK with me test function TestgfxSleepMilliseconds() but KO with gfxSleepMilliseconds()gfxSleepMilliseconds(...) can't return. This seems to be in gfxYield() function in this linevoid gfxYield(void) { if (!_setjmp(current->cxt)) { .....Rem : I use the bare metal port without any underlying OS.
inmarket Posted October 23, 2014 Report Posted October 23, 2014 You must still do the gfxinit () call as that initialises the code that gfxYield uses.At least you now know you have valid gfxSystemTicks and gfxMillisecondsToTicks functions.
LeMoussel Posted October 26, 2014 Author Report Posted October 26, 2014 Yep with the gfxinit () call, It's OK 8-) Thanks for your help.Final source code :/* Includes ------------------------------------------------------------------*/#include "stm32f10x_conf.h"// https://bitbucket.org/Tectu/ugfx/src/a61b4a71159f?at=master#include "gfx.h"#include "hardware.h"/* Private function prototypes -----------------------------------------------*/systemticks_t gfxSystemTicks(void);systemticks_t gfxMillisecondsToTicks(delaytime_t ms);// LED Definitions#define LED1 PAout(2) // on the board corresponds to LED1#define LED2 PAout(3) // on the board corresponds to LED2void GPIO_Configuration(void);void SysTick_Handler(void);static volatile uint32_t TimingDelay = 0;/*** @brief Main program.* @param None* @retval None*/int main(void){ /* Setup STM32 system (clock, PLL and Flash configuration) */ SystemInit(); /* Enable port GPIOA, GPIOB, GPIOC, GPIOD, GPIOE, GPIOF, GPIOG and AFIO clocks */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_GPIOF | RCC_APB2Periph_GPIOG | RCC_APB2Periph_AFIO | RCC_APB2Periph_ADC1, ENABLE); /* DMA1 and DMA2 clock enable */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 | RCC_AHBPeriph_DMA2, ENABLE); /* SystemCoreClock is 72000000Hz (72MHz) */ /* Setup SysTick Timer for 1 msec interrupts */ while(SysTick_Config(SystemCoreClock / 1000)); GPIO_Configuration(); // Initialize UGfx gfxInit(); while(TRUE) { LED1 = 1; // Turn on LED 1. LED2 = 0; // Turn off LED 2. gfxSleepMilliseconds(1000); // Wait 1 Sec; LED1 = !LED1; // Turn off LED 1. LED2 = !LED2; // Turn on LED 2. gfxSleepMilliseconds(1000); // Wait 1 Sec; }}/** * @brief This function handles SysTick Handler. * @param None * @retval : None */void SysTick_Handler(void){ TimingDelay++;}/*** @brief Configure IO port.* @param None* @retval None*/void GPIO_Configuration(void){ GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3; // Configure LED1, LED2 pin functions GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // universal push-pull output GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // maximum output frequency is 50MHz GPIO_Init (GPIOA, & GPIO_InitStructure); // initialization PA2, PA3}/*** @brief Gets a "tick" time from the hardware.* @param None* @retval a "tick" time*/systemticks_t gfxSystemTicks(void){ return TimingDelay;}/*** @brief Converts a number of milliseconds to a number of ticks.* @param None* @retval number of ticks*/systemticks_t gfxMillisecondsToTicks(delaytime_t ms){ return ms;}
Constantine Posted September 30, 2016 Report Posted September 30, 2016 (edited) Hello guys!) Could somebody clearly explain what these two functions should do: systemticks_t gfxSystemTicks(void){} and systemticks_t gfxMillisecondsToTicks(delaytime_t ms){} /* I'm using STM32 MCU with its awkward-to-handle HAL. And trying to build bare hardware)) project from this article: https://wiki.ugfx.io/index.php/Using_Keil_µVision_5_MDK-ARM */ In HAL this function: HAL_GetTick() returns ticks, One tick == one millisecond. It is obvious from this code - look file stm32fXxx_hal.c: ** * @brief This function provides accurate delay (in milliseconds) based * on variable incremented. * @note In the default implementation , SysTick timer is the source of time base. * It is used to generate interrupts at regular time intervals where uwTick * is incremented. * @note ThiS function is declared as __weak to be overwritten in case of other * implementations in user file. * @param Delay: specifies the delay time length, in milliseconds. * @retval None */ __weak void HAL_Delay(__IO uint32_t Delay) { uint32_t tickstart = 0; tickstart = HAL_GetTick(); while((HAL_GetTick() - tickstart) < Delay) { } } It will be the same for any STM32 MCU. So I try to implement it like this: systemticks_t gfxSystemTicks(void){ return ((systemticks_t)(HAL_GetTick())); } systemticks_t gfxMillisecondsToTicks(delaytime_t ms){ return ((systemticks_t)ms); } Because I suppose that 'gfxSystemTicks' provides system time for GUI library. And 'gfxMillisecondsToTicks' converts some mysterious internal GUI ticks into millisecond. I can compare this with emWin - there was just one variable 'extern volatile GUI_TIMER_TIME OS_TimeMS;' that you should increment every millisecond. It serves for emWin like a command to refresh screen. B.R. Constantine Edited October 1, 2016 by Joel Bodenmann Using CodeBox
inmarket Posted September 30, 2016 Report Posted September 30, 2016 What you have done is correct. The problem with the emWin approach is that not all hardware can generate a millisecond counter. Eg Old x86 hardware uses a 18.2ms hardware tick. Using the emWin strategy prevents easy use on that type of hardware. UGFX however overcomes that by not assuming that a tick is 1ms. It doesn't even need a regular hardware tick interrupt thereby enabling use on tickless hardware and operating systems eg Chibios in tickless mode. All it requires is the ability to measure time in some arbitrary manner through the use of a function call, and a way to translate between that arbitrary time measure and milliseconds.
Joel Bodenmann Posted October 1, 2016 Report Posted October 1, 2016 On 9/30/2016 at 10:59, Constantine said: Could somebody clearly explain what these two functions should do: systemticks_t gfxSystemTicks(void){} and systemticks_t gfxMillisecondsToTicks(delaytime_t ms){} Those functions are explained here: https://wiki.ugfx.io/index.php/BareMetal
Constantine Posted October 1, 2016 Report Posted October 1, 2016 (edited) Thanks Joel. B.R. Constantine. Edited October 1, 2016 by Constantine
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now