Jump to content

Using uGFX on bare metal with Coocox coIDE


LeMoussel

Recommended Posts

Hello,

I'm really new in Coocox CoIDE & uGFX library.

In this topic, I propose to build coIDE project with uGFX library V2.1 for STM32F103RB board.

Excuse me for my poor english, I'm french.

Architecture

- OS Abstractions: BareBone

- Chip: STM32F103RB (Cortex-M3 core)

- LCD controller: ILI9325

- Touchscreen controller: ADS7843

- Audio controller: ADC

Step 1: Default coIDE project

coIDE project basic components :

Common

- C Library: Implement the minimal functionality required to allow newlib to link

- Retarget printf: Implementation of printf(), sprintf() to reduce memory footprint

- CMSIS core: CMSIS core for Cortex M3 V3.01

Boot

- CMSIS Boot: CMSIS boot for STM32

Peripheral

- RCC: Reset and clock control driver.

- GPIO: General purpose I/O ports driver.

- EXTI: External interrupt and event controller driver.

- ADC: Analog to digital converter driver.

- USART: Universal synchronous asynchronous receiver transmitter driver

- MISC: Miscellaneous driver.

ib1lUM8ApamDGL.png

I use ARM GCC as the compiler. See CoIDE Compiler Setting.

Step 2: Integrate µGFX with coIDE

Directories

ibufF9ELqOOhiL.png

CoIDE compile settings

Set directory of uGFX library in Includepaths. For this example it is ../ugfx_lib

ij5oYzLHKyIJz.png

Copy gfx.h & gfxconf.example.h from ugfx_lib (directory of uGFX library) to Test_uGFX (directory of coIDE Project).

In Test_uGFX, rename gfxconf.example.h to gfxconf.h

I use bare metal without any underlying OS, I set GFX_USE_OS_RAW32 option to TRUE in gfxconf.h

You must get this

i3hqwQV0S8FAc.png

Step 3: Using GDISP

Enable the entire GDISP module in gfxconf.h (set GFX_USE_GDISP to TRUE).

Copy display config file uGfx library\boards\addons\gdisp\board_ILI9325_hy_stm32_100p.h to board_ILI9325.h in root project directory.

iW1a9ZOYcfEc9.png

Todo .......

Edited by Guest
Link to comment
Share on other sites

You might find it easier to move forward the ugfx integration. Reasons this may help...

1. ugfx supports bare bones implementation using the raw32 pseudo operating system. You only need to provide a tick counter. This also supports (cooperative) multitasking.

2. Ugfx already has implementations of printf etc.

3. Many of the drivers you mention are already provided by ugfx. You only have to write the driver to real hardware interface layer. This layer is written in the ugfx "board" files.

In short it could save you a lot of work.

Link to comment
Share on other sites

Tectu,

when configuring GDISP with ILI9325 driver files , I got this errors.

File: gdisp_lld_ILI9325.c, Line: 23

#include "drivers/gdisp/ILI9325/gdisp_lld_config.h"

I corrected in the following manner:

#include "gdisp_lld_config.h"

File: board_ILI9325.h, Line: 45

rccEnableAHB(RCC_AHBENR_FSMCEN, 0);

Error: gfx_gdisp\board_ILI9325.h:45:16: error: 'RCC_AHBENR_FSMCEN' undeclared (first use in this function)

File: board_ILI9325.h, Line: 58

FSMC_Bank1->BTCR[FSMC_Bank+1] = (6) | (10 << 8) | (10 << 16);

Error: gfx_gdisp\board_ILI9325.h:58:20: error: 'FSMC_Bank' undeclared (first use in this function)

File: board_ILI9325.h, Line: 62

FSMC_Bank1->BTCR[FSMC_Bank] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN;

Error: gfx_gdisp\board_ILI9325.h:62:69: error: 'FSMC_BCR1_MBKEN' undeclared (first use in this function)

Link to comment
Share on other sites

Full compiler log


GCC HOME: D:\Applications\CooCox\GNU Tools ARM Embedded\4.8 2014q2\bin
compile:
[mkdir] Created dir: D:\STM32F103 Projects\Test_uGFX\test_ugfx\Debug\bin
[mkdir] Created dir: D:\STM32F103 Projects\Test_uGFX\test_ugfx\Debug\obj
[cc] 52 total files to be compiled.
[cc] arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb -Wall -ffunction-sections -g -O0 -c -DSTM32F103RB -DSTM32F10X_MD -DUSE_STDPERIPH_DRIVER -D__ASSEMBLY__ "-ID:\STM32F103 Projects\Test_uGFX" "-ID:\STM32F103 Projects\ugfx_lib\src\gdisp\mcufont" "-ID:\STM32F103 Projects\Test_uGFX\cmsis_boot" "-ID:\STM32F103 Projects\ugfx_lib" -ID:\ "-ID:\STM32F103 Projects\ugfx_lib\src" "-ID:\STM32F103 Projects" "-ID:\STM32F103 Projects\ugfx_lib\src\gos" "-ID:\STM32F103 Projects\ugfx_lib\src\gdisp\fonts" "-ID:\STM32F103 Projects\ugfx_lib\src\gdisp" "-ID:\STM32F103 Projects\Test_uGFX\cmsis" "-ID:\STM32F103 Projects\Test_uGFX\stm_lib" "-ID:\STM32F103 Projects\Test_uGFX\stm_lib\inc" "-ID:\STM32F103 Projects\Test_uGFX\gfx_gdisp" '"D:\STM32F103 Projects\ugfx_lib\src\gdisp\fonts\DejaVuSans32.c"' '"D:\STM32F103 Projects\ugfx_lib\src\gdisp\fonts\fixed_10x20.c"' '"D:\STM32F103 Projects\ugfx_lib\src\gdisp\fonts\LargeNumbers.c"' '"D:\STM32F103 Projects\ugfx_lib\src\gdisp\fonts\DejaVuSansBold12_aa.c"' '"D:\STM32F103 Projects\ugfx_lib\src\gdisp\mcufont\mf_scaledfont.c"' '"D:\STM32F103 Projects\Test_uGFX\cmsis_boot\system_stm32f10x.c"' '"D:\STM32F103 Projects\Test_uGFX\gfx_gdisp\gdisp_lld_ILI9325.c"' '"D:\STM32F103 Projects\ugfx_lib\src\gdisp\image_bmp.c"' '"D:\STM32F103 Projects\Test_uGFX\cmsis_boot\startup\startup_stm32f10x_md.c"' '"D:\STM32F103 Projects\ugfx_lib\src\gos\win32.c"' '"D:\STM32F103 Projects\ugfx_lib\src\gos\chibios.c"' '"D:\STM32F103 Projects\Test_uGFX\stm_lib\src\stm32f10x_gpio.c"' '"D:\STM32F103 Projects\ugfx_lib\src\gdisp\image_jpg.c"' '"D:\STM32F103 Projects\ugfx_lib\src\gdisp\fonts\UI1.c"' '"D:\STM32F103 Projects\ugfx_lib\src\gos\osx.c"' '"D:\STM32F103 Projects\Test_uGFX\main.c"' '"D:\STM32F103 Projects\ugfx_lib\src\gdisp\fonts\DejaVuSans16_aa.c"' '"D:\STM32F103 Projects\ugfx_lib\src\gdisp\image_native.c"' '"D:\STM32F103 Projects\ugfx_lib\src\gdisp\fonts\fixed_5x8.c"' '"D:\STM32F103 Projects\ugfx_lib\src\gdisp\fonts\UI2.c"' '"D:\STM32F103 Projects\ugfx_lib\src\gdisp\image_gif.c"' '"D:\STM32F103 Projects\ugfx_lib\src\gdisp\mcufont\mf_font.c"' '"D:\STM32F103 Projects\Test_uGFX\stdio\printf.c"' '"D:\STM32F103 Projects\ugfx_lib\src\gdisp\fonts\DejaVuSansBold12.c"' '"D:\STM32F103 Projects\ugfx_lib\src\gdisp\mcufont\mf_rlefont.c"' '"D:\STM32F103 Projects\ugfx_lib\src\gdisp\mcufont\mf_bwfont.c"' '"D:\STM32F103 Projects\Test_uGFX\stm_lib\src\stm32f10x_rcc.c"' '"D:\STM32F103 Projects\ugfx_lib\src\gos\freertos.c"' '"D:\STM32F103 Projects\ugfx_lib\src\gdisp\fonts\fixed_7x14.c"' '"D:\STM32F103 Projects\Test_uGFX\stm_lib\src\stm32f10x_exti.c"' '"D:\STM32F103 Projects\ugfx_lib\src\gdisp\fonts\DejaVuSans10.c"' '"D:\STM32F103 Projects\Test_uGFX\stm_lib\src\stm32f10x_adc.c"' '"D:\STM32F103 Projects\ugfx_lib\src\gdisp\fonts.c"' '"D:\STM32F103 Projects\ugfx_lib\src\gdisp\mcufont\mf_encoding.c"' '"D:\STM32F103 Projects\Test_uGFX\stm_lib\src\stm32f10x_usart.c"' '"D:\STM32F103 Projects\ugfx_lib\src\gdisp\fonts\DejaVuSans12.c"' '"D:\STM32F103 Projects\ugfx_lib\src\gdisp\fonts\DejaVuSans32_aa.c"' '"D:\STM32F103 Projects\Test_uGFX\syscalls\syscalls.c"' '"D:\STM32F103 Projects\ugfx_lib\src\gdisp\mcufont\mf_justify.c"' '"D:\STM32F103 Projects\ugfx_lib\src\gos\linux.c"' '"D:\STM32F103 Projects\ugfx_lib\src\gdisp\fonts\DejaVuSans16.c"' '"D:\STM32F103 Projects\ugfx_lib\src\gdisp\gdisp.c"' '"D:\STM32F103 Projects\ugfx_lib\src\gdisp\image_png.c"' '"D:\STM32F103 Projects\ugfx_lib\src\gfx.c"' '"D:\STM32F103 Projects\Test_uGFX\stm_lib\src\misc.c"' '"D:\STM32F103 Projects\ugfx_lib\src\gdisp\fonts\DejaVuSans24.c"' '"D:\STM32F103 Projects\ugfx_lib\src\gdisp\mcufont\mf_wordwrap.c"' '"D:\STM32F103 Projects\ugfx_lib\src\gos\raw32.c"' '"D:\STM32F103 Projects\ugfx_lib\src\gdisp\image.c"' '"D:\STM32F103 Projects\ugfx_lib\src\gdisp\fonts\DejaVuSans12_aa.c"' '"D:\STM32F103 Projects\ugfx_lib\src\gdisp\fonts\DejaVuSans24_aa.c"' '"D:\STM32F103 Projects\ugfx_lib\src\gdisp\mcufont\mf_kerning.c"'
[cc] In file included from D:\STM32F103 Projects\Test_uGFX\gfx_gdisp\gdisp_lld_ILI9325.c:27:0:
[cc] D:\STM32F103 Projects\Test_uGFX\gfx_gdisp\board_ILI9325.h: In function 'init_board':
[cc] D:\STM32F103 Projects\Test_uGFX\gfx_gdisp\board_ILI9325.h:45:3: warning: implicit declaration of function 'rccEnableAHB' [-Wimplicit-function-declaration]
[cc] rccEnableAHB(RCC_AHBENR_FSMCEN, 0); //
[cc] ^
[cc] D:\STM32F103 Projects\Test_uGFX\gfx_gdisp\board_ILI9325.h:45:16: error: 'RCC_AHBENR_FSMCEN' undeclared (first use in this function)
[cc] rccEnableAHB(RCC_AHBENR_FSMCEN, 0); //
[cc] ^
[cc] D:\STM32F103 Projects\Test_uGFX\gfx_gdisp\board_ILI9325.h:45:16: note: each undeclared identifier is reported only once for each function it appears in
[cc] D:\STM32F103 Projects\Test_uGFX\gfx_gdisp\board_ILI9325.h:58:3: error: 'FSMC_Bank1' undeclared (first use in this function)
[cc] D:\STM32F103 Projects\Test_uGFX\gfx_gdisp\board_ILI9325.h:62:33: error: 'FSMC_BCR1_MWID_0' undeclared (first use in this function)
[cc] ^
[cc] FSMC_Bank1->BTCR[FSMC_Bank+1] = (6) | (10 << 8) | (10 << 16);
[cc] FSMC_Bank1->BTCR[FSMC_Bank] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN;
[cc] D:\STM32F103 Projects\Test_uGFX\gfx_gdisp\board_ILI9325.h:62:52: error: 'FSMC_BCR1_WREN' undeclared (first use in this function)
[cc] FSMC_Bank1->BTCR[FSMC_Bank] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN;
[cc] D:\STM32F103 Projects\Test_uGFX\gfx_gdisp\board_ILI9325.h:62:69: error: 'FSMC_BCR1_MBKEN' undeclared (first use in this function)
[cc] FSMC_Bank1->BTCR[FSMC_Bank] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN;
[cc] ^
[cc] D:\STM32F103 Projects\Test_uGFX\gfx_gdisp\gdisp_lld_ILI9325.c: In function 'gdisp_lld_init':
[cc] D:\STM32F103 Projects\Test_uGFX\gfx_gdisp\gdisp_lld_ILI9325.c:98:11: warning: variable 'cver' set but not used [-Wunused-but-set-variable]
[cc] uint16_t cver;
[cc] ^
[cc] ^
[cc] ^
[cc] D:\STM32F103 Projects\Test_uGFX\main.c: In function 'main':
[cc] D:\STM32F103 Projects\Test_uGFX\main.c:16:18: warning: variable 'height' set but not used [-Wunused-but-set-variable]
[cc] coord_t width, height;
[cc] ^
[cc] D:\STM32F103 Projects\Test_uGFX\main.c:16:11: warning: variable 'width' set but not used [-Wunused-but-set-variable]
[cc] coord_t width, height;
[cc] ^

BUILD FAILED
Total time: 11 seconds

main.c



#include "gfx.h"

int main(void)
{
coord_t width, height;

// Initialize and clear the display
gfxInit();

// Get the screen size
width = gdispGetWidth();
height = gdispGetHeight();

while(TRUE)
{
gfxSleepMilliseconds(500);
}
}

Link to comment
Share on other sites

The inclusion of the path when including the gdisp_lld_config.h has historically been required. This is due to multiple display support. I have been slowly changing things to a directory relative path where possible in the latest code. The full path should have worked for you anyway as you included "../ugfx_lib" in your include path and that path is relative to that directory.

The board file that you are using has been written assuming the ChibiOS operating system. It is ChibiOS that has provided the rccEnableAHB() function and the FMSC_Bank1 global variable.

Board files are the interface between the driver and the real hardware. They don't need to know about how to drive the controller but they do need to know how to talk to the hardware. As this often involves SPI or some other function that is wrapped by the operating system, these board files tend to be hardware and operating system specific.

As you are using RAW32 the board file will need to be updated using whatever mechanism you have available to you to talk to the hardware eg some combination of the STM32 library and direct bit banging.

FMSC_Bank1 refers to the STM32 FMSC registers, FSMC_BCR1_MBK is a STM32 bit within that register set and rccEnableAHB() is a function provided by ChibiOS to enable FMSC operation on a STM32 cpu. Similiarly palClearPad() and palSetPad() are functions for GPIO pin manipulation provided by ChibiOS.

I hope that helps.

Link to comment
Share on other sites

Just as a little tidy up aside,

gfx.h does not need to be copied to a local project directory. It is never changed by a ugfx program and can be found from the include path "../ugfx_lib".

Similiarly, as the gdisp driver files are not altered you could just add them to the compile from where they normally sit in the master ugfx source. The board_ILI9325.h file would then be placed in the same directory as your gfxconf.h file.

Well done on the work you are doing here. Documenting as you go is a great idea.

Thank-you.

Link to comment
Share on other sites

I move gfx.h to ../ugfx_lib directory. It's OK.

I place the file board_ILI9325.h in the same directory as gfxconf.h file (in root project directory). It's OK.

I add the ILI9325 gdisp driver files to the compile from the master ugfx source (../ugfx_lib/drivers/gdisp/ILI9325) . It's OK.

I've updated the last image with this information.

It remains to see how to update the board file when using the bare metal port without any underlying OS (RAW32).

Link to comment
Share on other sites

It is recommended to copy the /drivers/gdisp/ILI9325/board_ILI9325_template.h file to your project and keep it's routines empty so you can see if everything compiles successfully first. This will save you a lot of trouble.

From there you just have to use the STM stdperiph library functions to control your microcontrollers peripheral. There is sadly no example/template available for this setup.

~ Tectu

Link to comment
Share on other sites

I copy the /drivers/gdisp/ILI9325/board_ILI9325_template.h file to board_ILI9325.h in the same directory as gfxconf.h file (in root project directory).

I get this errors :


[cc] ..\obj\raw32.o: In function `gfxSleepMilliseconds':
[cc] D:\STM32F103 Projects\ugfx_lib\src\gos/raw32.c:381: undefined reference to `gfxMillisecondsToTicks'
[cc] D:\STM32F103 Projects\ugfx_lib\src\gos/raw32.c:382: undefined reference to `gfxSystemTicks'
[cc] D:\STM32F103 Projects\ugfx_lib\src\gos/raw32.c:386: undefined reference to `gfxSystemTicks'
[cc] ..\obj\raw32.o: In function `gfxSleepMicroseconds':
[cc] D:\STM32F103 Projects\ugfx_lib\src\gos/raw32.c:403: undefined reference to `gfxMillisecondsToTicks'
[cc] D:\STM32F103 Projects\ugfx_lib\src\gos/raw32.c:404: undefined reference to `gfxSystemTicks'
[cc] D:\STM32F103 Projects\ugfx_lib\src\gos/raw32.c:408: undefined
[cc] D:\STM32F103 Projects\ugfx_lib\src\gos/raw32.c:408: undefined reference to `gfxSystemTicks'
[cc] collect2.exe: error: ld returned 1 exit status

So I find in raw32.h this remarks

 * 	You must also define the following routines in your own code so that timing functions will work...
* systemticks_t gfxSystemTicks(void);
* systemticks_t gfxMillisecondsToTicks(delaytime_t ms);

In main.c I do

/* Includes ------------------------------------------------------------------*/
#include "gfx.h"

/* Private function prototypes -----------------------------------------------*/
systemticks_t gfxSystemTicks(void);
systemticks_t gfxMillisecondsToTicks(delaytime_t ms);

/**
* @brief Main program.
* @param None
* @retval None
*/
int main(void)
{
coord_t width, height;

// Initialize and clear the display
gfxInit();

// Get the screen size
width = gdispGetWidth();
height = gdispGetHeight();

while(TRUE)
{
gfxSleepMilliseconds(500);
}
}

systemticks_t gfxSystemTicks(void)
{
return 0;
}

systemticks_t gfxMillisecondsToTicks(delaytime_t ms)
{
return ms;
}

Everything compiles successfully 8-)

Link to comment
Share on other sites

Well I find some systick API from the standard peripheral library to implement gfxSystemTicks(void) like this


/**
* @brief Gets a "tick" time from the hardware.
* @param None
* @retval a "tick" time
*/
systemticks_t gfxSystemTicks(void)
{
return SysTick->VAL;
}

And in main.c, I call SysTick_Config() function to initialize SysTick

/**
* @brief Main program.
* @param None
* @retval None
*/
int main(void)
{
coord_t width, height;

/* Set the HCLK Clock as SysTick clock source (72MHz) */
/* Setup SysTick Timer for 1 msec interrupts */
SysTick_Config(72000000 / 1000);
.....

If I understood for the gfxMillisecondsToTicks() function, you have to convert convert a number of milliseconds to a number of ticks.

Link to comment
Share on other sites

So a timer at 72MHz gets 72 000 000 ticks per second.

/**
* @brief Converts a number of milliseconds to a number of ticks.
* @param None
* @retval a "tick" time
*/
systemticks_t gfxMillisecondsToTicks(delaytime_t ms)
{
uint32_t TicksPerSecond = 72000000;
systemticks_t TicksPerMillisecond = TicksPerSecond / 1000;

return ms * TicksPerMillisecond;
}

is this true?

Link to comment
Share on other sites

No. A tick is not the speed of the cpu. It is an arbitrary unit of time derived from the clock oscillator.

For example many embedded operating system use a 100 hz tick. DOS use to use 18.2 ticks per second.

The tick that you used for gfxgetsystemticks is the one that you initialised 1 tick = 1ms using systick_Config. Based on that your multiply factor is 1 so gfxMillisecondsToTicks (ms) will just return ms.

Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...