aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoel Bodenmann <joel@unormal.org>2013-11-10 21:07:16 +0100
committerJoel Bodenmann <joel@unormal.org>2013-11-10 21:07:16 +0100
commitda2740b706d720292113445ee1db30f8a9873dc4 (patch)
tree8f8b1902d4af6a23b3daf26990f580b76ea31ea4
parent6ca3537a696e7ace8098771a9a7105380604253d (diff)
parenta8ce005e2621b0108863297948cea0fa52c8bf2a (diff)
downloaduGFX-da2740b706d720292113445ee1db30f8a9873dc4.tar.gz
uGFX-da2740b706d720292113445ee1db30f8a9873dc4.tar.bz2
uGFX-da2740b706d720292113445ee1db30f8a9873dc4.zip
merging GDISPStreaming
-rw-r--r--Doxygenfile2
-rw-r--r--boards/addons/gdisp/ED060SC4_example_schematics.pngbin0 -> 305333 bytes
-rw-r--r--boards/addons/gdisp/board_ED060SC4_example.h143
-rw-r--r--boards/addons/gdisp/board_HX8347D_stm32f4discovery.h160
-rw-r--r--boards/addons/gdisp/board_ILI9320_olimex_pic32mx_lcd.h126
-rw-r--r--boards/addons/gdisp/board_ILI9320_olimex_stm32_lcd.h100
-rw-r--r--boards/addons/gdisp/board_ILI9325_hy_stm32_100p.h112
-rw-r--r--boards/addons/gdisp/board_ILI9481_firebullstm32f103.h107
-rw-r--r--boards/addons/gdisp/board_RA8875_marlin.h113
-rw-r--r--boards/addons/gdisp/board_S6D1121_olimex_e407.h91
-rw-r--r--boards/addons/gdisp/board_SSD1289_firebullstm32f103.h108
-rw-r--r--boards/addons/gdisp/board_SSD1289_stm32f4discovery.h172
-rw-r--r--boards/addons/gdisp/board_SSD1306_i2c.h129
-rw-r--r--boards/addons/gdisp/board_SSD1306_spi.h133
-rw-r--r--boards/addons/gdisp/board_SSD1963_fsmc.h105
-rw-r--r--boards/addons/gdisp/board_SSD1963_gpio.h102
-rw-r--r--boards/addons/gdisp/board_SSD2119_embest_dmstf4bb.h173
-rw-r--r--boards/addons/ginput/touch/ADS7843/ginput_lld_mouse_board_firebull_stm32f103.h (renamed from drivers/ginput/touch/ADS7843/ginput_lld_mouse_board_firebull_stm32f103.h)168
-rw-r--r--boards/addons/ginput/touch/ADS7843/ginput_lld_mouse_board_olimex_stm32_e407.h (renamed from drivers/ginput/touch/ADS7843/ginput_lld_mouse_board_olimex_stm32_e407.h)168
-rw-r--r--boards/addons/ginput/touch/ADS7843/ginput_lld_mouse_board_st_stm32f4_discovery.h (renamed from drivers/ginput/touch/ADS7843/ginput_lld_mouse_board_st_stm32f4_discovery.h)0
-rw-r--r--boards/addons/ginput/touch/FT5x06/ginput_lld_mouse_board_marlin.h (renamed from drivers/ginput/touch/FT5x06/ginput_lld_mouse_board_marlin.h)0
-rw-r--r--boards/addons/ginput/touch/MCU/ginput_lld_mouse_board_olimex_pic32mx_lcd.h (renamed from drivers/ginput/touch/MCU/ginput_lld_mouse_board_olimex_pic32mx_lcd.h)290
-rw-r--r--boards/addons/ginput/touch/MCU/ginput_lld_mouse_board_olimex_stm32_lcd.h (renamed from drivers/ginput/touch/MCU/ginput_lld_mouse_board_olimex_stm32_lcd.h)304
-rw-r--r--boards/addons/ginput/touch/STMPE811/ginput_lld_mouse_board_embest_dmstf4bb.h (renamed from drivers/ginput/touch/STMPE811/ginput_lld_mouse_board_embest_dmstf4bb.h)240
-rw-r--r--boards/addons/tdisp/HD44780/tdisp_lld_board_olimex_e407.h (renamed from drivers/tdisp/HD44780/tdisp_lld_board_olimex_e407.h)118
-rw-r--r--boards/addons/tdisp/HD44780/tdisp_lld_board_st_stm32f4_discovery.h (renamed from drivers/tdisp/HD44780/tdisp_lld_board_st_stm32f4_discovery.h)244
-rw-r--r--boards/base/Linux/board.mk4
-rw-r--r--boards/base/Linux/example/Makefile153
-rw-r--r--boards/base/Linux/example/readme.txt5
-rw-r--r--boards/base/Linux/readme.txt8
-rw-r--r--boards/base/Mikromedia-STM32-M4-ILI9341/ChibiOS_Board/board.c92
-rw-r--r--boards/base/Mikromedia-STM32-M4-ILI9341/ChibiOS_Board/board.h1299
-rw-r--r--boards/base/Mikromedia-STM32-M4-ILI9341/ChibiOS_Board/board.mk7
-rw-r--r--boards/base/Mikromedia-STM32-M4-ILI9341/ChibiOS_Board/board_orig.h1303
-rw-r--r--boards/base/Mikromedia-STM32-M4-ILI9341/ChibiOS_Board/cfg/board.chcfg1186
-rw-r--r--boards/base/Mikromedia-STM32-M4-ILI9341/ChibiOS_Board/flash_memory.c127
-rw-r--r--boards/base/Mikromedia-STM32-M4-ILI9341/ChibiOS_Board/flash_memory.h6
-rw-r--r--boards/base/Mikromedia-STM32-M4-ILI9341/board.mk5
-rw-r--r--boards/base/Mikromedia-STM32-M4-ILI9341/board_ILI9341.h124
-rw-r--r--boards/base/Mikromedia-STM32-M4-ILI9341/example/Makefile232
-rw-r--r--boards/base/Mikromedia-STM32-M4-ILI9341/example/chconf.h531
-rw-r--r--boards/base/Mikromedia-STM32-M4-ILI9341/example/halconf.h312
-rw-r--r--boards/base/Mikromedia-STM32-M4-ILI9341/example/mcuconf.h289
-rw-r--r--boards/base/Mikromedia-STM32-M4-ILI9341/example/openocd.cfg81
-rw-r--r--boards/base/Mikromedia-STM32-M4-ILI9341/ginput_lld_mouse_board.h152
-rw-r--r--boards/base/Mikromedia-STM32-M4-ILI9341/ginput_lld_mouse_config.h32
-rw-r--r--boards/base/Mikromedia-STM32-M4-ILI9341/readme.txt14
-rw-r--r--boards/base/Olimex-SAM7EX256-GE12/board.mk8
-rw-r--r--boards/base/Olimex-SAM7EX256-GE12/board_Nokia6610GE12.h195
-rw-r--r--boards/base/Olimex-SAM7EX256-GE12/readme.txt15
-rw-r--r--boards/base/Olimex-SAM7EX256-GE8/board.mk8
-rw-r--r--boards/base/Olimex-SAM7EX256-GE8/board_Nokia6610GE8.h195
-rw-r--r--boards/base/Olimex-SAM7EX256-GE8/example/Makefile201
-rw-r--r--boards/base/Olimex-SAM7EX256-GE8/example/chconf.h542
-rw-r--r--boards/base/Olimex-SAM7EX256-GE8/example/halconf.h360
-rw-r--r--boards/base/Olimex-SAM7EX256-GE8/example/linker.ld105
-rw-r--r--boards/base/Olimex-SAM7EX256-GE8/example/mcuconf.h71
-rw-r--r--boards/base/Olimex-SAM7EX256-GE8/example/openocd.cfg75
-rw-r--r--boards/base/Olimex-SAM7EX256-GE8/example/readme.txt3
-rw-r--r--boards/base/Olimex-SAM7EX256-GE8/gadc_lld_board.h (renamed from drivers/gadc/AT91SAM7/gadc_lld_board_olimexsam7ex256.h)12
-rw-r--r--boards/base/Olimex-SAM7EX256-GE8/gaudin_lld_board.h33
-rw-r--r--boards/base/Olimex-SAM7EX256-GE8/ginput_lld_dial_board.h30
-rw-r--r--boards/base/Olimex-SAM7EX256-GE8/ginput_lld_toggle_board.h (renamed from drivers/ginput/toggle/Pal/ginput_lld_toggle_board_olimexsam7ex256.h)8
-rw-r--r--boards/base/Olimex-SAM7EX256-GE8/readme.txt14
-rw-r--r--boards/base/Win32/board.mk3
-rw-r--r--boards/base/Win32/example/Makefile195
-rw-r--r--boards/base/Win32/example/chconf.h536
-rw-r--r--boards/base/Win32/example/halconf.h342
-rw-r--r--boards/base/Win32/example/readme.txt9
-rw-r--r--boards/base/Win32/readme.txt9
-rw-r--r--demos/3rdparty/boing/gfxconf.h41
-rw-r--r--demos/3rdparty/boing/main.c109
-rw-r--r--demos/3rdparty/bubbles/gfxconf.h9
-rw-r--r--demos/3rdparty/notepad-2/gfxconf.h9
-rw-r--r--demos/3rdparty/tdisp_f4_discovery/gfxconf.h7
-rw-r--r--demos/applications/mandelbrot/gfxconf.h20
-rw-r--r--demos/applications/notepad/gfxconf.h14
-rw-r--r--demos/benchmarks/gfxconf.h21
-rw-r--r--demos/modules/gadc/gfxconf.h77
-rw-r--r--demos/modules/gaudin/gfxconf.h84
-rw-r--r--demos/modules/gdisp/basics/gfxconf.h6
-rw-r--r--demos/modules/gdisp/circles/gfxconf.h6
-rw-r--r--demos/modules/gdisp/fonts/gfxconf.h22
-rw-r--r--demos/modules/gdisp/fonts_cyrillic/gfxconf.h10
-rw-r--r--demos/modules/gdisp/images/gfxconf.h6
-rw-r--r--demos/modules/gdisp/images_animated/gfxconf.h6
-rw-r--r--demos/modules/gdisp/multiple_displays/gfxconf.h80
-rw-r--r--demos/modules/gdisp/multiple_displays/main.c122
-rw-r--r--demos/modules/gdisp/streaming/gfxconf.h31
-rw-r--r--demos/modules/gdisp/streaming/main.c142
-rw-r--r--demos/modules/ginput/touch_driver_test/gfxconf.h21
-rw-r--r--demos/modules/gtimer/gfxconf.h9
-rw-r--r--demos/modules/gwin/basic/gfxconf.h6
-rw-r--r--demos/modules/gwin/button/gfxconf.h6
-rw-r--r--demos/modules/gwin/checkbox/gfxconf.h6
-rw-r--r--demos/modules/gwin/console/gfxconf.h6
-rw-r--r--demos/modules/gwin/graph/gfxconf.h6
-rw-r--r--demos/modules/gwin/list/gfxconf.h6
-rw-r--r--demos/modules/gwin/radio/gfxconf.h6
-rw-r--r--demos/modules/gwin/slider/gfxconf.h6
-rw-r--r--demos/modules/gwin/widgets/gfxconf.h12
-rw-r--r--demos/modules/tdisp/gfxconf.h9
-rw-r--r--drivers/gadc/AT91SAM7/gadc_lld_board_template.h37
-rw-r--r--drivers/gadc/AT91SAM7/gadc_lld_config.h12
-rw-r--r--drivers/gaudin/gadc/gaudin_lld_board_template.h (renamed from drivers/gaudin/gadc/gaudin_lld_board_olimexsam7ex256.h)15
-rw-r--r--drivers/gaudin/gadc/gaudin_lld_config.h11
-rw-r--r--drivers/gdisp/ED060SC4/board_ED060SC4_template.h202
-rw-r--r--drivers/gdisp/ED060SC4/gdisp_lld.mk2
-rw-r--r--drivers/gdisp/ED060SC4/gdisp_lld_ED060SC4.c625
-rw-r--r--drivers/gdisp/ED060SC4/gdisp_lld_config.h9
-rw-r--r--drivers/gdisp/ED060SC4/readme.txt3
-rw-r--r--drivers/gdisp/HX8347D/HX8347D.h2
-rw-r--r--drivers/gdisp/HX8347D/board_HX8347D_template.h156
-rw-r--r--drivers/gdisp/HX8347D/gdisp_lld.c485
-rw-r--r--drivers/gdisp/HX8347D/gdisp_lld.mk5
-rw-r--r--drivers/gdisp/HX8347D/gdisp_lld_HX8347D.c236
-rw-r--r--drivers/gdisp/HX8347D/gdisp_lld_board_st_stm32f4_discovery.h202
-rw-r--r--drivers/gdisp/HX8347D/gdisp_lld_board_template.h120
-rw-r--r--drivers/gdisp/HX8347D/gdisp_lld_config.h10
-rw-r--r--drivers/gdisp/ILI9320/board_ILI9320_template.h157
-rw-r--r--drivers/gdisp/ILI9320/gdisp_lld.c584
-rw-r--r--drivers/gdisp/ILI9320/gdisp_lld.mk7
-rw-r--r--drivers/gdisp/ILI9320/gdisp_lld_ILI9320.c380
-rw-r--r--drivers/gdisp/ILI9320/gdisp_lld_board_olimex_pic32mx_lcd.h106
-rw-r--r--drivers/gdisp/ILI9320/gdisp_lld_board_olimex_stm32_lcd.h80
-rw-r--r--drivers/gdisp/ILI9320/gdisp_lld_board_template.h53
-rw-r--r--drivers/gdisp/ILI9320/gdisp_lld_config.h64
-rw-r--r--drivers/gdisp/ILI9325/board_ILI9325_template.h155
-rw-r--r--drivers/gdisp/ILI9325/gdisp_lld.c582
-rw-r--r--drivers/gdisp/ILI9325/gdisp_lld.mk5
-rw-r--r--drivers/gdisp/ILI9325/gdisp_lld_ILI9325.c368
-rw-r--r--drivers/gdisp/ILI9325/gdisp_lld_board_hy_stm32_100p.h83
-rw-r--r--drivers/gdisp/ILI9325/gdisp_lld_board_template.h45
-rw-r--r--drivers/gdisp/ILI9325/gdisp_lld_config.h14
-rw-r--r--drivers/gdisp/ILI9341/ILI9341.h87
-rw-r--r--drivers/gdisp/ILI9341/board_ILI9341_template.h154
-rw-r--r--drivers/gdisp/ILI9341/gdisp_lld.mk2
-rw-r--r--drivers/gdisp/ILI9341/gdisp_lld_ILI9341.c353
-rw-r--r--drivers/gdisp/ILI9341/gdisp_lld_config.h35
-rw-r--r--drivers/gdisp/ILI9481/board_ILI9481_template.h155
-rw-r--r--drivers/gdisp/ILI9481/gdisp_lld.c598
-rw-r--r--drivers/gdisp/ILI9481/gdisp_lld.mk5
-rw-r--r--drivers/gdisp/ILI9481/gdisp_lld_ILI9481.c328
-rw-r--r--drivers/gdisp/ILI9481/gdisp_lld_board_firebullstm32f103.h145
-rw-r--r--drivers/gdisp/ILI9481/gdisp_lld_board_template.h107
-rw-r--r--drivers/gdisp/ILI9481/gdisp_lld_config.h11
-rw-r--r--drivers/gdisp/Nokia6610GE12/board_Nokia6610GE12_template.h131
-rw-r--r--drivers/gdisp/Nokia6610GE12/gdisp_lld.c505
-rw-r--r--drivers/gdisp/Nokia6610GE12/gdisp_lld.mk5
-rw-r--r--drivers/gdisp/Nokia6610GE12/gdisp_lld_Nokia6610GE12.c262
-rw-r--r--drivers/gdisp/Nokia6610GE12/gdisp_lld_board_olimexsam7ex256.h183
-rw-r--r--drivers/gdisp/Nokia6610GE12/gdisp_lld_board_template.h114
-rw-r--r--drivers/gdisp/Nokia6610GE12/gdisp_lld_config.h17
-rw-r--r--drivers/gdisp/Nokia6610GE8/board_Nokia6610GE8_template.h131
-rw-r--r--drivers/gdisp/Nokia6610GE8/gdisp_lld.c545
-rw-r--r--drivers/gdisp/Nokia6610GE8/gdisp_lld.mk5
-rw-r--r--drivers/gdisp/Nokia6610GE8/gdisp_lld_Nokia6610GE8.c570
-rw-r--r--drivers/gdisp/Nokia6610GE8/gdisp_lld_board_olimexsam7ex256.h225
-rw-r--r--drivers/gdisp/Nokia6610GE8/gdisp_lld_board_template.h114
-rw-r--r--drivers/gdisp/Nokia6610GE8/gdisp_lld_config.h33
-rw-r--r--drivers/gdisp/RA8875/board_RA8875_template.h143
-rw-r--r--drivers/gdisp/RA8875/gdisp_lld.c449
-rw-r--r--drivers/gdisp/RA8875/gdisp_lld.mk6
-rw-r--r--drivers/gdisp/RA8875/gdisp_lld_RA8875.c283
-rw-r--r--drivers/gdisp/RA8875/gdisp_lld_board_marlin.h193
-rw-r--r--drivers/gdisp/RA8875/gdisp_lld_board_template.h119
-rw-r--r--drivers/gdisp/RA8875/gdisp_lld_config.h13
-rw-r--r--drivers/gdisp/RA8875/ra8875.h18
-rw-r--r--drivers/gdisp/S6D1121/board_S6D1121_template.h154
-rw-r--r--drivers/gdisp/S6D1121/gdisp_lld.c561
-rw-r--r--drivers/gdisp/S6D1121/gdisp_lld.mk5
-rw-r--r--drivers/gdisp/S6D1121/gdisp_lld_S6D1121.c338
-rw-r--r--drivers/gdisp/S6D1121/gdisp_lld_board_olimex_e407.h81
-rw-r--r--drivers/gdisp/S6D1121/gdisp_lld_board_template.h106
-rw-r--r--drivers/gdisp/S6D1121/gdisp_lld_config.h12
-rw-r--r--drivers/gdisp/SSD1289/board_SSD1289_template.h191
-rw-r--r--drivers/gdisp/SSD1289/gdisp_lld.mk5
-rw-r--r--drivers/gdisp/SSD1289/gdisp_lld_SSD1289.c361
-rw-r--r--drivers/gdisp/SSD1289/gdisp_lld_board_firebullstm32f103.h144
-rw-r--r--drivers/gdisp/SSD1289/gdisp_lld_board_st_stm32f4_discovery.h172
-rw-r--r--drivers/gdisp/SSD1289/gdisp_lld_board_template.h106
-rw-r--r--drivers/gdisp/SSD1289/gdisp_lld_config.h24
-rw-r--r--drivers/gdisp/SSD1306/SSD1306.h3
-rw-r--r--drivers/gdisp/SSD1306/board_SSD1306_template.h116
-rw-r--r--drivers/gdisp/SSD1306/gdisp_lld.c646
-rw-r--r--drivers/gdisp/SSD1306/gdisp_lld.mk5
-rw-r--r--drivers/gdisp/SSD1306/gdisp_lld_SSD1306.c280
-rw-r--r--drivers/gdisp/SSD1306/gdisp_lld_board_example_i2c.h137
-rw-r--r--drivers/gdisp/SSD1306/gdisp_lld_board_example_spi.h139
-rw-r--r--drivers/gdisp/SSD1306/gdisp_lld_board_template.h74
-rw-r--r--drivers/gdisp/SSD1306/gdisp_lld_config.h16
-rw-r--r--drivers/gdisp/SSD1963/board_SSD1963_template.h148
-rw-r--r--drivers/gdisp/SSD1963/gdisp_lld.c427
-rw-r--r--drivers/gdisp/SSD1963/gdisp_lld.mk6
-rw-r--r--drivers/gdisp/SSD1963/gdisp_lld_SSD1963.c285
-rw-r--r--drivers/gdisp/SSD1963/gdisp_lld_board_example_fsmc.h177
-rw-r--r--drivers/gdisp/SSD1963/gdisp_lld_board_example_gpio.h191
-rw-r--r--drivers/gdisp/SSD1963/gdisp_lld_board_template.h115
-rw-r--r--drivers/gdisp/SSD1963/gdisp_lld_config.h12
-rw-r--r--drivers/gdisp/SSD1963/gdisp_lld_panel_example.h74
-rw-r--r--drivers/gdisp/SSD1963/ssd1963.h5
-rw-r--r--drivers/gdisp/SSD2119/board_SSD2119_template.h191
-rw-r--r--drivers/gdisp/SSD2119/gdisp_lld.c704
-rw-r--r--drivers/gdisp/SSD2119/gdisp_lld.mk5
-rw-r--r--drivers/gdisp/SSD2119/gdisp_lld_SSD2119.c411
-rw-r--r--drivers/gdisp/SSD2119/gdisp_lld_board_embest_dmstf4bb.h193
-rw-r--r--drivers/gdisp/SSD2119/gdisp_lld_board_template.h109
-rw-r--r--drivers/gdisp/SSD2119/gdisp_lld_config.h20
-rw-r--r--drivers/gdisp/ST7565/board_ST7565_template.h108
-rw-r--r--drivers/gdisp/ST7565/gdisp_lld.c267
-rw-r--r--drivers/gdisp/ST7565/gdisp_lld.mk6
-rw-r--r--drivers/gdisp/ST7565/gdisp_lld_ST7565.c262
-rw-r--r--drivers/gdisp/ST7565/gdisp_lld_board_template.h82
-rw-r--r--drivers/gdisp/ST7565/gdisp_lld_config.h11
-rw-r--r--drivers/gdisp/ST7565/st7565.h3
-rw-r--r--drivers/gdisp/TestStub/gdisp_lld.c118
-rw-r--r--drivers/gdisp/TestStub/gdisp_lld.mk5
-rw-r--r--drivers/gdisp/TestStub/gdisp_lld_TestStub.c61
-rw-r--r--drivers/gdisp/TestStub/gdisp_lld_config.h10
-rw-r--r--drivers/ginput/dial/GADC/ginput_lld_dial_board_template.h (renamed from drivers/ginput/dial/GADC/ginput_lld_dial_board_olimexsam7ex256.h)9
-rw-r--r--drivers/ginput/dial/GADC/ginput_lld_dial_config.h11
-rw-r--r--drivers/ginput/toggle/Pal/ginput_lld_toggle_board_template.h (renamed from drivers/ginput/toggle/Pal/ginput_lld_toggle_board_example.h)84
-rw-r--r--drivers/ginput/toggle/Pal/ginput_lld_toggle_config.h11
-rw-r--r--drivers/ginput/touch/MCU/ginput_lld_mouse.c10
-rw-r--r--drivers/multiple/Win32/gdisp_lld.c1028
-rw-r--r--drivers/multiple/Win32/gdisp_lld.mk5
-rw-r--r--drivers/multiple/Win32/gdisp_lld_Win32.c1160
-rw-r--r--drivers/multiple/Win32/gdisp_lld_config.h46
-rw-r--r--drivers/multiple/Win32/ginput_lld_toggle_config.h15
-rw-r--r--drivers/multiple/Win32/readme.txt13
-rw-r--r--drivers/multiple/X/gdisp_lld.c294
-rw-r--r--drivers/multiple/X/gdisp_lld.mk5
-rw-r--r--drivers/multiple/X/gdisp_lld_X.c340
-rw-r--r--drivers/multiple/X/gdisp_lld_config.h14
-rw-r--r--drivers/tdisp/HD44780/tdisp_lld.c10
-rw-r--r--gfxconf.example.h60
-rw-r--r--include/gdisp/colors.h377
-rw-r--r--include/gdisp/gdisp.h941
-rw-r--r--include/gdisp/image.h14
-rw-r--r--include/gdisp/lld/emulation.c558
-rw-r--r--include/gdisp/lld/gdisp_lld.h933
-rw-r--r--include/gdisp/lld/gdisp_lld_msgs.h181
-rw-r--r--include/gdisp/options.h201
-rw-r--r--include/gfx_rules.h51
-rw-r--r--include/ginput/mouse.h29
-rw-r--r--include/gmisc/gmisc.h18
-rw-r--r--include/gmisc/options.h39
-rw-r--r--include/gwin/button.h4
-rw-r--r--include/gwin/checkbox.h4
-rw-r--r--include/gwin/class_gwin.h6
-rw-r--r--include/gwin/console.h4
-rw-r--r--include/gwin/graph.h4
-rw-r--r--include/gwin/gwin.h5
-rw-r--r--include/gwin/image.h4
-rw-r--r--include/gwin/label.h14
-rw-r--r--include/gwin/list.h16
-rw-r--r--include/gwin/radio.h4
-rw-r--r--include/gwin/slider.h4
-rw-r--r--releases.txt28
-rw-r--r--src/gdisp/gdisp.c3098
-rw-r--r--src/gdisp/image.c17
-rw-r--r--src/gdisp/image_bmp.c12
-rw-r--r--src/gdisp/image_gif.c98
-rw-r--r--src/gdisp/image_native.c6
-rw-r--r--src/gfx.c1
-rw-r--r--src/ginput/mouse.c99
-rw-r--r--src/gmisc/trig.c44
-rw-r--r--src/gwin/button.c66
-rw-r--r--src/gwin/checkbox.c20
-rw-r--r--src/gwin/console.c16
-rw-r--r--src/gwin/gimage.c22
-rw-r--r--src/gwin/graph.c20
-rw-r--r--src/gwin/gwidget.c10
-rw-r--r--src/gwin/gwin.c99
-rw-r--r--src/gwin/gwm.c22
-rw-r--r--src/gwin/label.c16
-rw-r--r--src/gwin/list.c26
-rw-r--r--src/gwin/radio.c34
-rw-r--r--src/gwin/slider.c50
279 files changed, 26608 insertions, 15523 deletions
diff --git a/Doxygenfile b/Doxygenfile
index 3ffd08de..8b583591 100644
--- a/Doxygenfile
+++ b/Doxygenfile
@@ -34,7 +34,7 @@ PROJECT_NAME = uGFX
# This could be handy for archiving the generated documentation or
# if some version control system is used.
-PROJECT_NUMBER = 1.9
+PROJECT_NUMBER = 2.0
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer
diff --git a/boards/addons/gdisp/ED060SC4_example_schematics.png b/boards/addons/gdisp/ED060SC4_example_schematics.png
new file mode 100644
index 00000000..0d9d095f
--- /dev/null
+++ b/boards/addons/gdisp/ED060SC4_example_schematics.png
Binary files differ
diff --git a/boards/addons/gdisp/board_ED060SC4_example.h b/boards/addons/gdisp/board_ED060SC4_example.h
new file mode 100644
index 00000000..cb5a92b8
--- /dev/null
+++ b/boards/addons/gdisp/board_ED060SC4_example.h
@@ -0,0 +1,143 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/* Board interface definitions for ED060SC4 PrimeView E-ink panel.
+ *
+ * This file corresponds to the connections shown in example_schematics.png,
+ * and is designed to interface with ChibiOS/RT.
+ *
+ * Please note that this file has never been tested in exactly this pin
+ * configuration, because the actual boards I have are slightly different.
+ */
+
+#ifndef _GDISP_LLD_BOARD_H
+#define _GDISP_LLD_BOARD_H
+
+#include <hal.h>
+
+/*
+ * IO pins assignments.
+ */
+#define GPIOB_EINK_VDD 0
+#define GPIOB_EINK_GMODE 1
+#define GPIOB_EINK_SPV 2
+#define GPIOB_EINK_CKV 3
+#define GPIOB_EINK_CL 4
+#define GPIOB_EINK_LE 5
+#define GPIOB_EINK_OE 6
+#define GPIOB_EINK_SPH 7
+#define GPIOB_EINK_D0 8
+#define GPIOB_EINK_D1 9
+#define GPIOB_EINK_D2 10
+#define GPIOB_EINK_D3 11
+#define GPIOB_EINK_D4 12
+#define GPIOB_EINK_D5 13
+#define GPIOB_EINK_D6 14
+#define GPIOB_EINK_D7 15
+
+#define GPIOC_SMPS_CTRL 13
+#define GPIOC_VPOS_CTRL 14
+#define GPIOC_VNEG_CTRL 15
+
+static inline void init_board(GDisplay *g) {
+
+ // As we are not using multiple displays we set g->board to NULL as we don't use it.
+ g->board = 0;
+
+ switch(g->controllerdisplay) {
+ case 0: // Set up for Display 0
+ /* Main SMPS power control, active low
+ * (open collector so that MOSFET gate can be pulled up to Vbat) */
+ palWritePad(GPIOC, GPIOC_SMPS_CTRL, true);
+ palSetPadMode(GPIOC, GPIOC_SMPS_CTRL, PAL_MODE_OUTPUT_OPENDRAIN);
+
+ /* Power control for the positive & negative side */
+ palWritePad(GPIOC, GPIOC_VPOS_CTRL, false);
+ palSetPadMode(GPIOC, GPIOC_VPOS_CTRL, PAL_MODE_OUTPUT_PUSHPULL);
+ palWritePad(GPIOC, GPIOC_VNEG_CTRL, false);
+ palSetPadMode(GPIOC, GPIOC_VNEG_CTRL, PAL_MODE_OUTPUT_PUSHPULL);
+
+ /* Main data bus */
+ palWritePort(GPIOB, 0);
+ palSetGroupMode(GPIOB, 0xFFFF, 0, PAL_MODE_OUTPUT_PUSHPULL);
+ break;
+ }
+}
+
+/* Delay for display waveforms. Should be an accurate microsecond delay. */
+static void eink_delay(int us) {
+ halPolledDelay(US2RTT(us));
+}
+
+/* Turn the E-ink panel Vdd supply (+3.3V) on or off. */
+static inline void setpower_vdd(GDisplay *g, bool_t on) {
+ (void) g;
+ palWritePad(GPIOB, GPIOB_SMPS_CTRL, !on);
+ palWritePad(GPIOA, GPIOA_EINK_VDD, on);
+}
+
+/* Turn the E-ink panel negative supplies (-15V, -20V) on or off. */
+static inline void setpower_vneg(GDisplay *g, bool_t on) {
+ (void) g;
+ palWritePad(GPIOA, GPIOA_VNEG_CTRL, on);
+}
+
+/* Turn the E-ink panel positive supplies (-15V, -20V) on or off. */
+static inline void setpower_vpos(GDisplay *g, bool_t on) {
+ (void) g;
+ palWritePad(GPIOA, GPIOA_VPOS_CTRL, on);
+}
+
+/* Set the state of the LE (source driver Latch Enable) pin. */
+static inline void setpin_le(GDisplay *g, bool_t on) {
+ (void) g;
+ palWritePad(GPIOB, GPIOB_EINK_LE, on);
+}
+
+/* Set the state of the OE (source driver Output Enable) pin. */
+static inline void setpin_oe(GDisplay *g, bool_t on) {
+ (void) g;
+ palWritePad(GPIOB, GPIOB_EINK_OE, on);
+}
+
+/* Set the state of the CL (source driver Clock) pin. */
+static inline void setpin_cl(GDisplay *g, bool_t on) {
+ (void) g;
+ palWritePad(GPIOB, GPIOB_EINK_CL, on);
+}
+
+/* Set the state of the SPH (source driver Start Pulse Horizontal) pin. */
+static inline void setpin_sph(GDisplay *g, bool_t on) {
+ (void) g;
+ palWritePad(GPIOB, GPIOB_EINK_SPH, on);
+}
+
+/* Set the state of the D0-D7 (source driver Data) pins. */
+static inline void setpins_data(GDisplay *g, uint8_t value) {
+ (void) g;
+ palWriteGroup(GPIOB, 0xFF, GPIOB_EINK_D0, value);
+}
+
+/* Set the state of the CKV (gate driver Clock Vertical) pin. */
+static inline void setpin_ckv(GDisplay *g, bool_t on) {
+ (void) g;
+ palWritePad(GPIOB, GPIOB_EINK_CKV, on);
+}
+
+/* Set the state of the GMODE (gate driver Gate Mode) pin. */
+static inline void setpin_gmode(GDisplay *g, bool_t on) {
+ (void) g;
+ palWritePad(GPIOC, GPIOC_EINK_GMODE, on);
+}
+
+/* Set the state of the SPV (gate driver Start Pulse Vertical) pin. */
+static inline void setpin_spv(GDisplay *g, bool_t on) {
+ (void) g;
+ palWritePad(GPIOB, GPIOB_EINK_SPV, on);
+}
+
+#endif
diff --git a/boards/addons/gdisp/board_HX8347D_stm32f4discovery.h b/boards/addons/gdisp/board_HX8347D_stm32f4discovery.h
new file mode 100644
index 00000000..df287477
--- /dev/null
+++ b/boards/addons/gdisp/board_HX8347D_stm32f4discovery.h
@@ -0,0 +1,160 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/HX8347D/board_HX8347D_stm32f4discovery.h
+ * @brief GDISP Graphic Driver subsystem board SPI interface for the HX8347D display.
+ */
+
+#ifndef _GDISP_LLD_BOARD_H
+#define _GDISP_LLD_BOARD_H
+
+// For a multiple display configuration we would put all this in a structure and then
+// set g->board to that structure.
+
+/* Pin assignments */
+#define SET_RST palSetPad(GPIOB, 8)
+#define CLR_RST palClearPad(GPIOB, 8)
+#define SET_DATA palSetPad(GPIOB, 9)
+#define CLR_DATA palClearPad(GPIOB, 9)
+#define SET_CS palSetPad(GPIOA, 4)
+#define CLR_CS palClearPad(GPIOA, 4)
+
+/* PWM configuration structure. We use timer 4 channel 2 (orange LED on board). */
+static const PWMConfig pwmcfg = {
+ 1000000, /* 1 MHz PWM clock frequency. */
+ 100, /* PWM period is 100 cycles. */
+ NULL,
+ {
+ {PWM_OUTPUT_ACTIVE_HIGH, NULL},
+ {PWM_OUTPUT_ACTIVE_HIGH, NULL},
+ {PWM_OUTPUT_ACTIVE_HIGH, NULL},
+ {PWM_OUTPUT_ACTIVE_HIGH, NULL}
+ },
+ 0
+};
+
+/*
+ * SPI1 configuration structure.
+ * Speed 42MHz, CPHA=0, CPOL=0, 8bits frames, MSb transmitted first.
+ * The slave select line is the pin 4 on the port GPIOA.
+ */
+static const SPIConfig spi1cfg_8bit = {
+ NULL,
+ /* HW dependent part.*/
+ GPIOA,
+ 4,
+ 0 //SPI_CR1_BR_0
+};
+
+/*
+ * SPI1 configuration structure.
+ * Speed 42MHz, CPHA=0, CPOL=0, 16bits frames, MSb transmitted first.
+ * The slave select line is the pin 4 on the port GPIOA.
+ */
+static const SPIConfig spi1cfg_16bit = {
+ NULL,
+ /* HW dependent part.*/
+ GPIOA,
+ 4,
+ SPI_CR1_DFF //SPI_CR1_BR_0
+};
+
+static inline void init_board(GDisplay *g) {
+
+ // As we are not using multiple displays we set g->board to NULL as we don't use it.
+ g->board = 0;
+
+ switch(g->controllerdisplay) {
+ case 0: // Set up for Display 0
+ /* Display backlight control */
+ /* TIM4 is an alternate function 2 (AF2) */
+ pwmStart(&PWMD4, &pwmcfg);
+ palSetPadMode(GPIOD, 13, PAL_MODE_ALTERNATE(2));
+ pwmEnableChannel(&PWMD4, 1, 100);
+
+ palSetPadMode(GPIOB, 8, PAL_MODE_OUTPUT_PUSHPULL|PAL_STM32_OSPEED_HIGHEST); /* RST */
+ palSetPadMode(GPIOB, 9, PAL_MODE_OUTPUT_PUSHPULL|PAL_STM32_OSPEED_HIGHEST); /* RS */
+ /*
+ * Initializes the SPI driver 1. The SPI1 signals are routed as follow:
+ * PB12 - NSS.
+ * PB13 - SCK.
+ * PB14 - MISO.
+ * PB15 - MOSI.
+ */
+ SET_CS; SET_DATA;
+ spiStart(&SPID1, &spi1cfg_8bit);
+ palSetPadMode(GPIOA, 4, PAL_MODE_OUTPUT_PUSHPULL|PAL_STM32_OSPEED_HIGHEST); /* NSS. */
+ palSetPadMode(GPIOA, 5, PAL_MODE_ALTERNATE(5)|PAL_STM32_OSPEED_HIGHEST); /* SCK. */
+ palSetPadMode(GPIOA, 6, PAL_MODE_ALTERNATE(5)); /* MISO. */
+ palSetPadMode(GPIOA, 7, PAL_MODE_ALTERNATE(5)|PAL_STM32_OSPEED_HIGHEST); /* MOSI. */
+ break;
+ }
+}
+
+static inline void post_init_board(GDisplay *g) {
+ (void) g;
+}
+
+static inline void setpin_reset(GDisplay *g, bool_t state) {
+ (void) g;
+ if (state) {
+ CLR_RST;
+ } else {
+ SET_RST;
+ }
+}
+
+static inline void set_backlight(GDisplay *g, uint8_t percent) {
+ (void) g;
+ pwmEnableChannel(&PWMD4, 1, percent);
+}
+
+static inline void acquire_bus(GDisplay *g) {
+ (void) g;
+ spiAcquireBus(&SPID1);
+ while(((SPI1->SR & SPI_SR_TXE) == 0) || ((SPI1->SR & SPI_SR_BSY) != 0)); // Safety
+ CLR_CS;
+}
+
+static inline void release_bus(GDisplay *g) {
+ (void) g;
+ SET_CS;
+ spiReleaseBus(&SPID1);
+}
+
+static inline void busmode16(GDisplay *g) {
+ (void) g;
+ spiStart(&SPID1, &spi1cfg_16bit);
+}
+
+static inline void busmode8(GDisplay *g) {
+ (void) g;
+ spiStart(&SPID1, &spi1cfg_8bit);
+}
+
+static inline void write_index(GDisplay *g, uint8_t index) {
+ (void) g;
+ CLR_DATA;
+ SPI1->DR = index;
+ while(((SPI1->SR & SPI_SR_TXE) == 0) || ((SPI1->SR & SPI_SR_BSY) != 0));
+ SET_DATA;
+}
+
+static inline void write_data(GDisplay *g, uint8_t data) {
+ (void) g;
+ SPI1->DR = data;
+ while(((SPI1->SR & SPI_SR_TXE) == 0) || ((SPI1->SR & SPI_SR_BSY) != 0));
+}
+
+static inline void write_ram16(GDisplay *g, uint16_t data) {
+ (void) g;
+ SPI1->DR = data;
+ while((SPI1->SR & SPI_SR_TXE) == 0);
+}
+
+#endif /* _GDISP_LLD_BOARD_H */
diff --git a/boards/addons/gdisp/board_ILI9320_olimex_pic32mx_lcd.h b/boards/addons/gdisp/board_ILI9320_olimex_pic32mx_lcd.h
new file mode 100644
index 00000000..5315127b
--- /dev/null
+++ b/boards/addons/gdisp/board_ILI9320_olimex_pic32mx_lcd.h
@@ -0,0 +1,126 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/ILI9320/board_ILI9320_olimex_pic32mx_lcd.h
+ * @brief GDISP Graphic Driver subsystem board interface for the ILI9325 display.
+ */
+
+#ifndef GDISP_LLD_BOARD_H
+#define GDISP_LLD_BOARD_H
+
+#ifndef noinline
+#define noinline __attribute__((noinline))
+#endif
+
+static void init_board(GDisplay *g) {
+
+ // As we are not using multiple displays we set g->board to NULL as we don't use it.
+ g->board = 0;
+
+ switch(g->controllerdisplay) {
+ case 0: // Set up for Display 0
+ // RST
+ palSetPadMode(IOPORTA, 7, PAL_MODE_OUTPUT);
+ palClearPad(IOPORTA, 7);
+
+ // RS
+ palSetPadMode(IOPORTA, 10, PAL_MODE_OUTPUT);
+ palSetPad(IOPORTA, 10);
+
+ // CS
+ palSetPadMode(IOPORTA, 9, PAL_MODE_OUTPUT);
+ palClearPad(IOPORTA, 9);
+
+ // Backlight
+ palSetPadMode(IOPORTD, 3, PAL_MODE_OUTPUT);
+ palSetPad(IOPORTD, 3);
+
+ // PMP setup
+ PMMODE = 0;
+ PMAEN = 0;
+ PMCON = 0;
+ PMMODEbits.MODE = 2;
+ PMMODEbits.WAITB = 0;
+ PMMODEbits.WAITM = 1;
+ PMMODEbits.WAITE = 0;
+ PMCONbits.CSF = 0;
+ PMCONbits.PTRDEN = 1;
+ PMCONbits.PTWREN = 1;
+ PMMODEbits.MODE16 = 1;
+ PMCONbits.PMPEN = 1;
+
+ palClearPad(IOPORTA, 9);
+ break;
+ }
+}
+
+#define PmpWaitBusy() do {} while (PMMODEbits.BUSY)
+
+static inline void post_init_board(GDisplay *g) {
+ (void) g;
+}
+
+static noinline void setpin_reset(GDisplay *g, bool_t state) {
+ (void) g;
+ if (state)
+ palClearPad(IOPORTA, 7);
+ else
+ palSetPad(IOPORTA, 7);
+}
+
+static void set_backlight(GDisplay *g, uint8_t percent) {
+ (void) g;
+ if (percentage)
+ palClearPad(IOPORTD, 3);
+ else
+ palSetPad(IOPORTD, 3);
+}
+
+static inline void acquire_bus(GDisplay *g) {
+ (void) g;
+}
+
+static inline void release_bus(GDisplay *g) {
+ (void) g;
+}
+
+static noinline void write_index(GDisplay *g, uint16_t index) {
+ volatile uint16_t dummy;
+ (void) g;
+
+ PmpWaitBusy();
+ palClearPad(IOPORTA, 10);
+ PMDIN = index;
+ PmpWaitBusy();
+ palSetPad(IOPORTA, 10);
+
+ dummy = PMDIN;
+ (void)dummy;
+}
+
+static noinline void write_data(GDisplay *g, uint16_t data) {
+ (void) g;
+ PMDIN = data;
+ PmpWaitBusy();
+}
+
+static inline void setreadmode(GDisplay *g) {
+ (void) g;
+}
+
+static inline void setwritemode(GDisplay *g) {
+ (void) g;
+}
+
+static noinline uint16_t read_data(GDisplay *g) {
+ (void) g;
+ PmpWaitBusy();
+ return PMDIN;
+}
+
+#endif /* GDISP_LLD_BOARD_H */
diff --git a/boards/addons/gdisp/board_ILI9320_olimex_stm32_lcd.h b/boards/addons/gdisp/board_ILI9320_olimex_stm32_lcd.h
new file mode 100644
index 00000000..bca5caf8
--- /dev/null
+++ b/boards/addons/gdisp/board_ILI9320_olimex_stm32_lcd.h
@@ -0,0 +1,100 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/ILI9320/board_ILI9320_olimex_stm32_lcd.h
+ * @brief GDISP Graphic Driver subsystem board interface for the ILI9320 display.
+ */
+
+#ifndef GDISP_LLD_BOARD_H
+#define GDISP_LLD_BOARD_H
+
+// For a multiple display configuration we would put all this in a structure and then
+// set g->board to that structure.
+#define GDISP_REG (*((volatile uint16_t *) 0x60000000)) /* RS = 0 */
+#define GDISP_RAM (*((volatile uint16_t *) 0x60100000)) /* RS = 1 */
+
+static inline void init_board(GDisplay *g) {
+
+ // As we are not using multiple displays we set g->board to NULL as we don't use it.
+ g->board = 0;
+
+ switch(g->controllerdisplay) {
+ case 0: // Set up for Display 0
+ /* FSMC setup for F1 */
+ rccEnableAHB(RCC_AHBENR_FSMCEN, 0);
+
+ /* set pin modes */
+ IOBus busD = {GPIOD, PAL_WHOLE_PORT, 0};
+ IOBus busE = {GPIOE, PAL_WHOLE_PORT, 0};
+ palSetBusMode(&busD, PAL_MODE_STM32_ALTERNATE_PUSHPULL);
+ palSetBusMode(&busE, PAL_MODE_STM32_ALTERNATE_PUSHPULL);
+ palSetPadMode(GPIOE, GPIOE_TFT_RST, PAL_MODE_OUTPUT_PUSHPULL);
+ palSetPadMode(GPIOD, GPIOD_TFT_LIGHT, PAL_MODE_OUTPUT_PUSHPULL);
+
+ /* FSMC timing */
+ FSMC_Bank1->BTCR[0+1] = (6) | (10 << 8) | (10 << 16);
+
+ /* Bank1 NOR/SRAM control register configuration
+ * This is actually not needed as already set by default after reset */
+ FSMC_Bank1->BTCR[0] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN;
+ break;
+ }
+}
+
+static inline void post_init_board(GDisplay *g) {
+ (void) g;
+}
+
+static inline void setpin_reset(GDisplay *g, bool_t state) {
+ (void) g;
+ if(state)
+ palClearPad(GPIOE, GPIOE_TFT_RST);
+ else
+ palSetPad(GPIOE, GPIOE_TFT_RST);
+}
+
+static inline void set_backlight(GDisplay *g, uint8_t percent) {
+ (void) g;
+ if(percent)
+ palClearPad(GPIOD, GPIOD_TFT_LIGHT);
+ else
+ palSetPad(GPIOD, GPIOD_TFT_LIGHT);
+}
+
+static inline void acquire_bus(GDisplay *g) {
+ (void) g;
+}
+
+static inline void release_bus(GDisplay *g) {
+ (void) g;
+}
+
+static inline void write_index(GDisplay *g, uint16_t index) {
+ (void) g;
+ GDISP_REG = index;
+}
+
+static inline void write_data(GDisplay *g, uint16_t data) {
+ (void) g;
+ GDISP_RAM = data;
+}
+
+static inline void setreadmode(GDisplay *g) {
+ (void) g;
+}
+
+static inline void setwritemode(GDisplay *g) {
+ (void) g;
+}
+
+static inline uint16_t read_data(GDisplay *g) {
+ (void) g;
+ return GDISP_RAM;
+}
+
+#endif /* GDISP_LLD_BOARD_H */
diff --git a/boards/addons/gdisp/board_ILI9325_hy_stm32_100p.h b/boards/addons/gdisp/board_ILI9325_hy_stm32_100p.h
new file mode 100644
index 00000000..60508c1a
--- /dev/null
+++ b/boards/addons/gdisp/board_ILI9325_hy_stm32_100p.h
@@ -0,0 +1,112 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/*
+ driver quickly hacked together from a chinese sourcecode that came
+ with the board and existing ili9320 code by Chris van Dongen (sjaak)
+ (sjaak2002 at msn.com)
+
+ Also added rotation for 180 and 270 degrees and minor tweaks to
+ setcursor
+
+ Added code comes without warranty and free bugs. Feel free to use
+ or misuse the added code :D
+*/
+
+
+/**
+ * @file drivers/gdisp/ILI9325/board_ILI9325_hy_stm32_100p.h
+ * @brief GDISP Graphic Driver subsystem board interface for the ILI9325 display.
+ */
+
+#ifndef GDISP_LLD_BOARD_H
+#define GDISP_LLD_BOARD_H
+
+// For a multiple display configuration we would put all this in a structure and then
+// set g->board to that structure.
+#define GDISP_REG (*((volatile uint16_t *) 0x60000000)) /* RS = 0 */
+#define GDISP_RAM (*((volatile uint16_t *) 0x60020000)) /* RS = 1 */
+
+static inline void init_board(GDisplay *g) {
+
+ // As we are not using multiple displays we set g->board to NULL as we don't use it.
+ g->board = 0;
+
+ switch(g->controllerdisplay) {
+ case 0: // Set up for Display 0
+ /* FSMC setup for F1 */
+ rccEnableAHB(RCC_AHBENR_FSMCEN, 0);
+
+ /* set pin modes */
+ /* IOBus busD = {GPIOD, PAL_WHOLE_PORT, 0};
+ IOBus busE = {GPIOE, PAL_WHOLE_PORT, 0};
+ palSetBusMode(&busD, PAL_MODE_STM32_ALTERNATE_PUSHPULL);
+ palSetBusMode(&busE, PAL_MODE_STM32_ALTERNATE_PUSHPULL);
+ palSetPadMode(GPIOE, GPIOE_TFT_RST, PAL_MODE_OUTPUT_PUSHPULL);
+ palSetPadMode(GPIOD, GPIOD_TFT_LIGHT, PAL_MODE_OUTPUT_PUSHPULL); */
+
+ const unsigned char FSMC_Bank = 0;
+
+ /* FSMC timing */
+ FSMC_Bank1->BTCR[FSMC_Bank+1] = (6) | (10 << 8) | (10 << 16);
+
+ /* Bank1 NOR/SRAM control register configuration
+ * This is actually not needed as already set by default after reset */
+ FSMC_Bank1->BTCR[FSMC_Bank] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN;
+ break;
+ }
+}
+
+static inline void post_init_board(GDisplay *g) {
+ (void) g;
+}
+
+static inline void setpin_reset(GDisplay *g, bool_t state) {
+ (void) g;
+ if(state)
+ palClearPad(GPIOE, GPIOE_TFT_RST);
+ else
+ palSetPad(GPIOE, GPIOE_TFT_RST);
+}
+
+static inline void set_backlight(GDisplay *g, uint8_t percent) {
+ (void) g;
+ (void)percent;
+}
+
+static inline void acquire_bus(GDisplay *g) {
+ (void) g;
+}
+
+static inline void release_bus(GDisplay *g) {
+ (void) g;
+}
+
+static inline void write_index(GDisplay *g, uint16_t index) {
+ (void) g;
+ GDISP_REG = index;
+}
+
+static inline void write_data(GDisplay *g, uint16_t data) {
+ (void) g;
+ GDISP_RAM = data;
+}
+
+static inline void setreadmode(GDisplay *g) {
+ (void) g;
+}
+
+static inline void setwritemode(GDisplay *g) {
+ (void) g;
+}
+
+static inline uint16_t read_data(GDisplay *g) {
+ (void) g;
+ return GDISP_RAM;
+}
+
+#endif /* GDISP_LLD_BOARD_H */
diff --git a/boards/addons/gdisp/board_ILI9481_firebullstm32f103.h b/boards/addons/gdisp/board_ILI9481_firebullstm32f103.h
new file mode 100644
index 00000000..17bc554d
--- /dev/null
+++ b/boards/addons/gdisp/board_ILI9481_firebullstm32f103.h
@@ -0,0 +1,107 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/ILI9481/board_ILI9481_firebullstm32f103.h
+ * @brief GDISP Graphics Driver subsystem low level driver source for
+ * the ILI9481 and compatible HVGA display
+ */
+
+#ifndef _GDISP_LLD_BOARD_H
+#define _GDISP_LLD_BOARD_H
+
+// For a multiple display configuration we would put all this in a structure and then
+// set g->board to that structure.
+#define SET_CS palSetPad(GPIOD, 12);
+#define CLR_CS palClearPad(GPIOD, 12);
+#define SET_RS palSetPad(GPIOD, 13);
+#define CLR_RS palClearPad(GPIOD, 13);
+#define SET_WR palSetPad(GPIOD, 14);
+#define CLR_WR palClearPad(GPIOD, 14);
+#define SET_RD palSetPad(GPIOD, 15);
+#define CLR_RD palClearPad(GPIOD, 15);
+
+static inline void init_board(GDisplay *g) {
+
+ // As we are not using multiple displays we set g->board to NULL as we don't use it.
+ g->board = 0;
+
+ switch(g->controllerdisplay) {
+ case 0: // Set up for Display 0
+ palSetGroupMode(GPIOE, PAL_WHOLE_PORT, 0, PAL_MODE_OUTPUT_PUSHPULL);
+ palSetPadMode(GPIOD, 12, PAL_MODE_OUTPUT_PUSHPULL);
+ palSetPadMode(GPIOD, 13, PAL_MODE_OUTPUT_PUSHPULL);
+ palSetPadMode(GPIOD, 14, PAL_MODE_OUTPUT_PUSHPULL);
+ palSetPadMode(GPIOD, 15, PAL_MODE_OUTPUT_PUSHPULL);
+
+ // Configure the pins to a well know state
+ SET_RS;
+ SET_RD;
+ SET_WR;
+ CLR_CS;
+ break;
+ }
+}
+
+static inline void post_init_board(GDisplay *g) {
+ (void) g;
+}
+
+static inline void setpin_reset(GDisplay *g, bool_t state) {
+ (void) g;
+ (void) state;
+}
+
+static inline void set_backlight(GDisplay *g, uint8_t percent) {
+ (void) g;
+ (void) percent;
+}
+
+static inline void acquire_bus(GDisplay *g) {
+ (void) g;
+}
+
+static inline void release_bus(GDisplay *g) {
+ (void) g;
+}
+
+static inline void write_index(GDisplay *g, uint16_t index) {
+ (void) g;
+ palWritePort(GPIOE, index);
+ CLR_RS; CLR_WR; SET_WR; SET_RS;
+}
+
+static inline void write_data(GDisplay *g, uint16_t data) {
+ (void) g;
+ palWritePort(GPIOE, data);
+ CLR_WR; SET_WR;
+}
+
+static inline void setreadmode(GDisplay *g) {
+ (void) g;
+ // change pin mode to digital input
+ palSetGroupMode(GPIOE, PAL_WHOLE_PORT, 0, PAL_MODE_INPUT);
+}
+
+static inline void setwritemode(GDisplay *g) {
+ (void) g;
+ // change pin mode back to digital output
+ palSetGroupMode(GPIOE, PAL_WHOLE_PORT, 0, PAL_MODE_OUTPUT_PUSHPULL);
+}
+
+static inline uint16_t read_data(GDisplay *g) {
+ uint16_t value;
+ (void) g;
+
+ CLR_RD;
+ value = palReadPort(GPIOE);
+ SET_RD;
+
+ return value;
+}
+
+#endif /* _GDISP_LLD_BOARD_H */
diff --git a/boards/addons/gdisp/board_RA8875_marlin.h b/boards/addons/gdisp/board_RA8875_marlin.h
new file mode 100644
index 00000000..b1d55a92
--- /dev/null
+++ b/boards/addons/gdisp/board_RA8875_marlin.h
@@ -0,0 +1,113 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/RA8875/board_RA8875_marlin.h
+ * @brief GDISP Graphic Driver subsystem board interface for the RA8875 display.
+ */
+
+#ifndef _BOARD_RA8875_H
+#define _BOARD_RA8875_H
+
+// For a multiple display configuration we would put all this in a structure and then
+// set g->board to that structure.
+#define GDISP_RAM (*((volatile uint16_t *) 0x68000000)) /* RS = 0 */
+#define GDISP_REG (*((volatile uint16_t *) 0x68020000)) /* RS = 1 */
+#define FSMC_BANK 4
+
+
+static inline void init_board(GDisplay *g) {
+ // As we are not using multiple displays we set g->board to NULL as we don't use it.
+ g->board = 0;
+
+ switch(g->controllerdisplay) {
+ // setup for display 0
+ case 0: {
+
+ // enable the FSMC peripheral
+ rccEnableAHB3(RCC_AHB3ENR_FSMCEN, 0);
+
+ // setup the pin modes for FSMC
+ IOBus busD = {GPIOD, (1 << 0) | (1 << 1) | (1 << 4) | (1 << 5) | (1 << 8) |
+ (1 << 9) | (1 << 10) | (1 << 11) | (1 << 14) | (1 << 15), 0};
+
+ IOBus busE = {GPIOE, (1 << 7) | (1 << 8) | (1 << 9) | (1 << 10) | (1 << 11) | (1 << 12) |
+ (1 << 13) | (1 << 14) | (1 << 15), 0};
+
+ IOBus busG = {GPIOG, (1 << 10), 0};
+
+ palSetBusMode(&busD, PAL_MODE_ALTERNATE(12));
+ palSetBusMode(&busE, PAL_MODE_ALTERNATE(12));
+ palSetBusMode(&busG, PAL_MODE_ALTERNATE(12));
+
+ // FSMC timing
+ FSMC_Bank1->BTCR[FSMC_BANK+1] = (FSMC_BTR1_ADDSET_1 | FSMC_BTR1_ADDSET_3) \
+ | (FSMC_BTR1_DATAST_1 | FSMC_BTR1_DATAST_3) \
+ | (FSMC_BTR1_BUSTURN_1 | FSMC_BTR1_BUSTURN_3) ;
+
+ // Bank1 NOR/SRAM control register configuration
+ // This is actually not needed as already set by default after reset
+ FSMC_Bank1->BTCR[FSMC_BANK] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN;
+
+ break;
+ }
+
+ // marlin does not have any secondary display so far
+ default:
+ break;
+ }
+}
+
+static inline void post_init_board(GDisplay *g) {
+ (void) g;
+
+ // FSMC delay reduced as the controller now runs at full speed
+ FSMC_Bank1->BTCR[2+1] = FSMC_BTR1_ADDSET_0 | FSMC_BTR1_DATAST_2 | FSMC_BTR1_BUSTURN_0 ;
+ FSMC_Bank1->BTCR[2] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN;
+}
+
+static inline void setpin_reset(GDisplay *g, bool_t state) {
+ (void) g;
+ (void) state;
+}
+
+static inline void acquire_bus(GDisplay *g) {
+ (void) g;
+}
+
+static inline void release_bus(GDisplay *g) {
+ (void) g;
+}
+
+static inline void write_index(GDisplay *g, uint16_t index) {
+ (void) g;
+
+ GDISP_REG = index;
+}
+
+static inline void write_data(GDisplay *g, uint16_t data) {
+ (void) g;
+
+ GDISP_RAM = data;
+}
+
+static inline void setreadmode(GDisplay *g) {
+ (void) g;
+}
+
+static inline void setwritemode(GDisplay *g) {
+ (void) g;
+}
+
+static inline uint16_t read_data(GDisplay *g) {
+ (void) g;
+
+ return GDISP_RAM;
+}
+
+#endif /* _BOARD_RA8875_H */
+
diff --git a/boards/addons/gdisp/board_S6D1121_olimex_e407.h b/boards/addons/gdisp/board_S6D1121_olimex_e407.h
new file mode 100644
index 00000000..e0bb8e26
--- /dev/null
+++ b/boards/addons/gdisp/board_S6D1121_olimex_e407.h
@@ -0,0 +1,91 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/S6D1121/board_S6D1121_olimex_e407.h
+ * @brief GDISP Graphic Driver subsystem board interface for the S6D1121 display
+ */
+
+#ifndef _GDISP_LLD_BOARD_H
+#define _GDISP_LLD_BOARD_H
+
+// For a multiple display configuration we would put all this in a structure and then
+// set g->board to that structure.
+#define GDISP_REG (*((volatile uint16_t *) 0x60000000)) /* RS = 0 */
+#define GDISP_RAM (*((volatile uint16_t *) 0x60020000)) /* RS = 1 */
+
+static inline void init_board(GDisplay *g) {
+
+ // As we are not using multiple displays we set g->board to NULL as we don't use it.
+ g->board = 0;
+
+ switch(g->controllerdisplay) {
+ case 0: // Set up for Display 0
+ /* STM32F4 FSMC init */
+ rccEnableAHB3(RCC_AHB3ENR_FSMCEN, 0);
+
+ /* set pins to FSMC mode */
+ IOBus busD = {GPIOD, (1 << 0) | (1 << 1) | (1 << 4) | (1 << 5) | (1 << 7) | (1 << 8) |
+ (1 << 9) | (1 << 10) | (1 << 11) | (1 << 14) | (1 << 15), 0};
+
+ IOBus busE = {GPIOE, (1 << 7) | (1 << 8) | (1 << 9) | (1 << 10) | (1 << 11) | (1 << 12) |
+ (1 << 13) | (1 << 14) | (1 << 15), 0};
+
+ palSetBusMode(&busD, PAL_MODE_ALTERNATE(12));
+ palSetBusMode(&busE, PAL_MODE_ALTERNATE(12));
+
+ /* FSMC timing */
+ FSMC_Bank1->BTCR[0+1] = (6) | (10 << 8) | (10 << 16);
+
+ /* Bank1 NOR/SRAM control register configuration */
+ FSMC_Bank1->BTCR[0] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN;
+ break;
+ }
+}
+
+static inline void setpin_reset(GDisplay *g, bool_t state) {
+ (void) g;
+ (void) state;
+}
+
+static inline void set_backlight(GDisplay *g, uint8_t percent) {
+ (void) g;
+ (void) percent;
+}
+
+static inline void acquire_bus(GDisplay *g) {
+ (void) g;
+}
+
+static inline void release_bus(GDisplay *g) {
+ (void) g;
+}
+
+static inline void write_index(GDisplay *g, uint16_t index) {
+ (void) g;
+ GDISP_REG = index;
+}
+
+static inline void write_data(GDisplay *g, uint16_t data) {
+ (void) g;
+ GDISP_RAM = data;
+}
+
+static inline void setreadmode(GDisplay *g) {
+ (void) g;
+}
+
+static inline void setwritemode(GDisplay *g) {
+ (void) g;
+}
+
+static inline uint16_t read_data(GDisplay *g) {
+ (void) g;
+ return GDISP_RAM;
+}
+
+#endif /* _GDISP_LLD_BOARD_H */
diff --git a/boards/addons/gdisp/board_SSD1289_firebullstm32f103.h b/boards/addons/gdisp/board_SSD1289_firebullstm32f103.h
new file mode 100644
index 00000000..99d37299
--- /dev/null
+++ b/boards/addons/gdisp/board_SSD1289_firebullstm32f103.h
@@ -0,0 +1,108 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/SSD1289/board_SSD1289_firebullstm32f103.h
+ * @brief GDISP Graphic Driver subsystem board interface for the SSD1289 display.
+ */
+
+#ifndef _GDISP_LLD_BOARD_H
+#define _GDISP_LLD_BOARD_H
+
+// For a multiple display configuration we would put all this in a structure and then
+// set g->board to that structure.
+#define SET_CS palSetPad(GPIOD, 12);
+#define CLR_CS palClearPad(GPIOD, 12);
+#define SET_RS palSetPad(GPIOD, 13);
+#define CLR_RS palClearPad(GPIOD, 13);
+#define SET_WR palSetPad(GPIOD, 14);
+#define CLR_WR palClearPad(GPIOD, 14);
+#define SET_RD palSetPad(GPIOD, 15);
+#define CLR_RD palClearPad(GPIOD, 15);
+
+static inline void init_board(GDisplay *g) {
+
+ // As we are not using multiple displays we set g->board to NULL as we don't use it.
+ g->board = 0;
+
+ switch(g->controllerdisplay) {
+ case 0: // Set up for Display 0
+ palSetGroupMode(GPIOE, PAL_WHOLE_PORT, 0, PAL_MODE_OUTPUT_PUSHPULL);
+ palSetPadMode(GPIOD, 12, PAL_MODE_OUTPUT_PUSHPULL);
+ palSetPadMode(GPIOD, 13, PAL_MODE_OUTPUT_PUSHPULL);
+ palSetPadMode(GPIOD, 14, PAL_MODE_OUTPUT_PUSHPULL);
+ palSetPadMode(GPIOD, 15, PAL_MODE_OUTPUT_PUSHPULL);
+
+ // Configure the pins to a well know state
+ SET_RS;
+ SET_RD;
+ SET_WR;
+ CLR_CS;
+ break;
+ }
+}
+
+static inline void post_init_board(GDisplay *g) {
+ (void) g;
+}
+
+static inline void setpin_reset(GDisplay *g, bool_t state) {
+ (void) g;
+ (void) state;
+ /* Nothing to do here - reset pin tied to Vcc */
+}
+
+static inline void set_backlight(GDisplay *g, uint8_t percent) {
+ (void) g;
+ (void) percent;
+ /* Nothing to do here - Backlight always on */
+}
+
+static inline void acquire_bus(GDisplay *g) {
+ (void) g;
+}
+
+static inline void release_bus(GDisplay *g) {
+ (void) g;
+}
+
+static inline void write_index(GDisplay *g, uint16_t index) {
+ (void) g;
+ palWritePort(GPIOE, index);
+ CLR_RS; CLR_WR; SET_WR; SET_RS;
+}
+
+static inline void write_data(GDisplay *g, uint16_t data) {
+ (void) g;
+ palWritePort(GPIOE, data);
+ CLR_WR; SET_WR;
+}
+
+static inline void setreadmode(GDisplay *g) {
+ (void) g;
+ // change pin mode to digital input
+ palSetGroupMode(GPIOE, PAL_WHOLE_PORT, 0, PAL_MODE_INPUT);
+ CLR_RD;
+}
+
+static inline void setwritemode(GDisplay *g) {
+ (void) g;
+ // change pin mode back to digital output
+ SET_RD;
+ palSetGroupMode(GPIOE, PAL_WHOLE_PORT, 0, PAL_MODE_OUTPUT_PUSHPULL);
+}
+
+static inline uint16_t read_data(GDisplay *g) {
+ return palReadPort(GPIOE);
+}
+
+#if defined(GDISP_USE_DMA)
+ #error "GDISP - SSD1289: The GPIO interface does not support DMA"
+#endif
+
+#endif /* _GDISP_LLD_BOARD_H */
+
diff --git a/boards/addons/gdisp/board_SSD1289_stm32f4discovery.h b/boards/addons/gdisp/board_SSD1289_stm32f4discovery.h
new file mode 100644
index 00000000..866311dc
--- /dev/null
+++ b/boards/addons/gdisp/board_SSD1289_stm32f4discovery.h
@@ -0,0 +1,172 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/SSD1289/board_SSD1289_stm32f4discovery.h
+ * @brief GDISP Graphic Driver subsystem board interface for the SSD1289 display.
+ */
+
+#ifndef _GDISP_LLD_BOARD_H
+#define _GDISP_LLD_BOARD_H
+
+// For a multiple display configuration we would put all this in a structure and then
+// set g->board to that structure.
+#define GDISP_REG ((volatile uint16_t *) 0x60000000)[0] /* RS = 0 */
+#define GDISP_RAM ((volatile uint16_t *) 0x60020000)[0] /* RS = 1 */
+#define GDISP_DMA_STREAM STM32_DMA2_STREAM6
+#define FSMC_BANK 0
+
+/* PWM configuration structure. We use timer 3 channel 3 */
+static const PWMConfig pwmcfg = {
+ 100000, /* 100 kHz PWM clock frequency. */
+ 100, /* PWM period is 100 cycles. */
+ NULL,
+ {
+ {PWM_OUTPUT_DISABLED, NULL},
+ {PWM_OUTPUT_DISABLED, NULL},
+ {PWM_OUTPUT_ACTIVE_HIGH, NULL},
+ {PWM_OUTPUT_DISABLED, NULL}
+ },
+ 0
+};
+
+static inline void init_board(GDisplay *g) {
+
+ // As we are not using multiple displays we set g->board to NULL as we don't use it.
+ g->board = 0;
+
+ switch(g->controllerdisplay) {
+ case 0: // Set up for Display 0
+ /**
+ * Performs the following functions:
+ * 1. initialise the io port used by the display
+ * 2. initialise the reset pin (initial state not-in-reset)
+ * 3. initialise the chip select pin (initial state not-active)
+ * 4. initialise the backlight pin (initial state back-light off)
+ */
+
+ #if defined(STM32F1XX) || defined(STM32F3XX)
+ /* FSMC setup for F1/F3 */
+ rccEnableAHB(RCC_AHBENR_FSMCEN, 0);
+
+ #if defined(GDISP_USE_DMA)
+ #error "GDISP: SSD1289 - DMA not implemented for F1/F3 Devices"
+ #endif
+ #elif defined(STM32F4XX) || defined(STM32F2XX)
+ /* STM32F2-F4 FSMC init */
+ rccEnableAHB3(RCC_AHB3ENR_FSMCEN, 0);
+
+ #if defined(GDISP_USE_DMA)
+ if (dmaStreamAllocate(GDISP_DMA_STREAM, 0, NULL, NULL)) gfxExit();
+ dmaStreamSetMemory0(GDISP_DMA_STREAM, &GDISP_RAM);
+ dmaStreamSetMode(GDISP_DMA_STREAM, STM32_DMA_CR_PL(0) | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_DIR_M2M);
+ #else
+ #warning "GDISP: SSD1289 - DMA is supported for F2/F4 Devices. Define GDISP_USE_DMA in your gfxconf.h to turn this on for better performance."
+ #endif
+ #else
+ #error "GDISP: SSD1289 - FSMC not implemented for this device"
+ #endif
+
+ /* set pins to FSMC mode */
+ IOBus busD = {GPIOD, (1 << 0) | (1 << 1) | (1 << 4) | (1 << 5) | (1 << 7) | (1 << 8) |
+ (1 << 9) | (1 << 10) | (1 << 11) | (1 << 14) | (1 << 15), 0};
+
+ IOBus busE = {GPIOE, (1 << 7) | (1 << 8) | (1 << 9) | (1 << 10) | (1 << 11) | (1 << 12) |
+ (1 << 13) | (1 << 14) | (1 << 15), 0};
+
+ palSetBusMode(&busD, PAL_MODE_ALTERNATE(12));
+ palSetBusMode(&busE, PAL_MODE_ALTERNATE(12));
+
+ /* FSMC timing */
+ FSMC_Bank1->BTCR[FSMC_BANK+1] = FSMC_BTR1_ADDSET_0 | FSMC_BTR1_DATAST_2 | FSMC_BTR1_BUSTURN_0 ;
+
+ /* Bank1 NOR/SRAM control register configuration
+ * This is actually not needed as already set by default after reset */
+ FSMC_Bank1->BTCR[FSMC_BANK] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN;
+
+ /* Display backlight control */
+ /* TIM3 is an alternate function 2 (AF2) */
+ pwmStart(&PWMD3, &pwmcfg);
+ palSetPadMode(GPIOB, 0, PAL_MODE_ALTERNATE(2));
+ pwmEnableChannel(&PWMD3, 2, 100);
+ break;
+ }
+}
+
+static inline void post_init_board(GDisplay *g) {
+ (void) g;
+}
+
+static inline void setpin_reset(GDisplay *g, bool_t state) {
+ (void) g;
+ (void) state;
+}
+
+static inline void set_backlight(GDisplay *g, uint8_t percent) {
+ (void) g;
+ pwmEnableChannel(&PWMD3, 2, percent);
+}
+
+static inline void acquire_bus(GDisplay *g) {
+ (void) g;
+}
+
+static inline void release_bus(GDisplay *g) {
+ (void) g;
+}
+
+static inline void write_index(GDisplay *g, uint16_t index) {
+ (void) g;
+ GDISP_REG = index;
+}
+
+static inline void write_data(GDisplay *g, uint16_t data) {
+ (void) g;
+ GDISP_RAM = data;
+}
+
+static inline void setreadmode(GDisplay *g) {
+ (void) g;
+ FSMC_Bank1->BTCR[FSMC_BANK+1] = FSMC_BTR1_ADDSET_3 | FSMC_BTR1_DATAST_3 | FSMC_BTR1_BUSTURN_0; /* FSMC timing */
+}
+
+static inline void setwritemode(GDisplay *g) {
+ (void) g;
+ FSMC_Bank1->BTCR[FSMC_BANK+1] = FSMC_BTR1_ADDSET_0 | FSMC_BTR1_DATAST_2 | FSMC_BTR1_BUSTURN_0; /* FSMC timing */
+}
+
+static inline uint16_t read_data(GDisplay *g) {
+ (void) g;
+ return GDISP_RAM;
+}
+
+#if defined(GDISP_USE_DMA) || defined(__DOXYGEN__)
+ static inline void dma_with_noinc(GDisplay *g, color_t *buffer, int area) {
+ (void) g;
+ dmaStreamSetPeripheral(GDISP_DMA_STREAM, buffer);
+ dmaStreamSetMode(GDISP_DMA_STREAM, STM32_DMA_CR_PL(0) | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_DIR_M2M);
+ for (; area > 0; area -= 65535) {
+ dmaStreamSetTransactionSize(GDISP_DMA_STREAM, area > 65535 ? 65535 : area);
+ dmaStreamEnable(GDISP_DMA_STREAM);
+ dmaWaitCompletion(GDISP_DMA_STREAM);
+ }
+ }
+
+ static inline void dma_with_inc(GDisplay *g, color_t *buffer, int area) {
+ (void) g;
+ dmaStreamSetPeripheral(GDISP_DMA_STREAM, buffer);
+ dmaStreamSetMode(GDISP_DMA_STREAM, STM32_DMA_CR_PL(0) | STM32_DMA_CR_PINC | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_DIR_M2M);
+ for (; area > 0; area -= 65535) {
+ dmaStreamSetTransactionSize(GDISP_DMA_STREAM, area > 65535 ? 65535 : area);
+ dmaStreamEnable(GDISP_DMA_STREAM);
+ dmaWaitCompletion(GDISP_DMA_STREAM);
+ }
+ }
+#endif
+
+#endif /* _GDISP_LLD_BOARD_H */
+
diff --git a/boards/addons/gdisp/board_SSD1306_i2c.h b/boards/addons/gdisp/board_SSD1306_i2c.h
new file mode 100644
index 00000000..449d47ba
--- /dev/null
+++ b/boards/addons/gdisp/board_SSD1306_i2c.h
@@ -0,0 +1,129 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/SSD1306/board_SSD1306_i2c.h
+ * @brief GDISP Graphic Driver subsystem board interface for the SSD1306 display.
+ */
+
+#ifndef _GDISP_LLD_BOARD_H
+#define _GDISP_LLD_BOARD_H
+
+// The command byte to put on the front of each page line
+#define SSD1306_PAGE_PREFIX 0x40 // Co = 0, D/C = 1
+
+// For a multiple display configuration we would put all this in a structure and then
+// set g->board to that structure.
+#define SSD1306_RESET_PORT GPIOB
+#define SSD1306_RESET_PIN 5
+
+/**
+ * The default slave address is 0x3D, (talking about
+ * only the real address part here) and the slave
+ * address can be changed to 0x3C by soldering the
+ * SA0 pads on the bottom side of the module.
+ *
+ * b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0
+ * --------------------------------------
+ * 0 | 1 | 1 | 1 | 1 | 0 |SA0 | R/W
+ */
+#define SSD1306_I2C_ADDRESS 0x3D
+#define SSD1306_SDA_PORT GPIOB
+#define SSD1306_SDA_PIN 7
+#define SSD1306_SCL_PORT GPIOB
+#define SSD1306_SCL_PIN 6
+#define SET_RST palSetPad(SSD1306_RESET_PORT, SSD1306_RESET_PIN);
+#define CLR_RST palClearPad(SSD1306_RESET_PORT, SSD1306_RESET_PIN);
+
+// I2C configuration structure.
+static I2CConfig i2cconfig;
+
+#if GFX_USE_OS_CHIBIOS
+ static int32_t thdPriority = 0;
+#endif
+
+static inline void init_board(GDisplay *g) {
+
+ // As we are not using multiple displays we set g->board to NULL as we don't use it.
+ g->board = 0;
+
+ switch(g->controllerdisplay) {
+ case 0: // Set up for Display 0
+ // RESET pin.
+ palSetPadMode(SSD1306_RESET_PORT, SSD1306_RESET_PIN, PAL_MODE_OUTPUT_PUSHPULL);
+
+
+ /*
+ * Initializes the I2C driver 1. The I2C1 signals are routed as follows:
+ * PB6 - SCL.
+ * PB7 - SDA.
+ * Timing value comes from ST I2C config tool (xls):
+ * 0x00901D2B; // 100kHz Standard Mode
+ * 0x00300444; // 100kHz Fast Mode
+ * 0x0030020A; // 400kHz Fast Mode
+ * 0x00100002; // 800kHz Fast Mode +
+ */
+ palSetPadMode(SSD1306_SCL_PORT, SSD1306_SCL_PIN, PAL_MODE_ALTERNATE(1));
+ palSetPadMode(SSD1306_SDA_PORT, SSD1306_SDA_PIN, PAL_MODE_ALTERNATE(1));
+ i2cconfig.timingr = 0x00100002; // 800kHz Fast Mode+
+ i2cInit();
+ break;
+ }
+}
+
+static inline void post_init_board(GDisplay *g) {
+ (void) g;
+}
+
+static inline void setpin_reset(GDisplay *g, bool_t state) {
+ (void) g;
+ if(state)
+ CLR_RST
+ else
+ SET_RST
+}
+
+static inline void acquire_bus(GDisplay *g) {
+ (void) g;
+ #if GFX_USE_OS_CHIBIOS
+ thdPriority = (int32_t)chThdGetPriority();
+ chThdSetPriority(HIGHPRIO);
+ #endif
+ i2cAcquireBus(&I2CD1);
+}
+
+static inline void release_bus(GDisplay *g) {
+ (void) g;
+ #if GFX_USE_OS_CHIBIOS
+ chThdSetPriority(thdPriority);
+ #endif
+ i2cReleaseBus(&I2CD1);
+}
+
+static inline void write_cmd(GDisplay *g, uint8_t cmd) {
+ uint8_t command[2];
+ (void) g;
+
+ command[0] = 0x00; // Co = 0, D/C = 0
+ command[1] = cmd;
+
+ i2cStart(&I2CD1, &i2cconfig);
+ i2cMasterTransmitTimeout(&I2CD1, SSD1306_I2C_ADDRESS, command, 2, NULL, 0, MS2ST(10));
+ i2cStop(&I2CD1);
+}
+
+static inline void write_data(GDisplay *g, uint8_t* data, uint16_t length) {
+ (void) g;
+
+ i2cStart(&I2CD1, &i2cconfig);
+ i2cMasterTransmitTimeout(&I2CD1, SSD1306_I2C_ADDRESS, data, length, NULL, 0, MS2ST(10));
+ i2cStop(&I2CD1);
+}
+
+#endif /* _GDISP_LLD_BOARD_H */
+
+
diff --git a/boards/addons/gdisp/board_SSD1306_spi.h b/boards/addons/gdisp/board_SSD1306_spi.h
new file mode 100644
index 00000000..21bf095f
--- /dev/null
+++ b/boards/addons/gdisp/board_SSD1306_spi.h
@@ -0,0 +1,133 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/SSD1306/board_SSD1306_spi.h
+ * @brief GDISP Graphic Driver subsystem board interface for the SSD1306 display.
+ */
+
+#ifndef _GDISP_LLD_BOARD_H
+#define _GDISP_LLD_BOARD_H
+
+// The command byte to put on the front of each page line
+#define SSD1306_PAGE_PREFIX 0x40 // Co = 0, D/C = 1
+
+// For a multiple display configuration we would put all this in a structure and then
+// set g->board to that structure.
+#define SSD1306_RESET_PORT GPIOB
+#define SSD1306_RESET_PIN 5
+#define SSD1306_MISO_PORT GPIOB
+#define SSD1306_MISO_PIN 8
+#define SSD1306_MOSI_PORT GPIOB
+#define SSD1306_MOSI_PIN 7
+#define SSD1306_SCK_PORT GPIOB
+#define SSD1306_SCK_PIN 6
+#define SSD1306_CS_PORT GPIOB
+#define SSD1306_CS_PIN 5
+#define SET_RST palSetPad(SSD1306_RESET_PORT, SSD1306_RESET_PIN);
+#define CLR_RST palClearPad(SSD1306_RESET_PORT, SSD1306_RESET_PIN);
+
+/*
+ * SPI1 configuration structure.
+ * Speed 42MHz, CPHA=0, CPOL=0, 8bits frames, MSb transmitted first.
+ * The slave select line is the pin 4 on the port GPIOA.
+ */
+static const SPIConfig spi1config = {
+ NULL,
+ /* HW dependent part.*/
+ SSD1306_MISO_PORT,
+ SSD1306_MISO_PIN,
+ 0
+ //SPI_CR1_BR_0
+};
+
+#if GFX_USE_OS_CHIBIOS
+ static int32_t thdPriority = 0;
+#endif
+
+static inline void init_board(GDisplay *g) {
+ unsigned i;
+
+ // As we are not using multiple displays we set g->board to NULL as we don't use it.
+ g->board = 0;
+
+
+ switch(g->controllerdisplay) {
+ case 0: // Set up for Display 0
+ // RESET pin.
+ palSetPadMode(SSD1306_RESET_PORT, SSD1306_RESET_PIN, PAL_MODE_OUTPUT_PUSHPULL);
+
+ palSetPadMode(SSD1306_MISO_PORT, SSD1306_MISO_PIN, PAL_MODE_ALTERNATE(1)|
+ PAL_STM32_OSPEED_HIGHEST);
+ palSetPadMode(SSD1306_MOSI_PORT, SSD1306_MOSI_PIN, PAL_MODE_ALTERNATE(1)|
+ PAL_STM32_OSPEED_HIGHEST);
+ palSetPadMode(SSD1306_SCK_PORT, SSD1306_SCK_PIN, PAL_MODE_ALTERNATE(1)|
+ PAL_STM32_OSPEED_HIGHEST);
+ palSetPad(SSD1306_CS_PORT, SSD1306_CS_PIN);
+ palSetPadMode(SSD1306_CS_PORT, SSD1306_CS_PIN, PAL_MODE_ALTERNATE(1)|
+ PAL_STM32_OSPEED_HIGHEST);
+ spiInit();
+ break;
+ }
+}
+
+static inline void post_init_board(GDisplay *g) {
+ (void) g;
+}
+
+static inline void setpin_reset(GDisplay *g, bool_t state) {
+ (void) g;
+ if(state)
+ CLR_RST
+ else
+ SET_RST
+}
+
+static inline void acquire_bus(GDisplay *g) {
+ (void) g;
+ #if GFX_USE_OS_CHIBIOS
+ thdPriority = (int32_t)chThdGetPriority();
+ chThdSetPriority(HIGHPRIO);
+ #endif
+ spiAcquireBus(&SPID1);
+}
+
+static inline void release_bus(GDisplay *g) {
+ (void) g;
+ #if GFX_USE_OS_CHIBIOS
+ chThdSetPriority(thdPriority);
+ #endif
+ spiReleaseBus(&SPID1);
+}
+
+static inline void write_cmd(GDisplay *g, uint8_t cmd) {
+ uint8_t command[2];
+ (void) g;
+
+ command[0] = 0x00; // Co = 0, D/C = 0
+ command[1] = cmd;
+
+ spiStart(&SPID1, &spi1config);
+ spiSelect(&SPID1);
+ spiStartSend(&SPID1, 2, command);
+ spiUnselect(&SPID1);
+ spiStop(&SPID1);
+}
+
+static inline void write_data(GDisplay *g, uint8_t* data, uint16_t length) {
+ (void) g;
+
+ spiStart(&SPID1, &spi1config);
+ spiSelect(&SPID1);
+ spiStartSend(&SPID1, length, data);
+ spiUnselect(&SPID1);
+ spiStop(&SPID1);
+}
+
+
+#endif /* _GDISP_LLD_BOARD_H */
+
diff --git a/boards/addons/gdisp/board_SSD1963_fsmc.h b/boards/addons/gdisp/board_SSD1963_fsmc.h
new file mode 100644
index 00000000..6c7119a4
--- /dev/null
+++ b/boards/addons/gdisp/board_SSD1963_fsmc.h
@@ -0,0 +1,105 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://chibios-gfx.com/license.html
+ */
+
+/**
+ * @file drivers/gdisp/SSD1963/board_SSD1963_fsmc.h
+ * @brief GDISP Graphic Driver subsystem board interface for the SSD1963 display.
+ */
+
+#ifndef _GDISP_LLD_BOARD_H
+#define _GDISP_LLD_BOARD_H
+
+static const LCD_Parameters DisplayTimings[] = {
+ // You need one of these array elements per display
+ {
+ 480, 272, // Panel width and height
+ 2, 2, 41, // Horizontal Timings (back porch, front porch, pulse)
+ CALC_PERIOD(480,2,2,41), // Total Horizontal Period (calculated from above line)
+ 2, 2, 10, // Vertical Timings (back porch, front porch, pulse)
+ CALC_PERIOD(272,2,2,10), // Total Vertical Period (calculated from above line)
+ CALC_FPR(480,272,2,2,41,2,2,10,60ULL) // FPR - the 60ULL is the frames per second. Note the ULL!
+ },
+};
+
+// For a multiple display configuration we would put all this in a structure and then
+// set g->board to that structure.
+
+/* Using FSMC A16 as RS */
+#define GDISP_REG (*((volatile uint16_t *) 0x60000000)) /* RS = 0 */
+#define GDISP_RAM (*((volatile uint16_t *) 0x60020000)) /* RS = 1 */
+
+static inline void init_board(GDisplay *g) {
+
+ // As we are not using multiple displays we set g->board to NULL as we don't use it.
+ g->board = 0;
+
+ switch(g->controllerdisplay) {
+ case 0: // Set up for Display 0
+ #if defined(STM32F1XX) || defined(STM32F3XX)
+ /* FSMC setup for F1/F3 */
+ rccEnableAHB(RCC_AHBENR_FSMCEN, 0);
+ #elif defined(STM32F4XX) || defined(STM32F2XX)
+ /* STM32F2-F4 FSMC init */
+ rccEnableAHB3(RCC_AHB3ENR_FSMCEN, 0);
+ #else
+ #error "FSMC not implemented for this device"
+ #endif
+
+ /* set pins to FSMC mode */
+ IOBus busD = {GPIOD, (1 << 0) | (1 << 1) | (1 << 4) | (1 << 5) | (1 << 7) | (1 << 8) |
+ (1 << 9) | (1 << 10) | (1 << 11) | (1 << 14) | (1 << 15), 0};
+
+ IOBus busE = {GPIOE, (1 << 7) | (1 << 8) | (1 << 9) | (1 << 10) | (1 << 11) | (1 << 12) |
+ (1 << 13) | (1 << 14) | (1 << 15), 0};
+
+ palSetBusMode(&busD, PAL_MODE_ALTERNATE(12));
+ palSetBusMode(&busE, PAL_MODE_ALTERNATE(12));
+
+ /* FSMC timing */
+ FSMC_Bank1->BTCR[0+1] = (FSMC_BTR1_ADDSET_1 | FSMC_BTR1_ADDSET_3) \
+ | (FSMC_BTR1_DATAST_1 | FSMC_BTR1_DATAST_3) \
+ | (FSMC_BTR1_BUSTURN_1 | FSMC_BTR1_BUSTURN_3) ;
+
+ /* Bank1 NOR/SRAM control register configuration
+ * This is actually not needed as already set by default after reset */
+ FSMC_Bank1->BTCR[0] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN;
+ break;
+ }
+}
+
+static inline void post_init_board(GDisplay *g) {
+ (void) g;
+ /* FSMC delay reduced as the controller now runs at full speed */
+ FSMC_Bank1->BTCR[0+1] = FSMC_BTR1_ADDSET_0 | FSMC_BTR1_DATAST_2 | FSMC_BTR1_BUSTURN_0 ;
+ FSMC_Bank1->BTCR[0] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN;
+}
+
+static inline void setpin_reset(GDisplay *g, bool_t state) {
+ (void) g;
+ (void) state;
+}
+
+static inline void acquire_bus(GDisplay *g) {
+ (void) g;
+}
+
+static inline void release_bus(GDisplay *g) {
+ (void) g;
+}
+
+static inline void write_index(GDisplay *g, uint16_t index) {
+ (void) g;
+ GDISP_REG = index;
+}
+
+static inline void write_data(GDisplay *g, uint16_t data) {
+ (void) g;
+ GDISP_RAM = data;
+}
+
+#endif /* _GDISP_LLD_BOARD_H */
+
diff --git a/boards/addons/gdisp/board_SSD1963_gpio.h b/boards/addons/gdisp/board_SSD1963_gpio.h
new file mode 100644
index 00000000..0b9c0135
--- /dev/null
+++ b/boards/addons/gdisp/board_SSD1963_gpio.h
@@ -0,0 +1,102 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://chibios-gfx.com/license.html
+ */
+
+/**
+ * @file drivers/gdisp/SSD1963/board_SSD1963_gpio.h
+ * @brief GDISP Graphic Driver subsystem board interface for the SSD1963 display.
+ */
+
+#ifndef _GDISP_LLD_BOARD_H
+#define _GDISP_LLD_BOARD_H
+
+static const LCD_Parameters DisplayTimings[] = {
+ // You need one of these array elements per display
+ {
+ 480, 272, // Panel width and height
+ 2, 2, 41, // Horizontal Timings (back porch, front porch, pulse)
+ CALC_PERIOD(480,2,2,41), // Total Horizontal Period (calculated from above line)
+ 2, 2, 10, // Vertical Timings (back porch, front porch, pulse)
+ CALC_PERIOD(272,2,2,10), // Total Vertical Period (calculated from above line)
+ CALC_FPR(480,272,2,2,41,2,2,10,60ULL) // FPR - the 60ULL is the frames per second. Note the ULL!
+ },
+};
+
+// For a multiple display configuration we would put all this in a structure and then
+// set g->board to that structure.
+
+/**
+ * @brief The GPIO pin config
+ *
+ * @details This block of defines tell your driver how you wired your display
+ * controller to your MCU. Please change them accordingly.
+ */
+#define GDISP_CMD_PORT GPIOC
+#define GDISP_DATA_PORT GPIOD
+#define GDISP_CS 0
+#define GDISP_RS 1
+#define GDISP_WR 2
+#define GDISP_RD 3
+
+#define Set_CS palSetPad(GDISP_CMD_PORT, GDISP_CS);
+#define Clr_CS palClearPad(GDISP_CMD_PORT, GDISP_CS);
+#define Set_RS palSetPad(GDISP_CMD_PORT, GDISP_RS);
+#define Clr_RS palClearPad(GDISP_CMD_PORT, GDISP_RS);
+#define Set_WR palSetPad(GDISP_CMD_PORT, GDISP_WR);
+#define Clr_WR palClearPad(GDISP_CMD_PORT, GDISP_WR);
+#define Set_RD palSetPad(GDISP_CMD_PORT, GDISP_RD);
+#define Clr_RD palClearPad(GDISP_CMD_PORT, GDISP_RD);
+
+static inline void init_board(GDisplay *g) {
+
+ // As we are not using multiple displays we set g->board to NULL as we don't use it.
+ g->board = 0;
+
+ switch(g->controllerdisplay) {
+ case 0: // Set up for Display 0
+ IOBus busCMD = {GDISP_CMD_PORT, (1 << GDISP_CS) | (1 << GDISP_RS) | (1 << GDISP_WR) | (1 << GDISP_RD), 0};
+ IOBus busDATA = {GDISP_CMD_PORT, 0xFFFFF, 0};
+ palSetBusMode(&busCMD, PAL_MODE_OUTPUT_PUSHPULL);
+ palSetBusMode(&busDATA, PAL_MODE_OUTPUT_PUSHPULL);
+ break;
+ }
+}
+
+static inline void post_init_board(GDisplay *g) {
+ (void) g;
+}
+
+static inline void setpin_reset(GDisplay *g, bool_t state) {
+ (void) g;
+ (void) state;
+}
+
+static inline void acquire_bus(GDisplay *g) {
+ (void) g;
+ Set_CS;
+}
+
+static inline void release_bus(GDisplay *g) {
+ (void) g;
+ Clr_CS;
+}
+
+static inline void write_index(GDisplay *g, uint16_t index) {
+ (void) g;
+ Set_RS; Clr_RD; Set_WR;
+ palWritePort(GDISP_DATA_PORT, index);
+ Clr_WR;
+}
+
+static inline void write_data(GDisplay *g, uint16_t data) {
+ (void) g;
+ Clr_RS; Clr_RD; Set_WR;
+ palWritePort(GDISP_DATA_PORT, data);
+ Clr_WR;
+}
+
+#endif /* _GDISP_LLD_BOARD_H */
+
diff --git a/boards/addons/gdisp/board_SSD2119_embest_dmstf4bb.h b/boards/addons/gdisp/board_SSD2119_embest_dmstf4bb.h
new file mode 100644
index 00000000..927e93a4
--- /dev/null
+++ b/boards/addons/gdisp/board_SSD2119_embest_dmstf4bb.h
@@ -0,0 +1,173 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/SSD2119/board_SSD2119_embest_dmstf4bb.h
+ * @brief GDISP Graphic Driver subsystem board FSMC interface for the SSD2119 display.
+ */
+
+#ifndef _GDISP_LLD_BOARD_H
+#define _GDISP_LLD_BOARD_H
+
+// For a multiple display configuration we would put all this in a structure and then
+// set g->board to that structure.
+
+/* Using FSMC A19 (PE3) as DC */
+#define GDISP_REG (*((volatile uint16_t *) 0x60000000)) /* DC = 0 */
+#define GDISP_RAM (*((volatile uint16_t *) 0x60100000)) /* DC = 1 */
+#define GDISP_DMA_STREAM STM32_DMA2_STREAM6
+
+#define SET_RST palSetPad(GPIOD, 3);
+#define CLR_RST palClearPad(GPIOD, 3);
+
+/*
+ * PWM configuration structure. We use timer 4 channel 2 (orange LED on board).
+ * The reason for so high clock is that with any lower, onboard coil is squeaking.
+ * The major disadvantage of this clock is a lack of linearity between PWM duty
+ * cycle width and brightness. In fact only with low preset one sees any change
+ * (eg. duty cycle between 1-20). Feel free to adjust this, maybe only my board
+ * behaves like this. According to the G5126 datesheet (backlight LED driver)
+ * the PWM frequency should be somewhere between 200 Hz to 200 kHz.
+ */
+static const PWMConfig pwmcfg = {
+ 1000000, /* 1 MHz PWM clock frequency. */
+ 100, /* PWM period is 100 cycles. */
+ NULL,
+ {
+ {PWM_OUTPUT_ACTIVE_HIGH, NULL},
+ {PWM_OUTPUT_ACTIVE_HIGH, NULL},
+ {PWM_OUTPUT_ACTIVE_HIGH, NULL},
+ {PWM_OUTPUT_ACTIVE_HIGH, NULL}
+ },
+ 0
+};
+
+static inline void init_board(GDisplay *g) {
+
+ // As we are not using multiple displays we set g->board to NULL as we don't use it.
+ g->board = 0;
+
+ switch(g->controllerdisplay) {
+ case 0: // Set up for Display 0
+ #if defined(STM32F4XX) || defined(STM32F2XX)
+ /* STM32F4 FSMC init */
+ rccEnableAHB3(RCC_AHB3ENR_FSMCEN, 0);
+
+ #if defined(GDISP_USE_DMA) && defined(GDISP_DMA_STREAM)
+ if (dmaStreamAllocate(GDISP_DMA_STREAM, 0, NULL, NULL))
+ gfxExit();
+ dmaStreamSetMemory0(GDISP_DMA_STREAM, &GDISP_RAM);
+ dmaStreamSetMode(GDISP_DMA_STREAM, STM32_DMA_CR_PL(0) | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_DIR_M2M);
+ #endif
+ #else
+ #error "FSMC not implemented for this device"
+ #endif
+
+ /* Group pins */
+ IOBus busD = {GPIOD, (1 << 0) | (1 << 1) | (1 << 4) | (1 << 5) | (1 << 7) | (1 << 8) |
+ (1 << 9) | (1 << 10) | (1 << 14) | (1 << 15), 0};
+
+ IOBus busE = {GPIOE, (1 << 3) | (1 << 7) | (1 << 8) | (1 << 9) | (1 << 10) | (1 << 11) | (1 << 12) |
+ (1 << 13) | (1 << 14) | (1 << 15), 0};
+
+ /* FSMC is an alternate function 12 (AF12) */
+ palSetBusMode(&busD, PAL_MODE_ALTERNATE(12));
+ palSetBusMode(&busE, PAL_MODE_ALTERNATE(12));
+
+ /* FSMC timing register configuration */
+ FSMC_Bank1->BTCR[0 + 1] = (FSMC_BTR1_ADDSET_2 | FSMC_BTR1_ADDSET_1) \
+ | (FSMC_BTR1_DATAST_2 | FSMC_BTR1_DATAST_1) \
+ | FSMC_BTR1_BUSTURN_0;
+
+ /* Bank1 NOR/PSRAM control register configuration
+ * Write enable, memory databus width set to 16 bit, memory bank enable */
+ FSMC_Bank1->BTCR[0] = FSMC_BCR1_WREN | FSMC_BCR1_MWID_0 | FSMC_BCR1_MBKEN;
+
+ /* Display backlight control */
+ /* TIM4 is an alternate function 2 (AF2) */
+ pwmStart(&PWMD4, &pwmcfg);
+ palSetPadMode(GPIOD, 13, PAL_MODE_ALTERNATE(2));
+ pwmEnableChannel(&PWMD4, 1, 100);
+ break;
+ }
+}
+
+static inline void post_init_board(GDisplay *g) {
+ (void) g;
+}
+
+static inline void setpin_reset(GDisplay *g, bool_t state) {
+ (void) g;
+ if (state) {
+ CLR_RST;
+ } else {
+ SET_RST;
+ }
+}
+
+static inline void set_backlight(GDisplay *g, uint8_t percent) {
+ (void) g;
+ pwmEnableChannel(&PWMD4, 1, percent);
+}
+
+static inline void acquire_bus(GDisplay *g) {
+ (void) g;
+}
+
+static inline void release_bus(GDisplay *g) {
+ (void) g;
+}
+
+static inline void write_index(GDisplay *g, uint16_t index) {
+ (void) g;
+ GDISP_REG = index;
+}
+
+static inline void write_data(GDisplay *g, uint16_t data) {
+ (void) g;
+ GDISP_RAM = data;
+}
+
+static inline void setreadmode(GDisplay *g) {
+ (void) g;
+}
+
+static inline void setwritemode(GDisplay *g) {
+ (void) g;
+}
+
+static inline uint16_t read_data(GDisplay *g) {
+ (void) g;
+ return GDISP_RAM;
+}
+
+#if defined(GDISP_USE_DMA)
+ static inline void dma_with_noinc(GDisplay *g, color_t *buffer, int area) {
+ (void) g;
+ dmaStreamSetPeripheral(GDISP_DMA_STREAM, buffer);
+ dmaStreamSetMode(GDISP_DMA_STREAM, STM32_DMA_CR_PL(0) | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_DIR_M2M);
+ for (; area > 0; area -= 65535) {
+ dmaStreamSetTransactionSize(GDISP_DMA_STREAM, area > 65535 ? 65535 : area);
+ dmaStreamEnable(GDISP_DMA_STREAM);
+ dmaWaitCompletion(GDISP_DMA_STREAM);
+ }
+ }
+
+ static inline void dma_with_inc(GDisplay *g, color_t *buffer, int area) {
+ (void) g;
+ dmaStreamSetPeripheral(GDISP_DMA_STREAM, buffer);
+ dmaStreamSetMode(GDISP_DMA_STREAM, STM32_DMA_CR_PL(0) | STM32_DMA_CR_PINC | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_DIR_M2M);
+ for (; area > 0; area -= 65535) {
+ dmaStreamSetTransactionSize(GDISP_DMA_STREAM, area > 65535 ? 65535 : area);
+ dmaStreamEnable(GDISP_DMA_STREAM);
+ dmaWaitCompletion(GDISP_DMA_STREAM);
+ }
+ }
+#endif
+
+#endif /* _GDISP_LLD_BOARD_H */
+
diff --git a/drivers/ginput/touch/ADS7843/ginput_lld_mouse_board_firebull_stm32f103.h b/boards/addons/ginput/touch/ADS7843/ginput_lld_mouse_board_firebull_stm32f103.h
index ebcc26c7..63e9e3dd 100644
--- a/drivers/ginput/touch/ADS7843/ginput_lld_mouse_board_firebull_stm32f103.h
+++ b/boards/addons/ginput/touch/ADS7843/ginput_lld_mouse_board_firebull_stm32f103.h
@@ -4,87 +4,87 @@
*
* http://ugfx.org/license.html
*/
-
-/**
- * @file drivers/ginput/touch/ADS7843/ginput_lld_mouse_board_firebull_stm32f103.h
- * @brief GINPUT ouch low level driver source for the ADS7843 on the FireBull STM32F103-FB board.
- *
- * @defgroup Mouse Mouse
- * @ingroup GINPUT
- * @{
- */
-
-#ifndef _GINPUT_LLD_MOUSE_BOARD_H
-#define _GINPUT_LLD_MOUSE_BOARD_H
-
-static const SPIConfig spicfg = {
- NULL,
- GPIOC,
- 6,
- /* SPI_CR1_BR_2 |*/ SPI_CR1_BR_1 | SPI_CR1_BR_0,
-};
-
-/**
- * @brief Initialise the board for the touch.
- *
- * @notapi
- */
-static inline void init_board(void) {
- spiStart(&SPID1, &spicfg);
-}
-
-/**
- * @brief Check whether the surface is currently touched
- * @return TRUE if the surface is currently touched
- *
- * @notapi
- */
-static inline bool_t getpin_pressed(void) {
- return (!palReadPad(GPIOC, 4));
-}
-/**
- * @brief Aquire the bus ready for readings
- *
- * @notapi
- */
-static inline void aquire_bus(void) {
- spiAcquireBus(&SPID1);
- //TOUCHSCREEN_SPI_PROLOGUE();
- palClearPad(GPIOC, 6);
-}
-
-/**
- * @brief Release the bus after readings
- *
- * @notapi
- */
-static inline void release_bus(void) {
- palSetPad(GPIOC, 6);
- spiReleaseBus(&SPID1);
- //TOUCHSCREEN_SPI_EPILOGUE();
-}
-
-/**
- * @brief Read a value from touch controller
- * @return The value read from the controller
- *
- * params[in] port The controller port to read.
- *
- * @notapi
- */
-static inline uint16_t read_value(uint16_t port) {
- static uint8_t txbuf[3] = {0};
- static uint8_t rxbuf[3] = {0};
- uint16_t ret;
-
- txbuf[0] = port;
-
- spiExchange(&SPID1, 3, txbuf, rxbuf);
-
- ret = (rxbuf[1] << 5) | (rxbuf[2] >> 3);
-
- return ret;
-}
-
-#endif /* _GINPUT_LLD_MOUSE_BOARD_H */
-/** @} */
+
+/**
+ * @file drivers/ginput/touch/ADS7843/ginput_lld_mouse_board_firebull_stm32f103.h
+ * @brief GINPUT ouch low level driver source for the ADS7843 on the FireBull STM32F103-FB board.
+ *
+ * @defgroup Mouse Mouse
+ * @ingroup GINPUT
+ * @{
+ */
+
+#ifndef _GINPUT_LLD_MOUSE_BOARD_H
+#define _GINPUT_LLD_MOUSE_BOARD_H
+
+static const SPIConfig spicfg = {
+ NULL,
+ GPIOC,
+ 6,
+ /* SPI_CR1_BR_2 |*/ SPI_CR1_BR_1 | SPI_CR1_BR_0,
+};
+
+/**
+ * @brief Initialise the board for the touch.
+ *
+ * @notapi
+ */
+static inline void init_board(void) {
+ spiStart(&SPID1, &spicfg);
+}
+
+/**
+ * @brief Check whether the surface is currently touched
+ * @return TRUE if the surface is currently touched
+ *
+ * @notapi
+ */
+static inline bool_t getpin_pressed(void) {
+ return (!palReadPad(GPIOC, 4));
+}
+/**
+ * @brief Aquire the bus ready for readings
+ *
+ * @notapi
+ */
+static inline void aquire_bus(void) {
+ spiAcquireBus(&SPID1);
+ //TOUCHSCREEN_SPI_PROLOGUE();
+ palClearPad(GPIOC, 6);
+}
+
+/**
+ * @brief Release the bus after readings
+ *
+ * @notapi
+ */
+static inline void release_bus(void) {
+ palSetPad(GPIOC, 6);
+ spiReleaseBus(&SPID1);
+ //TOUCHSCREEN_SPI_EPILOGUE();
+}
+
+/**
+ * @brief Read a value from touch controller
+ * @return The value read from the controller
+ *
+ * params[in] port The controller port to read.
+ *
+ * @notapi
+ */
+static inline uint16_t read_value(uint16_t port) {
+ static uint8_t txbuf[3] = {0};
+ static uint8_t rxbuf[3] = {0};
+ uint16_t ret;
+
+ txbuf[0] = port;
+
+ spiExchange(&SPID1, 3, txbuf, rxbuf);
+
+ ret = (rxbuf[1] << 5) | (rxbuf[2] >> 3);
+
+ return ret;
+}
+
+#endif /* _GINPUT_LLD_MOUSE_BOARD_H */
+/** @} */
diff --git a/drivers/ginput/touch/ADS7843/ginput_lld_mouse_board_olimex_stm32_e407.h b/boards/addons/ginput/touch/ADS7843/ginput_lld_mouse_board_olimex_stm32_e407.h
index 01572f0d..e0ab85dc 100644
--- a/drivers/ginput/touch/ADS7843/ginput_lld_mouse_board_olimex_stm32_e407.h
+++ b/boards/addons/ginput/touch/ADS7843/ginput_lld_mouse_board_olimex_stm32_e407.h
@@ -4,87 +4,87 @@
*
* http://ugfx.org/license.html
*/
-
-/**
- * @file drivers/ginput/touch/ADS7843/ginput_lld_mouse_board_olimex_stm32_e407.h
- * @brief GINPUT Touch low level driver source for the ADS7843 on an Olimex STM32E407.
- *
- * @defgroup Mouse Mouse
- * @ingroup GINPUT
- * @{
- */
-
-#ifndef _GINPUT_LLD_MOUSE_BOARD_H
-#define _GINPUT_LLD_MOUSE_BOARD_H
-
-static const SPIConfig spicfg = {
- NULL,
- GPIOG,
- 10,
- /* SPI_CR1_BR_2 |*/ SPI_CR1_BR_1 | SPI_CR1_BR_0,
-};
-
-/**
- * @brief Initialise the board for the touch.
- *
- * @notapi
- */
-static inline void init_board(void) {
- spiStart(&SPID2, &spicfg);
-}
-
-/**
- * @brief Check whether the surface is currently touched
- * @return TRUE if the surface is currently touched
- *
- * @notapi
- */
-static inline bool_t getpin_pressed(void) {
- return (!palReadPad(GPIOG, 0));
-}
-/**
- * @brief Aquire the bus ready for readings
- *
- * @notapi
- */
-static inline void aquire_bus(void) {
- spiAcquireBus(&SPID2);
- //TOUCHSCREEN_SPI_PROLOGUE();
- palClearPad(GPIOG, 10);
-}
-
-/**
- * @brief Release the bus after readings
- *
- * @notapi
- */
-static inline void release_bus(void) {
- palSetPad(GPIOG, 10);
- spiReleaseBus(&SPID2);
- //TOUCHSCREEN_SPI_EPILOGUE();
-}
-
-/**
- * @brief Read a value from touch controller
- * @return The value read from the controller
- *
- * params[in] port The controller port to read.
- *
- * @notapi
- */
-static inline uint16_t read_value(uint16_t port) {
- static uint8_t txbuf[3] = {0};
- static uint8_t rxbuf[3] = {0};
- uint16_t ret;
-
- txbuf[0] = port;
-
- spiExchange(&SPID2, 3, txbuf, rxbuf);
-
- ret = (rxbuf[1] << 5) | (rxbuf[2] >> 3);
-
- return ret;
-}
-
-#endif /* _GINPUT_LLD_MOUSE_BOARD_H */
-/** @} */
+
+/**
+ * @file drivers/ginput/touch/ADS7843/ginput_lld_mouse_board_olimex_stm32_e407.h
+ * @brief GINPUT Touch low level driver source for the ADS7843 on an Olimex STM32E407.
+ *
+ * @defgroup Mouse Mouse
+ * @ingroup GINPUT
+ * @{
+ */
+
+#ifndef _GINPUT_LLD_MOUSE_BOARD_H
+#define _GINPUT_LLD_MOUSE_BOARD_H
+
+static const SPIConfig spicfg = {
+ NULL,
+ GPIOG,
+ 10,
+ /* SPI_CR1_BR_2 |*/ SPI_CR1_BR_1 | SPI_CR1_BR_0,
+};
+
+/**
+ * @brief Initialise the board for the touch.
+ *
+ * @notapi
+ */
+static inline void init_board(void) {
+ spiStart(&SPID2, &spicfg);
+}
+
+/**
+ * @brief Check whether the surface is currently touched
+ * @return TRUE if the surface is currently touched
+ *
+ * @notapi
+ */
+static inline bool_t getpin_pressed(void) {
+ return (!palReadPad(GPIOG, 0));
+}
+/**
+ * @brief Aquire the bus ready for readings
+ *
+ * @notapi
+ */
+static inline void aquire_bus(void) {
+ spiAcquireBus(&SPID2);
+ //TOUCHSCREEN_SPI_PROLOGUE();
+ palClearPad(GPIOG, 10);
+}
+
+/**
+ * @brief Release the bus after readings
+ *
+ * @notapi
+ */
+static inline void release_bus(void) {
+ palSetPad(GPIOG, 10);
+ spiReleaseBus(&SPID2);
+ //TOUCHSCREEN_SPI_EPILOGUE();
+}
+
+/**
+ * @brief Read a value from touch controller
+ * @return The value read from the controller
+ *
+ * params[in] port The controller port to read.
+ *
+ * @notapi
+ */
+static inline uint16_t read_value(uint16_t port) {
+ static uint8_t txbuf[3] = {0};
+ static uint8_t rxbuf[3] = {0};
+ uint16_t ret;
+
+ txbuf[0] = port;
+
+ spiExchange(&SPID2, 3, txbuf, rxbuf);
+
+ ret = (rxbuf[1] << 5) | (rxbuf[2] >> 3);
+
+ return ret;
+}
+
+#endif /* _GINPUT_LLD_MOUSE_BOARD_H */
+/** @} */
diff --git a/drivers/ginput/touch/ADS7843/ginput_lld_mouse_board_st_stm32f4_discovery.h b/boards/addons/ginput/touch/ADS7843/ginput_lld_mouse_board_st_stm32f4_discovery.h
index 158934b6..158934b6 100644
--- a/drivers/ginput/touch/ADS7843/ginput_lld_mouse_board_st_stm32f4_discovery.h
+++ b/boards/addons/ginput/touch/ADS7843/ginput_lld_mouse_board_st_stm32f4_discovery.h
diff --git a/drivers/ginput/touch/FT5x06/ginput_lld_mouse_board_marlin.h b/boards/addons/ginput/touch/FT5x06/ginput_lld_mouse_board_marlin.h
index e3e18c24..e3e18c24 100644
--- a/drivers/ginput/touch/FT5x06/ginput_lld_mouse_board_marlin.h
+++ b/boards/addons/ginput/touch/FT5x06/ginput_lld_mouse_board_marlin.h
diff --git a/drivers/ginput/touch/MCU/ginput_lld_mouse_board_olimex_pic32mx_lcd.h b/boards/addons/ginput/touch/MCU/ginput_lld_mouse_board_olimex_pic32mx_lcd.h
index c4689ecb..a7435c95 100644
--- a/drivers/ginput/touch/MCU/ginput_lld_mouse_board_olimex_pic32mx_lcd.h
+++ b/boards/addons/ginput/touch/MCU/ginput_lld_mouse_board_olimex_pic32mx_lcd.h
@@ -4,148 +4,148 @@
*
* http://ugfx.org/license.html
*/
-
-/**
- * @file drivers/ginput/touch/MCU/ginput_lld_mouse_board_olimex_stm32_lcd.h
- * @brief GINPUT Touch low level driver source for the MCU on the example board.
- *
- * @defgroup Mouse Mouse
- * @ingroup GINPUT
- *
- * @{
- */
-
-#ifndef _GINPUT_LLD_MOUSE_BOARD_H
-#define _GINPUT_LLD_MOUSE_BOARD_H
-
-static const ADCConfig ADCC = {
- .vref = ADC_VREF_CFG_AVDD_AVSS,
- .stime = 15,
- .irq = EIC_IRQ_ADC,
- .base = _ADC10_BASE_ADDRESS,
-};
-static struct ADCDriver ADCD;
-
-#define YNEG 13 // U
-#define XNEG 15 // R
-#define XPOS 12 // L
-#define YPOS 11 // D
-
-#define ADC_MAX 1023
-
-#define TOUCH_THRESHOULD 50
-
-static const ADCConversionGroup ADC_X_CG = {
- .circular = FALSE,
- .num_channels = 1,
- .channels = 1 << XNEG,
-};
-
-static const ADCConversionGroup ADC_Y_CG = {
- .circular = FALSE,
- .num_channels = 1,
- .channels = 1 << YPOS,
-};
-
-/**
- * @brief Initialise the board for the touch.
- *
- * @notapi
- */
-static inline void init_board(void) {
- adcObjectInit(&ADCD);
- adcStart(&ADCD, &ADCC);
-}
-
-/**
- * @brief Check whether the surface is currently touched
- * @return TRUE if the surface is currently touched
- *
- * @notapi
- */
-static inline bool_t getpin_pressed(void) {
- adcsample_t samples[2] = {0, };
-
- // Set X+ to ground
- palSetPadMode(IOPORTB, XPOS, PAL_MODE_OUTPUT);
- palClearPad(IOPORTB, XPOS);
-
- // Set Y- to VCC
- palSetPadMode(IOPORTB, YNEG, PAL_MODE_OUTPUT);
- palSetPad(IOPORTB, YNEG);
-
- palSetPadMode(IOPORTB, XNEG, PAL_MODE_INPUT_ANALOG);
- palSetPadMode(IOPORTB, YPOS, PAL_MODE_INPUT_ANALOG);
-
- adcConvert(&ADCD, &ADC_X_CG, &samples[0], 1);
- adcConvert(&ADCD, &ADC_Y_CG, &samples[1], 1);
-
- return (ADC_MAX - (samples[1] - samples[0])) > TOUCH_THRESHOULD;
-}
-
-/**
- * @brief Aquire the bus ready for readings
- *
- * @notapi
- */
-static inline void aquire_bus(void) {
-}
-
-/**
- * @brief Release the bus after readings
- *
- * @notapi
- */
-static inline void release_bus(void) {
-}
-
-/**
- * @brief Read an x value from touch controller
- * @return The value read from the controller
- *
- * @notapi
- */
-static inline uint16_t read_x_value(void) {
- adcsample_t sample;
-
- palSetPadMode(IOPORTB, XPOS, PAL_MODE_OUTPUT);
- palSetPad(IOPORTB, XPOS);
-
- palSetPadMode(IOPORTB, XNEG, PAL_MODE_OUTPUT);
- palClearPad(IOPORTB, XNEG);
-
- palSetPadMode(IOPORTB, YNEG, PAL_MODE_INPUT);
-
- palSetPadMode(IOPORTB, YPOS, PAL_MODE_INPUT_ANALOG);
-
- adcConvert(&ADCD, &ADC_Y_CG, &sample, 1);
-
- return ADC_MAX - sample;
-}
-
-/**
- * @brief Read an y value from touch controller
- * @return The value read from the controller
- *
- * @notapi
- */
-static inline uint16_t read_y_value(void) {
- adcsample_t sample;
-
- palSetPadMode(IOPORTB, YNEG, PAL_MODE_OUTPUT);
- palClearPad(IOPORTB, YNEG);
-
- palSetPadMode(IOPORTB, YPOS, PAL_MODE_OUTPUT);
- palSetPad(IOPORTB, YPOS);
-
- palSetPadMode(IOPORTB, XPOS, PAL_MODE_INPUT);
-
- palSetPadMode(IOPORTB, XNEG, PAL_MODE_INPUT_ANALOG);
-
- adcConvert(&ADCD, &ADC_X_CG, &sample, 1);
-
- return ADC_MAX - sample;
-}
-
-#endif /* _GINPUT_LLD_MOUSE_BOARD_H */
-/** @} */
+
+/**
+ * @file drivers/ginput/touch/MCU/ginput_lld_mouse_board_olimex_stm32_lcd.h
+ * @brief GINPUT Touch low level driver source for the MCU on the example board.
+ *
+ * @defgroup Mouse Mouse
+ * @ingroup GINPUT
+ *
+ * @{
+ */
+
+#ifndef _GINPUT_LLD_MOUSE_BOARD_H
+#define _GINPUT_LLD_MOUSE_BOARD_H
+
+static const ADCConfig ADCC = {
+ .vref = ADC_VREF_CFG_AVDD_AVSS,
+ .stime = 15,
+ .irq = EIC_IRQ_ADC,
+ .base = _ADC10_BASE_ADDRESS,
+};
+static struct ADCDriver ADCD;
+
+#define YNEG 13 // U
+#define XNEG 15 // R
+#define XPOS 12 // L
+#define YPOS 11 // D
+
+#define ADC_MAX 1023
+
+#define TOUCH_THRESHOULD 50
+
+static const ADCConversionGroup ADC_X_CG = {
+ .circular = FALSE,
+ .num_channels = 1,
+ .channels = 1 << XNEG,
+};
+
+static const ADCConversionGroup ADC_Y_CG = {
+ .circular = FALSE,
+ .num_channels = 1,
+ .channels = 1 << YPOS,
+};
+
+/**
+ * @brief Initialise the board for the touch.
+ *
+ * @notapi
+ */
+static inline void init_board(void) {
+ adcObjectInit(&ADCD);
+ adcStart(&ADCD, &ADCC);
+}
+
+/**
+ * @brief Check whether the surface is currently touched
+ * @return TRUE if the surface is currently touched
+ *
+ * @notapi
+ */
+static inline bool_t getpin_pressed(void) {
+ adcsample_t samples[2] = {0, };
+
+ // Set X+ to ground
+ palSetPadMode(IOPORTB, XPOS, PAL_MODE_OUTPUT);
+ palClearPad(IOPORTB, XPOS);
+
+ // Set Y- to VCC
+ palSetPadMode(IOPORTB, YNEG, PAL_MODE_OUTPUT);
+ palSetPad(IOPORTB, YNEG);
+
+ palSetPadMode(IOPORTB, XNEG, PAL_MODE_INPUT_ANALOG);
+ palSetPadMode(IOPORTB, YPOS, PAL_MODE_INPUT_ANALOG);
+
+ adcConvert(&ADCD, &ADC_X_CG, &samples[0], 1);
+ adcConvert(&ADCD, &ADC_Y_CG, &samples[1], 1);
+
+ return (ADC_MAX - (samples[1] - samples[0])) > TOUCH_THRESHOULD;
+}
+
+/**
+ * @brief Aquire the bus ready for readings
+ *
+ * @notapi
+ */
+static inline void aquire_bus(void) {
+}
+
+/**
+ * @brief Release the bus after readings
+ *
+ * @notapi
+ */
+static inline void release_bus(void) {
+}
+
+/**
+ * @brief Read an x value from touch controller
+ * @return The value read from the controller
+ *
+ * @notapi
+ */
+static inline uint16_t read_x_value(void) {
+ adcsample_t sample;
+
+ palSetPadMode(IOPORTB, XPOS, PAL_MODE_OUTPUT);
+ palSetPad(IOPORTB, XPOS);
+
+ palSetPadMode(IOPORTB, XNEG, PAL_MODE_OUTPUT);
+ palClearPad(IOPORTB, XNEG);
+
+ palSetPadMode(IOPORTB, YNEG, PAL_MODE_INPUT);
+
+ palSetPadMode(IOPORTB, YPOS, PAL_MODE_INPUT_ANALOG);
+
+ adcConvert(&ADCD, &ADC_Y_CG, &sample, 1);
+
+ return ADC_MAX - sample;
+}
+
+/**
+ * @brief Read an y value from touch controller
+ * @return The value read from the controller
+ *
+ * @notapi
+ */
+static inline uint16_t read_y_value(void) {
+ adcsample_t sample;
+
+ palSetPadMode(IOPORTB, YNEG, PAL_MODE_OUTPUT);
+ palClearPad(IOPORTB, YNEG);
+
+ palSetPadMode(IOPORTB, YPOS, PAL_MODE_OUTPUT);
+ palSetPad(IOPORTB, YPOS);
+
+ palSetPadMode(IOPORTB, XPOS, PAL_MODE_INPUT);
+
+ palSetPadMode(IOPORTB, XNEG, PAL_MODE_INPUT_ANALOG);
+
+ adcConvert(&ADCD, &ADC_X_CG, &sample, 1);
+
+ return ADC_MAX - sample;
+}
+
+#endif /* _GINPUT_LLD_MOUSE_BOARD_H */
+/** @} */
diff --git a/drivers/ginput/touch/MCU/ginput_lld_mouse_board_olimex_stm32_lcd.h b/boards/addons/ginput/touch/MCU/ginput_lld_mouse_board_olimex_stm32_lcd.h
index 2cc58f3c..ca177a89 100644
--- a/drivers/ginput/touch/MCU/ginput_lld_mouse_board_olimex_stm32_lcd.h
+++ b/boards/addons/ginput/touch/MCU/ginput_lld_mouse_board_olimex_stm32_lcd.h
@@ -1,152 +1,152 @@
-/*
- * This file is subject to the terms of the GFX License. If a copy of
- * the license was not distributed with this file, you can obtain one at:
- *
- * http://ugfx.org/license.html
- */
-
-/**
- * @file drivers/ginput/touch/MCU/ginput_lld_mouse_board_olimex_stm32_lcd.h
- * @brief GINPUT Touch low level driver source for the MCU on the example board.
- *
- * @defgroup Mouse Mouse
- * @ingroup GINPUT
- *
- * @{
- */
-
-#ifndef _GINPUT_LLD_MOUSE_BOARD_H
-#define _GINPUT_LLD_MOUSE_BOARD_H
-
-#define ADC_NUM_CHANNELS 2
-#define ADC_BUF_DEPTH 1
-
-static const ADCConversionGroup adc_y_config = {
- FALSE,
- ADC_NUM_CHANNELS,
- NULL,
- NULL,
- 0, 0,
- 0, 0,
- ADC_SQR1_NUM_CH(ADC_NUM_CHANNELS),
- 0,
- ADC_SQR3_SQ2_N(ADC_CHANNEL_IN12) | ADC_SQR3_SQ1_N(ADC_CHANNEL_IN13)
-};
-
-static const ADCConversionGroup adc_x_config = {
- FALSE,
- ADC_NUM_CHANNELS,
- NULL,
- NULL,
- 0, 0,
- 0, 0,
- ADC_SQR1_NUM_CH(ADC_NUM_CHANNELS),
- 0,
- ADC_SQR3_SQ2_N(ADC_CHANNEL_IN10) | ADC_SQR3_SQ1_N(ADC_CHANNEL_IN11)
-};
-
-/**
- * @brief Initialise the board for the touch.
- *
- * @notapi
- */
-static inline void init_board(void) {
- adcStart(&ADCD1, NULL);
-}
-
-/**
- * @brief Check whether the surface is currently touched
- * @return TRUE if the surface is currently touched
- *
- * @notapi
- */
-static inline bool_t getpin_pressed(void) {
- palSetPadMode(GPIOC, 0, PAL_MODE_INPUT_PULLDOWN);
- palSetPadMode(GPIOC, 1, PAL_MODE_INPUT);
- palSetPadMode(GPIOC, 2, PAL_MODE_INPUT);
- palSetPadMode(GPIOC, 3, PAL_MODE_OUTPUT_PUSHPULL);
- palSetPad(GPIOC, 3);
-
- return palReadPad(GPIOC, 0);
-}
-
-/**
- * @brief Aquire the bus ready for readings
- *
- * @notapi
- */
-static inline void aquire_bus(void) {
-
-}
-
-/**
- * @brief Release the bus after readings
- *
- * @notapi
- */
-static inline void release_bus(void) {
-
-}
-
-/**
- * @brief Read an x value from touch controller
- * @return The value read from the controller
- *
- * @notapi
- */
-static inline uint16_t read_x_value(void) {
- uint16_t val1, val2;
- adcsample_t samples[ADC_NUM_CHANNELS * ADC_BUF_DEPTH];
-
- palSetPadMode(GPIOC, 0, PAL_MODE_INPUT_ANALOG);
- palSetPadMode(GPIOC, 1, PAL_MODE_INPUT_ANALOG);
- palSetPadMode(GPIOC, 2, PAL_MODE_OUTPUT_PUSHPULL);
- palSetPadMode(GPIOC, 3, PAL_MODE_OUTPUT_PUSHPULL);
-
- palSetPad(GPIOC, 2);
- palClearPad(GPIOC, 3);
- gfxSleepMilliseconds(1);
- adcConvert(&ADCD1, &adc_x_config, samples, ADC_BUF_DEPTH);
- val1 = ((samples[0] + samples[1])/2);
-
- palClearPad(GPIOC, 2);
- palSetPad(GPIOC, 3);
- gfxSleepMilliseconds(1);
- adcConvert(&ADCD1, &adc_x_config, samples, ADC_BUF_DEPTH);
- val2 = ((samples[0] + samples[1])/2);
-
- return ((val1+((1<<12)-val2))/4);
-}
-
-/**
- * @brief Read an y value from touch controller
- * @return The value read from the controller
- *
- * @notapi
- */
-static inline uint16_t read_y_value(void) {
- uint16_t val1, val2;
- adcsample_t samples[ADC_NUM_CHANNELS * ADC_BUF_DEPTH];
-
- palSetPadMode(GPIOC, 2, PAL_MODE_INPUT_ANALOG);
- palSetPadMode(GPIOC, 3, PAL_MODE_INPUT_ANALOG);
- palSetPadMode(GPIOC, 0, PAL_MODE_OUTPUT_PUSHPULL);
- palSetPadMode(GPIOC, 1, PAL_MODE_OUTPUT_PUSHPULL);
-
- palSetPad(GPIOC, 1);
- palClearPad(GPIOC, 0);
- gfxSleepMilliseconds(1);
- adcConvert(&ADCD1, &adc_y_config, samples, ADC_BUF_DEPTH);
- val1 = ((samples[0] + samples[1])/2);
-
- palClearPad(GPIOC, 1);
- palSetPad(GPIOC, 0);
- gfxSleepMilliseconds(1);
- adcConvert(&ADCD1, &adc_y_config, samples, ADC_BUF_DEPTH);
- val2 = ((samples[0] + samples[1])/2);
-
- return ((val1+((1<<12)-val2))/4);
-}
-
-#endif /* _GINPUT_LLD_MOUSE_BOARD_H */
-/** @} */
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/ginput/touch/MCU/ginput_lld_mouse_board_olimex_stm32_lcd.h
+ * @brief GINPUT Touch low level driver source for the MCU on the example board.
+ *
+ * @defgroup Mouse Mouse
+ * @ingroup GINPUT
+ *
+ * @{
+ */
+
+#ifndef _GINPUT_LLD_MOUSE_BOARD_H
+#define _GINPUT_LLD_MOUSE_BOARD_H
+
+#define ADC_NUM_CHANNELS 2
+#define ADC_BUF_DEPTH 1
+
+static const ADCConversionGroup adc_y_config = {
+ FALSE,
+ ADC_NUM_CHANNELS,
+ NULL,
+ NULL,
+ 0, 0,
+ 0, 0,
+ ADC_SQR1_NUM_CH(ADC_NUM_CHANNELS),
+ 0,
+ ADC_SQR3_SQ2_N(ADC_CHANNEL_IN12) | ADC_SQR3_SQ1_N(ADC_CHANNEL_IN13)
+};
+
+static const ADCConversionGroup adc_x_config = {
+ FALSE,
+ ADC_NUM_CHANNELS,
+ NULL,
+ NULL,
+ 0, 0,
+ 0, 0,
+ ADC_SQR1_NUM_CH(ADC_NUM_CHANNELS),
+ 0,
+ ADC_SQR3_SQ2_N(ADC_CHANNEL_IN10) | ADC_SQR3_SQ1_N(ADC_CHANNEL_IN11)
+};
+
+/**
+ * @brief Initialise the board for the touch.
+ *
+ * @notapi
+ */
+static inline void init_board(void) {
+ adcStart(&ADCD1, NULL);
+}
+
+/**
+ * @brief Check whether the surface is currently touched
+ * @return TRUE if the surface is currently touched
+ *
+ * @notapi
+ */
+static inline bool_t getpin_pressed(void) {
+ palSetPadMode(GPIOC, 0, PAL_MODE_INPUT_PULLDOWN);
+ palSetPadMode(GPIOC, 1, PAL_MODE_INPUT);
+ palSetPadMode(GPIOC, 2, PAL_MODE_INPUT);
+ palSetPadMode(GPIOC, 3, PAL_MODE_OUTPUT_PUSHPULL);
+ palSetPad(GPIOC, 3);
+
+ return palReadPad(GPIOC, 0);
+}
+
+/**
+ * @brief Aquire the bus ready for readings
+ *
+ * @notapi
+ */
+static inline void aquire_bus(void) {
+
+}
+
+/**
+ * @brief Release the bus after readings
+ *
+ * @notapi
+ */
+static inline void release_bus(void) {
+
+}
+
+/**
+ * @brief Read an x value from touch controller
+ * @return The value read from the controller
+ *
+ * @notapi
+ */
+static inline uint16_t read_x_value(void) {
+ uint16_t val1, val2;
+ adcsample_t samples[ADC_NUM_CHANNELS * ADC_BUF_DEPTH];
+
+ palSetPadMode(GPIOC, 0, PAL_MODE_INPUT_ANALOG);
+ palSetPadMode(GPIOC, 1, PAL_MODE_INPUT_ANALOG);
+ palSetPadMode(GPIOC, 2, PAL_MODE_OUTPUT_PUSHPULL);
+ palSetPadMode(GPIOC, 3, PAL_MODE_OUTPUT_PUSHPULL);
+
+ palSetPad(GPIOC, 2);
+ palClearPad(GPIOC, 3);
+ gfxSleepMilliseconds(1);
+ adcConvert(&ADCD1, &adc_x_config, samples, ADC_BUF_DEPTH);
+ val1 = ((samples[0] + samples[1])/2);
+
+ palClearPad(GPIOC, 2);
+ palSetPad(GPIOC, 3);
+ gfxSleepMilliseconds(1);
+ adcConvert(&ADCD1, &adc_x_config, samples, ADC_BUF_DEPTH);
+ val2 = ((samples[0] + samples[1])/2);
+
+ return ((val1+((1<<12)-val2))/4);
+}
+
+/**
+ * @brief Read an y value from touch controller
+ * @return The value read from the controller
+ *
+ * @notapi
+ */
+static inline uint16_t read_y_value(void) {
+ uint16_t val1, val2;
+ adcsample_t samples[ADC_NUM_CHANNELS * ADC_BUF_DEPTH];
+
+ palSetPadMode(GPIOC, 2, PAL_MODE_INPUT_ANALOG);
+ palSetPadMode(GPIOC, 3, PAL_MODE_INPUT_ANALOG);
+ palSetPadMode(GPIOC, 0, PAL_MODE_OUTPUT_PUSHPULL);
+ palSetPadMode(GPIOC, 1, PAL_MODE_OUTPUT_PUSHPULL);
+
+ palSetPad(GPIOC, 1);
+ palClearPad(GPIOC, 0);
+ gfxSleepMilliseconds(1);
+ adcConvert(&ADCD1, &adc_y_config, samples, ADC_BUF_DEPTH);
+ val1 = ((samples[0] + samples[1])/2);
+
+ palClearPad(GPIOC, 1);
+ palSetPad(GPIOC, 0);
+ gfxSleepMilliseconds(1);
+ adcConvert(&ADCD1, &adc_y_config, samples, ADC_BUF_DEPTH);
+ val2 = ((samples[0] + samples[1])/2);
+
+ return ((val1+((1<<12)-val2))/4);
+}
+
+#endif /* _GINPUT_LLD_MOUSE_BOARD_H */
+/** @} */
diff --git a/drivers/ginput/touch/STMPE811/ginput_lld_mouse_board_embest_dmstf4bb.h b/boards/addons/ginput/touch/STMPE811/ginput_lld_mouse_board_embest_dmstf4bb.h
index 7246378d..a2d38d34 100644
--- a/drivers/ginput/touch/STMPE811/ginput_lld_mouse_board_embest_dmstf4bb.h
+++ b/boards/addons/ginput/touch/STMPE811/ginput_lld_mouse_board_embest_dmstf4bb.h
@@ -4,123 +4,123 @@
*
* http://ugfx.org/license.html
*/
-
-/**
- * @file drivers/ginput/touch/STMPE811/ginput_lld_mouse_board_embest_dmstf4bb.h
- * @brief GINPUT Touch low level driver source for the STMPE811 on the Embest DM-STF4BB board.
- *
- * @defgroup Mouse Mouse
- * @ingroup GINPUT
- * @{
- */
-
-#ifndef _GINPUT_LLD_MOUSE_BOARD_H
-#define _GINPUT_LLD_MOUSE_BOARD_H
-
-static const I2CConfig i2ccfg = {
- OPMODE_I2C,
- 400000,
- FAST_DUTY_CYCLE_2,
-};
-
-/**
- * @brief Initialise the board for the touch.
- *
- * @notapi
- */
-static void init_board(void)
-{
- palSetPadMode(GPIOC, 13, PAL_MODE_INPUT | PAL_STM32_PUDR_FLOATING); /* TP IRQ */
- palSetPadMode(GPIOB, 8, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN); /* SCL */
- palSetPadMode(GPIOB, 9, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN); /* SDA */
-
- i2cStart(&I2CD1, &i2ccfg);
-}
-
-/**
- * @brief Check whether an interrupt is raised
- * @return TRUE if there is an interrupt signal present
- *
- * @notapi
- */
-static inline bool_t getpin_irq(void) {
- return (!(palReadPad(GPIOC, 13)));
-}
-
-/**
- * @brief Write a value into a certain register
- *
- * @param[in] reg The register address
- * @param[in] n The amount of bytes (one or two)
- * @param[in] val The value
- *
- * @notapi
- */
-static void write_reg(uint8_t reg, uint8_t n, uint16_t val)
-{
- uint8_t txbuf[3];
-
- i2cAcquireBus(&I2CD1);
-
- txbuf[0] = reg;
-
- if (n == 1) {
- txbuf[1] = val;
- i2cMasterTransmitTimeout(&I2CD1, STMPE811_ADDR, txbuf, 2, NULL, 0, MS2ST(STMPE811_TIMEOUT));
- } else if (n == 2) {
- txbuf[1] = ((val & 0xFF00) >> 8);
- txbuf[2] = (val & 0x00FF);
- i2cMasterTransmitTimeout(&I2CD1, STMPE811_ADDR, txbuf, 3, NULL, 0, MS2ST(STMPE811_TIMEOUT));
- }
-
- i2cReleaseBus(&I2CD1);
-}
-
-/**
- * @brief Read the value of a certain register
- *
- * @param[in] reg The register address
- * @param[in] n The amount of bytes (one or two)
- *
- * @return Data read from device (one byte or two depending on n param)
- *
- * @notapi
- */
-static uint16_t read_reg(uint8_t reg, uint8_t n)
-{
- uint8_t txbuf[1], rxbuf[2];
- uint16_t ret;
-
- rxbuf[0] = 0;
- rxbuf[1] = 0;
-
- i2cAcquireBus(&I2CD1);
-
- txbuf[0] = reg;
- i2cMasterTransmitTimeout(&I2CD1, STMPE811_ADDR, txbuf, 1, rxbuf, n, MS2ST(STMPE811_TIMEOUT));
-
- if (n == 1) {
- ret = rxbuf[0];
- } else if (n == 2) {
- ret = ((rxbuf[0] << 8) | (rxbuf[1] & 0xFF));
- }
-
- i2cReleaseBus(&I2CD1);
-
- return ret;
-}
-
-static void read_reg_n(uint8_t reg, uint8_t n, uint8_t *rxbuf)
-{
- uint8_t txbuf[1];
-
- i2cAcquireBus(&I2CD1);
-
- txbuf[0] = reg;
- i2cMasterTransmitTimeout(&I2CD1, STMPE811_ADDR, txbuf, 1, rxbuf, n, MS2ST(STMPE811_TIMEOUT));
-
- i2cReleaseBus(&I2CD1);
-}
-
-#endif /* _GINPUT_LLD_MOUSE_BOARD_H */
-/** @} */
+
+/**
+ * @file drivers/ginput/touch/STMPE811/ginput_lld_mouse_board_embest_dmstf4bb.h
+ * @brief GINPUT Touch low level driver source for the STMPE811 on the Embest DM-STF4BB board.
+ *
+ * @defgroup Mouse Mouse
+ * @ingroup GINPUT
+ * @{
+ */
+
+#ifndef _GINPUT_LLD_MOUSE_BOARD_H
+#define _GINPUT_LLD_MOUSE_BOARD_H
+
+static const I2CConfig i2ccfg = {
+ OPMODE_I2C,
+ 400000,
+ FAST_DUTY_CYCLE_2,
+};
+
+/**
+ * @brief Initialise the board for the touch.
+ *
+ * @notapi
+ */
+static void init_board(void)
+{
+ palSetPadMode(GPIOC, 13, PAL_MODE_INPUT | PAL_STM32_PUDR_FLOATING); /* TP IRQ */
+ palSetPadMode(GPIOB, 8, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN); /* SCL */
+ palSetPadMode(GPIOB, 9, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN); /* SDA */
+
+ i2cStart(&I2CD1, &i2ccfg);
+}
+
+/**
+ * @brief Check whether an interrupt is raised
+ * @return TRUE if there is an interrupt signal present
+ *
+ * @notapi
+ */
+static inline bool_t getpin_irq(void) {
+ return (!(palReadPad(GPIOC, 13)));
+}
+
+/**
+ * @brief Write a value into a certain register
+ *
+ * @param[in] reg The register address
+ * @param[in] n The amount of bytes (one or two)
+ * @param[in] val The value
+ *
+ * @notapi
+ */
+static void write_reg(uint8_t reg, uint8_t n, uint16_t val)
+{
+ uint8_t txbuf[3];
+
+ i2cAcquireBus(&I2CD1);
+
+ txbuf[0] = reg;
+
+ if (n == 1) {
+ txbuf[1] = val;
+ i2cMasterTransmitTimeout(&I2CD1, STMPE811_ADDR, txbuf, 2, NULL, 0, MS2ST(STMPE811_TIMEOUT));
+ } else if (n == 2) {
+ txbuf[1] = ((val & 0xFF00) >> 8);
+ txbuf[2] = (val & 0x00FF);
+ i2cMasterTransmitTimeout(&I2CD1, STMPE811_ADDR, txbuf, 3, NULL, 0, MS2ST(STMPE811_TIMEOUT));
+ }
+
+ i2cReleaseBus(&I2CD1);
+}
+
+/**
+ * @brief Read the value of a certain register
+ *
+ * @param[in] reg The register address
+ * @param[in] n The amount of bytes (one or two)
+ *
+ * @return Data read from device (one byte or two depending on n param)
+ *
+ * @notapi
+ */
+static uint16_t read_reg(uint8_t reg, uint8_t n)
+{
+ uint8_t txbuf[1], rxbuf[2];
+ uint16_t ret;
+
+ rxbuf[0] = 0;
+ rxbuf[1] = 0;
+
+ i2cAcquireBus(&I2CD1);
+
+ txbuf[0] = reg;
+ i2cMasterTransmitTimeout(&I2CD1, STMPE811_ADDR, txbuf, 1, rxbuf, n, MS2ST(STMPE811_TIMEOUT));
+
+ if (n == 1) {
+ ret = rxbuf[0];
+ } else if (n == 2) {
+ ret = ((rxbuf[0] << 8) | (rxbuf[1] & 0xFF));
+ }
+
+ i2cReleaseBus(&I2CD1);
+
+ return ret;
+}
+
+static void read_reg_n(uint8_t reg, uint8_t n, uint8_t *rxbuf)
+{
+ uint8_t txbuf[1];
+
+ i2cAcquireBus(&I2CD1);
+
+ txbuf[0] = reg;
+ i2cMasterTransmitTimeout(&I2CD1, STMPE811_ADDR, txbuf, 1, rxbuf, n, MS2ST(STMPE811_TIMEOUT));
+
+ i2cReleaseBus(&I2CD1);
+}
+
+#endif /* _GINPUT_LLD_MOUSE_BOARD_H */
+/** @} */
diff --git a/drivers/tdisp/HD44780/tdisp_lld_board_olimex_e407.h b/boards/addons/tdisp/HD44780/tdisp_lld_board_olimex_e407.h
index 7eda4e38..12407356 100644
--- a/drivers/tdisp/HD44780/tdisp_lld_board_olimex_e407.h
+++ b/boards/addons/tdisp/HD44780/tdisp_lld_board_olimex_e407.h
@@ -1,59 +1,59 @@
-/*
- * This file is subject to the terms of the GFX License. If a copy of
- * the license was not distributed with this file, you can obtain one at:
- *
- * http://ugfx.org/license.html
- */
-
-/**
- * @file drivers/tdisp/HD44780/tdisp_lld_board_olimex_e407.h
- * @brief TDISP driver subsystem board interface for the HD44780 display
- *
- * @addtogroup TDISP
- * @{
- */
-
-#ifndef _TDISP_LLD_BOARD_H
-#define _TDISP_LLD_BOARD_H
-
-/* Configure these to match the hardware connections on your board */
-#define BUS_4BITS FALSE
-#define PORT_DATA GPIOG
-#define PORT_CTRL GPIOE
-#define PIN_RS 0
-#define PIN_RW 1
-#define PIN_EN 2
-
-static void init_board(void) {
- palSetGroupMode(PORT_CTRL, PAL_WHOLE_PORT, 0, PAL_MODE_OUTPUT_PUSHPULL);
- palSetGroupMode(PORT_DATA, PAL_WHOLE_PORT, 0, PAL_MODE_OUTPUT_PUSHPULL);
- palClearPad(PORT_CTRL, PIN_RW);
-}
-
-static void writeToLCD(uint8_t data) {
- palWritePort(PORT_DATA, data);
- palSetPad(PORT_CTRL, PIN_EN);
- gfxSleepMicroseconds(1);
- palClearPad(PORT_CTRL, PIN_EN);
- gfxSleepMicroseconds(5);
-}
-
-static void write_cmd(uint8_t data) {
- palClearPad(PORT_CTRL, PIN_RS);
- #if BUS_4BITS
- writeToLCD(data>>4);
- #endif
- writeToLCD(data);
-}
-
-static void write_data(uint8_t data) {
- palSetPad(PORT_CTRL, PIN_RS);
- #if BUS_4BITS
- writeToLCD(data>>4);
- #endif
- writeToLCD(data);
-}
-
-#endif /* _TDISP_LLD_BOARD_H */
-/** @} */
-
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/tdisp/HD44780/tdisp_lld_board_olimex_e407.h
+ * @brief TDISP driver subsystem board interface for the HD44780 display
+ *
+ * @addtogroup TDISP
+ * @{
+ */
+
+#ifndef _TDISP_LLD_BOARD_H
+#define _TDISP_LLD_BOARD_H
+
+/* Configure these to match the hardware connections on your board */
+#define BUS_4BITS FALSE
+#define PORT_DATA GPIOG
+#define PORT_CTRL GPIOE
+#define PIN_RS 0
+#define PIN_RW 1
+#define PIN_EN 2
+
+static void init_board(void) {
+ palSetGroupMode(PORT_CTRL, PAL_WHOLE_PORT, 0, PAL_MODE_OUTPUT_PUSHPULL);
+ palSetGroupMode(PORT_DATA, PAL_WHOLE_PORT, 0, PAL_MODE_OUTPUT_PUSHPULL);
+ palClearPad(PORT_CTRL, PIN_RW);
+}
+
+static void writeToLCD(uint8_t data) {
+ palWritePort(PORT_DATA, data);
+ palSetPad(PORT_CTRL, PIN_EN);
+ gfxSleepMicroseconds(1);
+ palClearPad(PORT_CTRL, PIN_EN);
+ gfxSleepMicroseconds(5);
+}
+
+static void write_cmd(uint8_t data) {
+ palClearPad(PORT_CTRL, PIN_RS);
+ #if BUS_4BITS
+ writeToLCD(data>>4);
+ #endif
+ writeToLCD(data);
+}
+
+static void write_data(uint8_t data) {
+ palSetPad(PORT_CTRL, PIN_RS);
+ #if BUS_4BITS
+ writeToLCD(data>>4);
+ #endif
+ writeToLCD(data);
+}
+
+#endif /* _TDISP_LLD_BOARD_H */
+/** @} */
+
diff --git a/drivers/tdisp/HD44780/tdisp_lld_board_st_stm32f4_discovery.h b/boards/addons/tdisp/HD44780/tdisp_lld_board_st_stm32f4_discovery.h
index e9a7ae33..43e161f1 100644
--- a/drivers/tdisp/HD44780/tdisp_lld_board_st_stm32f4_discovery.h
+++ b/boards/addons/tdisp/HD44780/tdisp_lld_board_st_stm32f4_discovery.h
@@ -1,122 +1,122 @@
-/*
- * This file is subject to the terms of the GFX License. If a copy of
- * the license was not distributed with this file, you can obtain one at:
- *
- * http://ugfx.org/license.html
- */
-
-/**
- * @file drivers/tdisp/HD44780/tdisp_lld_board_st_stm32f4_discovery.h
- * @brief TDISP driver subsystem board interface for the HD44780 display
- *
- * @addtogroup TDISP
- * @{
- */
-
-#ifndef _TDISP_LLD_BOARD_H
-#define _TDISP_LLD_BOARD_H
-
-/* Configure these to match the hardware connections on your board */
-#define BUS_4BITS TRUE
-
-/* Configure the bitoffset in the dataport so they match with the
- * hardware pins. An offset of 0 means bit0 stays at bit0 of the dataport.
- * If the offset is set to 3, bit0 of the nibble will be positioned at
- * P[A..G]3 of the hardware-port.
- */
-#define hardware_offset 3
-
-/* The port where the data is sent to. In the
- * low-leveldriver het hardware_offset is taken
- * into account. If for example the hardware_offset
- * is set to 3, then de data will be sent to
- * PE3, PE4, PE5 en PE6, if the dataport where GPIOE.
- */
-#define PORT_DATA GPIOE
-
-/* The port used to controle the controle lines of
- * the display.
- */
-#define PORT_CTRL GPIOD
-/* Pin to controle the R/S-line of the display */
-#define PIN_RS 0
-/* Pin to controle the EN-line of the display */
-#define PIN_EN 1
-/* Pin to controle the R/W-pin of the display.
- * If reading of the display is not used disable
- * reading in the gfxconf.h and put a dummy value here
- * as it will not be used.
- */
-#define PIN_RW 7
-
-
-static void init_board(void) {
- /* Initialize the ports for data and controle-lines */
- palSetGroupMode(PORT_CTRL, PAL_WHOLE_PORT, 0, PAL_MODE_OUTPUT_PUSHPULL);
- palSetGroupMode(PORT_DATA, PAL_WHOLE_PORT, 0, PAL_MODE_OUTPUT_PUSHPULL);
- /* Set alle controle pins to low */
- palClearPad(PORT_CTRL, PIN_RS);
- palClearPad(PORT_CTRL, PIN_EN);
- #if TDISP_NEED_READ
- palClearPad(PORT_CTRL, PIN_RW);
- #endif
-}
-
-/* This is the low-level routine for sending the bits
- * to the LCD-display. This routine shifts
- * the bits so they match the hardware port.
- */
-static void writeToLCD(uint8_t data) {
- palWritePort(PORT_DATA, data<<hardware_offset);
- palSetPad(PORT_CTRL, PIN_EN);
- gfxSleepMicroseconds(1);
- palClearPad(PORT_CTRL, PIN_EN);
- /* wait a little while so that de display can process the data */
- gfxSleepMicroseconds(5);
-}
-
-/* Writes a command to the display. The
- * RS-line is pulled low and than the
- * data is send.
- */
-static void write_cmd(uint8_t data) {
- palClearPad(PORT_CTRL, PIN_RS);
- #if BUS_4BITS
- /* first send the high-nibble */
- writeToLCD(data>>4);
- #endif
- /* send the low-nibble */
- #if BUS_4BITS
- /* in 4-bit mode the high-nibble is zeroed out */
- writeToLCD(data & 0x0F);
- #else
- writeToLCD(data);
- #endif
-}
-
-// static void write_initcmd(uint8_t data) {
-// write_cmd(data);
-// }
-
-/* Write data to the display. The
- * RS-line is pulled high and than the
- * data is send.
- */
-static void write_data(uint8_t data) {
- palSetPad(PORT_CTRL, PIN_RS);
- #if BUS_4BITS
- /* first send the high-nibble */
- writeToLCD(data>>4);
- #endif
- /* send the low-nibble */
- #if BUS_4BITS
- /* in 4-bit mode the high-nibble is zeroed out */
- writeToLCD(data & 0x0F);
- #else
- writeToLCD(data);
- #endif
-}
-
-#endif /* _TDISP_LLD_BOARD_H */
-/** @} */
-
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/tdisp/HD44780/tdisp_lld_board_st_stm32f4_discovery.h
+ * @brief TDISP driver subsystem board interface for the HD44780 display
+ *
+ * @addtogroup TDISP
+ * @{
+ */
+
+#ifndef _TDISP_LLD_BOARD_H
+#define _TDISP_LLD_BOARD_H
+
+/* Configure these to match the hardware connections on your board */
+#define BUS_4BITS TRUE
+
+/* Configure the bitoffset in the dataport so they match with the
+ * hardware pins. An offset of 0 means bit0 stays at bit0 of the dataport.
+ * If the offset is set to 3, bit0 of the nibble will be positioned at
+ * P[A..G]3 of the hardware-port.
+ */
+#define hardware_offset 3
+
+/* The port where the data is sent to. In the
+ * low-leveldriver het hardware_offset is taken
+ * into account. If for example the hardware_offset
+ * is set to 3, then de data will be sent to
+ * PE3, PE4, PE5 en PE6, if the dataport where GPIOE.
+ */
+#define PORT_DATA GPIOE
+
+/* The port used to controle the controle lines of
+ * the display.
+ */
+#define PORT_CTRL GPIOD
+/* Pin to controle the R/S-line of the display */
+#define PIN_RS 0
+/* Pin to controle the EN-line of the display */
+#define PIN_EN 1
+/* Pin to controle the R/W-pin of the display.
+ * If reading of the display is not used disable
+ * reading in the gfxconf.h and put a dummy value here
+ * as it will not be used.
+ */
+#define PIN_RW 7
+
+
+static void init_board(void) {
+ /* Initialize the ports for data and controle-lines */
+ palSetGroupMode(PORT_CTRL, PAL_WHOLE_PORT, 0, PAL_MODE_OUTPUT_PUSHPULL);
+ palSetGroupMode(PORT_DATA, PAL_WHOLE_PORT, 0, PAL_MODE_OUTPUT_PUSHPULL);
+ /* Set alle controle pins to low */
+ palClearPad(PORT_CTRL, PIN_RS);
+ palClearPad(PORT_CTRL, PIN_EN);
+ #if TDISP_NEED_READ
+ palClearPad(PORT_CTRL, PIN_RW);
+ #endif
+}
+
+/* This is the low-level routine for sending the bits
+ * to the LCD-display. This routine shifts
+ * the bits so they match the hardware port.
+ */
+static void writeToLCD(uint8_t data) {
+ palWritePort(PORT_DATA, data<<hardware_offset);
+ palSetPad(PORT_CTRL, PIN_EN);
+ gfxSleepMicroseconds(1);
+ palClearPad(PORT_CTRL, PIN_EN);
+ /* wait a little while so that de display can process the data */
+ gfxSleepMicroseconds(5);
+}
+
+/* Writes a command to the display. The
+ * RS-line is pulled low and than the
+ * data is send.
+ */
+static void write_cmd(uint8_t data) {
+ palClearPad(PORT_CTRL, PIN_RS);
+ #if BUS_4BITS
+ /* first send the high-nibble */
+ writeToLCD(data>>4);
+ #endif
+ /* send the low-nibble */
+ #if BUS_4BITS
+ /* in 4-bit mode the high-nibble is zeroed out */
+ writeToLCD(data & 0x0F);
+ #else
+ writeToLCD(data);
+ #endif
+}
+
+// static void write_initcmd(uint8_t data) {
+// write_cmd(data);
+// }
+
+/* Write data to the display. The
+ * RS-line is pulled high and than the
+ * data is send.
+ */
+static void write_data(uint8_t data) {
+ palSetPad(PORT_CTRL, PIN_RS);
+ #if BUS_4BITS
+ /* first send the high-nibble */
+ writeToLCD(data>>4);
+ #endif
+ /* send the low-nibble */
+ #if BUS_4BITS
+ /* in 4-bit mode the high-nibble is zeroed out */
+ writeToLCD(data & 0x0F);
+ #else
+ writeToLCD(data);
+ #endif
+}
+
+#endif /* _TDISP_LLD_BOARD_H */
+/** @} */
+
diff --git a/boards/base/Linux/board.mk b/boards/base/Linux/board.mk
new file mode 100644
index 00000000..f022947f
--- /dev/null
+++ b/boards/base/Linux/board.mk
@@ -0,0 +1,4 @@
+GFXINC += $(GFXLIB)/boards/base/Linux
+GFXSRC +=
+GFXDEFS += -DGFX_USE_OS_LINUX=TRUE
+include $(GFXLIB)/drivers/multiple/X/gdisp_lld.mk
diff --git a/boards/base/Linux/example/Makefile b/boards/base/Linux/example/Makefile
new file mode 100644
index 00000000..1d59fe43
--- /dev/null
+++ b/boards/base/Linux/example/Makefile
@@ -0,0 +1,153 @@
+#
+# !!!! Do NOT edit this makefile with an editor which replace tabs by spaces !!!!
+#
+##############################################################################################
+#
+# On command line:
+#
+# make all = Create project
+#
+# make clean = Clean project files.
+#
+# To rebuild project do "make clean" and "make all".
+#
+
+##############################################################################################
+# Start of default section
+#
+
+TRGT =
+CC = $(TRGT)gcc
+AS = $(TRGT)gcc -x assembler-with-cpp
+
+# List all default C defines here, like -D_DEBUG=1
+DDEFS =
+
+# List all default ASM defines here, like -D_DEBUG=1
+DADEFS =
+
+# List all default directories to look for include files here
+DINCDIR =
+
+# List the default directory to look for the libraries here
+DLIBDIR =
+
+# List all default libraries here
+DLIBS = -lX11 -pthread -lrt
+
+#
+# End of default section
+##############################################################################################
+
+##############################################################################################
+# Start of user section
+#
+
+# Define project name here
+PROJECT = ugfx
+
+# Imported source files and paths for uGFX
+GFXLIB = ../ugfx
+include ${GFXLIB}/gfx.mk
+include ${GFXLIB}/boards/base/Linux/board.mk
+
+# Where is our source code - alter these for your project.
+MYFILES = $(GFXLIB)/demos/modules/gdisp/basics
+MYCSRC = $(MYFILES)/main.c
+MYDEFS =
+
+# List all user C define here, like -D_DEBUG=1
+UDEFS = $(MYDEFS) $(GFXDEFS)
+
+# Define ASM defines here
+UADEFS =
+
+# List C source files here
+SRC = $(GFXSRC) \
+ $(MYCSRC)
+
+# List ASM source files here
+ASRC =
+
+# List all user directories here
+UINCDIR = $(MYFILES) $(GFXINC)
+
+# List the user directory to look for the libraries here
+ULIBDIR =
+
+# List all user libraries here
+ULIBS =
+
+# Define optimisation level here
+OPT = -ggdb -O0 -fomit-frame-pointer
+
+#
+# End of user defines
+##############################################################################################
+
+INCDIR = $(patsubst %,-I%,$(DINCDIR) $(UINCDIR))
+LIBDIR = $(patsubst %,-L%,$(DLIBDIR) $(ULIBDIR))
+DEFS = $(DDEFS) $(UDEFS)
+ADEFS = $(DADEFS) $(UADEFS)
+OBJS = $(ASRC:.s=.o) $(SRC:.c=.o)
+LIBS = $(DLIBS) $(ULIBS)
+
+ASFLAGS = -Wa,-amhls=$(<:.s=.lst) $(ADEFS)
+CPFLAGS = $(OPT) -Wall -Wextra -Wstrict-prototypes -fverbose-asm $(DEFS)
+
+ifeq ($(HOST_OSX),yes)
+ ifeq ($(OSX_SDK),)
+ OSX_SDK = /Developer/SDKs/MacOSX10.7.sdk
+ endif
+ ifeq ($(OSX_ARCH),)
+ OSX_ARCH = -mmacosx-version-min=10.3 -arch i386
+ endif
+
+ CPFLAGS += -isysroot $(OSX_SDK) $(OSX_ARCH)
+ LDFLAGS = -Wl -Map=$(PROJECT).map,-syslibroot,$(OSX_SDK),$(LIBDIR)
+ LIBS += $(OSX_ARCH)
+else
+ # Linux, or other
+ CPFLAGS += -m32 -Wa,-alms=$(<:.c=.lst)
+ LDFLAGS = -m32 -Wl,-Map=$(PROJECT).map,--cref,--no-warn-mismatch $(LIBDIR)
+endif
+
+# Generate dependency information
+CPFLAGS += -MD -MP -MF .dep/$(@F).d
+
+#
+# makefile rules
+#
+
+all: $(OBJS) $(PROJECT)
+
+%.o : %.c
+ $(CC) -c $(CPFLAGS) -I . $(INCDIR) $< -o $@
+
+%.o : %.s
+ $(AS) -c $(ASFLAGS) $< -o $@
+
+$(PROJECT): $(OBJS)
+ $(CC) $(OBJS) $(LDFLAGS) $(LIBS) -o $@
+
+gcov:
+ -mkdir gcov
+ $(COV) -u $(subst /,\,$(SRC))
+ -mv *.gcov ./gcov
+
+clean:
+ -rm -f $(OBJS)
+ -rm -f $(PROJECT)
+ -rm -f $(PROJECT).map
+ -rm -f $(SRC:.c=.c.bak)
+ -rm -f $(SRC:.c=.lst)
+ -rm -f $(ASRC:.s=.s.bak)
+ -rm -f $(ASRC:.s=.lst)
+ -rm -fR .dep
+
+#
+# Include the dependency files, should be the last of the makefile
+#
+-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)
+
+# *** EOF ***
diff --git a/boards/base/Linux/example/readme.txt b/boards/base/Linux/example/readme.txt
new file mode 100644
index 00000000..aff58bb1
--- /dev/null
+++ b/boards/base/Linux/example/readme.txt
@@ -0,0 +1,5 @@
+Copy these files into your own project directory and alter them to suite.
+
+Notes:
+
+1/ Look at the MYFILES definition and the MYCSRC definition.
diff --git a/boards/base/Linux/readme.txt b/boards/base/Linux/readme.txt
new file mode 100644
index 00000000..491c91f5
--- /dev/null
+++ b/boards/base/Linux/readme.txt
@@ -0,0 +1,8 @@
+This directory contains the interface for Linux
+running either native Linux.
+
+On this board uGFX currently supports:
+ - GDISP via the X driver
+ - GINPUT-touch via the X driver
+
+There is an example Makefile and project in the examples directory.
diff --git a/boards/base/Mikromedia-STM32-M4-ILI9341/ChibiOS_Board/board.c b/boards/base/Mikromedia-STM32-M4-ILI9341/ChibiOS_Board/board.c
new file mode 100644
index 00000000..7dc6f285
--- /dev/null
+++ b/boards/base/Mikromedia-STM32-M4-ILI9341/ChibiOS_Board/board.c
@@ -0,0 +1,92 @@
+#include "ch.h"
+#include "hal.h"
+
+#if HAL_USE_PAL || defined(__DOXYGEN__)
+/**
+ * @brief PAL setup.
+ * @details Digital I/O ports static configuration as defined in @p board.h.
+ * This variable is used by the HAL when initializing the PAL driver.
+ */
+const PALConfig pal_default_config =
+{
+ {VAL_GPIOA_MODER, VAL_GPIOA_OTYPER, VAL_GPIOA_OSPEEDR, VAL_GPIOA_PUPDR,
+ VAL_GPIOA_ODR, VAL_GPIOA_AFRL, VAL_GPIOA_AFRH},
+ {VAL_GPIOB_MODER, VAL_GPIOB_OTYPER, VAL_GPIOB_OSPEEDR, VAL_GPIOB_PUPDR,
+ VAL_GPIOB_ODR, VAL_GPIOB_AFRL, VAL_GPIOB_AFRH},
+ {VAL_GPIOC_MODER, VAL_GPIOC_OTYPER, VAL_GPIOC_OSPEEDR, VAL_GPIOC_PUPDR,
+ VAL_GPIOC_ODR, VAL_GPIOC_AFRL, VAL_GPIOC_AFRH},
+ {VAL_GPIOD_MODER, VAL_GPIOD_OTYPER, VAL_GPIOD_OSPEEDR, VAL_GPIOD_PUPDR,
+ VAL_GPIOD_ODR, VAL_GPIOD_AFRL, VAL_GPIOD_AFRH},
+ {VAL_GPIOE_MODER, VAL_GPIOE_OTYPER, VAL_GPIOE_OSPEEDR, VAL_GPIOE_PUPDR,
+ VAL_GPIOE_ODR, VAL_GPIOE_AFRL, VAL_GPIOE_AFRH},
+ {VAL_GPIOF_MODER, VAL_GPIOF_OTYPER, VAL_GPIOF_OSPEEDR, VAL_GPIOF_PUPDR,
+ VAL_GPIOF_ODR, VAL_GPIOF_AFRL, VAL_GPIOF_AFRH},
+ {VAL_GPIOG_MODER, VAL_GPIOG_OTYPER, VAL_GPIOG_OSPEEDR, VAL_GPIOG_PUPDR,
+ VAL_GPIOG_ODR, VAL_GPIOG_AFRL, VAL_GPIOG_AFRH},
+ {VAL_GPIOH_MODER, VAL_GPIOH_OTYPER, VAL_GPIOH_OSPEEDR, VAL_GPIOH_PUPDR,
+ VAL_GPIOH_ODR, VAL_GPIOH_AFRL, VAL_GPIOH_AFRH},
+ {VAL_GPIOI_MODER, VAL_GPIOI_OTYPER, VAL_GPIOI_OSPEEDR, VAL_GPIOI_PUPDR,
+ VAL_GPIOI_ODR, VAL_GPIOI_AFRL, VAL_GPIOI_AFRH}
+};
+#endif
+
+/**
+ * @brief Early initialization code.
+ * @details This initialization must be performed just after stack setup
+ * and before any other initialization.
+ */
+void __early_init(void) {
+
+ stm32_clock_init();
+}
+
+#if HAL_USE_SDC || defined(__DOXYGEN__)
+/**
+ * @brief SDC card detection.
+ */
+bool_t sdc_lld_is_card_inserted(SDCDriver *sdcp) {
+
+ (void)sdcp;
+ /* TODO: Fill the implementation.*/
+ return TRUE;
+}
+
+/**
+ * @brief SDC card write protection detection.
+ */
+bool_t sdc_lld_is_write_protected(SDCDriver *sdcp) {
+
+ (void)sdcp;
+ /* TODO: Fill the implementation.*/
+ return FALSE;
+}
+#endif /* HAL_USE_SDC */
+
+#if HAL_USE_MMC_SPI || defined(__DOXYGEN__)
+/**
+ * @brief MMC_SPI card detection.
+ */
+bool_t mmc_lld_is_card_inserted(MMCDriver *mmcp) {
+
+ (void)mmcp;
+ return !palReadPad(GPIOD, GPIOD_SD_CD);
+}
+
+/**
+ * @brief MMC_SPI card write protection detection.
+ */
+bool_t mmc_lld_is_write_protected(MMCDriver *mmcp) {
+
+ (void)mmcp;
+ /* Board has no write protection detection */
+ return FALSE;
+}
+#endif
+
+/**
+ * @brief Board-specific initialization code.
+ * @todo Add your board-specific code, if any.
+ */
+void boardInit(void) {
+
+}
diff --git a/boards/base/Mikromedia-STM32-M4-ILI9341/ChibiOS_Board/board.h b/boards/base/Mikromedia-STM32-M4-ILI9341/ChibiOS_Board/board.h
new file mode 100644
index 00000000..490c0307
--- /dev/null
+++ b/boards/base/Mikromedia-STM32-M4-ILI9341/ChibiOS_Board/board.h
@@ -0,0 +1,1299 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _BOARD_H_
+#define _BOARD_H_
+
+/*
+ * Setup for mikromedia STM32-M4 board.
+ */
+
+/*
+ * Board identifier.
+ */
+#define BOARD_MIKROE_MIKROMEDIA_M4
+#define BOARD_NAME "mikromedia STM32-M4"
+
+
+/*
+ * Board oscillators-related settings.
+ */
+#if !defined(STM32_LSECLK)
+#define STM32_LSECLK 32768
+#endif
+
+#if !defined(STM32_HSECLK)
+#define STM32_HSECLK 16000000
+#endif
+
+/*
+ * Board voltages.
+ * Required for performance limits calculation.
+ */
+#define STM32_VDD 330
+
+/*
+ * MCU type as defined in the ST header file stm32f4xx.h.
+ */
+#define STM32F4XX
+
+/*
+ * IO pins assignments.
+ */
+#define GPIOA_VSENSE 0
+#define GPIOA_PIN1 1
+#define GPIOA_PIN2 2
+#define GPIOA_PIN3 3
+#define GPIOA_PIN4 4
+#define GPIOA_PIN5 5
+#define GPIOA_PIN6 6
+#define GPIOA_PIN7 7
+#define GPIOA_PIN8 8
+#define GPIOA_VBUS_FS 9
+#define GPIOA_PIN10 10
+#define GPIOA_OTG_FS_DM 11
+#define GPIOA_OTG_FS_DP 12
+#define GPIOA_TMS 13
+#define GPIOA_TCK 14
+#define GPIOA_TDI 15
+
+#define GPIOB_LCD_YD 0
+#define GPIOB_LCD_XL 1
+#define GPIOB_PIN2 2
+#define GPIOB_TDO 3
+#define GPIOB_TRST 4
+#define GPIOB_PIN5 5
+#define GPIOB_SCL1 6
+#define GPIOB_SDA1 7
+#define GPIOB_DRIVEA 8
+#define GPIOB_DRIVEB 9
+#define GPIOB_SCL2 10
+#define GPIOB_SDA2 11
+#define GPIOB_PIN12 12
+#define GPIOB_SCK2 13
+#define GPIOB_MISO2 14
+#define GPIOB_MOSI2 15
+
+#define GPIOC_PIN0 0
+#define GPIOC_PIN1 1
+#define GPIOC_PIN2 2
+#define GPIOC_PIN3 3
+#define GPIOC_PIN4 4
+#define GPIOC_PIN5 5
+#define GPIOC_MP3_DREQ 6
+#define GPIOC_MP3_RST 7
+#define GPIOC_MP3_CS 8
+#define GPIOC_MP3_DCS 9
+#define GPIOC_SCK3 10
+#define GPIOC_MISO3 11
+#define GPIOC_MOSI3 12
+#define GPIOC_STAT 13
+#define GPIOC_PIN14 14
+#define GPIOC_PIN15 15
+
+#define GPIOD_PIN0 0
+#define GPIOD_PIN1 1
+#define GPIOD_PIN2 2
+#define GPIOD_SD_CS 3
+#define GPIOD_PIN4 4
+#define GPIOD_TX2 5
+#define GPIOD_RX2 6
+#define GPIOD_FLASH_CS 7
+#define GPIOD_PIN8 8
+#define GPIOD_PIN9 9
+#define GPIOD_PIN10 10
+#define GPIOD_PIN11 11
+#define GPIOD_PIN12 12
+#define GPIOD_PIN13 13
+#define GPIOD_PIN14 14
+#define GPIOD_SD_CD 15
+
+#define GPIOE_TD0 0
+#define GPIOE_TD1 1
+#define GPIOE_TD2 2
+#define GPIOE_TD3 3
+#define GPIOE_TD4 4
+#define GPIOE_TD5 5
+#define GPIOE_TD6 6
+#define GPIOE_TD7 7
+#define GPIOE_LCD_RST 8
+#define GPIOE_LCD_BLED 9
+#define GPIOE_PMRD 10
+#define GPIOE_PMWR 11
+#define GPIOE_LCD_RS 12
+#define GPIOE_PIN13 13
+#define GPIOE_PIN14 14
+#define GPIOE_LCD_CS 15
+
+#define GPIOF_PIN0 0
+#define GPIOF_PIN1 1
+#define GPIOF_PIN2 2
+#define GPIOF_PIN3 3
+#define GPIOF_PIN4 4
+#define GPIOF_PIN5 5
+#define GPIOF_PIN6 6
+#define GPIOF_PIN7 7
+#define GPIOF_PIN8 8
+#define GPIOF_PIN9 9
+#define GPIOF_PIN10 10
+#define GPIOF_PIN11 11
+#define GPIOF_PIN12 12
+#define GPIOF_PIN13 13
+#define GPIOF_PIN14 14
+#define GPIOF_PIN15 15
+
+#define GPIOG_PIN0 0
+#define GPIOG_PIN1 1
+#define GPIOG_PIN2 2
+#define GPIOG_PIN3 3
+#define GPIOG_PIN4 4
+#define GPIOG_PIN5 5
+#define GPIOG_PIN6 6
+#define GPIOG_PIN7 7
+#define GPIOG_PIN8 8
+#define GPIOG_PIN9 9
+#define GPIOG_PIN10 10
+#define GPIOG_PIN11 11
+#define GPIOG_PIN12 12
+#define GPIOG_PIN13 13
+#define GPIOG_PIN14 14
+#define GPIOG_PIN15 15
+
+#define GPIOH_OSC_IN 0
+#define GPIOH_OSC_OUT 1
+#define GPIOH_PIN2 2
+#define GPIOH_PIN3 3
+#define GPIOH_PIN4 4
+#define GPIOH_PIN5 5
+#define GPIOH_PIN6 6
+#define GPIOH_PIN7 7
+#define GPIOH_PIN8 8
+#define GPIOH_PIN9 9
+#define GPIOH_PIN10 10
+#define GPIOH_PIN11 11
+#define GPIOH_PIN12 12
+#define GPIOH_PIN13 13
+#define GPIOH_PIN14 14
+#define GPIOH_PIN15 15
+
+#define GPIOI_PIN0 0
+#define GPIOI_PIN1 1
+#define GPIOI_PIN2 2
+#define GPIOI_PIN3 3
+#define GPIOI_PIN4 4
+#define GPIOI_PIN5 5
+#define GPIOI_PIN6 6
+#define GPIOI_PIN7 7
+#define GPIOI_PIN8 8
+#define GPIOI_PIN9 9
+#define GPIOI_PIN10 10
+#define GPIOI_PIN11 11
+#define GPIOI_PIN12 12
+#define GPIOI_PIN13 13
+#define GPIOI_PIN14 14
+#define GPIOI_PIN15 15
+
+/*
+ * I/O ports initial setup, this configuration is established soon after reset
+ * in the initialization code.
+ * Please refer to the STM32 Reference Manual for details.
+ */
+#define PIN_MODE_INPUT(n) (0U << ((n) * 2))
+#define PIN_MODE_OUTPUT(n) (1U << ((n) * 2))
+#define PIN_MODE_ALTERNATE(n) (2U << ((n) * 2))
+#define PIN_MODE_ANALOG(n) (3U << ((n) * 2))
+#define PIN_ODR_LOW(n) (0U << (n))
+#define PIN_ODR_HIGH(n) (1U << (n))
+#define PIN_OTYPE_PUSHPULL(n) (0U << (n))
+#define PIN_OTYPE_OPENDRAIN(n) (1U << (n))
+#define PIN_OSPEED_2M(n) (0U << ((n) * 2))
+#define PIN_OSPEED_25M(n) (1U << ((n) * 2))
+#define PIN_OSPEED_50M(n) (2U << ((n) * 2))
+#define PIN_OSPEED_100M(n) (3U << ((n) * 2))
+#define PIN_PUPDR_FLOATING(n) (0U << ((n) * 2))
+#define PIN_PUPDR_PULLUP(n) (1U << ((n) * 2))
+#define PIN_PUPDR_PULLDOWN(n) (2U << ((n) * 2))
+#define PIN_AFIO_AF(n, v) ((v##U) << ((n % 8) * 4))
+
+/*
+ * GPIOA setup:
+ *
+ * PA0 - VSENSE (analog).
+ * PA1 - PIN1 (input pullup).
+ * PA2 - PIN2 (input pullup).
+ * PA3 - PIN3 (input pullup).
+ * PA4 - PIN4 (alternate 6).
+ * PA5 - PIN5 (alternate 5).
+ * PA6 - PIN6 (alternate 5).
+ * PA7 - PIN7 (alternate 5).
+ * PA8 - PIN8 (input pullup).
+ * PA9 - VBUS_FS (input floating).
+ * PA10 - PIN10 (input floating).
+ * PA11 - OTG_FS_DM (alternate 10).
+ * PA12 - OTG_FS_DP (alternate 10).
+ * PA13 - TMS (alternate 0).
+ * PA14 - TCK (alternate 0).
+ * PA15 - TDI (input pullup).
+ */
+#define VAL_GPIOA_MODER (PIN_MODE_ANALOG(GPIOA_VSENSE) | \
+ PIN_MODE_INPUT(GPIOA_PIN1) | \
+ PIN_MODE_INPUT(GPIOA_PIN2) | \
+ PIN_MODE_INPUT(GPIOA_PIN3) | \
+ PIN_MODE_ALTERNATE(GPIOA_PIN4) | \
+ PIN_MODE_ALTERNATE(GPIOA_PIN5) | \
+ PIN_MODE_ALTERNATE(GPIOA_PIN6) | \
+ PIN_MODE_ALTERNATE(GPIOA_PIN7) | \
+ PIN_MODE_INPUT(GPIOA_PIN8) | \
+ PIN_MODE_INPUT(GPIOA_VBUS_FS) | \
+ PIN_MODE_INPUT(GPIOA_PIN10) | \
+ PIN_MODE_ALTERNATE(GPIOA_OTG_FS_DM) | \
+ PIN_MODE_ALTERNATE(GPIOA_OTG_FS_DP) | \
+ PIN_MODE_ALTERNATE(GPIOA_TMS) | \
+ PIN_MODE_ALTERNATE(GPIOA_TCK) | \
+ PIN_MODE_INPUT(GPIOA_TDI))
+#define VAL_GPIOA_OTYPER (PIN_OTYPE_PUSHPULL(GPIOA_VSENSE) | \
+ PIN_OTYPE_PUSHPULL(GPIOA_PIN1) | \
+ PIN_OTYPE_PUSHPULL(GPIOA_PIN2) | \
+ PIN_OTYPE_PUSHPULL(GPIOA_PIN3) | \
+ PIN_OTYPE_PUSHPULL(GPIOA_PIN4) | \
+ PIN_OTYPE_PUSHPULL(GPIOA_PIN5) | \
+ PIN_OTYPE_PUSHPULL(GPIOA_PIN6) | \
+ PIN_OTYPE_PUSHPULL(GPIOA_PIN7) | \
+ PIN_OTYPE_PUSHPULL(GPIOA_PIN8) | \
+ PIN_OTYPE_PUSHPULL(GPIOA_VBUS_FS) | \
+ PIN_OTYPE_PUSHPULL(GPIOA_PIN10) | \
+ PIN_OTYPE_PUSHPULL(GPIOA_OTG_FS_DM) | \
+ PIN_OTYPE_PUSHPULL(GPIOA_OTG_FS_DP) | \
+ PIN_OTYPE_PUSHPULL(GPIOA_TMS) | \
+ PIN_OTYPE_PUSHPULL(GPIOA_TCK) | \
+ PIN_OTYPE_PUSHPULL(GPIOA_TDI))
+#define VAL_GPIOA_OSPEEDR (PIN_OSPEED_100M(GPIOA_VSENSE) | \
+ PIN_OSPEED_100M(GPIOA_PIN1) | \
+ PIN_OSPEED_100M(GPIOA_PIN2) | \
+ PIN_OSPEED_100M(GPIOA_PIN3) | \
+ PIN_OSPEED_100M(GPIOA_PIN4) | \
+ PIN_OSPEED_50M(GPIOA_PIN5) | \
+ PIN_OSPEED_50M(GPIOA_PIN6) | \
+ PIN_OSPEED_50M(GPIOA_PIN7) | \
+ PIN_OSPEED_100M(GPIOA_PIN8) | \
+ PIN_OSPEED_100M(GPIOA_VBUS_FS) | \
+ PIN_OSPEED_100M(GPIOA_PIN10) | \
+ PIN_OSPEED_100M(GPIOA_OTG_FS_DM) | \
+ PIN_OSPEED_100M(GPIOA_OTG_FS_DP) | \
+ PIN_OSPEED_100M(GPIOA_TMS) | \
+ PIN_OSPEED_100M(GPIOA_TCK) | \
+ PIN_OSPEED_100M(GPIOA_TDI))
+#define VAL_GPIOA_PUPDR (PIN_PUPDR_FLOATING(GPIOA_VSENSE) | \
+ PIN_PUPDR_PULLUP(GPIOA_PIN1) | \
+ PIN_PUPDR_PULLUP(GPIOA_PIN2) | \
+ PIN_PUPDR_PULLUP(GPIOA_PIN3) | \
+ PIN_PUPDR_FLOATING(GPIOA_PIN4) | \
+ PIN_PUPDR_FLOATING(GPIOA_PIN5) | \
+ PIN_PUPDR_FLOATING(GPIOA_PIN6) | \
+ PIN_PUPDR_FLOATING(GPIOA_PIN7) | \
+ PIN_PUPDR_PULLUP(GPIOA_PIN8) | \
+ PIN_PUPDR_FLOATING(GPIOA_VBUS_FS) | \
+ PIN_PUPDR_FLOATING(GPIOA_PIN10) | \
+ PIN_PUPDR_FLOATING(GPIOA_OTG_FS_DM) | \
+ PIN_PUPDR_FLOATING(GPIOA_OTG_FS_DP) | \
+ PIN_PUPDR_FLOATING(GPIOA_TMS) | \
+ PIN_PUPDR_FLOATING(GPIOA_TCK) | \
+ PIN_PUPDR_PULLUP(GPIOA_TDI))
+#define VAL_GPIOA_ODR (PIN_ODR_HIGH(GPIOA_VSENSE) | \
+ PIN_ODR_HIGH(GPIOA_PIN1) | \
+ PIN_ODR_HIGH(GPIOA_PIN2) | \
+ PIN_ODR_HIGH(GPIOA_PIN3) | \
+ PIN_ODR_HIGH(GPIOA_PIN4) | \
+ PIN_ODR_HIGH(GPIOA_PIN5) | \
+ PIN_ODR_HIGH(GPIOA_PIN6) | \
+ PIN_ODR_HIGH(GPIOA_PIN7) | \
+ PIN_ODR_HIGH(GPIOA_PIN8) | \
+ PIN_ODR_HIGH(GPIOA_VBUS_FS) | \
+ PIN_ODR_HIGH(GPIOA_PIN10) | \
+ PIN_ODR_HIGH(GPIOA_OTG_FS_DM) | \
+ PIN_ODR_HIGH(GPIOA_OTG_FS_DP) | \
+ PIN_ODR_HIGH(GPIOA_TMS) | \
+ PIN_ODR_HIGH(GPIOA_TCK) | \
+ PIN_ODR_HIGH(GPIOA_TDI))
+#define VAL_GPIOA_AFRL (PIN_AFIO_AF(GPIOA_VSENSE, 0) | \
+ PIN_AFIO_AF(GPIOA_PIN1, 0) | \
+ PIN_AFIO_AF(GPIOA_PIN2, 0) | \
+ PIN_AFIO_AF(GPIOA_PIN3, 0) | \
+ PIN_AFIO_AF(GPIOA_PIN4, 6) | \
+ PIN_AFIO_AF(GPIOA_PIN5, 5) | \
+ PIN_AFIO_AF(GPIOA_PIN6, 5) | \
+ PIN_AFIO_AF(GPIOA_PIN7, 5))
+#define VAL_GPIOA_AFRH (PIN_AFIO_AF(GPIOA_PIN8, 0) | \
+ PIN_AFIO_AF(GPIOA_VBUS_FS, 0) | \
+ PIN_AFIO_AF(GPIOA_PIN10, 0) | \
+ PIN_AFIO_AF(GPIOA_OTG_FS_DM, 10) | \
+ PIN_AFIO_AF(GPIOA_OTG_FS_DP, 10) | \
+ PIN_AFIO_AF(GPIOA_TMS, 0) | \
+ PIN_AFIO_AF(GPIOA_TCK, 0) | \
+ PIN_AFIO_AF(GPIOA_TDI, 0))
+
+/*
+ * GPIOB setup:
+ *
+ * PB0 - LCD_YD (analog).
+ * PB1 - LCD_XL (analog).
+ * PB2 - PIN2 (input pullup).
+ * PB3 - TDO (alternate 0).
+ * PB4 - TRST (input pullup).
+ * PB5 - PIN5 (input pullup).
+ * PB6 - SCL1 (alternate 4).
+ * PB7 - SDA1 (input pullup).
+ * PB8 - DRIVEA (output pushpull maximum).
+ * PB9 - DRIVEB (output opendrain maximum).
+ * PB10 - SCL2 (input pullup).
+ * PB11 - SDA2 (input pullup).
+ * PB12 - PIN12 (input pullup).
+ * PB13 - SCK2 (input pullup).
+ * PB14 - MISO2 (input pullup).
+ * PB15 - MOSI2 (input pullup).
+ */
+#define VAL_GPIOB_MODER (PIN_MODE_ANALOG(GPIOB_LCD_YD) | \
+ PIN_MODE_ANALOG(GPIOB_LCD_XL) | \
+ PIN_MODE_INPUT(GPIOB_PIN2) | \
+ PIN_MODE_ALTERNATE(GPIOB_TDO) | \
+ PIN_MODE_INPUT(GPIOB_TRST) | \
+ PIN_MODE_INPUT(GPIOB_PIN5) | \
+ PIN_MODE_ALTERNATE(GPIOB_SCL1) | \
+ PIN_MODE_INPUT(GPIOB_SDA1) | \
+ PIN_MODE_OUTPUT(GPIOB_DRIVEA) | \
+ PIN_MODE_OUTPUT(GPIOB_DRIVEB) | \
+ PIN_MODE_INPUT(GPIOB_SCL2) | \
+ PIN_MODE_INPUT(GPIOB_SDA2) | \
+ PIN_MODE_INPUT(GPIOB_PIN12) | \
+ PIN_MODE_INPUT(GPIOB_SCK2) | \
+ PIN_MODE_INPUT(GPIOB_MISO2) | \
+ PIN_MODE_INPUT(GPIOB_MOSI2))
+#define VAL_GPIOB_OTYPER (PIN_OTYPE_PUSHPULL(GPIOB_LCD_YD) | \
+ PIN_OTYPE_PUSHPULL(GPIOB_LCD_XL) | \
+ PIN_OTYPE_PUSHPULL(GPIOB_PIN2) | \
+ PIN_OTYPE_PUSHPULL(GPIOB_TDO) | \
+ PIN_OTYPE_PUSHPULL(GPIOB_TRST) | \
+ PIN_OTYPE_PUSHPULL(GPIOB_PIN5) | \
+ PIN_OTYPE_OPENDRAIN(GPIOB_SCL1) | \
+ PIN_OTYPE_PUSHPULL(GPIOB_SDA1) | \
+ PIN_OTYPE_PUSHPULL(GPIOB_DRIVEA) | \
+ PIN_OTYPE_OPENDRAIN(GPIOB_DRIVEB) | \
+ PIN_OTYPE_PUSHPULL(GPIOB_SCL2) | \
+ PIN_OTYPE_PUSHPULL(GPIOB_SDA2) | \
+ PIN_OTYPE_PUSHPULL(GPIOB_PIN12) | \
+ PIN_OTYPE_PUSHPULL(GPIOB_SCK2) | \
+ PIN_OTYPE_PUSHPULL(GPIOB_MISO2) | \
+ PIN_OTYPE_PUSHPULL(GPIOB_MOSI2))
+#define VAL_GPIOB_OSPEEDR (PIN_OSPEED_100M(GPIOB_LCD_YD) | \
+ PIN_OSPEED_100M(GPIOB_LCD_XL) | \
+ PIN_OSPEED_100M(GPIOB_PIN2) | \
+ PIN_OSPEED_100M(GPIOB_TDO) | \
+ PIN_OSPEED_100M(GPIOB_TRST) | \
+ PIN_OSPEED_100M(GPIOB_PIN5) | \
+ PIN_OSPEED_100M(GPIOB_SCL1) | \
+ PIN_OSPEED_100M(GPIOB_SDA1) | \
+ PIN_OSPEED_100M(GPIOB_DRIVEA) | \
+ PIN_OSPEED_100M(GPIOB_DRIVEB) | \
+ PIN_OSPEED_100M(GPIOB_SCL2) | \
+ PIN_OSPEED_100M(GPIOB_SDA2) | \
+ PIN_OSPEED_100M(GPIOB_PIN12) | \
+ PIN_OSPEED_100M(GPIOB_SCK2) | \
+ PIN_OSPEED_100M(GPIOB_MISO2) | \
+ PIN_OSPEED_100M(GPIOB_MOSI2))
+#define VAL_GPIOB_PUPDR (PIN_PUPDR_FLOATING(GPIOB_LCD_YD) | \
+ PIN_PUPDR_FLOATING(GPIOB_LCD_XL) | \
+ PIN_PUPDR_PULLUP(GPIOB_PIN2) | \
+ PIN_PUPDR_FLOATING(GPIOB_TDO) | \
+ PIN_PUPDR_PULLUP(GPIOB_TRST) | \
+ PIN_PUPDR_PULLUP(GPIOB_PIN5) | \
+ PIN_PUPDR_FLOATING(GPIOB_SCL1) | \
+ PIN_PUPDR_PULLUP(GPIOB_SDA1) | \
+ PIN_PUPDR_FLOATING(GPIOB_DRIVEA) | \
+ PIN_PUPDR_FLOATING(GPIOB_DRIVEB) | \
+ PIN_PUPDR_PULLUP(GPIOB_SCL2) | \
+ PIN_PUPDR_PULLUP(GPIOB_SDA2) | \
+ PIN_PUPDR_PULLUP(GPIOB_PIN12) | \
+ PIN_PUPDR_PULLUP(GPIOB_SCK2) | \
+ PIN_PUPDR_PULLUP(GPIOB_MISO2) | \
+ PIN_PUPDR_PULLUP(GPIOB_MOSI2))
+#define VAL_GPIOB_ODR (PIN_ODR_HIGH(GPIOB_LCD_YD) | \
+ PIN_ODR_HIGH(GPIOB_LCD_XL) | \
+ PIN_ODR_HIGH(GPIOB_PIN2) | \
+ PIN_ODR_HIGH(GPIOB_TDO) | \
+ PIN_ODR_HIGH(GPIOB_TRST) | \
+ PIN_ODR_HIGH(GPIOB_PIN5) | \
+ PIN_ODR_HIGH(GPIOB_SCL1) | \
+ PIN_ODR_HIGH(GPIOB_SDA1) | \
+ PIN_ODR_HIGH(GPIOB_DRIVEA) | \
+ PIN_ODR_HIGH(GPIOB_DRIVEB) | \
+ PIN_ODR_HIGH(GPIOB_SCL2) | \
+ PIN_ODR_HIGH(GPIOB_SDA2) | \
+ PIN_ODR_HIGH(GPIOB_PIN12) | \
+ PIN_ODR_HIGH(GPIOB_SCK2) | \
+ PIN_ODR_HIGH(GPIOB_MISO2) | \
+ PIN_ODR_HIGH(GPIOB_MOSI2))
+#define VAL_GPIOB_AFRL (PIN_AFIO_AF(GPIOB_LCD_YD, 0) | \
+ PIN_AFIO_AF(GPIOB_LCD_XL, 0) | \
+ PIN_AFIO_AF(GPIOB_PIN2, 0) | \
+ PIN_AFIO_AF(GPIOB_TDO, 0) | \
+ PIN_AFIO_AF(GPIOB_TRST, 0) | \
+ PIN_AFIO_AF(GPIOB_PIN5, 0) | \
+ PIN_AFIO_AF(GPIOB_SCL1, 4) | \
+ PIN_AFIO_AF(GPIOB_SDA1, 4))
+#define VAL_GPIOB_AFRH (PIN_AFIO_AF(GPIOB_DRIVEA, 0) | \
+ PIN_AFIO_AF(GPIOB_DRIVEB, 0) | \
+ PIN_AFIO_AF(GPIOB_SCL2, 0) | \
+ PIN_AFIO_AF(GPIOB_SDA2, 0) | \
+ PIN_AFIO_AF(GPIOB_PIN12, 0) | \
+ PIN_AFIO_AF(GPIOB_SCK2, 0) | \
+ PIN_AFIO_AF(GPIOB_MISO2, 0) | \
+ PIN_AFIO_AF(GPIOB_MOSI2, 0))
+
+/*
+ * GPIOC setup:
+ *
+ * PC0 - PIN0 (output pushpull maximum).
+ * PC1 - PIN1 (input pullup).
+ * PC2 - PIN2 (input pullup).
+ * PC3 - PIN3 (input pullup).
+ * PC4 - PIN4 (input pullup).
+ * PC5 - PIN5 (input pullup).
+ * PC6 - MP3_DREQ (input pullup).
+ * PC7 - MP3_RST (alternate 6).
+ * PC8 - MP3_CS (output pushpull maximum).
+ * PC9 - MP3_DCS (input pullup).
+ * PC10 - SCK3 (alternate 6).
+ * PC11 - MISO3 (alternate 6).
+ * PC12 - MOSI3 (alternate 6).
+ * PC13 - STAT (input pullup).
+ * PC14 - PIN14 (input pullup).
+ * PC15 - PIN15 (input pullup).
+ */
+#define VAL_GPIOC_MODER (PIN_MODE_OUTPUT(GPIOC_PIN0) | \
+ PIN_MODE_INPUT(GPIOC_PIN1) | \
+ PIN_MODE_INPUT(GPIOC_PIN2) | \
+ PIN_MODE_INPUT(GPIOC_PIN3) | \
+ PIN_MODE_INPUT(GPIOC_PIN4) | \
+ PIN_MODE_INPUT(GPIOC_PIN5) | \
+ PIN_MODE_INPUT(GPIOC_MP3_DREQ) | \
+ PIN_MODE_ALTERNATE(GPIOC_MP3_RST) | \
+ PIN_MODE_OUTPUT(GPIOC_MP3_CS) | \
+ PIN_MODE_INPUT(GPIOC_MP3_DCS) | \
+ PIN_MODE_ALTERNATE(GPIOC_SCK3) | \
+ PIN_MODE_ALTERNATE(GPIOC_MISO3) | \
+ PIN_MODE_ALTERNATE(GPIOC_MOSI3) | \
+ PIN_MODE_INPUT(GPIOC_STAT) | \
+ PIN_MODE_INPUT(GPIOC_PIN14) | \
+ PIN_MODE_INPUT(GPIOC_PIN15))
+#define VAL_GPIOC_OTYPER (PIN_OTYPE_PUSHPULL(GPIOC_PIN0) | \
+ PIN_OTYPE_PUSHPULL(GPIOC_PIN1) | \
+ PIN_OTYPE_PUSHPULL(GPIOC_PIN2) | \
+ PIN_OTYPE_PUSHPULL(GPIOC_PIN3) | \
+ PIN_OTYPE_PUSHPULL(GPIOC_PIN4) | \
+ PIN_OTYPE_PUSHPULL(GPIOC_PIN5) | \
+ PIN_OTYPE_PUSHPULL(GPIOC_MP3_DREQ) | \
+ PIN_OTYPE_PUSHPULL(GPIOC_MP3_RST) | \
+ PIN_OTYPE_PUSHPULL(GPIOC_MP3_CS) | \
+ PIN_OTYPE_PUSHPULL(GPIOC_MP3_DCS) | \
+ PIN_OTYPE_PUSHPULL(GPIOC_SCK3) | \
+ PIN_OTYPE_PUSHPULL(GPIOC_MISO3) | \
+ PIN_OTYPE_PUSHPULL(GPIOC_MOSI3) | \
+ PIN_OTYPE_PUSHPULL(GPIOC_STAT) | \
+ PIN_OTYPE_PUSHPULL(GPIOC_PIN14) | \
+ PIN_OTYPE_PUSHPULL(GPIOC_PIN15))
+#define VAL_GPIOC_OSPEEDR (PIN_OSPEED_100M(GPIOC_PIN0) | \
+ PIN_OSPEED_100M(GPIOC_PIN1) | \
+ PIN_OSPEED_100M(GPIOC_PIN2) | \
+ PIN_OSPEED_100M(GPIOC_PIN3) | \
+ PIN_OSPEED_100M(GPIOC_PIN4) | \
+ PIN_OSPEED_100M(GPIOC_PIN5) | \
+ PIN_OSPEED_100M(GPIOC_MP3_DREQ) | \
+ PIN_OSPEED_100M(GPIOC_MP3_RST) | \
+ PIN_OSPEED_100M(GPIOC_MP3_CS) | \
+ PIN_OSPEED_100M(GPIOC_MP3_DCS) | \
+ PIN_OSPEED_100M(GPIOC_SCK3) | \
+ PIN_OSPEED_100M(GPIOC_MISO3) | \
+ PIN_OSPEED_100M(GPIOC_MOSI3) | \
+ PIN_OSPEED_100M(GPIOC_STAT) | \
+ PIN_OSPEED_100M(GPIOC_PIN14) | \
+ PIN_OSPEED_100M(GPIOC_PIN15))
+#define VAL_GPIOC_PUPDR (PIN_PUPDR_FLOATING(GPIOC_PIN0) | \
+ PIN_PUPDR_PULLUP(GPIOC_PIN1) | \
+ PIN_PUPDR_PULLUP(GPIOC_PIN2) | \
+ PIN_PUPDR_PULLUP(GPIOC_PIN3) | \
+ PIN_PUPDR_PULLUP(GPIOC_PIN4) | \
+ PIN_PUPDR_PULLUP(GPIOC_PIN5) | \
+ PIN_PUPDR_PULLUP(GPIOC_MP3_DREQ) | \
+ PIN_PUPDR_FLOATING(GPIOC_MP3_RST) | \
+ PIN_PUPDR_PULLUP(GPIOC_MP3_CS) | \
+ PIN_PUPDR_PULLUP(GPIOC_MP3_DCS) | \
+ PIN_PUPDR_FLOATING(GPIOC_SCK3) | \
+ PIN_PUPDR_FLOATING(GPIOC_MISO3) | \
+ PIN_PUPDR_FLOATING(GPIOC_MOSI3) | \
+ PIN_PUPDR_PULLUP(GPIOC_STAT) | \
+ PIN_PUPDR_PULLUP(GPIOC_PIN14) | \
+ PIN_PUPDR_PULLUP(GPIOC_PIN15))
+#define VAL_GPIOC_ODR (PIN_ODR_HIGH(GPIOC_PIN0) | \
+ PIN_ODR_HIGH(GPIOC_PIN1) | \
+ PIN_ODR_HIGH(GPIOC_PIN2) | \
+ PIN_ODR_HIGH(GPIOC_PIN3) | \
+ PIN_ODR_HIGH(GPIOC_PIN4) | \
+ PIN_ODR_HIGH(GPIOC_PIN5) | \
+ PIN_ODR_HIGH(GPIOC_MP3_DREQ) | \
+ PIN_ODR_HIGH(GPIOC_MP3_RST) | \
+ PIN_ODR_HIGH(GPIOC_MP3_CS) | \
+ PIN_ODR_HIGH(GPIOC_MP3_DCS) | \
+ PIN_ODR_HIGH(GPIOC_SCK3) | \
+ PIN_ODR_HIGH(GPIOC_MISO3) | \
+ PIN_ODR_HIGH(GPIOC_MOSI3) | \
+ PIN_ODR_HIGH(GPIOC_STAT) | \
+ PIN_ODR_HIGH(GPIOC_PIN14) | \
+ PIN_ODR_HIGH(GPIOC_PIN15))
+#define VAL_GPIOC_AFRL (PIN_AFIO_AF(GPIOC_PIN0, 0) | \
+ PIN_AFIO_AF(GPIOC_PIN1, 0) | \
+ PIN_AFIO_AF(GPIOC_PIN2, 0) | \
+ PIN_AFIO_AF(GPIOC_PIN3, 0) | \
+ PIN_AFIO_AF(GPIOC_PIN4, 0) | \
+ PIN_AFIO_AF(GPIOC_PIN5, 0) | \
+ PIN_AFIO_AF(GPIOC_MP3_DREQ, 0) | \
+ PIN_AFIO_AF(GPIOC_MP3_RST, 6))
+#define VAL_GPIOC_AFRH (PIN_AFIO_AF(GPIOC_MP3_CS, 0) | \
+ PIN_AFIO_AF(GPIOC_MP3_DCS, 0) | \
+ PIN_AFIO_AF(GPIOC_SCK3, 6) | \
+ PIN_AFIO_AF(GPIOC_MISO3, 6) | \
+ PIN_AFIO_AF(GPIOC_MOSI3, 6) | \
+ PIN_AFIO_AF(GPIOC_STAT, 0) | \
+ PIN_AFIO_AF(GPIOC_PIN14, 0) | \
+ PIN_AFIO_AF(GPIOC_PIN15, 0))
+
+/*
+ * GPIOD setup:
+ *
+ * PD0 - PIN0 (input pullup).
+ * PD1 - PIN1 (input pullup).
+ * PD2 - PIN2 (input pullup).
+ * PD3 - SD_CS (output pushpull maximum).
+ * PD4 - PIN4 (output pushpull maximum).
+ * PD5 - TX2 (alternate 7).
+ * PD6 - RX2 (alternate 7).
+ * PD7 - FLASH_CS (output pushpull maximum).
+ * PD8 - PIN8 (input pullup).
+ * PD9 - PIN9 (input pullup).
+ * PD10 - PIN10 (input pullup).
+ * PD11 - PIN11 (input pullup).
+ * PD12 - PIN12 (output pushpull maximum).
+ * PD13 - PIN13 (output pushpull maximum).
+ * PD14 - PIN14 (output pushpull maximum).
+ * PD15 - SD_CD (output pushpull maximum).
+ */
+#define VAL_GPIOD_MODER (PIN_MODE_INPUT(GPIOD_PIN0) | \
+ PIN_MODE_INPUT(GPIOD_PIN1) | \
+ PIN_MODE_INPUT(GPIOD_PIN2) | \
+ PIN_MODE_OUTPUT(GPIOD_SD_CS) | \
+ PIN_MODE_OUTPUT(GPIOD_PIN4) | \
+ PIN_MODE_ALTERNATE(GPIOD_TX2) | \
+ PIN_MODE_ALTERNATE(GPIOD_RX2) | \
+ PIN_MODE_OUTPUT(GPIOD_FLASH_CS) | \
+ PIN_MODE_INPUT(GPIOD_PIN8) | \
+ PIN_MODE_INPUT(GPIOD_PIN9) | \
+ PIN_MODE_INPUT(GPIOD_PIN10) | \
+ PIN_MODE_INPUT(GPIOD_PIN11) | \
+ PIN_MODE_OUTPUT(GPIOD_PIN12) | \
+ PIN_MODE_OUTPUT(GPIOD_PIN13) | \
+ PIN_MODE_OUTPUT(GPIOD_PIN14) | \
+ PIN_MODE_INPUT(GPIOD_SD_CD))
+#define VAL_GPIOD_OTYPER (PIN_OTYPE_PUSHPULL(GPIOD_PIN0) | \
+ PIN_OTYPE_PUSHPULL(GPIOD_PIN1) | \
+ PIN_OTYPE_PUSHPULL(GPIOD_PIN2) | \
+ PIN_OTYPE_PUSHPULL(GPIOD_SD_CS) | \
+ PIN_OTYPE_PUSHPULL(GPIOD_PIN4) | \
+ PIN_OTYPE_PUSHPULL(GPIOD_TX2) | \
+ PIN_OTYPE_PUSHPULL(GPIOD_RX2) | \
+ PIN_OTYPE_PUSHPULL(GPIOD_FLASH_CS) | \
+ PIN_OTYPE_PUSHPULL(GPIOD_PIN8) | \
+ PIN_OTYPE_PUSHPULL(GPIOD_PIN9) | \
+ PIN_OTYPE_PUSHPULL(GPIOD_PIN10) | \
+ PIN_OTYPE_PUSHPULL(GPIOD_PIN11) | \
+ PIN_OTYPE_PUSHPULL(GPIOD_PIN12) | \
+ PIN_OTYPE_PUSHPULL(GPIOD_PIN13) | \
+ PIN_OTYPE_PUSHPULL(GPIOD_PIN14) | \
+ PIN_OTYPE_PUSHPULL(GPIOD_SD_CD))
+#define VAL_GPIOD_OSPEEDR (PIN_OSPEED_100M(GPIOD_PIN0) | \
+ PIN_OSPEED_100M(GPIOD_PIN1) | \
+ PIN_OSPEED_100M(GPIOD_PIN2) | \
+ PIN_OSPEED_100M(GPIOD_SD_CS) | \
+ PIN_OSPEED_100M(GPIOD_PIN4) | \
+ PIN_OSPEED_100M(GPIOD_TX2) | \
+ PIN_OSPEED_100M(GPIOD_RX2) | \
+ PIN_OSPEED_100M(GPIOD_FLASH_CS) | \
+ PIN_OSPEED_100M(GPIOD_PIN8) | \
+ PIN_OSPEED_100M(GPIOD_PIN9) | \
+ PIN_OSPEED_100M(GPIOD_PIN10) | \
+ PIN_OSPEED_100M(GPIOD_PIN11) | \
+ PIN_OSPEED_100M(GPIOD_PIN12) | \
+ PIN_OSPEED_100M(GPIOD_PIN13) | \
+ PIN_OSPEED_100M(GPIOD_PIN14) | \
+ PIN_OSPEED_100M(GPIOD_SD_CD))
+#define VAL_GPIOD_PUPDR (PIN_PUPDR_PULLUP(GPIOD_PIN0) | \
+ PIN_PUPDR_PULLUP(GPIOD_PIN1) | \
+ PIN_PUPDR_PULLUP(GPIOD_PIN2) | \
+ PIN_PUPDR_FLOATING(GPIOD_SD_CS) | \
+ PIN_PUPDR_FLOATING(GPIOD_PIN4) | \
+ PIN_PUPDR_FLOATING(GPIOD_TX2) | \
+ PIN_PUPDR_PULLUP(GPIOD_RX2) | \
+ PIN_PUPDR_PULLUP(GPIOD_FLASH_CS) | \
+ PIN_PUPDR_PULLUP(GPIOD_PIN8) | \
+ PIN_PUPDR_PULLUP(GPIOD_PIN9) | \
+ PIN_PUPDR_PULLUP(GPIOD_PIN10) | \
+ PIN_PUPDR_PULLUP(GPIOD_PIN11) | \
+ PIN_PUPDR_FLOATING(GPIOD_PIN12) | \
+ PIN_PUPDR_FLOATING(GPIOD_PIN13) | \
+ PIN_PUPDR_FLOATING(GPIOD_PIN14) | \
+ PIN_PUPDR_PULLUP(GPIOD_SD_CD))
+#define VAL_GPIOD_ODR (PIN_ODR_HIGH(GPIOD_PIN0) | \
+ PIN_ODR_HIGH(GPIOD_PIN1) | \
+ PIN_ODR_HIGH(GPIOD_PIN2) | \
+ PIN_ODR_HIGH(GPIOD_SD_CS) | \
+ PIN_ODR_HIGH(GPIOD_PIN4) | \
+ PIN_ODR_HIGH(GPIOD_TX2) | \
+ PIN_ODR_HIGH(GPIOD_RX2) | \
+ PIN_ODR_HIGH(GPIOD_FLASH_CS) | \
+ PIN_ODR_HIGH(GPIOD_PIN8) | \
+ PIN_ODR_HIGH(GPIOD_PIN9) | \
+ PIN_ODR_HIGH(GPIOD_PIN10) | \
+ PIN_ODR_HIGH(GPIOD_PIN11) | \
+ PIN_ODR_LOW(GPIOD_PIN12) | \
+ PIN_ODR_LOW(GPIOD_PIN13) | \
+ PIN_ODR_LOW(GPIOD_PIN14) | \
+ PIN_ODR_LOW(GPIOD_SD_CD))
+#define VAL_GPIOD_AFRL (PIN_AFIO_AF(GPIOD_PIN0, 0) | \
+ PIN_AFIO_AF(GPIOD_PIN1, 0) | \
+ PIN_AFIO_AF(GPIOD_PIN2, 0) | \
+ PIN_AFIO_AF(GPIOD_SD_CS, 0) | \
+ PIN_AFIO_AF(GPIOD_PIN4, 0) | \
+ PIN_AFIO_AF(GPIOD_TX2, 7) | \
+ PIN_AFIO_AF(GPIOD_RX2, 7) | \
+ PIN_AFIO_AF(GPIOD_FLASH_CS, 0))
+#define VAL_GPIOD_AFRH (PIN_AFIO_AF(GPIOD_PIN8, 0) | \
+ PIN_AFIO_AF(GPIOD_PIN9, 0) | \
+ PIN_AFIO_AF(GPIOD_PIN10, 0) | \
+ PIN_AFIO_AF(GPIOD_PIN11, 0) | \
+ PIN_AFIO_AF(GPIOD_PIN12, 0) | \
+ PIN_AFIO_AF(GPIOD_PIN13, 0) | \
+ PIN_AFIO_AF(GPIOD_PIN14, 0) | \
+ PIN_AFIO_AF(GPIOD_SD_CD, 0))
+
+/*
+ * GPIOE setup:
+ *
+ * PE0 - TD0 (output pushpull maximum).
+ * PE1 - TD1 (output pushpull maximum).
+ * PE2 - TD2 (output pushpull maximum).
+ * PE3 - TD3 (output pushpull maximum).
+ * PE4 - TD4 (output pushpull maximum).
+ * PE5 - TD5 (output pushpull maximum).
+ * PE6 - TD6 (output pushpull maximum).
+ * PE7 - TD7 (output pushpull maximum).
+ * PE8 - LCD_RST (output pushpull maximum).
+ * PE9 - LCD_BLED (output pushpull maximum).
+ * PE10 - PMRD (output pushpull maximum).
+ * PE11 - PMWR (output pushpull maximum).
+ * PE12 - LCD_RS (output pushpull maximum).
+ * PE13 - PIN13 (input floating).
+ * PE14 - PIN14 (input floating).
+ * PE15 - LCD_CS (output pushpull maximum).
+ */
+#define VAL_GPIOE_MODER (PIN_MODE_OUTPUT(GPIOE_TD0) | \
+ PIN_MODE_OUTPUT(GPIOE_TD1) | \
+ PIN_MODE_OUTPUT(GPIOE_TD2) | \
+ PIN_MODE_OUTPUT(GPIOE_TD3) | \
+ PIN_MODE_OUTPUT(GPIOE_TD4) | \
+ PIN_MODE_OUTPUT(GPIOE_TD5) | \
+ PIN_MODE_OUTPUT(GPIOE_TD6) | \
+ PIN_MODE_OUTPUT(GPIOE_TD7) | \
+ PIN_MODE_OUTPUT(GPIOE_LCD_RST) | \
+ PIN_MODE_OUTPUT(GPIOE_LCD_BLED) | \
+ PIN_MODE_OUTPUT(GPIOE_PMRD) | \
+ PIN_MODE_OUTPUT(GPIOE_PMWR) | \
+ PIN_MODE_OUTPUT(GPIOE_LCD_RS) | \
+ PIN_MODE_INPUT(GPIOE_PIN13) | \
+ PIN_MODE_INPUT(GPIOE_PIN14) | \
+ PIN_MODE_OUTPUT(GPIOE_LCD_CS))
+#define VAL_GPIOE_OTYPER (PIN_OTYPE_PUSHPULL(GPIOE_TD0) | \
+ PIN_OTYPE_PUSHPULL(GPIOE_TD1) | \
+ PIN_OTYPE_PUSHPULL(GPIOE_TD2) | \
+ PIN_OTYPE_PUSHPULL(GPIOE_TD3) | \
+ PIN_OTYPE_PUSHPULL(GPIOE_TD4) | \
+ PIN_OTYPE_PUSHPULL(GPIOE_TD5) | \
+ PIN_OTYPE_PUSHPULL(GPIOE_TD6) | \
+ PIN_OTYPE_PUSHPULL(GPIOE_TD7) | \
+ PIN_OTYPE_PUSHPULL(GPIOE_LCD_RST) | \
+ PIN_OTYPE_PUSHPULL(GPIOE_LCD_BLED) | \
+ PIN_OTYPE_PUSHPULL(GPIOE_PMRD) | \
+ PIN_OTYPE_PUSHPULL(GPIOE_PMWR) | \
+ PIN_OTYPE_PUSHPULL(GPIOE_LCD_RS) | \
+ PIN_OTYPE_PUSHPULL(GPIOE_PIN13) | \
+ PIN_OTYPE_PUSHPULL(GPIOE_PIN14) | \
+ PIN_OTYPE_PUSHPULL(GPIOE_LCD_CS))
+#define VAL_GPIOE_OSPEEDR (PIN_OSPEED_100M(GPIOE_TD0) | \
+ PIN_OSPEED_100M(GPIOE_TD1) | \
+ PIN_OSPEED_100M(GPIOE_TD2) | \
+ PIN_OSPEED_100M(GPIOE_TD3) | \
+ PIN_OSPEED_100M(GPIOE_TD4) | \
+ PIN_OSPEED_100M(GPIOE_TD5) | \
+ PIN_OSPEED_100M(GPIOE_TD6) | \
+ PIN_OSPEED_100M(GPIOE_TD7) | \
+ PIN_OSPEED_100M(GPIOE_LCD_RST) | \
+ PIN_OSPEED_100M(GPIOE_LCD_BLED) | \
+ PIN_OSPEED_100M(GPIOE_PMRD) | \
+ PIN_OSPEED_100M(GPIOE_PMWR) | \
+ PIN_OSPEED_100M(GPIOE_LCD_RS) | \
+ PIN_OSPEED_100M(GPIOE_PIN13) | \
+ PIN_OSPEED_100M(GPIOE_PIN14) | \
+ PIN_OSPEED_100M(GPIOE_LCD_CS))
+#define VAL_GPIOE_PUPDR (PIN_PUPDR_FLOATING(GPIOE_TD0) | \
+ PIN_PUPDR_FLOATING(GPIOE_TD1) | \
+ PIN_PUPDR_FLOATING(GPIOE_TD2) | \
+ PIN_PUPDR_FLOATING(GPIOE_TD3) | \
+ PIN_PUPDR_FLOATING(GPIOE_TD4) | \
+ PIN_PUPDR_FLOATING(GPIOE_TD5) | \
+ PIN_PUPDR_FLOATING(GPIOE_TD6) | \
+ PIN_PUPDR_FLOATING(GPIOE_TD7) | \
+ PIN_PUPDR_FLOATING(GPIOE_LCD_RST) | \
+ PIN_PUPDR_FLOATING(GPIOE_LCD_BLED) | \
+ PIN_PUPDR_FLOATING(GPIOE_PMRD) | \
+ PIN_PUPDR_FLOATING(GPIOE_PMWR) | \
+ PIN_PUPDR_FLOATING(GPIOE_LCD_RS) | \
+ PIN_PUPDR_FLOATING(GPIOE_PIN13) | \
+ PIN_PUPDR_FLOATING(GPIOE_PIN14) | \
+ PIN_PUPDR_FLOATING(GPIOE_LCD_CS))
+#define VAL_GPIOE_ODR (PIN_ODR_HIGH(GPIOE_TD0) | \
+ PIN_ODR_HIGH(GPIOE_TD1) | \
+ PIN_ODR_HIGH(GPIOE_TD2) | \
+ PIN_ODR_HIGH(GPIOE_TD3) | \
+ PIN_ODR_HIGH(GPIOE_TD4) | \
+ PIN_ODR_HIGH(GPIOE_TD5) | \
+ PIN_ODR_HIGH(GPIOE_TD6) | \
+ PIN_ODR_HIGH(GPIOE_TD7) | \
+ PIN_ODR_HIGH(GPIOE_LCD_RST) | \
+ PIN_ODR_LOW(GPIOE_LCD_BLED) | \
+ PIN_ODR_HIGH(GPIOE_PMRD) | \
+ PIN_ODR_HIGH(GPIOE_PMWR) | \
+ PIN_ODR_HIGH(GPIOE_LCD_RS) | \
+ PIN_ODR_HIGH(GPIOE_PIN13) | \
+ PIN_ODR_HIGH(GPIOE_PIN14) | \
+ PIN_ODR_LOW(GPIOE_LCD_CS))
+#define VAL_GPIOE_AFRL (PIN_AFIO_AF(GPIOE_TD0, 0) | \
+ PIN_AFIO_AF(GPIOE_TD1, 0) | \
+ PIN_AFIO_AF(GPIOE_TD2, 0) | \
+ PIN_AFIO_AF(GPIOE_TD3, 0) | \
+ PIN_AFIO_AF(GPIOE_TD4, 0) | \
+ PIN_AFIO_AF(GPIOE_TD5, 0) | \
+ PIN_AFIO_AF(GPIOE_TD6, 0) | \
+ PIN_AFIO_AF(GPIOE_TD7, 0))
+#define VAL_GPIOE_AFRH (PIN_AFIO_AF(GPIOE_LCD_RST, 0) | \
+ PIN_AFIO_AF(GPIOE_LCD_BLED, 0) | \
+ PIN_AFIO_AF(GPIOE_PMRD, 0) | \
+ PIN_AFIO_AF(GPIOE_PMWR, 0) | \
+ PIN_AFIO_AF(GPIOE_LCD_RS, 0) | \
+ PIN_AFIO_AF(GPIOE_PIN13, 0) | \
+ PIN_AFIO_AF(GPIOE_PIN14, 0) | \
+ PIN_AFIO_AF(GPIOE_LCD_CS, 0))
+
+/*
+ * GPIOF setup:
+ *
+ * PF0 - PIN0 (input floating).
+ * PF1 - PIN1 (input floating).
+ * PF2 - PIN2 (input floating).
+ * PF3 - PIN3 (input floating).
+ * PF4 - PIN4 (input floating).
+ * PF5 - PIN5 (input floating).
+ * PF6 - PIN6 (input floating).
+ * PF7 - PIN7 (input floating).
+ * PF8 - PIN8 (input floating).
+ * PF9 - PIN9 (input floating).
+ * PF10 - PIN10 (input floating).
+ * PF11 - PIN11 (input floating).
+ * PF12 - PIN12 (input floating).
+ * PF13 - PIN13 (input floating).
+ * PF14 - PIN14 (input floating).
+ * PF15 - PIN15 (input floating).
+ */
+#define VAL_GPIOF_MODER (PIN_MODE_INPUT(GPIOF_PIN0) | \
+ PIN_MODE_INPUT(GPIOF_PIN1) | \
+ PIN_MODE_INPUT(GPIOF_PIN2) | \
+ PIN_MODE_INPUT(GPIOF_PIN3) | \
+ PIN_MODE_INPUT(GPIOF_PIN4) | \
+ PIN_MODE_INPUT(GPIOF_PIN5) | \
+ PIN_MODE_INPUT(GPIOF_PIN6) | \
+ PIN_MODE_INPUT(GPIOF_PIN7) | \
+ PIN_MODE_INPUT(GPIOF_PIN8) | \
+ PIN_MODE_INPUT(GPIOF_PIN9) | \
+ PIN_MODE_INPUT(GPIOF_PIN10) | \
+ PIN_MODE_INPUT(GPIOF_PIN11) | \
+ PIN_MODE_INPUT(GPIOF_PIN12) | \
+ PIN_MODE_INPUT(GPIOF_PIN13) | \
+ PIN_MODE_INPUT(GPIOF_PIN14) | \
+ PIN_MODE_INPUT(GPIOF_PIN15))
+#define VAL_GPIOF_OTYPER (PIN_OTYPE_PUSHPULL(GPIOF_PIN0) | \
+ PIN_OTYPE_PUSHPULL(GPIOF_PIN1) | \
+ PIN_OTYPE_PUSHPULL(GPIOF_PIN2) | \
+ PIN_OTYPE_PUSHPULL(GPIOF_PIN3) | \
+ PIN_OTYPE_PUSHPULL(GPIOF_PIN4) | \
+ PIN_OTYPE_PUSHPULL(GPIOF_PIN5) | \
+ PIN_OTYPE_PUSHPULL(GPIOF_PIN6) | \
+ PIN_OTYPE_PUSHPULL(GPIOF_PIN7) | \
+ PIN_OTYPE_PUSHPULL(GPIOF_PIN8) | \
+ PIN_OTYPE_PUSHPULL(GPIOF_PIN9) | \
+ PIN_OTYPE_PUSHPULL(GPIOF_PIN10) | \
+ PIN_OTYPE_PUSHPULL(GPIOF_PIN11) | \
+ PIN_OTYPE_PUSHPULL(GPIOF_PIN12) | \
+ PIN_OTYPE_PUSHPULL(GPIOF_PIN13) | \
+ PIN_OTYPE_PUSHPULL(GPIOF_PIN14) | \
+ PIN_OTYPE_PUSHPULL(GPIOF_PIN15))
+#define VAL_GPIOF_OSPEEDR (PIN_OSPEED_100M(GPIOF_PIN0) | \
+ PIN_OSPEED_100M(GPIOF_PIN1) | \
+ PIN_OSPEED_100M(GPIOF_PIN2) | \
+ PIN_OSPEED_100M(GPIOF_PIN3) | \
+ PIN_OSPEED_100M(GPIOF_PIN4) | \
+ PIN_OSPEED_100M(GPIOF_PIN5) | \
+ PIN_OSPEED_100M(GPIOF_PIN6) | \
+ PIN_OSPEED_100M(GPIOF_PIN7) | \
+ PIN_OSPEED_100M(GPIOF_PIN8) | \
+ PIN_OSPEED_100M(GPIOF_PIN9) | \
+ PIN_OSPEED_100M(GPIOF_PIN10) | \
+ PIN_OSPEED_100M(GPIOF_PIN11) | \
+ PIN_OSPEED_100M(GPIOF_PIN12) | \
+ PIN_OSPEED_100M(GPIOF_PIN13) | \
+ PIN_OSPEED_100M(GPIOF_PIN14) | \
+ PIN_OSPEED_100M(GPIOF_PIN15))
+#define VAL_GPIOF_PUPDR (PIN_PUPDR_FLOATING(GPIOF_PIN0) | \
+ PIN_PUPDR_FLOATING(GPIOF_PIN1) | \
+ PIN_PUPDR_FLOATING(GPIOF_PIN2) | \
+ PIN_PUPDR_FLOATING(GPIOF_PIN3) | \
+ PIN_PUPDR_FLOATING(GPIOF_PIN4) | \
+ PIN_PUPDR_FLOATING(GPIOF_PIN5) | \
+ PIN_PUPDR_FLOATING(GPIOF_PIN6) | \
+ PIN_PUPDR_FLOATING(GPIOF_PIN7) | \
+ PIN_PUPDR_FLOATING(GPIOF_PIN8) | \
+ PIN_PUPDR_FLOATING(GPIOF_PIN9) | \
+ PIN_PUPDR_FLOATING(GPIOF_PIN10) | \
+ PIN_PUPDR_FLOATING(GPIOF_PIN11) | \
+ PIN_PUPDR_FLOATING(GPIOF_PIN12) | \
+ PIN_PUPDR_FLOATING(GPIOF_PIN13) | \
+ PIN_PUPDR_FLOATING(GPIOF_PIN14) | \
+ PIN_PUPDR_FLOATING(GPIOF_PIN15))
+#define VAL_GPIOF_ODR (PIN_ODR_HIGH(GPIOF_PIN0) | \
+ PIN_ODR_HIGH(GPIOF_PIN1) | \
+ PIN_ODR_HIGH(GPIOF_PIN2) | \
+ PIN_ODR_HIGH(GPIOF_PIN3) | \
+ PIN_ODR_HIGH(GPIOF_PIN4) | \
+ PIN_ODR_HIGH(GPIOF_PIN5) | \
+ PIN_ODR_HIGH(GPIOF_PIN6) | \
+ PIN_ODR_HIGH(GPIOF_PIN7) | \
+ PIN_ODR_HIGH(GPIOF_PIN8) | \
+ PIN_ODR_HIGH(GPIOF_PIN9) | \
+ PIN_ODR_HIGH(GPIOF_PIN10) | \
+ PIN_ODR_HIGH(GPIOF_PIN11) | \
+ PIN_ODR_HIGH(GPIOF_PIN12) | \
+ PIN_ODR_HIGH(GPIOF_PIN13) | \
+ PIN_ODR_HIGH(GPIOF_PIN14) | \
+ PIN_ODR_HIGH(GPIOF_PIN15))
+#define VAL_GPIOF_AFRL (PIN_AFIO_AF(GPIOF_PIN0, 0) | \
+ PIN_AFIO_AF(GPIOF_PIN1, 0) | \
+ PIN_AFIO_AF(GPIOF_PIN2, 0) | \
+ PIN_AFIO_AF(GPIOF_PIN3, 0) | \
+ PIN_AFIO_AF(GPIOF_PIN4, 0) | \
+ PIN_AFIO_AF(GPIOF_PIN5, 0) | \
+ PIN_AFIO_AF(GPIOF_PIN6, 0) | \
+ PIN_AFIO_AF(GPIOF_PIN7, 0))
+#define VAL_GPIOF_AFRH (PIN_AFIO_AF(GPIOF_PIN8, 0) | \
+ PIN_AFIO_AF(GPIOF_PIN9, 0) | \
+ PIN_AFIO_AF(GPIOF_PIN10, 0) | \
+ PIN_AFIO_AF(GPIOF_PIN11, 0) | \
+ PIN_AFIO_AF(GPIOF_PIN12, 0) | \
+ PIN_AFIO_AF(GPIOF_PIN13, 0) | \
+ PIN_AFIO_AF(GPIOF_PIN14, 0) | \
+ PIN_AFIO_AF(GPIOF_PIN15, 0))
+
+/*
+ * GPIOG setup:
+ *
+ * PG0 - PIN0 (input floating).
+ * PG1 - PIN1 (input floating).
+ * PG2 - PIN2 (input floating).
+ * PG3 - PIN3 (input floating).
+ * PG4 - PIN4 (input floating).
+ * PG5 - PIN5 (input floating).
+ * PG6 - PIN6 (input floating).
+ * PG7 - PIN7 (input floating).
+ * PG8 - PIN8 (input floating).
+ * PG9 - PIN9 (input floating).
+ * PG10 - PIN10 (input floating).
+ * PG11 - PIN11 (input floating).
+ * PG12 - PIN12 (input floating).
+ * PG13 - PIN13 (input floating).
+ * PG14 - PIN14 (input floating).
+ * PG15 - PIN15 (input floating).
+ */
+#define VAL_GPIOG_MODER (PIN_MODE_INPUT(GPIOG_PIN0) | \
+ PIN_MODE_INPUT(GPIOG_PIN1) | \
+ PIN_MODE_INPUT(GPIOG_PIN2) | \
+ PIN_MODE_INPUT(GPIOG_PIN3) | \
+ PIN_MODE_INPUT(GPIOG_PIN4) | \
+ PIN_MODE_INPUT(GPIOG_PIN5) | \
+ PIN_MODE_INPUT(GPIOG_PIN6) | \
+ PIN_MODE_INPUT(GPIOG_PIN7) | \
+ PIN_MODE_INPUT(GPIOG_PIN8) | \
+ PIN_MODE_INPUT(GPIOG_PIN9) | \
+ PIN_MODE_INPUT(GPIOG_PIN10) | \
+ PIN_MODE_INPUT(GPIOG_PIN11) | \
+ PIN_MODE_INPUT(GPIOG_PIN12) | \
+ PIN_MODE_INPUT(GPIOG_PIN13) | \
+ PIN_MODE_INPUT(GPIOG_PIN14) | \
+ PIN_MODE_INPUT(GPIOG_PIN15))
+#define VAL_GPIOG_OTYPER (PIN_OTYPE_PUSHPULL(GPIOG_PIN0) | \
+ PIN_OTYPE_PUSHPULL(GPIOG_PIN1) | \
+ PIN_OTYPE_PUSHPULL(GPIOG_PIN2) | \
+ PIN_OTYPE_PUSHPULL(GPIOG_PIN3) | \
+ PIN_OTYPE_PUSHPULL(GPIOG_PIN4) | \
+ PIN_OTYPE_PUSHPULL(GPIOG_PIN5) | \
+ PIN_OTYPE_PUSHPULL(GPIOG_PIN6) | \
+ PIN_OTYPE_PUSHPULL(GPIOG_PIN7) | \
+ PIN_OTYPE_PUSHPULL(GPIOG_PIN8) | \
+ PIN_OTYPE_PUSHPULL(GPIOG_PIN9) | \
+ PIN_OTYPE_PUSHPULL(GPIOG_PIN10) | \
+ PIN_OTYPE_PUSHPULL(GPIOG_PIN11) | \
+ PIN_OTYPE_PUSHPULL(GPIOG_PIN12) | \
+ PIN_OTYPE_PUSHPULL(GPIOG_PIN13) | \
+ PIN_OTYPE_PUSHPULL(GPIOG_PIN14) | \
+ PIN_OTYPE_PUSHPULL(GPIOG_PIN15))
+#define VAL_GPIOG_OSPEEDR (PIN_OSPEED_100M(GPIOG_PIN0) | \
+ PIN_OSPEED_100M(GPIOG_PIN1) | \
+ PIN_OSPEED_100M(GPIOG_PIN2) | \
+ PIN_OSPEED_100M(GPIOG_PIN3) | \
+ PIN_OSPEED_100M(GPIOG_PIN4) | \
+ PIN_OSPEED_100M(GPIOG_PIN5) | \
+ PIN_OSPEED_100M(GPIOG_PIN6) | \
+ PIN_OSPEED_100M(GPIOG_PIN7) | \
+ PIN_OSPEED_100M(GPIOG_PIN8) | \
+ PIN_OSPEED_100M(GPIOG_PIN9) | \
+ PIN_OSPEED_100M(GPIOG_PIN10) | \
+ PIN_OSPEED_100M(GPIOG_PIN11) | \
+ PIN_OSPEED_100M(GPIOG_PIN12) | \
+ PIN_OSPEED_100M(GPIOG_PIN13) | \
+ PIN_OSPEED_100M(GPIOG_PIN14) | \
+ PIN_OSPEED_100M(GPIOG_PIN15))
+#define VAL_GPIOG_PUPDR (PIN_PUPDR_FLOATING(GPIOG_PIN0) | \
+ PIN_PUPDR_FLOATING(GPIOG_PIN1) | \
+ PIN_PUPDR_FLOATING(GPIOG_PIN2) | \
+ PIN_PUPDR_FLOATING(GPIOG_PIN3) | \
+ PIN_PUPDR_FLOATING(GPIOG_PIN4) | \
+ PIN_PUPDR_FLOATING(GPIOG_PIN5) | \
+ PIN_PUPDR_FLOATING(GPIOG_PIN6) | \
+ PIN_PUPDR_FLOATING(GPIOG_PIN7) | \
+ PIN_PUPDR_FLOATING(GPIOG_PIN8) | \
+ PIN_PUPDR_FLOATING(GPIOG_PIN9) | \
+ PIN_PUPDR_FLOATING(GPIOG_PIN10) | \
+ PIN_PUPDR_FLOATING(GPIOG_PIN11) | \
+ PIN_PUPDR_FLOATING(GPIOG_PIN12) | \
+ PIN_PUPDR_FLOATING(GPIOG_PIN13) | \
+ PIN_PUPDR_FLOATING(GPIOG_PIN14) | \
+ PIN_PUPDR_FLOATING(GPIOG_PIN15))
+#define VAL_GPIOG_ODR (PIN_ODR_HIGH(GPIOG_PIN0) | \
+ PIN_ODR_HIGH(GPIOG_PIN1) | \
+ PIN_ODR_HIGH(GPIOG_PIN2) | \
+ PIN_ODR_HIGH(GPIOG_PIN3) | \
+ PIN_ODR_HIGH(GPIOG_PIN4) | \
+ PIN_ODR_HIGH(GPIOG_PIN5) | \
+ PIN_ODR_HIGH(GPIOG_PIN6) | \
+ PIN_ODR_HIGH(GPIOG_PIN7) | \
+ PIN_ODR_HIGH(GPIOG_PIN8) | \
+ PIN_ODR_HIGH(GPIOG_PIN9) | \
+ PIN_ODR_HIGH(GPIOG_PIN10) | \
+ PIN_ODR_HIGH(GPIOG_PIN11) | \
+ PIN_ODR_HIGH(GPIOG_PIN12) | \
+ PIN_ODR_HIGH(GPIOG_PIN13) | \
+ PIN_ODR_HIGH(GPIOG_PIN14) | \
+ PIN_ODR_HIGH(GPIOG_PIN15))
+#define VAL_GPIOG_AFRL (PIN_AFIO_AF(GPIOG_PIN0, 0) | \
+ PIN_AFIO_AF(GPIOG_PIN1, 0) | \
+ PIN_AFIO_AF(GPIOG_PIN2, 0) | \
+ PIN_AFIO_AF(GPIOG_PIN3, 0) | \
+ PIN_AFIO_AF(GPIOG_PIN4, 0) | \
+ PIN_AFIO_AF(GPIOG_PIN5, 0) | \
+ PIN_AFIO_AF(GPIOG_PIN6, 0) | \
+ PIN_AFIO_AF(GPIOG_PIN7, 0))
+#define VAL_GPIOG_AFRH (PIN_AFIO_AF(GPIOG_PIN8, 0) | \
+ PIN_AFIO_AF(GPIOG_PIN9, 0) | \
+ PIN_AFIO_AF(GPIOG_PIN10, 0) | \
+ PIN_AFIO_AF(GPIOG_PIN11, 0) | \
+ PIN_AFIO_AF(GPIOG_PIN12, 0) | \
+ PIN_AFIO_AF(GPIOG_PIN13, 0) | \
+ PIN_AFIO_AF(GPIOG_PIN14, 0) | \
+ PIN_AFIO_AF(GPIOG_PIN15, 0))
+
+/*
+ * GPIOH setup:
+ *
+ * PH0 - OSC_IN (input floating).
+ * PH1 - OSC_OUT (input floating).
+ * PH2 - PIN2 (input floating).
+ * PH3 - PIN3 (input floating).
+ * PH4 - PIN4 (input floating).
+ * PH5 - PIN5 (input floating).
+ * PH6 - PIN6 (input floating).
+ * PH7 - PIN7 (input floating).
+ * PH8 - PIN8 (input floating).
+ * PH9 - PIN9 (input floating).
+ * PH10 - PIN10 (input floating).
+ * PH11 - PIN11 (input floating).
+ * PH12 - PIN12 (input floating).
+ * PH13 - PIN13 (input floating).
+ * PH14 - PIN14 (input floating).
+ * PH15 - PIN15 (input floating).
+ */
+#define VAL_GPIOH_MODER (PIN_MODE_INPUT(GPIOH_OSC_IN) | \
+ PIN_MODE_INPUT(GPIOH_OSC_OUT) | \
+ PIN_MODE_INPUT(GPIOH_PIN2) | \
+ PIN_MODE_INPUT(GPIOH_PIN3) | \
+ PIN_MODE_INPUT(GPIOH_PIN4) | \
+ PIN_MODE_INPUT(GPIOH_PIN5) | \
+ PIN_MODE_INPUT(GPIOH_PIN6) | \
+ PIN_MODE_INPUT(GPIOH_PIN7) | \
+ PIN_MODE_INPUT(GPIOH_PIN8) | \
+ PIN_MODE_INPUT(GPIOH_PIN9) | \
+ PIN_MODE_INPUT(GPIOH_PIN10) | \
+ PIN_MODE_INPUT(GPIOH_PIN11) | \
+ PIN_MODE_INPUT(GPIOH_PIN12) | \
+ PIN_MODE_INPUT(GPIOH_PIN13) | \
+ PIN_MODE_INPUT(GPIOH_PIN14) | \
+ PIN_MODE_INPUT(GPIOH_PIN15))
+#define VAL_GPIOH_OTYPER (PIN_OTYPE_PUSHPULL(GPIOH_OSC_IN) | \
+ PIN_OTYPE_PUSHPULL(GPIOH_OSC_OUT) | \
+ PIN_OTYPE_PUSHPULL(GPIOH_PIN2) | \
+ PIN_OTYPE_PUSHPULL(GPIOH_PIN3) | \
+ PIN_OTYPE_PUSHPULL(GPIOH_PIN4) | \
+ PIN_OTYPE_PUSHPULL(GPIOH_PIN5) | \
+ PIN_OTYPE_PUSHPULL(GPIOH_PIN6) | \
+ PIN_OTYPE_PUSHPULL(GPIOH_PIN7) | \
+ PIN_OTYPE_PUSHPULL(GPIOH_PIN8) | \
+ PIN_OTYPE_PUSHPULL(GPIOH_PIN9) | \
+ PIN_OTYPE_PUSHPULL(GPIOH_PIN10) | \
+ PIN_OTYPE_PUSHPULL(GPIOH_PIN11) | \
+ PIN_OTYPE_PUSHPULL(GPIOH_PIN12) | \
+ PIN_OTYPE_PUSHPULL(GPIOH_PIN13) | \
+ PIN_OTYPE_PUSHPULL(GPIOH_PIN14) | \
+ PIN_OTYPE_PUSHPULL(GPIOH_PIN15))
+#define VAL_GPIOH_OSPEEDR (PIN_OSPEED_100M(GPIOH_OSC_IN) | \
+ PIN_OSPEED_100M(GPIOH_OSC_OUT) | \
+ PIN_OSPEED_100M(GPIOH_PIN2) | \
+ PIN_OSPEED_100M(GPIOH_PIN3) | \
+ PIN_OSPEED_100M(GPIOH_PIN4) | \
+ PIN_OSPEED_100M(GPIOH_PIN5) | \
+ PIN_OSPEED_100M(GPIOH_PIN6) | \
+ PIN_OSPEED_100M(GPIOH_PIN7) | \
+ PIN_OSPEED_100M(GPIOH_PIN8) | \
+ PIN_OSPEED_100M(GPIOH_PIN9) | \
+ PIN_OSPEED_100M(GPIOH_PIN10) | \
+ PIN_OSPEED_100M(GPIOH_PIN11) | \
+ PIN_OSPEED_100M(GPIOH_PIN12) | \
+ PIN_OSPEED_100M(GPIOH_PIN13) | \
+ PIN_OSPEED_100M(GPIOH_PIN14) | \
+ PIN_OSPEED_100M(GPIOH_PIN15))
+#define VAL_GPIOH_PUPDR (PIN_PUPDR_FLOATING(GPIOH_OSC_IN) | \
+ PIN_PUPDR_FLOATING(GPIOH_OSC_OUT) | \
+ PIN_PUPDR_FLOATING(GPIOH_PIN2) | \
+ PIN_PUPDR_FLOATING(GPIOH_PIN3) | \
+ PIN_PUPDR_FLOATING(GPIOH_PIN4) | \
+ PIN_PUPDR_FLOATING(GPIOH_PIN5) | \
+ PIN_PUPDR_FLOATING(GPIOH_PIN6) | \
+ PIN_PUPDR_FLOATING(GPIOH_PIN7) | \
+ PIN_PUPDR_FLOATING(GPIOH_PIN8) | \
+ PIN_PUPDR_FLOATING(GPIOH_PIN9) | \
+ PIN_PUPDR_FLOATING(GPIOH_PIN10) | \
+ PIN_PUPDR_FLOATING(GPIOH_PIN11) | \
+ PIN_PUPDR_FLOATING(GPIOH_PIN12) | \
+ PIN_PUPDR_FLOATING(GPIOH_PIN13) | \
+ PIN_PUPDR_FLOATING(GPIOH_PIN14) | \
+ PIN_PUPDR_FLOATING(GPIOH_PIN15))
+#define VAL_GPIOH_ODR (PIN_ODR_HIGH(GPIOH_OSC_IN) | \
+ PIN_ODR_HIGH(GPIOH_OSC_OUT) | \
+ PIN_ODR_HIGH(GPIOH_PIN2) | \
+ PIN_ODR_HIGH(GPIOH_PIN3) | \
+ PIN_ODR_HIGH(GPIOH_PIN4) | \
+ PIN_ODR_HIGH(GPIOH_PIN5) | \
+ PIN_ODR_HIGH(GPIOH_PIN6) | \
+ PIN_ODR_HIGH(GPIOH_PIN7) | \
+ PIN_ODR_HIGH(GPIOH_PIN8) | \
+ PIN_ODR_HIGH(GPIOH_PIN9) | \
+ PIN_ODR_HIGH(GPIOH_PIN10) | \
+ PIN_ODR_HIGH(GPIOH_PIN11) | \
+ PIN_ODR_HIGH(GPIOH_PIN12) | \
+ PIN_ODR_HIGH(GPIOH_PIN13) | \
+ PIN_ODR_HIGH(GPIOH_PIN14) | \
+ PIN_ODR_HIGH(GPIOH_PIN15))
+#define VAL_GPIOH_AFRL (PIN_AFIO_AF(GPIOH_OSC_IN, 0) | \
+ PIN_AFIO_AF(GPIOH_OSC_OUT, 0) | \
+ PIN_AFIO_AF(GPIOH_PIN2, 0) | \
+ PIN_AFIO_AF(GPIOH_PIN3, 0) | \
+ PIN_AFIO_AF(GPIOH_PIN4, 0) | \
+ PIN_AFIO_AF(GPIOH_PIN5, 0) | \
+ PIN_AFIO_AF(GPIOH_PIN6, 0) | \
+ PIN_AFIO_AF(GPIOH_PIN7, 0))
+#define VAL_GPIOH_AFRH (PIN_AFIO_AF(GPIOH_PIN8, 0) | \
+ PIN_AFIO_AF(GPIOH_PIN9, 0) | \
+ PIN_AFIO_AF(GPIOH_PIN10, 0) | \
+ PIN_AFIO_AF(GPIOH_PIN11, 0) | \
+ PIN_AFIO_AF(GPIOH_PIN12, 0) | \
+ PIN_AFIO_AF(GPIOH_PIN13, 0) | \
+ PIN_AFIO_AF(GPIOH_PIN14, 0) | \
+ PIN_AFIO_AF(GPIOH_PIN15, 0))
+
+/*
+ * GPIOI setup:
+ *
+ * PI0 - PIN0 (input floating).
+ * PI1 - PIN1 (input floating).
+ * PI2 - PIN2 (input floating).
+ * PI3 - PIN3 (input floating).
+ * PI4 - PIN4 (input floating).
+ * PI5 - PIN5 (input floating).
+ * PI6 - PIN6 (input floating).
+ * PI7 - PIN7 (input floating).
+ * PI8 - PIN8 (input floating).
+ * PI9 - PIN9 (input floating).
+ * PI10 - PIN10 (input floating).
+ * PI11 - PIN11 (input floating).
+ * PI12 - PIN12 (input floating).
+ * PI13 - PIN13 (input floating).
+ * PI14 - PIN14 (input floating).
+ * PI15 - PIN15 (input floating).
+ */
+#define VAL_GPIOI_MODER (PIN_MODE_INPUT(GPIOI_PIN0) | \
+ PIN_MODE_INPUT(GPIOI_PIN1) | \
+ PIN_MODE_INPUT(GPIOI_PIN2) | \
+ PIN_MODE_INPUT(GPIOI_PIN3) | \
+ PIN_MODE_INPUT(GPIOI_PIN4) | \
+ PIN_MODE_INPUT(GPIOI_PIN5) | \
+ PIN_MODE_INPUT(GPIOI_PIN6) | \
+ PIN_MODE_INPUT(GPIOI_PIN7) | \
+ PIN_MODE_INPUT(GPIOI_PIN8) | \
+ PIN_MODE_INPUT(GPIOI_PIN9) | \
+ PIN_MODE_INPUT(GPIOI_PIN10) | \
+ PIN_MODE_INPUT(GPIOI_PIN11) | \
+ PIN_MODE_INPUT(GPIOI_PIN12) | \
+ PIN_MODE_INPUT(GPIOI_PIN13) | \
+ PIN_MODE_INPUT(GPIOI_PIN14) | \
+ PIN_MODE_INPUT(GPIOI_PIN15))
+#define VAL_GPIOI_OTYPER (PIN_OTYPE_PUSHPULL(GPIOI_PIN0) | \
+ PIN_OTYPE_PUSHPULL(GPIOI_PIN1) | \
+ PIN_OTYPE_PUSHPULL(GPIOI_PIN2) | \
+ PIN_OTYPE_PUSHPULL(GPIOI_PIN3) | \
+ PIN_OTYPE_PUSHPULL(GPIOI_PIN4) | \
+ PIN_OTYPE_PUSHPULL(GPIOI_PIN5) | \
+ PIN_OTYPE_PUSHPULL(GPIOI_PIN6) | \
+ PIN_OTYPE_PUSHPULL(GPIOI_PIN7) | \
+ PIN_OTYPE_PUSHPULL(GPIOI_PIN8) | \
+ PIN_OTYPE_PUSHPULL(GPIOI_PIN9) | \
+ PIN_OTYPE_PUSHPULL(GPIOI_PIN10) | \
+ PIN_OTYPE_PUSHPULL(GPIOI_PIN11) | \
+ PIN_OTYPE_PUSHPULL(GPIOI_PIN12) | \
+ PIN_OTYPE_PUSHPULL(GPIOI_PIN13) | \
+ PIN_OTYPE_PUSHPULL(GPIOI_PIN14) | \
+ PIN_OTYPE_PUSHPULL(GPIOI_PIN15))
+#define VAL_GPIOI_OSPEEDR (PIN_OSPEED_100M(GPIOI_PIN0) | \
+ PIN_OSPEED_100M(GPIOI_PIN1) | \
+ PIN_OSPEED_100M(GPIOI_PIN2) | \
+ PIN_OSPEED_100M(GPIOI_PIN3) | \
+ PIN_OSPEED_100M(GPIOI_PIN4) | \
+ PIN_OSPEED_100M(GPIOI_PIN5) | \
+ PIN_OSPEED_100M(GPIOI_PIN6) | \
+ PIN_OSPEED_100M(GPIOI_PIN7) | \
+ PIN_OSPEED_100M(GPIOI_PIN8) | \
+ PIN_OSPEED_100M(GPIOI_PIN9) | \
+ PIN_OSPEED_100M(GPIOI_PIN10) | \
+ PIN_OSPEED_100M(GPIOI_PIN11) | \
+ PIN_OSPEED_100M(GPIOI_PIN12) | \
+ PIN_OSPEED_100M(GPIOI_PIN13) | \
+ PIN_OSPEED_100M(GPIOI_PIN14) | \
+ PIN_OSPEED_100M(GPIOI_PIN15))
+#define VAL_GPIOI_PUPDR (PIN_PUPDR_FLOATING(GPIOI_PIN0) | \
+ PIN_PUPDR_FLOATING(GPIOI_PIN1) | \
+ PIN_PUPDR_FLOATING(GPIOI_PIN2) | \
+ PIN_PUPDR_FLOATING(GPIOI_PIN3) | \
+ PIN_PUPDR_FLOATING(GPIOI_PIN4) | \
+ PIN_PUPDR_FLOATING(GPIOI_PIN5) | \
+ PIN_PUPDR_FLOATING(GPIOI_PIN6) | \
+ PIN_PUPDR_FLOATING(GPIOI_PIN7) | \
+ PIN_PUPDR_FLOATING(GPIOI_PIN8) | \
+ PIN_PUPDR_FLOATING(GPIOI_PIN9) | \
+ PIN_PUPDR_FLOATING(GPIOI_PIN10) | \
+ PIN_PUPDR_FLOATING(GPIOI_PIN11) | \
+ PIN_PUPDR_FLOATING(GPIOI_PIN12) | \
+ PIN_PUPDR_FLOATING(GPIOI_PIN13) | \
+ PIN_PUPDR_FLOATING(GPIOI_PIN14) | \
+ PIN_PUPDR_FLOATING(GPIOI_PIN15))
+#define VAL_GPIOI_ODR (PIN_ODR_HIGH(GPIOI_PIN0) | \
+ PIN_ODR_HIGH(GPIOI_PIN1) | \
+ PIN_ODR_HIGH(GPIOI_PIN2) | \
+ PIN_ODR_HIGH(GPIOI_PIN3) | \
+ PIN_ODR_HIGH(GPIOI_PIN4) | \
+ PIN_ODR_HIGH(GPIOI_PIN5) | \
+ PIN_ODR_HIGH(GPIOI_PIN6) | \
+ PIN_ODR_HIGH(GPIOI_PIN7) | \
+ PIN_ODR_HIGH(GPIOI_PIN8) | \
+ PIN_ODR_HIGH(GPIOI_PIN9) | \
+ PIN_ODR_HIGH(GPIOI_PIN10) | \
+ PIN_ODR_HIGH(GPIOI_PIN11) | \
+ PIN_ODR_HIGH(GPIOI_PIN12) | \
+ PIN_ODR_HIGH(GPIOI_PIN13) | \
+ PIN_ODR_HIGH(GPIOI_PIN14) | \
+ PIN_ODR_HIGH(GPIOI_PIN15))
+#define VAL_GPIOI_AFRL (PIN_AFIO_AF(GPIOI_PIN0, 0) | \
+ PIN_AFIO_AF(GPIOI_PIN1, 0) | \
+ PIN_AFIO_AF(GPIOI_PIN2, 0) | \
+ PIN_AFIO_AF(GPIOI_PIN3, 0) | \
+ PIN_AFIO_AF(GPIOI_PIN4, 0) | \
+ PIN_AFIO_AF(GPIOI_PIN5, 0) | \
+ PIN_AFIO_AF(GPIOI_PIN6, 0) | \
+ PIN_AFIO_AF(GPIOI_PIN7, 0))
+#define VAL_GPIOI_AFRH (PIN_AFIO_AF(GPIOI_PIN8, 0) | \
+ PIN_AFIO_AF(GPIOI_PIN9, 0) | \
+ PIN_AFIO_AF(GPIOI_PIN10, 0) | \
+ PIN_AFIO_AF(GPIOI_PIN11, 0) | \
+ PIN_AFIO_AF(GPIOI_PIN12, 0) | \
+ PIN_AFIO_AF(GPIOI_PIN13, 0) | \
+ PIN_AFIO_AF(GPIOI_PIN14, 0) | \
+ PIN_AFIO_AF(GPIOI_PIN15, 0))
+
+
+#if !defined(_FROM_ASM_)
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void boardInit(void);
+#ifdef __cplusplus
+}
+#endif
+#endif /* _FROM_ASM_ */
+
+#endif /* _BOARD_H_ */
diff --git a/boards/base/Mikromedia-STM32-M4-ILI9341/ChibiOS_Board/board.mk b/boards/base/Mikromedia-STM32-M4-ILI9341/ChibiOS_Board/board.mk
new file mode 100644
index 00000000..d6a45638
--- /dev/null
+++ b/boards/base/Mikromedia-STM32-M4-ILI9341/ChibiOS_Board/board.mk
@@ -0,0 +1,7 @@
+# Required include directories
+BOARDINC = $(GFXLIB)/boards/base/Mikromedia-STM32-M4-ILI9341/ChibiOS_Board
+
+# List of all the board related files.
+BOARDSRC = $(BOARDINC)/board.c \
+ $(BOARDINC)/flash_memory.c
+
diff --git a/boards/base/Mikromedia-STM32-M4-ILI9341/ChibiOS_Board/board_orig.h b/boards/base/Mikromedia-STM32-M4-ILI9341/ChibiOS_Board/board_orig.h
new file mode 100644
index 00000000..e4d2c31f
--- /dev/null
+++ b/boards/base/Mikromedia-STM32-M4-ILI9341/ChibiOS_Board/board_orig.h
@@ -0,0 +1,1303 @@
+
+#ifndef _BOARD_H_
+#define _BOARD_H_
+
+/*
+ * Setup for Mikroe mikromedia STM32-M4.
+ */
+
+/*
+ * Board identifier.
+ */
+#define BOARD_MIKROMEDIA_STM32_M4
+#define BOARD_NAME "mikromedia STM32-M4"
+
+
+/*
+ * Board oscillators-related settings.
+ * NOTE: LSE not fitted.
+ */
+#if !defined(STM32_LSECLK)
+#define STM32_LSECLK 32768
+#endif
+
+#if !defined(STM32_HSECLK)
+#define STM32_HSECLK 16000000
+#endif
+
+
+/*
+ * Board voltages.
+ * Required for performance limits calculation.
+ */
+#define STM32_VDD 330
+
+/*
+ * MCU type as defined in the ST header file stm32f4xx.h.
+ */
+#define STM32F4XX
+
+/*
+ * IO pins assignments.
+ */
+#define GPIOA_VSENSE 0
+#define GPIOA_PIN1 1
+#define GPIOA_PIN2 2
+#define GPIOA_PIN3 3
+#define GPIOA_PIN4 4
+#define GPIOA_PIN5 5
+#define GPIOA_PIN6 6
+#define GPIOA_PIN7 7
+#define GPIOA_PIN8 8
+#define GPIOA_VBUS_FS 9
+#define GPIOA_PIN10 10
+#define GPIOA_OTG_FS_DM 11
+#define GPIOA_OTG_FS_DP 12
+#define GPIOA_TMS 13
+#define GPIOA_TCK 14
+#define GPIOA_TDI 15
+
+#define GPIOB_LCD_YD 0
+#define GPIOB_LCD_XL 1
+#define GPIOB_PIN2 2
+#define GPIOB_TDO 3
+#define GPIOB_TRST 4
+#define GPIOB_PIN5 5
+#define GPIOB_SCL1 6
+#define GPIOB_SDA1 7
+#define GPIOB_DRIVEA 8
+#define GPIOB_DRIVEB 9
+#define GPIOB_SCL2 10
+#define GPIOB_SDA2 11
+#define GPIOB_PIN12 12
+#define GPIOB_SCK2 13
+#define GPIOB_MISO2 14
+#define GPIOB_MOSI2 15
+
+#define GPIOC_PIN0 0
+#define GPIOC_PIN1 1
+#define GPIOC_PIN2 2
+#define GPIOC_PIN3 3
+#define GPIOC_PIN4 4
+#define GPIOC_PIN5 5
+#define GPIOC_MP3_DREQ 6
+#define GPIOC_MP3_RST 7
+#define GPIOC_MP3_CS 8
+#define GPIOC_MP3_DCS 9
+#define GPIOC_SCL3 10
+#define GPIOC_MISO3 11
+#define GPIOC_MOSI3 12
+#define GPIOC_STAT 13
+#define GPIOC_OSC32_IN 14
+#define GPIOC_OSC32_OUT 15
+
+#define GPIOD_PIN0 0
+#define GPIOD_PIN1 1
+#define GPIOD_PIN2 2
+#define GPIOD_SD_CS 3
+#define GPIOD_PIN4 4
+#define GPIOD_TX2 5
+#define GPIOD_RX2 6
+#define GPIOD_FLASH_CS 7
+#define GPIOD_PIN8 8
+#define GPIOD_PIN9 9
+#define GPIOD_PIN10 10
+#define GPIOD_PIN11 11
+#define GPIOD_PIN12 12
+#define GPIOD_PIN13 13
+#define GPIOD_PIN14 14
+#define GPIOD_SD_CD 15
+
+// DONE TO HERE
+
+#define GPIOE_TD0 0
+#define GPIOE_TD1 1
+#define GPIOE_TD2 2
+#define GPIOE_TD3 3
+#define GPIOE_TD4 4
+#define GPIOE_TD5 5
+#define GPIOE_TD6 6
+#define GPIOE_TD7 7
+#define GPIOE_LCD_RST 8
+#define GPIOE_LCD_BLED 9
+#define GPIOE_PMRD 10
+#define GPIOE_PMWR 11
+#define GPIOE_LCD_RS 12
+#define GPIOE_PIN13 13
+#define GPIOE_PIN14 14
+#define GPIOE_LCD_CS 15
+
+#define GPIOF_PIN0 0
+#define GPIOF_PIN1 1
+#define GPIOF_PIN2 2
+#define GPIOF_PIN3 3
+#define GPIOF_PIN4 4
+#define GPIOF_PIN5 5
+#define GPIOF_PIN6 6
+#define GPIOF_PIN7 7
+#define GPIOF_PIN8 8
+#define GPIOF_PIN9 9
+#define GPIOF_PIN10 10
+#define GPIOF_PIN11 11
+#define GPIOF_PIN12 12
+#define GPIOF_PIN13 13
+#define GPIOF_PIN14 14
+#define GPIOF_PIN15 15
+
+#define GPIOG_PIN0 0
+#define GPIOG_PIN1 1
+#define GPIOG_PIN2 2
+#define GPIOG_PIN3 3
+#define GPIOG_PIN4 4
+#define GPIOG_PIN5 5
+#define GPIOG_PIN6 6
+#define GPIOG_PIN7 7
+#define GPIOG_PIN8 8
+#define GPIOG_PIN9 9
+#define GPIOG_PIN10 10
+#define GPIOG_PIN11 11
+#define GPIOG_PIN12 12
+#define GPIOG_PIN13 13
+#define GPIOG_PIN14 14
+#define GPIOG_PIN15 15
+
+#define GPIOH_OSC_IN 0
+#define GPIOH_OSC_OUT 1
+#define GPIOH_PIN2 2
+#define GPIOH_PIN3 3
+#define GPIOH_PIN4 4
+#define GPIOH_PIN5 5
+#define GPIOH_PIN6 6
+#define GPIOH_PIN7 7
+#define GPIOH_PIN8 8
+#define GPIOH_PIN9 9
+#define GPIOH_PIN10 10
+#define GPIOH_PIN11 11
+#define GPIOH_PIN12 12
+#define GPIOH_PIN13 13
+#define GPIOH_PIN14 14
+#define GPIOH_PIN15 15
+
+#define GPIOI_PIN0 0
+#define GPIOI_PIN1 1
+#define GPIOI_PIN2 2
+#define GPIOI_PIN3 3
+#define GPIOI_PIN4 4
+#define GPIOI_PIN5 5
+#define GPIOI_PIN6 6
+#define GPIOI_PIN7 7
+#define GPIOI_PIN8 8
+#define GPIOI_PIN9 9
+#define GPIOI_PIN10 10
+#define GPIOI_PIN11 11
+#define GPIOI_PIN12 12
+#define GPIOI_PIN13 13
+#define GPIOI_PIN14 14
+#define GPIOI_PIN15 15
+
+/*
+ * I/O ports initial setup, this configuration is established soon after reset
+ * in the initialization code.
+ * Please refer to the STM32 Reference Manual for details.
+ */
+#define PIN_MODE_INPUT(n) (0U << ((n) * 2))
+#define PIN_MODE_OUTPUT(n) (1U << ((n) * 2))
+#define PIN_MODE_ALTERNATE(n) (2U << ((n) * 2))
+#define PIN_MODE_ANALOG(n) (3U << ((n) * 2))
+#define PIN_ODR_LOW(n) (0U << (n))
+#define PIN_ODR_HIGH(n) (1U << (n))
+#define PIN_OTYPE_PUSHPULL(n) (0U << (n))
+#define PIN_OTYPE_OPENDRAIN(n) (1U << (n))
+#define PIN_OSPEED_2M(n) (0U << ((n) * 2))
+#define PIN_OSPEED_25M(n) (1U << ((n) * 2))
+#define PIN_OSPEED_50M(n) (2U << ((n) * 2))
+#define PIN_OSPEED_100M(n) (3U << ((n) * 2))
+#define PIN_PUPDR_FLOATING(n) (0U << ((n) * 2))
+#define PIN_PUPDR_PULLUP(n) (1U << ((n) * 2))
+#define PIN_PUPDR_PULLDOWN(n) (2U << ((n) * 2))
+#define PIN_AFIO_AF(n, v) ((v##U) << ((n % 8) * 4))
+
+/*
+ * GPIOA setup:
+ *
+ * PA0 - Battery Voltage Sense (Analog)
+ * PA0 - BUTTON (input floating).
+#define GPIOA_VSENSE 0
+#define GPIOA_PIN1 1
+#define GPIOA_PIN2 2
+#define GPIOA_PIN3 3
+#define GPIOA_PIN4 4
+#define GPIOA_PIN5 5
+#define GPIOA_PIN6 6
+#define GPIOA_PIN7 7
+#define GPIOA_PIN8 8
+#define GPIOA_VBUS_FS 9
+#define GPIOA_PIN10 10
+#define GPIOA_OTG_FS_DM 11
+#define GPIOA_OTG_FS_DP 12
+#define GPIOA_TMS 13
+#define GPIOA_TCK 14
+#define GPIOA_TDI 15
+ */
+#define VAL_GPIOA_MODER (PIN_MODE_ANALOG(GPIOA_VSENSE) | \
+ PIN_MODE_INPUT(GPIOA_PIN1) | \
+ PIN_MODE_INPUT(GPIOA_PIN2) | \
+ PIN_MODE_INPUT(GPIOA_PIN3) | \
+ PIN_MODE_INPUT(GPIOA_PIN4) | \
+ PIN_MODE_INPUT(GPIOA_PIN5) | \
+ PIN_MODE_INPUT(GPIOA_PIN6) | \
+ PIN_MODE_INPUT(GPIOA_PIN7) | \
+ PIN_MODE_INPUT(GPIOA_PIN8) | \
+ PIN_MODE_INPUT(GPIOA_VBUS_FS) | \
+ PIN_MODE_INPUT(GPIOA_PIN10) | \
+ PIN_MODE_ALTERNATE(GPIOA_OTG_FS_DM) | \
+ PIN_MODE_ALTERNATE(GPIOA_OTG_FS_DP) | \
+ PIN_MODE_ALTERNATE(GPIOA_TMS) | \
+ PIN_MODE_ALTERNATE(GPIOA_TCK) | \
+ PIN_MODE_ALTERNATE(GPIOA_TDI))
+#define VAL_GPIOA_OTYPER (PIN_OTYPE_PUSHPULL(GPIOA_VSENSE) | \
+ PIN_OTYPE_PUSHPULL(GPIOA_PIN1) | \
+ PIN_OTYPE_PUSHPULL(GPIOA_PIN2) | \
+ PIN_OTYPE_PUSHPULL(GPIOA_PIN3) | \
+ PIN_OTYPE_PUSHPULL(GPIOA_PIN4) | \
+ PIN_OTYPE_PUSHPULL(GPIOA_PIN5) | \
+ PIN_OTYPE_PUSHPULL(GPIOA_PIN6) | \
+ PIN_OTYPE_PUSHPULL(GPIOA_PIN7) | \
+ PIN_OTYPE_PUSHPULL(GPIOA_PIN8) | \
+ PIN_OTYPE_PUSHPULL(GPIOA_VBUS_FS) | \
+ PIN_OTYPE_PUSHPULL(GPIOA_PIN10) | \
+ PIN_OTYPE_PUSHPULL(GPIOA_OTG_FS_DM) | \
+ PIN_OTYPE_PUSHPULL(GPIOA_OTG_FS_DP) | \
+ PIN_OTYPE_PUSHPULL(GPIOA_TMS) | \
+ PIN_OTYPE_PUSHPULL(GPIOA_TCK) | \
+ PIN_OTYPE_PUSHPULL(GPIOA_TDI))
+#define VAL_GPIOA_OSPEEDR (PIN_OSPEED_100M(GPIOA_VSENSE) | \
+ PIN_OSPEED_100M(GPIOA_PIN1) | \
+ PIN_OSPEED_100M(GPIOA_PIN2) | \
+ PIN_OSPEED_100M(GPIOA_PIN3) | \
+ PIN_OSPEED_100M(GPIOA_PIN4) | \
+ PIN_OSPEED_100M(GPIOA_PIN5) | \
+ PIN_OSPEED_100M(GPIOA_PIN6) | \
+ PIN_OSPEED_100M(GPIOA_PIN7) | \
+ PIN_OSPEED_100M(GPIOA_PIN8) | \
+ PIN_OSPEED_100M(GPIOA_VBUS_FS) | \
+ PIN_OSPEED_100M(GPIOA_PIN10) | \
+ PIN_OSPEED_100M(GPIOA_OTG_FS_DM) | \
+ PIN_OSPEED_100M(GPIOA_OTG_FS_DP) | \
+ PIN_OSPEED_100M(GPIOA_TMS) | \
+ PIN_OSPEED_100M(GPIOA_TCK) | \
+ PIN_OSPEED_100M(GPIOA_TDI))
+#define VAL_GPIOA_PUPDR (PIN_PUPDR_FLOATING(GPIOA_VSENSE) | \
+ PIN_PUPDR_PULLUP(GPIOA_PIN1) | \
+ PIN_PUPDR_PULLUP(GPIOA_PIN2) | \
+ PIN_PUPDR_PULLUP(GPIOA_PIN3) | \
+ PIN_PUPDR_PULLUP(GPIOA_PIN4) | \
+ PIN_PUPDR_PULLUP(GPIOA_PIN5) | \
+ PIN_PUPDR_PULLUP(GPIOA_PIN6) | \
+ PIN_PUPDR_PULLUP(GPIOA_PIN7) | \
+ PIN_PUPDR_PULLUP(GPIOA_PIN8) | \
+ PIN_PUPDR_FLOATING(GPIOA_VBUS_FS) | \
+ PIN_PUPDR_PULLUP(GPIOA_PIN10) | \
+ PIN_PUPDR_FLOATING(GPIOA_OTG_FS_DM) | \
+ PIN_PUPDR_FLOATING(GPIOA_OTG_FS_DP) | \
+ PIN_PUPDR_FLOATING(GPIOA_TMS) | \
+ PIN_PUPDR_FLOATING(GPIOA_TCK) | \
+ PIN_PUPDR_FLOATING(GPIOA_TDI))
+#define VAL_GPIOA_ODR (PIN_ODR_HIGH(GPIOA_VSENSE) | \
+ PIN_ODR_HIGH(GPIOA_PIN1) | \
+ PIN_ODR_HIGH(GPIOA_PIN2) | \
+ PIN_ODR_HIGH(GPIOA_PIN3) | \
+ PIN_ODR_HIGH(GPIOA_PIN4) | \
+ PIN_ODR_HIGH(GPIOA_PIN5) | \
+ PIN_ODR_HIGH(GPIOA_PIN6) | \
+ PIN_ODR_HIGH(GPIOA_PIN7) | \
+ PIN_ODR_HIGH(GPIOA_PIN8) | \
+ PIN_ODR_HIGH(GPIOA_VBUS_FS) | \
+ PIN_ODR_HIGH(GPIOA_PIN10) | \
+ PIN_ODR_HIGH(GPIOA_OTG_FS_DM) | \
+ PIN_ODR_HIGH(GPIOA_OTG_FS_DP) | \
+ PIN_ODR_HIGH(GPIOA_TMS) | \
+ PIN_ODR_HIGH(GPIOA_TCK) | \
+ PIN_ODR_HIGH(GPIOA_TDI))
+#define VAL_GPIOA_AFRL (PIN_AFIO_AF(GPIOA_VSENSE, 0) | \
+ PIN_AFIO_AF(GPIOA_PIN1, 0) | \
+ PIN_AFIO_AF(GPIOA_PIN2, 0) | \
+ PIN_AFIO_AF(GPIOA_PIN3, 0) | \
+ PIN_AFIO_AF(GPIOA_PIN4, 0) | \
+ PIN_AFIO_AF(GPIOA_PIN5, 0) | \
+ PIN_AFIO_AF(GPIOA_PIN6, 0) | \
+ PIN_AFIO_AF(GPIOA_PIN7, 0))
+#define VAL_GPIOA_AFRH (PIN_AFIO_AF(GPIOA_PIN8, 0) | \
+ PIN_AFIO_AF(GPIOA_VBUS_FS, 0) | \
+ PIN_AFIO_AF(GPIOA_PIN10, 0) | \
+ PIN_AFIO_AF(GPIOA_OTG_FS_DM, 10) | \
+ PIN_AFIO_AF(GPIOA_OTG_FS_DP, 10) | \
+ PIN_AFIO_AF(GPIOA_TMS, 0) | \
+ PIN_AFIO_AF(GPIOA_TCK, 0) | \
+ PIN_AFIO_AF(GPIOA_TDI, 0))
+// DONE TO HERE
+/*
+ * GPIOB setup:
+ *
+ * PB0 - PIN0 (input pullup).
+ * PB1 - PIN1 (input pullup).
+ * PB2 - PIN2 (input pullup).
+ * PB3 - SWO (alternate 0).
+ * PB4 - PIN4 (input pullup).
+ * PB5 - PIN5 (input pullup).
+ * PB6 - SCL (alternate 4).
+ * PB7 - PIN7 (input pullup).
+ * PB8 - PIN8 (input pullup).
+ * PB9 - SDA (alternate 4).
+ * PB10 - CLK_IN (input pullup).
+ * PB11 - PIN11 (input pullup).
+ * PB12 - PIN12 (input pullup).
+ * PB13 - PIN13 (input pullup).
+ * PB14 - PIN14 (input pullup).
+ * PB15 - PIN15 (input pullup).
+
+#define GPIOB_LCD_YD 0
+#define GPIOB_LCD_XL 1
+
+#define GPIOB_TDO 3
+#define GPIOB_TRST 4
+#define GPIOB_PIN5 5
+#define GPIOB_SCL1 6
+#define GPIOB_SDA1 7
+#define GPIOB_DRIVEA 8
+#define GPIOB_DRIVEB 9
+#define GPIOB_SCL2 10
+#define GPIOB_SDA2 11
+#define GPIOB_PIN12 12
+#define GPIOB_SCK2 13
+#define GPIOB_MISO2 14
+#define GPIOB_MOSI2 15
+ */
+#define VAL_GPIOB_MODER (PIN_MODE_INPUT(GPIOB_LCD_YD) | \
+ PIN_MODE_INPUT(GPIOB_LCD_XL) | \
+ PIN_MODE_INPUT(GPIOB_PIN2) | \
+ PIN_MODE_ALTERNATE(GPIOB_TDO) | \
+ PIN_MODE_ALTERNATE(GPIOB_TRST) | \
+ PIN_MODE_INPUT(GPIOB_PIN5) | \
+ PIN_MODE_ALTERNATE(GPIOB_SCL1) | \
+ PIN_MODE_ALTERNATE(GPIOB_SDA1) | \
+ PIN_MODE_INPUT(GPIOB_DRIVEA) | \
+ PIN_MODE_INPUT(GPIOB_DRIVEB) | \
+ PIN_MODE_ALTERNATE(GPIOB_SCL2) | \
+ PIN_MODE_ALTERNATE(GPIOB_SDA2) | \
+ PIN_MODE_INPUT(GPIOB_PIN12) | \
+ PIN_MODE_ALTERNATE(GPIOB_SCK2) | \
+ PIN_MODE_ALTERNATE(GPIOB_MISO2) | \
+ PIN_MODE_ALTERNATE(GPIOB_MOSI2))
+#define VAL_GPIOB_OTYPER (PIN_OTYPE_PUSHPULL(GPIOB_LCD_YD) | \
+ PIN_OTYPE_PUSHPULL(GPIOB_LCD_XL) | \
+ PIN_OTYPE_PUSHPULL(GPIOB_PIN2) | \
+ PIN_OTYPE_PUSHPULL(GPIOB_TDO) | \
+ PIN_OTYPE_PUSHPULL(GPIOB_TRST) | \
+ PIN_OTYPE_PUSHPULL(GPIOB_PIN5) | \
+ PIN_OTYPE_OPENDRAIN(GPIOB_SCL1) | \
+ PIN_OTYPE_OPENDRAIN(GPIOB_SDA1) | \
+ PIN_OTYPE_PUSHPULL(GPIOB_DRIVEA) | \
+ PIN_OTYPE_PUSHPULL(GPIOB_DRIVEB) | \
+ PIN_OTYPE_OPENDRAIN(GPIOB_SCL2) | \
+ PIN_OTYPE_OPENDRAIN(GPIOB_SDA2) | \
+ PIN_OTYPE_PUSHPULL(GPIOB_PIN12) | \
+ PIN_OTYPE_PUSHPULL(GPIOB_SCK2 ) | \
+ PIN_OTYPE_PUSHPULL(GPIOB_MISO2) | \
+ PIN_OTYPE_PUSHPULL(GPIOB_MOSI2))
+#define VAL_GPIOB_OSPEEDR (PIN_OSPEED_100M(GPIOB_PIN0) | \
+ PIN_OSPEED_100M(GPIOB_PIN1) | \
+ PIN_OSPEED_100M(GPIOB_PIN2) | \
+ PIN_OSPEED_100M(GPIOB_SWO) | \
+ PIN_OSPEED_100M(GPIOB_PIN4) | \
+ PIN_OSPEED_100M(GPIOB_PIN5) | \
+ PIN_OSPEED_100M(GPIOB_SCL) | \
+ PIN_OSPEED_100M(GPIOB_PIN7) | \
+ PIN_OSPEED_100M(GPIOB_PIN8) | \
+ PIN_OSPEED_100M(GPIOB_SDA) | \
+ PIN_OSPEED_100M(GPIOB_CLK_IN) | \
+ PIN_OSPEED_100M(GPIOB_PIN11) | \
+ PIN_OSPEED_100M(GPIOB_PIN12) | \
+ PIN_OSPEED_100M(GPIOB_PIN13) | \
+ PIN_OSPEED_100M(GPIOB_PIN14) | \
+ PIN_OSPEED_100M(GPIOB_PIN15))
+#define VAL_GPIOB_PUPDR (PIN_PUPDR_PULLUP(GPIOB_PIN0) | \
+ PIN_PUPDR_PULLUP(GPIOB_PIN1) | \
+ PIN_PUPDR_PULLUP(GPIOB_PIN2) | \
+ PIN_PUPDR_FLOATING(GPIOB_SWO) | \
+ PIN_PUPDR_PULLUP(GPIOB_PIN4) | \
+ PIN_PUPDR_PULLUP(GPIOB_PIN5) | \
+ PIN_PUPDR_FLOATING(GPIOB_SCL) | \
+ PIN_PUPDR_PULLUP(GPIOB_PIN7) | \
+ PIN_PUPDR_PULLUP(GPIOB_PIN8) | \
+ PIN_PUPDR_FLOATING(GPIOB_SDA) | \
+ PIN_PUPDR_PULLUP(GPIOB_CLK_IN) | \
+ PIN_PUPDR_PULLUP(GPIOB_PIN11) | \
+ PIN_PUPDR_PULLUP(GPIOB_PIN12) | \
+ PIN_PUPDR_PULLUP(GPIOB_PIN13) | \
+ PIN_PUPDR_PULLUP(GPIOB_PIN14) | \
+ PIN_PUPDR_PULLUP(GPIOB_PIN15))
+#define VAL_GPIOB_ODR (PIN_ODR_HIGH(GPIOB_PIN0) | \
+ PIN_ODR_HIGH(GPIOB_PIN1) | \
+ PIN_ODR_HIGH(GPIOB_PIN2) | \
+ PIN_ODR_HIGH(GPIOB_SWO) | \
+ PIN_ODR_HIGH(GPIOB_PIN4) | \
+ PIN_ODR_HIGH(GPIOB_PIN5) | \
+ PIN_ODR_HIGH(GPIOB_SCL) | \
+ PIN_ODR_HIGH(GPIOB_PIN7) | \
+ PIN_ODR_HIGH(GPIOB_PIN8) | \
+ PIN_ODR_HIGH(GPIOB_SDA) | \
+ PIN_ODR_HIGH(GPIOB_CLK_IN) | \
+ PIN_ODR_HIGH(GPIOB_PIN11) | \
+ PIN_ODR_HIGH(GPIOB_PIN12) | \
+ PIN_ODR_HIGH(GPIOB_PIN13) | \
+ PIN_ODR_HIGH(GPIOB_PIN14) | \
+ PIN_ODR_HIGH(GPIOB_PIN15))
+#define VAL_GPIOB_AFRL (PIN_AFIO_AF(GPIOB_PIN0, 0) | \
+ PIN_AFIO_AF(GPIOB_PIN1, 0) | \
+ PIN_AFIO_AF(GPIOB_PIN2, 0) | \
+ PIN_AFIO_AF(GPIOB_SWO, 0) | \
+ PIN_AFIO_AF(GPIOB_PIN4, 0) | \
+ PIN_AFIO_AF(GPIOB_PIN5, 0) | \
+ PIN_AFIO_AF(GPIOB_SCL, 4) | \
+ PIN_AFIO_AF(GPIOB_PIN7, 0))
+#define VAL_GPIOB_AFRH (PIN_AFIO_AF(GPIOB_PIN8, 0) | \
+ PIN_AFIO_AF(GPIOB_SDA, 4) | \
+ PIN_AFIO_AF(GPIOB_CLK_IN, 0) | \
+ PIN_AFIO_AF(GPIOB_PIN11, 0) | \
+ PIN_AFIO_AF(GPIOB_PIN12, 0) | \
+ PIN_AFIO_AF(GPIOB_PIN13, 0) | \
+ PIN_AFIO_AF(GPIOB_PIN14, 0) | \
+ PIN_AFIO_AF(GPIOB_PIN15, 0))
+
+/*
+ * GPIOC setup:
+ *
+ * PC0 - OTG_FS_POWER_ON (output pushpull maximum).
+ * PC1 - PIN1 (input pullup).
+ * PC2 - PIN2 (input pullup).
+ * PC3 - PDM_OUT (input pullup).
+ * PC4 - PIN4 (input pullup).
+ * PC5 - PIN5 (input pullup).
+ * PC6 - PIN6 (input pullup).
+ * PC7 - MCLK (alternate 6).
+ * PC8 - PIN8 (input pullup).
+ * PC9 - PIN9 (input pullup).
+ * PC10 - SCLK (alternate 6).
+ * PC11 - PIN11 (input pullup).
+ * PC12 - SDIN (alternate 6).
+ * PC13 - PIN13 (input pullup).
+ * PC14 - PIN14 (input pullup).
+ * PC15 - PIN15 (input pullup).
+ */
+#define VAL_GPIOC_MODER (PIN_MODE_OUTPUT(GPIOC_OTG_FS_POWER_ON) |\
+ PIN_MODE_INPUT(GPIOC_PIN1) | \
+ PIN_MODE_INPUT(GPIOC_PIN2) | \
+ PIN_MODE_INPUT(GPIOC_PDM_OUT) | \
+ PIN_MODE_INPUT(GPIOC_PIN4) | \
+ PIN_MODE_INPUT(GPIOC_PIN5) | \
+ PIN_MODE_INPUT(GPIOC_PIN6) | \
+ PIN_MODE_ALTERNATE(GPIOC_MCLK) | \
+ PIN_MODE_INPUT(GPIOC_PIN8) | \
+ PIN_MODE_INPUT(GPIOC_PIN9) | \
+ PIN_MODE_ALTERNATE(GPIOC_SCLK) | \
+ PIN_MODE_INPUT(GPIOC_PIN11) | \
+ PIN_MODE_ALTERNATE(GPIOC_SDIN) | \
+ PIN_MODE_INPUT(GPIOC_PIN13) | \
+ PIN_MODE_INPUT(GPIOC_PIN14) | \
+ PIN_MODE_INPUT(GPIOC_PIN15))
+#define VAL_GPIOC_OTYPER (PIN_OTYPE_PUSHPULL(GPIOC_OTG_FS_POWER_ON) |\
+ PIN_OTYPE_PUSHPULL(GPIOC_PIN1) | \
+ PIN_OTYPE_PUSHPULL(GPIOC_PIN2) | \
+ PIN_OTYPE_PUSHPULL(GPIOC_PDM_OUT) | \
+ PIN_OTYPE_PUSHPULL(GPIOC_PIN4) | \
+ PIN_OTYPE_PUSHPULL(GPIOC_PIN5) | \
+ PIN_OTYPE_PUSHPULL(GPIOC_PIN6) | \
+ PIN_OTYPE_PUSHPULL(GPIOC_MCLK) | \
+ PIN_OTYPE_PUSHPULL(GPIOC_PIN8) | \
+ PIN_OTYPE_PUSHPULL(GPIOC_PIN9) | \
+ PIN_OTYPE_PUSHPULL(GPIOC_SCLK) | \
+ PIN_OTYPE_PUSHPULL(GPIOC_PIN11) | \
+ PIN_OTYPE_PUSHPULL(GPIOC_SDIN) | \
+ PIN_OTYPE_PUSHPULL(GPIOC_PIN13) | \
+ PIN_OTYPE_PUSHPULL(GPIOC_PIN14) | \
+ PIN_OTYPE_PUSHPULL(GPIOC_PIN15))
+#define VAL_GPIOC_OSPEEDR (PIN_OSPEED_100M(GPIOC_OTG_FS_POWER_ON) |\
+ PIN_OSPEED_100M(GPIOC_PIN1) | \
+ PIN_OSPEED_100M(GPIOC_PIN2) | \
+ PIN_OSPEED_100M(GPIOC_PDM_OUT) | \
+ PIN_OSPEED_100M(GPIOC_PIN4) | \
+ PIN_OSPEED_100M(GPIOC_PIN5) | \
+ PIN_OSPEED_100M(GPIOC_PIN6) | \
+ PIN_OSPEED_100M(GPIOC_MCLK) | \
+ PIN_OSPEED_100M(GPIOC_PIN8) | \
+ PIN_OSPEED_100M(GPIOC_PIN9) | \
+ PIN_OSPEED_100M(GPIOC_SCLK) | \
+ PIN_OSPEED_100M(GPIOC_PIN11) | \
+ PIN_OSPEED_100M(GPIOC_SDIN) | \
+ PIN_OSPEED_100M(GPIOC_PIN13) | \
+ PIN_OSPEED_100M(GPIOC_PIN14) | \
+ PIN_OSPEED_100M(GPIOC_PIN15))
+#define VAL_GPIOC_PUPDR (PIN_PUPDR_FLOATING(GPIOC_OTG_FS_POWER_ON) |\
+ PIN_PUPDR_PULLUP(GPIOC_PIN1) | \
+ PIN_PUPDR_PULLUP(GPIOC_PIN2) | \
+ PIN_PUPDR_PULLUP(GPIOC_PDM_OUT) | \
+ PIN_PUPDR_PULLUP(GPIOC_PIN4) | \
+ PIN_PUPDR_PULLUP(GPIOC_PIN5) | \
+ PIN_PUPDR_PULLUP(GPIOC_PIN6) | \
+ PIN_PUPDR_FLOATING(GPIOC_MCLK) | \
+ PIN_PUPDR_PULLUP(GPIOC_PIN8) | \
+ PIN_PUPDR_PULLUP(GPIOC_PIN9) | \
+ PIN_PUPDR_FLOATING(GPIOC_SCLK) | \
+ PIN_PUPDR_PULLUP(GPIOC_PIN11) | \
+ PIN_PUPDR_FLOATING(GPIOC_SDIN) | \
+ PIN_PUPDR_PULLUP(GPIOC_PIN13) | \
+ PIN_PUPDR_PULLUP(GPIOC_PIN14) | \
+ PIN_PUPDR_PULLUP(GPIOC_PIN15))
+#define VAL_GPIOC_ODR (PIN_ODR_HIGH(GPIOC_OTG_FS_POWER_ON) | \
+ PIN_ODR_HIGH(GPIOC_PIN1) | \
+ PIN_ODR_HIGH(GPIOC_PIN2) | \
+ PIN_ODR_HIGH(GPIOC_PDM_OUT) | \
+ PIN_ODR_HIGH(GPIOC_PIN4) | \
+ PIN_ODR_HIGH(GPIOC_PIN5) | \
+ PIN_ODR_HIGH(GPIOC_PIN6) | \
+ PIN_ODR_HIGH(GPIOC_MCLK) | \
+ PIN_ODR_HIGH(GPIOC_PIN8) | \
+ PIN_ODR_HIGH(GPIOC_PIN9) | \
+ PIN_ODR_HIGH(GPIOC_SCLK) | \
+ PIN_ODR_HIGH(GPIOC_PIN11) | \
+ PIN_ODR_HIGH(GPIOC_SDIN) | \
+ PIN_ODR_HIGH(GPIOC_PIN13) | \
+ PIN_ODR_HIGH(GPIOC_PIN14) | \
+ PIN_ODR_HIGH(GPIOC_PIN15))
+#define VAL_GPIOC_AFRL (PIN_AFIO_AF(GPIOC_OTG_FS_POWER_ON, 0) |\
+ PIN_AFIO_AF(GPIOC_PIN1, 0) | \
+ PIN_AFIO_AF(GPIOC_PIN2, 0) | \
+ PIN_AFIO_AF(GPIOC_PDM_OUT, 0) | \
+ PIN_AFIO_AF(GPIOC_PIN4, 0) | \
+ PIN_AFIO_AF(GPIOC_PIN5, 0) | \
+ PIN_AFIO_AF(GPIOC_PIN6, 0) | \
+ PIN_AFIO_AF(GPIOC_MCLK, 6))
+#define VAL_GPIOC_AFRH (PIN_AFIO_AF(GPIOC_PIN8, 0) | \
+ PIN_AFIO_AF(GPIOC_PIN9, 0) | \
+ PIN_AFIO_AF(GPIOC_SCLK, 6) | \
+ PIN_AFIO_AF(GPIOC_PIN11, 0) | \
+ PIN_AFIO_AF(GPIOC_SDIN, 6) | \
+ PIN_AFIO_AF(GPIOC_PIN13, 0) | \
+ PIN_AFIO_AF(GPIOC_PIN14, 0) | \
+ PIN_AFIO_AF(GPIOC_PIN15, 0))
+
+/*
+ * GPIOD setup:
+ *
+ * PD0 - PIN0 (input pullup).
+ * PD1 - PIN1 (input pullup).
+ * PD2 - PIN2 (input pullup).
+ * PD3 - PIN3 (input pullup).
+ * PD4 - RESET (output pushpull maximum).
+ * PD5 - OVER_CURRENT (input floating).
+ * PD6 - PIN6 (input pullup).
+ * PD7 - PIN7 (input pullup).
+ * PD8 - PIN8 (input pullup).
+ * PD9 - PIN9 (input pullup).
+ * PD10 - PIN10 (input pullup).
+ * PD11 - PIN11 (input pullup).
+ * PD12 - LED4 (output pushpull maximum).
+ * PD13 - LED3 (output pushpull maximum).
+ * PD14 - LED5 (output pushpull maximum).
+ * PD15 - LED6 (output pushpull maximum).
+ */
+#define VAL_GPIOD_MODER (PIN_MODE_INPUT(GPIOD_PIN0) | \
+ PIN_MODE_INPUT(GPIOD_PIN1) | \
+ PIN_MODE_INPUT(GPIOD_PIN2) | \
+ PIN_MODE_INPUT(GPIOD_PIN3) | \
+ PIN_MODE_OUTPUT(GPIOD_RESET) | \
+ PIN_MODE_INPUT(GPIOD_OVER_CURRENT) | \
+ PIN_MODE_INPUT(GPIOD_PIN6) | \
+ PIN_MODE_INPUT(GPIOD_PIN7) | \
+ PIN_MODE_INPUT(GPIOD_PIN8) | \
+ PIN_MODE_INPUT(GPIOD_PIN9) | \
+ PIN_MODE_INPUT(GPIOD_PIN10) | \
+ PIN_MODE_INPUT(GPIOD_PIN11) | \
+ PIN_MODE_OUTPUT(GPIOD_LED4) | \
+ PIN_MODE_OUTPUT(GPIOD_LED3) | \
+ PIN_MODE_OUTPUT(GPIOD_LED5) | \
+ PIN_MODE_OUTPUT(GPIOD_LED6))
+#define VAL_GPIOD_OTYPER (PIN_OTYPE_PUSHPULL(GPIOD_PIN0) | \
+ PIN_OTYPE_PUSHPULL(GPIOD_PIN1) | \
+ PIN_OTYPE_PUSHPULL(GPIOD_PIN2) | \
+ PIN_OTYPE_PUSHPULL(GPIOD_PIN3) | \
+ PIN_OTYPE_PUSHPULL(GPIOD_RESET) | \
+ PIN_OTYPE_PUSHPULL(GPIOD_OVER_CURRENT) |\
+ PIN_OTYPE_PUSHPULL(GPIOD_PIN6) | \
+ PIN_OTYPE_PUSHPULL(GPIOD_PIN7) | \
+ PIN_OTYPE_PUSHPULL(GPIOD_PIN8) | \
+ PIN_OTYPE_PUSHPULL(GPIOD_PIN9) | \
+ PIN_OTYPE_PUSHPULL(GPIOD_PIN10) | \
+ PIN_OTYPE_PUSHPULL(GPIOD_PIN11) | \
+ PIN_OTYPE_PUSHPULL(GPIOD_LED4) | \
+ PIN_OTYPE_PUSHPULL(GPIOD_LED3) | \
+ PIN_OTYPE_PUSHPULL(GPIOD_LED5) | \
+ PIN_OTYPE_PUSHPULL(GPIOD_LED6))
+#define VAL_GPIOD_OSPEEDR (PIN_OSPEED_100M(GPIOD_PIN0) | \
+ PIN_OSPEED_100M(GPIOD_PIN1) | \
+ PIN_OSPEED_100M(GPIOD_PIN2) | \
+ PIN_OSPEED_100M(GPIOD_PIN3) | \
+ PIN_OSPEED_100M(GPIOD_RESET) | \
+ PIN_OSPEED_100M(GPIOD_OVER_CURRENT) | \
+ PIN_OSPEED_100M(GPIOD_PIN6) | \
+ PIN_OSPEED_100M(GPIOD_PIN7) | \
+ PIN_OSPEED_100M(GPIOD_PIN8) | \
+ PIN_OSPEED_100M(GPIOD_PIN9) | \
+ PIN_OSPEED_100M(GPIOD_PIN10) | \
+ PIN_OSPEED_100M(GPIOD_PIN11) | \
+ PIN_OSPEED_100M(GPIOD_LED4) | \
+ PIN_OSPEED_100M(GPIOD_LED3) | \
+ PIN_OSPEED_100M(GPIOD_LED5) | \
+ PIN_OSPEED_100M(GPIOD_LED6))
+#define VAL_GPIOD_PUPDR (PIN_PUPDR_PULLUP(GPIOD_PIN0) | \
+ PIN_PUPDR_PULLUP(GPIOD_PIN1) | \
+ PIN_PUPDR_PULLUP(GPIOD_PIN2) | \
+ PIN_PUPDR_PULLUP(GPIOD_PIN3) | \
+ PIN_PUPDR_FLOATING(GPIOD_RESET) | \
+ PIN_PUPDR_FLOATING(GPIOD_OVER_CURRENT) |\
+ PIN_PUPDR_PULLUP(GPIOD_PIN6) | \
+ PIN_PUPDR_PULLUP(GPIOD_PIN7) | \
+ PIN_PUPDR_PULLUP(GPIOD_PIN8) | \
+ PIN_PUPDR_PULLUP(GPIOD_PIN9) | \
+ PIN_PUPDR_PULLUP(GPIOD_PIN10) | \
+ PIN_PUPDR_PULLUP(GPIOD_PIN11) | \
+ PIN_PUPDR_FLOATING(GPIOD_LED4) | \
+ PIN_PUPDR_FLOATING(GPIOD_LED3) | \
+ PIN_PUPDR_FLOATING(GPIOD_LED5) | \
+ PIN_PUPDR_FLOATING(GPIOD_LED6))
+#define VAL_GPIOD_ODR (PIN_ODR_HIGH(GPIOD_PIN0) | \
+ PIN_ODR_HIGH(GPIOD_PIN1) | \
+ PIN_ODR_HIGH(GPIOD_PIN2) | \
+ PIN_ODR_HIGH(GPIOD_PIN3) | \
+ PIN_ODR_HIGH(GPIOD_RESET) | \
+ PIN_ODR_HIGH(GPIOD_OVER_CURRENT) | \
+ PIN_ODR_HIGH(GPIOD_PIN6) | \
+ PIN_ODR_HIGH(GPIOD_PIN7) | \
+ PIN_ODR_HIGH(GPIOD_PIN8) | \
+ PIN_ODR_HIGH(GPIOD_PIN9) | \
+ PIN_ODR_HIGH(GPIOD_PIN10) | \
+ PIN_ODR_HIGH(GPIOD_PIN11) | \
+ PIN_ODR_LOW(GPIOD_LED4) | \
+ PIN_ODR_LOW(GPIOD_LED3) | \
+ PIN_ODR_LOW(GPIOD_LED5) | \
+ PIN_ODR_LOW(GPIOD_LED6))
+#define VAL_GPIOD_AFRL (PIN_AFIO_AF(GPIOD_PIN0, 0) | \
+ PIN_AFIO_AF(GPIOD_PIN1, 0) | \
+ PIN_AFIO_AF(GPIOD_PIN2, 0) | \
+ PIN_AFIO_AF(GPIOD_PIN3, 0) | \
+ PIN_AFIO_AF(GPIOD_RESET, 0) | \
+ PIN_AFIO_AF(GPIOD_OVER_CURRENT, 0) | \
+ PIN_AFIO_AF(GPIOD_PIN6, 0) | \
+ PIN_AFIO_AF(GPIOD_PIN7, 0))
+#define VAL_GPIOD_AFRH (PIN_AFIO_AF(GPIOD_PIN8, 0) | \
+ PIN_AFIO_AF(GPIOD_PIN9, 0) | \
+ PIN_AFIO_AF(GPIOD_PIN10, 0) | \
+ PIN_AFIO_AF(GPIOD_PIN11, 0) | \
+ PIN_AFIO_AF(GPIOD_LED4, 0) | \
+ PIN_AFIO_AF(GPIOD_LED3, 0) | \
+ PIN_AFIO_AF(GPIOD_LED5, 0) | \
+ PIN_AFIO_AF(GPIOD_LED6, 0))
+
+/*
+ * GPIOE setup:
+ *
+ * PE0 - INT1 (input floating).
+ * PE1 - INT2 (input floating).
+ * PE2 - PIN2 (input floating).
+ * PE3 - CS_SPI (output pushpull maximum).
+ * PE4 - PIN4 (input floating).
+ * PE5 - PIN5 (input floating).
+ * PE6 - PIN6 (input floating).
+ * PE7 - PIN7 (input floating).
+ * PE8 - PIN8 (input floating).
+ * PE9 - PIN9 (input floating).
+ * PE10 - PIN10 (input floating).
+ * PE11 - PIN11 (input floating).
+ * PE12 - PIN12 (input floating).
+ * PE13 - PIN13 (input floating).
+ * PE14 - PIN14 (input floating).
+ * PE15 - PIN15 (input floating).
+ */
+#define VAL_GPIOE_MODER (PIN_MODE_INPUT(GPIOE_INT1) | \
+ PIN_MODE_INPUT(GPIOE_INT2) | \
+ PIN_MODE_INPUT(GPIOE_PIN2) | \
+ PIN_MODE_OUTPUT(GPIOE_CS_SPI) | \
+ PIN_MODE_INPUT(GPIOE_PIN4) | \
+ PIN_MODE_INPUT(GPIOE_PIN5) | \
+ PIN_MODE_INPUT(GPIOE_PIN6) | \
+ PIN_MODE_INPUT(GPIOE_PIN7) | \
+ PIN_MODE_INPUT(GPIOE_PIN8) | \
+ PIN_MODE_INPUT(GPIOE_PIN9) | \
+ PIN_MODE_INPUT(GPIOE_PIN10) | \
+ PIN_MODE_INPUT(GPIOE_PIN11) | \
+ PIN_MODE_INPUT(GPIOE_PIN12) | \
+ PIN_MODE_INPUT(GPIOE_PIN13) | \
+ PIN_MODE_INPUT(GPIOE_PIN14) | \
+ PIN_MODE_INPUT(GPIOE_PIN15))
+#define VAL_GPIOE_OTYPER (PIN_OTYPE_PUSHPULL(GPIOE_INT1) | \
+ PIN_OTYPE_PUSHPULL(GPIOE_INT2) | \
+ PIN_OTYPE_PUSHPULL(GPIOE_PIN2) | \
+ PIN_OTYPE_PUSHPULL(GPIOE_CS_SPI) | \
+ PIN_OTYPE_PUSHPULL(GPIOE_PIN4) | \
+ PIN_OTYPE_PUSHPULL(GPIOE_PIN5) | \
+ PIN_OTYPE_PUSHPULL(GPIOE_PIN6) | \
+ PIN_OTYPE_PUSHPULL(GPIOE_PIN7) | \
+ PIN_OTYPE_PUSHPULL(GPIOE_PIN8) | \
+ PIN_OTYPE_PUSHPULL(GPIOE_PIN9) | \
+ PIN_OTYPE_PUSHPULL(GPIOE_PIN10) | \
+ PIN_OTYPE_PUSHPULL(GPIOE_PIN11) | \
+ PIN_OTYPE_PUSHPULL(GPIOE_PIN12) | \
+ PIN_OTYPE_PUSHPULL(GPIOE_PIN13) | \
+ PIN_OTYPE_PUSHPULL(GPIOE_PIN14) | \
+ PIN_OTYPE_PUSHPULL(GPIOE_PIN15))
+#define VAL_GPIOE_OSPEEDR (PIN_OSPEED_100M(GPIOE_INT1) | \
+ PIN_OSPEED_100M(GPIOE_INT2) | \
+ PIN_OSPEED_100M(GPIOE_PIN2) | \
+ PIN_OSPEED_100M(GPIOE_CS_SPI) | \
+ PIN_OSPEED_100M(GPIOE_PIN4) | \
+ PIN_OSPEED_100M(GPIOE_PIN5) | \
+ PIN_OSPEED_100M(GPIOE_PIN6) | \
+ PIN_OSPEED_100M(GPIOE_PIN7) | \
+ PIN_OSPEED_100M(GPIOE_PIN8) | \
+ PIN_OSPEED_100M(GPIOE_PIN9) | \
+ PIN_OSPEED_100M(GPIOE_PIN10) | \
+ PIN_OSPEED_100M(GPIOE_PIN11) | \
+ PIN_OSPEED_100M(GPIOE_PIN12) | \
+ PIN_OSPEED_100M(GPIOE_PIN13) | \
+ PIN_OSPEED_100M(GPIOE_PIN14) | \
+ PIN_OSPEED_100M(GPIOE_PIN15))
+#define VAL_GPIOE_PUPDR (PIN_PUPDR_FLOATING(GPIOE_INT1) | \
+ PIN_PUPDR_FLOATING(GPIOE_INT2) | \
+ PIN_PUPDR_FLOATING(GPIOE_PIN2) | \
+ PIN_PUPDR_FLOATING(GPIOE_CS_SPI) | \
+ PIN_PUPDR_FLOATING(GPIOE_PIN4) | \
+ PIN_PUPDR_FLOATING(GPIOE_PIN5) | \
+ PIN_PUPDR_FLOATING(GPIOE_PIN6) | \
+ PIN_PUPDR_FLOATING(GPIOE_PIN7) | \
+ PIN_PUPDR_FLOATING(GPIOE_PIN8) | \
+ PIN_PUPDR_FLOATING(GPIOE_PIN9) | \
+ PIN_PUPDR_FLOATING(GPIOE_PIN10) | \
+ PIN_PUPDR_FLOATING(GPIOE_PIN11) | \
+ PIN_PUPDR_FLOATING(GPIOE_PIN12) | \
+ PIN_PUPDR_FLOATING(GPIOE_PIN13) | \
+ PIN_PUPDR_FLOATING(GPIOE_PIN14) | \
+ PIN_PUPDR_FLOATING(GPIOE_PIN15))
+#define VAL_GPIOE_ODR (PIN_ODR_HIGH(GPIOE_INT1) | \
+ PIN_ODR_HIGH(GPIOE_INT2) | \
+ PIN_ODR_HIGH(GPIOE_PIN2) | \
+ PIN_ODR_HIGH(GPIOE_CS_SPI) | \
+ PIN_ODR_HIGH(GPIOE_PIN4) | \
+ PIN_ODR_HIGH(GPIOE_PIN5) | \
+ PIN_ODR_HIGH(GPIOE_PIN6) | \
+ PIN_ODR_HIGH(GPIOE_PIN7) | \
+ PIN_ODR_HIGH(GPIOE_PIN8) | \
+ PIN_ODR_HIGH(GPIOE_PIN9) | \
+ PIN_ODR_HIGH(GPIOE_PIN10) | \
+ PIN_ODR_HIGH(GPIOE_PIN11) | \
+ PIN_ODR_HIGH(GPIOE_PIN12) | \
+ PIN_ODR_HIGH(GPIOE_PIN13) | \
+ PIN_ODR_HIGH(GPIOE_PIN14) | \
+ PIN_ODR_HIGH(GPIOE_PIN15))
+#define VAL_GPIOE_AFRL (PIN_AFIO_AF(GPIOE_INT1, 0) | \
+ PIN_AFIO_AF(GPIOE_INT2, 0) | \
+ PIN_AFIO_AF(GPIOE_PIN2, 0) | \
+ PIN_AFIO_AF(GPIOE_CS_SPI, 0) | \
+ PIN_AFIO_AF(GPIOE_PIN4, 0) | \
+ PIN_AFIO_AF(GPIOE_PIN5, 0) | \
+ PIN_AFIO_AF(GPIOE_PIN6, 0) | \
+ PIN_AFIO_AF(GPIOE_PIN7, 0))
+#define VAL_GPIOE_AFRH (PIN_AFIO_AF(GPIOE_PIN8, 0) | \
+ PIN_AFIO_AF(GPIOE_PIN9, 0) | \
+ PIN_AFIO_AF(GPIOE_PIN10, 0) | \
+ PIN_AFIO_AF(GPIOE_PIN11, 0) | \
+ PIN_AFIO_AF(GPIOE_PIN12, 0) | \
+ PIN_AFIO_AF(GPIOE_PIN13, 0) | \
+ PIN_AFIO_AF(GPIOE_PIN14, 0) | \
+ PIN_AFIO_AF(GPIOE_PIN15, 0))
+
+/*
+ * GPIOF setup:
+ *
+ * PF0 - PIN0 (input floating).
+ * PF1 - PIN1 (input floating).
+ * PF2 - PIN2 (input floating).
+ * PF3 - PIN3 (input floating).
+ * PF4 - PIN4 (input floating).
+ * PF5 - PIN5 (input floating).
+ * PF6 - PIN6 (input floating).
+ * PF7 - PIN7 (input floating).
+ * PF8 - PIN8 (input floating).
+ * PF9 - PIN9 (input floating).
+ * PF10 - PIN10 (input floating).
+ * PF11 - PIN11 (input floating).
+ * PF12 - PIN12 (input floating).
+ * PF13 - PIN13 (input floating).
+ * PF14 - PIN14 (input floating).
+ * PF15 - PIN15 (input floating).
+ */
+#define VAL_GPIOF_MODER (PIN_MODE_INPUT(GPIOF_PIN0) | \
+ PIN_MODE_INPUT(GPIOF_PIN1) | \
+ PIN_MODE_INPUT(GPIOF_PIN2) | \
+ PIN_MODE_INPUT(GPIOF_PIN3) | \
+ PIN_MODE_INPUT(GPIOF_PIN4) | \
+ PIN_MODE_INPUT(GPIOF_PIN5) | \
+ PIN_MODE_INPUT(GPIOF_PIN6) | \
+ PIN_MODE_INPUT(GPIOF_PIN7) | \
+ PIN_MODE_INPUT(GPIOF_PIN8) | \
+ PIN_MODE_INPUT(GPIOF_PIN9) | \
+ PIN_MODE_INPUT(GPIOF_PIN10) | \
+ PIN_MODE_INPUT(GPIOF_PIN11) | \
+ PIN_MODE_INPUT(GPIOF_PIN12) | \
+ PIN_MODE_INPUT(GPIOF_PIN13) | \
+ PIN_MODE_INPUT(GPIOF_PIN14) | \
+ PIN_MODE_INPUT(GPIOF_PIN15))
+#define VAL_GPIOF_OTYPER (PIN_OTYPE_PUSHPULL(GPIOF_PIN0) | \
+ PIN_OTYPE_PUSHPULL(GPIOF_PIN1) | \
+ PIN_OTYPE_PUSHPULL(GPIOF_PIN2) | \
+ PIN_OTYPE_PUSHPULL(GPIOF_PIN3) | \
+ PIN_OTYPE_PUSHPULL(GPIOF_PIN4) | \
+ PIN_OTYPE_PUSHPULL(GPIOF_PIN5) | \
+ PIN_OTYPE_PUSHPULL(GPIOF_PIN6) | \
+ PIN_OTYPE_PUSHPULL(GPIOF_PIN7) | \
+ PIN_OTYPE_PUSHPULL(GPIOF_PIN8) | \
+ PIN_OTYPE_PUSHPULL(GPIOF_PIN9) | \
+ PIN_OTYPE_PUSHPULL(GPIOF_PIN10) | \
+ PIN_OTYPE_PUSHPULL(GPIOF_PIN11) | \
+ PIN_OTYPE_PUSHPULL(GPIOF_PIN12) | \
+ PIN_OTYPE_PUSHPULL(GPIOF_PIN13) | \
+ PIN_OTYPE_PUSHPULL(GPIOF_PIN14) | \
+ PIN_OTYPE_PUSHPULL(GPIOF_PIN15))
+#define VAL_GPIOF_OSPEEDR (PIN_OSPEED_100M(GPIOF_PIN0) | \
+ PIN_OSPEED_100M(GPIOF_PIN1) | \
+ PIN_OSPEED_100M(GPIOF_PIN2) | \
+ PIN_OSPEED_100M(GPIOF_PIN3) | \
+ PIN_OSPEED_100M(GPIOF_PIN4) | \
+ PIN_OSPEED_100M(GPIOF_PIN5) | \
+ PIN_OSPEED_100M(GPIOF_PIN6) | \
+ PIN_OSPEED_100M(GPIOF_PIN7) | \
+ PIN_OSPEED_100M(GPIOF_PIN8) | \
+ PIN_OSPEED_100M(GPIOF_PIN9) | \
+ PIN_OSPEED_100M(GPIOF_PIN10) | \
+ PIN_OSPEED_100M(GPIOF_PIN11) | \
+ PIN_OSPEED_100M(GPIOF_PIN12) | \
+ PIN_OSPEED_100M(GPIOF_PIN13) | \
+ PIN_OSPEED_100M(GPIOF_PIN14) | \
+ PIN_OSPEED_100M(GPIOF_PIN15))
+#define VAL_GPIOF_PUPDR (PIN_PUPDR_FLOATING(GPIOF_PIN0) | \
+ PIN_PUPDR_FLOATING(GPIOF_PIN1) | \
+ PIN_PUPDR_FLOATING(GPIOF_PIN2) | \
+ PIN_PUPDR_FLOATING(GPIOF_PIN3) | \
+ PIN_PUPDR_FLOATING(GPIOF_PIN4) | \
+ PIN_PUPDR_FLOATING(GPIOF_PIN5) | \
+ PIN_PUPDR_FLOATING(GPIOF_PIN6) | \
+ PIN_PUPDR_FLOATING(GPIOF_PIN7) | \
+ PIN_PUPDR_FLOATING(GPIOF_PIN8) | \
+ PIN_PUPDR_FLOATING(GPIOF_PIN9) | \
+ PIN_PUPDR_FLOATING(GPIOF_PIN10) | \
+ PIN_PUPDR_FLOATING(GPIOF_PIN11) | \
+ PIN_PUPDR_FLOATING(GPIOF_PIN12) | \
+ PIN_PUPDR_FLOATING(GPIOF_PIN13) | \
+ PIN_PUPDR_FLOATING(GPIOF_PIN14) | \
+ PIN_PUPDR_FLOATING(GPIOF_PIN15))
+#define VAL_GPIOF_ODR (PIN_ODR_HIGH(GPIOF_PIN0) | \
+ PIN_ODR_HIGH(GPIOF_PIN1) | \
+ PIN_ODR_HIGH(GPIOF_PIN2) | \
+ PIN_ODR_HIGH(GPIOF_PIN3) | \
+ PIN_ODR_HIGH(GPIOF_PIN4) | \
+ PIN_ODR_HIGH(GPIOF_PIN5) | \
+ PIN_ODR_HIGH(GPIOF_PIN6) | \
+ PIN_ODR_HIGH(GPIOF_PIN7) | \
+ PIN_ODR_HIGH(GPIOF_PIN8) | \
+ PIN_ODR_HIGH(GPIOF_PIN9) | \
+ PIN_ODR_HIGH(GPIOF_PIN10) | \
+ PIN_ODR_HIGH(GPIOF_PIN11) | \
+ PIN_ODR_HIGH(GPIOF_PIN12) | \
+ PIN_ODR_HIGH(GPIOF_PIN13) | \
+ PIN_ODR_HIGH(GPIOF_PIN14) | \
+ PIN_ODR_HIGH(GPIOF_PIN15))
+#define VAL_GPIOF_AFRL (PIN_AFIO_AF(GPIOF_PIN0, 0) | \
+ PIN_AFIO_AF(GPIOF_PIN1, 0) | \
+ PIN_AFIO_AF(GPIOF_PIN2, 0) | \
+ PIN_AFIO_AF(GPIOF_PIN3, 0) | \
+ PIN_AFIO_AF(GPIOF_PIN4, 0) | \
+ PIN_AFIO_AF(GPIOF_PIN5, 0) | \
+ PIN_AFIO_AF(GPIOF_PIN6, 0) | \
+ PIN_AFIO_AF(GPIOF_PIN7, 0))
+#define VAL_GPIOF_AFRH (PIN_AFIO_AF(GPIOF_PIN8, 0) | \
+ PIN_AFIO_AF(GPIOF_PIN9, 0) | \
+ PIN_AFIO_AF(GPIOF_PIN10, 0) | \
+ PIN_AFIO_AF(GPIOF_PIN11, 0) | \
+ PIN_AFIO_AF(GPIOF_PIN12, 0) | \
+ PIN_AFIO_AF(GPIOF_PIN13, 0) | \
+ PIN_AFIO_AF(GPIOF_PIN14, 0) | \
+ PIN_AFIO_AF(GPIOF_PIN15, 0))
+
+/*
+ * GPIOG setup:
+ *
+ * PG0 - PIN0 (input floating).
+ * PG1 - PIN1 (input floating).
+ * PG2 - PIN2 (input floating).
+ * PG3 - PIN3 (input floating).
+ * PG4 - PIN4 (input floating).
+ * PG5 - PIN5 (input floating).
+ * PG6 - PIN6 (input floating).
+ * PG7 - PIN7 (input floating).
+ * PG8 - PIN8 (input floating).
+ * PG9 - PIN9 (input floating).
+ * PG10 - PIN10 (input floating).
+ * PG11 - PIN11 (input floating).
+ * PG12 - PIN12 (input floating).
+ * PG13 - PIN13 (input floating).
+ * PG14 - PIN14 (input floating).
+ * PG15 - PIN15 (input floating).
+ */
+#define VAL_GPIOG_MODER (PIN_MODE_INPUT(GPIOG_PIN0) | \
+ PIN_MODE_INPUT(GPIOG_PIN1) | \
+ PIN_MODE_INPUT(GPIOG_PIN2) | \
+ PIN_MODE_INPUT(GPIOG_PIN3) | \
+ PIN_MODE_INPUT(GPIOG_PIN4) | \
+ PIN_MODE_INPUT(GPIOG_PIN5) | \
+ PIN_MODE_INPUT(GPIOG_PIN6) | \
+ PIN_MODE_INPUT(GPIOG_PIN7) | \
+ PIN_MODE_INPUT(GPIOG_PIN8) | \
+ PIN_MODE_INPUT(GPIOG_PIN9) | \
+ PIN_MODE_INPUT(GPIOG_PIN10) | \
+ PIN_MODE_INPUT(GPIOG_PIN11) | \
+ PIN_MODE_INPUT(GPIOG_PIN12) | \
+ PIN_MODE_INPUT(GPIOG_PIN13) | \
+ PIN_MODE_INPUT(GPIOG_PIN14) | \
+ PIN_MODE_INPUT(GPIOG_PIN15))
+#define VAL_GPIOG_OTYPER (PIN_OTYPE_PUSHPULL(GPIOG_PIN0) | \
+ PIN_OTYPE_PUSHPULL(GPIOG_PIN1) | \
+ PIN_OTYPE_PUSHPULL(GPIOG_PIN2) | \
+ PIN_OTYPE_PUSHPULL(GPIOG_PIN3) | \
+ PIN_OTYPE_PUSHPULL(GPIOG_PIN4) | \
+ PIN_OTYPE_PUSHPULL(GPIOG_PIN5) | \
+ PIN_OTYPE_PUSHPULL(GPIOG_PIN6) | \
+ PIN_OTYPE_PUSHPULL(GPIOG_PIN7) | \
+ PIN_OTYPE_PUSHPULL(GPIOG_PIN8) | \
+ PIN_OTYPE_PUSHPULL(GPIOG_PIN9) | \
+ PIN_OTYPE_PUSHPULL(GPIOG_PIN10) | \
+ PIN_OTYPE_PUSHPULL(GPIOG_PIN11) | \
+ PIN_OTYPE_PUSHPULL(GPIOG_PIN12) | \
+ PIN_OTYPE_PUSHPULL(GPIOG_PIN13) | \
+ PIN_OTYPE_PUSHPULL(GPIOG_PIN14) | \
+ PIN_OTYPE_PUSHPULL(GPIOG_PIN15))
+#define VAL_GPIOG_OSPEEDR (PIN_OSPEED_100M(GPIOG_PIN0) | \
+ PIN_OSPEED_100M(GPIOG_PIN1) | \
+ PIN_OSPEED_100M(GPIOG_PIN2) | \
+ PIN_OSPEED_100M(GPIOG_PIN3) | \
+ PIN_OSPEED_100M(GPIOG_PIN4) | \
+ PIN_OSPEED_100M(GPIOG_PIN5) | \
+ PIN_OSPEED_100M(GPIOG_PIN6) | \
+ PIN_OSPEED_100M(GPIOG_PIN7) | \
+ PIN_OSPEED_100M(GPIOG_PIN8) | \
+ PIN_OSPEED_100M(GPIOG_PIN9) | \
+ PIN_OSPEED_100M(GPIOG_PIN10) | \
+ PIN_OSPEED_100M(GPIOG_PIN11) | \
+ PIN_OSPEED_100M(GPIOG_PIN12) | \
+ PIN_OSPEED_100M(GPIOG_PIN13) | \
+ PIN_OSPEED_100M(GPIOG_PIN14) | \
+ PIN_OSPEED_100M(GPIOG_PIN15))
+#define VAL_GPIOG_PUPDR (PIN_PUPDR_FLOATING(GPIOG_PIN0) | \
+ PIN_PUPDR_FLOATING(GPIOG_PIN1) | \
+ PIN_PUPDR_FLOATING(GPIOG_PIN2) | \
+ PIN_PUPDR_FLOATING(GPIOG_PIN3) | \
+ PIN_PUPDR_FLOATING(GPIOG_PIN4) | \
+ PIN_PUPDR_FLOATING(GPIOG_PIN5) | \
+ PIN_PUPDR_FLOATING(GPIOG_PIN6) | \
+ PIN_PUPDR_FLOATING(GPIOG_PIN7) | \
+ PIN_PUPDR_FLOATING(GPIOG_PIN8) | \
+ PIN_PUPDR_FLOATING(GPIOG_PIN9) | \
+ PIN_PUPDR_FLOATING(GPIOG_PIN10) | \
+ PIN_PUPDR_FLOATING(GPIOG_PIN11) | \
+ PIN_PUPDR_FLOATING(GPIOG_PIN12) | \
+ PIN_PUPDR_FLOATING(GPIOG_PIN13) | \
+ PIN_PUPDR_FLOATING(GPIOG_PIN14) | \
+ PIN_PUPDR_FLOATING(GPIOG_PIN15))
+#define VAL_GPIOG_ODR (PIN_ODR_HIGH(GPIOG_PIN0) | \
+ PIN_ODR_HIGH(GPIOG_PIN1) | \
+ PIN_ODR_HIGH(GPIOG_PIN2) | \
+ PIN_ODR_HIGH(GPIOG_PIN3) | \
+ PIN_ODR_HIGH(GPIOG_PIN4) | \
+ PIN_ODR_HIGH(GPIOG_PIN5) | \
+ PIN_ODR_HIGH(GPIOG_PIN6) | \
+ PIN_ODR_HIGH(GPIOG_PIN7) | \
+ PIN_ODR_HIGH(GPIOG_PIN8) | \
+ PIN_ODR_HIGH(GPIOG_PIN9) | \
+ PIN_ODR_HIGH(GPIOG_PIN10) | \
+ PIN_ODR_HIGH(GPIOG_PIN11) | \
+ PIN_ODR_HIGH(GPIOG_PIN12) | \
+ PIN_ODR_HIGH(GPIOG_PIN13) | \
+ PIN_ODR_HIGH(GPIOG_PIN14) | \
+ PIN_ODR_HIGH(GPIOG_PIN15))
+#define VAL_GPIOG_AFRL (PIN_AFIO_AF(GPIOG_PIN0, 0) | \
+ PIN_AFIO_AF(GPIOG_PIN1, 0) | \
+ PIN_AFIO_AF(GPIOG_PIN2, 0) | \
+ PIN_AFIO_AF(GPIOG_PIN3, 0) | \
+ PIN_AFIO_AF(GPIOG_PIN4, 0) | \
+ PIN_AFIO_AF(GPIOG_PIN5, 0) | \
+ PIN_AFIO_AF(GPIOG_PIN6, 0) | \
+ PIN_AFIO_AF(GPIOG_PIN7, 0))
+#define VAL_GPIOG_AFRH (PIN_AFIO_AF(GPIOG_PIN8, 0) | \
+ PIN_AFIO_AF(GPIOG_PIN9, 0) | \
+ PIN_AFIO_AF(GPIOG_PIN10, 0) | \
+ PIN_AFIO_AF(GPIOG_PIN11, 0) | \
+ PIN_AFIO_AF(GPIOG_PIN12, 0) | \
+ PIN_AFIO_AF(GPIOG_PIN13, 0) | \
+ PIN_AFIO_AF(GPIOG_PIN14, 0) | \
+ PIN_AFIO_AF(GPIOG_PIN15, 0))
+
+/*
+ * GPIOH setup:
+ *
+ * PH0 - OSC_IN (input floating).
+ * PH1 - OSC_OUT (input floating).
+ * PH2 - PIN2 (input floating).
+ * PH3 - PIN3 (input floating).
+ * PH4 - PIN4 (input floating).
+ * PH5 - PIN5 (input floating).
+ * PH6 - PIN6 (input floating).
+ * PH7 - PIN7 (input floating).
+ * PH8 - PIN8 (input floating).
+ * PH9 - PIN9 (input floating).
+ * PH10 - PIN10 (input floating).
+ * PH11 - PIN11 (input floating).
+ * PH12 - PIN12 (input floating).
+ * PH13 - PIN13 (input floating).
+ * PH14 - PIN14 (input floating).
+ * PH15 - PIN15 (input floating).
+ */
+#define VAL_GPIOH_MODER (PIN_MODE_INPUT(GPIOH_OSC_IN) | \
+ PIN_MODE_INPUT(GPIOH_OSC_OUT) | \
+ PIN_MODE_INPUT(GPIOH_PIN2) | \
+ PIN_MODE_INPUT(GPIOH_PIN3) | \
+ PIN_MODE_INPUT(GPIOH_PIN4) | \
+ PIN_MODE_INPUT(GPIOH_PIN5) | \
+ PIN_MODE_INPUT(GPIOH_PIN6) | \
+ PIN_MODE_INPUT(GPIOH_PIN7) | \
+ PIN_MODE_INPUT(GPIOH_PIN8) | \
+ PIN_MODE_INPUT(GPIOH_PIN9) | \
+ PIN_MODE_INPUT(GPIOH_PIN10) | \
+ PIN_MODE_INPUT(GPIOH_PIN11) | \
+ PIN_MODE_INPUT(GPIOH_PIN12) | \
+ PIN_MODE_INPUT(GPIOH_PIN13) | \
+ PIN_MODE_INPUT(GPIOH_PIN14) | \
+ PIN_MODE_INPUT(GPIOH_PIN15))
+#define VAL_GPIOH_OTYPER (PIN_OTYPE_PUSHPULL(GPIOH_OSC_IN) | \
+ PIN_OTYPE_PUSHPULL(GPIOH_OSC_OUT) | \
+ PIN_OTYPE_PUSHPULL(GPIOH_PIN2) | \
+ PIN_OTYPE_PUSHPULL(GPIOH_PIN3) | \
+ PIN_OTYPE_PUSHPULL(GPIOH_PIN4) | \
+ PIN_OTYPE_PUSHPULL(GPIOH_PIN5) | \
+ PIN_OTYPE_PUSHPULL(GPIOH_PIN6) | \
+ PIN_OTYPE_PUSHPULL(GPIOH_PIN7) | \
+ PIN_OTYPE_PUSHPULL(GPIOH_PIN8) | \
+ PIN_OTYPE_PUSHPULL(GPIOH_PIN9) | \
+ PIN_OTYPE_PUSHPULL(GPIOH_PIN10) | \
+ PIN_OTYPE_PUSHPULL(GPIOH_PIN11) | \
+ PIN_OTYPE_PUSHPULL(GPIOH_PIN12) | \
+ PIN_OTYPE_PUSHPULL(GPIOH_PIN13) | \
+ PIN_OTYPE_PUSHPULL(GPIOH_PIN14) | \
+ PIN_OTYPE_PUSHPULL(GPIOH_PIN15))
+#define VAL_GPIOH_OSPEEDR (PIN_OSPEED_100M(GPIOH_OSC_IN) | \
+ PIN_OSPEED_100M(GPIOH_OSC_OUT) | \
+ PIN_OSPEED_100M(GPIOH_PIN2) | \
+ PIN_OSPEED_100M(GPIOH_PIN3) | \
+ PIN_OSPEED_100M(GPIOH_PIN4) | \
+ PIN_OSPEED_100M(GPIOH_PIN5) | \
+ PIN_OSPEED_100M(GPIOH_PIN6) | \
+ PIN_OSPEED_100M(GPIOH_PIN7) | \
+ PIN_OSPEED_100M(GPIOH_PIN8) | \
+ PIN_OSPEED_100M(GPIOH_PIN9) | \
+ PIN_OSPEED_100M(GPIOH_PIN10) | \
+ PIN_OSPEED_100M(GPIOH_PIN11) | \
+ PIN_OSPEED_100M(GPIOH_PIN12) | \
+ PIN_OSPEED_100M(GPIOH_PIN13) | \
+ PIN_OSPEED_100M(GPIOH_PIN14) | \
+ PIN_OSPEED_100M(GPIOH_PIN15))
+#define VAL_GPIOH_PUPDR (PIN_PUPDR_FLOATING(GPIOH_OSC_IN) | \
+ PIN_PUPDR_FLOATING(GPIOH_OSC_OUT) | \
+ PIN_PUPDR_FLOATING(GPIOH_PIN2) | \
+ PIN_PUPDR_FLOATING(GPIOH_PIN3) | \
+ PIN_PUPDR_FLOATING(GPIOH_PIN4) | \
+ PIN_PUPDR_FLOATING(GPIOH_PIN5) | \
+ PIN_PUPDR_FLOATING(GPIOH_PIN6) | \
+ PIN_PUPDR_FLOATING(GPIOH_PIN7) | \
+ PIN_PUPDR_FLOATING(GPIOH_PIN8) | \
+ PIN_PUPDR_FLOATING(GPIOH_PIN9) | \
+ PIN_PUPDR_FLOATING(GPIOH_PIN10) | \
+ PIN_PUPDR_FLOATING(GPIOH_PIN11) | \
+ PIN_PUPDR_FLOATING(GPIOH_PIN12) | \
+ PIN_PUPDR_FLOATING(GPIOH_PIN13) | \
+ PIN_PUPDR_FLOATING(GPIOH_PIN14) | \
+ PIN_PUPDR_FLOATING(GPIOH_PIN15))
+#define VAL_GPIOH_ODR (PIN_ODR_HIGH(GPIOH_OSC_IN) | \
+ PIN_ODR_HIGH(GPIOH_OSC_OUT) | \
+ PIN_ODR_HIGH(GPIOH_PIN2) | \
+ PIN_ODR_HIGH(GPIOH_PIN3) | \
+ PIN_ODR_HIGH(GPIOH_PIN4) | \
+ PIN_ODR_HIGH(GPIOH_PIN5) | \
+ PIN_ODR_HIGH(GPIOH_PIN6) | \
+ PIN_ODR_HIGH(GPIOH_PIN7) | \
+ PIN_ODR_HIGH(GPIOH_PIN8) | \
+ PIN_ODR_HIGH(GPIOH_PIN9) | \
+ PIN_ODR_HIGH(GPIOH_PIN10) | \
+ PIN_ODR_HIGH(GPIOH_PIN11) | \
+ PIN_ODR_HIGH(GPIOH_PIN12) | \
+ PIN_ODR_HIGH(GPIOH_PIN13) | \
+ PIN_ODR_HIGH(GPIOH_PIN14) | \
+ PIN_ODR_HIGH(GPIOH_PIN15))
+#define VAL_GPIOH_AFRL (PIN_AFIO_AF(GPIOH_OSC_IN, 0) | \
+ PIN_AFIO_AF(GPIOH_OSC_OUT, 0) | \
+ PIN_AFIO_AF(GPIOH_PIN2, 0) | \
+ PIN_AFIO_AF(GPIOH_PIN3, 0) | \
+ PIN_AFIO_AF(GPIOH_PIN4, 0) | \
+ PIN_AFIO_AF(GPIOH_PIN5, 0) | \
+ PIN_AFIO_AF(GPIOH_PIN6, 0) | \
+ PIN_AFIO_AF(GPIOH_PIN7, 0))
+#define VAL_GPIOH_AFRH (PIN_AFIO_AF(GPIOH_PIN8, 0) | \
+ PIN_AFIO_AF(GPIOH_PIN9, 0) | \
+ PIN_AFIO_AF(GPIOH_PIN10, 0) | \
+ PIN_AFIO_AF(GPIOH_PIN11, 0) | \
+ PIN_AFIO_AF(GPIOH_PIN12, 0) | \
+ PIN_AFIO_AF(GPIOH_PIN13, 0) | \
+ PIN_AFIO_AF(GPIOH_PIN14, 0) | \
+ PIN_AFIO_AF(GPIOH_PIN15, 0))
+
+/*
+ * GPIOI setup:
+ *
+ * PI0 - PIN0 (input floating).
+ * PI1 - PIN1 (input floating).
+ * PI2 - PIN2 (input floating).
+ * PI3 - PIN3 (input floating).
+ * PI4 - PIN4 (input floating).
+ * PI5 - PIN5 (input floating).
+ * PI6 - PIN6 (input floating).
+ * PI7 - PIN7 (input floating).
+ * PI8 - PIN8 (input floating).
+ * PI9 - PIN9 (input floating).
+ * PI10 - PIN10 (input floating).
+ * PI11 - PIN11 (input floating).
+ * PI12 - PIN12 (input floating).
+ * PI13 - PIN13 (input floating).
+ * PI14 - PIN14 (input floating).
+ * PI15 - PIN15 (input floating).
+ */
+#define VAL_GPIOI_MODER (PIN_MODE_INPUT(GPIOI_PIN0) | \
+ PIN_MODE_INPUT(GPIOI_PIN1) | \
+ PIN_MODE_INPUT(GPIOI_PIN2) | \
+ PIN_MODE_INPUT(GPIOI_PIN3) | \
+ PIN_MODE_INPUT(GPIOI_PIN4) | \
+ PIN_MODE_INPUT(GPIOI_PIN5) | \
+ PIN_MODE_INPUT(GPIOI_PIN6) | \
+ PIN_MODE_INPUT(GPIOI_PIN7) | \
+ PIN_MODE_INPUT(GPIOI_PIN8) | \
+ PIN_MODE_INPUT(GPIOI_PIN9) | \
+ PIN_MODE_INPUT(GPIOI_PIN10) | \
+ PIN_MODE_INPUT(GPIOI_PIN11) | \
+ PIN_MODE_INPUT(GPIOI_PIN12) | \
+ PIN_MODE_INPUT(GPIOI_PIN13) | \
+ PIN_MODE_INPUT(GPIOI_PIN14) | \
+ PIN_MODE_INPUT(GPIOI_PIN15))
+#define VAL_GPIOI_OTYPER (PIN_OTYPE_PUSHPULL(GPIOI_PIN0) | \
+ PIN_OTYPE_PUSHPULL(GPIOI_PIN1) | \
+ PIN_OTYPE_PUSHPULL(GPIOI_PIN2) | \
+ PIN_OTYPE_PUSHPULL(GPIOI_PIN3) | \
+ PIN_OTYPE_PUSHPULL(GPIOI_PIN4) | \
+ PIN_OTYPE_PUSHPULL(GPIOI_PIN5) | \
+ PIN_OTYPE_PUSHPULL(GPIOI_PIN6) | \
+ PIN_OTYPE_PUSHPULL(GPIOI_PIN7) | \
+ PIN_OTYPE_PUSHPULL(GPIOI_PIN8) | \
+ PIN_OTYPE_PUSHPULL(GPIOI_PIN9) | \
+ PIN_OTYPE_PUSHPULL(GPIOI_PIN10) | \
+ PIN_OTYPE_PUSHPULL(GPIOI_PIN11) | \
+ PIN_OTYPE_PUSHPULL(GPIOI_PIN12) | \
+ PIN_OTYPE_PUSHPULL(GPIOI_PIN13) | \
+ PIN_OTYPE_PUSHPULL(GPIOI_PIN14) | \
+ PIN_OTYPE_PUSHPULL(GPIOI_PIN15))
+#define VAL_GPIOI_OSPEEDR (PIN_OSPEED_100M(GPIOI_PIN0) | \
+ PIN_OSPEED_100M(GPIOI_PIN1) | \
+ PIN_OSPEED_100M(GPIOI_PIN2) | \
+ PIN_OSPEED_100M(GPIOI_PIN3) | \
+ PIN_OSPEED_100M(GPIOI_PIN4) | \
+ PIN_OSPEED_100M(GPIOI_PIN5) | \
+ PIN_OSPEED_100M(GPIOI_PIN6) | \
+ PIN_OSPEED_100M(GPIOI_PIN7) | \
+ PIN_OSPEED_100M(GPIOI_PIN8) | \
+ PIN_OSPEED_100M(GPIOI_PIN9) | \
+ PIN_OSPEED_100M(GPIOI_PIN10) | \
+ PIN_OSPEED_100M(GPIOI_PIN11) | \
+ PIN_OSPEED_100M(GPIOI_PIN12) | \
+ PIN_OSPEED_100M(GPIOI_PIN13) | \
+ PIN_OSPEED_100M(GPIOI_PIN14) | \
+ PIN_OSPEED_100M(GPIOI_PIN15))
+#define VAL_GPIOI_PUPDR (PIN_PUPDR_FLOATING(GPIOI_PIN0) | \
+ PIN_PUPDR_FLOATING(GPIOI_PIN1) | \
+ PIN_PUPDR_FLOATING(GPIOI_PIN2) | \
+ PIN_PUPDR_FLOATING(GPIOI_PIN3) | \
+ PIN_PUPDR_FLOATING(GPIOI_PIN4) | \
+ PIN_PUPDR_FLOATING(GPIOI_PIN5) | \
+ PIN_PUPDR_FLOATING(GPIOI_PIN6) | \
+ PIN_PUPDR_FLOATING(GPIOI_PIN7) | \
+ PIN_PUPDR_FLOATING(GPIOI_PIN8) | \
+ PIN_PUPDR_FLOATING(GPIOI_PIN9) | \
+ PIN_PUPDR_FLOATING(GPIOI_PIN10) | \
+ PIN_PUPDR_FLOATING(GPIOI_PIN11) | \
+ PIN_PUPDR_FLOATING(GPIOI_PIN12) | \
+ PIN_PUPDR_FLOATING(GPIOI_PIN13) | \
+ PIN_PUPDR_FLOATING(GPIOI_PIN14) | \
+ PIN_PUPDR_FLOATING(GPIOI_PIN15))
+#define VAL_GPIOI_ODR (PIN_ODR_HIGH(GPIOI_PIN0) | \
+ PIN_ODR_HIGH(GPIOI_PIN1) | \
+ PIN_ODR_HIGH(GPIOI_PIN2) | \
+ PIN_ODR_HIGH(GPIOI_PIN3) | \
+ PIN_ODR_HIGH(GPIOI_PIN4) | \
+ PIN_ODR_HIGH(GPIOI_PIN5) | \
+ PIN_ODR_HIGH(GPIOI_PIN6) | \
+ PIN_ODR_HIGH(GPIOI_PIN7) | \
+ PIN_ODR_HIGH(GPIOI_PIN8) | \
+ PIN_ODR_HIGH(GPIOI_PIN9) | \
+ PIN_ODR_HIGH(GPIOI_PIN10) | \
+ PIN_ODR_HIGH(GPIOI_PIN11) | \
+ PIN_ODR_HIGH(GPIOI_PIN12) | \
+ PIN_ODR_HIGH(GPIOI_PIN13) | \
+ PIN_ODR_HIGH(GPIOI_PIN14) | \
+ PIN_ODR_HIGH(GPIOI_PIN15))
+#define VAL_GPIOI_AFRL (PIN_AFIO_AF(GPIOI_PIN0, 0) | \
+ PIN_AFIO_AF(GPIOI_PIN1, 0) | \
+ PIN_AFIO_AF(GPIOI_PIN2, 0) | \
+ PIN_AFIO_AF(GPIOI_PIN3, 0) | \
+ PIN_AFIO_AF(GPIOI_PIN4, 0) | \
+ PIN_AFIO_AF(GPIOI_PIN5, 0) | \
+ PIN_AFIO_AF(GPIOI_PIN6, 0) | \
+ PIN_AFIO_AF(GPIOI_PIN7, 0))
+#define VAL_GPIOI_AFRH (PIN_AFIO_AF(GPIOI_PIN8, 0) | \
+ PIN_AFIO_AF(GPIOI_PIN9, 0) | \
+ PIN_AFIO_AF(GPIOI_PIN10, 0) | \
+ PIN_AFIO_AF(GPIOI_PIN11, 0) | \
+ PIN_AFIO_AF(GPIOI_PIN12, 0) | \
+ PIN_AFIO_AF(GPIOI_PIN13, 0) | \
+ PIN_AFIO_AF(GPIOI_PIN14, 0) | \
+ PIN_AFIO_AF(GPIOI_PIN15, 0))
+
+
+#if !defined(_FROM_ASM_)
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void boardInit(void);
+#ifdef __cplusplus
+}
+#endif
+#endif /* _FROM_ASM_ */
+
+#endif /* _BOARD_H_ */
diff --git a/boards/base/Mikromedia-STM32-M4-ILI9341/ChibiOS_Board/cfg/board.chcfg b/boards/base/Mikromedia-STM32-M4-ILI9341/ChibiOS_Board/cfg/board.chcfg
new file mode 100644
index 00000000..a5593446
--- /dev/null
+++ b/boards/base/Mikromedia-STM32-M4-ILI9341/ChibiOS_Board/cfg/board.chcfg
@@ -0,0 +1,1186 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--mikromedia STM32F4-->
+<board
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="http://www.chibios.org/xml/schema/boards/stm32f4xx_board.xsd">
+ <configuration_settings>
+ <templates_path>resources/gencfg/processors/boards/stm32f4xx/templates</templates_path>
+ <output_path>..</output_path>
+ </configuration_settings>
+ <board_name>mikromedia STM32-M4</board_name>
+ <board_id>MIKROE_MIKROMEDIA_M4</board_id>
+ <board_functions></board_functions>
+ <clocks HSEFrequency="16000000" HSEBypass="false" LSEFrequency="32768" VDD="330" />
+ <ports>
+ <GPIOA>
+ <pin0
+ ID="VSENSE"
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Analog"
+ Alternate="0" />
+ <pin1
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="PullUp"
+ Mode="Input"
+ Alternate="0" />
+ <pin2
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="PullUp"
+ Mode="Input"
+ Alternate="0" />
+ <pin3
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="PullUp"
+ Mode="Input"
+ Alternate="0" />
+ <pin4
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Alternate"
+ Alternate="6" />
+ <pin5
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="High"
+ Resistor="Floating"
+ Mode="Alternate"
+ Alternate="5" />
+ <pin6
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="High"
+ Resistor="Floating"
+ Mode="Alternate"
+ Alternate="5" />
+ <pin7
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="High"
+ Resistor="Floating"
+ Mode="Alternate"
+ Alternate="5" />
+ <pin8
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="PullUp"
+ Mode="Input"
+ Alternate="0" ></pin8>
+ <pin9
+ ID="VBUS_FS"
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin10
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin11
+ ID="OTG_FS_DM"
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Alternate"
+ Alternate="10" />
+ <pin12
+ ID="OTG_FS_DP"
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Alternate"
+ Alternate="10" />
+ <pin13
+ ID="TMS"
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Alternate"
+ Alternate="0" />
+ <pin14
+ ID="TCK"
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Alternate"
+ Alternate="0" />
+ <pin15
+ ID="TDI"
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="PullUp"
+ Mode="Input"
+ Alternate="0" />
+ </GPIOA>
+ <GPIOB>
+ <pin0
+ ID="LCD_YD"
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Analog"
+ Alternate="0" />
+ <pin1
+ ID="LCD_XL"
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Analog"
+ Alternate="0" />
+ <pin2
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="PullUp"
+ Mode="Input"
+ Alternate="0" />
+ <pin3
+ ID="TDO"
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Alternate"
+ Alternate="0" ></pin3>
+ <pin4
+ ID="TRST"
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="PullUp"
+ Mode="Input"
+ Alternate="0" />
+ <pin5
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="PullUp"
+ Mode="Input"
+ Alternate="0" />
+ <pin6
+ ID="SCL1"
+ Type="OpenDrain"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Alternate"
+ Alternate="4" />
+ <pin7
+ ID="SDA1"
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="PullUp"
+ Mode="Input"
+ Alternate="4" />
+ <pin8
+ ID="DRIVEA"
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Output"
+ Alternate="0" />
+ <pin9
+ ID="DRIVEB"
+ Type="OpenDrain"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Output"
+ Alternate="0" ></pin9>
+ <pin10
+ ID="SCL2"
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="PullUp"
+ Mode="Input"
+ Alternate="0" />
+ <pin11
+ ID="SDA2"
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="PullUp"
+ Mode="Input"
+ Alternate="0" />
+ <pin12
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="PullUp"
+ Mode="Input"
+ Alternate="0" />
+ <pin13
+ ID="SCK2"
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="PullUp"
+ Mode="Input"
+ Alternate="0" />
+ <pin14
+ ID="MISO2"
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="PullUp"
+ Mode="Input"
+ Alternate="0" />
+ <pin15
+ ID="MOSI2"
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="PullUp"
+ Mode="Input"
+ Alternate="0" />
+ </GPIOB>
+ <GPIOC>
+ <pin0
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Output"
+ Alternate="0" />
+ <pin1
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="PullUp"
+ Mode="Input"
+ Alternate="0" />
+ <pin2
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="PullUp"
+ Mode="Input"
+ Alternate="0" />
+ <pin3
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="PullUp"
+ Mode="Input"
+ Alternate="0" ></pin3>
+ <pin4
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="PullUp"
+ Mode="Input"
+ Alternate="0" />
+ <pin5
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="PullUp"
+ Mode="Input"
+ Alternate="0" />
+ <pin6
+ ID="MP3_DREQ"
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="PullUp"
+ Mode="Input"
+ Alternate="0" />
+ <pin7
+ ID="MP3_RST"
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Alternate"
+ Alternate="6" />
+ <pin8
+ ID="MP3_CS"
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="PullUp"
+ Mode="Output"
+ Alternate="0" />
+ <pin9
+ ID="MP3_DCS"
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="PullUp"
+ Mode="Input"
+ Alternate="0" />
+ <pin10
+ ID="SCK3"
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Alternate"
+ Alternate="6" />
+ <pin11
+ ID="MISO3"
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Alternate"
+ Alternate="6" />
+ <pin12
+ ID="MOSI3"
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Alternate"
+ Alternate="6" />
+ <pin13
+ ID="STAT"
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="PullUp"
+ Mode="Input"
+ Alternate="0" />
+ <pin14
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="PullUp"
+ Mode="Input"
+ Alternate="0" />
+ <pin15
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="PullUp"
+ Mode="Input"
+ Alternate="0" />
+ </GPIOC>
+ <GPIOD>
+ <pin0
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="PullUp"
+ Mode="Input"
+ Alternate="0" />
+ <pin1
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="PullUp"
+ Mode="Input"
+ Alternate="0" />
+ <pin2
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="PullUp"
+ Mode="Input"
+ Alternate="0" />
+ <pin3
+ ID="SD_CS"
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Output"
+ Alternate="0" />
+ <pin4
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Output"
+ Alternate="0" />
+ <pin5
+ ID="TX2"
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Alternate"
+ Alternate="7" ></pin5>
+ <pin6
+ ID="RX2"
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="PullUp"
+ Mode="Alternate"
+ Alternate="7" />
+ <pin7
+ ID="FLASH_CS"
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="PullUp"
+ Mode="Output"
+ Alternate="0" />
+ <pin8
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="PullUp"
+ Mode="Input"
+ Alternate="0" />
+ <pin9
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="PullUp"
+ Mode="Input"
+ Alternate="0" />
+ <pin10
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="PullUp"
+ Mode="Input"
+ Alternate="0" />
+ <pin11
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="PullUp"
+ Mode="Input"
+ Alternate="0" />
+ <pin12
+ ID=""
+ Type="PushPull"
+ Level="Low"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Output"
+ Alternate="0" />
+ <pin13
+ ID=""
+ Type="PushPull"
+ Level="Low"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Output"
+ Alternate="0" />
+ <pin14
+ ID=""
+ Type="PushPull"
+ Level="Low"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Output"
+ Alternate="0" ></pin14>
+ <pin15
+ ID="SD_CD"
+ Type="PushPull"
+ Level="Low"
+ Speed="Maximum"
+ Resistor="PullUp"
+ Mode="Input"
+ Alternate="0" />
+ </GPIOD>
+ <GPIOE>
+ <pin0
+ ID="TD0"
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Output"
+ Alternate="0" />
+ <pin1
+ ID="TD1"
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Output"
+ Alternate="0" />
+ <pin2
+ ID="TD2"
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Output"
+ Alternate="0" />
+ <pin3
+ ID="TD3"
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Output"
+ Alternate="0" />
+ <pin4
+ ID="TD4"
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Output"
+ Alternate="0" />
+ <pin5
+ ID="TD5"
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Output"
+ Alternate="0" />
+ <pin6
+ ID="TD6"
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Output"
+ Alternate="0" />
+ <pin7
+ ID="TD7"
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Output"
+ Alternate="0" />
+ <pin8
+ ID="LCD_RST"
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Output"
+ Alternate="0" />
+ <pin9
+ ID="LCD_BLED"
+ Type="PushPull"
+ Level="Low"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Output"
+ Alternate="0" />
+ <pin10
+ ID="PMRD"
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Output"
+ Alternate="0" />
+ <pin11
+ ID="PMWR"
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Output"
+ Alternate="0" />
+ <pin12
+ ID="LCD_RS"
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Output"
+ Alternate="0" />
+ <pin13
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin14
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin15
+ ID="LCD_CS"
+ Type="PushPull"
+ Level="Low"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Output"
+ Alternate="0" />
+ </GPIOE>
+ <GPIOF>
+ <pin0
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin1
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin2
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin3
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin4
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin5
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin6
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin7
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin8
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin9
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin10
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin11
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin12
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin13
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin14
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin15
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ </GPIOF>
+ <GPIOG>
+ <pin0
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin1
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin2
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin3
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin4
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin5
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin6
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin7
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin8
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin9
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin10
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin11
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin12
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin13
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin14
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin15
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ </GPIOG>
+ <GPIOH>
+ <pin0
+ ID="OSC_IN"
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin1
+ ID="OSC_OUT"
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin2
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" ></pin2>
+ <pin3
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin4
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin5
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin6
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin7
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin8
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin9
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin10
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin11
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin12
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin13
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin14
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin15
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ </GPIOH>
+ <GPIOI>
+ <pin0
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin1
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin2
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin3
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin4
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin5
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin6
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin7
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin8
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin9
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin10
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin11
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin12
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin13
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin14
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ <pin15
+ ID=""
+ Type="PushPull"
+ Level="High"
+ Speed="Maximum"
+ Resistor="Floating"
+ Mode="Input"
+ Alternate="0" />
+ </GPIOI>
+ </ports>
+</board>
diff --git a/boards/base/Mikromedia-STM32-M4-ILI9341/ChibiOS_Board/flash_memory.c b/boards/base/Mikromedia-STM32-M4-ILI9341/ChibiOS_Board/flash_memory.c
new file mode 100644
index 00000000..a27a3db5
--- /dev/null
+++ b/boards/base/Mikromedia-STM32-M4-ILI9341/ChibiOS_Board/flash_memory.c
@@ -0,0 +1,127 @@
+#include "hal.h"
+#include "flash_memory.h"
+
+static const unsigned short _SERIAL_FLASH_CMD_RDID = 0x9F; // 25P80
+static const unsigned short _SERIAL_FLASH_CMD_READ = 0x03;
+static const unsigned short _SERIAL_FLASH_CMD_WRITE = 0x02;
+static const unsigned short _SERIAL_FLASH_CMD_WREN = 0x06;
+static const unsigned short _SERIAL_FLASH_CMD_RDSR = 0x05;
+static const unsigned short _SERIAL_FLASH_CMD_ERASE = 0xC7; // 25P80
+static const unsigned short _SERIAL_FLASH_CMD_EWSR = 0x06; // 25P80
+static const unsigned short _SERIAL_FLASH_CMD_WRSR = 0x01;
+static const unsigned short _SERIAL_FLASH_CMD_SER = 0xD8; //25P80
+
+static const SPIConfig flash_spicfg = {
+ NULL,
+ GPIOD,
+ GPIOD_FLASH_CS,
+ 0
+};
+
+bool flash_is_write_busy(void) {
+ static uint8_t is_write_busy_cmd[1];
+ is_write_busy_cmd[0] = _SERIAL_FLASH_CMD_RDSR;
+
+ uint8_t result[1];
+
+ spiAcquireBus(&SPID3);
+ spiStart(&SPID3, &flash_spicfg);
+ spiSelect(&SPID3);
+ spiSend(&SPID3, sizeof(is_write_busy_cmd), is_write_busy_cmd);
+ spiReceive(&SPID3, sizeof(result), result);
+ spiUnselect(&SPID3);
+ spiReleaseBus(&SPID3);
+
+ return result[0]&0x01;
+}
+
+void flash_write_enable(void) {
+ spiAcquireBus(&SPID3);
+ spiStart(&SPID3, &flash_spicfg);
+ spiSelect(&SPID3);
+ spiSend(&SPID3, 1, &_SERIAL_FLASH_CMD_WREN);
+ spiUnselect(&SPID3);
+ spiReleaseBus(&SPID3);
+}
+
+void flash_sector_erase(uint32_t sector) {
+ flash_write_enable();
+ static uint8_t sector_erase_cmd[4];
+ sector_erase_cmd[0] = _SERIAL_FLASH_CMD_SER;
+ sector_erase_cmd[1] = (sector >> 16) & 0xFF;
+ sector_erase_cmd[2] = (sector >> 8) & 0xFF;
+ sector_erase_cmd[3] = sector & 0xFF;
+
+
+ spiAcquireBus(&SPID3);
+ spiStart(&SPID3, &flash_spicfg);
+ spiSelect(&SPID3);
+ spiSend(&SPID3, sizeof(sector_erase_cmd), sector_erase_cmd);
+ spiUnselect(&SPID3);
+ spiReleaseBus(&SPID3);
+
+ /* wait for complete */
+ while(flash_is_write_busy());
+}
+
+void flash_read(uint32_t address, size_t bytes, uint8_t *out) {
+ static uint8_t sector_read_cmd[4];
+ sector_read_cmd[0] = _SERIAL_FLASH_CMD_READ;
+ sector_read_cmd[1] = (address >> 16) & 0xFF;
+ sector_read_cmd[2] = (address >> 8) & 0xFF;
+ sector_read_cmd[3] = address & 0xFF;
+
+ spiAcquireBus(&SPID3);
+ spiStart(&SPID3, &flash_spicfg);
+ spiSelect(&SPID3);
+ spiSend(&SPID3, sizeof(sector_read_cmd), sector_read_cmd);
+ spiReceive(&SPID3, bytes, out);
+ spiUnselect(&SPID3);
+ spiReleaseBus(&SPID3);
+}
+
+void flash_write(uint32_t address, size_t bytes, const uint8_t *data) {
+ static uint8_t flash_write_cmd[4];
+
+ flash_write_enable();
+
+ flash_write_cmd[0] = _SERIAL_FLASH_CMD_WRITE;
+ flash_write_cmd[1] = (address >> 16) & 0xFF;
+ flash_write_cmd[2] = (address >> 8) & 0xFF;
+ flash_write_cmd[3] = address & 0xFF;
+
+ spiAcquireBus(&SPID3);
+ spiStart(&SPID3, &flash_spicfg);
+ spiSelect(&SPID3);
+ spiSend(&SPID3, sizeof(flash_write_cmd), flash_write_cmd);
+ spiSend(&SPID3, bytes, data);
+ spiUnselect(&SPID3);
+ spiReleaseBus(&SPID3);
+
+ /* wait for complete */
+ while(flash_is_write_busy());
+}
+
+bool flash_tp_calibrated(void) {
+ uint8_t out[1];
+ flash_read(0x0F0000, 1, out);
+
+ return (out[0] == 0x01);
+}
+
+void flash_tp_calibration_save(uint16_t instance, const uint8_t *calbuf, size_t sz) {
+ if (instance) return;
+ flash_sector_erase(0x0F0000);
+ uint8_t calibrated = 0x01;
+ flash_write(0x0F0000, 1, &calibrated);
+ flash_write(0x0F0001, sz, calbuf);
+}
+const char *flash_tp_calibration_load(uint16_t instance) {
+ static uint8_t foo[24];
+
+ if (instance) return 0;
+ if (!flash_tp_calibrated()) return 0;
+ flash_read(0x0F0001, 24, foo);
+
+ return (char *)foo;
+}
diff --git a/boards/base/Mikromedia-STM32-M4-ILI9341/ChibiOS_Board/flash_memory.h b/boards/base/Mikromedia-STM32-M4-ILI9341/ChibiOS_Board/flash_memory.h
new file mode 100644
index 00000000..2dcc9206
--- /dev/null
+++ b/boards/base/Mikromedia-STM32-M4-ILI9341/ChibiOS_Board/flash_memory.h
@@ -0,0 +1,6 @@
+void flash_sector_erase(uint32_t sector);
+void flash_read(uint32_t address, size_t bytes, uint8_t *out);
+void flash_write(uint32_t address, size_t bytes, const uint8_t *data);
+bool flash_tp_calibrated(void);
+void flash_tp_calibration_save(uint16_t instance, const uint8_t *calbuf, size_t sz);
+const char *flash_tp_calibration_load(uint16_t instance);
diff --git a/boards/base/Mikromedia-STM32-M4-ILI9341/board.mk b/boards/base/Mikromedia-STM32-M4-ILI9341/board.mk
new file mode 100644
index 00000000..e466621c
--- /dev/null
+++ b/boards/base/Mikromedia-STM32-M4-ILI9341/board.mk
@@ -0,0 +1,5 @@
+GFXINC += $(GFXLIB)/boards/base/Mikromedia-STM32-M4-ILI9341
+GFXSRC +=
+GFXDEFS += -DGFX_USE_OS_CHIBIOS=TRUE
+include $(GFXLIB)/drivers/gdisp/ILI9341/gdisp_lld.mk
+include $(GFXLIB)/drivers/ginput/touch/MCU/ginput_lld.mk
diff --git a/boards/base/Mikromedia-STM32-M4-ILI9341/board_ILI9341.h b/boards/base/Mikromedia-STM32-M4-ILI9341/board_ILI9341.h
new file mode 100644
index 00000000..c73c68a9
--- /dev/null
+++ b/boards/base/Mikromedia-STM32-M4-ILI9341/board_ILI9341.h
@@ -0,0 +1,124 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file boards/base/Mikromedia-STM32-M4-ILI9341/board_ILI9341.h
+ * @brief GDISP Graphics Driver subsystem low level driver source for the ILI9341 display.
+ */
+
+#ifndef _GDISP_LLD_BOARD_H
+#define _GDISP_LLD_BOARD_H
+
+// For a multiple display configuration we would put all this in a structure and then
+// set g->board to that structure.
+#define SET_CS palSetPad(GPIOE, GPIOE_LCD_CS);
+#define CLR_CS palClearPad(GPIOE, GPIOE_LCD_CS);
+#define SET_RS palSetPad(GPIOE, GPIOE_LCD_RS);
+#define CLR_RS palClearPad(GPIOE, GPIOE_LCD_RS);
+#define SET_WR palSetPad(GPIOE, GPIOE_PMWR);
+#define CLR_WR palClearPad(GPIOE, GPIOE_PMWR);
+#define SET_RD palSetPad(GPIOE, GPIOE_PMRD);
+#define CLR_RD palClearPad(GPIOE, GPIOE_PMRD);
+
+static inline void init_board(GDisplay *g) {
+
+ // As we are not using multiple displays we set g->board to NULL as we don't use it.
+ g->board = 0;
+
+ switch(g->controllerdisplay) {
+ case 0: // Set up for Display 0
+ /* Configure the pins to a well know state */
+ SET_RS;
+ SET_RD;
+ SET_WR;
+ CLR_CS;
+ break;
+ }
+}
+
+static inline void post_init_board(GDisplay *g) {
+ (void) g;
+}
+
+static inline void setpin_reset(GDisplay *g, bool_t state) {
+ (void) g;
+ if(state) {
+ // reset lcd
+ palClearPad(GPIOE, GPIOE_LCD_RST);
+ } else {
+ palSetPad(GPIOE, GPIOE_LCD_RST);
+ }
+}
+
+static inline void set_backlight(GDisplay *g, uint8_t percent) {
+ (void) g;
+ // TODO: can probably pwm this
+ if(percent) {
+ // turn back light on
+ palSetPad(GPIOE, GPIOE_LCD_BLED);
+ } else {
+ // turn off
+ palClearPad(GPIOE, GPIOE_LCD_BLED);
+ }
+}
+
+static inline void acquire_bus(GDisplay *g) {
+ (void) g;
+}
+
+static inline void release_bus(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Short delay
+ *
+ * @param[in] dly Length of delay
+ *
+ * @notapi
+ */
+static inline void ili9341_delay(uint16_t dly) {
+ static uint16_t i;
+ for(i = 0; i < dly; i++)
+ asm("nop");
+}
+
+static inline void write_index(GDisplay *g, uint16_t index) {
+ (void) g;
+ palWriteGroup(GPIOE, 0x00FF, 0, index);
+ CLR_RS; CLR_WR; ili9341_delay(1); SET_WR; ili9341_delay(1); SET_RS;
+}
+
+static inline void write_data(GDisplay *g, uint16_t data) {
+ (void) g;
+ palWriteGroup(GPIOE, 0x00FF, 0, data);
+ CLR_WR; ili9341_delay(1); SET_WR; ili9341_delay(1);
+}
+
+static inline void setreadmode(GDisplay *g) {
+ (void) g;
+ // change pin mode to digital input
+ palSetGroupMode(GPIOE, PAL_WHOLE_PORT, 0, PAL_MODE_INPUT);
+}
+
+static inline void setwritemode(GDisplay *g) {
+ (void) g;
+ // change pin mode back to digital output
+ palSetGroupMode(GPIOE, PAL_WHOLE_PORT, 0, PAL_MODE_OUTPUT_PUSHPULL);
+}
+
+static inline uint16_t read_data(GDisplay *g) {
+ uint16_t value;
+ (void) g;
+ CLR_RD;
+ value = palReadPort(GPIOE);
+ value = palReadPort(GPIOE);
+ SET_RD;
+ return value;
+}
+
+#endif /* _GDISP_LLD_BOARD_H */
diff --git a/boards/base/Mikromedia-STM32-M4-ILI9341/example/Makefile b/boards/base/Mikromedia-STM32-M4-ILI9341/example/Makefile
new file mode 100644
index 00000000..6fca731e
--- /dev/null
+++ b/boards/base/Mikromedia-STM32-M4-ILI9341/example/Makefile
@@ -0,0 +1,232 @@
+##############################################################################
+# Build global options
+# NOTE: Can be overridden externally.
+#
+
+# Compiler options here.
+ifeq ($(USE_OPT),)
+ # Replace -O0 with -O2 for a production build. -O2 just messes with the debugger.
+ USE_OPT = -O0 -g -fomit-frame-pointer -falign-functions=16
+endif
+
+# C specific options here (added to USE_OPT).
+ifeq ($(USE_COPT),)
+ USE_COPT =
+endif
+
+# C++ specific options here (added to USE_OPT).
+ifeq ($(USE_CPPOPT),)
+ USE_CPPOPT = -fno-rtti
+endif
+
+# Enable this if you want the linker to remove unused code and data
+ifeq ($(USE_LINK_GC),)
+ USE_LINK_GC = yes
+endif
+
+# If enabled, this option allows to compile the application in THUMB mode.
+ifeq ($(USE_THUMB),)
+ USE_THUMB = yes
+endif
+
+# Enable this if you want to see the full log while compiling.
+ifeq ($(USE_VERBOSE_COMPILE),)
+ USE_VERBOSE_COMPILE = no
+endif
+
+#
+# Build global options
+##############################################################################
+
+##############################################################################
+# Architecture or project specific options
+#
+
+# Enables the use of FPU on Cortex-M4.
+# Enable this if you really want to use the STM FWLib.
+ifeq ($(USE_FPU),)
+ USE_FPU = no
+endif
+
+# Enable this if you really want to use the STM FWLib.
+ifeq ($(USE_FWLIB),)
+ USE_FWLIB = no
+endif
+
+#
+# Architecture or project specific options
+##############################################################################
+
+##############################################################################
+# Project, sources and paths
+#
+
+SW = ..
+
+# Define project name here
+PROJECT = ch
+
+# Imported source files and paths
+CHIBIOS = ../ChibiOS
+#include $(CHIBIOS)/boards/MIKROMEDIA_STM32_M4/board.mk # Not a standard ChibiOS supported board
+include $(CHIBIOS)/os/hal/platforms/STM32F4xx/platform.mk
+include $(CHIBIOS)/os/hal/hal.mk
+include $(CHIBIOS)/os/ports/GCC/ARMCMx/STM32F4xx/port.mk
+include $(CHIBIOS)/os/kernel/kernel.mk
+LDSCRIPT= $(PORTLD)/STM32F407xG.ld
+
+# Imported source files and paths for uGFX
+GFXLIB = ../uGFX
+include $(GFXLIB)/gfx.mk
+include $(GFXLIB)/boards/base/Mikromedia-STM32-M4-ILI9341/board.mk
+include $(GFXLIB)/boards/base/Mikromedia-STM32-M4-ILI9341/ChibiOS_Board/board.mk # The replacement ChibiOS board files
+
+# Where is our source code - alter these for your project.
+MYFILES = $(GFXLIB)/demos/modules/gdisp/basics
+MYCSRC = $(MYFILES)/main.c
+
+# C sources that can be compiled in ARM or THUMB mode depending on the global
+# setting.
+CSRC = $(PORTSRC) \
+ $(KERNSRC) \
+ $(TESTSRC) \
+ $(HALSRC) \
+ $(PLATFORMSRC) \
+ $(BOARDSRC) \
+ $(GFXSRC) \
+ $(MYCSRC)
+
+# C++ sources that can be compiled in ARM or THUMB mode depending on the global
+# setting.
+CPPSRC =
+
+# C sources to be compiled in ARM mode regardless of the global setting.
+# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
+# option that results in lower performance and larger code size.
+ACSRC =
+
+# C++ sources to be compiled in ARM mode regardless of the global setting.
+# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
+# option that results in lower performance and larger code size.
+ACPPSRC =
+
+# C sources to be compiled in THUMB mode regardless of the global setting.
+# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
+# option that results in lower performance and larger code size.
+TCSRC =
+
+# C sources to be compiled in THUMB mode regardless of the global setting.
+# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
+# option that results in lower performance and larger code size.
+TCPPSRC =
+
+# List ASM source files here
+ASMSRC = $(PORTASM)
+
+INCDIR = $(PORTINC) $(KERNINC) $(TESTINC) \
+ $(HALINC) $(PLATFORMINC) $(BOARDINC) \
+ $(GFXINC) \
+ $(MYFILES)
+
+#
+# Project, sources and paths
+##############################################################################
+
+##############################################################################
+# Compiler settings
+#
+
+MCU = cortex-m4
+
+#TRGT = arm-elf-
+TRGT = arm-none-eabi-
+CC = $(TRGT)gcc
+CPPC = $(TRGT)g++
+# Enable loading with g++ only if you need C++ runtime support.
+# NOTE: You can use C++ even without C++ support if you are careful. C++
+# runtime support makes code size explode.
+LD = $(TRGT)gcc
+#LD = $(TRGT)g++
+CP = $(TRGT)objcopy
+AS = $(TRGT)gcc -x assembler-with-cpp
+OD = $(TRGT)objdump
+HEX = $(CP) -O ihex
+BIN = $(CP) -O binary
+
+# ARM-specific options here
+AOPT =
+
+# THUMB-specific options here
+TOPT = -mthumb -DTHUMB
+
+# Define C warning options here
+CWARN = -Wall -Wextra -Wstrict-prototypes
+
+# Define C++ warning options here
+CPPWARN = -Wall -Wextra
+
+#
+# Compiler settings
+##############################################################################
+
+##############################################################################
+# Start of default section
+#
+
+# List all default C defines here, like -D_DEBUG=1
+DDEFS = $(GFXDEFS)
+
+# List all default ASM defines here, like -D_DEBUG=1
+DADEFS =
+
+# List all default directories to look for include files here
+DINCDIR =
+
+# List the default directory to look for the libraries here
+DLIBDIR =
+
+# List all default libraries here
+DLIBS =
+
+#
+# End of default section
+##############################################################################
+
+##############################################################################
+# Start of user section
+#
+
+# List all user C define here, like -D_DEBUG=1
+UDEFS =
+
+# Define ASM defines here
+UADEFS =
+
+# List all user directories here
+UINCDIR =
+
+# List the user directory to look for the libraries here
+ULIBDIR =
+
+# List all user libraries here
+ULIBS =
+
+#
+# End of user defines
+##############################################################################
+
+ifeq ($(USE_FPU),yes)
+ USE_OPT += -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -fsingle-precision-constant
+ DDEFS += -DCORTEX_USE_FPU=TRUE
+else
+ DDEFS += -DCORTEX_USE_FPU=FALSE
+endif
+
+ifeq ($(USE_FWLIB),yes)
+ include $(CHIBIOS)/ext/stm32lib/stm32lib.mk
+ CSRC += $(STM32SRC)
+ INCDIR += $(STM32INC)
+ USE_OPT += -DUSE_STDPERIPH_DRIVER
+endif
+
+include $(CHIBIOS)/os/ports/GCC/ARMCMx/rules.mk
diff --git a/boards/base/Mikromedia-STM32-M4-ILI9341/example/chconf.h b/boards/base/Mikromedia-STM32-M4-ILI9341/example/chconf.h
new file mode 100644
index 00000000..f4682cb9
--- /dev/null
+++ b/boards/base/Mikromedia-STM32-M4-ILI9341/example/chconf.h
@@ -0,0 +1,531 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+
+ 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.
+*/
+
+/**
+ * @file templates/chconf.h
+ * @brief Configuration file template.
+ * @details A copy of this file must be placed in each project directory, it
+ * contains the application specific kernel settings.
+ *
+ * @addtogroup config
+ * @details Kernel related settings and hooks.
+ * @{
+ */
+
+#ifndef _CHCONF_H_
+#define _CHCONF_H_
+
+/*===========================================================================*/
+/**
+ * @name Kernel parameters and options
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief System tick frequency.
+ * @details Frequency of the system timer that drives the system ticks. This
+ * setting also defines the system tick time unit.
+ */
+#if !defined(CH_FREQUENCY) || defined(__DOXYGEN__)
+#define CH_FREQUENCY 1000
+#endif
+
+/**
+ * @brief Round robin interval.
+ * @details This constant is the number of system ticks allowed for the
+ * threads before preemption occurs. Setting this value to zero
+ * disables the preemption for threads with equal priority and the
+ * round robin becomes cooperative. Note that higher priority
+ * threads can still preempt, the kernel is always preemptive.
+ *
+ * @note Disabling the round robin preemption makes the kernel more compact
+ * and generally faster.
+ */
+#if !defined(CH_TIME_QUANTUM) || defined(__DOXYGEN__)
+#define CH_TIME_QUANTUM 20
+#endif
+
+/**
+ * @brief Managed RAM size.
+ * @details Size of the RAM area to be managed by the OS. If set to zero
+ * then the whole available RAM is used. The core memory is made
+ * available to the heap allocator and/or can be used directly through
+ * the simplified core memory allocator.
+ *
+ * @note In order to let the OS manage the whole RAM the linker script must
+ * provide the @p __heap_base__ and @p __heap_end__ symbols.
+ * @note Requires @p CH_USE_MEMCORE.
+ */
+#if !defined(CH_MEMCORE_SIZE) || defined(__DOXYGEN__)
+#define CH_MEMCORE_SIZE 0
+#endif
+
+/**
+ * @brief Idle thread automatic spawn suppression.
+ * @details When this option is activated the function @p chSysInit()
+ * does not spawn the idle thread automatically. The application has
+ * then the responsibility to do one of the following:
+ * - Spawn a custom idle thread at priority @p IDLEPRIO.
+ * - Change the main() thread priority to @p IDLEPRIO then enter
+ * an endless loop. In this scenario the @p main() thread acts as
+ * the idle thread.
+ * .
+ * @note Unless an idle thread is spawned the @p main() thread must not
+ * enter a sleep state.
+ */
+#if !defined(CH_NO_IDLE_THREAD) || defined(__DOXYGEN__)
+#define CH_NO_IDLE_THREAD FALSE
+#endif
+
+/** @} */
+
+/*===========================================================================*/
+/**
+ * @name Performance options
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief OS optimization.
+ * @details If enabled then time efficient rather than space efficient code
+ * is used when two possible implementations exist.
+ *
+ * @note This is not related to the compiler optimization options.
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_OPTIMIZE_SPEED) || defined(__DOXYGEN__)
+#define CH_OPTIMIZE_SPEED TRUE
+#endif
+
+/** @} */
+
+/*===========================================================================*/
+/**
+ * @name Subsystem options
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief Threads registry APIs.
+ * @details If enabled then the registry APIs are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_USE_REGISTRY) || defined(__DOXYGEN__)
+#define CH_USE_REGISTRY TRUE
+#endif
+
+/**
+ * @brief Threads synchronization APIs.
+ * @details If enabled then the @p chThdWait() function is included in
+ * the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_USE_WAITEXIT) || defined(__DOXYGEN__)
+#define CH_USE_WAITEXIT TRUE
+#endif
+
+/**
+ * @brief Semaphores APIs.
+ * @details If enabled then the Semaphores APIs are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_USE_SEMAPHORES) || defined(__DOXYGEN__)
+#define CH_USE_SEMAPHORES TRUE
+#endif
+
+/**
+ * @brief Semaphores queuing mode.
+ * @details If enabled then the threads are enqueued on semaphores by
+ * priority rather than in FIFO order.
+ *
+ * @note The default is @p FALSE. Enable this if you have special requirements.
+ * @note Requires @p CH_USE_SEMAPHORES.
+ */
+#if !defined(CH_USE_SEMAPHORES_PRIORITY) || defined(__DOXYGEN__)
+#define CH_USE_SEMAPHORES_PRIORITY FALSE
+#endif
+
+/**
+ * @brief Atomic semaphore API.
+ * @details If enabled then the semaphores the @p chSemSignalWait() API
+ * is included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_USE_SEMAPHORES.
+ */
+#if !defined(CH_USE_SEMSW) || defined(__DOXYGEN__)
+#define CH_USE_SEMSW TRUE
+#endif
+
+/**
+ * @brief Mutexes APIs.
+ * @details If enabled then the mutexes APIs are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_USE_MUTEXES) || defined(__DOXYGEN__)
+#define CH_USE_MUTEXES TRUE
+#endif
+
+/**
+ * @brief Conditional Variables APIs.
+ * @details If enabled then the conditional variables APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_USE_MUTEXES.
+ */
+#if !defined(CH_USE_CONDVARS) || defined(__DOXYGEN__)
+#define CH_USE_CONDVARS TRUE
+#endif
+
+/**
+ * @brief Conditional Variables APIs with timeout.
+ * @details If enabled then the conditional variables APIs with timeout
+ * specification are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_USE_CONDVARS.
+ */
+#if !defined(CH_USE_CONDVARS_TIMEOUT) || defined(__DOXYGEN__)
+#define CH_USE_CONDVARS_TIMEOUT TRUE
+#endif
+
+/**
+ * @brief Events Flags APIs.
+ * @details If enabled then the event flags APIs are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_USE_EVENTS) || defined(__DOXYGEN__)
+#define CH_USE_EVENTS TRUE
+#endif
+
+/**
+ * @brief Events Flags APIs with timeout.
+ * @details If enabled then the events APIs with timeout specification
+ * are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_USE_EVENTS.
+ */
+#if !defined(CH_USE_EVENTS_TIMEOUT) || defined(__DOXYGEN__)
+#define CH_USE_EVENTS_TIMEOUT TRUE
+#endif
+
+/**
+ * @brief Synchronous Messages APIs.
+ * @details If enabled then the synchronous messages APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_USE_MESSAGES) || defined(__DOXYGEN__)
+#define CH_USE_MESSAGES TRUE
+#endif
+
+/**
+ * @brief Synchronous Messages queuing mode.
+ * @details If enabled then messages are served by priority rather than in
+ * FIFO order.
+ *
+ * @note The default is @p FALSE. Enable this if you have special requirements.
+ * @note Requires @p CH_USE_MESSAGES.
+ */
+#if !defined(CH_USE_MESSAGES_PRIORITY) || defined(__DOXYGEN__)
+#define CH_USE_MESSAGES_PRIORITY FALSE
+#endif
+
+/**
+ * @brief Mailboxes APIs.
+ * @details If enabled then the asynchronous messages (mailboxes) APIs are
+ * included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_USE_SEMAPHORES.
+ */
+#if !defined(CH_USE_MAILBOXES) || defined(__DOXYGEN__)
+#define CH_USE_MAILBOXES TRUE
+#endif
+
+/**
+ * @brief I/O Queues APIs.
+ * @details If enabled then the I/O queues APIs are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_USE_QUEUES) || defined(__DOXYGEN__)
+#define CH_USE_QUEUES TRUE
+#endif
+
+/**
+ * @brief Core Memory Manager APIs.
+ * @details If enabled then the core memory manager APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_USE_MEMCORE) || defined(__DOXYGEN__)
+#define CH_USE_MEMCORE TRUE
+#endif
+
+/**
+ * @brief Heap Allocator APIs.
+ * @details If enabled then the memory heap allocator APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_USE_MEMCORE and either @p CH_USE_MUTEXES or
+ * @p CH_USE_SEMAPHORES.
+ * @note Mutexes are recommended.
+ */
+#if !defined(CH_USE_HEAP) || defined(__DOXYGEN__)
+#define CH_USE_HEAP TRUE
+#endif
+
+/**
+ * @brief C-runtime allocator.
+ * @details If enabled the the heap allocator APIs just wrap the C-runtime
+ * @p malloc() and @p free() functions.
+ *
+ * @note The default is @p FALSE.
+ * @note Requires @p CH_USE_HEAP.
+ * @note The C-runtime may or may not require @p CH_USE_MEMCORE, see the
+ * appropriate documentation.
+ */
+#if !defined(CH_USE_MALLOC_HEAP) || defined(__DOXYGEN__)
+#define CH_USE_MALLOC_HEAP FALSE
+#endif
+
+/**
+ * @brief Memory Pools Allocator APIs.
+ * @details If enabled then the memory pools allocator APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_USE_MEMPOOLS) || defined(__DOXYGEN__)
+#define CH_USE_MEMPOOLS TRUE
+#endif
+
+/**
+ * @brief Dynamic Threads APIs.
+ * @details If enabled then the dynamic threads creation APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_USE_WAITEXIT.
+ * @note Requires @p CH_USE_HEAP and/or @p CH_USE_MEMPOOLS.
+ */
+#if !defined(CH_USE_DYNAMIC) || defined(__DOXYGEN__)
+#define CH_USE_DYNAMIC TRUE
+#endif
+
+/** @} */
+
+/*===========================================================================*/
+/**
+ * @name Debug options
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief Debug option, system state check.
+ * @details If enabled the correct call protocol for system APIs is checked
+ * at runtime.
+ *
+ * @note The default is @p FALSE.
+ */
+#if !defined(CH_DBG_SYSTEM_STATE_CHECK) || defined(__DOXYGEN__)
+#define CH_DBG_SYSTEM_STATE_CHECK FALSE
+#endif
+
+/**
+ * @brief Debug option, parameters checks.
+ * @details If enabled then the checks on the API functions input
+ * parameters are activated.
+ *
+ * @note The default is @p FALSE.
+ */
+#if !defined(CH_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__)
+#define CH_DBG_ENABLE_CHECKS FALSE
+#endif
+
+/**
+ * @brief Debug option, consistency checks.
+ * @details If enabled then all the assertions in the kernel code are
+ * activated. This includes consistency checks inside the kernel,
+ * runtime anomalies and port-defined checks.
+ *
+ * @note The default is @p FALSE.
+ */
+#if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__)
+#define CH_DBG_ENABLE_ASSERTS FALSE
+#endif
+
+/**
+ * @brief Debug option, trace buffer.
+ * @details If enabled then the context switch circular trace buffer is
+ * activated.
+ *
+ * @note The default is @p FALSE.
+ */
+#if !defined(CH_DBG_ENABLE_TRACE) || defined(__DOXYGEN__)
+#define CH_DBG_ENABLE_TRACE FALSE
+#endif
+
+/**
+ * @brief Debug option, stack checks.
+ * @details If enabled then a runtime stack check is performed.
+ *
+ * @note The default is @p FALSE.
+ * @note The stack check is performed in a architecture/port dependent way.
+ * It may not be implemented or some ports.
+ * @note The default failure mode is to halt the system with the global
+ * @p panic_msg variable set to @p NULL.
+ */
+#if !defined(CH_DBG_ENABLE_STACK_CHECK) || defined(__DOXYGEN__)
+#define CH_DBG_ENABLE_STACK_CHECK FALSE
+#endif
+
+/**
+ * @brief Debug option, stacks initialization.
+ * @details If enabled then the threads working area is filled with a byte
+ * value when a thread is created. This can be useful for the
+ * runtime measurement of the used stack.
+ *
+ * @note The default is @p FALSE.
+ */
+#if !defined(CH_DBG_FILL_THREADS) || defined(__DOXYGEN__)
+#define CH_DBG_FILL_THREADS FALSE
+#endif
+
+/**
+ * @brief Debug option, threads profiling.
+ * @details If enabled then a field is added to the @p Thread structure that
+ * counts the system ticks occurred while executing the thread.
+ *
+ * @note The default is @p TRUE.
+ * @note This debug option is defaulted to TRUE because it is required by
+ * some test cases into the test suite.
+ */
+#if !defined(CH_DBG_THREADS_PROFILING) || defined(__DOXYGEN__)
+#define CH_DBG_THREADS_PROFILING TRUE
+#endif
+
+/** @} */
+
+/*===========================================================================*/
+/**
+ * @name Kernel hooks
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief Threads descriptor structure extension.
+ * @details User fields added to the end of the @p Thread structure.
+ */
+#if !defined(THREAD_EXT_FIELDS) || defined(__DOXYGEN__)
+#define THREAD_EXT_FIELDS \
+ /* Add threads custom fields here.*/
+#endif
+
+/**
+ * @brief Threads initialization hook.
+ * @details User initialization code added to the @p chThdInit() API.
+ *
+ * @note It is invoked from within @p chThdInit() and implicitly from all
+ * the threads creation APIs.
+ */
+#if !defined(THREAD_EXT_INIT_HOOK) || defined(__DOXYGEN__)
+#define THREAD_EXT_INIT_HOOK(tp) { \
+ /* Add threads initialization code here.*/ \
+}
+#endif
+
+/**
+ * @brief Threads finalization hook.
+ * @details User finalization code added to the @p chThdExit() API.
+ *
+ * @note It is inserted into lock zone.
+ * @note It is also invoked when the threads simply return in order to
+ * terminate.
+ */
+#if !defined(THREAD_EXT_EXIT_HOOK) || defined(__DOXYGEN__)
+#define THREAD_EXT_EXIT_HOOK(tp) { \
+ /* Add threads finalization code here.*/ \
+}
+#endif
+
+/**
+ * @brief Context switch hook.
+ * @details This hook is invoked just before switching between threads.
+ */
+#if !defined(THREAD_CONTEXT_SWITCH_HOOK) || defined(__DOXYGEN__)
+#define THREAD_CONTEXT_SWITCH_HOOK(ntp, otp) { \
+ /* System halt code here.*/ \
+}
+#endif
+
+/**
+ * @brief Idle Loop hook.
+ * @details This hook is continuously invoked by the idle thread loop.
+ */
+#if !defined(IDLE_LOOP_HOOK) || defined(__DOXYGEN__)
+#define IDLE_LOOP_HOOK() { \
+ /* Idle loop code here.*/ \
+}
+#endif
+
+/**
+ * @brief System tick event hook.
+ * @details This hook is invoked in the system tick handler immediately
+ * after processing the virtual timers queue.
+ */
+#if !defined(SYSTEM_TICK_EVENT_HOOK) || defined(__DOXYGEN__)
+#define SYSTEM_TICK_EVENT_HOOK() { \
+ /* System tick event code here.*/ \
+}
+#endif
+
+/**
+ * @brief System halt hook.
+ * @details This hook is invoked in case to a system halting error before
+ * the system is halted.
+ */
+#if !defined(SYSTEM_HALT_HOOK) || defined(__DOXYGEN__)
+#define SYSTEM_HALT_HOOK() { \
+ /* System halt code here.*/ \
+}
+#endif
+
+/** @} */
+
+/*===========================================================================*/
+/* Port-specific settings (override port settings defaulted in chcore.h). */
+/*===========================================================================*/
+
+#endif /* _CHCONF_H_ */
+
+/** @} */
diff --git a/boards/base/Mikromedia-STM32-M4-ILI9341/example/halconf.h b/boards/base/Mikromedia-STM32-M4-ILI9341/example/halconf.h
new file mode 100644
index 00000000..6585fb3e
--- /dev/null
+++ b/boards/base/Mikromedia-STM32-M4-ILI9341/example/halconf.h
@@ -0,0 +1,312 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+
+ 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.
+*/
+
+/**
+ * @file templates/halconf.h
+ * @brief HAL configuration header.
+ * @details HAL configuration file, this file allows to enable or disable the
+ * various device drivers from your application. You may also use
+ * this file in order to override the device drivers default settings.
+ *
+ * @addtogroup HAL_CONF
+ * @{
+ */
+
+#ifndef _HALCONF_H_
+#define _HALCONF_H_
+
+#include "mcuconf.h"
+
+/**
+ * @brief Enables the TM subsystem.
+ */
+#if !defined(HAL_USE_TM) || defined(__DOXYGEN__)
+#define HAL_USE_TM FALSE
+#endif
+
+/**
+ * @brief Enables the PAL subsystem.
+ */
+#if !defined(HAL_USE_PAL) || defined(__DOXYGEN__)
+#define HAL_USE_PAL TRUE
+#endif
+
+/**
+ * @brief Enables the ADC subsystem.
+ */
+#if !defined(HAL_USE_ADC) || defined(__DOXYGEN__)
+#define HAL_USE_ADC TRUE
+#endif
+
+/**
+ * @brief Enables the CAN subsystem.
+ */
+#if !defined(HAL_USE_CAN) || defined(__DOXYGEN__)
+#define HAL_USE_CAN FALSE
+#endif
+
+/**
+ * @brief Enables the EXT subsystem.
+ */
+#if !defined(HAL_USE_EXT) || defined(__DOXYGEN__)
+#define HAL_USE_EXT FALSE
+#endif
+
+/**
+ * @brief Enables the GPT subsystem.
+ */
+#if !defined(HAL_USE_GPT) || defined(__DOXYGEN__)
+#define HAL_USE_GPT FALSE
+#endif
+
+/**
+ * @brief Enables the I2C subsystem.
+ */
+#if !defined(HAL_USE_I2C) || defined(__DOXYGEN__)
+#define HAL_USE_I2C FALSE
+#endif
+
+/**
+ * @brief Enables the ICU subsystem.
+ */
+#if !defined(HAL_USE_ICU) || defined(__DOXYGEN__)
+#define HAL_USE_ICU FALSE
+#endif
+
+/**
+ * @brief Enables the MAC subsystem.
+ */
+#if !defined(HAL_USE_MAC) || defined(__DOXYGEN__)
+#define HAL_USE_MAC FALSE
+#endif
+
+/**
+ * @brief Enables the MMC_SPI subsystem.
+ */
+#if !defined(HAL_USE_MMC_SPI) || defined(__DOXYGEN__)
+#define HAL_USE_MMC_SPI TRUE
+#endif
+
+/**
+ * @brief Enables the PWM subsystem.
+ */
+#if !defined(HAL_USE_PWM) || defined(__DOXYGEN__)
+#define HAL_USE_PWM TRUE
+#endif
+
+/**
+ * @brief Enables the RTC subsystem.
+ */
+#if !defined(HAL_USE_RTC) || defined(__DOXYGEN__)
+#define HAL_USE_RTC FALSE
+#endif
+
+/**
+ * @brief Enables the SDC subsystem.
+ */
+#if !defined(HAL_USE_SDC) || defined(__DOXYGEN__)
+#define HAL_USE_SDC FALSE
+#endif
+
+/**
+ * @brief Enables the SERIAL subsystem.
+ */
+#if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__)
+#define HAL_USE_SERIAL TRUE
+#endif
+
+/**
+ * @brief Enables the SERIAL over USB subsystem.
+ */
+#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
+#define HAL_USE_SERIAL_USB FALSE
+#endif
+
+/**
+ * @brief Enables the SPI subsystem.
+ */
+#if !defined(HAL_USE_SPI) || defined(__DOXYGEN__)
+#define HAL_USE_SPI TRUE
+#endif
+
+/**
+ * @brief Enables the UART subsystem.
+ */
+#if !defined(HAL_USE_UART) || defined(__DOXYGEN__)
+#define HAL_USE_UART FALSE
+#endif
+
+/**
+ * @brief Enables the USB subsystem.
+ */
+#if !defined(HAL_USE_USB) || defined(__DOXYGEN__)
+#define HAL_USE_USB FALSE
+#endif
+
+/*===========================================================================*/
+/* ADC driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(ADC_USE_WAIT) || defined(__DOXYGEN__)
+#define ADC_USE_WAIT TRUE
+#endif
+
+/**
+ * @brief Enables the @p adcAcquireBus() and @p adcReleaseBus() APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
+#define ADC_USE_MUTUAL_EXCLUSION TRUE
+#endif
+
+/*===========================================================================*/
+/* CAN driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Sleep mode related APIs inclusion switch.
+ */
+#if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__)
+#define CAN_USE_SLEEP_MODE TRUE
+#endif
+
+/*===========================================================================*/
+/* I2C driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables the mutual exclusion APIs on the I2C bus.
+ */
+#if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
+#define I2C_USE_MUTUAL_EXCLUSION TRUE
+#endif
+
+/*===========================================================================*/
+/* MAC driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables an event sources for incoming packets.
+ */
+#if !defined(MAC_USE_ZERO_COPY) || defined(__DOXYGEN__)
+#define MAC_USE_ZERO_COPY FALSE
+#endif
+
+/**
+ * @brief Enables an event sources for incoming packets.
+ */
+#if !defined(MAC_USE_EVENTS) || defined(__DOXYGEN__)
+#define MAC_USE_EVENTS TRUE
+#endif
+
+/*===========================================================================*/
+/* MMC_SPI driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Delays insertions.
+ * @details If enabled this options inserts delays into the MMC waiting
+ * routines releasing some extra CPU time for the threads with
+ * lower priority, this may slow down the driver a bit however.
+ * This option is recommended also if the SPI driver does not
+ * use a DMA channel and heavily loads the CPU.
+ */
+#if !defined(MMC_NICE_WAITING) || defined(__DOXYGEN__)
+#define MMC_NICE_WAITING TRUE
+#endif
+
+/*===========================================================================*/
+/* SDC driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Number of initialization attempts before rejecting the card.
+ * @note Attempts are performed at 10mS intervals.
+ */
+#if !defined(SDC_INIT_RETRY) || defined(__DOXYGEN__)
+#define SDC_INIT_RETRY 100
+#endif
+
+/**
+ * @brief Include support for MMC cards.
+ * @note MMC support is not yet implemented so this option must be kept
+ * at @p FALSE.
+ */
+#if !defined(SDC_MMC_SUPPORT) || defined(__DOXYGEN__)
+#define SDC_MMC_SUPPORT FALSE
+#endif
+
+/**
+ * @brief Delays insertions.
+ * @details If enabled this options inserts delays into the MMC waiting
+ * routines releasing some extra CPU time for the threads with
+ * lower priority, this may slow down the driver a bit however.
+ */
+#if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__)
+#define SDC_NICE_WAITING TRUE
+#endif
+
+/*===========================================================================*/
+/* SERIAL driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Default bit rate.
+ * @details Configuration parameter, this is the baud rate selected for the
+ * default configuration.
+ */
+#if !defined(SERIAL_DEFAULT_BITRATE) || defined(__DOXYGEN__)
+#define SERIAL_DEFAULT_BITRATE 38400
+#endif
+
+/**
+ * @brief Serial buffers size.
+ * @details Configuration parameter, you can change the depth of the queue
+ * buffers depending on the requirements of your application.
+ * @note The default is 64 bytes for both the transmission and receive
+ * buffers.
+ */
+#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__)
+#define SERIAL_BUFFERS_SIZE 16
+#endif
+
+/*===========================================================================*/
+/* SPI driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(SPI_USE_WAIT) || defined(__DOXYGEN__)
+#define SPI_USE_WAIT TRUE
+#endif
+
+/**
+ * @brief Enables the @p spiAcquireBus() and @p spiReleaseBus() APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
+#define SPI_USE_MUTUAL_EXCLUSION TRUE
+#endif
+
+#endif /* _HALCONF_H_ */
+
+/** @} */
diff --git a/boards/base/Mikromedia-STM32-M4-ILI9341/example/mcuconf.h b/boards/base/Mikromedia-STM32-M4-ILI9341/example/mcuconf.h
new file mode 100644
index 00000000..64895943
--- /dev/null
+++ b/boards/base/Mikromedia-STM32-M4-ILI9341/example/mcuconf.h
@@ -0,0 +1,289 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+
+ 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.
+*/
+
+/*
+ * STM32F4xx drivers configuration.
+ * The following settings override the default settings present in
+ * the various device driver implementation headers.
+ * Note that the settings for each driver only have effect if the whole
+ * driver is enabled in halconf.h.
+ *
+ * IRQ priorities:
+ * 15...0 Lowest...Highest.
+ *
+ * DMA priorities:
+ * 0...3 Lowest...Highest.
+ */
+
+#define STM32F4xx_MCUCONF
+
+/*
+ * HAL driver system settings.
+ */
+#define STM32_NO_INIT FALSE
+#define STM32_HSI_ENABLED TRUE
+#define STM32_LSI_ENABLED TRUE
+#define STM32_HSE_ENABLED FALSE
+#define STM32_LSE_ENABLED TRUE
+#define STM32_CLOCK48_REQUIRED TRUE
+#define STM32_SW STM32_SW_PLL
+#define STM32_PLLSRC STM32_PLLSRC_HSI
+#define STM32_PLLM_VALUE 16
+#define STM32_PLLN_VALUE 336
+#define STM32_PLLP_VALUE 2
+#define STM32_PLLQ_VALUE 7
+#define STM32_HPRE STM32_HPRE_DIV1
+#define STM32_PPRE1 STM32_PPRE1_DIV4
+#define STM32_PPRE2 STM32_PPRE2_DIV2
+#define STM32_RTCSEL STM32_RTCSEL_LSI
+#define STM32_RTCPRE_VALUE 8
+#define STM32_MCO1SEL STM32_MCO1SEL_HSI
+#define STM32_MCO1PRE STM32_MCO1PRE_DIV1
+#define STM32_MCO2SEL STM32_MCO2SEL_SYSCLK
+#define STM32_MCO2PRE STM32_MCO2PRE_DIV5
+#define STM32_I2SSRC STM32_I2SSRC_CKIN
+#define STM32_PLLI2SN_VALUE 192
+#define STM32_PLLI2SR_VALUE 5
+#define STM32_VOS STM32_VOS_HIGH
+#define STM32_PVD_ENABLE FALSE
+#define STM32_PLS STM32_PLS_LEV0
+#define STM32_BKPRAM_ENABLE FALSE
+
+/*
+ * ADC driver system settings.
+ */
+#define STM32_ADC_ADCPRE ADC_CCR_ADCPRE_DIV4
+#define STM32_ADC_USE_ADC1 TRUE
+#define STM32_ADC_USE_ADC2 FALSE
+#define STM32_ADC_USE_ADC3 FALSE
+#define STM32_ADC_ADC1_DMA_STREAM STM32_DMA_STREAM_ID(2, 4)
+#define STM32_ADC_ADC2_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
+#define STM32_ADC_ADC3_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
+#define STM32_ADC_ADC1_DMA_PRIORITY 2
+#define STM32_ADC_ADC2_DMA_PRIORITY 2
+#define STM32_ADC_ADC3_DMA_PRIORITY 2
+#define STM32_ADC_IRQ_PRIORITY 6
+#define STM32_ADC_ADC1_DMA_IRQ_PRIORITY 6
+#define STM32_ADC_ADC2_DMA_IRQ_PRIORITY 6
+#define STM32_ADC_ADC3_DMA_IRQ_PRIORITY 6
+
+/*
+ * CAN driver system settings.
+ */
+#define STM32_CAN_USE_CAN1 FALSE
+#define STM32_CAN_USE_CAN2 FALSE
+#define STM32_CAN_CAN1_IRQ_PRIORITY 11
+#define STM32_CAN_CAN2_IRQ_PRIORITY 11
+
+/*
+ * EXT driver system settings.
+ */
+#define STM32_EXT_EXTI0_IRQ_PRIORITY 6
+#define STM32_EXT_EXTI1_IRQ_PRIORITY 6
+#define STM32_EXT_EXTI2_IRQ_PRIORITY 6
+#define STM32_EXT_EXTI3_IRQ_PRIORITY 6
+#define STM32_EXT_EXTI4_IRQ_PRIORITY 6
+#define STM32_EXT_EXTI5_9_IRQ_PRIORITY 6
+#define STM32_EXT_EXTI10_15_IRQ_PRIORITY 6
+#define STM32_EXT_EXTI16_IRQ_PRIORITY 6
+#define STM32_EXT_EXTI17_IRQ_PRIORITY 15
+#define STM32_EXT_EXTI18_IRQ_PRIORITY 6
+#define STM32_EXT_EXTI19_IRQ_PRIORITY 6
+#define STM32_EXT_EXTI20_IRQ_PRIORITY 6
+#define STM32_EXT_EXTI21_IRQ_PRIORITY 15
+#define STM32_EXT_EXTI22_IRQ_PRIORITY 15
+
+/*
+ * GPT driver system settings.
+ */
+#define STM32_GPT_USE_TIM1 FALSE
+#define STM32_GPT_USE_TIM2 FALSE
+#define STM32_GPT_USE_TIM3 FALSE
+#define STM32_GPT_USE_TIM4 FALSE
+#define STM32_GPT_USE_TIM5 FALSE
+#define STM32_GPT_USE_TIM6 FALSE
+#define STM32_GPT_USE_TIM7 FALSE
+#define STM32_GPT_USE_TIM8 FALSE
+#define STM32_GPT_USE_TIM9 FALSE
+#define STM32_GPT_USE_TIM11 FALSE
+#define STM32_GPT_USE_TIM12 FALSE
+#define STM32_GPT_USE_TIM14 FALSE
+#define STM32_GPT_TIM1_IRQ_PRIORITY 7
+#define STM32_GPT_TIM2_IRQ_PRIORITY 7
+#define STM32_GPT_TIM3_IRQ_PRIORITY 7
+#define STM32_GPT_TIM4_IRQ_PRIORITY 7
+#define STM32_GPT_TIM5_IRQ_PRIORITY 7
+#define STM32_GPT_TIM6_IRQ_PRIORITY 7
+#define STM32_GPT_TIM7_IRQ_PRIORITY 7
+#define STM32_GPT_TIM8_IRQ_PRIORITY 7
+#define STM32_GPT_TIM9_IRQ_PRIORITY 7
+#define STM32_GPT_TIM11_IRQ_PRIORITY 7
+#define STM32_GPT_TIM12_IRQ_PRIORITY 7
+#define STM32_GPT_TIM14_IRQ_PRIORITY 7
+
+/*
+ * I2C driver system settings.
+ */
+#define STM32_I2C_USE_I2C1 FALSE
+#define STM32_I2C_USE_I2C2 FALSE
+#define STM32_I2C_USE_I2C3 FALSE
+#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 0)
+#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
+#define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
+#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+#define STM32_I2C_I2C3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
+#define STM32_I2C_I2C3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+#define STM32_I2C_I2C1_IRQ_PRIORITY 5
+#define STM32_I2C_I2C2_IRQ_PRIORITY 5
+#define STM32_I2C_I2C3_IRQ_PRIORITY 5
+#define STM32_I2C_I2C1_DMA_PRIORITY 3
+#define STM32_I2C_I2C2_DMA_PRIORITY 3
+#define STM32_I2C_I2C3_DMA_PRIORITY 3
+#define STM32_I2C_I2C1_DMA_ERROR_HOOK() chSysHalt()
+#define STM32_I2C_I2C2_DMA_ERROR_HOOK() chSysHalt()
+#define STM32_I2C_I2C3_DMA_ERROR_HOOK() chSysHalt()
+
+/*
+ * ICU driver system settings.
+ */
+#define STM32_ICU_USE_TIM1 FALSE
+#define STM32_ICU_USE_TIM2 FALSE
+#define STM32_ICU_USE_TIM3 FALSE
+#define STM32_ICU_USE_TIM4 FALSE
+#define STM32_ICU_USE_TIM5 FALSE
+#define STM32_ICU_USE_TIM8 FALSE
+#define STM32_ICU_USE_TIM9 FALSE
+#define STM32_ICU_TIM1_IRQ_PRIORITY 7
+#define STM32_ICU_TIM2_IRQ_PRIORITY 7
+#define STM32_ICU_TIM3_IRQ_PRIORITY 7
+#define STM32_ICU_TIM4_IRQ_PRIORITY 7
+#define STM32_ICU_TIM5_IRQ_PRIORITY 7
+#define STM32_ICU_TIM8_IRQ_PRIORITY 7
+#define STM32_ICU_TIM9_IRQ_PRIORITY 7
+
+/*
+ * MAC driver system settings.
+ */
+#define STM32_MAC_TRANSMIT_BUFFERS 2
+#define STM32_MAC_RECEIVE_BUFFERS 4
+#define STM32_MAC_BUFFERS_SIZE 1522
+#define STM32_MAC_PHY_TIMEOUT 100
+#define STM32_MAC_ETH1_CHANGE_PHY_STATE TRUE
+#define STM32_MAC_ETH1_IRQ_PRIORITY 13
+#define STM32_MAC_IP_CHECKSUM_OFFLOAD 0
+
+/*
+ * PWM driver system settings.
+ */
+#define STM32_PWM_USE_ADVANCED FALSE
+#define STM32_PWM_USE_TIM1 FALSE
+#define STM32_PWM_USE_TIM2 FALSE
+#define STM32_PWM_USE_TIM3 FALSE
+#define STM32_PWM_USE_TIM4 TRUE
+#define STM32_PWM_USE_TIM5 FALSE
+#define STM32_PWM_USE_TIM8 FALSE
+#define STM32_PWM_USE_TIM9 FALSE
+#define STM32_PWM_TIM1_IRQ_PRIORITY 7
+#define STM32_PWM_TIM2_IRQ_PRIORITY 7
+#define STM32_PWM_TIM3_IRQ_PRIORITY 7
+#define STM32_PWM_TIM4_IRQ_PRIORITY 7
+#define STM32_PWM_TIM5_IRQ_PRIORITY 7
+#define STM32_PWM_TIM8_IRQ_PRIORITY 7
+#define STM32_PWM_TIM9_IRQ_PRIORITY 7
+
+/*
+ * SERIAL driver system settings.
+ */
+#define STM32_SERIAL_USE_USART1 FALSE
+#define STM32_SERIAL_USE_USART2 TRUE
+#define STM32_SERIAL_USE_USART3 FALSE
+#define STM32_SERIAL_USE_UART4 FALSE
+#define STM32_SERIAL_USE_UART5 FALSE
+#define STM32_SERIAL_USE_USART6 FALSE
+#define STM32_SERIAL_USART1_PRIORITY 12
+#define STM32_SERIAL_USART2_PRIORITY 12
+#define STM32_SERIAL_USART3_PRIORITY 12
+#define STM32_SERIAL_UART4_PRIORITY 12
+#define STM32_SERIAL_UART5_PRIORITY 12
+#define STM32_SERIAL_USART6_PRIORITY 12
+
+/*
+ * SPI driver system settings.
+ */
+#define STM32_SPI_USE_SPI1 FALSE
+#define STM32_SPI_USE_SPI2 TRUE
+#define STM32_SPI_USE_SPI3 TRUE
+#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 0)
+#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
+#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 0)
+#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+#define STM32_SPI_SPI1_DMA_PRIORITY 1
+#define STM32_SPI_SPI2_DMA_PRIORITY 1
+#define STM32_SPI_SPI3_DMA_PRIORITY 1
+#define STM32_SPI_SPI1_IRQ_PRIORITY 10
+#define STM32_SPI_SPI2_IRQ_PRIORITY 10
+#define STM32_SPI_SPI3_IRQ_PRIORITY 10
+#define STM32_SPI_DMA_ERROR_HOOK(spip) chSysHalt()
+
+/*
+ * UART driver system settings.
+ */
+#define STM32_UART_USE_USART1 FALSE
+#define STM32_UART_USE_USART2 FALSE
+#define STM32_UART_USE_USART3 FALSE
+#define STM32_UART_USE_UART4 FALSE
+#define STM32_UART_USE_UART5 FALSE
+#define STM32_UART_USE_USART6 FALSE
+#define STM32_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 5)
+#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 7)
+#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
+#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 1)
+#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+#define STM32_UART_UART4_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
+#define STM32_UART_UART4_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+#define STM32_UART_UART5_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 0)
+#define STM32_UART_UART5_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+#define STM32_UART_USART6_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
+#define STM32_UART_USART6_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 7)
+#define STM32_UART_USART1_IRQ_PRIORITY 12
+#define STM32_UART_USART2_IRQ_PRIORITY 12
+#define STM32_UART_USART3_IRQ_PRIORITY 12
+#define STM32_UART_UART4_IRQ_PRIORITY 12
+#define STM32_UART_UART5_IRQ_PRIORITY 12
+#define STM32_UART_USART6_IRQ_PRIORITY 12
+#define STM32_UART_USART1_DMA_PRIORITY 0
+#define STM32_UART_USART2_DMA_PRIORITY 0
+#define STM32_UART_USART3_DMA_PRIORITY 0
+#define STM32_UART_UART4_DMA_PRIORITY 0
+#define STM32_UART_UART5_DMA_PRIORITY 0
+#define STM32_UART_USART6_DMA_PRIORITY 0
+#define STM32_UART_DMA_ERROR_HOOK(uartp) chSysHalt()
+
+/*
+ * USB driver system settings.
+ */
+#define STM32_USB_USE_OTG1 FALSE
+#define STM32_USB_USE_OTG2 FALSE
+#define STM32_USB_OTG1_IRQ_PRIORITY 14
+#define STM32_USB_OTG2_IRQ_PRIORITY 14
+#define STM32_USB_OTG1_RX_FIFO_SIZE 512
+#define STM32_USB_OTG2_RX_FIFO_SIZE 1024
+#define STM32_USB_OTG_THREAD_PRIO LOWPRIO
+#define STM32_USB_OTG_THREAD_STACK_SIZE 128
+#define STM32_USB_OTGFIFO_FILL_BASEPRI 0
diff --git a/boards/base/Mikromedia-STM32-M4-ILI9341/example/openocd.cfg b/boards/base/Mikromedia-STM32-M4-ILI9341/example/openocd.cfg
new file mode 100644
index 00000000..f8b6a6f5
--- /dev/null
+++ b/boards/base/Mikromedia-STM32-M4-ILI9341/example/openocd.cfg
@@ -0,0 +1,81 @@
+# This is a script file for OpenOCD 0.7.0
+#
+# It is set up for the Mikromedia-STM32M4 board using the ST-Link JTAG adaptor.
+#
+# Assuming the current directory is your project directory containing this openocd.cfg file...
+#
+# To program your device:
+#
+# openocd -f openocd.cfg -c "Burn yourfile.bin" -c shutdown
+#
+# To debug your device:
+#
+# openocd
+# (This will run openocd in gdb server debug mode. Leave it running in the background)
+#
+# gdb yourfile.elf
+# (To start gdb. Then run the following commands in gdb...)
+#
+# target remote 127.0.0.1:3333
+# monitor Debug
+# stepi
+# (This last stepi resynchronizes gdb).
+#
+# If you want to reprogram from within gdb:
+#
+# monitor Burn yourfile.bin
+#
+
+echo ""
+echo "##### Loading debugger..."
+source [find interface/stlink-v2.cfg]
+
+echo ""
+echo "##### Loading CPU..."
+source [find target/stm32f4x_stlink.cfg]
+
+echo ""
+echo "##### Configuring..."
+reset_config srst_only srst_nogate
+#cortex_m maskisr (auto|on|off)
+#cortex_m vector_catch [all|none|list]
+#cortex_m reset_config (srst|sysresetreq|vectreset)
+#gdb_breakpoint_override hard
+
+proc Debug { } {
+ echo ""
+ echo "##### Debug Session Connected..."
+ reset init
+ echo "Ready..."
+}
+
+proc Burn {file} {
+ echo ""
+ echo "##### Burning $file to device..."
+ halt
+ # Due to an issue with the combination of the ST-Link adapters and OpenOCD
+ # applying the stm32f2x unlock 0 command actaully applies read protection - VERY BAD!
+ # If this happens to you - use the ST-Link utility to set the option byte back to normal.
+ # If you are using a different debugger eg a FT2232 based adapter you can uncomment the line below.
+ #stm32f2x unlock 0
+ flash protect 0 0 last off
+ reset init
+ flash write_image erase $file 0x08000000
+ verify_image $file 0x0
+ #flash protect 0 0 last on
+ reset
+ echo "Burning Complete!"
+}
+
+echo ""
+echo "##### Leaving Configuration Mode..."
+init
+reset init
+flash probe 0
+flash banks
+#flash info 0
+
+echo ""
+echo "##### Waiting for debug connections..."
+
+
diff --git a/boards/base/Mikromedia-STM32-M4-ILI9341/ginput_lld_mouse_board.h b/boards/base/Mikromedia-STM32-M4-ILI9341/ginput_lld_mouse_board.h
new file mode 100644
index 00000000..373a2474
--- /dev/null
+++ b/boards/base/Mikromedia-STM32-M4-ILI9341/ginput_lld_mouse_board.h
@@ -0,0 +1,152 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file boards/base/Mikromedia-STM32-M4-ILI9341/ginput_lld_mouse_board.h
+ * @brief GINPUT Touch low level driver source for the MCU.
+ */
+
+#ifndef _GINPUT_LLD_MOUSE_BOARD_H
+#define _GINPUT_LLD_MOUSE_BOARD_H
+
+/* read ADC if more than this many ticks since last read */
+#define ADC_UPDATE_INTERVAL 3
+
+#define ADC_NUM_CHANNELS 2
+#define ADC_BUF_DEPTH 1
+
+static const ADCConversionGroup adcgrpcfg = {
+ FALSE,
+ ADC_NUM_CHANNELS,
+ NULL,
+ NULL,
+ /* HW dependent part.*/
+ 0,
+ ADC_CR2_SWSTART,
+ 0,
+ 0,
+ ADC_SQR1_NUM_CH(ADC_NUM_CHANNELS),
+ 0,
+ ADC_SQR3_SQ2_N(ADC_CHANNEL_IN8) | ADC_SQR3_SQ1_N(ADC_CHANNEL_IN9)
+};
+
+static systime_t last_update;
+static volatile uint16_t tpx, tpy, detect;
+
+static inline void delay(uint16_t dly) {
+ static uint16_t i;
+ for(i = 0; i < dly; i++)
+ asm("nop");
+}
+
+
+void read_mikro_tp(void) {
+ systime_t now = chTimeNow();
+
+ adcsample_t samples[ADC_NUM_CHANNELS * ADC_BUF_DEPTH];
+ uint16_t _detect, _tpx, _tpy;
+
+ if(now < last_update || ((now - last_update) > ADC_UPDATE_INTERVAL)) {
+ // detect button press
+ // sample[0] will go from ~200 to ~4000 when pressed
+ adcConvert(&ADCD1, &adcgrpcfg, samples, ADC_BUF_DEPTH);
+ _detect = samples[0];
+
+ // read x channel
+ palSetPad(GPIOB, GPIOB_DRIVEA);
+ palClearPad(GPIOB, GPIOB_DRIVEB);
+ chThdSleepMilliseconds(1);
+ adcConvert(&ADCD1, &adcgrpcfg, samples, ADC_BUF_DEPTH);
+ _tpx = samples[1];
+
+ // read y channel (invert)
+ palClearPad(GPIOB, GPIOB_DRIVEA);
+ palSetPad(GPIOB, GPIOB_DRIVEB);
+ chThdSleepMilliseconds(1);
+ adcConvert(&ADCD1, &adcgrpcfg, samples, ADC_BUF_DEPTH);
+ _tpy = samples[0];
+
+ // ready for next read
+ palClearPad(GPIOB, GPIOB_DRIVEA);
+ palClearPad(GPIOB, GPIOB_DRIVEB);
+
+ chSysLock();
+ tpx = _tpx;
+ tpy = _tpy;
+ detect = _detect;
+ last_update = now;
+ chSysUnlock();
+ }
+}
+
+/**
+ * @brief Initialise the board for the touch.
+ *
+ * @notapi
+ */
+static inline void init_board(void) {
+ adcStart(&ADCD1, NULL);
+ last_update = chTimeNow();
+
+ // leave DRIVEA & DRIVEB ready for next read
+ palClearPad(GPIOB, GPIOB_DRIVEA);
+ palClearPad(GPIOB, GPIOB_DRIVEB);
+ chThdSleepMilliseconds(1);
+}
+
+/**
+ * @brief Check whether the surface is currently touched
+ * @return TRUE if the surface is currently touched
+ *
+ * @notapi
+ */
+static inline bool_t getpin_pressed(void) {
+ read_mikro_tp();
+ return (detect > 2000) ? true : false;
+}
+
+/**
+ * @brief Aquire the bus ready for readings
+ *
+ * @notapi
+ */
+static inline void aquire_bus(void) {
+
+}
+
+/**
+ * @brief Release the bus after readings
+ *
+ * @notapi
+ */
+static inline void release_bus(void) {
+
+}
+
+/**
+ * @brief Read an x value from touch controller
+ * @return The value read from the controller
+ *
+ * @notapi
+ */
+static inline uint16_t read_x_value(void) {
+ read_mikro_tp();
+ return tpx;
+}
+
+/**
+ * @brief Read an y value from touch controller
+ * @return The value read from the controller
+ *
+ * @notapi
+ */
+static inline uint16_t read_y_value(void) {
+ read_mikro_tp();
+ return tpy;
+}
+
+#endif /* _GINPUT_LLD_MOUSE_BOARD_H */
diff --git a/boards/base/Mikromedia-STM32-M4-ILI9341/ginput_lld_mouse_config.h b/boards/base/Mikromedia-STM32-M4-ILI9341/ginput_lld_mouse_config.h
new file mode 100644
index 00000000..0c0ff482
--- /dev/null
+++ b/boards/base/Mikromedia-STM32-M4-ILI9341/ginput_lld_mouse_config.h
@@ -0,0 +1,32 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file boards/base/Mikromedia-STM32-M4-ILI9341/ginput_lld_mouse_config.h
+ * @brief GINPUT LLD header file for touch driver.
+ *
+ * @defgroup Mouse Mouse
+ * @ingroup GINPUT
+ *
+ * @{
+ */
+
+#ifndef _LLD_GINPUT_MOUSE_CONFIG_H
+#define _LLD_GINPUT_MOUSE_CONFIG_H
+
+#define GINPUT_MOUSE_EVENT_TYPE GEVENT_TOUCH
+#define GINPUT_MOUSE_NEED_CALIBRATION TRUE
+#define GINPUT_MOUSE_LLD_CALIBRATION_LOADSAVE FALSE
+#define GINPUT_MOUSE_MAX_CALIBRATION_ERROR 12
+#define GINPUT_MOUSE_READ_CYCLES 4
+#define GINPUT_MOUSE_POLL_PERIOD 3
+#define GINPUT_MOUSE_MAX_CLICK_JITTER 2
+#define GINPUT_MOUSE_MAX_MOVE_JITTER 2
+#define GINPUT_MOUSE_CLICK_TIME 500
+
+#endif /* _LLD_GINPUT_MOUSE_CONFIG_H */
+/** @} */
diff --git a/boards/base/Mikromedia-STM32-M4-ILI9341/readme.txt b/boards/base/Mikromedia-STM32-M4-ILI9341/readme.txt
new file mode 100644
index 00000000..961f9793
--- /dev/null
+++ b/boards/base/Mikromedia-STM32-M4-ILI9341/readme.txt
@@ -0,0 +1,14 @@
+This directory contains the interface for the MikroMedia STM32 M4 board
+running under ChibiOS with the ILI9341 display.
+
+On this board uGFX currently supports:
+ - GDISP via the ILI9341 display
+ - GINPUT-touch via the MCU driver
+
+Note there are two variants of this board - one with the ILI9341 display
+ and an older one with a different display. This one is for the ILI9341 display.
+
+As this is not a standard ChibiOS supported board the necessary board files have also
+been provided in the ChibiOS_Board directory.
+
+There is an example Makefile and project in the examples directory.
diff --git a/boards/base/Olimex-SAM7EX256-GE12/board.mk b/boards/base/Olimex-SAM7EX256-GE12/board.mk
new file mode 100644
index 00000000..662178a6
--- /dev/null
+++ b/boards/base/Olimex-SAM7EX256-GE12/board.mk
@@ -0,0 +1,8 @@
+GFXINC += $(GFXLIB)/boards/base/Olimex-SAM7EX256-GE12 $(GFXLIB)/boards/base/Olimex-SAM7EX256-GE8
+GFXSRC +=
+GFXDEFS += -DGFX_USE_OS_CHIBIOS=TRUE
+include $(GFXLIB)/drivers/gdisp/Nokia6610GE12/gdisp_lld.mk
+include $(GFXLIB)/drivers/gadc/AT91SAM7/gadc_lld.mk
+include $(GFXLIB)/drivers/ginput/dial/GADC/ginput_lld.mk
+include $(GFXLIB)/drivers/ginput/toggle/Pal/ginput_lld.mk
+include $(GFXLIB)/drivers/gaudin/gadc/gaudin_lld.mk
diff --git a/boards/base/Olimex-SAM7EX256-GE12/board_Nokia6610GE12.h b/boards/base/Olimex-SAM7EX256-GE12/board_Nokia6610GE12.h
new file mode 100644
index 00000000..feb1887e
--- /dev/null
+++ b/boards/base/Olimex-SAM7EX256-GE12/board_Nokia6610GE12.h
@@ -0,0 +1,195 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file boards/base/Olimex-SAM7EX256-GE12/board_Nokia6610GE12.h
+ * @brief GDISP Graphic Driver subsystem board interface for the Olimex SAM7-EX256 board.
+ */
+
+#ifndef _GDISP_LLD_BOARD_H
+#define _GDISP_LLD_BOARD_H
+
+/*
+ * Set various display properties. These properties mostly depend on the exact controller chip you get.
+ * The defaults should work for most controllers.
+ */
+//#define GDISP_GE8_BROKEN_CONTROLLER FALSE // Uncomment this out if you have a controller thats not window wrap broken.
+//#define GDISP_SCREEN_HEIGHT 130 // The visible display height
+//#define GDISP_SCREEN_WIDTH 130 // The visible display width
+//#define GDISP_RAM_X_OFFSET 0 // The x offset of the visible area
+//#define GDISP_RAM_Y_OFFSET 2 // The y offset of the visible area
+//#define GDISP_SLEEP_SIZE 32 // The size of the sleep mode partial display
+//#define GDISP_SLEEP_POS 50 // The position of the sleep mode partial display
+//#define GDISP_INITIAL_CONTRAST 38 // The initial contrast percentage
+//#define GDISP_INITIAL_BACKLIGHT 100 // The initial backlight percentage
+
+// For a multiple display configuration we would put all this in a structure and then
+// set g->board to that structure.
+
+// ******************************************************
+// Pointers to AT91SAM7X256 peripheral data structures
+// ******************************************************
+static volatile AT91PS_PIO pPIOA = AT91C_BASE_PIOA;
+static volatile AT91PS_PIO pPIOB = AT91C_BASE_PIOB;
+static volatile AT91PS_SPI pSPI = AT91C_BASE_SPI0;
+static volatile AT91PS_PMC pPMC = AT91C_BASE_PMC;
+static volatile AT91PS_PDC pPDC = AT91C_BASE_PDC_SPI0;
+
+/* The PWM backlight control is non-linear on this board.
+ * We pick values here that make it look a bit more linear.
+ */
+#define PWM_TOP_VALUE 500
+#define PWM_BOTTOM_VALUE 200
+
+#define PWM_VALUE(x) (PWM_BOTTOM_VALUE+(PWM_TOP_VALUE-PWM_BOTTOM_VALUE)*(x)/100)
+
+/* PWM configuration structure. The LCD Backlight is on PWM1/PB20 ie PWM2/PIN1 in ChibiOS speak */
+static const PWMConfig pwmcfg = {
+ 1000000, /* 1 MHz PWM clock frequency. Ignored as we are using PWM_MCK_DIV_n */
+ 1000, /* PWM period is 1000 cycles. */
+ NULL,
+ {
+ {PWM_MCK_DIV_1 | PWM_OUTPUT_ACTIVE_HIGH | PWM_OUTPUT_PIN1 | PWM_DISABLEPULLUP_PIN1, NULL},
+ },
+};
+
+static bool_t pwmRunning = FALSE;
+
+/**
+ * @brief Initialise the board for the display.
+ * @notes Performs the following functions:
+ * 1. initialise the spi port used by your display
+ * 2. initialise the reset pin (initial state not-in-reset)
+ * 3. initialise the chip select pin (initial state not-active)
+ * 4. initialise the backlight pin (initial state back-light off)
+ *
+ * @notapi
+ */
+static inline void init_board(GDisplay *g) {
+
+ // As we are not using multiple displays we set g->board to NULL as we don't use it.
+ g->board = 0;
+
+ switch(g->controllerdisplay) {
+ case 0: // Set up for Display 0
+ // *********************************************************************************************
+ // InitSpi( )
+ //
+ // Sets up SPI channel 0 for communications to Nokia 6610 LCD Display
+ //
+ // I/O ports used: PA2 = LCD Reset (set to low to reset)
+ // PA12 = LCD chip select (set to low to select the LCD chip)
+ // PA16 = SPI0_MISO Master In - Slave Out (not used in LCD interface)
+ // PA17 = SPI0_MOSI Master Out - Slave In pin (Serial Data to LCD slave)
+ // PA18 = SPI0_SPCK Serial Clock (to LCD slave)
+ // PB20 = backlight control (normally PWM control, 1 = full on)
+ //
+ // *********************************************************************************************}
+
+ /* This code should really use the ChibiOS driver for these functions */
+
+ // Pin for backlight
+ pPIOB->PIO_CODR = PIOB_LCD_BL_MASK; // Set PB20 to LOW
+ pPIOB->PIO_OER = PIOB_LCD_BL_MASK; // Configure PB20 as output
+
+ // Reset pin
+ pPIOA->PIO_SODR = PIOA_LCD_RESET_MASK; // Set PA2 to HIGH
+ pPIOA->PIO_OER = PIOA_LCD_RESET_MASK; // Configure PA2 as output
+
+ // CS pin - this seems to be ignored
+ // pPIOA->PIO_SODR = 1<<12; // Set PA2 to HIGH
+ // pPIOA->PIO_OER = 1<<12; // Configure PA2 as output
+
+ // Init SPI0
+ // Disable the following pins from PIO control (will be used instead by the SPI0 peripheral)
+ // BIT12 = PA12 -> SPI0_NPCS0 chip select
+ // BIT16 = PA16 -> SPI0_MISO Master In - Slave Out (not used in LCD interface)
+ // BIT17 = PA17 -> SPI0_MOSI Master Out - Slave In pin (Serial Data to LCD slave)
+ // BIT18 = PA18 -> SPI0_SPCK Serial Clock (to LCD slave)
+ pPIOA->PIO_PDR = (1<<12) | (1<<16) | (1<<17) | (1<<18);
+ pPIOA->PIO_ASR = (1<<12) | (1<<16) | (1<<17) | (1<<18);
+ pPIOA->PIO_BSR = 0;
+
+ //enable the clock of SPI
+ pPMC->PMC_PCER = 1 << AT91C_ID_SPI0;
+
+ // Fixed mode
+ pSPI->SPI_CR = 0x81; //SPI Enable, Software reset
+ pSPI->SPI_CR = 0x01; //SPI Enable
+ pSPI->SPI_MR = 0xE0011; //Master mode, fixed select, disable decoder, PCS=1110
+ pSPI->SPI_CSR[0] = 0x01010311; //9bit, CPOL=1, ClockPhase=0, SCLK = 48Mhz/3 = 16MHz
+
+ /* Display backlight control at 100% */
+ pwmRunning = FALSE;
+ palSetPad(IOPORT2, PIOB_LCD_BL);
+ break;
+ }
+}
+
+static inline void post_init_board(GDisplay *g) {
+ (void) g;
+}
+
+static inline void setpin_reset(GDisplay *g, bool_t state) {
+ (void) g;
+ if (state)
+ palClearPad(IOPORT1, PIOA_LCD_RESET);
+ else
+ palSetPad(IOPORT1, PIOA_LCD_RESET);
+}
+
+static inline void set_backlight(GDisplay *g, uint8_t percent) {
+ (void) g;
+ if (percent == 100) {
+ /* Turn the pin on - No PWM */
+ if (pwmRunning) {
+ pwmStop(&PWMD2);
+ pwmRunning = FALSE;
+ }
+ palSetPad(IOPORT2, PIOB_LCD_BL);
+ } else if (percent == 0) {
+ /* Turn the pin off - No PWM */
+ if (pwmRunning) {
+ pwmStop(&PWMD2);
+ pwmRunning = FALSE;
+ }
+ palClearPad(IOPORT2, PIOB_LCD_BL);
+ } else {
+ /* Use the PWM */
+ if (!pwmRunning) {
+ pwmStart(&PWMD2, &pwmcfg);
+ pwmRunning = TRUE;
+ }
+ pwmEnableChannel(&PWMD2, 0, PWM_VALUE(percent));
+ }
+}
+
+static inline void acquire_bus(GDisplay *g) {
+ (void) g;
+}
+
+static inline void release_bus(GDisplay *g) {
+ (void) g;
+}
+
+static inline void write_index(GDisplay *g, uint16_t index) {
+ (void) g;
+ // wait for the previous transfer to complete
+ while((pSPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0);
+ // send the command
+ pSPI->SPI_TDR = index & 0xFF;
+}
+
+static inline void write_data(GDisplay *g, uint16_t data) {
+ (void) g;
+ // wait for the previous transfer to complete
+ while((pSPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0);
+ // send the data
+ pSPI->SPI_TDR = data | 0x0100;
+}
+
+#endif /* _GDISP_LLD_BOARD_H */
diff --git a/boards/base/Olimex-SAM7EX256-GE12/readme.txt b/boards/base/Olimex-SAM7EX256-GE12/readme.txt
new file mode 100644
index 00000000..ebf1497a
--- /dev/null
+++ b/boards/base/Olimex-SAM7EX256-GE12/readme.txt
@@ -0,0 +1,15 @@
+This directory contains the interface for the Olimex SAM7EX256 board
+running under ChibiOS.
+
+On this board uGFX currently supports:
+ - GDISP via the Nokia6610GE12 display
+ - GADC via the AT91SAM7 driver
+ - GINPUT-dials via the GADC driver
+ - GINPUT-toggles via the Pal driver
+ - GAUDIN via the GADC driver
+
+Note there are two variants of this board - one with the GE8 display
+ and one with the GE12 display. This one is for the GE12 display.
+
+See the Olimex-SAM7EX256-GE8 board file directory for example Makefiles etc.
+Don't forget to change the example Makefile to point the GFX board file to the GE12 instead of the GE8.
diff --git a/boards/base/Olimex-SAM7EX256-GE8/board.mk b/boards/base/Olimex-SAM7EX256-GE8/board.mk
new file mode 100644
index 00000000..6abd9a33
--- /dev/null
+++ b/boards/base/Olimex-SAM7EX256-GE8/board.mk
@@ -0,0 +1,8 @@
+GFXINC += $(GFXLIB)/boards/base/Olimex-SAM7EX256-GE8
+GFXSRC +=
+GFXDEFS += -DGFX_USE_OS_CHIBIOS=TRUE
+include $(GFXLIB)/drivers/gdisp/Nokia6610GE8/gdisp_lld.mk
+include $(GFXLIB)/drivers/gadc/AT91SAM7/gadc_lld.mk
+include $(GFXLIB)/drivers/ginput/dial/GADC/ginput_lld.mk
+include $(GFXLIB)/drivers/ginput/toggle/Pal/ginput_lld.mk
+include $(GFXLIB)/drivers/gaudin/gadc/gaudin_lld.mk
diff --git a/boards/base/Olimex-SAM7EX256-GE8/board_Nokia6610GE8.h b/boards/base/Olimex-SAM7EX256-GE8/board_Nokia6610GE8.h
new file mode 100644
index 00000000..c88dbe74
--- /dev/null
+++ b/boards/base/Olimex-SAM7EX256-GE8/board_Nokia6610GE8.h
@@ -0,0 +1,195 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file boards/base/Olimex-SAM7EX256-GE8/board_Nokia6610GE8.h
+ * @brief GDISP Graphic Driver subsystem board interface for the Olimex SAM7-EX256 board.
+ */
+
+#ifndef _GDISP_LLD_BOARD_H
+#define _GDISP_LLD_BOARD_H
+
+/*
+ * Set various display properties. These properties mostly depend on the exact controller chip you get.
+ * The defaults should work for most controllers.
+ */
+//#define GDISP_GE8_BROKEN_CONTROLLER FALSE // Uncomment this out if you have a controller thats not window wrap broken.
+//#define GDISP_SCREEN_HEIGHT 130 // The visible display height
+//#define GDISP_SCREEN_WIDTH 130 // The visible display width
+//#define GDISP_RAM_X_OFFSET 0 // The x offset of the visible area
+//#define GDISP_RAM_Y_OFFSET 2 // The y offset of the visible area
+//#define GDISP_SLEEP_SIZE 32 // The size of the sleep mode partial display
+//#define GDISP_SLEEP_POS 50 // The position of the sleep mode partial display
+//#define GDISP_INITIAL_CONTRAST 38 // The initial contrast percentage
+//#define GDISP_INITIAL_BACKLIGHT 100 // The initial backlight percentage
+
+// For a multiple display configuration we would put all this in a structure and then
+// set g->board to that structure.
+
+// ******************************************************
+// Pointers to AT91SAM7X256 peripheral data structures
+// ******************************************************
+static volatile AT91PS_PIO pPIOA = AT91C_BASE_PIOA;
+static volatile AT91PS_PIO pPIOB = AT91C_BASE_PIOB;
+static volatile AT91PS_SPI pSPI = AT91C_BASE_SPI0;
+static volatile AT91PS_PMC pPMC = AT91C_BASE_PMC;
+static volatile AT91PS_PDC pPDC = AT91C_BASE_PDC_SPI0;
+
+/* The PWM backlight control is non-linear on this board.
+ * We pick values here that make it look a bit more linear.
+ */
+#define PWM_TOP_VALUE 500
+#define PWM_BOTTOM_VALUE 200
+
+#define PWM_VALUE(x) (PWM_BOTTOM_VALUE+(PWM_TOP_VALUE-PWM_BOTTOM_VALUE)*(x)/100)
+
+/* PWM configuration structure. The LCD Backlight is on PWM1/PB20 ie PWM2/PIN1 in ChibiOS speak */
+static const PWMConfig pwmcfg = {
+ 1000000, /* 1 MHz PWM clock frequency. Ignored as we are using PWM_MCK_DIV_n */
+ 1000, /* PWM period is 1000 cycles. */
+ NULL,
+ {
+ {PWM_MCK_DIV_1 | PWM_OUTPUT_ACTIVE_HIGH | PWM_OUTPUT_PIN1 | PWM_DISABLEPULLUP_PIN1, NULL},
+ },
+};
+
+static bool_t pwmRunning = FALSE;
+
+/**
+ * @brief Initialise the board for the display.
+ * @notes Performs the following functions:
+ * 1. initialise the spi port used by your display
+ * 2. initialise the reset pin (initial state not-in-reset)
+ * 3. initialise the chip select pin (initial state not-active)
+ * 4. initialise the backlight pin (initial state back-light off)
+ *
+ * @notapi
+ */
+static inline void init_board(GDisplay *g) {
+
+ // As we are not using multiple displays we set g->board to NULL as we don't use it.
+ g->board = 0;
+
+ switch(g->controllerdisplay) {
+ case 0: // Set up for Display 0
+ // *********************************************************************************************
+ // InitSpi( )
+ //
+ // Sets up SPI channel 0 for communications to Nokia 6610 LCD Display
+ //
+ // I/O ports used: PA2 = LCD Reset (set to low to reset)
+ // PA12 = LCD chip select (set to low to select the LCD chip)
+ // PA16 = SPI0_MISO Master In - Slave Out (not used in LCD interface)
+ // PA17 = SPI0_MOSI Master Out - Slave In pin (Serial Data to LCD slave)
+ // PA18 = SPI0_SPCK Serial Clock (to LCD slave)
+ // PB20 = backlight control (normally PWM control, 1 = full on)
+ //
+ // *********************************************************************************************}
+
+ /* This code should really use the ChibiOS driver for these functions */
+
+ // Pin for backlight
+ pPIOB->PIO_CODR = PIOB_LCD_BL_MASK; // Set PB20 to LOW
+ pPIOB->PIO_OER = PIOB_LCD_BL_MASK; // Configure PB20 as output
+
+ // Reset pin
+ pPIOA->PIO_SODR = PIOA_LCD_RESET_MASK; // Set PA2 to HIGH
+ pPIOA->PIO_OER = PIOA_LCD_RESET_MASK; // Configure PA2 as output
+
+ // CS pin - this seems to be ignored
+ // pPIOA->PIO_SODR = 1<<12; // Set PA2 to HIGH
+ // pPIOA->PIO_OER = 1<<12; // Configure PA2 as output
+
+ // Init SPI0
+ // Disable the following pins from PIO control (will be used instead by the SPI0 peripheral)
+ // BIT12 = PA12 -> SPI0_NPCS0 chip select
+ // BIT16 = PA16 -> SPI0_MISO Master In - Slave Out (not used in LCD interface)
+ // BIT17 = PA17 -> SPI0_MOSI Master Out - Slave In pin (Serial Data to LCD slave)
+ // BIT18 = PA18 -> SPI0_SPCK Serial Clock (to LCD slave)
+ pPIOA->PIO_PDR = (1<<12) | (1<<16) | (1<<17) | (1<<18);
+ pPIOA->PIO_ASR = (1<<12) | (1<<16) | (1<<17) | (1<<18);
+ pPIOA->PIO_BSR = 0;
+
+ //enable the clock of SPI
+ pPMC->PMC_PCER = 1 << AT91C_ID_SPI0;
+
+ // Fixed mode
+ pSPI->SPI_CR = 0x81; //SPI Enable, Software reset
+ pSPI->SPI_CR = 0x01; //SPI Enable
+ pSPI->SPI_MR = 0xE0011; //Master mode, fixed select, disable decoder, PCS=1110
+ pSPI->SPI_CSR[0] = 0x01010311; //9bit, CPOL=1, ClockPhase=0, SCLK = 48Mhz/3 = 16MHz
+
+ /* Display backlight control at 100% */
+ pwmRunning = FALSE;
+ palSetPad(IOPORT2, PIOB_LCD_BL);
+ break;
+ }
+}
+
+static inline void post_init_board(GDisplay *g) {
+ (void) g;
+}
+
+static inline void setpin_reset(GDisplay *g, bool_t state) {
+ (void) g;
+ if (state)
+ palClearPad(IOPORT1, PIOA_LCD_RESET);
+ else
+ palSetPad(IOPORT1, PIOA_LCD_RESET);
+}
+
+static inline void set_backlight(GDisplay *g, uint8_t percent) {
+ (void) g;
+ if (percent == 100) {
+ /* Turn the pin on - No PWM */
+ if (pwmRunning) {
+ pwmStop(&PWMD2);
+ pwmRunning = FALSE;
+ }
+ palSetPad(IOPORT2, PIOB_LCD_BL);
+ } else if (percent == 0) {
+ /* Turn the pin off - No PWM */
+ if (pwmRunning) {
+ pwmStop(&PWMD2);
+ pwmRunning = FALSE;
+ }
+ palClearPad(IOPORT2, PIOB_LCD_BL);
+ } else {
+ /* Use the PWM */
+ if (!pwmRunning) {
+ pwmStart(&PWMD2, &pwmcfg);
+ pwmRunning = TRUE;
+ }
+ pwmEnableChannel(&PWMD2, 0, PWM_VALUE(percent));
+ }
+}
+
+static inline void acquire_bus(GDisplay *g) {
+ (void) g;
+}
+
+static inline void release_bus(GDisplay *g) {
+ (void) g;
+}
+
+static inline void write_index(GDisplay *g, uint16_t index) {
+ (void) g;
+ // wait for the previous transfer to complete
+ while((pSPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0);
+ // send the command
+ pSPI->SPI_TDR = index & 0xFF;
+}
+
+static inline void write_data(GDisplay *g, uint16_t data) {
+ (void) g;
+ // wait for the previous transfer to complete
+ while((pSPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0);
+ // send the data
+ pSPI->SPI_TDR = data | 0x0100;
+}
+
+#endif /* _GDISP_LLD_BOARD_H */
diff --git a/boards/base/Olimex-SAM7EX256-GE8/example/Makefile b/boards/base/Olimex-SAM7EX256-GE8/example/Makefile
new file mode 100644
index 00000000..d6161d5e
--- /dev/null
+++ b/boards/base/Olimex-SAM7EX256-GE8/example/Makefile
@@ -0,0 +1,201 @@
+##############################################################################
+# Build global options
+# NOTE: Can be overridden externally.
+#
+
+# Compiler options here.
+ifeq ($(USE_OPT),)
+ # If you are using gcc V4.5.1 or older then replace -g with -ggdb -gstabs+
+ # For debugging you probably want -O0 rather than -O2
+ USE_OPT = -O0 -g -fomit-frame-pointer -mabi=apcs-gnu
+endif
+
+# C specific options here (added to USE_OPT).
+ifeq ($(USE_COPT),)
+ USE_COPT =
+endif
+
+# C++ specific options here (added to USE_OPT).
+ifeq ($(USE_CPPOPT),)
+ USE_CPPOPT = -fno-rtti
+endif
+
+# Enable this if you want the linker to remove unused code and data
+ifeq ($(USE_LINK_GC),)
+ USE_LINK_GC = yes
+endif
+
+# If enabled, this option allows to compile the application in THUMB mode.
+ifeq ($(USE_THUMB),)
+ USE_THUMB = no
+endif
+
+# Enable this if you want to see the full log while compiling.
+ifeq ($(USE_VERBOSE_COMPILE),)
+ USE_VERBOSE_COMPILE = no
+endif
+
+#
+# Build global options
+##############################################################################
+
+##############################################################################
+# Project, sources and paths
+#
+
+# Define project name here
+PROJECT = ch
+
+# Imported source files and paths for ChibiOS
+CHIBIOS = ../ChibiOS
+include $(CHIBIOS)/boards/OLIMEX_SAM7_EX256/board.mk
+include $(CHIBIOS)/os/hal/platforms/AT91SAM7/platform.mk
+include $(CHIBIOS)/os/hal/hal.mk
+include $(CHIBIOS)/os/ports/GCC/ARM/AT91SAM7/port.mk
+include $(CHIBIOS)/os/kernel/kernel.mk
+
+# We define a non standard linker script here just to give us some more stack space
+# LDSCRIPT= $(PORTLD)/AT91SAM7X256.ld
+LDSCRIPT= linker.ld
+
+# Imported source files and paths for uGFX
+GFXLIB = ../uGFX
+include $(GFXLIB)/gfx.mk
+include $(GFXLIB)/boards/base/Olimex-SAM7EX256-GE8/board.mk
+
+# Where is our source code - alter these for your project.
+MYFILES = $(GFXLIB)/demos/modules/gdisp/basics
+MYCSRC = $(MYFILES)/main.c
+
+# C sources that can be compiled in ARM or THUMB mode depending on the global
+# setting.
+CSRC = $(PORTSRC) \
+ $(KERNSRC) \
+ $(TESTSRC) \
+ $(HALSRC) \
+ $(PLATFORMSRC) \
+ $(BOARDSRC) \
+ $(GFXSRC) \
+ $(MYCSRC)
+
+# C++ sources that can be compiled in ARM or THUMB mode depending on the global
+# setting.
+CPPSRC =
+
+# C sources to be compiled in ARM mode regardless of the global setting.
+# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
+# option that results in lower performance and larger code size.
+ACSRC =
+
+# C++ sources to be compiled in ARM mode regardless of the global setting.
+# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
+# option that results in lower performance and larger code size.
+ACPPSRC =
+
+# C sources to be compiled in THUMB mode regardless of the global setting.
+# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
+# option that results in lower performance and larger code size.
+TCSRC =
+
+# C sources to be compiled in THUMB mode regardless of the global setting.
+# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
+# option that results in lower performance and larger code size.
+TCPPSRC =
+
+# List ASM source files here
+ASMSRC = $(PORTASM)
+
+INCDIR = $(PORTINC) $(KERNINC) $(TESTINC) \
+ $(HALINC) $(PLATFORMINC) $(BOARDINC) \
+ $(GFXINC) \
+ $(MYFILES)
+
+#
+# Project, sources and paths
+##############################################################################
+
+##############################################################################
+# Compiler settings
+#
+
+MCU = arm7tdmi
+
+#TRGT = arm-elf-
+TRGT = arm-none-eabi-
+CC = $(TRGT)gcc
+CPPC = $(TRGT)g++
+# Enable loading with g++ only if you need C++ runtime support.
+# NOTE: You can use C++ even without C++ support if you are careful. C++
+# runtime support makes code size explode.
+# If you are using gcc V4.5.1 or older then add -ggdb -gstabs+ to the LD line
+LD = $(TRGT)gcc
+#LD = $(TRGT)g++
+CP = $(TRGT)objcopy
+AS = $(TRGT)gcc -x assembler-with-cpp
+OD = $(TRGT)objdump
+HEX = $(CP) -O ihex
+BIN = $(CP) -O binary
+
+# ARM-specific options here
+AOPT =
+
+# THUMB-specific options here
+TOPT = -mthumb -DTHUMB
+
+# Define C warning options here
+CWARN = -Wall -Wextra -Wstrict-prototypes
+
+# Define C++ warning options here
+CPPWARN = -Wall -Wextra
+
+#
+# Compiler settings
+##############################################################################
+
+##############################################################################
+# Start of default section
+#
+
+# List all default C defines here, like -D_DEBUG=1
+DDEFS = $(GFXDEFS)
+
+# List all default ASM defines here, like -D_DEBUG=1
+DADEFS =
+
+# List all default directories to look for include files here
+DINCDIR =
+
+# List the default directory to look for the libraries here
+DLIBDIR =
+
+# List all default libraries here
+DLIBS =
+
+#
+# End of default section
+##############################################################################
+
+##############################################################################
+# Start of user section
+#
+
+# List all user C define here, like -D_DEBUG=1
+UDEFS =
+
+# Define ASM defines here
+UADEFS =
+
+# List all user directories here
+UINCDIR =
+
+# List the user directory to look for the libraries here
+ULIBDIR =
+
+# List all user libraries here
+ULIBS =
+
+#
+# End of user defines
+##############################################################################
+
+include $(CHIBIOS)/os/ports/GCC/ARM/rules.mk
diff --git a/boards/base/Olimex-SAM7EX256-GE8/example/chconf.h b/boards/base/Olimex-SAM7EX256-GE8/example/chconf.h
new file mode 100644
index 00000000..6d012c3e
--- /dev/null
+++ b/boards/base/Olimex-SAM7EX256-GE8/example/chconf.h
@@ -0,0 +1,542 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ ---
+
+ A special exception to the GPL can be applied should you wish to distribute
+ a combined work that includes ChibiOS/RT, without being obliged to provide
+ the source code for any proprietary components. See the file exception.txt
+ for full details of how and when the exception can be applied.
+*/
+
+/**
+ * @file templates/chconf.h
+ * @brief Configuration file template.
+ * @details A copy of this file must be placed in each project directory, it
+ * contains the application specific kernel settings.
+ *
+ * @addtogroup config
+ * @details Kernel related settings and hooks.
+ * @{
+ */
+
+#ifndef _CHCONF_H_
+#define _CHCONF_H_
+
+/*===========================================================================*/
+/**
+ * @name Kernel parameters and options
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief System tick frequency.
+ * @details Frequency of the system timer that drives the system ticks. This
+ * setting also defines the system tick time unit.
+ */
+#if !defined(CH_FREQUENCY) || defined(__DOXYGEN__)
+#define CH_FREQUENCY 1000
+#endif
+
+/**
+ * @brief Round robin interval.
+ * @details This constant is the number of system ticks allowed for the
+ * threads before preemption occurs. Setting this value to zero
+ * disables the preemption for threads with equal priority and the
+ * round robin becomes cooperative. Note that higher priority
+ * threads can still preempt, the kernel is always preemptive.
+ *
+ * @note Disabling the round robin preemption makes the kernel more compact
+ * and generally faster.
+ */
+#if !defined(CH_TIME_QUANTUM) || defined(__DOXYGEN__)
+#define CH_TIME_QUANTUM 20
+#endif
+
+/**
+ * @brief Managed RAM size.
+ * @details Size of the RAM area to be managed by the OS. If set to zero
+ * then the whole available RAM is used. The core memory is made
+ * available to the heap allocator and/or can be used directly through
+ * the simplified core memory allocator.
+ *
+ * @note In order to let the OS manage the whole RAM the linker script must
+ * provide the @p __heap_base__ and @p __heap_end__ symbols.
+ * @note Requires @p CH_USE_MEMCORE.
+ */
+#if !defined(CH_MEMCORE_SIZE) || defined(__DOXYGEN__)
+#define CH_MEMCORE_SIZE 0
+#endif
+
+/**
+ * @brief Idle thread automatic spawn suppression.
+ * @details When this option is activated the function @p chSysInit()
+ * does not spawn the idle thread automatically. The application has
+ * then the responsibility to do one of the following:
+ * - Spawn a custom idle thread at priority @p IDLEPRIO.
+ * - Change the main() thread priority to @p IDLEPRIO then enter
+ * an endless loop. In this scenario the @p main() thread acts as
+ * the idle thread.
+ * .
+ * @note Unless an idle thread is spawned the @p main() thread must not
+ * enter a sleep state.
+ */
+#if !defined(CH_NO_IDLE_THREAD) || defined(__DOXYGEN__)
+#define CH_NO_IDLE_THREAD FALSE
+#endif
+
+/** @} */
+
+/*===========================================================================*/
+/**
+ * @name Performance options
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief OS optimization.
+ * @details If enabled then time efficient rather than space efficient code
+ * is used when two possible implementations exist.
+ *
+ * @note This is not related to the compiler optimization options.
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_OPTIMIZE_SPEED) || defined(__DOXYGEN__)
+#define CH_OPTIMIZE_SPEED TRUE
+#endif
+
+/** @} */
+
+/*===========================================================================*/
+/**
+ * @name Subsystem options
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief Threads registry APIs.
+ * @details If enabled then the registry APIs are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_USE_REGISTRY) || defined(__DOXYGEN__)
+#define CH_USE_REGISTRY TRUE
+#endif
+
+/**
+ * @brief Threads synchronization APIs.
+ * @details If enabled then the @p chThdWait() function is included in
+ * the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_USE_WAITEXIT) || defined(__DOXYGEN__)
+#define CH_USE_WAITEXIT TRUE
+#endif
+
+/**
+ * @brief Semaphores APIs.
+ * @details If enabled then the Semaphores APIs are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_USE_SEMAPHORES) || defined(__DOXYGEN__)
+#define CH_USE_SEMAPHORES TRUE
+#endif
+
+/**
+ * @brief Semaphores queuing mode.
+ * @details If enabled then the threads are enqueued on semaphores by
+ * priority rather than in FIFO order.
+ *
+ * @note The default is @p FALSE. Enable this if you have special requirements.
+ * @note Requires @p CH_USE_SEMAPHORES.
+ */
+#if !defined(CH_USE_SEMAPHORES_PRIORITY) || defined(__DOXYGEN__)
+#define CH_USE_SEMAPHORES_PRIORITY FALSE
+#endif
+
+/**
+ * @brief Atomic semaphore API.
+ * @details If enabled then the semaphores the @p chSemSignalWait() API
+ * is included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_USE_SEMAPHORES.
+ */
+#if !defined(CH_USE_SEMSW) || defined(__DOXYGEN__)
+#define CH_USE_SEMSW TRUE
+#endif
+
+/**
+ * @brief Mutexes APIs.
+ * @details If enabled then the mutexes APIs are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_USE_MUTEXES) || defined(__DOXYGEN__)
+#define CH_USE_MUTEXES TRUE
+#endif
+
+/**
+ * @brief Conditional Variables APIs.
+ * @details If enabled then the conditional variables APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_USE_MUTEXES.
+ */
+#if !defined(CH_USE_CONDVARS) || defined(__DOXYGEN__)
+#define CH_USE_CONDVARS TRUE
+#endif
+
+/**
+ * @brief Conditional Variables APIs with timeout.
+ * @details If enabled then the conditional variables APIs with timeout
+ * specification are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_USE_CONDVARS.
+ */
+#if !defined(CH_USE_CONDVARS_TIMEOUT) || defined(__DOXYGEN__)
+#define CH_USE_CONDVARS_TIMEOUT TRUE
+#endif
+
+/**
+ * @brief Events Flags APIs.
+ * @details If enabled then the event flags APIs are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_USE_EVENTS) || defined(__DOXYGEN__)
+#define CH_USE_EVENTS TRUE
+#endif
+
+/**
+ * @brief Events Flags APIs with timeout.
+ * @details If enabled then the events APIs with timeout specification
+ * are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_USE_EVENTS.
+ */
+#if !defined(CH_USE_EVENTS_TIMEOUT) || defined(__DOXYGEN__)
+#define CH_USE_EVENTS_TIMEOUT TRUE
+#endif
+
+/**
+ * @brief Synchronous Messages APIs.
+ * @details If enabled then the synchronous messages APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_USE_MESSAGES) || defined(__DOXYGEN__)
+#define CH_USE_MESSAGES TRUE
+#endif
+
+/**
+ * @brief Synchronous Messages queuing mode.
+ * @details If enabled then messages are served by priority rather than in
+ * FIFO order.
+ *
+ * @note The default is @p FALSE. Enable this if you have special requirements.
+ * @note Requires @p CH_USE_MESSAGES.
+ */
+#if !defined(CH_USE_MESSAGES_PRIORITY) || defined(__DOXYGEN__)
+#define CH_USE_MESSAGES_PRIORITY FALSE
+#endif
+
+/**
+ * @brief Mailboxes APIs.
+ * @details If enabled then the asynchronous messages (mailboxes) APIs are
+ * included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_USE_SEMAPHORES.
+ */
+#if !defined(CH_USE_MAILBOXES) || defined(__DOXYGEN__)
+#define CH_USE_MAILBOXES TRUE
+#endif
+
+/**
+ * @brief I/O Queues APIs.
+ * @details If enabled then the I/O queues APIs are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_USE_QUEUES) || defined(__DOXYGEN__)
+#define CH_USE_QUEUES TRUE
+#endif
+
+/**
+ * @brief Core Memory Manager APIs.
+ * @details If enabled then the core memory manager APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_USE_MEMCORE) || defined(__DOXYGEN__)
+#define CH_USE_MEMCORE TRUE
+#endif
+
+/**
+ * @brief Heap Allocator APIs.
+ * @details If enabled then the memory heap allocator APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_USE_MEMCORE and either @p CH_USE_MUTEXES or
+ * @p CH_USE_SEMAPHORES.
+ * @note Mutexes are recommended.
+ */
+#if !defined(CH_USE_HEAP) || defined(__DOXYGEN__)
+#define CH_USE_HEAP TRUE
+#endif
+
+/**
+ * @brief C-runtime allocator.
+ * @details If enabled the the heap allocator APIs just wrap the C-runtime
+ * @p malloc() and @p free() functions.
+ *
+ * @note The default is @p FALSE.
+ * @note Requires @p CH_USE_HEAP.
+ * @note The C-runtime may or may not require @p CH_USE_MEMCORE, see the
+ * appropriate documentation.
+ */
+#if !defined(CH_USE_MALLOC_HEAP) || defined(__DOXYGEN__)
+#define CH_USE_MALLOC_HEAP FALSE
+#endif
+
+/**
+ * @brief Memory Pools Allocator APIs.
+ * @details If enabled then the memory pools allocator APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_USE_MEMPOOLS) || defined(__DOXYGEN__)
+#define CH_USE_MEMPOOLS TRUE
+#endif
+
+/**
+ * @brief Dynamic Threads APIs.
+ * @details If enabled then the dynamic threads creation APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_USE_WAITEXIT.
+ * @note Requires @p CH_USE_HEAP and/or @p CH_USE_MEMPOOLS.
+ */
+#if !defined(CH_USE_DYNAMIC) || defined(__DOXYGEN__)
+#define CH_USE_DYNAMIC TRUE
+#endif
+
+/** @} */
+
+/*===========================================================================*/
+/**
+ * @name Debug options
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief Debug option, system state check.
+ * @details If enabled the correct call protocol for system APIs is checked
+ * at runtime.
+ *
+ * @note The default is @p FALSE.
+ */
+#if !defined(CH_DBG_SYSTEM_STATE_CHECK) || defined(__DOXYGEN__)
+#define CH_DBG_SYSTEM_STATE_CHECK FALSE
+#endif
+
+/**
+ * @brief Debug option, parameters checks.
+ * @details If enabled then the checks on the API functions input
+ * parameters are activated.
+ *
+ * @note The default is @p FALSE.
+ */
+#if !defined(CH_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__)
+#define CH_DBG_ENABLE_CHECKS FALSE
+#endif
+
+/**
+ * @brief Debug option, consistency checks.
+ * @details If enabled then all the assertions in the kernel code are
+ * activated. This includes consistency checks inside the kernel,
+ * runtime anomalies and port-defined checks.
+ *
+ * @note The default is @p FALSE.
+ */
+#if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__)
+#define CH_DBG_ENABLE_ASSERTS FALSE
+#endif
+
+/**
+ * @brief Debug option, trace buffer.
+ * @details If enabled then the context switch circular trace buffer is
+ * activated.
+ *
+ * @note The default is @p FALSE.
+ */
+#if !defined(CH_DBG_ENABLE_TRACE) || defined(__DOXYGEN__)
+#define CH_DBG_ENABLE_TRACE FALSE
+#endif
+
+/**
+ * @brief Debug option, stack checks.
+ * @details If enabled then a runtime stack check is performed.
+ *
+ * @note The default is @p FALSE.
+ * @note The stack check is performed in a architecture/port dependent way.
+ * It may not be implemented or some ports.
+ * @note The default failure mode is to halt the system with the global
+ * @p panic_msg variable set to @p NULL.
+ */
+#if !defined(CH_DBG_ENABLE_STACK_CHECK) || defined(__DOXYGEN__)
+#define CH_DBG_ENABLE_STACK_CHECK FALSE
+#endif
+
+/**
+ * @brief Debug option, stacks initialization.
+ * @details If enabled then the threads working area is filled with a byte
+ * value when a thread is created. This can be useful for the
+ * runtime measurement of the used stack.
+ *
+ * @note The default is @p FALSE.
+ */
+#if !defined(CH_DBG_FILL_THREADS) || defined(__DOXYGEN__)
+#define CH_DBG_FILL_THREADS FALSE
+#endif
+
+/**
+ * @brief Debug option, threads profiling.
+ * @details If enabled then a field is added to the @p Thread structure that
+ * counts the system ticks occurred while executing the thread.
+ *
+ * @note The default is @p TRUE.
+ * @note This debug option is defaulted to TRUE because it is required by
+ * some test cases into the test suite.
+ */
+#if !defined(CH_DBG_THREADS_PROFILING) || defined(__DOXYGEN__)
+#define CH_DBG_THREADS_PROFILING TRUE
+#endif
+
+/** @} */
+
+/*===========================================================================*/
+/**
+ * @name Kernel hooks
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief Threads descriptor structure extension.
+ * @details User fields added to the end of the @p Thread structure.
+ */
+#if !defined(THREAD_EXT_FIELDS) || defined(__DOXYGEN__)
+#define THREAD_EXT_FIELDS \
+ /* Add threads custom fields here.*/
+#endif
+
+/**
+ * @brief Threads initialization hook.
+ * @details User initialization code added to the @p chThdInit() API.
+ *
+ * @note It is invoked from within @p chThdInit() and implicitly from all
+ * the threads creation APIs.
+ */
+#if !defined(THREAD_EXT_INIT_HOOK) || defined(__DOXYGEN__)
+#define THREAD_EXT_INIT_HOOK(tp) { \
+ /* Add threads initialization code here.*/ \
+}
+#endif
+
+/**
+ * @brief Threads finalization hook.
+ * @details User finalization code added to the @p chThdExit() API.
+ *
+ * @note It is inserted into lock zone.
+ * @note It is also invoked when the threads simply return in order to
+ * terminate.
+ */
+#if !defined(THREAD_EXT_EXIT_HOOK) || defined(__DOXYGEN__)
+#define THREAD_EXT_EXIT_HOOK(tp) { \
+ /* Add threads finalization code here.*/ \
+}
+#endif
+
+/**
+ * @brief Context switch hook.
+ * @details This hook is invoked just before switching between threads.
+ */
+#if !defined(THREAD_CONTEXT_SWITCH_HOOK) || defined(__DOXYGEN__)
+#define THREAD_CONTEXT_SWITCH_HOOK(ntp, otp) { \
+ /* System halt code here.*/ \
+}
+#endif
+
+/**
+ * @brief Idle Loop hook.
+ * @details This hook is continuously invoked by the idle thread loop.
+ */
+#if !defined(IDLE_LOOP_HOOK) || defined(__DOXYGEN__)
+#define IDLE_LOOP_HOOK() { \
+ /* Idle loop code here.*/ \
+}
+#endif
+
+/**
+ * @brief System tick event hook.
+ * @details This hook is invoked in the system tick handler immediately
+ * after processing the virtual timers queue.
+ */
+#if !defined(SYSTEM_TICK_EVENT_HOOK) || defined(__DOXYGEN__)
+#define SYSTEM_TICK_EVENT_HOOK() { \
+ /* System tick event code here.*/ \
+}
+#endif
+
+/**
+ * @brief System halt hook.
+ * @details This hook is invoked in case to a system halting error before
+ * the system is halted.
+ */
+#if !defined(SYSTEM_HALT_HOOK) || defined(__DOXYGEN__)
+#define SYSTEM_HALT_HOOK() { \
+ /* System halt code here.*/ \
+}
+#endif
+
+/** @} */
+
+/*===========================================================================*/
+/* Port-specific settings (override port settings defaulted in chcore.h). */
+/*===========================================================================*/
+
+#endif /* _CHCONF_H_ */
+
+/** @} */
diff --git a/boards/base/Olimex-SAM7EX256-GE8/example/halconf.h b/boards/base/Olimex-SAM7EX256-GE8/example/halconf.h
new file mode 100644
index 00000000..db88d41b
--- /dev/null
+++ b/boards/base/Olimex-SAM7EX256-GE8/example/halconf.h
@@ -0,0 +1,360 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ ---
+
+ A special exception to the GPL can be applied should you wish to distribute
+ a combined work that includes ChibiOS/RT, without being obliged to provide
+ the source code for any proprietary components. See the file exception.txt
+ for full details of how and when the exception can be applied.
+*/
+
+/**
+ * @file templates/halconf.h
+ * @brief HAL configuration header.
+ * @details HAL configuration file, this file allows to enable or disable the
+ * various device drivers from your application. You may also use
+ * this file in order to override the device drivers default settings.
+ *
+ * @addtogroup HAL_CONF
+ * @{
+ */
+
+#ifndef _HALCONF_H_
+#define _HALCONF_H_
+
+#include "mcuconf.h"
+
+/**
+ * @brief Enables the TM subsystem.
+ */
+#if !defined(HAL_USE_TM) || defined(__DOXYGEN__)
+#define HAL_USE_TM FALSE
+#endif
+
+/**
+ * @brief Enables the PAL subsystem.
+ */
+#if !defined(HAL_USE_PAL) || defined(__DOXYGEN__)
+#define HAL_USE_PAL TRUE
+#endif
+
+/**
+ * @brief Enables the ADC subsystem.
+ */
+#if !defined(HAL_USE_ADC) || defined(__DOXYGEN__)
+#define HAL_USE_ADC TRUE
+#endif
+
+/**
+ * @brief Enables the CAN subsystem.
+ */
+#if !defined(HAL_USE_CAN) || defined(__DOXYGEN__)
+#define HAL_USE_CAN FALSE
+#endif
+
+/**
+ * @brief Enables the EXT subsystem.
+ */
+#if !defined(HAL_USE_EXT) || defined(__DOXYGEN__)
+#define HAL_USE_EXT FALSE
+#endif
+
+/**
+ * @brief Enables the GPT subsystem.
+ */
+#if !defined(HAL_USE_GPT) || defined(__DOXYGEN__)
+#define HAL_USE_GPT FALSE
+#endif
+
+/**
+ * @brief Enables the I2C subsystem.
+ */
+#if !defined(HAL_USE_I2C) || defined(__DOXYGEN__)
+#define HAL_USE_I2C FALSE
+#endif
+
+/**
+ * @brief Enables the ICU subsystem.
+ */
+#if !defined(HAL_USE_ICU) || defined(__DOXYGEN__)
+#define HAL_USE_ICU FALSE
+#endif
+
+/**
+ * @brief Enables the MAC subsystem.
+ */
+#if !defined(HAL_USE_MAC) || defined(__DOXYGEN__)
+#define HAL_USE_MAC FALSE
+#endif
+
+/**
+ * @brief Enables the MMC_SPI subsystem.
+ */
+#if !defined(HAL_USE_MMC_SPI) || defined(__DOXYGEN__)
+#define HAL_USE_MMC_SPI FALSE
+#endif
+
+/**
+ * @brief Enables the PWM subsystem.
+ */
+#if !defined(HAL_USE_PWM) || defined(__DOXYGEN__)
+#define HAL_USE_PWM TRUE
+#define PWM_USE_PWM1 FALSE
+#define PWM_USE_PWM2 TRUE
+#define PWM_USE_PWM3 FALSE
+#define PWM_USE_PWM4 FALSE
+#endif
+
+/**
+ * @brief Enables the RTC subsystem.
+ */
+#if !defined(HAL_USE_RTC) || defined(__DOXYGEN__)
+#define HAL_USE_RTC FALSE
+#endif
+
+/**
+ * @brief Enables the SDC subsystem.
+ */
+#if !defined(HAL_USE_SDC) || defined(__DOXYGEN__)
+#define HAL_USE_SDC FALSE
+#endif
+
+/**
+ * @brief Enables the SERIAL subsystem.
+ */
+#if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__)
+#define HAL_USE_SERIAL FALSE
+#endif
+
+/**
+ * @brief Enables the SERIAL over USB subsystem.
+ */
+#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
+#define HAL_USE_SERIAL_USB FALSE
+#endif
+
+/**
+ * @brief Enables the SPI subsystem.
+ */
+#if !defined(HAL_USE_SPI) || defined(__DOXYGEN__)
+#define HAL_USE_SPI TRUE
+#endif
+
+/**
+ * @brief Enables the UART subsystem.
+ */
+#if !defined(HAL_USE_UART) || defined(__DOXYGEN__)
+#define HAL_USE_UART FALSE
+#endif
+
+/**
+ * @brief Enables the USB subsystem.
+ */
+#if !defined(HAL_USE_USB) || defined(__DOXYGEN__)
+#define HAL_USE_USB FALSE
+#endif
+
+/*===========================================================================*/
+/* ADC driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(ADC_USE_WAIT) || defined(__DOXYGEN__)
+#define ADC_USE_WAIT TRUE
+#endif
+
+/**
+ * @brief Enables the @p adcAcquireBus() and @p adcReleaseBus() APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
+#define ADC_USE_MUTUAL_EXCLUSION TRUE
+#endif
+
+/*===========================================================================*/
+/* CAN driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Sleep mode related APIs inclusion switch.
+ */
+#if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__)
+#define CAN_USE_SLEEP_MODE TRUE
+#endif
+
+/*===========================================================================*/
+/* I2C driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables the mutual exclusion APIs on the I2C bus.
+ */
+#if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
+#define I2C_USE_MUTUAL_EXCLUSION TRUE
+#endif
+
+/*===========================================================================*/
+/* MAC driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables an event sources for incoming packets.
+ */
+#if !defined(MAC_USE_ZERO_COPY) || defined(__DOXYGEN__)
+#define MAC_USE_ZERO_COPY FALSE
+#endif
+
+/**
+ * @brief Enables an event sources for incoming packets.
+ */
+#if !defined(MAC_USE_EVENTS) || defined(__DOXYGEN__)
+#define MAC_USE_EVENTS TRUE
+#endif
+
+/*===========================================================================*/
+/* MMC_SPI driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Block size for MMC transfers.
+ */
+#if !defined(MMC_SECTOR_SIZE) || defined(__DOXYGEN__)
+#define MMC_SECTOR_SIZE 512
+#endif
+
+/**
+ * @brief Delays insertions.
+ * @details If enabled this options inserts delays into the MMC waiting
+ * routines releasing some extra CPU time for the threads with
+ * lower priority, this may slow down the driver a bit however.
+ * This option is recommended also if the SPI driver does not
+ * use a DMA channel and heavily loads the CPU.
+ */
+#if !defined(MMC_NICE_WAITING) || defined(__DOXYGEN__)
+#define MMC_NICE_WAITING TRUE
+#endif
+
+/**
+ * @brief Number of positive insertion queries before generating the
+ * insertion event.
+ */
+#if !defined(MMC_POLLING_INTERVAL) || defined(__DOXYGEN__)
+#define MMC_POLLING_INTERVAL 10
+#endif
+
+/**
+ * @brief Interval, in milliseconds, between insertion queries.
+ */
+#if !defined(MMC_POLLING_DELAY) || defined(__DOXYGEN__)
+#define MMC_POLLING_DELAY 10
+#endif
+
+/**
+ * @brief Uses the SPI polled API for small data transfers.
+ * @details Polled transfers usually improve performance because it
+ * saves two context switches and interrupt servicing. Note
+ * that this option has no effect on large transfers which
+ * are always performed using DMAs/IRQs.
+ */
+#if !defined(MMC_USE_SPI_POLLING) || defined(__DOXYGEN__)
+#define MMC_USE_SPI_POLLING TRUE
+#endif
+
+/*===========================================================================*/
+/* SDC driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Number of initialization attempts before rejecting the card.
+ * @note Attempts are performed at 10mS intervals.
+ */
+#if !defined(SDC_INIT_RETRY) || defined(__DOXYGEN__)
+#define SDC_INIT_RETRY 100
+#endif
+
+/**
+ * @brief Include support for MMC cards.
+ * @note MMC support is not yet implemented so this option must be kept
+ * at @p FALSE.
+ */
+#if !defined(SDC_MMC_SUPPORT) || defined(__DOXYGEN__)
+#define SDC_MMC_SUPPORT FALSE
+#endif
+
+/**
+ * @brief Delays insertions.
+ * @details If enabled this options inserts delays into the MMC waiting
+ * routines releasing some extra CPU time for the threads with
+ * lower priority, this may slow down the driver a bit however.
+ */
+#if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__)
+#define SDC_NICE_WAITING TRUE
+#endif
+
+/*===========================================================================*/
+/* SERIAL driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Default bit rate.
+ * @details Configuration parameter, this is the baud rate selected for the
+ * default configuration.
+ */
+#if !defined(SERIAL_DEFAULT_BITRATE) || defined(__DOXYGEN__)
+#define SERIAL_DEFAULT_BITRATE 38400
+#endif
+
+/**
+ * @brief Serial buffers size.
+ * @details Configuration parameter, you can change the depth of the queue
+ * buffers depending on the requirements of your application.
+ * @note The default is 64 bytes for both the transmission and receive
+ * buffers.
+ */
+#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__)
+#define SERIAL_BUFFERS_SIZE 16
+#endif
+
+/*===========================================================================*/
+/* SPI driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(SPI_USE_WAIT) || defined(__DOXYGEN__)
+#define SPI_USE_WAIT TRUE
+#endif
+
+/**
+ * @brief Enables the @p spiAcquireBus() and @p spiReleaseBus() APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
+#define SPI_USE_MUTUAL_EXCLUSION TRUE
+#endif
+
+#endif /* _HALCONF_H_ */
+
+/** @} */
diff --git a/boards/base/Olimex-SAM7EX256-GE8/example/linker.ld b/boards/base/Olimex-SAM7EX256-GE8/example/linker.ld
new file mode 100644
index 00000000..c36a07a3
--- /dev/null
+++ b/boards/base/Olimex-SAM7EX256-GE8/example/linker.ld
@@ -0,0 +1,105 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ * AT91SAM7X256 memory setup.
+ */
+__und_stack_size__ = 0x0004;
+__abt_stack_size__ = 0x0004;
+__fiq_stack_size__ = 0x0010;
+__irq_stack_size__ = 0x0080;
+__svc_stack_size__ = 0x0004;
+__sys_stack_size__ = 0x0400;
+__stacks_total_size__ = __und_stack_size__ + __abt_stack_size__ + __fiq_stack_size__ + __irq_stack_size__ + __svc_stack_size__ + __sys_stack_size__;
+
+MEMORY
+{
+ flash : org = 0x100000, len = 256k
+ ram : org = 0x200020, len = 64k - 0x20
+}
+
+__ram_start__ = ORIGIN(ram);
+__ram_size__ = LENGTH(ram);
+__ram_end__ = __ram_start__ + __ram_size__;
+
+SECTIONS
+{
+ . = 0;
+
+ .text : ALIGN(16) SUBALIGN(16)
+ {
+ _text = .;
+ KEEP(*(vectors))
+ *(.text)
+ *(.text.*)
+ *(.rodata)
+ *(.rodata.*)
+ *(.glue_7t)
+ *(.glue_7)
+ *(.gcc*)
+ *(.ctors)
+ *(.dtors)
+ } > flash
+
+ .ARM.extab : {*(.ARM.extab* .gnu.linkonce.armextab.*)}
+
+ __exidx_start = .;
+ .ARM.exidx : {*(.ARM.exidx* .gnu.linkonce.armexidx.*)} > flash
+ __exidx_end = .;
+
+ .eh_frame_hdr : {*(.eh_frame_hdr)}
+
+ .eh_frame : ONLY_IF_RO {*(.eh_frame)}
+
+ . = ALIGN(4);
+ _etext = .;
+ _textdata = _etext;
+
+ .data :
+ {
+ _data = .;
+ *(.data)
+ . = ALIGN(4);
+ *(.data.*)
+ . = ALIGN(4);
+ *(.ramtext)
+ . = ALIGN(4);
+ _edata = .;
+ } > ram AT > flash
+
+ .bss :
+ {
+ _bss_start = .;
+ *(.bss)
+ . = ALIGN(4);
+ *(.bss.*)
+ . = ALIGN(4);
+ *(COMMON)
+ . = ALIGN(4);
+ _bss_end = .;
+ } > ram
+}
+
+PROVIDE(end = .);
+_end = .;
+
+__heap_base__ = _end;
+__heap_end__ = __ram_end__ - __stacks_total_size__;
+__main_thread_stack_base__ = __ram_end__ - __stacks_total_size__;
diff --git a/boards/base/Olimex-SAM7EX256-GE8/example/mcuconf.h b/boards/base/Olimex-SAM7EX256-GE8/example/mcuconf.h
new file mode 100644
index 00000000..a9a0fea7
--- /dev/null
+++ b/boards/base/Olimex-SAM7EX256-GE8/example/mcuconf.h
@@ -0,0 +1,71 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ ---
+
+ A special exception to the GPL can be applied should you wish to distribute
+ a combined work that includes ChibiOS/RT, without being obliged to provide
+ the source code for any proprietary components. See the file exception.txt
+ for full details of how and when the exception can be applied.
+*/
+
+/*
+ * AT91SAM7 drivers configuration.
+ * The following settings override the default settings present in
+ * the various device driver implementation headers.
+ * Note that the settings for each driver only have effect if the driver
+ * is enabled in halconf.h.
+ */
+
+/*
+ * ADC driver system settings.
+ */
+
+/*
+ * CAN driver system settings.
+ */
+
+/*
+ * MAC driver system settings.
+ */
+#define MAC_TRANSMIT_BUFFERS 2
+#define MAC_RECEIVE_BUFFERS 2
+#define MAC_BUFFERS_SIZE 1518
+#define EMAC_INTERRUPT_PRIORITY (AT91C_AIC_PRIOR_HIGHEST - 3)
+
+/*
+ * PWM driver system settings.
+ */
+
+/*
+ * SERIAL driver system settings.
+ */
+#define USE_SAM7_USART0 TRUE
+#define USE_SAM7_USART1 TRUE
+#define SAM7_USART0_PRIORITY (AT91C_AIC_PRIOR_HIGHEST - 2)
+#define SAM7_USART1_PRIORITY (AT91C_AIC_PRIOR_HIGHEST - 2)
+
+/*
+ * SPI driver system settings.
+ */
+#define USE_AT91SAM7_SPI FALSE
+#define AT91SAM7_SPI_USE_SPI0 TRUE
+#define AT91SAM7_SPI_USE_SPI1 FALSE
+#define AT91SAM7_SPI0_PRIORITY (AT91C_AIC_PRIOR_HIGHEST - 1)
+#define AT91SAM7_SPI1_PRIORITY (AT91C_AIC_PRIOR_HIGHEST - 1)
diff --git a/boards/base/Olimex-SAM7EX256-GE8/example/openocd.cfg b/boards/base/Olimex-SAM7EX256-GE8/example/openocd.cfg
new file mode 100644
index 00000000..8c58e6f0
--- /dev/null
+++ b/boards/base/Olimex-SAM7EX256-GE8/example/openocd.cfg
@@ -0,0 +1,75 @@
+# This is a script file for OpenOCD 0.7.0
+#
+# It is set up for the Olimex SAM7EX256 board using the Olimex Tiny-H JTAG adaptor.
+#
+# Assuming the current directory is your project directory containing this openocd.cfg file...
+#
+# To program your device:
+#
+# openocd -f openocd.cfg -c "Burn yourfile.bin" -c shutdown
+#
+# To debug your device:
+#
+# openocd
+# (This will run openocd in gdb server debug mode. Leave it running in the background)
+#
+# gdb yourfile.elf
+# (To start gdb. Then run the following commands in gdb...)
+#
+# target remote 127.0.0.1:3333
+# monitor Debug
+# stepi
+# (This last stepi resynchronizes gdb).
+#
+# If you want to reprogram from within gdb:
+#
+# monitor Burn yourfile.bin
+#
+
+echo ""
+echo "##### Loading debugger..."
+source [find interface/olimex-arm-usb-tiny-h.cfg]
+#source [find interface/ftdi/olimex-arm-usb-tiny-h.cfg]
+
+echo ""
+echo "##### Loading CPU..."
+source [find target/at91sam7x256.cfg]
+
+echo ""
+echo "##### Configuring..."
+jtag_rclk 3000
+arm7_9 dcc_downloads enable
+arm7_9 fast_memory_access enable
+# flash protect 0 0 1 off
+#gdb_breakpoint_override hard
+arm7_9 dbgrq enable
+
+proc Debug { } {
+ echo ""
+ echo "##### Debug Session Connected..."
+ soft_reset_halt
+ reg pc 0x00100000
+ echo "Ready..."
+}
+
+proc Burn {file} {
+ echo ""
+ echo "##### Burning $file to device..."
+ halt
+ flash write_image erase unlock $file 0x00100000
+ reset
+ echo "Burning Complete!"
+}
+
+echo ""
+echo "##### Leaving Configuration Mode..."
+init
+soft_reset_halt
+$_TARGETNAME invoke-event reset-init
+flash probe 0
+flash banks
+
+echo ""
+echo "##### Waiting for debug connections..."
+
+
diff --git a/boards/base/Olimex-SAM7EX256-GE8/example/readme.txt b/boards/base/Olimex-SAM7EX256-GE8/example/readme.txt
new file mode 100644
index 00000000..a357dc52
--- /dev/null
+++ b/boards/base/Olimex-SAM7EX256-GE8/example/readme.txt
@@ -0,0 +1,3 @@
+Copy these files into your own project directory and alter them to suite.
+
+In particular look at the MYFILES definition and the MYCSRC definition. \ No newline at end of file
diff --git a/drivers/gadc/AT91SAM7/gadc_lld_board_olimexsam7ex256.h b/boards/base/Olimex-SAM7EX256-GE8/gadc_lld_board.h
index 8f047015..fef861e5 100644
--- a/drivers/gadc/AT91SAM7/gadc_lld_board_olimexsam7ex256.h
+++ b/boards/base/Olimex-SAM7EX256-GE8/gadc_lld_board.h
@@ -6,15 +6,12 @@
*/
/**
- * @file drivers/gadc/AT91SAM7/gadc_lld_board_olimexsam7ex256.h
+ * @file boards/base/Olimex-SAM7EX256-GE8/gadc_lld_board.h
* @brief GADC Driver config file.
- *
- * @addtogroup GADC
- * @{
*/
-#ifndef _GADC_LLD_BOARD_OLIMEXSAM7EX256_H
-#define _GADC_LLD_BOARD_OLIMEXSAM7EX256_H
+#ifndef _GADC_LLD_BOARD_H
+#define _GADC_LLD_BOARD_H
#if GFX_USE_GADC
@@ -28,6 +25,5 @@
#endif /* GFX_USE_GADC */
-#endif /* _GADC_LLD_BOARD_OLIMEXSAM7EX256_H */
-/** @} */
+#endif /* _GADC_LLD_BOARD_H */
diff --git a/boards/base/Olimex-SAM7EX256-GE8/gaudin_lld_board.h b/boards/base/Olimex-SAM7EX256-GE8/gaudin_lld_board.h
new file mode 100644
index 00000000..632f0659
--- /dev/null
+++ b/boards/base/Olimex-SAM7EX256-GE8/gaudin_lld_board.h
@@ -0,0 +1,33 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file boards/base/Olimex-SAM7EX256-GE8/gaudin_lld_board.h
+ * @brief GAUDIN Driver board config file for the Olimex SAM7EX256 board
+ */
+
+#ifndef _GAUDIN_LLD_BOARD_H
+#define _GAUDIN_LLD_BOARD_H
+
+/*===========================================================================*/
+/* Audio inputs on this board */
+/*===========================================================================*/
+
+#define GAUDIN_NUM_CHANNELS 1
+
+/**
+ * The list of audio channels and their uses
+ */
+#define GAUDIN_MICROPHONE 0
+
+#ifdef GAUDIN_LLD_IMPLEMENTATION
+ static uint32_t gaudin_lld_physdevs[GAUDIN_NUM_CHANNELS] = {
+ GADC_PHYSDEV_MICROPHONE,
+ };
+#endif
+
+#endif /* _GAUDIN_LLD_BOARD_H */
diff --git a/boards/base/Olimex-SAM7EX256-GE8/ginput_lld_dial_board.h b/boards/base/Olimex-SAM7EX256-GE8/ginput_lld_dial_board.h
new file mode 100644
index 00000000..c0d3ab3f
--- /dev/null
+++ b/boards/base/Olimex-SAM7EX256-GE8/ginput_lld_dial_board.h
@@ -0,0 +1,30 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file boards/base/Olimex-SAM7EX256-GE8/ginput_lld_dial_board.h
+ * @brief GINPUT Dial Driver config file.
+ */
+
+#ifndef _GINPUT_LLD_DIAL_BOARD_H
+#define _GINPUT_LLD_DIAL_BOARD_H
+
+#if GFX_USE_GINPUT && GINPUT_NEED_DIAL
+
+/*===========================================================================*/
+/* Analogue devices on this board */
+/*===========================================================================*/
+
+#define GINPUT_DIAL_NUM_PORTS 1
+#define GINPUT_DIAL_DEVICE0 GADC_PHYSDEV_DIAL
+#define GINPUT_DIAL_POLL_PERIOD 200
+#define GINPUT_DIAL_CYCLE_POLL FALSE
+
+#endif /* GFX_USE_GINPUT && GINPUT_NEED_DIAL */
+
+#endif /* _GINPUT_LLD_DIAL_BOARD_H */
+
diff --git a/drivers/ginput/toggle/Pal/ginput_lld_toggle_board_olimexsam7ex256.h b/boards/base/Olimex-SAM7EX256-GE8/ginput_lld_toggle_board.h
index 5861b6f5..39e7837a 100644
--- a/drivers/ginput/toggle/Pal/ginput_lld_toggle_board_olimexsam7ex256.h
+++ b/boards/base/Olimex-SAM7EX256-GE8/ginput_lld_toggle_board.h
@@ -6,12 +6,8 @@
*/
/**
- * @file drivers/ginput/toggle/Pal/ginput_lld_toggle_board_olimexsam7ex256.h
+ * @file boards/base/Olimex-SAM7EX256-GE8/ginput_lld_toggle_board.h
* @brief GINPUT Toggle low level driver source for the ChibiOS PAL hardware on the Olimex SAM7EX256 board.
- *
- * @defgroup Toggle Toggle
- * @ingroup GINPUT
- * @{
*/
#ifndef _GDISP_LLD_TOGGLE_BOARD_H
@@ -41,4 +37,4 @@
}
#endif /* _GDISP_LLD_TOGGLE_BOARD_H */
-/** @} */
+
diff --git a/boards/base/Olimex-SAM7EX256-GE8/readme.txt b/boards/base/Olimex-SAM7EX256-GE8/readme.txt
new file mode 100644
index 00000000..01b3f8b4
--- /dev/null
+++ b/boards/base/Olimex-SAM7EX256-GE8/readme.txt
@@ -0,0 +1,14 @@
+This directory contains the interface for the Olimex SAM7EX256 board
+running under ChibiOS.
+
+On this board uGFX currently supports:
+ - GDISP via the Nokia6610GE8 display
+ - GADC via the AT91SAM7 driver
+ - GINPUT-dials via the GADC driver
+ - GINPUT-toggles via the Pal driver
+ - GAUDIN via the GADC driver
+
+Note there are two variants of this board - one with the GE8 display
+ and one with the GE12 display. This one is for the GE8 display.
+
+There is an example Makefile and project in the examples directory.
diff --git a/boards/base/Win32/board.mk b/boards/base/Win32/board.mk
new file mode 100644
index 00000000..be5740ef
--- /dev/null
+++ b/boards/base/Win32/board.mk
@@ -0,0 +1,3 @@
+GFXINC += $(GFXLIB)/boards/base/Win32
+GFXSRC +=
+include $(GFXLIB)/drivers/multiple/Win32/gdisp_lld.mk
diff --git a/boards/base/Win32/example/Makefile b/boards/base/Win32/example/Makefile
new file mode 100644
index 00000000..66d4b918
--- /dev/null
+++ b/boards/base/Win32/example/Makefile
@@ -0,0 +1,195 @@
+#
+# !!!! Do NOT edit this makefile with an editor which replace tabs by spaces !!!!
+#
+##############################################################################################
+#
+# On command line:
+#
+# make all = Create project
+#
+# make clean = Clean project files.
+#
+# To rebuild project do "make clean" and "make all".
+#
+
+##############################################################################################
+# Start of default section
+#
+
+CC = i686-pc-mingw32-gcc -g
+
+# Turn ChibiOS simimulator on or off - uGFX doesn't need it but you might for other purposes.
+USE_CHIBIOS=no
+
+# List all default C defines here, like -D_DEBUG=1
+DDEFS =
+
+# List all default directories to look for include files here
+DINCDIR =
+
+# List the default directory to look for the libraries here
+DLIBDIR =
+
+# List all default libraries here
+DLIBS = -lws2_32 -lgdi32
+
+# Make sure this empty for now
+SRC =
+
+#
+# End of default section
+##############################################################################################
+
+##############################################################################################
+# Start of user section
+#
+
+# Define project name here
+PROJECT = uGFX
+
+# Imported source files and paths for uGFX
+GFXLIB = ../uGFX
+include $(GFXLIB)/gfx.mk
+include $(GFXLIB)/boards/base/Win32/board.mk
+
+# Imported source files and paths for ChibiOS
+ifeq ($(USE_CHIBIOS),yes)
+ CHIBIOS = ../ChibiOS
+ include $(CHIBIOS)/boards/simulator/board.mk
+ include ${CHIBIOS}/os/hal/hal.mk
+ include ${CHIBIOS}/os/hal/platforms/Win32/platform.mk
+ include ${CHIBIOS}/os/ports/GCC/SIMIA32/port.mk
+ include ${CHIBIOS}/os/kernel/kernel.mk
+ DDEFS += -DSIMULATOR -DSHELL_USE_IPRINTF=FALSE
+ UINCDIR += $(PORTINC) $(KERNINC) $(TESTINC) \
+ $(HALINC) $(PLATFORMINC) $(BOARDINC)
+ # ${CHIBIOS}/os/various
+ SRC += ${PORTSRC} \
+ ${KERNSRC} \
+ ${TESTSRC} \
+ ${HALSRC} \
+ ${PLATFORMSRC} \
+ $(BOARDSRC)
+ GFXDEFS += -DGFX_USE_OS_CHIBIOS=TRUE
+else
+ GFXDEFS += -DGFX_USE_OS_WIN32=TRUE
+endif
+
+# Where is our source code - alter these for your project.
+MYFILES = $(GFXLIB)/demos/modules/gdisp/basics
+MYCSRC = $(MYFILES)/main.c
+
+# List C source files here
+SRC += ${GFXSRC} \
+ ${MYCSRC}
+
+# List all user C define here, like -D_DEBUG=1
+UDEFS = ${GFXDEFS}
+
+# List all user directories here
+UINCDIR = ${GFXINC} \
+ ${MYFILES}
+
+# List the user directory to look for the libraries here
+ULIBDIR =
+
+# List all user libraries here
+ULIBS =
+
+# Define optimisation level here
+#OPT = -ggdb -O2 -fomit-frame-pointer
+OPT = -ggdb -O0 -fomit-frame-pointer
+
+#
+# End of user defines
+##############################################################################################
+
+
+# Output directory and files
+ifeq ($(BUILDDIR),)
+ BUILDDIR = .build
+endif
+ifeq ($(BUILDDIR),.)
+ BUILDDIR = .build
+endif
+
+OBJDIR = $(BUILDDIR)/obj
+LSTDIR = $(BUILDDIR)/lst
+MAPDIR = $(BUILDDIR)/map
+
+INCDIR = $(patsubst %,-I%,$(DINCDIR) $(UINCDIR))
+LIBDIR = $(patsubst %,-L%,$(DLIBDIR) $(ULIBDIR))
+DEFS = $(DDEFS) $(UDEFS)
+ADEFS = $(DADEFS) $(UADEFS)
+COBJ = $(addprefix $(OBJDIR)/, $(SRC:.c=.o))
+AOBJ = $(addprefix $(OBJDIR)/, $(ASRC:.s=.o))
+OBJS = $(AOBJ) $(COBJ)
+LIBS = $(DLIBS) $(ULIBS)
+
+LDFLAGS = -Wl,-Map=$(MAPDIR)/$(PROJECT).map,--cref,--no-warn-mismatch $(LIBDIR)
+CPFLAGS = $(OPT) -Wall -Wextra -Wstrict-prototypes -fverbose-asm -Wa,-alms=$(LSTDIR)/$(<:.c=.lst) $(DEFS)
+
+# Generate dependency information
+CPFLAGS += -MD -MP -MF .dep/$(@F).d
+
+#
+# makefile rules
+#
+
+all: $(BUILDDIR) $(OBJS) $(BUILDDIR)/$(PROJECT).exe MAKE_ALL_RULE_HOOK
+
+MAKE_ALL_RULE_HOOK:
+
+$(BUILDDIR) $(OBJDIR) $(LSTDIR):
+ mkdir -p $(OBJDIR)
+ mkdir -p $(LSTDIR)
+ mkdir -p $(MAPDIR)
+ifneq ($(USE_VERBOSE_COMPILE),yes)
+ @echo Compiler Options - $(CC) -c $(CPFLAGS) -I. $(INCDIR) main.c -o $(OBJDIR)/main.o
+ @echo
+endif
+
+$(OBJDIR)/%.o : %.c
+ @mkdir -p $(dir $@)
+ifeq ($(USE_VERBOSE_COMPILE),yes)
+ @echo
+ $(CC) -c $(CPFLAGS) -I. $(INCDIR) $< -o $@
+else
+ @echo Compiling $<
+ @$(CC) -c $(CPFLAGS) -I. $(INCDIR) $< -o $@
+endif
+
+$(OBJDIR)/%.o : %.s
+ @mkdir -p $(dir $@)
+ifeq ($(USE_VERBOSE_COMPILE),yes)
+ @echo
+ $(AS) -c $(ASFLAGS) -I. $(INCDIR) $< -o $@
+else
+ @echo Compiling $<
+ @$(AS) -c $(ASFLAGS) -I. $(INCDIR) $< -o $@
+endif
+
+%.exe: $(OBJS)
+ifeq ($(USE_VERBOSE_COMPILE),yes)
+ @echo
+ $(CC) $(OBJS) $(LDFLAGS) $(LIBS) -o $@
+else
+ @echo Linking $@
+ @$(CC) $(OBJS) $(LDFLAGS) $(LIBS) -o $@
+endif
+
+gcov:
+ -mkdir gcov
+ $(COV) -u $(subst /,\,$(SRC))
+ -mv *.gcov ./gcov
+
+clean:
+ -rm -fR .build
+ -rm -fR .dep
+
+#
+# Include the dependency files, should be the last of the makefile
+#
+-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)
+
+# *** EOF ***
diff --git a/boards/base/Win32/example/chconf.h b/boards/base/Win32/example/chconf.h
new file mode 100644
index 00000000..759f6be8
--- /dev/null
+++ b/boards/base/Win32/example/chconf.h
@@ -0,0 +1,536 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file templates/chconf.h
+ * @brief Configuration file template.
+ * @details A copy of this file must be placed in each project directory, it
+ * contains the application specific kernel settings.
+ *
+ * @addtogroup config
+ * @details Kernel related settings and hooks.
+ * @{
+ */
+
+#ifndef _CHCONF_H_
+#define _CHCONF_H_
+
+/*===========================================================================*/
+/**
+ * @name Kernel parameters and options
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief System tick frequency.
+ * @details Frequency of the system timer that drives the system ticks. This
+ * setting also defines the system tick time unit.
+ */
+#if !defined(CH_FREQUENCY) || defined(__DOXYGEN__)
+#define CH_FREQUENCY 1000
+#endif
+
+/**
+ * @brief Round robin interval.
+ * @details This constant is the number of system ticks allowed for the
+ * threads before preemption occurs. Setting this value to zero
+ * disables the preemption for threads with equal priority and the
+ * round robin becomes cooperative. Note that higher priority
+ * threads can still preempt, the kernel is always preemptive.
+ *
+ * @note Disabling the round robin preemption makes the kernel more compact
+ * and generally faster.
+ */
+#if !defined(CH_TIME_QUANTUM) || defined(__DOXYGEN__)
+#define CH_TIME_QUANTUM 20
+#endif
+
+/**
+ * @brief Managed RAM size.
+ * @details Size of the RAM area to be managed by the OS. If set to zero
+ * then the whole available RAM is used. The core memory is made
+ * available to the heap allocator and/or can be used directly through
+ * the simplified core memory allocator.
+ *
+ * @note In order to let the OS manage the whole RAM the linker script must
+ * provide the @p __heap_base__ and @p __heap_end__ symbols.
+ * @note Requires @p CH_USE_MEMCORE.
+ */
+#if !defined(CH_MEMCORE_SIZE) || defined(__DOXYGEN__)
+#define CH_MEMCORE_SIZE 0x20000
+#endif
+
+/**
+ * @brief Idle thread automatic spawn suppression.
+ * @details When this option is activated the function @p chSysInit()
+ * does not spawn the idle thread automatically. The application has
+ * then the responsibility to do one of the following:
+ * - Spawn a custom idle thread at priority @p IDLEPRIO.
+ * - Change the main() thread priority to @p IDLEPRIO then enter
+ * an endless loop. In this scenario the @p main() thread acts as
+ * the idle thread.
+ * .
+ * @note Unless an idle thread is spawned the @p main() thread must not
+ * enter a sleep state.
+ */
+#if !defined(CH_NO_IDLE_THREAD) || defined(__DOXYGEN__)
+#define CH_NO_IDLE_THREAD FALSE
+#endif
+
+/** @} */
+
+/*===========================================================================*/
+/**
+ * @name Performance options
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief OS optimization.
+ * @details If enabled then time efficient rather than space efficient code
+ * is used when two possible implementations exist.
+ *
+ * @note This is not related to the compiler optimization options.
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_OPTIMIZE_SPEED) || defined(__DOXYGEN__)
+#define CH_OPTIMIZE_SPEED TRUE
+#endif
+
+/** @} */
+
+/*===========================================================================*/
+/**
+ * @name Subsystem options
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief Threads registry APIs.
+ * @details If enabled then the registry APIs are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_USE_REGISTRY) || defined(__DOXYGEN__)
+#define CH_USE_REGISTRY TRUE
+#endif
+
+/**
+ * @brief Threads synchronization APIs.
+ * @details If enabled then the @p chThdWait() function is included in
+ * the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_USE_WAITEXIT) || defined(__DOXYGEN__)
+#define CH_USE_WAITEXIT TRUE
+#endif
+
+/**
+ * @brief Semaphores APIs.
+ * @details If enabled then the Semaphores APIs are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_USE_SEMAPHORES) || defined(__DOXYGEN__)
+#define CH_USE_SEMAPHORES TRUE
+#endif
+
+/**
+ * @brief Semaphores queuing mode.
+ * @details If enabled then the threads are enqueued on semaphores by
+ * priority rather than in FIFO order.
+ *
+ * @note The default is @p FALSE. Enable this if you have special requirements.
+ * @note Requires @p CH_USE_SEMAPHORES.
+ */
+#if !defined(CH_USE_SEMAPHORES_PRIORITY) || defined(__DOXYGEN__)
+#define CH_USE_SEMAPHORES_PRIORITY FALSE
+#endif
+
+/**
+ * @brief Atomic semaphore API.
+ * @details If enabled then the semaphores the @p chSemSignalWait() API
+ * is included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_USE_SEMAPHORES.
+ */
+#if !defined(CH_USE_SEMSW) || defined(__DOXYGEN__)
+#define CH_USE_SEMSW TRUE
+#endif
+
+/**
+ * @brief Mutexes APIs.
+ * @details If enabled then the mutexes APIs are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_USE_MUTEXES) || defined(__DOXYGEN__)
+#define CH_USE_MUTEXES TRUE
+#endif
+
+/**
+ * @brief Conditional Variables APIs.
+ * @details If enabled then the conditional variables APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_USE_MUTEXES.
+ */
+#if !defined(CH_USE_CONDVARS) || defined(__DOXYGEN__)
+#define CH_USE_CONDVARS TRUE
+#endif
+
+/**
+ * @brief Conditional Variables APIs with timeout.
+ * @details If enabled then the conditional variables APIs with timeout
+ * specification are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_USE_CONDVARS.
+ */
+#if !defined(CH_USE_CONDVARS_TIMEOUT) || defined(__DOXYGEN__)
+#define CH_USE_CONDVARS_TIMEOUT TRUE
+#endif
+
+/**
+ * @brief Events Flags APIs.
+ * @details If enabled then the event flags APIs are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_USE_EVENTS) || defined(__DOXYGEN__)
+#define CH_USE_EVENTS TRUE
+#endif
+
+/**
+ * @brief Events Flags APIs with timeout.
+ * @details If enabled then the events APIs with timeout specification
+ * are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_USE_EVENTS.
+ */
+#if !defined(CH_USE_EVENTS_TIMEOUT) || defined(__DOXYGEN__)
+#define CH_USE_EVENTS_TIMEOUT TRUE
+#endif
+
+/**
+ * @brief Synchronous Messages APIs.
+ * @details If enabled then the synchronous messages APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_USE_MESSAGES) || defined(__DOXYGEN__)
+#define CH_USE_MESSAGES TRUE
+#endif
+
+/**
+ * @brief Synchronous Messages queuing mode.
+ * @details If enabled then messages are served by priority rather than in
+ * FIFO order.
+ *
+ * @note The default is @p FALSE. Enable this if you have special requirements.
+ * @note Requires @p CH_USE_MESSAGES.
+ */
+#if !defined(CH_USE_MESSAGES_PRIORITY) || defined(__DOXYGEN__)
+#define CH_USE_MESSAGES_PRIORITY FALSE
+#endif
+
+/**
+ * @brief Mailboxes APIs.
+ * @details If enabled then the asynchronous messages (mailboxes) APIs are
+ * included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_USE_SEMAPHORES.
+ */
+#if !defined(CH_USE_MAILBOXES) || defined(__DOXYGEN__)
+#define CH_USE_MAILBOXES TRUE
+#endif
+
+/**
+ * @brief I/O Queues APIs.
+ * @details If enabled then the I/O queues APIs are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_USE_QUEUES) || defined(__DOXYGEN__)
+#define CH_USE_QUEUES TRUE
+#endif
+
+/**
+ * @brief Core Memory Manager APIs.
+ * @details If enabled then the core memory manager APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_USE_MEMCORE) || defined(__DOXYGEN__)
+#define CH_USE_MEMCORE TRUE
+#endif
+
+/**
+ * @brief Heap Allocator APIs.
+ * @details If enabled then the memory heap allocator APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_USE_MEMCORE and either @p CH_USE_MUTEXES or
+ * @p CH_USE_SEMAPHORES.
+ * @note Mutexes are recommended.
+ */
+#if !defined(CH_USE_HEAP) || defined(__DOXYGEN__)
+#define CH_USE_HEAP TRUE
+#endif
+
+/**
+ * @brief C-runtime allocator.
+ * @details If enabled the the heap allocator APIs just wrap the C-runtime
+ * @p malloc() and @p free() functions.
+ *
+ * @note The default is @p FALSE.
+ * @note Requires @p CH_USE_HEAP.
+ * @note The C-runtime may or may not require @p CH_USE_MEMCORE, see the
+ * appropriate documentation.
+ */
+#if !defined(CH_USE_MALLOC_HEAP) || defined(__DOXYGEN__)
+#define CH_USE_MALLOC_HEAP FALSE
+#endif
+
+/**
+ * @brief Memory Pools Allocator APIs.
+ * @details If enabled then the memory pools allocator APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#if !defined(CH_USE_MEMPOOLS) || defined(__DOXYGEN__)
+#define CH_USE_MEMPOOLS TRUE
+#endif
+
+/**
+ * @brief Dynamic Threads APIs.
+ * @details If enabled then the dynamic threads creation APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_USE_WAITEXIT.
+ * @note Requires @p CH_USE_HEAP and/or @p CH_USE_MEMPOOLS.
+ */
+#if !defined(CH_USE_DYNAMIC) || defined(__DOXYGEN__)
+#define CH_USE_DYNAMIC TRUE
+#endif
+
+/** @} */
+
+/*===========================================================================*/
+/**
+ * @name Debug options
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief Debug option, system state check.
+ * @details If enabled the correct call protocol for system APIs is checked
+ * at runtime.
+ *
+ * @note The default is @p FALSE.
+ */
+#if !defined(CH_DBG_SYSTEM_STATE_CHECK) || defined(__DOXYGEN__)
+#define CH_DBG_SYSTEM_STATE_CHECK FALSE
+#endif
+
+/**
+ * @brief Debug option, parameters checks.
+ * @details If enabled then the checks on the API functions input
+ * parameters are activated.
+ *
+ * @note The default is @p FALSE.
+ */
+#if !defined(CH_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__)
+#define CH_DBG_ENABLE_CHECKS FALSE
+#endif
+
+/**
+ * @brief Debug option, consistency checks.
+ * @details If enabled then all the assertions in the kernel code are
+ * activated. This includes consistency checks inside the kernel,
+ * runtime anomalies and port-defined checks.
+ *
+ * @note The default is @p FALSE.
+ */
+#if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__)
+#define CH_DBG_ENABLE_ASSERTS FALSE
+#endif
+
+/**
+ * @brief Debug option, trace buffer.
+ * @details If enabled then the context switch circular trace buffer is
+ * activated.
+ *
+ * @note The default is @p FALSE.
+ */
+#if !defined(CH_DBG_ENABLE_TRACE) || defined(__DOXYGEN__)
+#define CH_DBG_ENABLE_TRACE FALSE
+#endif
+
+/**
+ * @brief Debug option, stack checks.
+ * @details If enabled then a runtime stack check is performed.
+ *
+ * @note The default is @p FALSE.
+ * @note The stack check is performed in a architecture/port dependent way.
+ * It may not be implemented or some ports.
+ * @note The default failure mode is to halt the system with the global
+ * @p panic_msg variable set to @p NULL.
+ */
+#if !defined(CH_DBG_ENABLE_STACK_CHECK) || defined(__DOXYGEN__)
+#define CH_DBG_ENABLE_STACK_CHECK FALSE
+#endif
+
+/**
+ * @brief Debug option, stacks initialization.
+ * @details If enabled then the threads working area is filled with a byte
+ * value when a thread is created. This can be useful for the
+ * runtime measurement of the used stack.
+ *
+ * @note The default is @p FALSE.
+ */
+#if !defined(CH_DBG_FILL_THREADS) || defined(__DOXYGEN__)
+#define CH_DBG_FILL_THREADS FALSE
+#endif
+
+/**
+ * @brief Debug option, threads profiling.
+ * @details If enabled then a field is added to the @p Thread structure that
+ * counts the system ticks occurred while executing the thread.
+ *
+ * @note The default is @p TRUE.
+ * @note This debug option is defaulted to TRUE because it is required by
+ * some test cases into the test suite.
+ */
+#if !defined(CH_DBG_THREADS_PROFILING) || defined(__DOXYGEN__)
+#define CH_DBG_THREADS_PROFILING TRUE
+#endif
+
+/** @} */
+
+/*===========================================================================*/
+/**
+ * @name Kernel hooks
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief Threads descriptor structure extension.
+ * @details User fields added to the end of the @p Thread structure.
+ */
+#if !defined(THREAD_EXT_FIELDS) || defined(__DOXYGEN__)
+#define THREAD_EXT_FIELDS \
+ /* Add threads custom fields here.*/
+#endif
+
+/**
+ * @brief Threads initialization hook.
+ * @details User initialization code added to the @p chThdInit() API.
+ *
+ * @note It is invoked from within @p chThdInit() and implicitly from all
+ * the threads creation APIs.
+ */
+#if !defined(THREAD_EXT_INIT_HOOK) || defined(__DOXYGEN__)
+#define THREAD_EXT_INIT_HOOK(tp) { \
+ /* Add threads initialization code here.*/ \
+}
+#endif
+
+/**
+ * @brief Threads finalization hook.
+ * @details User finalization code added to the @p chThdExit() API.
+ *
+ * @note It is inserted into lock zone.
+ * @note It is also invoked when the threads simply return in order to
+ * terminate.
+ */
+#if !defined(THREAD_EXT_EXIT_HOOK) || defined(__DOXYGEN__)
+#define THREAD_EXT_EXIT_HOOK(tp) { \
+ /* Add threads finalization code here.*/ \
+}
+#endif
+
+/**
+ * @brief Context switch hook.
+ * @details This hook is invoked just before switching between threads.
+ */
+#if !defined(THREAD_CONTEXT_SWITCH_HOOK) || defined(__DOXYGEN__)
+#define THREAD_CONTEXT_SWITCH_HOOK(ntp, otp) { \
+ /* System halt code here.*/ \
+}
+#endif
+
+/**
+ * @brief Idle Loop hook.
+ * @details This hook is continuously invoked by the idle thread loop.
+ */
+#if !defined(IDLE_LOOP_HOOK) || defined(__DOXYGEN__)
+#define IDLE_LOOP_HOOK() { \
+ /* Idle loop code here.*/ \
+}
+#endif
+
+/**
+ * @brief System tick event hook.
+ * @details This hook is invoked in the system tick handler immediately
+ * after processing the virtual timers queue.
+ */
+#if !defined(SYSTEM_TICK_EVENT_HOOK) || defined(__DOXYGEN__)
+#define SYSTEM_TICK_EVENT_HOOK() { \
+ /* System tick event code here.*/ \
+}
+#endif
+
+
+/**
+ * @brief System halt hook.
+ * @details This hook is invoked in case to a system halting error before
+ * the system is halted.
+ */
+#if !defined(SYSTEM_HALT_HOOK) || defined(__DOXYGEN__)
+#define SYSTEM_HALT_HOOK() { \
+ /* System halt code here.*/ \
+}
+#endif
+
+/** @} */
+
+/*===========================================================================*/
+/* Port-specific settings (override port settings defaulted in chcore.h). */
+/*===========================================================================*/
+
+#endif /* _CHCONF_H_ */
+
+/** @} */
diff --git a/boards/base/Win32/example/halconf.h b/boards/base/Win32/example/halconf.h
new file mode 100644
index 00000000..81dc4dd2
--- /dev/null
+++ b/boards/base/Win32/example/halconf.h
@@ -0,0 +1,342 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file templates/halconf.h
+ * @brief HAL configuration header.
+ * @details HAL configuration file, this file allows to enable or disable the
+ * various device drivers from your application. You may also use
+ * this file in order to override the device drivers default settings.
+ *
+ * @addtogroup HAL_CONF
+ * @{
+ */
+
+#ifndef _HALCONF_H_
+#define _HALCONF_H_
+
+/*#include "mcuconf.h"*/
+
+/**
+ * @brief Enables the TM subsystem.
+ */
+#if !defined(HAL_USE_TM) || defined(__DOXYGEN__)
+#define HAL_USE_TM FALSE
+#endif
+
+/**
+ * @brief Enables the PAL subsystem.
+ */
+#if !defined(HAL_USE_PAL) || defined(__DOXYGEN__)
+#define HAL_USE_PAL TRUE
+#endif
+
+/**
+ * @brief Enables the ADC subsystem.
+ */
+#if !defined(HAL_USE_ADC) || defined(__DOXYGEN__)
+#define HAL_USE_ADC FALSE
+#endif
+
+/**
+ * @brief Enables the CAN subsystem.
+ */
+#if !defined(HAL_USE_CAN) || defined(__DOXYGEN__)
+#define HAL_USE_CAN FALSE
+#endif
+
+/**
+ * @brief Enables the EXT subsystem.
+ */
+#if !defined(HAL_USE_EXT) || defined(__DOXYGEN__)
+#define HAL_USE_EXT FALSE
+#endif
+
+/**
+ * @brief Enables the GPT subsystem.
+ */
+#if !defined(HAL_USE_GPT) || defined(__DOXYGEN__)
+#define HAL_USE_GPT FALSE
+#endif
+
+/**
+ * @brief Enables the I2C subsystem.
+ */
+#if !defined(HAL_USE_I2C) || defined(__DOXYGEN__)
+#define HAL_USE_I2C FALSE
+#endif
+
+/**
+ * @brief Enables the ICU subsystem.
+ */
+#if !defined(HAL_USE_ICU) || defined(__DOXYGEN__)
+#define HAL_USE_ICU FALSE
+#endif
+
+/**
+ * @brief Enables the MAC subsystem.
+ */
+#if !defined(HAL_USE_MAC) || defined(__DOXYGEN__)
+#define HAL_USE_MAC FALSE
+#endif
+
+/**
+ * @brief Enables the MMC_SPI subsystem.
+ */
+#if !defined(HAL_USE_MMC_SPI) || defined(__DOXYGEN__)
+#define HAL_USE_MMC_SPI FALSE
+#endif
+
+/**
+ * @brief Enables the PWM subsystem.
+ */
+#if !defined(HAL_USE_PWM) || defined(__DOXYGEN__)
+#define HAL_USE_PWM FALSE
+#endif
+
+/**
+ * @brief Enables the RTC subsystem.
+ */
+#if !defined(HAL_USE_RTC) || defined(__DOXYGEN__)
+#define HAL_USE_RTC FALSE
+#endif
+
+/**
+ * @brief Enables the SDC subsystem.
+ */
+#if !defined(HAL_USE_SDC) || defined(__DOXYGEN__)
+#define HAL_USE_SDC FALSE
+#endif
+
+/**
+ * @brief Enables the SERIAL subsystem.
+ */
+#if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__)
+#define HAL_USE_SERIAL TRUE
+#endif
+
+/**
+ * @brief Enables the SERIAL over USB subsystem.
+ */
+#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
+#define HAL_USE_SERIAL_USB FALSE
+#endif
+
+/**
+ * @brief Enables the SPI subsystem.
+ */
+#if !defined(HAL_USE_SPI) || defined(__DOXYGEN__)
+#define HAL_USE_SPI FALSE
+#endif
+
+/**
+ * @brief Enables the UART subsystem.
+ */
+#if !defined(HAL_USE_UART) || defined(__DOXYGEN__)
+#define HAL_USE_UART FALSE
+#endif
+
+/**
+ * @brief Enables the USB subsystem.
+ */
+#if !defined(HAL_USE_USB) || defined(__DOXYGEN__)
+#define HAL_USE_USB FALSE
+#endif
+
+/*===========================================================================*/
+/* ADC driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(ADC_USE_WAIT) || defined(__DOXYGEN__)
+#define ADC_USE_WAIT TRUE
+#endif
+
+/**
+ * @brief Enables the @p adcAcquireBus() and @p adcReleaseBus() APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
+#define ADC_USE_MUTUAL_EXCLUSION TRUE
+#endif
+
+/*===========================================================================*/
+/* CAN driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Sleep mode related APIs inclusion switch.
+ */
+#if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__)
+#define CAN_USE_SLEEP_MODE TRUE
+#endif
+
+/*===========================================================================*/
+/* I2C driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables the mutual exclusion APIs on the I2C bus.
+ */
+#if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
+#define I2C_USE_MUTUAL_EXCLUSION TRUE
+#endif
+
+/*===========================================================================*/
+/* MAC driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables an event sources for incoming packets.
+ */
+#if !defined(MAC_USE_EVENTS) || defined(__DOXYGEN__)
+#define MAC_USE_EVENTS TRUE
+#endif
+
+/*===========================================================================*/
+/* MMC_SPI driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Block size for MMC transfers.
+ */
+#if !defined(MMC_SECTOR_SIZE) || defined(__DOXYGEN__)
+#define MMC_SECTOR_SIZE 512
+#endif
+
+/**
+ * @brief Delays insertions.
+ * @details If enabled this options inserts delays into the MMC waiting
+ * routines releasing some extra CPU time for the threads with
+ * lower priority, this may slow down the driver a bit however.
+ * This option is recommended also if the SPI driver does not
+ * use a DMA channel and heavily loads the CPU.
+ */
+#if !defined(MMC_NICE_WAITING) || defined(__DOXYGEN__)
+#define MMC_NICE_WAITING TRUE
+#endif
+
+/**
+ * @brief Number of positive insertion queries before generating the
+ * insertion event.
+ */
+#if !defined(MMC_POLLING_INTERVAL) || defined(__DOXYGEN__)
+#define MMC_POLLING_INTERVAL 10
+#endif
+
+/**
+ * @brief Interval, in milliseconds, between insertion queries.
+ */
+#if !defined(MMC_POLLING_DELAY) || defined(__DOXYGEN__)
+#define MMC_POLLING_DELAY 10
+#endif
+
+/**
+ * @brief Uses the SPI polled API for small data transfers.
+ * @details Polled transfers usually improve performance because it
+ * saves two context switches and interrupt servicing. Note
+ * that this option has no effect on large transfers which
+ * are always performed using DMAs/IRQs.
+ */
+#if !defined(MMC_USE_SPI_POLLING) || defined(__DOXYGEN__)
+#define MMC_USE_SPI_POLLING TRUE
+#endif
+
+/*===========================================================================*/
+/* SDC driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Number of initialization attempts before rejecting the card.
+ * @note Attempts are performed at 10mS intervals.
+ */
+#if !defined(SDC_INIT_RETRY) || defined(__DOXYGEN__)
+#define SDC_INIT_RETRY 100
+#endif
+
+/**
+ * @brief Include support for MMC cards.
+ * @note MMC support is not yet implemented so this option must be kept
+ * at @p FALSE.
+ */
+#if !defined(SDC_MMC_SUPPORT) || defined(__DOXYGEN__)
+#define SDC_MMC_SUPPORT FALSE
+#endif
+
+/**
+ * @brief Delays insertions.
+ * @details If enabled this options inserts delays into the MMC waiting
+ * routines releasing some extra CPU time for the threads with
+ * lower priority, this may slow down the driver a bit however.
+ */
+#if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__)
+#define SDC_NICE_WAITING TRUE
+#endif
+
+/*===========================================================================*/
+/* SERIAL driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Default bit rate.
+ * @details Configuration parameter, this is the baud rate selected for the
+ * default configuration.
+ */
+#if !defined(SERIAL_DEFAULT_BITRATE) || defined(__DOXYGEN__)
+#define SERIAL_DEFAULT_BITRATE 38400
+#endif
+
+/**
+ * @brief Serial buffers size.
+ * @details Configuration parameter, you can change the depth of the queue
+ * buffers depending on the requirements of your application.
+ * @note The default is 64 bytes for both the transmission and receive
+ * buffers.
+ */
+#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__)
+#define SERIAL_BUFFERS_SIZE 16
+#endif
+
+/*===========================================================================*/
+/* SPI driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(SPI_USE_WAIT) || defined(__DOXYGEN__)
+#define SPI_USE_WAIT TRUE
+#endif
+
+/**
+ * @brief Enables the @p spiAcquireBus() and @p spiReleaseBus() APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
+#define SPI_USE_MUTUAL_EXCLUSION TRUE
+#endif
+
+#endif /* _HALCONF_H_ */
+
+/** @} */
diff --git a/boards/base/Win32/example/readme.txt b/boards/base/Win32/example/readme.txt
new file mode 100644
index 00000000..78b8552b
--- /dev/null
+++ b/boards/base/Win32/example/readme.txt
@@ -0,0 +1,9 @@
+Copy these files into your own project directory and alter them to suite.
+
+Notes:
+
+1/ This makefile uses the MINGW compiler tool chain and was run using the cygwin make.
+2/ At the top of the Makefile is the define USE_CHIBIOS. Win32 can build uGFX for either
+ native Win32 (the default) or for the ChibiOS simulator.
+3/ The files chconf.h and halconf.h are only needed if compiling for the ChibiOS simulator.
+4/ Look at the MYFILES definition and the MYCSRC definition.
diff --git a/boards/base/Win32/readme.txt b/boards/base/Win32/readme.txt
new file mode 100644
index 00000000..031a7c6e
--- /dev/null
+++ b/boards/base/Win32/readme.txt
@@ -0,0 +1,9 @@
+This directory contains the interface for Win32
+running either native Win32 or under the ChibiOS simulator.
+
+On this board uGFX currently supports:
+ - GDISP via the Win32 driver
+ - GINPUT-touch via the Win32 driver
+ - GINPUT-toggles via the Win32 driver
+
+There is an example Makefile and project in the examples directory.
diff --git a/demos/3rdparty/boing/gfxconf.h b/demos/3rdparty/boing/gfxconf.h
deleted file mode 100644
index 0afcd45b..00000000
--- a/demos/3rdparty/boing/gfxconf.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/**
- * This file has a different license to the rest of the GFX system.
- * You can copy, modify and distribute this file as you see fit.
- * You do not need to publish your source modifications to this file.
- * The only thing you are not permitted to do is to relicense it
- * under a different license.
- */
-
-#ifndef _GFXCONF_H
-#define _GFXCONF_H
-
-/* The operating system to use - one of these must be defined */
-#define GFX_USE_OS_CHIBIOS TRUE
-#define GFX_USE_OS_WIN32 FALSE
-#define GFX_USE_OS_POSIX FALSE
-
-/* GFX sub-systems to turn on */
-#define GFX_USE_GDISP TRUE
-
-/* Features for the GDISP sub-system. */
-#define GDISP_NEED_VALIDATION FALSE
-#define GDISP_NEED_CLIP FALSE
-#define GDISP_NEED_TEXT FALSE
-#define GDISP_NEED_CIRCLE FALSE
-#define GDISP_NEED_ELLIPSE FALSE
-#define GDISP_NEED_ARC FALSE
-#define GDISP_NEED_SCROLL FALSE
-#define GDISP_NEED_PIXELREAD FALSE
-#define GDISP_NEED_CONTROL FALSE
-#define GDISP_NEED_MULTITHREAD FALSE
-#define GDISP_NEED_ASYNC FALSE
-#define GDISP_NEED_MSGAPI FALSE
-
-/* Builtin Fonts */
-#define GDISP_INCLUDE_FONT_SMALL FALSE
-#define GDISP_INCLUDE_FONT_LARGER FALSE
-#define GDISP_INCLUDE_FONT_UI1 FALSE
-#define GDISP_INCLUDE_FONT_UI2 FALSE
-#define GDISP_INCLUDE_FONT_LARGENUMBERS FALSE
-
-#endif /* _GFXCONF_H */
diff --git a/demos/3rdparty/boing/main.c b/demos/3rdparty/boing/main.c
deleted file mode 100644
index 96ba5c9d..00000000
--- a/demos/3rdparty/boing/main.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/* Derived from the 2011 IOCCC submission by peter.eastman@gmail.com
- * http://www.ioccc.org/2011/eastman/eastman.c
- * --
- * Public Domain -- but you're looking at this for ideas of techniques
- * and methods, not trying to cut&paste an entire application, anyway.
- * --
- * When you need to blit an entire screenfull of data to an LCD
- * display, the basic idea is to exploit the auto-increment feature of
- * the display controller when it writes to screen memory. You start
- * by resetting the 'cursor' to the 0,0 position, and then stream
- * width*height pixels out.
- * --
- * Chris Baird,, <cjb@brushtail.apana.org.au> April 2013
- *
- * Modified Andrew Hannam (inmarket) 2013-04-29 New GFX support
- */
-
-#include <math.h>
-#include "gfx.h"
-#include "ssd2119.h"
-
-#define Lightgrey (HTML2COLOR(0xC0C0C0))
-#define Midgrey (HTML2COLOR(0x606060))
-#define Darkgrey (HTML2COLOR(0x303030))
-
-
-/* ---------------------------------------------------------------------- */
-/* As of early April 2013, the /gfx extension tries to keep the low-level
- * stuff away from our filthy paws. So Code Duplication.
- * (Possibly to be replaced with gdispStartStream(), gdispWriteStream()
- * and gdispStopStream() in the future.)
- */
-
-#define GDISP_REG (*((volatile uint16_t *) 0x60000000)) /* DC = 0 */
-#define GDISP_RAM (*((volatile uint16_t *) 0x60100000)) /* DC = 1 */
-
-inline void write_index (uint16_t index) { GDISP_REG = index; }
-inline void write_data (uint16_t data) { GDISP_RAM = data; }
-
-#define write_reg(reg, data) { write_index(reg); write_data(data); }
-
-void reset_cursor (void)
-{
- write_reg (SSD2119_REG_X_RAM_ADDR, 0);
- write_reg (SSD2119_REG_Y_RAM_ADDR, 0);
-}
-
-#define StartStream() { write_index (SSD2119_REG_RAM_DATA); }
-#define WriteStream(x) { write_data (x); }
-#define StopStream() /* NOP */
-
-
-/* ---------------------------------------------------------------------- */
-
-void main (void)
-{
- uint16_t xx, yy, colour;
-
- gfxInit();
-
- uint16_t width = (uint16_t)gdispGetWidth();
- uint16_t height = (uint16_t)gdispGetHeight();
-
- float i=height/5+height%2+1, floorstart=height/5-1, spherespin=0.0,
- l=width/2, m=height/4, n=.01*width, o=0.0, rotspeed=0.1, h, f, g;
-
- while (TRUE)
- {
- reset_cursor ();
- StartStream ();
-
- for (xx=yy=0;
- h = (m-yy)/i, f=-.3*(g=(l-xx)/i)+.954*h, yy<height;
- yy += (xx = ++xx%width)==0 )
- {
- if (g*g < 1-h*h) /* if inside the ball */
- if (((int)(9-spherespin+(.954*g+.3*h)/sqrtf(1-f*f))+(int)(2+f*2))%2==0)
- colour = Red;
- else
- colour = White;
- else
- {
- if (xx<floorstart || xx>width-floorstart)
- colour = Darkgrey; /* side wall */
- else
- colour = Lightgrey; /* back wall */
-
- if (yy > height-floorstart)
- if (xx < height-yy || height-yy > width-xx) /* floor */
- colour = Darkgrey;
- else
- colour = Midgrey;
-
- if (g*(g+.6)+.09+h*h < 1)
- colour >>= 1; /* ball shadow; make it darker */
- }
-
- WriteStream (colour); /* pixel to the LCD */
- }
-
- StopStream();
- spherespin += rotspeed;
- m += o;
- o = m > height-1.75*floorstart ? -.04*height : o+.002*height;
- n = (l+=n)<i || l>width-i ? rotspeed=-rotspeed,-n : n;
- }
-}
-
-/* ---------------------------------------------------------------------- */
diff --git a/demos/3rdparty/bubbles/gfxconf.h b/demos/3rdparty/bubbles/gfxconf.h
index 344a986e..1ecfc544 100644
--- a/demos/3rdparty/bubbles/gfxconf.h
+++ b/demos/3rdparty/bubbles/gfxconf.h
@@ -9,10 +9,11 @@
#ifndef _GFXCONF_H
#define _GFXCONF_H
-/* The operating system to use - one of these must be defined */
-#define GFX_USE_OS_CHIBIOS TRUE
-#define GFX_USE_OS_WIN32 FALSE
-#define GFX_USE_OS_POSIX FALSE
+/* The operating system to use. One of these must be defined - preferably in your Makefile */
+//#define GFX_USE_OS_CHIBIOS FALSE
+//#define GFX_USE_OS_WIN32 FALSE
+//#define GFX_USE_OS_LINUX FALSE
+//#define GFX_USE_OS_OSX FALSE
/* GFX sub-systems to turn on */
#define GFX_USE_GDISP TRUE
diff --git a/demos/3rdparty/notepad-2/gfxconf.h b/demos/3rdparty/notepad-2/gfxconf.h
index 7f436596..869b2ab2 100644
--- a/demos/3rdparty/notepad-2/gfxconf.h
+++ b/demos/3rdparty/notepad-2/gfxconf.h
@@ -9,10 +9,11 @@
#ifndef _GFXCONF_H
#define _GFXCONF_H
-/* GFX operating system to use */
-#define GFX_USE_OS_CHIBIOS TRUE
-//#define GFX_USE_OS_WIN32 TRUE
-//#define GFX_USE_OS_POSIX TRUE
+/* The operating system to use. One of these must be defined - preferably in your Makefile */
+//#define GFX_USE_OS_CHIBIOS FALSE
+//#define GFX_USE_OS_WIN32 FALSE
+//#define GFX_USE_OS_LINUX FALSE
+//#define GFX_USE_OS_OSX FALSE
/* GFX sub-systems to turn on */
#define GFX_USE_GDISP TRUE
diff --git a/demos/3rdparty/tdisp_f4_discovery/gfxconf.h b/demos/3rdparty/tdisp_f4_discovery/gfxconf.h
index 6d69b3c8..c00e3941 100644
--- a/demos/3rdparty/tdisp_f4_discovery/gfxconf.h
+++ b/demos/3rdparty/tdisp_f4_discovery/gfxconf.h
@@ -14,6 +14,12 @@
#ifndef _GFXCONF_H
#define _GFXCONF_H
+/* The operating system to use. One of these must be defined - preferably in your Makefile */
+//#define GFX_USE_OS_CHIBIOS FALSE
+//#define GFX_USE_OS_WIN32 FALSE
+//#define GFX_USE_OS_LINUX FALSE
+//#define GFX_USE_OS_OSX FALSE
+
/* GFX subsystems to turn on */
#define GFX_USE_GDISP FALSE
#define GFX_USE_TDISP TRUE
@@ -130,7 +136,6 @@
/* Optional Low Level Driver Definitions */
/*
- #define GDISP_USE_CUSTOM_BOARD FALSE
#define GDISP_SCREEN_WIDTH 320
#define GDISP_SCREEN_HEIGHT 240
#define GDISP_USE_FSMC
diff --git a/demos/applications/mandelbrot/gfxconf.h b/demos/applications/mandelbrot/gfxconf.h
index c2c56714..99a04b5c 100644
--- a/demos/applications/mandelbrot/gfxconf.h
+++ b/demos/applications/mandelbrot/gfxconf.h
@@ -30,26 +30,16 @@
#ifndef _GFXCONF_H
#define _GFXCONF_H
-/* The operating system to use - one of these must be defined */
-#define GFX_USE_OS_CHIBIOS TRUE
-#define GFX_USE_OS_WIN32 FALSE
-#define GFX_USE_OS_POSIX FALSE
+/* The operating system to use. One of these must be defined - preferably in your Makefile */
+//#define GFX_USE_OS_CHIBIOS FALSE
+//#define GFX_USE_OS_WIN32 FALSE
+//#define GFX_USE_OS_LINUX FALSE
+//#define GFX_USE_OS_OSX FALSE
/* GFX sub-systems to turn on */
#define GFX_USE_GDISP TRUE
/* Features for the GDISP sub-system. */
#define GDISP_NEED_VALIDATION TRUE
-#define GDISP_NEED_CLIP FALSE
-#define GDISP_NEED_TEXT FALSE
-#define GDISP_NEED_CIRCLE FALSE
-#define GDISP_NEED_ELLIPSE FALSE
-#define GDISP_NEED_ARC FALSE
-#define GDISP_NEED_SCROLL FALSE
-#define GDISP_NEED_PIXELREAD FALSE
-#define GDISP_NEED_CONTROL FALSE
-#define GDISP_NEED_MULTITHREAD FALSE
-#define GDISP_NEED_ASYNC FALSE
-#define GDISP_NEED_MSGAPI FALSE
#endif /* _GFXCONF_H */
diff --git a/demos/applications/notepad/gfxconf.h b/demos/applications/notepad/gfxconf.h
index 95d5dc5e..7ffb22fa 100644
--- a/demos/applications/notepad/gfxconf.h
+++ b/demos/applications/notepad/gfxconf.h
@@ -30,14 +30,14 @@
#ifndef _GFXCONF_H
#define _GFXCONF_H
-/* The operating system to use - one of these must be defined */
-//#define GFX_USE_OS_CHIBIOS TRUE
+/* The operating system to use. One of these must be defined - preferably in your Makefile */
+//#define GFX_USE_OS_CHIBIOS FALSE
//#define GFX_USE_OS_WIN32 FALSE
-//#define GFX_USE_OS_POSIX FALSE
+//#define GFX_USE_OS_LINUX FALSE
+//#define GFX_USE_OS_OSX FALSE
/* GFX sub-systems to turn on */
#define GFX_USE_GDISP TRUE
-#define GFX_USE_GWIN FALSE
#define GFX_USE_GEVENT TRUE
#define GFX_USE_GTIMER TRUE
#define GFX_USE_GINPUT TRUE
@@ -47,14 +47,8 @@
#define GDISP_NEED_CLIP TRUE
#define GDISP_NEED_TEXT TRUE
#define GDISP_NEED_CIRCLE TRUE
-#define GDISP_NEED_ELLIPSE FALSE
-#define GDISP_NEED_ARC FALSE
-#define GDISP_NEED_SCROLL FALSE
-#define GDISP_NEED_PIXELREAD FALSE
#define GDISP_NEED_CONTROL TRUE
#define GDISP_NEED_MULTITHREAD TRUE
-#define GDISP_NEED_ASYNC FALSE
-#define GDISP_NEED_MSGAPI FALSE
/* Builtin Fonts */
#define GDISP_INCLUDE_FONT_DEJAVUSANS12_AA TRUE
diff --git a/demos/benchmarks/gfxconf.h b/demos/benchmarks/gfxconf.h
index 36a6c5b9..aaacd3a2 100644
--- a/demos/benchmarks/gfxconf.h
+++ b/demos/benchmarks/gfxconf.h
@@ -30,10 +30,11 @@
#ifndef _GFXCONF_H
#define _GFXCONF_H
-/* The operating system to use - one of these must be defined */
-#define GFX_USE_OS_CHIBIOS TRUE
-#define GFX_USE_OS_WIN32 FALSE
-#define GFX_USE_OS_POSIX FALSE
+/* The operating system to use. One of these must be defined - preferably in your Makefile */
+//#define GFX_USE_OS_CHIBIOS FALSE
+//#define GFX_USE_OS_WIN32 FALSE
+//#define GFX_USE_OS_LINUX FALSE
+//#define GFX_USE_OS_OSX FALSE
/* GFX sub-systems to turn on */
#define GFX_USE_GDISP TRUE
@@ -42,22 +43,10 @@
#define GDISP_NEED_VALIDATION FALSE
#define GDISP_NEED_CLIP FALSE
#define GDISP_NEED_TEXT TRUE
-#define GDISP_NEED_CIRCLE FALSE
-#define GDISP_NEED_ELLIPSE FALSE
-#define GDISP_NEED_ARC FALSE
-#define GDISP_NEED_SCROLL FALSE
-#define GDISP_NEED_PIXELREAD FALSE
#define GDISP_NEED_CONTROL TRUE
-#define GDISP_NEED_MULTITHREAD FALSE
-#define GDISP_NEED_ASYNC FALSE
-#define GDISP_NEED_MSGAPI FALSE
/* Builtin Fonts */
-#define GDISP_INCLUDE_FONT_SMALL FALSE
-#define GDISP_INCLUDE_FONT_LARGER FALSE
-#define GDISP_INCLUDE_FONT_UI1 FALSE
#define GDISP_INCLUDE_FONT_UI2 TRUE
-#define GDISP_INCLUDE_FONT_LARGENUMBERS FALSE
#endif /* _GFXCONF_H */
diff --git a/demos/modules/gadc/gfxconf.h b/demos/modules/gadc/gfxconf.h
index ff306763..297265b5 100644
--- a/demos/modules/gadc/gfxconf.h
+++ b/demos/modules/gadc/gfxconf.h
@@ -35,96 +35,29 @@
#ifndef _GFXCONF_H
#define _GFXCONF_H
-/* The operating system to use - one of these must be defined */
-#define GFX_USE_OS_CHIBIOS TRUE
-#define GFX_USE_OS_WIN32 FALSE
-#define GFX_USE_OS_POSIX FALSE
+/* The operating system to use. One of these must be defined - preferably in your Makefile */
+//#define GFX_USE_OS_CHIBIOS FALSE
+//#define GFX_USE_OS_WIN32 FALSE
+//#define GFX_USE_OS_LINUX FALSE
+//#define GFX_USE_OS_OSX FALSE
/* GFX sub-systems to turn on */
#define GFX_USE_GDISP TRUE
-#define GFX_USE_TDISP FALSE
#define GFX_USE_GWIN TRUE
-#define GFX_USE_GEVENT FALSE
#define GFX_USE_GTIMER TRUE
-#define GFX_USE_GINPUT FALSE
#define GFX_USE_GADC TRUE
-#define GFX_USE_GAUDIN FALSE
-#define GFX_USE_GAUDOUT FALSE
-#define GFX_USE_GMISC FALSE
/* Features for the GDISP sub-system. */
#define GDISP_NEED_VALIDATION TRUE
#define GDISP_NEED_CLIP TRUE
#define GDISP_NEED_TEXT TRUE
-#define GDISP_NEED_CIRCLE FALSE
-#define GDISP_NEED_ELLIPSE FALSE
-#define GDISP_NEED_ARC FALSE
-#define GDISP_NEED_SCROLL FALSE
-#define GDISP_NEED_PIXELREAD FALSE
#define GDISP_NEED_CONTROL TRUE
#define GDISP_NEED_MULTITHREAD TRUE
-#define GDISP_NEED_ASYNC FALSE
-#define GDISP_NEED_MSGAPI FALSE
/* GDISP - builtin fonts */
-#define GDISP_INCLUDE_FONT_SMALL FALSE
-#define GDISP_INCLUDE_FONT_LARGER FALSE
-#define GDISP_INCLUDE_FONT_UI1 FALSE
#define GDISP_INCLUDE_FONT_UI2 TRUE
-#define GDISP_INCLUDE_FONT_LARGENUMBERS FALSE
-
-/* Features for the TDISP subsystem. */
-#define TDISP_NEED_MULTITHREAD FALSE
/* Features for the GWIN sub-system. */
-#define GWIN_NEED_BUTTON FALSE
#define GWIN_NEED_CONSOLE TRUE
-#define GWIN_NEED_GRAPH FALSE
-
-/* Features for the GEVENT sub-system. */
-#define GEVENT_ASSERT_NO_RESOURCE FALSE
-
-/* Features for the GTIMER sub-system. */
-/* NONE */
-
-/* Features for the GINPUT sub-system. */
-#define GINPUT_NEED_MOUSE FALSE
-#define GINPUT_NEED_KEYBOARD FALSE
-#define GINPUT_NEED_TOGGLE FALSE
-#define GINPUT_NEED_DIAL FALSE
-
-/* Features for the GADC sub-system. */
-/* NONE */
-
-/* Features for the GAUDIN sub-system. */
-/* NONE */
-
-/* Features for the GAUDOUT sub-system. */
-/* NONE */
-
-/* Features for the GMISC sub-system. */
-#define GMISC_NEED_ARRAYOPS FALSE
-
-/* Optional Parameters for various sub-systems */
-/*
- #define GDISP_MAX_FONT_HEIGHT 16
- #define GEVENT_MAXIMUM_SIZE 32
- #define GEVENT_MAX_SOURCE_LISTENERS 32
- #define GTIMER_THREAD_WORKAREA_SIZE 512
- #define GADC_MAX_LOWSPEED_DEVICES 4
-*/
-
-/* Optional Low Level Driver Definitions */
-/*
- #define GDISP_USE_CUSTOM_BOARD FALSE
- #define GDISP_SCREEN_WIDTH 320
- #define GDISP_SCREEN_HEIGHT 240
- #define GDISP_USE_FSMC
- #define GDISP_USE_GPIO
- #define GDISP_VMT_NAME1(x) x##YourDriver1
- #define GDISP_VMT_NAME2(x) x##YourDriver2
- #define TDISP_COLUMNS 16
- #define TDISP_ROWS 2
-*/
#endif /* _GFXCONF_H */
diff --git a/demos/modules/gaudin/gfxconf.h b/demos/modules/gaudin/gfxconf.h
index a17e4fd9..9525a020 100644
--- a/demos/modules/gaudin/gfxconf.h
+++ b/demos/modules/gaudin/gfxconf.h
@@ -35,96 +35,22 @@
#ifndef _GFXCONF_H
#define _GFXCONF_H
-/* The operating system to use - one of these must be defined */
-#define GFX_USE_OS_CHIBIOS TRUE
-#define GFX_USE_OS_WIN32 FALSE
-#define GFX_USE_OS_POSIX FALSE
+/* The operating system to use. One of these must be defined - preferably in your Makefile */
+//#define GFX_USE_OS_CHIBIOS FALSE
+//#define GFX_USE_OS_WIN32 FALSE
+//#define GFX_USE_OS_LINUX FALSE
+//#define GFX_USE_OS_OSX FALSE
/* GFX sub-systems to turn on */
#define GFX_USE_GDISP TRUE
-#define GFX_USE_TDISP FALSE
#define GFX_USE_GWIN TRUE
-#define GFX_USE_GEVENT FALSE
#define GFX_USE_GTIMER TRUE
-#define GFX_USE_GINPUT FALSE
#define GFX_USE_GADC TRUE
#define GFX_USE_GAUDIN TRUE
-#define GFX_USE_GAUDOUT FALSE
-#define GFX_USE_GMISC FALSE
/* Features for the GDISP sub-system. */
#define GDISP_NEED_VALIDATION TRUE
#define GDISP_NEED_CLIP TRUE
-#define GDISP_NEED_TEXT FALSE
-#define GDISP_NEED_CIRCLE FALSE
-#define GDISP_NEED_ELLIPSE FALSE
-#define GDISP_NEED_ARC FALSE
-#define GDISP_NEED_SCROLL FALSE
-#define GDISP_NEED_PIXELREAD FALSE
-#define GDISP_NEED_CONTROL FALSE
#define GDISP_NEED_MULTITHREAD TRUE
-#define GDISP_NEED_ASYNC FALSE
-#define GDISP_NEED_MSGAPI FALSE
-
-/* GDISP - builtin fonts */
-#define GDISP_INCLUDE_FONT_SMALL FALSE
-#define GDISP_INCLUDE_FONT_LARGER FALSE
-#define GDISP_INCLUDE_FONT_UI1 FALSE
-#define GDISP_INCLUDE_FONT_UI2 FALSE
-#define GDISP_INCLUDE_FONT_LARGENUMBERS FALSE
-
-/* Features for the TDISP subsystem. */
-#define TDISP_NEED_MULTITHREAD FALSE
-
-/* Features for the GWIN sub-system. */
-#define GWIN_NEED_BUTTON FALSE
-#define GWIN_NEED_CONSOLE FALSE
-#define GWIN_NEED_GRAPH FALSE
-
-/* Features for the GEVENT sub-system. */
-#define GEVENT_ASSERT_NO_RESOURCE FALSE
-
-/* Features for the GTIMER sub-system. */
-/* NONE */
-
-/* Features for the GINPUT sub-system. */
-#define GINPUT_NEED_MOUSE FALSE
-#define GINPUT_NEED_KEYBOARD FALSE
-#define GINPUT_NEED_TOGGLE FALSE
-#define GINPUT_NEED_DIAL FALSE
-
-/* Features for the GADC sub-system. */
-/* NONE */
-
-/* Features for the GAUDIN sub-system. */
-/* NONE */
-
-/* Features for the GAUDOUT sub-system. */
-/* NONE */
-
-/* Features for the GMISC sub-system. */
-#define GMISC_NEED_ARRAYOPS FALSE
-
-/* Optional Parameters for various sub-systems */
-/*
- #define GDISP_MAX_FONT_HEIGHT 16
- #define GEVENT_MAXIMUM_SIZE 32
- #define GEVENT_MAX_SOURCE_LISTENERS 32
- #define GTIMER_THREAD_WORKAREA_SIZE 512
- #define GADC_MAX_LOWSPEED_DEVICES 4
-*/
-
-/* Optional Low Level Driver Definitions */
-/*
- #define GDISP_USE_CUSTOM_BOARD FALSE
- #define GDISP_SCREEN_WIDTH 320
- #define GDISP_SCREEN_HEIGHT 240
- #define GDISP_USE_FSMC
- #define GDISP_USE_GPIO
- #define GDISP_VMT_NAME1(x) x##YourDriver1
- #define GDISP_VMT_NAME2(x) x##YourDriver2
- #define TDISP_COLUMNS 16
- #define TDISP_ROWS 2
-*/
#endif /* _GFXCONF_H */
diff --git a/demos/modules/gdisp/basics/gfxconf.h b/demos/modules/gdisp/basics/gfxconf.h
index 60b8888e..a37ef1e7 100644
--- a/demos/modules/gdisp/basics/gfxconf.h
+++ b/demos/modules/gdisp/basics/gfxconf.h
@@ -30,11 +30,11 @@
#ifndef _GFXCONF_H
#define _GFXCONF_H
-/* The operating system to use. One of these must be defined - perferably in your Makefile */
-//#define GFX_USE_OS_CHIBIOS FALSE
+/* The operating system to use. One of these must be defined - preferably in your Makefile */
+//#define GFX_USE_OS_CHIBIOS FALSE
//#define GFX_USE_OS_WIN32 FALSE
//#define GFX_USE_OS_LINUX FALSE
-//#define GFX_USE_OS_OSX FALSE
+//#define GFX_USE_OS_OSX FALSE
/* GFX sub-systems to turn on */
#define GFX_USE_GDISP TRUE
diff --git a/demos/modules/gdisp/circles/gfxconf.h b/demos/modules/gdisp/circles/gfxconf.h
index 28311ccb..4bb605ac 100644
--- a/demos/modules/gdisp/circles/gfxconf.h
+++ b/demos/modules/gdisp/circles/gfxconf.h
@@ -30,11 +30,11 @@
#ifndef _GFXCONF_H
#define _GFXCONF_H
-/* The operating system to use. One of these must be defined - perferably in your Makefile */
-//#define GFX_USE_OS_CHIBIOS FALSE
+/* The operating system to use. One of these must be defined - preferably in your Makefile */
+//#define GFX_USE_OS_CHIBIOS FALSE
//#define GFX_USE_OS_WIN32 FALSE
//#define GFX_USE_OS_LINUX FALSE
-//#define GFX_USE_OS_OSX FALSE
+//#define GFX_USE_OS_OSX FALSE
/* GFX sub-systems to turn on */
#define GFX_USE_GDISP TRUE
diff --git a/demos/modules/gdisp/fonts/gfxconf.h b/demos/modules/gdisp/fonts/gfxconf.h
index 9f569e37..64481774 100644
--- a/demos/modules/gdisp/fonts/gfxconf.h
+++ b/demos/modules/gdisp/fonts/gfxconf.h
@@ -30,11 +30,11 @@
#ifndef _GFXCONF_H
#define _GFXCONF_H
-/* The operating system to use. One of these must be defined - perferably in your Makefile */
-//#define GFX_USE_OS_CHIBIOS FALSE
+/* The operating system to use. One of these must be defined - preferably in your Makefile */
+//#define GFX_USE_OS_CHIBIOS FALSE
//#define GFX_USE_OS_WIN32 FALSE
//#define GFX_USE_OS_LINUX FALSE
-//#define GFX_USE_OS_OSX FALSE
+//#define GFX_USE_OS_OSX FALSE
/* GFX sub-systems to turn on */
#define GFX_USE_GDISP TRUE
@@ -43,18 +43,13 @@
#define GDISP_NEED_VALIDATION TRUE
#define GDISP_NEED_CLIP TRUE
#define GDISP_NEED_TEXT TRUE
-#define GDISP_NEED_CIRCLE FALSE
-#define GDISP_NEED_ELLIPSE FALSE
-#define GDISP_NEED_ARC FALSE
-#define GDISP_NEED_SCROLL FALSE
-#define GDISP_NEED_PIXELREAD FALSE
-#define GDISP_NEED_CONTROL FALSE
-#define GDISP_NEED_MULTITHREAD FALSE
-#define GDISP_NEED_ASYNC FALSE
-#define GDISP_NEED_MSGAPI FALSE
#define GDISP_NEED_ANTIALIAS TRUE
/* GDISP - fonts to include */
+#define GDISP_INCLUDE_USER_FONTS TRUE
+#define GDISP_INCLUDE_FONT_UI1 FALSE
+#define GDISP_INCLUDE_FONT_UI2 TRUE
+#define GDISP_INCLUDE_FONT_LARGENUMBERS FALSE
#define GDISP_INCLUDE_FONT_DEJAVUSANS10 TRUE
#define GDISP_INCLUDE_FONT_DEJAVUSANS12 FALSE
#define GDISP_INCLUDE_FONT_DEJAVUSANS16 FALSE
@@ -70,9 +65,6 @@
#define GDISP_INCLUDE_FONT_DEJAVUSANS32_AA FALSE
#define GDISP_INCLUDE_FONT_DEJAVUSANSBOLD12_AA FALSE
-#define GDISP_INCLUDE_FONT_UI1 FALSE
-#define GDISP_INCLUDE_FONT_UI2 TRUE
-#define GDISP_INCLUDE_FONT_LARGENUMBERS FALSE
#endif /* _GFXCONF_H */
diff --git a/demos/modules/gdisp/fonts_cyrillic/gfxconf.h b/demos/modules/gdisp/fonts_cyrillic/gfxconf.h
index 1bf1baeb..dab77ba1 100644
--- a/demos/modules/gdisp/fonts_cyrillic/gfxconf.h
+++ b/demos/modules/gdisp/fonts_cyrillic/gfxconf.h
@@ -30,11 +30,11 @@
#ifndef _GFXCONF_H
#define _GFXCONF_H
-/* The operating system to use. One of these must be defined - perferably in your Makefile */
-//#define GFX_USE_OS_CHIBIOS FALSE
-//#define GFX_USE_OS_WIN32 FALSE
-//#define GFX_USE_OS_LINUX FALSE
-//#define GFX_USE_OS_OSX FALSE
+/* The operating system to use. One of these must be defined - preferably in your Makefile */
+//#define GFX_USE_OS_CHIBIOS FALSE
+//#define GFX_USE_OS_WIN32 FALSE
+//#define GFX_USE_OS_LINUX FALSE
+//#define GFX_USE_OS_OSX FALSE
/* GFX subsystems to turn on */
#define GFX_USE_GDISP TRUE
diff --git a/demos/modules/gdisp/images/gfxconf.h b/demos/modules/gdisp/images/gfxconf.h
index 0bf9f1fc..6cd78b37 100644
--- a/demos/modules/gdisp/images/gfxconf.h
+++ b/demos/modules/gdisp/images/gfxconf.h
@@ -30,11 +30,11 @@
#ifndef _GFXCONF_H
#define _GFXCONF_H
-/* The operating system to use. One of these must be defined - perferably in your Makefile */
-//#define GFX_USE_OS_CHIBIOS FALSE
+/* The operating system to use. One of these must be defined - preferably in your Makefile */
+//#define GFX_USE_OS_CHIBIOS FALSE
//#define GFX_USE_OS_WIN32 FALSE
//#define GFX_USE_OS_LINUX FALSE
-//#define GFX_USE_OS_OSX FALSE
+//#define GFX_USE_OS_OSX FALSE
/* GFX sub-systems to turn on */
#define GFX_USE_GDISP TRUE
diff --git a/demos/modules/gdisp/images_animated/gfxconf.h b/demos/modules/gdisp/images_animated/gfxconf.h
index 8cf34e87..cc38ed36 100644
--- a/demos/modules/gdisp/images_animated/gfxconf.h
+++ b/demos/modules/gdisp/images_animated/gfxconf.h
@@ -30,11 +30,11 @@
#ifndef _GFXCONF_H
#define _GFXCONF_H
-/* The operating system to use. One of these must be defined - perferably in your Makefile */
-//#define GFX_USE_OS_CHIBIOS FALSE
+/* The operating system to use. One of these must be defined - preferably in your Makefile */
+//#define GFX_USE_OS_CHIBIOS FALSE
//#define GFX_USE_OS_WIN32 FALSE
//#define GFX_USE_OS_LINUX FALSE
-//#define GFX_USE_OS_OSX FALSE
+//#define GFX_USE_OS_OSX FALSE
/* GFX sub-systems to turn on */
#define GFX_USE_GDISP TRUE
diff --git a/demos/modules/gdisp/multiple_displays/gfxconf.h b/demos/modules/gdisp/multiple_displays/gfxconf.h
new file mode 100644
index 00000000..60467f93
--- /dev/null
+++ b/demos/modules/gdisp/multiple_displays/gfxconf.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2012, 2013, Joel Bodenmann aka Tectu <joel@unormal.org>
+ * Copyright (c) 2012, 2013, Andrew Hannam aka inmarket
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the <organization> nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _GFXCONF_H
+#define _GFXCONF_H
+
+//* The operating system to use. One of these must be defined - preferably in your Makefile */
+//#define GFX_USE_OS_CHIBIOS FALSE
+//#define GFX_USE_OS_WIN32 FALSE
+//#define GFX_USE_OS_LINUX FALSE
+//#define GFX_USE_OS_OSX FALSE
+
+/* GFX sub-systems to turn on */
+#define GFX_USE_GDISP TRUE
+
+/* Features for the GDISP sub-system. */
+#define GDISP_NEED_VALIDATION TRUE
+#define GDISP_NEED_CLIP TRUE
+#define GDISP_NEED_TEXT TRUE
+
+#define GDISP_INCLUDE_FONT_UI2 TRUE
+
+#define GDISP_TOTAL_DISPLAYS 2
+
+/* Uncomment the following lines if you want to use multiple displays on
+ * different controllers.
+ *
+ * Change the definitions to suit your hardware.
+ * Currently all controllers must use the same pixel format.
+ *
+ * Remember that GDISP_TOTAL_DISPLAYS above must match the **Total**
+ * number of displays in your system across all controllers.
+ *
+ * Optionally, you can also specify hardware characteristics that are common to
+ * all your controllers. This significantly improves code and speed efficiency
+ * as the program doesn't have to detect the hardware method to use on each call.
+ *
+ * Hardware definitions can be set to:
+ * - TRUE - all controllers support this routine
+ * - FALSE - no controllers support this routine
+ * - if not specified then the code auto-detects the hardware.
+ *
+ * e.g
+ * #define GDISP_HARDWARE_STREAM_WRITE FALSE
+ * #define GDISP_HARDWARE_STREAM_READ FALSE
+ * #define GDISP_HARDWARE_DRAWPIXEL TRUE
+ * #define GDISP_HARDWARE_FILLS TRUE
+ */
+//#define GDISP_TOTAL_CONTROLLERS 2
+//#define GDISP_CONTROLLER_LIST GDISPVMT_Win32, GDISPVMT_Win32
+//#define GDISP_CONTROLLER_DISPLAYS 1, 1
+//#define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_RGB888
+
+#endif /* _GFXCONF_H */
diff --git a/demos/modules/gdisp/multiple_displays/main.c b/demos/modules/gdisp/multiple_displays/main.c
new file mode 100644
index 00000000..443bee27
--- /dev/null
+++ b/demos/modules/gdisp/multiple_displays/main.c
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2012, 2013, Joel Bodenmann aka Tectu <joel@unormal.org>
+ * Copyright (c) 2012, 2013, Andrew Hannam aka inmarket
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the <organization> nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "gfx.h"
+
+#include <stdio.h>
+
+/*
+ * This demo demonstrates two ways to talk to multiple displays.
+ *
+ * Method 1 is the preferred way however Method 1 would be useful
+ * when quickly converting existing single display applications.
+ *
+ * Note you can combine the methods using method 2 for the first display
+ * and method 1 for any extra displays.
+ */
+
+#define USE_METHOD_1 FALSE
+
+#if USE_METHOD_1
+ int main(void) {
+ coord_t width, height;
+ coord_t display, i, j;
+ font_t f;
+ GDisplay *g;
+ char buf[16];
+
+ /* Initialize and clear the display */
+ gfxInit();
+
+ /* Get a font to write with */
+ f = gdispOpenFont("*");
+
+ /* Cycle through each display */
+ for(display = 0; display < GDISP_TOTAL_DISPLAYS; display++) {
+
+ // Get the specified display
+ g = gdispGetDisplay(display);
+
+ // Get the screen size
+ width = gdispGGetWidth(g);
+ height = gdispGGetHeight(g);
+
+ /* Draw draw draw */
+ gdispGDrawBox(g, 10, 10, width/2, height/2, Yellow);
+ sprintf(buf, "Display %u", display);
+ gdispGFillStringBox(g, width/2, height/2, width/2-10, height/2-10, buf, f, White, Blue, justifyCenter);
+ gdispGDrawLine(g, 5, 30, width-50, height-40, Red);
+
+ for(i = 5, j = 0; i < width && j < height; i += 7, j += i/20)
+ gdispGDrawPixel(g, i, j, White);
+ }
+
+ while(TRUE) {
+ gfxSleepMilliseconds(500);
+ }
+ }
+#else
+ int main(void) {
+ coord_t width, height;
+ coord_t display, i, j;
+ font_t f;
+ char buf[16];
+
+ /* Initialize and clear the display */
+ gfxInit();
+
+ /* Get a font to write with */
+ f = gdispOpenFont("*");
+
+ /* Cycle through each display */
+ for(display = 0; display < GDISP_TOTAL_DISPLAYS; display++) {
+
+ // Set the default display to the specified display
+ gdispSetDisplay(gdispGetDisplay(display));
+
+ // Get the screen size
+ width = gdispGetWidth();
+ height = gdispGetHeight();
+
+ /* Draw draw draw */
+ gdispDrawBox(10, 10, width/2, height/2, Yellow);
+ sprintf(buf, "Display %u", display);
+ gdispFillStringBox(width/2, height/2, width/2-10, height/2-10, buf, f, White, Blue, justifyCenter);
+ gdispDrawLine(5, 30, width-50, height-40, Red);
+
+ for(i = 5, j = 0; i < width && j < height; i += 7, j += i/20)
+ gdispDrawPixel(i, j, White);
+ }
+
+ while(TRUE) {
+ gfxSleepMilliseconds(500);
+ }
+ }
+#endif
+
diff --git a/demos/modules/gdisp/streaming/gfxconf.h b/demos/modules/gdisp/streaming/gfxconf.h
new file mode 100644
index 00000000..82843184
--- /dev/null
+++ b/demos/modules/gdisp/streaming/gfxconf.h
@@ -0,0 +1,31 @@
+/**
+ * This file has a different license to the rest of the GFX system.
+ * You can copy, modify and distribute this file as you see fit.
+ * You do not need to publish your source modifications to this file.
+ * The only thing you are not permitted to do is to relicense it
+ * under a different license.
+ */
+
+#ifndef _GFXCONF_H
+#define _GFXCONF_H
+
+/* The operating system to use. One of these must be defined - preferably in your Makefile */
+//#define GFX_USE_OS_CHIBIOS FALSE
+//#define GFX_USE_OS_WIN32 FALSE
+//#define GFX_USE_OS_LINUX FALSE
+//#define GFX_USE_OS_OSX FALSE
+
+/* GFX sub-systems to turn on */
+#define GFX_USE_GDISP TRUE
+#define GFX_USE_GMISC TRUE
+
+/* Features for the GDISP sub-system. */
+#define GDISP_NEED_VALIDATION TRUE
+#define GDISP_NEED_STREAMING TRUE
+
+#define GFX_USE_GMISC TRUE
+#define GMISC_NEED_INVSQRT TRUE
+//#define GMISC_INVSQRT_MIXED_ENDIAN TRUE
+//#define GMISC_INVSQRT_REAL_SLOW TRUE
+
+#endif /* _GFXCONF_H */
diff --git a/demos/modules/gdisp/streaming/main.c b/demos/modules/gdisp/streaming/main.c
new file mode 100644
index 00000000..4ad48b6c
--- /dev/null
+++ b/demos/modules/gdisp/streaming/main.c
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2012, 2013, Joel Bodenmann aka Tectu <joel@unormal.org>
+ * Copyright (c) 2012, 2013, Andrew Hannam aka inmarket
+ * Derived from the 2011 IOCCC submission by peter.eastman@gmail.com
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the <organization> nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "gfx.h"
+#include <math.h>
+
+/**
+ * NOTE:
+ *
+ * This demo uses floating point operations. Don't expect it to work with any
+ * speed unless your processor has an FPU.
+ *
+ * If you see garbage inside the ball as it is running rather than the red and yellow
+ * checkerboard pattern then the fast invsqrt() function in GMISC does not work on
+ * your processor.
+ *
+ * You can modify the implementation of invsqrt() by firstly defining
+ * #define GMISC_INVSQRT_MIXED_ENDIAN TRUE
+ * in your gfxconf.h file.
+ *
+ * If it still doesn't work then instead define
+ * #define GMISC_INVSQRT_REAL_SLOW TRUE
+ * in your gfxconf.h file. This should always work although it will probably be slow.
+ */
+#define BALLCOLOR1 Red
+#define BALLCOLOR2 Yellow
+#define WALLCOLOR HTML2COLOR(0x303030)
+#define BACKCOLOR HTML2COLOR(0xC0C0C0)
+#define FLOORCOLOR HTML2COLOR(0x606060)
+#define SHADOWALPHA (255-255*0.2)
+
+int main(void) {
+ coord_t width, height, x, y, radius, ballx, bally, dx, floor;
+ coord_t minx, miny, maxx, maxy;
+ coord_t ballcx, ballcy;
+ color_t colour;
+ float ii, spin, dy, spinspeed, h, f, g;
+
+ gfxInit();
+ #if GDISP_NEED_CONTROL
+ gdispSetOrientation(GDISP_ROTATE_90);
+ #endif
+
+ width = gdispGetWidth();
+ height = gdispGetHeight();
+
+ radius=height/5+height%2+1; // The ball radius
+ ii = 1.0/radius; // radius as easy math
+ floor=height/5-1; // floor position
+ spin=0.0; // current spin angle on the ball
+ spinspeed=0.1; // current spin speed of the ball
+ ballx=width/2; // ball x position (relative to the ball center)
+ bally=height/4; // ball y position (relative to the ball center)
+ dx=.01*width; // motion in the x axis
+ dy=0.0; // motion in the y axis
+ ballcx = 12*radius/5; // ball x diameter including the shadow
+ ballcy = 21*radius/10; // ball y diameter including the shadow
+
+
+ minx = miny = 0; maxx = width; maxy = height; // The clipping window for this frame.
+
+ while(1) {
+ // Draw one frame
+ gdispStreamStart(minx, miny, maxx-minx, maxy-miny);
+ for (y=miny; h = (bally-y)*ii, y<maxy; y++) {
+ for (x=minx; x < maxx; x++) {
+ g=(ballx-x)*ii;
+ f=-.3*g+.954*h;
+ if (g*g < 1-h*h) {
+ /* The inside of the ball */
+ if ((((int)(9-spin+(.954*g+.3*h)*invsqrt(1-f*f))+(int)(2+f*2))&1))
+ colour = BALLCOLOR1;
+ else
+ colour = BALLCOLOR2;
+ } else {
+ // The background (walls and floor)
+ if (y > height-floor) {
+ if (x < height-y || height-y > width-x)
+ colour = WALLCOLOR;
+ else
+ colour = FLOORCOLOR;
+ } else if (x<floor || x>width-floor)
+ colour = WALLCOLOR;
+ else
+ colour = BACKCOLOR;
+
+ // The ball shadow is darker
+ if (g*(g+.4)+h*(h+.1) < 1)
+ colour = gdispBlendColor(colour, Black, SHADOWALPHA);
+ }
+ gdispStreamColor(colour); /* pixel to the LCD */
+ }
+ }
+ gdispStreamStop();
+
+ // Force a display update if the controller supports it
+ gdispFlush();
+
+ // Calculate the new frame size (note this is a drawing optimisation only)
+ minx = ballx - radius; miny = bally - radius;
+ maxx = minx + ballcx; maxy = miny + ballcy;
+ if (dx > 0) maxx += dx; else minx += dx;
+ if (dy > 0) maxy += dy; else miny += dy;
+ if (minx < 0) minx = 0;
+ if (maxx > width) maxx = width;
+ if (miny < 0) miny = 0;
+ if (maxy > height) maxy = height;
+
+ // Motion
+ spin += spinspeed;
+ ballx += dx; bally += dy;
+ dx = ballx < radius || ballx > width-radius ? spinspeed=-spinspeed,-dx : dx;
+ dy = bally > height-1.75*floor ? -.04*height : dy+.002*height;
+ }
+}
diff --git a/demos/modules/ginput/touch_driver_test/gfxconf.h b/demos/modules/ginput/touch_driver_test/gfxconf.h
index 6e8cc8e1..9b2de86c 100644
--- a/demos/modules/ginput/touch_driver_test/gfxconf.h
+++ b/demos/modules/ginput/touch_driver_test/gfxconf.h
@@ -30,10 +30,11 @@
#ifndef _GFXCONF_H
#define _GFXCONF_H
-/* The operating system to use - one of these must be defined */
-#define GFX_USE_OS_CHIBIOS TRUE
-#define GFX_USE_OS_WIN32 FALSE
-#define GFX_USE_OS_POSIX FALSE
+/* The operating system to use. One of these must be defined - preferably in your Makefile */
+//#define GFX_USE_OS_CHIBIOS FALSE
+//#define GFX_USE_OS_WIN32 FALSE
+//#define GFX_USE_OS_LINUX FALSE
+//#define GFX_USE_OS_OSX FALSE
/* GFX sub-systems to turn on */
#define GFX_USE_GDISP TRUE
@@ -46,22 +47,10 @@
#define GDISP_NEED_VALIDATION TRUE
#define GDISP_NEED_CLIP TRUE
#define GDISP_NEED_TEXT TRUE
-#define GDISP_NEED_CIRCLE FALSE
-#define GDISP_NEED_ELLIPSE FALSE
-#define GDISP_NEED_ARC FALSE
-#define GDISP_NEED_SCROLL FALSE
-#define GDISP_NEED_PIXELREAD FALSE
-#define GDISP_NEED_CONTROL FALSE
#define GDISP_NEED_MULTITHREAD TRUE
-#define GDISP_NEED_ASYNC FALSE
-#define GDISP_NEED_MSGAPI FALSE
/* Builtin Fonts */
-#define GDISP_INCLUDE_FONT_SMALL FALSE
-#define GDISP_INCLUDE_FONT_LARGER FALSE
-#define GDISP_INCLUDE_FONT_UI1 FALSE
#define GDISP_INCLUDE_FONT_UI2 TRUE
-#define GDISP_INCLUDE_FONT_LARGENUMBERS FALSE
/* Features for the GWIN sub-system. */
#define GWIN_NEED_BUTTON TRUE
diff --git a/demos/modules/gtimer/gfxconf.h b/demos/modules/gtimer/gfxconf.h
index 1c4a31f8..8786fafe 100644
--- a/demos/modules/gtimer/gfxconf.h
+++ b/demos/modules/gtimer/gfxconf.h
@@ -30,10 +30,11 @@
#ifndef _GFXCONF_H
#define _GFXCONF_H
-/* The operating system to use - one of these must be defined */
-#define GFX_USE_OS_CHIBIOS TRUE
-#define GFX_USE_OS_WIN32 FALSE
-#define GFX_USE_OS_POSIX FALSE
+/* The operating system to use. One of these must be defined - preferably in your Makefile */
+//#define GFX_USE_OS_CHIBIOS FALSE
+//#define GFX_USE_OS_WIN32 FALSE
+//#define GFX_USE_OS_LINUX FALSE
+//#define GFX_USE_OS_OSX FALSE
/* GFX sub-systems to turn on */
#define GFX_USE_GTIMER TRUE
diff --git a/demos/modules/gwin/basic/gfxconf.h b/demos/modules/gwin/basic/gfxconf.h
index 411ad9cf..70149055 100644
--- a/demos/modules/gwin/basic/gfxconf.h
+++ b/demos/modules/gwin/basic/gfxconf.h
@@ -30,11 +30,11 @@
#ifndef _GFXCONF_H
#define _GFXCONF_H
-/* The operating system to use. One of these must be defined - perferably in your Makefile */
-//#define GFX_USE_OS_CHIBIOS FALSE
+/* The operating system to use. One of these must be defined - preferably in your Makefile */
+//#define GFX_USE_OS_CHIBIOS FALSE
//#define GFX_USE_OS_WIN32 FALSE
//#define GFX_USE_OS_LINUX FALSE
-//#define GFX_USE_OS_OSX FALSE
+//#define GFX_USE_OS_OSX FALSE
/* GFX sub-systems to turn on */
#define GFX_USE_GDISP TRUE
diff --git a/demos/modules/gwin/button/gfxconf.h b/demos/modules/gwin/button/gfxconf.h
index 2199e891..5376bd52 100644
--- a/demos/modules/gwin/button/gfxconf.h
+++ b/demos/modules/gwin/button/gfxconf.h
@@ -30,11 +30,11 @@
#ifndef _GFXCONF_H
#define _GFXCONF_H
-/* The operating system to use. One of these must be defined - perferably in your Makefile */
-//#define GFX_USE_OS_CHIBIOS FALSE
+/* The operating system to use. One of these must be defined - preferably in your Makefile */
+//#define GFX_USE_OS_CHIBIOS FALSE
//#define GFX_USE_OS_WIN32 FALSE
//#define GFX_USE_OS_LINUX FALSE
-//#define GFX_USE_OS_OSX FALSE
+//#define GFX_USE_OS_OSX FALSE
/* GFX sub-systems to turn on */
#define GFX_USE_GDISP TRUE
diff --git a/demos/modules/gwin/checkbox/gfxconf.h b/demos/modules/gwin/checkbox/gfxconf.h
index 9be70462..f9060599 100644
--- a/demos/modules/gwin/checkbox/gfxconf.h
+++ b/demos/modules/gwin/checkbox/gfxconf.h
@@ -30,11 +30,11 @@
#ifndef _GFXCONF_H
#define _GFXCONF_H
-/* The operating system to use. One of these must be defined - perferably in your Makefile */
-//#define GFX_USE_OS_CHIBIOS FALSE
+/* The operating system to use. One of these must be defined - preferably in your Makefile */
+//#define GFX_USE_OS_CHIBIOS FALSE
//#define GFX_USE_OS_WIN32 FALSE
//#define GFX_USE_OS_LINUX FALSE
-//#define GFX_USE_OS_OSX FALSE
+//#define GFX_USE_OS_OSX FALSE
/* GFX sub-systems to turn on */
#define GFX_USE_GDISP TRUE
diff --git a/demos/modules/gwin/console/gfxconf.h b/demos/modules/gwin/console/gfxconf.h
index 42ad5e12..3ada3b89 100644
--- a/demos/modules/gwin/console/gfxconf.h
+++ b/demos/modules/gwin/console/gfxconf.h
@@ -30,11 +30,11 @@
#ifndef _GFXCONF_H
#define _GFXCONF_H
-/* The operating system to use. One of these must be defined - perferably in your Makefile */
-//#define GFX_USE_OS_CHIBIOS FALSE
+/* The operating system to use. One of these must be defined - preferably in your Makefile */
+//#define GFX_USE_OS_CHIBIOS FALSE
//#define GFX_USE_OS_WIN32 FALSE
//#define GFX_USE_OS_LINUX FALSE
-//#define GFX_USE_OS_OSX FALSE
+//#define GFX_USE_OS_OSX FALSE
/* GFX sub-systems to turn on */
#define GFX_USE_GDISP TRUE
diff --git a/demos/modules/gwin/graph/gfxconf.h b/demos/modules/gwin/graph/gfxconf.h
index 684d0e7a..c09bfc6e 100644
--- a/demos/modules/gwin/graph/gfxconf.h
+++ b/demos/modules/gwin/graph/gfxconf.h
@@ -30,11 +30,11 @@
#ifndef _GFXCONF_H
#define _GFXCONF_H
-/* The operating system to use. One of these must be defined - perferably in your Makefile */
-//#define GFX_USE_OS_CHIBIOS FALSE
+/* The operating system to use. One of these must be defined - preferably in your Makefile */
+//#define GFX_USE_OS_CHIBIOS FALSE
//#define GFX_USE_OS_WIN32 FALSE
//#define GFX_USE_OS_LINUX FALSE
-//#define GFX_USE_OS_OSX FALSE
+//#define GFX_USE_OS_OSX FALSE
/* GFX sub-systems to turn on */
#define GFX_USE_GDISP TRUE
diff --git a/demos/modules/gwin/list/gfxconf.h b/demos/modules/gwin/list/gfxconf.h
index ab9cc008..40b509ff 100644
--- a/demos/modules/gwin/list/gfxconf.h
+++ b/demos/modules/gwin/list/gfxconf.h
@@ -30,11 +30,11 @@
#ifndef _GFXCONF_H
#define _GFXCONF_H
-/* The operating system to use. One of these must be defined - perferably in your Makefile */
-//#define GFX_USE_OS_CHIBIOS FALSE
+/* The operating system to use. One of these must be defined - preferably in your Makefile */
+//#define GFX_USE_OS_CHIBIOS FALSE
//#define GFX_USE_OS_WIN32 FALSE
//#define GFX_USE_OS_LINUX FALSE
-//#define GFX_USE_OS_OSX FALSE
+//#define GFX_USE_OS_OSX FALSE
/* GFX sub-systems to turn on */
#define GFX_USE_GDISP TRUE
diff --git a/demos/modules/gwin/radio/gfxconf.h b/demos/modules/gwin/radio/gfxconf.h
index 595042fb..7c3e441e 100644
--- a/demos/modules/gwin/radio/gfxconf.h
+++ b/demos/modules/gwin/radio/gfxconf.h
@@ -30,11 +30,11 @@
#ifndef _GFXCONF_H
#define _GFXCONF_H
-/* The operating system to use. One of these must be defined - perferably in your Makefile */
-//#define GFX_USE_OS_CHIBIOS FALSE
+/* The operating system to use. One of these must be defined - preferably in your Makefile */
+//#define GFX_USE_OS_CHIBIOS FALSE
//#define GFX_USE_OS_WIN32 FALSE
//#define GFX_USE_OS_LINUX FALSE
-//#define GFX_USE_OS_OSX FALSE
+//#define GFX_USE_OS_OSX FALSE
/* GFX sub-systems to turn on */
#define GFX_USE_GDISP TRUE
diff --git a/demos/modules/gwin/slider/gfxconf.h b/demos/modules/gwin/slider/gfxconf.h
index 8a1be49d..fc8d356e 100644
--- a/demos/modules/gwin/slider/gfxconf.h
+++ b/demos/modules/gwin/slider/gfxconf.h
@@ -30,11 +30,11 @@
#ifndef _GFXCONF_H
#define _GFXCONF_H
-/* The operating system to use. One of these must be defined - perferably in your Makefile */
-//#define GFX_USE_OS_CHIBIOS FALSE
+/* The operating system to use. One of these must be defined - preferably in your Makefile */
+//#define GFX_USE_OS_CHIBIOS FALSE
//#define GFX_USE_OS_WIN32 FALSE
//#define GFX_USE_OS_LINUX FALSE
-//#define GFX_USE_OS_OSX FALSE
+//#define GFX_USE_OS_OSX FALSE
/* GFX sub-systems to turn on */
#define GFX_USE_GDISP TRUE
diff --git a/demos/modules/gwin/widgets/gfxconf.h b/demos/modules/gwin/widgets/gfxconf.h
index 0299f2ef..111979e3 100644
--- a/demos/modules/gwin/widgets/gfxconf.h
+++ b/demos/modules/gwin/widgets/gfxconf.h
@@ -30,11 +30,11 @@
#ifndef _GFXCONF_H
#define _GFXCONF_H
-/* The operating system to use. One of these must be defined - perferably in your Makefile */
-//#define GFX_USE_OS_CHIBIOS FALSE
+/* The operating system to use. One of these must be defined - preferably in your Makefile */
+//#define GFX_USE_OS_CHIBIOS FALSE
//#define GFX_USE_OS_WIN32 FALSE
//#define GFX_USE_OS_LINUX FALSE
-//#define GFX_USE_OS_OSX FALSE
+//#define GFX_USE_OS_OSX FALSE
/* GFX sub-systems to turn on */
#define GFX_USE_GDISP TRUE
@@ -49,6 +49,12 @@
#define GDISP_NEED_CIRCLE TRUE
#define GDISP_NEED_TEXT TRUE
#define GDISP_NEED_IMAGE TRUE
+#define GDISP_NEED_CONVEX_POLYGON TRUE
+#define GDISP_NEED_CONTROL TRUE
+#define GDISP_DEFAULT_ORIENTATION GDISP_ROTATE_LANDSCAPE
+
+/* The following are optional depending on your hardware */
+//#define GDISP_NEED_SCROLL TRUE
/* GDISP fonts to include */
#define GDISP_INCLUDE_FONT_UI2 TRUE
diff --git a/demos/modules/tdisp/gfxconf.h b/demos/modules/tdisp/gfxconf.h
index 1f323be3..371a9f44 100644
--- a/demos/modules/tdisp/gfxconf.h
+++ b/demos/modules/tdisp/gfxconf.h
@@ -30,10 +30,11 @@
#ifndef _GFXCONF_H
#define _GFXCONF_H
-/* The operating system to use - one of these must be defined */
-#define GFX_USE_OS_CHIBIOS TRUE
-#define GFX_USE_OS_WIN32 FALSE
-#define GFX_USE_OS_POSIX FALSE
+/* The operating system to use. One of these must be defined - preferably in your Makefile */
+//#define GFX_USE_OS_CHIBIOS FALSE
+//#define GFX_USE_OS_WIN32 FALSE
+//#define GFX_USE_OS_LINUX FALSE
+//#define GFX_USE_OS_OSX FALSE
/* GFX sub-systems to turn on */
#define GFX_USE_TDISP TRUE
diff --git a/drivers/gadc/AT91SAM7/gadc_lld_board_template.h b/drivers/gadc/AT91SAM7/gadc_lld_board_template.h
new file mode 100644
index 00000000..045c0ed7
--- /dev/null
+++ b/drivers/gadc/AT91SAM7/gadc_lld_board_template.h
@@ -0,0 +1,37 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gadc/AT91SAM7/gadc_lld_board_template.h
+ * @brief GADC Driver config file.
+ *
+ * @addtogroup GADC
+ * @{
+ */
+
+#ifndef _GADC_LLD_BOARD_H
+#define _GADC_LLD_BOARD_H
+
+#if GFX_USE_GADC
+
+/*===========================================================================*/
+/* Analogue devices on this board */
+/*===========================================================================*/
+
+/**
+ * @brief The physical devices that are accessible via GADC and their physical device numbers.
+ * @note The numbers below are examples for this template file
+ */
+#define GADC_PHYSDEV_MICROPHONE 0x00000080
+#define GADC_PHYSDEV_DIAL 0x00000040
+#define GADC_PHYSDEV_TEMPERATURE 0x00000020
+
+#endif /* GFX_USE_GADC */
+
+#endif /* _GADC_LLD_BOARD_H */
+/** @} */
+
diff --git a/drivers/gadc/AT91SAM7/gadc_lld_config.h b/drivers/gadc/AT91SAM7/gadc_lld_config.h
index 8c6e1cc0..ba6cbda2 100644
--- a/drivers/gadc/AT91SAM7/gadc_lld_config.h
+++ b/drivers/gadc/AT91SAM7/gadc_lld_config.h
@@ -52,16 +52,8 @@
*/
#define GADC_SAMPLE_FORMAT ARRAY_DATA_10BITUNSIGNED
-/* Pull in board specific defines */
-#if defined(GADC_USE_CUSTOM_BOARD) && GADC_USE_CUSTOM_BOARD
- /* Include the user supplied board definitions */
- #include "gadc_lld_board.h"
-#elif defined(BOARD_OLIMEX_SAM7_EX256)
- #include "gadc_lld_board_olimexsam7ex256.h"
-#else
- /* Include the user supplied board definitions */
- #include "gadc_lld_board.h"
-#endif
+/* Include the user supplied board definitions */
+#include "gadc_lld_board.h"
#endif /* GFX_USE_GADC */
diff --git a/drivers/gaudin/gadc/gaudin_lld_board_olimexsam7ex256.h b/drivers/gaudin/gadc/gaudin_lld_board_template.h
index a98f392c..89cc0c12 100644
--- a/drivers/gaudin/gadc/gaudin_lld_board_olimexsam7ex256.h
+++ b/drivers/gaudin/gadc/gaudin_lld_board_template.h
@@ -6,15 +6,15 @@
*/
/**
- * @file drivers/gaudin/gadc/gaudin_lld_board_olimexsam7ex256.h
- * @brief GAUDIN Driver board config file for the Olimex SAM7EX256 board
+ * @file drivers/gaudin/gadc/gaudin_lld_board_template.h
+ * @brief GAUDIN Driver board config board file
*
* @addtogroup GAUDIN
* @{
*/
-#ifndef _GAUDIN_LLD_BOARD_OLIMEXSAM7EX256_H
-#define _GAUDIN_LLD_BOARD_OLIMEXSAM7EX256_H
+#ifndef _GAUDIN_LLD_BOARD_H
+#define _GAUDIN_LLD_BOARD_H
/*===========================================================================*/
/* Audio inputs on this board */
@@ -22,18 +22,21 @@
/**
* @brief The number of audio channels supported by this driver
+ * @note This is an example
*/
#define GAUDIN_NUM_CHANNELS 1
/**
* @brief The list of audio channels and their uses
+ * @note This is an example
* @{
*/
#define GAUDIN_MICROPHONE 0
/** @} */
/**
- * @brief The following defines are for the low level driver use only
+ * @brief The audio channel to GADC physical device assignment
+ * @note This is an example
* @{
*/
#ifdef GAUDIN_LLD_IMPLEMENTATION
@@ -43,5 +46,5 @@
#endif
/** @} */
-#endif /* _GAUDIN_LLD_BOARD_OLIMEXSAM7EX256_H */
+#endif /* _GAUDIN_LLD_BOARD_H */
/** @} */
diff --git a/drivers/gaudin/gadc/gaudin_lld_config.h b/drivers/gaudin/gadc/gaudin_lld_config.h
index f10e0575..a9fd02ae 100644
--- a/drivers/gaudin/gadc/gaudin_lld_config.h
+++ b/drivers/gaudin/gadc/gaudin_lld_config.h
@@ -50,15 +50,8 @@ typedef adcsample_t audin_sample_t;
* For the GAUDIN driver that uses GADC - all the remaining config definitions are specific
* to the board.
*/
-#if defined(GADC_USE_CUSTOM_BOARD) && GADC_USE_CUSTOM_BOARD
- /* Include the user supplied board definitions */
- #include "gaudin_lld_board.h"
-#elif defined(BOARD_OLIMEX_SAM7_EX256)
- #include "gaudin_lld_board_olimexsam7ex256.h"
-#else
- /* Include the user supplied board definitions */
- #include "gaudin_lld_board.h"
-#endif
+/* Include the user supplied board definitions */
+#include "gaudin_lld_board.h"
#endif /* GFX_USE_GAUDIN */
diff --git a/drivers/gdisp/ED060SC4/board_ED060SC4_template.h b/drivers/gdisp/ED060SC4/board_ED060SC4_template.h
new file mode 100644
index 00000000..6d71a986
--- /dev/null
+++ b/drivers/gdisp/ED060SC4/board_ED060SC4_template.h
@@ -0,0 +1,202 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/ST7565/board_ST7565_template.h
+ * @brief GDISP Graphic Driver subsystem board interface for the ST7565 display.
+ *
+ * @addtogroup GDISP
+ * @{
+ */
+
+#ifndef _GDISP_LLD_BOARD_H
+#define _GDISP_LLD_BOARD_H
+
+/**
+ * @brief Optional parameters that can be put in this file.
+ * @note The values listed below are the defaults.
+ *
+ * @note #define GDISP_SCREEN_HEIGHT 600
+ * @note #define GDISP_SCREEN_WIDTH 800
+ *
+ * @note Number of pixels per byte<br>
+ * #define EINK_PPB 4
+ *
+ * @note Delay for generating clock pulses.
+ * Unit is approximate clock cycles of the CPU (0 to 15).
+ * This should be atleast 50 ns.<br>
+ * #define EINK_CLOCKDELAY 0
+ *
+ * @note Width of one framebuffer block.
+ * Must be divisible by EINK_PPB and evenly divide GDISP_SCREEN_WIDTH.<br>
+ * #define EINK_BLOCKWIDTH 20
+ *
+ * @note
+ * @note Height of one framebuffer block.
+ * Must evenly divide GDISP_SCREEN_WIDTH.<br>
+ * #define EINK_BLOCKHEIGHT 20
+ *
+ * @note Number of block buffers to use for framebuffer emulation.<br>
+ * #define EINK_NUMBUFFERS 40
+ *
+ * @note Do a "blinking" clear, i.e. clear to opposite polarity first.
+ * This reduces the image persistence.<br>
+ * #define EINK_BLINKCLEAR TRUE
+ *
+ * @note Number of passes to use when clearing the display<br>
+ * #define EINK_CLEARCOUNT 10
+ *
+ * @note Number of passes to use when writing to the display<br>
+ * #define EINK_WRITECOUNT 4
+ */
+
+/**
+ * @brief Initialise the board for the display.
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @note Set the g->board member to whatever is appropriate. For multiple
+ * displays this might be a pointer to the appropriate register set.
+ *
+ * @notapi
+ */
+static inline void init_board(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Delay for display waveforms. Should be an accurate microsecond delay.
+ *
+ * @param[in] us The number of microseconds
+ */
+static void eink_delay(int us) {
+ (void) us;
+}
+
+/**
+ * @brief Turn the E-ink panel Vdd supply (+3.3V) on or off.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] on On or off
+ */
+static inline void setpower_vdd(GDisplay *g, bool_t on) {
+ (void) g;
+ (void) on;
+}
+
+/**
+ * @brief Turn the E-ink panel negative supplies (-15V, -20V) on or off.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] on On or off
+ */
+static inline void setpower_vneg(GDisplay *g, bool_t on) {
+ (void) g;
+ (void) on;
+}
+
+/**
+ * @brief Turn the E-ink panel positive supplies (-15V, -20V) on or off.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] on On or off
+ */
+static inline void setpower_vpos(GDisplay *g, bool_t on) {
+ (void) g;
+ (void) on;
+}
+
+/**
+ * @brief Set the state of the LE (source driver Latch Enable) pin.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] on On or off
+ */
+static inline void setpin_le(GDisplay *g, bool_t on) {
+ (void) g;
+ (void) on;
+}
+
+/**
+ * @brief Set the state of the OE (source driver Output Enable) pin.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] on On or off
+ */
+static inline void setpin_oe(GDisplay *g, bool_t on) {
+ (void) g;
+ (void) on;
+}
+
+/**
+ * @brief Set the state of the CL (source driver Clock) pin.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] on On or off
+ */
+static inline void setpin_cl(GDisplay *g, bool_t on) {
+ (void) g;
+ (void) on;
+}
+
+/**
+ * @brief Set the state of the SPH (source driver Start Pulse Horizontal) pin.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] on On or off
+ */
+static inline void setpin_sph(GDisplay *g, bool_t on) {
+ (void) g;
+ (void) on;
+}
+
+/**
+ * @brief Set the state of the D0-D7 (source driver Data) pins.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] value The byte to write
+ */
+static inline void setpins_data(GDisplay *g, uint8_t value) {
+ (void) g;
+ (void) value;
+}
+
+/**
+ * @brief Set the state of the CKV (gate driver Clock Vertical) pin.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] on On or off
+ */
+static inline void setpin_ckv(GDisplay *g, bool_t on) {
+ (void) g;
+ (void) on;
+}
+
+/**
+ * @brief Set the state of the GMODE (gate driver Gate Mode) pin.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] on On or off
+ */
+static inline void setpin_gmode(GDisplay *g, bool_t on) {
+ (void) g;
+ (void) on;
+}
+
+/**
+ * @brief Set the state of the SPV (gate driver Start Pulse Vertical) pin.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] on On or off
+ */
+static inline void setpin_spv(GDisplay *g, bool_t on) {
+ (void) g;
+ (void) on;
+}
+
+#endif /* _GDISP_LLD_BOARD_H */
+/** @} */
diff --git a/drivers/gdisp/ED060SC4/gdisp_lld.mk b/drivers/gdisp/ED060SC4/gdisp_lld.mk
index d5c1492f..0c78e1a7 100644
--- a/drivers/gdisp/ED060SC4/gdisp_lld.mk
+++ b/drivers/gdisp/ED060SC4/gdisp_lld.mk
@@ -1,2 +1,2 @@
-GFXSRC += $(GFXLIB)/drivers/gdisp/ED060SC4/gdisp_lld.c
GFXINC += $(GFXLIB)/drivers/gdisp/ED060SC4
+GFXSRC += $(GFXLIB)/drivers/gdisp/ED060SC4/gdisp_lld_ED060SC4.c
diff --git a/drivers/gdisp/ED060SC4/gdisp_lld_ED060SC4.c b/drivers/gdisp/ED060SC4/gdisp_lld_ED060SC4.c
new file mode 100644
index 00000000..3ab1de79
--- /dev/null
+++ b/drivers/gdisp/ED060SC4/gdisp_lld_ED060SC4.c
@@ -0,0 +1,625 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/ED060SC4/gdisp_lld.c
+ * @brief GDISP Graphics Driver for the E-ink panel ED060SC4.
+ */
+
+#include "gfx.h"
+
+#if GFX_USE_GDISP
+
+#define GDISP_DRIVER_VMT GDISPVMT_ED060SC4
+#include "../drivers/gdisp/ED060SC4/gdisp_lld_config.h"
+#include "gdisp/lld/gdisp_lld.h"
+
+#include "board_ED060SC4.h"
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+#ifndef GDISP_SCREEN_HEIGHT
+ #define GDISP_SCREEN_HEIGHT 600
+#endif
+#ifndef GDISP_SCREEN_WIDTH
+ #define GDISP_SCREEN_WIDTH 800
+#endif
+
+/* Number of pixels per byte */
+#ifndef EINK_PPB
+ #define EINK_PPB 4
+#endif
+
+/* Delay for generating clock pulses.
+ * Unit is approximate clock cycles of the CPU (0 to 15).
+ * This should be atleast 50 ns.
+ */
+#ifndef EINK_CLOCKDELAY
+ #define EINK_CLOCKDELAY 0
+#endif
+
+/* Width of one framebuffer block.
+ * Must be divisible by EINK_PPB and evenly divide GDISP_SCREEN_WIDTH. */
+#ifndef EINK_BLOCKWIDTH
+ #define EINK_BLOCKWIDTH 20
+#endif
+
+/* Height of one framebuffer block.
+ * Must evenly divide GDISP_SCREEN_WIDTH. */
+#ifndef EINK_BLOCKHEIGHT
+ #define EINK_BLOCKHEIGHT 20
+#endif
+
+/* Number of block buffers to use for framebuffer emulation. */
+#ifndef EINK_NUMBUFFERS
+ #define EINK_NUMBUFFERS 40
+#endif
+
+/* Do a "blinking" clear, i.e. clear to opposite polarity first.
+ * This reduces the image persistence. */
+#ifndef EINK_BLINKCLEAR
+ #define EINK_BLINKCLEAR TRUE
+#endif
+
+/* Number of passes to use when clearing the display */
+#ifndef EINK_CLEARCOUNT
+ #define EINK_CLEARCOUNT 10
+#endif
+
+/* Number of passes to use when writing to the display */
+#ifndef EINK_WRITECOUNT
+ #define EINK_WRITECOUNT 4
+#endif
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+#define PRIV(g) ((drvPriv *)g->priv)
+
+/** Delay between signal changes, to give time for IO pins to change state. */
+static inline void clockdelay(void)
+{
+ #if EINK_CLOCKDELAY & 1
+ asm("nop");
+ #endif
+ #if EINK_CLOCKDELAY & 2
+ asm("nop");
+ asm("nop");
+ #endif
+ #if EINK_CLOCKDELAY & 4
+ asm("nop");
+ asm("nop");
+ asm("nop");
+ asm("nop");
+ #endif
+ #if EINK_CLOCKDELAY & 8
+ asm("nop");
+ asm("nop");
+ asm("nop");
+ asm("nop");
+ asm("nop");
+ asm("nop");
+ asm("nop");
+ asm("nop");
+ #endif
+}
+
+/** Fast vertical clock pulse for gate driver, used during initializations */
+static void vclock_quick(GDisplay *g)
+{
+ setpin_ckv(g, TRUE);
+ eink_delay(1);
+ setpin_ckv(g, FALSE);
+ eink_delay(4);
+}
+
+/** Horizontal clock pulse for clocking data into source driver */
+static void hclock(GDisplay *g)
+{
+ clockdelay();
+ setpin_cl(g, TRUE);
+ clockdelay();
+ setpin_cl(g, FALSE);
+}
+
+/** Start a new vertical gate driver scan from top.
+ * Note: Does not clear any previous bits in the shift register,
+ * so you should always scan through the whole display before
+ * starting a new scan.
+ */
+static void vscan_start(GDisplay *g)
+{
+ setpin_gmode(g, TRUE);
+ vclock_quick(g);
+ setpin_spv(g, FALSE);
+ vclock_quick(g);
+ setpin_spv(g, TRUE);
+ vclock_quick(g);
+}
+
+/** Waveform for strobing a row of data onto the display.
+ * Attempts to minimize the leaking of color to other rows by having
+ * a long idle period after a medium-length strobe period.
+ */
+static void vscan_write(GDisplay *g)
+{
+ setpin_ckv(g, TRUE);
+ setpin_oe(g, TRUE);
+ eink_delay(5);
+ setpin_oe(g, FALSE);
+ setpin_ckv(g, FALSE);
+ eink_delay(200);
+}
+
+/** Waveform used when clearing the display. Strobes a row of data to the
+ * screen, but does not mind some of it leaking to other rows.
+ */
+static void vscan_bulkwrite(GDisplay *g)
+{
+ setpin_ckv(g, TRUE);
+ eink_delay(20);
+ setpin_ckv(g, FALSE);
+ eink_delay(200);
+}
+
+/** Waveform for skipping a vertical row without writing anything.
+ * Attempts to minimize the amount of change in any row.
+ */
+static void vscan_skip(GDisplay *g)
+{
+ setpin_ckv(g, TRUE);
+ eink_delay(1);
+ setpin_ckv(g, FALSE);
+ eink_delay(100);
+}
+
+/** Stop the vertical scan. The significance of this escapes me, but it seems
+ * necessary or the next vertical scan may be corrupted.
+ */
+static void vscan_stop(GDisplay *g)
+{
+ setpin_gmode(g, FALSE);
+ vclock_quick(g);
+ vclock_quick(g);
+ vclock_quick(g);
+ vclock_quick(g);
+ vclock_quick(g);
+}
+
+/** Start updating the source driver data (from left to right). */
+static void hscan_start(GDisplay *g)
+{
+ /* Disable latching and output enable while we are modifying the row. */
+ setpin_le(g, FALSE);
+ setpin_oe(g, FALSE);
+
+ /* The start pulse should remain low for the duration of the row. */
+ setpin_sph(g, FALSE);
+}
+
+/** Write data to the horizontal row. */
+static void hscan_write(GDisplay *g, const uint8_t *data, int count)
+{
+ while (count--)
+ {
+ /* Set the next byte on the data pins */
+ setpins_data(g, *data++);
+
+ /* Give a clock pulse to the shift register */
+ hclock(g);
+ }
+}
+
+/** Finish and transfer the row to the source drivers.
+ * Does not set the output enable, so the drivers are not yet active. */
+static void hscan_stop(GDisplay *g)
+{
+ /* End the scan */
+ setpin_sph(g, TRUE);
+ hclock(g);
+
+ /* Latch the new data */
+ setpin_le(g, TRUE);
+ clockdelay();
+ setpin_le(g, FALSE);
+}
+
+/** Turn on the power to the E-Ink panel, observing proper power sequencing. */
+static void power_on(GDisplay *g)
+{
+ unsigned i;
+
+ /* First the digital power supply and signal levels. */
+ setpower_vdd(g, TRUE);
+ setpin_le(g, FALSE);
+ setpin_oe(g, FALSE);
+ setpin_cl(g, FALSE);
+ setpin_sph(g, TRUE);
+ setpins_data(g, 0);
+ setpin_ckv(g, FALSE);
+ setpin_gmode(g, FALSE);
+ setpin_spv(g, TRUE);
+
+ /* Min. 100 microsecond delay after digital supply */
+ gfxSleepMicroseconds(100);
+
+ /* Then negative voltages and min. 1000 microsecond delay. */
+ setpower_vneg(g, TRUE);
+ gfxSleepMicroseconds(1000);
+
+ /* Finally the positive voltages. */
+ setpower_vpos(g, TRUE);
+
+ /* Clear the vscan shift register */
+ vscan_start(g);
+ for (i = 0; i < GDISP_SCREEN_HEIGHT; i++)
+ vclock_quick(g);
+ vscan_stop(g);
+}
+
+/** Turn off the power, observing proper power sequencing. */
+static void power_off(GDisplay *g)
+{
+ /* First the high voltages */
+ setpower_vpos(g, FALSE);
+ setpower_vneg(g, FALSE);
+
+ /* Wait for any capacitors to drain */
+ gfxSleepMilliseconds(100);
+
+ /* Then put all signals and digital supply to ground. */
+ setpin_le(g, FALSE);
+ setpin_oe(g, FALSE);
+ setpin_cl(g, FALSE);
+ setpin_sph(g, FALSE);
+ setpins_data(g, 0);
+ setpin_ckv(g, FALSE);
+ setpin_gmode(g, FALSE);
+ setpin_spv(g, FALSE);
+ setpower_vdd(g, FALSE);
+}
+
+/* ====================================
+ * Framebuffer emulation layer
+ * ==================================== */
+
+#if EINK_PPB == 4
+ #define PIXELMASK 3
+ #define PIXEL_WHITE 2
+ #define PIXEL_BLACK 1
+ #define BYTE_WHITE 0xAA
+ #define BYTE_BLACK 0x55
+#else
+ #error Unsupported EINK_PPB value.
+#endif
+
+#if GDISP_SCREEN_HEIGHT % EINK_BLOCKHEIGHT != 0
+ #error GDISP_SCREEN_HEIGHT must be evenly divisible by EINK_BLOCKHEIGHT
+#endif
+
+#if GDISP_SCREEN_WIDTH % EINK_BLOCKWIDTH != 0
+ #error GDISP_SCREEN_WIDTH must be evenly divisible by EINK_BLOCKWIDTH
+#endif
+
+#if EINK_BLOCKWIDTH % EINK_PPB != 0
+ #error EINK_BLOCKWIDTH must be evenly divisible by EINK_PPB
+#endif
+
+#if EINK_NUMBUFFERS > 254
+ #error EINK_NUMBUFFERS must be at most 254.
+#endif
+
+#define BLOCKS_Y (GDISP_SCREEN_HEIGHT / EINK_BLOCKHEIGHT)
+#define BLOCKS_X (GDISP_SCREEN_WIDTH / EINK_BLOCKWIDTH)
+#define WIDTH_BYTES (EINK_BLOCKWIDTH / EINK_PPB)
+
+/* Buffers that store the data for a small area of the display. */
+typedef struct {
+ uint8_t data[EINK_BLOCKHEIGHT][WIDTH_BYTES];
+} block_t;
+
+typedef struct drvPriv {
+ uint8_t g_next_block; /* Index of the next free block buffer. */
+ block_t g_blocks[EINK_NUMBUFFERS];
+
+ /* Map that stores the buffers associated to each area of the display.
+ * Value of 0 means that the block is not allocated.
+ * Other values are the index in g_blocks + 1.
+ */
+ uint8_t g_blockmap[BLOCKS_Y][BLOCKS_X];
+} drvPriv;
+
+/** Check if the row contains any allocated blocks. */
+static bool_t blocks_on_row(GDisplay *g, unsigned by)
+{
+ unsigned bx;
+ for (bx = 0; bx < BLOCKS_X; bx++)
+ {
+ if (PRIV(g)->g_blockmap[by][bx] != 0)
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/** Write out a block row. */
+static void write_block_row(GDisplay *g, unsigned by)
+{
+ unsigned bx, dy, dx;
+ for (dy = 0; dy < EINK_BLOCKHEIGHT; dy++)
+ {
+ hscan_start(g);
+ for (bx = 0; bx < BLOCKS_X; bx++)
+ {
+ if (PRIV(g)->g_blockmap[by][bx] == 0)
+ {
+ for (dx = 0; dx < WIDTH_BYTES; dx++)
+ {
+ const uint8_t dummy = 0;
+ hscan_write(g, &dummy, 1);
+ }
+ }
+ else
+ {
+ block_t *block = &PRIV(g)->g_blocks[PRIV(g)->g_blockmap[by][bx] - 1];
+ hscan_write(g, &block->data[dy][0], WIDTH_BYTES);
+ }
+ }
+ hscan_stop(g);
+
+ vscan_write(g);
+ }
+}
+
+/** Clear the block map, i.e. deallocate all blocks */
+static void clear_block_map(GDisplay *g)
+{
+ unsigned bx, by;
+ for (by = 0; by < BLOCKS_Y; by++)
+ {
+ for (bx = 0; bx < BLOCKS_X; bx++)
+ {
+ PRIV(g)->g_blockmap[by][bx] = 0;
+ }
+ }
+
+ PRIV(g)->g_next_block = 0;
+}
+
+/** Initialize a newly allocated block. */
+static void zero_block(block_t *block)
+{
+ unsigned dx, dy;
+ for (dy = 0; dy < EINK_BLOCKHEIGHT; dy++)
+ {
+ for (dx = 0; dx < WIDTH_BYTES; dx++)
+ {
+ block->data[dy][dx] = 0;
+ }
+ }
+}
+
+/** Allocate a buffer
+ * Automatically flushes if all buffers are full. */
+static block_t *alloc_buffer(GDisplay *g, unsigned bx, unsigned by)
+{
+ block_t *result;
+ drvPriv *priv;
+
+ priv = PRIV(g);
+ if (priv->g_blockmap[by][bx] == 0)
+ {
+ if (priv->g_next_block >= EINK_NUMBUFFERS)
+ gdisp_lld_flush(g);
+
+ result = &priv->g_blocks[priv->g_next_block];
+ priv->g_blockmap[by][bx] = priv->g_next_block + 1;
+ priv->g_next_block++;
+ zero_block(result);
+ return result;
+ }
+ else
+ {
+ result = &priv->g_blocks[priv->g_blockmap[by][bx] - 1];
+ return result;
+ }
+}
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
+ g->priv = gfxAlloc(sizeof(drvPriv));
+
+ init_board(g);
+
+ /* Make sure that all the pins are in "off" state.
+ * Having any pin high could cause voltage leaking to the
+ * display, which in turn causes the image to leak slowly away.
+ */
+ power_off(g);
+
+ clear_block_map(g);
+
+ /* Initialise the GDISP structure */
+ g->g.Width = GDISP_SCREEN_WIDTH;
+ g->g.Height = GDISP_SCREEN_HEIGHT;
+ g->g.Orientation = GDISP_ROTATE_0;
+ g->g.Powermode = powerOn;
+ g->g.Backlight = 100;
+ g->g.Contrast = 100;
+ return TRUE;
+}
+
+#if GDISP_HARDWARE_FLUSH
+ LLDSPEC void gdisp_lld_flush(GDisplay *g) {
+ unsigned by, dy, i;
+
+ for (i = 0; i < EINK_WRITECOUNT; i++) {
+ vscan_start(g);
+
+ for (by = 0; by < BLOCKS_Y; by++) {
+ if (!blocks_on_row(g, by)) {
+ /* Skip the whole row of blocks. */
+ for (dy = 0; dy < EINK_BLOCKHEIGHT; dy++)
+ vscan_skip(g);
+ } else {
+ /* Write out the blocks. */
+ write_block_row(g, by);
+ }
+ }
+
+ vscan_stop(g);
+ }
+
+ clear_block_map(g);
+ }
+#endif
+
+#if GDISP_HARDWARE_DRAWPIXEL
+ void gdisp_lld_draw_pixel(GDisplay *g) {
+ block_t *block;
+ uint8_t byte;
+ unsigned bx, by, dx, dy;
+ uint8_t bitpos;
+
+ switch(g->g.Orientation) {
+ case GDISP_ROTATE_0:
+ bx = g->p.x / EINK_BLOCKWIDTH;
+ dx = g->p.x % EINK_BLOCKWIDTH;
+ by = g->p.y / EINK_BLOCKHEIGHT;
+ dy = g->p.y % EINK_BLOCKHEIGHT;
+ break;
+ case GDISP_ROTATE_90:
+ bx = g->p.y / EINK_BLOCKWIDTH;
+ dx = g->p.y % EINK_BLOCKWIDTH;
+ by = (GDISP_SCREEN_HEIGHT-1 - g->p.x) / EINK_BLOCKHEIGHT;
+ dy = (GDISP_SCREEN_HEIGHT-1 - g->p.x) % EINK_BLOCKHEIGHT;
+ break;
+ case GDISP_ROTATE_180:
+ bx = (GDISP_SCREEN_WIDTH-1 - g->p.x) / EINK_BLOCKWIDTH;
+ dx = (GDISP_SCREEN_WIDTH-1 - g->p.x) % EINK_BLOCKWIDTH;
+ by = (GDISP_SCREEN_HEIGHT-1 - g->p.y) / EINK_BLOCKHEIGHT;
+ dy = (GDISP_SCREEN_HEIGHT-1 - g->p.y) % EINK_BLOCKHEIGHT;
+ break;
+ case GDISP_ROTATE_270:
+ bx = (GDISP_SCREEN_WIDTH-1 - g->p.y) / EINK_BLOCKWIDTH;
+ dx = (GDISP_SCREEN_WIDTH-1 - g->p.y) % EINK_BLOCKWIDTH;
+ by = g->p.x / EINK_BLOCKHEIGHT;
+ dy = g->p.x % EINK_BLOCKHEIGHT;
+ break;
+ }
+
+ block = alloc_buffer(g, bx, by);
+
+ bitpos = (6 - 2 * (dx % EINK_PPB));
+ byte = block->data[dy][dx / EINK_PPB];
+ byte &= ~(PIXELMASK << bitpos);
+ if (COLOR2NATIVE(g->p.color) != Black)
+ byte |= PIXEL_WHITE << bitpos;
+ else
+ byte |= PIXEL_BLACK << bitpos;
+ block->data[dy][dx / EINK_PPB] = byte;
+ }
+#endif
+
+#if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL
+ LLDSPEC void gdisp_lld_control(GDisplay *g) {
+ switch(g->p.x) {
+ case GDISP_CONTROL_POWER:
+ if (g->g.Powermode == (powermode_t)g->p.ptr)
+ return;
+ switch((powermode_t)g->p.ptr) {
+ case powerOff:
+ case powerSleep:
+ case powerDeepSleep:
+ gdisp_lld_flush(g);
+ power_off(g);
+ break;
+ case powerOn:
+ power_on(g);
+ break;
+ default:
+ return;
+ }
+ g->g.Powermode = (powermode_t)g->p.ptr;
+ return;
+
+ case GDISP_CONTROL_ORIENTATION:
+ if (g->g.Orientation == (orientation_t)g->p.ptr)
+ return;
+ switch((orientation_t)g->p.ptr) {
+ case GDISP_ROTATE_0:
+ case GDISP_ROTATE_180:
+ g->g.Height = GDISP_SCREEN_HEIGHT;
+ g->g.Width = GDISP_SCREEN_WIDTH;
+ break;
+ case GDISP_ROTATE_90:
+ case GDISP_ROTATE_270:
+ g->g.Height = GDISP_SCREEN_WIDTH;
+ g->g.Width = GDISP_SCREEN_HEIGHT;
+ break;
+ default:
+ return;
+ }
+ g->g.Orientation = (orientation_t)g->p.ptr;
+ return;
+
+ default:
+ return;
+ }
+ }
+#endif
+
+/* ===============================
+ * Accelerated routines
+ * =============================== */
+
+#if GDISP_HARDWARE_CLEARS
+ static void subclear(GDisplay *g, color_t color) {
+ unsigned x, y;
+ uint8_t byte;
+
+ hscan_start(g);
+ byte = color ? BYTE_WHITE : BYTE_BLACK;
+ for (x = 0; x < GDISP_SCREEN_WIDTH; x++)
+ {
+ hscan_write(g, &byte, 1);
+ }
+ hscan_stop(g);
+
+ setpin_oe(g, TRUE);
+ vscan_start(g);
+ for (y = 0; y < GDISP_SCREEN_HEIGHT; y++)
+ vscan_bulkwrite(g);
+ vscan_stop(g);
+ setpin_oe(g, FALSE);
+ }
+
+ void gdisp_lld_clear(GDisplay *g) {
+ unsigned i;
+
+ clear_block_map(g);
+
+ if (EINK_BLINKCLEAR) {
+ subclear(g, !g->p.color);
+ gfxSleepMilliseconds(50);
+ }
+
+ for (i = 0; i < EINK_CLEARCOUNT; i++) {
+ subclear(g, g->p.color);
+ gfxSleepMilliseconds(10);
+ }
+ }
+#endif
+
+#endif // GFX_USE_GDISP
diff --git a/drivers/gdisp/ED060SC4/gdisp_lld_config.h b/drivers/gdisp/ED060SC4/gdisp_lld_config.h
index befd997c..47e84779 100644
--- a/drivers/gdisp/ED060SC4/gdisp_lld_config.h
+++ b/drivers/gdisp/ED060SC4/gdisp_lld_config.h
@@ -12,15 +12,12 @@
#if GFX_USE_GDISP
-#define GDISP_DRIVER_NAME "ED060SC4"
+#define GDISP_HARDWARE_FLUSH TRUE // This controller requires flushing
+#define GDISP_HARDWARE_DRAWPIXEL TRUE
#define GDISP_HARDWARE_CLEARS TRUE
-#define GDISP_HARDWARE_FILLS FALSE
-#define GDISP_HARDWARE_BITFILLS FALSE
-#define GDISP_HARDWARE_SCROLL FALSE
-#define GDISP_HARDWARE_PIXELREAD FALSE
#define GDISP_HARDWARE_CONTROL TRUE
-#define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_MONO
+#define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_MONO
#endif
diff --git a/drivers/gdisp/ED060SC4/readme.txt b/drivers/gdisp/ED060SC4/readme.txt
index 5409d810..852a0010 100644
--- a/drivers/gdisp/ED060SC4/readme.txt
+++ b/drivers/gdisp/ED060SC4/readme.txt
@@ -38,8 +38,7 @@ result in faster drawing, but also use more RAM on the processor:
After drawing your images, you should flush the buffers using the following
command:
- #include <ed060sc4.h>
- gdispControl(GDISP_CONTROL_FLUSH, 0);
+ gdispFlush();
The buffers are also flushed whenever you turn the display off using:
diff --git a/drivers/gdisp/HX8347D/HX8347D.h b/drivers/gdisp/HX8347D/HX8347D.h
index b35dda12..280cd748 100644
--- a/drivers/gdisp/HX8347D/HX8347D.h
+++ b/drivers/gdisp/HX8347D/HX8347D.h
@@ -33,7 +33,7 @@
#define HX8347D_REG_PSLL 0x0b /* Partial area start row low */
#define HX8347D_REG_PELH 0x0c /* Partial area end row high */
#define HX8347D_REG_PELL 0x0d /* Partial area end row low */
-#define HX8347D_REG_TFAH 0x0e /* Vertical srcoll top fixed area high */
+#define HX8347D_REG_TFAH 0x0e /* Vertical scroll top fixed area high */
#define HX8347D_REG_TFAL 0x0f /* Vertical scroll top fixed area low */
#define HX8347D_REG_VSAH 0x10 /* Vertical scroll height area high */
diff --git a/drivers/gdisp/HX8347D/board_HX8347D_template.h b/drivers/gdisp/HX8347D/board_HX8347D_template.h
new file mode 100644
index 00000000..57ec75f6
--- /dev/null
+++ b/drivers/gdisp/HX8347D/board_HX8347D_template.h
@@ -0,0 +1,156 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/HX8347D/board_HX8347D_template.h
+ * @brief GDISP Graphic Driver subsystem board SPI interface for the HX8347D display.
+ *
+ * @addtogroup GDISP
+ * @{
+ */
+
+#ifndef _GDISP_LLD_BOARD_H
+#define _GDISP_LLD_BOARD_H
+
+/**
+ * @brief Initialise the board for the display.
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @note Set the g->board member to whatever is appropriate. For multiple
+ * displays this might be a pointer to the appropriate register set.
+ *
+ * @notapi
+ */
+static inline void init_board(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief After the initialisation.
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void post_init_board(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Set or clear the lcd reset pin.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] state TRUE = lcd in reset, FALSE = normal operation
+ *
+ * @notapi
+ */
+static inline void setpin_reset(GDisplay *g, bool_t state) {
+ (void) g;
+ (void) state;
+}
+
+/**
+ * @brief Set the lcd back-light level.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] percent 0 to 100%
+ *
+ * @notapi
+ */
+static inline void set_backlight(GDisplay *g, uint8_t percent) {
+ (void) g;
+ (void) percent;
+}
+
+/**
+ * @brief Take exclusive control of the bus
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void acquire_bus(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Release exclusive control of the bus
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void release_bus(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Set the bus in 16 bit mode
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void busmode16(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Set the bus in 8 bit mode (the default)
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void busmode8(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Send data to the index register.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] index The index register to set
+ *
+ * @notapi
+ */
+static inline void write_index(GDisplay *g, uint8_t index) {
+ (void) g;
+ (void) index;
+}
+
+/**
+ * @brief Send 8 bits of data to the lcd.
+ * @pre The bus is in 8 bit mode
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] data The data to send
+ *
+ * @notapi
+ */
+static inline void write_data(GDisplay *g, uint8_t data) {
+ (void) g;
+ (void) data;
+}
+
+/**
+ * @brief Send 16 bits of data to the lcd.
+ * @pre The bus is in 16 bit mode
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] data The data to send
+ *
+ * @notapi
+ */
+static inline void write_ram16(GDisplay *g, uint16_t data) {
+ (void) g;
+ (void) data;
+}
+
+#endif /* _GDISP_LLD_BOARD_H */
+/** @} */
diff --git a/drivers/gdisp/HX8347D/gdisp_lld.c b/drivers/gdisp/HX8347D/gdisp_lld.c
deleted file mode 100644
index bcb6dfc0..00000000
--- a/drivers/gdisp/HX8347D/gdisp_lld.c
+++ /dev/null
@@ -1,485 +0,0 @@
-/*
- * This file is subject to the terms of the GFX License. If a copy of
- * the license was not distributed with this file, you can obtain one at:
- *
- * http://ugfx.org/license.html
- */
-
-/**
- * @file drivers/gdisp/HX8347D/gdisp_lld.c
- * @brief GDISP Graphics Driver subsystem low level driver source for the HX8347D display.
- *
- * @addtogroup GDISP
- * @{
- */
-
-#include "gfx.h"
-
-#include "HX8347D.h"
-
-#if GFX_USE_GDISP /*|| defined(__DOXYGEN__)*/
-
-/* Include the emulation code for things we don't support */
-#include "gdisp/lld/emulation.c"
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-#ifndef GDISP_SCREEN_HEIGHT
- #define GDISP_SCREEN_HEIGHT 320
-#endif
-#ifndef GDISP_SCREEN_WIDTH
- #define GDISP_SCREEN_WIDTH 240
-#endif
-
-#define GDISP_INITIAL_CONTRAST 50
-#define GDISP_INITIAL_BACKLIGHT 50
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-#include "gdisp_lld_board.h"
-
-// Some common routines and macros
-#define write_reg(reg, data) { write_index(reg); write_data(data); }
-#define write_ram(color1, color2) { write_index(0x22); write_ram8(color1,color2); }
-#define stream_start() { write_index(0x22); spiStart(&SPID1, &spi1cfg2); }
-#define stream_stop() {while(((SPI1->SR & SPI_SR_TXE) == 0) || ((SPI1->SR & SPI_SR_BSY) != 0));palSetPad(GPIOA, 4);spiStart(&SPID1, &spi1cfg1); }
-#define delay(us) gfxSleepMicroseconds(us)
-#define delayms(ms) gfxSleepMilliseconds(ms)
-
-static inline void set_cursor(coord_t x, coord_t y) {
- write_reg(HX8347D_REG_SCL, (uint8_t) x);
- write_reg(HX8347D_REG_SCH, (uint8_t) (x >> 8));
- write_reg(HX8347D_REG_SPL, (uint8_t) y);
- write_reg(HX8347D_REG_SPH, (uint8_t) (y >> 8));
-}
-
-static void set_viewport(coord_t x, coord_t y, coord_t cx, coord_t cy) {
- write_reg(HX8347D_REG_SCL, (uint8_t) x);
- write_reg(HX8347D_REG_SCH, (uint8_t) (x >> 8));
- write_reg(HX8347D_REG_ECL, (uint8_t) (x + cx -1));
- write_reg(HX8347D_REG_ECH, (uint8_t) ((x + cx -1) >> 8));
- write_reg(HX8347D_REG_SPL, (uint8_t) y);
- write_reg(HX8347D_REG_SPH, (uint8_t) (y >> 8));
- write_reg(HX8347D_REG_EPL, (uint8_t) (y + cy -1));
- write_reg(HX8347D_REG_EPH, (uint8_t) ((y + cy -1) >> 8));
-}
-
-static inline void reset_viewport(void) {
- set_viewport(0, 0, GDISP.Width, GDISP.Height);
-}
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/* ---- Required Routines ---- */
-/*
- The following 2 routines are required.
- All other routines are optional.
-*/
-
-/**
- * @brief Low level GDISP driver initialization.
- *
- * @notapi
- */
-bool_t gdisp_lld_init(void) {
- /* Initialise your display */
- init_board();
-
- // Hardware reset
- setpin_reset(TRUE);
- delayms(1);
- setpin_reset(FALSE);
- delayms(5);
-
- // Get the bus for the following initialisation commands
- acquire_bus();
-
- /* Start Initial Sequence ----------------------------------------------------*/
- write_reg(HX8347D_REG_STBAH, 0x00); /* Reset Power Control 1 */
- write_reg(HX8347D_REG_STBAL, 0x20); /* Power Control 2 */
- write_reg(HX8347D_REG_PTBAH, 0x0C); /* Power Control 1 */
- write_reg(HX8347D_REG_PTBAL, 0xC4); /* Power Control 2 */
- write_reg(HX8347D_REG_OPONN, 0x40); /* Source OPON_N */
- write_reg(HX8347D_REG_OPONI, 0x38); /* Source OPON_I */
- write_reg(HX8347D_REG_DC2, 0xA3); /* Display Control 2 */
-
- /* Power On sequence ---------------------------------------------------------*/
- write_reg(HX8347D_REG_PWC2, 0x1B); /* Power Control 2 */
- write_reg(HX8347D_REG_PWC1, 0x01); /* Power Control 1 */
- write_reg(HX8347D_REG_VMH, 0x2F); /* Vcom Control 2 */
- write_reg(HX8347D_REG_VML, 0x57); /* Vcom Control 3 */
- write_reg(HX8347D_REG_VMF, 0x8D); /* Vcom Control 1 */
-
- /* Gamma settings -----------------------------------------------------------*/
- write_reg(HX8347D_REG_VRP0,0x01); // default setup
- write_reg(HX8347D_REG_VRP1,0x0e); //
- write_reg(HX8347D_REG_VRP2,0x11); //
- write_reg(HX8347D_REG_VRP3,0x1a); //
- write_reg(HX8347D_REG_VRP4,0x18); //
- write_reg(HX8347D_REG_VRP5,0x24); //
- write_reg(HX8347D_REG_PRP0,0x15); //
- write_reg(HX8347D_REG_PRP1,0x65); //
- write_reg(HX8347D_REG_PKP0,0x0b); //
- write_reg(HX8347D_REG_PKP1,0x18); //
- write_reg(HX8347D_REG_PKP2,0x19); //
- write_reg(HX8347D_REG_PKP3,0x1a); //
- write_reg(HX8347D_REG_PKP4,0x18); //
- write_reg(HX8347D_REG_VRN0,0x1b); //
- write_reg(HX8347D_REG_VRN1,0x27); //
- write_reg(HX8347D_REG_VRN2,0x25); //
- write_reg(HX8347D_REG_VRN3,0x2e); //
- write_reg(HX8347D_REG_VRN4,0x31); //
- write_reg(HX8347D_REG_VRN5,0x3e); //
- write_reg(HX8347D_REG_PRN0,0x1a); //
- write_reg(HX8347D_REG_PRN1,0x6a); //
- write_reg(HX8347D_REG_PKN0,0x07); //
- write_reg(HX8347D_REG_PKN1,0x05); //
- write_reg(HX8347D_REG_PKN2,0x06); //
- write_reg(HX8347D_REG_PKN3,0x0b); //
- write_reg(HX8347D_REG_PKN4,0x14); //
- write_reg(HX8347D_REG_CGM,0xcc); //
-
- /* Power + Osc ---------------------------------------------------------------*/
- write_reg(HX8347D_REG_OSCCH, 0x36); /* OSC Control 1 */
- write_reg(HX8347D_REG_OSCCL, 0x01); /* OSC Control 2 */
- write_reg(HX8347D_REG_DMODE, 0x00); /* Display Mode Control */
- write_reg(HX8347D_REG_PWC6, 0x88); /* Power Control 6 */
- delayms(5); /* Delay 5 ms */
- write_reg(HX8347D_REG_PWC6, 0x80); /* Power Control 6 */
- delayms(5); /* Delay 5 ms */
- write_reg(HX8347D_REG_PWC6, 0x90); /* Power Control 6 */
- delayms(5); /* Delay 5 ms */
- write_reg(HX8347D_REG_PWC6, 0xD0); /* Power Control 6 */
- delayms(5); /* Delay 5 ms */
- write_reg(HX8347D_REG_COLMOD, 0x05); /* Colmod 16Bit/Pixel */
- write_reg(HX8347D_REG_PCH, 0x00); /* Panel Characteristic */
- write_reg(HX8347D_REG_DC3, 0x38); /* Display Control 3 */
- delayms(40);
- write_reg(HX8347D_REG_DC3, 0x3C); /* Display Control 3 */
- write_reg(HX8347D_REG_MAC, 0x08); /* Memory access control */
-
- write_reg(HX8347D_REG_SCL, 0x00);
- write_reg(HX8347D_REG_SCH, 0x00);
- write_reg(HX8347D_REG_ECL, 0xef);
- write_reg(HX8347D_REG_ECH, 0x00);
- write_reg(HX8347D_REG_SPL, 0x00);
- write_reg(HX8347D_REG_SPH, 0x00);
- write_reg(HX8347D_REG_EPL, 0x3f);
- write_reg(HX8347D_REG_EPH, 0x01);
-
- // Release the bus
- release_bus();
-
- /* Turn on the backlight */
- set_backlight(GDISP_INITIAL_BACKLIGHT);
-
- /* Initialise the GDISP structure */
- GDISP.Width = GDISP_SCREEN_WIDTH;
- GDISP.Height = GDISP_SCREEN_HEIGHT;
- GDISP.Orientation = GDISP_ROTATE_0;
- GDISP.Powermode = powerOn;
- GDISP.Backlight = GDISP_INITIAL_BACKLIGHT;
- GDISP.Contrast = GDISP_INITIAL_CONTRAST;
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- GDISP.clipx0 = 0;
- GDISP.clipy0 = 0;
- GDISP.clipx1 = GDISP.Width;
- GDISP.clipy1 = GDISP.Height;
- #endif
- return TRUE;
-}
-
-/**
- * @brief Draws a pixel on the display.
- *
- * @param[in] x X location of the pixel
- * @param[in] y Y location of the pixel
- * @param[in] color The color of the pixel
- *
- * @notapi
- */
-void gdisp_lld_draw_pixel(coord_t x, coord_t y, color_t color) {
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- if (x < GDISP.clipx0 || y < GDISP.clipy0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
- #endif
-
- acquire_bus();
- set_cursor(x, y);
- write_ram((color >> 8) & 0xFF, color & 0xFF);
- release_bus();
-}
-
-/* ---- Optional Routines ---- */
-/*
- All the below routines are optional.
- Defining them will increase speed but everything
- will work if they are not defined.
- If you are not using a routine - turn it off using
- the appropriate GDISP_HARDWARE_XXXX macro.
- Don't bother coding for obvious similar routines if
- there is no performance penalty as the emulation software
- makes a good job of using similar routines.
- eg. If gfillarea() is defined there is little
- point in defining clear() unless the
- performance bonus is significant.
- For good performance it is suggested to implement
- fillarea() and blitarea().
-*/
-
-#if GDISP_HARDWARE_CLEARS || defined(__DOXYGEN__)
- /**
- * @brief Clear the display.
- * @note Optional - The high level driver can emulate using software.
- *
- * @param[in] color The color of the pixel
- *
- * @notapi
- */
- void gdisp_lld_clear(color_t color) {
- unsigned i;
-
- acquire_bus();
- reset_viewport();
- stream_start();
- for(i = 0; i < GDISP_SCREEN_WIDTH * GDISP_SCREEN_HEIGHT; i++)
- write_ram16(color);
- stream_stop();
- release_bus();
- }
-#endif
-
-#if GDISP_HARDWARE_FILLS || defined(__DOXYGEN__)
- /**
- * @brief Fill an area with a color.
- * @note Optional - The high level driver can emulate using software.
- *
- * @param[in] x, y The start filled area
- * @param[in] cx, cy The width and height to be filled
- * @param[in] color The color of the fill
- *
- * @notapi
- */
- void gdisp_lld_fill_area(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
- unsigned i, area;
-
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; }
- if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; }
- if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
- if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
- if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
- #endif
-
- area = cx*cy;
-
- acquire_bus();
- set_viewport(x, y, cx, cy);
- stream_start();
- for(i = 0; i < area; i++)
- write_ram16(color);
- stream_stop();
- release_bus();
- }
-#endif
-
-#if GDISP_HARDWARE_BITFILLS || defined(__DOXYGEN__)
- /**
- * @brief Fill an area with a bitmap.
- * @note Optional - The high level driver can emulate using software.
- *
- * @param[in] x, y The start filled area
- * @param[in] cx, cy The width and height to be filled
- * @param[in] srcx, srcy The bitmap position to start the fill from
- * @param[in] srccx The width of a line in the bitmap.
- * @param[in] buffer The pixels to use to fill the area.
- *
- * @notapi
- */
- void gdisp_lld_blit_area_ex(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx, coord_t srcy, coord_t srccx, const pixel_t *buffer) {
- coord_t endx, endy;
- unsigned lg;
-
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; srcx += GDISP.clipx0 - x; x = GDISP.clipx0; }
- if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; srcy += GDISP.clipy0 - y; y = GDISP.clipy0; }
- if (srcx+cx > srccx) cx = srccx - srcx;
- if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
- if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
- if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
- #endif
-
- acquire_bus();
- set_viewport(x, y, cx, cy);
- stream_start();
-
- endx = srcx + cx;
- endy = y + cy;
- lg = srccx - cx;
- buffer += srcx + srcy * srccx;
- for(; y < endy; y++, buffer += lg)
- for(x=srcx; x < endx; x++)
- write_data(*buffer++);
- stream_stop();
- release_bus();
- }
-#endif
-
-#if (GDISP_NEED_PIXELREAD && GDISP_HARDWARE_PIXELREAD) || defined(__DOXYGEN__)
- /**
- * @brief Get the color of a particular pixel.
- * @note Optional.
- * @note If x,y is off the screen, the result is undefined.
- *
- * @param[in] x, y The pixel to be read
- *
- * @notapi
- */
- color_t gdisp_lld_get_pixel_color(coord_t x, coord_t y) {
- color_t color;
-
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- if (x < 0 || x >= GDISP.Width || y < 0 || y >= GDISP.Height) return 0;
- #endif
-}
-#endif
-
-#if (GDISP_NEED_SCROLL && GDISP_HARDWARE_SCROLL) || defined(__DOXYGEN__)
- /**
- * @brief Scroll vertically a section of the screen.
- * @note Optional.
- * @note If x,y + cx,cy is off the screen, the result is undefined.
- * @note If lines is >= cy, it is equivelent to a area fill with bgcolor.
- *
- * @param[in] x, y The start of the area to be scrolled
- * @param[in] cx, cy The size of the area to be scrolled
- * @param[in] lines The number of lines to scroll (Can be positive or negative)
- * @param[in] bgcolor The color to fill the newly exposed area.
- *
- * @notapi
- */
- void gdisp_lld_vertical_scroll(coord_t x, coord_t y, coord_t cx, coord_t cy, int lines, color_t bgcolor) {
- static color_t buf[((GDISP_SCREEN_HEIGHT > GDISP_SCREEN_WIDTH ) ? GDISP_SCREEN_HEIGHT : GDISP_SCREEN_WIDTH)];
- coord_t row0, row1;
- unsigned i, abslines, j;
- static int gap;
-
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; }
- if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; }
- if (!lines || cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
- if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
- if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
- #endif
-
- }
-#endif
-
-#if (GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL) || defined(__DOXYGEN__)
- /**
- * @brief Driver Control
- * @details Unsupported control codes are ignored.
- * @note The value parameter should always be typecast to (void *).
- * @note There are some predefined and some specific to the low level driver.
- * @note GDISP_CONTROL_POWER - Takes a gdisp_powermode_t
- * GDISP_CONTROL_ORIENTATION - Takes a gdisp_orientation_t
- * GDISP_CONTROL_BACKLIGHT - Takes an int from 0 to 100. For a driver
- * that only supports off/on anything other
- * than zero is on.
- *
- * @param[in] what What to do.
- * @param[in] value The value to use (always cast to a void *).
- *
- * @notapi
- */
- void gdisp_lld_control(unsigned what, void *value) {
- switch(what) {
- case GDISP_CONTROL_ORIENTATION:
- if (GDISP.Orientation == (gdisp_orientation_t)value)
- return;
- switch((gdisp_orientation_t)value) {
- case GDISP_ROTATE_0:
- acquire_bus();
- write_reg(HX8347D_REG_MAC, 0x08); /* Memory access control */
- write_reg(HX8347D_REG_ECL, 0xef);
- write_reg(HX8347D_REG_ECH, 0x00);
- write_reg(HX8347D_REG_EPL, 0x3f);
- write_reg(HX8347D_REG_EPH, 0x01);
- release_bus();
- GDISP.Height = GDISP_SCREEN_HEIGHT;
- GDISP.Width = GDISP_SCREEN_WIDTH;
- break;
-
- case GDISP_ROTATE_90:
- acquire_bus();
- write_reg(HX8347D_REG_MAC, 0x68); /* Memory access control */
- write_reg(HX8347D_REG_ECL, 0x3f);
- write_reg(HX8347D_REG_ECH, 0x01);
- write_reg(HX8347D_REG_EPL, 0xef);
- write_reg(HX8347D_REG_EPH, 0x00);
- release_bus();
- GDISP.Height = GDISP_SCREEN_WIDTH;
- GDISP.Width = GDISP_SCREEN_HEIGHT;
- break;
-
- case GDISP_ROTATE_180:
- acquire_bus();
- write_reg(HX8347D_REG_MAC, 0xc8); /* Memory access control */
- write_reg(HX8347D_REG_ECL, 0xef);
- write_reg(HX8347D_REG_ECH, 0x00);
- write_reg(HX8347D_REG_EPL, 0x3f);
- write_reg(HX8347D_REG_EPH, 0x01);
- release_bus();
- GDISP.Height = GDISP_SCREEN_HEIGHT;
- GDISP.Width = GDISP_SCREEN_WIDTH;
- break;
-
- case GDISP_ROTATE_270:
- acquire_bus();
- write_reg(HX8347D_REG_MAC, 0xa8); /* Memory access control */
- write_reg(HX8347D_REG_ECL, 0x3f);
- write_reg(HX8347D_REG_ECH, 0x01);
- write_reg(HX8347D_REG_EPL, 0xef);
- write_reg(HX8347D_REG_EPH, 0x00);
- release_bus();
- GDISP.Height = GDISP_SCREEN_WIDTH;
- GDISP.Width = GDISP_SCREEN_HEIGHT;
- break;
-
- default:
- return;
- }
-
- #if GDISP_NEED_CLIP || GDISP_NEED_VALIDATION
- GDISP.clipx0 = 0;
- GDISP.clipy0 = 0;
- GDISP.clipx1 = GDISP.Width;
- GDISP.clipy1 = GDISP.Height;
- #endif
- GDISP.Orientation = (gdisp_orientation_t)value;
- return;
-
- case GDISP_CONTROL_BACKLIGHT:
- if ((unsigned)value > 100)
- value = (void *)100;
- set_backlight((unsigned)value);
- GDISP.Backlight = (unsigned)value;
- return;
-
- default:
- return;
- }
- }
-#endif
-
-#endif /* GFX_USE_GDISP */
-/** @} */
diff --git a/drivers/gdisp/HX8347D/gdisp_lld.mk b/drivers/gdisp/HX8347D/gdisp_lld.mk
index fed905e1..581e53e7 100644
--- a/drivers/gdisp/HX8347D/gdisp_lld.mk
+++ b/drivers/gdisp/HX8347D/gdisp_lld.mk
@@ -1,5 +1,2 @@
-# List the required driver.
-GFXSRC += $(GFXLIB)/drivers/gdisp/HX8347D/gdisp_lld.c
-
-# Required include directories
GFXINC += $(GFXLIB)/drivers/gdisp/HX8347D
+GFXSRC += $(GFXLIB)/drivers/gdisp/HX8347D/gdisp_lld_HX8347D.c
diff --git a/drivers/gdisp/HX8347D/gdisp_lld_HX8347D.c b/drivers/gdisp/HX8347D/gdisp_lld_HX8347D.c
new file mode 100644
index 00000000..4514b495
--- /dev/null
+++ b/drivers/gdisp/HX8347D/gdisp_lld_HX8347D.c
@@ -0,0 +1,236 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/HX8347D/gdisp_lld.c
+ * @brief GDISP Graphics Driver subsystem low level driver source for the HX8347D display.
+ */
+
+#include "gfx.h"
+
+#if GFX_USE_GDISP
+
+#define GDISP_DRIVER_VMT GDISPVMT_HX8347D
+#include "../drivers/gdisp/HX8347D/gdisp_lld_config.h"
+#include "gdisp/lld/gdisp_lld.h"
+
+#include "board_HX8347D.h"
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+#ifndef GDISP_SCREEN_HEIGHT
+ #define GDISP_SCREEN_HEIGHT 320
+#endif
+#ifndef GDISP_SCREEN_WIDTH
+ #define GDISP_SCREEN_WIDTH 240
+#endif
+#ifndef GDISP_INITIAL_CONTRAST
+ #define GDISP_INITIAL_CONTRAST 50
+#endif
+#ifndef GDISP_INITIAL_BACKLIGHT
+ #define GDISP_INITIAL_BACKLIGHT 100
+#endif
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+#include "../drivers/gdisp/HX8347D/HX8347D.h"
+
+#define write_reg(g, reg, data) { write_index(g, reg); write_data(g, data); }
+
+static inline void set_viewport(GDisplay* g) {
+ write_reg(g, HX8347D_REG_SCL, g->p.x);
+ write_reg(g, HX8347D_REG_SCH, g->p.x >> 8);
+ write_reg(g, HX8347D_REG_ECL, g->p.x + g->p.cx -1);
+ write_reg(g, HX8347D_REG_ECH, (g->p.x + g->p.cx -1) >> 8);
+ write_reg(g, HX8347D_REG_SPL, g->p.y);
+ write_reg(g, HX8347D_REG_SPH, g->p.y >> 8);
+ write_reg(g, HX8347D_REG_EPL, g->p.y + g->p.cy -1);
+ write_reg(g, HX8347D_REG_EPH, (g->p.y + g->p.cy -1) >> 8);
+ write_index(g, HX8347D_REG_SRAMWC);
+}
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
+ // No private area for this controller
+ g->priv = 0;
+
+ // Initialise the board interface
+ init_board(g);
+
+ // Hardware reset
+ setpin_reset(g, TRUE);
+ gfxSleepMilliseconds(1);
+ setpin_reset(g, FALSE);
+ gfxSleepMilliseconds(5);
+
+ // Get the bus for the following initialisation commands
+ acquire_bus(g);
+
+ /* Start Initial Sequence ----------------------------------------------------*/
+ write_reg(g, HX8347D_REG_STBAH, 0x00); /* Reset Power Control 1 */
+ write_reg(g, HX8347D_REG_STBAL, 0x20); /* Power Control 2 */
+ write_reg(g, HX8347D_REG_PTBAH, 0x0C); /* Power Control 1 */
+ write_reg(g, HX8347D_REG_PTBAL, 0xC4); /* Power Control 2 */
+ write_reg(g, HX8347D_REG_OPONN, 0x40); /* Source OPON_N */
+ write_reg(g, HX8347D_REG_OPONI, 0x38); /* Source OPON_I */
+ write_reg(g, HX8347D_REG_DC2, 0xA3); /* Display Control 2 */
+
+ /* Power On sequence ---------------------------------------------------------*/
+ write_reg(g, HX8347D_REG_PWC2, 0x1B); /* Power Control 2 */
+ write_reg(g, HX8347D_REG_PWC1, 0x01); /* Power Control 1 */
+ write_reg(g, HX8347D_REG_VMH, 0x2F); /* Vcom Control 2 */
+ write_reg(g, HX8347D_REG_VML, 0x57); /* Vcom Control 3 */
+ write_reg(g, HX8347D_REG_VMF, 0x8D); /* Vcom Control 1 */
+
+ /* Gamma settings -----------------------------------------------------------*/
+ write_reg(g, HX8347D_REG_VRP0, 0x01); // default setup
+ write_reg(g, HX8347D_REG_VRP1, 0x0e); //
+ write_reg(g, HX8347D_REG_VRP2, 0x11); //
+ write_reg(g, HX8347D_REG_VRP3, 0x1a); //
+ write_reg(g, HX8347D_REG_VRP4, 0x18); //
+ write_reg(g, HX8347D_REG_VRP5, 0x24); //
+ write_reg(g, HX8347D_REG_PRP0, 0x15); //
+ write_reg(g, HX8347D_REG_PRP1, 0x65); //
+ write_reg(g, HX8347D_REG_PKP0, 0x0b); //
+ write_reg(g, HX8347D_REG_PKP1, 0x18); //
+ write_reg(g, HX8347D_REG_PKP2, 0x19); //
+ write_reg(g, HX8347D_REG_PKP3, 0x1a); //
+ write_reg(g, HX8347D_REG_PKP4, 0x18); //
+ write_reg(g, HX8347D_REG_VRN0, 0x1b); //
+ write_reg(g, HX8347D_REG_VRN1, 0x27); //
+ write_reg(g, HX8347D_REG_VRN2, 0x25); //
+ write_reg(g, HX8347D_REG_VRN3, 0x2e); //
+ write_reg(g, HX8347D_REG_VRN4, 0x31); //
+ write_reg(g, HX8347D_REG_VRN5, 0x3e); //
+ write_reg(g, HX8347D_REG_PRN0, 0x1a); //
+ write_reg(g, HX8347D_REG_PRN1, 0x6a); //
+ write_reg(g, HX8347D_REG_PKN0, 0x07); //
+ write_reg(g, HX8347D_REG_PKN1, 0x05); //
+ write_reg(g, HX8347D_REG_PKN2, 0x06); //
+ write_reg(g, HX8347D_REG_PKN3, 0x0b); //
+ write_reg(g, HX8347D_REG_PKN4, 0x14); //
+ write_reg(g, HX8347D_REG_CGM, 0xcc); //
+
+ /* Power + Osc ---------------------------------------------------------------*/
+ write_reg(g, HX8347D_REG_OSCCH, 0x36); /* OSC Control 1 */
+ write_reg(g, HX8347D_REG_OSCCL, 0x01); /* OSC Control 2 */
+ write_reg(g, HX8347D_REG_DMODE, 0x00); /* Display Mode Control */
+ write_reg(g, HX8347D_REG_PWC6, 0x88); /* Power Control 6 */
+ gfxSleepMilliseconds(5); /* Delay 5 ms */
+ write_reg(g, HX8347D_REG_PWC6, 0x80); /* Power Control 6 */
+ gfxSleepMilliseconds(5); /* Delay 5 ms */
+ write_reg(g, HX8347D_REG_PWC6, 0x90); /* Power Control 6 */
+ gfxSleepMilliseconds(5); /* Delay 5 ms */
+ write_reg(g, HX8347D_REG_PWC6, 0xD0); /* Power Control 6 */
+ gfxSleepMilliseconds(5); /* Delay 5 ms */
+ write_reg(g, HX8347D_REG_COLMOD, 0x05); /* Colmod 16Bit/Pixel */
+ write_reg(g, HX8347D_REG_PCH, 0x00); /* Panel Characteristic */
+ write_reg(g, HX8347D_REG_DC3, 0x38); /* Display Control 3 */
+ gfxSleepMilliseconds(40); /* Delay 40 ms */
+ write_reg(g, HX8347D_REG_DC3, 0x3C); /* Display Control 3 */
+ write_reg(g, HX8347D_REG_MAC, 0x08); /* Memory access control */
+
+ // Finish Init
+ post_init_board(g);
+
+ // Release the bus
+ release_bus(g);
+
+ /* Turn on the backlight */
+ set_backlight(g, GDISP_INITIAL_BACKLIGHT);
+
+ /* Initialise the GDISP structure */
+ g->g.Width = GDISP_SCREEN_WIDTH;
+ g->g.Height = GDISP_SCREEN_HEIGHT;
+ g->g.Orientation = GDISP_ROTATE_0;
+ g->g.Powermode = powerOn;
+ g->g.Backlight = GDISP_INITIAL_BACKLIGHT;
+ g->g.Contrast = GDISP_INITIAL_CONTRAST;
+ return TRUE;
+}
+
+#if GDISP_HARDWARE_STREAM_WRITE
+ LLDSPEC void gdisp_lld_write_start(GDisplay *g) {
+ acquire_bus(g);
+ set_viewport(g);
+ busmode16(g);
+ }
+ LLDSPEC void gdisp_lld_write_color(GDisplay *g) {
+ write_ram16(g, COLOR2NATIVE(g->p.color));
+ }
+ LLDSPEC void gdisp_lld_write_stop(GDisplay *g) {
+ busmode8(g);
+ release_bus(g);
+ }
+#endif
+
+#if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL
+ LLDSPEC void gdisp_lld_control(GDisplay *g) {
+ switch(g->p.x) {
+ case GDISP_CONTROL_ORIENTATION:
+ if (g->g.Orientation == (orientation_t)g->p.ptr)
+ return;
+ switch((orientation_t)g->p.ptr) {
+ case GDISP_ROTATE_0:
+ acquire_bus(g);
+ write_reg(g, HX8347D_REG_MAC, 0x08); /* Memory access control */
+ release_bus(g);
+ g->g.Height = GDISP_SCREEN_HEIGHT;
+ g->g.Width = GDISP_SCREEN_WIDTH;
+ break;
+
+ case GDISP_ROTATE_90:
+ acquire_bus(g);
+ write_reg(g, HX8347D_REG_MAC, 0x68); /* Memory access control */
+ release_bus(g);
+ g->g.Height = GDISP_SCREEN_WIDTH;
+ g->g.Width = GDISP_SCREEN_HEIGHT;
+ break;
+
+ case GDISP_ROTATE_180:
+ acquire_bus(g);
+ write_reg(g, HX8347D_REG_MAC, 0xc8); /* Memory access control */
+ release_bus(g);
+ g->g.Height = GDISP_SCREEN_HEIGHT;
+ g->g.Width = GDISP_SCREEN_WIDTH;
+ break;
+
+ case GDISP_ROTATE_270:
+ acquire_bus(g);
+ write_reg(g, HX8347D_REG_MAC, 0xa8); /* Memory access control */
+ release_bus(g);
+ g->g.Height = GDISP_SCREEN_WIDTH;
+ g->g.Width = GDISP_SCREEN_HEIGHT;
+ break;
+
+ default:
+ return;
+ }
+ g->g.Orientation = (orientation_t)g->p.ptr;
+ return;
+
+ case GDISP_CONTROL_BACKLIGHT:
+ if ((unsigned)g->p.ptr > 100)
+ g->p.ptr = (void *)100;
+ set_backlight(g, (unsigned)g->p.ptr);
+ g->g.Backlight = (unsigned)g->p.ptr;
+ return;
+
+ default:
+ return;
+ }
+ }
+#endif
+
+#endif /* GFX_USE_GDISP */
diff --git a/drivers/gdisp/HX8347D/gdisp_lld_board_st_stm32f4_discovery.h b/drivers/gdisp/HX8347D/gdisp_lld_board_st_stm32f4_discovery.h
deleted file mode 100644
index 984b92dd..00000000
--- a/drivers/gdisp/HX8347D/gdisp_lld_board_st_stm32f4_discovery.h
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * This file is subject to the terms of the GFX License. If a copy of
- * the license was not distributed with this file, you can obtain one at:
- *
- * http://ugfx.org/license.html
- */
-
-/**
- * @file drivers/gdisp/HX8347D/gdisp_lld_board_st_stm32f4_discovery.h
- * @brief GDISP Graphic Driver subsystem board SPI interface for the HX8347D display.
- *
- * @addtogroup GDISP
- * @{
- */
-
-#ifndef _GDISP_LLD_BOARD_H
-#define _GDISP_LLD_BOARD_H
-
-#define SET_RST palSetPad(GPIOB, 8);
-#define CLR_RST palClearPad(GPIOB, 8);
-
-/* PWM configuration structure. We use timer 4 channel 2 (orange LED on board). */
-static const PWMConfig pwmcfg = {
- 1000000, /* 1 MHz PWM clock frequency. */
- 100, /* PWM period is 100 cycles. */
- NULL,
- {
- {PWM_OUTPUT_ACTIVE_HIGH, NULL},
- {PWM_OUTPUT_ACTIVE_HIGH, NULL},
- {PWM_OUTPUT_ACTIVE_HIGH, NULL},
- {PWM_OUTPUT_ACTIVE_HIGH, NULL}
- },
- 0
-};
-
-/*
- * SPI1 configuration structure.
- * Speed 42MHz, CPHA=0, CPOL=0, 8bits frames, MSb transmitted first.
- * The slave select line is the pin 4 on the port GPIOA.
- */
-static const SPIConfig spi1cfg1 = {
- NULL,
- /* HW dependent part.*/
- GPIOA,
- 4,
- 0 //SPI_CR1_BR_0
-};
-
-/*
- * SPI1 configuration structure.
- * Speed 42MHz, CPHA=0, CPOL=0, 16bits frames, MSb transmitted first.
- * The slave select line is the pin 4 on the port GPIOA.
- */
-static const SPIConfig spi1cfg2 = {
- NULL,
- /* HW dependent part.*/
- GPIOA,
- 4,
- SPI_CR1_DFF //SPI_CR1_BR_0
-};
-
-/**
- * @brief Initialise the board for the display.
- * @notes This board definition uses GPIO and assumes exclusive access to these GPIO pins
- *
- * @notapi
- */
-static inline void init_board(void) {
-
- /* Display backlight control */
- /* TIM4 is an alternate function 2 (AF2) */
- pwmStart(&PWMD4, &pwmcfg);
- palSetPadMode(GPIOD, 13, PAL_MODE_ALTERNATE(2));
- pwmEnableChannel(&PWMD4, 1, 100);
-
- palSetPadMode(GPIOB, 8, PAL_MODE_OUTPUT_PUSHPULL |
- PAL_STM32_OSPEED_HIGHEST); /* RST */
- palSetPadMode(GPIOB, 9, PAL_MODE_OUTPUT_PUSHPULL |
- PAL_STM32_OSPEED_HIGHEST); /* RS */
- /*
- * Initializes the SPI driver 1. The SPI1 signals are routed as follow:
- * PB12 - NSS.
- * PB13 - SCK.
- * PB14 - MISO.
- * PB15 - MOSI.
- */
- spiStart(&SPID1, &spi1cfg1);
- palSetPad(GPIOA, 4);
- palSetPadMode(GPIOA, 4, PAL_MODE_OUTPUT_PUSHPULL |
- PAL_STM32_OSPEED_HIGHEST); /* NSS. */
- palSetPadMode(GPIOA, 5, PAL_MODE_ALTERNATE(5) |
- PAL_STM32_OSPEED_HIGHEST); /* SCK. */
- palSetPadMode(GPIOA, 6, PAL_MODE_ALTERNATE(5)); /* MISO. */
- palSetPadMode(GPIOA, 7, PAL_MODE_ALTERNATE(5) |
- PAL_STM32_OSPEED_HIGHEST); /* MOSI. */
-
-}
-
-/**
- * @brief Set or clear the lcd reset pin.
- *
- * @param[in] state TRUE = lcd in reset, FALSE = normal operation
- *
- * @notapi
- */
-static inline void setpin_reset(bool_t state) {
- if (state) {
- CLR_RST;
- } else {
- SET_RST;
- }
-}
-
-/**
- * @brief Set the lcd back-light level.
- *
- * @param[in] percent 0 to 100%
- *
- * @notapi
- */
-static inline void set_backlight(uint8_t percent) {
- pwmEnableChannel(&PWMD4, 1, percent);
-}
-
-/**
- * @brief Take exclusive control of the bus
- * @note Not needed, not implemented
- *
- * @notapi
- */
-static inline void acquire_bus(void) {
- spiAcquireBus(&SPID1);
-}
-
-/**
- * @brief Release exclusive control of the bus
- * @note Not needed, not implemented
- *
- * @notapi
- */
-static inline void release_bus(void) {
- spiReleaseBus(&SPID1);
-}
-
-/**
- * @brief Send data to the index register.
- *
- * @param[in] index The index register to set
- *
- * @notapi
- */
-static inline void write_index(uint8_t cmd) {
- palClearPad(GPIOB, 9);
- palClearPad(GPIOA, 4);
- while((SPI1->SR & SPI_SR_TXE) == 0);
- SPI1->DR = cmd;
- while(((SPI1->SR & SPI_SR_TXE) == 0) || ((SPI1->SR & SPI_SR_BSY) != 0));
- palSetPad(GPIOB, 9);
-}
-
-/**
- * @brief Send data to the lcd.
- *
- * @param[in] data The data to send
- *
- * @notapi
- */
-static inline void write_data(uint8_t data) {
- SPI1->DR = data;
- while(((SPI1->SR & SPI_SR_TXE) == 0) || ((SPI1->SR & SPI_SR_BSY) != 0));
- palSetPad(GPIOA, 4);
-}
-
-static inline void write_ram8(uint8_t data1, uint8_t data2) {
- SPI1->DR = data1;
- while((SPI1->SR & SPI_SR_TXE) == 0);
- SPI1->DR = data2;
- while(((SPI1->SR & SPI_SR_TXE) == 0) || ((SPI1->SR & SPI_SR_BSY) != 0));
- palSetPad(GPIOA, 4);
-}
-
-static inline void write_ram16(uint16_t data) {
- while((SPI1->SR & SPI_SR_TXE) == 0);
- SPI1->DR = data;
-}
-
-#if GDISP_HARDWARE_READPIXEL || defined(__DOXYGEN__)
-/**
- * @brief Read data from the lcd.
- *
- * @return The data from the lcd
- * @note The chip select may need to be asserted/de-asserted
- * around the actual spi read
- *
- * @notapi
- */
-static inline uint16_t read_data(void) {
-}
-#endif
-
-#endif /* _GDISP_LLD_BOARD_H */
-/** @} */
diff --git a/drivers/gdisp/HX8347D/gdisp_lld_board_template.h b/drivers/gdisp/HX8347D/gdisp_lld_board_template.h
deleted file mode 100644
index 295a7997..00000000
--- a/drivers/gdisp/HX8347D/gdisp_lld_board_template.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * This file is subject to the terms of the GFX License. If a copy of
- * the license was not distributed with this file, you can obtain one at:
- *
- * http://ugfx.org/license.html
- */
-
-/**
- * @file drivers/gdisp/HX8347D/gdisp_lld_board_template.h
- * @brief GDISP Graphic Driver subsystem board SPI interface for the HX8347D display.
- *
- * @addtogroup GDISP
- * @{
- */
-
-#ifndef _GDISP_LLD_BOARD_H
-#define _GDISP_LLD_BOARD_H
-
-/**
- * @brief Initialise the board for the display.
- * @notes This board definition uses GPIO and assumes exclusive access to these GPIO pins
- *
- * @notapi
- */
-static inline void init_board(void) {
-
-}
-
-/**
- * @brief Set or clear the lcd reset pin.
- *
- * @param[in] state TRUE = lcd in reset, FALSE = normal operation
- *
- * @notapi
- */
-static inline void setpin_reset(bool_t state) {
-
-}
-
-/**
- * @brief Set the lcd back-light level.
- *
- * @param[in] percent 0 to 100%
- *
- * @notapi
- */
-static inline void set_backlight(uint8_t percent) {
-
-}
-
-/**
- * @brief Take exclusive control of the bus
- * @note Not needed, not implemented
- *
- * @notapi
- */
-static inline void acquire_bus(void) {
-
-}
-
-/**
- * @brief Release exclusive control of the bus
- * @note Not needed, not implemented
- *
- * @notapi
- */
-static inline void release_bus(void) {
-
-}
-
-/**
- * @brief Send data to the index register.
- *
- * @param[in] index The index register to set
- *
- * @notapi
- */
-static inline void write_index(uint8_t cmd) {
-
-}
-
-/**
- * @brief Send data to the lcd.
- *
- * @param[in] data The data to send
- *
- * @notapi
- */
-static inline void write_data(uint8_t data) {
-
-
-
-}
-
-static inline void write_ram8(uint8_t data1, uint8_t data2) {
-
-}
-
-static inline void write_ram16(uint16_t data) {
-
-}
-
-#if GDISP_HARDWARE_READPIXEL || defined(__DOXYGEN__)
-/**
- * @brief Read data from the lcd.
- *
- * @return The data from the lcd
- * @note The chip select may need to be asserted/de-asserted
- * around the actual spi read
- *
- * @notapi
- */
-static inline uint16_t read_data(void) {
-
-}
-#endif
-
-#endif /* _GDISP_LLD_BOARD_H */
-/** @} */
-
diff --git a/drivers/gdisp/HX8347D/gdisp_lld_config.h b/drivers/gdisp/HX8347D/gdisp_lld_config.h
index 7bf47ade..ab4c8639 100644
--- a/drivers/gdisp/HX8347D/gdisp_lld_config.h
+++ b/drivers/gdisp/HX8347D/gdisp_lld_config.h
@@ -22,16 +22,10 @@
/* Driver hardware support. */
/*===========================================================================*/
-#define GDISP_DRIVER_NAME "HX8347D"
-
-#define GDISP_HARDWARE_CLEARS TRUE
-#define GDISP_HARDWARE_FILLS TRUE
-#define GDISP_HARDWARE_BITFILLS TRUE
-#define GDISP_HARDWARE_SCROLL FALSE
-#define GDISP_HARDWARE_PIXELREAD FALSE
+#define GDISP_HARDWARE_STREAM_WRITE TRUE
#define GDISP_HARDWARE_CONTROL TRUE
-#define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_RGB565
+#define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_RGB565
#endif /* GFX_USE_GDISP */
diff --git a/drivers/gdisp/ILI9320/board_ILI9320_template.h b/drivers/gdisp/ILI9320/board_ILI9320_template.h
new file mode 100644
index 00000000..6f5ad16d
--- /dev/null
+++ b/drivers/gdisp/ILI9320/board_ILI9320_template.h
@@ -0,0 +1,157 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/ILI9320/board_ILI9320_template.h
+ * @brief GDISP Graphic Driver subsystem board interface for the ILI9320 display.
+ *
+ * @addtogroup GDISP
+ * @{
+ */
+
+#ifndef GDISP_LLD_BOARD_H
+#define GDISP_LLD_BOARD_H
+
+/**
+ * @brief Initialise the board for the display.
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @note Set the g->board member to whatever is appropriate. For multiple
+ * displays this might be a pointer to the appropriate register set.
+ *
+ * @notapi
+ */
+static inline void init_board(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief After the initialisation.
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void post_init_board(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Set or clear the lcd reset pin.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] state TRUE = lcd in reset, FALSE = normal operation
+ *
+ * @notapi
+ */
+static inline void setpin_reset(GDisplay *g, bool_t state) {
+ (void) g;
+ (void) state;
+}
+
+/**
+ * @brief Set the lcd back-light level.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] percent 0 to 100%
+ *
+ * @notapi
+ */
+static inline void set_backlight(GDisplay *g, uint8_t percent) {
+ (void) g;
+ (void) percent;
+}
+
+/**
+ * @brief Take exclusive control of the bus
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void acquire_bus(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Release exclusive control of the bus
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void release_bus(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Send data to the index register.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] index The index register to set
+ *
+ * @notapi
+ */
+static inline void write_index(GDisplay *g, uint16_t index) {
+ (void) g;
+ (void) index;
+}
+
+/**
+ * @brief Send data to the lcd.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] data The data to send
+ *
+ * @notapi
+ */
+static inline void write_data(GDisplay *g, uint16_t data) {
+ (void) g;
+ (void) data;
+}
+
+/**
+ * @brief Set the bus in read mode
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void setreadmode(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Set the bus back into write mode
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void setwritemode(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Read data from the lcd.
+ * @return The data from the lcd
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @note The chip select may need to be asserted/de-asserted
+ * around the actual spi read
+ *
+ * @notapi
+ */
+static inline uint16_t read_data(GDisplay *g) {
+ (void) g;
+ return 0;
+}
+
+#endif /* GDISP_LLD_BOARD_H */
+/** @} */
diff --git a/drivers/gdisp/ILI9320/gdisp_lld.c b/drivers/gdisp/ILI9320/gdisp_lld.c
deleted file mode 100644
index c432cd35..00000000
--- a/drivers/gdisp/ILI9320/gdisp_lld.c
+++ /dev/null
@@ -1,584 +0,0 @@
-/*
- * This file is subject to the terms of the GFX License. If a copy of
- * the license was not distributed with this file, you can obtain one at:
- *
- * http://ugfx.org/license.html
- */
-
-/**
- * @file drivers/gdisp/ILI9320/gdisp_lld.c
- * @brief GDISP Graphics Driver subsystem low level driver source for the ILI9320 display.
- *
- * @addtogroup GDISP
- * @{
- */
-
-#include "gfx.h"
-
-#if GFX_USE_GDISP /*|| defined(__DOXYGEN__)*/
-
-/* Include the emulation code for things we don't support */
-#include "gdisp/lld/emulation.c"
-
-#include "gdisp_lld_board.h"
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-/* This controller is only ever used with a 240 x 320 display */
-#if defined(GDISP_SCREEN_HEIGHT)
- #warning "GDISP: This low level driver does not support setting a screen size. It is being ignored."
- #undef GDISP_SCREEN_HEIGHT
-#endif
-#if defined(GDISP_SCREEN_WIDTH)
- #warning "GDISP: This low level driver does not support setting a screen size. It is being ignored."
- #undef GDISP_SCREEN_WIDTH
-#endif
-
-#define GDISP_SCREEN_WIDTH 240
-#define GDISP_SCREEN_HEIGHT 320
-
-#define GDISP_INITIAL_CONTRAST 50
-#define GDISP_INITIAL_BACKLIGHT 100
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver local variables. */
-/*===========================================================================*/
-uint32_t DISPLAY_CODE;
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-static inline void lld_lcdDelay(uint16_t us) {
- gfxSleepMicroseconds(us);
-}
-
-static inline void lld_lcdWriteIndex(uint16_t index) {
- gdisp_lld_write_index(index);
-}
-
-static inline void lld_lcdWriteData(uint16_t data) {
- gdisp_lld_write_data(data);
-}
-
-static inline void lld_lcdWriteReg(uint16_t lcdReg, uint16_t lcdRegValue) {
- gdisp_lld_write_index(lcdReg);
- gdisp_lld_write_data(lcdRegValue);
-}
-
-static inline uint16_t lld_lcdReadData(void) {
- return gdisp_lld_read_data();
-}
-
-static inline uint16_t lld_lcdReadReg(uint16_t lcdReg) {
- volatile uint16_t dummy;
-
- gdisp_lld_write_index(lcdReg);
- dummy = lld_lcdReadData();
- (void)dummy;
-
- return lld_lcdReadData();
-}
-
-static inline void lld_lcdWriteStreamStart(void) {
- lld_lcdWriteIndex(0x0022);
-}
-
-static inline void lld_lcdWriteStreamStop(void) {
-
-}
-
-static inline void lld_lcdWriteStream(uint16_t *buffer, uint16_t size) {
- uint16_t i;
-
- for(i = 0; i < size; i++)
- lld_lcdWriteData(buffer[i]);
-}
-
-static inline void lld_lcdReadStreamStart(void) {
- lld_lcdWriteIndex(0x0022);
-}
-
-static inline void lld_lcdReadStreamStop(void) {
-
-}
-
-static inline void lld_lcdReadStream(uint16_t *buffer, size_t size) {
- uint16_t i;
- volatile uint16_t dummy;
-
- dummy = lld_lcdReadData();
- (void)dummy;
-
- for(i = 0; i < size; i++)
- buffer[i] = lld_lcdReadData();
-}
-
-bool_t gdisp_lld_init(void) {
- /* Initialise your display */
- gdisp_lld_init_board();
-
- /* Hardware reset */
- gdisp_lld_reset_pin(TRUE);
- lld_lcdDelay(1000);
- gdisp_lld_reset_pin(FALSE);
- lld_lcdDelay(1000);
-
- DISPLAY_CODE = lld_lcdReadReg(0);
- lld_lcdWriteReg(0x0000, 0x0001); //start Int. osc
- lld_lcdDelay(500);
- lld_lcdWriteReg(0x0001, 0x0100); //Set SS bit (shift direction of outputs is from S720 to S1)
- lld_lcdWriteReg(0x0002, 0x0700); //select the line inversion
- lld_lcdWriteReg(0x0003, 0x1038); //Entry mode(Horizontal : increment,Vertical : increment, AM=1)
- lld_lcdWriteReg(0x0004, 0x0000); //Resize control(No resizing)
- lld_lcdWriteReg(0x0008, 0x0202); //front and back porch 2 lines
- lld_lcdWriteReg(0x0009, 0x0000); //select normal scan
- lld_lcdWriteReg(0x000A, 0x0000); //display control 4
- lld_lcdWriteReg(0x000C, 0x0000); //system interface(2 transfer /pixel), internal sys clock,
- lld_lcdWriteReg(0x000D, 0x0000); //Frame marker position
- lld_lcdWriteReg(0x000F, 0x0000); //selects clk, enable and sync signal polarity,
- lld_lcdWriteReg(0x0010, 0x0000); //
- lld_lcdWriteReg(0x0011, 0x0000); //power control 2 reference voltages = 1:1,
- lld_lcdWriteReg(0x0012, 0x0000); //power control 3 VRH
- lld_lcdWriteReg(0x0013, 0x0000); //power control 4 VCOM amplitude
- lld_lcdDelay(500);
- lld_lcdWriteReg(0x0010, 0x17B0); //power control 1 BT,AP
- lld_lcdWriteReg(0x0011, 0x0137); //power control 2 DC,VC
- lld_lcdDelay(500);
- lld_lcdWriteReg(0x0012, 0x0139); //power control 3 VRH
- lld_lcdDelay(500);
- lld_lcdWriteReg(0x0013, 0x1d00); //power control 4 vcom amplitude
- lld_lcdWriteReg(0x0029, 0x0011); //power control 7 VCOMH
- lld_lcdDelay(500);
- lld_lcdWriteReg(0x0030, 0x0007);
- lld_lcdWriteReg(0x0031, 0x0403);
- lld_lcdWriteReg(0x0032, 0x0404);
- lld_lcdWriteReg(0x0035, 0x0002);
- lld_lcdWriteReg(0x0036, 0x0707);
- lld_lcdWriteReg(0x0037, 0x0606);
- lld_lcdWriteReg(0x0038, 0x0106);
- lld_lcdWriteReg(0x0039, 0x0007);
- lld_lcdWriteReg(0x003c, 0x0700);
- lld_lcdWriteReg(0x003d, 0x0707);
- lld_lcdWriteReg(0x0020, 0x0000); //starting Horizontal GRAM Address
- lld_lcdWriteReg(0x0021, 0x0000); //starting Vertical GRAM Address
- lld_lcdWriteReg(0x0050, 0x0000); //Horizontal GRAM Start Position
- lld_lcdWriteReg(0x0051, 0x00EF); //Horizontal GRAM end Position
- lld_lcdWriteReg(0x0052, 0x0000); //Vertical GRAM Start Position
- lld_lcdWriteReg(0x0053, 0x013F); //Vertical GRAM end Position
- switch (DISPLAY_CODE) {
- case 0x9320:
- lld_lcdWriteReg(0x0060, 0x2700); //starts scanning from G1, and 320 drive lines
- break;
- case 0x9325:
- lld_lcdWriteReg(0x0060, 0xA700); //starts scanning from G1, and 320 drive lines
- break;
- }
-
- lld_lcdWriteReg(0x0061, 0x0001); //fixed base display
- lld_lcdWriteReg(0x006a, 0x0000); //no scroll
- lld_lcdWriteReg(0x0090, 0x0010); //set Clocks/Line =16, Internal Operation Clock Frequency=fosc/1,
- lld_lcdWriteReg(0x0092, 0x0000); //set gate output non-overlap period=0
- lld_lcdWriteReg(0x0093, 0x0003); //set Source Output Position=3
- lld_lcdWriteReg(0x0095, 0x0110); //RGB interface(Clocks per line period=16 clocks)
- lld_lcdWriteReg(0x0097, 0x0110); //set Gate Non-overlap Period 0 locksc
- lld_lcdWriteReg(0x0098, 0x0110); //
- lld_lcdWriteReg(0x0007, 0x0173); //display On
-
- // Turn on the backlight
- gdisp_lld_backlight(GDISP_INITIAL_BACKLIGHT);
-
- /* Initialise the GDISP structure */
- GDISP.Width = GDISP_SCREEN_WIDTH;
- GDISP.Height = GDISP_SCREEN_HEIGHT;
- GDISP.Orientation = GDISP_ROTATE_0;
- GDISP.Powermode = powerOn;
- GDISP.Backlight = GDISP_INITIAL_BACKLIGHT;
- GDISP.Contrast = GDISP_INITIAL_CONTRAST;
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- GDISP.clipx0 = 0;
- GDISP.clipy0 = 0;
- GDISP.clipx1 = GDISP.Width;
- GDISP.clipy1 = GDISP.Height;
- #endif
-
- return TRUE;
-}
-
-static void lld_lcdSetCursor(uint16_t x, uint16_t y) {
-
- switch(GDISP.Orientation) {
- case GDISP_ROTATE_0:
- lld_lcdWriteReg(0x0020, x);
- lld_lcdWriteReg(0x0021, y);
- break;
-
- case GDISP_ROTATE_90:
- lld_lcdWriteReg(0x0020, y);
- lld_lcdWriteReg(0x0021, x);
- break;
-
- case GDISP_ROTATE_180:
- lld_lcdWriteReg(0x0020, x);
- lld_lcdWriteReg(0x0021, y);
- break;
-
- case GDISP_ROTATE_270:
- lld_lcdWriteReg(0x0020, y);
- lld_lcdWriteReg(0x0021, x);
- break;
- }
-}
-
-static void lld_lcdSetViewPort(uint16_t x, uint16_t y, uint16_t cx, uint16_t cy) {
- switch(GDISP.Orientation) {
- case GDISP_ROTATE_0:
- lld_lcdWriteReg(0x0050, x);
- lld_lcdWriteReg(0x0051, x + cx - 1);
- lld_lcdWriteReg(0x0052, y);
- lld_lcdWriteReg(0x0053, y + cy - 1);
- break;
-
- case GDISP_ROTATE_90:
- lld_lcdWriteReg(0x0050, y);
- lld_lcdWriteReg(0x0051, y + cy - 1);
- lld_lcdWriteReg(0x0052, x);
- lld_lcdWriteReg(0x0053, x + cx - 1);
- break;
-
- case GDISP_ROTATE_180:
- lld_lcdWriteReg(0x0050, x);
- lld_lcdWriteReg(0x0051, x + cx - 1);
- lld_lcdWriteReg(0x0052, y);
- lld_lcdWriteReg(0x0053, y + cy - 1);
- break;
-
- case GDISP_ROTATE_270:
- lld_lcdWriteReg(0x0050, y);
- lld_lcdWriteReg(0x0051, y + cy - 1);
- lld_lcdWriteReg(0x0052, x);
- lld_lcdWriteReg(0x0053, x + cx - 1);
- break;
- }
-
- lld_lcdSetCursor(x, y);
-}
-
-static inline void lld_lcdResetViewPort(void) {
- switch(GDISP.Orientation) {
- case GDISP_ROTATE_0:
- case GDISP_ROTATE_180:
- lld_lcdSetViewPort(0, 0, GDISP_SCREEN_WIDTH, GDISP_SCREEN_HEIGHT);
- break;
- case GDISP_ROTATE_90:
- case GDISP_ROTATE_270:
- lld_lcdSetViewPort(0, 0, GDISP_SCREEN_HEIGHT, GDISP_SCREEN_WIDTH);
- break;
- }
-}
-
-void gdisp_lld_draw_pixel(coord_t x, coord_t y, color_t color) {
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- if (x < GDISP.clipx0 || y < GDISP.clipy0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
- #endif
- lld_lcdSetCursor(x, y);
- lld_lcdWriteReg(0x0022, color);
-}
-
-#if GDISP_HARDWARE_CLEARS || defined(__DOXYGEN__)
- void gdisp_lld_clear(color_t color) {
- unsigned i;
-
- lld_lcdSetCursor(0, 0);
- lld_lcdWriteStreamStart();
-
- for(i = 0; i < GDISP_SCREEN_WIDTH * GDISP_SCREEN_HEIGHT; i++)
- lld_lcdWriteData(color);
-
- lld_lcdWriteStreamStop();
- }
-#endif
-
-#if GDISP_HARDWARE_FILLS || defined(__DOXYGEN__)
- void gdisp_lld_fill_area(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; }
- if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; }
- if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
- if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
- if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
- #endif
-
- unsigned i, area;
-
- area = cx*cy;
- lld_lcdSetViewPort(x, y, cx, cy);
- lld_lcdWriteStreamStart();
- for(i = 0; i < area; i++)
- lld_lcdWriteData(color);
- lld_lcdWriteStreamStop();
- lld_lcdResetViewPort();
- }
-#endif
-
-#if GDISP_HARDWARE_BITFILLS || defined(__DOXYGEN__)
- void gdisp_lld_blit_area_ex(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx, coord_t srcy, coord_t srccx, const pixel_t *buffer) {
- coord_t endx, endy;
- unsigned lg;
-
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; srcx += GDISP.clipx0 - x; x = GDISP.clipx0; }
- if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; srcy += GDISP.clipy0 - y; y = GDISP.clipy0; }
- if (srcx+cx > srccx) cx = srccx - srcx;
- if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
- if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
- if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
- #endif
-
- lld_lcdSetViewPort(x, y, cx, cy);
- lld_lcdWriteStreamStart();
-
- endx = srcx + cx;
- endy = y + cy;
- lg = srccx - cx;
- buffer += srcx + srcy * srccx;
- for(; y < endy; y++, buffer += lg)
- for(x=srcx; x < endx; x++)
- lld_lcdWriteData(*buffer++);
- lld_lcdWriteStreamStop();
- lld_lcdResetViewPort();
- }
-#endif
-
-#if (GDISP_NEED_PIXELREAD && GDISP_HARDWARE_PIXELREAD) || defined(__DOXYGEN__)
- color_t gdisp_lld_get_pixel_color(coord_t x, coord_t y) {
- color_t color;
-
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- if (x < 0 || x >= GDISP.Width || y < 0 || y >= GDISP.Height) return 0;
- #endif
-
- lld_lcdSetCursor(x, y);
- lld_lcdWriteStreamStart();
-
- color = lld_lcdReadData();
- color = lld_lcdReadData();
-
- lld_lcdWriteStreamStop();
-
- return color;
- }
-#endif
-
-#if (GDISP_NEED_SCROLL && GDISP_HARDWARE_SCROLL) || defined(__DOXYGEN__)
- void gdisp_lld_vertical_scroll(coord_t x, coord_t y, coord_t cx, coord_t cy, int lines, color_t bgcolor) {
- static color_t buf[((GDISP_SCREEN_HEIGHT > GDISP_SCREEN_WIDTH ) ? GDISP_SCREEN_HEIGHT : GDISP_SCREEN_WIDTH)];
- coord_t row0, row1;
- unsigned i, gap, abslines;
-
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; }
- if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; }
- if (!lines || cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
- if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
- if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
- #endif
-
- abslines = lines < 0 ? -lines : lines;
-
- if (abslines >= cy) {
- abslines = cy;
- gap = 0;
- } else {
- gap = cy - abslines;
- for(i = 0; i < gap; i++) {
- if(lines > 0) {
- row0 = y + i + lines;
- row1 = y + i;
- } else {
- row0 = (y - i - 1) + lines;
- row1 = (y - i - 1);
- }
-
- /* read row0 into the buffer and then write at row1*/
- lld_lcdSetViewPort(x, row0, cx, 1);
- lld_lcdReadStreamStart();
- lld_lcdReadStream(buf, cx);
- lld_lcdReadStreamStop();
-
- lld_lcdSetViewPort(x, row1, cx, 1);
- lld_lcdWriteStreamStart();
- lld_lcdWriteStream(buf, cx);
- lld_lcdWriteStreamStop();
- }
- }
-
- /* fill the remaining gap */
- lld_lcdSetViewPort(x, lines > 0 ? (y+gap) : y, cx, abslines);
- lld_lcdWriteStreamStart();
- gap = cx*abslines;
- for(i = 0; i < gap; i++) lld_lcdWriteData(bgcolor);
- lld_lcdWriteStreamStop();
- lld_lcdResetViewPort();
- }
-#endif
-
-#if (GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL) || defined(__DOXYGEN__)
- void gdisp_lld_control(unsigned what, void *value) {
- switch(what) {
- case GDISP_CONTROL_POWER:
- if(GDISP.Powermode == (gdisp_powermode_t)value)
- return;
- switch((gdisp_powermode_t)value) {
- case powerOff:
- acquire_bus();
- lld_lcdWriteReg(0x0007, 0x0000);
- lld_lcdWriteReg(0x0010, 0x0000);
- lld_lcdWriteReg(0x0011, 0x0000);
- lld_lcdWriteReg(0x0012, 0x0000);
- lld_lcdWriteReg(0x0013, 0x0000);
- release_bus();
-
- gdisp_lld_backlight(0);
- break;
-
- case powerOn:
- //*************Power On sequence ******************//
- acquire_bus();
- lld_lcdWriteReg(0x0010, 0x0000); /* SAP, BT[3:0], AP, DSTB, SLP, STB */
- lld_lcdWriteReg(0x0011, 0x0000); /* DC1[2:0], DC0[2:0], VC[2:0] */
- lld_lcdWriteReg(0x0012, 0x0000); /* VREG1OUT voltage */
- lld_lcdWriteReg(0x0013, 0x0000); /* VDV[4:0] for VCOM amplitude */
- lld_lcdDelay(2000); /* Dis-charge capacitor power voltage */
- lld_lcdWriteReg(0x0010, 0x17B0); /* SAP, BT[3:0], AP, DSTB, SLP, STB */
- lld_lcdWriteReg(0x0011, 0x0147); /* DC1[2:0], DC0[2:0], VC[2:0] */
- lld_lcdDelay(500);
- lld_lcdWriteReg(0x0012, 0x013C); /* VREG1OUT voltage */
- lld_lcdDelay(500);
- lld_lcdWriteReg(0x0013, 0x0E00); /* VDV[4:0] for VCOM amplitude */
- lld_lcdWriteReg(0x0029, 0x0009); /* VCM[4:0] for VCOMH */
- lld_lcdDelay(500);
- lld_lcdWriteReg(0x0007, 0x0173); /* 262K color and display ON */
- release_bus();
-
- gdisp_lld_backlight(GDISP.Backlight);
- if(GDISP.Powermode != powerSleep || GDISP.Powermode != powerDeepSleep)
- gdisp_lld_init();
- break;
-
- case powerSleep:
- acquire_bus();
- lld_lcdWriteReg(0x0007, 0x0000); /* display OFF */
- lld_lcdWriteReg(0x0010, 0x0000); /* SAP, BT[3:0], APE, AP, DSTB, SLP */
- lld_lcdWriteReg(0x0011, 0x0000); /* DC1[2:0], DC0[2:0], VC[2:0] */
- lld_lcdWriteReg(0x0012, 0x0000); /* VREG1OUT voltage */
- lld_lcdWriteReg(0x0013, 0x0000); /* VDV[4:0] for VCOM amplitude */
- lld_lcdDelay(2000); /* Dis-charge capacitor power voltage */
- lld_lcdWriteReg(0x0010, 0x0002); /* SAP, BT[3:0], APE, AP, DSTB, SLP */
- release_bus();
-
- gdisp_lld_backlight(0);
- break;
-
- case powerDeepSleep:
- acquire_bus();
- lld_lcdWriteReg(0x0007, 0x0000); /* display OFF */
- lld_lcdWriteReg(0x0010, 0x0000); /* SAP, BT[3:0], APE, AP, DSTB, SLP */
- lld_lcdWriteReg(0x0011, 0x0000); /* DC1[2:0], DC0[2:0], VC[2:0] */
- lld_lcdWriteReg(0x0012, 0x0000); /* VREG1OUT voltage */
- lld_lcdWriteReg(0x0013, 0x0000); /* VDV[4:0] for VCOM amplitude */
- lld_lcdDelay(2000); /* Dis-charge capacitor power voltage */
- lld_lcdWriteReg(0x0010, 0x0004); /* SAP, BT[3:0], APE, AP, DSTB, SLP */
- release_bus();
-
- gdisp_lld_backlight(0);
- break;
-
- default:
- return;
- }
- GDISP.Powermode = (gdisp_powermode_t)value;
- return;
-
- case GDISP_CONTROL_ORIENTATION:
- if(GDISP.Orientation == (gdisp_orientation_t)value)
- return;
- switch((gdisp_orientation_t)value) {
- case GDISP_ROTATE_0:
- acquire_bus();
- lld_lcdWriteReg(0x0001, 0x0100);
- lld_lcdWriteReg(0x0003, 0x1038);
- lld_lcdWriteReg(0x0060, 0x2700);
- release_bus();
-
- GDISP.Height = GDISP_SCREEN_HEIGHT;
- GDISP.Width = GDISP_SCREEN_WIDTH;
- break;
-
- case GDISP_ROTATE_90:
- acquire_bus();
- lld_lcdWriteReg(0x0001, 0x0100);
- lld_lcdWriteReg(0x0003, 0x1030);
- lld_lcdWriteReg(0x0060, 0x2700);
- release_bus();
-
- GDISP.Height = GDISP_SCREEN_WIDTH;
- GDISP.Width = GDISP_SCREEN_HEIGHT;
- break;
-
- case GDISP_ROTATE_180:
- acquire_bus();
- lld_lcdWriteReg(0x0001, 0x0000);
- lld_lcdWriteReg(0x0003, 0x1030);
- lld_lcdWriteReg(0x0060, 0x2700);
- release_bus();
-
- GDISP.Height = GDISP_SCREEN_HEIGHT;
- GDISP.Width = GDISP_SCREEN_WIDTH;
- break;
-
- case GDISP_ROTATE_270:
- acquire_bus();
- lld_lcdWriteReg(0x0001, 0x0000);
- lld_lcdWriteReg(0x0003, 0x1038);
- lld_lcdWriteReg(0x0060, 0xA700);
- release_bus();
-
- GDISP.Height = GDISP_SCREEN_WIDTH;
- GDISP.Width = GDISP_SCREEN_HEIGHT;
- break;
-
- default:
- return;
- }
-
- #if GDISP_NEED_CLIP || GDISP_NEED_VALIDATION
- GDISP.clipx0 = 0;
- GDISP.clipy0 = 0;
- GDISP.clipx1 = GDISP.Width;
- GDISP.clipy1 = GDISP.Height;
- #endif
- GDISP.Orientation = (gdisp_orientation_t)value;
- return;
-
- case GDISP_CONTROL_BACKLIGHT:
- if((unsigned)value > 100) value = (void *)100;
- gdisp_lld_backlight((unsigned)value);
- GDISP.Backlight = (unsigned)value;
- break;
-
- default:
- return;
- }
- }
-
-#endif
-
-#endif /* GFX_USE_GDISP */
-/** @} */
-
diff --git a/drivers/gdisp/ILI9320/gdisp_lld.mk b/drivers/gdisp/ILI9320/gdisp_lld.mk
index bcdd3230..d61fbc33 100644
--- a/drivers/gdisp/ILI9320/gdisp_lld.mk
+++ b/drivers/gdisp/ILI9320/gdisp_lld.mk
@@ -1,5 +1,2 @@
-# List the required driver.
-GFXSRC += $(GFXLIB)/drivers/gdisp/ILI9320/gdisp_lld.c
-
-# Required include directories
-GFXINC += $(GFXLIB)/drivers/gdisp/ILI9320
+GFXINC += $(GFXLIB)/drivers/gdisp/ILI9320
+GFXSRC += $(GFXLIB)/drivers/gdisp/ILI9320/gdisp_lld_ILI9320.c
diff --git a/drivers/gdisp/ILI9320/gdisp_lld_ILI9320.c b/drivers/gdisp/ILI9320/gdisp_lld_ILI9320.c
new file mode 100644
index 00000000..e65e0a77
--- /dev/null
+++ b/drivers/gdisp/ILI9320/gdisp_lld_ILI9320.c
@@ -0,0 +1,380 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/ILI9320/gdisp_lld.c
+ * @brief GDISP Graphics Driver subsystem low level driver source for the ILI9320 display.
+ */
+
+#include "gfx.h"
+
+#if GFX_USE_GDISP
+
+/* This controller is only ever used with a 240 x 320 display */
+#if defined(GDISP_SCREEN_HEIGHT)
+ #warning "GDISP: This low level driver does not support setting a screen size. It is being ignored."
+ #undef GDISP_SCREEN_HEIGHT
+#endif
+#if defined(GDISP_SCREEN_WIDTH)
+ #warning "GDISP: This low level driver does not support setting a screen size. It is being ignored."
+ #undef GDISP_SCREEN_WIDTH
+#endif
+
+#define GDISP_DRIVER_VMT GDISPVMT_ILI9320
+#include "../drivers/gdisp/ILI9320/gdisp_lld_config.h"
+#include "gdisp/lld/gdisp_lld.h"
+
+#include "board_ILI9320.h"
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+#ifndef GDISP_SCREEN_HEIGHT
+ #define GDISP_SCREEN_HEIGHT 320
+#endif
+#ifndef GDISP_SCREEN_WIDTH
+ #define GDISP_SCREEN_WIDTH 240
+#endif
+#ifndef GDISP_INITIAL_CONTRAST
+ #define GDISP_INITIAL_CONTRAST 50
+#endif
+#ifndef GDISP_INITIAL_BACKLIGHT
+ #define GDISP_INITIAL_BACKLIGHT 100
+#endif
+
+/*===========================================================================*/
+/* Driver local variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+#define dummy_read(g) { volatile uint16_t dummy; dummy = read_data(g); (void) dummy; }
+#define write_reg(g, reg, data) { write_index(g, reg); write_data(g, data); }
+
+static void set_cursor(GDisplay *g) {
+ switch(g->g.Orientation) {
+ case GDISP_ROTATE_0:
+ case GDISP_ROTATE_180:
+ write_reg(g, 0x20, g->p.x);
+ write_reg(g, 0x21, g->p.y);
+ break;
+
+ case GDISP_ROTATE_90:
+ case GDISP_ROTATE_270:
+ write_reg(g, 0x20, g->p.y);
+ write_reg(g, 0x21, g->p.x);
+ break;
+ }
+ write_index(g, 0x22);
+}
+
+static void set_viewport(GDisplay *g) {
+ switch(g->g.Orientation) {
+ case GDISP_ROTATE_0:
+ case GDISP_ROTATE_180:
+ write_reg(g, 0x50, g->p.x);
+ write_reg(g, 0x51, g->p.x + g->p.cx - 1);
+ write_reg(g, 0x52, g->p.y);
+ write_reg(g, 0x53, g->p.y + g->p.cy - 1);
+ break;
+
+ case GDISP_ROTATE_90:
+ case GDISP_ROTATE_270:
+ write_reg(g, 0x50, g->p.y);
+ write_reg(g, 0x51, g->p.y + g->p.cy - 1);
+ write_reg(g, 0x52, g->p.x);
+ write_reg(g, 0x53, g->p.x + g->p.cx - 1);
+ break;
+ }
+}
+
+LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
+ uint16_t cver;
+
+ // No private area for this controller
+ g->priv = 0;
+
+ // Initialise the board interface
+ init_board(g);
+
+ /* Hardware reset */
+ setpin_reset(g, TRUE);
+ gfxSleepMicroseconds(1000);
+ setpin_reset(g, FALSE);
+ gfxSleepMicroseconds(1000);
+
+ acquire_bus(g);
+ write_index(g, 0); // Get controller version
+ setreadmode(g);
+ dummy_read(g);
+ cver = read_data(g);
+ setwritemode(g);
+ write_reg(g, 0x00, 0x0001); //start Int. osc
+ gfxSleepMicroseconds(500);
+ write_reg(g, 0x01, 0x0100); //Set SS bit (shift direction of outputs is from S720 to S1)
+ write_reg(g, 0x02, 0x0700); //select the line inversion
+ write_reg(g, 0x03, 0x1038); //Entry mode(Horizontal : increment,Vertical : increment, AM=1)
+ write_reg(g, 0x04, 0x0000); //Resize control(No resizing)
+ write_reg(g, 0x08, 0x0202); //front and back porch 2 lines
+ write_reg(g, 0x09, 0x0000); //select normal scan
+ write_reg(g, 0x0A, 0x0000); //display control 4
+ write_reg(g, 0x0C, 0x0000); //system interface(2 transfer /pixel), internal sys clock,
+ write_reg(g, 0x0D, 0x0000); //Frame marker position
+ write_reg(g, 0x0F, 0x0000); //selects clk, enable and sync signal polarity,
+ write_reg(g, 0x10, 0x0000); //
+ write_reg(g, 0x11, 0x0000); //power control 2 reference voltages = 1:1,
+ write_reg(g, 0x12, 0x0000); //power control 3 VRH
+ write_reg(g, 0x13, 0x0000); //power control 4 VCOM amplitude
+ gfxSleepMicroseconds(500);
+ write_reg(g, 0x10, 0x17B0); //power control 1 BT,AP
+ write_reg(g, 0x11, 0x0137); //power control 2 DC,VC
+ gfxSleepMicroseconds(500);
+ write_reg(g, 0x12, 0x0139); //power control 3 VRH
+ gfxSleepMicroseconds(500);
+ write_reg(g, 0x13, 0x1d00); //power control 4 vcom amplitude
+ write_reg(g, 0x29, 0x0011); //power control 7 VCOMH
+ gfxSleepMicroseconds(500);
+ write_reg(g, 0x30, 0x0007);
+ write_reg(g, 0x31, 0x0403);
+ write_reg(g, 0x32, 0x0404);
+ write_reg(g, 0x35, 0x0002);
+ write_reg(g, 0x36, 0x0707);
+ write_reg(g, 0x37, 0x0606);
+ write_reg(g, 0x38, 0x0106);
+ write_reg(g, 0x39, 0x0007);
+ write_reg(g, 0x3c, 0x0700);
+ write_reg(g, 0x3d, 0x0707);
+ write_reg(g, 0x20, 0x0000); //starting Horizontal GRAM Address
+ write_reg(g, 0x21, 0x0000); //starting Vertical GRAM Address
+ write_reg(g, 0x50, 0x0000); //Horizontal GRAM Start Position
+ write_reg(g, 0x51, 0x00EF); //Horizontal GRAM end Position
+ write_reg(g, 0x52, 0x0000); //Vertical GRAM Start Position
+ write_reg(g, 0x53, 0x013F); //Vertical GRAM end Position
+ switch (cver) {
+ case 0x9320:
+ write_reg(g, 0x60, 0x2700); //starts scanning from G1, and 320 drive lines
+ break;
+ case 0x9325:
+ write_reg(g, 0x60, 0xA700); //starts scanning from G1, and 320 drive lines
+ break;
+ }
+
+ write_reg(g, 0x61, 0x0001); //fixed base display
+ write_reg(g, 0x6a, 0x0000); //no scroll
+ write_reg(g, 0x90, 0x0010); //set Clocks/Line =16, Internal Operation Clock Frequency=fosc/1,
+ write_reg(g, 0x92, 0x0000); //set gate output non-overlap period=0
+ write_reg(g, 0x93, 0x0003); //set Source Output Position=3
+ write_reg(g, 0x95, 0x0110); //RGB interface(Clocks per line period=16 clocks)
+ write_reg(g, 0x97, 0x0110); //set Gate Non-overlap Period 0 locksc
+ write_reg(g, 0x98, 0x0110); //
+ write_reg(g, 0x07, 0x0173); //display On
+
+ // Finish Init
+ post_init_board(g);
+
+ // Release the bus
+ release_bus(g);
+
+ // Turn on the backlight
+ set_backlight(g, GDISP_INITIAL_BACKLIGHT);
+
+ /* Initialise the GDISP structure */
+ g->g.Width = GDISP_SCREEN_WIDTH;
+ g->g.Height = GDISP_SCREEN_HEIGHT;
+ g->g.Orientation = GDISP_ROTATE_0;
+ g->g.Powermode = powerOn;
+ g->g.Backlight = GDISP_INITIAL_BACKLIGHT;
+ g->g.Contrast = GDISP_INITIAL_CONTRAST;
+ return TRUE;
+}
+
+#if GDISP_HARDWARE_STREAM_WRITE
+ LLDSPEC void gdisp_lld_write_start(GDisplay *g) {
+ acquire_bus(g);
+ set_viewport(g);
+ #if !GDISP_HARDWARE_STREAM_POS
+ set_cursor(g);
+ #endif
+ }
+ LLDSPEC void gdisp_lld_write_color(GDisplay *g) {
+ write_data(g, COLOR2NATIVE(g->p.color));
+ }
+ LLDSPEC void gdisp_lld_write_stop(GDisplay *g) {
+ release_bus(g);
+ }
+ #if GDISP_HARDWARE_STREAM_POS
+ LLDSPEC void gdisp_lld_write_pos(GDisplay *g) {
+ set_cursor(g);
+ }
+ #endif
+#endif
+
+#if GDISP_HARDWARE_STREAM_READ
+ LLDSPEC void gdisp_lld_read_start(GDisplay *g) {
+ acquire_bus(g);
+ set_viewport(g);
+ set_cursor(g);
+ setreadmode(g);
+ dummy_read(g);
+ }
+ LLDSPEC color_t gdisp_lld_read_color(GDisplay *g) {
+ uint16_t data;
+
+ data = read_data(g);
+ return NATIVE2COLOR(data);
+ }
+ LLDSPEC void gdisp_lld_read_stop(GDisplay *g) {
+ setwritemode(g);
+ release_bus(g);
+ }
+#endif
+
+#if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL
+ LLDSPEC void gdisp_lld_control(GDisplay *g) {
+ switch(g->p.x) {
+ case GDISP_CONTROL_POWER:
+ if (g->g.Powermode == (powermode_t)g->p.ptr)
+ return;
+ switch((powermode_t)g->p.ptr) {
+ case powerOff:
+ acquire_bus(g);
+ write_reg(g, 0x07, 0x0000);
+ write_reg(g, 0x10, 0x0000);
+ write_reg(g, 0x11, 0x0000);
+ write_reg(g, 0x12, 0x0000);
+ write_reg(g, 0x13, 0x0000);
+ release_bus(g);
+
+ set_backlight(g, 0);
+ break;
+
+ case powerOn:
+ //*************Power On sequence ******************//
+ acquire_bus(g);
+ write_reg(g, 0x10, 0x0000); /* SAP, BT[3:0], AP, DSTB, SLP, STB */
+ write_reg(g, 0x11, 0x0000); /* DC1[2:0], DC0[2:0], VC[2:0] */
+ write_reg(g, 0x12, 0x0000); /* VREG1OUT voltage */
+ write_reg(g, 0x13, 0x0000); /* VDV[4:0] for VCOM amplitude */
+ gfxSleepMicroseconds(2000); /* Dis-charge capacitor power voltage */
+ write_reg(g, 0x10, 0x17B0); /* SAP, BT[3:0], AP, DSTB, SLP, STB */
+ write_reg(g, 0x11, 0x0147); /* DC1[2:0], DC0[2:0], VC[2:0] */
+ gfxSleepMicroseconds(500);
+ write_reg(g, 0x12, 0x013C); /* VREG1OUT voltage */
+ gfxSleepMicroseconds(500);
+ write_reg(g, 0x13, 0x0E00); /* VDV[4:0] for VCOM amplitude */
+ write_reg(g, 0x29, 0x0009); /* VCM[4:0] for VCOMH */
+ gfxSleepMicroseconds(500);
+ write_reg(g, 0x07, 0x0173); /* 262K color and display ON */
+ release_bus(g);
+
+ set_backlight(g, g->g.Backlight);
+ break;
+
+ case powerSleep:
+ acquire_bus(g);
+ write_reg(g, 0x07, 0x0000); /* display OFF */
+ write_reg(g, 0x10, 0x0000); /* SAP, BT[3:0], APE, AP, DSTB, SLP */
+ write_reg(g, 0x11, 0x0000); /* DC1[2:0], DC0[2:0], VC[2:0] */
+ write_reg(g, 0x12, 0x0000); /* VREG1OUT voltage */
+ write_reg(g, 0x13, 0x0000); /* VDV[4:0] for VCOM amplitude */
+ gfxSleepMicroseconds(2000); /* Dis-charge capacitor power voltage */
+ write_reg(g, 0x10, 0x0002); /* SAP, BT[3:0], APE, AP, DSTB, SLP */
+ release_bus(g);
+
+ set_backlight(g, 0);
+ break;
+
+ case powerDeepSleep:
+ acquire_bus(g);
+ write_reg(g, 0x07, 0x0000); /* display OFF */
+ write_reg(g, 0x10, 0x0000); /* SAP, BT[3:0], APE, AP, DSTB, SLP */
+ write_reg(g, 0x11, 0x0000); /* DC1[2:0], DC0[2:0], VC[2:0] */
+ write_reg(g, 0x12, 0x0000); /* VREG1OUT voltage */
+ write_reg(g, 0x13, 0x0000); /* VDV[4:0] for VCOM amplitude */
+ gfxSleepMicroseconds(2000); /* Dis-charge capacitor power voltage */
+ write_reg(g, 0x10, 0x0004); /* SAP, BT[3:0], APE, AP, DSTB, SLP */
+ release_bus(g);
+
+ set_backlight(g, 0);
+ break;
+
+ default:
+ return;
+ }
+ g->g.Powermode = (powermode_t)g->p.ptr;
+ return;
+
+ case GDISP_CONTROL_ORIENTATION:
+ if (g->g.Orientation == (orientation_t)g->p.ptr)
+ return;
+ switch((orientation_t)g->p.ptr) {
+ case GDISP_ROTATE_0:
+ acquire_bus(g);
+ write_reg(g, 0x01, 0x0100);
+ write_reg(g, 0x03, 0x1038);
+ write_reg(g, 0x60, 0x2700);
+ release_bus(g);
+
+ g->g.Height = GDISP_SCREEN_HEIGHT;
+ g->g.Width = GDISP_SCREEN_WIDTH;
+ break;
+
+ case GDISP_ROTATE_90:
+ acquire_bus(g);
+ write_reg(g, 0x01, 0x0100);
+ write_reg(g, 0x03, 0x1030);
+ write_reg(g, 0x60, 0x2700);
+ release_bus(g);
+
+ g->g.Height = GDISP_SCREEN_WIDTH;
+ g->g.Width = GDISP_SCREEN_HEIGHT;
+ break;
+
+ case GDISP_ROTATE_180:
+ acquire_bus(g);
+ write_reg(g, 0x01, 0x0000);
+ write_reg(g, 0x03, 0x1030);
+ write_reg(g, 0x60, 0x2700);
+ release_bus(g);
+
+ g->g.Height = GDISP_SCREEN_HEIGHT;
+ g->g.Width = GDISP_SCREEN_WIDTH;
+ break;
+
+ case GDISP_ROTATE_270:
+ acquire_bus(g);
+ write_reg(g, 0x01, 0x0000);
+ write_reg(g, 0x03, 0x1038);
+ write_reg(g, 0x60, 0xA700);
+ release_bus(g);
+
+ g->g.Height = GDISP_SCREEN_WIDTH;
+ g->g.Width = GDISP_SCREEN_HEIGHT;
+ break;
+
+ default:
+ return;
+ }
+ g->g.Orientation = (orientation_t)g->p.ptr;
+ return;
+
+ case GDISP_CONTROL_BACKLIGHT:
+ if ((unsigned)g->p.ptr > 100)
+ g->p.ptr = (void *)100;
+ set_backlight(g, (unsigned)g->p.ptr);
+ g->g.Backlight = (unsigned)g->p.ptr;
+ return;
+ default:
+ return;
+ }
+ }
+#endif
+
+#endif /* GFX_USE_GDISP */
diff --git a/drivers/gdisp/ILI9320/gdisp_lld_board_olimex_pic32mx_lcd.h b/drivers/gdisp/ILI9320/gdisp_lld_board_olimex_pic32mx_lcd.h
deleted file mode 100644
index 177a7cd8..00000000
--- a/drivers/gdisp/ILI9320/gdisp_lld_board_olimex_pic32mx_lcd.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * This file is subject to the terms of the GFX License. If a copy of
- * the license was not distributed with this file, you can obtain one at:
- *
- * http://ugfx.org/license.html
- */
-
-/**
- * @file drivers/gdisp/ILI9320/gdisp_lld_board_olimex_pic32mx_lcd.h
- * @brief GDISP Graphic Driver subsystem board interface for the ILI9325 display.
- *
- * @addtogroup GDISP
- * @{
- */
-
-#ifndef GDISP_LLD_BOARD_H
-#define GDISP_LLD_BOARD_H
-
-#ifndef noinline
-#define noinline __attribute__((noinline))
-#endif
-
-static void gdisp_lld_init_board(void) {
- // RST
- palSetPadMode(IOPORTA, 7, PAL_MODE_OUTPUT);
- palClearPad(IOPORTA, 7);
-
- // RS
- palSetPadMode(IOPORTA, 10, PAL_MODE_OUTPUT);
- palSetPad(IOPORTA, 10);
-
- // CS
- palSetPadMode(IOPORTA, 9, PAL_MODE_OUTPUT);
- palClearPad(IOPORTA, 9);
-
- // Backlight
- palSetPadMode(IOPORTD, 3, PAL_MODE_OUTPUT);
- palSetPad(IOPORTD, 3);
-
- // PMP setup
- PMMODE = 0;
- PMAEN = 0;
- PMCON = 0;
- PMMODEbits.MODE = 2;
- PMMODEbits.WAITB = 0;
- PMMODEbits.WAITM = 1;
- PMMODEbits.WAITE = 0;
- PMCONbits.CSF = 0;
- PMCONbits.PTRDEN = 1;
- PMCONbits.PTWREN = 1;
- PMMODEbits.MODE16 = 1;
- PMCONbits.PMPEN = 1;
-
- palClearPad(IOPORTA, 9);
-}
-
-#define PmpWaitBusy() do {} while (PMMODEbits.BUSY)
-
-static noinline void gdisp_lld_reset_pin(bool_t state) {
- if (state)
- palClearPad(IOPORTA, 7);
- else
- palSetPad(IOPORTA, 7);
-}
-
-static noinline void gdisp_lld_write_index(uint16_t data) {
- volatile uint16_t dummy;
-
- PmpWaitBusy();
- palClearPad(IOPORTA, 10);
- PMDIN = data;
- PmpWaitBusy();
- palSetPad(IOPORTA, 10);
-
- dummy = PMDIN;
- (void)dummy;
-}
-
-static noinline void gdisp_lld_write_data(uint16_t data) {
- PMDIN = data;
- PmpWaitBusy();
-}
-
-static noinline uint16_t gdisp_lld_read_data(void) {
- PmpWaitBusy();
- return PMDIN;
-}
-
-/* if not available, just ignore the argument and return */
-static void gdisp_lld_backlight(uint8_t percentage) {
- if (percentage)
- palClearPad(IOPORTD, 3);
- else
- palSetPad(IOPORTD, 3);
-}
-
-static inline void acquire_bus(void) {
- /* Nothing to do here since LCD is the only device on that bus */
-}
-
-static inline void release_bus(void) {
- /* Nothing to do here since LCD is the only device on that bus */
-}
-#endif /* GDISP_LLD_BOARD_H */
-/** @} */
-
diff --git a/drivers/gdisp/ILI9320/gdisp_lld_board_olimex_stm32_lcd.h b/drivers/gdisp/ILI9320/gdisp_lld_board_olimex_stm32_lcd.h
deleted file mode 100644
index 0d9f8364..00000000
--- a/drivers/gdisp/ILI9320/gdisp_lld_board_olimex_stm32_lcd.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * This file is subject to the terms of the GFX License. If a copy of
- * the license was not distributed with this file, you can obtain one at:
- *
- * http://ugfx.org/license.html
- */
-
-/**
- * @file drivers/gdisp/ILI9320/gdisp_lld_board_olimex_stm32_lcd.h
- * @brief GDISP Graphic Driver subsystem board interface for the ILI9320 display.
- *
- * @addtogroup GDISP
- * @{
- */
-
-#ifndef GDISP_LLD_BOARD_H
-#define GDISP_LLD_BOARD_H
-
-#define GDISP_REG (*((volatile uint16_t *) 0x60000000)) /* RS = 0 */
-#define GDISP_RAM (*((volatile uint16_t *) 0x60100000)) /* RS = 1 */
-
-static inline void gdisp_lld_init_board(void) {
- /* FSMC setup for F1 */
- rccEnableAHB(RCC_AHBENR_FSMCEN, 0);
-
- /* set pin modes */
- IOBus busD = {GPIOD, PAL_WHOLE_PORT, 0};
- IOBus busE = {GPIOE, PAL_WHOLE_PORT, 0};
- palSetBusMode(&busD, PAL_MODE_STM32_ALTERNATE_PUSHPULL);
- palSetBusMode(&busE, PAL_MODE_STM32_ALTERNATE_PUSHPULL);
- palSetPadMode(GPIOE, GPIOE_TFT_RST, PAL_MODE_OUTPUT_PUSHPULL);
- palSetPadMode(GPIOD, GPIOD_TFT_LIGHT, PAL_MODE_OUTPUT_PUSHPULL);
-
- const unsigned char FSMC_Bank = 0;
-
- /* FSMC timing */
- FSMC_Bank1->BTCR[FSMC_Bank+1] = (6) | (10 << 8) | (10 << 16);
-
- /* Bank1 NOR/SRAM control register configuration
- * This is actually not needed as already set by default after reset */
- FSMC_Bank1->BTCR[FSMC_Bank] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN;
-}
-
-static inline void gdisp_lld_reset_pin(bool_t state) {
- if(state)
- palClearPad(GPIOE, GPIOE_TFT_RST);
- else
- palSetPad(GPIOE, GPIOE_TFT_RST);
-}
-
-static inline void acquire_bus(void) {
- /* Nothing to do here since LCD is the only device on that bus */
-}
-
-static inline void release_bus(void) {
- /* Nothing to do here since LCD is the only device on that bus */
-}
-
-static inline void gdisp_lld_write_index(uint16_t reg) {
- GDISP_REG = reg;
-}
-
-static inline void gdisp_lld_write_data(uint16_t data) {
- GDISP_RAM = data;
-}
-
-static inline uint16_t gdisp_lld_read_data(void) {
- return GDISP_RAM;
-}
-
-static inline void gdisp_lld_backlight(uint8_t percent) {
- if(percent == 100)
- palClearPad(GPIOD, GPIOD_TFT_LIGHT);
- else
- palSetPad(GPIOD, GPIOD_TFT_LIGHT);
-}
-
-#endif /* GDISP_LLD_BOARD_H */
-/** @} */
-
diff --git a/drivers/gdisp/ILI9320/gdisp_lld_board_template.h b/drivers/gdisp/ILI9320/gdisp_lld_board_template.h
deleted file mode 100644
index dafaec48..00000000
--- a/drivers/gdisp/ILI9320/gdisp_lld_board_template.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * This file is subject to the terms of the GFX License. If a copy of
- * the license was not distributed with this file, you can obtain one at:
- *
- * http://ugfx.org/license.html
- */
-
-/**
- * @file drivers/gdisp/ILI9320/gdisp_lld_board_template.h
- * @brief GDISP Graphic Driver subsystem board interface for the ILI9320 display.
- *
- * @addtogroup GDISP
- * @{
- */
-
-#ifndef GDISP_LLD_BOARD_H
-#define GDISP_LLD_BOARD_H
-
-static inline void gdisp_lld_init_board(void) {
-
-}
-
-static inline void gdisp_lld_reset_pin(bool_t state) {
-
-}
-
-static inline void acquire_bus(void) {
-
-}
-
-static inline void release_bus(void) {
-
-}
-
-static inline void gdisp_lld_write_index(uint16_t data) {
-
-}
-
-static inline void gdisp_lld_write_data(uint16_t data) {
-
-}
-
-static inline uint16_t gdisp_lld_read_data(void) {
-
-}
-
-static inline uint16_t gdisp_lld_backlight(uint8_t percentage) {
-
-}
-
-#endif /* GDISP_LLD_BOARD_H */
-/** @} */
-
diff --git a/drivers/gdisp/ILI9320/gdisp_lld_config.h b/drivers/gdisp/ILI9320/gdisp_lld_config.h
index 4907c6b8..5709de50 100644
--- a/drivers/gdisp/ILI9320/gdisp_lld_config.h
+++ b/drivers/gdisp/ILI9320/gdisp_lld_config.h
@@ -4,37 +4,33 @@
*
* http://ugfx.org/license.html
*/
-
-/**
- * @file drivers/gdisp/ILI9320/gdisp_lld_config.h
- * @brief GDISP Graphic Driver subsystem low level driver header for the ILI9320 display.
- *
- * @addtogroup GDISP
- * @{
- */
-
-#ifndef GDISP_LLD_CONFIG_H
-#define GDISP_LLD_CONFIG_H
-
-#if GFX_USE_GDISP
-
-/*===========================================================================*/
-/* Driver hardware support. */
-/*===========================================================================*/
-
-#define GDISP_DRIVER_NAME "ILI9320"
-
-#define GDISP_HARDWARE_CLEARS TRUE
-#define GDISP_HARDWARE_FILLS TRUE
-#define GDISP_HARDWARE_BITFILLS FALSE
-#define GDISP_HARDWARE_SCROLL FALSE
-#define GDISP_HARDWARE_PIXELREAD TRUE
-#define GDISP_HARDWARE_CONTROL TRUE
-
-#define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_RGB565
-
-#endif /* GFX_USE_GDISP */
-
-#endif /* _GDISP_LLD_CONFIG_H */
-/** @} */
-
+
+/**
+ * @file drivers/gdisp/ILI9320/gdisp_lld_config.h
+ * @brief GDISP Graphic Driver subsystem low level driver header for the ILI9320 display.
+ *
+ * @addtogroup GDISP
+ * @{
+ */
+
+#ifndef GDISP_LLD_CONFIG_H
+#define GDISP_LLD_CONFIG_H
+
+#if GFX_USE_GDISP
+
+/*===========================================================================*/
+/* Driver hardware support. */
+/*===========================================================================*/
+
+#define GDISP_HARDWARE_STREAM_WRITE TRUE
+#define GDISP_HARDWARE_STREAM_READ TRUE
+//#define GDISP_HARDWARE_STREAM_POS TRUE
+#define GDISP_HARDWARE_CONTROL TRUE
+
+#define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_RGB565
+
+#endif /* GFX_USE_GDISP */
+
+#endif /* _GDISP_LLD_CONFIG_H */
+/** @} */
+
diff --git a/drivers/gdisp/ILI9325/board_ILI9325_template.h b/drivers/gdisp/ILI9325/board_ILI9325_template.h
new file mode 100644
index 00000000..07c2fdee
--- /dev/null
+++ b/drivers/gdisp/ILI9325/board_ILI9325_template.h
@@ -0,0 +1,155 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/ILI9325/board_ILI9325_template.h
+ * @brief GDISP Graphic Driver subsystem board interface for the ILI9325 display.
+ *
+ * @addtogroup GDISP
+ * @{
+ */
+
+#ifndef GDISP_LLD_BOARD_H
+#define GDISP_LLD_BOARD_H
+
+/**
+ * @brief Initialise the board for the display.
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @note Set the g->board member to whatever is appropriate. For multiple
+ * displays this might be a pointer to the appropriate register set.
+ *
+ * @notapi
+ */
+static inline void init_board(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief After the initialisation.
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void post_init_board(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Set or clear the lcd reset pin.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] state TRUE = lcd in reset, FALSE = normal operation
+ *
+ * @notapi
+ */
+static inline void setpin_reset(GDisplay *g, bool_t state) {
+ (void) g;
+ (void) state;
+}
+
+/**
+ * @brief Set the lcd back-light level.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] percent 0 to 100%
+ *
+ * @notapi
+ */
+static inline void set_backlight(GDisplay *g, uint8_t percent) {
+ (void) g;
+ (void) percent;
+}
+
+/**
+ * @brief Take exclusive control of the bus
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void acquire_bus(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Release exclusive control of the bus
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void release_bus(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Send data to the index register.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] index The index register to set
+ *
+ * @notapi
+ */
+static inline void write_index(GDisplay *g, uint16_t index) {
+ (void) g;
+ (void) index;
+}
+
+/**
+ * @brief Send data to the lcd.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] data The data to send
+ *
+ * @notapi
+ */
+static inline void write_data(GDisplay *g, uint16_t data) {
+ (void) g;
+ (void) data;
+}
+
+/**
+ * @brief Set the bus in read mode
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void setreadmode(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Set the bus back into write mode
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void setwritemode(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Read data from the lcd.
+ * @return The data from the lcd
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline uint16_t read_data(GDisplay *g) {
+ (void) g;
+ return 0;
+}
+
+#endif /* GDISP_LLD_BOARD_H */
+/** @} */
+
diff --git a/drivers/gdisp/ILI9325/gdisp_lld.c b/drivers/gdisp/ILI9325/gdisp_lld.c
deleted file mode 100644
index d47adb3a..00000000
--- a/drivers/gdisp/ILI9325/gdisp_lld.c
+++ /dev/null
@@ -1,582 +0,0 @@
-/*
- * This file is subject to the terms of the GFX License. If a copy of
- * the license was not distributed with this file, you can obtain one at:
- *
- * http://ugfx.org/license.html
- */
-
-/**
- * @file drivers/gdisp/ILI9325/gdisp_lld.c
- * @brief GDISP Graphics Driver subsystem low level driver source for the ILI9325 display.
- *
- * @addtogroup GDISP
- * @{
- */
-
-#include "gfx.h"
-
-#if GFX_USE_GDISP /*|| defined(__DOXYGEN__)*/
-
-/* Include the emulation code for things we don't support */
-#include "gdisp/lld/emulation.c"
-
-#include "gdisp_lld_board.h"
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-/* This controller is only ever used with a 240 x 320 display */
-#if defined(GDISP_SCREEN_HEIGHT)
- #warning "GDISP: This low level driver does not support setting a screen size. It is being ignored."
- #undef GDISP_SCREEN_HEIGHT
-#endif
-#if defined(GDISP_SCREEN_WIDTH)
- #warning "GDISP: This low level driver does not support setting a screen size. It is being ignored."
- #undef GDISP_SCREEN_WIDTH
-#endif
-
-#define GDISP_SCREEN_WIDTH 240
-#define GDISP_SCREEN_HEIGHT 320
-
-#define GDISP_INITIAL_CONTRAST 50
-#define GDISP_INITIAL_BACKLIGHT 100
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver local variables. */
-/*===========================================================================*/
-uint32_t DISPLAY_CODE;
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-static inline void lld_lcdDelay(uint16_t us) {
- gfxSleepMicroseconds(us);
-}
-
-static inline void lld_lcdWriteIndex(uint16_t index) {
- gdisp_lld_write_index(index);
-}
-
-static inline void lld_lcdWriteData(uint16_t data) {
- gdisp_lld_write_data(data);
-}
-
-static inline void lld_lcdWriteReg(uint16_t lcdReg, uint16_t lcdRegValue) {
- gdisp_lld_write_index(lcdReg);
- gdisp_lld_write_data(lcdRegValue);
-}
-
-static inline uint16_t lld_lcdReadData(void) {
- return gdisp_lld_read_data();
-}
-
-static inline uint16_t lld_lcdReadReg(uint16_t lcdReg) {
- volatile uint16_t dummy;
-
- gdisp_lld_write_index(lcdReg);
- dummy = lld_lcdReadData();
- (void)dummy;
-
- return lld_lcdReadData();
-}
-
-static inline void lld_lcdWriteStreamStart(void) {
- lld_lcdWriteIndex(0x0022);
-}
-
-static inline void lld_lcdWriteStreamStop(void) {
-
-}
-
-static inline void lld_lcdWriteStream(uint16_t *buffer, uint16_t size) {
- uint16_t i;
-
- for(i = 0; i < size; i++)
- lld_lcdWriteData(buffer[i]);
-}
-
-static inline void lld_lcdReadStreamStart(void) {
- lld_lcdWriteIndex(0x0022);
-}
-
-static inline void lld_lcdReadStreamStop(void) {
-
-}
-
-static inline void lld_lcdReadStream(uint16_t *buffer, size_t size) {
- uint16_t i;
- volatile uint16_t dummy;
-
- dummy = lld_lcdReadData();
- (void)dummy;
-
- for(i = 0; i < size; i++)
- buffer[i] = lld_lcdReadData();
-}
-
-bool_t gdisp_lld_init(void) {
- /* Initialise your display */
- gdisp_lld_init_board();
-
- /* Hardware reset */
- gdisp_lld_reset_pin(TRUE);
- lld_lcdDelay(1000);
- gdisp_lld_reset_pin(FALSE);
- lld_lcdDelay(1000);
-
- DISPLAY_CODE = lld_lcdReadReg(0);
-
- // chinese code starts here
- lld_lcdWriteReg(0x0000,0x0001);
- lld_lcdDelay(10);
-
- lld_lcdWriteReg(0x0015,0x0030);
- lld_lcdWriteReg(0x0011,0x0040);
- lld_lcdWriteReg(0x0010,0x1628);
- lld_lcdWriteReg(0x0012,0x0000);
- lld_lcdWriteReg(0x0013,0x104d);
- lld_lcdDelay(10);
- lld_lcdWriteReg(0x0012,0x0010);
- lld_lcdDelay(10);
- lld_lcdWriteReg(0x0010,0x2620);
- lld_lcdWriteReg(0x0013,0x344d); //304d
- lld_lcdDelay(10);
-
- lld_lcdWriteReg(0x0001,0x0100);
- lld_lcdWriteReg(0x0002,0x0300);
- lld_lcdWriteReg(0x0003,0x1038);//0x1030
- lld_lcdWriteReg(0x0008,0x0604);
- lld_lcdWriteReg(0x0009,0x0000);
- lld_lcdWriteReg(0x000A,0x0008);
-
- lld_lcdWriteReg(0x0041,0x0002);
- lld_lcdWriteReg(0x0060,0x2700);
- lld_lcdWriteReg(0x0061,0x0001);
- lld_lcdWriteReg(0x0090,0x0182);
- lld_lcdWriteReg(0x0093,0x0001);
- lld_lcdWriteReg(0x00a3,0x0010);
- lld_lcdDelay(10);
-
- //################# void Gamma_Set(void) ####################//
- lld_lcdWriteReg(0x30,0x0000);
- lld_lcdWriteReg(0x31,0x0502);
- lld_lcdWriteReg(0x32,0x0307);
- lld_lcdWriteReg(0x33,0x0305);
- lld_lcdWriteReg(0x34,0x0004);
- lld_lcdWriteReg(0x35,0x0402);
- lld_lcdWriteReg(0x36,0x0707);
- lld_lcdWriteReg(0x37,0x0503);
- lld_lcdWriteReg(0x38,0x1505);
- lld_lcdWriteReg(0x39,0x1505);
- lld_lcdDelay(10);
-
- //################## void Display_ON(void) ####################//
- lld_lcdWriteReg(0x0007,0x0001);
- lld_lcdDelay(10);
- lld_lcdWriteReg(0x0007,0x0021);
- lld_lcdWriteReg(0x0007,0x0023);
- lld_lcdDelay(10);
- lld_lcdWriteReg(0x0007,0x0033);
- lld_lcdDelay(10);
- lld_lcdWriteReg(0x0007,0x0133);
-
- // chinese code ends here
-
- // Turn on the backlight
- gdisp_lld_backlight(GDISP_INITIAL_BACKLIGHT);
-
- /* Initialise the GDISP structure */
- GDISP.Width = GDISP_SCREEN_WIDTH;
- GDISP.Height = GDISP_SCREEN_HEIGHT;
- GDISP.Orientation = GDISP_ROTATE_0;
- GDISP.Powermode = powerOn;
- GDISP.Backlight = GDISP_INITIAL_BACKLIGHT;
- GDISP.Contrast = GDISP_INITIAL_CONTRAST;
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- GDISP.clipx0 = 0;
- GDISP.clipy0 = 0;
- GDISP.clipx1 = GDISP.Width;
- GDISP.clipy1 = GDISP.Height;
- #endif
-
- return TRUE;
-}
-
-static void lld_lcdSetCursor(uint16_t x, uint16_t y) {
-
- switch(GDISP.Orientation) {
- case GDISP_ROTATE_0:
- lld_lcdWriteReg(0x0020, x);
- lld_lcdWriteReg(0x0021, y);
- break;
-
- case GDISP_ROTATE_90:
- lld_lcdWriteReg(0x0020, y);
- lld_lcdWriteReg(0x0021, x);
- break;
-
- case GDISP_ROTATE_180:
- lld_lcdWriteReg(0x0020, x);
- lld_lcdWriteReg(0x0021, y);
- break;
-
- case GDISP_ROTATE_270:
- lld_lcdWriteReg(0x0020, y);
- lld_lcdWriteReg(0x0021, x);
- break;
- }
-}
-
-static void lld_lcdSetViewPort(uint16_t x, uint16_t y, uint16_t cx, uint16_t cy) {
- switch(GDISP.Orientation) {
- case GDISP_ROTATE_0:
- lld_lcdWriteReg(0x0050, x);
- lld_lcdWriteReg(0x0051, x + cx - 1);
- lld_lcdWriteReg(0x0052, y);
- lld_lcdWriteReg(0x0053, y + cy - 1);
- break;
-
- case GDISP_ROTATE_90:
- lld_lcdWriteReg(0x0050, y);
- lld_lcdWriteReg(0x0051, y + cy - 1);
- lld_lcdWriteReg(0x0052, x);
- lld_lcdWriteReg(0x0053, x + cx - 1);
- break;
-
- case GDISP_ROTATE_180:
- lld_lcdWriteReg(0x0050, x);
- lld_lcdWriteReg(0x0051, x + cx - 1);
- lld_lcdWriteReg(0x0052, y);
- lld_lcdWriteReg(0x0053, y + cy - 1);
- break;
-
- case GDISP_ROTATE_270:
- lld_lcdWriteReg(0x0050, y);
- lld_lcdWriteReg(0x0051, y + cy - 1);
- lld_lcdWriteReg(0x0052, x);
- lld_lcdWriteReg(0x0053, x + cx - 1);
- break;
-
- }
-
- lld_lcdSetCursor(x, y);
-}
-
-static inline void lld_lcdResetViewPort(void) {
- switch(GDISP.Orientation) {
- case GDISP_ROTATE_0:
- case GDISP_ROTATE_180:
- lld_lcdSetViewPort(0, 0, GDISP_SCREEN_WIDTH, GDISP_SCREEN_HEIGHT);
- break;
- case GDISP_ROTATE_90:
- case GDISP_ROTATE_270:
- lld_lcdSetViewPort(0, 0, GDISP_SCREEN_HEIGHT, GDISP_SCREEN_WIDTH);
- break;
- }
-}
-
-void gdisp_lld_draw_pixel(coord_t x, coord_t y, color_t color) {
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- if (x < GDISP.clipx0 || y < GDISP.clipy0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
- #endif
- lld_lcdSetCursor(x, y);
- lld_lcdWriteReg(0x0022, color);
-}
-
-#if GDISP_HARDWARE_CLEARS || defined(__DOXYGEN__)
- void gdisp_lld_clear(color_t color) {
- unsigned i;
-
- lld_lcdSetCursor(0, 0);
- lld_lcdWriteStreamStart();
-
- for(i = 0; i < GDISP_SCREEN_WIDTH * GDISP_SCREEN_HEIGHT; i++)
- lld_lcdWriteData(color);
-
- lld_lcdWriteStreamStop();
- }
-#endif
-
-#if GDISP_HARDWARE_FILLS || defined(__DOXYGEN__)
- void gdisp_lld_fill_area(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; }
- if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; }
- if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
- if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
- if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
- #endif
-
- unsigned i, area;
-
- area = cx*cy;
- lld_lcdSetViewPort(x, y, cx, cy);
- lld_lcdWriteStreamStart();
- for(i = 0; i < area; i++)
- lld_lcdWriteData(color);
- lld_lcdWriteStreamStop();
- lld_lcdResetViewPort();
- }
-#endif
-
-#if GDISP_HARDWARE_BITFILLS || defined(__DOXYGEN__)
- void gdisp_lld_blit_area_ex(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx, coord_t srcy, coord_t srccx, const pixel_t *buffer) {
- coord_t endx, endy;
- unsigned lg;
-
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; srcx += GDISP.clipx0 - x; x = GDISP.clipx0; }
- if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; srcy += GDISP.clipy0 - y; y = GDISP.clipy0; }
- if (srcx+cx > srccx) cx = srccx - srcx;
- if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
- if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
- if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
- #endif
-
- lld_lcdSetViewPort(x, y, cx, cy);
- lld_lcdWriteStreamStart();
-
- endx = srcx + cx;
- endy = y + cy;
- lg = srccx - cx;
- buffer += srcx + srcy * srccx;
- for(; y < endy; y++, buffer += lg)
- for(x=srcx; x < endx; x++)
- lld_lcdWriteData(*buffer++);
- lld_lcdWriteStreamStop();
- lld_lcdResetViewPort();
- }
-#endif
-
-#if (GDISP_NEED_PIXELREAD && GDISP_HARDWARE_PIXELREAD) || defined(__DOXYGEN__)
- color_t gdisp_lld_get_pixel_color(coord_t x, coord_t y) {
- color_t color;
-
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- if (x < 0 || x >= GDISP.Width || y < 0 || y >= GDISP.Height) return 0;
- #endif
-
- lld_lcdSetCursor(x, y);
- lld_lcdWriteStreamStart();
-
- color = lld_lcdReadData();
- color = lld_lcdReadData();
-
- lld_lcdWriteStreamStop();
-
- return color;
- }
-#endif
-
-#if (GDISP_NEED_SCROLL && GDISP_HARDWARE_SCROLL) || defined(__DOXYGEN__)
- void gdisp_lld_vertical_scroll(coord_t x, coord_t y, coord_t cx, coord_t cy, int lines, color_t bgcolor) {
- static color_t buf[((GDISP_SCREEN_HEIGHT > GDISP_SCREEN_WIDTH ) ? GDISP_SCREEN_HEIGHT : GDISP_SCREEN_WIDTH)];
- coord_t row0, row1;
- unsigned i, gap, abslines;
-
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; }
- if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; }
- if (!lines || cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
- if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
- if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
- #endif
-
- abslines = lines < 0 ? -lines : lines;
-
- if (abslines >= cy) {
- abslines = cy;
- gap = 0;
- } else {
- gap = cy - abslines;
- for(i = 0; i < gap; i++) {
- if(lines > 0) {
- row0 = y + i + lines;
- row1 = y + i;
- } else {
- row0 = (y - i - 1) + lines;
- row1 = (y - i - 1);
- }
-
- /* read row0 into the buffer and then write at row1*/
- lld_lcdSetViewPort(x, row0, cx, 1);
- lld_lcdReadStreamStart();
- lld_lcdReadStream(buf, cx);
- lld_lcdReadStreamStop();
-
- lld_lcdSetViewPort(x, row1, cx, 1);
- lld_lcdWriteStreamStart();
- lld_lcdWriteStream(buf, cx);
- lld_lcdWriteStreamStop();
- }
- }
-
- /* fill the remaining gap */
- lld_lcdSetViewPort(x, lines > 0 ? (y+gap) : y, cx, abslines);
- lld_lcdWriteStreamStart();
- gap = cx*abslines;
- for(i = 0; i < gap; i++) lld_lcdWriteData(bgcolor);
- lld_lcdWriteStreamStop();
- lld_lcdResetViewPort();
- }
-#endif
-
-#if (GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL) || defined(__DOXYGEN__)
- void gdisp_lld_control(unsigned what, void *value) {
- switch(what) {
- case GDISP_CONTROL_POWER:
- if(GDISP.Powermode == (gdisp_powermode_t)value)
- return;
- switch((gdisp_powermode_t)value) {
- case powerOff:
- acquire_bus();
- lld_lcdWriteReg(0x0007, 0x0000);
- lld_lcdWriteReg(0x0010, 0x0000);
- lld_lcdWriteReg(0x0011, 0x0000);
- lld_lcdWriteReg(0x0012, 0x0000);
- lld_lcdWriteReg(0x0013, 0x0000);
- release_bus();
-
- gdisp_lld_backlight(0);
- break;
-
- case powerOn:
- //*************Power On sequence ******************//
- acquire_bus();
- lld_lcdWriteReg(0x0010, 0x0000); /* SAP, BT[3:0], AP, DSTB, SLP, STB */
- lld_lcdWriteReg(0x0011, 0x0000); /* DC1[2:0], DC0[2:0], VC[2:0] */
- lld_lcdWriteReg(0x0012, 0x0000); /* VREG1OUT voltage */
- lld_lcdWriteReg(0x0013, 0x0000); /* VDV[4:0] for VCOM amplitude */
- lld_lcdDelay(2000); /* Dis-charge capacitor power voltage */
- lld_lcdWriteReg(0x0010, 0x17B0); /* SAP, BT[3:0], AP, DSTB, SLP, STB */
- lld_lcdWriteReg(0x0011, 0x0147); /* DC1[2:0], DC0[2:0], VC[2:0] */
- lld_lcdDelay(500);
- lld_lcdWriteReg(0x0012, 0x013C); /* VREG1OUT voltage */
- lld_lcdDelay(500);
- lld_lcdWriteReg(0x0013, 0x0E00); /* VDV[4:0] for VCOM amplitude */
- lld_lcdWriteReg(0x0029, 0x0009); /* VCM[4:0] for VCOMH */
- lld_lcdDelay(500);
- lld_lcdWriteReg(0x0007, 0x0173); /* 262K color and display ON */
- release_bus();
-
- gdisp_lld_backlight(GDISP.Backlight);
- if(GDISP.Powermode != powerSleep || GDISP.Powermode != powerDeepSleep)
- gdisp_lld_init();
- break;
-
- case powerSleep:
- acquire_bus();
- lld_lcdWriteReg(0x0007, 0x0000); /* display OFF */
- lld_lcdWriteReg(0x0010, 0x0000); /* SAP, BT[3:0], APE, AP, DSTB, SLP */
- lld_lcdWriteReg(0x0011, 0x0000); /* DC1[2:0], DC0[2:0], VC[2:0] */
- lld_lcdWriteReg(0x0012, 0x0000); /* VREG1OUT voltage */
- lld_lcdWriteReg(0x0013, 0x0000); /* VDV[4:0] for VCOM amplitude */
- lld_lcdDelay(2000); /* Dis-charge capacitor power voltage */
- lld_lcdWriteReg(0x0010, 0x0002); /* SAP, BT[3:0], APE, AP, DSTB, SLP */
- release_bus();
-
- gdisp_lld_backlight(0);
- break;
-
- case powerDeepSleep:
- acquire_bus();
- lld_lcdWriteReg(0x0007, 0x0000); /* display OFF */
- lld_lcdWriteReg(0x0010, 0x0000); /* SAP, BT[3:0], APE, AP, DSTB, SLP */
- lld_lcdWriteReg(0x0011, 0x0000); /* DC1[2:0], DC0[2:0], VC[2:0] */
- lld_lcdWriteReg(0x0012, 0x0000); /* VREG1OUT voltage */
- lld_lcdWriteReg(0x0013, 0x0000); /* VDV[4:0] for VCOM amplitude */
- lld_lcdDelay(2000); /* Dis-charge capacitor power voltage */
- lld_lcdWriteReg(0x0010, 0x0004); /* SAP, BT[3:0], APE, AP, DSTB, SLP */
- release_bus();
-
- gdisp_lld_backlight(0);
- break;
-
- default:
- return;
- }
- GDISP.Powermode = (gdisp_powermode_t)value;
- return;
-
- case GDISP_CONTROL_ORIENTATION:
- if(GDISP.Orientation == (gdisp_orientation_t)value)
- return;
- switch((gdisp_orientation_t)value) {
- case GDISP_ROTATE_0:
- acquire_bus();
- lld_lcdWriteReg(0x0001, 0x0100);
- lld_lcdWriteReg(0x0003, 0x1038);
- lld_lcdWriteReg(0x0060, 0x2700);
- release_bus();
-
- GDISP.Height = GDISP_SCREEN_HEIGHT;
- GDISP.Width = GDISP_SCREEN_WIDTH;
- break;
-
- case GDISP_ROTATE_90:
- acquire_bus();
- lld_lcdWriteReg(0x0001, 0x0000);
- lld_lcdWriteReg(0x0003, 0x1030);
- lld_lcdWriteReg(0x0060, 0x2700);
- release_bus();
-
- GDISP.Height = GDISP_SCREEN_WIDTH;
- GDISP.Width = GDISP_SCREEN_HEIGHT;
- break;
-
- case GDISP_ROTATE_180:
- acquire_bus();
- lld_lcdWriteReg(0x0001, 0x0000);
- lld_lcdWriteReg(0x0003, 0x1038);
- lld_lcdWriteReg(0x0060, 0xa700);
- release_bus();
-
- GDISP.Height = GDISP_SCREEN_HEIGHT;
- GDISP.Width = GDISP_SCREEN_WIDTH;
- break;
-
- case GDISP_ROTATE_270:
- acquire_bus();
- lld_lcdWriteReg(0x0001, 0x0100);
- lld_lcdWriteReg(0x0003, 0x1030);
- lld_lcdWriteReg(0x0060, 0xA700);
- release_bus();
-
- GDISP.Height = GDISP_SCREEN_WIDTH;
- GDISP.Width = GDISP_SCREEN_HEIGHT;
- break;
-
- default:
- return;
- }
-
- #if GDISP_NEED_CLIP || GDISP_NEED_VALIDATION
- GDISP.clipx0 = 0;
- GDISP.clipy0 = 0;
- GDISP.clipx1 = GDISP.Width;
- GDISP.clipy1 = GDISP.Height;
- #endif
- GDISP.Orientation = (gdisp_orientation_t)value;
- return;
-
- case GDISP_CONTROL_BACKLIGHT:
- if((unsigned)value > 100) value = (void *)100;
- gdisp_lld_backlight((unsigned)value);
- GDISP.Backlight = (unsigned)value;
- break;
-
- default:
- return;
- }
- }
-
-#endif
-
-#endif /* GFX_USE_GDISP */
-/** @} */
-
diff --git a/drivers/gdisp/ILI9325/gdisp_lld.mk b/drivers/gdisp/ILI9325/gdisp_lld.mk
index b5061324..4dbda578 100644
--- a/drivers/gdisp/ILI9325/gdisp_lld.mk
+++ b/drivers/gdisp/ILI9325/gdisp_lld.mk
@@ -1,5 +1,2 @@
-# List the required driver.
-GFXSRC += $(GFXLIB)/drivers/gdisp/ILI9325/gdisp_lld.c
-
-# Required include directories
GFXINC += $(GFXLIB)/drivers/gdisp/ILI9325
+GFXSRC += $(GFXLIB)/drivers/gdisp/ILI9325/gdisp_lld_ILI9325.c
diff --git a/drivers/gdisp/ILI9325/gdisp_lld_ILI9325.c b/drivers/gdisp/ILI9325/gdisp_lld_ILI9325.c
new file mode 100644
index 00000000..ffd67cf7
--- /dev/null
+++ b/drivers/gdisp/ILI9325/gdisp_lld_ILI9325.c
@@ -0,0 +1,368 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/ILI9325/gdisp_lld.c
+ * @brief GDISP Graphics Driver subsystem low level driver source for the ILI9325 display.
+ */
+
+#include "gfx.h"
+
+#if GFX_USE_GDISP /*|| defined(__DOXYGEN__)*/
+
+/* This controller is only ever used with a 240 x 320 display */
+#if defined(GDISP_SCREEN_HEIGHT)
+ #warning "GDISP: This low level driver does not support setting a screen size. It is being ignored."
+ #undef GDISP_SCREEN_HEIGHT
+#endif
+#if defined(GDISP_SCREEN_WIDTH)
+ #warning "GDISP: This low level driver does not support setting a screen size. It is being ignored."
+ #undef GDISP_SCREEN_WIDTH
+#endif
+
+#define GDISP_DRIVER_VMT GDISPVMT_ILI9325
+#include "../drivers/gdisp/ILI9325/gdisp_lld_config.h"
+#include "gdisp/lld/gdisp_lld.h"
+
+#include "board_ILI9325.h"
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+#ifndef GDISP_SCREEN_HEIGHT
+ #define GDISP_SCREEN_HEIGHT 320
+#endif
+#ifndef GDISP_SCREEN_WIDTH
+ #define GDISP_SCREEN_WIDTH 240
+#endif
+#ifndef GDISP_INITIAL_CONTRAST
+ #define GDISP_INITIAL_CONTRAST 50
+#endif
+#ifndef GDISP_INITIAL_BACKLIGHT
+ #define GDISP_INITIAL_BACKLIGHT 100
+#endif
+
+/*===========================================================================*/
+/* Driver local variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+// Some common routines and macros
+#define dummy_read(g) { volatile uint16_t dummy; dummy = read_data(g); (void) dummy; }
+#define write_reg(g, reg, data) { write_index(g, reg); write_data(g, data); }
+
+static void set_cursor(GDisplay *g) {
+ switch(g->g.Orientation) {
+ case GDISP_ROTATE_0:
+ case GDISP_ROTATE_180:
+ write_reg(g, 0x20, g->p.x);
+ write_reg(g, 0x21, g->p.y);
+ break;
+
+ case GDISP_ROTATE_90:
+ case GDISP_ROTATE_270:
+ write_reg(g, 0x20, g->p.y);
+ write_reg(g, 0x21, g->p.x);
+ break;
+ }
+ write_index(g, 0x22);
+}
+
+static void set_viewport(GDisplay* g) {
+ switch(g->g.Orientation) {
+ case GDISP_ROTATE_0:
+ case GDISP_ROTATE_180:
+ write_reg(g, 0x50, g->p.x);
+ write_reg(g, 0x51, g->p.x + g->p.cx - 1);
+ write_reg(g, 0x52, g->p.y);
+ write_reg(g, 0x53, g->p.y + g->p.cy - 1);
+ break;
+
+ case GDISP_ROTATE_90:
+ case GDISP_ROTATE_270:
+ write_reg(g, 0x50, g->p.y);
+ write_reg(g, 0x51, g->p.y + g->p.cy - 1);
+ write_reg(g, 0x52, g->p.x);
+ write_reg(g, 0x53, g->p.x + g->p.cx - 1);
+ break;
+ }
+}
+
+LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
+ uint16_t cver;
+
+ // No private area for this controller
+ g->priv = 0;
+
+ // Initialise the board interface
+ init_board(g);
+
+ /* Hardware reset */
+ setpin_reset(g, TRUE);
+ gfxSleepMicroseconds(1000);
+ setpin_reset(g, FALSE);
+ gfxSleepMicroseconds(1000);
+
+ acquire_bus(g);
+ write_index(g, 0); // Get controller version
+ setreadmode(g);
+ dummy_read(g);
+ cver = read_data(g);
+ setwritemode(g);
+
+ // chinese code starts here
+ write_reg(g, 0x00, 0x0001);
+ gfxSleepMilliseconds(10);
+
+ write_reg(g, 0x15, 0x0030);
+ write_reg(g, 0x11, 0x0040);
+ write_reg(g, 0x10, 0x1628);
+ write_reg(g, 0x12, 0x0000);
+ write_reg(g, 0x13, 0x104d);
+ gfxSleepMilliseconds(10);
+ write_reg(g, 0x12, 0x0010);
+ gfxSleepMilliseconds(10);
+ write_reg(g, 0x10, 0x2620);
+ write_reg(g, 0x13, 0x344d); //304d
+ gfxSleepMilliseconds(10);
+
+ write_reg(g, 0x01, 0x0100);
+ write_reg(g, 0x02, 0x0300);
+ write_reg(g, 0x03, 0x1038);//0x1030
+ write_reg(g, 0x08, 0x0604);
+ write_reg(g, 0x09, 0x0000);
+ write_reg(g, 0x0A, 0x0008);
+
+ write_reg(g, 0x41, 0x0002);
+ write_reg(g, 0x60, 0x2700);
+ write_reg(g, 0x61, 0x0001);
+ write_reg(g, 0x90, 0x0182);
+ write_reg(g, 0x93, 0x0001);
+ write_reg(g, 0xa3, 0x0010);
+ gfxSleepMilliseconds(10);
+
+ //################# void Gamma_Set(void) ####################//
+ write_reg(g, 0x30, 0x0000);
+ write_reg(g, 0x31, 0x0502);
+ write_reg(g, 0x32, 0x0307);
+ write_reg(g, 0x33, 0x0305);
+ write_reg(g, 0x34, 0x0004);
+ write_reg(g, 0x35, 0x0402);
+ write_reg(g, 0x36, 0x0707);
+ write_reg(g, 0x37, 0x0503);
+ write_reg(g, 0x38, 0x1505);
+ write_reg(g, 0x39, 0x1505);
+ gfxSleepMilliseconds(10);
+
+ //################## void Display_ON(void) ####################//
+ write_reg(g, 0x07, 0x0001);
+ gfxSleepMilliseconds(10);
+ write_reg(g, 0x07, 0x0021);
+ write_reg(g, 0x07, 0x0023);
+ gfxSleepMilliseconds(10);
+ write_reg(g, 0x07, 0x0033);
+ gfxSleepMilliseconds(10);
+ write_reg(g, 0x07, 0x0133);
+
+ // chinese code ends here
+
+ // Finish Init
+ post_init_board(g);
+
+ // Release the bus
+ release_bus(g);
+
+ // Turn on the backlight
+ set_backlight(g, GDISP_INITIAL_BACKLIGHT);
+
+ /* Initialise the GDISP structure */
+ g->g.Width = GDISP_SCREEN_WIDTH;
+ g->g.Height = GDISP_SCREEN_HEIGHT;
+ g->g.Orientation = GDISP_ROTATE_0;
+ g->g.Powermode = powerOn;
+ g->g.Backlight = GDISP_INITIAL_BACKLIGHT;
+ g->g.Contrast = GDISP_INITIAL_CONTRAST;
+
+ return TRUE;
+}
+
+#if GDISP_HARDWARE_STREAM_WRITE
+ LLDSPEC void gdisp_lld_write_start(GDisplay *g) {
+ acquire_bus(g);
+ set_viewport(g);
+ }
+ LLDSPEC void gdisp_lld_write_color(GDisplay *g) {
+ write_data(g, COLOR2NATIVE(g->p.color));
+ }
+ LLDSPEC void gdisp_lld_write_stop(GDisplay *g) {
+ release_bus(g);
+ }
+ LLDSPEC void gdisp_lld_write_pos(GDisplay *g) {
+ set_cursor(g);
+ }
+#endif
+
+#if GDISP_HARDWARE_STREAM_READ
+ LLDSPEC void gdisp_lld_read_start(GDisplay *g) {
+ acquire_bus(g);
+ set_viewport(g);
+ set_cursor(g);
+ setreadmode(g);
+ dummy_read(g);
+ }
+ LLDSPEC color_t gdisp_lld_read_color(GDisplay *g) {
+ uint16_t data;
+
+ data = read_data(g);
+ return NATIVE2COLOR(data);
+ }
+ LLDSPEC void gdisp_lld_read_stop(GDisplay *g) {
+ setwritemode(g);
+ release_bus(g);
+ }
+#endif
+
+#if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL
+ LLDSPEC void gdisp_lld_control(GDisplay *g) {
+ switch(g->p.x) {
+ case GDISP_CONTROL_POWER:
+ if (g->g.Powermode == (powermode_t)g->p.ptr)
+ return;
+ switch((powermode_t)g->p.ptr) {
+ case powerOff:
+ acquire_bus(g);
+ write_reg(g, 0x07, 0x0000);
+ write_reg(g, 0x10, 0x0000);
+ write_reg(g, 0x11, 0x0000);
+ write_reg(g, 0x12, 0x0000);
+ write_reg(g, 0x13, 0x0000);
+ release_bus(g);
+ set_backlight(g, 0);
+ break;
+
+ case powerOn:
+ //*************Power On sequence ******************//
+ acquire_bus(g);
+ write_reg(g, 0x10, 0x0000); /* SAP, BT[3:0], AP, DSTB, SLP, STB */
+ write_reg(g, 0x11, 0x0000); /* DC1[2:0], DC0[2:0], VC[2:0] */
+ write_reg(g, 0x12, 0x0000); /* VREG1OUT voltage */
+ write_reg(g, 0x13, 0x0000); /* VDV[4:0] for VCOM amplitude */
+ gfxSleepMilliseconds(200); /* Dis-charge capacitor power voltage */
+ write_reg(g, 0x10, 0x17B0); /* SAP, BT[3:0], AP, DSTB, SLP, STB */
+ write_reg(g, 0x11, 0x0147); /* DC1[2:0], DC0[2:0], VC[2:0] */
+ gfxSleepMilliseconds(50);
+ write_reg(g, 0x12, 0x013C); /* VREG1OUT voltage */
+ gfxSleepMilliseconds(50);
+ write_reg(g, 0x13, 0x0E00); /* VDV[4:0] for VCOM amplitude */
+ write_reg(g, 0x29, 0x0009); /* VCM[4:0] for VCOMH */
+ gfxSleepMilliseconds(50);
+ write_reg(g, 0x07, 0x0173); /* 262K color and display ON */
+ release_bus(g);
+ set_backlight(g, g->g.Backlight);
+ break;
+
+ case powerSleep:
+ acquire_bus(g);
+ write_reg(g, 0x07, 0x0000); /* display OFF */
+ write_reg(g, 0x10, 0x0000); /* SAP, BT[3:0], APE, AP, DSTB, SLP */
+ write_reg(g, 0x11, 0x0000); /* DC1[2:0], DC0[2:0], VC[2:0] */
+ write_reg(g, 0x12, 0x0000); /* VREG1OUT voltage */
+ write_reg(g, 0x13, 0x0000); /* VDV[4:0] for VCOM amplitude */
+ gfxSleepMilliseconds(200); /* Dis-charge capacitor power voltage */
+ write_reg(g, 0x10, 0x0002); /* SAP, BT[3:0], APE, AP, DSTB, SLP */
+ release_bus(g);
+ gdisp_lld_backlight(g, 0);
+ break;
+
+ case powerDeepSleep:
+ acquire_bus(g);
+ write_reg(g, 0x07, 0x0000); /* display OFF */
+ write_reg(g, 0x10, 0x0000); /* SAP, BT[3:0], APE, AP, DSTB, SLP */
+ write_reg(g, 0x11, 0x0000); /* DC1[2:0], DC0[2:0], VC[2:0] */
+ write_reg(g, 0x12, 0x0000); /* VREG1OUT voltage */
+ write_reg(g, 0x13, 0x0000); /* VDV[4:0] for VCOM amplitude */
+ gfxSleepMilliseconds(200); /* Dis-charge capacitor power voltage */
+ write_reg(g, 0x10, 0x0004); /* SAP, BT[3:0], APE, AP, DSTB, SLP */
+ release_bus(g);
+ gdisp_lld_backlight(g, 0);
+ break;
+
+ default:
+ return;
+ }
+ g->g.Powermode = (powermode_t)g->p.ptr;
+ return;
+
+ case GDISP_CONTROL_ORIENTATION:
+ if (g->g.Orientation == (orientation_t)g->p.ptr)
+ return;
+ switch((orientation_t)g->p.ptr) {
+ case GDISP_ROTATE_0:
+ acquire_bus(g);
+ write_reg(g, 0x01, 0x0100);
+ write_reg(g, 0x03, 0x1038);
+ write_reg(g, 0x60, 0x2700);
+ release_bus(g);
+ g->g.Height = GDISP_SCREEN_HEIGHT;
+ g->g.Width = GDISP_SCREEN_WIDTH;
+ break;
+
+ case GDISP_ROTATE_90:
+ acquire_bus(g);
+ write_reg(g, 0x01, 0x0000);
+ write_reg(g, 0x03, 0x1030);
+ write_reg(g, 0x60, 0x2700);
+ release_bus(g);
+ g->g.Height = GDISP_SCREEN_WIDTH;
+ g->g.Width = GDISP_SCREEN_HEIGHT;
+ break;
+
+ case GDISP_ROTATE_180:
+ acquire_bus(g);
+ write_reg(g, 0x01, 0x0000);
+ write_reg(g, 0x03, 0x1038);
+ write_reg(g, 0x60, 0xa700);
+ release_bus(g);
+ g->g.Height = GDISP_SCREEN_HEIGHT;
+ g->g.Width = GDISP_SCREEN_WIDTH;
+ break;
+
+ case GDISP_ROTATE_270:
+ acquire_bus(g);
+ write_reg(g, 0x01, 0x0100);
+ write_reg(g, 0x03, 0x1030);
+ write_reg(g, 0x60, 0xA700);
+ release_bus(g);
+ g->g.Height = GDISP_SCREEN_WIDTH;
+ g->g.Width = GDISP_SCREEN_HEIGHT;
+ break;
+
+ default:
+ return;
+ }
+
+ g->g.Orientation = (orientation_t)g->p.ptr;
+ return;
+
+ case GDISP_CONTROL_BACKLIGHT:
+ if ((unsigned)g->p.ptr > 100)
+ g->p.ptr = (void *)100;
+ set_backlight(g, (unsigned)g->p.ptr);
+ g->g.Backlight = (unsigned)g->p.ptr;
+ return;
+
+ default:
+ return;
+ }
+ }
+#endif
+
+#endif /* GFX_USE_GDISP */
diff --git a/drivers/gdisp/ILI9325/gdisp_lld_board_hy_stm32_100p.h b/drivers/gdisp/ILI9325/gdisp_lld_board_hy_stm32_100p.h
deleted file mode 100644
index 3c2cc78b..00000000
--- a/drivers/gdisp/ILI9325/gdisp_lld_board_hy_stm32_100p.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * This file is subject to the terms of the GFX License. If a copy of
- * the license was not distributed with this file, you can obtain one at:
- *
- * http://ugfx.org/license.html
- */
-
-/*
- driver quickly hacked together from a chinese sourcecode that came
- with the board and existing ili9320 code by Chris van Dongen (sjaak)
- (sjaak2002 at msn.com)
-
- Also added rotation for 180 and 270 degrees and minor tweaks to
- setcursor
-
- Added code comes without warranty and free bugs. Feel free to use
- or misuse the added code :D
-*/
-
-
-/**
- * @file drivers/gdisp/ILI9325/gdisp_lld_board_hy_stm32_100p.h
- * @brief GDISP Graphic Driver subsystem board interface for the ILI9325 display.
- *
- * @addtogroup GDISP
- * @{
- */
-
-#ifndef GDISP_LLD_BOARD_H
-#define GDISP_LLD_BOARD_H
-
-#define GDISP_REG (*((volatile uint16_t *) 0x60000000)) /* RS = 0 */
-#define GDISP_RAM (*((volatile uint16_t *) 0x60020000)) /* RS = 1 */
-
-static inline void gdisp_lld_init_board(void) {
- /* FSMC setup for F1 */
- rccEnableAHB(RCC_AHBENR_FSMCEN, 0);
-
- /* set pin modes */
-/* IOBus busD = {GPIOD, PAL_WHOLE_PORT, 0};
- IOBus busE = {GPIOE, PAL_WHOLE_PORT, 0};
- palSetBusMode(&busD, PAL_MODE_STM32_ALTERNATE_PUSHPULL);
- palSetBusMode(&busE, PAL_MODE_STM32_ALTERNATE_PUSHPULL);
- palSetPadMode(GPIOE, GPIOE_TFT_RST, PAL_MODE_OUTPUT_PUSHPULL);
- palSetPadMode(GPIOD, GPIOD_TFT_LIGHT, PAL_MODE_OUTPUT_PUSHPULL); */
-
- const unsigned char FSMC_Bank = 0;
-
- /* FSMC timing */
- FSMC_Bank1->BTCR[FSMC_Bank+1] = (6) | (10 << 8) | (10 << 16);
-
- /* Bank1 NOR/SRAM control register configuration
- * This is actually not needed as already set by default after reset */
- FSMC_Bank1->BTCR[FSMC_Bank] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN;
-
-}
-
-static inline void gdisp_lld_reset_pin(bool_t state) {
- if(state)
- palClearPad(GPIOE, GPIOE_TFT_RST);
- else
- palSetPad(GPIOE, GPIOE_TFT_RST);
-}
-
-static inline void gdisp_lld_write_index(uint16_t reg) {
- GDISP_REG = reg;
-}
-
-static inline void gdisp_lld_write_data(uint16_t data) {
- GDISP_RAM = data;
-}
-
-static inline uint16_t gdisp_lld_read_data(void) {
- return GDISP_RAM;
-}
-
-static inline void gdisp_lld_backlight(uint8_t percent) {
- percent=percent; // avoid a warning
-}
-
-#endif /* GDISP_LLD_BOARD_H */
-/** @} */
-
diff --git a/drivers/gdisp/ILI9325/gdisp_lld_board_template.h b/drivers/gdisp/ILI9325/gdisp_lld_board_template.h
deleted file mode 100644
index 2dd346a3..00000000
--- a/drivers/gdisp/ILI9325/gdisp_lld_board_template.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * This file is subject to the terms of the GFX License. If a copy of
- * the license was not distributed with this file, you can obtain one at:
- *
- * http://ugfx.org/license.html
- */
-
-/**
- * @file drivers/gdisp/ILI9325/gdisp_lld_board_template.h
- * @brief GDISP Graphic Driver subsystem board interface for the ILI9325 display.
- *
- * @addtogroup GDISP
- * @{
- */
-
-#ifndef GDISP_LLD_BOARD_H
-#define GDISP_LLD_BOARD_H
-
-static inline void gdisp_lld_init_board(void) {
-
-}
-
-static inline void gdisp_lld_reset_pin(bool_t state) {
-
-}
-
-static inline void gdisp_lld_write_index(uint16_t data) {
-
-}
-
-static inline void gdisp_lld_write_data(uint16_t data) {
-
-}
-
-static inline uint16_t gdisp_lld_read_data(void) {
-
-}
-
-static inline uint16_t gdisp_lld_backlight(uint8_t percentage) {
-
-}
-
-#endif /* GDISP_LLD_BOARD_H */
-/** @} */
-
diff --git a/drivers/gdisp/ILI9325/gdisp_lld_config.h b/drivers/gdisp/ILI9325/gdisp_lld_config.h
index ac07173c..c40bd2b7 100644
--- a/drivers/gdisp/ILI9325/gdisp_lld_config.h
+++ b/drivers/gdisp/ILI9325/gdisp_lld_config.h
@@ -22,16 +22,12 @@
/* Driver hardware support. */
/*===========================================================================*/
-#define GDISP_DRIVER_NAME "ILI9325"
+#define GDISP_HARDWARE_STREAM_WRITE TRUE
+#define GDISP_HARDWARE_STREAM_READ TRUE
+#define GDISP_HARDWARE_STREAM_POS TRUE
+#define GDISP_HARDWARE_CONTROL TRUE
-#define GDISP_HARDWARE_CLEARS TRUE
-#define GDISP_HARDWARE_FILLS TRUE
-#define GDISP_HARDWARE_BITFILLS FALSE
-#define GDISP_HARDWARE_SCROLL FALSE
-#define GDISP_HARDWARE_PIXELREAD TRUE
-#define GDISP_HARDWARE_CONTROL TRUE
-
-#define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_RGB565
+#define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_RGB565
#endif /* GFX_USE_GDISP */
diff --git a/drivers/gdisp/ILI9341/ILI9341.h b/drivers/gdisp/ILI9341/ILI9341.h
new file mode 100644
index 00000000..bace6907
--- /dev/null
+++ b/drivers/gdisp/ILI9341/ILI9341.h
@@ -0,0 +1,87 @@
+
+#define LCD_VERTICAL_MAX 320
+#define LCD_HORIZONTAL_MAX 240
+
+#define ILI9341_DEVICE_CODE_READ_REG 0x00
+#define ILI9341_SOFT_RESET_REG 0x01
+#define ILI9341_IDENTINFO_R_REG 0x04
+#define ILI9341_STATUS_R_REG 0x09
+#define ILI9341_POWERMODE_R_REG 0x0A
+#define ILI9341_MADCTL_R_REG 0x0B
+#define ILI9341_PIXFORMAT_R_REG 0x0C
+#define ILI9341_IMGFORMAT_R_REG 0x0D
+#define ILI9341_SIGMODE_R_REG 0x0E
+#define ILI9341_SD_RESULT_R_REG 0x0F
+#define ILI9341_SLEEP_ENTER_REG 0x10
+#define ILI9341_SLEEP_OUT_REG 0x11
+#define ILI9341_PARTIALMODE_REG 0x12
+#define ILI9341_NORDISPMODE_REG 0x13
+#define ILI9341_INVERSIONOFF_REG 0x20
+#define ILI9341_INVERSIONON_REG 0x21
+#define ILI9341_GAMMASET_REG 0x26
+#define ILI9341_DISPLAYOFF_REG 0x28
+#define ILI9341_DISPLAYON_REG 0x29
+#define ILI9341_COLADDRSET_REG 0x2A
+#define ILI9341_PAGEADDRSET_REG 0x2B
+#define ILI9341_MEMORYWRITE_REG 0x2C
+#define ILI9341_COLORSET_REG 0x2D
+#define ILI9341_MEMORYREAD_REG 0x2E
+#define ILI9341_PARTIALAREA_REG 0x30
+#define ILI9341_VERTSCROLL_REG 0x33
+#define ILI9341_TEAREFFECTLINEOFF_REG 0x34
+#define ILI9341_TEAREFFECTLINEON_REG 0x35
+#define ILI9341_MEMACCESS_REG 0x36
+#define ILI9341_VERSCRSRART_REG 0x37
+#define ILI9341_IDLEMODEOFF_REG 0x38
+#define ILI9341_IDLEMODEON_REG 0x39
+#define ILI9341_PIXFORMATSET_REG 0x3A
+#define ILI9341_WRITEMEMCONTINUE_REG 0x3C
+#define ILI9341_READMEMCONTINUE_REG 0x3E
+#define ILI9341_SETTEATSCAN_REG 0x44
+#define ILI9341_GETSCANLINE_REG 0x45
+#define ILI9341_WRITEBRIGHT_REG 0x51
+#define ILI9341_READBRIGHT_REG 0x52
+#define ILI9341_WRITECTRL_REG 0x53
+#define ILI9341_READCTRL_REG 0x54
+#define ILI9341_WRITECABC_REG 0x55
+#define ILI9341_READCABC_REG 0x56
+#define ILI9341_WRITECABCMB_REG 0x5E
+#define ILI9341_READCABCMB_REG 0x5F
+#define ILI9341_RGB_ISCTL_REG 0xB0
+#define ILI9341_FRAMECTL_NOR_REG 0xB1
+#define ILI9341_FRAMECTL_IDLE_REG 0xB2
+#define ILI9341_FRAMECTL_PARTIAL_REG 0xB3
+#define ILI9341_INVERCTL_REG 0xB4
+#define ILI9341_BLANKPORCTL_REG 0xB5
+#define ILI9341_FUNCTONCTL_REG 0xB6
+#define ILI9341_ENTRYMODE_REG 0xB7
+#define ILI9341_BLIGHTCTL1_REG 0xB8
+#define ILI9341_BLIGHTCTL2_REG 0xB9
+#define ILI9341_BLIGHTCTL3_REG 0xBA
+#define ILI9341_BLIGHTCTL4_REG 0xBB
+#define ILI9341_BLIGHTCTL5_REG 0xBC
+#define ILI9341_BLIGHTCTL7_REG 0xBE
+#define ILI9341_BLIGHTCTL8_REG 0xBF
+#define ILI9341_POWERCTL1_REG 0xC0
+#define ILI9341_POWERCTL2_REG 0xC1
+#define ILI9341_VCOMCTL1_REG 0xC5
+#define ILI9341_VCOMCTL2_REG 0xC7
+#define ILI9341_POWERCTLA_REG 0xCB
+#define ILI9341_POWERCTLB_REG 0xCF
+#define ILI9341_NVMEMWRITE_REG 0xD0
+#define ILI9341_NVMEMPROTECTKEY_REG 0xD1
+#define ILI9341_NVMEMSTATUS_REG 0xD2
+#define ILI9341_READID4_REG 0xD3
+#define ILI9341_READID1_REG 0xDA
+#define ILI9341_READID2_REG 0xDB
+#define ILI9341_READID3_REG 0xDC
+#define ILI9341_POSGAMMACORRECTION_REG 0xE0
+#define ILI9341_NEGGAMMACORRECTION_REG 0xE1
+#define ILI9341_DIGGAMCTL1_REG 0xE2
+#define ILI9341_DIGGAMCTL2_REG 0xE3
+#define ILI9341_DIVTIMCTL_A_REG 0xE8
+#define ILI9341_DIVTIMCTL_B_REG 0xEA
+#define ILI9341_POWONSEQCTL_REG 0xED
+#define ILI9341_ENABLE_3G_REG 0xF2
+#define ILI9341_INTERFCTL_REG 0xF6
+#define ILI9341_PUMPRATIOCTL_REG 0xF7
diff --git a/drivers/gdisp/ILI9341/board_ILI9341_template.h b/drivers/gdisp/ILI9341/board_ILI9341_template.h
new file mode 100644
index 00000000..b8f55dc1
--- /dev/null
+++ b/drivers/gdisp/ILI9341/board_ILI9341_template.h
@@ -0,0 +1,154 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/ILI9341/board_ILI9341_template.h
+ * @brief GDISP Graphic Driver subsystem board interface for the ILI9341 display.
+ *
+ * @addtogroup GDISP
+ * @{
+ */
+
+#ifndef _GDISP_LLD_BOARD_H
+#define _GDISP_LLD_BOARD_H
+
+/**
+ * @brief Initialise the board for the display.
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @note Set the g->board member to whatever is appropriate. For multiple
+ * displays this might be a pointer to the appropriate register set.
+ *
+ * @notapi
+ */
+static inline void init_board(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief After the initialisation.
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void post_init_board(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Set or clear the lcd reset pin.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] state TRUE = lcd in reset, FALSE = normal operation
+ *
+ * @notapi
+ */
+static inline void setpin_reset(GDisplay *g, bool_t state) {
+ (void) g;
+ (void) state;
+}
+
+/**
+ * @brief Set the lcd back-light level.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] percent 0 to 100%
+ *
+ * @notapi
+ */
+static inline void set_backlight(GDisplay *g, uint8_t percent) {
+ (void) g;
+ (void) percent;
+}
+
+/**
+ * @brief Take exclusive control of the bus
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void acquire_bus(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Release exclusive control of the bus
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void release_bus(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Send data to the index register.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] index The index register to set
+ *
+ * @notapi
+ */
+static inline void write_index(GDisplay *g, uint16_t index) {
+ (void) g;
+ (void) index;
+}
+
+/**
+ * @brief Send data to the lcd.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] data The data to send
+ *
+ * @notapi
+ */
+static inline void write_data(GDisplay *g, uint16_t data) {
+ (void) g;
+ (void) data;
+}
+
+/**
+ * @brief Set the bus in read mode
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void setreadmode(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Set the bus back into write mode
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void setwritemode(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Read data from the lcd.
+ * @return The data from the lcd
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline uint16_t read_data(GDisplay *g) {
+ (void) g;
+ return 0;
+}
+
+#endif /* _GDISP_LLD_BOARD_H */
+/** @} */
diff --git a/drivers/gdisp/ILI9341/gdisp_lld.mk b/drivers/gdisp/ILI9341/gdisp_lld.mk
new file mode 100644
index 00000000..326b67ad
--- /dev/null
+++ b/drivers/gdisp/ILI9341/gdisp_lld.mk
@@ -0,0 +1,2 @@
+GFXINC += $(GFXLIB)/drivers/gdisp/ILI9341
+GFXSRC += $(GFXLIB)/drivers/gdisp/ILI9341/gdisp_lld_ILI9341.c
diff --git a/drivers/gdisp/ILI9341/gdisp_lld_ILI9341.c b/drivers/gdisp/ILI9341/gdisp_lld_ILI9341.c
new file mode 100644
index 00000000..2513c48d
--- /dev/null
+++ b/drivers/gdisp/ILI9341/gdisp_lld_ILI9341.c
@@ -0,0 +1,353 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/ILI9341/gdisp_lld.c
+ * @brief GDISP Graphics Driver subsystem low level driver source for
+ * the ILI9341 and compatible HVGA display
+ */
+
+#include "gfx.h"
+
+#if GFX_USE_GDISP
+
+#if defined(GDISP_SCREEN_HEIGHT)
+ #warning "GDISP: This low level driver does not support setting a screen size. It is being ignored."
+ #undef GISP_SCREEN_HEIGHT
+#endif
+#if defined(GDISP_SCREEN_WIDTH)
+ #warning "GDISP: This low level driver does not support setting a screen size. It is being ignored."
+ #undef GDISP_SCREEN_WIDTH
+#endif
+
+#define GDISP_DRIVER_VMT GDISPVMT_ILI9341
+#include "../drivers/gdisp/ILI9341/gdisp_lld_config.h"
+#include "gdisp/lld/gdisp_lld.h"
+
+#include "board_ILI9341.h"
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+#ifndef GDISP_SCREEN_HEIGHT
+ #define GDISP_SCREEN_HEIGHT 320
+#endif
+#ifndef GDISP_SCREEN_WIDTH
+ #define GDISP_SCREEN_WIDTH 240
+#endif
+#ifndef GDISP_INITIAL_CONTRAST
+ #define GDISP_INITIAL_CONTRAST 50
+#endif
+#ifndef GDISP_INITIAL_BACKLIGHT
+ #define GDISP_INITIAL_BACKLIGHT 100
+#endif
+
+#include "../drivers/gdisp/ILI9341/ILI9341.h"
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+// Some common routines and macros
+#define dummy_read(g) { volatile uint16_t dummy; dummy = read_data(g); (void) dummy; }
+#define write_reg(g, reg, data) { write_index(g, reg); write_data(g, data); }
+#define write_data16(g, data) { write_data(g, data >> 8); write_data(g, (uint8_t)data); }
+#define delay(us) gfxSleepMicroseconds(us)
+#define delayms(ms) gfxSleepMilliseconds(ms)
+
+static void set_viewport(GDisplay *g) {
+ write_index(g, 0x2A);
+ write_data(g, (g->p.x >> 8));
+ write_data(g, (uint8_t) g->p.x);
+ write_data(g, (g->p.x + g->p.cx - 1) >> 8);
+ write_data(g, (uint8_t) (g->p.x + g->p.cx - 1));
+
+ write_index(g, 0x2B);
+ write_data(g, (g->p.y >> 8));
+ write_data(g, (uint8_t) g->p.y);
+ write_data(g, (g->p.y + g->p.cy - 1) >> 8);
+ write_data(g, (uint8_t) (g->p.y + g->p.cy - 1));
+}
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
+ // No private area for this controller
+ g->priv = 0;
+
+ // Initialise the board interface
+ init_board(g);
+
+ // Hardware reset
+ setpin_reset(g, TRUE);
+ gfxSleepMilliseconds(20);
+ setpin_reset(g, FALSE);
+ gfxSleepMilliseconds(20);
+
+ // Get the bus for the following initialisation commands
+ acquire_bus(g);
+
+ write_index(g, 0x01); //software reset
+ chThdSleepMilliseconds(5);
+ write_index(g, 0x28);
+ // display off
+ //---------------------------------------------------------
+ // magic?
+ write_index(g, 0xcf);
+ write_data(g, 0x00);
+ write_data(g, 0x83);
+ write_data(g, 0x30);
+
+ write_index(g, 0xed);
+ write_data(g, 0x64);
+ write_data(g, 0x03);
+ write_data(g, 0x12);
+ write_data(g, 0x81);
+ write_index(g, 0xe8);
+ write_data(g, 0x85);
+ write_data(g, 0x01);
+ write_data(g, 0x79);
+ write_index(g, 0xcb);
+ write_data(g, 0x39);
+ write_data(g, 0x2c);
+ write_data(g, 0x00);
+ write_data(g, 0x34);
+ write_data(g, 0x02);
+ write_index(g, 0xf7);
+ write_data(g, 0x20);
+ write_index(g, 0xea);
+ write_data(g, 0x00);
+ write_data(g, 0x00);
+ //------------power control------------------------------
+ write_index(g, 0xc0); //power control
+ write_data(g, 0x26);
+ write_index(g, 0xc1); //power control
+ write_data(g, 0x11);
+ //--------------VCOM
+ write_index(g, 0xc5); //vcom control
+ write_data(g, 0x35);//35
+ write_data(g, 0x3e);//3E
+ write_index(g, 0xc7); //vcom control
+ write_data(g, 0xbe); // 0x94
+ //------------memory access control------------------------
+ write_index(g, 0x36);
+ // memory access control
+ write_data(g, 0x48); //0048 my,mx,mv,ml,BGR,mh,0.0
+ write_index(g, 0x3a); // pixel format set
+ write_data(g, 0x55);//16bit /pixel
+ //----------------- frame rate------------------------------
+ write_index(g, 0xb1);
+ // frame rate
+ write_data(g, 0x00);
+ write_data(g, 0x1B); //70
+ //----------------Gamma---------------------------------
+ write_index(g, 0xf2); // 3Gamma Function Disable
+ write_data(g, 0x08);
+ write_index(g, 0x26);
+ write_data(g, 0x01); // gamma set 4 gamma curve 01/02/04/08
+
+ write_index(g, 0xE0); //positive gamma correction
+ write_data(g, 0x1f);
+ write_data(g, 0x1a);
+ write_data(g, 0x18);
+ write_data(g, 0x0a);
+ write_data(g, 0x0f);
+ write_data(g, 0x06);
+ write_data(g, 0x45);
+ write_data(g, 0x87);
+ write_data(g, 0x32);
+ write_data(g, 0x0a);
+ write_data(g, 0x07);
+ write_data(g, 0x02);
+ write_data(g, 0x07);
+ write_data(g, 0x05);
+ write_data(g, 0x00);
+ write_index(g, 0xE1); //negamma correction
+ write_data(g, 0x00);
+ write_data(g, 0x25);
+ write_data(g, 0x27);
+ write_data(g, 0x05);
+ write_data(g, 0x10);
+ write_data(g, 0x09);
+ write_data(g, 0x3a);
+ write_data(g, 0x78);
+ write_data(g, 0x4d);
+ write_data(g, 0x05);
+ write_data(g, 0x18);
+ write_data(g, 0x0d);
+ write_data(g, 0x38);
+ write_data(g, 0x3a);
+ write_data(g, 0x1f);
+ //--------------ddram ---------------------
+ write_index(g, 0x2a);
+ // column set
+ // size = 239
+ write_data(g, 0x00);
+ write_data(g, 0x00);
+ write_data(g, 0x00);
+ write_data(g, 0xEF);
+ write_index(g, 0x2b);
+ // page address set
+ // size = 319
+ write_data(g, 0x00);
+ write_data(g, 0x00);
+ write_data(g, 0x01);
+ write_data(g, 0x3F);
+ // write_index(g, 0x34);
+ //write_index(g, 0x35);
+ // tearing effect off
+ // tearing effect on
+ // write_index(g, 0xb4); // display inversion
+ // write_data(g, 0x00);
+ write_index(g, 0xb7); //entry mode set
+ write_data(g, 0x07);
+ //-----------------display---------------------
+ write_index(g, 0xb6);
+ // display function control
+ write_data(g, 0x0a);
+ write_data(g, 0x82);
+ write_data(g, 0x27);
+ write_data(g, 0x00);
+ write_index(g, 0x11); //sleep out
+ chThdSleepMilliseconds(100);
+ write_index(g, 0x29); // display on
+ chThdSleepMilliseconds(100);
+
+ // Finish Init
+ post_init_board(g);
+
+ // Release the bus
+ release_bus(g);
+
+ /* Turn on the back-light */
+ set_backlight(g, GDISP_INITIAL_BACKLIGHT);
+
+ /* Initialise the GDISP structure */
+ g->g.Width = GDISP_SCREEN_WIDTH;
+ g->g.Height = GDISP_SCREEN_HEIGHT;
+ g->g.Orientation = GDISP_ROTATE_0;
+ g->g.Powermode = powerOn;
+ g->g.Backlight = GDISP_INITIAL_BACKLIGHT;
+ g->g.Contrast = GDISP_INITIAL_CONTRAST;
+ return TRUE;
+}
+
+#if GDISP_HARDWARE_STREAM_WRITE
+ LLDSPEC void gdisp_lld_write_start(GDisplay *g) {
+ acquire_bus(g);
+ set_viewport(g);
+ write_index(g, 0x2C);
+ }
+ LLDSPEC void gdisp_lld_write_color(GDisplay *g) {
+ write_data16(g, COLOR2NATIVE(g->p.color));
+ }
+ LLDSPEC void gdisp_lld_write_stop(GDisplay *g) {
+ release_bus(g);
+ }
+#endif
+
+#if GDISP_HARDWARE_STREAM_READ
+ LLDSPEC void gdisp_lld_read_start(GDisplay *g) {
+ acquire_bus(g);
+ set_viewport(g);
+ write_index(g, 0x2E);
+ setreadmode(g);
+ dummy_read(g);
+ }
+ LLDSPEC color_t gdisp_lld_read_color(GDisplay *g) {
+ uint16_t data;
+
+ data = read_data(g);
+ return NATIVE2COLOR(data);
+ }
+ LLDSPEC void gdisp_lld_read_stop(GDisplay *g) {
+ setwritemode(g);
+ release_bus(g);
+ }
+#endif
+
+#if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL
+ LLDSPEC void gdisp_lld_control(GDisplay *g) {
+ switch(g->p.x) {
+ case GDISP_CONTROL_POWER:
+ if (g->g.Powermode == (powermode_t)g->p.ptr)
+ return;
+ switch((powermode_t)g->p.ptr) {
+ case powerOff:
+ case powerSleep:
+ case powerDeepSleep:
+ acquire_bus(g);
+ write_reg(g, 0x0010, 0x0001); /* enter sleep mode */
+ release_bus(g);
+ break;
+ case powerOn:
+ acquire_bus(g);
+ write_reg(g, 0x0010, 0x0000); /* leave sleep mode */
+ release_bus(g);
+ break;
+ default:
+ return;
+ }
+ g->g.Powermode = (powermode_t)g->p.ptr;
+ return;
+
+ case GDISP_CONTROL_ORIENTATION:
+ if (g->g.Orientation == (orientation_t)g->p.ptr)
+ return;
+ switch((orientation_t)g->p.ptr) {
+ case GDISP_ROTATE_0:
+ acquire_bus(g);
+ write_reg(g, 0x36, 0x00); /* X and Y axes non-inverted */
+ release_bus(g);
+ g->g.Height = GDISP_SCREEN_HEIGHT;
+ g->g.Width = GDISP_SCREEN_WIDTH;
+ break;
+ case GDISP_ROTATE_90:
+ acquire_bus(g);
+ write_reg(g, 0x36, 0xE8); /* Invert X and Y axes */
+ release_bus(g);
+ g->g.Height = GDISP_SCREEN_WIDTH;
+ g->g.Width = GDISP_SCREEN_HEIGHT;
+ break;
+ case GDISP_ROTATE_180:
+ acquire_bus(g);
+ write_reg(g, 0x36, 0x88); /* X and Y axes non-inverted */
+ release_bus(g);
+ g->g.Height = GDISP_SCREEN_HEIGHT;
+ g->g.Width = GDISP_SCREEN_WIDTH;
+ break;
+ case GDISP_ROTATE_270:
+ acquire_bus(g);
+ write_reg(g, 0x36, 0x28); /* Invert X and Y axes */
+ release_bus(g);
+ g->g.Height = GDISP_SCREEN_WIDTH;
+ g->g.Width = GDISP_SCREEN_HEIGHT;
+ break;
+ default:
+ return;
+ }
+ g->g.Orientation = (orientation_t)g->p.ptr;
+ return;
+
+ case GDISP_CONTROL_BACKLIGHT:
+ if ((unsigned)g->p.ptr > 100)
+ g->p.ptr = (void *)100;
+ set_backlight(g, (unsigned)g->p.ptr);
+ g->g.Backlight = (unsigned)g->p.ptr;
+ return;
+
+ //case GDISP_CONTROL_CONTRAST:
+ default:
+ return;
+ }
+ }
+#endif
+
+#endif /* GFX_USE_GDISP */
diff --git a/drivers/gdisp/ILI9341/gdisp_lld_config.h b/drivers/gdisp/ILI9341/gdisp_lld_config.h
new file mode 100644
index 00000000..668a06c9
--- /dev/null
+++ b/drivers/gdisp/ILI9341/gdisp_lld_config.h
@@ -0,0 +1,35 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/ILI9481/gdisp_lld_config.h
+ * @brief GDISP Graphics Driver subsystem low level driver source for
+ * the ILI9481 and compatible HVGA display
+ *
+ * @addtogroup GDISP
+ * @{
+ */
+
+#ifndef _GDISP_LLD_CONFIG_H
+#define _GDISP_LLD_CONFIG_H
+
+#if GFX_USE_GDISP
+
+/*===========================================================================*/
+/* Driver hardware support. */
+/*===========================================================================*/
+
+#define GDISP_HARDWARE_STREAM_WRITE TRUE
+//#define GDISP_HARDWARE_STREAM_READ TRUE
+#define GDISP_HARDWARE_CONTROL TRUE
+
+#define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_RGB565
+
+#endif /* GFX_USE_GDISP */
+
+#endif /* _GDISP_LLD_CONFIG_H */
+/** @} */
diff --git a/drivers/gdisp/ILI9481/board_ILI9481_template.h b/drivers/gdisp/ILI9481/board_ILI9481_template.h
new file mode 100644
index 00000000..7824c936
--- /dev/null
+++ b/drivers/gdisp/ILI9481/board_ILI9481_template.h
@@ -0,0 +1,155 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/ILI9481/board_ILI9481_template.h
+ * @brief GDISP Graphics Driver subsystem low level driver source for
+ * the ILI9481 and compatible HVGA display
+ *
+ * @addtogroup GDISP
+ * @{
+ */
+
+#ifndef _GDISP_LLD_BOARD_H
+#define _GDISP_LLD_BOARD_H
+
+/**
+ * @brief Initialise the board for the display.
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @note Set the g->board member to whatever is appropriate. For multiple
+ * displays this might be a pointer to the appropriate register set.
+ *
+ * @notapi
+ */
+static inline void init_board(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief After the initialisation.
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void post_init_board(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Set or clear the lcd reset pin.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] state TRUE = lcd in reset, FALSE = normal operation
+ *
+ * @notapi
+ */
+static inline void setpin_reset(GDisplay *g, bool_t state) {
+ (void) g;
+ (void) state;
+}
+
+/**
+ * @brief Set the lcd back-light level.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] percent 0 to 100%
+ *
+ * @notapi
+ */
+static inline void set_backlight(GDisplay *g, uint8_t percent) {
+ (void) g;
+ (void) percent;
+}
+
+/**
+ * @brief Take exclusive control of the bus
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void acquire_bus(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Release exclusive control of the bus
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void release_bus(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Send data to the index register.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] index The index register to set
+ *
+ * @notapi
+ */
+static inline void write_index(GDisplay *g, uint16_t index) {
+ (void) g;
+ (void) index;
+}
+
+/**
+ * @brief Send data to the lcd.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] data The data to send
+ *
+ * @notapi
+ */
+static inline void write_data(GDisplay *g, uint16_t data) {
+ (void) g;
+ (void) data;
+}
+
+/**
+ * @brief Set the bus in read mode
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void setreadmode(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Set the bus back into write mode
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void setwritemode(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Read data from the lcd.
+ * @return The data from the lcd
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline uint16_t read_data(GDisplay *g) {
+ (void) g;
+ return 0;
+}
+
+#endif /* _GDISP_LLD_BOARD_H */
+/** @} */
diff --git a/drivers/gdisp/ILI9481/gdisp_lld.c b/drivers/gdisp/ILI9481/gdisp_lld.c
deleted file mode 100644
index cb407dce..00000000
--- a/drivers/gdisp/ILI9481/gdisp_lld.c
+++ /dev/null
@@ -1,598 +0,0 @@
-/*
- * This file is subject to the terms of the GFX License. If a copy of
- * the license was not distributed with this file, you can obtain one at:
- *
- * http://ugfx.org/license.html
- */
-
-/**
- * @file drivers/gdisp/ILI9481/gdisp_lld.c
- * @brief GDISP Graphics Driver subsystem low level driver source for
- * the ILI9481 and compatible HVGA display
- *
- * @addtogroup GDISP
- * @{
- */
-
-#include "gfx.h"
-
-#if GFX_USE_GDISP /*|| defined(__DOXYGEN__)*/
-
-/* Include the emulation code for things we don't support */
-#include "gdisp/lld/emulation.c"
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-#if defined(GDISP_SCREEN_HEIGHT)
- #warning "GDISP: This low level driver does not support setting a screen size. It is being ignored."
- #undef GISP_SCREEN_HEIGHT
-#endif
-#if defined(GDISP_SCREEN_WIDTH)
- #warning "GDISP: This low level driver does not support setting a screen size. It is being ignored."
- #undef GDISP_SCREEN_WIDTH
-#endif
-
-#define GDISP_SCREEN_HEIGHT 480
-#define GDISP_SCREEN_WIDTH 320
-
-#define GDISP_INITIAL_CONTRAST 50
-#define GDISP_INITIAL_BACKLIGHT 100
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-#include "gdisp_lld_board.h"
-
-// Some common routines and macros
-#define write_reg(reg, data) { write_index(reg); write_data(data); }
-#define stream_start() write_index(0x2C);
-#define stream_stop()
-#define delay(us) gfxSleepMicroseconds(us)
-#define delayms(ms) gfxSleepMilliseconds(ms)
-
-static inline void set_cursor(coord_t x, coord_t y) {
- write_index(0x2A);
- write_data((x >> 8));
- write_data((uint8_t) x);
- write_data((x) >> 8);
- write_data((uint8_t) (x));
-
- write_index(0x2B);
- write_data((y >> 8));
- write_data((uint8_t) y);
- write_data((y) >> 8);
- write_data((uint8_t) (y));
-}
-
-static void set_viewport(coord_t x, coord_t y, coord_t cx, coord_t cy) {
- write_index(0x2A);
- write_data((x >> 8));
- write_data((uint8_t) x);
- write_data((x + cx - 1) >> 8);
- write_data((uint8_t) (x + cx - 1));
-
- write_index(0x2B);
- write_data((y >> 8));
- write_data((uint8_t) y);
- write_data((y + cy - 1) >> 8);
- write_data((uint8_t) (y + cy - 1));
-}
-
-static inline void reset_viewport(void) {
- set_viewport(0, 0, GDISP.Width, GDISP.Height);
-}
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/* ---- Required Routines ---- */
-/*
- The following 2 routines are required.
- All other routines are optional.
-*/
-
-/**
- * @brief Low level GDISP driver initialization.
- *
- * @notapi
- */
-bool_t gdisp_lld_init(void) {
- /* Initialise your display */
- init_board();
-
- /* Hardware reset */
- setpin_reset(TRUE);
- delayms(20);
- setpin_reset(FALSE);
- delayms(20);
-
- /* Get the bus for the following initialisation commands */
- acquire_bus();
-
- /* Enable Access to all Manufacturer commands (0xB0 and higher opcodes) */
- write_index(0xB0);
- write_data(0x00);
-
- /* Frame Memory Access and Interface Setting */
- write_index(0xB3);
- write_data(0x02);
- write_data(0x00);
- write_data(0x00);
- write_data(0x10);
-
- /* Display Mode and Frame Memory Write Mode Setting (B4h) */
- /* Use internal clock for synchronization */
- /* Use DBI interface (only DB0-17, no HSYNC, VSYNC or CLK) */
- write_index(0xB4);
- write_data(0x00);
-
- /* Internal Backlight Control */
-/* write_index(0xB9); /*PWM Settings for Brightness Control */
-/* write_data(0x01); /* Disabled by default. */
-/* write_data(0xFF); /*0xFF = Max brightness */
-/* write_data(0xFF);
-/* write_data(0x18);
-
- /* Panel Driving settings */
- write_index(0xC0);
- write_data(0x03);
- write_data(0x3B);
- write_data(0x00);
- write_data(0x00);
- write_data(0x00);
- write_data(0x01);
- write_data(0x00); /* NW */
- write_data(0x43);
-
- /* Display timings in Operating Mode */
- write_index(0xC1);
- write_data(0x08);
- write_data(0x15); /* CLOCK */
- write_data(0x08);
- write_data(0x08);
-
- /* S/VCOM/Gate Driving timing setting */
- write_index(0xC4);
- write_data(0x15);
- write_data(0x03);
- write_data(0x03);
- write_data(0x01);
-
- /* Interface Setting */
- write_index(0xC6);
- write_data(0x02);
-
- /* Gamma Setting - should be changed if using a different panel */
- write_index(0xC8);
- write_data(0x0C);
- write_data(0x05);
- write_data(0x0A); /*0X12 */
- write_data(0x6B); /*0x7D */
- write_data(0x04);
- write_data(0x06); /*0x08 */
- write_data(0x15); /*0x0A */
- write_data(0x10);
- write_data(0x00);
- write_data(0x60); /*0x23 */
-
- /* Address Mode setting */
- write_index(0x36);
- write_data(0x00);
-
- /* Set Pixel Format = 16 bits per pixel */
- /* The driver supports upto 24 bits per pixel, with dither */
- write_index(0x3A);
- write_data(0x55);
-
- /* Exit Idle Mode */
- write_index(0x38);
-
- /* Power Setting */
- write_index(0xD0);
- write_data(0x07);
- write_data(0x07); /* VCI = VCI1 */
- write_data(0x14); /* VRH 0x1D */
- write_data(0xA2); /* BT 0x06 */
-
- /* VCOM Setting */
- write_index(0xD1);
- write_data(0x03);
- write_data(0x5A); /* VCM 0x5A */
- write_data(0x10); /* VDV */
-
- /* Power Setting for Normal Mode */
- write_index(0xD2);
- write_data(0x03);
- write_data(0x04); /* 0x24 */
- write_data(0x04);
-
- /* Exit Sleep Mode */
- write_index(0x11);
- delay(150);
-
- /* Display ON */
- write_index(0x29);
- delay(30);
-
- /* Release the bus */
- release_bus();
-
- /* Turn on the back-light */
- set_backlight(GDISP_INITIAL_BACKLIGHT);
-
- /* Initialise the GDISP structure */
- GDISP.Width = GDISP_SCREEN_WIDTH;
- GDISP.Height = GDISP_SCREEN_HEIGHT;
- GDISP.Orientation = GDISP_ROTATE_0;
- GDISP.Powermode = powerOn;
- GDISP.Backlight = GDISP_INITIAL_BACKLIGHT;
- GDISP.Contrast = GDISP_INITIAL_CONTRAST;
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- GDISP.clipx0 = 0;
- GDISP.clipy0 = 0;
- GDISP.clipx1 = GDISP.Width;
- GDISP.clipy1 = GDISP.Height;
- #endif
- return TRUE;
-}
-
-/**
- * @brief Draws a pixel on the display.
- *
- * @param[in] x X location of the pixel
- * @param[in] y Y location of the pixel
- * @param[in] color The color of the pixel
- *
- * @notapi
- */
-void gdisp_lld_draw_pixel(coord_t x, coord_t y, color_t color) {
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- if (x < GDISP.clipx0 || y < GDISP.clipy0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
- #endif
-
- acquire_bus();
-
- set_cursor(x, y);
- write_reg(0x002c, color);
-
- release_bus();
-}
-
-/* ---- Optional Routines ---- */
-/*
- All the below routines are optional.
- Defining them will increase speed but everything
- will work if they are not defined.
- If you are not using a routine - turn it off using
- the appropriate GDISP_HARDWARE_XXXX macro.
- Don't bother coding for obvious similar routines if
- there is no performance penalty as the emulation software
- makes a good job of using similar routines.
- eg. If gfillarea() is defined there is little
- point in defining clear() unless the
- performance bonus is significant.
- For good performance it is suggested to implement
- fillarea() and blitarea().
-*/
-
-#if GDISP_HARDWARE_CLEARS || defined(__DOXYGEN__)
- /**
- * @brief Clear the display.
- * @note Optional - The high level driver can emulate using software.
- *
- * @param[in] color The color of the pixel
- *
- * @notapi
- */
- void gdisp_lld_clear(color_t color) {
- unsigned i;
-
- acquire_bus();
- reset_viewport();
- stream_start();
- for(i = 0; i < GDISP_SCREEN_WIDTH * GDISP_SCREEN_HEIGHT; i++)
- write_data(color);
- stream_stop();
- release_bus();
- }
-#endif
-
-#if GDISP_HARDWARE_FILLS || defined(__DOXYGEN__)
- /**
- * @brief Fill an area with a color.
- * @note Optional - The high level driver can emulate using software.
- *
- * @param[in] x, y The start filled area
- * @param[in] cx, cy The width and height to be filled
- * @param[in] color The color of the fill
- *
- * @notapi
- */
- void gdisp_lld_fill_area(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
- unsigned i, area;
-
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; }
- if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; }
- if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
- if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
- if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
- #endif
-
- area = cx*cy;
-
- acquire_bus();
-
- set_viewport(x, y, cx, cy);
-
- stream_start();
- for(i = 0; i < area; i++)
- write_data(color);
- stream_stop();
-
- release_bus();
- }
-#endif
-
-#if GDISP_HARDWARE_BITFILLS || defined(__DOXYGEN__)
- /**
- * @brief Fill an area with a bitmap.
- * @note Optional - The high level driver can emulate using software.
- *
- * @param[in] x, y The start filled area
- * @param[in] cx, cy The width and height to be filled
- * @param[in] srcx, srcy The bitmap position to start the fill from
- * @param[in] srccx The width of a line in the bitmap.
- * @param[in] buffer The pixels to use to fill the area.
- *
- * @notapi
- */
- void gdisp_lld_blit_area_ex(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx, coord_t srcy, coord_t srccx, const pixel_t *buffer) {
- coord_t endx, endy;
- unsigned lg;
-
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; srcx += GDISP.clipx0 - x; x = GDISP.clipx0; }
- if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; srcy += GDISP.clipy0 - y; y = GDISP.clipy0; }
- if (srcx+cx > srccx) cx = srccx - srcx;
- if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
- if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
- if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
- #endif
-
- acquire_bus();
- set_viewport(x, y, cx, cy);
- stream_start();
-
- endx = srcx + cx;
- endy = y + cy;
- lg = srccx - cx;
- buffer += srcx + srcy * srccx;
- for(; y < endy; y++, buffer += lg)
- for(x=srcx; x < endx; x++)
- write_data(*buffer++);
- stream_stop();
- release_bus();
- }
-#endif
-
-#if (GDISP_NEED_PIXELREAD && GDISP_HARDWARE_PIXELREAD) || defined(__DOXYGEN__)
- /**
- * @brief Get the color of a particular pixel.
- * @note Optional.
- * @note If x,y is off the screen, the result is undefined.
- *
- * @param[in] x, y The pixel to be read
- *
- * @notapi
- */
- color_t gdisp_lld_get_pixel_color(coord_t x, coord_t y) {
- color_t color;
-
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- if (x < 0 || x >= GDISP.Width || y < 0 || y >= GDISP.Height) return 0;
- #endif
-
- acquire_bus();
- set_cursor(x, y);
- stream_start();
- color = read_data(); // dummy read
- color = read_data();
- stream_stop();
- release_bus();
-
- return color;
- }
-#endif
-
-#if (GDISP_NEED_SCROLL && GDISP_HARDWARE_SCROLL) || defined(__DOXYGEN__)
- /**
- * @brief Scroll vertically a section of the screen.
- * @note Optional.
- * @note If x,y + cx,cy is off the screen, the result is undefined.
- * @note If lines is >= cy, it is equivelent to a area fill with bgcolor.
- *
- * @param[in] x, y The start of the area to be scrolled
- * @param[in] cx, cy The size of the area to be scrolled
- * @param[in] lines The number of lines to scroll (Can be positive or negative)
- * @param[in] bgcolor The color to fill the newly exposed area.
- *
- * @notapi
- */
- void gdisp_lld_vertical_scroll(coord_t x, coord_t y, coord_t cx, coord_t cy, int lines, color_t bgcolor) {
- static color_t buf[((GDISP_SCREEN_HEIGHT > GDISP_SCREEN_WIDTH ) ? GDISP_SCREEN_HEIGHT : GDISP_SCREEN_WIDTH)];
- coord_t row0, row1;
- unsigned i, gap, abslines, j;
-
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; }
- if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; }
- if (!lines || cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
- if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
- if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
- #endif
-
- abslines = lines < 0 ? -lines : lines;
-
- acquire_bus();
- if ((coord_t)abslines >= cy) {
- abslines = cy;
- gap = 0;
- } else {
- gap = cy - abslines;
- for(i = 0; i < gap; i++) {
- if(lines > 0) {
- row0 = y + i + lines;
- row1 = y + i;
- } else {
- row0 = (y - i - 1) + lines;
- row1 = (y - i - 1);
- }
-
- /* read row0 into the buffer and then write at row1*/
- set_viewport(x, row0, cx, 1);
- stream_start();
- j = read_data(); // dummy read
- for (j = 0; (coord_t)j < cx; j++)
- buf[j] = read_data();
- stream_stop();
-
- set_viewport(x, row1, cx, 1);
- stream_start();
- for (j = 0; (coord_t)j < cx; j++)
- write_data(buf[j]);
- stream_stop();
- }
- }
-
- /* fill the remaining gap */
- set_viewport(x, lines > 0 ? (y+(coord_t)gap) : y, cx, abslines);
- stream_start();
- gap = cx*abslines;
- for(i = 0; i < gap; i++) write_data(bgcolor);
- stream_stop();
- release_bus();
- }
-#endif
-
-#if (GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL) || defined(__DOXYGEN__)
- /**
- * @brief Driver Control
- * @details Unsupported control codes are ignored.
- * @note The value parameter should always be typecast to (void *).
- * @note There are some predefined and some specific to the low level driver.
- * @note GDISP_CONTROL_POWER - Takes a gdisp_powermode_t
- * GDISP_CONTROL_ORIENTATION - Takes a gdisp_orientation_t
- * GDISP_CONTROL_BACKLIGHT - Takes an int from 0 to 100. For a driver
- * that only supports off/on anything other
- * than zero is on.
- * GDISP_CONTROL_CONTRAST - Takes an int from 0 to 100.
- * GDISP_CONTROL_LLD - Low level driver control constants start at
- * this value.
- *
- * @param[in] what What to do.
- * @param[in] value The value to use (always cast to a void *).
- *
- * @notapi
- */
- void gdisp_lld_control(unsigned what, void *value) {
- switch(what) {
- case GDISP_CONTROL_POWER:
- if (GDISP.Powermode == (gdisp_powermode_t)value)
- return;
- switch((gdisp_powermode_t)value) {
- case powerOff:
- acquire_bus();
- write_reg(0x0010, 0x0001); /* enter sleep mode */
- release_bus();
- break;
- case powerOn:
- acquire_bus();
- write_reg(0x0010, 0x0000); /* leave sleep mode */
- release_bus();
- if (GDISP.Powermode != powerSleep)
- gdisp_lld_init();
- break;
- case powerSleep:
- acquire_bus();
- write_reg(0x0010, 0x0001); /* enter sleep mode */
- release_bus();
- break;
- default:
- return;
- }
- GDISP.Powermode = (gdisp_powermode_t)value;
- return;
- case GDISP_CONTROL_ORIENTATION:
- if (GDISP.Orientation == (gdisp_orientation_t)value)
- return;
- switch((gdisp_orientation_t)value) {
- case GDISP_ROTATE_0:
- acquire_bus();
-
- write_reg(0xC0, 0x03);
- write_reg(0x36, 0x00); /* X and Y axes non-inverted */
-
- release_bus();
- GDISP.Height = GDISP_SCREEN_HEIGHT;
- GDISP.Width = GDISP_SCREEN_WIDTH;
- break;
- case GDISP_ROTATE_90:
- acquire_bus();
-
- write_reg(0xC0, 0x02);
- write_reg(0x36, 0x20); /* Invert X and Y axes */
-
- release_bus();
- GDISP.Height = GDISP_SCREEN_WIDTH;
- GDISP.Width = GDISP_SCREEN_HEIGHT;
- break;
- case GDISP_ROTATE_180:
- acquire_bus();
-
- write_reg(0xC0, 0x06);
- write_reg(0x36, 0x00); /* X and Y axes non-inverted */
-
- release_bus();
- GDISP.Height = GDISP_SCREEN_HEIGHT;
- GDISP.Width = GDISP_SCREEN_WIDTH;
- break;
- case GDISP_ROTATE_270:
- acquire_bus();
-
- write_reg(0xC0, 0x07);
- write_reg(0x36, 0x20); /* Invert X and Y axes */
-
- release_bus();
- GDISP.Height = GDISP_SCREEN_WIDTH;
- GDISP.Width = GDISP_SCREEN_HEIGHT;
- break;
- default:
- return;
- }
- #if GDISP_NEED_CLIP || GDISP_NEED_VALIDATION
- GDISP.clipx0 = 0;
- GDISP.clipy0 = 0;
- GDISP.clipx1 = GDISP.Width;
- GDISP.clipy1 = GDISP.Height;
- #endif
- GDISP.Orientation = (gdisp_orientation_t)value;
- return;
-/*
- case GDISP_CONTROL_BACKLIGHT:
- case GDISP_CONTROL_CONTRAST:
-*/
- }
- }
-#endif
-
-#endif /* GFX_USE_GDISP */
-/** @} */
diff --git a/drivers/gdisp/ILI9481/gdisp_lld.mk b/drivers/gdisp/ILI9481/gdisp_lld.mk
index b0b3f533..8c971788 100644
--- a/drivers/gdisp/ILI9481/gdisp_lld.mk
+++ b/drivers/gdisp/ILI9481/gdisp_lld.mk
@@ -1,5 +1,2 @@
-# List the required driver.
-GFXSRC += $(GFXLIB)/drivers/gdisp/ILI9481/gdisp_lld.c
-
-# Required include directories
GFXINC += $(GFXLIB)/drivers/gdisp/ILI9481
+GFXSRC += $(GFXLIB)/drivers/gdisp/ILI9481/gdisp_lld_ILI9481.c
diff --git a/drivers/gdisp/ILI9481/gdisp_lld_ILI9481.c b/drivers/gdisp/ILI9481/gdisp_lld_ILI9481.c
new file mode 100644
index 00000000..2b2f0917
--- /dev/null
+++ b/drivers/gdisp/ILI9481/gdisp_lld_ILI9481.c
@@ -0,0 +1,328 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/ILI9481/gdisp_lld.c
+ * @brief GDISP Graphics Driver subsystem low level driver source for
+ * the ILI9481 and compatible HVGA display
+ */
+
+#include "gfx.h"
+
+#if GFX_USE_GDISP
+
+#if defined(GDISP_SCREEN_HEIGHT)
+ #warning "GDISP: This low level driver does not support setting a screen size. It is being ignored."
+ #undef GISP_SCREEN_HEIGHT
+#endif
+#if defined(GDISP_SCREEN_WIDTH)
+ #warning "GDISP: This low level driver does not support setting a screen size. It is being ignored."
+ #undef GDISP_SCREEN_WIDTH
+#endif
+
+#define GDISP_DRIVER_VMT GDISPVMT_ILI9481
+#include "../drivers/gdisp/ILI9481/gdisp_lld_config.h"
+#include "gdisp/lld/gdisp_lld.h"
+
+#include "board_ILI9481.h"
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+#ifndef GDISP_SCREEN_HEIGHT
+ #define GDISP_SCREEN_HEIGHT 480
+#endif
+#ifndef GDISP_SCREEN_WIDTH
+ #define GDISP_SCREEN_WIDTH 320
+#endif
+#ifndef GDISP_INITIAL_CONTRAST
+ #define GDISP_INITIAL_CONTRAST 50
+#endif
+#ifndef GDISP_INITIAL_BACKLIGHT
+ #define GDISP_INITIAL_BACKLIGHT 100
+#endif
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+// Some common routines and macros
+#define dummy_read(g) { volatile uint16_t dummy; dummy = read_data(g); (void) dummy; }
+#define write_reg(g, reg, data) { write_index(g, reg); write_data(g, data); }
+#define write_reg2x16(g, reg, data1, data2) { write_index(g, reg); write_data(g, (data1)>>8); write_data(g, (uint8_t)(data1)); write_data(g, (data2)>>8); write_data(g, (uint8_t)(data2));}
+
+static void set_viewport(GDisplay* g) {
+ write_reg2x16(g, 0x2A, g->p.x, g->p.x + g->p.cx - 1);
+ write_reg2x16(g, 0x2B, g->p.y, g->p.y + g->p.cy - 1);
+ write_index(g, 0x2C);
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
+ // No private area for this controller
+ g->priv = 0;
+
+ // Initialise the board interface
+ init_board(g);
+
+ /* Hardware reset */
+ setpin_reset(g, TRUE);
+ gfxSleepMilliseconds(20);
+ setpin_reset(g, FALSE);
+ gfxSleepMilliseconds(20);
+
+ /* Get the bus for the following initialisation commands */
+ acquire_bus(g);
+
+ /* Enable Access to all Manufacturer commands (0xB0 and higher opcodes) */
+ write_reg(g, 0xB0, 0x00);
+
+ /* Frame Memory Access and Interface Setting */
+ write_index(g, 0xB3);
+ write_data(g, 0x02);
+ write_data(g, 0x00);
+ write_data(g, 0x00);
+ write_data(g, 0x10);
+
+ /* Display Mode and Frame Memory Write Mode Setting (B4h) */
+ /* Use internal clock for synchronization */
+ /* Use DBI interface (only DB0-17, no HSYNC, VSYNC or CLK) */
+ write_reg(g, 0xB4, 0x00);
+
+ /* Internal Backlight Control */
+/* write_index(g, 0xB9); // PWM Settings for Brightness Control
+ write_data(g, 0x01); // Disabled by default.
+ write_data(g, 0xFF); // 0xFF = Max brightness
+ write_data(g, 0xFF);
+ write_data(g, 0x18); */
+
+ /* Panel Driving settings */
+ write_index(g, 0xC0);
+ write_data(g, 0x03);
+ write_data(g, 0x3B);
+ write_data(g, 0x00);
+ write_data(g, 0x00);
+ write_data(g, 0x00);
+ write_data(g, 0x01);
+ write_data(g, 0x00); /* NW */
+ write_data(g, 0x43);
+
+ /* Display timings in Operating Mode */
+ write_index(g, 0xC1);
+ write_data(g, 0x08);
+ write_data(g, 0x15); /* CLOCK */
+ write_data(g, 0x08);
+ write_data(g, 0x08);
+
+ /* S/VCOM/Gate Driving timing setting */
+ write_index(g, 0xC4);
+ write_data(g, 0x15);
+ write_data(g, 0x03);
+ write_data(g, 0x03);
+ write_data(g, 0x01);
+
+ /* Interface Setting */
+ write_reg(g, 0xC6, 0x02);
+
+ /* Gamma Setting - should be changed if using a different panel */
+ write_index(g, 0xC8);
+ write_data(g, 0x0C);
+ write_data(g, 0x05);
+ write_data(g, 0x0A); /*0X12 */
+ write_data(g, 0x6B); /*0x7D */
+ write_data(g, 0x04);
+ write_data(g, 0x06); /*0x08 */
+ write_data(g, 0x15); /*0x0A */
+ write_data(g, 0x10);
+ write_data(g, 0x00);
+ write_data(g, 0x60); /*0x23 */
+
+ /* Address Mode setting */
+ write_reg(g, 0x36, 0x00);
+
+ /* Set Pixel Format = 16 bits per pixel */
+ /* The driver supports upto 24 bits per pixel, with dither */
+ write_reg(g, 0x3A, 0x55);
+
+ /* Exit Idle Mode */
+ write_index(g, 0x38);
+
+ /* Power Setting */
+ write_index(g, 0xD0);
+ write_data(g, 0x07);
+ write_data(g, 0x07); /* VCI = VCI1 */
+ write_data(g, 0x14); /* VRH 0x1D */
+ write_data(g, 0xA2); /* BT 0x06 */
+
+ /* VCOM Setting */
+ write_index(g, 0xD1);
+ write_data(g, 0x03);
+ write_data(g, 0x5A); /* VCM 0x5A */
+ write_data(g, 0x10); /* VDV */
+
+ /* Power Setting for Normal Mode */
+ write_index(g, 0xD2);
+ write_data(g, 0x03);
+ write_data(g, 0x04); /* 0x24 */
+ write_data(g, 0x04);
+
+ /* Exit Sleep Mode */
+ write_index(g, 0x11);
+ gfxSleepMilliseconds(150);
+
+ /* Display ON */
+ write_index(g, 0x29);
+ gfxSleepMilliseconds(30);
+
+ // Finish Init
+ post_init_board(g);
+
+ // Release the bus
+ release_bus(g);
+
+ /* Turn on the back-light */
+ set_backlight(g, GDISP_INITIAL_BACKLIGHT);
+
+ /* Initialise the GDISP structure */
+ g->g.Width = GDISP_SCREEN_WIDTH;
+ g->g.Height = GDISP_SCREEN_HEIGHT;
+ g->g.Orientation = GDISP_ROTATE_0;
+ g->g.Powermode = powerOn;
+ g->g.Backlight = GDISP_INITIAL_BACKLIGHT;
+ g->g.Contrast = GDISP_INITIAL_CONTRAST;
+ return TRUE;
+}
+
+#if GDISP_HARDWARE_STREAM_WRITE
+ LLDSPEC void gdisp_lld_write_start(GDisplay *g) {
+ acquire_bus(g);
+ set_viewport(g);
+ }
+ LLDSPEC void gdisp_lld_write_color(GDisplay *g) {
+ write_data(g, COLOR2NATIVE(g->p.color));
+ }
+ LLDSPEC void gdisp_lld_write_stop(GDisplay *g) {
+ release_bus(g);
+ }
+#endif
+
+#if GDISP_HARDWARE_STREAM_READ
+ LLDSPEC void gdisp_lld_read_start(GDisplay *g) {
+ acquire_bus(g);
+ set_viewport(g);
+ setreadmode(g);
+ dummy_read(g);
+ }
+ LLDSPEC color_t gdisp_lld_read_color(GDisplay *g) {
+ uint16_t data;
+
+ data = read_data(g);
+ return NATIVE2COLOR(data);
+ }
+ LLDSPEC void gdisp_lld_read_stop(GDisplay *g) {
+ setwritemode(g);
+ release_bus(g);
+ }
+#endif
+
+#if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL
+ LLDSPEC void gdisp_lld_control(GDisplay *g) {
+ switch(g->p.x) {
+ case GDISP_CONTROL_POWER:
+ if (g->g.Powermode == (powermode_t)g->p.ptr)
+ return;
+ switch((powermode_t)g->p.ptr) {
+ case powerOff:
+ acquire_bus(g);
+ write_reg(g, 0x0010, 0x0001); /* enter sleep mode */
+ release_bus(g);
+ break;
+ case powerOn:
+ acquire_bus(g);
+ write_reg(g, 0x0010, 0x0000); /* leave sleep mode */
+ release_bus(g);
+ if (g->g.Powermode != powerSleep)
+ gdisp_lld_init();
+ break;
+ case powerSleep:
+ acquire_bus(g);
+ write_reg(g, 0x0010, 0x0001); /* enter sleep mode */
+ release_bus(g);
+ break;
+ default:
+ return;
+ }
+ g->g.Powermode = (powermode_t)g->p.ptr;
+ return;
+
+ case GDISP_CONTROL_ORIENTATION:
+ if (g->g.Orientation == (orientation_t)g->p.ptr)
+ return;
+ switch((orientation_t)g->p.ptr) {
+ case GDISP_ROTATE_0:
+ acquire_bus(g);
+
+ write_reg(g, 0xC0, 0x03);
+ write_reg(g, 0x36, 0x00); /* X and Y axes non-inverted */
+
+ release_bus(g);
+ g->g.Height = GDISP_SCREEN_HEIGHT;
+ g->g.Width = GDISP_SCREEN_WIDTH;
+ break;
+ case GDISP_ROTATE_90:
+ acquire_bus(g);
+
+ write_reg(g, 0xC0, 0x02);
+ write_reg(g, 0x36, 0x20); /* Invert X and Y axes */
+
+ release_bus(g);
+ g->g.Height = GDISP_SCREEN_WIDTH;
+ g->g.Width = GDISP_SCREEN_HEIGHT;
+ break;
+ case GDISP_ROTATE_180:
+ acquire_bus(g);
+
+ write_reg(g, 0xC0, 0x06);
+ write_reg(g, 0x36, 0x00); /* X and Y axes non-inverted */
+
+ release_bus(g);
+ g->g.Height = GDISP_SCREEN_HEIGHT;
+ g->g.Width = GDISP_SCREEN_WIDTH;
+ break;
+ case GDISP_ROTATE_270:
+ acquire_bus(g);
+
+ write_reg(g, 0xC0, 0x07);
+ write_reg(g, 0x36, 0x20); /* Invert X and Y axes */
+
+ release_bus(g);
+ g->g.Height = GDISP_SCREEN_WIDTH;
+ g->g.Width = GDISP_SCREEN_HEIGHT;
+ break;
+ default:
+ return;
+ }
+ g->g.Orientation = (orientation_t)g->p.ptr;
+ return;
+ //case GDISP_CONTROL_BACKLIGHT:
+ //case GDISP_CONTROL_CONTRAST:
+ default:
+ return;
+ }
+ }
+#endif
+
+#endif /* GFX_USE_GDISP */
+/** @} */
diff --git a/drivers/gdisp/ILI9481/gdisp_lld_board_firebullstm32f103.h b/drivers/gdisp/ILI9481/gdisp_lld_board_firebullstm32f103.h
deleted file mode 100644
index cef9911d..00000000
--- a/drivers/gdisp/ILI9481/gdisp_lld_board_firebullstm32f103.h
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * This file is subject to the terms of the GFX License. If a copy of
- * the license was not distributed with this file, you can obtain one at:
- *
- * http://ugfx.org/license.html
- */
-
-/**
- * @file drivers/gdisp/ILI9481/gdisp_lld_board_firebullstm32f103.h
- * @brief GDISP Graphics Driver subsystem low level driver source for
- * the ILI9481 and compatible HVGA display
- *
- * @addtogroup GDISP
- * @{
- */
-
-#ifndef _GDISP_LLD_BOARD_H
-#define _GDISP_LLD_BOARD_H
-
-#define SET_CS palSetPad(GPIOD, 12);
-#define CLR_CS palClearPad(GPIOD, 12);
-#define SET_RS palSetPad(GPIOD, 13);
-#define CLR_RS palClearPad(GPIOD, 13);
-#define SET_WR palSetPad(GPIOD, 14);
-#define CLR_WR palClearPad(GPIOD, 14);
-#define SET_RD palSetPad(GPIOD, 15);
-#define CLR_RD palClearPad(GPIOD, 15);
-
-/**
- * @brief Initialise the board for the display.
- * @notes This board definition uses GPIO and assumes exclusive access to these GPIO pins
- *
- * @notapi
- */
-static inline void init_board(void) {
- palSetGroupMode(GPIOE, PAL_WHOLE_PORT, 0, PAL_MODE_OUTPUT_PUSHPULL);
- palSetPadMode(GPIOD, 12, PAL_MODE_OUTPUT_PUSHPULL);
- palSetPadMode(GPIOD, 13, PAL_MODE_OUTPUT_PUSHPULL);
- palSetPadMode(GPIOD, 14, PAL_MODE_OUTPUT_PUSHPULL);
- palSetPadMode(GPIOD, 15, PAL_MODE_OUTPUT_PUSHPULL);
-
- // Configure the pins to a well know state
- SET_RS;
- SET_RD;
- SET_WR;
- CLR_CS;
-}
-
-
-/**
- * @brief Set or clear the lcd reset pin.
- *
- * @param[in] state TRUE = lcd in reset, FALSE = normal operation
- *
- * @notapi
- */
-static inline void setpin_reset(bool_t state) {
- (void) state;
- /* Nothing to do here - reset pin tied to Vcc */
-}
-
-/**
- * @brief Set the lcd back-light level.
- *
- * @param[in] percent 0 to 100%
- *
- * @notapi
- */
-static inline void set_backlight(uint8_t percent) {
- (void) percent;
- /* Nothing to do here - Backlight always on */
-}
-
-/**
- * @brief Take exclusive control of the bus
- *
- * @notapi
- */
-static inline void acquire_bus(void) {
- /* Nothing to do here since LCD is the only device on that bus */
-}
-
-/**
- * @brief Release exclusive control of the bus
- *
- * @notapi
- */
-static inline void release_bus(void) {
- /* Nothing to do here since LCD is the only device on that bus */
-}
-
-/**
- * @brief Send data to the index register.
- *
- * @param[in] index The index register to set
- *
- * @notapi
- */
-static inline void write_index(uint16_t index) {
- palWritePort(GPIOE, index);
- CLR_RS; CLR_WR; SET_WR; SET_RS;
-}
-
-/**
- * @brief Send data to the lcd.
- *
- * @param[in] data The data to send
- *
- * @notapi
- */
-static inline void write_data(uint16_t data) {
- palWritePort(GPIOE, data);
- CLR_WR; SET_WR;
-}
-
-#if GDISP_HARDWARE_READPIXEL || GDISP_HARDWARE_SCROLL || defined(__DOXYGEN__)
-/**
- * @brief Read data from the lcd.
- *
- * @return The data from the lcd
- * @note The chip select may need to be asserted/de-asserted
- * around the actual spi read
- *
- * @notapi
- */
-static inline uint16_t read_data(void) {
- uint16_t value;
-
- // change pin mode to digital input
- palSetGroupMode(GPIOE, PAL_WHOLE_PORT, 0, PAL_MODE_INPUT);
-
- CLR_RD;
- value = palReadPort(GPIOE);
- value = palReadPort(GPIOE);
- SET_RD;
-
- // change pin mode back to digital output
- palSetGroupMode(GPIOE, PAL_WHOLE_PORT, 0, PAL_MODE_OUTPUT_PUSHPULL);
-
- return value;
-}
-#endif
-
-#endif /* _GDISP_LLD_BOARD_H */
-/** @} */
diff --git a/drivers/gdisp/ILI9481/gdisp_lld_board_template.h b/drivers/gdisp/ILI9481/gdisp_lld_board_template.h
deleted file mode 100644
index 1bbcf282..00000000
--- a/drivers/gdisp/ILI9481/gdisp_lld_board_template.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * This file is subject to the terms of the GFX License. If a copy of
- * the license was not distributed with this file, you can obtain one at:
- *
- * http://ugfx.org/license.html
- */
-
-/**
- * @file drivers/gdisp/ILI9481/gdisp_lld_board_template.h
- * @brief GDISP Graphics Driver subsystem low level driver source for
- * the ILI9481 and compatible HVGA display
- *
- * @addtogroup GDISP
- * @{
- */
-
-#ifndef _GDISP_LLD_BOARD_H
-#define _GDISP_LLD_BOARD_H
-
-/**
- * @brief Initialise the board for the display.
- *
- * @notapi
- */
-static inline void init_board(void) {
-
-}
-
-/**
- * @brief Set or clear the lcd reset pin.
- *
- * @param[in] state TRUE = lcd in reset, FALSE = normal operation
- *
- * @notapi
- */
-static inline void setpin_reset(bool_t state) {
-
-}
-
-/**
- * @brief Set the lcd back-light level.
- *
- * @param[in] percent 0 to 100%
- *
- * @notapi
- */
-static inline void set_backlight(uint8_t percent) {
-
-}
-
-/**
- * @brief Take exclusive control of the bus
- *
- * @notapi
- */
-static inline void acquire_bus(void) {
-
-}
-
-/**
- * @brief Release exclusive control of the bus
- *
- * @notapi
- */
-static inline void release_bus(void) {
-
-}
-
-/**
- * @brief Send data to the index register.
- *
- * @param[in] index The index register to set
- *
- * @notapi
- */
-static inline void write_index(uint16_t index) {
-
-}
-
-/**
- * @brief Send data to the lcd.
- *
- * @param[in] data The data to send
- *
- * @notapi
- */
-static inline void write_data(uint16_t data) {
-
-}
-
-#if GDISP_HARDWARE_READPIXEL || GDISP_HARDWARE_SCROLL || defined(__DOXYGEN__)
-/**
- * @brief Read data from the lcd.
- *
- * @return The data from the lcd
- * @note The chip select may need to be asserted/de-asserted
- * around the actual spi read
- *
- * @notapi
- */
-static inline uint16_t read_data(void) {
-
-}
-#endif
-
-#endif /* _GDISP_LLD_BOARD_H */
-/** @} */
diff --git a/drivers/gdisp/ILI9481/gdisp_lld_config.h b/drivers/gdisp/ILI9481/gdisp_lld_config.h
index 79fea9f3..3f3a4834 100644
--- a/drivers/gdisp/ILI9481/gdisp_lld_config.h
+++ b/drivers/gdisp/ILI9481/gdisp_lld_config.h
@@ -23,16 +23,11 @@
/* Driver hardware support. */
/*===========================================================================*/
-#define GDISP_DRIVER_NAME "ILI9481"
-
-#define GDISP_HARDWARE_CLEARS TRUE
-#define GDISP_HARDWARE_FILLS TRUE
-#define GDISP_HARDWARE_BITFILLS TRUE
-#define GDISP_HARDWARE_SCROLL TRUE
-#define GDISP_HARDWARE_PIXELREAD TRUE
+#define GDISP_HARDWARE_STREAM_WRITE TRUE
+#define GDISP_HARDWARE_STREAM_READ TRUE
#define GDISP_HARDWARE_CONTROL TRUE
-#define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_RGB565
+#define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_RGB565
#endif /* GFX_USE_GDISP */
diff --git a/drivers/gdisp/Nokia6610GE12/board_Nokia6610GE12_template.h b/drivers/gdisp/Nokia6610GE12/board_Nokia6610GE12_template.h
new file mode 100644
index 00000000..160c9278
--- /dev/null
+++ b/drivers/gdisp/Nokia6610GE12/board_Nokia6610GE12_template.h
@@ -0,0 +1,131 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/Nokia6610GE12/board_Nokia6610GE12_template.h
+ * @brief GDISP Graphic Driver subsystem board interface for the Nokia6610 GE12 display.
+ *
+ * @addtogroup GDISP
+ * @{
+ */
+
+#ifndef _GDISP_LLD_BOARD_H
+#define _GDISP_LLD_BOARD_H
+
+/*
+ * Set various display properties. These properties mostly depend on the exact controller chip you get.
+ * The defaults should work for most controllers.
+ */
+//#define GDISP_SCREEN_HEIGHT 130 // The visible display height
+//#define GDISP_SCREEN_WIDTH 130 // The visible display width
+//#define GDISP_RAM_X_OFFSET 0 // The x offset of the visible area
+//#define GDISP_RAM_Y_OFFSET 2 // The y offset of the visible area
+//#define GDISP_SLEEP_POS 50 // The position of the sleep mode partial display
+//#define GDISP_INITIAL_CONTRAST 50 // The initial contrast percentage
+//#define GDISP_INITIAL_BACKLIGHT 100 // The initial backlight percentage
+
+/**
+ * @brief Initialise the board for the display.
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @note Set the g->board member to whatever is appropriate. For multiple
+ * displays this might be a pointer to the appropriate register set.
+ *
+ * @notapi
+ */
+static inline void init_board(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief After the initialisation.
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void post_init_board(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Set or clear the lcd reset pin.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] state TRUE = lcd in reset, FALSE = normal operation
+ *
+ * @notapi
+ */
+static inline void setpin_reset(GDisplay *g, bool_t state) {
+ (void) g;
+ (void) state;
+}
+
+/**
+ * @brief Set the lcd back-light level.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] percent 0 to 100%
+ *
+ * @notapi
+ */
+static inline void set_backlight(GDisplay *g, uint8_t percent) {
+ (void) g;
+ (void) percent;
+}
+
+/**
+ * @brief Take exclusive control of the bus
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void acquire_bus(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Release exclusive control of the bus
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void release_bus(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Send data to the index register.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] index The index register to set
+ *
+ * @notapi
+ */
+static inline void write_index(GDisplay *g, uint16_t index) {
+ (void) g;
+ (void) index;
+}
+
+/**
+ * @brief Send data to the lcd.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] data The data to send
+ *
+ * @notapi
+ */
+static inline void write_data(GDisplay *g, uint16_t data) {
+ (void) g;
+ (void) data;
+}
+
+#endif /* _GDISP_LLD_BOARD_H */
+/** @} */
diff --git a/drivers/gdisp/Nokia6610GE12/gdisp_lld.c b/drivers/gdisp/Nokia6610GE12/gdisp_lld.c
deleted file mode 100644
index a991a9a6..00000000
--- a/drivers/gdisp/Nokia6610GE12/gdisp_lld.c
+++ /dev/null
@@ -1,505 +0,0 @@
-/*
- * This file is subject to the terms of the GFX License. If a copy of
- * the license was not distributed with this file, you can obtain one at:
- *
- * http://ugfx.org/license.html
- */
-
-/**
- * @file drivers/gdisp/Nokia6610GE12/gdisp_lld.c
- * @brief GDISP Graphics Driver subsystem low level driver source for the Nokia6610 GE12 display.
- *
- * @addtogroup GDISP
- * @{
- */
-
-#include "gfx.h"
-
-#if GFX_USE_GDISP /*|| defined(__DOXYGEN__)*/
-
-/* Include the emulation code for things we don't support */
-#include "gdisp/lld/emulation.c"
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-/* Controller definitions */
-#include "GE12.h"
-
-/* This controller is only ever used with a 132 x 132 display */
-#if defined(GDISP_SCREEN_HEIGHT)
- #warning "GDISP: This low level driver does not support setting a screen size. It is being ignored."
- #undef GDISP_SCREEN_HEIGHT
-#endif
-#if defined(GDISP_SCREEN_WIDTH)
- #warning "GDISP: This low level driver does not support setting a screen size. It is being ignored."
- #undef GDISP_SCREEN_WIDTH
-#endif
-#define GDISP_SCREEN_HEIGHT 132
-#define GDISP_SCREEN_WIDTH 132
-
-#define GDISP_INITIAL_CONTRAST 38
-#define GDISP_INITIAL_BACKLIGHT 100
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver local variables. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-#include "gdisp_lld_board.h"
-
-// Some macros just to make reading the code easier
-#define delayms(ms) gfxSleepMilliseconds(ms)
-#define write_data2(d1, d2) { write_data(d1); write_data(d2); }
-#define write_data3(d1, d2, d3) { write_data(d1); write_data(d2); write_data(d3); }
-#define write_cmd1(cmd, d1) { write_cmd(cmd); write_data(d1); }
-#define write_cmd2(cmd, d1, d2) { write_cmd(cmd); write_data2(d1, d2); }
-#define write_cmd3(cmd, d1, d2, d3) { write_cmd(cmd); write_data3(d1, d2, d3); }
-
-// A very common thing to do.
-// An inline function has been used here incase the parameters have side effects with the internal calculations.
-static inline void setviewport(coord_t x, coord_t y, coord_t cx, coord_t cy) {
- write_cmd2(CASET, x, x+cx-1); // Column address set
- write_cmd2(PASET, y, y+cy-1); // Page address set
-}
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/* ---- Required Routines ---- */
-/*
- The following 2 routines are required.
- All other routines are optional.
-*/
-
-/**
- * @brief Low level GDISP driver initialization.
- *
- * @notapi
- */
-bool_t gdisp_lld_init(void) {
- /* Initialise your display */
- init_board();
-
- // Hardware reset
- setpin_reset(TRUE);
- delayms(20);
- setpin_reset(FALSE);
- delayms(20);
-
- // Get the bus for the following initialisation commands
- acquire_bus();
-
- // UNTESTED
- #if 1
- write_cmd(SLEEPOUT); // Sleep out
- write_cmd(INVON); // Inversion on: seems to be required for this controller
- write_cmd1(COLMOD, 0x03); // Color Interface Pixel Format - 0x03 = 12 bits-per-pixel
- write_cmd1(MADCTL, 0xC8); // Memory access controler - 0xC0 = mirror x and y, reverse rgb
- write_cmd1(SETCON, GDISP_INITIAL_CONTRAST); // Write contrast
- delayms(20);
- write_cmd(DISPON); // Display On
- #else
- // Alternative
- write_cmd(SOFTRST); // Software Reset
- delayms(20);
- write_cmd(INITESC); // Initial escape
- delayms(20);
- write_cmd1(REFSET, 0x00); // Refresh set
- write_cmd(DISPCTRL); // Set Display control - really 7 bytes of data
- write_data(128); // Set the lenght of one selection term
- write_data(128); // Set N inversion -> no N inversion
- write_data(134); // Set frame frequence and bias rate -> 2 devision of frequency and 1/8 bias, 1/67 duty, 96x67 size
- write_data(84); // Set duty parameter
- write_data(69); // Set duty parameter
- write_data(82); // Set duty parameter
- write_data(67); // Set duty parameter
- write_cmd(GRAYSCALE0); // Grey scale 0 position set - really 15 bytes of data
- write_data(1); // GCP1 - gray lavel to be output when the RAM data is "0001"
- write_data(2); // GCP2 - gray lavel to be output when the RAM data is "0010"
- write_data(4); // GCP3 - gray lavel to be output when the RAM data is "0011"
- write_data(8); // GCP4 - gray lavel to be output when the RAM data is "0100"
- write_data(16); // GCP5 - gray lavel to be output when the RAM data is "0101"
- write_data(30); // GCP6 - gray lavel to be output when the RAM data is "0110"
- write_data(40); // GCP7 - gray lavel to be output when the RAM data is "0111"
- write_data(50); // GCP8 - gray lavel to be output when the RAM data is "1000"
- write_data(60); // GCP9 - gray lavel to be output when the RAM data is "1001"
- write_data(70); // GCP10 - gray lavel to be output when the RAM data is "1010"
- write_data(80); // GCP11 - gray lavel to be output when the RAM data is "1011"
- write_data(90); // GCP12 - gray lavel to be output when the RAM data is "1100"
- write_data(100); // GCP13 - gray lavel to be output when the RAM data is "1101"
- write_data(110); // GCP14 - gray lavel to be output when the RAM data is "1110"
- write_data(127); // GCP15 - gray lavel to be output when the RAM data is "1111"
- write_cmd1(GAMMA, 0x01); // Gamma curve set - select gray scale - GRAYSCALE 0 or GREYSCALE 1 - Select grey scale 0
- write_cmd1(COMMONDRV, 0x00); // Command driver output - Set COM1-COM41 side come first, normal mod
- write_cmd(NORMALMODE); // Set Normal mode (my)
- // write_cmd(INVERSIONOFF); // Inversion off
- write_cmd2(COLADDRSET, 0, 131); // Column address set
- write_cmd2(PAGEADDRSET, 0, 131); // Page address set
- write_cmd1(ACCESSCTRL, 0x40); // Memory access controler - 0x40 horizontal
- // write_data(0x20); // vertical
- write_cmd1(PWRCTRL, 0x04); // Power control - Internal resistance, V1OUT -> high power mode, oscilator devision rate
- write_cmd(SLEEPOUT); // Sleep out
- write_cmd(VOLTCTRL); // Voltage control - voltage control and write contrast define LCD electronic volume
- // write_data(0x7f); // full voltage control
- // write_data(0x03); // must be "1"
- write_cmd1(CONTRAST, GDISP_INITIAL_CONTRAST); // Write contrast
- delayms(20);
- write_cmd(TEMPGRADIENT); // Temperature gradient - really 14 bytes of data
- for(i=0; i<14; i++)
- write_data(0);
- write_cmd(BOOSTVON); // Booster voltage ON
- write_cmd(DISPLAYON); // Finally - Display On
- #endif
-
- // Release the bus
- release_bus();
-
- /* Turn on the back-light */
- set_backlight(GDISP_INITIAL_BACKLIGHT);
-
- /* Initialise the GDISP structure to match */
- GDISP.Width = GDISP_SCREEN_WIDTH;
- GDISP.Height = GDISP_SCREEN_HEIGHT;
- GDISP.Orientation = GDISP_ROTATE_0;
- GDISP.Powermode = powerOn;
- GDISP.Backlight = GDISP_INITIAL_BACKLIGHT;
- GDISP.Contrast = GDISP_INITIAL_CONTRAST;
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- GDISP.clipx0 = 0;
- GDISP.clipy0 = 0;
- GDISP.clipx1 = GDISP.Width;
- GDISP.clipy1 = GDISP.Height;
- #endif
- return TRUE;
-}
-
-/**
- * @brief Draws a pixel on the display.
- *
- * @param[in] x X location of the pixel
- * @param[in] y Y location of the pixel
- * @param[in] color The color of the pixel
- *
- * @notapi
- */
-void gdisp_lld_draw_pixel(coord_t x, coord_t y, color_t color) {
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- if (x < GDISP.clipx0 || y < GDISP.clipy0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
- #endif
- acquire_bus();
- setviewport(x, y, 1, 1);
- write_cmd3(RAMWR, 0, (color>>8) & 0x0F, color & 0xFF);
- release_bus();
-}
-
-/* ---- Optional Routines ---- */
-
-#if GDISP_HARDWARE_FILLS || defined(__DOXYGEN__)
- /**
- * @brief Fill an area with a color.
- *
- * @param[in] x, y The start filled area
- * @param[in] cx, cy The width and height to be filled
- * @param[in] color The color of the fill
- *
- * @notapi
- */
- void gdisp_lld_fill_area(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
- unsigned i, tuples;
-
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; }
- if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; }
- if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
- if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
- if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
- #endif
-
- tuples = (cx*cy+1)/2; // With an odd sized area we over-print by one pixel.
- // This extra pixel is ignored by the controller.
-
- acquire_bus();
- setviewport(x, y, cx, cy);
- write_cmd(RAMWR);
- for(i=0; i < tuples; i++)
- write_data3(((color >> 4) & 0xFF), (((color << 4) & 0xF0)|((color >> 8) & 0x0F)), (color & 0xFF));
- release_bus();
- }
-#endif
-
-#if GDISP_HARDWARE_BITFILLS || defined(__DOXYGEN__)
- /**
- * @brief Fill an area with a bitmap.
- *
- * @param[in] x, y The start filled area
- * @param[in] cx, cy The width and height to be filled
- * @param[in] srcx, srcy The bitmap position to start the fill from
- * @param[in] srccx The width of a line in the bitmap.
- * @param[in] buffer The pixels to use to fill the area.
- *
- * @notapi
- */
- void gdisp_lld_blit_area_ex(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx, coord_t srcy, coord_t srccx, const pixel_t *buffer) {
- coord_t endx, endy, lg;
- color_t c1, c2;
- #if GDISP_PACKED_PIXELS
- coord_t pos;
- const uint8_t *p;
- #endif
-
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; srcx += GDISP.clipx0 - x; x = GDISP.clipx0; }
- if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; srcy += GDISP.clipy0 - y; y = GDISP.clipy0; }
- if (srcx+cx > srccx) cx = srccx - srcx;
- if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
- if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
- if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
- #endif
-
- /* What are our end points */
- endx = srcx + cx;
- endy = y + cy;
-
- acquire_bus();
- setviewport(x, y, cx, cy);
- write_cmd(RAMWR);
-
- #if !GDISP_PACKED_PIXELS
- // Although this controller uses packed pixels we support unpacked pixel
- // formats in this blit by packing the data as we feed it to the controller.
- lg = srccx - cx;
- buffer += srcy * srccx + srcx;
- x = srcx;
- while (1) {
- /* Get a pixel */
- c1 = *buffer++;
- if (++x >= endx) {
- if (++y >= endy) {
- /* Odd pixel at end */
- write_data3(0, ((c1 >> 8) & 0x0F), (c1 & 0xFF));
- break;
- }
- x = srcx;
- buffer += lg;
- }
- /* Get the next pixel */
- c2 = *buffer++;
- write_data3(((c1 >> 4) & 0xFF), (((c1 << 4) & 0xF0)|((c2 >> 8) & 0x0F)), (c2 & 0xFF));
- if (++x >= endx) {
- if (++y >= endy)
- break;
- x = srcx;
- buffer += lg;
- }
- }
-
- #else
-
- // Although this controller uses packed pixels, we may have to feed it into
- // the controller with different packing to the source bitmap
- #if !GDISP_PACKED_LINES
- srccx = (srccx + 1) & ~1;
- #endif
- pos = srcy*srccx;
- lg = (srccx - cx)/2*3;
- p = ((const uint8_t *)buffer) + ((pos+srcx)/2 * 3);
-
- x = srcx;
- while (1) {
- /* Get a pixel */
- switch((pos+x)&1) {
- case 0: c1 = (((color_t)p[0]) << 4)|(((color_t)p[1])>>4); break;
- case 1: c1 = (((color_t)p[1]&0x0F) << 8)|((color_t)p[1]); break;
- }
- if (++x >= endx) {
- if (++y >= endy) {
- /* Odd pixel at end */
- write_data3(0, ((c1 >> 8) & 0x0F), (c1 & 0xFF));
- break;
- }
- x = srcx;
- p += lg;
- pos += srccx;
- }
- /* Get the next pixel */
- switch((pos+x)&1) {
- case 0: c2 = (((color_t)p[0]) << 4)|(((color_t)p[1])>>4); break;
- case 1: c2 = (((color_t)p[1]&0x0F) << 8)|((color_t)p[1]); break;
- }
- write_data3(((c1 >> 4) & 0xFF), (((c1 << 4) & 0xF0)|((c2 >> 8) & 0x0F)), (c2 & 0xFF));
- if (++x >= endx) {
- if (++y >= endy)
- break;
- x = srcx;
- p += lg;
- pos += srccx;
- }
- }
- #endif
- release_bus();
- }
-#endif
-
-#if (GDISP_NEED_PIXELREAD && GDISP_HARDWARE_PIXELREAD)
- /**
- * @brief Get the color of a particular pixel.
- * @note If x,y is off the screen, the result is undefined.
- *
- * @param[in] x, y The start of the text
- *
- * @notapi
- */
- color_t gdisp_lld_get_pixel_color(coord_t x, coord_t y) {
- /* NOT IMPLEMENTED */
- /* Some board hardware might support this in the future.
- * The Olimex board doesn't.
- */
- }
-#endif
-
-#if (GDISP_NEED_SCROLL && GDISP_HARDWARE_SCROLL)
- /**
- * @brief Scroll vertically a section of the screen.
- * @note If x,y + cx,cy is off the screen, the result is undefined.
- * @note If lines is >= cy, it is equivelent to a area fill with bgcolor.
- *
- * @param[in] x, y The start of the area to be scrolled
- * @param[in] cx, cy The size of the area to be scrolled
- * @param[in] lines The number of lines to scroll (Can be positive or negative)
- * @param[in] bgcolor The color to fill the newly exposed area.
- *
- * @notapi
- */
- void gdisp_lld_vertical_scroll(coord_t x, coord_t y, coord_t cx, coord_t cy, int lines, color_t bgcolor) {
- /* NOT IMPLEMENTED */
- /* The hardware seems capable of doing this.
- * It is just really complex so we leave it out for now.
- */
- }
-#endif
-
-#if GDISP_HARDWARE_CONTROL || defined(__DOXYGEN__)
- /**
- * @brief Driver Control
- * @details Unsupported control codes are ignored.
- * @note The value parameter should always be typecast to (void *).
- * @note There are some predefined and some specific to the low level driver.
- * @note GDISP_CONTROL_POWER - Takes a gdisp_powermode_t
- * GDISP_CONTROL_ORIENTATION - Takes a gdisp_orientation_t
- * GDISP_CONTROL_BACKLIGHT - Takes an int from 0 to 100. For a driver
- * that only supports off/on anything other
- * than zero is on.
- * GDISP_CONTROL_CONTRAST - Takes an int from 0 to 100.
- * GDISP_CONTROL_LLD - Low level driver control constants start at
- * this value.
- *
- * @param[in] what What to do.
- * @param[in] value The value to use (always cast to a void *).
- *
- * @notapi
- */
- void gdisp_lld_control(unsigned what, void *value) {
- /* The hardware is capable of supporting...
- * GDISP_CONTROL_POWER - not implemented yet
- * GDISP_CONTROL_ORIENTATION - not implemented yet
- * GDISP_CONTROL_BACKLIGHT - supported (the OlimexSAM7EX256 board.h currently only implements off/on although PWM is supported by the hardware)
- * GDISP_CONTROL_CONTRAST - supported
- */
- switch(what) {
-#if 0
- // NOT IMPLEMENTED YET
- case GDISP_CONTROL_POWER:
- if (GDISP.Powermode == (gdisp_powermode_t)value)
- return;
- switch((gdisp_powermode_t)value) {
- case powerOff:
- // Code here
- break;
- case powerOn:
- // Code here
- /* You may need this ---
- * if (GDISP.Powermode != powerSleep)
- * gdisp_lld_init();
- */
- break;
- case powerSleep:
- /* Code here */
- break;
- default:
- return;
- }
- GDISP.Powermode = (gdisp_powermode_t)value;
- return;
-#endif
-#if 0
- // NOT IMPLEMENTED YET
- case GDISP_CONTROL_ORIENTATION:
- if (GDISP.Orientation == (gdisp_orientation_t)value)
- return;
- // WriteSpiData(0x48); // no mirror Y (temporary to satisfy Olimex bmptoarray utility)
- // WriteSpiData(0xC8); // restore to (mirror x and y, reverse rgb)
- switch((gdisp_orientation_t)value) {
- case GDISP_ROTATE_0:
- // Code here
- GDISP.Height = GDISP_SCREEN_HEIGHT;
- GDISP.Width = GDISP_SCREEN_WIDTH;
- break;
- case GDISP_ROTATE_90:
- // Code here
- GDISP.Height = GDISP_SCREEN_WIDTH;
- GDISP.Width = GDISP_SCREEN_HEIGHT;
- break;
- case GDISP_ROTATE_180:
- // Code here
- GDISP.Height = GDISP_SCREEN_HEIGHT;
- GDISP.Width = GDISP_SCREEN_WIDTH;
- break;
- case GDISP_ROTATE_270:
- // Code here
- GDISP.Height = GDISP_SCREEN_WIDTH;
- GDISP.Width = GDISP_SCREEN_HEIGHT;
- break;
- default:
- return;
- }
- #if GDISP_NEED_CLIP || GDISP_NEED_VALIDATION
- GDISP.clipx0 = 0;
- GDISP.clipy0 = 0;
- GDISP.clipx1 = GDISP.Width;
- GDISP.clipy1 = GDISP.Height;
- #endif
- GDISP.Orientation = (gdisp_orientation_t)value;
- return;
-#endif
- case GDISP_CONTROL_BACKLIGHT:
- if ((unsigned)value > 100) value = (void *)100;
- set_backlight((unsigned)value);
- GDISP.Backlight = (unsigned)value;
- return;
- case GDISP_CONTROL_CONTRAST:
- if ((unsigned)value > 100) value = (void *)100;
- acquire_bus();
- write_cmd1(CONTRAST,(unsigned)value);
- release_bus();
- GDISP.Contrast = (unsigned)value;
- return;
- }
- }
-#endif
-
-#endif /* GFX_USE_GDISP */
-/** @} */
diff --git a/drivers/gdisp/Nokia6610GE12/gdisp_lld.mk b/drivers/gdisp/Nokia6610GE12/gdisp_lld.mk
index 575d52a3..65781667 100644
--- a/drivers/gdisp/Nokia6610GE12/gdisp_lld.mk
+++ b/drivers/gdisp/Nokia6610GE12/gdisp_lld.mk
@@ -1,5 +1,2 @@
-# List the required driver.
-GFXSRC += $(GFXLIB)/drivers/gdisp/Nokia6610GE12/gdisp_lld.c
-
-# Required include directories
GFXINC += $(GFXLIB)/drivers/gdisp/Nokia6610GE12
+GFXSRC += $(GFXLIB)/drivers/gdisp/Nokia6610GE12/gdisp_lld_Nokia6610GE12.c
diff --git a/drivers/gdisp/Nokia6610GE12/gdisp_lld_Nokia6610GE12.c b/drivers/gdisp/Nokia6610GE12/gdisp_lld_Nokia6610GE12.c
new file mode 100644
index 00000000..28a2fceb
--- /dev/null
+++ b/drivers/gdisp/Nokia6610GE12/gdisp_lld_Nokia6610GE12.c
@@ -0,0 +1,262 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/Nokia6610GE12/gdisp_lld.c
+ * @brief GDISP Graphics Driver subsystem low level driver source for the Nokia6610 GE12 display.
+ */
+
+#include "gfx.h"
+
+#if GFX_USE_GDISP
+
+#if defined(GDISP_SCREEN_HEIGHT)
+ #warning "GDISP: This low level driver does not support setting a screen size. It is being ignored."
+ #undef GDISP_SCREEN_HEIGHT
+#endif
+#if defined(GDISP_SCREEN_WIDTH)
+ #warning "GDISP: This low level driver does not support setting a screen size. It is being ignored."
+ #undef GDISP_SCREEN_WIDTH
+#endif
+
+#define GDISP_DRIVER_VMT GDISPVMT_Nokia6610GE12
+#include "../drivers/gdisp/Nokia6610GE12/gdisp_lld_config.h"
+#include "gdisp/lld/gdisp_lld.h"
+
+#include "board_Nokia6610GE12.h"
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+#include "GE12.h"
+
+#define GDISP_SCAN_LINES 132
+#define GDISP_SLEEP_SIZE 32 /* Sleep mode window lines - this must be 32 on this controller */
+
+// Set parameters if they are not already set
+#ifndef GDISP_SCREEN_HEIGHT
+ #define GDISP_SCREEN_HEIGHT 130
+#endif
+#ifndef GDISP_SCREEN_WIDTH
+ #define GDISP_SCREEN_WIDTH 130
+#endif
+#ifndef GDISP_RAM_X_OFFSET
+ #define GDISP_RAM_X_OFFSET 0 /* Offset in RAM of visible area */
+#endif
+#ifndef GDISP_RAM_Y_OFFSET
+ #define GDISP_RAM_Y_OFFSET 2 /* Offset in RAM of visible area */
+#endif
+#ifndef GDISP_SLEEP_POS
+ #define GDISP_SLEEP_POS ((GDISP_SCAN_LINES-GDISP_SLEEP_SIZE)/2 & ~3)
+#endif
+#ifndef GDISP_INITIAL_CONTRAST
+ #define GDISP_INITIAL_CONTRAST 50
+#endif
+#ifndef GDISP_INITIAL_BACKLIGHT
+ #define GDISP_INITIAL_BACKLIGHT 100
+#endif
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local variables. */
+/*===========================================================================*/
+
+// Use the priv pointer itself to save our color. This save allocating ram for it
+// and works provided sizeof(uint16_t) <= sizeof(void *)
+#define savecolor(g) (*(uint16_t *)&g->priv)
+
+#define GDISP_FLG_ODDBYTE (GDISP_FLG_DRIVER<<0)
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+// Some macros just to make reading the code easier
+#define delayms(ms) gfxSleepMilliseconds(ms)
+#define write_data2(g, d1, d2) { write_data(g, d1); write_data(g, d2); }
+#define write_data3(g, d1, d2, d3) { write_data(g, d1); write_data(g, d2); write_data(g, d3); }
+#define write_reg(g, cmd, d1) { write_index(g, cmd); write_data(g, d1); }
+#define write_reg2(g, cmd, d1, d2) { write_index(g, cmd); write_data2(g, d1, d2); }
+#define write_reg3(g, cmd, d1, d2, d3) { write_index(g, cmd); write_data3(g, d1, d2, d3); }
+
+static inline void set_viewport(GDisplay* g) {
+ write_reg2(g, CASET, GDISP_RAM_X_OFFSET+g->p.x, GDISP_RAM_X_OFFSET+g->p.x+g->p.cx-1); // Column address set
+ write_reg2(g, PASET, GDISP_RAM_Y_OFFSET+g->p.y, GDISP_RAM_Y_OFFSET+g->p.y+g->p.cy-1); // Page address set
+ write_index(g, RAMWR);
+}
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
+ // No private area for this controller
+ g->priv = 0;
+
+ // Initialise the board interface
+ init_board(g);
+
+ // Hardware reset
+ setpin_reset(g, TRUE);
+ delayms(20);
+ setpin_reset(g, FALSE);
+ delayms(20);
+
+ acquire_bus(g);
+
+ write_index(g, SLEEPOUT); // Sleep out
+ write_reg(g, COLMOD, 0x03); // Color Interface Pixel Format - 0x03 = 12 bits-per-pixel
+ write_reg(g, MADCTL, 0x00); // Memory access controller
+ write_reg(g, SETCON, 128*GDISP_INITIAL_CONTRAST/101-64); // Write contrast
+ delayms(20);
+
+ // Finish Init
+ post_init_board(g);
+
+ release_bus(g);
+
+ /* Turn on the back-light */
+ set_backlight(g, GDISP_INITIAL_BACKLIGHT);
+
+ /* Initialise the GDISP structure to match */
+ g->g.Width = GDISP_SCREEN_WIDTH;
+ g->g.Height = GDISP_SCREEN_HEIGHT;
+ g->g.Orientation = GDISP_ROTATE_0;
+ g->g.Powermode = powerOn;
+ g->g.Backlight = GDISP_INITIAL_BACKLIGHT;
+ g->g.Contrast = GDISP_INITIAL_CONTRAST;
+ return TRUE;
+}
+
+#if GDISP_HARDWARE_STREAM_WRITE
+ LLDSPEC void gdisp_lld_write_start(GDisplay *g) {
+ acquire_bus(g);
+ set_viewport(g);
+ g->flags &= ~GDISP_FLG_ODDBYTE;
+ }
+ LLDSPEC void gdisp_lld_write_color(GDisplay *g) {
+ uint16_t c;
+
+ c = COLOR2NATIVE(g->p.color);
+ if ((g->flags & GDISP_FLG_ODDBYTE)) {
+ // Write the pair of pixels to the display
+ write_data3(g, ((savecolor(g) >> 4) & 0xFF),
+ (((savecolor(g) << 4) & 0xF0)|((c >> 8) & 0x0F)),
+ (c & 0xFF));
+ g->flags &= ~GDISP_FLG_ODDBYTE;
+ } else {
+ savecolor(g) = c;
+ g->flags |= GDISP_FLG_ODDBYTE;
+ }
+ }
+ LLDSPEC void gdisp_lld_write_stop(GDisplay *g) {
+ if ((g->flags & GDISP_FLG_ODDBYTE)) {
+ write_data2(g, ((savecolor(g) >> 4) & 0xFF), ((savecolor(g) << 4) & 0xF0));
+ write_index(g, NOP);
+ }
+ release_bus(g);
+ }
+#endif
+
+#if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL
+ LLDSPEC void gdisp_lld_control(GDisplay *g) {
+ /* The hardware is capable of supporting...
+ * GDISP_CONTROL_POWER - supported
+ * GDISP_CONTROL_ORIENTATION - supported
+ * GDISP_CONTROL_BACKLIGHT - supported
+ * GDISP_CONTROL_CONTRAST - supported
+ */
+ switch(g->p.x) {
+ case GDISP_CONTROL_POWER:
+ if (g->g.Powermode == (powermode_t)g->p.ptr)
+ return;
+ switch((powermode_t)g->p.ptr) {
+ case powerOff:
+ acquire_bus(g);
+ write_index(g, SLEEPIN);
+ release_bus(g);
+ break;
+ case powerOn:
+ acquire_bus(g);
+ write_index(g, SLEEPOUT);
+ delayms(20);
+ write_index(g, NORON); // Set Normal mode (my)
+ release_bus(g);
+ break;
+ case powerSleep:
+ acquire_bus(g);
+ write_index(g, SLEEPOUT);
+ delayms(20);
+ write_reg2(g, PTLAR, GDISP_SLEEP_POS, GDISP_SLEEP_POS+GDISP_SLEEP_SIZE)
+ write_index(g, PTLON);
+ release_bus(g);
+ break;
+ default:
+ return;
+ }
+ g->g.Powermode = (powermode_t)g->p.ptr;
+ return;
+
+ case GDISP_CONTROL_ORIENTATION:
+ if (g->g.Orientation == (orientation_t)g->p.ptr)
+ return;
+ switch((orientation_t)g->p.ptr) {
+ case GDISP_ROTATE_0:
+ acquire_bus(g);
+ write_reg(g, MADCTL, 0x00);
+ release_bus(g);
+ g->g.Height = GDISP_SCREEN_HEIGHT;
+ g->g.Width = GDISP_SCREEN_WIDTH;
+ break;
+ case GDISP_ROTATE_90:
+ acquire_bus(g);
+ write_reg(g, MADCTL, 0xA0); // MY, MX, V, LAO, RGB, X, X, X
+ release_bus(g);
+ g->g.Height = GDISP_SCREEN_WIDTH;
+ g->g.Width = GDISP_SCREEN_HEIGHT;
+ break;
+ case GDISP_ROTATE_180:
+ acquire_bus(g);
+ write_reg(g, MADCTL, 0xC0);
+ release_bus(g);
+ g->g.Height = GDISP_SCREEN_HEIGHT;
+ g->g.Width = GDISP_SCREEN_WIDTH;
+ break;
+ case GDISP_ROTATE_270:
+ acquire_bus(g);
+ write_reg(g, MADCTL, 0x60);
+ release_bus(g);
+ g->g.Height = GDISP_SCREEN_WIDTH;
+ g->g.Width = GDISP_SCREEN_HEIGHT;
+ break;
+ default:
+ return;
+ }
+ g->g.Orientation = (orientation_t)g->p.ptr;
+ return;
+
+ case GDISP_CONTROL_BACKLIGHT:
+ if ((unsigned)g->p.ptr > 100) g->p.ptr = (void *)100;
+ set_backlight(g, (unsigned)g->p.ptr);
+ g->g.Backlight = (unsigned)g->p.ptr;
+ return;
+ case GDISP_CONTROL_CONTRAST:
+ if ((unsigned)g->p.ptr > 100) g->p.ptr = (void *)100;
+ acquire_bus(g);
+ write_reg(g, SETCON,(unsigned)128*(unsigned)g->p.ptr/101-64);
+ release_bus(g);
+ g->g.Contrast = (unsigned)g->p.ptr;
+ return;
+ }
+ }
+#endif
+
+#endif /* GFX_USE_GDISP */
diff --git a/drivers/gdisp/Nokia6610GE12/gdisp_lld_board_olimexsam7ex256.h b/drivers/gdisp/Nokia6610GE12/gdisp_lld_board_olimexsam7ex256.h
deleted file mode 100644
index ce0f7362..00000000
--- a/drivers/gdisp/Nokia6610GE12/gdisp_lld_board_olimexsam7ex256.h
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * This file is subject to the terms of the GFX License. If a copy of
- * the license was not distributed with this file, you can obtain one at:
- *
- * http://ugfx.org/license.html
- */
-
-/**
- * @file drivers/gdisp/Nokia6610GE12/gdisp_lld_board_olimexsam7ex256.h
- * @brief GDISP Graphic Driver subsystem board interface for the Olimex SAM7-EX256 board.
- *
- * @addtogroup GDISP
- * @{
- */
-
-#ifndef _GDISP_LLD_BOARD_H
-#define _GDISP_LLD_BOARD_H
-
-// ******************************************************
-// Pointers to AT91SAM7X256 peripheral data structures
-// ******************************************************
-volatile AT91PS_PIO pPIOA = AT91C_BASE_PIOA;
-volatile AT91PS_PIO pPIOB = AT91C_BASE_PIOB;
-volatile AT91PS_SPI pSPI = AT91C_BASE_SPI0;
-volatile AT91PS_PMC pPMC = AT91C_BASE_PMC;
-volatile AT91PS_PDC pPDC = AT91C_BASE_PDC_SPI0;
-
-/**
- * @brief Initialise the board for the display.
- * @notes Performs the following functions:
- * 1. initialise the spi port used by your display
- * 2. initialise the reset pin (initial state not-in-reset)
- * 3. initialise the chip select pin (initial state not-active)
- * 4. initialise the backlight pin (initial state back-light off)
- *
- * @notapi
- */
-static inline void init_board(void) {
- // *********************************************************************************************
- // InitSpi( )
- //
- // Sets up SPI channel 0 for communications to Nokia 6610 LCD Display
- //
- // I/O ports used: PA2 = LCD Reset (set to low to reset)
- // PA12 = LCD chip select (set to low to select the LCD chip)
- // PA16 = SPI0_MISO Master In - Slave Out (not used in LCD interface)
- // PA17 = SPI0_MOSI Master Out - Slave In pin (Serial Data to LCD slave)
- // PA18 = SPI0_SPCK Serial Clock (to LCD slave)
- // PB20 = backlight control (normally PWM control, 1 = full on)
- //
- // *********************************************************************************************}
-
- /* This code should really use the ChibiOS driver for these functions */
-
- // Pin for backlight
- pPIOB->PIO_CODR = PIOB_LCD_BL_MASK; // Set PB20 to LOW
- pPIOB->PIO_OER = PIOB_LCD_BL_MASK; // Configure PB20 as output
-
- // Reset pin
- pPIOA->PIO_SODR = PIOA_LCD_RESET_MASK; // Set PA2 to HIGH
- pPIOA->PIO_OER = PIOA_LCD_RESET_MASK; // Configure PA2 as output
-
- // CS pin - this seems to be ignored
- // pPIOA->PIO_SODR = 1<<12; // Set PA2 to HIGH
- // pPIOA->PIO_OER = 1<<12; // Configure PA2 as output
-
- // Init SPI0
- // Disable the following pins from PIO control (will be used instead by the SPI0 peripheral)
- // BIT12 = PA12 -> SPI0_NPCS0 chip select
- // BIT16 = PA16 -> SPI0_MISO Master In - Slave Out (not used in LCD interface)
- // BIT17 = PA17 -> SPI0_MOSI Master Out - Slave In pin (Serial Data to LCD slave)
- // BIT18 = PA18 -> SPI0_SPCK Serial Clock (to LCD slave)
- pPIOA->PIO_PDR = (1<<12) | (1<<16) | (1<<17) | (1<<18);
- pPIOA->PIO_ASR = (1<<12) | (1<<16) | (1<<17) | (1<<18);
- pPIOA->PIO_BSR = 0;
-
- //enable the clock of SPI
- pPMC->PMC_PCER = 1 << AT91C_ID_SPI0;
-
- // Fixed mode
- pSPI->SPI_CR = 0x81; //SPI Enable, Sowtware reset
- pSPI->SPI_CR = 0x01; //SPI Enable
-
- //pSPI->SPI_MR = 0xE0019; //Master mode, fixed select, disable decoder, FDIV=1 (MCK), PCS=1110
- pSPI->SPI_MR = 0xE0011; //Master mode, fixed select, disable decoder, FDIV=0 (MCK), PCS=1110
-
- //pSPI->SPI_CSR[0] = 0x01010C11; //9bit, CPOL=1, ClockPhase=0, SCLK = 48Mhz/32*12 = 125kHz
- pSPI->SPI_CSR[0] = 0x01010311; //9bit, CPOL=1, ClockPhase=0, SCLK = 48Mhz/8 = 6MHz if using commented MR line above
-}
-
-/**
- * @brief Set or clear the lcd reset pin.
- *
- * @param[in] state TRUE = lcd in reset, FALSE = normal operation
- *
- * @notapi
- */
-static inline void setpin_reset(bool_t state) {
- if (state)
- palClearPad(IOPORT1, PIOA_LCD_RESET);
- else
- palSetPad(IOPORT1, PIOA_LCD_RESET);
-}
-
-/**
- * @brief Set the lcd back-light level.
- * @note For now 0% turns the backlight off, anything else the backlight is on.
- * While the hardware supports PWM backlight control, we are not using it
- * yet.
- *
- * @param[in] percent 0 to 100%
- *
- * @notapi
- */
-static inline void set_backlight(uint8_t percent) {
- if (percent)
- palSetPad(IOPORT2, PIOB_LCD_BL);
- else
- palClearPad(IOPORT2, PIOB_LCD_BL);
-}
-
-/**
- * @brief Take exclusive control of the bus
- *
- * @notapi
- */
-static inline void acquire_bus(void) {
- /* Nothing to do for this board as the LCD is the only device on the SPI port */
-}
-
-/**
- * @brief Release exclusive control of the bus
- *
- * @notapi
- */
-static inline void release_bus(void) {
- // Nothing to do for this board as the LCD is the only device on the SPI port
-}
-
-/**
- * @brief Send an 8 bit command to the lcd.
- *
- * @param[in] cmd The command to send
- *
- * @notapi
- */
-static inline void write_cmd(uint16_t cmd) {
- // wait for the previous transfer to complete
- while((pSPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0);
- // send the command
- pSPI->SPI_TDR = cmd & 0xFF;
-}
-
-/**
- * @brief Send an 8 bit data to the lcd.
- *
- * @param[in] data The data to send
- *
- * @notapi
- */
-static inline void write_data(uint16_t data) {
- // wait for the previous transfer to complete
- while((pSPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0);
- // send the data
- pSPI->SPI_TDR = data | 0x0100;
-}
-
-#if GDISP_HARDWARE_READPIXEL || GDISP_HARDWARE_SCROLL || defined(__DOXYGEN__)
-/**
- * @brief Read data from the lcd.
- *
- * @return The data from the lcd
- *
- * @notapi
- */
-static inline uint16_t read_data(void) {
- #error "gdispNokia6610GE12: GDISP_HARDWARE_READPIXEL and GDISP_HARDWARE_SCROLL are not supported on this board"
- return 0;
-}
-#endif
-
-#endif /* _GDISP_LLD_BOARD_H */
-/** @} */
diff --git a/drivers/gdisp/Nokia6610GE12/gdisp_lld_board_template.h b/drivers/gdisp/Nokia6610GE12/gdisp_lld_board_template.h
deleted file mode 100644
index a1fa6050..00000000
--- a/drivers/gdisp/Nokia6610GE12/gdisp_lld_board_template.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * This file is subject to the terms of the GFX License. If a copy of
- * the license was not distributed with this file, you can obtain one at:
- *
- * http://ugfx.org/license.html
- */
-
-/**
- * @file drivers/gdisp/Nokia6610GE8/gdisp_lld_board_template.h
- * @brief GDISP Graphic Driver subsystem board interface for the Nokia6610 GE8 display.
- *
- * @addtogroup GDISP
- * @{
- */
-
-#ifndef _GDISP_LLD_BOARD_H
-#define _GDISP_LLD_BOARD_H
-
-/**
- * @brief Initialise the board for the display.
- * @notes Performs the following functions:
- * 1. initialise the spi port used by your display
- * 2. initialise the reset pin (initial state not-in-reset)
- * 3. initialise the chip select pin (initial state not-active)
- * 4. initialise the backlight pin (initial state back-light off)
- *
- * @notapi
- */
-static inline void init_board(void) {
-
-}
-
-/**
- * @brief Set or clear the lcd reset pin.
- *
- * @param[in] state TRUE = lcd in reset, FALSE = normal operation
- *
- * @notapi
- */
-static inline void setpin_reset(bool_t state) {
-
-}
-
-/**
- * @brief Set the lcd back-light level.
- * @note For now 0% turns the backlight off, anything else the backlight is on.
- * While the hardware supports PWM backlight control, we are not using it
- * yet.
- *
- * @param[in] percent 0 to 100%
- *
- * @notapi
- */
-static inline void set_backlight(uint8_t percent) {
-
-}
-
-/**
- * @brief Take exclusive control of the bus
- *
- * @notapi
- */
-static inline void acquire_bus(void) {
-
-}
-
-/**
- * @brief Release exclusive control of the bus
- *
- * @notapi
- */
-static inline void release_bus(void) {
-
-}
-
-/**
- * @brief Send an 8 bit command to the lcd.
- *
- * @param[in] cmd The command to send
- *
- * @notapi
- */
-static inline void write_cmd(uint16_t cmd) {
-
-}
-
-/**
- * @brief Send an 8 bit data to the lcd.
- *
- * @param[in] data The data to send
- *
- * @notapi
- */
-static inline void write_data(uint16_t data) {
-
-}
-
-#if GDISP_HARDWARE_READPIXEL || GDISP_HARDWARE_SCROLL || defined(__DOXYGEN__)
-/**
- * @brief Read data from the lcd.
- *
- * @return The data from the lcd
- * @note The chip select may need to be asserted/de-asserted
- * around the actual spi read
- *
- * @notapi
- */
-static inline uint16_t read_data(void) {
-
-}
-#endif
-
-#endif /* _GDISP_LLD_BOARD_H */
-/** @} */
diff --git a/drivers/gdisp/Nokia6610GE12/gdisp_lld_config.h b/drivers/gdisp/Nokia6610GE12/gdisp_lld_config.h
index 57b8b916..19a455d8 100644
--- a/drivers/gdisp/Nokia6610GE12/gdisp_lld_config.h
+++ b/drivers/gdisp/Nokia6610GE12/gdisp_lld_config.h
@@ -22,21 +22,10 @@
/* Driver hardware support. */
/*===========================================================================*/
-#define GDISP_DRIVER_NAME "Nokia6610GE12"
+#define GDISP_HARDWARE_CONTROL TRUE
+#define GDISP_HARDWARE_STREAM_WRITE TRUE
-#define GDISP_HARDWARE_FILLS TRUE
-#define GDISP_HARDWARE_BITFILLS TRUE
-#define GDISP_HARDWARE_CONTROL TRUE
-
-#define GDISP_SOFTWARE_TEXTFILLDRAW FALSE
-#define GDISP_SOFTWARE_TEXTBLITCOLUMN FALSE
-
-#define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_RGB444
-/* This driver supports both packed and unpacked pixel formats and line formats.
- * By default we leave these as FALSE.
- */
-#define GDISP_PACKED_PIXELS FALSE
-#define GDISP_PACKED_LINES FALSE
+#define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_RGB444
#endif /* GFX_USE_GDISP */
diff --git a/drivers/gdisp/Nokia6610GE8/board_Nokia6610GE8_template.h b/drivers/gdisp/Nokia6610GE8/board_Nokia6610GE8_template.h
new file mode 100644
index 00000000..28fc9f70
--- /dev/null
+++ b/drivers/gdisp/Nokia6610GE8/board_Nokia6610GE8_template.h
@@ -0,0 +1,131 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/Nokia6610GE8/board_Nokia6610GE8_template.h
+ * @brief GDISP Graphic Driver subsystem board interface for the Nokia6610 GE12 display.
+ *
+ * @addtogroup GDISP
+ * @{
+ */
+
+#ifndef _GDISP_LLD_BOARD_H
+#define _GDISP_LLD_BOARD_H
+
+/*
+ * Set various display properties. These properties mostly depend on the exact controller chip you get.
+ * The defaults should work for most controllers.
+ */
+//#define GDISP_SCREEN_HEIGHT 130 // The visible display height
+//#define GDISP_SCREEN_WIDTH 130 // The visible display width
+//#define GDISP_RAM_X_OFFSET 0 // The x offset of the visible area
+//#define GDISP_RAM_Y_OFFSET 2 // The y offset of the visible area
+//#define GDISP_SLEEP_POS 50 // The position of the sleep mode partial display
+//#define GDISP_INITIAL_CONTRAST 50 // The initial contrast percentage
+//#define GDISP_INITIAL_BACKLIGHT 100 // The initial backlight percentage
+
+/**
+ * @brief Initialise the board for the display.
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @note Set the g->board member to whatever is appropriate. For multiple
+ * displays this might be a pointer to the appropriate register set.
+ *
+ * @notapi
+ */
+static inline void init_board(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief After the initialisation.
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void post_init_board(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Set or clear the lcd reset pin.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] state TRUE = lcd in reset, FALSE = normal operation
+ *
+ * @notapi
+ */
+static inline void setpin_reset(GDisplay *g, bool_t state) {
+ (void) g;
+ (void) state;
+}
+
+/**
+ * @brief Set the lcd back-light level.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] percent 0 to 100%
+ *
+ * @notapi
+ */
+static inline void set_backlight(GDisplay *g, uint8_t percent) {
+ (void) g;
+ (void) percent;
+}
+
+/**
+ * @brief Take exclusive control of the bus
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void acquire_bus(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Release exclusive control of the bus
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void release_bus(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Send data to the index register.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] index The index register to set
+ *
+ * @notapi
+ */
+static inline void write_index(GDisplay *g, uint16_t index) {
+ (void) g;
+ (void) index;
+}
+
+/**
+ * @brief Send data to the lcd.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] data The data to send
+ *
+ * @notapi
+ */
+static inline void write_data(GDisplay *g, uint16_t data) {
+ (void) g;
+ (void) data;
+}
+
+#endif /* _GDISP_LLD_BOARD_H */
+/** @} */
diff --git a/drivers/gdisp/Nokia6610GE8/gdisp_lld.c b/drivers/gdisp/Nokia6610GE8/gdisp_lld.c
deleted file mode 100644
index ba5178d8..00000000
--- a/drivers/gdisp/Nokia6610GE8/gdisp_lld.c
+++ /dev/null
@@ -1,545 +0,0 @@
-/*
- * This file is subject to the terms of the GFX License. If a copy of
- * the license was not distributed with this file, you can obtain one at:
- *
- * http://ugfx.org/license.html
- */
-
-/**
- * @file drivers/gdisp/Nokia6610GE8/gdisp_lld.c
- * @brief GDISP Graphics Driver subsystem low level driver source for the Nokia6610 GE8 display.
- *
- * @addtogroup GDISP
- * @{
- */
-
-#include "gfx.h"
-
-#if GFX_USE_GDISP /*|| defined(__DOXYGEN__)*/
-
-/* Include the emulation code for things we don't support */
-#include "gdisp/lld/emulation.c"
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-#include "GE8.h"
-
-/* This controller is only ever used with a 130 x 130 display */
-#if defined(GDISP_SCREEN_HEIGHT)
- #warning "GDISP: This low level driver does not support setting a screen size. It is being ignored."
- #undef GDISP_SCREEN_HEIGHT
-#endif
-#if defined(GDISP_SCREEN_WIDTH)
- #warning "GDISP: This low level driver does not support setting a screen size. It is being ignored."
- #undef GDISP_SCREEN_WIDTH
-#endif
-#define GDISP_SCREEN_HEIGHT 130
-#define GDISP_SCREEN_WIDTH 130
-
-#define GDISP_SCAN_LINES 132 /* 130 lines + 2 invisible lines */
-#define GDISP_RAM_X_OFFSET 0 /* Offset in RAM of visible area */
-#define GDISP_RAM_Y_OFFSET 2 /* Offset in RAM of visible area */
-#define GDISP_SLEEP_SIZE 32 /* Sleep mode window lines */
-#define GDISP_SLEEP_POS ((GDISP_SCAN_LINES-GDISP_SLEEP_SIZE)/2)
-
-#define GDISP_INITIAL_CONTRAST 38
-#define GDISP_INITIAL_BACKLIGHT 100
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver local variables. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-#include "gdisp_lld_board.h"
-
-// Some macros just to make reading the code easier
-#define delayms(ms) gfxSleepMilliseconds(ms)
-#define write_data2(d1, d2) { write_data(d1); write_data(d2); }
-#define write_data3(d1, d2, d3) { write_data(d1); write_data(d2); write_data(d3); }
-#define write_data4(d1, d2, d3, d4) { write_data(d1); write_data(d2); write_data(d3); write_data(d4); }
-#define write_cmd1(cmd, d1) { write_cmd(cmd); write_data(d1); }
-#define write_cmd2(cmd, d1, d2) { write_cmd(cmd); write_data2(d1, d2); }
-#define write_cmd3(cmd, d1, d2, d3) { write_cmd(cmd); write_data3(d1, d2, d3); }
-#define write_cmd4(cmd, d1, d2, d3, d4) { write_cmd(cmd); write_data4(d1, d2, d3, d4); }
-
-// Set the drawing window on the controller.
-// An inline function has been used here incase the parameters have side effects with the internal calculations.
-static __inline void setviewport(coord_t x, coord_t y, coord_t cx, coord_t cy) {
- switch(GDISP.Orientation) {
- case GDISP_ROTATE_0:
- write_cmd2(CASET, GDISP_RAM_X_OFFSET+x, GDISP_RAM_X_OFFSET+x+cx-1); // Column address set
- write_cmd2(PASET, GDISP_RAM_Y_OFFSET+y, GDISP_RAM_Y_OFFSET+y+cy-1); // Page address set
- break;
- case GDISP_ROTATE_90:
- write_cmd2(CASET, GDISP_RAM_X_OFFSET+GDISP.Height-y-cy, GDISP_RAM_X_OFFSET+GDISP.Height-y-1);
- write_cmd2(PASET, GDISP_RAM_Y_OFFSET+x, GDISP_RAM_Y_OFFSET+x+cx-1);
- break;
- case GDISP_ROTATE_180:
- write_cmd2(CASET, GDISP_RAM_X_OFFSET+GDISP.Width-x-cx, GDISP_RAM_X_OFFSET+GDISP.Width-x-1);
- write_cmd2(PASET, GDISP_RAM_Y_OFFSET+GDISP.Height-y-cy, GDISP_RAM_Y_OFFSET+GDISP.Height-y-1);
- break;
- case GDISP_ROTATE_270:
- write_cmd2(CASET, GDISP_RAM_X_OFFSET+y, GDISP_RAM_X_OFFSET+y+cy-1);
- write_cmd2(PASET, GDISP_RAM_Y_OFFSET+GDISP.Width-x-cx, GDISP_RAM_Y_OFFSET+GDISP.Width-x-1);
- break;
- }
-}
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Low level GDISP driver initialisation.
- *
- * @notapi
- */
-bool_t gdisp_lld_init(void) {
- /* Initialise your display */
- init_board();
-
- // Hardware reset
- setpin_reset(TRUE);
- delayms(20);
- setpin_reset(FALSE);
- delayms(20);
-
- // Get the bus for the following initialisation commands
- acquire_bus();
-
- write_cmd4(DISCTL, 0x00, GDISP_SCAN_LINES/4-1, 0x0A, 0x00); // Display control - How the controller drives the LCD
- // P1: 0x00 = 2 divisions, switching period=8 (default)
- // P2: 0x20 = nlines/4 - 1 = 132/4 - 1 = 32)
- // P3: 0x0A = standard inverse highlight, inversion every frame
- // P4: 0x00 = dispersion on
- write_cmd1(COMSCN, 0x01); // COM scan - How the LCD is connected to the controller
- // P1: 0x01 = Scan 1->80, 160<-81
- write_cmd(OSCON); // Internal oscillator ON
- write_cmd(SLPOUT); // Sleep out
- write_cmd1(PWRCTR, 0x0F); // Power control - reference voltage regulator on, circuit voltage follower on, BOOST ON
- write_cmd3(DATCTL, 0x00, 0x00, 0x02); // Data control
- // P1: 0x00 = page address normal, column address normal, address scan in column direction
- // P2: 0x00 = RGB sequence (default value)
- // P3: 0x02 = 4 bits per colour (Type A)
- write_cmd2(VOLCTR, GDISP_INITIAL_CONTRAST, 0x03); // Voltage control (contrast setting)
- // P1 = Contrast
- // P2 = 3 resistance ratio (only value that works)
- delayms(100); // Allow power supply to stabilise
- write_cmd(DISON); // Turn on the display
-
- // Release the bus
- release_bus();
-
- /* Turn on the back-light */
- set_backlight(GDISP_INITIAL_BACKLIGHT);
-
- /* Initialise the GDISP structure to match */
- GDISP.Width = GDISP_SCREEN_WIDTH;
- GDISP.Height = GDISP_SCREEN_HEIGHT;
- GDISP.Orientation = GDISP_ROTATE_0;
- GDISP.Powermode = powerOn;
- GDISP.Backlight = GDISP_INITIAL_BACKLIGHT;
- GDISP.Contrast = GDISP_INITIAL_CONTRAST;
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- GDISP.clipx0 = 0;
- GDISP.clipy0 = 0;
- GDISP.clipx1 = GDISP.Width;
- GDISP.clipy1 = GDISP.Height;
- #endif
- return TRUE;
-}
-
-/**
- * @brief Draws a pixel on the display.
- *
- * @param[in] x X location of the pixel
- * @param[in] y Y location of the pixel
- * @param[in] color The color of the pixel
- *
- * @notapi
- */
-void gdisp_lld_draw_pixel(coord_t x, coord_t y, color_t color) {
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- if (x < GDISP.clipx0 || y < GDISP.clipy0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
- #endif
- acquire_bus();
- setviewport(x, y, 1, 1);
- write_cmd3(RAMWR, 0, (color>>8) & 0x0F, color & 0xFF);
- release_bus();
-}
-
-/* ---- Optional Routines ---- */
-
-#if GDISP_HARDWARE_FILLS || defined(__DOXYGEN__)
- /**
- * @brief Fill an area with a color.
- *
- * @param[in] x, y The start filled area
- * @param[in] cx, cy The width and height to be filled
- * @param[in] color The color of the fill
- *
- * @notapi
- */
- void gdisp_lld_fill_area(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
- unsigned tuples;
-
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; }
- if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; }
- if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
- if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
- if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
- #endif
-
- tuples = (cx*cy+1)>>1; // With an odd sized area we over-print by one pixel.
- // This extra pixel overwrites the first pixel (harmless as it is the same colour)
-
- acquire_bus();
- setviewport(x, y, cx, cy);
- write_cmd(RAMWR);
- while(tuples--)
- write_data3(((color >> 4) & 0xFF), (((color << 4) & 0xF0)|((color >> 8) & 0x0F)), (color & 0xFF));
- release_bus();
- }
-#endif
-
-#if GDISP_HARDWARE_BITFILLS || defined(__DOXYGEN__)
- /**
- * @brief Fill an area with a bitmap.
- *
- * @param[in] x, y The start filled area
- * @param[in] cx, cy The width and height to be filled
- * @param[in] srcx, srcy The bitmap position to start the fill from
- * @param[in] srccx The width of a line in the bitmap.
- * @param[in] buffer The pixels to use to fill the area.
- *
- * @notapi
- */
- void gdisp_lld_blit_area_ex(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx, coord_t srcy, coord_t srccx, const pixel_t *buffer) {
- coord_t lg;
- color_t c1, c2;
- unsigned tuples;
- #if GDISP_PACKED_PIXELS
- unsigned pnum, pstart;
- const uint8_t *p;
- #else
- const pixel_t *p;
- #endif
-
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; srcx += GDISP.clipx0 - x; x = GDISP.clipx0; }
- if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; srcy += GDISP.clipy0 - y; y = GDISP.clipy0; }
- if (srcx+cx > srccx) cx = srccx - srcx;
- if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
- if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
- if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
- #endif
-
- /* Set up the data window to transfer */
- tuples = (cx * cy + 1)>>1;
- acquire_bus();
- setviewport(x, y, cx, cy);
- write_cmd(RAMWR);
-
- /*
- * Due to the way the Nokia6610 handles a decrementing column or page,
- * we have to make adjustments as to where it is actually drawing from in the bitmap.
- * For example, for 90 degree rotation the column is decremented on each
- * memory write. The controller always starts with column 0 and then decrements
- * to column cx-1, cx-2 etc. We therefore have to write-out the last bitmap line first.
- */
- switch(GDISP.Orientation) {
- case GDISP_ROTATE_0: x = 0; y = 0; break;
- case GDISP_ROTATE_90: x = 0; y = cy-1; break;
- case GDISP_ROTATE_180: x = cx-1; y = cy-1; break;
- case GDISP_ROTATE_270: x = cx-1; y = 0; break;
- }
-
- #if !GDISP_PACKED_PIXELS
- // Although this controller uses packed pixels we support unpacked pixel
- // formats in this blit by packing the data as we feed it to the controller.
-
- lg = srccx - cx; // The buffer gap between lines
- buffer += srcy * srccx + srcx; // The buffer start position
- p = buffer + srccx*y + x; // Adjustment for controller craziness
-
- while(tuples--) {
- /* Get a pixel */
- c1 = *p++;
-
- /* Check for line or buffer wrapping */
- if (++x >= cx) {
- x = 0;
- p += lg;
- if (++y >= cy) {
- y = 0;
- p = buffer;
- }
- }
-
- /* Get the next pixel */
- c2 = *p++;
-
- /* Check for line or buffer wrapping */
- if (++x >= cx) {
- x = 0;
- p += lg;
- if (++y >= cy) {
- y = 0;
- p = buffer;
- }
- }
-
- /* Write the pair of pixels to the display */
- write_data3(((c1 >> 4) & 0xFF), (((c1 << 4) & 0xF0)|((c2 >> 8) & 0x0F)), (c2 & 0xFF));
- }
-
- #else
-
- // Although this controller uses packed pixels, we may have to feed it into
- // the controller with different packing to the source bitmap
- // There are 2 pixels per 3 bytes
-
- #if !GDISP_PACKED_LINES
- srccx = (srccx + 1) & ~1;
- #endif
- pstart = srcy * srccx + srcx; // The starting pixel number
- buffer = (const pixel_t)(((const uint8_t *)buffer) + ((pstart>>1) * 3)); // The buffer start position
- lg = ((srccx-cx)>>1)*3; // The buffer gap between lines
- pnum = pstart + srccx*y + x; // Adjustment for controller craziness
- p = ((const uint8_t *)buffer) + (((srccx*y + x)>>1)*3); // Adjustment for controller craziness
-
- while (tuples--) {
- /* Get a pixel */
- switch(pnum++ & 1) {
- case 0: c1 = (((color_t)p[0]) << 4)|(((color_t)p[1])>>4); break;
- case 1: c1 = (((color_t)p[1]&0x0F) << 8)|((color_t)p[1]); p += 3; break;
- }
-
- /* Check for line or buffer wrapping */
- if (++x >= cx) {
- x = 0;
- p += lg;
- pnum += srccx - cx;
- if (++y >= cy) {
- y = 0;
- p = (const uint8_t *)buffer;
- pnum = pstart;
- }
- }
-
- /* Get the next pixel */
- switch(pnum++ & 1) {
- case 0: c1 = (((color_t)p[0]) << 4)|(((color_t)p[1])>>4); break;
- case 1: c1 = (((color_t)p[1]&0x0F) << 8)|((color_t)p[1]); p += 3; break;
- }
-
- /* Check for line or buffer wrapping */
- if (++x >= cx) {
- x = 0;
- p += lg;
- pnum += srccx - cx;
- if (++y >= cy) {
- y = 0;
- p = (const uint8_t *)buffer;
- pnum = pstart;
- }
- }
-
- /* Write the pair of pixels to the display */
- write_data3(((c1 >> 4) & 0xFF), (((c1 << 4) & 0xF0)|((c2 >> 8) & 0x0F)), (c2 & 0xFF));
- }
- #endif
-
- /* All done */
- release_bus();
- }
-#endif
-
-#if (GDISP_NEED_PIXELREAD && GDISP_HARDWARE_PIXELREAD)
- /**
- * @brief Get the color of a particular pixel.
- * @note If x,y is off the screen, the result is undefined.
- *
- * @param[in] x, y The start of the text
- *
- * @notapi
- */
- color_t gdisp_lld_get_pixel_color(coord_t x, coord_t y) {
- /* NOT IMPLEMENTED */
- /* This controller does not support reading back over the SPI interface.
- * Additionally, the Olimex board doesn't even connect the pin.
- */
- }
-#endif
-
-#if (GDISP_NEED_SCROLL && GDISP_HARDWARE_SCROLL)
- /**
- * @brief Scroll vertically a section of the screen.
- * @note If x,y + cx,cy is off the screen, the result is undefined.
- * @note If lines is >= cy, it is equivelent to a area fill with bgcolor.
- *
- * @param[in] x, y The start of the area to be scrolled
- * @param[in] cx, cy The size of the area to be scrolled
- * @param[in] lines The number of lines to scroll (Can be positive or negative)
- * @param[in] bgcolor The color to fill the newly exposed area.
- *
- * @notapi
- */
- void gdisp_lld_vertical_scroll(coord_t x, coord_t y, coord_t cx, coord_t cy, int lines, color_t bgcolor) {
- /* NOT IMPLEMENTED */
- /**
- * The hardware is capable of doing full width vertical scrolls aligned
- * on a 4 line boundary however that is not sufficient to support this routine.
- *
- * We also can't manually do read/modify scrolling because we can't read in SPI mode.
- */
- }
-#endif
-
-#if GDISP_HARDWARE_CONTROL || defined(__DOXYGEN__)
- /**
- * @brief Driver Control
- * @details Unsupported control codes are ignored.
- * @note The value parameter should always be typecast to (void *).
- * @note There are some predefined and some specific to the low level driver.
- * @note GDISP_CONTROL_POWER - Takes a gdisp_powermode_t
- * GDISP_CONTROL_ORIENTATION - Takes a gdisp_orientation_t
- * GDISP_CONTROL_BACKLIGHT - Takes an int from 0 to 100. For a driver
- * that only supports off/on anything other
- * than zero is on.
- * GDISP_CONTROL_CONTRAST - Takes an int from 0 to 100.
- * GDISP_CONTROL_LLD - Low level driver control constants start at
- * this value.
- *
- * @param[in] what What to do.
- * @param[in] value The value to use (always cast to a void *).
- *
- * @notapi
- */
- void gdisp_lld_control(unsigned what, void *value) {
- /* The hardware is capable of supporting...
- * GDISP_CONTROL_POWER - supported
- * GDISP_CONTROL_ORIENTATION - supported
- * GDISP_CONTROL_BACKLIGHT - supported
- * GDISP_CONTROL_CONTRAST - supported
- */
- switch(what) {
- case GDISP_CONTROL_POWER:
- if (GDISP.Powermode == (gdisp_powermode_t)value)
- return;
- acquire_bus();
- switch((gdisp_powermode_t)value) {
- case powerOff:
- set_backlight(0); // Turn off the backlight
- write_cmd(DISOFF); // Turn off the display
- write_cmd1(PWRCTR, 0x00); // Power control - all off
- write_cmd(SLPIN); // Sleep in
- write_cmd(OSCOFF); // Internal oscillator off
- break;
- case powerOn:
- write_cmd(OSCON); // Internal oscillator on
- write_cmd(SLPOUT); // Sleep out
- write_cmd1(PWRCTR, 0x0F); // Power control - reference voltage regulator on, circuit voltage follower on, BOOST ON
- write_cmd2(VOLCTR, GDISP.Contrast, 0x03); // Voltage control (contrast setting)
- delayms(100); // Allow power supply to stabilise
- write_cmd(DISON); // Turn on the display
- write_cmd(PTLOUT); // Remove sleep window
- set_backlight(GDISP.Backlight); // Turn on the backlight
- break;
- case powerSleep:
- write_cmd(OSCON); // Internal oscillator on
- write_cmd(SLPOUT); // Sleep out
- write_cmd1(PWRCTR, 0x0F); // Power control - reference voltage regulator on, circuit voltage follower on, BOOST ON
- write_cmd2(VOLCTR, GDISP.Contrast, 0x03); // Voltage control (contrast setting)
- delayms(100); // Allow power supply to stabilise
- write_cmd(DISON); // Turn on the display
- write_cmd2(PTLIN, GDISP_SLEEP_POS/4, (GDISP_SLEEP_POS+GDISP_SLEEP_SIZE)/4); // Sleep Window
- set_backlight(GDISP.Backlight); // Turn on the backlight
- break;
- case powerDeepSleep:
- write_cmd(OSCON); // Internal oscillator on
- write_cmd(SLPOUT); // Sleep out
- write_cmd1(PWRCTR, 0x0F); // Power control - reference voltage regulator on, circuit voltage follower on, BOOST ON
- write_cmd2(VOLCTR, GDISP.Contrast, 0x03); // Voltage control (contrast setting)
- delayms(100); // Allow power supply to stabilise
- write_cmd(DISON); // Turn on the display
- write_cmd2(PTLIN, GDISP_SLEEP_POS/4, (GDISP_SLEEP_POS+GDISP_SLEEP_SIZE)/4); // Sleep Window
- set_backlight(0); // Turn off the backlight
- break;
- default:
- release_bus();
- return;
- }
- release_bus();
- GDISP.Powermode = (gdisp_powermode_t)value;
- return;
- case GDISP_CONTROL_ORIENTATION:
- if (GDISP.Orientation == (gdisp_orientation_t)value)
- return;
- acquire_bus();
- switch((gdisp_orientation_t)value) {
- case GDISP_ROTATE_0:
- write_cmd3(DATCTL, 0x00, 0x00, 0x02); // P1: page normal, column normal, scan in column direction
- GDISP.Height = GDISP_SCREEN_HEIGHT;
- GDISP.Width = GDISP_SCREEN_WIDTH;
- break;
- case GDISP_ROTATE_90:
- write_cmd3(DATCTL, 0x06, 0x00, 0x02); // P1: page normal, column reverse, scan in page direction
- GDISP.Height = GDISP_SCREEN_WIDTH;
- GDISP.Width = GDISP_SCREEN_HEIGHT;
- break;
- case GDISP_ROTATE_180:
- write_cmd3(DATCTL, 0x03, 0x00, 0x02); // P1: page reverse, column reverse, scan in column direction
- GDISP.Height = GDISP_SCREEN_HEIGHT;
- GDISP.Width = GDISP_SCREEN_WIDTH;
- break;
- case GDISP_ROTATE_270:
- write_cmd3(DATCTL, 0x05, 0x00, 0x02); // P1: page reverse, column normal, scan in page direction
- GDISP.Height = GDISP_SCREEN_WIDTH;
- GDISP.Width = GDISP_SCREEN_HEIGHT;
- break;
- default:
- release_bus();
- return;
- }
- release_bus();
- #if GDISP_NEED_CLIP || GDISP_NEED_VALIDATION
- GDISP.clipx0 = 0;
- GDISP.clipy0 = 0;
- GDISP.clipx1 = GDISP.Width;
- GDISP.clipy1 = GDISP.Height;
- #endif
- GDISP.Orientation = (gdisp_orientation_t)value;
- return;
- case GDISP_CONTROL_BACKLIGHT:
- if ((unsigned)value > 100) value = (void *)100;
- set_backlight((unsigned)value);
- GDISP.Backlight = (unsigned)value;
- return;
- case GDISP_CONTROL_CONTRAST:
- if ((unsigned)value > 100) value = (void *)100;
- acquire_bus();
- write_cmd2(VOLCTR, (unsigned)value, 0x03);
- release_bus();
- GDISP.Contrast = (unsigned)value;
- return;
- }
- }
-#endif
-
-#endif /* GFX_USE_GDISP */
-/** @} */
diff --git a/drivers/gdisp/Nokia6610GE8/gdisp_lld.mk b/drivers/gdisp/Nokia6610GE8/gdisp_lld.mk
index 3e1f1851..a61948b3 100644
--- a/drivers/gdisp/Nokia6610GE8/gdisp_lld.mk
+++ b/drivers/gdisp/Nokia6610GE8/gdisp_lld.mk
@@ -1,5 +1,2 @@
-# List the required driver.
-GFXSRC += $(GFXLIB)/drivers/gdisp/Nokia6610GE8/gdisp_lld.c
-
-# Required include directories
GFXINC += $(GFXLIB)/drivers/gdisp/Nokia6610GE8
+GFXSRC += $(GFXLIB)/drivers/gdisp/Nokia6610GE8/gdisp_lld_Nokia6610GE8.c
diff --git a/drivers/gdisp/Nokia6610GE8/gdisp_lld_Nokia6610GE8.c b/drivers/gdisp/Nokia6610GE8/gdisp_lld_Nokia6610GE8.c
new file mode 100644
index 00000000..f6ce4278
--- /dev/null
+++ b/drivers/gdisp/Nokia6610GE8/gdisp_lld_Nokia6610GE8.c
@@ -0,0 +1,570 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/Nokia6610GE8/gdisp_lld.c
+ * @brief GDISP Graphics Driver subsystem low level driver source for the Nokia6610 GE8 display.
+ *
+ * @addtogroup GDISP
+ * @{
+ */
+
+#include "gfx.h"
+
+#if GFX_USE_GDISP
+
+/**
+ * This is for the EPSON (GE8) controller driving a Nokia6610 color LCD display.
+ * Note that there is also a PHILIPS (GE12) controller for the same display that this code
+ * does not support.
+ *
+ * The controller drives a 132x132 display but a 1 pixel surround is not visible
+ * which gives a visible area of 130x130.
+ *
+ * This controller does not support reading back over the SPI interface.
+ * Additionally, the Olimex board doesn't even connect the pin.
+ *
+ * The hardware is capable of doing full width vertical scrolls aligned
+ * on a 4 line boundary however that is not sufficient to support general vertical scrolling.
+ * We also can't manually do read/modify scrolling because we can't read in SPI mode.
+ *
+ * The controller has some quirkyness when operating in other than rotation 0 mode.
+ * When any direction is decremented it starts at location 0 rather than the end of
+ * the area. Whilst this can be handled when we know the specific operation (pixel, fill, blit)
+ * it cannot be handled in a generic stream operation. So, when orientation support is turned
+ * on (and needed) we use complex operation specific routines instead of simple streaming
+ * routines. This has a (small) performance penalty and a significant code size penalty so
+ * don't turn on orientation support unless you really need it.
+ *
+ * Some of the more modern controllers have a broken command set. If you have one of these
+ * you will recognise it by the colors being off on anything drawn after an odd (as opposed to
+ * even) pixel count area being drawn. If so then set GDISP_GE8_BROKEN_CONTROLLER to TRUE
+ * on your gdisp_lld_board.h file. The price is that streaming calls that are completed
+ * without exactly the window size write operations and where the number of write operations
+ * is odd (rather than even), it will draw an extra pixel. If this is important to you, turn on
+ * orientation support and the streaming operations will be emulated (as described above).
+ */
+
+#if defined(GDISP_SCREEN_HEIGHT)
+ #warning "GDISP: This low level driver does not support setting a screen size. It is being ignored."
+ #undef GDISP_SCREEN_HEIGHT
+#endif
+#if defined(GDISP_SCREEN_WIDTH)
+ #warning "GDISP: This low level driver does not support setting a screen size. It is being ignored."
+ #undef GDISP_SCREEN_WIDTH
+#endif
+
+#define GDISP_DRIVER_VMT GDISPVMT_Nokia6610GE8
+#include "../drivers/gdisp/Nokia6610GE8/gdisp_lld_config.h"
+#include "gdisp/lld/gdisp_lld.h"
+
+#include "board_Nokia6610GE8.h"
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+#include "GE8.h"
+
+#define GDISP_SCAN_LINES 132
+
+// Set parameters if they are not already set
+#ifndef GDISP_GE8_BROKEN_CONTROLLER
+ #define GDISP_GE8_BROKEN_CONTROLLER TRUE
+#endif
+#ifndef GDISP_SCREEN_HEIGHT
+ #define GDISP_SCREEN_HEIGHT 130
+#endif
+#ifndef GDISP_SCREEN_WIDTH
+ #define GDISP_SCREEN_WIDTH 130
+#endif
+#ifndef GDISP_RAM_X_OFFSET
+ #define GDISP_RAM_X_OFFSET 0 /* Offset in RAM of visible area */
+#endif
+#ifndef GDISP_RAM_Y_OFFSET
+ #define GDISP_RAM_Y_OFFSET 2 /* Offset in RAM of visible area */
+#endif
+#ifndef GDISP_SLEEP_SIZE
+ #define GDISP_SLEEP_SIZE 32 /* Sleep mode window lines */
+#endif
+#ifndef GDISP_SLEEP_POS
+ #define GDISP_SLEEP_POS ((GDISP_SCAN_LINES-GDISP_SLEEP_SIZE)/2)
+#endif
+#ifndef GDISP_INITIAL_CONTRAST
+ #define GDISP_INITIAL_CONTRAST 60
+#endif
+#ifndef GDISP_INITIAL_BACKLIGHT
+ #define GDISP_INITIAL_BACKLIGHT 100
+#endif
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local variables. */
+/*===========================================================================*/
+
+#if GDISP_HARDWARE_STREAM_WRITE
+ typedef struct dvrPriv {
+ uint16_t savecolor;
+ #if GDISP_GE8_BROKEN_CONTROLLER
+ uint16_t firstcolor;
+ #endif
+ } dvrPriv;
+ #define PRIV ((dvrPriv *)g->priv)
+#endif
+
+#define GDISP_FLG_ODDBYTE (GDISP_FLG_DRIVER<<0)
+#define GDISP_FLG_RUNBYTE (GDISP_FLG_DRIVER<<1)
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+// Some macros just to make reading the code easier
+#define delayms(ms) gfxSleepMilliseconds(ms)
+#define write_data2(g, d1, d2) { write_data(g, d1); write_data(g, d2); }
+#define write_data3(g, d1, d2, d3) { write_data(g, d1); write_data(g, d2); write_data(g, d3); }
+#define write_data4(g, d1, d2, d3, d4) { write_data(g, d1); write_data(g, d2); write_data(g, d3); write_data(g, d4); }
+#define write_cmd1(g, cmd, d1) { write_index(g, cmd); write_data(g, d1); }
+#define write_cmd2(g, cmd, d1, d2) { write_index(g, cmd); write_data2(g, d1, d2); }
+#define write_cmd3(g, cmd, d1, d2, d3) { write_index(g, cmd); write_data3(g, d1, d2, d3); }
+#define write_cmd4(g, cmd, d1, d2, d3, d4) { write_index(g, cmd); write_data4(g, d1, d2, d3, d4); }
+
+static inline void set_viewport(GDisplay* g) {
+ #if GDISP_NOKIA_ORIENTATION && GDISP_NEED_CONTROL
+ switch(g->g.Orientation) {
+ case GDISP_ROTATE_0:
+ write_cmd2(g, CASET, GDISP_RAM_X_OFFSET+g->p.x, GDISP_RAM_X_OFFSET+g->p.x); // Column address set
+ write_cmd2(g, PASET, GDISP_RAM_Y_OFFSET+g->p.y, GDISP_RAM_Y_OFFSET+g->p.y); // Page address set
+ break;
+ case GDISP_ROTATE_90:
+ write_cmd2(g, CASET, GDISP_RAM_X_OFFSET+g->p.y, GDISP_RAM_X_OFFSET+g->p.y);
+ write_cmd2(g, PASET, GDISP_RAM_Y_OFFSET-1+g->g.Width-g->p.x, GDISP_RAM_Y_OFFSET-1+g->g.Width-g->p.x);
+ break;
+ case GDISP_ROTATE_180:
+ write_cmd2(g, CASET, GDISP_RAM_X_OFFSET-1+g->g.Width-g->p.x, GDISP_RAM_X_OFFSET-1+g->g.Width-g->p.x);
+ write_cmd2(g, PASET, GDISP_RAM_Y_OFFSET-1+g->g.Height-g->p.y, GDISP_RAM_Y_OFFSET-1+g->g.Height-g->p.y);
+ break;
+ case GDISP_ROTATE_270:
+ write_cmd2(g, CASET, GDISP_RAM_X_OFFSET-1+g->g.Height-g->p.y, GDISP_RAM_X_OFFSET-1+g->g.Height-g->p.y);
+ write_cmd2(g, PASET, GDISP_RAM_Y_OFFSET+g->p.x, GDISP_RAM_Y_OFFSET+g->p.x);
+ break;
+ }
+ #else
+ write_cmd2(g, CASET, GDISP_RAM_X_OFFSET+g->p.x, GDISP_RAM_X_OFFSET+g->p.x+g->p.cx-1); // Column address set
+ write_cmd2(g, PASET, GDISP_RAM_Y_OFFSET+g->p.y, GDISP_RAM_Y_OFFSET+g->p.y+g->p.cy-1); // Page address set
+ #endif
+ write_index(g, RAMWR);
+}
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
+ #if GDISP_HARDWARE_STREAM_WRITE
+ g->priv = gfxAlloc(sizeof(dvrPriv));
+ #else
+ g->priv = 0;
+ #endif
+
+ // Initialise the board interface
+ init_board(g);
+
+ // Hardware reset
+ setpin_reset(g, TRUE);
+ delayms(20);
+ setpin_reset(g, FALSE);
+ delayms(20);
+
+ // Get the bus for the following initialisation commands
+ acquire_bus(g);
+
+ write_cmd4(g, DISCTL, 0x00, GDISP_SCAN_LINES/4-1, 0x0A, 0x00); // Display control - How the controller drives the LCD
+ // P1: 0x00 = 2 divisions, switching period=8 (default)
+ // P2: 0x20 = nlines/4 - 1 = 132/4 - 1 = 32)
+ // P3: 0x0A = standard inverse highlight, inversion every frame
+ // P4: 0x00 = dispersion on
+ write_cmd1(g, COMSCN, 0x01); // COM scan - How the LCD is connected to the controller
+ // P1: 0x01 = Scan 1->80, 160<-81
+ write_index(g, OSCON); // Internal oscillator ON
+ write_index(g, SLPOUT); // Sleep out
+ write_cmd1(g, PWRCTR, 0x0F); // Power control - reference voltage regulator on, circuit voltage follower on, BOOST ON
+ write_cmd3(g, DATCTL, 0x00, 0x00, 0x02); // Data control
+ // P1: 0x00 = page address normal, column address normal, address scan in column direction
+ // P2: 0x00 = RGB sequence (default value)
+ // P3: 0x02 = 4 bits per colour (Type A)
+ write_cmd2(g, VOLCTR, 64*GDISP_INITIAL_CONTRAST/101, 0x03); // Voltage control (contrast setting)
+ // P1 = Contrast (0..63)
+ // P2 = 3 resistance ratio (only value that works)
+ delayms(100); // Allow power supply to stabilise
+ write_index(g, DISON); // Turn on the display
+
+ // Finish Init
+ post_init_board(g);
+
+ // Release the bus
+ release_bus(g);
+
+ /* Turn on the back-light */
+ set_backlight(g, GDISP_INITIAL_BACKLIGHT);
+
+ /* Initialise the GDISP structure to match */
+ g->g.Orientation = GDISP_ROTATE_0;
+ g->g.Powermode = powerOn;
+ g->g.Backlight = GDISP_INITIAL_BACKLIGHT;
+ g->g.Contrast = GDISP_INITIAL_CONTRAST;
+ g->g.Width = GDISP_SCREEN_WIDTH;
+ g->g.Height = GDISP_SCREEN_HEIGHT;
+ return TRUE;
+}
+
+#if GDISP_HARDWARE_STREAM_WRITE
+ LLDSPEC void gdisp_lld_write_start(GDisplay *g) {
+ acquire_bus(g);
+ set_viewport(g);
+ g->flags &= ~(GDISP_FLG_ODDBYTE|GDISP_FLG_RUNBYTE);
+ }
+ LLDSPEC void gdisp_lld_write_color(GDisplay *g) {
+ uint16_t c;
+
+ c = COLOR2NATIVE(g->p.color);
+ #if GDISP_GE8_BROKEN_CONTROLLER
+ if (!(g->flags & GDISP_FLG_RUNBYTE)) {
+ PRIV->firstcolor = c;
+ g->flags |= GDISP_FLG_RUNBYTE;
+ }
+ #endif
+ if ((g->flags & GDISP_FLG_ODDBYTE)) {
+ // Write the pair of pixels to the display
+ write_data3(g, ((PRIV->savecolor >> 4) & 0xFF),
+ (((PRIV->savecolor << 4) & 0xF0)|((c >> 8) & 0x0F)),
+ (c & 0xFF));
+ g->flags &= ~GDISP_FLG_ODDBYTE;
+ } else {
+ PRIV->savecolor = c;
+ g->flags |= GDISP_FLG_ODDBYTE;
+ }
+ }
+ LLDSPEC void gdisp_lld_write_stop(GDisplay *g) {
+ if ((g->flags & GDISP_FLG_ODDBYTE)) {
+ #if GDISP_GE8_BROKEN_CONTROLLER
+ /**
+ * We have a real problem here - we need to write a singular pixel
+ * Methods that are supposed to work...
+ * 1/ Write the pixel (2 bytes) and then send a NOP command. This doesn't work, the pixel doesn't get written
+ * and it is maintained in the latch where it causes problems for the next window.
+ * 2/ Just write a dummy extra pixel as stuff beyond the window gets discarded. This doesn't work as contrary to
+ * the documentation the buffer wraps and the first pixel gets overwritten.
+ * 3/ Put the controller in 16 bits per pixel Type B mode where each pixel is performed by writing two bytes. This
+ * also doesn't work as the controller refuses to enter Type B mode (it stays in Type A mode).
+ *
+ * These methods might work on some controllers - just not on the one of the broken versions.
+ *
+ * For these broken controllers:
+ * We know we can wrap to the first byte (just overprint it) if we are at the end of the stream area.
+ * If not, we need to create a one pixel by one pixel window to fix this - Uuch. Fortunately this should only happen if the
+ * user application uses the streaming calls and then terminates the stream early or after buffer wrap.
+ * Since this is such an unlikely situation we just don't handle it.
+ */
+ write_data3(g, ((PRIV->savecolor >> 4) & 0xFF),
+ (((PRIV->savecolor << 4) & 0xF0)|((PRIV->firstcolor >> 8) & 0x0F)),
+ (PRIV->firstcolor & 0xFF));
+ #else
+ write_data2(g, ((PRIV->savecolor >> 4) & 0xFF), ((PRIV->savecolor << 4) & 0xF0));
+ write_index(g, NOP);
+ #endif
+ }
+
+ release_bus(g);
+ }
+#endif
+
+#if GDISP_HARDWARE_DRAWPIXEL
+ LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) {
+ uint16_t c;
+
+ c = COLOR2NATIVE(g->p.color);
+ acquire_bus(g);
+ set_viewport(g);
+ write_data3(g, 0, (c>>8) & 0x0F, c & 0xFF);
+ release_bus(g);
+ }
+#endif
+
+/* ---- Optional Routines ---- */
+
+#if GDISP_HARDWARE_FILLS
+ LLDSPEC void gdisp_lld_fill_area(GDisplay *g) {
+ unsigned tuples;
+ uint16_t c;
+
+ tuples = (g->p.cx*g->p.cy+1)>>1; // With an odd sized area we over-print by one pixel.
+ // This extra pixel overwrites the first pixel (harmless as it is the same colour)
+
+ c = COLOR2NATIVE(g->p.color);
+ acquire_bus(g);
+ set_viewport(g);
+ while(tuples--)
+ write_data3(g, ((c >> 4) & 0xFF), (((c << 4) & 0xF0)|((c >> 8) & 0x0F)), (c & 0xFF));
+ release_bus(g);
+ }
+#endif
+
+#if GDISP_HARDWARE_BITFILLS
+ LLDSPEC void gdisp_lld_blit_area(GDisplay *g) {
+ coord_t lg, x, y;
+ uint16_t c1, c2;
+ unsigned tuples;
+ const pixel_t *buffer;
+ #if GDISP_PACKED_PIXELS
+ unsigned pnum, pstart;
+ const uint8_t *p;
+ #else
+ const pixel_t *p;
+ #endif
+
+ tuples = (g->p.cx * g->p.cy + 1)>>1;
+ buffer = (const pixel_t *)g->p.ptr;
+
+ /* Set up the data window to transfer */
+ acquire_bus(g);
+ set_viewport(g);
+
+ /* to suppress compiler warnings */
+ x = 0;
+ y = 0;
+
+ /*
+ * Due to the way the Nokia6610 handles a decrementing column or page,
+ * we have to make adjustments as to where it is actually drawing from in the bitmap.
+ * For example, for 90 degree rotation the column is decremented on each
+ * memory write. The controller always starts with column 0 and then decrements
+ * to column cx-1, cx-2 etc. We therefore have to write-out the last bitmap line first.
+ */
+ switch(g->g.Orientation) {
+ case GDISP_ROTATE_0: x = 0; y = 0; break;
+ case GDISP_ROTATE_90: x = g->p.cx-1; y = 0; break;
+ case GDISP_ROTATE_180: x = g->p.cx-1; y = g->p.cy-1; break;
+ case GDISP_ROTATE_270: x = 0; y = g->p.cy-1; break;
+ }
+
+ #if !GDISP_PACKED_PIXELS
+ // Although this controller uses packed pixels we support unpacked pixel
+ // formats in this blit by packing the data as we feed it to the controller.
+
+ lg = g->p.x2 - g->p.cx; // The buffer gap between lines
+ buffer += g->p.y1 * g->p.x2 + g->p.x1; // The buffer start position
+ p = buffer + g->p.x2*y + x; // Adjustment for controller craziness
+
+ while(tuples--) {
+ /* Get a pixel */
+ c1 = COLOR2NATIVE(*p++);
+
+ /* Check for line or buffer wrapping */
+ if (++x >= g->p.cx) {
+ x = 0;
+ p += lg;
+ if (++y >= g->p.cy) {
+ y = 0;
+ p = buffer;
+ }
+ }
+
+ /* Get the next pixel */
+ c2 = COLOR2NATIVE(*p++);
+
+ /* Check for line or buffer wrapping */
+ if (++x >= g->p.cx) {
+ x = 0;
+ p += lg;
+ if (++y >= g->p.cy) {
+ y = 0;
+ p = buffer;
+ }
+ }
+
+ /* Write the pair of pixels to the display */
+ write_data3(g, ((c1 >> 4) & 0xFF), (((c1 << 4) & 0xF0)|((c2 >> 8) & 0x0F)), (c2 & 0xFF));
+ }
+
+ #elif GDISP_PIXELFORMAT == GDISP_LLD_PIXELFORMAT
+
+ // Although this controller uses packed pixels, we may have to feed it into
+ // the controller with different packing to the source bitmap
+ // There are 2 pixels per 3 bytes
+
+ #if !GDISP_PACKED_LINES
+ srccx = (g->p.x2 + 1) & ~1;
+ #endif
+ pstart = g->p.y1 * g->p.x2 + g->p.x1; // The starting pixel number
+ buffer = (const pixel_t)(((const uint8_t *)buffer) + ((pstart>>1) * 3)); // The buffer start position
+ lg = ((g->p.x2-g->p.cx)>>1)*3; // The buffer gap between lines
+ pnum = pstart + g->p.x2*y + x; // Adjustment for controller craziness
+ p = ((const uint8_t *)buffer) + (((g->p.x2*y + x)>>1)*3); // Adjustment for controller craziness
+
+ while (tuples--) {
+ /* Get a pixel */
+ switch(pnum++ & 1) {
+ case 0: c1 = (((color_t)p[0]) << 4)|(((color_t)p[1])>>4); break;
+ case 1: c1 = (((color_t)p[1]&0x0F) << 8)|((color_t)p[1]); p += 3; break;
+ }
+
+ /* Check for line or buffer wrapping */
+ if (++x >= g->p.cx) {
+ x = 0;
+ p += lg;
+ pnum += g->p.x2 - g->p.cx;
+ if (++y >= g->p.cy) {
+ y = 0;
+ p = (const uint8_t *)buffer;
+ pnum = pstart;
+ }
+ }
+
+ /* Get the next pixel */
+ switch(pnum++ & 1) {
+ case 0: c2 = (((color_t)p[0]) << 4)|(((color_t)p[1])>>4); break;
+ case 1: c2 = (((color_t)p[1]&0x0F) << 8)|((color_t)p[1]); p += 3; break;
+ }
+
+ /* Check for line or buffer wrapping */
+ if (++x >= g->p.cx) {
+ x = 0;
+ p += lg;
+ pnum += g->p.x2 - g->p.cx;
+ if (++y >= g->p.cy) {
+ y = 0;
+ p = (const uint8_t *)buffer;
+ pnum = pstart;
+ }
+ }
+
+ /* Write the pair of pixels to the display */
+ write_data3(g, ((c1 >> 4) & 0xFF), (((c1 << 4) & 0xF0)|((c2 >> 8) & 0x0F)), (c2 & 0xFF));
+ }
+
+ #else
+ #error "Packed pixels is broken if you are not running native pixel format"
+ #endif
+
+ /* All done */
+ release_bus(g);
+ }
+#endif
+
+#if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL
+ LLDSPEC void gdisp_lld_control(GDisplay *g) {
+ /* The hardware is capable of supporting...
+ * GDISP_CONTROL_POWER - supported
+ * GDISP_CONTROL_ORIENTATION - supported
+ * GDISP_CONTROL_BACKLIGHT - supported
+ * GDISP_CONTROL_CONTRAST - supported
+ */
+ switch(g->p.x) {
+ case GDISP_CONTROL_POWER:
+ if (g->g.Powermode == (powermode_t)g->p.ptr)
+ return;
+ acquire_bus(g);
+ switch((powermode_t)g->p.ptr) {
+ case powerOff:
+ set_backlight(g, 0); // Turn off the backlight
+ write_index(g, DISOFF); // Turn off the display
+ write_cmd1(g, PWRCTR, 0x00); // Power control - all off
+ write_index(g, SLPIN); // Sleep in
+ write_index(g, OSCOFF); // Internal oscillator off
+ break;
+ case powerOn:
+ write_index(g, OSCON); // Internal oscillator on
+ write_index(g, SLPOUT); // Sleep out
+ write_cmd1(g, PWRCTR, 0x0F); // Power control - reference voltage regulator on, circuit voltage follower on, BOOST ON
+ write_cmd2(g, VOLCTR, g->g.Contrast, 0x03); // Voltage control (contrast setting)
+ delayms(100); // Allow power supply to stabilise
+ write_index(g, DISON); // Turn on the display
+ write_index(g, PTLOUT); // Remove sleep window
+ set_backlight(g, g->g.Backlight); // Turn on the backlight
+ break;
+ case powerSleep:
+ write_index(g, OSCON); // Internal oscillator on
+ write_index(g, SLPOUT); // Sleep out
+ write_cmd1(g, PWRCTR, 0x0F); // Power control - reference voltage regulator on, circuit voltage follower on, BOOST ON
+ write_cmd2(g, VOLCTR, g->g.Contrast, 0x03); // Voltage control (contrast setting)
+ delayms(100); // Allow power supply to stabilise
+ write_index(g, DISON); // Turn on the display
+ write_cmd2(g, PTLIN, GDISP_SLEEP_POS/4, (GDISP_SLEEP_POS+GDISP_SLEEP_SIZE)/4); // Sleep Window
+ set_backlight(g, g->g.Backlight); // Turn on the backlight
+ break;
+ case powerDeepSleep:
+ write_index(g, OSCON); // Internal oscillator on
+ write_index(g, SLPOUT); // Sleep out
+ write_cmd1(g, PWRCTR, 0x0F); // Power control - reference voltage regulator on, circuit voltage follower on, BOOST ON
+ write_cmd2(g, VOLCTR, g->g.Contrast, 0x03); // Voltage control (contrast setting)
+ delayms(100); // Allow power supply to stabilise
+ write_index(g, DISON); // Turn on the display
+ write_cmd2(g, PTLIN, GDISP_SLEEP_POS/4, (GDISP_SLEEP_POS+GDISP_SLEEP_SIZE)/4); // Sleep Window
+ set_backlight(g, 0); // Turn off the backlight
+ break;
+ default:
+ release_bus(g);
+ return;
+ }
+ release_bus(g);
+ g->g.Powermode = (powermode_t)g->p.ptr;
+ return;
+ #if GDISP_NOKIA_ORIENTATION
+ case GDISP_CONTROL_ORIENTATION:
+ if (g->g.Orientation == (orientation_t)g->p.ptr)
+ return;
+ acquire_bus(g);
+ switch((orientation_t)g->p.ptr) {
+ case GDISP_ROTATE_0:
+ write_cmd3(g, DATCTL, 0x00, 0x00, 0x02); // P1: page normal, column normal, scan in column direction
+ g->g.Height = GDISP_SCREEN_HEIGHT;
+ g->g.Width = GDISP_SCREEN_WIDTH;
+ break;
+ case GDISP_ROTATE_90:
+ write_cmd3(g, DATCTL, 0x05, 0x00, 0x02); // P1: page reverse, column normal, scan in page direction
+ g->g.Height = GDISP_SCREEN_WIDTH;
+ g->g.Width = GDISP_SCREEN_HEIGHT;
+ break;
+ case GDISP_ROTATE_180:
+ write_cmd3(g, DATCTL, 0x03, 0x00, 0x02); // P1: page reverse, column reverse, scan in column direction
+ g->g.Height = GDISP_SCREEN_HEIGHT;
+ g->g.Width = GDISP_SCREEN_WIDTH;
+ break;
+ case GDISP_ROTATE_270:
+ write_cmd3(g, DATCTL, 0x06, 0x00, 0x02); // P1: page normal, column reverse, scan in page direction
+ g->g.Height = GDISP_SCREEN_WIDTH;
+ g->g.Width = GDISP_SCREEN_HEIGHT;
+ break;
+ default:
+ release_bus(g);
+ return;
+ }
+ release_bus(g);
+ g->g.Orientation = (orientation_t)g->p.ptr;
+ return;
+ #endif
+ case GDISP_CONTROL_BACKLIGHT:
+ if ((unsigned)g->p.ptr > 100) g->p.ptr = (void *)100;
+ set_backlight(g, (unsigned)g->p.ptr);
+ g->g.Backlight = (unsigned)g->p.ptr;
+ return;
+ case GDISP_CONTROL_CONTRAST:
+ if ((unsigned)g->p.ptr > 100) g->p.ptr = (void *)100;
+ acquire_bus(g);
+ write_cmd2(g, VOLCTR, 64*(unsigned)g->p.ptr/101, 0x03);
+ release_bus(g);
+ g->g.Contrast = (unsigned)g->p.ptr;
+ return;
+ }
+ }
+#endif
+
+#endif /* GFX_USE_GDISP */
+/** @} */
diff --git a/drivers/gdisp/Nokia6610GE8/gdisp_lld_board_olimexsam7ex256.h b/drivers/gdisp/Nokia6610GE8/gdisp_lld_board_olimexsam7ex256.h
deleted file mode 100644
index 90a1277b..00000000
--- a/drivers/gdisp/Nokia6610GE8/gdisp_lld_board_olimexsam7ex256.h
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * This file is subject to the terms of the GFX License. If a copy of
- * the license was not distributed with this file, you can obtain one at:
- *
- * http://ugfx.org/license.html
- */
-
-/**
- * @file drivers/gdisp/Nokia6610GE8/gdisp_lld_board_olimexsam7ex256.h
- * @brief GDISP Graphic Driver subsystem board interface for the Olimex SAM7-EX256 board.
- *
- * @addtogroup GDISP
- * @{
- */
-
-#ifndef _GDISP_LLD_BOARD_H
-#define _GDISP_LLD_BOARD_H
-
-// ******************************************************
-// Pointers to AT91SAM7X256 peripheral data structures
-// ******************************************************
-static volatile AT91PS_PIO pPIOA = AT91C_BASE_PIOA;
-static volatile AT91PS_PIO pPIOB = AT91C_BASE_PIOB;
-static volatile AT91PS_SPI pSPI = AT91C_BASE_SPI0;
-static volatile AT91PS_PMC pPMC = AT91C_BASE_PMC;
-static volatile AT91PS_PDC pPDC = AT91C_BASE_PDC_SPI0;
-
-/* The PWM backlight control is non-linear on this board.
- * We pick values here that make it look a bit more linear.
- */
-#define PWM_TOP_VALUE 500
-#define PWM_BOTTOM_VALUE 200
-
-#define PWM_VALUE(x) (PWM_BOTTOM_VALUE+(PWM_TOP_VALUE-PWM_BOTTOM_VALUE)*(x)/100)
-
-/* PWM configuration structure. The LCD Backlight is on PWM1/PB20 ie PWM2/PIN1 in ChibiOS speak */
-static const PWMConfig pwmcfg = {
- 1000000, /* 1 MHz PWM clock frequency. Ignored as we are using PWM_MCK_DIV_n */
- 1000, /* PWM period is 1000 cycles. */
- NULL,
- {
- {PWM_MCK_DIV_1 | PWM_OUTPUT_ACTIVE_HIGH | PWM_OUTPUT_PIN1 | PWM_DISABLEPULLUP_PIN1, NULL},
- },
-};
-
-static bool_t pwmRunning = FALSE;
-
-/**
- * @brief Initialise the board for the display.
- * @notes Performs the following functions:
- * 1. initialise the spi port used by your display
- * 2. initialise the reset pin (initial state not-in-reset)
- * 3. initialise the chip select pin (initial state not-active)
- * 4. initialise the backlight pin (initial state back-light off)
- *
- * @notapi
- */
-static inline void init_board(void) {
- // *********************************************************************************************
- // InitSpi( )
- //
- // Sets up SPI channel 0 for communications to Nokia 6610 LCD Display
- //
- // I/O ports used: PA2 = LCD Reset (set to low to reset)
- // PA12 = LCD chip select (set to low to select the LCD chip)
- // PA16 = SPI0_MISO Master In - Slave Out (not used in LCD interface)
- // PA17 = SPI0_MOSI Master Out - Slave In pin (Serial Data to LCD slave)
- // PA18 = SPI0_SPCK Serial Clock (to LCD slave)
- // PB20 = backlight control (normally PWM control, 1 = full on)
- //
- // *********************************************************************************************}
-
- /* This code should really use the ChibiOS driver for these functions */
-
- // Pin for backlight
- pPIOB->PIO_CODR = PIOB_LCD_BL_MASK; // Set PB20 to LOW
- pPIOB->PIO_OER = PIOB_LCD_BL_MASK; // Configure PB20 as output
-
- // Reset pin
- pPIOA->PIO_SODR = PIOA_LCD_RESET_MASK; // Set PA2 to HIGH
- pPIOA->PIO_OER = PIOA_LCD_RESET_MASK; // Configure PA2 as output
-
- // CS pin - this seems to be ignored
- // pPIOA->PIO_SODR = 1<<12; // Set PA2 to HIGH
- // pPIOA->PIO_OER = 1<<12; // Configure PA2 as output
-
- // Init SPI0
- // Disable the following pins from PIO control (will be used instead by the SPI0 peripheral)
- // BIT12 = PA12 -> SPI0_NPCS0 chip select
- // BIT16 = PA16 -> SPI0_MISO Master In - Slave Out (not used in LCD interface)
- // BIT17 = PA17 -> SPI0_MOSI Master Out - Slave In pin (Serial Data to LCD slave)
- // BIT18 = PA18 -> SPI0_SPCK Serial Clock (to LCD slave)
- pPIOA->PIO_PDR = (1<<12) | (1<<16) | (1<<17) | (1<<18);
- pPIOA->PIO_ASR = (1<<12) | (1<<16) | (1<<17) | (1<<18);
- pPIOA->PIO_BSR = 0;
-
- //enable the clock of SPI
- pPMC->PMC_PCER = 1 << AT91C_ID_SPI0;
-
- // Fixed mode
- pSPI->SPI_CR = 0x81; //SPI Enable, Sowtware reset
- pSPI->SPI_CR = 0x01; //SPI Enable
-
- //pSPI->SPI_MR = 0xE0019; //Master mode, fixed select, disable decoder, FDIV=1 (MCK), PCS=1110
- pSPI->SPI_MR = 0xE0011; //Master mode, fixed select, disable decoder, FDIV=0 (MCK), PCS=1110
-
- //pSPI->SPI_CSR[0] = 0x01010C11; //9bit, CPOL=1, ClockPhase=0, SCLK = 48Mhz/32*12 = 125kHz
- pSPI->SPI_CSR[0] = 0x01010311; //9bit, CPOL=1, ClockPhase=0, SCLK = 48Mhz/8 = 6MHz if using commented MR line above
-
- /* Display backlight control at 100% */
- pwmRunning = FALSE;
- palSetPad(IOPORT2, PIOB_LCD_BL);
-}
-
-/**
- * @brief Set or clear the lcd reset pin.
- *
- * @param[in] state TRUE = lcd in reset, FALSE = normal operation
- *
- * @notapi
- */
-static inline void setpin_reset(bool_t state) {
- if (state)
- palClearPad(IOPORT1, PIOA_LCD_RESET);
- else
- palSetPad(IOPORT1, PIOA_LCD_RESET);
-}
-
-/**
- * @brief Set the lcd back-light level.
- * @note For now 0% turns the backlight off, anything else the backlight is on.
- * While the hardware supports PWM backlight control, we are not using it
- * yet.
- *
- * @param[in] percent 0 to 100%
- *
- * @notapi
- */
-static inline void set_backlight(uint8_t percent) {
- if (percent == 100) {
- /* Turn the pin on - No PWM */
- if (pwmRunning) {
- pwmStop(&PWMD2);
- pwmRunning = FALSE;
- }
- palSetPad(IOPORT2, PIOB_LCD_BL);
- } else if (percent == 0) {
- /* Turn the pin off - No PWM */
- if (pwmRunning) {
- pwmStop(&PWMD2);
- pwmRunning = FALSE;
- }
- palClearPad(IOPORT2, PIOB_LCD_BL);
- } else {
- /* Use the PWM */
- if (!pwmRunning) {
- pwmStart(&PWMD2, &pwmcfg);
- pwmRunning = TRUE;
- }
- pwmEnableChannel(&PWMD2, 0, PWM_VALUE(percent));
- }
-}
-
-/**
- * @brief Take exclusive control of the bus
- *
- * @notapi
- */
-static inline void acquire_bus(void) {
- /* Nothing to do for this board as the LCD is the only device on the SPI port */
-}
-
-/**
- * @brief Release exclusive control of the bus
- *
- * @notapi
- */
-static inline void release_bus(void) {
- // Nothing to do for this board as the LCD is the only device on the SPI port
-}
-
-/**
- * @brief Send an 8 bit command to the lcd.
- *
- * @param[in] cmd The command to send
- *
- * @notapi
- */
-static inline void write_cmd(uint16_t cmd) {
- // wait for the previous transfer to complete
- while((pSPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0);
- // send the command
- pSPI->SPI_TDR = cmd & 0xFF;
-}
-
-/**
- * @brief Send an 8 bit data to the lcd.
- *
- * @param[in] data The data to send
- *
- * @notapi
- */
-static inline void write_data(uint16_t data) {
- // wait for the previous transfer to complete
- while((pSPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0);
- // send the data
- pSPI->SPI_TDR = data | 0x0100;
-}
-
-#if GDISP_HARDWARE_READPIXEL || GDISP_HARDWARE_SCROLL || defined(__DOXYGEN__)
-/**
- * @brief Read data from the lcd.
- *
- * @return The data from the lcd
- *
- * @notapi
- */
-static inline uint16_t read_data(void) {
- #error "gdispNokia6610GE8: GDISP_HARDWARE_READPIXEL and GDISP_HARDWARE_SCROLL are not supported on this board"
- return 0;
-}
-#endif
-
-#endif /* _GDISP_LLD_BOARD_H */
-/** @} */
diff --git a/drivers/gdisp/Nokia6610GE8/gdisp_lld_board_template.h b/drivers/gdisp/Nokia6610GE8/gdisp_lld_board_template.h
deleted file mode 100644
index a1fa6050..00000000
--- a/drivers/gdisp/Nokia6610GE8/gdisp_lld_board_template.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * This file is subject to the terms of the GFX License. If a copy of
- * the license was not distributed with this file, you can obtain one at:
- *
- * http://ugfx.org/license.html
- */
-
-/**
- * @file drivers/gdisp/Nokia6610GE8/gdisp_lld_board_template.h
- * @brief GDISP Graphic Driver subsystem board interface for the Nokia6610 GE8 display.
- *
- * @addtogroup GDISP
- * @{
- */
-
-#ifndef _GDISP_LLD_BOARD_H
-#define _GDISP_LLD_BOARD_H
-
-/**
- * @brief Initialise the board for the display.
- * @notes Performs the following functions:
- * 1. initialise the spi port used by your display
- * 2. initialise the reset pin (initial state not-in-reset)
- * 3. initialise the chip select pin (initial state not-active)
- * 4. initialise the backlight pin (initial state back-light off)
- *
- * @notapi
- */
-static inline void init_board(void) {
-
-}
-
-/**
- * @brief Set or clear the lcd reset pin.
- *
- * @param[in] state TRUE = lcd in reset, FALSE = normal operation
- *
- * @notapi
- */
-static inline void setpin_reset(bool_t state) {
-
-}
-
-/**
- * @brief Set the lcd back-light level.
- * @note For now 0% turns the backlight off, anything else the backlight is on.
- * While the hardware supports PWM backlight control, we are not using it
- * yet.
- *
- * @param[in] percent 0 to 100%
- *
- * @notapi
- */
-static inline void set_backlight(uint8_t percent) {
-
-}
-
-/**
- * @brief Take exclusive control of the bus
- *
- * @notapi
- */
-static inline void acquire_bus(void) {
-
-}
-
-/**
- * @brief Release exclusive control of the bus
- *
- * @notapi
- */
-static inline void release_bus(void) {
-
-}
-
-/**
- * @brief Send an 8 bit command to the lcd.
- *
- * @param[in] cmd The command to send
- *
- * @notapi
- */
-static inline void write_cmd(uint16_t cmd) {
-
-}
-
-/**
- * @brief Send an 8 bit data to the lcd.
- *
- * @param[in] data The data to send
- *
- * @notapi
- */
-static inline void write_data(uint16_t data) {
-
-}
-
-#if GDISP_HARDWARE_READPIXEL || GDISP_HARDWARE_SCROLL || defined(__DOXYGEN__)
-/**
- * @brief Read data from the lcd.
- *
- * @return The data from the lcd
- * @note The chip select may need to be asserted/de-asserted
- * around the actual spi read
- *
- * @notapi
- */
-static inline uint16_t read_data(void) {
-
-}
-#endif
-
-#endif /* _GDISP_LLD_BOARD_H */
-/** @} */
diff --git a/drivers/gdisp/Nokia6610GE8/gdisp_lld_config.h b/drivers/gdisp/Nokia6610GE8/gdisp_lld_config.h
index 1a748684..1476dbcf 100644
--- a/drivers/gdisp/Nokia6610GE8/gdisp_lld_config.h
+++ b/drivers/gdisp/Nokia6610GE8/gdisp_lld_config.h
@@ -22,21 +22,26 @@
/* Driver hardware support. */
/*===========================================================================*/
-#define GDISP_DRIVER_NAME "Nokia6610GE8"
-
-#define GDISP_HARDWARE_FILLS TRUE
-#define GDISP_HARDWARE_BITFILLS TRUE
-#define GDISP_HARDWARE_CONTROL TRUE
-
-#define GDISP_SOFTWARE_TEXTFILLDRAW FALSE
-#define GDISP_SOFTWARE_TEXTBLITCOLUMN FALSE
-
-#define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_RGB444
-/* This driver supports both packed and unpacked pixel formats and line formats.
- * By default we leave these as FALSE.
+/* This driver has problems with other orientations and requires significantly
+ * extra code to handle them. By default we turn this on (only if the GDISP_NEED_CONTROL
+ * is turned on). If you are worried about code size and don't need orientation support
+ * define GDISP_NOKIA_ORIENTATION as false.
*/
-#define GDISP_PACKED_PIXELS FALSE
-#define GDISP_PACKED_LINES FALSE
+#ifndef GDISP_NOKIA_ORIENTATION
+ #define GDISP_NOKIA_ORIENTATION TRUE
+#endif
+
+#if GDISP_NOKIA_ORIENTATION && GDISP_NEED_CONTROL
+ #define GDISP_HARDWARE_CONTROL TRUE
+ #define GDISP_HARDWARE_DRAWPIXEL TRUE
+ #define GDISP_HARDWARE_FILLS TRUE
+ #define GDISP_HARDWARE_BITFILLS TRUE
+#else
+ #define GDISP_HARDWARE_CONTROL TRUE
+ #define GDISP_HARDWARE_STREAM_WRITE TRUE
+#endif
+
+#define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_RGB444
#endif /* GFX_USE_GDISP */
diff --git a/drivers/gdisp/RA8875/board_RA8875_template.h b/drivers/gdisp/RA8875/board_RA8875_template.h
new file mode 100644
index 00000000..fce05129
--- /dev/null
+++ b/drivers/gdisp/RA8875/board_RA8875_template.h
@@ -0,0 +1,143 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/SSD1963/board_RA8875_template.h
+ * @brief GDISP Graphic Driver subsystem board interface for the RA8875 display.
+ *
+ * @addtogroup GDISP
+ * @{
+ */
+
+#ifndef _GDISP_LLD_BOARD_H
+#define _GDISP_LLD_BOARD_H
+
+/**
+ * @brief Initialise the board for the display.
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @note Set the g->board member to whatever is appropriate. For multiple
+ * displays this might be a pointer to the appropriate register set.
+ *
+ * @notapi
+ */
+static inline void init_board(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief After the initialisation.
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void post_init_board(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Set or clear the lcd reset pin.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] state TRUE = lcd in reset, FALSE = normal operation
+ *
+ * @notapi
+ */
+static inline void setpin_reset(GDisplay *g, bool_t state) {
+ (void) g;
+ (void) state;
+}
+
+/**
+ * @brief Take exclusive control of the bus
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void acquire_bus(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Release exclusive control of the bus
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void release_bus(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Send data to the index register.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] index The index register to set
+ *
+ * @notapi
+ */
+static inline void write_index(GDisplay *g, uint16_t index) {
+ (void) g;
+ (void) index;
+}
+
+/**
+ * @brief Send data to the lcd.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] data The data to send
+ *
+ * @notapi
+ */
+static inline void write_data(GDisplay *g, uint16_t data) {
+ (void) g;
+ (void) data;
+}
+
+/**
+ * @brief Set the bus in read mode
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void setreadmode(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Set the bus back into write mode
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void setwritemode(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Read data from the lcd.
+ * @return The data from the lcd
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @note The chip select may need to be asserted/de-asserted
+ * around the actual spi read
+ *
+ * @notapi
+ */
+static inline uint16_t read_data(GDisplay *g) {
+ (void) g;
+}
+
+#endif /* _GDISP_LLD_BOARD_H */
+/** @} */
diff --git a/drivers/gdisp/RA8875/gdisp_lld.c b/drivers/gdisp/RA8875/gdisp_lld.c
deleted file mode 100644
index 397c933a..00000000
--- a/drivers/gdisp/RA8875/gdisp_lld.c
+++ /dev/null
@@ -1,449 +0,0 @@
-/*
- * This file is subject to the terms of the GFX License. If a copy of
- * the license was not distributed with this file, you can obtain one at:
- *
- * http://ugfx.org/license.html
- */
-
-/**
- * @file drivers/gdisp/RA8875/gdisp_lld.c
- * @brief GDISP Graphics Driver subsystem low level driver source.
- *
- * @addtogroup GDISP
- * @{
- */
-
-#include "gfx.h"
-
-#if GFX_USE_GDISP /*|| defined(__DOXYGEN__)*/
-
-/* Include the emulation code for things we don't support */
-#include "gdisp/lld/emulation.c"
-
-#include "ra8875.h"
-
-/* include the board abstraction */
-#include "gdisp_lld_board.h"
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-
-/* ---- Required Routines ---- */
-/*
- The following 2 routines are required.
- All other routines are optional.
-*/
-
-/**
- * @brief Low level GDISP driver initialisation.
- * @return TRUE if successful, FALSE on error.
- *
- * @notapi
- */
-bool_t gdisp_lld_init(void) {
- /* Initialise the display */
- init_board();
-
- /* soft reset */
- write_index(0x01);
- write_data(0x01);
- write_data(0x00);
- gfxSleepMilliseconds(1);
-
- /* Driver PLL config 480x272*/
- write_index(0x88);
- write_data(0x08);
- gfxSleepMilliseconds(1);
- write_index(0x89);
- write_data(0x02);
- gfxSleepMilliseconds(1);
-
- write_index(0x10); //SYSR bit[4:3]=00 256 color bit[2:1]= 00 8bit MPU interface
- write_data(0x0F); // if 16bit MCU interface and 65k color display
-
- write_index(0x04); //set PCLK invers
- write_data(0x82);
- gfxSleepMilliseconds(1);
-
- //Horizontal set
- write_index(0x14); //HDWR//Horizontal Display Width Setting Bit[6:0]
- write_data(0x3B);//Horizontal display width(pixels) = (HDWR + 1)*8
- write_index(0x15); //Horizontal Non-Display Period Fine Tuning Option Register (HNDFTR)
- write_data(0x00);//Horizontal Non-Display Period Fine Tuning(HNDFT) [3:0]
- write_index(0x16); //HNDR//Horizontal Non-Display Period Bit[4:0]
- write_data(0x01);//Horizontal Non-Display Period (pixels) = (HNDR + 1)*8
- write_index(0x17); //HSTR//HSYNC Start Position[4:0]
- write_data(0x00);//HSYNC Start Position(PCLK) = (HSTR + 1)*8
- write_index(0x18); //HPWR//HSYNC Polarity ,The period width of HSYNC.
- write_data(0x05);//HSYNC Width [4:0] HSYNC Pulse width(PCLK) = (HPWR + 1)*8
-
- //Vertical set
- write_index(0x19); //VDHR0 //Vertical Display Height Bit [7:0]
- write_data(0x0f); //Vertical pixels = VDHR + 1
- write_index(0x1a); //VDHR1 //Vertical Display Height Bit [8]
- write_data(0x01); //Vertical pixels = VDHR + 1
- write_index(0x1b); //VNDR0 //Vertical Non-Display Period Bit [7:0]
- write_data(0x02); //VSYNC Start Position(PCLK) = (VSTR + 1)
- write_index(0x1c); //VNDR1 //Vertical Non-Display Period Bit [8]
- write_data(0x00); //Vertical Non-Display area = (VNDR + 1)
- write_index(0x1d); //VSTR0 //VSYNC Start Position[7:0]
- write_data(0x07);//VSYNC Start Position(PCLK) = (VSTR + 1)
- write_index(0x1e); //VSTR1 //VSYNC Start Position[8]
- write_data(0x00);//VSYNC Start Position(PCLK) = (VSTR + 1)
- write_index(0x1f); //VPWR //VSYNC Polarity ,VSYNC Pulse Width[6:0]
- write_data(0x09); //VSYNC Pulse Width(PCLK) = (VPWR + 1)
-
- //Active window set
- //setting active window X
- write_index(0x30); //Horizontal Start Point 0 of Active Window (HSAW0)
- write_data(0x00); //Horizontal Start Point of Active Window [7:0]
- write_index(0x31); //Horizontal Start Point 1 of Active Window (HSAW1)
- write_data(0x00); //Horizontal Start Point of Active Window [9:8]
- write_index(0x34); //Horizontal End Point 0 of Active Window (HEAW0)
- write_data(0xDF); //Horizontal End Point of Active Window [7:0]
- write_index(0x35); //Horizontal End Point 1 of Active Window (HEAW1)
- write_data(0x01); //Horizontal End Point of Active Window [9:8]
-
- //setting active window Y
- write_index(0x32); //Vertical Start Point 0 of Active Window (VSAW0)
- write_data(0x00); //Vertical Start Point of Active Window [7:0]
- write_index(0x33); //Vertical Start Point 1 of Active Window (VSAW1)
- write_data(0x00); //Vertical Start Point of Active Window [8]
- write_index(0x36); //Vertical End Point of Active Window 0 (VEAW0)
- write_data(0x0F); //Vertical End Point of Active Window [7:0]
- write_index(0x37); //Vertical End Point of Active Window 1 (VEAW1)
- write_data(0x01); //Vertical End Point of Active Window [8]
-
- // Display ON
- write_index(0x01); //PWRR
- write_data(0x80);
-
- // GPO0 DISP high
- write_index(0x13); //GPO
- write_data(0x01);
-
- set_backlight(0x80); //set to 90% brightness
-
- post_init_board();
-
- /* Initialise the GDISP structure to match */
- GDISP.Width = GDISP_SCREEN_WIDTH;
- GDISP.Height = GDISP_SCREEN_HEIGHT;
- GDISP.Orientation = GDISP_ROTATE_0;
- GDISP.Powermode = powerOn;
- GDISP.Backlight = 100;
- GDISP.Contrast = 50;
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- GDISP.clipx0 = 0;
- GDISP.clipy0 = 0;
- GDISP.clipx1 = GDISP.Width;
- GDISP.clipy1 = GDISP.Height;
- #endif
-
- return TRUE;
-}
-
-void gdisp_lld_setwindow(coord_t x0, coord_t y0, coord_t x1, coord_t y1) {
- /* We don't need to validate here as the LLD routines will validate first.
- *
- * #if GDISP_NEED_VALIDATION
- * if (x0 >= GDISP.Width || y0 >= GDISP.Height || x0 < 0 || y0 < 0) return;
- * else if (x1 >= GDISP.Width || y1 >= GDISP.Height || y1 < 0 || y2 < 0) return;
- * #endif
- */
-
- //setting active window X
- write_index(0x30); //HSAW0
- write_data(x0);
- write_index(0x31); //HSAW1
- write_data(x0>>8);
-
- write_index(0x34); //HEAW0
- write_data(x1);
- write_index(0x35); //HEAW1
- write_data(x1>>8);
-
- //setting active window Y
- write_index(0x32); //VSAW0
- write_data(y0);
- write_index(0x33); //VSAW1
- write_data(y0>>8);
-
- write_index(0x36); //VEAW0
- write_data(y1);
- write_index(0x37); //VEAW1
- write_data(y1>>8);
-
- write_index(0x46);
- write_data(x0);
- write_index(0x47);
- write_data(x0>>8);
-
- write_index(0x48);
- write_data(y0);
- write_index(0x49);
- write_data(y0>>8);
-}
-
-/**
- * @brief Draws a pixel on the display.
- *
- * @param[in] x X location of the pixel
- * @param[in] y Y location of the pixel
- * @param[in] color The color of the pixel
- *
- * @notapi
- */
-void gdisp_lld_draw_pixel(coord_t x, coord_t y, color_t color) {
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- if (x < GDISP.clipx0 || y < GDISP.clipy0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
- #endif
-
- gdisp_lld_setwindow(x, y, x, y);
- write_index(RA8875_WRITE_MEMORY_START);
- write_data(color);
-}
-
-/* ---- Optional Routines ---- */
-
-#if GDISP_HARDWARE_FILLS || defined(__DOXYGEN__)
- /**
- * @brief Fill an area with a color.
- * @note Optional - The high level driver can emulate using software.
- *
- * @param[in] x, y The start filled area
- * @param[in] cx, cy The width and height to be filled
- * @param[in] color The color of the fill
- *
- * @notapi
- */
- void gdisp_lld_fill_area(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
- uint32_t area;
-
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; }
- if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; }
- if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
- if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
- if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
- #endif
-
- area = cx*cy;
-
- gdisp_lld_setwindow(x, y, x+cx-1, y+cy-1);
- write_index(RA8875_WRITE_MEMORY_START);
-
- #if defined(GDISP_USE_FSMC) && defined(GDISP_USE_DMA) && defined(GDISP_DMA_STREAM)
- uint8_t i;
- dmaStreamSetPeripheral(GDISP_DMA_STREAM, &color);
- dmaStreamSetMode(GDISP_DMA_STREAM, STM32_DMA_CR_PL(0) | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_DIR_M2M);
- for (i = area/65535; i; i--) {
- dmaStreamSetTransactionSize(GDISP_DMA_STREAM, 65535);
- dmaStreamEnable(GDISP_DMA_STREAM);
- dmaWaitCompletion(GDISP_DMA_STREAM);
- }
- dmaStreamSetTransactionSize(GDISP_DMA_STREAM, area%65535);
- dmaStreamEnable(GDISP_DMA_STREAM);
- dmaWaitCompletion(GDISP_DMA_STREAM);
- #else
- uint32_t index;
- for(index = 0; index < area; index++)
- write_data(color);
- #endif //#ifdef GDISP_USE_DMA
-}
-#endif
-
-#if GDISP_HARDWARE_BITFILLS || defined(__DOXYGEN__)
- /**
- * @brief Fill an area with a bitmap.
- * @note Optional - The high level driver can emulate using software.
- *
- * @param[in] x, y The start filled area
- * @param[in] cx, cy The width and height to be filled
- * @param[in] srcx, srcy The bitmap position to start the fill from
- * @param[in] srccx The width of a line in the bitmap.
- * @param[in] buffer The pixels to use to fill the area.
- *
- * @notapi
- */
- void gdisp_lld_blit_area_ex(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx, coord_t srcy, coord_t srccx, const pixel_t *buffer) {
-
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; srcx += GDISP.clipx0 - x; x = GDISP.clipx0; }
- if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; srcy += GDISP.clipy0 - y; y = GDISP.clipy0; }
- if (srcx+cx > srccx) cx = srccx - srcx;
- if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
- if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
- if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
- #endif
-
- gdisp_lld_setwindow(x, y, x+cx-1, y+cy-1);
- write_index(RA8875_WRITE_MEMORY_START);
-
- buffer += srcx + srcy * srccx;
-
- #if defined(GDISP_USE_FSMC) && defined(GDISP_USE_DMA) && defined(GDISP_DMA_STREAM)
- uint32_t area = cx*cy;
- uint8_t i;
- dmaStreamSetPeripheral(GDISP_DMA_STREAM, buffer);
- dmaStreamSetMode(GDISP_DMA_STREAM, STM32_DMA_CR_PL(0) | STM32_DMA_CR_PINC | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_DIR_M2M);
- for (i = area/65535; i; i--) {
- dmaStreamSetTransactionSize(GDISP_DMA_STREAM, 65535);
- dmaStreamEnable(GDISP_DMA_STREAM);
- dmaWaitCompletion(GDISP_DMA_STREAM);
- }
- dmaStreamSetTransactionSize(GDISP_DMA_STREAM, area%65535);
- dmaStreamEnable(GDISP_DMA_STREAM);
- dmaWaitCompletion(GDISP_DMA_STREAM);
- #else
- coord_t endx, endy;
- uint32_t lg;
- endx = srcx + cx;
- endy = y + cy;
- lg = srccx - cx;
- for(; y < endy; y++, buffer += lg)
- for(x=srcx; x < endx; x++)
- write_data(*buffer++);
- #endif //#ifdef GDISP_USE_DMA
- }
-#endif
-
-#if (GDISP_NEED_SCROLL && GDISP_HARDWARE_SCROLL) || defined(__DOXYGEN__)
- /**
- * @brief Scroll vertically a section of the screen.
- * @note Optional.
- * @note If x,y + cx,cy is off the screen, the result is undefined.
- * @note If lines is >= cy, it is equivelent to a area fill with bgcolor.
- *
- * @param[in] x, y The start of the area to be scrolled
- * @param[in] cx, cy The size of the area to be scrolled
- * @param[in] lines The number of lines to scroll (Can be positive or negative)
- * @param[in] bgcolor The color to fill the newly exposed area.
- *
- * @notapi
- */
- void gdisp_lld_vertical_scroll(coord_t x, coord_t y, coord_t cx, coord_t cy, int lines, color_t bgcolor) {
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; }
- if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; }
- if (!lines || cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
- if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
- if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
- #endif
- /* NOT IMPLEMENTED YET */
-
- /*
- uint16_t size = x1 - x0 ;
-
- write_index(SSD1963_SET_SCROLL_AREA);
- write_data((x0 >> 8) & 0xFF);
- write_data((x0 >> 0) & 0xFF);
- write_data((size >> 8) & 0xFF);
- write_data((size >> 0) & 0xFF);
- write_data(((lcd_height-x1) >> 8) & 0xFF);
- write_data(((lcd_height-x1) >> 0) & 0xFF);
-
- write_index(SSD1963_SET_SCROLL_START);
- write_data((lines >> 8) & 0xFF);
- write_data((lines >> 0) & 0xFF);
- */
- }
-
-#endif
-
-#if (GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL) || defined(__DOXYGEN__)
- /**
- * @brief Driver Control
- * @details Unsupported control codes are ignored.
- * @note The value parameter should always be typecast to (void *).
- * @note There are some predefined and some specific to the low level driver.
- * @note GDISP_CONTROL_POWER - Takes a gdisp_powermode_t
- * GDISP_CONTROL_ORIENTATION - Takes a gdisp_orientation_t
- * GDISP_CONTROL_BACKLIGHT - Takes an int from 0 to 100. For a driver
- * that only supports off/on anything other
- * than zero is on.
- * GDISP_CONTROL_CONTRAST - Takes an int from 0 to 100.
- * GDISP_CONTROL_LLD - Low level driver control constants start at
- * this value.
- *
- * @param[in] what What to do.
- * @param[in] value The value to use (always cast to a void *).
- *
- * @notapi
- */
- void gdisp_lld_control(unsigned what, void *value) {
- /* NOT IMPLEMENTED YET */
- switch(what) {
- case GDISP_CONTROL_POWER:
- if (GDISP.Powermode == (gdisp_powermode_t)value)
- return;
- switch((gdisp_powermode_t)value) {
- case powerOff:
- /* ToDo */
- break;
- case powerOn:
- /* ToDo */
- break;
- case powerSleep:
- /* ToDo */
- break;
- default:
- return;
- }
- GDISP.Powermode = (gdisp_powermode_t)value;
- return;
- case GDISP_CONTROL_ORIENTATION:
- if (GDISP.Orientation == (gdisp_orientation_t)value)
- return;
- switch((gdisp_orientation_t)value) {
- case GDISP_ROTATE_0:
- /* Code here */
- GDISP.Height = GDISP_SCREEN_HEIGHT;
- GDISP.Width = GDISP_SCREEN_WIDTH;
- break;
- case GDISP_ROTATE_90:
- /* Code here */
- GDISP.Height = GDISP_SCREEN_WIDTH;
- GDISP.Width = GDISP_SCREEN_HEIGHT;
- break;
- case GDISP_ROTATE_180:
- /* Code here */
- GDISP.Height = GDISP_SCREEN_HEIGHT;
- GDISP.Width = GDISP_SCREEN_WIDTH;
- break;
- case GDISP_ROTATE_270:
- /* Code here */
- GDISP.Height = GDISP_SCREEN_WIDTH;
- GDISP.Width = GDISP_SCREEN_HEIGHT;
- break;
- default:
- return;
- }
- #if GDISP_NEED_CLIP || GDISP_NEED_VALIDATION
- GDISP.clipx0 = 0;
- GDISP.clipy0 = 0;
- GDISP.clipx1 = GDISP.Width;
- GDISP.clipy1 = GDISP.Height;
- #endif
- GDISP.Orientation = (gdisp_orientation_t)value;
- return;
- case GDISP_CONTROL_BACKLIGHT:
- set_backlight((uint8_t )value);
- //gdisp_lld_bg_dimmer(54 + ((uint8_t)value) << 1);//turn 0..100% in 54..255
- return;
-/*
- case GDISP_CONTROL_CONTRAST:
-*/
- }
- }
-#endif
-
-#endif /* GFX_USE_GDISP */
-/** @} */
-
diff --git a/drivers/gdisp/RA8875/gdisp_lld.mk b/drivers/gdisp/RA8875/gdisp_lld.mk
index 471b7e83..146cf255 100644
--- a/drivers/gdisp/RA8875/gdisp_lld.mk
+++ b/drivers/gdisp/RA8875/gdisp_lld.mk
@@ -1,6 +1,2 @@
-# List the required driver.
-GFXSRC += $(GFXLIB)/drivers/gdisp/RA8875/gdisp_lld.c
-
-# Required include directories
GFXINC += $(GFXLIB)/drivers/gdisp/RA8875
-
+GFXSRC += $(GFXLIB)/drivers/gdisp/RA8875/gdisp_lld_RA8875.c
diff --git a/drivers/gdisp/RA8875/gdisp_lld_RA8875.c b/drivers/gdisp/RA8875/gdisp_lld_RA8875.c
new file mode 100644
index 00000000..d28670c6
--- /dev/null
+++ b/drivers/gdisp/RA8875/gdisp_lld_RA8875.c
@@ -0,0 +1,283 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/RA8875/gdisp_lld.c
+ * @brief GDISP Graphics Driver subsystem low level driver source.
+ */
+
+#include "gfx.h"
+
+#if GFX_USE_GDISP /*|| defined(__DOXYGEN__)*/
+
+#define GDISP_DRIVER_VMT GDISPVMT_RA8875
+#include "../drivers/gdisp/RA8875/gdisp_lld_config.h"
+#include "gdisp/lld/gdisp_lld.h"
+
+/* include the users board interface */
+#include "board_RA8875.h"
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+#ifndef GDISP_SCREEN_HEIGHT
+ #define GDISP_SCREEN_HEIGHT 272
+#endif
+#ifndef GDISP_SCREEN_WIDTH
+ #define GDISP_SCREEN_WIDTH 480
+#endif
+#ifndef GDISP_INITIAL_CONTRAST
+ #define GDISP_INITIAL_CONTRAST 50
+#endif
+#ifndef GDISP_INITIAL_BACKLIGHT
+ #define GDISP_INITIAL_BACKLIGHT 74
+#endif
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+// Some common routines and macros
+#define dummy_read(g) { volatile uint16_t dummy; dummy = read_data(g); (void) dummy; }
+#define write_reg8(g, reg, data) { write_index(g, reg); write_data(g, data); }
+#define write_reg16(g, reg, data) { write_index(g, reg); write_data(g, data); write_index(g, reg+1); write_data(g, (data)>>8); }
+#define write_reg8x2(g, reg, d1, d2) { write_index(g, reg); write_data(g, d1); write_data(g, d2); }
+
+static inline void set_cursor(GDisplay *g) {
+ write_reg16(g, 0x46, g->p.x);
+ write_reg16(g, 0x48, g->p.y);
+ write_index(g, 0x02);
+}
+
+static inline void set_viewport(GDisplay* g) {
+ write_reg16(g, 0x30, g->p.x); //HSAW0 & HSAW1
+ write_reg16(g, 0x34, g->p.x+g->p.cx-1); //HEAW0 & HEAW1
+ write_reg16(g, 0x32, g->p.y); //VSAW0 & VSAW1
+ write_reg16(g, 0x36, g->p.y+g->p.cy-1); //VEAW0 & VEAW1
+}
+
+// On this controller the back-light is controlled by the controllers internal PWM
+// which is why it is in this file rather than the board file.
+static inline void set_backlight(GDisplay* g, uint8_t percent) {
+ uint8_t temp;
+
+ //Work in progress: the RA8875 has a built-in PWM, its output can
+ //be used by a Dynamic Background Control or by a host (user)
+
+ // Enable PWM1
+ write_index(g, 0x8a); //MCLR
+ setreadmode(g);
+ temp = read_data(g);
+ setwritemode(g);
+ temp |= 1<<7 ;
+ write_data(g, temp);
+
+ // PWM1 function select
+ write_index(g, 0x8a); //MCLR
+ setreadmode(g);
+ temp = read_data(g);
+ setwritemode(g);
+ temp &= ~(1<<4);
+ write_data(g, temp);
+
+ // PWM1 Clock ratio
+ write_index(g, 0x8a); //MCLR
+ setreadmode(g);
+ temp = read_data(g);
+ setwritemode(g);
+ temp &= 0xf0;
+ temp |= 0x0b & 0x0f;
+ write_data(g, temp);
+
+ // PWM1 Write duty cycle
+ write_reg8(g, 0x8b, 54+percent); // PTNO: Also change percent to range from 0x00 to 0xFF
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
+ // No private area for this controller
+ g->priv = 0;
+
+ // Initialise the board interface
+ init_board(g);
+
+ // Hardware reset
+ setpin_reset(g, TRUE);
+ gfxSleepMilliseconds(20);
+ setpin_reset(g, FALSE);
+ gfxSleepMilliseconds(20);
+
+ // Get the bus for the following initialisation commands
+ acquire_bus(g);
+
+ // Soft reset
+ write_reg8x2(g, 0x01, 0x01, 0x00); gfxSleepMilliseconds(1);
+
+ // PLL config
+ write_reg8(g, 0x88, 0x08); gfxSleepMilliseconds(1);
+ write_reg8(g, 0x89, 0x02); gfxSleepMilliseconds(1);
+
+ write_reg8(g, 0x10, 0x0F); //SYSR bit[4:3]=00 256 color bit[2:1]= 00 8bit MPU interface
+ // 0x0F = 16bit MCU interface and 65k color display
+
+ write_reg8(g, 0x04, 0x82); gfxSleepMilliseconds(1); //set PCLK inverse
+
+ // Horizontal set
+ write_reg8(g, 0x14, GDISP_SCREEN_WIDTH/8-1); //HDWR: Horizontal Display Width Setting Bit[6:0] - pixels = (HDWR + 1)*8
+ write_reg8(g, 0x15, 0x00); //Horizontal Non-Display Period Fine Tuning Option Register (HNDFTR) - HNDFT = [3:0]
+ write_reg8(g, 0x16, 0x01); //HNDR: Horizontal Non-Display Period Bit[4:0] - pixels = (HNDR + 1)*8
+ write_reg8(g, 0x17, 0x00); //HSTR: HSYNC Start Position[4:0] - Position(PCLK) = (HSTR + 1)*8
+ write_reg8(g, 0x18, 0x05); //HPWR: HSYNC Polarity, The period width of HSYNC. Width [4:0] width(PCLK) = (HPWR + 1)*8
+
+ // Vertical set
+ write_reg16(g, 0x19, GDISP_SCREEN_HEIGHT-1); //VDHR0,1: Vertical Display Height = VDHR + 1
+ write_reg16(g, 0x1b, 0x0002); //VNDR0,1: Vertical Non-Display Period Bit = (VSTR + 1)
+ write_reg16(g, 0x1d, 0x0007); //VSTR0,1: VSYNC Start Position = (VSTR + 1)
+ write_reg8(g, 0x1f, 0x09); //VPWR: VSYNC Polarity, VSYNC Pulse Width[6:0] - Width(PCLK) = (VPWR + 1)
+
+ // Active window set
+ write_reg16(g, 0x30, 0); //HSAW0 & HSAW1
+ write_reg16(g, 0x34, GDISP_SCREEN_WIDTH-1); //HEAW0 & HEAW1
+ write_reg16(g, 0x32, 0); //VSAW0 & VSAW1
+ write_reg16(g, 0x36, GDISP_SCREEN_HEIGHT-1); //VEAW0 & VEAW1
+
+ // Display ON
+ write_reg8(g, 0x01, 0x80); //PWRR
+
+ // GPO0 DISP high
+ write_reg8(g, 0x13, 0x01); //GPO
+
+ // Set initial back-light
+ set_backlight(g, GDISP_INITIAL_BACKLIGHT);
+
+ // Change timings for faster access
+ post_init_board(g);
+
+ // Release the bus
+ release_bus(g);
+
+ /* Initialise the GDISP structure */
+ g->g.Width = GDISP_SCREEN_WIDTH;
+ g->g.Height = GDISP_SCREEN_HEIGHT;
+ g->g.Orientation = GDISP_ROTATE_0;
+ g->g.Powermode = powerOn;
+ g->g.Backlight = GDISP_INITIAL_BACKLIGHT;
+ g->g.Contrast = GDISP_INITIAL_CONTRAST;
+ return TRUE;
+}
+
+#if GDISP_HARDWARE_STREAM_WRITE
+ LLDSPEC void gdisp_lld_write_start(GDisplay *g) {
+ acquire_bus(g);
+ set_viewport(g);
+ }
+ LLDSPEC void gdisp_lld_write_color(GDisplay *g) {
+ write_data(g, COLOR2NATIVE(g->p.color));
+ }
+ LLDSPEC void gdisp_lld_write_stop(GDisplay *g) {
+ release_bus(g);
+ }
+ LLDSPEC void gdisp_lld_write_pos(GDisplay *g) {
+ set_cursor(g);
+ }
+#endif
+
+#if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL
+ LLDSPEC void gdisp_lld_control(GDisplay *g) {
+ switch(g->p.x) {
+ #if 0
+ case GDISP_CONTROL_POWER:
+ if (g->g.Powermode == (powermode_t)g->p.ptr)
+ return;
+ switch((powermode_t)g->p.ptr) {
+ case powerOff:
+ acquire_bus(g);
+ // TODO
+ release_bus(g);
+ break;
+ case powerOn:
+ acquire_bus(g);
+ // TODO
+ release_bus(g);
+ break;
+ case powerSleep:
+ acquire_bus(g);
+ // TODO
+ release_bus(g);
+ break;
+ default:
+ return;
+ }
+ g->g.Powermode = (powermode_t)g->p.ptr;
+ return;
+ #endif
+
+ #if 0
+ case GDISP_CONTROL_ORIENTATION:
+ if (g->g.Orientation == (orientation_t)g->p.ptr)
+ return;
+ switch((orientation_t)g->p.ptr) {
+ case GDISP_ROTATE_0:
+ acquire_bus(g);
+ // TODO
+ release_bus(g);
+ g->g.Height = GDISP_SCREEN_HEIGHT;
+ g->g.Width = GDISP_SCREEN_WIDTH;
+ break;
+ case GDISP_ROTATE_90:
+ acquire_bus(g);
+ // TODO
+ release_bus(g);
+ g->g.Height = GDISP_SCREEN_WIDTH;
+ g->g.Width = GDISP_SCREEN_HEIGHT;
+ break;
+ case GDISP_ROTATE_180:
+ acquire_bus(g);
+ // TODO
+ release_bus(g);
+ g->g.Height = GDISP_SCREEN_HEIGHT;
+ g->g.Width = GDISP_SCREEN_WIDTH;
+ break;
+ case GDISP_ROTATE_270:
+ acquire_bus(g);
+ // TODO
+ release_bus(g);
+ g->g.Height = GDISP_SCREEN_WIDTH;
+ g->g.Width = GDISP_SCREEN_HEIGHT;
+ break;
+ default:
+ return;
+ }
+ g->g.Orientation = (orientation_t)g->p.ptr;
+ return;
+ #endif
+
+ case GDISP_CONTROL_BACKLIGHT:
+ if ((unsigned)g->p.ptr > 100)
+ g->p.ptr = (void *)100;
+ acquire_bus(g);
+ set_backlight(g, (unsigned)g->p.ptr);
+ release_bus(g);
+ g->g.Backlight = (unsigned)g->p.ptr;
+ return;
+
+ //case GDISP_CONTROL_CONTRAST:
+ default:
+ return;
+ }
+ }
+#endif
+
+#endif /* GFX_USE_GDISP */
diff --git a/drivers/gdisp/RA8875/gdisp_lld_board_marlin.h b/drivers/gdisp/RA8875/gdisp_lld_board_marlin.h
deleted file mode 100644
index 072ba32e..00000000
--- a/drivers/gdisp/RA8875/gdisp_lld_board_marlin.h
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * This file is subject to the terms of the GFX License. If a copy of
- * the license was not distributed with this file, you can obtain one at:
- *
- * http://ugfx.org/license.html
- */
-
-/**
- * @file drivers/gdisp/RA8875/gdisp_lld_board_marlin.h
- * @brief GDISP Graphic Driver subsystem board interface for the RA8875 display.
- *
- * @addtogroup GDISP
- * @{
- */
-
-#ifndef _GDISP_LLD_BOARD_H
-#define _GDISP_LLD_BOARD_H
-
-/* Using FSMC A16 as RS */
-#define GDISP_RAM (*((volatile uint16_t *) 0x68000000)) /* RS = 0 */
-#define GDISP_REG (*((volatile uint16_t *) 0x68020000)) /* RS = 1 */
-
-/**
- * @brief Send data to the index register.
- *
- * @param[in] index The index register to set
- *
- * @notapi
- */
-static inline void write_index(uint16_t index) {
- GDISP_REG = index;
-}
-
-/**
- * @brief Send data to the lcd.
- *
- * @param[in] data The data to send
- *
- * @notapi
- */
-static inline void write_data(uint16_t data) {
- GDISP_RAM = data;
-}
-
-/**
- * @brief Read data from the lcd.
- *
- * @return The data from the lcd
- * @note The chip select may need to be asserted/de-asserted
- * around the actual spi read
- *
- * @notapi
- */
-static inline uint16_t read_data(void) {
- return GDISP_RAM;
-}
-
-/**
- * @brief Initialise the board for the display.
- * @notes Performs the following functions:
- * 1. initialise the io port used by your display
- * 2. initialise the reset pin (initial state not-in-reset)
- * 3. initialise the chip select pin (initial state not-active)
- * 4. initialise the backlight pin (initial state back-light off)
- *
- * @notapi
- */
-static inline void init_board(void) {
- const unsigned char FSMC_Bank = 4;
-
- #if defined(STM32F1XX) || defined(STM32F3XX)
- /* FSMC setup for F1/F3 */
- rccEnableAHB(RCC_AHBENR_FSMCEN, 0);
-
- #if defined(GDISP_USE_DMA) && defined(GDISP_DMA_STREAM)
- #error "DMA not implemented for F1/F3 Devices"
- #endif
- #elif defined(STM32F4XX) || defined(STM32F2XX)
- /* STM32F2-F4 FSMC init */
- rccEnableAHB3(RCC_AHB3ENR_FSMCEN, 0);
-
- #if defined(GDISP_USE_DMA) && defined(GDISP_DMA_STREAM)
- if (dmaStreamAllocate(GDISP_DMA_STREAM, 0, NULL, NULL)) chSysHalt();
- dmaStreamSetMemory0(GDISP_DMA_STREAM, &GDISP_RAM);
- dmaStreamSetMode(GDISP_DMA_STREAM, STM32_DMA_CR_PL(0) | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_DIR_M2M);
- #endif
- #else
- #error "FSMC not implemented for this device"
- #endif
-
- /* set pins to FSMC mode */
- IOBus busD = {GPIOD, (1 << 0) | (1 << 1) | (1 << 4) | (1 << 5) | (1 << 8) |
- (1 << 9) | (1 << 10) | (1 << 11) | (1 << 14) | (1 << 15), 0};
-
- IOBus busE = {GPIOE, (1 << 7) | (1 << 8) | (1 << 9) | (1 << 10) | (1 << 11) | (1 << 12) |
- (1 << 13) | (1 << 14) | (1 << 15), 0};
-
- IOBus busG = {GPIOG, (1 << 10), 0};
-
- palSetBusMode(&busD, PAL_MODE_ALTERNATE(12));
- palSetBusMode(&busE, PAL_MODE_ALTERNATE(12));
- palSetBusMode(&busG, PAL_MODE_ALTERNATE(12));
-
- /* FSMC timing */
- FSMC_Bank1->BTCR[FSMC_Bank+1] = (FSMC_BTR1_ADDSET_1 | FSMC_BTR1_ADDSET_3) \
- | (FSMC_BTR1_DATAST_1 | FSMC_BTR1_DATAST_3) \
- | (FSMC_BTR1_BUSTURN_1 | FSMC_BTR1_BUSTURN_3) ;
-
- /* Bank1 NOR/SRAM control register configuration
- * This is actually not needed as already set by default after reset */
- FSMC_Bank1->BTCR[FSMC_Bank] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN;
-}
-
-static inline void post_init_board(void) {
- const unsigned char FSMC_Bank = 2;
- /* FSMC delay reduced as the controller now runs at full speed */
- FSMC_Bank1->BTCR[FSMC_Bank+1] = FSMC_BTR1_ADDSET_0 | FSMC_BTR1_DATAST_2 | FSMC_BTR1_BUSTURN_0 ;
- FSMC_Bank1->BTCR[FSMC_Bank] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN;
-}
-
-/**
- * @brief Set or clear the lcd reset pin.
- *
- * @param[in] state TRUE = lcd in reset, FALSE = normal operation
- *
- * @notapi
- */
-static inline void setpin_reset(bool_t state) {
- (void) state;
- /* Nothing to do here */
-}
-
-/**
- * @brief Set the lcd back-light level.
- *
- * @param[in] percent 0 to 100%
- *
- * @notapi
- */
-static inline void set_backlight(uint8_t percent) {
-
- //duty_cycle is 00..FF
- //Work in progress: the RA8875 has a built-in PWM, its output can
- //be used by a Dynamic Background Control or by a host (user)
-
- uint8_t temp, temp1;
- // Enable PWM1
- write_index(0x8a);//MCLR
- temp = read_data();
- temp |= 1<<7 ;
- write_data(temp);
-
- // PWM1 function select
- write_index(0x8a);//MCLR
- temp = read_data();
- temp &= ~(1<<4);
- write_data(temp);
-
- // PWM1 Clock ratio
- temp1= 0x0b&0x0f;
- write_index(0x8a);//MCLR
- temp = read_data();
- temp &= 0xf0;
- temp |= temp1 ;
- write_data(temp);
-
- // Write duty cycle
- write_index(0x8b);//PTNO
- write_data(percent);
- // PWM1 duty cycle
-}
-
-/**
- * @brief Take exclusive control of the bus
- *
- * @notapi
- */
-static inline void acquire_bus(void) {
- /* Nothing to do here */
-}
-
-/**
- * @brief Release exclusive control of the bus
- *
- * @notapi
- */
-static inline void release_bus(void) {
- /* Nothing to do here */
-}
-
-#endif /* _GDISP_LLD_BOARD_H */
-/** @} */
-
diff --git a/drivers/gdisp/RA8875/gdisp_lld_board_template.h b/drivers/gdisp/RA8875/gdisp_lld_board_template.h
deleted file mode 100644
index a11c11ab..00000000
--- a/drivers/gdisp/RA8875/gdisp_lld_board_template.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * This file is subject to the terms of the GFX License. If a copy of
- * the license was not distributed with this file, you can obtain one at:
- *
- * http://ugfx.org/license.html
- */
-
-/**
- * @file drivers/gdisp/SSD1963/gdisp_lld_board_template.h
- * @brief GDISP Graphic Driver subsystem board interface for the SSD1963 display.
- *
- * @addtogroup GDISP
- * @{
- */
-
-#ifndef _GDISP_LLD_BOARD_H
-#define _GDISP_LLD_BOARD_H
-
-/**
- * @brief Send data to the index register.
- *
- * @param[in] index The index register to set
- *
- * @notapi
- */
-static inline void write_index(uint16_t index) {
-
-}
-
-/**
- * @brief Send data to the lcd.
- *
- * @param[in] data The data to send
- *
- * @notapi
- */
-static inline void write_data(uint16_t data) {
-
-}
-
-/**
- * @brief Initialise the board for the display.
- *
- * @notapi
- */
-static inline void init_board(void) {
-
-}
-
-static inline void post_init_board(void) {
-
-}
-
-/**
- * @brief Set or clear the lcd reset pin.
- *
- * @param[in] state TRUE = lcd in reset, FALSE = normal operation
- *
- * @notapi
- */
-static inline void setpin_reset(bool_t state) {
-
-}
-
-/**
- * @brief Set the lcd back-light level.
- *
- * @param[in] percent 0 to 100%
- *
- * @notapi
- */
-static inline void set_backlight(uint8_t percent) {
-
-}
-
-/**
- * @brief Take exclusive control of the bus
- *
- * @notapi
- */
-static inline void acquire_bus(void) {
-
-}
-
-/**
- * @brief Release exclusive control of the bus
- *
- * @notapi
- */
-static inline void release_bus(void) {
-
-}
-
-__inline void write_stream(uint16_t *buffer, uint16_t size) {
-
-}
-
-__inline void read_stream(uint16_t *buffer, size_t size) {
-
-}
-
-#if GDISP_HARDWARE_READPIXEL || GDISP_HARDWARE_SCROLL || defined(__DOXYGEN__)
-/**
- * @brief Read data from the lcd.
- *
- * @return The data from the lcd
- * @note The chip select may need to be asserted/de-asserted
- * around the actual spi read
- *
- * @notapi
- */
-static inline uint16_t read_data(void) {
-
-}
-#endif
-
-#endif /* _GDISP_LLD_BOARD_H */
-/** @} */
-
diff --git a/drivers/gdisp/RA8875/gdisp_lld_config.h b/drivers/gdisp/RA8875/gdisp_lld_config.h
index f49c3e03..55a07839 100644
--- a/drivers/gdisp/RA8875/gdisp_lld_config.h
+++ b/drivers/gdisp/RA8875/gdisp_lld_config.h
@@ -22,17 +22,12 @@
/* Driver hardware support. */
/*===========================================================================*/
-#define GDISP_DRIVER_NAME "RA8875"
-
-#define GDISP_HARDWARE_FILLS TRUE
-#define GDISP_HARDWARE_BITFILL TRUE
-#define GDISP_HARDWARE_READPIXEL TRUE
-
-/* Maybe someday soon */
-#define GDISP_HARDWARE_SCROLL FALSE
+#define GDISP_HARDWARE_STREAM_WRITE TRUE
+#define GDISP_HARDWARE_STREAM_READ TRUE
+#define GDISP_HARDWARE_STREAM_POS TRUE
#define GDISP_HARDWARE_CONTROL TRUE
-#define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_RGB565
+#define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_RGB565
#endif /* GFX_USE_GDISP */
diff --git a/drivers/gdisp/RA8875/ra8875.h b/drivers/gdisp/RA8875/ra8875.h
deleted file mode 100644
index 43210b66..00000000
--- a/drivers/gdisp/RA8875/ra8875.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * This file is subject to the terms of the GFX License. If a copy of
- * the license was not distributed with this file, you can obtain one at:
- *
- * http://ugfx.org/license.html
- */
-
-#ifndef RA8875_H
-#define RA8875_H
-
-#define mHIGH(x) (x >> 8)
-#define mLOW(x) (x & 0xFF)
-
-#define RA8875_WRITE_MEMORY_START 0x0002
-#define RA8875_READ_MEMORY_START 0x0002
-
-#endif
-
diff --git a/drivers/gdisp/S6D1121/board_S6D1121_template.h b/drivers/gdisp/S6D1121/board_S6D1121_template.h
new file mode 100644
index 00000000..04742f56
--- /dev/null
+++ b/drivers/gdisp/S6D1121/board_S6D1121_template.h
@@ -0,0 +1,154 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/S6D1121/board_S6D1121_template.h
+ * @brief GDISP Graphic Driver subsystem board interface for the S6D1121 display.
+ *
+ * @addtogroup GDISP
+ * @{
+ */
+
+#ifndef _GDISP_LLD_BOARD_H
+#define _GDISP_LLD_BOARD_H
+
+/**
+ * @brief Initialise the board for the display.
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @note Set the g->board member to whatever is appropriate. For multiple
+ * displays this might be a pointer to the appropriate register set.
+ *
+ * @notapi
+ */
+static inline void init_board(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief After the initialisation.
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void post_init_board(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Set or clear the lcd reset pin.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] state TRUE = lcd in reset, FALSE = normal operation
+ *
+ * @notapi
+ */
+static inline void setpin_reset(GDisplay *g, bool_t state) {
+ (void) g;
+ (void) state;
+}
+
+/**
+ * @brief Set the lcd back-light level.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] percent 0 to 100%
+ *
+ * @notapi
+ */
+static inline void set_backlight(GDisplay *g, uint8_t percent) {
+ (void) g;
+ (void) percent;
+}
+
+/**
+ * @brief Take exclusive control of the bus
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void acquire_bus(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Release exclusive control of the bus
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void release_bus(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Send data to the index register.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] index The index register to set
+ *
+ * @notapi
+ */
+static inline void write_index(GDisplay *g, uint16_t index) {
+ (void) g;
+ (void) index;
+}
+
+/**
+ * @brief Send data to the lcd.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] data The data to send
+ *
+ * @notapi
+ */
+static inline void write_data(GDisplay *g, uint16_t data) {
+ (void) g;
+ (void) data;
+}
+
+/**
+ * @brief Set the bus in read mode
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void setreadmode(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Set the bus back into write mode
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void setwritemode(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Read data from the lcd.
+ * @return The data from the lcd
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline uint16_t read_data(GDisplay *g) {
+ (void) g;
+ return 0;
+}
+
+#endif /* _GDISP_LLD_BOARD_H */
+/** @} */
diff --git a/drivers/gdisp/S6D1121/gdisp_lld.c b/drivers/gdisp/S6D1121/gdisp_lld.c
deleted file mode 100644
index e570c1e8..00000000
--- a/drivers/gdisp/S6D1121/gdisp_lld.c
+++ /dev/null
@@ -1,561 +0,0 @@
-/*
- * This file is subject to the terms of the GFX License. If a copy of
- * the license was not distributed with this file, you can obtain one at:
- *
- * http://ugfx.org/license.html
- */
-
-/**
- * @file drivers/gdisp/S6D1121/gdisp_lld.c
- * @brief GDISP Graphics Driver subsystem low level driver source for the S6d1121 display.
- *
- * @addtogroup GDISP
- * @{
- */
-
-#include "gfx.h"
-
-#if GFX_USE_GDISP /*|| defined(__DOXYGEN__)*/
-
-/* Include the emulation code for things we don't support */
-#include "gdisp/lld/emulation.c"
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-#if defined(GDISP_SCREEN_HEIGHT)
- #warning "GDISP: This low level driver does not support setting a screen size. It is being ignored."
- #undef GISP_SCREEN_HEIGHT
-#endif
-#if defined(GDISP_SCREEN_WIDTH)
- #warning "GDISP: This low level driver does not support setting a screen size. It is being ignored."
- #undef GDISP_SCREEN_WIDTH
-#endif
-
-#define GDISP_SCREEN_HEIGHT 320
-#define GDISP_SCREEN_WIDTH 240
-
-#define GDISP_INITIAL_CONTRAST 50
-#define GDISP_INITIAL_BACKLIGHT 100
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-#include "gdisp_lld_board.h"
-
-/* Some common routines and macros */
-#define write_reg(reg, data) { write_index(reg); write_data(data); }
-#define stream_start() write_index(0x0022);
-#define stream_stop()
-#define delay(us) gfxSleepMicroseconds(us)
-#define delayms(ms) gfxSleepMilliseconds(ms)
-
-static inline void set_cursor(coord_t x, coord_t y) {
- /* R20h - 8 bit
- * R21h - 9 bit
- */
- switch(GDISP.Orientation) {
- case GDISP_ROTATE_0:
- write_reg(0x0020, x & 0x00FF);
- write_reg(0x0021, y & 0x01FF);
- break;
- case GDISP_ROTATE_90:
- /* Note X has already been mirrored, so we do it directly */
- write_reg(0x0020, y & 0x00FF);
- write_reg(0x0021, x & 0x01FF);
- break;
- case GDISP_ROTATE_180:
- write_reg(0x0020, (GDISP_SCREEN_WIDTH - 1 - x) & 0x00FF);
- write_reg(0x0021, (GDISP_SCREEN_HEIGHT - 1 - y) & 0x01FF);
- break;
- case GDISP_ROTATE_270:
- write_reg(0x0020, (GDISP_SCREEN_WIDTH - 1 - y) & 0x00FF);
- write_reg(0x0021, (GDISP_SCREEN_HEIGHT - 1 - x) & 0x01FF);
- break;
- }
-}
-
-static inline void set_viewport(coord_t x, coord_t y, coord_t cx, coord_t cy) {
- /* HSA / HEA are 8 bit
- * VSA / VEA are 9 bit
- * use masks 0x00FF and 0x01FF to enforce this
- */
-
- switch(GDISP.Orientation) {
- case GDISP_ROTATE_0:
- write_reg(0x46, (((x + cx - 1) << 8) & 0xFF00 ) |
- (x & 0x00FF));
-
- write_reg(0x48, y & 0x01FF);
- write_reg(0x47, (y + cy - 1) & 0x01FF);
- break;
- case GDISP_ROTATE_90:
- write_reg(0x46, (((y + cy - 1) << 8) & 0xFF00) |
- (y & 0x00FF));
-
- write_reg(0x48, x & 0x01FF);
- write_reg(0x47, (x + cx - 1) & 0x01FF);
- break;
- case GDISP_ROTATE_180:
- write_reg(0x46, (((GDISP_SCREEN_WIDTH - x - 1) & 0x00FF) << 8) |
- ((GDISP_SCREEN_WIDTH - (x + cx)) & 0x00FF));
- write_reg(0x48, (GDISP_SCREEN_HEIGHT - (y + cy)) & 0x01FF);
- write_reg(0x47, (GDISP_SCREEN_HEIGHT- y - 1) & 0x01FF);
- break;
- case GDISP_ROTATE_270:
- write_reg(0x46, (((GDISP_SCREEN_WIDTH - y - 1) & 0x00FF) << 8) |
- ((GDISP_SCREEN_WIDTH - (y + cy)) & 0x00FF));
- write_reg(0x48, (GDISP_SCREEN_HEIGHT - (x + cx)) & 0x01FF);
- write_reg(0x47, (GDISP_SCREEN_HEIGHT - x - 1) & 0x01FF);
- break;
- }
-
- set_cursor(x, y);
-}
-
-static inline void reset_viewport(void) {
- switch(GDISP.Orientation) {
- case GDISP_ROTATE_0:
- case GDISP_ROTATE_180:
- set_viewport(0, 0, GDISP_SCREEN_WIDTH, GDISP_SCREEN_HEIGHT);
- break;
- case GDISP_ROTATE_90:
- case GDISP_ROTATE_270:
- set_viewport(0, 0, GDISP_SCREEN_HEIGHT, GDISP_SCREEN_WIDTH);
- break;
- }
-}
-
-bool_t gdisp_lld_init(void) {
- /* initialize the hardware */
- init_board();
-
- /* Hardware reset */
- setpin_reset(TRUE);
- delayms(20);
- setpin_reset(TRUE);
- delayms(20);
-
- /* Get the bus for the following initialisation commands */
- acquire_bus();
-
- write_reg(0x11,0x2004);
- write_reg(0x13,0xCC00);
- write_reg(0x15,0x2600);
- write_reg(0x14,0x252A);
- write_reg(0x12,0x0033);
- write_reg(0x13,0xCC04);
-
- delayms(1);
-
- write_reg(0x13,0xCC06);
-
- delayms(1);
-
- write_reg(0x13,0xCC4F);
-
- delayms(1);
-
- write_reg(0x13,0x674F);
- write_reg(0x11,0x2003);
-
- delayms(1);
-
- // Gamma Setting
- write_reg(0x30,0x2609);
- write_reg(0x31,0x242C);
- write_reg(0x32,0x1F23);
- write_reg(0x33,0x2425);
- write_reg(0x34,0x2226);
- write_reg(0x35,0x2523);
- write_reg(0x36,0x1C1A);
- write_reg(0x37,0x131D);
- write_reg(0x38,0x0B11);
- write_reg(0x39,0x1210);
- write_reg(0x3A,0x1315);
- write_reg(0x3B,0x3619);
- write_reg(0x3C,0x0D00);
- write_reg(0x3D,0x000D);
-
- write_reg(0x16,0x0007);
- write_reg(0x02,0x0013);
- write_reg(0x03,0x0003);
- write_reg(0x01,0x0127);
-
- delayms(1);
-
- write_reg(0x08,0x0303);
- write_reg(0x0A,0x000B);
- write_reg(0x0B,0x0003);
- write_reg(0x0C,0x0000);
- write_reg(0x41,0x0000);
- write_reg(0x50,0x0000);
- write_reg(0x60,0x0005);
- write_reg(0x70,0x000B);
- write_reg(0x71,0x0000);
- write_reg(0x78,0x0000);
- write_reg(0x7A,0x0000);
- write_reg(0x79,0x0007);
- write_reg(0x07,0x0051);
-
- delayms(1);
-
- write_reg(0x07,0x0053);
- write_reg(0x79,0x0000);
-
- reset_viewport();
- set_backlight(GDISP_INITIAL_BACKLIGHT);
-
- /* Now initialise the GDISP structure */
- GDISP.Width = GDISP_SCREEN_WIDTH;
- GDISP.Height = GDISP_SCREEN_HEIGHT;
- GDISP.Orientation = GDISP_ROTATE_0;
- GDISP.Powermode = powerOn;
- GDISP.Backlight = 100;
- GDISP.Contrast = 50;
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- GDISP.clipx0 = 0;
- GDISP.clipy0 = 0;
- GDISP.clipx1 = GDISP.Width;
- GDISP.clipy1 = GDISP.Height;
- #endif
- return TRUE;
-}
-
-/**
- * @brief Draws a pixel on the display.
- *
- * @param[in] x X location of the pixel
- * @param[in] y Y location of the pixel
- * @param[in] color The color of the pixel
- *
- * @notapi
- */
-void gdisp_lld_draw_pixel(coord_t x, coord_t y, color_t color) {
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- if (x < GDISP.clipx0 || y < GDISP.clipy0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
- #endif
-
- acquire_bus();
- set_cursor(x, y);
- write_reg(0x0022, color);
- release_bus();
-}
-
-/* ---- Optional Routines ---- */
-
-#if GDISP_HARDWARE_CLEARS || defined(__DOXYGEN__)
- /**
- * @brief Clear the display.
- * @note Optional - The high level driver can emulate using software.
- *
- * @param[in] color The color of the pixel
- *
- * @notapi
- */
- void gdisp_lld_clear(color_t color) {
- unsigned i;
-
- acquire_bus();
- set_cursor(0, 0);
- stream_start();
-
- for(i = 0; i < GDISP_SCREEN_WIDTH * GDISP_SCREEN_HEIGHT; i++)
- write_data(color);
-
- stream_stop();
- release_bus();
- }
-#endif
-
-#if GDISP_HARDWARE_FILLS || defined(__DOXYGEN__)
- /**
- * @brief Fill an area with a color.
- * @note Optional - The high level driver can emulate using software.
- *
- * @param[in] x, y The start filled area
- * @param[in] cx, cy The width and height to be filled
- * @param[in] color The color of the fill
- *
- * @notapi
- */
- void gdisp_lld_fill_area(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
- unsigned i, area;
-
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; }
- if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; }
- if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
- if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
- if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
- #endif
-
- area = cx*cy;
- acquire_bus();
- set_viewport(x, y, cx, cy);
- stream_start();
- for(i = 0; i < area; i++)
- write_data(color);
- stream_stop();
- reset_viewport();
- release_bus();
- }
-#endif
-
-#if GDISP_HARDWARE_BITFILLS || defined(__DOXYGEN__)
- /**
- * @brief Fill an area with a bitmap.
- * @note Optional - The high level driver can emulate using software.
- *
- * @param[in] x, y The start filled area
- * @param[in] cx, cy The width and height to be filled
- * @param[in] srcx, srcy The bitmap position to start the fill from
- * @param[in] srccx The width of a line in the bitmap.
- * @param[in] buffer The pixels to use to fill the area.
- *
- * @notapi
- */
- void gdisp_lld_blit_area_ex(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx, coord_t srcy, coord_t srccx, const pixel_t *buffer) {
- coord_t endx, endy;
- unsigned lg;
-
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; srcx += GDISP.clipx0 - x; x = GDISP.clipx0; }
- if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; srcy += GDISP.clipy0 - y; y = GDISP.clipy0; }
- if (srcx+cx > srccx) cx = srccx - srcx;
- if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
- if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
- if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
- #endif
-
- acquire_bus();
- set_viewport(x, y, cx, cy);
- stream_start();
-
- endx = srcx + cx;
- endy = y + cy;
- lg = srccx - cx;
- buffer += srcx + srcy * srccx;
- for(; y < endy; y++, buffer += lg)
- for(x=srcx; x < endx; x++)
- write_data(*buffer++);
- stream_stop();
- reset_viewport();
- release_bus();
- }
-#endif
-
-#if (GDISP_NEED_PIXELREAD && GDISP_HARDWARE_PIXELREAD) || defined(__DOXYGEN__)
- /**
- * @brief Get the color of a particular pixel.
- * @note Optional.
- * @note If x,y is off the screen, the result is undefined.
- *
- * @param[in] x, y The start of the text
- *
- * @notapi
- */
- color_t gdisp_lld_get_pixel_color(coord_t x, coord_t y) {
- /* This routine is marked "DO NOT USE" in the original
- * GLCD driver. We just keep our GDISP_HARDWARE_READPIXEL
- * turned off for now.
- */
- color_t color;
-
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- if (x < 0 || x >= GDISP.Width || y < 0 || y >= GDISP.Height) return 0;
- #endif
-
- aquire_bus();
- set_cursor(x, y);
- stream_start();
-
- color = lld_lcdReadData();
- color = lld_lcdReadData();
-
- stream_stop();
- release_bus();
-
- return color;
- }
-#endif
-
-#if (GDISP_NEED_SCROLL && GDISP_HARDWARE_SCROLL) || defined(__DOXYGEN__)
- /**
- * @brief Scroll vertically a section of the screen.
- * @note Optional.
- * @note If x,y + cx,cy is off the screen, the result is undefined.
- * @note If lines is >= cy, it is equivelent to a area fill with bgcolor.
- *
- * @param[in] x, y The start of the area to be scrolled
- * @param[in] cx, cy The size of the area to be scrolled
- * @param[in] lines The number of lines to scroll (Can be positive or negative)
- * @param[in] bgcolor The color to fill the newly exposed area.
- *
- * @notapi
- */
- void gdisp_lld_vertical_scroll(coord_t x, coord_t y, coord_t cx, coord_t cy, int lines, color_t bgcolor) {
- /* This is marked as "TODO: Test this" in the original GLCD driver.
- * For now we just leave the GDISP_HARDWARE_SCROLL off.
- */
- static color_t buf[((GDISP_SCREEN_HEIGHT > GDISP_SCREEN_WIDTH ) ? GDISP_SCREEN_HEIGHT : GDISP_SCREEN_WIDTH)];
- coord_t row0, row1;
- unsigned i, gap, abslines;
-
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; }
- if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; }
- if (!lines || cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
- if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
- if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
- #endif
-
- abslines = lines < 0 ? -lines : lines;
-
- acquire_bus();
- if (abslines >= cy) {
- abslines = cy;
- gap = 0;
- } else {
- gap = cy - abslines;
- for(i = 0; i < gap; i++) {
- if(lines > 0) {
- row0 = y + i + lines;
- row1 = y + i;
- } else {
- row0 = (y - i - 1) + lines;
- row1 = (y - i - 1);
- }
-
- /* read row0 into the buffer and then write at row1*/
- set_viewport(x, row0, cx, 1);
- lld_lcdReadStreamStart();
- lld_lcdReadStream(buf, cx);
- lld_lcdReadStreamStop();
-
- set_viewport(x, row1, cx, 1);
- stream_start();
- write_data(buf, cx);
- stream_stop();
- }
- }
-
- /* fill the remaining gap */
- set_viewport(x, lines > 0 ? (y+gap) : y, cx, abslines);
- stream_start();
- gap = cx*abslines;
- for(i = 0; i < gap; i++) write_data(bgcolor);
- stream_stop();
- reset_viewport();
- release_bus();
- }
-#endif
-
-#if GDISP_HARDWARE_CONTROL || defined(__DOXYGEN__)
- /**
- * @brief Driver Control
- * @details Unsupported control codes are ignored.
- * @note The value parameter should always be typecast to (void *).
- * @note There are some predefined and some specific to the low level driver.
- * @note GDISP_CONTROL_POWER - Takes a gdisp_powermode_t
- * GDISP_CONTROL_ORIENTATION - Takes a gdisp_orientation_t
- * GDISP_CONTROL_BACKLIGHT - Takes an int from 0 to 100. For a driver
- * that only supports off/on anything other
- * than zero is on.
- * GDISP_CONTROL_CONTRAST - Takes an int from 0 to 100.
- * GDISP_CONTROL_LLD - Low level driver control constants start at
- * this value.
- *
- * @param[in] what What to do.
- * @param[in] value The value to use (always cast to a void *).
- *
- * @notapi
- */
- void gdisp_lld_control(unsigned what, void *value) {
- switch(what) {
- case GDISP_CONTROL_POWER:
- if (GDISP.Powermode == (gdisp_powermode_t)value)
- return;
- switch((gdisp_powermode_t)value) {
- case powerOff:
- /* Code here */
- /* break; */
- case powerOn:
- /* Code here */
- /* You may need this ---
- if (GDISP.Powermode != powerSleep)
- gdisp_lld_init();
- */
- /* break; */
- case powerSleep:
- /* Code here */
- /* break; */
- default:
- return;
- }
- GDISP.Powermode = (gdisp_powermode_t)value;
- return;
- case GDISP_CONTROL_ORIENTATION:
- if (GDISP.Orientation == (gdisp_orientation_t)value)
- return;
- switch((gdisp_orientation_t)value) {
- case GDISP_ROTATE_0:
- acquire_bus();
- write_reg(0x0001,0x0127);
- write_reg(0x03, 0b0011);
- release_bus();
-
- GDISP.Height = GDISP_SCREEN_HEIGHT;
- GDISP.Width = GDISP_SCREEN_WIDTH;
- break;
- case GDISP_ROTATE_90:
- acquire_bus();
- write_reg(0x0001,0x0027);
- write_reg(0x0003, 0b1011);
- release_bus();
-
- GDISP.Height = GDISP_SCREEN_WIDTH;
- GDISP.Width = GDISP_SCREEN_HEIGHT;
- break;
- case GDISP_ROTATE_180:
- acquire_bus();
- write_reg(0x0001,0x0127);
- write_reg(0x0003, 0b0000);
- release_bus();
-
- GDISP.Height = GDISP_SCREEN_HEIGHT;
- GDISP.Width = GDISP_SCREEN_WIDTH;
- break;
- case GDISP_ROTATE_270:
- acquire_bus();
- write_reg(0x0001,0x0027);
- write_reg(0x0003, 0b1000);
- release_bus();
-
- GDISP.Height = GDISP_SCREEN_WIDTH;
- GDISP.Width = GDISP_SCREEN_HEIGHT;
- break;
- default:
- return;
- }
- #if GDISP_NEED_CLIP || GDISP_NEED_VALIDATION
- GDISP.clipx0 = 0;
- GDISP.clipy0 = 0;
- GDISP.clipx1 = GDISP.Width;
- GDISP.clipy1 = GDISP.Height;
- #endif
- GDISP.Orientation = (gdisp_orientation_t)value;
- return;
-/*
- case GDISP_CONTROL_BACKLIGHT:
- case GDISP_CONTROL_CONTRAST:
-*/
- }
- }
-#endif
-
-#endif /* GFX_USE_GDISP */
-/** @} */
-
diff --git a/drivers/gdisp/S6D1121/gdisp_lld.mk b/drivers/gdisp/S6D1121/gdisp_lld.mk
index 07f9c380..583feb41 100644
--- a/drivers/gdisp/S6D1121/gdisp_lld.mk
+++ b/drivers/gdisp/S6D1121/gdisp_lld.mk
@@ -1,5 +1,2 @@
-# List the required driver.
-GFXSRC += $(GFXLIB)/drivers/gdisp/S6D1121/gdisp_lld.c
-
-# Required include directories
GFXINC += $(GFXLIB)/drivers/gdisp/S6D1121
+GFXSRC += $(GFXLIB)/drivers/gdisp/S6D1121/gdisp_lld_S6D1121.c
diff --git a/drivers/gdisp/S6D1121/gdisp_lld_S6D1121.c b/drivers/gdisp/S6D1121/gdisp_lld_S6D1121.c
new file mode 100644
index 00000000..cca9d67e
--- /dev/null
+++ b/drivers/gdisp/S6D1121/gdisp_lld_S6D1121.c
@@ -0,0 +1,338 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/S6D1121/gdisp_lld.c
+ * @brief GDISP Graphics Driver subsystem low level driver source for the S6d1121 display.
+ *
+ * @addtogroup GDISP
+ * @{
+ */
+
+#include "gfx.h"
+
+#if GFX_USE_GDISP
+
+#if defined(GDISP_SCREEN_HEIGHT)
+ #warning "GDISP: This low level driver does not support setting a screen size. It is being ignored."
+ #undef GISP_SCREEN_HEIGHT
+#endif
+#if defined(GDISP_SCREEN_WIDTH)
+ #warning "GDISP: This low level driver does not support setting a screen size. It is being ignored."
+ #undef GDISP_SCREEN_WIDTH
+#endif
+
+#define GDISP_DRIVER_VMT GDISPVMT_S6D1121
+#include "../drivers/gdisp/S6D1121/gdisp_lld_config.h"
+#include "gdisp/lld/gdisp_lld.h"
+
+#include "board_S6D1121.h"
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+#ifndef GDISP_SCREEN_HEIGHT
+ #define GDISP_SCREEN_HEIGHT 320
+#endif
+#ifndef GDISP_SCREEN_WIDTH
+ #define GDISP_SCREEN_WIDTH 240
+#endif
+#ifndef GDISP_INITIAL_CONTRAST
+ #define GDISP_INITIAL_CONTRAST 50
+#endif
+#ifndef GDISP_INITIAL_BACKLIGHT
+ #define GDISP_INITIAL_BACKLIGHT 100
+#endif
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+/* Some common routines and macros */
+#define dummy_read(g) { volatile uint16_t dummy; dummy = read_data(g); (void) dummy; }
+#define write_reg(g, reg, data) { write_index(g, reg); write_data(g, data); }
+#define delay(us) gfxSleepMicroseconds(us)
+#define delayms(ms) gfxSleepMilliseconds(ms)
+
+static inline void set_cursor(GDisplay *g) {
+ /* R20h - 8 bit
+ * R21h - 9 bit
+ */
+ switch(g->g.Orientation) {
+ case GDISP_ROTATE_0:
+ write_reg(g, 0x20, g->p.x & 0x00FF);
+ write_reg(g, 0x21, g->p.y & 0x01FF);
+ break;
+ case GDISP_ROTATE_90:
+ write_reg(g, 0x20, g->p.y & 0x00FF);
+ write_reg(g, 0x21, (GDISP_SCREEN_HEIGHT - 1 - g->p.x) & 0x01FF);
+ break;
+ case GDISP_ROTATE_180:
+ write_reg(g, 0x20, (GDISP_SCREEN_WIDTH - 1 - g->p.x) & 0x00FF);
+ write_reg(g, 0x21, (GDISP_SCREEN_HEIGHT - 1 - g->p.y) & 0x01FF);
+ break;
+ case GDISP_ROTATE_270:
+ write_reg(g, 0x20, (GDISP_SCREEN_WIDTH - 1 - g->p.y) & 0x00FF);
+ write_reg(g, 0x21, g->p.x & 0x01FF);
+ break;
+ }
+ write_index(g, 0x22);
+}
+
+static inline void set_viewport(GDisplay *g) {
+ /* HSA / HEA are 8 bit
+ * VSA / VEA are 9 bit
+ * use masks 0x00FF and 0x01FF to enforce this
+ */
+
+ switch(g->g.Orientation) {
+ case GDISP_ROTATE_0:
+ write_reg(g, 0x46, (((g->p.x + g->p.cx - 1) << 8) & 0xFF00 ) | (g->p.x & 0x00FF));
+ write_reg(g, 0x48, g->p.y & 0x01FF);
+ write_reg(g, 0x47, (g->p.y + g->p.cy - 1) & 0x01FF);
+ break;
+ case GDISP_ROTATE_90:
+ write_reg(g, 0x46, (((g->p.y + g->p.cy - 1) << 8) & 0xFF00) | (g->p.y & 0x00FF));
+ write_reg(g, 0x48, (GDISP_SCREEN_HEIGHT - (g->p.x + g->p.cx)) & 0x01FF);
+ write_reg(g, 0x47, (GDISP_SCREEN_HEIGHT-1 - g->p.x) & 0x01FF);
+ break;
+ case GDISP_ROTATE_180:
+ write_reg(g, 0x46, (((GDISP_SCREEN_WIDTH-1 - g->p.x) & 0x00FF) << 8) |
+ ((GDISP_SCREEN_WIDTH - (g->p.x + g->p.cx)) & 0x00FF));
+ write_reg(g, 0x48, (GDISP_SCREEN_HEIGHT - (g->p.y + g->p.cy)) & 0x01FF);
+ write_reg(g, 0x47, (GDISP_SCREEN_HEIGHT-1 - g->p.y) & 0x01FF);
+ break;
+ case GDISP_ROTATE_270:
+ write_reg(g, 0x46, (((GDISP_SCREEN_WIDTH-1 - g->p.y) & 0x00FF) << 8) |
+ ((GDISP_SCREEN_WIDTH - (g->p.y + g->p.cy)) & 0x00FF));
+ write_reg(g, 0x48, g->p.x & 0x01FF);
+ write_reg(g, 0x47, (g->p.x + g->p.cx - 1) & 0x01FF);
+ break;
+ }
+}
+
+LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
+ // No private area for this controller
+ g->priv = 0;
+
+ // Initialise the board interface
+ init_board(g);
+
+ /* Hardware reset */
+ setpin_reset(g, TRUE);
+ delayms(20);
+ setpin_reset(g, TRUE);
+ delayms(20);
+
+ /* Get the bus for the following initialisation commands */
+ acquire_bus(g);
+
+ write_reg(g, 0x11, 0x2004);
+ write_reg(g, 0x13, 0xCC00);
+ write_reg(g, 0x15, 0x2600);
+ write_reg(g, 0x14, 0x252A);
+ write_reg(g, 0x12, 0x0033);
+ write_reg(g, 0x13, 0xCC04);
+
+ delayms(1);
+
+ write_reg(g, 0x13, 0xCC06);
+
+ delayms(1);
+
+ write_reg(g, 0x13, 0xCC4F);
+
+ delayms(1);
+
+ write_reg(g, 0x13, 0x674F);
+ write_reg(g, 0x11, 0x2003);
+
+ delayms(1);
+
+ // Gamma Setting
+ write_reg(g, 0x30, 0x2609);
+ write_reg(g, 0x31, 0x242C);
+ write_reg(g, 0x32, 0x1F23);
+ write_reg(g, 0x33, 0x2425);
+ write_reg(g, 0x34, 0x2226);
+ write_reg(g, 0x35, 0x2523);
+ write_reg(g, 0x36, 0x1C1A);
+ write_reg(g, 0x37, 0x131D);
+ write_reg(g, 0x38, 0x0B11);
+ write_reg(g, 0x39, 0x1210);
+ write_reg(g, 0x3A, 0x1315);
+ write_reg(g, 0x3B, 0x3619);
+ write_reg(g, 0x3C, 0x0D00);
+ write_reg(g, 0x3D, 0x000D);
+
+ write_reg(g, 0x16, 0x0007);
+ write_reg(g, 0x02, 0x0013);
+ write_reg(g, 0x03, 0x0003);
+ write_reg(g, 0x01, 0x0127);
+
+ delayms(1);
+
+ write_reg(g, 0x08, 0x0303);
+ write_reg(g, 0x0A, 0x000B);
+ write_reg(g, 0x0B, 0x0003);
+ write_reg(g, 0x0C, 0x0000);
+ write_reg(g, 0x41, 0x0000);
+ write_reg(g, 0x50, 0x0000);
+ write_reg(g, 0x60, 0x0005);
+ write_reg(g, 0x70, 0x000B);
+ write_reg(g, 0x71, 0x0000);
+ write_reg(g, 0x78, 0x0000);
+ write_reg(g, 0x7A, 0x0000);
+ write_reg(g, 0x79, 0x0007);
+ write_reg(g, 0x07, 0x0051);
+
+ delayms(1);
+
+ write_reg(g, 0x07,0x0053);
+ write_reg(g, 0x79,0x0000);
+
+ // Finish Init
+ post_init_board(g);
+
+ // Release the bus
+ release_bus(g);
+
+ /* Turn on the back-light */
+ set_backlight(g, GDISP_INITIAL_BACKLIGHT);
+
+ /* Initialise the GDISP structure */
+ g->g.Width = GDISP_SCREEN_WIDTH;
+ g->g.Height = GDISP_SCREEN_HEIGHT;
+ g->g.Orientation = GDISP_ROTATE_0;
+ g->g.Powermode = powerOn;
+ g->g.Backlight = GDISP_INITIAL_BACKLIGHT;
+ g->g.Contrast = GDISP_INITIAL_CONTRAST;
+ return TRUE;
+}
+
+#if GDISP_HARDWARE_STREAM_WRITE
+ LLDSPEC void gdisp_lld_write_start(GDisplay *g) {
+ acquire_bus(g);
+ set_viewport(g);
+ }
+ LLDSPEC void gdisp_lld_write_color(GDisplay *g) {
+ write_data(g, COLOR2NATIVE(g->p.color));
+ }
+ LLDSPEC void gdisp_lld_write_stop(GDisplay *g) {
+ release_bus(g);
+ }
+ LLDSPEC void gdisp_lld_write_pos(GDisplay *g) {
+ set_cursor(g);
+ }
+#endif
+
+#if GDISP_HARDWARE_STREAM_READ
+ LLDSPEC void gdisp_lld_read_start(GDisplay *g) {
+ acquire_bus(g);
+ set_viewport(g);
+ set_cursor(g);
+ setreadmode(g);
+ dummy_read(g);
+ }
+ LLDSPEC color_t gdisp_lld_read_color(GDisplay *g) {
+ uint16_t data;
+
+ data = read_data(g);
+ return NATIVE2COLOR(data);
+ }
+ LLDSPEC void gdisp_lld_read_stop(GDisplay *g) {
+ setwritemode(g);
+ release_bus(g);
+ }
+#endif
+
+#if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL
+ LLDSPEC void gdisp_lld_control(GDisplay *g) {
+ switch(g->p.x) {
+ #if 0
+ case GDISP_CONTROL_POWER:
+ if (g->g.Powermode == (powermode_t)g->p.ptr)
+ return;
+ switch((powermode_t)g->p.ptr) {
+ case powerOff:
+ acquire_bus(g);
+ // TODO
+ release_bus(g);
+ break;
+ case powerOn:
+ acquire_bus(g);
+ // TODO
+ release_bus(g);
+ break;
+ case powerSleep:
+ acquire_bus(g);
+ // TODO
+ release_bus(g);
+ break;
+ default:
+ return;
+ }
+ g->g.Powermode = (powermode_t)g->p.ptr;
+ return;
+ #endif
+
+ case GDISP_CONTROL_ORIENTATION:
+ if (g->g.Orientation == (orientation_t)g->p.ptr)
+ return;
+ switch((orientation_t)g->p.ptr) {
+ case GDISP_ROTATE_0:
+ acquire_bus(g);
+ write_reg(g, 0x03, 0b0011);
+ release_bus(g);
+ g->g.Height = GDISP_SCREEN_HEIGHT;
+ g->g.Width = GDISP_SCREEN_WIDTH;
+ break;
+ case GDISP_ROTATE_90:
+ acquire_bus(g);
+ write_reg(g, 0x03, 0b1001);
+ release_bus(g);
+ g->g.Height = GDISP_SCREEN_WIDTH;
+ g->g.Width = GDISP_SCREEN_HEIGHT;
+ break;
+ case GDISP_ROTATE_180:
+ acquire_bus(g);
+ write_reg(g, 0x03, 0b0000);
+ release_bus(g);
+ g->g.Height = GDISP_SCREEN_HEIGHT;
+ g->g.Width = GDISP_SCREEN_WIDTH;
+ break;
+ case GDISP_ROTATE_270:
+ acquire_bus(g);
+ write_reg(g, 0x03, 0b1010);
+ release_bus(g);
+ g->g.Height = GDISP_SCREEN_WIDTH;
+ g->g.Width = GDISP_SCREEN_HEIGHT;
+ break;
+ default:
+ return;
+ }
+ g->g.Orientation = (orientation_t)g->p.ptr;
+ return;
+
+ case GDISP_CONTROL_BACKLIGHT:
+ if ((unsigned)g->p.ptr > 100)
+ g->p.ptr = (void *)100;
+ set_backlight(g, (unsigned)g->p.ptr);
+ g->g.Backlight = (unsigned)g->p.ptr;
+ return;
+
+ //case GDISP_CONTROL_CONTRAST:
+ default:
+ return;
+ }
+ }
+#endif
+
+#endif /* GFX_USE_GDISP */
+/** @} */
+
diff --git a/drivers/gdisp/S6D1121/gdisp_lld_board_olimex_e407.h b/drivers/gdisp/S6D1121/gdisp_lld_board_olimex_e407.h
deleted file mode 100644
index 0ce843b4..00000000
--- a/drivers/gdisp/S6D1121/gdisp_lld_board_olimex_e407.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * This file is subject to the terms of the GFX License. If a copy of
- * the license was not distributed with this file, you can obtain one at:
- *
- * http://ugfx.org/license.html
- */
-
-/**
- * @file drivers/gdisp/S6D1121/gdisp_lld_board_olimex_e407.h
- * @brief GDISP Graphic Driver subsystem board interface for the S6D1121 display
- *
- * @addtogroup GDISP
- * @{
- */
-
-#ifndef _GDISP_LLD_BOARD_H
-#define _GDISP_LLD_BOARD_H
-
-#define GDISP_REG (*((volatile uint16_t *) 0x60000000)) /* RS = 0 */
-#define GDISP_RAM (*((volatile uint16_t *) 0x60020000)) /* RS = 1 */
-
-static inline void init_board(void) {
- int FSMC_Bank = 0;
-
- /* STM32F4 FSMC init */
- rccEnableAHB3(RCC_AHB3ENR_FSMCEN, 0);
-
- /* set pins to FSMC mode */
- IOBus busD = {GPIOD, (1 << 0) | (1 << 1) | (1 << 4) | (1 << 5) | (1 << 7) | (1 << 8) |
- (1 << 9) | (1 << 10) | (1 << 11) | (1 << 14) | (1 << 15), 0};
-
- IOBus busE = {GPIOE, (1 << 7) | (1 << 8) | (1 << 9) | (1 << 10) | (1 << 11) | (1 << 12) |
- (1 << 13) | (1 << 14) | (1 << 15), 0};
-
- palSetBusMode(&busD, PAL_MODE_ALTERNATE(12));
- palSetBusMode(&busE, PAL_MODE_ALTERNATE(12));
-
- /* FSMC timing */
- FSMC_Bank1->BTCR[FSMC_Bank+1] = (6) | (10 << 8) | (10 << 16);
-
- /* Bank1 NOR/SRAM control register configuration */
- FSMC_Bank1->BTCR[FSMC_Bank] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN;
-}
-
-static inline void setpin_reset(bool_t state) {
- (void)state;
-
- /* Nothing to do here */
-}
-
-static inline void set_backlight(uint8_t percent) {
- (void)percent;
-
- /* Nothing to do here */
-}
-
-static inline void acquire_bus(void) {
- /* Nothing to do here */
-}
-
-static inline void release_bus(void) {
- /* Nothing to do here */
-}
-
-static inline void write_index(uint16_t index) {
- GDISP_REG = index;
-}
-
-static inline void write_data(uint16_t data) {
- GDISP_RAM = data;
-}
-
-#if GDISP_HARDWARE_READPIXEL || GDISP_HARDWARE_SCROLL || defined(__DOXYGEN__)
-static inline uint16_t read_data(void) {
- return GDISP_RAM;
-}
-#endif
-
-#endif /* _GDISP_LLD_BOARD_H */
-/** @} */
-
diff --git a/drivers/gdisp/S6D1121/gdisp_lld_board_template.h b/drivers/gdisp/S6D1121/gdisp_lld_board_template.h
deleted file mode 100644
index f123bd06..00000000
--- a/drivers/gdisp/S6D1121/gdisp_lld_board_template.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * This file is subject to the terms of the GFX License. If a copy of
- * the license was not distributed with this file, you can obtain one at:
- *
- * http://ugfx.org/license.html
- */
-
-/**
- * @file drivers/gdisp/S6D1121/gdisp_lld_board_template.h
- * @brief GDISP Graphic Driver subsystem board interface for the S6D1121 display.
- *
- * @addtogroup GDISP
- * @{
- */
-
-#ifndef _GDISP_LLD_BOARD_H
-#define _GDISP_LLD_BOARD_H
-
-/**
- * @brief Initialise the board for the display.
- *
- * @notapi
- */
-static inline void init_board(void) {
-
-}
-
-/**
- * @brief Set or clear the lcd reset pin.
- *
- * @param[in] state TRUE = lcd in reset, FALSE = normal operation
- *
- * @notapi
- */
-static inline void setpin_reset(bool_t state) {
-
-}
-
-/**
- * @brief Set the lcd back-light level.
- *
- * @param[in] percent 0 to 100%
- *
- * @notapi
- */
-static inline void set_backlight(uint8_t percent) {
-
-}
-
-/**
- * @brief Take exclusive control of the bus
- *
- * @notapi
- */
-static inline void acquire_bus(void) {
-
-}
-
-/**
- * @brief Release exclusive control of the bus
- *
- * @notapi
- */
-static inline void release_bus(void) {
-
-}
-
-/**
- * @brief Send data to the index register.
- *
- * @param[in] index The index register to set
- *
- * @notapi
- */
-static inline void write_index(uint16_t index) {
-
-}
-
-/**
- * @brief Send data to the lcd.
- *
- * @param[in] data The data to send
- *
- * @notapi
- */
-static inline void write_data(uint16_t data) {
-
-}
-
-#if GDISP_HARDWARE_READPIXEL || GDISP_HARDWARE_SCROLL || defined(__DOXYGEN__)
-/**
- * @brief Read data from the lcd.
- *
- * @return The data from the lcd
- * @note The chip select may need to be asserted/de-asserted
- * around the actual spi read
- *
- * @notapi
- */
-static inline uint16_t read_data(void) {
-
-}
-#endif
-
-#endif /* _GDISP_LLD_BOARD_H */
-/** @} */
diff --git a/drivers/gdisp/S6D1121/gdisp_lld_config.h b/drivers/gdisp/S6D1121/gdisp_lld_config.h
index bace096c..79e859bc 100644
--- a/drivers/gdisp/S6D1121/gdisp_lld_config.h
+++ b/drivers/gdisp/S6D1121/gdisp_lld_config.h
@@ -22,16 +22,12 @@
/* Driver hardware support. */
/*===========================================================================*/
-#define GDISP_DRIVER_NAME "S6D1121"
-
-#define GDISP_HARDWARE_CLEARS TRUE
-#define GDISP_HARDWARE_FILLS TRUE
-#define GDISP_HARDWARE_BITFILLS TRUE
-#define GDISP_HARDWARE_SCROLL TRUE
-#define GDISP_HARDWARE_PIXELREAD FALSE
+#define GDISP_HARDWARE_STREAM_WRITE TRUE
+#define GDISP_HARDWARE_STREAM_READ TRUE
+#define GDISP_HARDWARE_STREAM_POS TRUE
#define GDISP_HARDWARE_CONTROL TRUE
-#define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_RGB565
+#define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_RGB565
#endif /* GFX_USE_GDISP */
diff --git a/drivers/gdisp/SSD1289/board_SSD1289_template.h b/drivers/gdisp/SSD1289/board_SSD1289_template.h
new file mode 100644
index 00000000..7c9cd757
--- /dev/null
+++ b/drivers/gdisp/SSD1289/board_SSD1289_template.h
@@ -0,0 +1,191 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/SSD1289/board_SSD1289_template.h
+ * @brief GDISP Graphic Driver subsystem board interface for the SSD1289 display.
+ *
+ * @addtogroup GDISP
+ * @{
+ */
+
+#ifndef _GDISP_LLD_BOARD_H
+#define _GDISP_LLD_BOARD_H
+
+/**
+ * @brief Initialise the board for the display.
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @note Set the g->board member to whatever is appropriate. For multiple
+ * displays this might be a pointer to the appropriate register set.
+ *
+ * @notapi
+ */
+static inline void init_board(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief After the initialisation.
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void post_init_board(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Set or clear the lcd reset pin.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] state TRUE = lcd in reset, FALSE = normal operation
+ *
+ * @notapi
+ */
+static inline void setpin_reset(GDisplay *g, bool_t state) {
+ (void) g;
+ (void) state;
+}
+
+/**
+ * @brief Set the lcd back-light level.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] percent 0 to 100%
+ *
+ * @notapi
+ */
+static inline void set_backlight(GDisplay *g, uint8_t percent) {
+ (void) g;
+ (void) percent;
+}
+
+/**
+ * @brief Take exclusive control of the bus
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void acquire_bus(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Release exclusive control of the bus
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void release_bus(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Send data to the index register.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] index The index register to set
+ *
+ * @notapi
+ */
+static inline void write_index(GDisplay *g, uint16_t index) {
+ (void) g;
+ (void) index;
+}
+
+/**
+ * @brief Send data to the lcd.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] data The data to send
+ *
+ * @notapi
+ */
+static inline void write_data(GDisplay *g, uint16_t data) {
+ (void) g;
+ (void) data;
+}
+
+/**
+ * @brief Set the bus in read mode
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void setreadmode(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Set the bus back into write mode
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void setwritemode(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Read data from the lcd.
+ * @return The data from the lcd
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline uint16_t read_data(GDisplay *g) {
+ (void) g;
+ return 0;
+}
+
+/**
+ * The below section you can replace with #error if your interface doesn't support DMA
+ */
+#if defined(GDISP_USE_DMA) || defined(__DOXYGEN__)
+ //#error "GDISP - SSD1289: This interface does not support DMA"
+
+ /**
+ * @brief Transfer data using DMA but don't increment the source address
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] buffer The source buffer location
+ * @param[in] area The number of pixels to transfer
+ *
+ * @notapi
+ */
+ static inline void dma_with_noinc(GDisplay *g, color_t *buffer, int area) {
+ (void) g;
+ (void) buffer;
+ (void) area;
+ }
+
+ /**
+ * @brief Transfer data using DMA incrementing the source address
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] buffer The source buffer location
+ * @param[in] area The number of pixels to transfer
+ *
+ * @notapi
+ */
+ static inline void dma_with_inc(GDisplay *g, color_t *buffer, int area) {
+ (void) g;
+ (void) buffer;
+ (void) area;
+ }
+#endif
+
+#endif /* _GDISP_LLD_BOARD_H */
+/** @} */
diff --git a/drivers/gdisp/SSD1289/gdisp_lld.mk b/drivers/gdisp/SSD1289/gdisp_lld.mk
index e340a7dc..fd2713bc 100644
--- a/drivers/gdisp/SSD1289/gdisp_lld.mk
+++ b/drivers/gdisp/SSD1289/gdisp_lld.mk
@@ -1,5 +1,2 @@
-# List the required driver.
-GFXSRC += $(GFXLIB)/drivers/gdisp/SSD1289/gdisp_lld.c
-
-# Required include directories
GFXINC += $(GFXLIB)/drivers/gdisp/SSD1289
+GFXSRC += $(GFXLIB)/drivers/gdisp/SSD1289/gdisp_lld_SSD1289.c
diff --git a/drivers/gdisp/SSD1289/gdisp_lld_SSD1289.c b/drivers/gdisp/SSD1289/gdisp_lld_SSD1289.c
new file mode 100644
index 00000000..a33b6564
--- /dev/null
+++ b/drivers/gdisp/SSD1289/gdisp_lld_SSD1289.c
@@ -0,0 +1,361 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/SSD1289/gdisp_lld.c
+ * @brief GDISP Graphics Driver subsystem low level driver source for the SSD1289 display.
+ */
+
+#include "gfx.h"
+
+#if GFX_USE_GDISP
+
+#define GDISP_DRIVER_VMT GDISPVMT_SSD1289
+#include "../drivers/gdisp/SSD1289/gdisp_lld_config.h"
+#include "gdisp/lld/gdisp_lld.h"
+
+#include "board_SSD1289.h"
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+#ifndef GDISP_SCREEN_HEIGHT
+ #define GDISP_SCREEN_HEIGHT 320
+#endif
+#ifndef GDISP_SCREEN_WIDTH
+ #define GDISP_SCREEN_WIDTH 240
+#endif
+#ifndef GDISP_INITIAL_CONTRAST
+ #define GDISP_INITIAL_CONTRAST 50
+#endif
+#ifndef GDISP_INITIAL_BACKLIGHT
+ #define GDISP_INITIAL_BACKLIGHT 100
+#endif
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+// Some common routines and macros
+#define dummy_read(g) { volatile uint16_t dummy; dummy = read_data(g); (void) dummy; }
+#define write_reg(g, reg, data) { write_index(g, reg); write_data(g, data); }
+
+static void set_cursor(GDisplay *g) {
+ /*
+ * Reg 0x004E is an 8 bit value - start x position
+ * Reg 0x004F is 9 bit - start y position
+ * Use a bit mask to make sure they are not set too high
+ */
+ switch(g->g.Orientation) {
+ case GDISP_ROTATE_0:
+ write_reg(g, 0x4e, g->p.x & 0x00FF);
+ write_reg(g, 0x4f, g->p.y & 0x01FF);
+ break;
+ case GDISP_ROTATE_90:
+ write_reg(g, 0x4e, g->p.y & 0x00FF);
+ write_reg(g, 0x4f, (GDISP_SCREEN_HEIGHT-1-g->p.x) & 0x01FF);
+ break;
+ case GDISP_ROTATE_180:
+ write_reg(g, 0x4e, (GDISP_SCREEN_WIDTH-1-g->p.x) & 0x00FF);
+ write_reg(g, 0x4f, (GDISP_SCREEN_HEIGHT-1-g->p.y) & 0x01FF);
+ break;
+ case GDISP_ROTATE_270:
+ write_reg(g, 0x4e, (GDISP_SCREEN_WIDTH-1-g->p.y) & 0x00FF);
+ write_reg(g, 0x4f, g->p.x & 0x01FF);
+ break;
+ }
+ write_index(g, 0x22);
+}
+
+static void set_viewport(GDisplay* g) {
+ /* Reg 0x44 - Horizontal RAM address position
+ * Upper Byte - HEA
+ * Lower Byte - HSA
+ * 0 <= HSA <= HEA <= 0xEF
+ * Reg 0x45,0x46 - Vertical RAM address position
+ * Lower 9 bits gives 0-511 range in each value
+ * 0 <= Reg(0x45) <= Reg(0x46) <= 0x13F
+ * Use a bit mask to make sure they are not set too high
+ */
+ switch(g->g.Orientation) {
+ case GDISP_ROTATE_0:
+ write_reg(g, 0x44, (((g->p.x+g->p.cx-1) << 8) & 0xFF00 ) | (g->p.x & 0x00FF));
+ write_reg(g, 0x45, g->p.y & 0x01FF);
+ write_reg(g, 0x46, (g->p.y+g->p.cy-1) & 0x01FF);
+ break;
+ case GDISP_ROTATE_90:
+ write_reg(g, 0x44, (((g->p.y+g->p.cy-1) << 8) & 0xFF00 ) | (g->p.y & 0x00FF));
+ write_reg(g, 0x45, (GDISP_SCREEN_HEIGHT-(g->p.x+g->p.cx)) & 0x01FF);
+ write_reg(g, 0x46, (GDISP_SCREEN_HEIGHT-1-g->p.x) & 0x01FF);
+ break;
+ case GDISP_ROTATE_180:
+ write_reg(g, 0x44, (((GDISP_SCREEN_WIDTH-1-g->p.x) & 0x00FF) << 8) | ((GDISP_SCREEN_WIDTH - (g->p.x+g->p.cx)) & 0x00FF));
+ write_reg(g, 0x45, (GDISP_SCREEN_HEIGHT-(g->p.y+g->p.cy)) & 0x01FF);
+ write_reg(g, 0x46, (GDISP_SCREEN_HEIGHT-1-g->p.y) & 0x01FF);
+ break;
+ case GDISP_ROTATE_270:
+ write_reg(g, 0x44, (((GDISP_SCREEN_WIDTH-1-g->p.y) & 0x00FF) << 8) | ((GDISP_SCREEN_WIDTH-(g->p.y+g->p.cy)) & 0x00FF));
+ write_reg(g, 0x45, g->p.x & 0x01FF);
+ write_reg(g, 0x46, (g->p.x+g->p.cx-1) & 0x01FF);
+ break;
+ }
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
+ // No private area for this controller
+ g->priv = 0;
+
+ // Initialise the board interface
+ init_board(g);
+
+ // Hardware reset
+ setpin_reset(g, TRUE);
+ gfxSleepMilliseconds(20);
+ setpin_reset(g, FALSE);
+ gfxSleepMilliseconds(20);
+
+ // Get the bus for the following initialisation commands
+ acquire_bus(g);
+
+ write_reg(g, 0x00, 0x0001); gfxSleepMicroseconds(5);
+ write_reg(g, 0x03, 0xA8A4); gfxSleepMicroseconds(5);
+ write_reg(g, 0x0C, 0x0000); gfxSleepMicroseconds(5);
+ write_reg(g, 0x0D, 0x080C); gfxSleepMicroseconds(5);
+ write_reg(g, 0x0E, 0x2B00); gfxSleepMicroseconds(5);
+ write_reg(g, 0x1E, 0x00B0); gfxSleepMicroseconds(5);
+ write_reg(g, 0x01, 0x2B3F); gfxSleepMicroseconds(5);
+ write_reg(g, 0x02, 0x0600); gfxSleepMicroseconds(5);
+ write_reg(g, 0x10, 0x0000); gfxSleepMicroseconds(5);
+ write_reg(g, 0x11, 0x6070); gfxSleepMicroseconds(5);
+ write_reg(g, 0x05, 0x0000); gfxSleepMicroseconds(5);
+ write_reg(g, 0x06, 0x0000); gfxSleepMicroseconds(5);
+ write_reg(g, 0x16, 0xEF1C); gfxSleepMicroseconds(5);
+ write_reg(g, 0x17, 0x0003); gfxSleepMicroseconds(5);
+ write_reg(g, 0x07, 0x0133); gfxSleepMicroseconds(5);
+ write_reg(g, 0x0B, 0x0000); gfxSleepMicroseconds(5);
+ write_reg(g, 0x0F, 0x0000); gfxSleepMicroseconds(5);
+ write_reg(g, 0x41, 0x0000); gfxSleepMicroseconds(5);
+ write_reg(g, 0x42, 0x0000); gfxSleepMicroseconds(5);
+ write_reg(g, 0x48, 0x0000); gfxSleepMicroseconds(5);
+ write_reg(g, 0x49, 0x013F); gfxSleepMicroseconds(5);
+ write_reg(g, 0x4A, 0x0000); gfxSleepMicroseconds(5);
+ write_reg(g, 0x4B, 0x0000); gfxSleepMicroseconds(5);
+ write_reg(g, 0x44, 0xEF00); gfxSleepMicroseconds(5);
+ write_reg(g, 0x45, 0x0000); gfxSleepMicroseconds(5);
+ write_reg(g, 0x46, 0x013F); gfxSleepMicroseconds(5);
+ write_reg(g, 0x30, 0x0707); gfxSleepMicroseconds(5);
+ write_reg(g, 0x31, 0x0204); gfxSleepMicroseconds(5);
+ write_reg(g, 0x32, 0x0204); gfxSleepMicroseconds(5);
+ write_reg(g, 0x33, 0x0502); gfxSleepMicroseconds(5);
+ write_reg(g, 0x34, 0x0507); gfxSleepMicroseconds(5);
+ write_reg(g, 0x35, 0x0204); gfxSleepMicroseconds(5);
+ write_reg(g, 0x36, 0x0204); gfxSleepMicroseconds(5);
+ write_reg(g, 0x37, 0x0502); gfxSleepMicroseconds(5);
+ write_reg(g, 0x3A, 0x0302); gfxSleepMicroseconds(5);
+ write_reg(g, 0x3B, 0x0302); gfxSleepMicroseconds(5);
+ write_reg(g, 0x23, 0x0000); gfxSleepMicroseconds(5);
+ write_reg(g, 0x24, 0x0000); gfxSleepMicroseconds(5);
+ write_reg(g, 0x25, 0x8000); gfxSleepMicroseconds(5);
+ write_reg(g, 0x4f, 0x0000); gfxSleepMicroseconds(5);
+ write_reg(g, 0x4e, 0x0000); gfxSleepMicroseconds(5);
+
+ // Finish Init
+ post_init_board(g);
+
+ // Release the bus
+ release_bus(g);
+
+ /* Turn on the back-light */
+ set_backlight(g, GDISP_INITIAL_BACKLIGHT);
+
+ /* Initialise the GDISP structure */
+ g->g.Width = GDISP_SCREEN_WIDTH;
+ g->g.Height = GDISP_SCREEN_HEIGHT;
+ g->g.Orientation = GDISP_ROTATE_0;
+ g->g.Powermode = powerOn;
+ g->g.Backlight = GDISP_INITIAL_BACKLIGHT;
+ g->g.Contrast = GDISP_INITIAL_CONTRAST;
+ return TRUE;
+}
+
+#if GDISP_HARDWARE_STREAM_WRITE
+ LLDSPEC void gdisp_lld_write_start(GDisplay *g) {
+ acquire_bus(g);
+ set_viewport(g);
+ #if !GDISP_HARDWARE_STREAM_POS
+ set_cursor(g);
+ #endif
+ }
+ LLDSPEC void gdisp_lld_write_color(GDisplay *g) {
+ write_data(g, COLOR2NATIVE(g->p.color));
+ }
+ LLDSPEC void gdisp_lld_write_stop(GDisplay *g) {
+ release_bus(g);
+ }
+ #if GDISP_HARDWARE_STREAM_POS
+ LLDSPEC void gdisp_lld_write_pos(GDisplay *g) {
+ set_cursor(g);
+ }
+ #endif
+#endif
+
+#if GDISP_HARDWARE_STREAM_READ
+ LLDSPEC void gdisp_lld_read_start(GDisplay *g) {
+ acquire_bus(g);
+ set_viewport(g);
+ set_cursor(g);
+ setreadmode(g);
+ dummy_read(g);
+ }
+ LLDSPEC color_t gdisp_lld_read_color(GDisplay *g) {
+ uint16_t data;
+
+ data = read_data(g);
+ return NATIVE2COLOR(data);
+ }
+ LLDSPEC void gdisp_lld_read_stop(GDisplay *g) {
+ setwritemode(g);
+ release_bus(g);
+ }
+#endif
+
+#if GDISP_HARDWARE_FILLS && defined(GDISP_USE_DMA)
+ LLDSPEC void gdisp_lld_fill_area(GDisplay *g) {
+ uint16_t c;
+
+ c = COLOR2NATIVE(g->p.color);
+ acquire_bus(g);
+ set_viewport(g);
+ set_cursor(g);
+ dma_with_noinc(g, &c, g->p.cx*g->p.cy)
+ release_bus(g);
+ }
+#endif
+
+#if GDISP_HARDWARE_BITFILLS && defined(GDISP_USE_DMA)
+ #if GDISP_PIXELFORMAT != GDISP_LLD_PIXELFORMAT
+ #error "GDISP: SSD1289: BitBlit is only available in RGB565 pixel format"
+ #endif
+
+ LLDSPEC void gdisp_lld_blit_area(GDisplay *g) {
+ pixel_t *buffer;
+ coord_t ycnt;
+
+ buffer = (pixel_t *)g->p.ptr + g->p.x1 + g->p.y1 * g->p.x2;
+
+ acquire_bus(g);
+ set_viewport(g);
+ set_cursor(g);
+ if (g->p.x2 == g->p.cx) {
+ dma_with_inc(g, buffer, g->p.cx*g->p.cy);
+ } else {
+ for (ycnt = g->p.cy; ycnt; ycnt--, buffer += g->p.x2)
+ dma_with_inc(g, buffer, g->p.cy);
+ }
+ release_bus(g);
+ }
+#endif
+
+#if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL
+ LLDSPEC void gdisp_lld_control(GDisplay *g) {
+ switch(g->p.x) {
+ case GDISP_CONTROL_POWER:
+ if (g->g.Powermode == (powermode_t)g->p.ptr)
+ return;
+ switch((powermode_t)g->p.ptr) {
+ case powerOff:
+ acquire_bus(g);
+ write_reg(g, 0x10, 0x0000); // leave sleep mode
+ write_reg(g, 0x07, 0x0000); // halt operation
+ write_reg(g, 0x00, 0x0000); // turn off oscillator
+ write_reg(g, 0x10, 0x0001); // enter sleep mode
+ release_bus(g);
+ break;
+ case powerOn:
+ acquire_bus(g);
+ write_reg(g, 0x10, 0x0000); // leave sleep mode
+ write_reg(g, 0x00, 0x0001); // turn on oscillator
+ gfxSleepMicroseconds(5);
+ release_bus(g);
+ break;
+ case powerSleep:
+ acquire_bus(g);
+ write_reg(g, 0x10, 0x0001); // enter sleep mode
+ release_bus(g);
+ break;
+ default:
+ return;
+ }
+ g->g.Powermode = (powermode_t)g->p.ptr;
+ return;
+
+ case GDISP_CONTROL_ORIENTATION:
+ if (g->g.Orientation == (orientation_t)g->p.ptr)
+ return;
+ switch((orientation_t)g->p.ptr) {
+ case GDISP_ROTATE_0:
+ acquire_bus(g);
+ /* ID = 11 AM = 0 */
+ write_reg(g, 0x11, 0x6070);
+ release_bus(g);
+ g->g.Height = GDISP_SCREEN_HEIGHT;
+ g->g.Width = GDISP_SCREEN_WIDTH;
+ break;
+ case GDISP_ROTATE_90:
+ acquire_bus(g);
+ /* ID = 01 AM = 1 */
+ write_reg(g, 0x11, 0x6058);
+ release_bus(g);
+ g->g.Height = GDISP_SCREEN_WIDTH;
+ g->g.Width = GDISP_SCREEN_HEIGHT;
+ break;
+ case GDISP_ROTATE_180:
+ acquire_bus(g);
+ /* ID = 00 AM = 0 */
+ write_reg(g, 0x11, 0x6040);
+ release_bus(g);
+ g->g.Height = GDISP_SCREEN_HEIGHT;
+ g->g.Width = GDISP_SCREEN_WIDTH;
+ break;
+ case GDISP_ROTATE_270:
+ acquire_bus(g);
+ /* ID = 10 AM = 1 */
+ write_reg(g, 0x11, 0x6068);
+ release_bus(g);
+ g->g.Height = GDISP_SCREEN_WIDTH;
+ g->g.Width = GDISP_SCREEN_HEIGHT;
+ break;
+ default:
+ return;
+ }
+ g->g.Orientation = (orientation_t)g->p.ptr;
+ return;
+
+ case GDISP_CONTROL_BACKLIGHT:
+ if ((unsigned)g->p.ptr > 100)
+ g->p.ptr = (void *)100;
+ set_backlight(g, (unsigned)g->p.ptr);
+ g->g.Backlight = (unsigned)g->p.ptr;
+ return;
+
+ //case GDISP_CONTROL_CONTRAST:
+ default:
+ return;
+ }
+ }
+#endif
+
+#endif /* GFX_USE_GDISP */
diff --git a/drivers/gdisp/SSD1289/gdisp_lld_board_firebullstm32f103.h b/drivers/gdisp/SSD1289/gdisp_lld_board_firebullstm32f103.h
deleted file mode 100644
index 38d9e04d..00000000
--- a/drivers/gdisp/SSD1289/gdisp_lld_board_firebullstm32f103.h
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * This file is subject to the terms of the GFX License. If a copy of
- * the license was not distributed with this file, you can obtain one at:
- *
- * http://ugfx.org/license.html
- */
-
-/**
- * @file drivers/gdisp/SSD1289/gdisp_lld_board_firebullstm32f103.h
- * @brief GDISP Graphic Driver subsystem board interface for the SSD1289 display.
- *
- * @addtogroup GDISP
- * @{
- */
-
-#ifndef _GDISP_LLD_BOARD_H
-#define _GDISP_LLD_BOARD_H
-
-#define SET_CS palSetPad(GPIOD, 12);
-#define CLR_CS palClearPad(GPIOD, 12);
-#define SET_RS palSetPad(GPIOD, 13);
-#define CLR_RS palClearPad(GPIOD, 13);
-#define SET_WR palSetPad(GPIOD, 14);
-#define CLR_WR palClearPad(GPIOD, 14);
-#define SET_RD palSetPad(GPIOD, 15);
-#define CLR_RD palClearPad(GPIOD, 15);
-
-/**
- * @brief Initialise the board for the display.
- * @notes This board definition uses GPIO and assumes exclusive access to these GPIO pins
- *
- * @notapi
- */
-static inline void init_board(void) {
- palSetGroupMode(GPIOE, PAL_WHOLE_PORT, 0, PAL_MODE_OUTPUT_PUSHPULL);
- palSetPadMode(GPIOD, 12, PAL_MODE_OUTPUT_PUSHPULL);
- palSetPadMode(GPIOD, 13, PAL_MODE_OUTPUT_PUSHPULL);
- palSetPadMode(GPIOD, 14, PAL_MODE_OUTPUT_PUSHPULL);
- palSetPadMode(GPIOD, 15, PAL_MODE_OUTPUT_PUSHPULL);
-
- // Configure the pins to a well know state
- SET_RS;
- SET_RD;
- SET_WR;
- CLR_CS;
-}
-
-
-/**
- * @brief Set or clear the lcd reset pin.
- *
- * @param[in] state TRUE = lcd in reset, FALSE = normal operation
- *
- * @notapi
- */
-static inline void setpin_reset(bool_t state) {
- (void) state;
- /* Nothing to do here - reset pin tied to Vcc */
-}
-
-/**
- * @brief Set the lcd back-light level.
- *
- * @param[in] percent 0 to 100%
- *
- * @notapi
- */
-static inline void set_backlight(uint8_t percent) {
- (void) percent;
- /* Nothing to do here - Backlight always on */
-}
-
-/**
- * @brief Take exclusive control of the bus
- *
- * @notapi
- */
-static inline void acquire_bus(void) {
- /* Nothing to do here since LCD is the only device on that bus */
-}
-
-/**
- * @brief Release exclusive control of the bus
- *
- * @notapi
- */
-static inline void release_bus(void) {
- /* Nothing to do here since LCD is the only device on that bus */
-}
-
-/**
- * @brief Send data to the index register.
- *
- * @param[in] index The index register to set
- *
- * @notapi
- */
-static inline void write_index(uint16_t index) {
- palWritePort(GPIOE, index);
- CLR_RS; CLR_WR; SET_WR; SET_RS;
-}
-
-/**
- * @brief Send data to the lcd.
- *
- * @param[in] data The data to send
- *
- * @notapi
- */
-static inline void write_data(uint16_t data) {
- palWritePort(GPIOE, data);
- CLR_WR; SET_WR;
-}
-
-#if GDISP_HARDWARE_READPIXEL || GDISP_HARDWARE_SCROLL || defined(__DOXYGEN__)
-/**
- * @brief Read data from the lcd.
- *
- * @return The data from the lcd
- * @note The chip select may need to be asserted/de-asserted
- * around the actual spi read
- *
- * @notapi
- */
-static inline uint16_t read_data(void) {
- uint16_t value;
-
- // change pin mode to digital input
- palSetGroupMode(GPIOE, PAL_WHOLE_PORT, 0, PAL_MODE_INPUT);
-
- CLR_RD;
- value = palReadPort(GPIOE);
- value = palReadPort(GPIOE);
- SET_RD;
-
- // change pin mode back to digital output
- palSetGroupMode(GPIOE, PAL_WHOLE_PORT, 0, PAL_MODE_OUTPUT_PUSHPULL);
-
- return value;
-}
-#endif
-
-#endif /* _GDISP_LLD_BOARD_H */
-/** @} */
diff --git a/drivers/gdisp/SSD1289/gdisp_lld_board_st_stm32f4_discovery.h b/drivers/gdisp/SSD1289/gdisp_lld_board_st_stm32f4_discovery.h
deleted file mode 100644
index 9d46d64b..00000000
--- a/drivers/gdisp/SSD1289/gdisp_lld_board_st_stm32f4_discovery.h
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * This file is subject to the terms of the GFX License. If a copy of
- * the license was not distributed with this file, you can obtain one at:
- *
- * http://ugfx.org/license.html
- */
-
-/**
- * @file drivers/gdisp/SSD1289/gdisp_lld_board_st_stm32f4_discovery.h
- * @brief GDISP Graphic Driver subsystem board interface for the SSD1289 display.
- *
- * @addtogroup GDISP
- * @{
- */
-
-#ifndef _GDISP_LLD_BOARD_H
-#define _GDISP_LLD_BOARD_H
-
-#define GDISP_REG ((volatile uint16_t *) 0x60000000)[0] /* RS = 0 */
-#define GDISP_RAM ((volatile uint16_t *) 0x60020000)[0] /* RS = 1 */
-
-#define GDISP_USE_FSMC
-#define GDISP_USE_DMA
-#define GDISP_DMA_STREAM STM32_DMA2_STREAM6
-
-const unsigned char FSMC_Bank = 0;
-
-/* PWM configuration structure. We use timer 3 channel 3 */
-static const PWMConfig pwmcfg = {
- 100000, /* 100 kHz PWM clock frequency. */
- 100, /* PWM period is 100 cycles. */
- NULL,
- {
- {PWM_OUTPUT_DISABLED, NULL},
- {PWM_OUTPUT_DISABLED, NULL},
- {PWM_OUTPUT_ACTIVE_HIGH, NULL},
- {PWM_OUTPUT_DISABLED, NULL}
- },
- 0
-};
-
-/**
- * @brief Initialise the board for the display.
- * @notes Performs the following functions:
- * 1. initialise the io port used by your display
- * 2. initialise the reset pin (initial state not-in-reset)
- * 3. initialise the chip select pin (initial state not-active)
- * 4. initialise the backlight pin (initial state back-light off)
- *
- * @notapi
- */
-static inline void init_board(void) {
-
- #if defined(STM32F1XX) || defined(STM32F3XX)
- /* FSMC setup for F1/F3 */
- rccEnableAHB(RCC_AHBENR_FSMCEN, 0);
-
- #if defined(GDISP_USE_DMA) && defined(GDISP_DMA_STREAM)
- #error "DMA not implemented for F1/F3 Devices"
- #endif
- #elif defined(STM32F4XX) || defined(STM32F2XX)
- /* STM32F2-F4 FSMC init */
- rccEnableAHB3(RCC_AHB3ENR_FSMCEN, 0);
-
- #if defined(GDISP_USE_DMA) && defined(GDISP_DMA_STREAM)
- if (dmaStreamAllocate(GDISP_DMA_STREAM, 0, NULL, NULL)) gfxExit();
- dmaStreamSetMemory0(GDISP_DMA_STREAM, &GDISP_RAM);
- dmaStreamSetMode(GDISP_DMA_STREAM, STM32_DMA_CR_PL(0) | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_DIR_M2M);
- #endif
- #else
- #error "FSMC not implemented for this device"
- #endif
-
- /* set pins to FSMC mode */
- IOBus busD = {GPIOD, (1 << 0) | (1 << 1) | (1 << 4) | (1 << 5) | (1 << 7) | (1 << 8) |
- (1 << 9) | (1 << 10) | (1 << 11) | (1 << 14) | (1 << 15), 0};
-
- IOBus busE = {GPIOE, (1 << 7) | (1 << 8) | (1 << 9) | (1 << 10) | (1 << 11) | (1 << 12) |
- (1 << 13) | (1 << 14) | (1 << 15), 0};
-
- palSetBusMode(&busD, PAL_MODE_ALTERNATE(12));
- palSetBusMode(&busE, PAL_MODE_ALTERNATE(12));
-
- /* FSMC timing */
- FSMC_Bank1->BTCR[FSMC_Bank+1] = FSMC_BTR1_ADDSET_0 | FSMC_BTR1_DATAST_2 | FSMC_BTR1_BUSTURN_0 ;
-
- /* Bank1 NOR/SRAM control register configuration
- * This is actually not needed as already set by default after reset */
- FSMC_Bank1->BTCR[FSMC_Bank] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN;
-
- /* Display backlight control */
- /* TIM3 is an alternate function 2 (AF2) */
- pwmStart(&PWMD3, &pwmcfg);
- palSetPadMode(GPIOB, 0, PAL_MODE_ALTERNATE(2));
- pwmEnableChannel(&PWMD3, 2, 100);
-
-}
-
-/**
- * @brief Set or clear the lcd reset pin.
- *
- * @param[in] state TRUE = lcd in reset, FALSE = normal operation
- *
- * @notapi
- */
-static inline void setpin_reset(bool_t state) {
- (void) state;
- /* Nothing to do here */
-}
-
-/**
- * @brief Set the lcd back-light level.
- *
- * @param[in] percent 0 to 100%
- *
- * @notapi
- */
-static inline void set_backlight(uint8_t percent) {
- pwmEnableChannel(&PWMD3, 2, percent);
-}
-
-/**
- * @brief Take exclusive control of the bus
- *
- * @notapi
- */
-static inline void acquire_bus(void) {
- /* Nothing to do here */
-}
-
-/**
- * @brief Release exclusive control of the bus
- *
- * @notapi
- */
-static inline void release_bus(void) {
- /* Nothing to do here */
-}
-
-/**
- * @brief Send data to the index register.
- *
- * @param[in] index The index register to set
- *
- * @notapi
- */
-static inline void write_index(uint16_t index) { GDISP_REG = index; }
-
-/**
- * @brief Send data to the lcd.
- *
- * @param[in] data The data to send
- *
- * @notapi
- */
-static inline void write_data(uint16_t data) { GDISP_RAM = data; }
-
-#if GDISP_HARDWARE_READPIXEL || GDISP_HARDWARE_SCROLL || defined(__DOXYGEN__)
-/**
- * @brief Read data from the lcd.
- *
- * @return The data from the lcd
- * @note The chip select may need to be asserted/de-asserted
- * around the actual spi read
- *
- * @notapi
- */
-static inline uint16_t read_data(void) { return GDISP_RAM; }
-#endif
-
-#endif /* _GDISP_LLD_BOARD_H */
-/** @} */
diff --git a/drivers/gdisp/SSD1289/gdisp_lld_board_template.h b/drivers/gdisp/SSD1289/gdisp_lld_board_template.h
deleted file mode 100644
index e5d10355..00000000
--- a/drivers/gdisp/SSD1289/gdisp_lld_board_template.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * This file is subject to the terms of the GFX License. If a copy of
- * the license was not distributed with this file, you can obtain one at:
- *
- * http://ugfx.org/license.html
- */
-
-/**
- * @file drivers/gdisp/SSD1289/gdisp_lld_board_template.h
- * @brief GDISP Graphic Driver subsystem board interface for the SSD1289 display.
- *
- * @addtogroup GDISP
- * @{
- */
-
-#ifndef _GDISP_LLD_BOARD_H
-#define _GDISP_LLD_BOARD_H
-
-/**
- * @brief Initialise the board for the display.
- *
- * @notapi
- */
-static inline void init_board(void) {
-
-}
-
-/**
- * @brief Set or clear the lcd reset pin.
- *
- * @param[in] state TRUE = lcd in reset, FALSE = normal operation
- *
- * @notapi
- */
-static inline void setpin_reset(bool_t state) {
-
-}
-
-/**
- * @brief Set the lcd back-light level.
- *
- * @param[in] percent 0 to 100%
- *
- * @notapi
- */
-static inline void set_backlight(uint8_t percent) {
-
-}
-
-/**
- * @brief Take exclusive control of the bus
- *
- * @notapi
- */
-static inline void acquire_bus(void) {
-
-}
-
-/**
- * @brief Release exclusive control of the bus
- *
- * @notapi
- */
-static inline void release_bus(void) {
-
-}
-
-/**
- * @brief Send data to the index register.
- *
- * @param[in] index The index register to set
- *
- * @notapi
- */
-static inline void write_index(uint16_t index) {
-
-}
-
-/**
- * @brief Send data to the lcd.
- *
- * @param[in] data The data to send
- *
- * @notapi
- */
-static inline void write_data(uint16_t data) {
-
-}
-
-#if GDISP_HARDWARE_READPIXEL || GDISP_HARDWARE_SCROLL || defined(__DOXYGEN__)
-/**
- * @brief Read data from the lcd.
- *
- * @return The data from the lcd
- * @note The chip select may need to be asserted/de-asserted
- * around the actual spi read
- *
- * @notapi
- */
-static inline uint16_t read_data(void) {
-
-}
-#endif
-
-#endif /* _GDISP_LLD_BOARD_H */
-/** @} */
diff --git a/drivers/gdisp/SSD1289/gdisp_lld_config.h b/drivers/gdisp/SSD1289/gdisp_lld_config.h
index 989cc3af..a9166553 100644
--- a/drivers/gdisp/SSD1289/gdisp_lld_config.h
+++ b/drivers/gdisp/SSD1289/gdisp_lld_config.h
@@ -22,16 +22,20 @@
/* Driver hardware support. */
/*===========================================================================*/
-#define GDISP_DRIVER_NAME "SSD1289"
-
-#define GDISP_HARDWARE_CLEARS TRUE
-#define GDISP_HARDWARE_FILLS TRUE
-#define GDISP_HARDWARE_BITFILLS TRUE
-#define GDISP_HARDWARE_SCROLL TRUE
-#define GDISP_HARDWARE_PIXELREAD TRUE
-#define GDISP_HARDWARE_CONTROL TRUE
-
-#define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_RGB565
+#define GDISP_HARDWARE_STREAM_WRITE TRUE
+#define GDISP_HARDWARE_STREAM_READ TRUE
+#define GDISP_HARDWARE_STREAM_POS TRUE
+#define GDISP_HARDWARE_CONTROL TRUE
+
+#if defined(GDISP_USE_DMA)
+ #define GDISP_HARDWARE_FILLS TRUE
+ #if !defined(GDISP_PIXELFORMAT) || GDISP_PIXELFORMAT == 0x2565
+ // Hardware BitBlts are only supported in native pixel format on this controller
+ #define GDISP_HARDWARE_BITFILLS TRUE
+ #endif
+#endif
+
+#define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_RGB565
#endif /* GFX_USE_GDISP */
diff --git a/drivers/gdisp/SSD1306/SSD1306.h b/drivers/gdisp/SSD1306/SSD1306.h
index 38507d48..47ca39e4 100644
--- a/drivers/gdisp/SSD1306/SSD1306.h
+++ b/drivers/gdisp/SSD1306/SSD1306.h
@@ -8,9 +8,6 @@
#ifndef _SSD1306_H
#define _SSD1306_H
-#define SSD1306_BLACK 0
-#define SSD1306_WHITE 1
-
#define SSD1306_SETCONTRAST 0x81
#define SSD1306_DISPLAYALLON_RESUME 0xA4
#define SSD1306_DISPLAYALLON 0xA5
diff --git a/drivers/gdisp/SSD1306/board_SSD1306_template.h b/drivers/gdisp/SSD1306/board_SSD1306_template.h
new file mode 100644
index 00000000..5b4bd05c
--- /dev/null
+++ b/drivers/gdisp/SSD1306/board_SSD1306_template.h
@@ -0,0 +1,116 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/SSD1306/board_SSD1306_template.h
+ * @brief GDISP Graphic Driver subsystem board interface for the SSD1306 display.
+ *
+ * @addtogroup GDISP
+ * @{
+ */
+
+#ifndef _GDISP_LLD_BOARD_H
+#define _GDISP_LLD_BOARD_H
+
+/**
+ * @brief Optional: A byte to prefix on each display page line.
+ * @note If not defined then no byte is prefixed on each page line.
+ *
+ * @notapi
+ */
+//#define SSD1306_PAGE_PREFIX 0x40
+
+/**
+ * @brief Initialise the board for the display.
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @note Set the g->board member to whatever is appropriate. For multiple
+ * displays this might be a pointer to the appropriate register set.
+ *
+ * @notapi
+ */
+static inline void init_board(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief After the initialisation.
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void post_init_board(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Set or clear the lcd reset pin.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] state TRUE = lcd in reset, FALSE = normal operation
+ *
+ * @notapi
+ */
+static inline void setpin_reset(GDisplay *g, bool_t state) {
+ (void) g;
+ (void) state;
+}
+
+/**
+ * @brief Take exclusive control of the bus
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void acquire_bus(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Release exclusive control of the bus
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void release_bus(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Send a command to the controller.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] cmd The command to send *
+ *
+ * @notapi
+ */
+static inline void write_cmd(GDisplay *g, uint8_t cmd) {
+ (void) g;
+ (void) cmd;
+}
+
+/**
+ * @brief Send data to the lcd.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] data The data to send
+ *
+ * @notapi
+ */
+static inline void write_data(GDisplay *g, uint8_t* data, uint16_t length) {
+ (void) g;
+ (void) data;
+ (void) length;
+}
+
+#endif /* _GDISP_LLD_BOARD_H */
+/** @} */
+
diff --git a/drivers/gdisp/SSD1306/gdisp_lld.c b/drivers/gdisp/SSD1306/gdisp_lld.c
deleted file mode 100644
index 9c20d853..00000000
--- a/drivers/gdisp/SSD1306/gdisp_lld.c
+++ /dev/null
@@ -1,646 +0,0 @@
-/*
- * This file is subject to the terms of the GFX License. If a copy of
- * the license was not distributed with this file, you can obtain one at:
- *
- * http://ugfx.org/license.html
- */
-
-#include "gfx.h"
-
-#include "SSD1306.h"
-
-#if GFX_USE_GDISP
-
-/* Include the emulation code for things we don't support */
-#include "gdisp/lld/emulation.c"
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-#ifndef GDISP_SCREEN_HEIGHT
- #define GDISP_SCREEN_HEIGHT 64
-#endif
-#ifndef GDISP_SCREEN_WIDTH
- #define GDISP_SCREEN_WIDTH 128
-#endif
-
-#define GDISP_INITIAL_CONTRAST 0xFF
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-// Include wiring specific header
-#include "gdisp_lld_board_example_i2c.h"
-
-// Some common routines and macros
-#define delay(us) gfxSleepMicroseconds(us)
-#define delayms(ms) gfxSleepMilliseconds(ms)
-
-// The memory buffer for the display
-static uint8_t gdisp_buffer[GDISP_SCREEN_HEIGHT * GDISP_SCREEN_WIDTH / 8];
-
-/** Set the display to normal or inverse.
- * @param[in] value 0 for normal mode, or 1 for inverse mode.
- * @notapi
- */
-static void invert_display(uint8_t i) {
- write_cmd(i ? SSD1306_INVERTDISPLAY : SSD1306_NORMALDISPLAY);
-}
-
-/** Turn the whole display off.
- * Sends the display to sleep, but leaves RAM intact.
- * @notapi
- */
-static void display_off(){
- write_cmd(SSD1306_DISPLAYOFF);
-}
-
-/** Turn the whole display on.
- * Wakes up this display following a sleep() call.
- * @notapi
- */
-static void display_on() {
- write_cmd(SSD1306_DISPLAYON);
-}
-
-/** Set the vertical shift by COM.
- * @param[in] value The number of rows to shift, from 0 - 63.
- * @notapi
-*/
-static void set_display_offset(unsigned char value) {
- write_cmd(SSD1306_SETDISPLAYOFFSET);
- write_cmd(value & 0x3F);
-}
-
-/** Set the display contrast.
- * @param[in] value The contrast, from 1 to 256.
- * @notapi
- */
-static void set_contrast(unsigned char value) {
- write_cmd(SSD1306_SETCONTRAST);
- write_cmd(value);
-}
-
-/** Set the display start line. This is the line at which the display will start rendering.
- * @param[in] value A value from 0 to 63 denoting the line to start at.
- * @notapi
- */
-static void set_display_start_line(unsigned char value) {
- write_cmd(SSD1306_SETSTARTLINE | value);
-}
-
-/** Set the segment remap state. This allows the module to be addressed as if flipped horizontally.
- * NOTE: Changing this setting has no effect on data already in the module's GDDRAM.
- * @param[in] value 0 = column address 0 = segment 0 (the default), 1 = column address 127 = segment 0 (flipped).
- * @notapi
- */
-static void set_segment_remap(unsigned char value) {
- write_cmd(value ? SSD1306_SEGREMAP+1 : SSD1306_SEGREMAP);
-}
-
-/** Set the multiplex ratio.
- * @param[in] value MUX will be set to (value+1). Valid values range from 15 to 63 - MUX 16 to 64.
- * @notapi
- */
-static void set_multiplex_ratio(unsigned char value) {
- write_cmd(SSD1306_SETMULTIPLEX);
- write_cmd(value & 0x3F);
-}
-
-/** Set COM output scan direction. If the display is active, this will immediately vertically
- * flip the display.
- * @param[in] value 0 = Scan from COM0 (default), 1 = reversed (scan from COM[N-1]).
- * @notapi
- */
-static void set_com_output_scan_direction(unsigned char value) {
- write_cmd(value ? SSD1306_COMSCANDEC : SSD1306_COMSCANINC);
-}
-
-static void set_com_pins_hardware_configuration(unsigned char sequential, unsigned char lr_remap) {
- write_cmd(SSD1306_SETCOMPINS);
- write_cmd(0x02 | ((sequential & 1) << 4) | ((lr_remap & 1) << 5));
-}
-
-/** Flip display content horizontally.
- * NOTE: This only flips display content, but doesn't turn the char writing around.
- * You have to unmirror everything manually.
- * @param[in] value 0 = column address 0 = segment 0 (the default), 1 = column address 127 = segment 0 (flipped).
- * @notapi
- */
-static void flip_display(unsigned char enable) {
- if( enable && GDISP.Orientation == GDISP_ROTATE_0) {
- set_com_output_scan_direction(0);
- set_segment_remap(0);
- GDISP.Orientation = GDISP_ROTATE_0;
- }
- if( !enable && GDISP.Orientation == GDISP_ROTATE_180) {
- set_com_output_scan_direction(1);
- set_segment_remap(1);
- GDISP.Orientation = GDISP_ROTATE_180;
- }
- else
- return;
-}
-
-/** Perform a "no operation".
- * @notapi
- */
-static void nop() {
- write_cmd(0xE3);
-}
-
-/** Page Addressing Mode: Set the column start address register for
- * page addressing mode.
- * @param[in] address The address (full byte).
- * @notapi
- */
-static void set_start_address_pam(unsigned char address)
-{
- // "Set Lower Column Start Address for Page Addressing Mode"
- write_cmd(address & 0x0F);
-
- // "Set Higher Column Start Address for Page Addressing Mode"
- write_cmd((address << 4) & 0x0F);
-}
-
-/** Set memory addressing mode to the given value.
- * @param[in] mode 0 for Horizontal addressing mode,\n 1 for Vertical addressing mode,\n or 2 for Page addressing mode (PAM). 2 is the default.
- * @notapi
- */
-static void set_memory_addressing_mode(unsigned char mode)
-{
- write_cmd(SSD1306_MEMORYMODE);
- write_cmd(mode & 0x3);
-}
-
-/** Set column address range for horizontal/vertical addressing mode.
- * @param[in] start Column start address, 0 - 127.
- * @param[in] end Column end address, 0 - 127.
- * @notapi
- */
-static void set_column_address_hvam(unsigned char start, unsigned char end)
-{
- write_cmd(SSD1306_HV_COLUMN_ADDRESS);
- write_cmd(start & 0x7F);
- write_cmd(end & 0x7F);
-}
-
-/** Set page start and end address for horizontal/vertical addressing mode.
- * @param[in] start The start page, 0 - 7.
- * @param[in] end The end page, 0 - 7.
- * @notapi
- */
-static void set_page_address_hvam(unsigned char start, unsigned char end)
-{
- write_cmd(SSD1306_HV_PAGE_ADDRESS);
- write_cmd(start & 0x07);
- write_cmd(end & 0x07);
-}
-
-/** Set the GDDRAM page start address for page addressing mode.
- * @param[in] address The start page, 0 - 7.
- * @notapi
- */
-static void set_page_start_pam(unsigned char address)
-{
- write_cmd(SSD1306_PAM_PAGE_START | (address & 0x07));
-}
-
-/** Set the display clock divide ratio and the oscillator frequency.
- * @param[in] ratio The divide ratio, default is 0.
- * @param[in] frequency The oscillator frequency, 0 - 127. Default is 8.
- * @notapi
- */
-static void set_display_clock_ratio_and_frequency(unsigned char ratio, unsigned char frequency)
-{
- write_cmd(SSD1306_SETDISPLAYCLOCKDIV);
- write_cmd((ratio & 0x0F) | ((frequency & 0x0F) << 4));
-}
-
-/** Set the precharge period.
- * @param[in] phase1 Phase 1 period in DCLK clocks. 1 - 15, default is 2.
- * @param[in] phase2 Phase 2 period in DCLK clocks. 1 - 15, default is 2.
- * @notapi
- */
-static void set_precharge_period(unsigned char phase1, unsigned char phase2)
-{
- write_cmd(SSD1306_SETPRECHARGE);
- write_cmd((phase1 & 0x0F) | ((phase2 & 0x0F ) << 4));
-}
-
-/** Set the Vcomh deselect level.
- * @param[in] level @p 0 = 0.65 x Vcc, @p 1 = 0.77 x Vcc (default), @p 2 = 0.83 x Vcc.
- * @notapi
- */
-static void set_vcomh_deselect_level(unsigned char level)
-{
- write_cmd(SSD1306_SETVCOMDETECT);
- write_cmd((level & 0x03) << 4);
-}
-
-/** Enable/disable charge pump.
- * @param[in] enable 0 to disable, 1 to enable the internal charge pump.
- * @notapi
- */
-static void set_charge_pump(unsigned char enable)
-{
- write_cmd(SSD1306_ENABLE_CHARGE_PUMP);
- write_cmd(enable ? 0x14 : 0x10);
-}
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/* ---- Required Routines ---- */
-/*
- The following 2 routines are required.
- All other routines are optional.
-*/
-
-/**
- * @brief Low level GDISP driver initialization.
- *
- * @notapi
- */
-bool_t gdisp_lld_init(void) {
- // Initialize your display
- init_board();
-
- // Hardware reset.
- setpin_reset(TRUE);
- delayms(1);
- setpin_reset(FALSE);
- delayms(10);
- setpin_reset(TRUE);
-
- // Get the bus for the following initialization commands.
- acquire_bus();
-
- display_off();
- set_display_clock_ratio_and_frequency(0, 8);
- #if GDISP_SCREEN_HEIGHT == 64
- set_multiplex_ratio(0x3F); // 1/64 duty
- #endif
- #if GDISP_SCREEN_HEIGHT == 32
- set_multiplex_ratio(0x1F); // 1/32 duty
- #endif
- set_precharge_period(0xF, 0x01); //
- set_display_offset(0); //
- set_display_start_line(0); //
- set_charge_pump(1); // Enable internal charge pump.
- set_memory_addressing_mode(0); // horizontal addressing mode; across then down //act like ks0108 (horizontal addressing mode)
- set_segment_remap(1); //
- set_com_output_scan_direction(1); //
- #if GDISP_SCREEN_HEIGHT == 64
- set_com_pins_hardware_configuration(1, 0);
- #endif
- #if GDISP_SCREEN_HEIGHT == 32
- set_com_pins_hardware_configuration(0, 1);
- #endif
- set_contrast(GDISP_INITIAL_CONTRAST); // Set initial contrast.
- set_vcomh_deselect_level(1); //
- display_on(); // Turn on OLED panel.
- invert_display(0); // Disable Inversion of display.
- set_column_address_hvam(0, 127); //
- set_page_address_hvam(0, 7); //
-
- release_bus();
-
- gdisp_lld_display();
-
- // Initialize the GDISP structure
- GDISP.Width = GDISP_SCREEN_WIDTH;
- GDISP.Height = GDISP_SCREEN_HEIGHT;
- GDISP.Orientation = GDISP_ROTATE_0;
- GDISP.Powermode = powerOn;
- GDISP.Contrast = GDISP_INITIAL_CONTRAST;
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- GDISP.clipx0 = 0;
- GDISP.clipy0 = 0;
- GDISP.clipx1 = GDISP.Width;
- GDISP.clipy1 = GDISP.Height;
- #endif
- return TRUE;
-}
-
-/**
- * @brief Draws a pixel on the display.
- *
- * @param[in] x X location of the pixel
- * @param[in] y Y location of the pixel
- * @param[in] color The color of the pixel
- *
- * @notapi
- */
-void gdisp_lld_draw_pixel(coord_t x, coord_t y, color_t color) {
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- if (x < GDISP.clipx0 || y < GDISP.clipy0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
- #endif
-
- if (color == SSD1306_WHITE)
- gdisp_buffer[x+ (y/8)*GDISP_SCREEN_WIDTH] |= (1<<y%8);
- else
- gdisp_buffer[x+ (y/8)*GDISP_SCREEN_WIDTH] &= ~(1<<y%8);
-}
-
-void gdisp_lld_display() {
- set_display_start_line(0);
-
- /* We're sending half a line in one X-mission.*/
- uint8_t command[GDISP_SCREEN_WIDTH/2],
- cmdLength = sizeof(command)/sizeof(command[0]),
- parts = GDISP_SCREEN_WIDTH/cmdLength;
-
- for(int i=0; i<GDISP_SCREEN_HEIGHT/8; i++){
- for(int j = 0; j<parts; j++){
- memmove(command, &gdisp_buffer[i*GDISP_SCREEN_WIDTH + j*cmdLength], cmdLength);
- write_data(command, cmdLength);
- }
- }
-}
-
-/* ---- Optional Routines ---- */
-/*
- All the below routines are optional.
- Defining them will increase speed but everything
- will work if they are not defined.
- If you are not using a routine - turn it off using
- the appropriate GDISP_HARDWARE_XXXX macro.
- Don't bother coding for obvious similar routines if
- there is no performance penalty as the emulation software
- makes a good job of using similar routines.
- eg. If gfillarea() is defined there is little
- point in defining clear() unless the
- performance bonus is significant.
- For good performance it is suggested to implement
- fillarea() and blitarea().
-*/
-
-#if (GDISP_NEED_SCROLL && GDISP_HARDWARE_SCROLL) || defined(__DOXYGEN__)
- /**
- * @brief Scroll vertically a section of the screen.
- * @note Optional.
- * @note If x,y + cx,cy is off the screen, the result is undefined.
- * @note If lines is >= cy, it is equivalent to a area fill with bgcolor.
- *
- * @param[in] x, y The start of the area to be scrolled
- * @param[in] cx, cy The size of the area to be scrolled
- * @param[in] lines The number of lines to scroll (Can be positive or negative)
- * @param[in] bgcolor The color to fill the newly exposed area.
- *
- * @notapi
- */
- void gdisp_lld_vertical_scroll(coord_t x, coord_t y, coord_t cx, coord_t cy, int lines, color_t bgcolor) {
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; }
- if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; }
- if (!lines || cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
- if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
- if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
- #endif
-
- /* See datasheet table T10-1 for this*/
- uint8_t fHeight = (uint8_t)gdispGetFontMetric(gwinGetDefaultFont(), fontLineSpacing);
- set_multiplex_ratio(GDISP_SCREEN_HEIGHT - fHeight+1);
- set_display_offset(fHeight-2);
-
- /* Scrolling animation.*/
- for(int i=0; i<fHeight; i++){
- set_display_start_line(i);
- gfxSleepMilliseconds(10);
- }
-
- /* Shift buffer up a font line.*/
- for (int i = 0; i < GDISP_SCREEN_WIDTH*(GDISP_SCREEN_HEIGHT/8-1); i++) {
- gdisp_buffer[i] = gdisp_buffer[i+GDISP_SCREEN_WIDTH*(fHeight/8)] >> fHeight % 8;
- gdisp_buffer[i] |= gdisp_buffer[i+GDISP_SCREEN_WIDTH*(fHeight/8 + 1)] << (8 - fHeight%8);
- }
-
- /* Clear last page.*/
- memset( &gdisp_buffer[GDISP_SCREEN_HEIGHT*GDISP_SCREEN_WIDTH/8 - GDISP_SCREEN_WIDTH*2], SSD1306_BLACK, GDISP_SCREEN_WIDTH*2);
-
- /* Update display.*/
- gdisp_lld_display();
- }
-
- /**
- * @warning Implementation only fully supports left and right...some command issues here.
- * Activate a scroll for rows start through stop.
- * Hint, the display is 16 rows tall. To scroll the whole display, run:
- * @code
- * display.scrollright(0x00, 0x0F)
- * @endcode
- * @param[in] start The start of the area to be scrolled
- * @param[in] stop The size of the area to be scrolled
- * @param[in] dir direction of scrolling
- * [left, right, up, down, up_right, up_left, down_left, down_right]
- * @note Optional. *
- *
- * @notapi
- */
- void gdisp_lld_start_scroll(uint8_t dir, uint8_t start, uint8_t stop, uint8_t interval){
-// if(dir == GDISP_SCROLL_RIGHT || GDISP_SCROLL_LEFT || GDISP_SCROLL_UP) {
-// switch (dir) {
-// case GDISP_SCROLL_RIGHT:
-// write_cmd(SSD1306_SCROLL_HORIZONTAL_RIGHT);
-// break;
-// case GDISP_SCROLL_LEFT:
-// write_cmd(SSD1306_SCROLL_HORIZONTAL_LEFT);
-// break;
-// }
-// write_cmd(0X00); // Dummy byte.
-// write_cmd(start & 0x07); // Define start page address.
-// switch (interval) { // Set time interval between each scroll step (5 frames)
-// case 2: write_cmd(0x07); break; // 111b
-// case 3: write_cmd(0x04); break; // 100b
-// case 4: write_cmd(0x05); break; // 101b
-// case 5: write_cmd(0x00); break; // 000b
-// case 25: write_cmd(0x06); break; // 110b
-// case 64: write_cmd(0x01); break; // 001b
-// case 128: write_cmd(0x02); break; // 010b
-// case 256: write_cmd(0x03); break; // 011b
-// default:
-// // default to 2 frame interval
-// write_cmd(0x07); break;
-// }
-// write_cmd(stop & 0x07); // Define stop page address
-// write_cmd(0X01); // Set vertical scrolling offset as no row.
-// write_cmd(0XFF); // Undocumented but needed.
-// write_cmd(SSD1306_SCROLL_ACTIVATE);
-// }
-// else if(dir == GDISP_SCROLL_UP || GDISP_SCROLL_DOWN) {
-// switch (dir) {
-// case GDISP_SCROLL_UP:
-// gdisp_lld_set_vertical_scroll_area(0x00, GDISP_SCREEN_HEIGHT);
-// write_cmd(SSD1306_SCROLL_VERTICAL_AND_HORIZONTAL_RIGHT);
-// break;
-//
-// case GDISP_SCROLL_DOWN:
-// gdisp_lld_set_vertical_scroll_area(0x00, GDISP_SCREEN_HEIGHT);
-// write_cmd(SSD1306_SCROLL_VERTICAL_AND_HORIZONTAL_LEFT);
-// break;
-// }
-// write_cmd(0X00); // Dummy byte.
-// write_cmd(start); // Define start page address.
-// write_cmd(0X00); // Set time interval between each scroll step (5 frames)
-// write_cmd(stop); // Define stop page address
-// write_cmd(0X01); // Set vertical scrolling offset as no row.
-// write_cmd(SSD1306_SCROLL_ACTIVATE);
-// gdisp_lld_set_vertical_scroll_area(0x00, GDISP_SCREEN_HEIGHT-10);
-// write_cmd(SSD1306_SCROLL_VERTICAL_AND_HORIZONTAL_RIGHT);
-// write_cmd(0X00); // Dummy byte.
-// write_cmd(start); // Define start page address.
-// write_cmd(0X00); // Set time interval between each scroll step (5 frames)
-// write_cmd(stop); // Define stop page address
-// write_cmd(0X03); // Set vertical scrolling offset as no row.
-// write_cmd(SSD1306_SCROLL_ACTIVATE);
-// }
- }
-
- /**
- * Sets vertical scroll area of display.
- * @param[in] start The start of the area to be scrolled [y coordinate]
- * @param[in] stop The size of the area to be scrolled [y coordinate]
- * @note Optional. *
- *
- * @notapi
- */
- void gdisp_lld_set_vertical_scroll_area(uint8_t start, uint8_t stop){
- write_cmd(SSD1306_SCROLL_SET_VERTICAL_SCROLL_AREA);
- write_cmd(start);
- write_cmd(stop);
- }
-
- /** Deactivate the continuous scroll set up with start_horizontal_scroll() or
- * start_vertical_and_horizontal_scroll().
- * @see set_horizontal_scroll, set_vertical_and_horizontal_scroll
- * @notapi
- */
- void gdisp_lld_stop_scroll(void){
- write_cmd(SSD1306_SCROLL_DEACTIVATE);
- }
-#endif // GDISP_NEED_SCROLL
-
-#if GDISP_HARDWARE_FILLS || defined(__DOXYGEN__)
- void gdisp_lld_fill_area(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; }
- if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; }
- if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
- if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
- if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
- #endif
-
- for(int i=x; i<x+cx; i++) {
- for(int j=y; j<y+cy; j++) {
- gdisp_lld_draw_pixel(i,j,color);
- }
- }
- }
-#endif // GDISP_HARDWARE_FILLS
-
-#if (GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL) || defined(__DOXYGEN__)
- /**
- * @brief Driver Control
- * @details Unsupported control codes are ignored.
- * @note The value parameter should always be typecast to (void *).
- * @note There are some predefined and some specific to the low level driver.
- * @note GDISP_CONTROL_POWER - Takes a gdisp_powermode_t
- * GDISP_CONTROL_ORIENTATION - Takes a gdisp_orientation_t
- * GDISP_CONTROL_BACKLIGHT - Takes an int from 0 to 100. For a driver
- * that only supports off/on anything other
- * than zero is on.
- * GDISP_CONTROL_CONTRAST - Takes an int from 0 to 100.
- * GDISP_CONTROL_LLD - Low level driver control constants start at
- * this value.
- *
- * @param[in] what What to do.
- * @param[in] value The value to use (always cast to a void *).
- *
- * @notapi
- */
- void gdisp_lld_control(unsigned what, void *value) {
- switch(what) {
- case GDISP_CONTROL_POWER:
- if (GDISP.Powermode == (gdisp_powermode_t)value)
- return;
- switch((gdisp_powermode_t)value) {
- case powerOff:
- display_off();
- case powerSleep:
- display_off();
- case powerDeepSleep:
- display_off();
- case powerOn:
- display_on();
- default:
- return;
- }
- GDISP.Powermode = (gdisp_powermode_t)value;
- return;
- case GDISP_CONTROL_ORIENTATION:
- if (GDISP.Orientation == (gdisp_orientation_t)value)
- return;
- switch((gdisp_orientation_t)value) {
- case GDISP_ROTATE_0:
- flip_display(0);
- GDISP.Height = GDISP_SCREEN_HEIGHT;
- GDISP.Width = GDISP_SCREEN_WIDTH;
- break;
- case GDISP_ROTATE_180:
- flip_display(1);
- GDISP.Height = GDISP_SCREEN_HEIGHT;
- GDISP.Width = GDISP_SCREEN_WIDTH;
- break;
- default:
- return;
- }
- #if GDISP_NEED_CLIP || GDISP_NEED_VALIDATION
- GDISP.clipx0 = 0;
- GDISP.clipy0 = 0;
- GDISP.clipx1 = GDISP.Width;
- GDISP.clipy1 = GDISP.Height;
- #endif
- GDISP.Orientation = (gdisp_orientation_t)value;
- return;
- case GDISP_CONTROL_CONTRAST:
- if ((unsigned)value > 100)
- value = (void *)100;
- if (GDISP.Contrast == (uint8_t)((float)((uint8_t)value) * 256.0/100.0) )
- return;
- set_contrast((uint8_t)((float)((uint8_t)value) * 256.0/100.0) );
- GDISP.Contrast = (unsigned)value;
- return;
- }
- }
-#endif // GDISP_NEED_CONTROL
-
-/**
- * Let the display blink several times by means of invert and invert back.
- * @param num number of blink cycles to do
- * @param speed milliseconds to wait between toggling inversion
- * @param wait milliseconds to wait before start of all blink cycles and after finishing blink cycles
- * @notapi
- */
- void gdisp_lld_display_blink(uint8_t num, uint16_t speed, uint16_t wait){
- uint8_t inv = 0;
-
- gfxSleepMilliseconds(wait);
- for(int i=0; i<2*num; i++) {
- inv ^= 1;
- invert_display(inv);
- gfxSleepMilliseconds(speed);
- }
- gfxSleepMilliseconds(wait);
-}
-
-#endif // GFX_USE_GDISP
-/** @} */
-
diff --git a/drivers/gdisp/SSD1306/gdisp_lld.mk b/drivers/gdisp/SSD1306/gdisp_lld.mk
index 2a2e1364..13df4230 100644
--- a/drivers/gdisp/SSD1306/gdisp_lld.mk
+++ b/drivers/gdisp/SSD1306/gdisp_lld.mk
@@ -1,5 +1,2 @@
-# List the required driver.
-GFXSRC += $(GFXLIB)/drivers/gdisp/SSD1306/gdisp_lld.c
-
-# Required include directories
GFXINC += $(GFXLIB)/drivers/gdisp/SSD1306
+GFXSRC += $(GFXLIB)/drivers/gdisp/SSD1306/gdisp_lld_SSD1306.c
diff --git a/drivers/gdisp/SSD1306/gdisp_lld_SSD1306.c b/drivers/gdisp/SSD1306/gdisp_lld_SSD1306.c
new file mode 100644
index 00000000..b72ba781
--- /dev/null
+++ b/drivers/gdisp/SSD1306/gdisp_lld_SSD1306.c
@@ -0,0 +1,280 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/SSD1306/gdisp_lld.c
+ * @brief GDISP Graphics Driver subsystem low level driver source for the SSD1306 display.
+ */
+
+#include "gfx.h"
+
+#if GFX_USE_GDISP
+
+#define GDISP_DRIVER_VMT GDISPVMT_SSD1306
+#include "../drivers/gdisp/SSD1306/gdisp_lld_config.h"
+#include "gdisp/lld/gdisp_lld.h"
+
+#include "board_SSD1306.h"
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+#ifndef GDISP_SCREEN_HEIGHT
+ #define GDISP_SCREEN_HEIGHT 64 // This controller should support 32 (untested) or 64
+#endif
+#ifndef GDISP_SCREEN_WIDTH
+ #define GDISP_SCREEN_WIDTH 128
+#endif
+#ifndef GDISP_INITIAL_CONTRAST
+ #define GDISP_INITIAL_CONTRAST 100
+#endif
+#ifndef GDISP_INITIAL_BACKLIGHT
+ #define GDISP_INITIAL_BACKLIGHT 100
+#endif
+#ifdef SSD1306_PAGE_PREFIX
+ #define SSD1306_PAGE_WIDTH (GDISP_SCREEN_WIDTH+1)
+ #define SSD1306_PAGE_OFFSET 1
+#else
+ #define SSD1306_PAGE_WIDTH GDISP_SCREEN_WIDTH
+ #define SSD1306_PAGE_OFFSET 0
+#endif
+
+#define GDISP_FLG_NEEDFLUSH (GDISP_FLG_DRIVER<<0)
+
+#include "SSD1306.h"
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+// Some common routines and macros
+#define RAM(g) ((uint8_t *)g->priv)
+#define write_cmd2(g, cmd1, cmd2) { write_cmd(g, cmd1); write_cmd(g, cmd2); }
+#define write_cmd3(g, cmd1, cmd2, cmd3) { write_cmd(g, cmd1); write_cmd(g, cmd2); write_cmd(g, cmd3); }
+
+// Some common routines and macros
+#define delay(us) gfxSleepMicroseconds(us)
+#define delayms(ms) gfxSleepMilliseconds(ms)
+
+#define xyaddr(x, y) (SSD1306_PAGE_OFFSET + (x) + ((y)>>3)*SSD1306_PAGE_WIDTH)
+#define xybit(y) (1<<((y)&7))
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * As this controller can't update on a pixel boundary we need to maintain the
+ * the entire display surface in memory so that we can do the necessary bit
+ * operations. Fortunately it is a small display in monochrome.
+ * 64 * 128 / 8 = 1024 bytes.
+ */
+
+LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
+ // The private area is the display surface.
+ g->priv = gfxAlloc(GDISP_SCREEN_HEIGHT/8 * SSD1306_PAGE_WIDTH);
+
+ // Fill in the prefix command byte on each page line of the display buffer
+ // We can do it during initialisation as this byte is never overwritten.
+ #ifdef SSD1306_PAGE_PREFIX
+ {
+ unsigned i;
+
+ for(i=0; i < GDISP_SCREEN_HEIGHT/8 * SSD1306_PAGE_WIDTH; i+=SSD1306_PAGE_WIDTH)
+ RAM(g)[i] = SSD1306_PAGE_PREFIX;
+ }
+ #endif
+
+ // Initialise the board interface
+ init_board(g);
+
+ // Hardware reset
+ setpin_reset(g, TRUE);
+ gfxSleepMilliseconds(20);
+ setpin_reset(g, FALSE);
+ gfxSleepMilliseconds(20);
+
+ acquire_bus(g);
+
+ write_cmd(g, SSD1306_DISPLAYOFF);
+ write_cmd2(g, SSD1306_SETDISPLAYCLOCKDIV, 0x80);
+ write_cmd2(g, SSD1306_SETMULTIPLEX, GDISP_SCREEN_HEIGHT-1);
+ write_cmd2(g, SSD1306_SETPRECHARGE, 0x1F);
+ write_cmd2(g, SSD1306_SETDISPLAYOFFSET, 0);
+ write_cmd(g, SSD1306_SETSTARTLINE | 0);
+ write_cmd2(g, SSD1306_ENABLE_CHARGE_PUMP, 0x14);
+ write_cmd2(g, SSD1306_MEMORYMODE, 0);
+ write_cmd(g, SSD1306_SEGREMAP+1);
+ write_cmd(g, SSD1306_COMSCANDEC);
+ #if GDISP_SCREEN_HEIGHT == 64
+ write_cmd2(g, SSD1306_SETCOMPINS, 0x12);
+ #else
+ write_cmd2(g, SSD1306_SETCOMPINS, 0x22);
+ #endif
+ write_cmd2(g, SSD1306_SETCONTRAST, (uint8_t)(GDISP_INITIAL_CONTRAST*256/101)); // Set initial contrast.
+ write_cmd2(g, SSD1306_SETVCOMDETECT, 0x10);
+ write_cmd(g, SSD1306_DISPLAYON);
+ write_cmd(g, SSD1306_NORMALDISPLAY);
+ write_cmd3(g, SSD1306_HV_COLUMN_ADDRESS, 0, GDISP_SCREEN_WIDTH-1);
+ write_cmd3(g, SSD1306_HV_PAGE_ADDRESS, 0, GDISP_SCREEN_HEIGHT/8-1);
+
+ // Finish Init
+ post_init_board(g);
+
+ // Release the bus
+ release_bus(g);
+
+ /* Initialise the GDISP structure */
+ g->g.Width = GDISP_SCREEN_WIDTH;
+ g->g.Height = GDISP_SCREEN_HEIGHT;
+ g->g.Orientation = GDISP_ROTATE_0;
+ g->g.Powermode = powerOn;
+ g->g.Backlight = GDISP_INITIAL_BACKLIGHT;
+ g->g.Contrast = GDISP_INITIAL_CONTRAST;
+ return TRUE;
+}
+
+#if GDISP_HARDWARE_FLUSH
+ LLDSPEC void gdisp_lld_flush(GDisplay *g) {
+ unsigned i;
+
+ // Don't flush if we don't need it.
+ if (!(g->flags & GDISP_FLG_NEEDFLUSH))
+ return;
+
+ write_cmd(g, SSD1306_SETSTARTLINE | 0);
+
+ for(i=0; i < GDISP_SCREEN_HEIGHT/8 * SSD1306_PAGE_WIDTH; i+=SSD1306_PAGE_WIDTH)
+ write_data(g, RAM(g)+i, SSD1306_PAGE_WIDTH);
+ }
+#endif
+
+#if GDISP_HARDWARE_DRAWPIXEL
+ LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) {
+ coord_t x, y;
+
+ switch(g->g.Orientation) {
+ case GDISP_ROTATE_0:
+ x = g->p.x;
+ y = g->p.y;
+ break;
+ case GDISP_ROTATE_90:
+ x = g->p.y;
+ y = GDISP_SCREEN_HEIGHT-1 - g->p.x;
+ break;
+ case GDISP_ROTATE_180:
+ x = GDISP_SCREEN_WIDTH-1 - g->p.x;
+ y = GDISP_SCREEN_HEIGHT-1 - g->p.y;
+ break;
+ case GDISP_ROTATE_270:
+ x = GDISP_SCREEN_HEIGHT-1 - g->p.y;
+ x = g->p.x;
+ break;
+ }
+ if (COLOR2NATIVE(g->p.color) != Black)
+ RAM(g)[xyaddr(x, y)] |= xybit(y);
+ else
+ RAM(g)[xyaddr(x, y)] &= ~xybit(y);
+ g->flags |= GDISP_FLG_NEEDFLUSH;
+ }
+#endif
+
+#if GDISP_HARDWARE_PIXELREAD
+ LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g) {
+ coord_t x, y;
+
+ switch(g->g.Orientation) {
+ case GDISP_ROTATE_0:
+ x = g->p.x;
+ y = g->p.y;
+ break;
+ case GDISP_ROTATE_90:
+ x = g->p.y;
+ y = GDISP_SCREEN_HEIGHT-1 - g->p.x;
+ break;
+ case GDISP_ROTATE_180:
+ x = GDISP_SCREEN_WIDTH-1 - g->p.x;
+ y = GDISP_SCREEN_HEIGHT-1 - g->p.y;
+ break;
+ case GDISP_ROTATE_270:
+ x = GDISP_SCREEN_HEIGHT-1 - g->p.y;
+ y = g->p.x;
+ break;
+ }
+ return (RAM(g)[xyaddr(x, y)] & xybit(y)) ? White : Black;
+ }
+#endif
+
+#if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL
+ LLDSPEC void gdisp_lld_control(GDisplay *g) {
+ switch(g->p.x) {
+ case GDISP_CONTROL_POWER:
+ if (g->g.Powermode == (powermode_t)g->p.ptr)
+ return;
+ switch((powermode_t)g->p.ptr) {
+ case powerOff:
+ case powerSleep:
+ case powerDeepSleep:
+ acquire_bus(g);
+ write_cmd(g, SSD1306_DISPLAYOFF);
+ release_bus(g);
+ break;
+ case powerOn:
+ acquire_bus(g);
+ write_cmd(g, SSD1306_DISPLAYON);
+ release_bus(g);
+ break;
+ default:
+ return;
+ }
+ g->g.Powermode = (powermode_t)g->p.ptr;
+ return;
+
+ case GDISP_CONTROL_ORIENTATION:
+ if (g->g.Orientation == (orientation_t)g->p.ptr)
+ return;
+ switch((orientation_t)g->p.ptr) {
+ /* Rotation is handled by the drawing routines */
+ case GDISP_ROTATE_0:
+ case GDISP_ROTATE_180:
+ g->g.Height = GDISP_SCREEN_HEIGHT;
+ g->g.Width = GDISP_SCREEN_WIDTH;
+ break;
+ case GDISP_ROTATE_90:
+ case GDISP_ROTATE_270:
+ g->g.Height = GDISP_SCREEN_WIDTH;
+ g->g.Width = GDISP_SCREEN_HEIGHT;
+ break;
+ default:
+ return;
+ }
+ g->g.Orientation = (orientation_t)g->p.ptr;
+ return;
+
+ case GDISP_CONTROL_CONTRAST:
+ if ((unsigned)g->p.ptr > 100)
+ g->p.ptr = (void *)100;
+ acquire_bus(g);
+ write_cmd2(g, SSD1306_SETCONTRAST, (((unsigned)g->p.ptr)<<8)/101);
+ release_bus(g);
+ g->g.Contrast = (unsigned)g->p.ptr;
+ return;
+
+ // Our own special controller code to inverse the display
+ // 0 = normal, 1 = inverse
+ case GDISP_CONTROL_INVERSE:
+ acquire_bus(g);
+ write_cmd(g, g->p.ptr ? SSD1306_INVERTDISPLAY : SSD1306_NORMALDISPLAY);
+ release_bus(g);
+ return;
+ }
+ }
+#endif // GDISP_NEED_CONTROL
+
+#endif // GFX_USE_GDISP
+
diff --git a/drivers/gdisp/SSD1306/gdisp_lld_board_example_i2c.h b/drivers/gdisp/SSD1306/gdisp_lld_board_example_i2c.h
deleted file mode 100644
index 0e7e153a..00000000
--- a/drivers/gdisp/SSD1306/gdisp_lld_board_example_i2c.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * This file is subject to the terms of the GFX License. If a copy of
- * the license was not distributed with this file, you can obtain one at:
- *
- * http://ugfx.org/license.html
- */
-
-#ifndef _GDISP_LLD_BOARD_H
-#define _GDISP_LLD_BOARD_H
-
-#define SSD1306_RESET_PORT GPIOB
-#define SSD1306_RESET_PIN 5
-
-/**
- * The default slave address is 0x3D, (talking about
- * only the real address part here) and the slave
- * address can be changed to 0x3C by soldering the
- * SA0 pads on the bottom side of the module.
- *
- * b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0
- * --------------------------------------
- * 0 | 1 | 1 | 1 | 1 | 0 |SA0 | R/W
- */
-#define SSD1306_I2C_ADDRESS 0x3D
-#define SSD1306_SDA_PORT GPIOB
-#define SSD1306_SDA_PIN 7
-#define SSD1306_SCL_PORT GPIOB
-#define SSD1306_SCL_PIN 6
-#define SET_RST palSetPad(SSD1306_RESET_PORT, SSD1306_RESET_PIN);
-#define CLR_RST palClearPad(SSD1306_RESET_PORT, SSD1306_RESET_PIN);
-int8_t vccstate;
-int32_t row_offset = 0;
-
-// I2C configuration structure.
-static I2CConfig i2cconfig;
-
-
-/**
- * @brief Initialize the board for the display.
- * @notes This board definition uses GPIO and assumes exclusive access to these GPIO pins
- * @notapi
- */
-static inline void init_board(void) {
-
- // RESET pin.
- palSetPadMode(SSD1306_RESET_PORT, SSD1306_RESET_PIN, PAL_MODE_OUTPUT_PUSHPULL);
-
-
- /*
- * Initializes the I2C driver 1. The I2C1 signals are routed as follows:
- * PB6 - SCL.
- * PB7 - SDA.
- * Timing value comes from ST I2C config tool (xls):
- * 0x00901D2B; // 100kHz Standard Mode
- * 0x00300444; // 100kHz Fast Mode
- * 0x0030020A; // 400kHz Fast Mode
- * 0x00100002; // 800kHz Fast Mode +
- */
- i2cconfig.timingr = 0x00100002; // 800kHz Fast Mode+
- i2cInit();
- palSetPadMode(SSD1306_SCL_PORT, SSD1306_SCL_PIN, PAL_MODE_ALTERNATE(1));
- palSetPadMode(SSD1306_SDA_PORT, SSD1306_SDA_PIN, PAL_MODE_ALTERNATE(1));
- vccstate = SSD1306_SWITCHCAPVCC;
-}
-
-/**
- * @brief Set or clear the lcd reset pin.
- * @param[in] state TRUE = lcd in reset, FALSE = normal operation
- * @notapi
- */
-static inline void setpin_reset(bool_t state) {
- if(state)
- SET_RST
- else
- CLR_RST
-}
-
-/**
- * @brief Set the lcd back-light level.
- * @param[in] percent 0 to 100%
- * @notapi
- */
-static inline void set_backlight(uint8_t percent) {
- // Since we are on OLED no backlight needed
-}
-
-/**
- * @brief Take exclusive control of the bus
- * @notapi
- */
-static inline void acquire_bus(void) {
- i2cAcquireBus(&I2CD1);
-}
-
-/**
- * @brief Release exclusive control of the bus
- * @notapi
- */
-static inline void release_bus(void) {
- i2cReleaseBus(&I2CD1);
-}
-
-/**
- * @brief Send command to the display.
- * @param[in] cmd The command to send *
- * @notapi
- */
-static inline void write_cmd(uint8_t cmd) {
- uint8_t command[] = { 0x00, // Co = 0, D/C = 0
- cmd },
- txLength = sizeof(command)/sizeof(command[0]),
- rxLength = 0;
- i2cStart(&I2CD1, &i2cconfig);
- i2cMasterTransmitTimeout(&I2CD1, SSD1306_I2C_ADDRESS, command, txLength, NULL, rxLength, MS2ST(10));
- i2cStop(&I2CD1);
-}
-
-/**
- * @brief Send data to the display.
- * @param[in] data The data to send
- * @notapi
- */
-static inline void write_data(uint8_t* data, uint16_t length) {
- uint8_t command[length+1],
- txLength = length+1,
- rxLength = 0;
- command[0] = 0x40; // Co = 0, D/C = 1
- memmove(&command[1], data, length);
-
- i2cStart(&I2CD1, &i2cconfig);
- i2cMasterTransmitTimeout(&I2CD1, SSD1306_I2C_ADDRESS, command, txLength, NULL, rxLength, MS2ST(10));
- i2cStop(&I2CD1);
-}
-
-#endif /* _GDISP_LLD_BOARD_H */
-/** @} */
-
diff --git a/drivers/gdisp/SSD1306/gdisp_lld_board_example_spi.h b/drivers/gdisp/SSD1306/gdisp_lld_board_example_spi.h
deleted file mode 100644
index 232cd58c..00000000
--- a/drivers/gdisp/SSD1306/gdisp_lld_board_example_spi.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * This file is subject to the terms of the GFX License. If a copy of
- * the license was not distributed with this file, you can obtain one at:
- *
- * http://ugfx.org/license.html
- */
-
-#ifndef _GDISP_LLD_BOARD_H
-#define _GDISP_LLD_BOARD_H
-
-#define SSD1306_RESET_PORT GPIOB
-#define SSD1306_RESET_PIN 5
-#define SSD1306_MISO_PORT GPIOB
-#define SSD1306_MISO_PIN 8
-#define SSD1306_MOSI_PORT GPIOB
-#define SSD1306_MOSI_PIN 7
-#define SSD1306_SCK_PORT GPIOB
-#define SSD1306_SCK_PIN 6
-#define SSD1306_CS_PORT GPIOB
-#define SSD1306_CS_PIN 5
-#define SET_RST palSetPad(SSD1306_RESET_PORT, SSD1306_RESET_PIN);
-#define CLR_RST palClearPad(SSD1306_RESET_PORT, SSD1306_RESET_PIN);
-int8_t vccstate;
-int32_t row_offset = 0;
-
-/*
- * SPI1 configuration structure.
- * Speed 42MHz, CPHA=0, CPOL=0, 8bits frames, MSb transmitted first.
- * The slave select line is the pin 4 on the port GPIOA.
- */
-static const SPIConfig spi1config = {
- NULL,
- /* HW dependent part.*/
- SSD1306_MISO_PORT,
- SSD1306_MISO_PIN,
- 0
- //SPI_CR1_BR_0
-};
-
-/**
- * @brief Initialize the board for the display.
- * @notes This board definition uses GPIO and assumes exclusive access to these GPIO pins
- * @notapi
- */
-static inline void init_board(void) {
-
- // RESET pin.
- palSetPadMode(SSD1306_RESET_PORT, SSD1306_RESET_PIN, PAL_MODE_OUTPUT_PUSHPULL);
-
- spiInit();
- palSetPadMode(SSD1306_MISO_PORT, SSD1306_MISO_PIN, PAL_MODE_ALTERNATE(1)|
- PAL_STM32_OSPEED_HIGHEST);
- palSetPadMode(SSD1306_MOSI_PORT, SSD1306_MOSI_PIN, PAL_MODE_ALTERNATE(1)|
- PAL_STM32_OSPEED_HIGHEST);
- palSetPadMode(SSD1306_SCK_PORT, SSD1306_SCK_PIN, PAL_MODE_ALTERNATE(1)|
- PAL_STM32_OSPEED_HIGHEST);
- palSetPad(SSD1306_CS_PORT, SSD1306_CS_PIN);
- palSetPadMode(SSD1306_CS_PORT, SSD1306_CS_PIN, PAL_MODE_ALTERNATE(1)|
- PAL_STM32_OSPEED_HIGHEST);
- vccstate = SSD1306_SWITCHCAPVCC;
-}
-
-/**
- * @brief Set or clear the lcd reset pin.
- * @param[in] state TRUE = lcd in reset, FALSE = normal operation
- * @notapi
- */
-static inline void setpin_reset(bool_t state) {
- if(state)
- SET_RST
- else
- CLR_RST
-}
-
-/**
- * @brief Set the lcd back-light level.
- * @param[in] percent 0 to 100%
- * @notapi
- */
-static inline void set_backlight(uint8_t percent) {
- // Since we are on OLED no backlight needed
-}
-
-/**
- * @brief Take exclusive control of the bus
- * @notapi
- */
-static inline void acquire_bus(void) {
- spiAcquireBus(&SPID1);
-}
-
-/**
- * @brief Release exclusive control of the bus
- * @notapi
- */
-static inline void release_bus(void) {
- spiReleaseBus(&SPID1);
-}
-
-/**
- * @brief Send command to the display.
- * @param[in] cmd The command to send *
- * @notapi
- */
-static inline void write_cmd(uint8_t cmd) {
- uint8_t command[] = { 0x00, // Co = 0, D/C = 0
- cmd },
- txLength = sizeof(command)/sizeof(command[0]),
- rxLength = 0;
-
- spiStart(&SPID1, &spi1config);
- spiSelect(&SPID1);
- spiStartSend(&SPID1, txLength, command);
- spiUnselect(&SPID1);
- spiStop(&SPID1);
-}
-
-/**
- * @brief Send data to the display.
- * @param[in] data The data to send
- * @notapi
- */
-static inline void write_data(uint8_t* data, uint16_t length) {
- uint8_t command[length+1],
- txLength = length+1;
- command[0] = 0x40; // Co = 0, D/C = 1
- memmove(&command[1], data, length);
-
- spiStart(&SPID1, &spi1config);
- spiSelect(&SPID1);
- spiStartSend(&SPID1, txLength, command);
- spiUnselect(&SPID1);
- spiStop(&SPID1);
-}
-
-
-#endif /* _GDISP_LLD_BOARD_H */
-/** @} */
-
diff --git a/drivers/gdisp/SSD1306/gdisp_lld_board_template.h b/drivers/gdisp/SSD1306/gdisp_lld_board_template.h
deleted file mode 100644
index 48028e83..00000000
--- a/drivers/gdisp/SSD1306/gdisp_lld_board_template.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * This file is subject to the terms of the GFX License. If a copy of
- * the license was not distributed with this file, you can obtain one at:
- *
- * http://ugfx.org/license.html
- */
-
-#ifndef _GDISP_LLD_BOARD_H
-#define _GDISP_LLD_BOARD_H
-
-/**
- * @brief Initialize the board for the display.
- * @notes This board definition uses GPIO and assumes exclusive access to these GPIO pins
- * @notapi
- */
-static inline void init_board(void) {
-
-}
-
-/**
- * @brief Set or clear the lcd reset pin.
- * @param[in] state TRUE = lcd in reset, FALSE = normal operation
- * @notapi
- */
-static inline void setpin_reset(bool_t state) {
-
-}
-
-/**
- * @brief Set the lcd back-light level.
- * @param[in] percent 0 to 100%
- * @notapi
- */
-static inline void set_backlight(uint8_t percent) {
- // Since we are on OLED no backlight needed
-}
-
-/**
- * @brief Take exclusive control of the bus
- * @notapi
- */
-static inline void acquire_bus(void) {
-
-}
-
-/**
- * @brief Release exclusive control of the bus
- * @notapi
- */
-static inline void release_bus(void) {
-
-}
-
-/**
- * @brief Send command to the display.
- * @param[in] cmd The command to send *
- * @notapi
- */
-static inline void write_cmd(uint8_t cmd) {
-
-}
-
-/**
- * @brief Send data to the display.
- * @param[in] data The data to send
- * @notapi
- */
-static inline void write_data(uint8_t* data, uint16_t length) {
-
-}
-
-#endif /* _GDISP_LLD_BOARD_H */
-/** @} */
-
diff --git a/drivers/gdisp/SSD1306/gdisp_lld_config.h b/drivers/gdisp/SSD1306/gdisp_lld_config.h
index f0efc18e..627de17b 100644
--- a/drivers/gdisp/SSD1306/gdisp_lld_config.h
+++ b/drivers/gdisp/SSD1306/gdisp_lld_config.h
@@ -14,16 +14,16 @@
/* Driver hardware support. */
/*===========================================================================*/
-#define GDISP_DRIVER_NAME "SSD1306"
-
-#define GDISP_HARDWARE_CLEARS FALSE
-#define GDISP_HARDWARE_FILLS TRUE
-#define GDISP_HARDWARE_BITFILLS FALSE
-#define GDISP_HARDWARE_SCROLL TRUE
-#define GDISP_HARDWARE_PIXELREAD FALSE
+#define GDISP_HARDWARE_FLUSH TRUE // This controller requires flushing
+#define GDISP_HARDWARE_DRAWPIXEL TRUE
+#define GDISP_HARDWARE_PIXELREAD TRUE
#define GDISP_HARDWARE_CONTROL TRUE
-#define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_MONO
+#define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_MONO
+
+// This controller supports a special gdispControl() to inverse the display.
+// Pass a parameter of 1 for inverse and 0 for normal.
+#define GDISP_CONTROL_INVERSE (GDISP_CONTROL_LLD+0)
#endif /* GFX_USE_GDISP */
diff --git a/drivers/gdisp/SSD1963/board_SSD1963_template.h b/drivers/gdisp/SSD1963/board_SSD1963_template.h
new file mode 100644
index 00000000..5e1999b8
--- /dev/null
+++ b/drivers/gdisp/SSD1963/board_SSD1963_template.h
@@ -0,0 +1,148 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/SSD1963/board_SSD1963_template.h
+ * @brief GDISP Graphic Driver subsystem board interface for the SSD1963 display.
+ *
+ * @addtogroup GDISP
+ * @{
+ */
+
+#ifndef _GDISP_LLD_BOARD_H
+#define _GDISP_LLD_BOARD_H
+
+/**
+ * @brief LCD panel specs
+ *
+ * @note The timings need to follow the datasheet for your particular TFT/LCD screen
+ * (the actual screen, not the controller).
+ * @note Datasheets normally use a specific set of timings and acronyms, their value refers
+ * to the number of pixel clocks. Non-display periods refer to pulses/timings that occur
+ * before or after the timings that actually put pixels on the screen. Display periods
+ * refer to pulses/timings that directly put pixels on the screen.
+ * @note HDP: Horizontal Display Period, normally the width - 1<br>
+ * HT: Horizontal Total period (display + non-display)<br>
+ * HPS: non-display period between the start of the horizontal sync (LLINE) signal
+ * and the first display data<br>
+ * LPS: horizontal sync pulse (LLINE) start location in pixel clocks<br>
+ * HPW: Horizontal sync Pulse Width<br>
+ * VDP: Vertical Display period, normally height - 1<br>
+ * VT: Vertical Total period (display + non-display)<br>
+ * VPS: non-display period in lines between the start of the frame and the first display
+ * data in number of lines<br>
+ * FPS: vertical sync pulse (LFRAME) start location in lines.<br>
+ * VPW: Vertical sync Pulse Width
+ * @note Here's how to convert them:<br>
+ * SCREEN_HSYNC_FRONT_PORCH = ( HT - HPS ) - GDISP_SCREEN_WIDTH<br>
+ * SCREEN_HSYNC_PULSE = HPW<br>
+ * SCREEN_HSYNC_BACK_PORCH = HPS - HPW<br>
+ * SCREEN_VSYNC_FRONT_PORCH = ( VT - VPS ) - GDISP_SCREEN_HEIGHT<br>
+ * SCREEN_VSYNC_PULSE = VPW<br>
+ * SCREEN_VSYNC_BACK_PORCH = VPS - LPS<br>
+ */
+
+static const LCD_Parameters DisplayTimings[] = {
+ // You need one of these array elements per display
+ {
+ 480, 272, // Panel width and height
+ 2, 2, 41, // Horizontal Timings (back porch, front porch, pulse)
+ CALC_PERIOD(480,2,2,41), // Total Horizontal Period (calculated from above line)
+ 2, 2, 10, // Vertical Timings (back porch, front porch, pulse)
+ CALC_PERIOD(272,2,2,10), // Total Vertical Period (calculated from above line)
+ CALC_FPR(480,272,2,2,41,2,2,10,60ULL) // FPR - the 60ULL is the frames per second. Note the ULL!
+ },
+};
+
+/**
+ * @brief Initialise the board for the display.
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @note Set the g->board member to whatever is appropriate. For multiple
+ * displays this might be a pointer to the appropriate register set.
+ *
+ * @notapi
+ */
+static inline void init_board(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief After the initialisation.
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void post_init_board(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Set or clear the lcd reset pin.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] state TRUE = lcd in reset, FALSE = normal operation
+ *
+ * @notapi
+ */
+static inline void setpin_reset(GDisplay *g, bool_t state) {
+ (void) g;
+ (void) state;
+}
+
+/**
+ * @brief Take exclusive control of the bus
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void acquire_bus(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Release exclusive control of the bus
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void release_bus(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Send data to the index register.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] index The index register to set
+ *
+ * @notapi
+ */
+static inline void write_index(GDisplay *g, uint16_t index) {
+ (void) g;
+ (void) index;
+}
+
+/**
+ * @brief Send data to the lcd.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] data The data to send
+ *
+ * @notapi
+ */
+static inline void write_data(GDisplay *g, uint16_t data) {
+ (void) g;
+ (void) data;
+}
+
+#endif /* _GDISP_LLD_BOARD_H */
+/** @} */
diff --git a/drivers/gdisp/SSD1963/gdisp_lld.c b/drivers/gdisp/SSD1963/gdisp_lld.c
deleted file mode 100644
index 39889731..00000000
--- a/drivers/gdisp/SSD1963/gdisp_lld.c
+++ /dev/null
@@ -1,427 +0,0 @@
-/*
- * This file is subject to the terms of the GFX License. If a copy of
- * the license was not distributed with this file, you can obtain one at:
- *
- * http://ugfx.org/license.html
- */
-
-/**
- * @file drivers/gdisp/SSD1963/gdisp_lld.c
- * @brief GDISP Graphics Driver subsystem low level driver source.
- *
- * @addtogroup GDISP
- * @{
- */
-
-#include "gfx.h"
-
-#if GFX_USE_GDISP /*|| defined(__DOXYGEN__)*/
-
-/* Include the emulation code for things we don't support */
-#include "gdisp/lld/emulation.c"
-
-#include "ssd1963.h"
-
-/* All the board specific code should go in these include file so the driver
- * can be ported to another board just by creating a suitable file.
- */
-#include "gdisp_lld_board.h"
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-
-/* ---- Required Routines ---- */
-/*
- The following 2 routines are required.
- All other routines are optional.
-*/
-
-/**
- * @brief Low level GDISP driver initialisation.
- * @return TRUE if successful, FALSE on error.
- *
- * @notapi
- */
-bool_t gdisp_lld_init(void) {
- /* Initialise the display */
-
- init_board();
-
- write_index(SSD1963_SOFT_RESET);
- gfxSleepMicroseconds(100);
-
- /* Driver PLL config */
- write_index(SSD1963_SET_PLL_MN);
- write_data(35); // PLLclk = REFclk (10Mhz) * 36 (360Mhz)
- write_data(2); // SYSclk = PLLclk / 3 (120MHz)
- write_data(4); // Apply calculation bit, else it is ignored
-
- write_index(SSD1963_SET_PLL); // Enable PLL
- write_data(0x01);
- gfxSleepMicroseconds(200);
-
- write_index(SSD1963_SET_PLL); // Use PLL
- write_data(0x03);
- gfxSleepMicroseconds(200);
-
- write_index(SSD1963_SOFT_RESET);
- gfxSleepMicroseconds(100);
-
- /* Screen size */
- write_index(SSD1963_SET_GDISP_MODE);
-// write_data(0x0000);
- write_data(0b00011000); //Enabled dithering
- write_data(0x0000);
- write_data(mHIGH((GDISP_SCREEN_WIDTH+1)));
- write_data((GDISP_SCREEN_WIDTH+1));
- write_data(mHIGH((GDISP_SCREEN_HEIGHT+1)));
- write_data((GDISP_SCREEN_HEIGHT+1));
- write_data(0x0000);
-
- write_index(SSD1963_SET_PIXEL_DATA_INTERFACE);
- write_data(SSD1963_PDI_16BIT565);
-
- /* LCD Clock specs */
- write_index(SSD1963_SET_LSHIFT_FREQ);
- write_data((GDISP_FPR >> 16) & 0xFF);
- write_data((GDISP_FPR >> 8) & 0xFF);
- write_data(GDISP_FPR & 0xFF);
-
- write_index(SSD1963_SET_HORI_PERIOD);
- write_data(mHIGH(SCREEN_HSYNC_PERIOD));
- write_data(mLOW(SCREEN_HSYNC_PERIOD));
- write_data(mHIGH((SCREEN_HSYNC_PULSE + SCREEN_HSYNC_BACK_PORCH)));
- write_data(mLOW((SCREEN_HSYNC_PULSE + SCREEN_HSYNC_BACK_PORCH)));
- write_data(SCREEN_HSYNC_PULSE);
- write_data(0x00);
- write_data(0x00);
- write_data(0x00);
-
- write_index(SSD1963_SET_VERT_PERIOD);
- write_data(mHIGH(SCREEN_VSYNC_PERIOD));
- write_data(mLOW(SCREEN_VSYNC_PERIOD));
- write_data(mHIGH((SCREEN_VSYNC_PULSE + SCREEN_VSYNC_BACK_PORCH)));
- write_data(mLOW((SCREEN_VSYNC_PULSE + SCREEN_VSYNC_BACK_PORCH)));
- write_data(SCREEN_VSYNC_PULSE);
- write_data(0x00);
- write_data(0x00);
-
- /* Tear effect indicator ON. This is used to tell the host MCU when the driver is not refreshing the panel (during front/back porch) */
- write_index(SSD1963_SET_TEAR_ON);
- write_data(0x0000);
-
- /* Turn on */
- write_index(SSD1963_SET_DISPLAY_ON);
-
- set_backlight(0xE5);//set to 90% brightness
-
- post_init_board();
-
- /* Initialise the GDISP structure to match */
- GDISP.Width = GDISP_SCREEN_WIDTH;
- GDISP.Height = GDISP_SCREEN_HEIGHT;
- GDISP.Orientation = GDISP_ROTATE_0;
- GDISP.Powermode = powerOn;
- GDISP.Backlight = 100;
- GDISP.Contrast = 50;
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- GDISP.clipx0 = 0;
- GDISP.clipy0 = 0;
- GDISP.clipx1 = GDISP.Width;
- GDISP.clipy1 = GDISP.Height;
- #endif
-
- return TRUE;
-}
-
-void gdisp_lld_setwindow(coord_t x0, coord_t y0, coord_t x1, coord_t y1) {
- /* We don't need to validate here as the LLD routines will validate first.
- *
- * #if GDISP_NEED_VALIDATION
- * if (x0 >= GDISP.Width || y0 >= GDISP.Height || x0 < 0 || y0 < 0) return;
- * else if (x1 >= GDISP.Width || y1 >= GDISP.Height || y1 < 0 || y2 < 0) return;
- * #endif
- */
- write_index(SSD1963_SET_PAGE_ADDRESS);
- write_data((y0 >> 8) & 0xFF);
- write_data((y0 >> 0) & 0xFF);
- write_data((y1 >> 8) & 0xFF);
- write_data((y1 >> 0) & 0xFF);
- write_index(SSD1963_SET_COLUMN_ADDRESS);
- write_data((x0 >> 8) & 0xFF);
- write_data((x0 >> 0) & 0xFF);
- write_data((x1 >> 8) & 0xFF);
- write_data((x1 >> 0) & 0xFF);
-}
-
-/**
- * @brief Draws a pixel on the display.
- *
- * @param[in] x X location of the pixel
- * @param[in] y Y location of the pixel
- * @param[in] color The color of the pixel
- *
- * @notapi
- */
-void gdisp_lld_draw_pixel(coord_t x, coord_t y, color_t color) {
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- if (x < GDISP.clipx0 || y < GDISP.clipy0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
- #endif
-
- gdisp_lld_setwindow(x, y, x, y);
- write_index(SSD1963_WRITE_MEMORY_START);
- write_data(color);
-}
-
-/* ---- Optional Routines ---- */
-
-#if GDISP_HARDWARE_FILLS || defined(__DOXYGEN__)
- /**
- * @brief Fill an area with a color.
- * @note Optional - The high level driver can emulate using software.
- *
- * @param[in] x, y The start filled area
- * @param[in] cx, cy The width and height to be filled
- * @param[in] color The color of the fill
- *
- * @notapi
- */
- void gdisp_lld_fill_area(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
- uint32_t area;
-
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; }
- if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; }
- if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
- if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
- if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
- #endif
-
- area = cx*cy;
-
- gdisp_lld_setwindow(x, y, x+cx-1, y+cy-1);
- write_index(SSD1963_WRITE_MEMORY_START);
-
- #if defined(GDISP_USE_FSMC) && defined(GDISP_USE_DMA) && defined(GDISP_DMA_STREAM)
- uint8_t i;
- dmaStreamSetPeripheral(GDISP_DMA_STREAM, &color);
- dmaStreamSetMode(GDISP_DMA_STREAM, STM32_DMA_CR_PL(0) | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_DIR_M2M);
- for (i = area/65535; i; i--) {
- dmaStreamSetTransactionSize(GDISP_DMA_STREAM, 65535);
- dmaStreamEnable(GDISP_DMA_STREAM);
- dmaWaitCompletion(GDISP_DMA_STREAM);
- }
- dmaStreamSetTransactionSize(GDISP_DMA_STREAM, area%65535);
- dmaStreamEnable(GDISP_DMA_STREAM);
- dmaWaitCompletion(GDISP_DMA_STREAM);
- #else
- uint32_t index;
- for(index = 0; index < area; index++)
- write_data(color);
- #endif //#ifdef GDISP_USE_DMA
-}
-#endif
-
-#if GDISP_HARDWARE_BITFILLS || defined(__DOXYGEN__)
- /**
- * @brief Fill an area with a bitmap.
- * @note Optional - The high level driver can emulate using software.
- *
- * @param[in] x, y The start filled area
- * @param[in] cx, cy The width and height to be filled
- * @param[in] srcx, srcy The bitmap position to start the fill from
- * @param[in] srccx The width of a line in the bitmap.
- * @param[in] buffer The pixels to use to fill the area.
- *
- * @notapi
- */
- void gdisp_lld_blit_area_ex(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx, coord_t srcy, coord_t srccx, const pixel_t *buffer) {
-
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; srcx += GDISP.clipx0 - x; x = GDISP.clipx0; }
- if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; srcy += GDISP.clipy0 - y; y = GDISP.clipy0; }
- if (srcx+cx > srccx) cx = srccx - srcx;
- if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
- if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
- if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
- #endif
-
- gdisp_lld_setwindow(x, y, x+cx-1, y+cy-1);
- write_index(SSD1963_WRITE_MEMORY_START);
-
- buffer += srcx + srcy * srccx;
-
- #if defined(GDISP_USE_FSMC) && defined(GDISP_USE_DMA) && defined(GDISP_DMA_STREAM)
- uint32_t area = cx*cy;
- uint8_t i;
- dmaStreamSetPeripheral(GDISP_DMA_STREAM, buffer);
- dmaStreamSetMode(GDISP_DMA_STREAM, STM32_DMA_CR_PL(0) | STM32_DMA_CR_PINC | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_DIR_M2M);
- for (i = area/65535; i; i--) {
- dmaStreamSetTransactionSize(GDISP_DMA_STREAM, 65535);
- dmaStreamEnable(GDISP_DMA_STREAM);
- dmaWaitCompletion(GDISP_DMA_STREAM);
- }
- dmaStreamSetTransactionSize(GDISP_DMA_STREAM, area%65535);
- dmaStreamEnable(GDISP_DMA_STREAM);
- dmaWaitCompletion(GDISP_DMA_STREAM);
- #else
- coord_t endx, endy;
- uint32_t lg;
- endx = srcx + cx;
- endy = y + cy;
- lg = srccx - cx;
- for(; y < endy; y++, buffer += lg)
- for(x=srcx; x < endx; x++)
- write_data(*buffer++);
- #endif //#ifdef GDISP_USE_DMA
- }
-#endif
-
-#if (GDISP_NEED_SCROLL && GDISP_HARDWARE_SCROLL) || defined(__DOXYGEN__)
- /**
- * @brief Scroll vertically a section of the screen.
- * @note Optional.
- * @note If x,y + cx,cy is off the screen, the result is undefined.
- * @note If lines is >= cy, it is equivelent to a area fill with bgcolor.
- *
- * @param[in] x, y The start of the area to be scrolled
- * @param[in] cx, cy The size of the area to be scrolled
- * @param[in] lines The number of lines to scroll (Can be positive or negative)
- * @param[in] bgcolor The color to fill the newly exposed area.
- *
- * @notapi
- */
- void gdisp_lld_vertical_scroll(coord_t x, coord_t y, coord_t cx, coord_t cy, int lines, color_t bgcolor) {
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; }
- if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; }
- if (!lines || cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
- if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
- if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
- #endif
- /* NOT IMPLEMENTED YET */
-
- /*
- uint16_t size = x1 - x0 ;
-
- write_index(SSD1963_SET_SCROLL_AREA);
- write_data((x0 >> 8) & 0xFF);
- write_data((x0 >> 0) & 0xFF);
- write_data((size >> 8) & 0xFF);
- write_data((size >> 0) & 0xFF);
- write_data(((lcd_height-x1) >> 8) & 0xFF);
- write_data(((lcd_height-x1) >> 0) & 0xFF);
-
- write_index(SSD1963_SET_SCROLL_START);
- write_data((lines >> 8) & 0xFF);
- write_data((lines >> 0) & 0xFF);
- */
- }
-
-#endif
-
-#if (GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL) || defined(__DOXYGEN__)
- /**
- * @brief Driver Control
- * @details Unsupported control codes are ignored.
- * @note The value parameter should always be typecast to (void *).
- * @note There are some predefined and some specific to the low level driver.
- * @note GDISP_CONTROL_POWER - Takes a gdisp_powermode_t
- * GDISP_CONTROL_ORIENTATION - Takes a gdisp_orientation_t
- * GDISP_CONTROL_BACKLIGHT - Takes an int from 0 to 100. For a driver
- * that only supports off/on anything other
- * than zero is on.
- * GDISP_CONTROL_CONTRAST - Takes an int from 0 to 100.
- * GDISP_CONTROL_LLD - Low level driver control constants start at
- * this value.
- *
- * @param[in] what What to do.
- * @param[in] value The value to use (always cast to a void *).
- *
- * @notapi
- */
- void gdisp_lld_control(unsigned what, void *value) {
- /* NOT IMPLEMENTED YET */
- switch(what) {
- case GDISP_CONTROL_POWER:
- if (GDISP.Powermode == (gdisp_powermode_t)value)
- return;
- switch((gdisp_powermode_t)value) {
- case powerOff:
- write_index(SSD1963_EXIT_SLEEP_MODE); // leave sleep mode
- gfxSleepMilliseconds(5);
- write_index(SSD1963_SET_DISPLAY_OFF);
- write_index(SSD1963_SET_DEEP_SLEEP); // enter deep sleep mode
- break;
- case powerOn:
- read_reg(0x0000); gfxSleepMilliseconds(5); // 2x Dummy reads to wake up from deep sleep
- read_reg(0x0000); gfxSleepMilliseconds(5);
- if (GDISP.Powermode != powerSleep)
- gdisp_lld_init();
- write_index(SSD1963_SET_DISPLAY_ON);
-
- break;
- case powerSleep:
- write_index(SSD1963_SET_DISPLAY_OFF);
- write_index(SSD1963_ENTER_SLEEP_MODE); // enter sleep mode
- gfxSleepMilliseconds(5);
- break;
- default:
- return;
- }
- GDISP.Powermode = (gdisp_powermode_t)value;
- return;
- case GDISP_CONTROL_ORIENTATION:
- if (GDISP.Orientation == (gdisp_orientation_t)value)
- return;
- switch((gdisp_orientation_t)value) {
- case GDISP_ROTATE_0:
- /* Code here */
- GDISP.Height = GDISP_SCREEN_HEIGHT;
- GDISP.Width = GDISP_SCREEN_WIDTH;
- break;
- case GDISP_ROTATE_90:
- /* Code here */
- GDISP.Height = GDISP_SCREEN_WIDTH;
- GDISP.Width = GDISP_SCREEN_HEIGHT;
- break;
- case GDISP_ROTATE_180:
- /* Code here */
- GDISP.Height = GDISP_SCREEN_HEIGHT;
- GDISP.Width = GDISP_SCREEN_WIDTH;
- break;
- case GDISP_ROTATE_270:
- /* Code here */
- GDISP.Height = GDISP_SCREEN_WIDTH;
- GDISP.Width = GDISP_SCREEN_HEIGHT;
- break;
- default:
- return;
- }
- #if GDISP_NEED_CLIP || GDISP_NEED_VALIDATION
- GDISP.clipx0 = 0;
- GDISP.clipy0 = 0;
- GDISP.clipx1 = GDISP.Width;
- GDISP.clipy1 = GDISP.Height;
- #endif
- GDISP.Orientation = (gdisp_orientation_t)value;
- return;
- case GDISP_CONTROL_BACKLIGHT:
- gdisp_lld_bg_dimmer(54 + ((uint8_t)value) << 1);//turn 0..100% in 54..255
- return;
-/*
- case GDISP_CONTROL_CONTRAST:
-*/
- }
- }
-#endif
-
-#endif /* GFX_USE_GDISP */
-/** @} */
-
diff --git a/drivers/gdisp/SSD1963/gdisp_lld.mk b/drivers/gdisp/SSD1963/gdisp_lld.mk
index c2ce22b6..f56f11de 100644
--- a/drivers/gdisp/SSD1963/gdisp_lld.mk
+++ b/drivers/gdisp/SSD1963/gdisp_lld.mk
@@ -1,6 +1,2 @@
-# List the required driver.
-GFXSRC += $(GFXLIB)/drivers/gdisp/SSD1963/gdisp_lld.c
-
-# Required include directories
GFXINC += $(GFXLIB)/drivers/gdisp/SSD1963
-
+GFXSRC += $(GFXLIB)/drivers/gdisp/SSD1963/gdisp_lld_SSD1963.c
diff --git a/drivers/gdisp/SSD1963/gdisp_lld_SSD1963.c b/drivers/gdisp/SSD1963/gdisp_lld_SSD1963.c
new file mode 100644
index 00000000..eb1b9b15
--- /dev/null
+++ b/drivers/gdisp/SSD1963/gdisp_lld_SSD1963.c
@@ -0,0 +1,285 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/SSD1963/gdisp_lld.c
+ * @brief GDISP Graphics Driver subsystem low level driver source.
+ */
+
+#include "gfx.h"
+
+#if GFX_USE_GDISP
+
+#define GDISP_DRIVER_VMT GDISPVMT_SSD1963
+#include "../drivers/gdisp/SSD1963/gdisp_lld_config.h"
+#include "gdisp/lld/gdisp_lld.h"
+
+#define CALC_PERIOD(w,b,f,p) (p+b+w+f)
+#define CALC_FPR(w,h,hb,hf,hp,vb,vf,vp,fps) ((fps * CALC_PERIOD(w,hb,hf,hp) * CALC_PERIOD(h,vb,vf,vp) * 1048576)/100000000)
+
+typedef struct LCD_Parameters {
+ coord_t width, height; // Panel width and height
+ uint16_t hbporch; // Horizontal Back Porch
+ uint16_t hfporch; // Horizontal Front Porch
+ uint16_t hpulse; // Horizontal Pulse
+ uint16_t hperiod; // Horizontal Period (Total)
+ uint16_t vbporch; // Vertical Back Porch
+ uint16_t vfporch; // Vertical Front Porch
+ uint16_t vpulse; // Vertical Pulse
+ uint16_t vperiod; // Vertical Period (Total)
+ uint32_t fpr; // Calculated FPR
+} LCD_Parameters;
+
+#include "board_SSD1963.h"
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+#ifndef GDISP_INITIAL_CONTRAST
+ #define GDISP_INITIAL_CONTRAST 50
+#endif
+#ifndef GDISP_INITIAL_BACKLIGHT
+ #define GDISP_INITIAL_BACKLIGHT 90
+#endif
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+#include "ssd1963.h"
+
+#define write_reg(g, reg, data) { write_index(g, reg); write_data(g, data); }
+#define write_data16(g, data) { write_data(g, (data)>>8); write_data(g, (data) & 0xFF); }
+
+static inline void set_viewport(GDisplay* g) {
+ write_index(g, SSD1963_SET_PAGE_ADDRESS);
+ write_data16(g, g->p.y);
+ write_data16(g, g->p.y+g->p.cy-1);
+ write_index(g, SSD1963_SET_COLUMN_ADDRESS);
+ write_data16(g, g->p.x);
+ write_data16(g, g->p.x+g->p.cx-1);
+ write_index(g, SSD1963_WRITE_MEMORY_START);
+}
+
+/**
+ * The backlight is controlled by the controller.
+ */
+static inline void set_backlight(GDisplay *g, uint8_t percent) {
+ //duty_cycle is 00..FF
+ //Work in progress: the SSD1963 has a built-in PWM, its output can
+ //be used by a Dynamic Background Control or by a host (user)
+ //Check your LCD's hardware, the PWM connection is default left open and instead
+ //connected to a LED connection on the breakout board
+ write_index(g, SSD1963_SET_PWM_CONF); //set PWM for BackLight
+ write_data(g, 0x01);
+ write_data(g, (55+percent*2) & 0x00FF);
+ write_data(g, 0x01); //controlled by host (not DBC), enabled
+ write_data(g, 0xFF);
+ write_data(g, 0x60); //don't let it go too dark, avoid a useless LCD
+ write_data(g, 0x0F); //prescaler ???
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
+ LCD_Parameters * lcdp;
+
+ // The private area for this controller is the LCD timings
+ lcdp = (void *)&DisplayTimings[g->controllerdisplay];
+ g->priv = lcdp;
+
+ // Initialise the board interface
+ init_board(g);
+
+ // Hardware reset
+ setpin_reset(g, TRUE);
+ gfxSleepMilliseconds(20);
+ setpin_reset(g, FALSE);
+ gfxSleepMilliseconds(20);
+
+ // Get the bus for the following initialisation commands
+ acquire_bus(g);
+
+ write_index(g, SSD1963_SOFT_RESET);
+ gfxSleepMilliseconds(5);
+
+ /* Driver PLL config */
+ write_index(g, SSD1963_SET_PLL_MN);
+ write_data(g, 35); // PLLclk = REFclk (10Mhz) * 36 (360Mhz)
+ write_data(g, 2); // SYSclk = PLLclk / 3 (120MHz)
+ write_data(g, 4); // Apply calculation bit, else it is ignored
+ write_reg(g, SSD1963_SET_PLL, 0x01); // Enable PLL
+ gfxSleepMilliseconds(5);
+ write_reg(g, SSD1963_SET_PLL, 0x03); // Use PLL
+ gfxSleepMilliseconds(5);
+ write_index(g, SSD1963_SOFT_RESET);
+ gfxSleepMilliseconds(5);
+
+ /* Screen size */
+ write_index(g, SSD1963_SET_GDISP_MODE);
+ write_data(g, 0x18); //Enabled dithering
+ write_data(g, 0x00);
+ write_data16(g, lcdp->width-1);
+ write_data16(g, lcdp->height-1);
+ write_data(g, 0x00); // RGB
+
+ write_reg(g, SSD1963_SET_PIXEL_DATA_INTERFACE, SSD1963_PDI_16BIT565);
+
+ /* LCD Clock specs */
+ write_index(g, SSD1963_SET_LSHIFT_FREQ);
+ write_data(g, (lcdp->fpr >> 16) & 0xFF);
+ write_data(g, (lcdp->fpr >> 8) & 0xFF);
+ write_data(g, lcdp->fpr & 0xFF);
+
+ write_index(g, SSD1963_SET_HORI_PERIOD);
+ write_data16(g, lcdp->hperiod);
+ write_data16(g, lcdp->hpulse + lcdp->hbporch);
+ write_data(g, lcdp->hpulse);
+ write_data(g, 0x00);
+ write_data(g, 0x00);
+ write_data(g, 0x00);
+
+ write_index(g, SSD1963_SET_VERT_PERIOD);
+ write_data16(g, lcdp->vperiod);
+ write_data16(g, lcdp->vpulse + lcdp->vbporch);
+ write_data(g, lcdp->vpulse);
+ write_data(g, 0x00);
+ write_data(g, 0x00);
+
+ /* Tear effect indicator ON. This is used to tell the host MCU when the driver is not refreshing the panel (during front/back porch) */
+ write_reg(g, SSD1963_SET_TEAR_ON, 0x00);
+
+ /* Turn on */
+ write_index(g, SSD1963_SET_DISPLAY_ON);
+
+ /* Turn on the back-light */
+ set_backlight(g, GDISP_INITIAL_BACKLIGHT);
+
+ // Finish Init
+ post_init_board(g);
+
+ // Release the bus
+ release_bus(g);
+
+ /* Initialise the GDISP structure */
+ g->g.Width = lcdp->width;
+ g->g.Height = lcdp->height;
+ g->g.Orientation = GDISP_ROTATE_0;
+ g->g.Powermode = powerOn;
+ g->g.Backlight = GDISP_INITIAL_BACKLIGHT;
+ g->g.Contrast = GDISP_INITIAL_CONTRAST;
+ return TRUE;
+}
+
+#if GDISP_HARDWARE_STREAM_WRITE
+ LLDSPEC void gdisp_lld_write_start(GDisplay *g) {
+ acquire_bus(g);
+ set_viewport(g);
+ }
+ LLDSPEC void gdisp_lld_write_color(GDisplay *g) {
+ write_data(g, COLOR2NATIVE(g->p.color));
+ }
+ LLDSPEC void gdisp_lld_write_stop(GDisplay *g) {
+ release_bus(g);
+ }
+#endif
+
+// Not implemented yet.
+#if 0 && GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL
+ LLDSPEC void gdisp_lld_control(GDisplay *g) {
+ switch(g->p.x) {
+ case GDISP_CONTROL_POWER:
+ if (g->g.Powermode == (powermode_t)g->p.ptr)
+ return;
+ switch((powermode_t)g->p.ptr) {
+ case powerOff:
+ acquire_bus(g);
+ write_index(g, SSD1963_EXIT_SLEEP_MODE); // leave sleep mode
+ gfxSleepMilliseconds(5);
+ write_index(g, SSD1963_SET_DISPLAY_OFF);
+ write_index(g, SSD1963_SET_DEEP_SLEEP); // enter deep sleep mode
+ release_bus(g);
+ break;
+ case powerOn:
+ acquire_bus(g);
+ read_reg(0x0000); gfxSleepMilliseconds(5); // 2x Dummy reads to wake up from deep sleep
+ read_reg(0x0000); gfxSleepMilliseconds(5);
+ write_index(g, SSD1963_SET_DISPLAY_ON);
+ release_bus(g);
+ break;
+ case powerSleep:
+ acquire_bus(g);
+ write_index(g, SSD1963_SET_DISPLAY_OFF);
+ write_index(g, SSD1963_ENTER_SLEEP_MODE); // enter sleep mode
+ release_bus(g);
+ break;
+ default:
+ return;
+ }
+ g->g.Powermode = (powermode_t)g->p.ptr;
+ return;
+
+ case GDISP_CONTROL_ORIENTATION:
+ if (g->g.Orientation == (orientation_t)g->p.ptr)
+ return;
+ case GDISP_ROTATE_0:
+ acquire_bus(g);
+ /* Code here */
+ release_bus(g);
+ g->g.Height = ((LCD_Parameters *)g->priv)->height;
+ g->g.Width = ((LCD_Parameters *)g->priv)->width;
+ break;
+ case GDISP_ROTATE_90:
+ acquire_bus(g);
+ /* Code here */
+ release_bus(g);
+ g->g.Height = ((LCD_Parameters *)g->priv)->width;
+ g->g.Width = ((LCD_Parameters *)g->priv)->height;
+ break;
+ case GDISP_ROTATE_180:
+ acquire_bus(g);
+ /* Code here */
+ release_bus(g);
+ g->g.Height = ((LCD_Parameters *)g->priv)->height;
+ g->g.Width = ((LCD_Parameters *)g->priv)->width;
+ break;
+ case GDISP_ROTATE_270:
+ acquire_bus(g);
+ /* Code here */
+ release_bus(g);
+ g->g.Height = ((LCD_Parameters *)g->priv)->width;
+ g->g.Width = ((LCD_Parameters *)g->priv)->height;
+ break;
+ default:
+ return;
+ }
+ g->g.Orientation = (orientation_t)g->p.ptr;
+ return;
+
+ case GDISP_CONTROL_BACKLIGHT:
+ if ((unsigned)g->p.ptr > 100)
+ g->p.ptr = (void *)100;
+ set_backlight(g, (unsigned)g->p.ptr);
+ g->g.Backlight = (unsigned)g->p.ptr;
+ return;
+
+ //case GDISP_CONTROL_CONTRAST:
+ default:
+ return;
+ }
+ }
+#endif
+
+#endif /* GFX_USE_GDISP */
+
diff --git a/drivers/gdisp/SSD1963/gdisp_lld_board_example_fsmc.h b/drivers/gdisp/SSD1963/gdisp_lld_board_example_fsmc.h
deleted file mode 100644
index a2c296b9..00000000
--- a/drivers/gdisp/SSD1963/gdisp_lld_board_example_fsmc.h
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * This file is subject to the terms of the GFX License. If a copy of
- * the license was not distributed with this file, you can obtain one at:
- *
- * http://chibios-gfx.com/license.html
- */
-
-/**
- * @file drivers/gdisp/SSD1963/gdisp_lld_board_example_fsmc.h
- * @brief GDISP Graphic Driver subsystem board interface for the SSD1963 display.
- *
- * @details This file demonstrates how to interface an SSD1963 based display to an
- * STM32 microcontroller using ChibiOS/RT.
- *
- * @addtogroup GDISP
- * @{
- */
-
-#ifndef _GDISP_LLD_BOARD_H
-#define _GDISP_LLD_BOARD_H
-
-/* Using FSMC A16 as RS */
-#define GDISP_REG (*((volatile uint16_t *) 0x60000000)) /* RS = 0 */
-#define GDISP_RAM (*((volatile uint16_t *) 0x60020000)) /* RS = 1 */
-
-/**
- * @brief Send data to the index register.
- *
- * @param[in] index The index register to set
- *
- * @notapi
- */
-static inline void write_index(uint16_t index) {
- GDISP_REG = index;
-}
-
-/**
- * @brief Send data to the lcd.
- *
- * @param[in] data The data to send
- *
- * @notapi
- */
-static inline void write_data(uint16_t data) {
- GDISP_RAM = data;
-}
-
-/**
- * @brief Initialise the board for the display.
- * @notes Performs the following functions:
- * 1. initialise the io port used by your display
- * 2. initialise the reset pin (initial state not-in-reset)
- * 3. initialise the chip select pin (initial state not-active)
- * 4. initialise the backlight pin (initial state back-light off)
- *
- * @notapi
- */
-static inline void init_board(void) {
- const unsigned char FSMC_Bank = 0;
-
- #if defined(STM32F1XX) || defined(STM32F3XX)
- /* FSMC setup for F1/F3 */
- rccEnableAHB(RCC_AHBENR_FSMCEN, 0);
-
- #if defined(GDISP_USE_DMA) && defined(GDISP_DMA_STREAM)
- #error "DMA not implemented for F1/F3 Devices"
- #endif
- #elif defined(STM32F4XX) || defined(STM32F2XX)
- /* STM32F2-F4 FSMC init */
- rccEnableAHB3(RCC_AHB3ENR_FSMCEN, 0);
-
- #if defined(GDISP_USE_DMA) && defined(GDISP_DMA_STREAM)
- if (dmaStreamAllocate(GDISP_DMA_STREAM, 0, NULL, NULL)) gfxExit();
- dmaStreamSetMemory0(GDISP_DMA_STREAM, &GDISP_RAM);
- dmaStreamSetMode(GDISP_DMA_STREAM, STM32_DMA_CR_PL(0) | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_DIR_M2M);
- #endif
- #else
- #error "FSMC not implemented for this device"
- #endif
-
-< /* set pins to FSMC mode */
- IOBus busD = {GPIOD, (1 << 0) | (1 << 1) | (1 << 4) | (1 << 5) | (1 << 7) | (1 << 8) |
- (1 << 9) | (1 << 10) | (1 << 11) | (1 << 14) | (1 << 15), 0};
-
- IOBus busE = {GPIOE, (1 << 7) | (1 << 8) | (1 << 9) | (1 << 10) | (1 << 11) | (1 << 12) |
- (1 << 13) | (1 << 14) | (1 << 15), 0};
-
- palSetBusMode(&busD, PAL_MODE_ALTERNATE(12));
- palSetBusMode(&busE, PAL_MODE_ALTERNATE(12));
-
- /* FSMC timing */
- FSMC_Bank1->BTCR[FSMC_Bank+1] = (FSMC_BTR1_ADDSET_1 | FSMC_BTR1_ADDSET_3) \
- | (FSMC_BTR1_DATAST_1 | FSMC_BTR1_DATAST_3) \
- | (FSMC_BTR1_BUSTURN_1 | FSMC_BTR1_BUSTURN_3) ;
-
- /* Bank1 NOR/SRAM control register configuration
- * This is actually not needed as already set by default after reset */
- FSMC_Bank1->BTCR[FSMC_Bank] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN;
-}
-
-static inline void post_init_board(void) {
- const unsigned char FSMC_Bank = 0;
- /* FSMC delay reduced as the controller now runs at full speed */
- FSMC_Bank1->BTCR[FSMC_Bank+1] = FSMC_BTR1_ADDSET_0 | FSMC_BTR1_DATAST_2 | FSMC_BTR1_BUSTURN_0 ;
- FSMC_Bank1->BTCR[FSMC_Bank] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN;
-}
-
-/**
- * @brief Set or clear the lcd reset pin.
- *
- * @param[in] state TRUE = lcd in reset, FALSE = normal operation
- *
- * @notapi
- */
-static inline void setpin_reset(bool_t state) {
- (void) state;
- /* Nothing to do here */
-}
-
-/**
- * @brief Set the lcd back-light level.
- *
- * @param[in] percent 0 to 100%
- *
- * @notapi
- */
-static inline void set_backlight(uint8_t percent) {
- //duty_cycle is 00..FF
- //Work in progress: the SSD1963 has a built-in PWM, its output can
- //be used by a Dynamic Background Control or by a host (user)
- //Check your LCD's hardware, the PWM connection is default left open and instead
- //connected to a LED connection on the breakout board
- write_index(SSD1963_SET_PWM_CONF);//set PWM for BackLight
- write_data(0x0001);
- write_data(percent & 0x00FF);
- write_data(0x0001);//controlled by host (not DBC), enabled
- write_data(0x00FF);
- write_data(0x0060);//don't let it go too dark, avoid a useless LCD
- write_data(0x000F);//prescaler ???
-}
-
-/**
- * @brief Take exclusive control of the bus
- *
- * @notapi
- */
-static inline void acquire_bus(void) {
- /* Nothing to do here */
-}
-
-/**
- * @brief Release exclusive control of the bus
- *
- * @notapi
- */
-static inline void release_bus(void) {
- /* Nothing to do here */
-}
-
-#if GDISP_HARDWARE_READPIXEL || GDISP_HARDWARE_SCROLL || defined(__DOXYGEN__)
-/**
- * @brief Read data from the lcd.
- *
- * @return The data from the lcd
- * @note The chip select may need to be asserted/de-asserted
- * around the actual spi read
- *
- * @notapi
- */
-static inline uint16_t read_data(void) {
- return GDISP_RAM;
-}
-#endif
-
-#endif /* _GDISP_LLD_BOARD_H */
-/** @} */
-
diff --git a/drivers/gdisp/SSD1963/gdisp_lld_board_example_gpio.h b/drivers/gdisp/SSD1963/gdisp_lld_board_example_gpio.h
deleted file mode 100644
index 38f5b2a5..00000000
--- a/drivers/gdisp/SSD1963/gdisp_lld_board_example_gpio.h
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * This file is subject to the terms of the GFX License. If a copy of
- * the license was not distributed with this file, you can obtain one at:
- *
- * http://chibios-gfx.com/license.html
- */
-
-/**
- * @file drivers/gdisp/SSD1963/gdisp_lld_board_example_gpio.h
- * @brief GDISP Graphic Driver subsystem board interface for the SSD1963 display.
- *
- * @brief This file demonstrates how to interface an SSD1963 based display using
- * a GPIO interface of an STM32 out of ChibiOS/RT.
- *
- * @addtogroup GDISP
- * @{
- */
-
-#ifndef _GDISP_LLD_BOARD_H
-#define _GDISP_LLD_BOARD_H
-
-/**
- * @brief The GPIO pin config
- *
- * @details This block of defines tell your driver how you wired your display
- * controller to your MCU. Please change them accordingly.
- */
-#define GDISP_CMD_PORT GPIOC
-#define GDISP_DATA_PORT GPIOD
-#define GDISP_CS 0
-#define GDISP_RS 1
-#define GDISP_WR 2
-#define GDISP_RD 3
-
-#define Set_CS palSetPad(GDISP_CMD_PORT, GDISP_CS);
-#define Clr_CS palClearPad(GDISP_CMD_PORT, GDISP_CS);
-#define Set_RS palSetPad(GDISP_CMD_PORT, GDISP_RS);
-#define Clr_RS palClearPad(GDISP_CMD_PORT, GDISP_RS);
-#define Set_WR palSetPad(GDISP_CMD_PORT, GDISP_WR);
-#define Clr_WR palClearPad(GDISP_CMD_PORT, GDISP_WR);
-#define Set_RD palSetPad(GDISP_CMD_PORT, GDISP_RD);
-#define Clr_RD palClearPad(GDISP_CMD_PORT, GDISP_RD);
-
-/**
- * @brief Send data to the index register.
- *
- * @param[in] index The index register to set
- *
- * @notapi
- */
-static inline void write_index(uint16_t index) {
- Set_CS; Set_RS; Set_WR; Clr_RD;
-
- palWritePort(GDISP_DATA_PORT, index);
-
- Clr_CS;
-}
-
-/**
- * @brief Send data to the lcd.
- *
- * @param[in] data The data to send
- *
- * @notapi
- */
-static inline void write_data(uint16_t data) {
- Set_CS; Clr_RS; Set_WR; Clr_RD;
-
- palWritePort(GDISP_DATA_PORT, data);
-
- Clr_CS;
-}
-
-/**
- * @brief Initialise the board for the display.
- *
- * @notapi
- */
-static inline void init_board(void) {
- IOBus busCMD = {GDISP_CMD_PORT, (1 << GDISP_CS) | (1 << GDISP_RS) | (1 << GDISP_WR) | (1 << GDISP_RD), 0};
- IOBus busDATA = {GDISP_CMD_PORT, 0xFFFFF, 0};
- palSetBusMode(&busCMD, PAL_MODE_OUTPUT_PUSHPULL);
- palSetBusMode(&busDATA, PAL_MODE_OUTPUT_PUSHPULL);
-}
-
-static inline void post_init_board(void) {
- /* Nothing to do here */
-}
-
-/**
- * @brief Set or clear the lcd reset pin.
- *
- * @param[in] state TRUE = lcd in reset, FALSE = normal operation
- *
- * @notapi
- */
-static inline void setpin_reset(bool_t state) {
- /* optional */
-}
-
-/**
- * @brief Set the lcd back-light level.
- *
- * @param[in] percent 0 to 100%
- *
- * @notapi
- */
-static inline void set_backlight(uint8_t percent) {
- //duty_cycle is 00..FF
- //Work in progress: the SSD1963 has a built-in PWM, its output can
- //be used by a Dynamic Background Control or by a host (user)
- //Check your LCD's hardware, the PWM connection is default left open and instead
- //connected to a LED connection on the breakout board
- write_index(SSD1963_SET_PWM_CONF);//set PWM for BackLight
- write_data(0x0001);
- write_data(percent & 0x00FF);
- write_data(0x0001);//controlled by host (not DBC), enabled
- write_data(0x00FF);
- write_data(0x0060);//don't let it go too dark, avoid a useless LCD
- write_data(0x000F);//prescaler ???
-}
-
-/**
- * @brief Take exclusive control of the bus
- *
- * @notapi
- */
-static inline void acquire_bus(void) {
- /* Nothing to do here */
-}
-
-/**
- * @brief Release exclusive control of the bus
- *
- * @notapi
- */
-static inline void release_bus(void) {
- /* Nothing to do here */
-}
-
-__inline void write_stream(uint16_t *buffer, uint16_t size) {
- uint16_t i;
-
- Set_CS; Clr_RS; Set_WR; Clr_RD;
-
- for (i = 0; i < size; i++) {
- Set_WR;
- palWritePort(GDISP_DATA_PORT, buffer[i]);
- Clr_WR;
- }
-
- Clr_CS;
-}
-
-__inline void read_stream(uint16_t *buffer, size_t size) {
- uint16_t i;
-
- Set_CS; Clr_RS; Clr_WR; Set_RD;
-
- for (i = 0; i < size; i++) {
- Set_RD;
- buffer[i] = palReadPort(GDISP_DATA_PORT);
- Clr_RD;
- }
-}
-
-#if GDISP_HARDWARE_READPIXEL || GDISP_HARDWARE_SCROLL || defined(__DOXYGEN__)
-/**
- * @brief Read data from the lcd.
- *
- * @return The data from the lcd
- * @note The chip select may need to be asserted/de-asserted
- * around the actual spi read
- *
- * @notapi
- */
-static inline uint16_t read_data(void) {
- uint16_t data;
-
- Set_CS; Clr_RS; Clr_WR; Set_RD;
-
- data = palReadPort(GDISP_DATA_PORT);
-
- Clr_CS;
-
- return data;
-}
-#endif
-
-#endif /* _GDISP_LLD_BOARD_H */
-/** @} */
diff --git a/drivers/gdisp/SSD1963/gdisp_lld_board_template.h b/drivers/gdisp/SSD1963/gdisp_lld_board_template.h
deleted file mode 100644
index 44cd3712..00000000
--- a/drivers/gdisp/SSD1963/gdisp_lld_board_template.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * This file is subject to the terms of the GFX License. If a copy of
- * the license was not distributed with this file, you can obtain one at:
- *
- * http://ugfx.org/license.html
- */
-
-/**
- * @file drivers/gdisp/SSD1963/gdisp_lld_board_template.h
- * @brief GDISP Graphic Driver subsystem board interface for the SSD1963 display.
- *
- * @addtogroup GDISP
- * @{
- */
-
-#ifndef _GDISP_LLD_BOARD_H
-#define _GDISP_LLD_BOARD_H
-
-/**
- * @brief Send data to the index register.
- *
- * @param[in] index The index register to set
- *
- * @notapi
- */
-static inline void write_index(uint16_t index) {
-
-}
-
-/**
- * @brief Send data to the lcd.
- *
- * @param[in] data The data to send
- *
- * @notapi
- */
-static inline void write_data(uint16_t data) {
-
-}
-
-/**
- * @brief Initialise the board for the display.
- * @notes Performs the following functions:
- * 1. initialise the io port used by your display
- * 2. initialise the reset pin (initial state not-in-reset)
- * 3. initialise the chip select pin (initial state not-active)
- * 4. initialise the backlight pin (initial state back-light off)
- *
- * @notapi
- */
-static inline void init_board(void) {
-
-}
-
-static inline void post_init_board(void) {
-
-}
-
-/**
- * @brief Set or clear the lcd reset pin.
- *
- * @param[in] state TRUE = lcd in reset, FALSE = normal operation
- *
- * @notapi
- */
-static inline void setpin_reset(bool_t state) {
-
-}
-
-/**
- * @brief Set the lcd back-light level.
- *
- * @param[in] percent 0 to 100%
- *
- * @notapi
- */
-static inline void set_backlight(uint8_t percent) {
-
-}
-
-/**
- * @brief Take exclusive control of the bus
- *
- * @notapi
- */
-static inline void acquire_bus(void) {
-
-}
-
-/**
- * @brief Release exclusive control of the bus
- *
- * @notapi
- */
-static inline void release_bus(void) {
-
-}
-
-#if GDISP_HARDWARE_READPIXEL || GDISP_HARDWARE_SCROLL || defined(__DOXYGEN__)
-/**
- * @brief Read data from the lcd.
- *
- * @return The data from the lcd
- * @note The chip select may need to be asserted/de-asserted
- * around the actual spi read
- *
- * @notapi
- */
-static inline uint16_t read_data(void) {
-
-}
-#endif
-
-#endif /* _GDISP_LLD_BOARD_H */
-/** @} */
diff --git a/drivers/gdisp/SSD1963/gdisp_lld_config.h b/drivers/gdisp/SSD1963/gdisp_lld_config.h
index 70eec579..8ad94738 100644
--- a/drivers/gdisp/SSD1963/gdisp_lld_config.h
+++ b/drivers/gdisp/SSD1963/gdisp_lld_config.h
@@ -22,16 +22,10 @@
/* Driver hardware support. */
/*===========================================================================*/
-#define GDISP_DRIVER_NAME "SSD1963"
-#define GDISP_LLD(x) gdisp_lld_##x##_SSD1963
+#define GDISP_HARDWARE_STREAM_WRITE TRUE
+//#define GDISP_HARDWARE_CONTROL TRUE // Not Yet.
-#define GDISP_HARDWARE_FILLS TRUE
-#define GDISP_HARDWARE_BITFILLS TRUE
-/* Maybe someday soon */
-#define GDISP_HARDWARE_SCROLL FALSE
-#define GDISP_HARDWARE_CONTROL FALSE
-
-#define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_RGB565
+#define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_RGB565
#endif /* GFX_USE_GDISP */
diff --git a/drivers/gdisp/SSD1963/gdisp_lld_panel_example.h b/drivers/gdisp/SSD1963/gdisp_lld_panel_example.h
deleted file mode 100644
index 72095495..00000000
--- a/drivers/gdisp/SSD1963/gdisp_lld_panel_example.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * This file is subject to the terms of the GFX License. If a copy of
- * the license was not distributed with this file, you can obtain one at:
- *
- * http://ugfx.org/license.html
- */
-
-/**
- * @file drivers/gdisp/SSD1963/gdisp_lld_panel_example.h
- * @brief TFT LCD panel properties.
- *
- * @addtogroup GDISP
- * @{
- */
-
-#ifndef _GDISP_LLD_PANEL_H
-#define _GDISP_LLD_PANEL_H
-
-/* LCD panel specs */
-
-/* The timings need to follow the datasheet for your particular TFT/LCD screen (the actual screen, not the controller)
-*** Datasheets normally use a specific set of timings and acronyms, their value refers to the number of pixel clocks
-** Non-display periods refer to pulses/timings that occur before or after the timings that actually put pixels on the screen
-** Display periods refer to pulses/timings that directly put pixels on the screen
-HDP: Horizontal Display Period, normally the width - 1
-HT: Horizontal Total period (display + non-display)
-HPS: non-display period between the start of the horizontal sync (LLINE) signal and the first display data
-LPS: horizontal sync pulse (LLINE) start location in pixel clocks
-HPW: Horizontal sync Pulse Width
-VDP: Vertical Display period, normally height - 1
-VT: Vertical Total period (display + non-display)
-VPS: non-display period in lines between the start of the frame and the first display data in number of lines
-FPS: vertical sync pulse (LFRAME) start location in lines.
-VPW: Vertical sync Pulse Width
-
-*** Here's how to convert them:
-HPS = SCREEN_HSYNC_PULSE + SCREEN_HSYNC_BACK_PORCH
-HT - HPS = GDISP_SCREEN_WIDTH + SCREEN_HSYNC_FRONT_PORCH
-=> SCREEN_HSYNC_FRONT_PORCH = ( HT - HPS ) - GDISP_SCREEN_WIDTH
- SCREEN_HSYNC_PULSE = HPW
- SCREEN_HSYNC_BACK_PORCH = HPS - HPW
- SCREEN_HSYNC_PERIOD = HT
-
-VPS = SCREEN_VSYNC_PULSE + SCREEN_VSYNC_BACK_PORCH
-VT - VPS = GDISP_SCREEN_HEIGHT + SCREEN_VSYNC_FRONT_PORCH
-=> SCREEN_VSYNC_FRONT_PORCH = ( VT - VPS ) - GDISP_SCREEN_HEIGHT
- SCREEN_VSYNC_PULSE = VPW
- SCREEN_VSYNC_BACK_PORCH = VPS - LPS
- SCREEN_VSYNC_PERIOD = VT
-*/
-
-#define SCREEN_FPS 60ULL
-
-//The following values are for a 4.3" TFT LCD
-
-#define GDISP_SCREEN_WIDTH 480
-#define GDISP_SCREEN_HEIGHT 272
-
-#define SCREEN_HSYNC_BACK_PORCH 2
-#define SCREEN_HSYNC_FRONT_PORCH 2
-#define SCREEN_HSYNC_PULSE 41
-
-#define SCREEN_VSYNC_BACK_PORCH 2
-#define SCREEN_VSYNC_FRONT_PORCH 2
-#define SCREEN_VSYNC_PULSE 10
-
-#define SCREEN_HSYNC_PERIOD (SCREEN_HSYNC_PULSE + SCREEN_HSYNC_BACK_PORCH + GDISP_SCREEN_WIDTH + SCREEN_HSYNC_FRONT_PORCH)
-#define SCREEN_VSYNC_PERIOD (SCREEN_VSYNC_PULSE + SCREEN_VSYNC_BACK_PORCH + GDISP_SCREEN_HEIGHT + SCREEN_VSYNC_FRONT_PORCH)
-
-#define SCREEN_PCLK (SCREEN_HSYNC_PERIOD * SCREEN_VSYNC_PERIOD * SCREEN_FPS)
-#define GDISP_FPR ((SCREEN_PCLK * 1048576)/100000000)
-
-#endif
-/** @} */
diff --git a/drivers/gdisp/SSD1963/ssd1963.h b/drivers/gdisp/SSD1963/ssd1963.h
index 46369be6..be328775 100644
--- a/drivers/gdisp/SSD1963/ssd1963.h
+++ b/drivers/gdisp/SSD1963/ssd1963.h
@@ -8,11 +8,6 @@
#ifndef SSD1963_H
#define SSD1963_H
-#include "gdisp_lld_panel.h"
-
-#define mHIGH(x) (x >> 8)
-#define mLOW(x) (x & 0xFF)
-
/* SSD1963 commands */
#define SSD1963_NOP 0x0000
diff --git a/drivers/gdisp/SSD2119/board_SSD2119_template.h b/drivers/gdisp/SSD2119/board_SSD2119_template.h
new file mode 100644
index 00000000..b4c6341d
--- /dev/null
+++ b/drivers/gdisp/SSD2119/board_SSD2119_template.h
@@ -0,0 +1,191 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/SSD2119/board_SSD2119_template.h
+ * @brief GDISP Graphic Driver subsystem board template for the SSD2119 display.
+ *
+ * @addtogroup GDISP
+ * @{
+ */
+
+#ifndef _GDISP_LLD_BOARD_H
+#define _GDISP_LLD_BOARD_H
+
+/**
+ * @brief Initialise the board for the display.
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @note Set the g->board member to whatever is appropriate. For multiple
+ * displays this might be a pointer to the appropriate register set.
+ *
+ * @notapi
+ */
+static inline void init_board(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief After the initialisation.
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void post_init_board(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Set or clear the lcd reset pin.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] state TRUE = lcd in reset, FALSE = normal operation
+ *
+ * @notapi
+ */
+static inline void setpin_reset(GDisplay *g, bool_t state) {
+ (void) g;
+ (void) state;
+}
+
+/**
+ * @brief Set the lcd back-light level.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] percent 0 to 100%
+ *
+ * @notapi
+ */
+static inline void set_backlight(GDisplay *g, uint8_t percent) {
+ (void) g;
+ (void) percent;
+}
+
+/**
+ * @brief Take exclusive control of the bus
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void acquire_bus(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Release exclusive control of the bus
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void release_bus(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Send data to the index register.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] index The index register to set
+ *
+ * @notapi
+ */
+static inline void write_index(GDisplay *g, uint16_t index) {
+ (void) g;
+ (void) index;
+}
+
+/**
+ * @brief Send data to the lcd.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] data The data to send
+ *
+ * @notapi
+ */
+static inline void write_data(GDisplay *g, uint16_t data) {
+ (void) g;
+ (void) data;
+}
+
+/**
+ * @brief Set the bus in read mode
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void setreadmode(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Set the bus back into write mode
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void setwritemode(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Read data from the lcd.
+ * @return The data from the lcd
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline uint16_t read_data(GDisplay *g) {
+ (void) g;
+ return 0;
+}
+
+/**
+ * The below section you can replace with #error if your interface doesn't support DMA
+ */
+#if defined(GDISP_USE_DMA) || defined(__DOXYGEN__)
+ //#error "GDISP - SSD2119: This interface does not support DMA"
+
+ /**
+ * @brief Transfer data using DMA but don't increment the source address
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] buffer The source buffer location
+ * @param[in] area The number of pixels to transfer
+ *
+ * @notapi
+ */
+ static inline void dma_with_noinc(GDisplay *g, color_t *buffer, int area) {
+ (void) g;
+ (void) buffer;
+ (void) area;
+ }
+
+ /**
+ * @brief Transfer data using DMA incrementing the source address
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] buffer The source buffer location
+ * @param[in] area The number of pixels to transfer
+ *
+ * @notapi
+ */
+ static inline void dma_with_inc(GDisplay *g, color_t *buffer, int area) {
+ (void) g;
+ (void) buffer;
+ (void) area;
+ }
+#endif
+
+#endif /* _GDISP_LLD_BOARD_H */
+/** @} */
diff --git a/drivers/gdisp/SSD2119/gdisp_lld.c b/drivers/gdisp/SSD2119/gdisp_lld.c
deleted file mode 100644
index de97d805..00000000
--- a/drivers/gdisp/SSD2119/gdisp_lld.c
+++ /dev/null
@@ -1,704 +0,0 @@
-/*
- * This file is subject to the terms of the GFX License. If a copy of
- * the license was not distributed with this file, you can obtain one at:
- *
- * http://ugfx.org/license.html
- */
-
-/**
- * @file drivers/gdisp/SSD2119/gdisp_lld.c
- * @brief GDISP Graphics Driver subsystem low level driver source for the SSD2119 display.
- *
- * @addtogroup GDISP
- * @{
- */
-
-#include "gfx.h"
-
-#include "ssd2119.h"
-
-#if GFX_USE_GDISP /*|| defined(__DOXYGEN__)*/
-
-/* Include the emulation code for things we don't support */
-#include "gdisp/lld/emulation.c"
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-#ifndef GDISP_SCREEN_HEIGHT
- #define GDISP_SCREEN_HEIGHT 240
-#endif
-#ifndef GDISP_SCREEN_WIDTH
- #define GDISP_SCREEN_WIDTH 320
-#endif
-
-#define GDISP_INITIAL_CONTRAST 50
-#define GDISP_INITIAL_BACKLIGHT 100
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-#include "gdisp_lld_board.h"
-
-// Some common routines and macros
-#define write_reg(reg, data) { write_index(reg); write_data(data); }
-#define stream_start() write_index(SSD2119_REG_RAM_DATA);
-#define stream_stop()
-#define delay(us) gfxSleepMicroseconds(us)
-#define delayms(ms) gfxSleepMilliseconds(ms)
-
-static inline void set_cursor(coord_t x, coord_t y) {
- /* Reg SSD2119_REG_X_RAM_ADDR is 9 bit value
- * Reg SSD2119_REG_Y_RAM_ADDR is an 8 bit
- * Use a bit mask to make sure they are not set too high
- */
- switch(GDISP.Orientation) {
- case GDISP_ROTATE_0:
- write_reg(SSD2119_REG_X_RAM_ADDR, x & 0x01FF);
- write_reg(SSD2119_REG_Y_RAM_ADDR, y & 0x00FF);
- break;
- case GDISP_ROTATE_90:
- write_reg(SSD2119_REG_X_RAM_ADDR, (GDISP_SCREEN_WIDTH - y - 1) & 0x01FF);
- write_reg(SSD2119_REG_Y_RAM_ADDR, (GDISP_SCREEN_HEIGHT - x - 1) & 0x00FF);
- break;
- case GDISP_ROTATE_180:
- write_reg(SSD2119_REG_X_RAM_ADDR, (GDISP_SCREEN_WIDTH - 1 - x) & 0x01FF);
- write_reg(SSD2119_REG_Y_RAM_ADDR, (GDISP_SCREEN_HEIGHT - 1 - y) & 0x00FF);
- break;
- case GDISP_ROTATE_270:
- write_reg(SSD2119_REG_X_RAM_ADDR, y & 0x01FF);
- write_reg(SSD2119_REG_Y_RAM_ADDR, x & 0x00FF);
- break;
- }
-}
-
-static void set_viewport(coord_t x, coord_t y, coord_t cx, coord_t cy) {
-
- set_cursor(x, y);
-
- /* Reg 0x44 - Vertical RAM address position
- * Upper Byte - VEA
- * Lower Byte - VSA
- * 0 <= VSA <= VEA <= 0xEF
- * Reg 0x45,0x46 - Horizontal RAM address position
- * Lower 9 bits gives 0-511 range in each value, HSA and HEA respectively
- * 0 <= HSA <= HEA <= 0x13F
- */
-
- switch(GDISP.Orientation) {
- case GDISP_ROTATE_0:
- write_reg(SSD2119_REG_V_RAM_POS, (((y + cy - 1) << 8) & 0xFF00 ) | (y & 0x00FF));
- write_reg(SSD2119_REG_H_RAM_START, (x & 0x01FF));
- write_reg(SSD2119_REG_H_RAM_END, (x + cx - 1) & 0x01FF);
- break;
- case GDISP_ROTATE_90:
- write_reg(SSD2119_REG_V_RAM_POS, (((GDISP_SCREEN_HEIGHT - x - 1) & 0x00FF) << 8) | ((GDISP_SCREEN_HEIGHT - (x + cx)) & 0x00FF));
- write_reg(SSD2119_REG_H_RAM_START, (GDISP_SCREEN_WIDTH - (y + cy)) & 0x01FF);
- write_reg(SSD2119_REG_H_RAM_END, (GDISP_SCREEN_WIDTH - y - 1) & 0x01FF);
- break;
- case GDISP_ROTATE_180:
- write_reg(SSD2119_REG_V_RAM_POS, (((GDISP_SCREEN_HEIGHT - y - 1) & 0x00FF) << 8) | ((GDISP_SCREEN_HEIGHT - (y + cy)) & 0x00FF));
- write_reg(SSD2119_REG_H_RAM_START, (GDISP_SCREEN_WIDTH - (x + cx)) & 0x01FF);
- write_reg(SSD2119_REG_H_RAM_END, (GDISP_SCREEN_WIDTH - x - 1) & 0x01FF);
- break;
- case GDISP_ROTATE_270:
- write_reg(SSD2119_REG_V_RAM_POS, (((x + cx - 1) << 8) & 0xFF00 ) | (x & 0x00FF));
- write_reg(SSD2119_REG_H_RAM_START, (y & 0x01FF));
- write_reg(SSD2119_REG_H_RAM_END, (y + cy - 1) & 0x01FF);
- break;
- }
-
- set_cursor(x, y);
-}
-
-static inline void reset_viewport(void) {
- set_viewport(0, 0, GDISP.Width, GDISP.Height);
-}
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/* ---- Required Routines ---- */
-/*
- The following 2 routines are required.
- All other routines are optional.
-*/
-
-/**
- * @brief Low level GDISP driver initialization.
- *
- * @notapi
- */
-bool_t gdisp_lld_init(void) {
- /* Initialise your display */
- init_board();
-
- // Hardware reset
- setpin_reset(TRUE);
- delayms(20);
- setpin_reset(FALSE);
- delayms(20);
-
- // Get the bus for the following initialisation commands
- acquire_bus();
-
- // Enter sleep mode (if we are not already there).
- write_reg(SSD2119_REG_SLEEP_MODE_1, 0x0001);
- delay(5);
-
- // Set initial power parameters.
- write_reg(SSD2119_REG_PWR_CTRL_5, 0x00B2);
- delay(5);
- write_reg(SSD2119_REG_VCOM_OTP_1, 0x0006);
- delay(5);
-
- // Start the oscillator.
- write_reg(SSD2119_REG_OSC_START, 0x0001);
- delay(5);
-
- // Set pixel format and basic display orientation (scanning direction).
- write_reg(SSD2119_REG_OUTPUT_CTRL, 0x30EF);
- delay(5);
- write_reg(SSD2119_REG_LCD_DRIVE_AC_CTRL, 0x0600);
- delay(5);
-
- // Exit sleep mode.
- write_reg(SSD2119_REG_SLEEP_MODE_1, 0x0000);
- delay(5);
-
- // Configure pixel color format and MCU interface parameters.
- write_reg(SSD2119_REG_ENTRY_MODE, 0x6830); // ENTRY_MODE_DEFAULT
- delay(5);
-
- // Set analog parameters.
- write_reg(SSD2119_REG_SLEEP_MODE_2, 0x0999);
- delay(5);
- write_reg(SSD2119_REG_ANALOG_SET, 0x3800);
- delay(5);
-
- // Enable the display.
- write_reg(SSD2119_REG_DISPLAY_CTRL, 0x0033);
- delay(5);
-
- // Set VCIX2 voltage to 6.1V.
- write_reg(SSD2119_REG_PWR_CTRL_2, 0x0005);
- delay(5);
-
- // Configure gamma correction.
- write_reg(SSD2119_REG_GAMMA_CTRL_1, 0x0000);
- delay(5);
- write_reg(SSD2119_REG_GAMMA_CTRL_2, 0x0303);
- delay(5);
- write_reg(SSD2119_REG_GAMMA_CTRL_3, 0x0407);
- delay(5);
- write_reg(SSD2119_REG_GAMMA_CTRL_4, 0x0301);
- delay(5);
- write_reg(SSD2119_REG_GAMMA_CTRL_5, 0x0301);
- delay(5);
- write_reg(SSD2119_REG_GAMMA_CTRL_6, 0x0403);
- delay(5);
- write_reg(SSD2119_REG_GAMMA_CTRL_7, 0x0707);
- delay(5);
- write_reg(SSD2119_REG_GAMMA_CTRL_8, 0x0400);
- delay(5);
- write_reg(SSD2119_REG_GAMMA_CTRL_9, 0x0a00);
- delay(5);
- write_reg(SSD2119_REG_GAMMA_CTRL_10, 0x1000);
- delay(5);
-
- // Configure Vlcd63 and VCOMl.
- write_reg(SSD2119_REG_PWR_CTRL_3, 0x000A);
- delay(5);
- write_reg(SSD2119_REG_PWR_CTRL_4, 0x2E00);
- delay(5);
-
- // Set the display size and ensure that the GRAM window is set to allow access to the full display buffer.
- write_reg(SSD2119_REG_V_RAM_POS, (GDISP_SCREEN_HEIGHT - 1) << 8);
- delay(5);
- write_reg(SSD2119_REG_H_RAM_START, 0x0000);
- delay(5);
- write_reg(SSD2119_REG_H_RAM_END, GDISP_SCREEN_WIDTH - 1);
- delay(5);
-
- write_reg(SSD2119_REG_X_RAM_ADDR, 0x00);
- delay(5);
- write_reg(SSD2119_REG_Y_RAM_ADDR, 0x00);
- delay(5);
-
- // Release the bus
- release_bus();
-
- /* Turn on the backlight */
- set_backlight(GDISP_INITIAL_BACKLIGHT);
-
- /* Initialise the GDISP structure */
- GDISP.Width = GDISP_SCREEN_WIDTH;
- GDISP.Height = GDISP_SCREEN_HEIGHT;
- GDISP.Orientation = GDISP_ROTATE_0;
- GDISP.Powermode = powerOn;
- GDISP.Backlight = GDISP_INITIAL_BACKLIGHT;
- GDISP.Contrast = GDISP_INITIAL_CONTRAST;
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- GDISP.clipx0 = 0;
- GDISP.clipy0 = 0;
- GDISP.clipx1 = GDISP.Width;
- GDISP.clipy1 = GDISP.Height;
- #endif
- return TRUE;
-}
-
-/**
- * @brief Draws a pixel on the display.
- *
- * @param[in] x X location of the pixel
- * @param[in] y Y location of the pixel
- * @param[in] color The color of the pixel
- *
- * @notapi
- */
-void gdisp_lld_draw_pixel(coord_t x, coord_t y, color_t color) {
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- if (x < GDISP.clipx0 || y < GDISP.clipy0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
- #endif
-
- acquire_bus();
- set_cursor(x, y);
- write_reg(SSD2119_REG_RAM_DATA, color);
- release_bus();
-}
-
-/* ---- Optional Routines ---- */
-/*
- All the below routines are optional.
- Defining them will increase speed but everything
- will work if they are not defined.
- If you are not using a routine - turn it off using
- the appropriate GDISP_HARDWARE_XXXX macro.
- Don't bother coding for obvious similar routines if
- there is no performance penalty as the emulation software
- makes a good job of using similar routines.
- eg. If gfillarea() is defined there is little
- point in defining clear() unless the
- performance bonus is significant.
- For good performance it is suggested to implement
- fillarea() and blitarea().
-*/
-
-#if GDISP_HARDWARE_CLEARS || defined(__DOXYGEN__)
- /**
- * @brief Clear the display.
- * @note Optional - The high level driver can emulate using software.
- *
- * @param[in] color The color of the pixel
- *
- * @notapi
- */
- void gdisp_lld_clear(color_t color) {
- unsigned area;
-
- area = GDISP_SCREEN_WIDTH * GDISP_SCREEN_HEIGHT;
-
- acquire_bus();
- reset_viewport();
- set_cursor(0, 0);
- stream_start();
-
- #if defined(GDISP_USE_FSMC) && defined(GDISP_USE_DMA) && defined(GDISP_DMA_STREAM)
- uint8_t i;
- dmaStreamSetPeripheral(GDISP_DMA_STREAM, &color);
- dmaStreamSetMode(GDISP_DMA_STREAM, STM32_DMA_CR_PL(0) | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_DIR_M2M);
- for (i = area / 65535; i; i--) {
- dmaStreamSetTransactionSize(GDISP_DMA_STREAM, 65535);
- dmaStreamEnable(GDISP_DMA_STREAM);
- dmaWaitCompletion(GDISP_DMA_STREAM);
- }
- dmaStreamSetTransactionSize(GDISP_DMA_STREAM, area % 65535);
- dmaStreamEnable(GDISP_DMA_STREAM);
- dmaWaitCompletion(GDISP_DMA_STREAM);
- #else
- uint32_t index;
- for(index = 0; index < area; index++)
- write_data(color);
- #endif // defined(GDISP_USE_FSMC) && defined(GDISP_USE_DMA) && defined(GDISP_DMA_STREAM)
-
- stream_stop();
- release_bus();
- }
-#endif
-
-#if GDISP_HARDWARE_FILLS || defined(__DOXYGEN__)
- /**
- * @brief Fill an area with a color.
- * @note Optional - The high level driver can emulate using software.
- *
- * @param[in] x, y The start filled area
- * @param[in] cx, cy The width and height to be filled
- * @param[in] color The color of the fill
- *
- * @notapi
- */
- void gdisp_lld_fill_area(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
- unsigned area;
-
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; }
- if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; }
- if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
- if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
- if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
- #endif
-
- area = cx*cy;
-
- acquire_bus();
- set_viewport(x, y, cx, cy);
- stream_start();
-
- #if defined(GDISP_USE_FSMC) && defined(GDISP_USE_DMA) && defined(GDISP_DMA_STREAM)
- uint8_t i;
- dmaStreamSetPeripheral(GDISP_DMA_STREAM, &color);
- dmaStreamSetMode(GDISP_DMA_STREAM, STM32_DMA_CR_PL(0) | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_DIR_M2M);
- for (i = area / 65535; i; i--) {
- dmaStreamSetTransactionSize(GDISP_DMA_STREAM, 65535);
- dmaStreamEnable(GDISP_DMA_STREAM);
- dmaWaitCompletion(GDISP_DMA_STREAM);
- }
- dmaStreamSetTransactionSize(GDISP_DMA_STREAM, area % 65535);
- dmaStreamEnable(GDISP_DMA_STREAM);
- dmaWaitCompletion(GDISP_DMA_STREAM);
- #else
- uint32_t index;
- for(index = 0; index < area; index++)
- write_data(color);
- #endif // defined(GDISP_USE_FSMC) && defined(GDISP_USE_DMA) && defined(GDISP_DMA_STREAM)
-
- stream_stop();
- release_bus();
- }
-#endif
-
-#if GDISP_HARDWARE_BITFILLS || defined(__DOXYGEN__)
- /**
- * @brief Fill an area with a bitmap.
- * @note Optional - The high level driver can emulate using software.
- *
- * @param[in] x, y The start filled area
- * @param[in] cx, cy The width and height to be filled
- * @param[in] srcx, srcy The bitmap position to start the fill from
- * @param[in] srccx The width of a line in the bitmap.
- * @param[in] buffer The pixels to use to fill the area.
- *
- * @notapi
- */
- void gdisp_lld_blit_area_ex(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx, coord_t srcy, coord_t srccx, const pixel_t *buffer) {
-
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; srcx += GDISP.clipx0 - x; x = GDISP.clipx0; }
- if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; srcy += GDISP.clipy0 - y; y = GDISP.clipy0; }
- if (srcx+cx > srccx) cx = srccx - srcx;
- if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
- if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
- if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
- #endif
-
- buffer += srcx + srcy * srccx;
-
- acquire_bus();
- set_viewport(x, y, cx, cy);
- stream_start();
-
- #if defined(GDISP_USE_FSMC) && defined(GDISP_USE_DMA) && defined(GDISP_DMA_STREAM)
- uint32_t area = cx * cy;
- uint8_t i;
- dmaStreamSetPeripheral(GDISP_DMA_STREAM, buffer);
- dmaStreamSetMode(GDISP_DMA_STREAM, STM32_DMA_CR_PL(0) | STM32_DMA_CR_PINC | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_DIR_M2M);
- for (i = area / 65535; i; i--) {
- dmaStreamSetTransactionSize(GDISP_DMA_STREAM, 65535);
- dmaStreamEnable(GDISP_DMA_STREAM);
- dmaWaitCompletion(GDISP_DMA_STREAM);
- }
- dmaStreamSetTransactionSize(GDISP_DMA_STREAM, area % 65535);
- dmaStreamEnable(GDISP_DMA_STREAM);
- dmaWaitCompletion(GDISP_DMA_STREAM);
- #else
- coord_t endx, endy;
- uint32_t lg;
- endx = srcx + cx;
- endy = y + cy;
- lg = srccx - cx;
- for(; y < endy; y++, buffer += lg)
- for(x=srcx; x < endx; x++)
- write_data(*buffer++);
- #endif // defined(GDISP_USE_FSMC) && defined(GDISP_USE_DMA) && defined(GDISP_DMA_STREAM)
-
- stream_stop();
- release_bus();
- }
-#endif
-
-#if (GDISP_NEED_PIXELREAD && GDISP_HARDWARE_PIXELREAD) || defined(__DOXYGEN__)
- /**
- * @brief Get the color of a particular pixel.
- * @note Optional.
- * @note If x,y is off the screen, the result is undefined.
- *
- * @param[in] x, y The pixel to be read
- *
- * @notapi
- */
- color_t gdisp_lld_get_pixel_color(coord_t x, coord_t y) {
- color_t color;
-
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- if (x < 0 || x >= GDISP.Width || y < 0 || y >= GDISP.Height) return 0;
- #endif
-
- acquire_bus();
- set_cursor(x, y);
- stream_start();
-
- color = read_data(); // dummy read
- color = read_data();
-
- stream_stop();
- release_bus();
-
- return color;
- }
-#endif
-
-#if (GDISP_NEED_SCROLL && GDISP_HARDWARE_SCROLL) || defined(__DOXYGEN__)
- /**
- * @brief Scroll vertically a section of the screen.
- * @note Optional.
- * @note If x,y + cx,cy is off the screen, the result is undefined.
- * @note If lines is >= cy, it is equivelent to a area fill with bgcolor.
- *
- * @param[in] x, y The start of the area to be scrolled
- * @param[in] cx, cy The size of the area to be scrolled
- * @param[in] lines The number of lines to scroll (Can be positive or negative)
- * @param[in] bgcolor The color to fill the newly exposed area.
- *
- * @notapi
- */
- void gdisp_lld_vertical_scroll(coord_t x, coord_t y, coord_t cx, coord_t cy, int lines, color_t bgcolor) {
- static color_t buf[((GDISP_SCREEN_HEIGHT > GDISP_SCREEN_WIDTH ) ? GDISP_SCREEN_HEIGHT : GDISP_SCREEN_WIDTH)];
- coord_t row0, row1;
- unsigned i, gap, abslines, j;
-
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; }
- if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; }
- if (!lines || cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
- if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
- if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
- #endif
-
- abslines = lines < 0 ? -lines : lines;
-
- acquire_bus();
- if ((coord_t)abslines >= cy) {
- abslines = cy;
- gap = 0;
- } else {
- gap = cy - abslines;
- for(i = 0; i < gap; i++) {
- if(lines > 0) {
- row0 = y + i + lines;
- row1 = y + i;
- } else {
- row0 = (y - i - 1) + lines;
- row1 = (y - i - 1);
- }
-
- /* read row0 into the buffer and then write at row1*/
- set_viewport(x, row0, cx, 1);
- stream_start();
-
- j = read_data(); // dummy read
- for (j = 0; (coord_t)j < cx; j++)
- buf[j] = read_data();
-
- stream_stop();
-
- set_viewport(x, row1, cx, 1);
- stream_start();
- for (j = 0; (coord_t)j < cx; j++)
- write_data(buf[j]);
- stream_stop();
- }
- }
-
- /* fill the remaining gap */
- set_viewport(x, lines > 0 ? (y+(coord_t)gap) : y, cx, abslines);
- stream_start();
- gap = cx*abslines;
- for(i = 0; i < gap; i++) write_data(bgcolor);
- stream_stop();
- release_bus();
- }
-#endif
-
-#if (GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL) || defined(__DOXYGEN__)
- /**
- * @brief Driver Control
- * @details Unsupported control codes are ignored.
- * @note The value parameter should always be typecast to (void *).
- * @note There are some predefined and some specific to the low level driver.
- * @note GDISP_CONTROL_POWER - Takes a gdisp_powermode_t
- * GDISP_CONTROL_ORIENTATION - Takes a gdisp_orientation_t
- * GDISP_CONTROL_BACKLIGHT - Takes an int from 0 to 100. For a driver
- * that only supports off/on anything other
- * than zero is on.
- *
- * @param[in] what What to do.
- * @param[in] value The value to use (always cast to a void *).
- *
- * @notapi
- */
- void gdisp_lld_control(unsigned what, void *value) {
- switch(what) {
- case GDISP_CONTROL_POWER:
- if (GDISP.Powermode == (gdisp_powermode_t)value)
- return;
- switch((gdisp_powermode_t)value) {
- case powerOff:
- acquire_bus();
- write_reg(SSD2119_REG_SLEEP_MODE_1, 0x0001); // Enter sleep mode
- write_reg(SSD2119_REG_DISPLAY_CTRL, 0x0000); // Display off
- write_reg(SSD2119_REG_OSC_START, 0x0000); // Turn off oscillator
- release_bus();
- set_backlight(0);
- break;
-
- case powerOn:
- if (GDISP.Powermode == powerSleep) {
- acquire_bus();
- write_reg(SSD2119_REG_SLEEP_MODE_1, 0x0000); // Leave sleep mode
- write_reg(SSD2119_REG_DISPLAY_CTRL, 0x0033); // Display on
- release_bus();
- delayms(170);
- } else if (GDISP.Powermode == powerDeepSleep) {
- acquire_bus();
- write_reg(SSD2119_REG_SLEEP_MODE_2, 0x0999); // Disable deep sleep function
- write_reg(SSD2119_REG_SLEEP_MODE_1, 0x0000); // Leave sleep mode
- write_reg(SSD2119_REG_DISPLAY_CTRL, 0x0033); // Display on
- release_bus();
- delayms(170);
- } else {
- acquire_bus();
- write_reg(SSD2119_REG_SLEEP_MODE_1, 0x0000); // Leave sleep mode
- release_bus();
- gdisp_lld_init();
- }
- set_backlight(100);
- break;
-
- case powerSleep:
- acquire_bus();
- write_reg(SSD2119_REG_SLEEP_MODE_1, 0x0001); // Enter sleep mode
- write_reg(SSD2119_REG_DISPLAY_CTRL, 0x0000); // Display off
- release_bus();
- set_backlight(0);
- delayms(25);
- break;
-
- case powerDeepSleep:
- acquire_bus();
- write_reg(SSD2119_REG_SLEEP_MODE_1, 0x0001); // Enter sleep mode
- write_reg(SSD2119_REG_SLEEP_MODE_2, 0x2999); // Enable deep sleep function
- write_reg(SSD2119_REG_DISPLAY_CTRL, 0x0000); // Display off
- release_bus();
- set_backlight(0);
- delayms(25);
- break;
-
- default:
- return;
- }
- GDISP.Powermode = (gdisp_powermode_t)value;
- return;
-
- case GDISP_CONTROL_ORIENTATION:
- if (GDISP.Orientation == (gdisp_orientation_t)value)
- return;
- switch((gdisp_orientation_t)value) {
- case GDISP_ROTATE_0:
- acquire_bus();
- /* TB = 0 */
- write_reg(SSD2119_REG_OUTPUT_CTRL, 0x30EF);
- /* ID = 11 AM = 0 */
- write_reg(SSD2119_REG_ENTRY_MODE, 0x6830);
- release_bus();
- GDISP.Height = GDISP_SCREEN_HEIGHT;
- GDISP.Width = GDISP_SCREEN_WIDTH;
- break;
-
- case GDISP_ROTATE_90:
- acquire_bus();
- /* TB = 1 */
- write_reg(SSD2119_REG_OUTPUT_CTRL, 0x32EF);
- /* ID = 10 AM = 1 */
- write_reg(SSD2119_REG_ENTRY_MODE, 0x6828);
- release_bus();
- GDISP.Height = GDISP_SCREEN_WIDTH;
- GDISP.Width = GDISP_SCREEN_HEIGHT;
- break;
-
- case GDISP_ROTATE_180:
- acquire_bus();
- /* TB = 0 */
- write_reg(SSD2119_REG_OUTPUT_CTRL, 0x30EF);
- /* ID = 00 AM = 0 */
- write_reg(SSD2119_REG_ENTRY_MODE, 0x6800);
- release_bus();
- GDISP.Height = GDISP_SCREEN_HEIGHT;
- GDISP.Width = GDISP_SCREEN_WIDTH;
- break;
-
- case GDISP_ROTATE_270:
- acquire_bus();
- /* TB = 1 */
- write_reg(SSD2119_REG_OUTPUT_CTRL, 0x32EF);
- /* ID = 01 AM = 1 */
- write_reg(SSD2119_REG_ENTRY_MODE, 0x6818);
- release_bus();
- GDISP.Height = GDISP_SCREEN_WIDTH;
- GDISP.Width = GDISP_SCREEN_HEIGHT;
- break;
-
- default:
- return;
- }
-
- #if GDISP_NEED_CLIP || GDISP_NEED_VALIDATION
- GDISP.clipx0 = 0;
- GDISP.clipy0 = 0;
- GDISP.clipx1 = GDISP.Width;
- GDISP.clipy1 = GDISP.Height;
- #endif
- GDISP.Orientation = (gdisp_orientation_t)value;
- return;
-
- case GDISP_CONTROL_BACKLIGHT:
- if ((unsigned)value > 100)
- value = (void *)100;
- set_backlight((unsigned)value);
- GDISP.Backlight = (unsigned)value;
- return;
-
- default:
- return;
- }
- }
-#endif
-
-#endif /* GFX_USE_GDISP */
-/** @} */
diff --git a/drivers/gdisp/SSD2119/gdisp_lld.mk b/drivers/gdisp/SSD2119/gdisp_lld.mk
index e9c70efb..921eaa2c 100644
--- a/drivers/gdisp/SSD2119/gdisp_lld.mk
+++ b/drivers/gdisp/SSD2119/gdisp_lld.mk
@@ -1,5 +1,2 @@
-# List the required driver.
-GFXSRC += $(GFXLIB)/drivers/gdisp/SSD2119/gdisp_lld.c
-
-# Required include directories
GFXINC += $(GFXLIB)/drivers/gdisp/SSD2119
+GFXSRC += $(GFXLIB)/drivers/gdisp/SSD2119/gdisp_lld_SSD2119.c
diff --git a/drivers/gdisp/SSD2119/gdisp_lld_SSD2119.c b/drivers/gdisp/SSD2119/gdisp_lld_SSD2119.c
new file mode 100644
index 00000000..9594ff95
--- /dev/null
+++ b/drivers/gdisp/SSD2119/gdisp_lld_SSD2119.c
@@ -0,0 +1,411 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/SSD2119/gdisp_lld.c
+ * @brief GDISP Graphics Driver subsystem low level driver source for the SSD2119 display.
+ */
+
+#include "gfx.h"
+
+#if GFX_USE_GDISP
+
+#define GDISP_DRIVER_VMT GDISPVMT_SSD2119
+#include "../drivers/gdisp/SSD2119/gdisp_lld_config.h"
+#include "gdisp/lld/gdisp_lld.h"
+
+#include "board_SSD2119.h"
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+#ifndef GDISP_SCREEN_HEIGHT
+ #define GDISP_SCREEN_HEIGHT 240
+#endif
+#ifndef GDISP_SCREEN_WIDTH
+ #define GDISP_SCREEN_WIDTH 320
+#endif
+#ifndef GDISP_INITIAL_CONTRAST
+ #define GDISP_INITIAL_CONTRAST 50
+#endif
+#ifndef GDISP_INITIAL_BACKLIGHT
+ #define GDISP_INITIAL_BACKLIGHT 100
+#endif
+
+#include "ssd2119.h"
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+// Some common routines and macros
+#define dummy_read(g) { volatile uint16_t dummy; dummy = read_data(g); (void) dummy; }
+#define write_reg(g, reg, data) { write_index(g, reg); write_data(g, data); }
+
+static void set_cursor(GDisplay* g) {
+ /* Reg SSD2119_REG_X_RAM_ADDR is 9 bit value
+ * Reg SSD2119_REG_Y_RAM_ADDR is an 8 bit
+ * Use a bit mask to make sure they are not set too high
+ */
+ switch(g->g.Orientation) {
+ case GDISP_ROTATE_0:
+ write_reg(g, SSD2119_REG_X_RAM_ADDR, g->p.x & 0x01FF);
+ write_reg(g, SSD2119_REG_Y_RAM_ADDR, g->p.y & 0x00FF);
+ break;
+ case GDISP_ROTATE_90:
+ write_reg(g, SSD2119_REG_X_RAM_ADDR, g->p.y & 0x01FF);
+ write_reg(g, SSD2119_REG_Y_RAM_ADDR, (GDISP_SCREEN_HEIGHT-1 - g->p.x) & 0x00FF);
+ break;
+ case GDISP_ROTATE_180:
+ write_reg(g, SSD2119_REG_X_RAM_ADDR, (GDISP_SCREEN_WIDTH-1 - g->p.x) & 0x01FF);
+ write_reg(g, SSD2119_REG_Y_RAM_ADDR, (GDISP_SCREEN_HEIGHT-1 - g->p.y) & 0x00FF);
+ break;
+ case GDISP_ROTATE_270:
+ write_reg(g, SSD2119_REG_X_RAM_ADDR, (GDISP_SCREEN_WIDTH-1 - g->p.y) & 0x01FF);
+ write_reg(g, SSD2119_REG_Y_RAM_ADDR, g->p.x & 0x00FF);
+ break;
+ }
+ write_index(g, SSD2119_REG_RAM_DATA);
+}
+
+static void set_viewport(GDisplay* g) {
+ /* Reg 0x44 - Vertical RAM address position
+ * Upper Byte - VEA
+ * Lower Byte - VSA
+ * 0 <= VSA <= VEA <= 0xEF
+ * Reg 0x45,0x46 - Horizontal RAM address position
+ * Lower 9 bits gives 0-511 range in each value, HSA and HEA respectively
+ * 0 <= HSA <= HEA <= 0x13F
+ */
+ switch(g->g.Orientation) {
+ case GDISP_ROTATE_0:
+ write_reg(g, SSD2119_REG_V_RAM_POS, (((g->p.y + g->p.cy - 1) << 8) & 0xFF00 ) | (g->p.y & 0x00FF));
+ write_reg(g, SSD2119_REG_H_RAM_START, (g->p.x & 0x01FF));
+ write_reg(g, SSD2119_REG_H_RAM_END, (g->p.x + g->p.cx - 1) & 0x01FF);
+ break;
+ case GDISP_ROTATE_90:
+ write_reg(g, SSD2119_REG_V_RAM_POS, (((GDISP_SCREEN_HEIGHT-1 - g->p.x) & 0x00FF) << 8) | ((GDISP_SCREEN_HEIGHT - (g->p.x + g->p.cx)) & 0x00FF));
+ write_reg(g, SSD2119_REG_H_RAM_START, (g->p.y & 0x01FF));
+ write_reg(g, SSD2119_REG_H_RAM_END, (g->p.y + g->p.cy - 1) & 0x01FF);
+ break;
+ case GDISP_ROTATE_180:
+ write_reg(g, SSD2119_REG_V_RAM_POS, (((GDISP_SCREEN_HEIGHT-1 - g->p.y) & 0x00FF) << 8) | ((GDISP_SCREEN_HEIGHT - (g->p.y + g->p.cy)) & 0x00FF));
+ write_reg(g, SSD2119_REG_H_RAM_START, (GDISP_SCREEN_WIDTH - (g->p.x + g->p.cx)) & 0x01FF);
+ write_reg(g, SSD2119_REG_H_RAM_END, (GDISP_SCREEN_WIDTH-1 - g->p.x) & 0x01FF);
+ break;
+ case GDISP_ROTATE_270:
+ write_reg(g, SSD2119_REG_V_RAM_POS, (((g->p.x + g->p.cx - 1) << 8) & 0xFF00 ) | (g->p.x & 0x00FF));
+ write_reg(g, SSD2119_REG_H_RAM_START, (GDISP_SCREEN_WIDTH - (g->p.y + g->p.cy)) & 0x01FF);
+ write_reg(g, SSD2119_REG_H_RAM_END, (GDISP_SCREEN_WIDTH-1 - g->p.y) & 0x01FF);
+ break;
+ }
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+LLDSPEC bool_t gdisp_lld_init(GDisplay* g) {
+ // no private area for this controller
+ g->priv = 0;
+
+ // initialise the board interface
+ init_board(g);
+
+ // Hardware reset
+ setpin_reset(g, TRUE);
+ gfxSleepMilliseconds(20);
+ setpin_reset(g, FALSE);
+ gfxSleepMilliseconds(20);
+
+ // Get the bus for the following initialisation commands
+ acquire_bus(g);
+
+ // Enter sleep mode (if we are not already there).
+ write_reg(g, SSD2119_REG_SLEEP_MODE_1, 0x0001);
+ gfxSleepMicroseconds(5);
+
+ // Set initial power parameters.
+ write_reg(g, SSD2119_REG_PWR_CTRL_5, 0x00B2);
+ gfxSleepMicroseconds(5);
+ write_reg(g, SSD2119_REG_VCOM_OTP_1, 0x0006);
+ gfxSleepMicroseconds(5);
+
+ // Start the oscillator.
+ write_reg(g, SSD2119_REG_OSC_START, 0x0001);
+ gfxSleepMicroseconds(5);
+
+ // Set pixel format and basic display orientation (scanning direction).
+ write_reg(g, SSD2119_REG_OUTPUT_CTRL, 0x30EF);
+ gfxSleepMicroseconds(5);
+ write_reg(g, SSD2119_REG_LCD_DRIVE_AC_CTRL, 0x0600);
+ gfxSleepMicroseconds(5);
+
+ // Exit sleep mode.
+ write_reg(g, SSD2119_REG_SLEEP_MODE_1, 0x0000);
+ gfxSleepMicroseconds(5);
+
+ // Configure pixel color format and MCU interface parameters.
+ write_reg(g, SSD2119_REG_ENTRY_MODE, 0x6830); // ENTRY_MODE_DEFAULT
+ gfxSleepMicroseconds(5);
+
+ // Set analog parameters.
+ write_reg(g, SSD2119_REG_SLEEP_MODE_2, 0x0999);
+ gfxSleepMicroseconds(5);
+ write_reg(g, SSD2119_REG_ANALOG_SET, 0x3800);
+ gfxSleepMicroseconds(5);
+
+ // Enable the display.
+ write_reg(g, SSD2119_REG_DISPLAY_CTRL, 0x0033);
+ gfxSleepMicroseconds(5);
+
+ // Set VCIX2 voltage to 6.1V.
+ write_reg(g, SSD2119_REG_PWR_CTRL_2, 0x0005);
+ gfxSleepMicroseconds(5);
+
+ // Configure gamma correction.
+ write_reg(g, SSD2119_REG_GAMMA_CTRL_1, 0x0000);
+ gfxSleepMicroseconds(5);
+ write_reg(g, SSD2119_REG_GAMMA_CTRL_2, 0x0303);
+ gfxSleepMicroseconds(5);
+ write_reg(g, SSD2119_REG_GAMMA_CTRL_3, 0x0407);
+ gfxSleepMicroseconds(5);
+ write_reg(g, SSD2119_REG_GAMMA_CTRL_4, 0x0301);
+ gfxSleepMicroseconds(5);
+ write_reg(g, SSD2119_REG_GAMMA_CTRL_5, 0x0301);
+ gfxSleepMicroseconds(5);
+ write_reg(g, SSD2119_REG_GAMMA_CTRL_6, 0x0403);
+ gfxSleepMicroseconds(5);
+ write_reg(g, SSD2119_REG_GAMMA_CTRL_7, 0x0707);
+ gfxSleepMicroseconds(5);
+ write_reg(g, SSD2119_REG_GAMMA_CTRL_8, 0x0400);
+ gfxSleepMicroseconds(5);
+ write_reg(g, SSD2119_REG_GAMMA_CTRL_9, 0x0a00);
+ gfxSleepMicroseconds(5);
+ write_reg(g, SSD2119_REG_GAMMA_CTRL_10, 0x1000);
+ gfxSleepMicroseconds(5);
+
+ // Configure Vlcd63 and VCOMl.
+ write_reg(g, SSD2119_REG_PWR_CTRL_3, 0x000A);
+ gfxSleepMicroseconds(5);
+ write_reg(g, SSD2119_REG_PWR_CTRL_4, 0x2E00);
+ gfxSleepMicroseconds(5);
+
+ // Set the display size and ensure that the GRAM window is set to allow access to the full display buffer.
+ write_reg(g, SSD2119_REG_V_RAM_POS, (GDISP_SCREEN_HEIGHT - 1) << 8);
+ gfxSleepMicroseconds(5);
+ write_reg(g, SSD2119_REG_H_RAM_START, 0x0000);
+ gfxSleepMicroseconds(5);
+ write_reg(g, SSD2119_REG_H_RAM_END, GDISP_SCREEN_WIDTH - 1);
+ gfxSleepMicroseconds(5);
+
+ write_reg(g, SSD2119_REG_X_RAM_ADDR, 0x00);
+ gfxSleepMicroseconds(5);
+ write_reg(g, SSD2119_REG_Y_RAM_ADDR, 0x00);
+ gfxSleepMicroseconds(5);
+
+ // Finish Init
+ post_init_board(g);
+
+ // Release the bus
+ release_bus(g);
+
+ /* Turn on the back-light */
+ set_backlight(g, GDISP_INITIAL_BACKLIGHT);
+
+ /* Initialise the GDISP structure */
+ g->g.Width = GDISP_SCREEN_WIDTH;
+ g->g.Height = GDISP_SCREEN_HEIGHT;
+ g->g.Orientation = GDISP_ROTATE_0;
+ g->g.Powermode = powerOn;
+ g->g.Backlight = GDISP_INITIAL_BACKLIGHT;
+ g->g.Contrast = GDISP_INITIAL_CONTRAST;
+ return TRUE;
+}
+
+#if GDISP_HARDWARE_STREAM_WRITE
+ LLDSPEC void gdisp_lld_write_start(GDisplay* g) {
+ acquire_bus(g);
+ set_viewport(g);
+ }
+ LLDSPEC void gdisp_lld_write_color(GDisplay* g) {
+ write_data(g, COLOR2NATIVE(g->p.color));
+ }
+ LLDSPEC void gdisp_lld_write_stop(GDisplay* g) {
+ release_bus(g);
+ }
+ LLDSPEC void gdisp_lld_write_pos(GDisplay* g) {
+ set_cursor(g);
+ }
+#endif
+
+#if GDISP_HARDWARE_STREAM_READ
+ LLDSPEC void gdisp_lld_read_start(GDisplay* g) {
+ acquire_bus(g);
+ set_viewport(g);
+ set_cursor(g);
+ setreadmode(g);
+ dummy_read(g);
+ }
+ LLDSPEC color_t gdisp_lld_read_color(GDisplay* g) {
+ uint16_t data;
+
+ data = read_data(g);
+ return NATIVE2COLOR(data);
+ }
+ LLDSPEC void gdisp_lld_read_stop(GDisplay* g) {
+ setwritemode(g);
+ release_bus(g);
+ }
+#endif
+
+#if GDISP_HARDWARE_FILLS && defined(GDISP_USE_DMA)
+ LLDSPEC void gdisp_lld_fill_area(GDisplay* g) {
+ uint16_t c;
+
+ c = COLOR2NATIVE(g->p.color);
+ acquire_bus(g);
+ set_viewport(g);
+ set_cursor(g);
+ dma_with_noinc(g, &c, g->p.cx * g->p.cy);
+ release_bus(g);
+ }
+#endif
+
+#if GDISP_HARDWARE_BITFILLS && defined(GDISP_USE_DMA)
+ #if GDISP_PIXELFORMAT != GDISP_LLD_PIXELFORMAT
+ #error "GDISP: SSD2119: BitBlit is only available in RGB565 pixel format"
+ #endif
+
+ LLDSPEC void gdisp_lld_blit_area(GDisplay* g) {
+ pixel_t* buffer;
+ coord_t ynct;
+
+ buffer = (pixel_t*)g->p.ptr + g->p.x1 + g->p.y1 * g->p.x2;
+
+ acquire_bus(g);
+ set_viewport(g);
+ set_cursor(g);
+
+ if (g->p.x2 == g->p.cx) {
+ dma_with_inc(g, buffer, g->p.cx * g->p.cy);
+ } else {
+ for (ycnt = g->p.cy; ycnt; ycnt--, buffer += g->p.x2)
+ dma_with_inc(g, buffer, g->p.cy);
+ }
+
+ release_bus(g);
+ }
+#endif
+
+#if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL
+ LLDSPEC void gdisp_lld_control(GDisplay *g) {
+ switch(g->p.x) {
+ case GDISP_CONTROL_POWER:
+ if (g->g.Powermode == (powermode_t)g->p.ptr)
+ return;
+ switch((powermode_t)g->p.ptr) {
+ case powerOff:
+ case powerDeepSleep:
+ acquire_bus(g);
+ write_reg(g, SSD2119_REG_SLEEP_MODE_1, 0x0001); // Enter sleep mode
+ write_reg(g, SSD2119_REG_SLEEP_MODE_2, 0x2999); // Enable deep sleep function
+ write_reg(g, SSD2119_REG_DISPLAY_CTRL, 0x0000); // Display off
+ if ((powermode_t)g->p.ptr == powerOff)
+ write_reg(g, SSD2119_REG_OSC_START, 0x0000); // Turn off oscillator
+ release_bus(g);
+ set_backlight(g, 0);
+ break;
+ case powerSleep:
+ acquire_bus(g);
+ write_reg(g, SSD2119_REG_SLEEP_MODE_1, 0x0001); // Enter sleep mode
+ write_reg(g, SSD2119_REG_DISPLAY_CTRL, 0x0000); // Display off
+ release_bus(g);
+ set_backlight(g, 0);
+ break;
+ case powerOn:
+ acquire_bus(g);
+ if (g->g.Powermode == powerOff) {
+ write_reg(g, SSD2119_REG_OSC_START, 0x0001); // Start the oscillator
+ gfxSleepMicroseconds(5);
+ write_reg(g, SSD2119_REG_SLEEP_MODE_2, 0x0999); // Disable deep sleep function
+ } else if (g->g.Powermode == powerDeepSleep)
+ write_reg(g, SSD2119_REG_SLEEP_MODE_2, 0x0999); // Disable deep sleep function
+ write_reg(g, SSD2119_REG_SLEEP_MODE_1, 0x0000); // Leave sleep mode
+ write_reg(g, SSD2119_REG_DISPLAY_CTRL, 0x0033); // Display on
+ release_bus(g);
+ gfxSleepMicroseconds(25);
+ set_backlight(g, g->g.Backlight);
+ break;
+ default:
+ return;
+ }
+ g->g.Powermode = (powermode_t)g->p.ptr;
+ return;
+
+ case GDISP_CONTROL_ORIENTATION:
+ if (g->g.Orientation == (orientation_t)g->p.ptr)
+ return;
+ switch((orientation_t)g->p.ptr) {
+ case GDISP_ROTATE_0:
+ acquire_bus(g);
+ /* ID = 11 AM = 0 */
+ write_reg(g, SSD2119_REG_ENTRY_MODE, 0x6830);
+ release_bus(g);
+ g->g.Height = GDISP_SCREEN_HEIGHT;
+ g->g.Width = GDISP_SCREEN_WIDTH;
+ break;
+ case GDISP_ROTATE_90:
+ acquire_bus(g);
+ /* ID = 01 AM = 1 */
+ write_reg(g, SSD2119_REG_ENTRY_MODE, 0x6818);
+ release_bus(g);
+ g->g.Height = GDISP_SCREEN_WIDTH;
+ g->g.Width = GDISP_SCREEN_HEIGHT;
+ break;
+ case GDISP_ROTATE_180:
+ acquire_bus(g);
+ /* ID = 00 AM = 0 */
+ write_reg(g, SSD2119_REG_ENTRY_MODE, 0x6800);
+ release_bus(g);
+ g->g.Height = GDISP_SCREEN_HEIGHT;
+ g->g.Width = GDISP_SCREEN_WIDTH;
+ break;
+ case GDISP_ROTATE_270:
+ acquire_bus(g);
+ /* ID = 10 AM = 1 */
+ write_reg(g, SSD2119_REG_ENTRY_MODE, 0x6828);
+ release_bus(g);
+ g->g.Height = GDISP_SCREEN_WIDTH;
+ g->g.Width = GDISP_SCREEN_HEIGHT;
+ break;
+ default:
+ return;
+ }
+ g->g.Orientation = (orientation_t)g->p.ptr;
+ return;
+
+ case GDISP_CONTROL_BACKLIGHT:
+ if ((unsigned)g->p.ptr > 100)
+ g->p.ptr = (void *)100;
+ set_backlight(g, (unsigned)g->p.ptr);
+ g->g.Backlight = (unsigned)g->p.ptr;
+ return;
+
+ //case GDISP_CONTROL_CONTRAST:
+ default:
+ return;
+ }
+ }
+#endif
+
+#endif /* GFX_USE_GDISP */
diff --git a/drivers/gdisp/SSD2119/gdisp_lld_board_embest_dmstf4bb.h b/drivers/gdisp/SSD2119/gdisp_lld_board_embest_dmstf4bb.h
deleted file mode 100644
index 126cd960..00000000
--- a/drivers/gdisp/SSD2119/gdisp_lld_board_embest_dmstf4bb.h
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * This file is subject to the terms of the GFX License. If a copy of
- * the license was not distributed with this file, you can obtain one at:
- *
- * http://ugfx.org/license.html
- */
-
-/**
- * @file drivers/gdisp/SSD2119/gdisp_lld_board_embest_dmstf4bb.h
- * @brief GDISP Graphic Driver subsystem board FSMC interface for the SSD2119 display.
- *
- * @addtogroup GDISP
- * @{
- */
-
-#ifndef _GDISP_LLD_BOARD_H
-#define _GDISP_LLD_BOARD_H
-
-/* This board file uses only FSMC, so don't undefine this. */
-#define GDISP_USE_FSMC
-/* But it is OK to disable DMA use. */
-#define GDISP_USE_DMA
-#define GDISP_DMA_STREAM STM32_DMA2_STREAM6
-
-/* Using FSMC A19 (PE3) as DC */
-#define GDISP_REG (*((volatile uint16_t *) 0x60000000)) /* DC = 0 */
-#define GDISP_RAM (*((volatile uint16_t *) 0x60100000)) /* DC = 1 */
-
-#define SET_RST palSetPad(GPIOD, 3);
-#define CLR_RST palClearPad(GPIOD, 3);
-
-/*
- * PWM configuration structure. We use timer 4 channel 2 (orange LED on board).
- * The reason for so high clock is that with any lower, onboard coil is squeaking.
- * The major disadvantage of this clock is a lack of linearity between PWM duty
- * cycle width and brightness. In fact only with low preset one sees any change
- * (eg. duty cycle between 1-20). Feel free to adjust this, maybe only my board
- * behaves like this. According to the G5126 datesheet (backlight LED driver)
- * the PWM frequency should be somewhere between 200 Hz to 200 kHz.
- */
-static const PWMConfig pwmcfg = {
- 1000000, /* 1 MHz PWM clock frequency. */
- 100, /* PWM period is 100 cycles. */
- NULL,
- {
- {PWM_OUTPUT_ACTIVE_HIGH, NULL},
- {PWM_OUTPUT_ACTIVE_HIGH, NULL},
- {PWM_OUTPUT_ACTIVE_HIGH, NULL},
- {PWM_OUTPUT_ACTIVE_HIGH, NULL}
- },
- 0
-};
-
-/**
- * @brief Initialise the board for the display.
- * @notes This board definition uses GPIO and assumes exclusive access to these GPIO pins
- *
- * @notapi
- */
-static inline void init_board(void) {
- unsigned char FSMC_Bank;
-
- #ifndef GDISP_USE_FSMC
- #error "This board uses only FSMC, please define GDISP_USE_FSMC"
- #endif
-
- #if defined(STM32F4XX) || defined(STM32F2XX)
- /* STM32F4 FSMC init */
- rccEnableAHB3(RCC_AHB3ENR_FSMCEN, 0);
-
- #if defined(GDISP_USE_DMA) && defined(GDISP_DMA_STREAM)
- if (dmaStreamAllocate(GDISP_DMA_STREAM, 0, NULL, NULL))
- gfxExit();
- dmaStreamSetMemory0(GDISP_DMA_STREAM, &GDISP_RAM);
- dmaStreamSetMode(GDISP_DMA_STREAM, STM32_DMA_CR_PL(0) | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_DIR_M2M);
- #endif
- #else
- #error "FSMC not implemented for this device"
- #endif
-
- /* Group pins */
- IOBus busD = {GPIOD, (1 << 0) | (1 << 1) | (1 << 4) | (1 << 5) | (1 << 7) | (1 << 8) |
- (1 << 9) | (1 << 10) | (1 << 14) | (1 << 15), 0};
-
- IOBus busE = {GPIOE, (1 << 3) | (1 << 7) | (1 << 8) | (1 << 9) | (1 << 10) | (1 << 11) | (1 << 12) |
- (1 << 13) | (1 << 14) | (1 << 15), 0};
-
- /* FSMC is an alternate function 12 (AF12) */
- palSetBusMode(&busD, PAL_MODE_ALTERNATE(12));
- palSetBusMode(&busE, PAL_MODE_ALTERNATE(12));
-
- FSMC_Bank = 0;
- /* FSMC timing register configuration */
- FSMC_Bank1->BTCR[FSMC_Bank + 1] = (FSMC_BTR1_ADDSET_2 | FSMC_BTR1_ADDSET_1) \
- | (FSMC_BTR1_DATAST_2 | FSMC_BTR1_DATAST_1) \
- | FSMC_BTR1_BUSTURN_0;
-
- /* Bank1 NOR/PSRAM control register configuration
- * Write enable, memory databus width set to 16 bit, memory bank enable */
- FSMC_Bank1->BTCR[FSMC_Bank] = FSMC_BCR1_WREN | FSMC_BCR1_MWID_0 | FSMC_BCR1_MBKEN;
-
- /* Display backlight control */
- /* TIM4 is an alternate function 2 (AF2) */
- pwmStart(&PWMD4, &pwmcfg);
- palSetPadMode(GPIOD, 13, PAL_MODE_ALTERNATE(2));
- pwmEnableChannel(&PWMD4, 1, 100);
-}
-
-/**
- * @brief Set or clear the lcd reset pin.
- *
- * @param[in] state TRUE = lcd in reset, FALSE = normal operation
- *
- * @notapi
- */
-static inline void setpin_reset(bool_t state) {
- if (state) {
- CLR_RST;
- } else {
- SET_RST;
- }
-}
-
-/**
- * @brief Set the lcd back-light level.
- *
- * @param[in] percent 0 to 100%
- *
- * @notapi
- */
-static inline void set_backlight(uint8_t percent) {
- pwmEnableChannel(&PWMD4, 1, percent);
-}
-
-/**
- * @brief Take exclusive control of the bus
- * @note Not needed, not implemented
- *
- * @notapi
- */
-static inline void acquire_bus(void) {
- /* Nothing to do here since LCD is the only device on that bus */
-}
-
-/**
- * @brief Release exclusive control of the bus
- * @note Not needed, not implemented
- *
- * @notapi
- */
-static inline void release_bus(void) {
- /* Nothing to do here since LCD is the only device on that bus */
-}
-
-/**
- * @brief Send data to the index register.
- *
- * @param[in] index The index register to set
- *
- * @notapi
- */
-static inline void write_index(uint16_t index) {
- GDISP_REG = index;
-}
-
-/**
- * @brief Send data to the lcd.
- *
- * @param[in] data The data to send
- *
- * @notapi
- */
-static inline void write_data(uint16_t data) {
- GDISP_RAM = data;
-}
-
-#if GDISP_HARDWARE_READPIXEL || GDISP_HARDWARE_SCROLL || defined(__DOXYGEN__)
-/**
- * @brief Read data from the lcd.
- *
- * @return The data from the lcd
- * @note The chip select may need to be asserted/de-asserted
- * around the actual spi read
- *
- * @notapi
- */
-static inline uint16_t read_data(void) {
- return GDISP_RAM;
-}
-#endif
-
-#endif /* _GDISP_LLD_BOARD_H */
-/** @} */
diff --git a/drivers/gdisp/SSD2119/gdisp_lld_board_template.h b/drivers/gdisp/SSD2119/gdisp_lld_board_template.h
deleted file mode 100644
index 2e4d53df..00000000
--- a/drivers/gdisp/SSD2119/gdisp_lld_board_template.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * This file is subject to the terms of the GFX License. If a copy of
- * the license was not distributed with this file, you can obtain one at:
- *
- * http://ugfx.org/license.html
- */
-
-/**
- * @file drivers/gdisp/SSD2119/gdisp_lld_board_template.h
- * @brief GDISP Graphic Driver subsystem board template for the SSD2119 display.
- *
- * @addtogroup GDISP
- * @{
- */
-
-#ifndef _GDISP_LLD_BOARD_H
-#define _GDISP_LLD_BOARD_H
-
-/**
- * @brief Initialise the board for the display.
- * @notes This board definition uses GPIO and assumes exclusive access to these GPIO pins
- *
- * @notapi
- */
-static inline void init_board(void) {
-
-}
-
-/**
- * @brief Set or clear the lcd reset pin.
- *
- * @param[in] state TRUE = lcd in reset, FALSE = normal operation
- *
- * @notapi
- */
-static inline void setpin_reset(bool_t state) {
-
-}
-
-/**
- * @brief Set the lcd back-light level.
- *
- * @param[in] percent 0 to 100%
- *
- * @notapi
- */
-static inline void set_backlight(uint8_t percent) {
-
-}
-
-/**
- * @brief Take exclusive control of the bus
- * @note Not needed, not implemented
- *
- * @notapi
- */
-static inline void acquire_bus(void) {
- /* Nothing to do here since LCD is the only device on that bus */
-}
-
-/**
- * @brief Release exclusive control of the bus
- * @note Not needed, not implemented
- *
- * @notapi
- */
-static inline void release_bus(void) {
- /* Nothing to do here since LCD is the only device on that bus */
-}
-
-/**
- * @brief Send data to the index register.
- *
- * @param[in] index The index register to set
- *
- * @notapi
- */
-static inline void write_index(uint16_t index) {
-
-}
-
-/**
- * @brief Send data to the lcd.
- *
- * @param[in] data The data to send
- *
- * @notapi
- */
-static inline void write_data(uint16_t data) {
-
-}
-
-#if GDISP_HARDWARE_READPIXEL || GDISP_HARDWARE_SCROLL || defined(__DOXYGEN__)
-/**
- * @brief Read data from the lcd.
- *
- * @return The data from the lcd
- * @note The chip select may need to be asserted/de-asserted
- * around the actual spi read
- *
- * @notapi
- */
-static inline uint16_t read_data(void) {
-
-}
-#endif
-
-#endif /* _GDISP_LLD_BOARD_H */
-/** @} */
diff --git a/drivers/gdisp/SSD2119/gdisp_lld_config.h b/drivers/gdisp/SSD2119/gdisp_lld_config.h
index 3ad247e6..ec034bef 100644
--- a/drivers/gdisp/SSD2119/gdisp_lld_config.h
+++ b/drivers/gdisp/SSD2119/gdisp_lld_config.h
@@ -22,16 +22,20 @@
/* Driver hardware support. */
/*===========================================================================*/
-#define GDISP_DRIVER_NAME "SSD2119"
-
-#define GDISP_HARDWARE_CLEARS TRUE
-#define GDISP_HARDWARE_FILLS TRUE
-#define GDISP_HARDWARE_BITFILLS TRUE
-#define GDISP_HARDWARE_SCROLL TRUE
-#define GDISP_HARDWARE_PIXELREAD TRUE
+#define GDISP_HARDWARE_STREAM_WRITE TRUE
+#define GDISP_HARDWARE_STREAM_READ TRUE
+#define GDISP_HARDWARE_STREAM_POS TRUE
#define GDISP_HARDWARE_CONTROL TRUE
-#define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_RGB565
+#if defined(GDISP_USE_DMA)
+ #define GDISP_HARDWARE_FILLS TRUE
+ #if !defined(GDISP_PIXELFORMAT) || GDISP_PIXELFORMAT == 0x2565
+ // Hardware BitBlts are only supported in native pixel format on this controller
+ #define GDISP_HARDWARE_BITFILLS TRUE
+ #endif
+#endif
+
+#define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_RGB565
#endif /* GFX_USE_GDISP */
diff --git a/drivers/gdisp/ST7565/board_ST7565_template.h b/drivers/gdisp/ST7565/board_ST7565_template.h
new file mode 100644
index 00000000..aef6cf2b
--- /dev/null
+++ b/drivers/gdisp/ST7565/board_ST7565_template.h
@@ -0,0 +1,108 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/ST7565/board_ST7565_template.h
+ * @brief GDISP Graphic Driver subsystem board interface for the ST7565 display.
+ *
+ * @addtogroup GDISP
+ * @{
+ */
+
+#ifndef _GDISP_LLD_BOARD_H
+#define _GDISP_LLD_BOARD_H
+
+/**
+ * @brief Initialise the board for the display.
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @note Set the g->board member to whatever is appropriate. For multiple
+ * displays this might be a pointer to the appropriate register set.
+ *
+ * @notapi
+ */
+static inline void init_board(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief After the initialisation.
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void post_init_board(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Set or clear the lcd reset pin.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] state TRUE = lcd in reset, FALSE = normal operation
+ *
+ * @notapi
+ */
+static inline void setpin_reset(GDisplay *g, bool_t state) {
+ (void) g;
+ (void) state;
+}
+
+/**
+ * @brief Take exclusive control of the bus
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void acquire_bus(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Release exclusive control of the bus
+ *
+ * @param[in] g The GDisplay structure
+ *
+ * @notapi
+ */
+static inline void release_bus(GDisplay *g) {
+ (void) g;
+}
+
+/**
+ * @brief Send a command to the controller.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] cmd The command to send *
+ *
+ * @notapi
+ */
+static inline void write_cmd(GDisplay *g, uint8_t cmd) {
+ (void) g;
+ (void) cmd;
+}
+
+/**
+ * @brief Send data to the lcd.
+ *
+ * @param[in] g The GDisplay structure
+ * @param[in] data The data to send
+ *
+ * @notapi
+ */
+static inline void write_data(GDisplay *g, uint8_t* data, uint16_t length) {
+ (void) g;
+ (void) data;
+ (void) length;
+}
+
+#endif /* _GDISP_LLD_BOARD_H */
+/** @} */
+
diff --git a/drivers/gdisp/ST7565/gdisp_lld.c b/drivers/gdisp/ST7565/gdisp_lld.c
deleted file mode 100644
index f46a166c..00000000
--- a/drivers/gdisp/ST7565/gdisp_lld.c
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * This file is subject to the terms of the GFX License. If a copy of
- * the license was not distributed with this file, you can obtain one at:
- *
- * http://ugfx.org/license.html
- */
-
-#include "gfx.h"
-
-#if GFX_USE_GDISP
-
-/* Include the emulation code for things we don't support */
-#include "gdisp/lld/emulation.c"
-#include "st7565.h"
-#include "gdisp_lld_board.h"
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-#ifndef GDISP_SCREEN_HEIGHT
-#define GDISP_SCREEN_HEIGHT 64
-#endif
-#ifndef GDISP_SCREEN_WIDTH
-#define GDISP_SCREEN_WIDTH 128
-#endif
-
-#define GDISP_INITIAL_CONTRAST 0xFF
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-// Some common routines and macros
-#define delay(us) gfxSleepMicroseconds(us)
-#define delay_ms(ms) gfxSleepMilliseconds(ms)
-
-// The memory buffer for the display
-static uint8_t gdisp_buffer[GDISP_SCREEN_HEIGHT * GDISP_SCREEN_WIDTH / 8];
-
-/** Set the display to normal or inverse.
- * @param[in] value 0 for normal mode, or 1 for inverse mode.
- * @notapi
- */
-static void invert_display(uint8_t i) {
- write_cmd(i ? ST7565_INVERT_DISPLAY : ST7565_POSITIVE_DISPLAY);
-}
-
-/** Turn the whole display off.
- * Sends the display to sleep, but leaves RAM intact.
- * @notapi
- */
-static void display_off(void) {
- write_cmd(ST7565_DISPLAY_OFF);
-}
-
-/** Turn the whole display on.
- * Wakes up this display following a sleep() call.
- * @notapi
- */
-static void display_on(void) {
- write_cmd(ST7565_DISPLAY_ON);
-}
-
-/** Set the display contrast.
- * @param[in] value The contrast, from 1 to 63.
- * @notapi
- */
-static void set_contrast(uint8_t value) {
- write_cmd(ST7565_CONTRAST);
- write_cmd(value & 0x3F);
-}
-
-/** Set the display start line. This is the line at which the display will start rendering.
- * @param[in] value A value from 0 to 63 denoting the line to start at.
- * @notapi
- */
-static void set_display_start_line(unsigned char value) {
- write_cmd(ST7565_START_LINE | value);
-}
-
-static void gdisp_lld_display(void) {
- uint8_t p;
- set_display_start_line(0);
-
- for (p = 0; p < 8; p++) {
- write_cmd(ST7565_PAGE | p);
- write_cmd(ST7565_COLUMN_MSB | 0);
- write_cmd(ST7565_COLUMN_LSB | 0);
- write_cmd(ST7565_RMW);
- write_data(&gdisp_buffer[p * GDISP_SCREEN_WIDTH], GDISP_SCREEN_WIDTH);
- }
-}
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/* ---- Required Routines ---- */
-/*
- The following 2 routines are required.
- All other routines are optional.
- */
-
-/**
- * @brief Low level GDISP driver initialization.
- *
- * @notapi
- */
-bool_t gdisp_lld_init(void) {
- // Initialize your display
- init_board();
-
- // Hardware reset.
- setpin_reset(TRUE);
- delay_ms(10);
- setpin_reset(FALSE);
- delay_ms(1);
-
- write_cmd(ST7565_LCD_BIAS_7);
- write_cmd(ST7565_ADC_NORMAL);
- write_cmd(ST7565_COM_SCAN_INC);
- set_display_start_line(0);
-
- set_contrast(32);
- write_cmd(ST7565_RESISTOR_RATIO | 0x3);
-
- // turn on voltage converter (VC=1, VR=0, VF=0)
- write_cmd(ST7565_POWER_CONTROL | 0x04);
- delay_ms(50);
- // turn on voltage regulator (VC=1, VR=1, VF=0)
- write_cmd(ST7565_POWER_CONTROL | 0x06);
- delay_ms(50);
- // turn on voltage follower (VC=1, VR=1, VF=1)
- write_cmd(ST7565_POWER_CONTROL | 0x07);
- delay_ms(50);
-
- display_on();
- write_cmd(ST7565_ALLON_NORMAL);
- invert_display(0);// Disable Inversion of display.
-
- write_cmd(ST7565_RMW);
- gdisp_lld_display();
-
- // Initialize the GDISP structure
- GDISP.Width = GDISP_SCREEN_WIDTH;
- GDISP.Height = GDISP_SCREEN_HEIGHT;
- GDISP.Orientation = GDISP_ROTATE_0;
- GDISP.Powermode = powerOn;
- GDISP.Contrast = 50;
-#if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- GDISP.clipx0 = 0;
- GDISP.clipy0 = 0;
- GDISP.clipx1 = GDISP.Width;
- GDISP.clipy1 = GDISP.Height;
-#endif
- return TRUE;
-}
-
-/**
- * @brief Draws a pixel on the display.
- *
- * @param[in] x X location of the pixel
- * @param[in] y Y location of the pixel
- * @param[in] color The color of the pixel
- *
- * @notapi
- */
-void gdisp_lld_draw_pixel(coord_t x, coord_t y, color_t color) {
-#if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- if (x < GDISP.clipx0 || y < GDISP.clipy0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
-#endif
-
- if (color == 1)
- gdisp_buffer[x+ (y/8)*GDISP_SCREEN_WIDTH] |= (1<<y%8);
- else
- gdisp_buffer[x+ (y/8)*GDISP_SCREEN_WIDTH] &= ~(1<<y%8);
-}
-
-/* ---- Optional Routines ---- */
-/*
- All the below routines are optional.
- Defining them will increase speed but everything
- will work if they are not defined.
- If you are not using a routine - turn it off using
- the appropriate GDISP_HARDWARE_XXXX macro.
- Don't bother coding for obvious similar routines if
- there is no performance penalty as the emulation software
- makes a good job of using similar routines.
- eg. If gfillarea() is defined there is little
- point in defining clear() unless the
- performance bonus is significant.
- For good performance it is suggested to implement
- fillarea() and blitarea().
- */
-
-#if (GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL) || defined(__DOXYGEN__)
-/**
- * @brief Driver Control
- * @details Unsupported control codes are ignored.
- * @note The value parameter should always be typecast to (void *).
- * @note There are some predefined and some specific to the low level driver.
- * @note GDISP_CONTROL_POWER - Takes a gdisp_powermode_t
- * GDISP_CONTROL_ORIENTATION - Takes a gdisp_orientation_t
- * GDISP_CONTROL_BACKLIGHT - Takes an int from 0 to 100. For a driver
- * that only supports off/on anything other
- * than zero is on.
- * GDISP_CONTROL_CONTRAST - Takes an int from 0 to 100.
- * GDISP_CONTROL_LLD - Low level driver control constants start at
- * this value.
- *
- * @param[in] what What to do.
- * @param[in] value The value to use (always cast to a void *).
- *
- * @notapi
- */
-void gdisp_lld_control(unsigned what, void *value) {
- switch(what) {
- case GDISP_CONTROL_POWER:
- if (GDISP.Powermode == (gdisp_powermode_t)value)
- return;
-
- switch((gdisp_powermode_t)value) {
- case powerOff:
- display_off();
- break;
- case powerSleep:
- display_off();
- break;
- case powerDeepSleep:
- display_off();
- break;
- case powerOn:
- display_on();
- break;
- default:
- return;
- }
- GDISP.Powermode = (gdisp_powermode_t)value;
- return;
-
- case GDISP_CONTROL_BACKLIGHT:
- set_backlight((uint8_t)(size_t)value);
- return;
-
- case GDISP_CONTROL_CONTRAST:
- if ((unsigned)value > 100) value = (void*)100;
- if (GDISP.Contrast == (uint8_t)((float)((size_t)value) * 63.0/100.0))
- return;
- set_contrast((uint8_t)((float)((size_t)value) * 63.0/100.0) );
- GDISP.Contrast = (unsigned)value;
- return;
-
- case GDISP_CONTROL_LLD_FLUSH:
- gdisp_lld_display();
- return;
- }
-}
-#endif // GDISP_NEED_CONTROL
-
-#endif // GFX_USE_GDISP
-/** @} */
-
diff --git a/drivers/gdisp/ST7565/gdisp_lld.mk b/drivers/gdisp/ST7565/gdisp_lld.mk
index cd925824..9f9c5408 100644
--- a/drivers/gdisp/ST7565/gdisp_lld.mk
+++ b/drivers/gdisp/ST7565/gdisp_lld.mk
@@ -1,6 +1,2 @@
-# List the required driver.
-GFXSRC += $(GFXLIB)/drivers/gdisp/ST7565/gdisp_lld.c
-
-# Required include directories
GFXINC += $(GFXLIB)/drivers/gdisp/ST7565
-
+GFXSRC += $(GFXLIB)/drivers/gdisp/ST7565/gdisp_lld_ST7565.c
diff --git a/drivers/gdisp/ST7565/gdisp_lld_ST7565.c b/drivers/gdisp/ST7565/gdisp_lld_ST7565.c
new file mode 100644
index 00000000..2bb5406f
--- /dev/null
+++ b/drivers/gdisp/ST7565/gdisp_lld_ST7565.c
@@ -0,0 +1,262 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/ST7565/gdisp_lld.c
+ * @brief GDISP Graphics Driver subsystem low level driver source for the ST7565 display.
+ */
+
+#include "gfx.h"
+
+#if GFX_USE_GDISP
+
+#define GDISP_DRIVER_VMT GDISPVMT_ST7565
+#include "../drivers/gdisp/ST7565/gdisp_lld_config.h"
+#include "gdisp/lld/gdisp_lld.h"
+
+#include "board_ST7565.h"
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+#ifndef GDISP_SCREEN_HEIGHT
+ #define GDISP_SCREEN_HEIGHT 64
+#endif
+#ifndef GDISP_SCREEN_WIDTH
+ #define GDISP_SCREEN_WIDTH 128
+#endif
+#ifndef GDISP_INITIAL_CONTRAST
+ #define GDISP_INITIAL_CONTRAST 51
+#endif
+#ifndef GDISP_INITIAL_BACKLIGHT
+ #define GDISP_INITIAL_BACKLIGHT 100
+#endif
+
+#define GDISP_FLG_NEEDFLUSH (GDISP_FLG_DRIVER<<0)
+
+#include "st7565.h"
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+// Some common routines and macros
+#define RAM(g) ((uint8_t *)g->priv)
+#define write_cmd2(g, cmd1, cmd2) { write_cmd(g, cmd1); write_cmd(g, cmd2); }
+#define write_cmd3(g, cmd1, cmd2, cmd3) { write_cmd(g, cmd1); write_cmd(g, cmd2); write_cmd(g, cmd3); }
+
+// Some common routines and macros
+#define delay(us) gfxSleepMicroseconds(us)
+#define delay_ms(ms) gfxSleepMilliseconds(ms)
+
+#define xyaddr(x, y) ((x) + ((y)>>3)*GDISP_SCREEN_WIDTH)
+#define xybit(y) (1<<((y)&7))
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * As this controller can't update on a pixel boundary we need to maintain the
+ * the entire display surface in memory so that we can do the necessary bit
+ * operations. Fortunately it is a small display in monochrome.
+ * 64 * 128 / 8 = 1024 bytes.
+ */
+
+LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
+ // The private area is the display surface.
+ g->priv = gfxAlloc(GDISP_SCREEN_HEIGHT * GDISP_SCREEN_WIDTH / 8);
+
+ // Initialise the board interface
+ init_board(g);
+
+ // Hardware reset
+ setpin_reset(g, TRUE);
+ gfxSleepMilliseconds(20);
+ setpin_reset(g, FALSE);
+ gfxSleepMilliseconds(20);
+
+ acquire_bus(g);
+
+ write_cmd(g, ST7565_LCD_BIAS_7);
+ write_cmd(g, ST7565_ADC_NORMAL);
+ write_cmd(g, ST7565_COM_SCAN_INC);
+ write_cmd(g, ST7565_START_LINE | 0);
+
+ write_cmd2(g, ST7565_CONTRAST, GDISP_INITIAL_CONTRAST*64/101);
+ write_cmd(g, ST7565_RESISTOR_RATIO | 0x3);
+
+ // turn on voltage converter (VC=1, VR=0, VF=0)
+ write_cmd(g, ST7565_POWER_CONTROL | 0x04);
+ delay_ms(50);
+
+ // turn on voltage regulator (VC=1, VR=1, VF=0)
+ write_cmd(g, ST7565_POWER_CONTROL | 0x06);
+ delay_ms(50);
+
+ // turn on voltage follower (VC=1, VR=1, VF=1)
+ write_cmd(g, ST7565_POWER_CONTROL | 0x07);
+ delay_ms(50);
+
+ write_cmd(g, ST7565_DISPLAY_ON);
+ write_cmd(g, ST7565_ALLON_NORMAL);
+ write_cmd(g, ST7565_POSITIVE_DISPLAY); // Disable Inversion of display.
+
+ write_cmd(g, ST7565_RMW);
+
+ // Finish Init
+ post_init_board(g);
+
+ // Release the bus
+ release_bus(g);
+
+ /* Initialise the GDISP structure */
+ g->g.Width = GDISP_SCREEN_WIDTH;
+ g->g.Height = GDISP_SCREEN_HEIGHT;
+ g->g.Orientation = GDISP_ROTATE_0;
+ g->g.Powermode = powerOn;
+ g->g.Backlight = GDISP_INITIAL_BACKLIGHT;
+ g->g.Contrast = GDISP_INITIAL_CONTRAST;
+ return TRUE;
+}
+
+#if GDISP_HARDWARE_FLUSH
+ LLDSPEC void gdisp_lld_flush(GDisplay *g) {
+ unsigned p;
+
+ // Don't flush if we don't need it.
+ if (!(g->flags & GDISP_FLG_NEEDFLUSH))
+ return;
+
+ acquire_bus(g);
+ for (p = 0; p < 8; p++) {
+ write_cmd(g, ST7565_PAGE | p);
+ write_cmd(g, ST7565_COLUMN_MSB | 0);
+ write_cmd(g, ST7565_COLUMN_LSB | 0);
+ write_cmd(g, ST7565_RMW);
+ write_data(g, RAM(g) + (p*GDISP_SCREEN_WIDTH), GDISP_SCREEN_WIDTH);
+ }
+ release_bus(g);
+ }
+#endif
+
+#if GDISP_HARDWARE_DRAWPIXEL
+ LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) {
+ coord_t x, y;
+
+ switch(g->g.Orientation) {
+ case GDISP_ROTATE_0:
+ x = g->p.x;
+ y = g->p.y;
+ break;
+ case GDISP_ROTATE_90:
+ x = g->p.y;
+ y = GDISP_SCREEN_HEIGHT-1 - g->p.x;
+ break;
+ case GDISP_ROTATE_180:
+ x = GDISP_SCREEN_WIDTH-1 - g->p.x;
+ y = GDISP_SCREEN_HEIGHT-1 - g->p.y;
+ break;
+ case GDISP_ROTATE_270:
+ x = GDISP_SCREEN_HEIGHT-1 - g->p.y;
+ y = g->p.x;
+ break;
+ }
+ if (COLOR2NATIVE(g->p.color) != Black)
+ RAM(g)[xyaddr(x, y)] |= xybit(y);
+ else
+ RAM(g)[xyaddr(x, y)] &= ~xybit(y);
+ g->flags |= GDISP_FLG_NEEDFLUSH;
+ }
+#endif
+
+#if GDISP_HARDWARE_PIXELREAD
+ LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g) {
+ coord_t x, y;
+
+ switch(g->g.Orientation) {
+ case GDISP_ROTATE_0:
+ x = g->p.x;
+ y = g->p.y;
+ break;
+ case GDISP_ROTATE_90:
+ x = g->p.y;
+ y = GDISP_SCREEN_HEIGHT-1 - g->p.x;
+ break;
+ case GDISP_ROTATE_180:
+ x = GDISP_SCREEN_WIDTH-1 - g->p.x;
+ y = GDISP_SCREEN_HEIGHT-1 - g->p.y;
+ break;
+ case GDISP_ROTATE_270:
+ x = GDISP_SCREEN_HEIGHT-1 - g->p.y;
+ x = g->p.x;
+ break;
+ }
+ return (RAM(g)[xyaddr(x, y)] & xybit(y)) ? White : Black;
+ }
+#endif
+
+#if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL
+ LLDSPEC void gdisp_lld_control(GDisplay *g) {
+ switch(g->p.x) {
+ case GDISP_CONTROL_POWER:
+ if (g->g.Powermode == (powermode_t)g->p.ptr)
+ return;
+ switch((powermode_t)g->p.ptr) {
+ case powerOff:
+ case powerSleep:
+ case powerDeepSleep:
+ acquire_bus(g);
+ write_cmd(g, ST7565_DISPLAY_OFF);
+ release_bus(g);
+ break;
+ case powerOn:
+ acquire_bus(g);
+ write_cmd(g, ST7565_DISPLAY_ON);
+ release_bus(g);
+ break;
+ default:
+ return;
+ }
+ g->g.Powermode = (powermode_t)g->p.ptr;
+ return;
+
+ case GDISP_CONTROL_ORIENTATION:
+ if (g->g.Orientation == (orientation_t)g->p.ptr)
+ return;
+ switch((orientation_t)g->p.ptr) {
+ /* Rotation is handled by the drawing routines */
+ case GDISP_ROTATE_0:
+ case GDISP_ROTATE_180:
+ g->g.Height = GDISP_SCREEN_HEIGHT;
+ g->g.Width = GDISP_SCREEN_WIDTH;
+ break;
+ case GDISP_ROTATE_90:
+ case GDISP_ROTATE_270:
+ g->g.Height = GDISP_SCREEN_WIDTH;
+ g->g.Width = GDISP_SCREEN_HEIGHT;
+ break;
+ default:
+ return;
+ }
+ g->g.Orientation = (orientation_t)g->p.ptr;
+ return;
+
+ case GDISP_CONTROL_CONTRAST:
+ if ((unsigned)g->p.ptr > 100)
+ g->p.ptr = (void *)100;
+ acquire_bus(g);
+ write_cmd2(g, ST7565_CONTRAST, ((((unsigned)g->p.ptr)<<6)/101) & 0x3F);
+ release_bus(g);
+ g->g.Contrast = (unsigned)g->p.ptr;
+ return;
+ }
+ }
+#endif // GDISP_NEED_CONTROL
+
+#endif // GFX_USE_GDISP
diff --git a/drivers/gdisp/ST7565/gdisp_lld_board_template.h b/drivers/gdisp/ST7565/gdisp_lld_board_template.h
deleted file mode 100644
index 2f40ccc7..00000000
--- a/drivers/gdisp/ST7565/gdisp_lld_board_template.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * This file is subject to the terms of the GFX License. If a copy of
- * the license was not distributed with this file, you can obtain one at:
- *
- * http://ugfx.org/license.html
- */
-
-#ifndef _GDISP_LLD_BOARD_H
-#define _GDISP_LLD_BOARD_H
-
-/**
- * @brief Initialize the board for the display.
- * @notes This board definition uses GPIO and assumes exclusive access to these GPIO pins
- * @notapi
- */
-static inline void init_board(void) {
- /* Configure SPI bus here. Up to 10Mhz, SPI Mode = 3 (CPOL = 1, CPHA = 0) */
- /* Configure A0, !CS, !RST pin for output */
-}
-
-/**
- * @brief Set or clear the lcd reset pin.
- * @param[in] state TRUE = lcd in reset, FALSE = normal operation
- * @notapi
- */
-static inline void setpin_reset(bool_t state) {
- /* Set !CS to low */
- if (state) {
- /* Set !RST to low */
- } else {
- /* Set !RST to high */
- }
-}
-
-/**
- * @brief Set the lcd back-light level.
- * @param[in] percent 0 to 100%
- * @notapi
- */
-static inline void set_backlight(uint8_t percent) {
-
-}
-
-/**
- * @brief Take exclusive control of the bus
- * @notapi
- */
-static inline void acquire_bus(void) {
-
-}
-
-/**
- * @brief Release exclusive control of the bus
- * @notapi
- */
-static inline void release_bus(void) {
-
-}
-
-/**
- * @brief Send command to the display.
- * @param[in] cmd The command to send
- * @notapi
- */
-static inline void write_cmd(uint8_t cmd) {
- /* Set A0 to low */
- /* Transmit cmd over SPI */
-}
-
-/**
- * @brief Send data to the display.
- * @param[in] data The data to send
- * @notapi
- */
-static inline void write_data(uint8_t* data, uint16_t length) {
- /* Set A0 to high */
- /* Transmit data for length over SPI. DMA is recommended. */
-}
-
-#endif /* _GDISP_LLD_BOARD_H */
-/** @} */
-
diff --git a/drivers/gdisp/ST7565/gdisp_lld_config.h b/drivers/gdisp/ST7565/gdisp_lld_config.h
index 8d26a0aa..f774e8fa 100644
--- a/drivers/gdisp/ST7565/gdisp_lld_config.h
+++ b/drivers/gdisp/ST7565/gdisp_lld_config.h
@@ -14,13 +14,12 @@
/* Driver hardware support. */
/*===========================================================================*/
-#define GDISP_DRIVER_NAME "ST7565"
+#define GDISP_HARDWARE_FLUSH TRUE // This controller requires flushing
+#define GDISP_HARDWARE_DRAWPIXEL TRUE
+#define GDISP_HARDWARE_PIXELREAD TRUE
+#define GDISP_HARDWARE_CONTROL TRUE
-#define GDISP_HARDWARE_CONTROL TRUE
-
-#define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_MONO
-
-#define GDISP_CONTROL_LLD_FLUSH (GDISP_CONTROL_LLD + 1)
+#define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_MONO
#endif /* GFX_USE_GDISP */
diff --git a/drivers/gdisp/ST7565/st7565.h b/drivers/gdisp/ST7565/st7565.h
index b1f43f6b..9542dd3f 100644
--- a/drivers/gdisp/ST7565/st7565.h
+++ b/drivers/gdisp/ST7565/st7565.h
@@ -8,9 +8,6 @@
#ifndef _ST7565_H
#define _ST7565_H
-#define ST7565_BLACK 0
-#define ST7565_WHITE 1
-
#define ST7565_CONTRAST 0x81
#define ST7565_ALLON_NORMAL 0xA4
#define ST7565_ALLON 0xA5
diff --git a/drivers/gdisp/TestStub/gdisp_lld.c b/drivers/gdisp/TestStub/gdisp_lld.c
deleted file mode 100644
index e5167989..00000000
--- a/drivers/gdisp/TestStub/gdisp_lld.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * This file is subject to the terms of the GFX License. If a copy of
- * the license was not distributed with this file, you can obtain one at:
- *
- * http://ugfx.org/license.html
- */
-
-/**
- * @file drivers/gdisp/TestStub/gdisp_lld.c
- * @brief GDISP Graphics Driver subsystem low level driver source (stub).
- *
- * @addtogroup GDISP
- * @{
- */
-
-#include "gfx.h"
-
-#if GFX_USE_GDISP /*|| defined(__DOXYGEN__)*/
-
-/* Include the emulation code for things we don't support */
-#include "gdisp/lld/emulation.c"
-
-#ifndef GDISP_SCREEN_HEIGHT
- #define GDISP_SCREEN_HEIGHT 128
-#endif
-#ifndef GDISP_SCREEN_WIDTH
- #define GDISP_SCREEN_WIDTH 128
-#endif
-
-/* ---- Required Routines ---- */
-/*
- The following 2 routines are required.
- All other routines are optional.
-*/
-
-/**
- * @brief Low level GDISP driver initialization.
- *
- * @notapi
- */
-bool_t gdisp_lld_init(void) {
- /* Initialise the GDISP structure */
- GDISP.Width = GDISP_SCREEN_WIDTH;
- GDISP.Height = GDISP_SCREEN_HEIGHT;
- GDISP.Orientation = GDISP_ROTATE_0;
- GDISP.Powermode = powerOff;
- GDISP.Backlight = 100;
- GDISP.Contrast = 50;
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- GDISP.clipx0 = 0;
- GDISP.clipy0 = 0;
- GDISP.clipx1 = GDISP.Width;
- GDISP.clipy1 = GDISP.Height;
- #endif
- return TRUE;
-}
-
-/**
- * @brief Draws a pixel on the display.
- *
- * @param[in] x X location of the pixel
- * @param[in] y Y location of the pixel
- * @param[in] color The color of the pixel
- *
- * @notapi
- */
-void gdisp_lld_draw_pixel(coord_t x, coord_t y, color_t color) {
- (void)x;
- (void)y;
- (void)color;
-}
-
-/* ---- Optional Routines ---- */
-
-#if (GDISP_NEED_PIXELREAD && GDISP_HARDWARE_PIXELREAD) || defined(__DOXYGEN__)
- /**
- * @brief Get the color of a particular pixel.
- * @note Optional.
- * @note If x,y is off the screen, the result is undefined.
- *
- * @param[in] x, y The start of the text
- *
- * @notapi
- */
- color_t gdisp_lld_get_pixel_color(coord_t x, coord_t y) {
- (void)x;
- (void)y;
-
- return 0;
- }
-#endif
-
-#if (GDISP_NEED_SCROLL && GDISP_HARDWARE_SCROLL) || defined(__DOXYGEN__)
- /**
- * @brief Scroll vertically a section of the screen.
- * @note Optional.
- * @note If x,y + cx,cy is off the screen, the result is undefined.
- * @note If lines is >= cy, it is equivelent to a area fill with bgcolor.
- *
- * @param[in] x, y The start of the area to be scrolled
- * @param[in] cx, cy The size of the area to be scrolled
- * @param[in] lines The number of lines to scroll (Can be positive or negative)
- * @param[in] bgcolor The color to fill the newly exposed area.
- *
- * @notapi
- */
- void gdisp_lld_vertical_scroll(coord_t x, coord_t y, coord_t cx, coord_t cy, int lines, color_t bgcolor) {
- (void)x;
- (void)y;
- (void)cx;
- (void)cy;
- (void)lines;
- (void)bgcolor;
- }
-#endif
-
-#endif /* GFX_USE_GDISP */
-/** @} */
diff --git a/drivers/gdisp/TestStub/gdisp_lld.mk b/drivers/gdisp/TestStub/gdisp_lld.mk
index 5f35be9d..d8faa3e9 100644
--- a/drivers/gdisp/TestStub/gdisp_lld.mk
+++ b/drivers/gdisp/TestStub/gdisp_lld.mk
@@ -1,5 +1,2 @@
-# List the required driver.
-GFXSRC += $(GFXLIB)/drivers/gdisp/TestStub/gdisp_lld.c
-
-# Required include directories
GFXINC += $(GFXLIB)/drivers/gdisp/TestStub
+GFXSRC += $(GFXLIB)/drivers/gdisp/TestStub/gdisp_lld_TestStub.c
diff --git a/drivers/gdisp/TestStub/gdisp_lld_TestStub.c b/drivers/gdisp/TestStub/gdisp_lld_TestStub.c
new file mode 100644
index 00000000..1a5ad81f
--- /dev/null
+++ b/drivers/gdisp/TestStub/gdisp_lld_TestStub.c
@@ -0,0 +1,61 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/gdisp/TestStub/gdisp_lld.c
+ * @brief GDISP Graphics Driver subsystem low level driver source (stub).
+ */
+
+#include "gfx.h"
+
+#if GFX_USE_GDISP /*|| defined(__DOXYGEN__)*/
+
+#define GDISP_DRIVER_VMT GDISPVMT_TestStub
+#include "../drivers/gdisp/TestStub/gdisp_lld_config.h"
+#include "gdisp/lld/gdisp_lld.h"
+
+#ifndef GDISP_SCREEN_HEIGHT
+ #define GDISP_SCREEN_HEIGHT 128
+#endif
+#ifndef GDISP_SCREEN_WIDTH
+ #define GDISP_SCREEN_WIDTH 128
+#endif
+#ifndef GDISP_INITIAL_CONTRAST
+ #define GDISP_INITIAL_CONTRAST 50
+#endif
+#ifndef GDISP_INITIAL_BACKLIGHT
+ #define GDISP_INITIAL_BACKLIGHT 100
+#endif
+
+LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
+ /* No board interface and no private driver area */
+ g->priv = g->board = 0;
+
+ /* Initialise the GDISP structure */
+ g->g.Width = GDISP_SCREEN_WIDTH;
+ g->g.Height = GDISP_SCREEN_HEIGHT;
+ g->g.Orientation = GDISP_ROTATE_0;
+ g->g.Powermode = powerOn;
+ g->g.Backlight = GDISP_INITIAL_BACKLIGHT;
+ g->g.Contrast = GDISP_INITIAL_CONTRAST;
+ return TRUE;
+}
+
+#if GDISP_HARDWARE_DRAWPIXEL
+ void gdisp_lld_draw_pixel(GDisplay *g) {
+ (void) g;
+ }
+#endif
+
+#if GDISP_HARDWARE_PIXELREAD
+ color_t gdisp_lld_get_pixel_color(GDisplay *g) {
+ (void) g;
+ return 0;
+ }
+#endif
+
+#endif /* GFX_USE_GDISP */
diff --git a/drivers/gdisp/TestStub/gdisp_lld_config.h b/drivers/gdisp/TestStub/gdisp_lld_config.h
index 38c55992..63471c6c 100644
--- a/drivers/gdisp/TestStub/gdisp_lld_config.h
+++ b/drivers/gdisp/TestStub/gdisp_lld_config.h
@@ -22,14 +22,10 @@
/* Driver hardware support. */
/*===========================================================================*/
-#define GDISP_DRIVER_NAME "TestStub"
+#define GDISP_HARDWARE_DRAWPIXEL TRUE
+#define GDISP_HARDWARE_PIXELREAD TRUE
-#define GDISP_HARDWARE_SCROLL GDISP_NEED_SCROLL
-#define GDISP_HARDWARE_PIXELREAD GDISP_NEED_PIXELREAD
-
-#define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_RGB565
-#define GDISP_PACKED_PIXELS FALSE
-#define GDISP_PACKED_LINES FALSE
+#define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_RGB565
#endif /* GFX_USE_GDISP */
diff --git a/drivers/ginput/dial/GADC/ginput_lld_dial_board_olimexsam7ex256.h b/drivers/ginput/dial/GADC/ginput_lld_dial_board_template.h
index 09ca3dc0..202b5386 100644
--- a/drivers/ginput/dial/GADC/ginput_lld_dial_board_olimexsam7ex256.h
+++ b/drivers/ginput/dial/GADC/ginput_lld_dial_board_template.h
@@ -6,7 +6,7 @@
*/
/**
- * @file drivers/ginput/dial/GADC/ginput_lld_dial_board_olimexsam7ex256.h
+ * @file drivers/ginput/dial/GADC/ginput_lld_dial_board_template.h
* @brief GINPUT Dial Driver config file.
*
* @defgroup Dial Dial
@@ -14,8 +14,8 @@
* @{
*/
-#ifndef _GINPUT_LLD_DIAL_BOARD_OLIMEXSAM7EX256_H
-#define _GINPUT_LLD_DIAL_BOARD_OLIMEXSAM7EX256_H
+#ifndef _GINPUT_LLD_DIAL_BOARD_H
+#define _GINPUT_LLD_DIAL_BOARD_H
#if GFX_USE_GINPUT && GINPUT_NEED_DIAL
@@ -23,6 +23,7 @@
/* Analogue devices on this board */
/*===========================================================================*/
+/* Example values */
#define GINPUT_DIAL_NUM_PORTS 1
#define GINPUT_DIAL_DEVICE0 GADC_PHYSDEV_DIAL
#define GINPUT_DIAL_POLL_PERIOD 200
@@ -30,6 +31,6 @@
#endif /* GFX_USE_GINPUT && GINPUT_NEED_DIAL */
-#endif /* _GINPUT_LLD_DIAL_BOARD_OLIMEXSAM7EX256_H */
+#endif /* _GINPUT_LLD_DIAL_BOARD_H */
/** @} */
diff --git a/drivers/ginput/dial/GADC/ginput_lld_dial_config.h b/drivers/ginput/dial/GADC/ginput_lld_dial_config.h
index 3dc7bfca..3e54b4ca 100644
--- a/drivers/ginput/dial/GADC/ginput_lld_dial_config.h
+++ b/drivers/ginput/dial/GADC/ginput_lld_dial_config.h
@@ -21,15 +21,8 @@
#define GINPUT_DIAL_MAX_VALUE ((1<<GADC_BITS_PER_SAMPLE)-1)
-#if GINPUT_TOGGLE_USE_CUSTOM_BOARD
- /* Include the user supplied board definitions */
- #include "ginput_lld_dial_board.h"
-#elif defined(BOARD_OLIMEX_SAM7_EX256)
- #include "ginput_lld_dial_board_olimexsam7ex256.h"
-#else
- /* Include the user supplied board definitions */
- #include "ginput_lld_dial_board.h"
-#endif
+/* Include the user supplied board definitions */
+#include "ginput_lld_dial_board.h"
#endif /* GFX_USE_GDISP && GINPUT_NEED_DIAL */
diff --git a/drivers/ginput/toggle/Pal/ginput_lld_toggle_board_example.h b/drivers/ginput/toggle/Pal/ginput_lld_toggle_board_template.h
index e0a501df..84038d16 100644
--- a/drivers/ginput/toggle/Pal/ginput_lld_toggle_board_example.h
+++ b/drivers/ginput/toggle/Pal/ginput_lld_toggle_board_template.h
@@ -4,45 +4,45 @@
*
* http://ugfx.org/license.html
*/
-
-/**
- * @file drivers/ginput/toggle/Pal/ginput_lld_toggle_board_example.h
- * @brief GINPUT Toggle low level driver source for the ChibiOS PAL hardware on the example board.
- *
- * @defgroup Toggle Toggle
- * @ingroup GINPUT
- * @{
- */
-
-#ifndef _GDISP_LLD_TOGGLE_BOARD_H
-#define _GDISP_LLD_TOGGLE_BOARD_H
-
-#error "GINPUT Toggle Pal Driver: You need to define your board definitions"
-
-// The below are example values
-
-#define GINPUT_TOGGLE_NUM_PORTS 7 // The total number of toggle inputs
-#define GINPUT_TOGGLE_CONFIG_ENTRIES 2 // The total number of GToggleConfig entries
-
-#define GINPUT_TOGGLE_SW1 0 // Switch 1
-#define GINPUT_TOGGLE_SW2 1 // Switch 2
-#define GINPUT_TOGGLE_UP 2 // Joystick Up
-#define GINPUT_TOGGLE_DOWN 3 // Joystick Down
-#define GINPUT_TOGGLE_LEFT 4 // Joystick Left
-#define GINPUT_TOGGLE_RIGHT 5 // Joystick Right
-#define GINPUT_TOGGLE_CENTER 6 // Joystick Center
-
-#define GINPUT_TOGGLE_DECLARE_STRUCTURE() \
- const GToggleConfig GInputToggleConfigTable[GINPUT_TOGGLE_CONFIG_ENTRIES] = { \
- {AT91C_BASE_PIOB, /* Switch 1 and Switch 2 */ \
- PIOB_SW1_MASK|PIOB_SW2_MASK, \
- PIOB_SW1_MASK|PIOB_SW2_MASK, \
- PAL_MODE_INPUT}, \
- {AT91C_BASE_PIOA, /* B1..4 Joystick */ \
- PIOA_B1_MASK|PIOA_B2_MASK|PIOA_B3_MASK|PIOA_B4_MASK|PIOA_B5_MASK, \
- PIOA_B1_MASK|PIOA_B2_MASK|PIOA_B3_MASK|PIOA_B4_MASK|PIOA_B5_MASK, \
- PAL_MODE_INPUT}, \
- }
-
-#endif /* _GDISP_LLD_TOGGLE_BOARD_H */
-/** @} */
+
+/**
+ * @file drivers/ginput/toggle/Pal/ginput_lld_toggle_board_template.h
+ * @brief GINPUT Toggle low level driver source for the ChibiOS PAL hardware on the example board.
+ *
+ * @defgroup Toggle Toggle
+ * @ingroup GINPUT
+ * @{
+ */
+
+#ifndef _GDISP_LLD_TOGGLE_BOARD_H
+#define _GDISP_LLD_TOGGLE_BOARD_H
+
+#error "GINPUT Toggle Pal Driver: You need to define your board definitions"
+
+// The below are example values
+
+#define GINPUT_TOGGLE_NUM_PORTS 7 // The total number of toggle inputs
+#define GINPUT_TOGGLE_CONFIG_ENTRIES 2 // The total number of GToggleConfig entries
+
+#define GINPUT_TOGGLE_SW1 0 // Switch 1
+#define GINPUT_TOGGLE_SW2 1 // Switch 2
+#define GINPUT_TOGGLE_UP 2 // Joystick Up
+#define GINPUT_TOGGLE_DOWN 3 // Joystick Down
+#define GINPUT_TOGGLE_LEFT 4 // Joystick Left
+#define GINPUT_TOGGLE_RIGHT 5 // Joystick Right
+#define GINPUT_TOGGLE_CENTER 6 // Joystick Center
+
+#define GINPUT_TOGGLE_DECLARE_STRUCTURE() \
+ const GToggleConfig GInputToggleConfigTable[GINPUT_TOGGLE_CONFIG_ENTRIES] = { \
+ {AT91C_BASE_PIOB, /* Switch 1 and Switch 2 */ \
+ PIOB_SW1_MASK|PIOB_SW2_MASK, \
+ PIOB_SW1_MASK|PIOB_SW2_MASK, \
+ PAL_MODE_INPUT}, \
+ {AT91C_BASE_PIOA, /* B1..4 Joystick */ \
+ PIOA_B1_MASK|PIOA_B2_MASK|PIOA_B3_MASK|PIOA_B4_MASK|PIOA_B5_MASK, \
+ PIOA_B1_MASK|PIOA_B2_MASK|PIOA_B3_MASK|PIOA_B4_MASK|PIOA_B5_MASK, \
+ PAL_MODE_INPUT}, \
+ }
+
+#endif /* _GDISP_LLD_TOGGLE_BOARD_H */
+/** @} */
diff --git a/drivers/ginput/toggle/Pal/ginput_lld_toggle_config.h b/drivers/ginput/toggle/Pal/ginput_lld_toggle_config.h
index e2bff490..84155956 100644
--- a/drivers/ginput/toggle/Pal/ginput_lld_toggle_config.h
+++ b/drivers/ginput/toggle/Pal/ginput_lld_toggle_config.h
@@ -19,15 +19,8 @@
#if GFX_USE_GINPUT && GINPUT_NEED_TOGGLE
-#if GINPUT_TOGGLE_USE_CUSTOM_BOARD
- /* Include the user supplied board definitions */
- #include "ginput_lld_toggle_board.h"
-#elif defined(BOARD_OLIMEX_SAM7_EX256)
- #include "ginput_lld_toggle_board_olimexsam7ex256.h"
-#else
- /* Include the user supplied board definitions */
- #include "ginput_lld_toggle_board.h"
-#endif
+/* Include the user supplied board definitions */
+#include "ginput_lld_toggle_board.h"
#endif /* GFX_USE_GDISP && GINPUT_NEED_TOGGLE */
diff --git a/drivers/ginput/touch/MCU/ginput_lld_mouse.c b/drivers/ginput/touch/MCU/ginput_lld_mouse.c
index 1bb7cd50..a64bf6cb 100644
--- a/drivers/ginput/touch/MCU/ginput_lld_mouse.c
+++ b/drivers/ginput/touch/MCU/ginput_lld_mouse.c
@@ -21,15 +21,7 @@
#include "ginput/lld/mouse.h"
-#if defined(GINPUT_MOUSE_USE_CUSTOM_BOARD) && GINPUT_MOUSE_USE_CUSTOM_BOARD
- #include "ginput_lld_mouse_board.h"
-#elif defined(BOARD_OLIMEX_STM32_LCD)
- #include "ginput_lld_mouse_board_olimex_stm32_lcd.h"
-#elif defined(BOARD_OLIMEX_PIC32MX_LCD)
- #include "ginput_lld_mouse_board_olimex_pic32mx_lcd.h"
-#else
- #include "ginput_lld_mouse_board.h"
-#endif
+#include "ginput_lld_mouse_board.h"
static uint16_t sampleBuf[7];
static coord_t lastx, lasty;
diff --git a/drivers/multiple/Win32/gdisp_lld.c b/drivers/multiple/Win32/gdisp_lld.c
deleted file mode 100644
index 0bac0fde..00000000
--- a/drivers/multiple/Win32/gdisp_lld.c
+++ /dev/null
@@ -1,1028 +0,0 @@
-/*
- * This file is subject to the terms of the GFX License. If a copy of
- * the license was not distributed with this file, you can obtain one at:
- *
- * http://ugfx.org/license.html
- */
-
-/**
- * @file drivers/multiple/Win32/gdisp_lld.c
- * @brief GDISP Graphics Driver subsystem low level driver source for Win32.
- *
- * @addtogroup GDISP
- * @{
- */
-
-#include "gfx.h"
-
-#if GFX_USE_GDISP /*|| defined(__DOXYGEN__)*/
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <windows.h>
-#include <wingdi.h>
-#include <assert.h>
-
-#ifndef GDISP_SCREEN_WIDTH
- #define GDISP_SCREEN_WIDTH 640
-#endif
-#ifndef GDISP_SCREEN_HEIGHT
- #define GDISP_SCREEN_HEIGHT 480
-#endif
-
-#if GINPUT_NEED_TOGGLE
- /* Include toggle support code */
- #include "ginput/lld/toggle.h"
-
- const GToggleConfig GInputToggleConfigTable[GINPUT_TOGGLE_CONFIG_ENTRIES] = {
- {0, 0xFF, 0x00, 0},
- };
-#endif
-
-#if GINPUT_NEED_MOUSE
- /* Include mouse support code */
- #include "ginput/lld/mouse.h"
-#endif
-
-/* Include the emulation code for things we don't support */
-#include "gdisp/lld/emulation.c"
-
-/*===========================================================================*/
-/* Driver local routines . */
-/*===========================================================================*/
-
-#define WIN32_USE_MSG_REDRAW FALSE
-#if GINPUT_NEED_TOGGLE
- #define WIN32_BUTTON_AREA 16
-#else
- #define WIN32_BUTTON_AREA 0
-#endif
-
-#define APP_NAME "GDISP"
-
-#define COLOR2BGR(c) ((((c) & 0xFF)<<16)|((c) & 0xFF00)|(((c)>>16) & 0xFF))
-#define BGR2COLOR(c) COLOR2BGR(c)
-
-static HWND winRootWindow = NULL;
-static HDC dcBuffer = NULL;
-static HBITMAP dcBitmap = NULL;
-static HBITMAP dcOldBitmap;
-static volatile bool_t isReady = FALSE;
-static coord_t wWidth, wHeight;
-
-#if GINPUT_NEED_MOUSE
- static coord_t mousex, mousey;
- static uint16_t mousebuttons;
-#endif
-#if GINPUT_NEED_TOGGLE
- static uint8_t toggles = 0;
-#endif
-
-static LRESULT myWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
-{
- HDC dc;
- PAINTSTRUCT ps;
- #if GINPUT_NEED_TOGGLE
- HBRUSH hbrOn, hbrOff;
- HPEN pen;
- RECT rect;
- HGDIOBJ old;
- POINT p;
- coord_t pos;
- uint8_t bit;
- #endif
-
- switch (Msg) {
- case WM_CREATE:
- break;
- case WM_LBUTTONDOWN:
- #if GINPUT_NEED_MOUSE
- if ((coord_t)HIWORD(lParam) < wHeight) {
- mousebuttons |= GINPUT_MOUSE_BTN_LEFT;
- goto mousemove;
- }
- #endif
- #if GINPUT_NEED_TOGGLE
- bit = 1 << ((coord_t)LOWORD(lParam)*8/wWidth);
- toggles ^= bit;
- rect.left = 0;
- rect.right = wWidth;
- rect.top = wHeight;
- rect.bottom = wHeight + WIN32_BUTTON_AREA;
- InvalidateRect(hWnd, &rect, FALSE);
- UpdateWindow(hWnd);
- #if GINPUT_TOGGLE_POLL_PERIOD == TIME_INFINITE
- ginputToggleWakeup();
- #endif
- #endif
- break;
- case WM_LBUTTONUP:
- #if GINPUT_NEED_TOGGLE
- if ((toggles & 0x0F)) {
- toggles &= ~0x0F;
- rect.left = 0;
- rect.right = wWidth;
- rect.top = wHeight;
- rect.bottom = wHeight + WIN32_BUTTON_AREA;
- InvalidateRect(hWnd, &rect, FALSE);
- UpdateWindow(hWnd);
- #if GINPUT_TOGGLE_POLL_PERIOD == TIME_INFINITE
- ginputToggleWakeup();
- #endif
- }
- #endif
- #if GINPUT_NEED_MOUSE
- if ((coord_t)HIWORD(lParam) < wHeight) {
- mousebuttons &= ~GINPUT_MOUSE_BTN_LEFT;
- goto mousemove;
- }
- #endif
- break;
-#if GINPUT_NEED_MOUSE
- case WM_MBUTTONDOWN:
- if ((coord_t)HIWORD(lParam) < wHeight) {
- mousebuttons |= GINPUT_MOUSE_BTN_MIDDLE;
- goto mousemove;
- }
- break;
- case WM_MBUTTONUP:
- if ((coord_t)HIWORD(lParam) < wHeight) {
- mousebuttons &= ~GINPUT_MOUSE_BTN_MIDDLE;
- goto mousemove;
- }
- break;
- case WM_RBUTTONDOWN:
- if ((coord_t)HIWORD(lParam) < wHeight) {
- mousebuttons |= GINPUT_MOUSE_BTN_RIGHT;
- goto mousemove;
- }
- break;
- case WM_RBUTTONUP:
- if ((coord_t)HIWORD(lParam) < wHeight) {
- mousebuttons &= ~GINPUT_MOUSE_BTN_RIGHT;
- goto mousemove;
- }
- break;
- case WM_MOUSEMOVE:
- if ((coord_t)HIWORD(lParam) >= wHeight)
- break;
- mousemove:
- mousex = (coord_t)LOWORD(lParam);
- mousey = (coord_t)HIWORD(lParam);
- #if GINPUT_MOUSE_POLL_PERIOD == TIME_INFINITE
- ginputMouseWakeup();
- #endif
- break;
-#endif
- case WM_SYSKEYDOWN:
- case WM_KEYDOWN:
- case WM_SYSKEYUP:
- case WM_KEYUP:
- break;
- case WM_CHAR:
- case WM_DEADCHAR:
- case WM_SYSCHAR:
- case WM_SYSDEADCHAR:
- break;
- case WM_PAINT:
- dc = BeginPaint(hWnd, &ps);
- BitBlt(dc, ps.rcPaint.left, ps.rcPaint.top,
- ps.rcPaint.right - ps.rcPaint.left,
- (ps.rcPaint.bottom > wHeight ? wHeight : ps.rcPaint.bottom) - ps.rcPaint.top,
- dcBuffer, ps.rcPaint.left, ps.rcPaint.top, SRCCOPY);
- #if GINPUT_NEED_TOGGLE
- if (ps.rcPaint.bottom >= wHeight) {
- pen = CreatePen(PS_SOLID, 1, COLOR2BGR(Black));
- hbrOn = CreateSolidBrush(COLOR2BGR(Blue));
- hbrOff = CreateSolidBrush(COLOR2BGR(Gray));
- old = SelectObject(dc, pen);
- MoveToEx(dc, 0, wHeight, &p);
- LineTo(dc, wWidth, wHeight);
- for(pos = 0, bit=1; pos < wWidth; pos=rect.right, bit <<= 1) {
- rect.left = pos;
- rect.right = pos + wWidth/8;
- rect.top = wHeight;
- rect.bottom = wHeight + WIN32_BUTTON_AREA;
- FillRect(dc, &rect, (toggles & bit) ? hbrOn : hbrOff);
- if (pos > 0) {
- MoveToEx(dc, rect.left, rect.top, &p);
- LineTo(dc, rect.left, rect.bottom);
- }
- }
- DeleteObject(hbrOn);
- DeleteObject(hbrOff);
- SelectObject(dc, old);
- }
- #endif
- EndPaint(hWnd, &ps);
- break;
- case WM_DESTROY:
- PostQuitMessage(0);
- SelectObject(dcBuffer, dcOldBitmap);
- DeleteDC(dcBuffer);
- DeleteObject(dcBitmap);
- winRootWindow = NULL;
- break;
- default:
- return DefWindowProc(hWnd, Msg, wParam, lParam);
- }
- return 0;
-}
-
-static void InitWindow(void) {
- HANDLE hInstance;
- WNDCLASS wc;
- RECT rect;
- HDC dc;
-
- hInstance = GetModuleHandle(NULL);
-
- wc.style = CS_HREDRAW | CS_VREDRAW; // | CS_OWNDC;
- wc.lpfnWndProc = (WNDPROC)myWindowProc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- wc.hInstance = hInstance;
- wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
- wc.hCursor = LoadCursor(NULL, IDC_ARROW);
- wc.hbrBackground = GetStockObject(WHITE_BRUSH);
- wc.lpszMenuName = NULL;
- wc.lpszClassName = APP_NAME;
- RegisterClass(&wc);
-
- rect.top = 0; rect.bottom = wHeight+WIN32_BUTTON_AREA;
- rect.left = 0; rect.right = wWidth;
- AdjustWindowRect(&rect, WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU, 0);
- winRootWindow = CreateWindow(APP_NAME, "", WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU, 0, 0,
- rect.right-rect.left, rect.bottom-rect.top, 0, 0, hInstance, NULL);
- assert(winRootWindow != NULL);
-
-
- GetClientRect(winRootWindow, &rect);
- wWidth = rect.right-rect.left;
- wHeight = rect.bottom - rect.top - WIN32_BUTTON_AREA;
-
- dc = GetDC(winRootWindow);
- dcBitmap = CreateCompatibleBitmap(dc, wWidth, wHeight);
- dcBuffer = CreateCompatibleDC(dc);
- ReleaseDC(winRootWindow, dc);
- dcOldBitmap = SelectObject(dcBuffer, dcBitmap);
-
- ShowWindow(winRootWindow, SW_SHOW);
- UpdateWindow(winRootWindow);
- isReady = TRUE;
-}
-
-static DECLARE_THREAD_STACK(waWindowThread, 1024);
-static DECLARE_THREAD_FUNCTION(WindowThread, param) {
- (void)param;
- MSG msg;
-
- InitWindow();
- do {
- gfxSleepMilliseconds(1);
- while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- } while (msg.message != WM_QUIT);
- ExitProcess(0);
- return msg.wParam;
-}
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/* ---- Required Routines ---- */
-/*
- The following 2 routines are required.
- All other routines are optional.
-*/
-
-/**
- * @brief Low level GDISP driver initialisation.
- * @return TRUE if successful, FALSE on error.
- *
- * @notapi
- */
-bool_t gdisp_lld_init(void) {
- RECT rect;
- gfxThreadHandle hth;
-
- /* Set the window dimensions */
- GetWindowRect(GetDesktopWindow(), &rect);
- wWidth = rect.right - rect.left;
- wHeight = rect.bottom - rect.top - WIN32_BUTTON_AREA;
- if (wWidth > GDISP_SCREEN_WIDTH)
- wWidth = GDISP_SCREEN_WIDTH;
- if (wHeight > GDISP_SCREEN_HEIGHT)
- wHeight = GDISP_SCREEN_HEIGHT;
-
- /* Initialise the window */
- if (!(hth = gfxThreadCreate(waWindowThread, sizeof(waWindowThread), HIGH_PRIORITY, WindowThread, 0))) {
- fprintf(stderr, "Cannot create window thread\n");
- exit(-1);
- }
- gfxThreadClose(hth);
- while (!isReady)
- Sleep(1);
-
- /* Initialise the GDISP structure to match */
- GDISP.Orientation = GDISP_ROTATE_0;
- GDISP.Powermode = powerOn;
- GDISP.Backlight = 100;
- GDISP.Contrast = 50;
- GDISP.Width = wWidth;
- GDISP.Height = wHeight;
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- GDISP.clipx0 = 0;
- GDISP.clipy0 = 0;
- GDISP.clipx1 = GDISP.Width;
- GDISP.clipy1 = GDISP.Height;
- #endif
- return TRUE;
-}
-
-/**
- * @brief Draws a pixel on the display.
- *
- * @param[in] x X location of the pixel
- * @param[in] y Y location of the pixel
- * @param[in] color The color of the pixel
- *
- * @notapi
- */
-void gdisp_lld_draw_pixel(coord_t x, coord_t y, color_t color) {
- HDC dc;
- #if WIN32_USE_MSG_REDRAW
- RECT rect;
- #endif
- #if GDISP_NEED_CONTROL
- coord_t t;
- #endif
-
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- // Clip pre orientation change
- if (x < GDISP.clipx0 || y < GDISP.clipy0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
- #endif
-
- #if GDISP_NEED_CONTROL
- switch(GDISP.Orientation) {
- case GDISP_ROTATE_0:
- break;
- case GDISP_ROTATE_90:
- t = GDISP.Height - 1 - y;
- y = x;
- x = t;
- break;
- case GDISP_ROTATE_180:
- x = GDISP.Width - 1 - x;
- y = GDISP.Height - 1 - y;
- break;
- case GDISP_ROTATE_270:
- t = GDISP.Width - 1 - x;
- x = y;
- y = t;
- break;
- }
- #endif
-
- // Draw the pixel in the buffer
- color = COLOR2BGR(color);
- SetPixel(dcBuffer, x, y, color);
-
- #if WIN32_USE_MSG_REDRAW
- rect.left = x; rect.right = x+1;
- rect.top = y; rect.bottom = y+1;
- InvalidateRect(winRootWindow, &rect, FALSE);
- UpdateWindow(winRootWindow);
- #else
- // Draw the pixel again directly on the screen.
- // This is cheaper than invalidating a single pixel in the window
- dc = GetDC(winRootWindow);
- SetPixel(dc, x, y, color);
- ReleaseDC(winRootWindow, dc);
- #endif
-}
-
-/* ---- Optional Routines ---- */
-
-#if GDISP_HARDWARE_LINES || defined(__DOXYGEN__)
- /**
- * @brief Draw a line.
- * @note Optional - The high level driver can emulate using software.
- *
- * @param[in] x0, y0 The start of the line
- * @param[in] x1, y1 The end of the line
- * @param[in] color The color of the line
- *
- * @notapi
- */
- void gdisp_lld_draw_line(coord_t x0, coord_t y0, coord_t x1, coord_t y1, color_t color) {
- POINT p;
- HPEN pen;
- HDC dc;
- HGDIOBJ old;
- #if GDISP_NEED_CLIP
- HRGN clip;
- #endif
- #if WIN32_USE_MSG_REDRAW
- RECT rect;
- #endif
- #if GDISP_NEED_CONTROL
- coord_t t;
- #endif
-
- #if GDISP_NEED_CLIP
- clip = NULL;
- #endif
-
- #if GDISP_NEED_CONTROL
- switch(GDISP.Orientation) {
- case GDISP_ROTATE_0:
- #if GDISP_NEED_CLIP
- // Clip post orientation change
- if (GDISP.clipx0 != 0 || GDISP.clipy0 != 0 || GDISP.clipx1 != GDISP.Width || GDISP.clipy1 != GDISP.Height)
- clip = CreateRectRgn(GDISP.clipx0, GDISP.clipy0, GDISP.clipx1, GDISP.clipy1);
- #endif
- break;
- case GDISP_ROTATE_90:
- t = GDISP.Height - 1 - y0;
- y0 = x0;
- x0 = t;
- t = GDISP.Height - 1 - y1;
- y1 = x1;
- x1 = t;
- #if GDISP_NEED_CLIP
- // Clip post orientation change
- if (GDISP.clipx0 != 0 || GDISP.clipy0 != 0 || GDISP.clipx1 != GDISP.Width || GDISP.clipy1 != GDISP.Height)
- clip = CreateRectRgn(GDISP.Height-1-GDISP.clipy1, GDISP.clipx0, GDISP.Height-1-GDISP.clipy0, GDISP.clipx1);
- #endif
- break;
- case GDISP_ROTATE_180:
- x0 = GDISP.Width - 1 - x0;
- y0 = GDISP.Height - 1 - y0;
- x1 = GDISP.Width - 1 - x1;
- y1 = GDISP.Height - 1 - y1;
- #if GDISP_NEED_CLIP
- // Clip post orientation change
- if (GDISP.clipx0 != 0 || GDISP.clipy0 != 0 || GDISP.clipx1 != GDISP.Width || GDISP.clipy1 != GDISP.Height)
- clip = CreateRectRgn(GDISP.Width-1-GDISP.clipx1, GDISP.Height-1-GDISP.clipy1, GDISP.Width-1-GDISP.clipx0, GDISP.Height-1-GDISP.clipy0);
- #endif
- break;
- case GDISP_ROTATE_270:
- t = GDISP.Width - 1 - x0;
- x0 = y0;
- y0 = t;
- t = GDISP.Width - 1 - x1;
- x1 = y1;
- y1 = t;
- #if GDISP_NEED_CLIP
- // Clip post orientation change
- if (GDISP.clipx0 != 0 || GDISP.clipy0 != 0 || GDISP.clipx1 != GDISP.Width || GDISP.clipy1 != GDISP.Height)
- clip = CreateRectRgn(GDISP.clipy0, GDISP.Width-1-GDISP.clipx1, GDISP.clipy1, GDISP.Width-1-GDISP.clipx0);
- #endif
- break;
- }
- #else
- #if GDISP_NEED_CLIP
- clip = NULL;
- if (GDISP.clipx0 != 0 || GDISP.clipy0 != 0 || GDISP.clipx1 != GDISP.Width || GDISP.clipy1 != GDISP.Height)
- clip = CreateRectRgn(GDISP.clipx0, GDISP.clipy0, GDISP.clipx1, GDISP.clipy1);
- #endif
- #endif
-
- color = COLOR2BGR(color);
- pen = CreatePen(PS_SOLID, 1, color);
- if (pen) {
- // Draw the line in the buffer
- #if GDISP_NEED_CLIP
- if (clip) SelectClipRgn(dcBuffer, clip);
- #endif
- old = SelectObject(dcBuffer, pen);
- MoveToEx(dcBuffer, x0, y0, &p);
- LineTo(dcBuffer, x1, y1);
- SelectObject(dcBuffer, old);
- SetPixel(dcBuffer, x1, y1, color);
- #if GDISP_NEED_CLIP
- if (clip) SelectClipRgn(dcBuffer, NULL);
- #endif
-
- #if WIN32_USE_MSG_REDRAW
- rect.left = x0; rect.right = x1+1;
- rect.top = y0; rect.bottom = y1+1;
- InvalidateRect(winRootWindow, &rect, FALSE);
- UpdateWindow(winRootWindow);
- #else
- // Redrawing the line on the screen is cheaper than invalidating the whole rectangular area
- dc = GetDC(winRootWindow);
- #if GDISP_NEED_CLIP
- if (clip) SelectClipRgn(dc, clip);
- #endif
- old = SelectObject(dc, pen);
- MoveToEx(dc, x0, y0, &p);
- LineTo(dc, x1, y1);
- SelectObject(dc, old);
- SetPixel(dc, x1, y1, color);
- #if GDISP_NEED_CLIP
- if (clip) SelectClipRgn(dc, NULL);
- #endif
- ReleaseDC(winRootWindow, dc);
- #endif
-
- DeleteObject(pen);
- }
- }
-#endif
-
-#if GDISP_HARDWARE_FILLS || defined(__DOXYGEN__)
- /**
- * @brief Fill an area with a color.
- * @note Optional - The high level driver can emulate using software.
- *
- * @param[in] x, y The start filled area
- * @param[in] cx, cy The width and height to be filled
- * @param[in] color The color of the fill
- *
- * @notapi
- */
- void gdisp_lld_fill_area(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
- HDC dc;
- RECT rect;
- HBRUSH hbr;
-
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- // Clip pre orientation change
- if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; }
- if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; }
- if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
- if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
- if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
- #endif
-
- #if GDISP_NEED_CONTROL
- switch(GDISP.Orientation) {
- case GDISP_ROTATE_0:
- rect.top = y;
- rect.bottom = rect.top+cy;
- rect.left = x;
- rect.right = rect.left+cx;
- break;
- case GDISP_ROTATE_90:
- rect.top = x;
- rect.bottom = rect.top+cx;
- rect.right = GDISP.Height - y;
- rect.left = rect.right-cy;
- break;
- case GDISP_ROTATE_180:
- rect.bottom = GDISP.Height - y;
- rect.top = rect.bottom-cy;
- rect.right = GDISP.Width - x;
- rect.left = rect.right-cx;
- break;
- case GDISP_ROTATE_270:
- rect.bottom = GDISP.Width - x;
- rect.top = rect.bottom-cx;
- rect.left = y;
- rect.right = rect.left+cy;
- break;
- }
- #else
- rect.top = y;
- rect.bottom = rect.top+cy;
- rect.left = x;
- rect.right = rect.left+cx;
- #endif
-
- color = COLOR2BGR(color);
- hbr = CreateSolidBrush(color);
-
- if (hbr) {
- // Fill the area
- FillRect(dcBuffer, &rect, hbr);
-
- #if WIN32_USE_MSG_REDRAW
- InvalidateRect(winRootWindow, &rect, FALSE);
- UpdateWindow(winRootWindow);
- #else
- // Filling the area directly on the screen is likely to be cheaper than invalidating it
- dc = GetDC(winRootWindow);
- FillRect(dc, &rect, hbr);
- ReleaseDC(winRootWindow, dc);
- #endif
-
- DeleteObject(hbr);
- }
- }
-#endif
-
-#if (GDISP_HARDWARE_BITFILLS && GDISP_NEED_CONTROL) || defined(__DOXYGEN__)
- static pixel_t *rotateimg(coord_t cx, coord_t cy, coord_t srcx, coord_t srccx, const pixel_t *buffer) {
- pixel_t *dstbuf;
- pixel_t *dst;
- const pixel_t *src;
- size_t sz;
- coord_t i, j;
-
- // Shortcut.
- if (GDISP.Orientation == GDISP_ROTATE_0 && srcx == 0 && cx == srccx)
- return (pixel_t *)buffer;
-
- // Allocate the destination buffer
- sz = (size_t)cx * (size_t)cy;
- if (!(dstbuf = (pixel_t *)malloc(sz * sizeof(pixel_t))))
- return 0;
-
- // Copy the bits we need
- switch(GDISP.Orientation) {
- case GDISP_ROTATE_0:
- for(dst = dstbuf, src = buffer+srcx, j = 0; j < cy; j++)
- for(i = 0; i < cx; i++, src += srccx - cx)
- *dst++ = *src++;
- break;
- case GDISP_ROTATE_90:
- for(src = buffer+srcx, j = 0; j < cy; j++) {
- dst = dstbuf+cy-j-1;
- for(i = 0; i < cx; i++, src += srccx - cx, dst += cy)
- *dst = *src++;
- }
- break;
- case GDISP_ROTATE_180:
- for(dst = dstbuf+sz, src = buffer+srcx, j = 0; j < cy; j++)
- for(i = 0; i < cx; i++, src += srccx - cx)
- *--dst = *src++;
- break;
- case GDISP_ROTATE_270:
- for(src = buffer+srcx, j = 0; j < cy; j++) {
- dst = dstbuf+sz-cy+j;
- for(i = 0; i < cx; i++, src += srccx - cx, dst -= cy)
- *dst = *src++;
- }
- break;
- }
- return dstbuf;
- }
-#endif
-
-#if GDISP_HARDWARE_BITFILLS || defined(__DOXYGEN__)
- /**
- * @brief Fill an area with a bitmap.
- * @note Optional - The high level driver can emulate using software.
- *
- * @param[in] x, y The start filled area
- * @param[in] cx, cy The width and height to be filled
- * @param[in] srcx, srcy The bitmap position to start the fill from
- * @param[in] srccx The width of a line in the bitmap.
- * @param[in] buffer The pixels to use to fill the area.
- *
- * @notapi
- */
- void gdisp_lld_blit_area_ex(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx, coord_t srcy, coord_t srccx, const pixel_t *buffer) {
- BITMAPV4HEADER bmpInfo;
- RECT rect;
- #if GDISP_NEED_CONTROL
- pixel_t *srcimg;
- #endif
-
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- // Clip pre orientation change
- if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; srcx += GDISP.clipx0 - x; x = GDISP.clipx0; }
- if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; srcy += GDISP.clipy0 - y; y = GDISP.clipy0; }
- if (srcx+cx > srccx) cx = srccx - srcx;
- if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
- if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
- if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
- #endif
-
- // Make everything relative to the start of the line
- buffer += srccx*srcy;
- srcy = 0;
-
- memset(&bmpInfo, 0, sizeof(bmpInfo));
- bmpInfo.bV4Size = sizeof(bmpInfo);
- bmpInfo.bV4Planes = 1;
- bmpInfo.bV4BitCount = 32;
- bmpInfo.bV4AlphaMask = 0;
- bmpInfo.bV4RedMask = RGB2COLOR(255,0,0);
- bmpInfo.bV4GreenMask = RGB2COLOR(0,255,0);
- bmpInfo.bV4BlueMask = RGB2COLOR(0,0,255);
- bmpInfo.bV4V4Compression = BI_BITFIELDS;
- bmpInfo.bV4XPelsPerMeter = 3078;
- bmpInfo.bV4YPelsPerMeter = 3078;
- bmpInfo.bV4ClrUsed = 0;
- bmpInfo.bV4ClrImportant = 0;
- bmpInfo.bV4CSType = 0; //LCS_sRGB;
-
- #if GDISP_NEED_CONTROL
- bmpInfo.bV4SizeImage = (cy*cx) * sizeof(pixel_t);
- srcimg = rotateimg(cx, cy, srcx, srccx, buffer);
- if (!srcimg) return;
-
- switch(GDISP.Orientation) {
- case GDISP_ROTATE_0:
- bmpInfo.bV4Width = cx;
- bmpInfo.bV4Height = -cy; /* top-down image */
- rect.top = y;
- rect.bottom = rect.top+cy;
- rect.left = x;
- rect.right = rect.left+cx;
- break;
- case GDISP_ROTATE_90:
- bmpInfo.bV4Width = cy;
- bmpInfo.bV4Height = -cx; /* top-down image */
- rect.top = x;
- rect.bottom = rect.top+cx;
- rect.right = GDISP.Height - y;
- rect.left = rect.right-cy;
- break;
- case GDISP_ROTATE_180:
- bmpInfo.bV4Width = cx;
- bmpInfo.bV4Height = -cy; /* top-down image */
- rect.bottom = GDISP.Height - y;
- rect.top = rect.bottom-cy;
- rect.right = GDISP.Width - x;
- rect.left = rect.right-cx;
- break;
- case GDISP_ROTATE_270:
- bmpInfo.bV4Width = cy;
- bmpInfo.bV4Height = -cx; /* top-down image */
- rect.bottom = GDISP.Width - x;
- rect.top = rect.bottom-cx;
- rect.left = y;
- rect.right = rect.left+cy;
- break;
- }
- SetDIBitsToDevice(dcBuffer, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, 0, 0, 0, rect.bottom-rect.top, srcimg, (BITMAPINFO*)&bmpInfo, DIB_RGB_COLORS);
- if (srcimg != (pixel_t *)buffer)
- free(srcimg);
-
- #else
- bmpInfo.bV4Width = srccx;
- bmpInfo.bV4Height = -cy; /* top-down image */
- bmpInfo.bV4SizeImage = (cy*srccx) * sizeof(pixel_t);
- rect.top = y;
- rect.bottom = rect.top+cy;
- rect.left = x;
- rect.right = rect.left+cx;
- SetDIBitsToDevice(dcBuffer, x, y, cx, cy, srcx, 0, 0, cy, buffer, (BITMAPINFO*)&bmpInfo, DIB_RGB_COLORS);
- #endif
-
- // Invalidate the region to get it on the screen.
- InvalidateRect(winRootWindow, &rect, FALSE);
- UpdateWindow(winRootWindow);
- }
-#endif
-
-#if (GDISP_NEED_PIXELREAD && GDISP_HARDWARE_PIXELREAD) || defined(__DOXYGEN__)
- /**
- * @brief Get the color of a particular pixel.
- * @note Optional.
- * @note If x,y is off the screen, the result is undefined.
- * @return The color of the specified pixel.
- *
- * @param[in] x, y The start of the text
- *
- * @notapi
- */
- color_t gdisp_lld_get_pixel_color(coord_t x, coord_t y) {
- color_t color;
- #if GDISP_NEED_CONTROL
- coord_t t;
- #endif
-
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- // Clip pre orientation change
- if (x < 0 || x >= GDISP.Width || y < 0 || y >= GDISP.Height) return 0;
- #endif
-
- #if GDISP_NEED_CONTROL
- switch(GDISP.Orientation) {
- case GDISP_ROTATE_0:
- break;
- case GDISP_ROTATE_90:
- t = GDISP.Height - 1 - y;
- y = x;
- x = t;
- break;
- case GDISP_ROTATE_180:
- x = GDISP.Width - 1 - x;
- y = GDISP.Height - 1 - y;
- break;
- case GDISP_ROTATE_270:
- t = GDISP.Width - 1 - x;
- x = y;
- y = t;
- break;
- }
- #endif
-
- color = GetPixel(dcBuffer, x, y);
- return BGR2COLOR(color);
- }
-#endif
-
-#if (GDISP_NEED_SCROLL && GDISP_HARDWARE_SCROLL) || defined(__DOXYGEN__)
- /**
- * @brief Scroll vertically a section of the screen.
- * @note Optional.
- * @note If x,y + cx,cy is off the screen, the result is undefined.
- * @note If lines is >= cy, it is equivelent to a area fill with bgcolor.
- *
- * @param[in] x, y The start of the area to be scrolled
- * @param[in] cx, cy The size of the area to be scrolled
- * @param[in] lines The number of lines to scroll (Can be positive or negative)
- * @param[in] bgcolor The color to fill the newly exposed area.
- *
- * @notapi
- */
- void gdisp_lld_vertical_scroll(coord_t x, coord_t y, coord_t cx, coord_t cy, int lines, color_t bgcolor) {
- RECT rect, frect, srect;
- HBRUSH hbr;
-
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- // Clip pre orientation change
- if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; }
- if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; }
- if (!lines || cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
- if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
- if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
- #endif
-
- if (lines > cy) lines = cy;
- else if (-lines > cy) lines = -cy;
-
- bgcolor = COLOR2BGR(bgcolor);
- hbr = CreateSolidBrush(bgcolor);
-
- #if GDISP_NEED_CONTROL
- switch(GDISP.Orientation) {
- case GDISP_ROTATE_0:
- rect.top = y;
- rect.bottom = rect.top+cy;
- rect.left = x;
- rect.right = rect.left+cx;
- lines = -lines;
- goto vertical_scroll;
- case GDISP_ROTATE_90:
- rect.top = x;
- rect.bottom = rect.top+cx;
- rect.right = GDISP.Height - y;
- rect.left = rect.right-cy;
- goto horizontal_scroll;
- case GDISP_ROTATE_180:
- rect.bottom = GDISP.Height - y;
- rect.top = rect.bottom-cy;
- rect.right = GDISP.Width - x;
- rect.left = rect.right-cx;
- vertical_scroll:
- srect.left = frect.left = rect.left;
- srect.right = frect.right = rect.right;
- if (lines > 0) {
- srect.top = frect.top = rect.top;
- frect.bottom = rect.top+lines;
- srect.bottom = rect.bottom-lines;
- } else {
- srect.bottom = frect.bottom = rect.bottom;
- frect.top = rect.bottom+lines;
- srect.top = rect.top-lines;
- }
- if (cy >= lines && cy >= -lines)
- ScrollDC(dcBuffer, 0, lines, &srect, 0, 0, 0);
- break;
- case GDISP_ROTATE_270:
- rect.bottom = GDISP.Width - x;
- rect.top = rect.bottom-cx;
- rect.left = y;
- rect.right = rect.left+cy;
- lines = -lines;
- horizontal_scroll:
- srect.top = frect.top = rect.top;
- srect.bottom = frect.bottom = rect.bottom;
- if (lines > 0) {
- srect.left = frect.left = rect.left;
- frect.right = rect.left+lines;
- srect.right = rect.right-lines;
- } else {
- srect.right = frect.right = rect.right;
- frect.left = rect.right+lines;
- srect.left = rect.left-lines;
- }
- if (cy >= lines && cy >= -lines)
- ScrollDC(dcBuffer, lines, 0, &srect, 0, 0, 0);
- break;
- }
- #else
- rect.top = y;
- rect.bottom = rect.top+cy;
- rect.left = x;
- rect.right = rect.left+cx;
- lines = -lines;
- srect.left = frect.left = rect.left;
- srect.right = frect.right = rect.right;
- if (lines > 0) {
- srect.top = frect.top = rect.top;
- frect.bottom = rect.top+lines;
- srect.bottom = rect.bottom-lines;
- } else {
- srect.bottom = frect.bottom = rect.bottom;
- frect.top = rect.bottom+lines;
- srect.top = rect.top-lines;
- }
- if (cy >= lines && cy >= -lines)
- ScrollDC(dcBuffer, 0, lines, &srect, 0, 0, 0);
- #endif
-
- if (hbr)
- FillRect(dcBuffer, &frect, hbr);
- InvalidateRect(winRootWindow, &rect, FALSE);
- UpdateWindow(winRootWindow);
- }
-#endif
-
-#if (GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL) || defined(__DOXYGEN__)
- /**
- * @brief Driver Control
- * @detail Unsupported control codes are ignored.
- * @note The value parameter should always be typecast to (void *).
- * @note There are some predefined and some specific to the low level driver.
- * @note GDISP_CONTROL_POWER - Takes a gdisp_powermode_t
- * GDISP_CONTROL_ORIENTATION - Takes a gdisp_orientation_t
- * GDISP_CONTROL_BACKLIGHT - Takes an int from 0 to 100. For a driver
- * that only supports off/on anything other
- * than zero is on.
- * GDISP_CONTROL_CONTRAST - Takes an int from 0 to 100.
- * GDISP_CONTROL_LLD - Low level driver control constants start at
- * this value.
- *
- * @param[in] what What to do.
- * @param[in] value The value to use (always cast to a void *).
- *
- * @notapi
- */
- void gdisp_lld_control(unsigned what, void *value) {
- switch(what) {
- case GDISP_CONTROL_ORIENTATION:
- if (GDISP.Orientation == (gdisp_orientation_t)value)
- return;
- switch((gdisp_orientation_t)value) {
- case GDISP_ROTATE_0:
- GDISP.Width = wWidth;
- GDISP.Height = wHeight;
- break;
- case GDISP_ROTATE_90:
- GDISP.Height = wWidth;
- GDISP.Width = wHeight;
- break;
- case GDISP_ROTATE_180:
- GDISP.Width = wWidth;
- GDISP.Height = wHeight;
- break;
- case GDISP_ROTATE_270:
- GDISP.Height = wWidth;
- GDISP.Width = wHeight;
- break;
- default:
- return;
- }
-
- #if GDISP_NEED_CLIP || GDISP_NEED_VALIDATION
- GDISP.clipx0 = 0;
- GDISP.clipy0 = 0;
- GDISP.clipx1 = GDISP.Width;
- GDISP.clipy1 = GDISP.Height;
- #endif
- GDISP.Orientation = (gdisp_orientation_t)value;
- return;
-/*
- case GDISP_CONTROL_POWER:
- case GDISP_CONTROL_BACKLIGHT:
- case GDISP_CONTROL_CONTRAST:
-*/
- }
- }
-#endif
-
-#if GINPUT_NEED_MOUSE
-
- void ginput_lld_mouse_init(void) {}
-
- void ginput_lld_mouse_get_reading(MouseReading *pt) {
- pt->x = mousex;
- pt->y = mousey > wHeight ? wHeight : mousey;
- pt->z = (mousebuttons & GINPUT_MOUSE_BTN_LEFT) ? 100 : 0;
- pt->buttons = mousebuttons;
- }
-
-#endif /* GINPUT_NEED_MOUSE */
-
-#if GINPUT_NEED_TOGGLE
-
- void ginput_lld_toggle_init(const GToggleConfig *ptc) { (void) ptc; }
- unsigned ginput_lld_toggle_getbits(const GToggleConfig *ptc) { (void) ptc; return toggles; }
-
-#endif /* GINPUT_NEED_MOUSE */
-
-#endif /* GFX_USE_GDISP */
-/** @} */
-
diff --git a/drivers/multiple/Win32/gdisp_lld.mk b/drivers/multiple/Win32/gdisp_lld.mk
index b116088b..f9242380 100644
--- a/drivers/multiple/Win32/gdisp_lld.mk
+++ b/drivers/multiple/Win32/gdisp_lld.mk
@@ -1,5 +1,2 @@
-# List the required driver.
-GFXSRC += $(GFXLIB)/drivers/multiple/Win32/gdisp_lld.c
-
-# Required include directories
GFXINC += $(GFXLIB)/drivers/multiple/Win32
+GFXSRC += $(GFXLIB)/drivers/multiple/Win32/gdisp_lld_Win32.c
diff --git a/drivers/multiple/Win32/gdisp_lld_Win32.c b/drivers/multiple/Win32/gdisp_lld_Win32.c
new file mode 100644
index 00000000..9484c823
--- /dev/null
+++ b/drivers/multiple/Win32/gdisp_lld_Win32.c
@@ -0,0 +1,1160 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/multiple/Win32/gdisp_lld.c
+ * @brief GDISP Graphics Driver subsystem low level driver source for Win32.
+ */
+#include "gfx.h"
+
+#if GFX_USE_GDISP
+
+#define GDISP_DRIVER_VMT GDISPVMT_Win32
+#include "../drivers/multiple/Win32/gdisp_lld_config.h"
+#include "gdisp/lld/gdisp_lld.h"
+
+#ifndef GDISP_SCREEN_WIDTH
+ #define GDISP_SCREEN_WIDTH 640
+#endif
+#ifndef GDISP_SCREEN_HEIGHT
+ #define GDISP_SCREEN_HEIGHT 480
+#endif
+
+// Setting this to TRUE delays updating the screen
+// to the windows paint routine. Due to the
+// drawing lock this does not add as much speed
+// as might be expected but it is still faster in
+// all tested circumstances and for all operations
+// even draw_pixel().
+// This is probably due to drawing operations being
+// combined as the update regions are merged.
+// The only time you might want to turn this off is
+// if you are debugging drawing and want to see each
+// pixel as it is set.
+#define GDISP_WIN32_USE_INDIRECT_UPDATE TRUE
+//#define GDISP_WIN32_USE_INDIRECT_UPDATE FALSE
+
+// How far extra windows (multiple displays) should be offset from the first.
+#define DISPLAY_X_OFFSET 50
+#define DISPLAY_Y_OFFSET 50
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <windows.h>
+#include <wingdi.h>
+#include <assert.h>
+
+#define GDISP_FLG_READY (GDISP_FLG_DRIVER<<0)
+#define GDISP_FLG_HASTOGGLE (GDISP_FLG_DRIVER<<1)
+#define GDISP_FLG_HASMOUSE (GDISP_FLG_DRIVER<<2)
+#if GDISP_HARDWARE_STREAM_WRITE || GDISP_HARDWARE_STREAM_READ
+ #define GDISP_FLG_WSTREAM (GDISP_FLG_DRIVER<<3)
+ #define GDISP_FLG_WRAPPED (GDISP_FLG_DRIVER<<4)
+#endif
+
+#if GINPUT_NEED_TOGGLE
+ /* Include toggle support code */
+ #include "ginput/lld/toggle.h"
+#endif
+
+#if GINPUT_NEED_MOUSE
+ /* Include mouse support code */
+ #include "ginput/lld/mouse.h"
+#endif
+
+static DWORD winThreadId;
+static ATOM winClass;
+static volatile bool_t QReady;
+static HANDLE drawMutex;
+#if GINPUT_NEED_MOUSE
+ static GDisplay * mouseDisplay;
+#endif
+
+/*===========================================================================*/
+/* Driver local routines . */
+/*===========================================================================*/
+
+#if GINPUT_NEED_TOGGLE
+ #define WIN32_BUTTON_AREA 16
+#else
+ #define WIN32_BUTTON_AREA 0
+#endif
+
+#define APP_NAME "uGFX"
+
+typedef struct winPriv {
+ HWND hwnd;
+ HDC dcBuffer;
+ HBITMAP dcBitmap;
+ HBITMAP dcOldBitmap;
+ #if GINPUT_NEED_MOUSE
+ coord_t mousex, mousey;
+ uint16_t mousebuttons;
+ #endif
+ #if GINPUT_NEED_TOGGLE
+ uint8_t toggles;
+ #endif
+ #if GDISP_HARDWARE_STREAM_WRITE || GDISP_HARDWARE_STREAM_READ
+ coord_t x0, y0, x1, y1;
+ coord_t x, y;
+ #endif
+} winPriv;
+
+
+static LRESULT myWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
+{
+ HDC dc;
+ PAINTSTRUCT ps;
+ GDisplay * g;
+ winPriv * priv;
+ #if GINPUT_NEED_TOGGLE
+ HBRUSH hbrOn, hbrOff;
+ HPEN pen;
+ RECT rect;
+ HGDIOBJ old;
+ POINT p;
+ coord_t pos;
+ uint8_t bit;
+ #endif
+
+ switch (Msg) {
+ case WM_CREATE:
+ // Get our GDisplay structure and attach it to the window
+ g = (GDisplay *)((LPCREATESTRUCT)lParam)->lpCreateParams;
+ priv = (winPriv *)g->priv;
+ SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)g);
+
+ // Fill in the private area
+ priv->hwnd = hWnd;
+ dc = GetDC(hWnd);
+ priv->dcBitmap = CreateCompatibleBitmap(dc, g->g.Width, g->g.Height);
+ priv->dcBuffer = CreateCompatibleDC(dc);
+ ReleaseDC(hWnd, dc);
+ priv->dcOldBitmap = SelectObject(priv->dcBuffer, priv->dcBitmap);
+
+ // Mark the window as ready to go
+ g->flags |= GDISP_FLG_READY;
+ break;
+
+ #if GINPUT_NEED_MOUSE || GINPUT_NEED_TOGGLE
+ case WM_LBUTTONDOWN:
+ // Get our GDisplay structure
+ g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
+ priv = (winPriv *)g->priv;
+
+ // Handle mouse down on the window
+ #if GINPUT_NEED_MOUSE
+ if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT && (g->flags & GDISP_FLG_HASMOUSE)) {
+ priv->mousebuttons |= GINPUT_MOUSE_BTN_LEFT;
+ goto mousemove;
+ }
+ #endif
+
+ // Handle mouse down on the toggle area
+ #if GINPUT_NEED_TOGGLE
+ if ((coord_t)HIWORD(lParam) >= GDISP_SCREEN_HEIGHT && (g->flags & GDISP_FLG_HASTOGGLE)) {
+ bit = 1 << ((coord_t)LOWORD(lParam)*8/g->g.Width);
+ priv->toggles ^= bit;
+ rect.left = 0;
+ rect.right = GDISP_SCREEN_WIDTH;
+ rect.top = GDISP_SCREEN_HEIGHT;
+ rect.bottom = GDISP_SCREEN_HEIGHT + WIN32_BUTTON_AREA;
+ InvalidateRect(hWnd, &rect, FALSE);
+ UpdateWindow(hWnd);
+ #if GINPUT_TOGGLE_POLL_PERIOD == TIME_INFINITE
+ ginputToggleWakeup();
+ #endif
+ }
+ #endif
+ break;
+
+ case WM_LBUTTONUP:
+ // Get our GDisplay structure
+ g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
+ priv = (winPriv *)g->priv;
+
+ // Handle mouse up on the toggle area
+ #if GINPUT_NEED_TOGGLE
+ if ((g->flags & GDISP_FLG_HASTOGGLE)) {
+ if ((priv->toggles & 0x0F)) {
+ priv->toggles &= ~0x0F;
+ rect.left = 0;
+ rect.right = GDISP_SCREEN_WIDTH;
+ rect.top = GDISP_SCREEN_HEIGHT;
+ rect.bottom = GDISP_SCREEN_HEIGHT + WIN32_BUTTON_AREA;
+ InvalidateRect(hWnd, &rect, FALSE);
+ UpdateWindow(hWnd);
+ #if GINPUT_TOGGLE_POLL_PERIOD == TIME_INFINITE
+ ginputToggleWakeup();
+ #endif
+ }
+ }
+ #endif
+
+ // Handle mouse up on the window
+ #if GINPUT_NEED_MOUSE
+ if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT && (g->flags & GDISP_FLG_HASMOUSE)) {
+ priv->mousebuttons &= ~GINPUT_MOUSE_BTN_LEFT;
+ goto mousemove;
+ }
+ #endif
+ break;
+ #endif
+
+ #if GINPUT_NEED_MOUSE
+ case WM_MBUTTONDOWN:
+ g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
+ priv = (winPriv *)g->priv;
+ if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT && (g->flags & GDISP_FLG_HASMOUSE)) {
+ priv->mousebuttons |= GINPUT_MOUSE_BTN_MIDDLE;
+ goto mousemove;
+ }
+ break;
+ case WM_MBUTTONUP:
+ g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
+ priv = (winPriv *)g->priv;
+ if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT && (g->flags & GDISP_FLG_HASMOUSE)) {
+ priv->mousebuttons &= ~GINPUT_MOUSE_BTN_MIDDLE;
+ goto mousemove;
+ }
+ break;
+ case WM_RBUTTONDOWN:
+ g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
+ priv = (winPriv *)g->priv;
+ if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT && (g->flags & GDISP_FLG_HASMOUSE)) {
+ priv->mousebuttons |= GINPUT_MOUSE_BTN_RIGHT;
+ goto mousemove;
+ }
+ break;
+ case WM_RBUTTONUP:
+ g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
+ priv = (winPriv *)g->priv;
+ if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT && (g->flags & GDISP_FLG_HASMOUSE)) {
+ priv->mousebuttons &= ~GINPUT_MOUSE_BTN_RIGHT;
+ goto mousemove;
+ }
+ break;
+ case WM_MOUSEMOVE:
+ g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
+ priv = (winPriv *)g->priv;
+ if ((coord_t)HIWORD(lParam) >= GDISP_SCREEN_HEIGHT || !(g->flags & GDISP_FLG_HASMOUSE))
+ break;
+ mousemove:
+ priv->mousex = (coord_t)LOWORD(lParam);
+ priv->mousey = (coord_t)HIWORD(lParam);
+ #if GINPUT_MOUSE_POLL_PERIOD == TIME_INFINITE
+ ginputMouseWakeup();
+ #endif
+ break;
+ #endif
+
+ case WM_SYSKEYDOWN:
+ case WM_KEYDOWN:
+ case WM_SYSKEYUP:
+ case WM_KEYUP:
+ break;
+ case WM_CHAR:
+ case WM_DEADCHAR:
+ case WM_SYSCHAR:
+ case WM_SYSDEADCHAR:
+ break;
+
+ case WM_ERASEBKGND:
+ // Pretend we have erased the background.
+ // We know we don't really need to do this as we
+ // redraw the entire surface in the WM_PAINT handler.
+ return TRUE;
+
+ case WM_PAINT:
+ // Get our GDisplay structure
+ g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
+ priv = (winPriv *)g->priv;
+
+ // Paint the main window area
+ WaitForSingleObject(drawMutex, INFINITE);
+ dc = BeginPaint(hWnd, &ps);
+ BitBlt(dc, ps.rcPaint.left, ps.rcPaint.top,
+ ps.rcPaint.right - ps.rcPaint.left,
+ (ps.rcPaint.bottom > GDISP_SCREEN_HEIGHT ? GDISP_SCREEN_HEIGHT : ps.rcPaint.bottom) - ps.rcPaint.top,
+ priv->dcBuffer, ps.rcPaint.left, ps.rcPaint.top, SRCCOPY);
+
+ // Paint the toggle area
+ #if GINPUT_NEED_TOGGLE
+ if (ps.rcPaint.bottom >= GDISP_SCREEN_HEIGHT && (g->flags & GDISP_FLG_HASTOGGLE)) {
+ pen = CreatePen(PS_SOLID, 1, COLOR2NATIVE(Black));
+ hbrOn = CreateSolidBrush(COLOR2NATIVE(Blue));
+ hbrOff = CreateSolidBrush(COLOR2NATIVE(Gray));
+ old = SelectObject(dc, pen);
+ MoveToEx(dc, 0, GDISP_SCREEN_HEIGHT, &p);
+ LineTo(dc, GDISP_SCREEN_WIDTH, GDISP_SCREEN_HEIGHT);
+ for(pos = 0, bit=1; pos < wWidth; pos=rect.right, bit <<= 1) {
+ rect.left = pos;
+ rect.right = pos + GDISP_SCREEN_WIDTH/8;
+ rect.top = GDISP_SCREEN_HEIGHT;
+ rect.bottom = GDISP_SCREEN_HEIGHT + WIN32_BUTTON_AREA;
+ FillRect(dc, &rect, (priv->toggles & bit) ? hbrOn : hbrOff);
+ if (pos > 0) {
+ MoveToEx(dc, rect.left, rect.top, &p);
+ LineTo(dc, rect.left, rect.bottom);
+ }
+ }
+ DeleteObject(hbrOn);
+ DeleteObject(hbrOff);
+ SelectObject(dc, old);
+ }
+ #endif
+ EndPaint(hWnd, &ps);
+ ReleaseMutex(drawMutex);
+ break;
+
+ case WM_DESTROY:
+ // Get our GDisplay structure
+ g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
+ priv = (winPriv *)g->priv;
+
+ // Restore the window and free our bitmaps
+ SelectObject(priv->dcBuffer, priv->dcOldBitmap);
+ DeleteDC(priv->dcBuffer);
+ DeleteObject(priv->dcBitmap);
+
+ // Cleanup the private area
+ gfxFree(priv);
+
+ // Quit the application
+ PostQuitMessage(0);
+
+ // Actually the above doesn't work (who knows why)
+ ExitProcess(0);
+ break;
+
+ default:
+ return DefWindowProc(hWnd, Msg, wParam, lParam);
+ }
+ return 0;
+}
+
+static DECLARE_THREAD_STACK(waWindowThread, 1024);
+static DECLARE_THREAD_FUNCTION(WindowThread, param) {
+ (void)param;
+ MSG msg;
+
+ // Establish this thread as a message queue thread
+ winThreadId = GetCurrentThreadId();
+ PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
+ QReady = TRUE;
+
+ do {
+ gfxSleepMilliseconds(1);
+ while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
+ // Is this our special thread message to create a new window?
+ if (!msg.hwnd && msg.message == WM_USER) {
+ RECT rect;
+ GDisplay *g;
+
+ g = (GDisplay *)msg.lParam;
+
+ // Set the window rectangle
+ rect.top = 0; rect.bottom = g->g.Height;
+ rect.left = 0; rect.right = g->g.Width;
+ #if GINPUT_NEED_TOGGLE
+ if ((g->flags & GDISP_FLG_HASTOGGLE))
+ rect.bottom += WIN32_BUTTON_AREA;
+ #endif
+ AdjustWindowRect(&rect, WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU, 0);
+
+ // Create the window
+ msg.hwnd = CreateWindow(APP_NAME, "", WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_BORDER, msg.wParam*DISPLAY_X_OFFSET, msg.wParam*DISPLAY_Y_OFFSET,
+ rect.right-rect.left, rect.bottom-rect.top, 0, 0,
+ GetModuleHandle(NULL), g);
+ assert(msg.hwnd != NULL);
+
+ // Or just a normal window message
+ } else {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ }
+ } while (msg.message != WM_QUIT);
+ ExitProcess(0);
+ return msg.wParam;
+}
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
+ winPriv * priv;
+ char buf[132];
+
+ // Initialise the window thread and the window class (if it hasn't been done already)
+ if (!QReady) {
+ gfxThreadHandle hth;
+ WNDCLASS wc;
+
+ // Create the draw mutex
+ drawMutex = CreateMutex(NULL, FALSE, NULL);
+
+ // Create the thread
+ hth = gfxThreadCreate(waWindowThread, sizeof(waWindowThread), HIGH_PRIORITY, WindowThread, 0);
+ assert(hth != NULL);
+ gfxThreadClose(hth);
+
+ wc.style = CS_HREDRAW | CS_VREDRAW; // | CS_OWNDC;
+ wc.lpfnWndProc = (WNDPROC)myWindowProc;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 0;
+ wc.hInstance = GetModuleHandle(NULL);
+ wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
+ wc.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wc.hbrBackground = GetStockObject(WHITE_BRUSH);
+ wc.lpszMenuName = NULL;
+ wc.lpszClassName = APP_NAME;
+ winClass = RegisterClass(&wc);
+ assert(winClass != 0);
+
+ // Wait for our thread to be ready
+ while (!QReady)
+ Sleep(1);
+ }
+
+ // Initialise the GDISP structure
+ g->g.Orientation = GDISP_ROTATE_0;
+ g->g.Powermode = powerOn;
+ g->g.Backlight = 100;
+ g->g.Contrast = 50;
+ g->g.Width = GDISP_SCREEN_WIDTH;
+ g->g.Height = GDISP_SCREEN_HEIGHT;
+
+ // Turn on toggles for the first GINPUT_TOGGLE_CONFIG_ENTRIES windows
+ #if GINPUT_NEED_TOGGLE
+ if (g->controllerdisplay < GINPUT_TOGGLE_CONFIG_ENTRIES)
+ g->flags |= GDISP_FLG_HASTOGGLE;
+ #endif
+
+ // Only turn on mouse on the first window for now
+ #if GINPUT_NEED_MOUSE
+ if (!g->controllerdisplay) {
+ mouseDisplay = g;
+ g->flags |= GDISP_FLG_HASMOUSE;
+ }
+ #endif
+
+ // Create a private area for this window
+ priv = (winPriv *)gfxAlloc(sizeof(winPriv));
+ assert(priv != NULL);
+ memset(priv, 0, sizeof(winPriv));
+ g->priv = priv;
+ #if GDISP_HARDWARE_STREAM_WRITE || GDISP_HARDWARE_STREAM_READ
+ // Initialise with an invalid window
+ g->flags &= ~GDISP_FLG_WSTREAM;
+ #endif
+ g->board = 0; // no board interface for this controller
+
+ // Create the window in the message thread
+ PostThreadMessage(winThreadId, WM_USER, (WPARAM)g->controllerdisplay, (LPARAM)g);
+
+ // Wait for the window creation to complete (for safety)
+ while(!(((volatile GDisplay *)g)->flags & GDISP_FLG_READY))
+ Sleep(1);
+
+ sprintf(buf, APP_NAME " - %u", g->systemdisplay+1);
+ SetWindowText(priv->hwnd, buf);
+ ShowWindow(priv->hwnd, SW_SHOW);
+ UpdateWindow(priv->hwnd);
+
+ return TRUE;
+}
+
+#if GDISP_HARDWARE_FLUSH
+ LLDSPEC void gdisp_lld_flush(GDisplay *g) {
+ winPriv * priv;
+
+ priv = g->priv;
+ UpdateWindow(priv->hwnd);
+ }
+#endif
+
+#if GDISP_HARDWARE_STREAM_WRITE || GDISP_HARDWARE_STREAM_READ
+ void BAD_PARAMETER(const char *msg) {
+ fprintf(stderr, "%s\n", msg);
+ }
+#endif
+
+#if GDISP_HARDWARE_STREAM_WRITE
+ LLDSPEC void gdisp_lld_write_start(GDisplay *g) {
+ winPriv * priv;
+
+ if (g->flags & GDISP_FLG_WSTREAM)
+ BAD_PARAMETER("write_start: already in streaming mode");
+ if (g->p.cx <= 0 || g->p.cy <= 0 || g->p.x < 0 || g->p.y < 0 || g->p.x+g->p.cx > g->g.Width || g->p.y+g->p.cy > g->g.Height)
+ BAD_PARAMETER("write_start: bad window parameter");
+
+ priv = g->priv;
+ priv->x0 = g->p.x; priv->x1 = g->p.x + g->p.cx - 1;
+ priv->y0 = g->p.y; priv->y1 = g->p.y + g->p.cy - 1;
+ #if GDISP_HARDWARE_STREAM_POS
+ priv->x = g->p.x-1; // Make sure these values are invalid (for testing)
+ priv->y = g->p.y-1;
+ #else
+ priv->x = g->p.x;
+ priv->y = g->p.y;
+ #endif
+ g->flags |= GDISP_FLG_WSTREAM;
+ g->flags &= ~GDISP_FLG_WRAPPED;
+ }
+ LLDSPEC void gdisp_lld_write_color(GDisplay *g) {
+ winPriv * priv;
+ int x, y;
+ COLORREF color;
+
+ priv = g->priv;
+ color = COLOR2NATIVE(g->p.color);
+
+ if (!(g->flags & GDISP_FLG_WSTREAM))
+ BAD_PARAMETER("write_color: not in streaming mode");
+ if (priv->x < priv->x0 || priv->x > priv->x1 || priv->y < priv->y0 || priv->y > priv->y1)
+ BAD_PARAMETER("write_color: cursor outside streaming area");
+ if (g->flags & GDISP_FLG_WRAPPED) {
+ BAD_PARAMETER("write_color: Warning - Area wrapped.");
+ g->flags &= ~GDISP_FLG_WRAPPED;
+ }
+
+ #if GDISP_NEED_CONTROL
+ switch(g->g.Orientation) {
+ case GDISP_ROTATE_0:
+ x = priv->x;
+ y = priv->y;
+ break;
+ case GDISP_ROTATE_90:
+ x = priv->y;
+ y = g->g.Width - 1 - priv->x;
+ break;
+ case GDISP_ROTATE_180:
+ x = g->g.Width - 1 - priv->x;
+ y = g->g.Height - 1 - priv->y;
+ break;
+ case GDISP_ROTATE_270:
+ x = g->g.Height - 1 - priv->y;
+ y = priv->x;
+ break;
+ }
+ #else
+ x = priv->x;
+ y = priv->y;
+ #endif
+
+ // Draw the pixel on the screen and in the buffer.
+ WaitForSingleObject(drawMutex, INFINITE);
+ SetPixel(priv->dcBuffer, x, y, color);
+ #if GDISP_WIN32_USE_INDIRECT_UPDATE
+ ReleaseMutex(drawMutex);
+ {
+ RECT r;
+ r.left = x; r.right = x+1;
+ r.top = y; r.bottom = y+1;
+ InvalidateRect(priv->hwnd, &r, FALSE);
+ }
+ #else
+ {
+ HDC dc;
+ dc = GetDC(priv->hwnd);
+ SetPixel(dc, x, y, color);
+ ReleaseDC(priv->hwnd, dc);
+ ReleaseMutex(drawMutex);
+ }
+ #endif
+
+ // Update the cursor
+ if (++priv->x > priv->x1) {
+ priv->x = priv->x0;
+ if (++priv->y > priv->y1) {
+ g->flags |= GDISP_FLG_WRAPPED;
+ priv->y = priv->y0;
+ }
+ }
+ }
+ LLDSPEC void gdisp_lld_write_stop(GDisplay *g) {
+ if (!(g->flags & GDISP_FLG_WSTREAM))
+ BAD_PARAMETER("write_stop: not in streaming mode");
+ g->flags &= ~GDISP_FLG_WSTREAM;
+ }
+ #if GDISP_HARDWARE_STREAM_POS
+ LLDSPEC void gdisp_lld_write_pos(GDisplay *g) {
+ winPriv * priv;
+
+ priv = g->priv;
+
+ if (!(g->flags & GDISP_FLG_WSTREAM))
+ BAD_PARAMETER("write_pos: not in streaming mode");
+ if (g->p.x < priv->x0 || g->p.x > priv->x1 || g->p.y < priv->y0 || g->p.y > priv->y1)
+ BAD_PARAMETER("write_color: new cursor outside streaming area");
+ priv->x = g->p.x;
+ priv->y = g->p.y;
+ }
+ #endif
+#endif
+
+#if GDISP_HARDWARE_STREAM_READ
+ LLDSPEC void gdisp_lld_read_start(GDisplay *g) {
+ winPriv * priv;
+
+ if (g->flags & GDISP_FLG_WSTREAM)
+ BAD_PARAMETER("read_start: already in streaming mode");
+ if (g->p.cx <= 0 || g->p.cy <= 0 || g->p.x < 0 || g->p.y < 0 || g->p.x+g->p.cx > g->g.Width || g->p.y+g->p.cy > g->g.Height)
+ BAD_PARAMETER("read_start: bad window parameter");
+
+ priv = g->priv;
+ priv->x0 = g->p.x; priv->x1 = g->p.x + g->p.cx - 1;
+ priv->y0 = g->p.y; priv->y1 = g->p.y + g->p.cy - 1;
+ priv->x = g->p.x;
+ priv->y = g->p.y;
+ g->flags |= GDISP_FLG_WSTREAM;
+ g->flags &= ~GDISP_FLG_WRAPPED;
+ }
+ LLDSPEC color_t gdisp_lld_read_color(GDisplay *g) {
+ winPriv * priv;
+ COLORREF color;
+
+ priv = g->priv;
+
+ if (!(g->flags & GDISP_FLG_WSTREAM))
+ BAD_PARAMETER("read_color: not in streaming mode");
+ if (priv->x < priv->x0 || priv->x > priv->x1 || priv->y < priv->y0 || priv->y > priv->y1)
+ BAD_PARAMETER("read_color: cursor outside streaming area");
+ if (g->flags & GDISP_FLG_WRAPPED) {
+ BAD_PARAMETER("read_color: Warning - Area wrapped.");
+ g->flags &= ~GDISP_FLG_WRAPPED;
+ }
+
+ WaitForSingleObject(drawMutex, INFINITE);
+ #if GDISP_NEED_CONTROL
+ switch(g->g.Orientation) {
+ case GDISP_ROTATE_0:
+ color = GetPixel(priv->dcBuffer, priv->x, priv->y);
+ break;
+ case GDISP_ROTATE_90:
+ color = GetPixel(priv->dcBuffer, priv->y, g->g.Width - 1 - priv->x);
+ break;
+ case GDISP_ROTATE_180:
+ color = GetPixel(priv->dcBuffer, g->g.Width - 1 - priv->x, g->g.Height - 1 - priv->y);
+ break;
+ case GDISP_ROTATE_270:
+ color = GetPixel(priv->dcBuffer, g->g.Height - 1 - priv->y, priv->x);
+ break;
+ }
+ #else
+ color = GetPixel(priv->dcBuffer, priv->x, priv->y);
+ #endif
+ ReleaseMutex(drawMutex);
+
+ // Update the cursor
+ if (++priv->x > priv->x1) {
+ priv->x = priv->x0;
+ if (++priv->y > priv->y1) {
+ g->flags |= GDISP_FLG_WRAPPED;
+ priv->y = priv->y0;
+ }
+ }
+
+ return NATIVE2COLOR(color);
+ }
+ LLDSPEC void gdisp_lld_read_stop(GDisplay *g) {
+ if (!(g->flags & GDISP_FLG_WSTREAM))
+ BAD_PARAMETER("write_stop: not in streaming mode");
+ g->flags &= ~GDISP_FLG_WSTREAM;
+ }
+#endif
+
+#if GDISP_HARDWARE_DRAWPIXEL
+ LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) {
+ winPriv * priv;
+ int x, y;
+ COLORREF color;
+
+ priv = g->priv;
+ color = COLOR2NATIVE(g->p.color);
+
+ #if GDISP_NEED_CONTROL
+ switch(g->g.Orientation) {
+ case GDISP_ROTATE_0:
+ x = g->p.x;
+ y = g->p.y;
+ break;
+ case GDISP_ROTATE_90:
+ x = g->p.y;
+ y = g->g.Width - 1 - g->p.x;
+ break;
+ case GDISP_ROTATE_180:
+ x = g->g.Width - 1 - g->p.x;
+ y = g->g.Height - 1 - g->p.y;
+ break;
+ case GDISP_ROTATE_270:
+ x = g->g.Height - 1 - g->p.y;
+ y = g->p.x;
+ break;
+ }
+ #else
+ x = g->p.x;
+ y = g->p.y;
+ #endif
+
+ // Draw the pixel on the screen and in the buffer.
+ WaitForSingleObject(drawMutex, INFINITE);
+ SetPixel(priv->dcBuffer, x, y, color);
+ #if GDISP_WIN32_USE_INDIRECT_UPDATE
+ ReleaseMutex(drawMutex);
+ {
+ RECT r;
+ r.left = x; r.right = x+1;
+ r.top = y; r.bottom = y+1;
+ InvalidateRect(priv->hwnd, &r, FALSE);
+ }
+ #else
+ {
+ HDC dc;
+ dc = GetDC(priv->hwnd);
+ SetPixel(dc, x, y, color);
+ ReleaseDC(priv->hwnd, dc);
+ ReleaseMutex(drawMutex);
+ }
+ #endif
+ }
+#endif
+
+/* ---- Optional Routines ---- */
+
+#if GDISP_HARDWARE_FILLS
+ LLDSPEC void gdisp_lld_fill_area(GDisplay *g) {
+ winPriv * priv;
+ RECT rect;
+ HBRUSH hbr;
+ COLORREF color;
+
+ priv = g->priv;
+ color = COLOR2NATIVE(g->p.color);
+ hbr = CreateSolidBrush(color);
+
+ #if GDISP_NEED_CONTROL
+ switch(g->g.Orientation) {
+ case GDISP_ROTATE_0:
+ rect.top = g->p.y;
+ rect.bottom = rect.top + g->p.cy;
+ rect.left = g->p.x;
+ rect.right = rect.left + g->p.cx;
+ break;
+ case GDISP_ROTATE_90:
+ rect.bottom = g->g.Width - g->p.x;
+ rect.top = rect.bottom - g->p.cx;
+ rect.left = g->p.y;
+ rect.right = rect.left + g->p.cy;
+ break;
+ case GDISP_ROTATE_180:
+ rect.bottom = g->g.Height - g->p.y;
+ rect.top = rect.bottom - g->p.cy;
+ rect.right = g->g.Width - g->p.x;
+ rect.left = rect.right - g->p.cx;
+ break;
+ case GDISP_ROTATE_270:
+ rect.top = g->p.x;
+ rect.bottom = rect.top + g->p.cx;
+ rect.right = g->g.Height - g->p.y;
+ rect.left = rect.right - g->p.cy;
+ break;
+ }
+ #else
+ rect.top = g->p.y;
+ rect.bottom = rect.top + g->p.cy;
+ rect.left = g->p.x;
+ rect.right = rect.left + g->p.cx;
+ #endif
+
+
+ WaitForSingleObject(drawMutex, INFINITE);
+ FillRect(priv->dcBuffer, &rect, hbr);
+ #if GDISP_WIN32_USE_INDIRECT_UPDATE
+ ReleaseMutex(drawMutex);
+ InvalidateRect(priv->hwnd, &rect, FALSE);
+ #else
+ {
+ HDC dc;
+ dc = GetDC(priv->hwnd);
+ FillRect(dc, &rect, hbr);
+ ReleaseDC(priv->hwnd, dc);
+ ReleaseMutex(drawMutex);
+ }
+ #endif
+
+ DeleteObject(hbr);
+ }
+#endif
+
+#if GDISP_HARDWARE_BITFILLS && GDISP_NEED_CONTROL
+ static pixel_t *rotateimg(GDisplay *g, const pixel_t *buffer) {
+ pixel_t *dstbuf;
+ pixel_t *dst;
+ const pixel_t *src;
+ size_t sz;
+ coord_t i, j;
+
+ // Allocate the destination buffer
+ sz = (size_t)g->p.cx * (size_t)g->p.cy;
+ if (!(dstbuf = (pixel_t *)malloc(sz * sizeof(pixel_t))))
+ return 0;
+
+ // Copy the bits we need
+ switch(g->g.Orientation) {
+ case GDISP_ROTATE_0:
+ return 0; // not handled as it doesn't need to be.
+ case GDISP_ROTATE_90:
+ for(src = buffer+g->p.x1, j = 0; j < g->p.cy; j++, src += g->p.x2 - g->p.cx) {
+ dst = dstbuf+sz-g->p.cy+j;
+ for(i = 0; i < g->p.cx; i++, dst -= g->p.cy)
+ *dst = *src++;
+ }
+ break;
+ case GDISP_ROTATE_180:
+ for(dst = dstbuf+sz, src = buffer+g->p.x1, j = 0; j < g->p.cy; j++, src += g->p.x2 - g->p.cx)
+ for(i = 0; i < g->p.cx; i++)
+ *--dst = *src++;
+ break;
+ case GDISP_ROTATE_270:
+ for(src = buffer+g->p.x1, j = 0; j < g->p.cy; j++, src += g->p.x2 - g->p.cx) {
+ dst = dstbuf+g->p.cy-j-1;
+ for(i = 0; i < g->p.cx; i++, dst += g->p.cy)
+ *dst = *src++;
+ }
+ break;
+ }
+ return dstbuf;
+ }
+#endif
+
+#if GDISP_HARDWARE_BITFILLS
+ #if COLOR_SYSTEM != GDISP_COLORSYSTEM_TRUECOLOR || COLOR_TYPE_BITS <= 8
+ #error "GDISP Win32: This driver's bitblit currently only supports true-color with bit depths > 8 bits."
+ #endif
+
+ LLDSPEC void gdisp_lld_blit_area(GDisplay *g) {
+ winPriv * priv;
+ pixel_t * buffer;
+ RECT rect;
+ BITMAPV4HEADER bmpInfo;
+
+ // Make everything relative to the start of the line
+ priv = g->priv;
+ buffer = g->p.ptr;
+ buffer += g->p.x2*g->p.y1;
+
+ memset(&bmpInfo, 0, sizeof(bmpInfo));
+ bmpInfo.bV4Size = sizeof(bmpInfo);
+ bmpInfo.bV4Planes = 1;
+ bmpInfo.bV4BitCount = COLOR_TYPE_BITS;
+ bmpInfo.bV4AlphaMask = 0;
+ bmpInfo.bV4RedMask = RGB2COLOR(255,0,0);
+ bmpInfo.bV4GreenMask = RGB2COLOR(0,255,0);
+ bmpInfo.bV4BlueMask = RGB2COLOR(0,0,255);
+ bmpInfo.bV4V4Compression = BI_BITFIELDS;
+ bmpInfo.bV4XPelsPerMeter = 3078;
+ bmpInfo.bV4YPelsPerMeter = 3078;
+ bmpInfo.bV4ClrUsed = 0;
+ bmpInfo.bV4ClrImportant = 0;
+ bmpInfo.bV4CSType = 0; //LCS_sRGB;
+
+ #if GDISP_NEED_CONTROL
+ switch(g->g.Orientation) {
+ case GDISP_ROTATE_0:
+ bmpInfo.bV4SizeImage = (g->p.cy*g->p.x2) * sizeof(pixel_t);
+ bmpInfo.bV4Width = g->p.x2;
+ bmpInfo.bV4Height = -g->p.cy; /* top-down image */
+ rect.top = g->p.y;
+ rect.bottom = rect.top+g->p.cy;
+ rect.left = g->p.x;
+ rect.right = rect.left+g->p.cx;
+ break;
+ case GDISP_ROTATE_90:
+ if (!(buffer = rotateimg(g, buffer))) return;
+ bmpInfo.bV4SizeImage = (g->p.cy*g->p.cx) * sizeof(pixel_t);
+ bmpInfo.bV4Width = g->p.cy;
+ bmpInfo.bV4Height = -g->p.cx; /* top-down image */
+ rect.bottom = g->g.Width - g->p.x;
+ rect.top = rect.bottom-g->p.cx;
+ rect.left = g->p.y;
+ rect.right = rect.left+g->p.cy;
+ break;
+ case GDISP_ROTATE_180:
+ if (!(buffer = rotateimg(g, buffer))) return;
+ bmpInfo.bV4SizeImage = (g->p.cy*g->p.cx) * sizeof(pixel_t);
+ bmpInfo.bV4Width = g->p.cx;
+ bmpInfo.bV4Height = -g->p.cy; /* top-down image */
+ rect.bottom = g->g.Height-1 - g->p.y;
+ rect.top = rect.bottom-g->p.cy;
+ rect.right = g->g.Width - g->p.x;
+ rect.left = rect.right-g->p.cx;
+ break;
+ case GDISP_ROTATE_270:
+ if (!(buffer = rotateimg(g, buffer))) return;
+ bmpInfo.bV4SizeImage = (g->p.cy*g->p.cx) * sizeof(pixel_t);
+ bmpInfo.bV4Width = g->p.cy;
+ bmpInfo.bV4Height = -g->p.cx; /* top-down image */
+ rect.top = g->p.x;
+ rect.bottom = rect.top+g->p.cx;
+ rect.right = g->g.Height - g->p.y;
+ rect.left = rect.right-g->p.cy;
+ break;
+ }
+ #else
+ bmpInfo.bV4SizeImage = (g->p.cy*g->p.x2) * sizeof(pixel_t);
+ bmpInfo.bV4Width = g->p.x2;
+ bmpInfo.bV4Height = -g->p.cy; /* top-down image */
+ rect.top = g->p.y;
+ rect.bottom = rect.top+g->p.cy;
+ rect.left = g->p.x;
+ rect.right = rect.left+g->p.cx;
+ #endif
+
+ WaitForSingleObject(drawMutex, INFINITE);
+ SetDIBitsToDevice(priv->dcBuffer, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, 0, 0, 0, rect.bottom-rect.top, buffer, (BITMAPINFO*)&bmpInfo, DIB_RGB_COLORS);
+ #if GDISP_WIN32_USE_INDIRECT_UPDATE
+ ReleaseMutex(drawMutex);
+ InvalidateRect(priv->hwnd, &rect, FALSE);
+ #else
+ {
+ HDC dc;
+ dc = GetDC(priv->hwnd);
+ SetDIBitsToDevice(dc, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, 0, 0, 0, rect.bottom-rect.top, buffer, (BITMAPINFO*)&bmpInfo, DIB_RGB_COLORS);
+ ReleaseDC(priv->hwnd, dc);
+ ReleaseMutex(drawMutex);
+ }
+ #endif
+
+ #if GDISP_NEED_CONTROL
+ if (buffer != (pixel_t *)g->p.ptr)
+ free(buffer);
+ #endif
+ }
+#endif
+
+#if GDISP_HARDWARE_PIXELREAD
+ LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g) {
+ winPriv * priv;
+ COLORREF color;
+
+ priv = g->priv;
+
+ WaitForSingleObject(drawMutex, INFINITE);
+ #if GDISP_NEED_CONTROL
+ switch(g->g.Orientation) {
+ case GDISP_ROTATE_0:
+ color = GetPixel(priv->dcBuffer, g->p.x, g->p.y);
+ break;
+ case GDISP_ROTATE_90:
+ color = GetPixel(priv->dcBuffer, g->p.y, g->g.Width - 1 - g->p.x);
+ break;
+ case GDISP_ROTATE_180:
+ color = GetPixel(priv->dcBuffer, g->g.Width - 1 - g->p.x, g->g.Height - 1 - g->p.y);
+ break;
+ case GDISP_ROTATE_270:
+ color = GetPixel(priv->dcBuffer, g->g.Height - 1 - g->p.y, g->p.x);
+ break;
+ }
+ #else
+ color = GetPixel(priv->dcBuffer, g->p.x, g->p.y);
+ #endif
+ ReleaseMutex(drawMutex);
+
+ return NATIVE2COLOR(color);
+ }
+#endif
+
+#if GDISP_NEED_SCROLL && GDISP_HARDWARE_SCROLL
+ LLDSPEC void gdisp_lld_vertical_scroll(GDisplay *g) {
+ winPriv * priv;
+ RECT rect;
+ coord_t lines;
+
+ priv = g->priv;
+
+ #if GDISP_NEED_CONTROL
+ switch(g->g.Orientation) {
+ case GDISP_ROTATE_0:
+ rect.top = g->p.y;
+ rect.bottom = rect.top+g->p.cy;
+ rect.left = g->p.x;
+ rect.right = rect.left+g->p.cx;
+ lines = -g->p.y1;
+ goto vertical_scroll;
+ case GDISP_ROTATE_90:
+ rect.bottom = g->g.Width - g->p.x;
+ rect.top = rect.bottom-g->p.cx;
+ rect.left = g->p.y;
+ rect.right = rect.left+g->p.cy;
+ lines = -g->p.y1;
+ goto horizontal_scroll;
+ case GDISP_ROTATE_180:
+ rect.bottom = g->g.Height - g->p.y;
+ rect.top = rect.bottom-g->p.cy;
+ rect.right = g->g.Width - g->p.x;
+ rect.left = rect.right-g->p.cx;
+ lines = g->p.y1;
+ vertical_scroll:
+ if (lines > 0) {
+ rect.bottom -= lines;
+ } else {
+ rect.top -= lines;
+ }
+ if (g->p.cy >= lines && g->p.cy >= -lines) {
+ WaitForSingleObject(drawMutex, INFINITE);
+ ScrollDC(priv->dcBuffer, 0, lines, &rect, 0, 0, 0);
+ #if GDISP_WIN32_USE_INDIRECT_UPDATE
+ ReleaseMutex(drawMutex);
+ InvalidateRect(priv->hwnd, &rect, FALSE);
+ #else
+ {
+ HDC dc;
+ dc = GetDC(priv->hwnd);
+ ScrollDC(dc, 0, lines, &rect, 0, 0, 0);
+ ReleaseDC(priv->hwnd, dc);
+ ReleaseMutex(drawMutex);
+ }
+ #endif
+ }
+ break;
+ case GDISP_ROTATE_270:
+ rect.top = g->p.x;
+ rect.bottom = rect.top+g->p.cx;
+ rect.right = g->g.Height - g->p.y;
+ rect.left = rect.right-g->p.cy;
+ lines = g->p.y1;
+ horizontal_scroll:
+ if (lines > 0) {
+ rect.right -= lines;
+ } else {
+ rect.left -= lines;
+ }
+ if (g->p.cy >= lines && g->p.cy >= -lines) {
+ WaitForSingleObject(drawMutex, INFINITE);
+ ScrollDC(priv->dcBuffer, lines, 0, &rect, 0, 0, 0);
+ #if GDISP_WIN32_USE_INDIRECT_UPDATE
+ ReleaseMutex(drawMutex);
+ InvalidateRect(priv->hwnd, &rect, FALSE);
+ #else
+ {
+ HDC dc;
+ dc = GetDC(priv->hwnd);
+ ScrollDC(dc, lines, 0, &rect, 0, 0, 0);
+ ReleaseDC(priv->hwnd, dc);
+ ReleaseMutex(drawMutex);
+ }
+ #endif
+ }
+ break;
+ }
+ #else
+ rect.top = g->p.y;
+ rect.bottom = rect.top+g->p.cy;
+ rect.left = g->p.x;
+ rect.right = rect.left+g->p.cx;
+ lines = -g->p.y1;
+ if (lines > 0) {
+ rect.bottom -= lines;
+ } else {
+ rect.top -= lines;
+ }
+ if (g->p.cy >= lines && g->p.cy >= -lines) {
+ WaitForSingleObject(drawMutex, INFINITE);
+ ScrollDC(priv->dcBuffer, 0, lines, &rect, 0, 0, 0);
+ #if GDISP_WIN32_USE_INDIRECT_UPDATE
+ ReleaseMutex(drawMutex);
+ InvalidateRect(priv->hwnd, &rect, FALSE);
+ #else
+ {
+ HDC dc;
+ dc = GetDC(priv->hwnd);
+ ScrollDC(dc, 0, lines, &rect, 0, 0, 0);
+ ReleaseDC(priv->hwnd, dc);
+ ReleaseMutex(drawMutex);
+ }
+ #endif
+ }
+ #endif
+ }
+#endif
+
+#if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL
+ LLDSPEC void gdisp_lld_control(GDisplay *g) {
+ switch(g->p.x) {
+ case GDISP_CONTROL_ORIENTATION:
+ if (g->g.Orientation == (orientation_t)g->p.ptr)
+ return;
+ switch((orientation_t)g->p.ptr) {
+ case GDISP_ROTATE_0:
+ case GDISP_ROTATE_180:
+ g->g.Width = GDISP_SCREEN_WIDTH;
+ g->g.Height = GDISP_SCREEN_HEIGHT;
+ break;
+ case GDISP_ROTATE_90:
+ case GDISP_ROTATE_270:
+ g->g.Height = GDISP_SCREEN_WIDTH;
+ g->g.Width = GDISP_SCREEN_HEIGHT;
+ break;
+ default:
+ return;
+ }
+ g->g.Orientation = (orientation_t)g->p.ptr;
+ return;
+/*
+ case GDISP_CONTROL_POWER:
+ case GDISP_CONTROL_BACKLIGHT:
+ case GDISP_CONTROL_CONTRAST:
+*/
+ }
+ }
+#endif
+
+#if GINPUT_NEED_MOUSE
+ void ginput_lld_mouse_init(void) {}
+ void ginput_lld_mouse_get_reading(MouseReading *pt) {
+ GDisplay * g;
+ winPriv * priv;
+
+ g = mouseDisplay;
+ priv = g->priv;
+
+ pt->x = priv->mousex;
+ pt->y = priv->mousey > g->g.Height ? g->g.Height : priv->mousey;
+ pt->z = (priv->mousebuttons & GINPUT_MOUSE_BTN_LEFT) ? 100 : 0;
+ pt->buttons = priv->mousebuttons;
+ }
+#endif /* GINPUT_NEED_MOUSE */
+
+#if GINPUT_NEED_TOGGLE
+ #if GINPUT_TOGGLE_CONFIG_ENTRIES > GDISP_DRIVER_COUNT_WIN32
+ #error "GDISP Win32: GINPUT_TOGGLE_CONFIG_ENTRIES must not be greater than GDISP_DRIVER_COUNT_WIN32"
+ #endif
+
+ GToggleConfig GInputToggleConfigTable[GINPUT_TOGGLE_CONFIG_ENTRIES];
+
+ void ginput_lld_toggle_init(const GToggleConfig *ptc) {
+ // Save the associated window struct
+ ptc->id = &GDISP_WIN32[ptc - GInputToggleConfigTable];
+
+ // We have 8 buttons per window.
+ ptc->mask = 0xFF;
+
+ // No inverse or special mode
+ ptc->invert = 0x00;
+ ptc->mode = 0;
+ }
+ unsigned ginput_lld_toggle_getbits(const GToggleConfig *ptc) {
+ return ((GDisplay *)(ptc->id))->priv->toggles;
+ }
+#endif /* GINPUT_NEED_TOGGLE */
+
+#endif /* GFX_USE_GDISP */
+
diff --git a/drivers/multiple/Win32/gdisp_lld_config.h b/drivers/multiple/Win32/gdisp_lld_config.h
index b6fa874a..1554161b 100644
--- a/drivers/multiple/Win32/gdisp_lld_config.h
+++ b/drivers/multiple/Win32/gdisp_lld_config.h
@@ -16,22 +16,44 @@
#ifndef _GDISP_LLD_CONFIG_H
#define _GDISP_LLD_CONFIG_H
-#if GFX_USE_GDISP /*|| defined(__DOXYGEN__)*/
+#if GFX_USE_GDISP
/*===========================================================================*/
/* Driver hardware support. */
/*===========================================================================*/
-
-#define GDISP_DRIVER_NAME "Win32"
-
-#define GDISP_HARDWARE_LINES TRUE
-#define GDISP_HARDWARE_FILLS TRUE
-#define GDISP_HARDWARE_BITFILLS TRUE
-#define GDISP_HARDWARE_SCROLL TRUE
-#define GDISP_HARDWARE_PIXELREAD TRUE
-#define GDISP_HARDWARE_CONTROL TRUE
-
-#define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_RGB888
+
+// Calling gdispGFlush() is optional for this driver but can be used by the
+// application to force a display update. eg after streaming.
+
+#define GDISP_HARDWARE_FLUSH TRUE
+#define GDISP_HARDWARE_CONTROL TRUE
+
+//#define GDISP_WIN32_STREAMING_TEST
+#ifdef GDISP_WIN32_STREAMING_TEST
+ // These streaming routines are here only to debug the high level gdisp
+ // code for streaming controllers. They are slow, inefficient and have
+ // lots of debugging turned on.
+ #define GDISP_HARDWARE_STREAM_WRITE TRUE
+ #define GDISP_HARDWARE_STREAM_READ TRUE
+ #define GDISP_HARDWARE_STREAM_POS TRUE
+#else
+ // The proper way on the Win32. These routines are nice and fast.
+ #define GDISP_HARDWARE_DRAWPIXEL TRUE
+ #define GDISP_HARDWARE_FILLS TRUE
+ #define GDISP_HARDWARE_PIXELREAD TRUE
+ #define GDISP_HARDWARE_SCROLL TRUE
+
+ // Bit-blits on Win32 are currently only supported for True-Color bit-depths greater than 8 bits
+ // Note: At the time this file is included we have not calculated all our color
+ // definitions so we need to do this by hand.
+ #if !defined(GDISP_PIXELFORMAT)
+ #define GDISP_HARDWARE_BITFILLS TRUE
+ #elif (GDISP_PIXELFORMAT & 0x2000) && (((GDISP_PIXELFORMAT & 0x0F00)>>8)+((GDISP_PIXELFORMAT & 0x00F0)>>4)+((GDISP_PIXELFORMAT & 0x000F))) > 8
+ #define GDISP_HARDWARE_BITFILLS TRUE
+ #endif
+#endif
+
+#define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_BGR888
#endif /* GFX_USE_GDISP */
diff --git a/drivers/multiple/Win32/ginput_lld_toggle_config.h b/drivers/multiple/Win32/ginput_lld_toggle_config.h
index 2e61d073..dd0c9b5c 100644
--- a/drivers/multiple/Win32/ginput_lld_toggle_config.h
+++ b/drivers/multiple/Win32/ginput_lld_toggle_config.h
@@ -20,9 +20,16 @@
#if GFX_USE_GINPUT && GINPUT_NEED_TOGGLE
-#define GINPUT_TOGGLE_POLL_PERIOD TIME_INFINITE // We are interrupt driven (or polled - ether works here)
-#define GINPUT_TOGGLE_NUM_PORTS 8 // The total number of toggle inputs
-#define GINPUT_TOGGLE_CONFIG_ENTRIES 1 // The total number of GToggleConfig entries
+#define GINPUT_TOGGLE_POLL_PERIOD TIME_INFINITE // We are interrupt driven (or polled - either works here)
+
+// This driver is unique in that it can support 8 buttons per window across multiple windows.
+// GINPUT_TOGGLE_CONFIG_ENTRIES just must be less than the number of GDISP windows (GDISP_DRIVER_COUNT_WIN32).
+#ifndef GINPUT_TOGGLE_CONFIG_ENTRIES
+ #define GINPUT_TOGGLE_CONFIG_ENTRIES 1 // The total number of GToggleConfig entries
+#endif
+
+// The total number of toggle inputs
+#define GINPUT_TOGGLE_NUM_PORTS (8 * GINPUT_TOGGLE_CONFIG_ENTRIES)
#define GINPUT_TOGGLE_SW1 0 // Switch 1 - Toggle
#define GINPUT_TOGGLE_SW2 1 // Switch 2 - Toggle
@@ -33,6 +40,8 @@
#define GINPUT_TOGGLE_MOMENTARY2 5 // Switch 6 - Momentary
#define GINPUT_TOGGLE_MOMENTARY3 6 // Switch 7 - Momentary
#define GINPUT_TOGGLE_MOMENTARY4 7 // Switch 8 - Momentary
+
+// This pattern of switch and momentary action is repeated across all windows.
#endif /* GFX_USE_GDISP && GINPUT_NEED_TOGGLE */
diff --git a/drivers/multiple/Win32/readme.txt b/drivers/multiple/Win32/readme.txt
index 7ff8546c..353f5a5b 100644
--- a/drivers/multiple/Win32/readme.txt
+++ b/drivers/multiple/Win32/readme.txt
@@ -1,14 +1,15 @@
To use this driver:
-This driver is special in that it implements both the gdisp low level driver
-and a touchscreen driver.
+This driver is special in that it implements both the gdisp low level driver,
+optionally a touchscreen driver, and optionally a toggle driver.
1. Add in your gfxconf.h:
a) #define GFX_USE_GDISP TRUE
- b) #define GFX_USE_GINPUT TRUE
- #define GINPUT_USE_MOUSE TRUE
+ b) Optionally #define GFX_USE_GINPUT TRUE
+ #define GINPUT_USE_MOUSE TRUE
+ #define GINPUT_USE_TOGGLE TRUE
c) Any optional high level driver defines (see gdisp.h) eg: GDISP_NEED_MULTITHREAD
- d) All of the following (with appropriate values):
+ d) Optionally the following (with appropriate values):
#define GDISP_SCREEN_WIDTH 640
#define GDISP_SCREEN_HEIGHT 480
@@ -17,5 +18,5 @@ and a touchscreen driver.
include $(GFXLIB)/gfx.mk
include $(GFXLIB)/drivers/multiple/Win32/gdisp_lld.mk
-3. Modify your makefile to add -lgdi32 to the DLIBS line. i.e.
+3. Modify your makefile to add -lws2_32 and -lgdi32 to the DLIBS line. i.e.
DLIBS = -lws2_32 -lgdi32
diff --git a/drivers/multiple/X/gdisp_lld.c b/drivers/multiple/X/gdisp_lld.c
deleted file mode 100644
index 13368bc1..00000000
--- a/drivers/multiple/X/gdisp_lld.c
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * This file is subject to the terms of the GFX License. If a copy of
- * the license was not distributed with this file, you can obtain one at:
- *
- * http://ugfx.org/license.html
- */
-
-/**
- * @file drivers/multiple/X/gdisp_lld.c
- * @brief GDISP Graphics Driver subsystem low level driver source for X.
- */
-
-#include "gfx.h"
-
-#if GFX_USE_GDISP
-
-/**
- * Our color model - Default or 24 bit only.
- *
- * At present we don't define this as we don't need to.
- * It may however be useful later if we implement bitblits.
- * As this may be dead code we don't include it in gdisp/options.h
- */
-#ifndef GDISP_FORCE_24BIT
- #define GDISP_FORCE_24BIT FALSE
-#endif
-
-#if GINPUT_NEED_MOUSE
- /* Include mouse support code */
- #include "ginput/lld/mouse.h"
-#endif
-
-/* Include the emulation code for things we don't support */
-#include "gdisp/lld/emulation.c"
-
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#ifndef GDISP_SCREEN_HEIGHT
- #define GDISP_SCREEN_HEIGHT 480
-#endif
-#ifndef GDISP_SCREEN_WIDTH
- #define GDISP_SCREEN_WIDTH 640
-#endif
-
-Display *dis;
-int scr;
-Window win;
-Pixmap pix;
-XEvent evt;
-GC gc;
-Colormap cmap;
-XVisualInfo vis;
-int depth;
-#if GINPUT_NEED_MOUSE
- coord_t mousex, mousey;
- uint16_t mousebuttons;
-#endif
-
-static void ProcessEvent(void) {
- XColor col;
-
- switch(evt.type) {
- case Expose:
- XCopyArea(dis, pix, win, gc,
- evt.xexpose.x, evt.xexpose.y,
- evt.xexpose.width, evt.xexpose.height,
- evt.xexpose.x, evt.xexpose.y);
- break;
-#if GINPUT_NEED_MOUSE
- case ButtonPress:
- mousex = evt.xbutton.x;
- mousey = evt.xbutton.y;
- switch(evt.xbutton.button){
- case 1: mousebuttons |= GINPUT_MOUSE_BTN_LEFT; break;
- case 2: mousebuttons |= GINPUT_MOUSE_BTN_MIDDLE; break;
- case 3: mousebuttons |= GINPUT_MOUSE_BTN_RIGHT; break;
- case 4: mousebuttons |= GINPUT_MOUSE_BTN_4; break;
- }
- #if GINPUT_MOUSE_POLL_PERIOD == TIME_INFINITE
- ginputMouseWakeup();
- #endif
- break;
- case ButtonRelease:
- mousex = evt.xbutton.x;
- mousey = evt.xbutton.y;
- switch(evt.xbutton.button){
- case 1: mousebuttons &= ~GINPUT_MOUSE_BTN_LEFT; break;
- case 2: mousebuttons &= ~GINPUT_MOUSE_BTN_MIDDLE; break;
- case 3: mousebuttons &= ~GINPUT_MOUSE_BTN_RIGHT; break;
- case 4: mousebuttons &= ~GINPUT_MOUSE_BTN_4; break;
- }
- #if GINPUT_MOUSE_POLL_PERIOD == TIME_INFINITE
- ginputMouseWakeup();
- #endif
- break;
- case MotionNotify:
- mousex = evt.xmotion.x;
- mousey = evt.xmotion.y;
- #if GINPUT_MOUSE_POLL_PERIOD == TIME_INFINITE
- ginputMouseWakeup();
- #endif
- break;
-#endif
- }
-}
-
-/* this is the X11 thread which keeps track of all events */
-static DECLARE_THREAD_STACK(waXThread, 1024);
-static DECLARE_THREAD_FUNCTION(ThreadX, arg) {
- (void)arg;
-
- while(1) {
- gfxSleepMilliseconds(100);
- while(XPending(dis)) {
- XNextEvent(dis, &evt);
- ProcessEvent();
- }
- }
- return 0;
-}
-
-static int FatalXIOError(Display *d) {
- (void) d;
-
- /* The window has closed */
- fprintf(stderr, "GFX Window closed!\n");
- exit(0);
-}
-
-bool_t gdisp_lld_init(void)
-{
- XSizeHints *pSH;
- XSetWindowAttributes xa;
- XTextProperty WindowTitle;
- char * WindowTitleText;
- gfxThreadHandle hth;
-
- #if GFX_USE_OS_LINUX || GFX_USE_OS_OSX
- XInitThreads();
- #endif
-
- dis = XOpenDisplay(NULL);
- scr = DefaultScreen(dis);
-
- #if GDISP_FORCE_24BIT
- if (!XMatchVisualInfo(dis, scr, 24, TrueColor, &vis)) {
- fprintf(stderr, "Your display has no TrueColor mode\n");
- XCloseDisplay(dis);
- return FALSE;
- }
- cmap = XCreateColormap(dis, RootWindow(dis, scr),
- vis.visual, AllocNone);
- #else
- vis.visual = CopyFromParent;
- vis.depth = DefaultDepth(dis, scr);
- cmap = DefaultColormap(dis, scr);
- #endif
- fprintf(stderr, "Running GFX Window in %d bit color\n", vis.depth);
-
- xa.colormap = cmap;
- xa.border_pixel = 0xFFFFFF;
- xa.background_pixel = 0x000000;
-
- win = XCreateWindow(dis, RootWindow(dis, scr), 16, 16,
- GDISP_SCREEN_WIDTH, GDISP_SCREEN_HEIGHT,
- 0, vis.depth, InputOutput, vis.visual,
- CWBackPixel|CWColormap|CWBorderPixel, &xa);
- XSync(dis, TRUE);
-
- WindowTitleText = "GFX";
- XStringListToTextProperty(&WindowTitleText, 1, &WindowTitle);
- XSetWMName(dis, win, &WindowTitle);
- XSetWMIconName(dis, win, &WindowTitle);
- XSync(dis, TRUE);
-
- pSH = XAllocSizeHints();
- pSH->flags = PSize | PMinSize | PMaxSize;
- pSH->min_width = pSH->max_width = pSH->base_width = GDISP_SCREEN_WIDTH;
- pSH->min_height = pSH->max_height = pSH->base_height = GDISP_SCREEN_HEIGHT;
- XSetWMNormalHints(dis, win, pSH);
- XFree(pSH);
- XSync(dis, TRUE);
-
- pix = XCreatePixmap(dis, win,
- GDISP_SCREEN_WIDTH, GDISP_SCREEN_HEIGHT, vis.depth);
- XSync(dis, TRUE);
-
- gc = XCreateGC(dis, win, 0, 0);
- XSetBackground(dis, gc, BlackPixel(dis, scr));
- XSync(dis, TRUE);
-
- XSelectInput(dis, win, StructureNotifyMask);
- XMapWindow(dis, win);
- do { XNextEvent(dis, &evt); } while (evt.type != MapNotify);
-
- /* start the X11 thread */
- XSetIOErrorHandler(FatalXIOError);
- XSelectInput(dis, win,
- ExposureMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask);
-
- if (!(hth = gfxThreadCreate(waXThread, sizeof(waXThread), HIGH_PRIORITY, ThreadX, 0))) {
- fprintf(stderr, "Cannot start X Thread\n");
- XCloseDisplay(dis);
- exit(0);
- }
- #if GFX_USE_OS_LINUX || GFX_USE_OS_OSX
- pthread_detach(hth);
- #endif
- gfxThreadClose(hth);
-
- /* Initialise the GDISP structure to match */
- GDISP.Orientation = GDISP_ROTATE_0;
- GDISP.Powermode = powerOn;
- GDISP.Backlight = 100;
- GDISP.Contrast = 50;
- GDISP.Width = GDISP_SCREEN_WIDTH;
- GDISP.Height = GDISP_SCREEN_HEIGHT;
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- GDISP.clipx0 = 0;
- GDISP.clipy0 = 0;
- GDISP.clipx1 = GDISP.Width;
- GDISP.clipy1 = GDISP.Height;
- #endif
- return TRUE;
-}
-
-void gdisp_lld_draw_pixel(coord_t x, coord_t y, color_t color)
-{
- XColor col;
-
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- // Clip pre orientation change
- if (x < GDISP.clipx0 || y < GDISP.clipy0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
- #endif
-
- col.red = RED_OF(color) << 8;
- col.green = GREEN_OF(color) << 8;
- col.blue = BLUE_OF(color) << 8;
- XAllocColor(dis, cmap, &col);
- XSetForeground(dis, gc, col.pixel);
- XDrawPoint(dis, pix, gc, (int)x, (int)y );
- XDrawPoint(dis, win, gc, (int)x, (int)y );
- XFlush(dis);
-}
-
-void gdisp_lld_fill_area(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
- XColor col;
-
- #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
- // Clip pre orientation change
- if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; }
- if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; }
- if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
- if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
- if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
- #endif
-
- col.red = RED_OF(color) << 8;
- col.green = GREEN_OF(color) << 8;
- col.blue = BLUE_OF(color) << 8;
- XAllocColor(dis, cmap, &col);
- XSetForeground(dis, gc, col.pixel);
- XFillRectangle(dis, pix, gc, x, y, cx, cy);
- XFillRectangle(dis, win, gc, x, y, cx, cy);
- XFlush(dis);
-}
-
-// Start of Bitblit code
-//XImage bitmap;
-//pixel_t *bits;
-// bits = malloc(vis.depth * GDISP_SCREEN_WIDTH * GDISP_SCREEN_HEIGHT);
-// bitmap = XCreateImage(dis, vis, vis.depth, ZPixmap,
-// 0, bits, GDISP_SCREEN_WIDTH, GDISP_SCREEN_HEIGHT,
-// 0, 0);
-
-#if GINPUT_NEED_MOUSE
-
- void ginput_lld_mouse_init(void) {}
-
- void ginput_lld_mouse_get_reading(MouseReading *pt) {
- pt->x = mousex;
- pt->y = mousey;
- pt->z = (mousebuttons & GINPUT_MOUSE_BTN_LEFT) ? 100 : 0;
- pt->buttons = mousebuttons;
- }
-
-#endif /* GINPUT_NEED_MOUSE */
-
-#endif /* GFX_USE_GDISP */
-/** @} */
-
diff --git a/drivers/multiple/X/gdisp_lld.mk b/drivers/multiple/X/gdisp_lld.mk
index 1a4fc4d7..572a5b7d 100644
--- a/drivers/multiple/X/gdisp_lld.mk
+++ b/drivers/multiple/X/gdisp_lld.mk
@@ -1,5 +1,2 @@
-# List the required driver.
-GFXSRC += $(GFXLIB)/drivers/multiple/X/gdisp_lld.c
-
-# Required include directories
GFXINC += $(GFXLIB)/drivers/multiple/X
+GFXSRC += $(GFXLIB)/drivers/multiple/X/gdisp_lld_X.c
diff --git a/drivers/multiple/X/gdisp_lld_X.c b/drivers/multiple/X/gdisp_lld_X.c
new file mode 100644
index 00000000..c9beb821
--- /dev/null
+++ b/drivers/multiple/X/gdisp_lld_X.c
@@ -0,0 +1,340 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file drivers/multiple/X/gdisp_lld.c
+ * @brief GDISP Graphics Driver subsystem low level driver source for X.
+ */
+
+#include "gfx.h"
+
+#if GFX_USE_GDISP
+
+#define GDISP_DRIVER_VMT GDISPVMT_X11
+#include "../drivers/multiple/X/gdisp_lld_config.h"
+#include "gdisp/lld/gdisp_lld.h"
+
+/**
+ * Our color model - Default or 24 bit only.
+ *
+ * At present we don't define this as we don't need to.
+ * It may however be useful later if we implement bitblits.
+ * As this may be dead code we don't include it in gdisp/options.h
+ */
+#ifndef GDISP_FORCE_24BIT
+ #define GDISP_FORCE_24BIT FALSE
+#endif
+
+#ifndef GDISP_SCREEN_HEIGHT
+ #define GDISP_SCREEN_HEIGHT 480
+#endif
+#ifndef GDISP_SCREEN_WIDTH
+ #define GDISP_SCREEN_WIDTH 640
+#endif
+
+#define GDISP_FLG_READY (GDISP_FLG_DRIVER<<0)
+
+#if GINPUT_NEED_MOUSE
+ /* Include mouse support code */
+ #include "ginput/lld/mouse.h"
+#endif
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+static bool_t initdone;
+static Display *dis;
+static int scr;
+static XEvent evt;
+static Colormap cmap;
+static XVisualInfo vis;
+static XContext cxt;
+#if GINPUT_NEED_MOUSE
+ coord_t mousex, mousey;
+ uint16_t mousebuttons;
+#endif
+
+typedef struct xPriv {
+ Pixmap pix;
+ GC gc;
+ Window win;
+} xPriv;
+
+static void ProcessEvent(GDisplay *g, xPriv *priv) {
+ switch(evt.type) {
+ case MapNotify:
+ XSelectInput(dis, evt.xmap.window, StructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask);
+ g->flags |= GDISP_FLG_READY;
+ break;
+ case UnmapNotify:
+ XCloseDisplay(dis);
+ exit(0);
+ break;
+ case Expose:
+ XCopyArea(dis, priv->pix, evt.xexpose.window, priv->gc,
+ evt.xexpose.x, evt.xexpose.y,
+ evt.xexpose.width, evt.xexpose.height,
+ evt.xexpose.x, evt.xexpose.y);
+ break;
+#if GINPUT_NEED_MOUSE
+ case ButtonPress:
+ mousex = evt.xbutton.x;
+ mousey = evt.xbutton.y;
+ switch(evt.xbutton.button){
+ case 1: mousebuttons |= GINPUT_MOUSE_BTN_LEFT; break;
+ case 2: mousebuttons |= GINPUT_MOUSE_BTN_MIDDLE; break;
+ case 3: mousebuttons |= GINPUT_MOUSE_BTN_RIGHT; break;
+ case 4: mousebuttons |= GINPUT_MOUSE_BTN_4; break;
+ }
+ #if GINPUT_MOUSE_POLL_PERIOD == TIME_INFINITE
+ ginputMouseWakeup();
+ #endif
+ break;
+ case ButtonRelease:
+ mousex = evt.xbutton.x;
+ mousey = evt.xbutton.y;
+ switch(evt.xbutton.button){
+ case 1: mousebuttons &= ~GINPUT_MOUSE_BTN_LEFT; break;
+ case 2: mousebuttons &= ~GINPUT_MOUSE_BTN_MIDDLE; break;
+ case 3: mousebuttons &= ~GINPUT_MOUSE_BTN_RIGHT; break;
+ case 4: mousebuttons &= ~GINPUT_MOUSE_BTN_4; break;
+ }
+ #if GINPUT_MOUSE_POLL_PERIOD == TIME_INFINITE
+ ginputMouseWakeup();
+ #endif
+ break;
+ case MotionNotify:
+ mousex = evt.xmotion.x;
+ mousey = evt.xmotion.y;
+ #if GINPUT_MOUSE_POLL_PERIOD == TIME_INFINITE
+ ginputMouseWakeup();
+ #endif
+ break;
+#endif
+ }
+}
+
+/* this is the X11 thread which keeps track of all events */
+static DECLARE_THREAD_STACK(waXThread, 1024);
+static DECLARE_THREAD_FUNCTION(ThreadX, arg) {
+ GDisplay *g;
+ (void)arg;
+
+ while(1) {
+ gfxSleepMilliseconds(100);
+ while(XPending(dis)) {
+ XNextEvent(dis, &evt);
+ XFindContext(evt.xany.display, evt.xany.window, cxt, (XPointer*)&g);
+ ProcessEvent(g, (xPriv *)g->priv);
+ }
+ }
+ return 0;
+}
+
+static int FatalXIOError(Display *d) {
+ (void) d;
+
+ /* The window has closed */
+ fprintf(stderr, "GFX Window closed!\n");
+ exit(0);
+}
+
+LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
+ XSizeHints *pSH;
+ XSetWindowAttributes xa;
+ XTextProperty WindowTitle;
+ char * WindowTitleText;
+ xPriv *priv;
+
+ if (!initdone) {
+ gfxThreadHandle hth;
+
+ initdone = TRUE;
+ #if GFX_USE_OS_LINUX || GFX_USE_OS_OSX
+ XInitThreads();
+ #endif
+
+ dis = XOpenDisplay(NULL);
+ scr = DefaultScreen(dis);
+ cxt = XUniqueContext();
+ XSetIOErrorHandler(FatalXIOError);
+
+ #if GDISP_FORCE_24BIT
+ if (!XMatchVisualInfo(dis, scr, 24, TrueColor, &vis)) {
+ fprintf(stderr, "Your display has no TrueColor mode\n");
+ XCloseDisplay(dis);
+ return FALSE;
+ }
+ cmap = XCreateColormap(dis, RootWindow(dis, scr),
+ vis.visual, AllocNone);
+ #else
+ vis.visual = CopyFromParent;
+ vis.depth = DefaultDepth(dis, scr);
+ cmap = DefaultColormap(dis, scr);
+ #endif
+ fprintf(stderr, "Running GFX Window in %d bit color\n", vis.depth);
+
+ if (!(hth = gfxThreadCreate(waXThread, sizeof(waXThread), HIGH_PRIORITY, ThreadX, 0))) {
+ fprintf(stderr, "Cannot start X Thread\n");
+ XCloseDisplay(dis);
+ exit(0);
+ }
+ #if GFX_USE_OS_LINUX || GFX_USE_OS_OSX
+ pthread_detach(hth);
+ #endif
+ gfxThreadClose(hth);
+ }
+
+ g->priv = gfxAlloc(sizeof(xPriv));
+ priv = (xPriv *)g->priv;
+ g->board = 0; // No board interface for this driver
+
+ xa.colormap = cmap;
+ xa.border_pixel = 0xFFFFFF;
+ xa.background_pixel = 0x000000;
+
+ priv->win = XCreateWindow(dis, RootWindow(dis, scr), 16, 16,
+ GDISP_SCREEN_WIDTH, GDISP_SCREEN_HEIGHT,
+ 0, vis.depth, InputOutput, vis.visual,
+ CWBackPixel|CWColormap|CWBorderPixel, &xa);
+ XSync(dis, TRUE);
+
+ XSaveContext(dis, priv->win, cxt, (XPointer)g);
+
+ {
+ char buf[132];
+ sprintf(buf, "uGFX - %u", g->systemdisplay+1);
+ WindowTitleText = buf;
+ XStringListToTextProperty(&WindowTitleText, 1, &WindowTitle);
+ XSetWMName(dis, priv->win, &WindowTitle);
+ XSetWMIconName(dis, priv->win, &WindowTitle);
+ XSync(dis, TRUE);
+ }
+
+ pSH = XAllocSizeHints();
+ pSH->flags = PSize | PMinSize | PMaxSize;
+ pSH->min_width = pSH->max_width = pSH->base_width = GDISP_SCREEN_WIDTH;
+ pSH->min_height = pSH->max_height = pSH->base_height = GDISP_SCREEN_HEIGHT;
+ XSetWMNormalHints(dis, priv->win, pSH);
+ XFree(pSH);
+ XSync(dis, TRUE);
+
+ priv->pix = XCreatePixmap(dis, priv->win,
+ GDISP_SCREEN_WIDTH, GDISP_SCREEN_HEIGHT, vis.depth);
+ XSync(dis, TRUE);
+
+ priv->gc = XCreateGC(dis, priv->win, 0, 0);
+ XSetBackground(dis, priv->gc, BlackPixel(dis, scr));
+ XSync(dis, TRUE);
+
+ XSelectInput(dis, priv->win, StructureNotifyMask);
+ XMapWindow(dis, priv->win);
+
+ // Wait for the window creation to complete (for safety)
+ while(!(((volatile GDisplay *)g)->flags & GDISP_FLG_READY))
+ gfxSleepMilliseconds(100);
+
+ /* Initialise the GDISP structure to match */
+ g->g.Orientation = GDISP_ROTATE_0;
+ g->g.Powermode = powerOn;
+ g->g.Backlight = 100;
+ g->g.Contrast = 50;
+ g->g.Width = GDISP_SCREEN_WIDTH;
+ g->g.Height = GDISP_SCREEN_HEIGHT;
+ return TRUE;
+}
+
+LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g)
+{
+ xPriv * priv = (xPriv *)g->priv;
+ XColor col;
+
+ col.red = RED_OF(g->p.color) << 8;
+ col.green = GREEN_OF(g->p.color) << 8;
+ col.blue = BLUE_OF(g->p.color) << 8;
+ XAllocColor(dis, cmap, &col);
+ XSetForeground(dis, priv->gc, col.pixel);
+ XDrawPoint(dis, priv->pix, priv->gc, (int)g->p.x, (int)g->p.y );
+ XDrawPoint(dis, priv->win, priv->gc, (int)g->p.x, (int)g->p.y );
+ XFlush(dis);
+}
+
+#if GDISP_HARDWARE_FILLS
+ LLDSPEC void gdisp_lld_fill_area(GDisplay *g) {
+ xPriv * priv = (xPriv *)g->priv;
+ XColor col;
+
+ col.red = RED_OF(g->p.color) << 8;
+ col.green = GREEN_OF(g->p.color) << 8;
+ col.blue = BLUE_OF(g->p.color) << 8;
+ XAllocColor(dis, cmap, &col);
+ XSetForeground(dis, priv->gc, col.pixel);
+ XFillRectangle(dis, priv->pix, priv->gc, g->p.x, g->p.y, g->p.cx, g->p.cy);
+ XFillRectangle(dis, priv->win, priv->gc, g->p.x, g->p.y, g->p.cx, g->p.cy);
+ XFlush(dis);
+ }
+#endif
+
+#if 0 && GDISP_HARDWARE_BITFILLS
+ LLDSPEC void gdisp_lld_blit_area(GDisplay *g) {
+ // Start of Bitblit code
+
+ //XImage bitmap;
+ //pixel_t *bits;
+ // bits = malloc(vis.depth * GDISP_SCREEN_WIDTH * GDISP_SCREEN_HEIGHT);
+ // bitmap = XCreateImage(dis, vis, vis.depth, ZPixmap,
+ // 0, bits, GDISP_SCREEN_WIDTH, GDISP_SCREEN_HEIGHT,
+ // 0, 0);
+ }
+#endif
+
+#if GDISP_HARDWARE_PIXELREAD
+ LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g) {
+ xPriv * priv = (xPriv *)g->priv;
+ XColor color;
+ XImage *img;
+
+ img = XGetImage (dis, priv->pix, g->p.x, g->p.y, 1, 1, AllPlanes, XYPixmap);
+ color.pixel = XGetPixel (img, 0, 0);
+ XFree(img);
+ XQueryColor(dis, cmap, &color);
+ return RGB2COLOR(color.red>>8, color.green>>8, color.blue>>8);
+ }
+#endif
+
+#if GDISP_NEED_SCROLL && GDISP_HARDWARE_SCROLL
+ LLDSPEC void gdisp_lld_vertical_scroll(GDisplay *g) {
+ xPriv * priv = (xPriv *)g->priv;
+
+ if (g->p.y1 > 0) {
+ XCopyArea(dis, priv->pix, priv->pix, priv->gc, g->p.x, g->p.y+g->p.y1, g->p.cx, g->p.cy-g->p.y1, g->p.x, g->p.y);
+ XCopyArea(dis, priv->pix, priv->win, priv->gc, g->p.x, g->p.y, g->p.cx, g->p.cy-g->p.y1, g->p.x, g->p.y);
+ } else {
+ XCopyArea(dis, priv->pix, priv->pix, priv->gc, g->p.x, g->p.y, g->p.cx, g->p.cy+g->p.y1, g->p.x, g->p.y-g->p.y1);
+ XCopyArea(dis, priv->pix, priv->win, priv->gc, g->p.x, g->p.y-g->p.y1, g->p.cx, g->p.cy+g->p.y1, g->p.x, g->p.y-g->p.y1);
+ }
+ }
+#endif
+
+#if GINPUT_NEED_MOUSE
+
+ void ginput_lld_mouse_init(void) {}
+
+ void ginput_lld_mouse_get_reading(MouseReading *pt) {
+ pt->x = mousex;
+ pt->y = mousey;
+ pt->z = (mousebuttons & GINPUT_MOUSE_BTN_LEFT) ? 100 : 0;
+ pt->buttons = mousebuttons;
+ }
+
+#endif /* GINPUT_NEED_MOUSE */
+
+#endif /* GFX_USE_GDISP */
+/** @} */
+
diff --git a/drivers/multiple/X/gdisp_lld_config.h b/drivers/multiple/X/gdisp_lld_config.h
index 0cacc4f8..631ecf46 100644
--- a/drivers/multiple/X/gdisp_lld_config.h
+++ b/drivers/multiple/X/gdisp_lld_config.h
@@ -22,20 +22,14 @@
/* Driver hardware support. */
/*===========================================================================*/
-#define GDISP_DRIVER_NAME "Linux emulator - X11"
-
-#define GDISP_HARDWARE_CLEARS FALSE
+#define GDISP_HARDWARE_DRAWPIXEL TRUE
#define GDISP_HARDWARE_FILLS TRUE
#define GDISP_HARDWARE_BITFILLS FALSE
-#define GDISP_HARDWARE_SCROLL FALSE
-#define GDISP_HARDWARE_PIXELREAD FALSE
+#define GDISP_HARDWARE_SCROLL TRUE
+#define GDISP_HARDWARE_PIXELREAD TRUE
#define GDISP_HARDWARE_CONTROL FALSE
-#define GDISP_HARDWARE_CIRCLES FALSE
-#define GDISP_HARDWARE_CIRCLEFILLS FALSE
-#define GDISP_HARDWARE_ARCS FALSE
-#define GDISP_HARDWARE_ARCFILLS FALSE
-#define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_RGB888
+#define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_RGB888
#endif /* GFX_USE_GDISP */
diff --git a/drivers/tdisp/HD44780/tdisp_lld.c b/drivers/tdisp/HD44780/tdisp_lld.c
index 2232955c..7b731c34 100644
--- a/drivers/tdisp/HD44780/tdisp_lld.c
+++ b/drivers/tdisp/HD44780/tdisp_lld.c
@@ -17,15 +17,7 @@
#if GFX_USE_TDISP /*|| defined(__DOXYGEN__)*/
-/* check first if the user has defined his/her own lowlevel-board file */
-#if defined(TDISP_USE_CUSTOM_BOARD) && TDISP_USE_CUSTOM_BOARD
- /* Include the user supplied board definitions */
- #include "tdisp_lld_board.h"
-#elif defined(BOARD_OLIMEX_STM32_E407)
- #include "tdisp_lld_board_olimex_e407.h"
-#elif defined(BOARD_ST_STM32F4_DISCOVERY)
- #include "tdisp_lld_board_example.h"
-#endif
+#include "tdisp_lld_board.h"
/* Controller Specific Properties */
#define CUSTOM_CHAR_COUNT 8
diff --git a/gfxconf.example.h b/gfxconf.example.h
index f7e72890..2625d820 100644
--- a/gfxconf.example.h
+++ b/gfxconf.example.h
@@ -14,11 +14,11 @@
#ifndef _GFXCONF_H
#define _GFXCONF_H
-/* The operating system to use. One of these must be defined - perferably in your Makefile */
-#define GFX_USE_OS_CHIBIOS FALSE
-#define GFX_USE_OS_WIN32 FALSE
-#define GFX_USE_OS_LINUX FALSE
-#define GFX_USE_OS_OSX FALSE
+/* The operating system to use. One of these must be defined - preferably in your Makefile */
+//#define GFX_USE_OS_CHIBIOS FALSE
+//#define GFX_USE_OS_WIN32 FALSE
+//#define GFX_USE_OS_LINUX FALSE
+//#define GFX_USE_OS_OSX FALSE
/* GFX subsystems to turn on */
#define GFX_USE_GDISP FALSE
@@ -34,11 +34,13 @@
#define GFX_USE_GMISC FALSE
/* Features for the GDISP subsystem */
+#define GDISP_NEED_AUTOFLUSH FALSE
+#define GDISP_NEED_TIMERFLUSH FALSE
#define GDISP_NEED_VALIDATION TRUE
#define GDISP_NEED_CLIP TRUE
#define GDISP_NEED_TEXT TRUE
-#define GDISP_NEED_CIRCLE TRUE
-#define GDISP_NEED_ELLIPSE TRUE
+#define GDISP_NEED_CIRCLE FALSE
+#define GDISP_NEED_ELLIPSE FALSE
#define GDISP_NEED_ARC FALSE
#define GDISP_NEED_CONVEX_POLYGON FALSE
#define GDISP_NEED_SCROLL FALSE
@@ -47,13 +49,17 @@
#define GDISP_NEED_QUERY FALSE
#define GDISP_NEED_IMAGE FALSE
#define GDISP_NEED_MULTITHREAD FALSE
-#define GDISP_NEED_ASYNC FALSE
-#define GDISP_NEED_MSGAPI FALSE
+#define GDISP_NEED_STREAMING FALSE
+
+/* GDISP - text features */
#define GDISP_NEED_ANTIALIAS FALSE
#define GDISP_NEED_UTF8 FALSE
#define GDISP_NEED_TEXT_KERNING FALSE
/* GDISP - fonts to include */
+#define GDISP_INCLUDE_FONT_UI1 FALSE
+#define GDISP_INCLUDE_FONT_UI2 FALSE
+#define GDISP_INCLUDE_FONT_LARGENUMBERS FALSE
#define GDISP_INCLUDE_FONT_DEJAVUSANS10 FALSE
#define GDISP_INCLUDE_FONT_DEJAVUSANS12 FALSE
#define GDISP_INCLUDE_FONT_DEJAVUSANS16 FALSE
@@ -68,10 +74,6 @@
#define GDISP_INCLUDE_FONT_DEJAVUSANS24_AA FALSE
#define GDISP_INCLUDE_FONT_DEJAVUSANS32_AA FALSE
#define GDISP_INCLUDE_FONT_DEJAVUSANSBOLD12_AA FALSE
-
-#define GDISP_INCLUDE_FONT_UI1 FALSE
-#define GDISP_INCLUDE_FONT_UI2 FALSE
-#define GDISP_INCLUDE_FONT_LARGENUMBERS FALSE
#define GDISP_INCLUDE_USER_FONTS FALSE
/* GDISP image decoders */
@@ -140,10 +142,37 @@
#define GMISC_NEED_ARRAYOPS FALSE
#define GMISC_NEED_FASTTRIG FALSE
#define GMISC_NEED_FIXEDTRIG FALSE
+#define GMISC_NEED_INVSQRT FALSE
+
+/* Optional Multiple Display support */
+/*
+ #define GDISP_TOTAL_DISPLAYS 1
+ #define GDISP_TOTAL_CONTROLLERS 1
+
+ // Extra stuff required when GDISP_TOTAL_CONTROLLERS > 1
+ #define GDISP_CONTROLLER_LIST GDISPVMT_Win32, GDISPVMT_Win32
+ #define GDISP_CONTROLLER_DISPLAYS 1, 1
+ #define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_RGB888
+
+ // Optional extra stuff when GDISP_TOTAL_CONTROLLERS > 1
+ #define GDISP_HARDWARE_STREAM_WRITE FALSE
+ #define GDISP_HARDWARE_STREAM_READ FALSE
+ #define GDISP_HARDWARE_STREAM_POS FALSE
+ #define GDISP_HARDWARE_DRAWPIXEL FALSE
+ #define GDISP_HARDWARE_CLEARS FALSE
+ #define GDISP_HARDWARE_FILLS FALSE
+ #define GDISP_HARDWARE_BITFILLS FALSE
+ #define GDISP_HARDWARE_SCROLL FALSE
+ #define GDISP_HARDWARE_PIXELREAD FALSE
+ #define GDISP_HARDWARE_CONTROL FALSE
+ #define GDISP_HARDWARE_QUERY FALSE
+ #define GDISP_HARDWARE_CLIP FALSE
+*/
/* Optional Parameters for various subsystems */
/*
- #define GDISP_THREAD_PRIORITY NORMAL_PRIORITY
+ #define GDISP_DEFAULT_ORIENTATION GDISP_ROTATE_LANDSCAPE
+ #define GDISP_LINEBUF_SIZE 128
#define GEVENT_MAXIMUM_SIZE 32
#define GEVENT_MAX_SOURCE_LISTENERS 32
#define GTIMER_THREAD_PRIORITY HIGH_PRIORITY
@@ -153,11 +182,12 @@
#define GWIN_CONSOLE_USE_BASESTREAM FALSE
#define GWIN_CONSOLE_USE_FLOAT FALSE
#define GWIN_NEED_IMAGE_ANIMATION FALSE
+ #define GMISC_INVSQRT_MIXED_ENDIAN FALSE
+ #define GMISC_INVSQRT_REAL_SLOW FALSE
*/
/* Optional Low Level Driver Definitions */
/*
- #define GDISP_USE_CUSTOM_BOARD FALSE
#define GDISP_SCREEN_WIDTH 320
#define GDISP_SCREEN_HEIGHT 240
#define TDISP_COLUMNS 16
diff --git a/include/gdisp/colors.h b/include/gdisp/colors.h
new file mode 100644
index 00000000..efd7076c
--- /dev/null
+++ b/include/gdisp/colors.h
@@ -0,0 +1,377 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+/**
+ * @file include/gdisp/colors.h
+ * @brief GDISP color definitions header file.
+ *
+ * @defgroup Colors Colors
+ * @ingroup GDISP
+ * @{
+ */
+
+#ifndef _GDISP_COLORS_H
+#define _GDISP_COLORS_H
+
+#include "gfx.h"
+
+#if GFX_USE_GDISP || defined(__DOXYGEN__)
+
+/**
+ * For pixel formats we do some assignment of codes to enable
+ * format auto-calculation. (Undocumented).
+ * 0x2RGB TRUECOLOR RGB format, R = red bits, G = green bits, B = blue bits
+ * 0x3RGB TRUECOLOR BGR format, R = red bits, G = green bits, B = blue bits
+ * 0x40XX GRAYSCALE XX = bits
+ * 0x60XX PALLETTE XX = bits
+ * 0x8XXX CUSTOM format.
+ */
+#define GDISP_COLORSYSTEM_MASK 0xF000
+#define GDISP_COLORSYSTEM_RGB 0x2000
+#define GDISP_COLORSYSTEM_BGR 0x3000
+
+/**
+ * @brief Color Type Constants
+ * @{
+ */
+#define GDISP_COLORSYSTEM_TRUECOLOR 0x2000
+#define GDISP_COLORSYSTEM_GRAYSCALE 0x4000
+#define GDISP_COLORSYSTEM_PALETTE 0x6000
+/** @} */
+
+/**
+ * @brief Pixel Format Constants
+ * @{
+ */
+#define GDISP_PIXELFORMAT_MONO (GDISP_COLORSYSTEM_GRAYSCALE|0x0001)
+#define GDISP_PIXELFORMAT_GRAY4 (GDISP_COLORSYSTEM_GRAYSCALE|0x0002)
+#define GDISP_PIXELFORMAT_GRAY16 (GDISP_COLORSYSTEM_GRAYSCALE|0x0004)
+#define GDISP_PIXELFORMAT_GRAY256 (GDISP_COLORSYSTEM_GRAYSCALE|0x0008)
+#define GDISP_PIXELFORMAT_RGB565 (GDISP_COLORSYSTEM_RGB|0x0565)
+#define GDISP_PIXELFORMAT_BGR565 (GDISP_COLORSYSTEM_BGR|0x0565)
+#define GDISP_PIXELFORMAT_RGB888 (GDISP_COLORSYSTEM_RGB|0x0888)
+#define GDISP_PIXELFORMAT_BGR888 (GDISP_COLORSYSTEM_BGR|0x0888)
+#define GDISP_PIXELFORMAT_RGB444 (GDISP_COLORSYSTEM_RGB|0x0444)
+#define GDISP_PIXELFORMAT_BGR444 (GDISP_COLORSYSTEM_BGR|0x0444)
+#define GDISP_PIXELFORMAT_RGB332 (GDISP_COLORSYSTEM_RGB|0x0332)
+#define GDISP_PIXELFORMAT_BGR332 (GDISP_COLORSYSTEM_BGR|0x0332)
+#define GDISP_PIXELFORMAT_RGB666 (GDISP_COLORSYSTEM_RGB|0x0666)
+#define GDISP_PIXELFORMAT_BGR666 (GDISP_COLORSYSTEM_BGR|0x0666)
+#define GDISP_PIXELFORMAT_ERROR 0x0000
+/** @} */
+
+/**
+ * @name Some basic colors
+ * @{
+ */
+#define White HTML2COLOR(0xFFFFFF)
+#define Black HTML2COLOR(0x000000)
+#define Gray HTML2COLOR(0x808080)
+#define Grey Gray
+#define Blue HTML2COLOR(0x0000FF)
+#define Red HTML2COLOR(0xFF0000)
+#define Fuchsia HTML2COLOR(0xFF00FF)
+#define Magenta Fuchsia
+#define Green HTML2COLOR(0x008000)
+#define Yellow HTML2COLOR(0xFFFF00)
+#define Aqua HTML2COLOR(0x00FFFF)
+#define Cyan Aqua
+#define Lime HTML2COLOR(0x00FF00)
+#define Maroon HTML2COLOR(0x800000)
+#define Navy HTML2COLOR(0x000080)
+#define Olive HTML2COLOR(0x808000)
+#define Purple HTML2COLOR(0x800080)
+#define Silver HTML2COLOR(0xC0C0C0)
+#define Teal HTML2COLOR(0x008080)
+#define Orange HTML2COLOR(0xFFA500)
+#define Pink HTML2COLOR(0xFFC0CB)
+#define SkyBlue HTML2COLOR(0x87CEEB)
+/** @} */
+
+#if defined(__DOXYGEN__)
+ /**
+ * @brief The color system (grayscale, palette or truecolor)
+ */
+ #define COLOR_SYSTEM GDISP_COLORSYSTEM_TRUECOLOR
+ /**
+ * @brief The number of bits in a color value
+ */
+ #define COLOR_BITS 16
+ /**
+ * @brief The number of bits for each of red, green and blue
+ * @{
+ */
+ #define COLOR_BITS_R 5
+ #define COLOR_BITS_G 6
+ #define COLOR_BITS_B 5
+ /** @} */
+ /**
+ * @brief The number of bits to shift each of red, green and blue to put it in the correct place in the color
+ * @{
+ */
+ #define COLOR_SHIFT_R 11
+ #define COLOR_SHIFT_G 5
+ #define COLOR_SHIFT_B 0
+ /** @} */
+ /**
+ * @brief Does the color need masking to remove invalid bits
+ */
+ #define COLOR_NEEDS_MASK FALSE
+ /**
+ * @brief If the color needs masking to remove invalid bits, this is the mask
+ */
+ #define COLOR_MASK 0xFFFF
+ /**
+ * @brief The color type
+ * @{
+ */
+ #define COLOR_TYPE uint16_t
+ /** @} */
+ /**
+ * @brief The number of bits in the color type (not necessarily the same as COLOR_BITS).
+ */
+ #define COLOR_TYPE_BITS 16
+ /**
+ * @brief Convert a luminance (0 to 255) into a color value.
+ * @note The word "Luma" is used instead of grey or gray due to the spelling ambiguities of the word grey
+ * @note This is not a weighted luminance conversion in the color tv style.
+ * @note @p LUMA2COLOR() uses a linear conversion (0.33R + 0.33G + 0.33B). Note this is different to color
+ * tv luminance (0.26126R + 0.7152G + 0.0722B), digital tv luminance of (0.299R + 0.587G + 0.114B), or
+ * @p LUMA_OF() which uses (0.25R + 0.5G + 0.25B).
+ */
+ #define LUMA2COLOR(l) ((color_t)((((l) & 0xF8)<<8) | (((l) & 0xFC)<<3) | (((l) & 0xF8)>>3)))
+ /**
+ * @brief Convert red, green, blue (each 0 to 255) into a color value.
+ */
+ #define RGB2COLOR(r,g,b) ((color_t)((((r) & 0xF8)<<8) | (((g) & 0xFC)<<3) | (((b) & 0xF8)>>3)))
+ /**
+ * @brief Convert a 6 digit HTML code (hex) into a color value.
+ */
+ #define HTML2COLOR(h) ((color_t)((((h) & 0xF80000)>>8) | (((h) & 0x00FC00)>>5) | (((h) & 0x0000F8)>>3)))
+ /**
+ * @brief Extract the luma/red/green/blue component (0 to 255) of a color value.
+ * @note This uses quick and dirty bit shifting. If you want more exact colors
+ * use @p EXACT_RED_OF() etc which uses multiplies and divides. For constant
+ * colors using @p EXACT_RED_OF() is no more expensive because the compiler
+ * evaluates the arithmetic.
+ * @note @p LUMA_OF() returns a roughly weighted luminance (0.25R + 0.5G + 0.25B). Note this is
+ * different to @p LUMA2COLOR() which uses a linear conversion (0.33R + 0.33G + 0.33B) and
+ * color tv luminance of (0.26126R + 0.7152G + 0.0722B) and digital tv luminance of (0.299R + 0.587G + 0.114B).
+ * @note A 5 bit color component maximum value (0x1F) converts to 0xF8 (slightly off-color)
+ * @{
+ */
+ #define LUMA_OF(c) ((RED_OF(c)+((uint16_t)GREEN_OF(c)<<1)+BLUE_OF(c))>>2)
+ #define RED_OF(c) (((c) & 0xF800)>>8)
+ #define GREEN_OF(c) (((c)&0x007E)>>3)
+ #define BLUE_OF(c) (((c)&0x001F)<<3)
+ /** @} */
+ /**
+ * @brief Extract the exact luma/red/green/blue component (0 to 255) of a color value.
+ * @note This uses multiplies and divides rather than bit shifting.
+ * This gives exact equivalent colors at the expense of more cpu intensive
+ * operations. Note for constants this is no more expensive than @p REF_OF()
+ * because the compiler evaluates the arithmetic.
+ * @note @p EXACT_LUMA_OF() returns a roughly weighted luminance (0.25R + 0.5G + 0.25B). Note this is
+ * different to @p LUMA2COLOR() which uses a linear conversion (0.33R + 0.33G + 0.33B) and
+ * color tv luminance of (0.26126R + 0.7152G + 0.0722B) and digital tv luminance of (0.299R + 0.587G + 0.114B).
+ * @note A 5 bit color component maximum value (0x1F) converts to 0xFF (the true equivalent color)
+ * @{
+ */
+ #define EXACT_LUMA_OF(c) ((EXACT_RED_OF(c)+((uint16_t)EXACT_GREEN_OF(c)<<1)+EXACT_BLUE_OF(c))>>2)
+ #define EXACT_RED_OF(c) (((((c)>>11)&0x1F)*255)/31)
+ #define EXACT_GREEN_OF(c) (((((c)>>5)&0x3F)*255)/63)
+ #define EXACT_BLUE_OF(c) (((((c)>>0)&0x1F)*255)/31)
+ /** @} */
+#endif
+
+/*
+ * We use this big mess of macros to calculate all the components
+ * to prevent user errors in the color definitions. It greatly simplifies
+ * the above definitions and ensures a consistent implementation.
+ */
+
+//-------------------------
+// True-Color color system
+//-------------------------
+#if GDISP_PIXELFORMAT & GDISP_COLORSYSTEM_TRUECOLOR
+ #define COLOR_SYSTEM GDISP_COLORSYSTEM_TRUECOLOR
+
+ // Calculate the number of bits
+ #define COLOR_BITS_R ((GDISP_PIXELFORMAT>>8) & 0x0F)
+ #define COLOR_BITS_G ((GDISP_PIXELFORMAT>>4) & 0x0F)
+ #define COLOR_BITS_B ((GDISP_PIXELFORMAT>>0) & 0x0F)
+ #define COLOR_BITS (COLOR_BITS_R + COLOR_BITS_G + COLOR_BITS_B)
+
+ // From the number of bits determine COLOR_TYPE, COLOR_TYPE_BITS and masking
+ #if COLOR_BITS <= 8
+ #define COLOR_TYPE uint8_t
+ #define COLOR_TYPE_BITS 8
+ #elif COLOR_BITS <= 16
+ #define COLOR_TYPE uint16_t
+ #define COLOR_TYPE_BITS 16
+ #elif COLOR_BITS <= 32
+ #define COLOR_TYPE uint32_t
+ #define COLOR_TYPE_BITS 32
+ #else
+ #error "GDISP: Cannot define color types with more than 32 bits"
+ #endif
+ #if COLOR_TYPE_BITS == COLOR_BITS
+ #define COLOR_NEEDS_MASK FALSE
+ #else
+ #define COLOR_NEEDS_MASK TRUE
+ #endif
+ #define COLOR_MASK() ((1 << COLOR_BITS)-1)
+
+ // Calculate the component bit shifts
+ #if (GDISP_PIXELFORMAT & GDISP_COLORSYSTEM_MASK) == GDISP_COLORSYSTEM_RGB
+ #define COLOR_SHIFT_R (COLOR_BITS_B+COLOR_BITS_G)
+ #define COLOR_SHIFT_G COLOR_BITS_B
+ #define COLOR_SHIFT_B 0
+ #else
+ #define COLOR_SHIFT_B (COLOR_BITS_R+COLOR_BITS_G)
+ #define COLOR_SHIFT_G COLOR_BITS_R
+ #define COLOR_SHIFT_R 0
+ #endif
+
+ // Calculate RED_OF, GREEN_OF, BLUE_OF and RGB2COLOR
+ #if COLOR_BITS_R + COLOR_SHIFT_R == 8
+ #define RED_OF(c) ((c) & (((1<<COLOR_BITS_R)-1) << COLOR_SHIFT_R))
+ #define RGB2COLOR_R(r) ((COLOR_TYPE)((r) & (0xFF & ~((1<<(8-COLOR_BITS_R))-1))))
+ #elif COLOR_BITS_R + COLOR_SHIFT_R > 8
+ #define RED_OF(c) (((c) & (((1<<COLOR_BITS_R)-1) << COLOR_SHIFT_R)) >> (COLOR_BITS_R+COLOR_SHIFT_R-8))
+ #define RGB2COLOR_R(r) (((COLOR_TYPE)((r) & (0xFF & ~((1<<(8-COLOR_BITS_R))-1)))) << (COLOR_BITS_R+COLOR_SHIFT_R-8))
+ #else // COLOR_BITS_R + COLOR_SHIFT_R < 8
+ #define RED_OF(c) (((c) & (((1<<COLOR_BITS_R)-1) << COLOR_SHIFT_R)) << (8-(COLOR_BITS_R+COLOR_SHIFT_R)))
+ #define RGB2COLOR_R(r) (((COLOR_TYPE)((r) & (0xFF & ~((1<<(8-COLOR_BITS_R))-1)))) >> (8-(COLOR_BITS_R+COLOR_SHIFT_R)))
+ #endif
+ #if COLOR_BITS_G + COLOR_SHIFT_G == 8
+ #define GREEN_OF(c) ((c) & (((1<<COLOR_BITS_G)-1) << COLOR_SHIFT_G))
+ #define RGB2COLOR_G(g) ((COLOR_TYPE)((g) & (0xFF & ~((1<<(8-COLOR_BITS_G))-1))))
+ #elif COLOR_BITS_G + COLOR_SHIFT_G > 8
+ #define GREEN_OF(c) (((c) & (((1<<COLOR_BITS_G)-1) << COLOR_SHIFT_G)) >> (COLOR_BITS_G+COLOR_SHIFT_G-8))
+ #define RGB2COLOR_G(g) (((COLOR_TYPE)((g) & (0xFF & ~((1<<(8-COLOR_BITS_G))-1)))) << (COLOR_BITS_G+COLOR_SHIFT_G-8))
+ #else // COLOR_BITS_G + COLOR_SHIFT_G < 8
+ #define GREEN_OF(c) (((c) & (((1<<COLOR_BITS_G)-1) << COLOR_SHIFT_G)) << (8-(COLOR_BITS_G+COLOR_SHIFT_G)))
+ #define RGB2COLOR_G(g) (((COLOR_TYPE)((g) & (0xFF & ~((1<<(8-COLOR_BITS_G))-1)))) >> (8-(COLOR_BITS_G+COLOR_SHIFT_G)))
+ #endif
+ #if COLOR_BITS_B + COLOR_SHIFT_B == 8
+ #define BLUE_OF(c) ((c) & (((1<<COLOR_BITS_B)-1) << COLOR_SHIFT_B))
+ #define RGB2COLOR_B(b) ((COLOR_TYPE)((b) & (0xFF & ~((1<<(8-COLOR_BITS_B))-1))))
+ #elif COLOR_BITS_B + COLOR_SHIFT_B > 8
+ #define BLUE_OF(c) (((c) & (((1<<COLOR_BITS_B)-1) << COLOR_SHIFT_B)) >> (COLOR_BITS_B+COLOR_SHIFT_B-8))
+ #define RGB2COLOR_B(b) (((COLOR_TYPE)((b) & (0xFF & ~((1<<(8-COLOR_BITS_B))-1)))) << (COLOR_BITS_B+COLOR_SHIFT_B-8))
+ #else // COLOR_BITS_B + COLOR_SHIFT_B < 8
+ #define BLUE_OF(c) (((c) & (((1<<COLOR_BITS_B)-1) << COLOR_SHIFT_B)) << (8-(COLOR_BITS_B+COLOR_SHIFT_B)))
+ #define RGB2COLOR_B(b) (((COLOR_TYPE)((b) & (0xFF & ~((1<<(8-COLOR_BITS_B))-1)))) >> (8-(COLOR_BITS_B+COLOR_SHIFT_B)))
+ #endif
+ #define LUMA_OF(c) ((RED_OF(c)+((uint16_t)GREEN_OF(c)<<1)+BLUE_OF(c))>>2)
+ #define EXACT_RED_OF(c) (((uint16_t)(((c)>>COLOR_SHIFT_R)&((1<<COLOR_BITS_R)-1))*255)/((1<<COLOR_BITS_R)-1))
+ #define EXACT_GREEN_OF(c) (((uint16_t)(((c)>>COLOR_SHIFT_G)&((1<<COLOR_BITS_G)-1))*255)/((1<<COLOR_BITS_G)-1))
+ #define EXACT_BLUE_OF(c) (((uint16_t)(((c)>>COLOR_SHIFT_B)&((1<<COLOR_BITS_B)-1))*255)/((1<<COLOR_BITS_B)-1))
+ #define EXACT_LUMA_OF(c) ((EXACT_RED_OF(c)+((uint16_t)EXACT_GREEN_OF(c)<<1)+EXACT_BLUE_OF(c))>>2)
+ #define LUMA2COLOR(l) (RGB2COLOR_R(l) | RGB2COLOR_G(l) | RGB2COLOR_B(l))
+ #define RGB2COLOR(r,g,b) (RGB2COLOR_R(r) | RGB2COLOR_G(g) | RGB2COLOR_B(b))
+
+ // Calculate HTML2COLOR
+ #if COLOR_BITS_R + COLOR_SHIFT_R == 24
+ #define HTML2COLOR_R(h) ((h) & ((0xFF & ~((1<<(8-COLOR_BITS_R))-1))<<16))
+ #elif COLOR_BITS_R + COLOR_SHIFT_R > 24
+ #define HTML2COLOR_R(h) (((h) & ((0xFF & ~((1<<(8-COLOR_BITS_R))-1))<<16)) << (COLOR_BITS_R+COLOR_SHIFT_R-24))
+ #else // COLOR_BITS_R + COLOR_SHIFT_R < 24
+ #define HTML2COLOR_R(h) (((h) & ((0xFF & ~((1<<(8-COLOR_BITS_R))-1))<<16)) >> (24-(COLOR_BITS_R+COLOR_SHIFT_R)))
+ #endif
+ #if COLOR_BITS_G + COLOR_SHIFT_G == 16
+ #define HTML2COLOR_G(h) ((h) & ((0xFF & ~((1<<(8-COLOR_BITS_G))-1))<<8))
+ #elif COLOR_BITS_G + COLOR_SHIFT_G > 16
+ #define HTML2COLOR_G(h) (((h) & ((0xFF & ~((1<<(8-COLOR_BITS_G))-1))<<8)) << (COLOR_BITS_G+COLOR_SHIFT_G-16))
+ #else // COLOR_BITS_G + COLOR_SHIFT_G < 16
+ #define HTML2COLOR_G(h) (((h) & ((0xFF & ~((1<<(8-COLOR_BITS_G))-1))<<8)) >> (16-(COLOR_BITS_G+COLOR_SHIFT_G)))
+ #endif
+ #if COLOR_BITS_B + COLOR_SHIFT_B == 8
+ #define HTML2COLOR_B(h) ((h) & (0xFF & ~((1<<(8-COLOR_BITS_B))-1)))
+ #elif COLOR_BITS_B + COLOR_SHIFT_B > 8
+ #define HTML2COLOR_B(h) (((h) & (0xFF & ~((1<<(8-COLOR_BITS_B))-1))) << (COLOR_BITS_B+COLOR_SHIFT_B-8))
+ #else // COLOR_BITS_B + COLOR_SHIFT_B < 8
+ #define HTML2COLOR_B(h) (((h) & (0xFF & ~((1<<(8-COLOR_BITS_B))-1))) >> (8-(COLOR_BITS_B+COLOR_SHIFT_B)))
+ #endif
+ #define HTML2COLOR(h) ((COLOR_TYPE)(HTML2COLOR_R(h) | HTML2COLOR_G(h) | HTML2COLOR_B(h)))
+
+//-------------------------
+// Gray-scale color system
+//-------------------------
+#elif (GDISP_PIXELFORMAT & GDISP_COLORSYSTEM_MASK) == GDISP_COLORSYSTEM_GRAYSCALE
+ #define COLOR_SYSTEM GDISP_COLORSYSTEM_GRAYSCALE
+
+ // Calculate the number of bits and shifts
+ #define COLOR_BITS (GDISP_PIXELFORMAT & 0xFF)
+ #define COLOR_BITS_R COLOR_BITS
+ #define COLOR_BITS_G COLOR_BITS
+ #define COLOR_BITS_B COLOR_BITS
+ #define COLOR_SHIFT_R 0
+ #define COLOR_SHIFT_G 0
+ #define COLOR_SHIFT_B 0
+
+ // From the number of bits determine COLOR_TYPE, COLOR_TYPE_BITS and masking
+ #if COLOR_BITS <= 8
+ #define COLOR_TYPE uint8_t
+ #define COLOR_TYPE_BITS 8
+ #else
+ #error "GDISP: Cannot define gray-scale color types with more than 8 bits"
+ #endif
+ #if COLOR_TYPE_BITS == COLOR_BITS
+ #define COLOR_NEEDS_MASK FALSE
+ #else
+ #define COLOR_NEEDS_MASK TRUE
+ #endif
+ #define COLOR_MASK() ((1 << COLOR_BITS)-1)
+
+ #if COLOR_BITS == 1
+ #define RGB2COLOR(r,g,b) (((r)|(g)|(b)) ? 1 : 0)
+ #define LUMA2COLOR(l) ((l) ? 1 : 0)
+ #define HTML2COLOR(h) ((h) ? 1 : 0)
+ #define LUMA_OF(c) ((c) ? 255 : 0)
+ #define EXACT_LUMA_OF(c) LUMA_OF(c)
+ #else
+ // They eye is more sensitive to green
+ #define RGB2COLOR(r,g,b) ((COLOR_TYPE)(((uint16_t)(r)+(g)+(g)+(b)) >> (10-COLOR_BITS)))
+ #define LUMA2COLOR(l) ((COLOR_TYPE)((l)>>(8-COLOR_BITS)))
+ #define HTML2COLOR(h) ((COLOR_TYPE)(((((h)&0xFF0000)>>16)+(((h)&0x00FF00)>>7)+((h)&0x0000FF)) >> (10-COLOR_BITS)))
+ #define LUMA_OF(c) (((c) & ((1<<COLOR_BITS)-1)) << (8-COLOR_BITS))
+ #define EXACT_LUMA_OF(c) ((((uint16_t)(c) & ((1<<COLOR_BITS)-1))*255)/((1<<COLOR_BITS)-1))
+ #endif
+
+ #define RED_OF(c) LUMA_OF(c)
+ #define GREEN_OF(c) LUMA_OF(c)
+ #define BLUE_OF(c) LUMA_OF(c)
+ #define EXACT_RED_OF(c) EXACT_LUMA_OF(c)
+ #define EXACT_GREEN_OF(c) EXACT_LUMA_OF(c)
+ #define EXACT_BLUE_OF(c) EXACT_LUMA_OF(c)
+
+//-------------------------
+// Palette color system
+//-------------------------
+#elif (GDISP_PIXELFORMAT & GDISP_COLORSYSTEM_MASK) == GDISP_COLORSYSTEM_PALETTE
+ #define COLOR_SYSTEM GDISP_COLORSYSTEM_PALETTE
+
+ #error "GDISP: A palette color system is not currently supported"
+
+//-------------------------
+// Some other color system
+//-------------------------
+#else
+ #error "GDISP: Unsupported color system"
+#endif
+
+/**
+ * @brief The color type definition
+ */
+typedef COLOR_TYPE color_t;
+
+#endif /* GFX_USE_GDISP */
+
+#endif /* _GDISP_COLORS_H */
+/** @} */
diff --git a/include/gdisp/gdisp.h b/include/gdisp/gdisp.h
index b82c9f3c..51415805 100644
--- a/include/gdisp/gdisp.h
+++ b/include/gdisp/gdisp.h
@@ -17,6 +17,10 @@
*
* @pre GFX_USE_GDISP must be set to TRUE in gfxconf.h
*
+ * @note Each drawing routine supports a gispXXXX and a gdispGXXXX function. The difference is that the
+ * gdispXXXX function does not require a display to be specified. Note there is a slight anomoly
+ * in the naming with gdispGBlitArea() vs gdispBlitAreaEx() and gdispBlitArea(), the later of
+ * which is now deprecated.
* @{
*/
@@ -43,53 +47,56 @@ typedef int16_t coord_t;
/**
* @brief Type for a 2D point on the screen.
*/
-typedef struct point_t {
- coord_t x, y;
- } point;
+typedef struct point { coord_t x, y; } point, point_t;
/**
* @brief Type for the text justification.
*/
-typedef enum justify {
- justifyLeft = 0,
- justifyCenter = 1,
- justifyRight = 2
-} justify_t;
+typedef enum justify { justifyLeft=0, justifyCenter=1, justifyRight=2 } justify_t;
/**
* @brief Type for the font metric.
*/
-typedef enum fontmetric {fontHeight, fontDescendersHeight, fontLineSpacing, fontCharPadding, fontMinWidth, fontMaxWidth} fontmetric_t;
+typedef enum fontmetric { fontHeight, fontDescendersHeight, fontLineSpacing, fontCharPadding, fontMinWidth, fontMaxWidth } fontmetric_t;
/**
* @brief The type of a font.
*/
typedef const struct mf_font_s* font_t;
/**
* @brief Type for the screen orientation.
+ * @note GDISP_ROTATE_LANDSCAPE and GDISP_ROTATE_PORTRAIT are internally converted to the
+ * most appropriate other orientation.
*/
-typedef enum orientation {GDISP_ROTATE_0, GDISP_ROTATE_90, GDISP_ROTATE_180, GDISP_ROTATE_270} gdisp_orientation_t;
+typedef enum orientation { GDISP_ROTATE_0=0, GDISP_ROTATE_90=90, GDISP_ROTATE_180=180, GDISP_ROTATE_270=270, GDISP_ROTATE_PORTRAIT=1000, GDISP_ROTATE_LANDSCAPE=1001 } orientation_t;
/**
* @brief Type for the available power modes for the screen.
*/
-typedef enum powermode {powerOff, powerSleep, powerDeepSleep, powerOn} gdisp_powermode_t;
+typedef enum powermode { powerOff, powerSleep, powerDeepSleep, powerOn } powermode_t;
/*
* This is not documented in Doxygen as it is meant to be a black-box.
* Applications should always use the routines and macros defined
* below to access it in case the implementation ever changed.
*/
-typedef struct GDISPDriver_t {
+typedef struct GDISPControl {
coord_t Width;
coord_t Height;
- gdisp_orientation_t Orientation;
- gdisp_powermode_t Powermode;
+ orientation_t Orientation;
+ powermode_t Powermode;
uint8_t Backlight;
uint8_t Contrast;
- #if GDISP_NEED_CLIP || GDISP_NEED_VALIDATION
- coord_t clipx0, clipy0;
- coord_t clipx1, clipy1; /* not inclusive */
- #endif
- } GDISPDriver;
+ } GDISPControl;
-extern GDISPDriver GDISP;
+/*
+ * Our black box display structure. We know only one thing about it...
+ * The first member is a GDISPControl structure.
+ */
+typedef struct GDisplay GDisplay;
+
+/**
+ * @brief The default screen to use for the gdispXXXX calls.
+ * @note This is set by default to the first display in the system. You can change
+ * it by calling @p gdispGSetDisplay().
+ */
+extern GDisplay *GDISP;
/*===========================================================================*/
/* Constants. */
@@ -115,475 +122,476 @@ extern GDISPDriver GDISP;
#define GDISP_CONTROL_CONTRAST 3
#define GDISP_CONTROL_LLD 1000
-/**
- * @brief Driver Query Constants
- * @details Unsupported query codes return (void *)-1.
- * @note The result should be typecast the required type.
- * @note GDISP_QUERY_LLD - Low level driver control constants start at
- * this value.
- */
-#define GDISP_QUERY_LLD 1000
+/*===========================================================================*/
+/* Defines relating to the display hardware */
+/*===========================================================================*/
-/**
- * @brief Driver Pixel Format Constants
- */
-#define GDISP_PIXELFORMAT_MONO 1
-#define GDISP_PIXELFORMAT_RGB565 565
-#define GDISP_PIXELFORMAT_RGB888 888
-#define GDISP_PIXELFORMAT_RGB444 444
-#define GDISP_PIXELFORMAT_RGB332 332
-#define GDISP_PIXELFORMAT_RGB666 666
-#define GDISP_PIXELFORMAT_CUSTOM 99999
-#define GDISP_PIXELFORMAT_ERROR 88888
+#if !defined(GDISP_TOTAL_CONTROLLERS) || GDISP_TOTAL_CONTROLLERS == 1
+ // Pull in the default hardware configuration for a single controller.
+ // If we have multiple controllers the settings must be set in the
+ // users gfxconf.h file.
+ #include "gdisp_lld_config.h"
+
+ // Unless the user has specified a specific pixel format, use
+ // the native format for the controller.
+ #if !defined(GDISP_PIXELFORMAT) && defined(GDISP_LLD_PIXELFORMAT)
+ #define GDISP_PIXELFORMAT GDISP_LLD_PIXELFORMAT
+ #endif
+#endif
/**
- * @name Some basic colors
+ * @name GDISP pixel format choices
* @{
*/
-#define White HTML2COLOR(0xFFFFFF)
-#define Black HTML2COLOR(0x000000)
-#define Gray HTML2COLOR(0x808080)
-#define Grey Gray
-#define Blue HTML2COLOR(0x0000FF)
-#define Red HTML2COLOR(0xFF0000)
-#define Fuchsia HTML2COLOR(0xFF00FF)
-#define Magenta Fuchsia
-#define Green HTML2COLOR(0x008000)
-#define Yellow HTML2COLOR(0xFFFF00)
-#define Aqua HTML2COLOR(0x00FFFF)
-#define Cyan Aqua
-#define Lime HTML2COLOR(0x00FF00)
-#define Maroon HTML2COLOR(0x800000)
-#define Navy HTML2COLOR(0x000080)
-#define Olive HTML2COLOR(0x808000)
-#define Purple HTML2COLOR(0x800080)
-#define Silver HTML2COLOR(0xC0C0C0)
-#define Teal HTML2COLOR(0x008080)
-#define Orange HTML2COLOR(0xFFA500)
-#define Pink HTML2COLOR(0xFFC0CB)
-#define SkyBlue HTML2COLOR(0x87CEEB)
+ /**
+ * @brief The pixel format.
+ * @default It generally defaults to the hardware pixel format.
+ * @note This doesn't need to match the hardware pixel format.
+ * It is definitely more efficient when it does.
+ * @note When GDISP_TOTAL_CONTROLLERS > 1, this must
+ * be explicitly defined and should ensure the best match
+ * with your hardware across all devices.
+ */
+ #ifndef GDISP_PIXELFORMAT
+ #define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_ERROR
+ #endif
+ /**
+ * @brief Do pixels require packing for a blit
+ * @note Is only valid for a pixel format that doesn't fill it's datatype. eg formats:
+ * GDISP_PIXELFORMAT_RGB888
+ * GDISP_PIXELFORMAT_RGB444
+ * GDISP_PIXELFORMAT_RGB666
+ * GDISP_PIXELFORMAT_CUSTOM
+ * @note Very few cases should actually require packed pixels as the low
+ * level driver can also pack on the fly as it is sending it
+ * to the graphics device.
+ * @note Packed pixels are not really supported at this point.
+ */
+ #ifndef GDISP_PACKED_PIXELS
+ #define GDISP_PACKED_PIXELS FALSE
+ #endif
+
+ /**
+ * @brief Do lines of pixels require packing for a blit
+ * @note Ignored if GDISP_PACKED_PIXELS is FALSE
+ */
+ #ifndef GDISP_PACKED_LINES
+ #define GDISP_PACKED_LINES FALSE
+ #endif
/** @} */
/*===========================================================================*/
/* Defines related to the pixel format */
/*===========================================================================*/
-#if defined(__DOXYGEN__)
- /**
- * @brief The color of a pixel.
- */
- typedef uint16_t color_t;
- /**
- * @brief Convert a number (of any type) to a color_t.
- * @details Masks any invalid bits in the color
- */
- #define COLOR(c) ((color_t)(c))
- /**
- * @brief Does the color_t type contain invalid bits that need masking.
- */
- #define MASKCOLOR FALSE
- /**
- * @brief Convert red, green, blue (each 0 to 255) into a color value.
- */
- #define RGB2COLOR(r,g,b) ((color_t)((((r) & 0xF8)<<8) | (((g) & 0xFC)<<3) | (((b) & 0xF8)>>3)))
- /**
- * @brief Convert a 6 digit HTML code (hex) into a color value.
- */
- #define HTML2COLOR(h) ((color_t)((((h) & 0xF80000)>>8) | (((h) & 0x00FC00)>>5) | (((h) & 0x0000F8)>>3)))
- /**
- * @brief Extract the red component (0 to 255) of a color value.
- */
- #define RED_OF(c) (((c) & 0xF800)>>8)
- /**
- * @brief Extract the green component (0 to 255) of a color value.
- */
- #define GREEN_OF(c) (((c)&0x007E)>>3)
- /**
- * @brief Extract the blue component (0 to 255) of a color value.
- */
- #define BLUE_OF(c) (((c)&0x001F)<<3)
+/* Load our color definitions and pixel formats */
+#include "colors.h"
+
+/**
+ * @brief The type of a pixel.
+ */
+typedef color_t pixel_t;
-#elif GDISP_PIXELFORMAT == GDISP_PIXELFORMAT_MONO
- typedef uint8_t color_t;
- #define COLOR(c) ((color_t)(c))
- #define MASKCOLOR FALSE
- #define RGB2COLOR(r,g,b) ((r|g|b) ? 1 : 0)
- #define HTML2COLOR(h) (h ? 1 : 0)
- #define RED_OF(c) (c ? 255 : 0)
- #define GREEN_OF(c) (c ? 255 : 0)
- #define BLUE_OF(c) (c ? 255 : 0)
+#ifdef __cplusplus
+extern "C" {
+#endif
-#elif GDISP_PIXELFORMAT == GDISP_PIXELFORMAT_RGB565
- typedef uint16_t color_t;
- #define COLOR(c) ((color_t)(c))
- #define MASKCOLOR FALSE
- #define RGB2COLOR(r,g,b) ((color_t)((((r) & 0xF8)<<8) | (((g) & 0xFC)<<3) | (((b) & 0xF8)>>3)))
- #define HTML2COLOR(h) ((color_t)((((h) & 0xF80000)>>8) | (((h) & 0x00FC00)>>5) | (((h) & 0x0000F8)>>3)))
- #define RED_OF(c) (((c) & 0xF800)>>8)
- #define GREEN_OF(c) (((c)&0x07E0)>>3)
- #define BLUE_OF(c) (((c)&0x001F)<<3)
+/* Base Functions */
-#elif GDISP_PIXELFORMAT == GDISP_PIXELFORMAT_RGB888
- typedef uint32_t color_t;
- #define COLOR(c) ((color_t)(((c) & 0xFFFFFF)))
- #define MASKCOLOR TRUE
- #define RGB2COLOR(r,g,b) ((color_t)((((r) & 0xFF)<<16) | (((g) & 0xFF) << 8) | ((b) & 0xFF)))
- #define HTML2COLOR(h) ((color_t)(h))
- #define RED_OF(c) (((c) & 0xFF0000)>>16)
- #define GREEN_OF(c) (((c)&0x00FF00)>>8)
- #define BLUE_OF(c) ((c)&0x0000FF)
+/**
+ * @brief Blend 2 colors according to the alpha
+ * @return The combined color
+ *
+ * @param[in] fg The foreground color
+ * @param[in] bg The background color
+ * @param[in] alpha The alpha value (0-255). 0 is all background, 255 is all foreground.
+ *
+ * @api
+ */
+color_t gdispBlendColor(color_t fg, color_t bg, uint8_t alpha);
-#elif GDISP_PIXELFORMAT == GDISP_PIXELFORMAT_RGB444
- typedef uint16_t color_t;
- #define COLOR(c) ((color_t)(((c) & 0x0FFF)))
- #define MASKCOLOR TRUE
- #define RGB2COLOR(r,g,b) ((color_t)((((r) & 0xF0)<<4) | ((g) & 0xF0) | (((b) & 0xF0)>>4)))
- #define HTML2COLOR(h) ((color_t)((((h) & 0xF00000)>>12) | (((h) & 0x00F000)>>8) | (((h) & 0x0000F0)>>4)))
- #define RED_OF(c) (((c) & 0x0F00)>>4)
- #define GREEN_OF(c) ((c)&0x00F0)
- #define BLUE_OF(c) (((c)&0x000F)<<4)
+/**
+ * @brief Get the specified display
+ * @return The pointer to the display or NULL if the display doesn't exist
+ * @note The GDISP variable contains the display used by the gdispXxxx routines
+ * as opposed to the gdispGXxxx routines which take an explicit display
+ * parameter.
+ * @note Displays are numbered from 0 to GDISP_TOTAL_DISPLAYS - 1
+ *
+ * @param[in] display The display number (0..n)
+ *
+ * @api
+ */
+GDisplay *gdispGetDisplay(unsigned display);
-#elif GDISP_PIXELFORMAT == GDISP_PIXELFORMAT_RGB332
- typedef uint8_t color_t;
- #define COLOR(c) ((color_t)(c))
- #define MASKCOLOR FALSE
- #define RGB2COLOR(r,g,b) ((color_t)(((r) & 0xE0) | (((g) & 0xE0)>>3) | (((b) & 0xC0)>>6)))
- #define HTML2COLOR(h) ((color_t)((((h) & 0xE00000)>>16) | (((h) & 0x00E000)>>11) | (((h) & 0x0000C0)>>6)))
- #define RED_OF(c) ((c) & 0xE0)
- #define GREEN_OF(c) (((c)&0x1C)<<3)
- #define BLUE_OF(c) (((c)&0x03)<<6)
+/**
+ * @brief Set the current default display to the specified display
+ * @note The default display is used for the gdispXxxx functions.
+ * @note The default display is contained in the variable GDISP. Using
+ * this function to set it protects against it being set to a NULL
+ * value.
+ * @note If a NULL is passed for the dispay this call is ignored.
+ *
+ * @param[in] display The display number (0..n)
+ *
+ * @api
+ */
+void gdispSetDisplay(GDisplay *g);
-#elif GDISP_PIXELFORMAT == GDISP_PIXELFORMAT_RGB666
- typedef uint32_t color_t;
- #define COLOR(c) ((color_t)(((c) & 0x03FFFF)))
- #define MASKCOLOR TRUE
- #define RGB2COLOR(r,g,b) ((color_t)((((r) & 0xFC)<<10) | (((g) & 0xFC)<<4) | (((b) & 0xFC)>>2)))
- #define HTML2COLOR(h) ((color_t)((((h) & 0xFC0000)>>6) | (((h) & 0x00FC00)>>4) | (((h) & 0x0000FC)>>2)))
- #define RED_OF(c) (((c) & 0x03F000)>>12)
- #define GREEN_OF(c) (((c)&0x00FC00)>>8)
- #define BLUE_OF(c) (((c)&0x00003F)<<2)
+/* Drawing Functions */
-#elif GDISP_PIXELFORMAT != GDISP_PIXELFORMAT_CUSTOM
- #error "GDISP: No supported pixel format has been specified."
-#endif
+/**
+ * @brief Flush current drawing operations to the display
+ * @note Some low level drivers do not update the display until
+ * the display is flushed. For others it is optional but can
+ * help prevent tearing effects. For some it is ignored.
+ * Calling it at the end of a logic set of drawing operations
+ * in your application will ensure controller portability. If you
+ * know your controller does not need to be flushed there is no
+ * need to call it (which is in reality most controllers).
+ * @note Even for displays that require flushing, there is no need to
+ * call this function if GDISP_NEED_AUTOFLUSH is TRUE.
+ * Calling it again won't hurt though.
+ *
+ *
+ * @param[in] display The display number (0..n)
+ *
+ * @api
+ */
+void gdispGFlush(GDisplay *g);
+#define gdispFlush() gdispGFlush(GDISP)
-/* Verify information for packed pixels and define a non-packed pixel macro */
-#if !GDISP_PACKED_PIXELS
- #define gdispPackPixels(buf,cx,x,y,c) { ((color_t *)(buf))[(y)*(cx)+(x)] = (c); }
-#elif !GDISP_HARDWARE_BITFILLS
- #error "GDISP: packed pixel formats are only supported for hardware accelerated drivers."
-#elif GDISP_PIXELFORMAT != GDISP_PIXELFORMAT_RGB888 \
- && GDISP_PIXELFORMAT != GDISP_PIXELFORMAT_RGB444 \
- && GDISP_PIXELFORMAT != GDISP_PIXELFORMAT_RGB666 \
- && GDISP_PIXELFORMAT != GDISP_PIXELFORMAT_CUSTOM
- #error "GDISP: A packed pixel format has been specified for an unsupported pixel format."
-#endif
+/**
+ * @brief Clear the display to the specified color.
+ *
+ * @param[in] g The display to use
+ * @param[in] color The color to use when clearing the screen
+ *
+ * @api
+ */
+void gdispGClear(GDisplay *g, color_t color);
+#define gdispClear(c) gdispGClear(GDISP, c)
-#if GDISP_NEED_SCROLL && !GDISP_HARDWARE_SCROLL
- #error "GDISP: Hardware scrolling is wanted but not supported."
-#endif
+/**
+ * @brief Set a pixel in the specified color.
+ *
+ * @param[in] g The display to use
+ * @param[in] x,y The position to set the pixel.
+ * @param[in] color The color to use
+ *
+ * @api
+ */
+void gdispGDrawPixel(GDisplay *g, coord_t x, coord_t y, color_t color);
+#define gdispDrawPixel(x,y,c) gdispGDrawPixel(GDISP,x,y,c)
-#if GDISP_NEED_PIXELREAD && !GDISP_HARDWARE_PIXELREAD
- #error "GDISP: Pixel read-back is wanted but not supported."
-#endif
+/**
+ * @brief Draw a line.
+ *
+ * @param[in] g The display to use
+ * @param[in] x0,y0 The start position
+ * @param[in] x1,y1 The end position
+ * @param[in] color The color to use
+ *
+ * @api
+ */
+void gdispGDrawLine(GDisplay *g, coord_t x0, coord_t y0, coord_t x1, coord_t y1, color_t color);
+#define gdispDrawLine(x0,y0,x1,y1,c) gdispGDrawLine(GDISP,x0,y0,x1,y1,c)
/**
- * @brief The type of a pixel.
+ * @brief Fill an area with a color.
+ *
+ * @param[in] g The display to use
+ * @param[in] x,y The start position
+ * @param[in] cx,cy The size of the box (outside dimensions)
+ * @param[in] color The color to use
+ *
+ * @api
*/
-typedef color_t pixel_t;
+void gdispGFillArea(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
+#define gdispFillArea(x,y,cx,cy,c) gdispGFillArea(GDISP,x,y,cx,cy,c)
-#ifdef __cplusplus
-extern "C" {
-#endif
+/**
+ * @brief Fill an area using the supplied bitmap.
+ * @details The bitmap is in the pixel format specified by the low level driver
+ * @note If a packed pixel format is used and the width doesn't
+ * match a whole number of bytes, the next line will start on a
+ * non-byte boundary (no end-of-line padding).
+ * @note If GDISP_NEED_ASYNC is defined then the buffer must be static
+ * or at least retained until this call has finished the blit. You can
+ * tell when all graphics drawing is finished by @p gdispIsBusy() going FALSE.
+ *
+ * @param[in] g The display to use
+ * @param[in] x,y The start position
+ * @param[in] cx,cy The size of the filled area
+ * @param[in] srcx,srcy The bitmap position to start the fill form
+ * @param[in] srccx The width of a line in the bitmap
+ * @param[in] buffer The bitmap in the driver's pixel format
+ *
+ * @api
+ */
+void gdispGBlitArea(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx, coord_t srcy, coord_t srccx, const pixel_t *buffer);
+#define gdispBlitAreaEx(x,y,cx,cy,sx,sy,rx,b) gdispGBlitArea(GDISP,x,y,cx,cy,sx,sy,rx,b)
-#if GDISP_NEED_MULTITHREAD || GDISP_NEED_ASYNC || defined(__DOXYGEN__)
- /* These routines can be hardware accelerated
- * - Do not add a routine here unless it has also been added to the hardware acceleration layer
+/**
+ * @brief Draw a rectangular box.
+ *
+ * @param[in] g The display to use
+ * @param[in] x,y The start position
+ * @param[in] cx,cy The size of the box (outside dimensions)
+ * @param[in] color The color to use
+ *
+ * @api
+ */
+void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
+#define gdispDrawBox(x,y,cx,cy,c) gdispGDrawBox(GDISP,x,y,cx,cy,c)
+
+/* Streaming Functions */
+
+#if GDISP_NEED_STREAMING || defined(__DOXYGEN__)
+ /**
+ * @brief Start a streaming operation.
+ * @details Stream data to a window on the display sequentially and very fast.
+ * @note While streaming is in operation - no other calls to GDISP functions
+ * can be made (with the exception of @p gdispBlendColor() and streaming
+ * functions). If a call is made (eg in a multi-threaded application) the other
+ * call is blocked waiting for the streaming operation to finish.
+ * @note @p gdispStreamStop() must be called to finish the streaming operation.
+ * @note If more data is written than the defined area then the results are unspecified.
+ * Some drivers may wrap back to the beginning of the area, others may just
+ * ignore subsequent data.
+ * @note Unlike most operations that clip the defined area to the display to generate
+ * a smaller active area, this call will just silently fail if any of the stream
+ * region lies outside the current clipping area.
+ * @note A streaming operation may be terminated early (without writing to every location
+ * in the stream area) by calling @p gdispStreamStop().
+ *
+ * @param[in] g The display to use
+ * @param[in] x,y The start position
+ * @param[in] cx,cy The size of the streamable area
+ *
+ * @api
*/
+ void gdispGStreamStart(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy);
+ #define gdispStreamStart(x,y,cx,cy) gdispGStreamStart(GDISP,x,y,cx,cy)
- /* Base Functions */
+ /**
+ * @brief Send pixel data to the stream.
+ * @details Write a pixel to the next position in the streamed area and increment the position
+ * @pre @p gdispStreamStart() has been called.
+ * @note If the gdispStreamStart() has not been called (or failed due to clipping), the
+ * data provided here is simply thrown away.
+ *
+ * @param[in] g The display to use
+ * @param[in] color The color of the pixel to write
+ *
+ * @api
+ */
+ void gdispGStreamColor(GDisplay *g, color_t color);
+ #define gdispStreamColor(c) gdispGStreamColor(GDISP,c)
/**
- * @brief Test if the GDISP engine is currently drawing.
- * @note This function will always return FALSE if
- * GDISP_NEED_ASYNC is not defined.
+ * @brief Finish the current streaming operation.
+ * @details Completes the current streaming operation and allows other GDISP calls to operate again.
+ * @pre @p gdispStreamStart() has been called.
+ * @note If the gdispStreamStart() has not been called (or failed due to clipping), this
+ * call is simply ignored.
*
- * @return TRUE if gdisp is busy, FALSE otherwise
+ * @param[in] g The display to use
*
* @api
*/
- bool_t gdispIsBusy(void);
+ void gdispGStreamStop(GDisplay *g);
+ #define gdispStreamStop() gdispGStreamStop(GDISP)
+#endif
- /* Drawing Functions */
+/* Clipping Functions */
+#if GDISP_NEED_CLIP || defined(__DOXYGEN__)
/**
- * @brief Clear the display to the specified color.
+ * @brief Clip all drawing to the defined area.
*
- * @param[in] color The color to use when clearing the screen
+ * @param[in] g The display to use
+ * @param[in] x,y The start position
+ * @param[in] cx,cy The size of the clip area
*
* @api
*/
- void gdispClear(color_t color);
+ void gdispGSetClip(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy);
+ #define gdispSetClip(x,y,cx,cy) gdispGSetClip(GDISP,x,y,cx,cy)
+#endif
+
+/* Circle Functions */
+#if GDISP_NEED_CIRCLE || defined(__DOXYGEN__)
/**
- * @brief Set a pixel in the specified color.
+ * @brief Draw a circle.
*
- * @param[in] x,y The position to set the pixel.
- * @param[in] color The color to use
+ * @param[in] g The display to use
+ * @param[in] x,y The center of the circle
+ * @param[in] radius The radius of the circle
+ * @param[in] color The color to use
*
* @api
*/
- void gdispDrawPixel(coord_t x, coord_t y, color_t color);
+ void gdispGDrawCircle(GDisplay *g, coord_t x, coord_t y, coord_t radius, color_t color);
+ #define gdispDrawCircle(x,y,r,c) gdispGDrawCircle(GDISP,x,y,r,c)
/**
- * @brief Draw a line.
+ * @brief Draw a filled circle.
*
- * @param[in] x0,y0 The start position
- * @param[in] x1,y1 The end position
+ * @param[in] g The display to use
+ * @param[in] x,y The center of the circle
+ * @param[in] radius The radius of the circle
* @param[in] color The color to use
*
* @api
*/
- void gdispDrawLine(coord_t x0, coord_t y0, coord_t x1, coord_t y1, color_t color);
+ void gdispGFillCircle(GDisplay *g, coord_t x, coord_t y, coord_t radius, color_t color);
+ #define gdispFillCircle(x,y,r,c) gdispGFillCircle(GDISP,x,y,r,c)
+#endif
+/* Ellipse Functions */
+
+#if GDISP_NEED_ELLIPSE || defined(__DOXYGEN__)
/**
- * @brief Fill an area with a color.
+ * @brief Draw an ellipse.
*
- * @param[in] x,y The start position
- * @param[in] cx,cy The size of the box (outside dimensions)
+ * @param[in] g The display to use
+ * @param[in] x,y The center of the ellipse
+ * @param[in] a,b The dimensions of the ellipse
* @param[in] color The color to use
*
* @api
*/
- void gdispFillArea(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
+ void gdispGDrawEllipse(GDisplay *g, coord_t x, coord_t y, coord_t a, coord_t b, color_t color);
+ #define gdispDrawEllipse(x,y,a,b,c) gdispGDrawEllipse(GDISP,x,y,a,b,c)
/**
- * @brief Fill an area using the supplied bitmap.
- * @details The bitmap is in the pixel format specified by the low level driver
- * @note If a packed pixel format is used and the width doesn't
- * match a whole number of bytes, the next line will start on a
- * non-byte boundary (no end-of-line padding).
- * @note If GDISP_NEED_ASYNC is defined then the buffer must be static
- * or at least retained until this call has finished the blit. You can
- * tell when all graphics drawing is finished by @p gdispIsBusy() going FALSE.
+ * @brief Draw a filled ellipse.
*
- * @param[in] x,y The start position
- * @param[in] cx,cy The size of the filled area
- * @param[in] srcx,srcy The bitmap position to start the fill form
- * @param[in] srccx The width of a line in the bitmap
- * @param[in] buffer The bitmap in the driver's pixel format
+ * @param[in] g The display to use
+ * @param[in] x,y The center of the ellipse
+ * @param[in] a,b The dimensions of the ellipse
+ * @param[in] color The color to use
*
* @api
*/
- void gdispBlitAreaEx(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx, coord_t srcy, coord_t srccx, const pixel_t *buffer);
-
- /* Clipping Functions */
+ void gdispGFillEllipse(GDisplay *g, coord_t x, coord_t y, coord_t a, coord_t b, color_t color);
+ #define gdispFillEllipse(x,y,a,b,c) gdispGFillEllipse(GDISP,x,y,a,b,c)
+#endif
- #if GDISP_NEED_CLIP || defined(__DOXYGEN__)
- /**
- * @brief Clip all drawing to the defined area.
- *
- * @param[in] x,y The start position
- * @param[in] cx,cy The size of the clip area
- *
- * @api
- */
- void gdispSetClip(coord_t x, coord_t y, coord_t cx, coord_t cy);
- #endif
+/* Arc Functions */
- /* Circle Functions */
-
- #if GDISP_NEED_CIRCLE || defined(__DOXYGEN__)
- /**
- * @brief Draw a circle.
- *
- * @param[in] x,y The center of the circle
- * @param[in] radius The radius of the circle
- * @param[in] color The color to use
- *
- * @api
- */
- void gdispDrawCircle(coord_t x, coord_t y, coord_t radius, color_t color);
-
- /**
- * @brief Draw a filled circle.
- *
- * @param[in] x,y The center of the circle
- * @param[in] radius The radius of the circle
- * @param[in] color The color to use
- *
- * @api
- */
- void gdispFillCircle(coord_t x, coord_t y, coord_t radius, color_t color);
- #endif
-
- /* Ellipse Functions */
-
- #if GDISP_NEED_ELLIPSE || defined(__DOXYGEN__)
- /**
- * @brief Draw an ellipse.
- *
- * @param[in] x,y The center of the ellipse
- * @param[in] a,b The dimensions of the ellipse
- * @param[in] color The color to use
- *
- * @api
- */
- void gdispDrawEllipse(coord_t x, coord_t y, coord_t a, coord_t b, color_t color);
-
- /**
- * @brief Draw a filled ellipse.
- *
- * @param[in] x,y The center of the ellipse
- * @param[in] a,b The dimensions of the ellipse
- * @param[in] color The color to use
- *
- * @api
- */
- void gdispFillEllipse(coord_t x, coord_t y, coord_t a, coord_t b, color_t color);
- #endif
+#if GDISP_NEED_ARC || defined(__DOXYGEN__)
+ /*
+ * @brief Draw an arc.
+ *
+ * @param[in] g The display to use
+ * @param[in] x0,y0 The center point
+ * @param[in] radius The radius of the arc
+ * @param[in] start The start angle (0 to 360)
+ * @param[in] end The end angle (0 to 360)
+ * @param[in] color The color of the arc
+ *
+ * @api
+ */
+ void gdispGDrawArc(GDisplay *g, coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle, color_t color);
+ #define gdispDrawArc(x,y,r,s,e,c) gdispGDrawArc(GDISP,x,y,r,s,e,c)
- /* Arc Functions */
-
- #if GDISP_NEED_ARC || defined(__DOXYGEN__)
- /*
- * @brief Draw an arc.
- *
- * @param[in] x0,y0 The center point
- * @param[in] radius The radius of the arc
- * @param[in] start The start angle (0 to 360)
- * @param[in] end The end angle (0 to 360)
- * @param[in] color The color of the arc
- *
- * @api
- */
- void gdispDrawArc(coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle, color_t color);
-
- /*
- * @brief Draw a filled arc.
- * @note Not very efficient currently - does lots of overdrawing
- *
- * @param[in] x0,y0 The center point
- * @param[in] radius The radius of the arc
- * @param[in] start The start angle (0 to 360)
- * @param[in] end The end angle (0 to 360)
- * @param[in] color The color of the arc
- *
- * @api
- */
- void gdispFillArc(coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle, color_t color);
- #endif
+ /*
+ * @brief Draw a filled arc.
+ * @note Not very efficient currently - does lots of overdrawing
+ *
+ * @param[in] g The display to use
+ * @param[in] x0,y0 The center point
+ * @param[in] radius The radius of the arc
+ * @param[in] start The start angle (0 to 360)
+ * @param[in] end The end angle (0 to 360)
+ * @param[in] color The color of the arc
+ *
+ * @api
+ */
+ void gdispGFillArc(GDisplay *g, coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle, color_t color);
+ #define gdispFillArc(x,y,r,s,e,c) gdispGFillArc(GDISP,x,y,r,s,e,c)
+#endif
- /* Read a pixel Function */
-
- #if GDISP_NEED_PIXELREAD || defined(__DOXYGEN__)
- /**
- * @brief Get the color of a pixel.
- * @return The color of the pixel.
- *
- * @param[in] x,y The position of the pixel
- *
- * @api
- */
- color_t gdispGetPixelColor(coord_t x, coord_t y);
- #endif
+/* Read a pixel Function */
- /* Scrolling Function - clears the area scrolled out */
-
- #if GDISP_NEED_SCROLL || defined(__DOXYGEN__)
- /**
- * @brief Scroll vertically a section of the screen.
- * @pre GDISP_NEED_SCROLL must be set to TRUE in gfxconf.h
- * @note Optional.
- * @note If lines is >= cy, it is equivelent to a area fill with bgcolor.
- *
- * @param[in] x, y The start of the area to be scrolled
- * @param[in] cx, cy The size of the area to be scrolled
- * @param[in] lines The number of lines to scroll (Can be positive or negative)
- * @param[in] bgcolor The color to fill the newly exposed area.
- *
- * @api
- */
- void gdispVerticalScroll(coord_t x, coord_t y, coord_t cx, coord_t cy, int lines, color_t bgcolor);
- #endif
+#if GDISP_NEED_PIXELREAD || defined(__DOXYGEN__)
+ /**
+ * @brief Get the color of a pixel.
+ * @return The color of the pixel.
+ *
+ * @param[in] g The display to use
+ * @param[in] x,y The position of the pixel
+ *
+ * @api
+ */
+ color_t gdispGGetPixelColor(GDisplay *g, coord_t x, coord_t y);
+ #define gdispGetPixelColor(x,y) gdispGGetPixelColor(GDISP,x,y)
+#endif
- /* Set driver specific control */
-
- #if GDISP_NEED_CONTROL || defined(__DOXYGEN__)
- /**
- * @brief Control hardware specific parts of the display. eg powermodes, backlight etc
- * @note Depending on the hardware implementation this function may not
- * support some codes. They will be ignored.
- *
- * @param[in] what what you want to control
- * @param[in] value The value to be assigned
- *
- * @api
- */
- void gdispControl(unsigned what, void *value);
- #endif
+/* Scrolling Function - clears the area scrolled out */
- /* Query driver specific data */
-
- #if GDISP_NEED_QUERY || defined(__DOXYGEN__)
- /**
- * @brief Query a property of the display.
- * @note The result must be typecast to the correct type.
- * @note An unsupported query will return (void *)-1.
- *
- * @param[in] what What to query
- *
- * @api
- */
- void *gdispQuery(unsigned what);
- #endif
+#if GDISP_NEED_SCROLL || defined(__DOXYGEN__)
+ /**
+ * @brief Scroll vertically a section of the screen.
+ * @pre GDISP_NEED_SCROLL must be set to TRUE in gfxconf.h
+ * @note Optional.
+ * @note If lines is >= cy, it is equivelent to a area fill with bgcolor.
+ *
+ * @param[in] g The display to use
+ * @param[in] x, y The start of the area to be scrolled
+ * @param[in] cx, cy The size of the area to be scrolled
+ * @param[in] lines The number of lines to scroll (Can be positive or negative)
+ * @param[in] bgcolor The color to fill the newly exposed area.
+ *
+ * @api
+ */
+ void gdispGVerticalScroll(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, int lines, color_t bgcolor);
+ #define gdispVerticalScroll(x,y,cx,cy,l,b) gdispGVerticalScroll(GDISP,x,y,cx,cy,l,b)
+#endif
-#else
- /* Include the low level driver information */
- #include "gdisp/lld/gdisp_lld.h"
-
- /* The same as above but use the low level driver directly if no multi-thread support is needed */
- #define gdispIsBusy() FALSE
- #define gdispClear(color) gdisp_lld_clear(color)
- #define gdispDrawPixel(x, y, color) gdisp_lld_draw_pixel(x, y, color)
- #define gdispDrawLine(x0, y0, x1, y1, color) gdisp_lld_draw_line(x0, y0, x1, y1, color)
- #define gdispFillArea(x, y, cx, cy, color) gdisp_lld_fill_area(x, y, cx, cy, color)
- #define gdispBlitAreaEx(x, y, cx, cy, sx, sy, scx, buf) gdisp_lld_blit_area_ex(x, y, cx, cy, sx, sy, scx, buf)
- #define gdispSetClip(x, y, cx, cy) gdisp_lld_set_clip(x, y, cx, cy)
- #define gdispDrawCircle(x, y, radius, color) gdisp_lld_draw_circle(x, y, radius, color)
- #define gdispFillCircle(x, y, radius, color) gdisp_lld_fill_circle(x, y, radius, color)
- #define gdispDrawArc(x, y, radius, sangle, eangle, color) gdisp_lld_draw_arc(x, y, radius, sangle, eangle, color)
- #define gdispFillArc(x, y, radius, sangle, eangle, color) gdisp_lld_fill_arc(x, y, radius, sangle, eangle, color)
- #define gdispDrawEllipse(x, y, a, b, color) gdisp_lld_draw_ellipse(x, y, a, b, color)
- #define gdispFillEllipse(x, y, a, b, color) gdisp_lld_fill_ellipse(x, y, a, b, color)
- #define gdispGetPixelColor(x, y) gdisp_lld_get_pixel_color(x, y)
- #define gdispVerticalScroll(x, y, cx, cy, lines, bgcolor) gdisp_lld_vertical_scroll(x, y, cx, cy, lines, bgcolor)
- #define gdispControl(what, value) gdisp_lld_control(what, value)
- #define gdispQuery(what) gdisp_lld_query(what)
+/* Set driver specific control */
+#if GDISP_NEED_CONTROL || defined(__DOXYGEN__)
+ /**
+ * @brief Control hardware specific parts of the display. eg powermodes, backlight etc
+ * @note Depending on the hardware implementation this function may not
+ * support some codes. They will be ignored.
+ *
+ * @param[in] g The display to use
+ * @param[in] what what you want to control
+ * @param[in] value The value to be assigned
+ *
+ * @api
+ */
+ void gdispGControl(GDisplay *g, unsigned what, void *value);
+ #define gdispControl(w,v) gdispGControl(GDISP,w,v)
#endif
-/* These routines are not hardware accelerated
- * - Do not add a hardware accelerated routines here.
- */
+/* Query driver specific data */
-/* Extra drawing functions */
-
-/**
- * @brief Draw a rectangular box.
- *
- * @param[in] x,y The start position
- * @param[in] cx,cy The size of the box (outside dimensions)
- * @param[in] color The color to use
- *
- * @api
- */
-void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
+#if GDISP_NEED_QUERY || defined(__DOXYGEN__)
+ /**
+ * @brief Query a property of the display.
+ * @note The result must be typecast to the correct type.
+ * @note An unsupported query will return (void *)-1.
+ *
+ * @param[in] g The display to use
+ * @param[in] what What to query
+ *
+ * @api
+ */
+ void *gdispGQuery(GDisplay *g, unsigned what);
+ #define gdispQuery(w) gdispGQuery(GDISP,w)
+#endif
#if GDISP_NEED_CONVEX_POLYGON || defined(__DOXYGEN__)
/**
* @brief Draw an enclosed polygon (convex, non-convex or complex).
*
+ * @param[in] g The display to use
* @param[in] tx, ty Transform all points in pntarray by tx, ty
* @param[in] pntarray An array of points
* @param[in] cnt The number of points in the array
@@ -591,12 +599,14 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
*
* @api
*/
- void gdispDrawPoly(coord_t tx, coord_t ty, const point *pntarray, unsigned cnt, color_t color);
+ void gdispGDrawPoly(GDisplay *g, coord_t tx, coord_t ty, const point *pntarray, unsigned cnt, color_t color);
+ #define gdispDrawPoly(x,y,p,i,c) gdispGDrawPoly(GDISP,x,y,p,i,c)
/**
* @brief Fill a convex polygon
* @details Doesn't handle non-convex or complex polygons.
*
+ * @param[in] g The display to use
* @param[in] tx, ty Transform all points in pntarray by tx, ty
* @param[in] pntarray An array of points
* @param[in] cnt The number of points in the array
@@ -612,7 +622,8 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
*
* @api
*/
- void gdispFillConvexPoly(coord_t tx, coord_t ty, const point *pntarray, unsigned cnt, color_t color);
+ void gdispGFillConvexPoly(GDisplay *g, coord_t tx, coord_t ty, const point *pntarray, unsigned cnt, color_t color);
+ #define gdispFillConvexPoly(x,y,p,i,c) gdispGFillConvexPoly(GDISP,x,y,p,i,c)
#endif
/* Text Functions */
@@ -621,6 +632,7 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
/**
* @brief Draw a text character.
*
+ * @param[in] g The display to use
* @param[in] x,y The position for the text
* @param[in] c The character to draw
* @param[in] font The font to use
@@ -628,11 +640,13 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
*
* @api
*/
- void gdispDrawChar(coord_t x, coord_t y, uint16_t c, font_t font, color_t color);
+ void gdispGDrawChar(GDisplay *g, coord_t x, coord_t y, uint16_t c, font_t font, color_t color);
+ #define gdispDrawChar(x,y,s,f,c) gdispGDrawChar(GDISP,x,y,s,f,c)
/**
* @brief Draw a text character with a filled background.
*
+ * @param[in] g The display to use
* @param[in] x,y The position for the text
* @param[in] c The character to draw
* @param[in] font The font to use
@@ -641,11 +655,13 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
*
* @api
*/
- void gdispFillChar(coord_t x, coord_t y, uint16_t c, font_t font, color_t color, color_t bgcolor);
+ void gdispGFillChar(GDisplay *g, coord_t x, coord_t y, uint16_t c, font_t font, color_t color, color_t bgcolor);
+ #define gdispFillChar(x,y,s,f,c,b) gdispGFillChar(GDISP,x,y,s,f,c,b)
/**
* @brief Draw a text string.
*
+ * @param[in] g The display to use
* @param[in] x,y The position for the text
* @param[in] font The font to use
* @param[in] str The string to draw
@@ -653,11 +669,13 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
*
* @api
*/
- void gdispDrawString(coord_t x, coord_t y, const char *str, font_t font, color_t color);
+ void gdispGDrawString(GDisplay *g, coord_t x, coord_t y, const char *str, font_t font, color_t color);
+ #define gdispDrawString(x,y,s,f,c) gdispGDrawString(GDISP,x,y,s,f,c)
/**
* @brief Draw a text string.
*
+ * @param[in] g The display to use
* @param[in] x,y The position for the text
* @param[in] str The string to draw
* @param[in] font The font to use
@@ -666,11 +684,13 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
*
* @api
*/
- void gdispFillString(coord_t x, coord_t y, const char *str, font_t font, color_t color, color_t bgcolor);
+ void gdispGFillString(GDisplay *g, coord_t x, coord_t y, const char *str, font_t font, color_t color, color_t bgcolor);
+ #define gdispFillString(x,y,s,f,c,b) gdispGFillString(GDISP,x,y,s,f,c,b)
/**
* @brief Draw a text string vertically centered within the specified box.
*
+ * @param[in] g The display to use
* @param[in] x,y The position for the text (need to define top-right or base-line - check code)
* @param[in] cx,cy The width and height of the box
* @param[in] str The string to draw
@@ -680,12 +700,14 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
*
* @api
*/
- void gdispDrawStringBox(coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, font_t font, color_t color, justify_t justify);
+ void gdispGDrawStringBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, font_t font, color_t color, justify_t justify);
+ #define gdispDrawStringBox(x,y,cx,cy,s,f,c,j) gdispGDrawStringBox(GDISP,x,y,cx,cy,s,f,c,j)
/**
* @brief Draw a text string vertically centered within the specified box. The box background is filled with the specified background color.
* @note The entire box is filled
*
+ * @param[in] g The display to use
* @param[in] x,y The position for the text (need to define top-right or base-line - check code)
* @param[in] cx,cy The width and height of the box
* @param[in] str The string to draw
@@ -696,7 +718,8 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
*
* @api
*/
- void gdispFillStringBox(coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, font_t font, color_t color, color_t bgColor, justify_t justify);
+ void gdispGFillStringBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, font_t font, color_t color, color_t bgColor, justify_t justify);
+ #define gdispFillStringBox(x,y,cx,cy,s,f,c,b,j) gdispGFillStringBox(GDISP,x,y,cx,cy,s,f,c,b,j)
/**
* @brief Get a metric of a font.
@@ -781,6 +804,7 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
/**
* @brief Draw a rectangular box with rounded corners
*
+ * @param[in] g The display to use
* @param[in] x,y The start position
* @param[in] cx,cy The size of the box (outside dimensions)
* @param[in] radius The radius of the rounded corners
@@ -788,11 +812,13 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
*
* @api
*/
- void gdispDrawRoundedBox(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t radius, color_t color);
+ void gdispGDrawRoundedBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t radius, color_t color);
+ #define gdispDrawRoundedBox(x,y,cx,cy,r,c) gdispGDrawRoundedBox(GDISP,x,y,cx,cy,r,c)
/**
* @brief Draw a filled rectangular box with rounded corners
*
+ * @param[in] g The display to use
* @param[in] x,y The start position
* @param[in] cx,cy The size of the box (outside dimensions)
* @param[in] radius The radius of the rounded corners
@@ -800,37 +826,8 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
*
* @api
*/
- void gdispFillRoundedBox(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t radius, color_t color);
-#endif
-
-
-/**
- * @brief Blend 2 colors according to the alpha
- * @return The combined color
- *
- * @param[in] fg The foreground color
- * @param[in] bg The background color
- * @param[in] alpha The alpha value (0-255). 0 is all background, 255 is all foreground.
- *
- * @api
- */
-color_t gdispBlendColor(color_t fg, color_t bg, uint8_t alpha);
-
-/* Support routine for packed pixel formats */
-#if !defined(gdispPackPixels) || defined(__DOXYGEN__)
- /**
- * @brief Pack a pixel into a pixel buffer.
- * @note This function performs no buffer boundary checking
- * regardless of whether GDISP_NEED_CLIP has been specified.
- *
- * @param[in] buf The buffer to put the pixel in
- * @param[in] cx The width of a pixel line
- * @param[in] x, y The location of the pixel to place
- * @param[in] color The color to put into the buffer
- *
- * @api
- */
- void gdispPackPixels(const pixel_t *buf, coord_t cx, coord_t x, coord_t y, color_t color);
+ void gdispGFillRoundedBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t radius, color_t color);
+ #define gdispFillRoundedBox(x,y,cx,cy,r,c) gdispGFillRoundedBox(GDISP,x,y,cx,cy,r,c)
#endif
/*
@@ -838,7 +835,7 @@ color_t gdispBlendColor(color_t fg, color_t bg, uint8_t alpha);
*/
/* Now obsolete functions */
-#define gdispBlitArea(x, y, cx, cy, buffer) gdispBlitAreaEx(x, y, cx, cy, 0, 0, cx, buffer)
+#define gdispBlitArea(x, y, cx, cy, buffer) gdispGBlitArea(GDISP, x, y, cx, cy, 0, 0, cx, buffer)
/* Macro definitions for common gets and sets */
@@ -846,26 +843,31 @@ color_t gdispBlendColor(color_t fg, color_t bg, uint8_t alpha);
* @brief Set the display power mode.
* @note Ignored if not supported by the display.
*
+ * @param[in] g The display to use
* @param[in] powerMode The new power mode
*
* @api
*/
-#define gdispSetPowerMode(powerMode) gdispControl(GDISP_CONTROL_POWER, (void *)(unsigned)(powerMode))
+#define gdispGSetPowerMode(g, powerMode) gdispGControl((g), GDISP_CONTROL_POWER, (void *)(unsigned)(powerMode))
+#define gdispSetPowerMode(powerMode) gdispGControl(GDISP, GDISP_CONTROL_POWER, (void *)(unsigned)(powerMode))
/**
* @brief Set the display orientation.
* @note Ignored if not supported by the display.
*
+ * @param[in] g The display to use
* @param[in] newOrientation The new orientation
*
* @api
*/
-#define gdispSetOrientation(newOrientation) gdispControl(GDISP_CONTROL_ORIENTATION, (void *)(unsigned)(newOrientation))
+#define gdispGSetOrientation(g, newOrientation) gdispGControl((g), GDISP_CONTROL_ORIENTATION, (void *)(unsigned)(newOrientation))
+#define gdispSetOrientation(newOrientation) gdispGControl(GDISP, GDISP_CONTROL_ORIENTATION, (void *)(unsigned)(newOrientation))
/**
* @brief Set the display backlight.
* @note Ignored if not supported by the display.
*
+ * @param[in] g The display to use
* @param[in] percent The new brightness (0 - 100%)
*
* @note For displays that only support backlight off and on,
@@ -873,69 +875,92 @@ color_t gdispBlendColor(color_t fg, color_t bg, uint8_t alpha);
*
* @api
*/
-#define gdispSetBacklight(percent) gdispControl(GDISP_CONTROL_BACKLIGHT, (void *)(unsigned)(percent))
+#define gdispGSetBacklight(g, percent) gdispGControl((g), GDISP_CONTROL_BACKLIGHT, (void *)(unsigned)(percent))
+#define gdispSetBacklight(percent) gdispGControl(GDISP, GDISP_CONTROL_BACKLIGHT, (void *)(unsigned)(percent))
/**
* @brief Set the display contrast.
* @note Ignored if not supported by the display.
*
+ * @param[in] g The display to use
* @param[in] percent The new contrast (0 - 100%)
*
* @api
*/
-#define gdispSetContrast(percent) gdispControl(GDISP_CONTROL_CONTRAST, (void *)(unsigned)(percent))
+#define gdispGSetContrast(g, percent) gdispGControl((g), GDISP_CONTROL_CONTRAST, (void *)(unsigned)(percent))
+#define gdispSetContrast(percent) gdispGControl(GDISP, GDISP_CONTROL_CONTRAST, (void *)(unsigned)(percent))
/**
* @brief Get the display width in pixels.
*
+ * @param[in] g The display to use
+ *
* @api
*/
-#define gdispGetWidth() (GDISP.Width)
+#define gdispGGetWidth(g) (((GDISPControl *)(g))->Width)
+#define gdispGetWidth() gdispGGetWidth(GDISP)
/**
* @brief Get the display height in pixels.
*
+ * @param[in] g The display to use
+ *
* @api
*/
-#define gdispGetHeight() (GDISP.Height)
+#define gdispGGetHeight(g) (((GDISPControl *)(g))->Height)
+#define gdispGetHeight() gdispGGetHeight(GDISP)
/**
* @brief Get the current display power mode.
*
+ * @param[in] g The display to use
+ *
* @api
*/
-#define gdispGetPowerMode() (GDISP.Powermode)
+#define gdispGGetPowerMode(g) (((GDISPControl *)(g))->Powermode)
+#define gdispGetPowerMode() gdispGGetPowerMode(GDISP)
/**
* @brief Get the current display orientation.
*
+ * @param[in] g The display to use
+ *
* @api
*/
-#define gdispGetOrientation() (GDISP.Orientation)
+#define gdispGGetOrientation(g) (((GDISPControl *)(g))->Orientation)
+#define gdispGetOrientation() gdispGGetOrientation(GDISP)
/**
* @brief Get the current display backlight brightness.
*
+ * @param[in] g The display to use
+ *
* @api
*/
-#define gdispGetBacklight() (GDISP.Backlight)
+#define gdispGGetBacklight(g) (((GDISPControl *)(g))->Backlight)
+#define gdispGetBacklight() gdispGGetBacklight(GDISP)
/**
* @brief Get the current display contrast.
*
+ * @param[in] g The display to use
+ *
* @api
*/
-#define gdispGetContrast() (GDISP.Contrast)
+#define gdispGGetContrast(g) (((GDISPControl *)(g))->Contrast)
+#define gdispGetContrast() gdispGGetContrast(GDISP)
/* More interesting macro's */
/**
* @brief Reset the clip area to the full screen
*
+ * @param[in] g The display to use
+ *
* @api
*/
-#define gdispUnsetClip() gdispSetClip(0,0,gdispGetWidth(),gdispGetHeight())
-
+#define gdispGUnsetClip(g) gdispGSetClip((g),0,0,gdispGGetWidth(g),gdispGGetHeight(g))
+#define gdispUnsetClip() gdispGUnsetClip(GDISP)
#ifdef __cplusplus
}
diff --git a/include/gdisp/image.h b/include/gdisp/image.h
index 8619cb9c..ff2e9d85 100644
--- a/include/gdisp/image.h
+++ b/include/gdisp/image.h
@@ -243,6 +243,7 @@ extern "C" {
* @brief Draw the image
* @return GDISP_IMAGE_ERR_OK (0) on success or an error code.
*
+ * @param[in] g The display to draw on
* @param[in] img The image structure
* @param[in] x,y The screen location to draw the image
* @param[in] cx,cy The area on the screen to draw
@@ -257,7 +258,8 @@ extern "C" {
* is drawing. This may be significantly slower than if the image has been cached (but
* uses a lot less RAM)
*/
- gdispImageError gdispImageDraw(gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy);
+ gdispImageError gdispGImageDraw(GDisplay *g, gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy);
+ #define gdispImageDraw(img,x,y,cx,cy,sx,sy) gdispGImageDraw(GDISP,img,x,y,cx,cy,sx,sy)
/**
* @brief Prepare for the next frame/page in the image file.
@@ -299,7 +301,7 @@ extern "C" {
gdispImageError gdispImageOpen_NATIVE(gdispImage *img);
void gdispImageClose_NATIVE(gdispImage *img);
gdispImageError gdispImageCache_NATIVE(gdispImage *img);
- gdispImageError gdispImageDraw_NATIVE(gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy);
+ gdispImageError gdispGImageDraw_NATIVE(GDisplay *g, gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy);
delaytime_t gdispImageNext_NATIVE(gdispImage *img);
/* @} */
#endif
@@ -315,7 +317,7 @@ extern "C" {
gdispImageError gdispImageOpen_GIF(gdispImage *img);
void gdispImageClose_GIF(gdispImage *img);
gdispImageError gdispImageCache_GIF(gdispImage *img);
- gdispImageError gdispImageDraw_GIF(gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy);
+ gdispImageError gdispGImageDraw_GIF(GDisplay *g, gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy);
delaytime_t gdispImageNext_GIF(gdispImage *img);
/* @} */
#endif
@@ -331,7 +333,7 @@ extern "C" {
gdispImageError gdispImageOpen_BMP(gdispImage *img);
void gdispImageClose_BMP(gdispImage *img);
gdispImageError gdispImageCache_BMP(gdispImage *img);
- gdispImageError gdispImageDraw_BMP(gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy);
+ gdispImageError gdispGImageDraw_BMP(GDisplay *g, gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy);
delaytime_t gdispImageNext_BMP(gdispImage *img);
/* @} */
#endif
@@ -347,7 +349,7 @@ extern "C" {
gdispImageError gdispImageOpen_JPG(gdispImage *img);
void gdispImageClose_JPG(gdispImage *img);
gdispImageError gdispImageCache_JPG(gdispImage *img);
- gdispImageError gdispImageDraw_JPG(gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy);
+ gdispImageError gdispGImageDraw_JPG(GDisplay *g, gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy);
delaytime_t gdispImageNext_JPG(gdispImage *img);
/* @} */
#endif
@@ -363,7 +365,7 @@ extern "C" {
gdispImageError gdispImageOpen_PNG(gdispImage *img);
void gdispImageClose_PNG(gdispImage *img);
gdispImageError gdispImageCache_PNG(gdispImage *img);
- gdispImageError gdispImageDraw_PNG(gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy);
+ gdispImageError gdispGImageDraw_PNG(GDisplay *g, gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy);
delaytime_t gdispImageNext_PNG(gdispImage *img);
/* @} */
#endif
diff --git a/include/gdisp/lld/emulation.c b/include/gdisp/lld/emulation.c
deleted file mode 100644
index cb0c9c4b..00000000
--- a/include/gdisp/lld/emulation.c
+++ /dev/null
@@ -1,558 +0,0 @@
-/*
- * This file is subject to the terms of the GFX License. If a copy of
- * the license was not distributed with this file, you can obtain one at:
- *
- * http://ugfx.org/license.html
- */
-
-/**
- * @file include/gdisp/lld/emulation.c
- * @brief GDISP emulation routines for stuff the driver dosen't support
- *
- * @addtogroup GDISP
- *
- * @details Even though this is a software emulation of a low level driver
- * most validation doesn't need to happen here as eventually
- * we call a real low level driver routine and if validation is
- * required - it will do it.
- *
- * @{
- */
-#ifndef GDISP_EMULATION_C
-#define GDISP_EMULATION_C
-
-#if GFX_USE_GDISP
-
-/* Include the low level driver information */
-#include "gdisp/lld/gdisp_lld.h"
-
-/* Declare the GDISP structure */
-GDISPDriver GDISP;
-
-#if !GDISP_HARDWARE_CLEARS
- void gdisp_lld_clear(color_t color) {
- gdisp_lld_fill_area(0, 0, GDISP.Width, GDISP.Height, color);
- }
-#endif
-
-#if !GDISP_HARDWARE_LINES
- void gdisp_lld_draw_line(coord_t x0, coord_t y0, coord_t x1, coord_t y1, color_t color) {
- int16_t dy, dx;
- int16_t addx, addy;
- int16_t P, diff, i;
-
- #if GDISP_HARDWARE_FILLS || GDISP_HARDWARE_SCROLL
- // speed improvement if vertical or horizontal
- if (x0 == x1) {
- if (y1 > y0)
- gdisp_lld_fill_area(x0, y0, 1, y1-y0+1, color);
- else
- gdisp_lld_fill_area(x0, y1, 1, y0-y1+1, color);
- return;
- }
- if (y0 == y1) {
- if (x1 > x0)
- gdisp_lld_fill_area(x0, y0, x1-x0+1, 1, color);
- else
- gdisp_lld_fill_area(x1, y0, x0-x1+1, 1, color);
- return;
- }
- #endif
-
- if (x1 >= x0) {
- dx = x1 - x0;
- addx = 1;
- } else {
- dx = x0 - x1;
- addx = -1;
- }
- if (y1 >= y0) {
- dy = y1 - y0;
- addy = 1;
- } else {
- dy = y0 - y1;
- addy = -1;
- }
-
- if (dx >= dy) {
- dy *= 2;
- P = dy - dx;
- diff = P - dx;
-
- for(i=0; i<=dx; ++i) {
- gdisp_lld_draw_pixel(x0, y0, color);
- if (P < 0) {
- P += dy;
- x0 += addx;
- } else {
- P += diff;
- x0 += addx;
- y0 += addy;
- }
- }
- } else {
- dx *= 2;
- P = dx - dy;
- diff = P - dy;
-
- for(i=0; i<=dy; ++i) {
- gdisp_lld_draw_pixel(x0, y0, color);
- if (P < 0) {
- P += dx;
- y0 += addy;
- } else {
- P += diff;
- x0 += addx;
- y0 += addy;
- }
- }
- }
- }
-#endif
-
-#if !GDISP_HARDWARE_FILLS
- void gdisp_lld_fill_area(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
- #if GDISP_HARDWARE_SCROLL
- gdisp_lld_vertical_scroll(x, y, cx, cy, cy, color);
- #elif GDISP_HARDWARE_LINES
- coord_t x1, y1;
-
- x1 = x + cx - 1;
- y1 = y + cy;
- for(; y < y1; y++)
- gdisp_lld_draw_line(x, y, x1, y, color);
- #else
- coord_t x0, x1, y1;
-
- x0 = x;
- x1 = x + cx;
- y1 = y + cy;
- for(; y < y1; y++)
- for(x = x0; x < x1; x++)
- gdisp_lld_draw_pixel(x, y, color);
- #endif
- }
-#endif
-
-#if !GDISP_HARDWARE_BITFILLS
- void gdisp_lld_blit_area_ex(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx, coord_t srcy, coord_t srccx, const pixel_t *buffer) {
- coord_t x0, x1, y1;
-
- x0 = x;
- x1 = x + cx;
- y1 = y + cy;
- buffer += srcy*srccx+srcx;
- srccx -= cx;
- for(; y < y1; y++, buffer += srccx)
- for(x=x0; x < x1; x++)
- gdisp_lld_draw_pixel(x, y, *buffer++);
- }
-#endif
-
-#if GDISP_NEED_CLIP && !GDISP_HARDWARE_CLIP
- void gdisp_lld_set_clip(coord_t x, coord_t y, coord_t cx, coord_t cy) {
- #if GDISP_NEED_VALIDATION
- if (x >= GDISP.Width || y >= GDISP.Height || cx < 0 || cy < 0)
- return;
- if (x < 0) x = 0;
- if (y < 0) y = 0;
- if (x+cx > GDISP.Width) cx = GDISP.Width - x;
- if (y+cy > GDISP.Height) cy = GDISP.Height - y;
- #endif
- GDISP.clipx0 = x;
- GDISP.clipy0 = y;
- GDISP.clipx1 = x+cx;
- GDISP.clipy1 = y+cy;
- }
-#endif
-
-#if GDISP_NEED_CIRCLE && !GDISP_HARDWARE_CIRCLES
- void gdisp_lld_draw_circle(coord_t x, coord_t y, coord_t radius, color_t color) {
- coord_t a, b, P;
-
- a = 0;
- b = radius;
- P = 1 - radius;
-
- do {
- gdisp_lld_draw_pixel(x+a, y+b, color);
- gdisp_lld_draw_pixel(x+b, y+a, color);
- gdisp_lld_draw_pixel(x-a, y+b, color);
- gdisp_lld_draw_pixel(x-b, y+a, color);
- gdisp_lld_draw_pixel(x+b, y-a, color);
- gdisp_lld_draw_pixel(x+a, y-b, color);
- gdisp_lld_draw_pixel(x-a, y-b, color);
- gdisp_lld_draw_pixel(x-b, y-a, color);
- if (P < 0)
- P += 3 + 2*a++;
- else
- P += 5 + 2*(a++ - b--);
- } while(a <= b);
- }
-#endif
-
-#if GDISP_NEED_CIRCLE && !GDISP_HARDWARE_CIRCLEFILLS
- void gdisp_lld_fill_circle(coord_t x, coord_t y, coord_t radius, color_t color) {
- coord_t a, b, P;
-
- a = 0;
- b = radius;
- P = 1 - radius;
-
- do {
- gdisp_lld_draw_line(x-a, y+b, x+a, y+b, color);
- gdisp_lld_draw_line(x-a, y-b, x+a, y-b, color);
- gdisp_lld_draw_line(x-b, y+a, x+b, y+a, color);
- gdisp_lld_draw_line(x-b, y-a, x+b, y-a, color);
- if (P < 0)
- P += 3 + 2*a++;
- else
- P += 5 + 2*(a++ - b--);
- } while(a <= b);
- }
-#endif
-
-#if GDISP_NEED_ELLIPSE && !GDISP_HARDWARE_ELLIPSES
- void gdisp_lld_draw_ellipse(coord_t x, coord_t y, coord_t a, coord_t b, color_t color) {
- int dx = 0, dy = b; /* im I. Quadranten von links oben nach rechts unten */
- long a2 = a*a, b2 = b*b;
- long err = b2-(2*b-1)*a2, e2; /* Fehler im 1. Schritt */
-
- do {
- gdisp_lld_draw_pixel(x+dx, y+dy, color); /* I. Quadrant */
- gdisp_lld_draw_pixel(x-dx, y+dy, color); /* II. Quadrant */
- gdisp_lld_draw_pixel(x-dx, y-dy, color); /* III. Quadrant */
- gdisp_lld_draw_pixel(x+dx, y-dy, color); /* IV. Quadrant */
-
- e2 = 2*err;
- if(e2 < (2*dx+1)*b2) {
- dx++;
- err += (2*dx+1)*b2;
- }
- if(e2 > -(2*dy-1)*a2) {
- dy--;
- err -= (2*dy-1)*a2;
- }
- } while(dy >= 0);
-
- while(dx++ < a) { /* fehlerhafter Abbruch bei flachen Ellipsen (b=1) */
- gdisp_lld_draw_pixel(x+dx, y, color); /* -> Spitze der Ellipse vollenden */
- gdisp_lld_draw_pixel(x-dx, y, color);
- }
- }
-#endif
-
-#if GDISP_NEED_ELLIPSE && !GDISP_HARDWARE_ELLIPSEFILLS
- void gdisp_lld_fill_ellipse(coord_t x, coord_t y, coord_t a, coord_t b, color_t color) {
- int dx = 0, dy = b; /* im I. Quadranten von links oben nach rechts unten */
- long a2 = a*a, b2 = b*b;
- long err = b2-(2*b-1)*a2, e2; /* Fehler im 1. Schritt */
-
- do {
- gdisp_lld_draw_line(x-dx,y+dy,x+dx,y+dy, color);
- gdisp_lld_draw_line(x-dx,y-dy,x+dx,y-dy, color);
-
- e2 = 2*err;
- if(e2 < (2*dx+1)*b2) {
- dx++;
- err += (2*dx+1)*b2;
- }
- if(e2 > -(2*dy-1)*a2) {
- dy--;
- err -= (2*dy-1)*a2;
- }
- } while(dy >= 0);
-
- while(dx++ < a) { /* fehlerhafter Abbruch bei flachen Ellipsen (b=1) */
- gdisp_lld_draw_pixel(x+dx, y, color); /* -> Spitze der Ellipse vollenden */
- gdisp_lld_draw_pixel(x-dx, y, color);
- }
- }
-#endif
-
-#if GDISP_NEED_ARC && !GDISP_HARDWARE_ARCS
-
- #include <math.h>
-
- /*
- * @brief Internal helper function for gdispDrawArc()
- *
- * @note DO NOT USE DIRECTLY!
- *
- * @param[in] x, y The middle point of the arc
- * @param[in] start The start angle of the arc
- * @param[in] end The end angle of the arc
- * @param[in] radius The radius of the arc
- * @param[in] color The color in which the arc will be drawn
- *
- * @notapi
- */
- static void _draw_arc(coord_t x, coord_t y, uint16_t start, uint16_t end, uint16_t radius, color_t color) {
- if (/*start >= 0 && */start <= 180) {
- float x_maxI = x + radius*cos(start*M_PI/180);
- float x_minI;
-
- if (end > 180)
- x_minI = x - radius;
- else
- x_minI = x + radius*cos(end*M_PI/180);
-
- int a = 0;
- int b = radius;
- int P = 1 - radius;
-
- do {
- if(x-a <= x_maxI && x-a >= x_minI)
- gdisp_lld_draw_pixel(x-a, y-b, color);
- if(x+a <= x_maxI && x+a >= x_minI)
- gdisp_lld_draw_pixel(x+a, y-b, color);
- if(x-b <= x_maxI && x-b >= x_minI)
- gdisp_lld_draw_pixel(x-b, y-a, color);
- if(x+b <= x_maxI && x+b >= x_minI)
- gdisp_lld_draw_pixel(x+b, y-a, color);
-
- if (P < 0) {
- P = P + 3 + 2*a;
- a = a + 1;
- } else {
- P = P + 5 + 2*(a - b);
- a = a + 1;
- b = b - 1;
- }
- } while(a <= b);
- }
-
- if (end > 180 && end <= 360) {
- float x_maxII = x+radius*cos(end*M_PI/180);
- float x_minII;
-
- if(start <= 180)
- x_minII = x - radius;
- else
- x_minII = x+radius*cos(start*M_PI/180);
-
- int a = 0;
- int b = radius;
- int P = 1 - radius;
-
- do {
- if(x-a <= x_maxII && x-a >= x_minII)
- gdisp_lld_draw_pixel(x-a, y+b, color);
- if(x+a <= x_maxII && x+a >= x_minII)
- gdisp_lld_draw_pixel(x+a, y+b, color);
- if(x-b <= x_maxII && x-b >= x_minII)
- gdisp_lld_draw_pixel(x-b, y+a, color);
- if(x+b <= x_maxII && x+b >= x_minII)
- gdisp_lld_draw_pixel(x+b, y+a, color);
-
- if (P < 0) {
- P = P + 3 + 2*a;
- a = a + 1;
- } else {
- P = P + 5 + 2*(a - b);
- a = a + 1;
- b = b - 1;
- }
- } while (a <= b);
- }
- }
-
- void gdisp_lld_draw_arc(coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle, color_t color) {
- if(endangle < startangle) {
- _draw_arc(x, y, startangle, 360, radius, color);
- _draw_arc(x, y, 0, endangle, radius, color);
- } else {
- _draw_arc(x, y, startangle, endangle, radius, color);
- }
- }
-#endif
-
-#if GDISP_NEED_ARC && !GDISP_HARDWARE_ARCFILLS
- /*
- * @brief Internal helper function for gdispDrawArc()
- *
- * @note DO NOT USE DIRECTLY!
- *
- * @param[in] x, y The middle point of the arc
- * @param[in] start The start angle of the arc
- * @param[in] end The end angle of the arc
- * @param[in] radius The radius of the arc
- * @param[in] color The color in which the arc will be drawn
- *
- * @notapi
- */
- static void _fill_arc(coord_t x, coord_t y, uint16_t start, uint16_t end, uint16_t radius, color_t color) {
- if (/*start >= 0 && */start <= 180) {
- float x_maxI = x + radius*cos(start*M_PI/180);
- float x_minI;
-
- if (end > 180)
- x_minI = x - radius;
- else
- x_minI = x + radius*cos(end*M_PI/180);
-
- int a = 0;
- int b = radius;
- int P = 1 - radius;
-
- do {
- if(x-a <= x_maxI && x-a >= x_minI)
- gdisp_lld_draw_line(x, y, x-a, y-b, color);
- if(x+a <= x_maxI && x+a >= x_minI)
- gdisp_lld_draw_line(x, y, x+a, y-b, color);
- if(x-b <= x_maxI && x-b >= x_minI)
- gdisp_lld_draw_line(x, y, x-b, y-a, color);
- if(x+b <= x_maxI && x+b >= x_minI)
- gdisp_lld_draw_line(x, y, x+b, y-a, color);
-
- if (P < 0) {
- P = P + 3 + 2*a;
- a = a + 1;
- } else {
- P = P + 5 + 2*(a - b);
- a = a + 1;
- b = b - 1;
- }
- } while(a <= b);
- }
-
- if (end > 180 && end <= 360) {
- float x_maxII = x+radius*cos(end*M_PI/180);
- float x_minII;
-
- if(start <= 180)
- x_minII = x - radius;
- else
- x_minII = x+radius*cos(start*M_PI/180);
-
- int a = 0;
- int b = radius;
- int P = 1 - radius;
-
- do {
- if(x-a <= x_maxII && x-a >= x_minII)
- gdisp_lld_draw_line(x, y, x-a, y+b, color);
- if(x+a <= x_maxII && x+a >= x_minII)
- gdisp_lld_draw_line(x, y, x+a, y+b, color);
- if(x-b <= x_maxII && x-b >= x_minII)
- gdisp_lld_draw_line(x, y, x-b, y+a, color);
- if(x+b <= x_maxII && x+b >= x_minII)
- gdisp_lld_draw_line(x, y, x+b, y+a, color);
-
- if (P < 0) {
- P = P + 3 + 2*a;
- a = a + 1;
- } else {
- P = P + 5 + 2*(a - b);
- a = a + 1;
- b = b - 1;
- }
- } while (a <= b);
- }
- }
-
- void gdisp_lld_fill_arc(coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle, color_t color) {
- if(endangle < startangle) {
- _fill_arc(x, y, startangle, 360, radius, color);
- _fill_arc(x, y, 0, endangle, radius, color);
- } else {
- _fill_arc(x, y, startangle, endangle, radius, color);
- }
- }
-#endif
-
-#if GDISP_NEED_CONTROL && !GDISP_HARDWARE_CONTROL
- void gdisp_lld_control(unsigned what, void *value) {
- (void)what;
- (void)value;
- /* Ignore everything */
- }
-#endif
-
-#if GDISP_NEED_QUERY && !GDISP_HARDWARE_QUERY
-void *gdisp_lld_query(unsigned what) {
- (void) what;
- return (void *)-1;
-}
-#endif
-
-#if GDISP_NEED_MSGAPI
- void gdisp_lld_msg_dispatch(gdisp_lld_msg_t *msg) {
- switch(msg->action) {
- case GDISP_LLD_MSG_NOP:
- break;
- case GDISP_LLD_MSG_INIT:
- gdisp_lld_init();
- break;
- case GDISP_LLD_MSG_CLEAR:
- gdisp_lld_clear(msg->clear.color);
- break;
- case GDISP_LLD_MSG_DRAWPIXEL:
- gdisp_lld_draw_pixel(msg->drawpixel.x, msg->drawpixel.y, msg->drawpixel.color);
- break;
- case GDISP_LLD_MSG_FILLAREA:
- gdisp_lld_fill_area(msg->fillarea.x, msg->fillarea.y, msg->fillarea.cx, msg->fillarea.cy, msg->fillarea.color);
- break;
- case GDISP_LLD_MSG_BLITAREA:
- gdisp_lld_blit_area_ex(msg->blitarea.x, msg->blitarea.y, msg->blitarea.cx, msg->blitarea.cy, msg->blitarea.srcx, msg->blitarea.srcy, msg->blitarea.srccx, msg->blitarea.buffer);
- break;
- case GDISP_LLD_MSG_DRAWLINE:
- gdisp_lld_draw_line(msg->drawline.x0, msg->drawline.y0, msg->drawline.x1, msg->drawline.y1, msg->drawline.color);
- break;
- #if GDISP_NEED_CLIP
- case GDISP_LLD_MSG_SETCLIP:
- gdisp_lld_set_clip(msg->setclip.x, msg->setclip.y, msg->setclip.cx, msg->setclip.cy);
- break;
- #endif
- #if GDISP_NEED_CIRCLE
- case GDISP_LLD_MSG_DRAWCIRCLE:
- gdisp_lld_draw_circle(msg->drawcircle.x, msg->drawcircle.y, msg->drawcircle.radius, msg->drawcircle.color);
- break;
- case GDISP_LLD_MSG_FILLCIRCLE:
- gdisp_lld_fill_circle(msg->fillcircle.x, msg->fillcircle.y, msg->fillcircle.radius, msg->fillcircle.color);
- break;
- #endif
- #if GDISP_NEED_ELLIPSE
- case GDISP_LLD_MSG_DRAWELLIPSE:
- gdisp_lld_draw_ellipse(msg->drawellipse.x, msg->drawellipse.y, msg->drawellipse.a, msg->drawellipse.b, msg->drawellipse.color);
- break;
- case GDISP_LLD_MSG_FILLELLIPSE:
- gdisp_lld_fill_ellipse(msg->fillellipse.x, msg->fillellipse.y, msg->fillellipse.a, msg->fillellipse.b, msg->fillellipse.color);
- break;
- #endif
- #if GDISP_NEED_ARC
- case GDISP_LLD_MSG_DRAWARC:
- gdisp_lld_draw_circle(msg->drawarc.x, msg->drawarc.y, msg->drawarc.radius, msg->drawarc.startangle, msg->drawarc.endangle, msg->drawarc.color);
- break;
- case GDISP_LLD_MSG_FILLARC:
- gdisp_lld_fill_circle(msg->fillarc.x, msg->fillarc.y, msg->fillarc.radius, msg->fillarc.startangle, msg->fillarc.endangle, msg->fillarc.color);
- break;
- #endif
- #if GDISP_NEED_PIXELREAD
- case GDISP_LLD_MSG_GETPIXELCOLOR:
- msg->getpixelcolor.result = gdisp_lld_get_pixel_color(msg->getpixelcolor.x, msg->getpixelcolor.y);
- break;
- #endif
- #if GDISP_NEED_SCROLL
- case GDISP_LLD_MSG_VERTICALSCROLL:
- gdisp_lld_vertical_scroll(msg->verticalscroll.x, msg->verticalscroll.y, msg->verticalscroll.cx, msg->verticalscroll.cy, msg->verticalscroll.lines, msg->verticalscroll.bgcolor);
- break;
- #endif
- #if GDISP_NEED_CONTROL
- case GDISP_LLD_MSG_CONTROL:
- gdisp_lld_control(msg->control.what, msg->control.value);
- break;
- #endif
- #if GDISP_NEED_QUERY
- case GDISP_LLD_MSG_QUERY:
- msg->query.result = gdisp_lld_query(msg->query.what);
- break;
- #endif
- }
- }
-#endif
-
-#endif /* GFX_USE_GDISP */
-#endif /* GDISP_EMULATION_C */
-/** @} */
-
diff --git a/include/gdisp/lld/gdisp_lld.h b/include/gdisp/lld/gdisp_lld.h
index 98c7569c..d928d83d 100644
--- a/include/gdisp/lld/gdisp_lld.h
+++ b/include/gdisp/lld/gdisp_lld.h
@@ -22,266 +22,881 @@
/* Error checks. */
/*===========================================================================*/
+#if GDISP_TOTAL_CONTROLLERS > 1 && !defined(GDISP_DRIVER_VMT)
+ #define HARDWARE_AUTODETECT 2
+ #define HARDWARE_DEFAULT HARDWARE_AUTODETECT
+#else
+ #define HARDWARE_AUTODETECT 2
+ #define HARDWARE_DEFAULT FALSE
+#endif
+
/**
* @name GDISP hardware accelerated support
* @{
*/
/**
- * @brief Hardware accelerated line drawing.
- * @details If set to @p FALSE software emulation is used.
- */
- #ifndef GDISP_HARDWARE_LINES
- #define GDISP_HARDWARE_LINES FALSE
- #endif
-
- /**
- * @brief Hardware accelerated screen clears.
- * @details If set to @p FALSE software emulation is used.
+ * @brief The display hardware can benefit from being flushed.
+ * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT
+ *
+ * @note HARDWARE_AUTODETECT is only meaningful when GDISP_TOTAL_CONTROLLERS > 1
+ * @note Some controllers ** require ** the application to flush
*/
- #ifndef GDISP_HARDWARE_CLEARS
- #define GDISP_HARDWARE_CLEARS FALSE
+ #ifndef GDISP_HARDWARE_FLUSH
+ #define GDISP_HARDWARE_FLUSH HARDWARE_DEFAULT
#endif
/**
- * @brief Hardware accelerated rectangular fills.
- * @details If set to @p FALSE software emulation is used.
+ * @brief Hardware streaming writing is supported.
+ * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT
+ *
+ * @note HARDWARE_AUTODETECT is only meaningful when GDISP_TOTAL_CONTROLLERS > 1
+ * @note Either GDISP_HARDWARE_STREAM_WRITE or GDISP_HARDWARE_DRAWPIXEL must be provided by each driver
*/
- #ifndef GDISP_HARDWARE_FILLS
- #define GDISP_HARDWARE_FILLS FALSE
+ #ifndef GDISP_HARDWARE_STREAM_WRITE
+ #define GDISP_HARDWARE_STREAM_WRITE HARDWARE_DEFAULT
#endif
/**
- * @brief Hardware accelerated fills from an image.
- * @details If set to @p FALSE software emulation is used.
+ * @brief Hardware streaming reading of the display surface is supported.
+ * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT
+ *
+ * @note HARDWARE_AUTODETECT is only meaningful when GDISP_TOTAL_CONTROLLERS > 1
+ *
*/
- #ifndef GDISP_HARDWARE_BITFILLS
- #define GDISP_HARDWARE_BITFILLS FALSE
+ #ifndef GDISP_HARDWARE_STREAM_READ
+ #define GDISP_HARDWARE_STREAM_READ HARDWARE_DEFAULT
#endif
/**
- * @brief Hardware accelerated circles.
- * @details If set to @p FALSE software emulation is used.
+ * @brief Hardware supports setting the cursor position within the stream window.
+ * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT
+ *
+ * @note HARDWARE_AUTODETECT is only meaningful when GDISP_TOTAL_CONTROLLERS > 1
+ * @note This is used to optimise setting of individual pixels within a stream window.
+ * It should therefore not be implemented unless it is cheaper than just setting
+ * a new window.
*/
- #ifndef GDISP_HARDWARE_CIRCLES
- #define GDISP_HARDWARE_CIRCLES FALSE
+ #ifndef GDISP_HARDWARE_STREAM_POS
+ #define GDISP_HARDWARE_STREAM_POS HARDWARE_DEFAULT
#endif
/**
- * @brief Hardware accelerated filled circles.
- * @details If set to @p FALSE software emulation is used.
+ * @brief Hardware accelerated draw pixel.
+ * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT
+ *
+ * @note HARDWARE_AUTODETECT is only meaningful when GDISP_TOTAL_CONTROLLERS > 1
+ * @note Either GDISP_HARDWARE_STREAM_WRITE or GDISP_HARDWARE_DRAWPIXEL must be provided by the driver
*/
- #ifndef GDISP_HARDWARE_CIRCLEFILLS
- #define GDISP_HARDWARE_CIRCLEFILLS FALSE
+ #ifndef GDISP_HARDWARE_DRAWPIXEL
+ #define GDISP_HARDWARE_DRAWPIXEL HARDWARE_DEFAULT
#endif
/**
- * @brief Hardware accelerated ellipses.
- * @details If set to @p FALSE software emulation is used.
- */
- #ifndef GDISP_HARDWARE_ELLIPSES
- #define GDISP_HARDWARE_ELLIPSES FALSE
- #endif
-
- /**
- * @brief Hardware accelerated filled ellipses.
- * @details If set to @p FALSE software emulation is used.
+ * @brief Hardware accelerated screen clears.
+ * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT
+ *
+ * @note HARDWARE_AUTODETECT is only meaningful when GDISP_TOTAL_CONTROLLERS > 1
+ * @note This clears the entire display surface regardless of the clipping area currently set
*/
- #ifndef GDISP_HARDWARE_ELLIPSEFILLS
- #define GDISP_HARDWARE_ELLIPSEFILLS FALSE
+ #ifndef GDISP_HARDWARE_CLEARS
+ #define GDISP_HARDWARE_CLEARS HARDWARE_DEFAULT
#endif
/**
- * @brief Hardware accelerated arc's.
- * @details If set to @p FALSE software emulation is used.
+ * @brief Hardware accelerated rectangular fills.
+ * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT
+ *
+ * @note HARDWARE_AUTODETECT is only meaningful when GDISP_TOTAL_CONTROLLERS > 1
*/
- #ifndef GDISP_HARDWARE_ARCS
- #define GDISP_HARDWARE_ARCS FALSE
+ #ifndef GDISP_HARDWARE_FILLS
+ #define GDISP_HARDWARE_FILLS HARDWARE_DEFAULT
#endif
/**
- * @brief Hardware accelerated filled arcs.
- * @details If set to @p FALSE software emulation is used.
+ * @brief Hardware accelerated fills from an image.
+ * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT
+ *
+ * @note HARDWARE_AUTODETECT is only meaningful when GDISP_TOTAL_CONTROLLERS > 1
*/
- #ifndef GDISP_HARDWARE_ARCFILLS
- #define GDISP_HARDWARE_ARCFILLS FALSE
+ #ifndef GDISP_HARDWARE_BITFILLS
+ #define GDISP_HARDWARE_BITFILLS HARDWARE_DEFAULT
#endif
/**
* @brief Hardware accelerated scrolling.
- * @details If set to @p FALSE there is no support for scrolling.
+ * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT
+ *
+ * @note HARDWARE_AUTODETECT is only meaningful when GDISP_TOTAL_CONTROLLERS > 1
*/
#ifndef GDISP_HARDWARE_SCROLL
- #define GDISP_HARDWARE_SCROLL FALSE
+ #define GDISP_HARDWARE_SCROLL HARDWARE_DEFAULT
#endif
/**
* @brief Reading back of pixel values.
- * @details If set to @p FALSE there is no support for pixel read-back.
+ * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT
+ *
+ * @note HARDWARE_AUTODETECT is only meaningful when GDISP_TOTAL_CONTROLLERS > 1
*/
#ifndef GDISP_HARDWARE_PIXELREAD
- #define GDISP_HARDWARE_PIXELREAD FALSE
+ #define GDISP_HARDWARE_PIXELREAD HARDWARE_DEFAULT
#endif
/**
* @brief The driver supports one or more control commands.
- * @details If set to @p FALSE there is no support for control commands.
+ * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT
+ *
+ * @note HARDWARE_AUTODETECT is only meaningful when GDISP_TOTAL_CONTROLLERS > 1
*/
#ifndef GDISP_HARDWARE_CONTROL
- #define GDISP_HARDWARE_CONTROL FALSE
+ #define GDISP_HARDWARE_CONTROL HARDWARE_DEFAULT
#endif
/**
* @brief The driver supports a non-standard query.
- * @details If set to @p FALSE there is no support for non-standard queries.
+ * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT
+ *
+ * @note HARDWARE_AUTODETECT is only meaningful when GDISP_TOTAL_CONTROLLERS > 1
*/
#ifndef GDISP_HARDWARE_QUERY
- #define GDISP_HARDWARE_QUERY FALSE
+ #define GDISP_HARDWARE_QUERY HARDWARE_DEFAULT
#endif
/**
* @brief The driver supports a clipping in hardware.
- * @details If set to @p FALSE there is no support for non-standard queries.
+ * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT
+ *
+ * @note HARDWARE_AUTODETECT is only meaningful when GDISP_TOTAL_CONTROLLERS > 1
+ * @note If this is defined the driver must perform its own clipping on all calls to
+ * the driver and respond appropriately if a parameter is outside the display area.
+ * @note If this is not defined then the software ensures that all calls to the
+ * driver do not exceed the display area (provided GDISP_NEED_CLIP or GDISP_NEED_VALIDATION
+ * has been set).
*/
#ifndef GDISP_HARDWARE_CLIP
- #define GDISP_HARDWARE_CLIP FALSE
+ #define GDISP_HARDWARE_CLIP HARDWARE_DEFAULT
#endif
/** @} */
-/**
- * @name GDISP software algorithm choices
- * @{
- */
-/** @} */
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
-/**
- * @name GDISP pixel format choices
- * @{
- */
- /**
- * @brief The native pixel format for this device
- * @note Should be set to one of the following:
- * GDISP_PIXELFORMAT_RGB565
- * GDISP_PIXELFORMAT_RGB888
- * GDISP_PIXELFORMAT_RGB444
- * GDISP_PIXELFORMAT_RGB332
- * GDISP_PIXELFORMAT_RGB666
- * GDISP_PIXELFORMAT_CUSTOM
- * @note If you set GDISP_PIXELFORMAT_CUSTOM you need to also define
- * color_t, RGB2COLOR(r,g,b), HTML2COLOR(h),
- * RED_OF(c), GREEN_OF(c), BLUE_OF(c),
- * COLOR(c) and MASKCOLOR.
- */
- #ifndef GDISP_PIXELFORMAT
- #define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_ERROR
+struct GDisplay {
+ // The public GDISP stuff - must be the first element
+ GDISPControl g;
+
+ #if GDISP_TOTAL_CONTROLLERS > 1
+ const struct GDISPVMT const * vmt; // The Virtual Method Table
#endif
- /**
- * @brief Do pixels require packing for a blit
- * @note Is only valid for a pixel format that doesn't fill it's datatype. ie formats:
- * GDISP_PIXELFORMAT_RGB888
- * GDISP_PIXELFORMAT_RGB444
- * GDISP_PIXELFORMAT_RGB666
- * GDISP_PIXELFORMAT_CUSTOM
- * @note If you use GDISP_PIXELFORMAT_CUSTOM and packed bit fills
- * you need to also define @p gdispPackPixels(buf,cx,x,y,c)
- * @note If you are using GDISP_HARDWARE_BITFILLS = FALSE then the pixel
- * format must not be a packed format as the software blit does
- * not support packed pixels
- * @note Very few cases should actually require packed pixels as the low
- * level driver can also pack on the fly as it is sending it
- * to the graphics device.
- */
- #ifndef GDISP_PACKED_PIXELS
- #define GDISP_PACKED_PIXELS FALSE
+ void * priv; // A private area just for the drivers use.
+ void * board; // A private area just for the board interfaces use.
+
+ uint8_t systemdisplay;
+ uint8_t controllerdisplay;
+ uint16_t flags;
+ #define GDISP_FLG_INSTREAM 0x0001 // We are in a user based stream operation
+ #define GDISP_FLG_SCRSTREAM 0x0002 // The stream area currently covers the whole screen
+ #define GDISP_FLG_DRIVER 0x0004 // This flags and above are for use by the driver
+
+ // Multithread Mutex
+ #if GDISP_NEED_MULTITHREAD
+ gfxMutex mutex;
+ #endif
+
+ // Software clipping
+ #if GDISP_HARDWARE_CLIP != TRUE && (GDISP_NEED_CLIP || GDISP_NEED_VALIDATION)
+ coord_t clipx0, clipy0;
+ coord_t clipx1, clipy1; /* not inclusive */
+ #endif
+
+ // Driver call parameters
+ struct {
+ coord_t x, y;
+ coord_t cx, cy;
+ coord_t x1, y1;
+ coord_t x2, y2;
+ color_t color;
+ void *ptr;
+ } p;
+
+ // In call working buffers
+
+ #if GDISP_NEED_TEXT
+ // Text rendering parameters
+ struct {
+ font_t font;
+ color_t color;
+ color_t bgcolor;
+ coord_t clipx0, clipy0;
+ coord_t clipx1, clipy1;
+ } t;
+ #endif
+ #if GDISP_LINEBUF_SIZE != 0 && ((GDISP_NEED_SCROLL && !GDISP_HARDWARE_SCROLL) || (!GDISP_HARDWARE_STREAM_WRITE && GDISP_HARDWARE_BITFILLS))
+ // A pixel line buffer
+ color_t linebuf[GDISP_LINEBUF_SIZE];
+ #endif
+
+};
+
+#if GDISP_TOTAL_CONTROLLERS == 1 || defined(GDISP_DRIVER_VMT) || defined(__DOXYGEN__)
+ #if GDISP_TOTAL_CONTROLLERS > 1
+ #define LLDSPEC static
+ #else
+ #define LLDSPEC
+ #endif
+
+ #ifdef __cplusplus
+ extern "C" {
#endif
/**
- * @brief Do lines of pixels require packing for a blit
- * @note Ignored if GDISP_PACKED_PIXELS is FALSE
+ * @brief Initialize the driver.
+ * @return TRUE if successful.
+ * @param[in] g The driver structure
+ * @param[out] g->g The driver must fill in the GDISPControl structure
*/
- #ifndef GDISP_PACKED_LINES
- #define GDISP_PACKED_LINES FALSE
+ LLDSPEC bool_t gdisp_lld_init(GDisplay *g);
+
+ #if GDISP_HARDWARE_FLUSH || defined(__DOXYGEN__)
+ /**
+ * @brief Flush the current drawing operations to the display
+ * @pre GDISP_HARDWARE_FLUSH is TRUE
+ *
+ * @param[in] g The driver structure
+ *
+ * @note The parameter variables must not be altered by the driver.
+ */
+ LLDSPEC void gdisp_lld_flush(GDisplay *g);
#endif
-/** @} */
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
+ #if GDISP_HARDWARE_STREAM_WRITE || defined(__DOXYGEN__)
+ /**
+ * @brief Start a streamed write operation
+ * @pre GDISP_HARDWARE_STREAM_WRITE is TRUE
+ *
+ * @param[in] g The driver structure
+ * @param[in] g->p.x,g->p.y The window position
+ * @param[in] g->p.cx,g->p.cy The window size
+ *
+ * @note The parameter variables must not be altered by the driver.
+ * @note Streaming operations that wrap the defined window have
+ * undefined results.
+ * @note This must be followed by a call to @p gdisp_lld_write_pos() if GDISP_HARDWARE_STREAM_POS is TRUE.
+ */
+ LLDSPEC void gdisp_lld_write_start(GDisplay *g);
+
+ /**
+ * @brief Send a pixel to the current streaming position and then increment that position
+ * @pre GDISP_HARDWARE_STREAM_WRITE is TRUE
+ *
+ * @param[in] g The driver structure
+ * @param[in] g->p.color The color to display at the curent position
+ *
+ * @note The parameter variables must not be altered by the driver.
+ */
+ LLDSPEC void gdisp_lld_write_color(GDisplay *g);
+
+ /**
+ * @brief End the current streaming write operation
+ * @pre GDISP_HARDWARE_STREAM_WRITE is TRUE
+ *
+ * @param[in] g The driver structure
+ *
+ * @note The parameter variables must not be altered by the driver.
+ */
+ LLDSPEC void gdisp_lld_write_stop(GDisplay *g);
+
+ #if GDISP_HARDWARE_STREAM_POS || defined(__DOXYGEN__)
+ /**
+ * @brief Change the current position within the current streaming window
+ * @pre GDISP_HARDWARE_STREAM_POS is TRUE and GDISP_HARDWARE_STREAM_WRITE is TRUE
+ *
+ * @param[in] g The driver structure
+ * @param[in] g->p.x,g->p.y The new position (which will always be within the existing stream window)
+ *
+ * @note The parameter variables must not be altered by the driver.
+ */
+ LLDSPEC void gdisp_lld_write_pos(GDisplay *g);
+ #endif
+ #endif
-#ifdef __cplusplus
-extern "C" {
-#endif
+ #if GDISP_HARDWARE_STREAM_READ || defined(__DOXYGEN__)
+ /**
+ * @brief Start a streamed read operation
+ * @pre GDISP_HARDWARE_STREAM_READ is TRUE
+ *
+ * @param[in] g The driver structure
+ * @param[in] g->p.x,g->p.y The window position
+ * @param[in] g->p.cx,g->p.cy The window size
+ *
+ * @note The parameter variables must not be altered by the driver.
+ * @note Streaming operations that wrap the defined window have
+ * undefined results.
+ */
+ LLDSPEC void gdisp_lld_read_start(GDisplay *g);
+
+ /**
+ * @brief Read a pixel from the current streaming position and then increment that position
+ * @return The color at the current position
+ * @pre GDISP_HARDWARE_STREAM_READ is TRUE
+ *
+ * @param[in] g The driver structure
+ *
+ * @note The parameter variables must not be altered by the driver.
+ */
+ LLDSPEC color_t gdisp_lld_read_color(GDisplay *g);
+
+ /**
+ * @brief End the current streaming operation
+ * @pre GDISP_HARDWARE_STREAM_READ is TRUE
+ *
+ * @param[in] g The driver structure
+ *
+ * @note The parameter variables must not be altered by the driver.
+ */
+ LLDSPEC void gdisp_lld_read_stop(GDisplay *g);
+ #endif
- /* Core functions */
- extern bool_t gdisp_lld_init(void);
+ #if GDISP_HARDWARE_DRAWPIXEL || defined(__DOXYGEN__)
+ /**
+ * @brief Draw a pixel
+ * @pre GDISP_HARDWARE_DRAWPIXEL is TRUE
+ *
+ * @param[in] g The driver structure
+ * @param[in] g->p.x,g->p.y The pixel position
+ * @param[in] g->p.color The color to set
+ *
+ * @note The parameter variables must not be altered by the driver.
+ */
+ LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g);
+ #endif
- /* Some of these functions will be implemented in software by the high level driver
- depending on the GDISP_HARDWARE_XXX macros defined in gdisp_lld_config.h.
- */
+ #if GDISP_HARDWARE_CLEARS || defined(__DOXYGEN__)
+ /**
+ * @brief Clear the screen using the defined color
+ * @pre GDISP_HARDWARE_CLEARS is TRUE
+ *
+ * @param[in] g The driver structure
+ * @param[in] g->p.color The color to set
+ *
+ * @note The parameter variables must not be altered by the driver.
+ */
+ LLDSPEC void gdisp_lld_clear(GDisplay *g);
+ #endif
- /* Drawing functions */
- extern void gdisp_lld_clear(color_t color);
- extern void gdisp_lld_draw_pixel(coord_t x, coord_t y, color_t color);
- extern void gdisp_lld_fill_area(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
- extern void gdisp_lld_blit_area_ex(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx, coord_t srcy, coord_t srccx, const pixel_t *buffer);
- extern void gdisp_lld_draw_line(coord_t x0, coord_t y0, coord_t x1, coord_t y1, color_t color);
+ #if GDISP_HARDWARE_FILLS || defined(__DOXYGEN__)
+ /**
+ * @brief Fill an area with a single color
+ * @pre GDISP_HARDWARE_FILLS is TRUE
+ *
+ * @param[in] g The driver structure
+ * @param[in] g->p.x,g->p.y The area position
+ * @param[in] g->p.cx,g->p.cy The area size
+ * @param[in] g->p.color The color to set
+ *
+ * @note The parameter variables must not be altered by the driver.
+ */
+ LLDSPEC void gdisp_lld_fill_area(GDisplay *g);
+ #endif
- /* Circular Drawing Functions */
- #if GDISP_NEED_CIRCLE
- extern void gdisp_lld_draw_circle(coord_t x, coord_t y, coord_t radius, color_t color);
- extern void gdisp_lld_fill_circle(coord_t x, coord_t y, coord_t radius, color_t color);
+ #if GDISP_HARDWARE_BITFILLS || defined(__DOXYGEN__)
+ /**
+ * @brief Fill an area using a bitmap
+ * @pre GDISP_HARDWARE_BITFILLS is TRUE
+ *
+ * @param[in] g The driver structure
+ * @param[in] g->p.x,g->p.y The area position
+ * @param[in] g->p.cx,g->p.cy The area size
+ * @param[in] g->p.x1,g->p.y1 The starting position in the bitmap
+ * @param[in] g->p.x2 The width of a bitmap line
+ * @param[in] g->p.ptr The pointer to the bitmap
+ *
+ * @note The parameter variables must not be altered by the driver.
+ */
+ LLDSPEC void gdisp_lld_blit_area(GDisplay *g);
#endif
- #if GDISP_NEED_ELLIPSE
- extern void gdisp_lld_draw_ellipse(coord_t x, coord_t y, coord_t a, coord_t b, color_t color);
- extern void gdisp_lld_fill_ellipse(coord_t x, coord_t y, coord_t a, coord_t b, color_t color);
+ #if GDISP_HARDWARE_PIXELREAD || defined(__DOXYGEN__)
+ /**
+ * @brief Read a pixel from the display
+ * @return The color at the defined position
+ * @pre GDISP_HARDWARE_PIXELREAD is TRUE (and the application needs it)
+ *
+ * @param[in] g The driver structure
+ * @param[in] g->p.x,g->p.y The pixel position
+ *
+ * @note The parameter variables must not be altered by the driver.
+ */
+ LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g);
#endif
- /* Arc Drawing Functions */
- #if GDISP_NEED_ARC
- extern void gdisp_lld_draw_arc(coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle, color_t color);
- extern void gdisp_lld_fill_arc(coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle, color_t color);
+ #if (GDISP_HARDWARE_SCROLL && GDISP_NEED_SCROLL) || defined(__DOXYGEN__)
+ /**
+ * @brief Scroll an area of the screen
+ * @pre GDISP_HARDWARE_SCROLL is TRUE (and the application needs it)
+ *
+ * @param[in] g The driver structure
+ * @param[in] g->p.x,g->p.y The area position
+ * @param[in] g->p.cx,g->p.cy The area size
+ * @param[in] g->p.y1 The number of lines to scroll (positive or negative)
+ *
+ * @note The parameter variables must not be altered by the driver.
+ * @note This can be easily implemented if the hardware supports
+ * display area to display area copying.
+ * @note Clearing the exposed area on the scroll operation is not
+ * needed as the high level code handles this.
+ */
+ LLDSPEC void gdisp_lld_vertical_scroll(GDisplay *g);
#endif
- /* Text Rendering Functions */
- #if GDISP_NEED_TEXT
- extern void gdisp_lld_draw_char(coord_t x, coord_t y, uint16_t c, font_t font, color_t color);
- extern void gdisp_lld_fill_char(coord_t x, coord_t y, uint16_t c, font_t font, color_t color, color_t bgcolor);
+ #if (GDISP_HARDWARE_CONTROL && GDISP_NEED_CONTROL) || defined(__DOXYGEN__)
+ /**
+ * @brief Control some feature of the hardware
+ * @pre GDISP_HARDWARE_CONTROL is TRUE (and the application needs it)
+ *
+ * @param[in] g The driver structure
+ * @param[in] g->p.x The operation to perform
+ * @param[in] g->p.ptr The operation parameter
+ *
+ * @note The parameter variables must not be altered by the driver.
+ */
+ LLDSPEC void gdisp_lld_control(GDisplay *g);
#endif
- /* Pixel readback */
- #if GDISP_NEED_PIXELREAD
- extern color_t gdisp_lld_get_pixel_color(coord_t x, coord_t y);
+ #if (GDISP_HARDWARE_QUERY && GDISP_NEED_QUERY) || defined(__DOXYGEN__)
+ /**
+ * @brief Query some feature of the hardware
+ * @return The information requested (typecast as void *)
+ * @pre GDISP_HARDWARE_QUERY is TRUE (and the application needs it)
+ *
+ * @param[in] g The driver structure
+ * @param[in] g->p.x What to query
+ *
+ * @note The parameter variables must not be altered by the driver.
+ */
+ LLDSPEC void *gdisp_lld_query(GDisplay *g); // Uses p.x (=what);
#endif
- /* Scrolling Function - clears the area scrolled out */
- #if GDISP_NEED_SCROLL
- extern void gdisp_lld_vertical_scroll(coord_t x, coord_t y, coord_t cx, coord_t cy, int lines, color_t bgcolor);
+ #if (GDISP_HARDWARE_CLIP && (GDISP_NEED_CLIP || GDISP_NEED_VALIDATION)) || defined(__DOXYGEN__)
+ /**
+ * @brief Set the hardware clipping area
+ * @pre GDISP_HARDWARE_CLIP is TRUE (and the application needs it)
+ *
+ * @param[in] g The driver structure
+ * @param[in] g->p.x,g->p.y The area position
+ * @param[in] g->p.cx,g->p.cy The area size
+ *
+ * @note The parameter variables must not be altered by the driver.
+ */
+ LLDSPEC void gdisp_lld_set_clip(GDisplay *g);
#endif
- /* Set driver specific control */
- #if GDISP_NEED_CONTROL
- extern void gdisp_lld_control(unsigned what, void *value);
+ #ifdef __cplusplus
+ }
#endif
+#endif // GDISP_TOTAL_CONTROLLERS == 1 || defined(GDISP_DRIVER_VMT)
+
+
+#if GDISP_TOTAL_CONTROLLERS > 1
+
+ typedef struct GDISPVMT {
+ bool_t (*init)(GDisplay *g);
+ void (*writestart)(GDisplay *g); // Uses p.x,p.y p.cx,p.cy
+ void (*writepos)(GDisplay *g); // Uses p.x,p.y
+ void (*writecolor)(GDisplay *g); // Uses p.color
+ void (*writestop)(GDisplay *g); // Uses no parameters
+ void (*readstart)(GDisplay *g); // Uses p.x,p.y p.cx,p.cy
+ color_t (*readcolor)(GDisplay *g); // Uses no parameters
+ void (*readstop)(GDisplay *g); // Uses no parameters
+ void (*pixel)(GDisplay *g); // Uses p.x,p.y p.color
+ void (*clear)(GDisplay *g); // Uses p.color
+ void (*fill)(GDisplay *g); // Uses p.x,p.y p.cx,p.cy p.color
+ void (*blit)(GDisplay *g); // Uses p.x,p.y p.cx,p.cy p.x1,p.y1 (=srcx,srcy) p.x2 (=srccx), p.ptr (=buffer)
+ color_t (*get)(GDisplay *g); // Uses p.x,p.y
+ void (*vscroll)(GDisplay *g); // Uses p.x,p.y p.cx,p.cy, p.y1 (=lines) p.color
+ void (*control)(GDisplay *g); // Uses p.x (=what) p.ptr (=value)
+ void *(*query)(GDisplay *g); // Uses p.x (=what);
+ void (*setclip)(GDisplay *g); // Uses p.x,p.y p.cx,p.cy
+ void (*flush)(GDisplay *g); // Uses no parameters
+ } GDISPVMT;
+
+ #if defined(GDISP_DRIVER_VMT)
+ #if !GDISP_HARDWARE_STREAM_WRITE && !GDISP_HARDWARE_DRAWPIXEL
+ #error "GDISP Driver: Either GDISP_HARDWARE_STREAM_WRITE or GDISP_HARDWARE_DRAWPIXEL must be TRUE"
+ #endif
+ const GDISPVMT const GDISP_DRIVER_VMT[1] = {{
+ gdisp_lld_init,
+ #if GDISP_HARDWARE_FLUSH
+ gdisp_lld_flush,
+ #else
+ 0,
+ #endif
+ #if GDISP_HARDWARE_STREAM_WRITE
+ gdisp_lld_write_start,
+ #if GDISP_HARDWARE_STREAM_POS
+ gdisp_lld_write_pos,
+ #else
+ 0,
+ #endif
+ gdisp_lld_write_color,
+ gdisp_lld_write_stop,
+ #else
+ 0, 0, 0, 0,
+ #endif
+ #if GDISP_HARDWARE_STREAM_READ
+ gdisp_lld_read_start,
+ gdisp_lld_read_color,
+ gdisp_lld_read_stop,
+ #else
+ 0, 0, 0,
+ #endif
+ #if GDISP_HARDWARE_DRAWPIXEL
+ gdisp_lld_draw_pixel,
+ #else
+ 0,
+ #endif
+ #if GDISP_HARDWARE_CLEARS
+ gdisp_lld_clear,
+ #else
+ 0,
+ #endif
+ #if GDISP_HARDWARE_FILLS
+ gdisp_lld_fill_area,
+ #else
+ 0,
+ #endif
+ #if GDISP_HARDWARE_BITFILLS
+ gdisp_lld_blit_area,
+ #else
+ 0,
+ #endif
+ #if GDISP_HARDWARE_PIXELREAD
+ gdisp_lld_get_pixel_color,
+ #else
+ 0,
+ #endif
+ #if GDISP_HARDWARE_SCROLL && GDISP_NEED_SCROLL
+ gdisp_lld_vertical_scroll,
+ #else
+ 0,
+ #endif
+ #if GDISP_HARDWARE_CONTROL && GDISP_NEED_CONTROL
+ gdisp_lld_control,
+ #else
+ 0,
+ #endif
+ #if GDISP_HARDWARE_QUERY && GDISP_NEED_QUERY
+ gdisp_lld_query,
+ #else
+ 0,
+ #endif
+ #if GDISP_HARDWARE_CLIP && (GDISP_NEED_CLIP || GDISP_NEED_VALIDATION)
+ gdisp_lld_set_clip,
+ #else
+ 0,
+ #endif
+ }};
+
+ #else
+ #define gdisp_lld_init(g) g->vmt->init(g)
+ #define gdisp_lld_flush(g) g->vmt->flush(g)
+ #define gdisp_lld_write_start(g) g->vmt->writestart(g)
+ #define gdisp_lld_write_pos(g) g->vmt->writepos(g)
+ #define gdisp_lld_write_color(g) g->vmt->writecolor(g)
+ #define gdisp_lld_write_stop(g) g->vmt->writestop(g)
+ #define gdisp_lld_read_start(g) g->vmt->readstart(g)
+ #define gdisp_lld_read_color(g) g->vmt->readcolor(g)
+ #define gdisp_lld_read_stop(g) g->vmt->readstop(g)
+ #define gdisp_lld_draw_pixel(g) g->vmt->pixel(g)
+ #define gdisp_lld_clear(g) g->vmt->clear(g)
+ #define gdisp_lld_fill_area(g) g->vmt->fill(g)
+ #define gdisp_lld_blit_area(g) g->vmt->blit(g)
+ #define gdisp_lld_get_pixel_color(g) g->vmt->get(g)
+ #define gdisp_lld_vertical_scroll(g) g->vmt->vscroll(g)
+ #define gdisp_lld_control(g) g->vmt->control(g)
+ #define gdisp_lld_query(g) g->vmt->query(g)
+ #define gdisp_lld_set_clip(g) g->vmt->setclip(g)
+ #endif // GDISP_LLD_DECLARATIONS
+
+#endif // GDISP_TOTAL_CONTROLLERS > 1
+
+/* Verify information for packed pixels and define a non-packed pixel macro */
+#if !GDISP_PACKED_PIXELS
+ #define gdispPackPixels(buf,cx,x,y,c) { ((color_t *)(buf))[(y)*(cx)+(x)] = (c); }
+#elif !GDISP_HARDWARE_BITFILLS
+ #error "GDISP: packed pixel formats are only supported for hardware accelerated drivers."
+#elif GDISP_PIXELFORMAT != GDISP_PIXELFORMAT_RGB888 \
+ && GDISP_PIXELFORMAT != GDISP_PIXELFORMAT_RGB444 \
+ && GDISP_PIXELFORMAT != GDISP_PIXELFORMAT_RGB666 \
+ && GDISP_PIXELFORMAT != GDISP_PIXELFORMAT_CUSTOM
+ #error "GDISP: A packed pixel format has been specified for an unsupported pixel format."
+#endif
+
+/* Support routine for packed pixel formats */
+#if !defined(gdispPackPixels) || defined(__DOXYGEN__)
+ /**
+ * @brief Pack a pixel into a pixel buffer.
+ * @note This function performs no buffer boundary checking
+ * regardless of whether GDISP_NEED_CLIP has been specified.
+ *
+ * @param[in] buf The buffer to put the pixel in
+ * @param[in] cx The width of a pixel line
+ * @param[in] x, y The location of the pixel to place
+ * @param[in] color The color to put into the buffer
+ *
+ * @api
+ */
+ void gdispPackPixels(const pixel_t *buf, coord_t cx, coord_t x, coord_t y, color_t color);
+#endif
- /* Query driver specific data */
- #if GDISP_NEED_QUERY
- extern void *gdisp_lld_query(unsigned what);
+/* Low level driver pixel format information */
+//-------------------------
+// True-Color color system
+//-------------------------
+#if GDISP_LLD_PIXELFORMAT & GDISP_COLORSYSTEM_TRUECOLOR
+ #define LLDCOLOR_SYSTEM GDISP_COLORSYSTEM_TRUECOLOR
+
+ // Calculate the number of bits
+ #define LLDCOLOR_BITS_R ((GDISP_LLD_PIXELFORMAT>>8) & 0x0F)
+ #define LLDCOLOR_BITS_G ((GDISP_LLD_PIXELFORMAT>>4) & 0x0F)
+ #define LLDCOLOR_BITS_B ((GDISP_LLD_PIXELFORMAT>>0) & 0x0F)
+ #define LLDCOLOR_BITS (LLDCOLOR_BITS_R + LLDCOLOR_BITS_G + LLDCOLOR_BITS_B)
+
+ // From the number of bits determine COLOR_TYPE, COLOR_TYPE_BITS and masking
+ #if LLDCOLOR_BITS <= 8
+ #define LLDCOLOR_TYPE uint8_t
+ #define LLDCOLOR_TYPE_BITS 8
+ #elif LLDCOLOR_BITS <= 16
+ #define LLDCOLOR_TYPE uint16_t
+ #define LLDCOLOR_TYPE_BITS 16
+ #elif LLDCOLOR_BITS <= 32
+ #define LLDCOLOR_TYPE uint32_t
+ #define LLDCOLOR_TYPE_BITS 32
+ #else
+ #error "GDISP: Cannot define low level driver color types with more than 32 bits"
+ #endif
+ #if LLDCOLOR_TYPE_BITS == LLDCOLOR_BITS
+ #define LLDCOLOR_NEEDS_MASK FALSE
+ #else
+ #define LLDCOLOR_NEEDS_MASK TRUE
+ #endif
+ #define LLDCOLOR_MASK() ((1 << LLDCOLOR_BITS)-1)
+
+ // Calculate the component bit shifts
+ #if (GDISP_LLD_PIXELFORMAT & GDISP_COLORSYSTEM_MASK) == GDISP_COLORSYSTEM_RGB
+ #define LLDCOLOR_SHIFT_R (LLDCOLOR_BITS_B+LLDCOLOR_BITS_G)
+ #define LLDCOLOR_SHIFT_G LLDCOLOR_BITS_B
+ #define LLDCOLOR_SHIFT_B 0
+ #else
+ #define LLDCOLOR_SHIFT_B (LLDCOLOR_BITS_R+LLDCOLOR_BITS_G)
+ #define LLDCOLOR_SHIFT_G LLDCOLOR_BITS_R
+ #define LLDCOLOR_SHIFT_R 0
#endif
- /* Clipping Functions */
- #if GDISP_NEED_CLIP
- extern void gdisp_lld_set_clip(coord_t x, coord_t y, coord_t cx, coord_t cy);
+ // Calculate LLDRED_OF, LLDGREEN_OF, LLDBLUE_OF and LLDRGB2COLOR
+ #if LLDCOLOR_BITS_R + LLDCOLOR_SHIFT_R == 8
+ #define LLDRED_OF(c) ((c) & (((1<<LLDCOLOR_BITS_R)-1) << LLDCOLOR_SHIFT_R))
+ #define LLDRGB2COLOR_R(r) ((LLDCOLOR_TYPE)((r) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_R))-1))))
+ #elif LLDCOLOR_BITS_R + LLDCOLOR_SHIFT_R > 8
+ #define LLDRED_OF(c) (((c) & (((1<<LLDCOLOR_BITS_R)-1) << LLDCOLOR_SHIFT_R)) >> (LLDCOLOR_BITS_R+LLDCOLOR_SHIFT_R-8))
+ #define LLDRGB2COLOR_R(r) (((LLDCOLOR_TYPE)((r) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_R))-1)))) << (LLDCOLOR_BITS_R+LLDCOLOR_SHIFT_R-8))
+ #else // LLDCOLOR_BITS_R + LLDCOLOR_SHIFT_R < 8
+ #define LLDRED_OF(c) (((c) & (((1<<LLDCOLOR_BITS_R)-1) << LLDCOLOR_SHIFT_R)) << (8-(LLDCOLOR_BITS_R+LLDCOLOR_SHIFT_R)))
+ #define LLDRGB2COLOR_R(r) (((LLDCOLOR_TYPE)((r) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_R))-1)))) >> (8-(LLDCOLOR_BITS_R+LLDCOLOR_SHIFT_R)))
+ #endif
+ #if LLDCOLOR_BITS_G + LLDCOLOR_SHIFT_G == 8
+ #define LLDGREEN_OF(c) ((c) & (((1<<LLDCOLOR_BITS_G)-1) << LLDCOLOR_SHIFT_G))
+ #define LLDRGB2COLOR_G(g) ((LLDCOLOR_TYPE)((g) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_G))-1))))
+ #elif LLDCOLOR_BITS_G + LLDCOLOR_SHIFT_G > 8
+ #define LLDGREEN_OF(c) (((c) & (((1<<LLDCOLOR_BITS_G)-1) << LLDCOLOR_SHIFT_G)) >> (LLDCOLOR_BITS_G+LLDCOLOR_SHIFT_G-8))
+ #define LLDRGB2COLOR_G(g) (((LLDCOLOR_TYPE)((g) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_G))-1)))) << (LLDCOLOR_BITS_G+LLDCOLOR_SHIFT_G-8))
+ #else // LLDCOLOR_BITS_G + LLDCOLOR_SHIFT_G < 8
+ #define LLDGREEN_OF(c) (((c) & (((1<<LLDCOLOR_BITS_G)-1) << LLDCOLOR_SHIFT_G)) << (8-(LLDCOLOR_BITS_G+LLDCOLOR_SHIFT_G)))
+ #define LLDRGB2COLOR_G(g) (((LLDCOLOR_TYPE)((g) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_G))-1)))) >> (8-(LLDCOLOR_BITS_LLDG+COLOR_SHIFT_G)))
+ #endif
+ #if LLDCOLOR_BITS_B + LLDCOLOR_SHIFT_B == 8
+ #define LLDBLUE_OF(c) ((c) & (((1<<LLDCOLOR_BITS_B)-1) << LLDCOLOR_SHIFT_B))
+ #define LLDRGB2COLOR_B(b) ((LLDCOLOR_TYPE)((b) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_B))-1))))
+ #elif LLDCOLOR_BITS_B + LLDCOLOR_SHIFT_B > 8
+ #define LLDBLUE_OF(c) (((c) & (((1<<LLDCOLOR_BITS_B)-1) << LLDCOLOR_SHIFT_B)) >> (LLDCOLOR_BITS_B+LLDCOLOR_SHIFT_B-8))
+ #define LLDRGB2COLOR_B(b) (((LLDCOLOR_TYPE)((b) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_B))-1)))) << (LLDCOLOR_BITS_B+LLDCOLOR_SHIFT_B-8))
+ #else // LLDCOLOR_BITS_B + LLDCOLOR_SHIFT_B < 8
+ #define LLDBLUE_OF(c) (((c) & (((1<<LLDCOLOR_BITS_B)-1) << LLDCOLOR_SHIFT_B)) << (8-(LLDCOLOR_BITS_B+LLDCOLOR_SHIFT_B)))
+ #define LLDRGB2COLOR_B(b) (((COLOR_TYPE)((b) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_B))-1)))) >> (8-(LLDCOLOR_BITS_B+LLDCOLOR_SHIFT_B)))
+ #endif
+ #define LLDLUMA_OF(c) ((LLDRED_OF(c)+((uint16_t)LLDGREEN_OF(c)<<1)+LLDBLUE_OF(c))>>2)
+ #define LLDEXACT_RED_OF(c) (((uint16_t)(((c)>>LLDCOLOR_SHIFT_R)&((1<<LLDCOLOR_BITS_R)-1))*255)/((1<<LLDCOLOR_BITS_R)-1))
+ #define LLDEXACT_GREEN_OF(c) (((uint16_t)(((c)>>LLDCOLOR_SHIFT_G)&((1<<LLDCOLOR_BITS_G)-1))*255)/((1<<LLDCOLOR_BITS_G)-1))
+ #define LLDEXACT_BLUE_OF(c) (((uint16_t)(((c)>>LLDCOLOR_SHIFT_B)&((1<<LLDCOLOR_BITS_B)-1))*255)/((1<<LLDCOLOR_BITS_B)-1))
+ #define LLDEXACT_LUMA_OF(c) ((LLDEXACT_RED_OF(c)+((uint16_t)LLDEXACT_GREEN_OF(c)<<1)+LLDEXACT_BLUE_OF(c))>>2)
+ #define LLDLUMA2COLOR(l) (LLDRGB2COLOR_R(l) | LLDRGB2COLOR_G(l) | LLDRGB2COLOR_B(l))
+ #define LLDRGB2COLOR(r,g,b) (LLDRGB2COLOR_R(r) | LLDRGB2COLOR_G(g) | LLDRGB2COLOR_B(b))
+
+ // Calculate LLDHTML2COLOR
+ #if LLDCOLOR_BITS_R + LLDCOLOR_SHIFT_R == 24
+ #define LLDHTML2COLOR_R(h) ((h) & ((0xFF & ~((1<<(8-LLDCOLOR_BITS_R))-1))<<16))
+ #elif COLOR_BITS_R + COLOR_SHIFT_R > 24
+ #define LLDHTML2COLOR_R(h) (((h) & ((0xFF & ~((1<<(8-LLDCOLOR_BITS_R))-1))<<16)) << (LLDCOLOR_BITS_R+LLDCOLOR_SHIFT_R-24))
+ #else // COLOR_BITS_R + COLOR_SHIFT_R < 24
+ #define LLDHTML2COLOR_R(h) (((h) & ((0xFF & ~((1<<(8-LLDCOLOR_BITS_R))-1))<<16)) >> (24-(LLDCOLOR_BITS_R+LLDCOLOR_SHIFT_R)))
+ #endif
+ #if LLDCOLOR_BITS_G + LLDCOLOR_SHIFT_G == 16
+ #define LLDHTML2COLOR_G(h) ((h) & ((0xFF & ~((1<<(8-LLDCOLOR_BITS_G))-1))<<8))
+ #elif LLDCOLOR_BITS_G + LLDCOLOR_SHIFT_G > 16
+ #define LLDHTML2COLOR_G(h) (((h) & ((0xFF & ~((1<<(8-LLDCOLOR_BITS_G))-1))<<8)) << (LLDCOLOR_BITS_G+LLDCOLOR_SHIFT_G-16))
+ #else // LLDCOLOR_BITS_G + LLDCOLOR_SHIFT_G < 16
+ #define LLDHTML2COLOR_G(h) (((h) & ((0xFF & ~((1<<(8-LLDCOLOR_BITS_G))-1))<<8)) >> (16-(LLDCOLOR_BITS_G+LLDCOLOR_SHIFT_G)))
#endif
+ #if LLDCOLOR_BITS_B + LLDCOLOR_SHIFT_B == 8
+ #define LLDHTML2COLOR_B(h) ((h) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_B))-1)))
+ #elif LLDCOLOR_BITS_B + LLDCOLOR_SHIFT_B > 8
+ #define LLDHTML2COLOR_B(h) (((h) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_B))-1))) << (LLDCOLOR_BITS_B+LLDCOLOR_SHIFT_B-8))
+ #else // LLDCOLOR_BITS_B + LLDCOLOR_SHIFT_B < 8
+ #define LLDHTML2COLOR_B(h) (((h) & (0xFF & ~((1<<(8-LLDCOLOR_BITS_B))-1))) >> (8-(LLDCOLOR_BITS_B+LLDCOLOR_SHIFT_B)))
+ #endif
+ #define LLDHTML2COLOR(h) ((LLDCOLOR_TYPE)(LLDHTML2COLOR_R(h) | LLDHTML2COLOR_G(h) | LLDHTML2COLOR_B(h)))
+
+//-------------------------
+// Gray-scale color system
+//-------------------------
+#elif (GDISP_LLD_PIXELFORMAT & GDISP_COLORSYSTEM_MASK) == GDISP_COLORSYSTEM_GRAYSCALE
+ #define LLDCOLOR_SYSTEM GDISP_COLORSYSTEM_GRAYSCALE
+
+ // Calculate the number of bits and shifts
+ #define LLDCOLOR_BITS (GDISP_LLD_PIXELFORMAT & 0xFF)
+ #define LLDCOLOR_BITS_R LLDCOLOR_BITS
+ #define LLDCOLOR_BITS_G LLDCOLOR_BITS
+ #define LLDCOLOR_BITS_B LLDCOLOR_BITS
+ #define LLDCOLOR_SHIFT_R 0
+ #define LLDCOLOR_SHIFT_G 0
+ #define LLDCOLOR_SHIFT_B 0
+
+ // From the number of bits determine COLOR_TYPE, COLOR_TYPE_BITS and masking
+ #if LLDCOLOR_BITS <= 8
+ #define LLDCOLOR_TYPE uint8_t
+ #define LLDCOLOR_TYPE_BITS 8
+ #else
+ #error "GDISP: Cannot define gray-scale low level driver color types with more than 8 bits"
+ #endif
+ #if LLDCOLOR_TYPE_BITS == LLDCOLOR_BITS
+ #define LLDCOLOR_NEEDS_MASK FALSE
+ #else
+ #define LLDCOLOR_NEEDS_MASK TRUE
+ #endif
+ #define LLDCOLOR_MASK() ((1 << LLDCOLOR_BITS)-1)
+
+ #if COLOR_BITS == 1
+ #define LLDRGB2COLOR(r,g,b) (((r)|(g)|(b)) ? 1 : 0)
+ #define LLDLUMA2COLOR(l) ((l) ? 1 : 0)
+ #define LLDHTML2COLOR(h) ((h) ? 1 : 0)
+ #define LLDLUMA_OF(c) ((c) ? 255 : 0)
+ #define LLDEXACT_LUMA_OF(c) LLDLUMA_OF(c)
+ #else
+ // They eye is more sensitive to green
+ #define LLDRGB2COLOR(r,g,b) ((LLDCOLOR_TYPE)(((uint16_t)(r)+(g)+(g)+(b)) >> (10-LLDCOLOR_BITS)))
+ #define LLDLUMA2COLOR(l) ((LLDCOLOR_TYPE)((l)>>(8-LLDCOLOR_BITS)))
+ #define LLDHTML2COLOR(h) ((LLDCOLOR_TYPE)(((((h)&0xFF0000)>>16)+(((h)&0x00FF00)>>7)+((h)&0x0000FF)) >> (10-LLDCOLOR_BITS)))
+ #define LLDLUMA_OF(c) (((c) & ((1<<LLDCOLOR_BITS)-1)) << (8-LLDCOLOR_BITS))
+ #define LLDEXACT_LUMA_OF(c) ((((uint16_t)(c) & ((1<<LLDCOLOR_BITS)-1))*255)/((1<<LLDCOLOR_BITS)-1))
+ #endif
+
+ #define LLDRED_OF(c) LLDLUMA_OF(c)
+ #define LLDGREEN_OF(c) LLDLUMA_OF(c)
+ #define LLDBLUE_OF(c) LLDLUMA_OF(c)
+ #define LLDEXACT_RED_OF(c) LLDEXACT_LUMA_OF(c)
+ #define LLDEXACT_GREEN_OF(c) LLDEXACT_LUMA_OF(c)
+ #define LLDEXACT_BLUE_OF(c) LLDEXACT_LUMA_OF(c)
+
+//-------------------------
+// Palette color system
+//-------------------------
+#elif (GDISP_LLD_PIXELFORMAT & GDISP_COLORSYSTEM_MASK) == GDISP_COLORSYSTEM_PALETTE
+ #define LLDCOLOR_SYSTEM GDISP_COLORSYSTEM_PALETTE
+
+ #error "GDISP: A palette color system for low level drivers is not currently supported"
+
+//-------------------------
+// Some other color system
+//-------------------------
+#else
+ #error "GDISP: Unsupported color system for low level drivers"
+#endif
+
+/* Which is the larger color type */
+#if COLOR_BITS > LLDCOLOR_BITS
+ #define LARGER_COLOR_BITS COLOR_BITS
+ #define LARGER_COLOR_TYPE COLOR_TYPE
+#else
+ #define LARGER_COLOR_BITS LLDCOLOR_BITS
+ #define LARGER_COLOR_TYPE LLDCOLOR_TYPE
+#endif
- /* Messaging API */
- #if GDISP_NEED_MSGAPI
- #include "gdisp_lld_msgs.h"
- extern void gdisp_lld_msg_dispatch(gdisp_lld_msg_t *msg);
+/**
+ * @brief Controls color conversion accuracy for a low level driver
+ * @details Should higher precision be used when converting colors.
+ * @note Color conversion is only necessary if GDISP_PIXELFORMAT != GDISP_LLD_PIXELFORMAT
+ * @note It only makes sense to turn this on if you have a high bit depth display but
+ * are running the application in low bit depths.
+ * @note To achieve higher color accuracy bit shifting is replaced with multiplies and divides.
+ */
+#ifndef GDISP_HARDWARE_USE_EXACT_COLOR
+ #if LLDCOLOR_BITS_R - COLOR_BITS_R >= LLDCOLOR_BITS_R/2 || LLDCOLOR_BITS_G - COLOR_BITS_G >= LLDCOLOR_BITS_G/2 || LLDCOLOR_BITS_B - COLOR_BITS_B >= LLDCOLOR_BITS_B/2
+ #define GDISP_HARDWARE_USE_EXACT_COLOR TRUE
+ #else
+ #define GDISP_HARDWARE_USE_EXACT_COLOR FALSE
#endif
+#endif
-#ifdef __cplusplus
-}
+/* Low level driver pixel format conversion functions */
+#if GDISP_PIXELFORMAT == GDISP_LLD_PIXELFORMAT || defined(__DOXYGEN__)
+ /**
+ * @brief Convert from a standard color format to the low level driver pixel format
+ * @note For use only by low level drivers
+ */
+ #define COLOR2NATIVE(c) (c)
+ /**
+ * @brief Convert from a low level driver pixel format to the standard color format
+ * @note For use only by low level drivers
+ */
+ #define NATIVE2COLOR(c) (c)
+
+#else
+ #if COLOR_SYSTEM == GDISP_COLORSYSTEM_GRAYSCALE || LLDCOLOR_SYSTEM == GDISP_COLORSYSTEM_GRAYSCALE
+ #if GDISP_HARDWARE_USE_EXACT_COLOR
+ #define COLOR2NATIVE(c) LLDLUMA2COLOR(EXACT_LUMA_OF(c))
+ #define NATIVE2COLOR(c) LUMA2COLOR(LLDEXACT_LUMA_OF(c))
+ #else
+ #define COLOR2NATIVE(c) LLDLUMA2COLOR(LUMA_OF(c))
+ #define NATIVE2COLOR(c) LUMA2COLOR(LLDLUMA_OF(c))
+ #endif
+ #elif COLOR_SYSTEM == GDISP_COLORSYSTEM_TRUECOLOR && LLDCOLOR_SYSTEM == GDISP_COLORSYSTEM_TRUECOLOR
+ #if GDISP_HARDWARE_USE_EXACT_COLOR
+ #define COLOR2NATIVE(c) LLDRGB2COLOR(EXACT_RED_OF(c), EXACT_GREEN_OF(c), EXACT_BLUE_OF(c))
+ #define NATIVE2COLOR(c) RGB2COLOR(LLDEXACT_RED_OF(c), LLDEXACT_GREEN_OF(c), LLDEXACT_BLUE_OF(c))
+ #else
+ #define COLOR2NATIVE(c) LLDRGB2COLOR(RED_OF(c), GREEN_OF(c), BLUE_OF(c))
+ #define NATIVE2COLOR(c) RGB2COLOR(LLDRED_OF(c), LLDGREEN_OF(c), LLDBLUE_OF(c))
+ #endif
+
+ /*
+ #elif GDISP_PIXELFORMAT == GDISP_PIXELFORMAT_RGB888 && GDISP_LLD_PIXELFORMAT == GDISP_PIXELFORMAT_BGR888
+ #define COLOR2NATIVE(c) ((LLDCOLOR_TYPE)(((c)&0xFF0000)>>16)|((c)&0x00FF00)|(((c)&0x0000FF)<<16))
+ #define NATIVE2COLOR(c) ((COLOR_TYPE)(((c)&0xFF0000)>>16)|((c)&0x00FF00)|(((c)&0x0000FF)<<16))
+ #elif GDISP_PIXELFORMAT == GDISP_PIXELFORMAT_RGB565 && GDISP_LLD_PIXELFORMAT == GDISP_PIXELFORMAT_BGR888
+ #define COLOR2NATIVE(c) ((LLDCOLOR_TYPE)( \
+ ((LARGER_COLOR_TYPE)((c)&(((1<<COLOR_BITS_R)-1)<<COLOR_SHIFT_R))>>(COLOR_BITS_R+COLOR_SHIFT_R-8))| \
+ ((LARGER_COLOR_TYPE)((c)&(((1<<COLOR_BITS_G)-1)<<COLOR_SHIFT_G))<<(16-(COLOR_BITS_G+COLOR_SHIFT_G)))| \
+ ((LARGER_COLOR_TYPE)((c)&(((1<<COLOR_BITS_B)-1)<<COLOR_SHIFT_B))<<(24-(COLOR_BITS_B+COLOR_SHIFT_B)))))
+ #define NATIVE2COLOR(c) ((COLOR_TYPE)( \
+ ((LARGER_COLOR_TYPE)((c)&0x0000F8)<<COLOR_SHIFT_R)| \
+ ((LARGER_COLOR_TYPE)((c)&0x00FC00)>>(16-(COLOR_BITS_G+COLOR_SHIFT_G)))| \
+ ((LARGER_COLOR_TYPE)((c)&0xF80000)>>(24-(COLOR_BITS_B+COLOR_SHIFT_B)))))
+ */
+ #else
+ #error "GDISP: This pixel format conversion is not supported yet"
+ #endif
#endif
#endif /* GFX_USE_GDISP */
diff --git a/include/gdisp/lld/gdisp_lld_msgs.h b/include/gdisp/lld/gdisp_lld_msgs.h
deleted file mode 100644
index 2c199cbe..00000000
--- a/include/gdisp/lld/gdisp_lld_msgs.h
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * This file is subject to the terms of the GFX License. If a copy of
- * the license was not distributed with this file, you can obtain one at:
- *
- * http://ugfx.org/license.html
- */
-
-/**
- * @file include/gdisp/lld/gdisp_lld_msgs.h
- * @brief GDISP Graphic Driver subsystem low level driver message structures.
- *
- * @addtogroup GDISP
- * @{
- */
-
-#ifndef _GDISP_LLD_MSGS_H
-#define _GDISP_LLD_MSGS_H
-
-/* This file describes the message API for gdisp_lld */
-#if GFX_USE_GDISP && GDISP_NEED_MSGAPI
-
-typedef enum gdisp_msgaction {
- GDISP_LLD_MSG_NOP,
- GDISP_LLD_MSG_INIT,
- GDISP_LLD_MSG_CLEAR,
- GDISP_LLD_MSG_DRAWPIXEL,
- GDISP_LLD_MSG_FILLAREA,
- GDISP_LLD_MSG_BLITAREA,
- GDISP_LLD_MSG_DRAWLINE,
- #if GDISP_NEED_CLIP
- GDISP_LLD_MSG_SETCLIP,
- #endif
- #if GDISP_NEED_CIRCLE
- GDISP_LLD_MSG_DRAWCIRCLE,
- GDISP_LLD_MSG_FILLCIRCLE,
- #endif
- #if GDISP_NEED_ELLIPSE
- GDISP_LLD_MSG_DRAWELLIPSE,
- GDISP_LLD_MSG_FILLELLIPSE,
- #endif
- #if GDISP_NEED_ARC
- GDISP_LLD_MSG_DRAWARC,
- GDISP_LLD_MSG_FILLARC,
- #endif
- #if GDISP_NEED_PIXELREAD
- GDISP_LLD_MSG_GETPIXELCOLOR,
- #endif
- #if GDISP_NEED_SCROLL
- GDISP_LLD_MSG_VERTICALSCROLL,
- #endif
- #if GDISP_NEED_CONTROL
- GDISP_LLD_MSG_CONTROL,
- #endif
- GDISP_LLD_MSG_QUERY,
-} gdisp_msgaction_t;
-
-typedef union gdisp_lld_msg {
- struct {
- gfxQueueItem qi;
- gdisp_msgaction_t action;
- };
- struct gdisp_lld_msg_init {
- gfxQueueItem qi;
- gdisp_msgaction_t action; // GDISP_LLD_MSG_INIT
- } init;
- struct gdisp_lld_msg_clear {
- gfxQueueItem qi;
- gdisp_msgaction_t action; // GDISP_LLD_MSG_CLEAR
- color_t color;
- } clear;
- struct gdisp_lld_msg_drawpixel {
- gfxQueueItem qi;
- gdisp_msgaction_t action; // GDISP_LLD_MSG_DRAWPIXEL
- coord_t x, y;
- color_t color;
- } drawpixel;
- struct gdisp_lld_msg_fillarea {
- gfxQueueItem qi;
- gdisp_msgaction_t action; // GDISP_LLD_MSG_FILLAREA
- coord_t x, y;
- coord_t cx, cy;
- color_t color;
- } fillarea;
- struct gdisp_lld_msg_blitarea {
- gfxQueueItem qi;
- gdisp_msgaction_t action; // GDISP_LLD_MSG_BLITAREA
- coord_t x, y;
- coord_t cx, cy;
- coord_t srcx, srcy;
- coord_t srccx;
- const pixel_t *buffer;
- } blitarea;
- struct gdisp_lld_msg_setclip {
- gfxQueueItem qi;
- gdisp_msgaction_t action; // GDISP_LLD_MSG_SETCLIP
- coord_t x, y;
- coord_t cx, cy;
- } setclip;
- struct gdisp_lld_msg_drawline {
- gfxQueueItem qi;
- gdisp_msgaction_t action; // GDISP_LLD_MSG_DRAWLINE
- coord_t x0, y0;
- coord_t x1, y1;
- color_t color;
- } drawline;
- struct gdisp_lld_msg_drawcircle {
- gfxQueueItem qi;
- gdisp_msgaction_t action; // GDISP_LLD_MSG_DRAWCIRCLE
- coord_t x, y;
- coord_t radius;
- color_t color;
- } drawcircle;
- struct gdisp_lld_msg_fillcircle {
- gfxQueueItem qi;
- gdisp_msgaction_t action; // GDISP_LLD_MSG_FILLCIRCLE
- coord_t x, y;
- coord_t radius;
- color_t color;
- } fillcircle;
- struct gdisp_lld_msg_drawellipse {
- gfxQueueItem qi;
- gdisp_msgaction_t action; // GDISP_LLD_MSG_DRAWELLIPSE
- coord_t x, y;
- coord_t a, b;
- color_t color;
- } drawellipse;
- struct gdisp_lld_msg_fillellipse {
- gfxQueueItem qi;
- gdisp_msgaction_t action; // GDISP_LLD_MSG_FILLELLIPSE
- coord_t x, y;
- coord_t a, b;
- color_t color;
- } fillellipse;
- struct gdisp_lld_msg_drawarc {
- gfxQueueItem qi;
- gdisp_msgaction_t action; // GDISP_LLD_MSG_DRAWARC
- coord_t x, y;
- coord_t radius;
- coord_t startangle, endangle;
- color_t color;
- } drawarc;
- struct gdisp_lld_msg_fillarc {
- gfxQueueItem qi;
- gdisp_msgaction_t action; // GDISP_LLD_MSG_FILLARC
- coord_t x, y;
- coord_t radius;
- coord_t startangle, endangle;
- color_t color;
- } fillarc;
- struct gdisp_lld_msg_getpixelcolor {
- gfxQueueItem qi;
- gdisp_msgaction_t action; // GDISP_LLD_MSG_GETPIXELCOLOR
- coord_t x, y;
- color_t result;
- } getpixelcolor;
- struct gdisp_lld_msg_verticalscroll {
- gfxQueueItem qi;
- gdisp_msgaction_t action; // GDISP_LLD_MSG_VERTICALSCROLL
- coord_t x, y;
- coord_t cx, cy;
- int lines;
- color_t bgcolor;
- } verticalscroll;
- struct gdisp_lld_msg_control {
- gfxQueueItem qi;
- gdisp_msgaction_t action; // GDISP_LLD_MSG_CONTROL
- int what;
- void * value;
- } control;
- struct gdisp_lld_msg_query {
- gfxQueueItem qi;
- gdisp_msgaction_t action; // GDISP_LLD_MSG_QUERY
- int what;
- void * result;
- } query;
-} gdisp_lld_msg_t;
-
-#endif /* GFX_USE_GDISP && GDISP_NEED_MSGAPI */
-#endif /* _GDISP_LLD_MSGS_H */
-/** @} */
-
diff --git a/include/gdisp/options.h b/include/gdisp/options.h
index efabe417..650e81c5 100644
--- a/include/gdisp/options.h
+++ b/include/gdisp/options.h
@@ -21,11 +21,31 @@
* @{
*/
/**
- * @brief The priority of the GDISP thread.
- * @details Defaults to NORMAL_PRIORITY
+ * @brief Should drawing operations be automatically flushed.
+ * @details Defaults to FALSE
+ * @note If set to FALSE and the controller requires flushing
+ * then the application must manually call @p gdispGFlush().
+ * Setting this to TRUE causes GDISP to automatically flush
+ * after each drawing operation. Note this may be slow but enables
+ * an application to avoid having to manually call the flush routine.
+ * @note If TRUE and GDISP_NEED_TIMERFLUSH is also TRUE, this takes precedence.
+ * @note Most controllers don't need flushing which is why this is set to
+ * FALSE by default.
+ */
+ #ifndef GDISP_NEED_AUTOFLUSH
+ #define GDISP_NEED_AUTOFLUSH FALSE
+ #endif
+ /**
+ * @brief Should drawing operations be automatically flushed on a timer.
+ * @details Defaults to FALSE, Can be set to FALSE or a timer period in milliseconds.
+ * @note The period should not be set too short or it will consume all your CPU. A
+ * value between 250 and 500 milliseconds would probably be suitable.
+ * @note If TRUE and GDISP_NEED_AUTOFLUSH is also TRUE, this is ineffective.
+ * @note Most controllers don't need flushing which is why this is set to
+ * FALSE by default.
*/
- #ifndef GDISP_THREAD_PRIORITY
- #define GDISP_THREAD_PRIORITY NORMAL_PRIORITY
+ #ifndef GDISP_NEED_TIMERFLUSH
+ #define GDISP_NEED_TIMERFLUSH FALSE
#endif
/**
* @brief Should all operations be clipped to the screen and colors validated.
@@ -33,49 +53,67 @@
* @note If this is FALSE, any operations that extend beyond the
* edge of the screen will have undefined results. Any
* out-of-range colors will produce undefined results.
- * @note If defined then all low level and high level GDISP driver routines
- * must check the validity of inputs and do something sensible
- * if they are out of range. It doesn't have to be efficient,
- * just valid.
+ * @note This should always be left as the default (TRUE) unless you
+ * are a maniac for speed and you have thoroughly tested your code
+ * and it never overwrites the edges of the screen.
+ * @note Setting GDISP_NEED_CLIP to TRUE internally uses the same mechanism
+ * as this validation. There is no advantage in setting this FALSE if
+ * GDISP_NEED_CLIP is TRUE.
*/
#ifndef GDISP_NEED_VALIDATION
- #define GDISP_NEED_VALIDATION TRUE
+ #define GDISP_NEED_VALIDATION TRUE
#endif
/**
* @brief Are clipping functions needed.
* @details Defaults to TRUE
*/
#ifndef GDISP_NEED_CLIP
- #define GDISP_NEED_CLIP TRUE
+ #define GDISP_NEED_CLIP TRUE
+ #endif
+ /**
+ * @brief Streaming functions are needed
+ * @details Defaults to FALSE.
+ */
+ #ifndef GDISP_NEED_STREAMING
+ #define GDISP_NEED_STREAMING FALSE
#endif
/**
* @brief Are text functions needed.
* @details Defaults to FALSE
+ * @note You must also define at least one font.
*/
#ifndef GDISP_NEED_TEXT
- #define GDISP_NEED_TEXT FALSE
+ #define GDISP_NEED_TEXT FALSE
#endif
/**
* @brief Are circle functions needed.
- * @details Defaults to TRUE
+ * @details Defaults to FALSE
+ * @note Uses integer algorithms only. It does not use any trig or floating point.
*/
#ifndef GDISP_NEED_CIRCLE
- #define GDISP_NEED_CIRCLE TRUE
+ #define GDISP_NEED_CIRCLE FALSE
#endif
/**
* @brief Are ellipse functions needed.
* @details Defaults to FALSE
+ * @note Uses integer algorithms only. It does not use any trig or floating point.
*/
#ifndef GDISP_NEED_ELLIPSE
- #define GDISP_NEED_ELLIPSE FALSE
+ #define GDISP_NEED_ELLIPSE FALSE
#endif
/**
* @brief Are arc functions needed.
* @details Defaults to FALSE
- * @note Requires the maths library to be included in the link. ie -lm
+ * @note This can be compiled using fully integer mathematics by
+ * defining GFX_USE_GMISC and GMISC_NEED_FIXEDTRIG as TRUE.
+ * @note This can be compiled to use floating point but no trig functions
+ * by defining GFX_USE_GMISC and GMISC_NEED_FASTTRIG as TRUE.
+ * @note If neither of the above are defined it requires the maths library
+ * to be included in the link to provide floating point and trig support.
+ * ie include -lm in your compiler flags.
*/
#ifndef GDISP_NEED_ARC
- #define GDISP_NEED_ARC FALSE
+ #define GDISP_NEED_ARC FALSE
#endif
/**
* @brief Are convex polygon functions needed.
@@ -95,7 +133,7 @@
* option will cause a compile error.
*/
#ifndef GDISP_NEED_SCROLL
- #define GDISP_NEED_SCROLL FALSE
+ #define GDISP_NEED_SCROLL FALSE
#endif
/**
* @brief Is the capability to read pixels back needed.
@@ -105,7 +143,7 @@
* option will cause a compile error.
*/
#ifndef GDISP_NEED_PIXELREAD
- #define GDISP_NEED_PIXELREAD FALSE
+ #define GDISP_NEED_PIXELREAD FALSE
#endif
/**
* @brief Control some aspect of the hardware operation.
@@ -114,7 +152,7 @@
* screen rotation, backlight levels, contrast etc
*/
#ifndef GDISP_NEED_CONTROL
- #define GDISP_NEED_CONTROL FALSE
+ #define GDISP_NEED_CONTROL FALSE
#endif
/**
* @brief Query some aspect of the hardware operation.
@@ -122,21 +160,58 @@
* @note This allows query of hardware specific features
*/
#ifndef GDISP_NEED_QUERY
- #define GDISP_NEED_QUERY FALSE
+ #define GDISP_NEED_QUERY FALSE
#endif
/**
* @brief Is the image interface required.
* @details Defaults to FALSE
*/
#ifndef GDISP_NEED_IMAGE
- #define GDISP_NEED_IMAGE FALSE
+ #define GDISP_NEED_IMAGE FALSE
#endif
+/**
+ * @}
+ *
+ * @name GDISP Multiple Display Support
+ * @{
+ */
/**
- * @brief Is the messaging api interface required.
- * @details Defaults to FALSE
+ * @brief The total number of displays.
+ * @note This can be on just one type of controller or spread across several different controllers
*/
- #ifndef GDISP_NEED_MSGAPI
- #define GDISP_NEED_MSGAPI FALSE
+ #ifndef GDISP_TOTAL_DISPLAYS
+ #define GDISP_TOTAL_DISPLAYS 1
+ #endif
+ /**
+ * @brief The total number of controllers.
+ * @note If this is greater than one, all the hardware acceleration options below
+ * and the pixel format must be manually specified in your gfxconf.h along with
+ * @p GDISP_CONTROLLER_LIST. See the gdisp_lld_config.h in each driver to get a list
+ * of hardware capabilities for each driver in order to work out the common set across
+ * all the controllers you want to use.
+ */
+ #ifndef GDISP_TOTAL_CONTROLLERS
+ #define GDISP_TOTAL_CONTROLLERS 1
+ #endif
+
+ #if defined(__DOXYGEN__)
+ /**
+ * @brief The list of controllers.
+ * @note This is required if @p GDISP_TOTAL_CONTROLLERS is greater than one.
+ * @note The number of entries must match @p GDISP_TOTAL_CONTROLLERS.
+ * @note See the gdisp_lld.c in each driver (near the top) to get the name of the VMT for a driver.
+ * @note Replace this example with your own definition in your gfxconf.h file.
+ */
+ #define GDISP_CONTROLLER_LIST GDISPVMT_Win32, GDISPVMT_SSD1963
+ /**
+ * @brief The number of displays for each controller.
+ * @note This is required if @p GDISP_TOTAL_CONTROLLERS is greater than one.
+ * @note The number of entries must match @p GDISP_TOTAL_CONTROLLERS.
+ * @note The sum of all the display counts must equal @p GDISP_TOTAL_DISPLAYS (3 for this example)
+ * or bad things will happen.
+ * @note Replace this example with your own definition in your gfxconf.h file.
+ */
+ #define GDISP_CONTROLLER_DISPLAYS 2, 1
#endif
/**
* @}
@@ -150,42 +225,42 @@
* @details Defaults to FALSE
*/
#ifndef GDISP_NEED_IMAGE_NATIVE
- #define GDISP_NEED_IMAGE_NATIVE FALSE
+ #define GDISP_NEED_IMAGE_NATIVE FALSE
#endif
/**
* @brief Is GIF image decoding required.
* @details Defaults to FALSE
*/
#ifndef GDISP_NEED_IMAGE_GIF
- #define GDISP_NEED_IMAGE_GIF FALSE
+ #define GDISP_NEED_IMAGE_GIF FALSE
#endif
/**
* @brief Is BMP image decoding required.
* @details Defaults to FALSE
*/
#ifndef GDISP_NEED_IMAGE_BMP
- #define GDISP_NEED_IMAGE_BMP FALSE
+ #define GDISP_NEED_IMAGE_BMP FALSE
#endif
/**
* @brief Is JPG image decoding required.
* @details Defaults to FALSE
*/
#ifndef GDISP_NEED_IMAGE_JPG
- #define GDISP_NEED_IMAGE_JPG FALSE
+ #define GDISP_NEED_IMAGE_JPG FALSE
#endif
/**
* @brief Is PNG image decoding required.
* @details Defaults to FALSE
*/
#ifndef GDISP_NEED_IMAGE_PNG
- #define GDISP_NEED_IMAGE_PNG FALSE
+ #define GDISP_NEED_IMAGE_PNG FALSE
#endif
/**
* @brief Is memory accounting required during image decoding.
* @details Defaults to FALSE
*/
#ifndef GDISP_NEED_IMAGE_ACCOUNTING
- #define GDISP_NEED_IMAGE_ACCOUNTING FALSE
+ #define GDISP_NEED_IMAGE_ACCOUNTING FALSE
#endif
/**
* @}
@@ -198,7 +273,7 @@
* @details Defaults to FALSE
*/
#ifndef GDISP_NEED_UTF8
- #define GDISP_NEED_UTF8 FALSE
+ #define GDISP_NEED_UTF8 FALSE
#endif
/**
@@ -206,7 +281,7 @@
* @details Defaults to FALSE
*/
#ifndef GDISP_NEED_TEXT_KERNING
- #define GDISP_NEED_TEXT_KERNING FALSE
+ #define GDISP_NEED_TEXT_KERNING FALSE
#endif
/**
@@ -214,7 +289,7 @@
* @details Defaults to FALSE
*/
#ifndef GDISP_NEED_ANTIALIAS
- #define GDISP_NEED_ANTIALIAS FALSE
+ #define GDISP_NEED_ANTIALIAS FALSE
#endif
/**
@@ -226,27 +301,10 @@
/**
* @brief Do the drawing functions need to be thread-safe.
* @details Defaults to FALSE
- * @note Both GDISP_NEED_MULTITHREAD and GDISP_NEED_ASYNC make
- * the gdisp API thread-safe.
- * @note This is more efficient than GDISP_NEED_ASYNC as it only
- * requires a context switch if something else is already
- * drawing.
*/
#ifndef GDISP_NEED_MULTITHREAD
#define GDISP_NEED_MULTITHREAD FALSE
#endif
- /**
- * @brief Use asynchronous calls (multi-thread safe).
- * @details Defaults to FALSE
- * @note Both GDISP_NEED_MULTITHREAD and GDISP_NEED_ASYNC make
- * the gdisp API thread-safe.
- * @note Turning this on adds two context switches per transaction
- * so it can significantly slow graphics drawing but it allows
- * drawing operations to continue in the background.
- */
- #ifndef GDISP_NEED_ASYNC
- #define GDISP_NEED_ASYNC FALSE
- #endif
/**
* @}
*
@@ -264,6 +322,23 @@
* @name GDISP Optional Sizing Parameters
* @{
*/
+ /**
+ * @brief The size of pixel buffer (in pixels) used for optimization.
+ * @details Set to zero to guarantee disabling of the buffer.
+ * @note Depending on the driver and what operations the application
+ * needs, this buffer may never be allocated.
+ * @note Setting the size to zero may cause some operations to not
+ * compile eg. Scrolling if there is no hardware scroll support.
+ * @note Increasing the size will speedup certain operations
+ * at the expense of RAM.
+ * @note Currently only used to support scrolling on hardware without
+ * scrolling support, and to increase the speed of streaming
+ * operations on non-streaming hardware where there is a
+ * hardware supported bit-blit.
+ */
+ #ifndef GDISP_LINEBUF_SIZE
+ #define GDISP_LINEBUF_SIZE 128
+ #endif
/**
* @}
*
@@ -271,14 +346,10 @@
* @{
*/
/**
- * @brief Use a custom board definition even if a board definition exists.
- * @details Defaults to FALSE
- * @details If TRUE, add gdisp_lld_board.h to your project directory and customise it.
- * @note Not all GDISP low level drivers currently use board definition files.
+ * @brief Define the default orientation for all displays in the system.
+ * @note GDISP_NEED_CONTROL must also be set (and the hardware must support it)
*/
- #ifndef GDISP_USE_CUSTOM_BOARD
- #define GDISP_USE_CUSTOM_BOARD FALSE
- #endif
+ // #define GDISP_DEFAULT_ORIENTATION GDISP_ROTATE_LANDSCAPE
/**
* @brief Set the screen height and width.
* @note Ignored by some low level GDISP drivers, optional for others.
@@ -289,24 +360,14 @@
/* #define GDISP_SCREEN_WIDTH nnnn */
/* #define GDISP_SCREEN_HEIGHT nnnn */
/**
- * @brief Define which threading model to use.
- * @details Optional for the X11 driver.
- * @note Defaults to TRUE. Setting to FALSE causes POSIX threads to be used
- */
- /* #define GDISP_THREAD_CHIBIOS FALSE */
- /**
* @brief Define which bus interface to use.
* @details Only required by the SSD1963 driver.
* @note This will be replaced eventually by board definition files
*/
- /* #define GDISP_USE_FSMC */
- /* #define GDISP_USE_GPIO */
+ // #define GDISP_USE_FSMC
+ // #define GDISP_USE_GPIO
/** @} */
-#if GFX_USE_GDISP
- #include "gdisp_lld_config.h"
-#endif
-
#endif /* _GDISP_OPTIONS_H */
/** @} */
diff --git a/include/gfx_rules.h b/include/gfx_rules.h
index afd2a8fe..534c2cc9 100644
--- a/include/gfx_rules.h
+++ b/include/gfx_rules.h
@@ -87,10 +87,9 @@
#undef GWIN_NEED_WINDOWMANAGER
#define GWIN_NEED_WINDOWMANAGER TRUE
#endif
- #if !GDISP_NEED_MULTITHREAD && !GDISP_NEED_ASYNC
+ #if !GDISP_NEED_MULTITHREAD
#if GFX_DISPLAY_RULE_WARNINGS
- #warning "GWIN: Either GDISP_NEED_MULTITHREAD or GDISP_NEED_ASYNC is required if GWIN_NEED_WIDGET is TRUE."
- #warning "GWIN: GDISP_NEED_MULTITHREAD has been turned on for you."
+ #warning "GWIN: GDISP_NEED_MULTITHREAD is required if GWIN_NEED_WIDGET is TRUE. It has been turned on for you"
#endif
#undef GDISP_NEED_MULTITHREAD
#define GDISP_NEED_MULTITHREAD TRUE
@@ -134,17 +133,37 @@
#endif
#if GFX_USE_GDISP
- #if GDISP_NEED_MULTITHREAD && GDISP_NEED_ASYNC
- #error "GDISP: Only one of GDISP_NEED_MULTITHREAD and GDISP_NEED_ASYNC should be defined."
+ #if GDISP_TOTAL_CONTROLLERS > 1
+ #ifndef GDISP_CONTROLLER_LIST
+ #error "GDISP Multiple Controllers: You must specify a value for GDISP_CONTROLLER_LIST"
+ #endif
+ #ifndef GDISP_CONTROLLER_DISPLAYS
+ #error "GDISP Multiple Controllers: You must specify a value for GDISP_CONTROLLER_DISPLAYS"
+ #endif
+ #ifndef GDISP_PIXELFORMAT
+ #error "GDISP Multiple Controllers: You must specify a value for GDISP_PIXELFORMAT"
+ #endif
#endif
- #if GDISP_NEED_ASYNC && !(GFX_USE_GQUEUE && GQUEUE_NEED_GSYNC)
+ #if GDISP_NEED_AUTOFLUSH && GDISP_NEED_TIMERFLUSH
#if GFX_DISPLAY_RULE_WARNINGS
- #warning "GDISP: GDISP_NEED_ASYNC requires GFX_USE_GQUEUE and GQUEUE_NEED_GSYNC. They have been turned on for you."
+ #warning "GDISP: Both GDISP_NEED_AUTOFLUSH and GDISP_NEED_TIMERFLUSH has been set. GDISP_NEED_TIMERFLUSH has disabled for you."
+ #endif
+ #undef GDISP_NEED_TIMERFLUSH
+ #define GDISP_NEED_TIMERFLUSH FALSE
+ #endif
+ #if GDISP_NEED_TIMERFLUSH
+ #if GDISP_NEED_TIMERFLUSH < 50 || GDISP_NEED_TIMERFLUSH > 1200
+ #error "GDISP: GDISP_NEED_TIMERFLUSH has been set to an invalid value (FALSE, 50-1200)."
+ #endif
+ #if !GFX_USE_GTIMER
+ #if GFX_DISPLAY_RULE_WARNINGS
+ #warning "GDISP: GDISP_NEED_TIMERFLUSH has been set but GFX_USE_GTIMER has not been set. It has been turned on for you."
+ #endif
+ #undef GFX_USE_GTIMER
+ #define GFX_USE_GTIMER TRUE
+ #undef GDISP_NEED_MULTITHREAD
+ #define GDISP_NEED_MULTITHREAD TRUE
#endif
- #undef GFX_USE_GQUEUE
- #define GFX_USE_GQUEUE TRUE
- #undef GQUEUE_NEED_GSYNC
- #define GQUEUE_NEED_GSYNC TRUE
#endif
#if GDISP_NEED_ANTIALIAS && !GDISP_NEED_PIXELREAD
#if GDISP_HARDWARE_PIXELREAD
@@ -161,11 +180,11 @@
#endif
#if (defined(GDISP_INCLUDE_FONT_SMALL) && GDISP_INCLUDE_FONT_SMALL) || (defined(GDISP_INCLUDE_FONT_LARGER) && GDISP_INCLUDE_FONT_LARGER)
#if GFX_DISPLAY_RULE_WARNINGS
- #warning "GDISP: An old font (Small or Larger) has been defined. A single default font of DEJAVUSANS12 has been added instead."
+ #warning "GDISP: An old font (Small or Larger) has been defined. A single default font of UI2 has been added instead."
#warning "GDISP: Please see <$(GFXLIB)/include/gdisp/fonts/fonts.h> for a list of available font names."
#endif
- #undef GDISP_INCLUDE_FONT_DEJAVUSANS12
- #define GDISP_INCLUDE_FONT_DEJAVUSANS12 TRUE
+ #undef GDISP_INCLUDE_FONT_UI2
+ #define GDISP_INCLUDE_FONT_UI2 TRUE
#endif
#endif
@@ -196,9 +215,9 @@
#endif
#if GFX_USE_GTIMER
- #if GFX_USE_GDISP && !GDISP_NEED_MULTITHREAD && !GDISP_NEED_ASYNC
+ #if GFX_USE_GDISP && !GDISP_NEED_MULTITHREAD
#if GFX_DISPLAY_RULE_WARNINGS
- #warning "GTIMER: Neither GDISP_NEED_MULTITHREAD nor GDISP_NEED_ASYNC has been specified."
+ #warning "GTIMER: GDISP_NEED_MULTITHREAD has not been specified."
#warning "GTIMER: Make sure you are not performing any GDISP/GWIN drawing operations in the timer callback!"
#endif
#endif
diff --git a/include/ginput/mouse.h b/include/ginput/mouse.h
index 93537329..aa9864a9 100644
--- a/include/ginput/mouse.h
+++ b/include/ginput/mouse.h
@@ -56,6 +56,7 @@ typedef struct GEventMouse_t {
GMETA_MOUSE_CXTCLICK = 8 // For mice - The right button has just been depressed
// For touch - a long press has just occurred
} meta;
+ GDisplay * display; // The display this mouse is currently associated with.
} GEventMouse;
// Mouse/Touch Listen Flags - passed to geventAddSourceToListener()
@@ -84,7 +85,8 @@ extern "C" {
/**
* @brief Creates an instance of a mouse and returns the Source handler
- * @note hack: if the instance is 9999, no calibration will be performed!
+ * @note HACK: if the instance is 9999, it is treated as instance 0 except
+ * that no calibration will be performed!
*
* @param[in] instance The ID of the mouse input instance (from 0 to 9999)
*
@@ -93,6 +95,28 @@ extern "C" {
GSourceHandle ginputGetMouse(uint16_t instance);
/**
+ * @brief Assign the display associated with the mouse
+ * @note This only needs to be called if the mouse is associated with a display
+ * other than the current default display. It must be called before
+ * @p ginputGetMouse() if the new display is to be used during the calibration
+ * process. Other than calibration the display is used for range checking,
+ * and may also be used to display a mouse pointer.
+ *
+ * @param[in] instance The ID of the mouse input instance
+ * @param[in] g The GDisplay to which this mouse belongs
+ */
+ void ginputSetMouseDisplay(uint16_t instance, GDisplay *g);
+
+ /**
+ * @brief Get the display currently associated with the mouse
+ * @return A pointer to the display
+ *
+ * @param[in] instance The ID of the mouse input instance
+ * @param[in] g The GDisplay to which this mouse belongs
+ */
+ GDisplay *ginputGetMouseDisplay(uint16_t instance);
+
+ /**
* @brief Get the current mouse position and button status
* @note Unlinke a listener event, this status cannot record meta events such as
* "CLICK".
@@ -129,12 +153,11 @@ extern "C" {
* as the gdispGetMouse() routine may attempt to fetch calibration data and perform a startup calibration if there is no way to get it.
* If this is called after gdispGetMouse() has been called and the driver requires calibration storage, it will immediately save the
* data is has already obtained.
- * The 'requireFree' parameter indicates if the fetch buffer must be free()'d to deallocate the buffer provided by the Fetch routine.
*
* @param[in] instance The ID of the mouse input instance
* @param[in] fnsave The routine to save the data
* @param[in] fnload The routine to restore the data
- * @param[in] requireFree ToDo
+ * @param[in] requireFree TRUE if the buffer returned by the load function must be freed by the mouse code.
*/
void ginputSetMouseCalibrationRoutines(uint16_t instance, GMouseCalibrationSaveRoutine fnsave, GMouseCalibrationLoadRoutine fnload, bool_t requireFree);
diff --git a/include/gmisc/gmisc.h b/include/gmisc/gmisc.h
index 998dda50..ff3d0c76 100644
--- a/include/gmisc/gmisc.h
+++ b/include/gmisc/gmisc.h
@@ -51,6 +51,7 @@ typedef int32_t fixed;
*/
#define FIXED(x) ((fixed)(x)<<16) /* @< integer to fixed */
#define NONFIXED(x) ((x)>>16) /* @< fixed to integer */
+#define FIXED0_5 32768 /* @< 0.5 as a fixed (used for rounding) */
#define FP2FIXED(x) ((fixed)((x)*65536.0)) /* @< floating point to fixed */
#define FIXED2FP(x) ((double)(x)/65536.0) /* @< fixed to floating point */
/* @} */
@@ -183,6 +184,23 @@ extern "C" {
/** @} */
#endif
+#if GMISC_NEED_INVSQRT
+ /**
+ * @brief Fast inverse square root function (x^-1/2)
+ * @return The approximate inverse square root
+ *
+ * @param[in] n The number to find the inverse square root of
+ *
+ * @note This function generates an approximate result. Higher accuracy (at the expense
+ * of speed) can be obtained by modifying the source code (the necessary line
+ * is already there - just commented out).
+ * @note This function relies on the internal machine format of a float and a long.
+ * If your machine architecture is very unusual this function may not work.
+ *
+ * @api
+ */
+ float invsqrt(float n);
+#endif
#ifdef __cplusplus
}
#endif
diff --git a/include/gmisc/options.h b/include/gmisc/options.h
index d5cf5898..06f689ec 100644
--- a/include/gmisc/options.h
+++ b/include/gmisc/options.h
@@ -28,25 +28,50 @@
#define GMISC_NEED_ARRAYOPS FALSE
#endif
/**
- * @brief Include fast array based trig functions (sin, cos)
+ * @brief Include fast fixed point trig functions (sin, cos)
* @details Defaults to FALSE
*/
- #ifndef GMISC_NEED_FASTTRIG
- #define GMISC_NEED_FASTTRIG FALSE
+ #ifndef GMISC_NEED_FIXEDTRIG
+ #define GMISC_NEED_FIXEDTRIG FALSE
#endif
/**
- * @brief Include fast fixed point trig functions (sin, cos)
+ * @brief Include fast inverse square root (x^-1/2)
* @details Defaults to FALSE
*/
- #ifndef GMISC_NEED_FIXEDTRIG
- #define GMISC_NEED_FIXEDTRIG FALSE
+ #ifndef GMISC_NEED_INVSQRT
+ #define GMISC_NEED_INVSQRT FALSE
#endif
/**
* @}
*
- * @name GMISC Optional Sizing Parameters
+ * @name GMISC Optional Parameters
* @{
*/
+ /**
+ * @brief Modifies the @p invsqrt() function to assume a different integer to floating point endianness.
+ * @note Normally the floating point format and the integer format have
+ * the same endianness. Unfortunately there are some strange
+ * processors that don't eg. some very early ARM devices.
+ * For those where the endianness doesn't match you can fix it by
+ * defining GMISC_INVSQRT_MIXED_ENDIAN.
+ * @note This still assumes the processor is using an ieee floating point format.
+ *
+ * If you have a software floating point that uses a non-standard
+ * floating point format (or very strange hardware) then define
+ * GMISC_INVSQRT_REAL_SLOW and it will do it the hard way.
+ */
+ #ifndef GMISC_INVSQRT_MIXED_ENDIAN
+ #define GMISC_INVSQRT_MIXED_ENDIAN FALSE
+ #endif
+ /**
+ * @brief Modifies the @p invsqrt() function to do things the long slow way.
+ * @note This causes the @p invsqrt() function to work regardless of the
+ * processor floating point format.
+ * @note This makes the @p invsqrt() function very slow.
+ */
+ #ifndef GMISC_INVSQRT_REAL_SLOW
+ #define GMISC_INVSQRT_REAL_SLOW FALSE
+ #endif
/** @} */
#endif /* _GMISC_OPTIONS_H */
diff --git a/include/gwin/button.h b/include/gwin/button.h
index 13b135a3..d11764d6 100644
--- a/include/gwin/button.h
+++ b/include/gwin/button.h
@@ -59,6 +59,7 @@ extern "C" {
* @brief Create a button widget.
* @return NULL if there is no resultant drawing area, otherwise a window handle.
*
+ * @param[in] g The GDisplay to display this window on
* @param[in] gb The GButtonObject structure to initialise. If this is NULL the structure is dynamically allocated.
* @param[in] pInit The initialisation parameters
*
@@ -74,7 +75,8 @@ extern "C" {
*
* @api
*/
-GHandle gwinButtonCreate(GButtonObject *gb, const GWidgetInit *pInit);
+GHandle gwinGButtonCreate(GDisplay *g, GButtonObject *gb, const GWidgetInit *pInit);
+#define gwinButtonCreate(gb, pInit) gwinGButtonCreate(GDISP, gb, pInit)
/**
* @brief Is the button current pressed
diff --git a/include/gwin/checkbox.h b/include/gwin/checkbox.h
index 29ebe96e..946f7e4a 100644
--- a/include/gwin/checkbox.h
+++ b/include/gwin/checkbox.h
@@ -52,6 +52,7 @@ typedef struct GCheckboxObject {
* @brief Create a checkbox window.
* @return NULL if there is no resultant drawing area, otherwise a window handle.
*
+ * @param[in] g The GDisplay to display this window on
* @param[in] gb The GCheckboxObject structure to initialise. If this is NULL, the structure is dynamically allocated.
* @param[in] pInit The initialization parameters to use
*
@@ -67,7 +68,8 @@ typedef struct GCheckboxObject {
*
* @api
*/
-GHandle gwinCheckboxCreate(GCheckboxObject *gb, const GWidgetInit *pInit);
+GHandle gwinGCheckboxCreate(GDisplay *g, GCheckboxObject *gb, const GWidgetInit *pInit);
+#define gwinCheckboxCreate(gb, pInit) gwinGCheckboxCreate(GDISP, gb, pInit)
/**
* @brief Set the state of a checkbox
diff --git a/include/gwin/class_gwin.h b/include/gwin/class_gwin.h
index b3f630e3..62b1752e 100644
--- a/include/gwin/class_gwin.h
+++ b/include/gwin/class_gwin.h
@@ -150,6 +150,7 @@ extern "C" {
/**
* @brief Initialise (and allocate if necessary) the base GWIN object
*
+ * @param[in] g The GDisplay to use for this window
* @param[in] pgw The GWindowObject structure. If NULL one is allocated from the heap
* @param[in] pInit The user initialization parameters
* @param[in] vmt The virtual method table for the GWIN object
@@ -159,12 +160,13 @@ extern "C" {
*
* @notapi
*/
-GHandle _gwindowCreate(GWindowObject *pgw, const GWindowInit *pInit, const gwinVMT *vmt, uint16_t flags);
+GHandle _gwindowCreate(GDisplay *g, GWindowObject *pgw, const GWindowInit *pInit, const gwinVMT *vmt, uint16_t flags);
#if GWIN_NEED_WIDGET || defined(__DOXYGEN__)
/**
* @brief Initialise (and allocate if necessary) the base Widget object
*
+ * @param[in] g The GDisplay to display this window on
* @param[in] pgw The GWidgetObject structure. If NULL one is allocated from the heap
* @param[in] pInit The user initialization parameters
* @param[in] vmt The virtual method table for the Widget object
@@ -173,7 +175,7 @@ GHandle _gwindowCreate(GWindowObject *pgw, const GWindowInit *pInit, const gwinV
*
* @notapi
*/
- GHandle _gwidgetCreate(GWidgetObject *pgw, const GWidgetInit *pInit, const gwidgetVMT *vmt);
+ GHandle _gwidgetCreate(GDisplay *g, GWidgetObject *pgw, const GWidgetInit *pInit, const gwidgetVMT *vmt);
/**
* @brief Destroy the Widget object
diff --git a/include/gwin/console.h b/include/gwin/console.h
index c05c4ad2..ed65581e 100644
--- a/include/gwin/console.h
+++ b/include/gwin/console.h
@@ -50,6 +50,7 @@ extern "C" {
* @note Text in a console window supports newlines and will wrap text as required.
* @return NULL if there is no resultant drawing area, otherwise a window handle.
*
+ * @param[in] g The GDisplay to display this window on
* @param[in] gc The GConsoleObject structure to initialise. If this is NULL the structure is dynamically allocated.
* @param[in] pInit The initialization parameters to use
*
@@ -64,7 +65,8 @@ extern "C" {
*
* @api
*/
-GHandle gwinConsoleCreate(GConsoleObject *gc, const GWindowInit *pInit);
+GHandle gwinGConsoleCreate(GDisplay *g, GConsoleObject *gc, const GWindowInit *pInit);
+#define gwinConsoleCreate(gc, pInit) gwinGConsoleCreate(GDISP, gc, pInit)
#if GFX_USE_OS_CHIBIOS && GWIN_CONSOLE_USE_BASESTREAM
/**
diff --git a/include/gwin/graph.h b/include/gwin/graph.h
index fd99458d..65a64126 100644
--- a/include/gwin/graph.h
+++ b/include/gwin/graph.h
@@ -90,6 +90,7 @@ extern "C" {
* @brief Create a graph window.
* @return NULL if there is no resultant drawing area, otherwise a window handle.
*
+ * @param[in] g The GDisplay to display this window on
* @param[in] gg The GGraphObject structure to initialise. If this is NULL the structure is dynamically allocated.
* @param[in] pInit The initialization parameters to use
*
@@ -107,7 +108,8 @@ extern "C" {
*
* @api
*/
-GHandle gwinGraphCreate(GGraphObject *gg, const GWindowInit *pInit);
+GHandle gwinGGraphCreate(GDisplay *g, GGraphObject *gg, const GWindowInit *pInit);
+#define gwinGraphCreate(gg, pInit) gwinGGraphCreate(GDISP, gg, pInit)
/**
* @brief Set the style of the graphing operations.
diff --git a/include/gwin/gwin.h b/include/gwin/gwin.h
index 45e29b00..fa5ba613 100644
--- a/include/gwin/gwin.h
+++ b/include/gwin/gwin.h
@@ -38,6 +38,7 @@ typedef struct GWindowObject {
gfxQueueASyncItem wmq; // @< The next window (for the window manager)
#endif
const struct gwinVMT *vmt; // @< The VMT for this GWIN
+ GDisplay * display; // @< The display this window is on.
coord_t x, y; // @< Screen relative position
coord_t width, height; // @< Dimensions of this window
color_t color, bgcolor; // @< The current drawing colors
@@ -165,6 +166,7 @@ extern "C" {
* @brief Create a basic window.
* @return NULL if there is no resultant drawing area, otherwise a window handle.
*
+ * @param[in] g The GDisplay to display this window on
* @param[in] pgw The window structure to initialize. If this is NULL the structure is dynamically allocated.
* @param[in] pInit How to initialise the window
*
@@ -177,7 +179,8 @@ extern "C" {
*
* @api
*/
- GHandle gwinWindowCreate(GWindowObject *pgw, const GWindowInit *pInit);
+ GHandle gwinGWindowCreate(GDisplay *g, GWindowObject *pgw, const GWindowInit *pInit);
+ #define gwinWindowCreate(pgw, pInit) gwinGWindowCreate(GDISP, pgw, pInit);
/**
* @brief Destroy a window (of any type). Releases any dynamically allocated memory.
diff --git a/include/gwin/image.h b/include/gwin/image.h
index eae196e9..66dd0b94 100644
--- a/include/gwin/image.h
+++ b/include/gwin/image.h
@@ -47,6 +47,7 @@ extern "C" {
* @details Display's a picture.
* @return NULL if there is no resultant drawing area, otherwise the widget handle.
*
+ * @param[in] g The GDisplay to display this window on
* @param[in] widget The image widget structure to initialise. If this is NULL, the structure is dynamically allocated.
* @param[in] pInit The initialization parameters to use.
*
@@ -55,7 +56,8 @@ extern "C" {
*
* @api
*/
-GHandle gwinImageCreate(GImageObject *widget, GWindowInit *pInit);
+GHandle gwinGImageCreate(GDisplay *g, GImageObject *widget, GWindowInit *pInit);
+#define gwinImageCreate(w, pInit) gwinGImageCreate(GDISP, w, pInit)
/**
* @brief Sets the input routines that support reading the image from memory
diff --git a/include/gwin/label.h b/include/gwin/label.h
index 3156ca71..caa4c1d1 100644
--- a/include/gwin/label.h
+++ b/include/gwin/label.h
@@ -42,6 +42,7 @@ extern "C" {
* @brief Create a label widget.
* @details A label widget is a simple window which has a static text.
*
+ * @param[in] g The GDisplay to display this window on
* @param[in] widget The label structure to initialise. If this is NULL, the structure is dynamically allocated.
* @param[in] pInit The initialisation parameters to use.
*
@@ -49,7 +50,18 @@ extern "C" {
*
* @api
*/
-GHandle gwinLabelCreate(GLabelObject *widget, GWidgetInit *pInit);
+GHandle gwinGLabelCreate(GDisplay *g, GLabelObject *widget, GWidgetInit *pInit);
+#define gwinLabelCreate(w, pInit) gwinGLabelCreate(GDISP, w, pInit)
+
+/**
+ * @brief Border settings for the default rendering routine
+ *
+ * @param[in] gh The widget handle (must be a list handle)
+ * @param[in] border Shall a border be rendered?
+ *
+ * @api
+ */
+void gwinLabelSetBorder(GHandle gh, bool_t border);
/**
* @brief Border settings for the default rendering routine
diff --git a/include/gwin/list.h b/include/gwin/list.h
index b45e7767..11815d05 100644
--- a/include/gwin/list.h
+++ b/include/gwin/list.h
@@ -82,6 +82,7 @@ extern "C" {
* one toggle to a role, it will forget the previous toggle. Two roles are supported:
* Role 0 = toggle for down, role 1 = toggle for up
*
+ * @param[in] g The GDisplay to display this window on
* @param[in] widget The GListObject structure to initialize. If this is NULL, the structure is dynamically allocated.
* @param[in] pInit The initialization parameters to use
* @param[in] multiselect If TRUE the list is multi-select instead of single-select.
@@ -90,7 +91,20 @@ extern "C" {
*
* @api
*/
-GHandle gwinListCreate(GListObject *widget, GWidgetInit *pInit, bool_t multiselect);
+GHandle gwinGListCreate(GDisplay *g, GListObject *widget, GWidgetInit *pInit, bool_t multiselect);
+#define gwinListCreate(w, pInit, m) gwinGListCreate(GDISP, w, pInit, m)
+
+/**
+ * @brief Change the behaviour of the scroll bar
+ *
+ * @note Current possible values: @p scrollAlways and @p scrollAuto
+ *
+ * @param[in] gh The widget handle (must be a list handle)
+ * @param[in] flag The behaviour to be set
+ *
+ * @api
+ */
+void gwinListSetScroll(GHandle gh, scroll_t flag);
/**
* @brief Change the behaviour of the scroll bar
diff --git a/include/gwin/radio.h b/include/gwin/radio.h
index e59c526e..3ee2918f 100644
--- a/include/gwin/radio.h
+++ b/include/gwin/radio.h
@@ -59,6 +59,7 @@ extern "C" {
* @brief Create a radio widget.
* @return NULL if there is no resultant drawing area, otherwise a window handle.
*
+ * @param[in] g The GDisplay to display this window on
* @param[in] gb The GRadioObject structure to initialise. If this is NULL the structure is dynamically allocated.
* @param[in] pInit The initialisation parameters
* @param[in] group The group of radio buttons this radio button belongs to.
@@ -77,7 +78,8 @@ extern "C" {
*
* @api
*/
-GHandle gwinRadioCreate(GRadioObject *gb, const GWidgetInit *pInit, uint16_t group);
+GHandle gwinGRadioCreate(GDisplay *g, GRadioObject *gb, const GWidgetInit *pInit, uint16_t group);
+#define gwinRadioCreate(w, pInit, gr) gwinGRadioCreate(GDISP, w, pInit, gr)
/**
* @brief Press this radio button (and by definition unset any others in the group)
diff --git a/include/gwin/slider.h b/include/gwin/slider.h
index b037a621..8f87745c 100644
--- a/include/gwin/slider.h
+++ b/include/gwin/slider.h
@@ -58,6 +58,7 @@ extern "C" {
* @brief Create a slider window.
* @return NULL if there is no resultant drawing area, otherwise a window handle.
*
+ * @param[in] g The GDisplay to display this window on
* @param[in] gb The GSliderObject structure to initialise. If this is NULL the structure is dynamically allocated.
* @param[in] pInit The initialization parameters to use
*
@@ -77,7 +78,8 @@ extern "C" {
*
* @api
*/
-GHandle gwinSliderCreate(GSliderObject *gb, const GWidgetInit *pInit);
+GHandle gwinGSliderCreate(GDisplay *g, GSliderObject *gb, const GWidgetInit *pInit);
+#define gwinSliderCreate(w, pInit) gwinGSliderCreate(GDISP, w, pInit)
/**
* @brief Set the slider range.
diff --git a/releases.txt b/releases.txt
index 9a2d7aa6..d3a274b7 100644
--- a/releases.txt
+++ b/releases.txt
@@ -2,11 +2,32 @@
*** Releases ***
*****************************************************************************
-current release: 1.9
-
+current release: 2.0
*** changes after 1.9 ***
-
+FEATURE: GDISP Streaming API and demos.
+DEPRECATE: GDISP_NEED_ASYNC is now deprecated.
+DEPRECATE: 3rd party boing demo is now deprecated (replaced by GDISP Streaming demo)
+FIX: Remove GOS definitions from demo conf files so that it can be supplied by a makefile.
+FEATURE: Repair GDISP low level driver interfaces so they can now be included in the doxygen documentation.
+FEATURE: New driver interface for GDISP
+FEATURE: Multiple display support
+FEATURE: Multiple controller support
+FEATURE: Application pixel format no longer has to match the low level driver pixel format.
+FEATURE: Many more pixel formats are now supported.
+FEATURE: Many performance optimisations
+FEATURE: Vertical scrolling is now supported if the low level driver supports read_pixel.
+FEATURE: Add gdispFlush() for those controllers that need it
+FEATURE: Add GDISP_NEED_AUTOFLUSH and GDISP_NEED_TIMERFLUSH to automatically flush when required.
+FEATURE: Add support for generic portrait and landscape orientation modes
+FEATURE: Add macro GDISP_DEFAULT_ORIENTATION so an application can specify a default orientation.
+FEATURE: Driver files renamed to allow compiles when all object files go in the same directory
+FEATURE: New directory structure for board files. Predefined boards have all the hardware definitions predefined.
+FEATURE: Board defintions, example projects and makefiles for Win32.
+FEATURE: Board defintions, example projects and makefiles for X.
+FEATURE: Board defintions, example projects and makefiles for Olimex SAM7-EX256 board.
+FEATURE: Board defintions, example projects and makefiles for Mikromedia STM32-M4 board.
+FEATURE: New invsqrt() routine added to GMISC
*** changes after 1.8 ***
FEATURE: GWIN list boxes.
@@ -21,7 +42,6 @@ FEATURE: Added gwinListGetSelectedText()
FEATURE: Added gwinListSetScroll()
FEATURE: Added gwinLabelSetBorder()
-
*** changes after 1.7 ***
FEATURE: Rename of the project from ChibiOS/GFX to uGFX
FEATURE: Moved from github.com to bitbucket.org
diff --git a/src/gdisp/gdisp.c b/src/gdisp/gdisp.c
index 176839b4..2af30f15 100644
--- a/src/gdisp/gdisp.c
+++ b/src/gdisp/gdisp.c
@@ -19,481 +19,2492 @@
/* Include the low level driver information */
#include "gdisp/lld/gdisp_lld.h"
+#if 1
+ #undef INLINE
+ #define INLINE inline
+#else
+ #undef INLINE
+ #define INLINE
+#endif
+
+// Number of milliseconds for the startup logo - 0 means disabled.
+#define GDISP_STARTUP_LOGO_TIMEOUT 1000
+
+// The color to clear the display on startup
+#define GDISP_STARTUP_COLOR Black
+
/*===========================================================================*/
/* Driver local variables. */
/*===========================================================================*/
-#if GDISP_NEED_MULTITHREAD || GDISP_NEED_ASYNC
- static gfxMutex gdispMutex;
+// The controller array, the display array and the default display
+#if GDISP_TOTAL_CONTROLLERS > 1
+ typedef const struct GDISPVMT const VMTEL[1];
+ extern VMTEL GDISP_CONTROLLER_LIST;
+ static const struct GDISPVMT const * ControllerList[GDISP_TOTAL_CONTROLLERS] = {GDISP_CONTROLLER_LIST};
+ static const unsigned DisplayCountList[GDISP_TOTAL_CONTROLLERS] = {GDISP_CONTROLLER_DISPLAYS};
+#endif
+
+#if GDISP_NEED_TIMERFLUSH
+ static GTimer FlushTimer;
#endif
-#if GDISP_NEED_ASYNC
- #define GDISP_THREAD_STACK_SIZE 256 /* Just a number - not yet a reflection of actual use */
- #define GDISP_QUEUE_SIZE 8 /* We only allow a short queue */
+static GDisplay GDisplayArray[GDISP_TOTAL_DISPLAYS];
+GDisplay *GDISP = GDisplayArray;
- static gfxQueue gdispQueue;
- static gfxMutex gdispMsgsMutex;
- static gfxSem gdispMsgsSem;
- static gdisp_lld_msg_t gdispMsgs[GDISP_QUEUE_SIZE];
- static DECLARE_THREAD_STACK(waGDISPThread, GDISP_THREAD_STACK_SIZE);
+#if GDISP_NEED_MULTITHREAD
+ #define MUTEX_INIT(g) gfxMutexInit(&(g)->mutex)
+ #define MUTEX_ENTER(g) gfxMutexEnter(&(g)->mutex)
+ #define MUTEX_EXIT(g) gfxMutexExit(&(g)->mutex)
+#else
+ #define MUTEX_INIT(g)
+ #define MUTEX_ENTER(g)
+ #define MUTEX_EXIT(g)
#endif
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
+#define NEED_CLIPPING (GDISP_HARDWARE_CLIP != TRUE && (GDISP_NEED_VALIDATION || GDISP_NEED_CLIP))
+
+#if !NEED_CLIPPING
+ #define TEST_CLIP_AREA(g)
+#elif GDISP_HARDWARE_CLIP == HARDWARE_AUTODETECT
+ #define TEST_CLIP_AREA(g) \
+ if (!g->vmt->setclip) { \
+ if ((g)->p.x < (g)->clipx0) { (g)->p.cx -= (g)->clipx0 - (g)->p.x; (g)->p.x = (g)->clipx0; } \
+ if ((g)->p.y < (g)->clipy0) { (g)->p.cy -= (g)->clipy0 - (g)->p.y; (g)->p.y = (g)->clipy0; } \
+ if ((g)->p.x + (g)->p.cx > (g)->clipx1) (g)->p.cx = (g)->clipx1 - (g)->p.x; \
+ if ((g)->p.y + (g)->p.cy > (g)->clipy1) (g)->p.cy = (g)->clipy1 - (g)->p.y; \
+ } \
+ if ((g)->p.cx > 0 && (g)->p.cy > 0)
+#else
+ #define TEST_CLIP_AREA(g) \
+ if ((g)->p.x < (g)->clipx0) { (g)->p.cx -= (g)->clipx0 - (g)->p.x; (g)->p.x = (g)->clipx0; } \
+ if ((g)->p.y < (g)->clipy0) { (g)->p.cy -= (g)->clipy0 - (g)->p.y; (g)->p.y = (g)->clipy0; } \
+ if ((g)->p.x + (g)->p.cx > (g)->clipx1) (g)->p.cx = (g)->clipx1 - (g)->p.x; \
+ if ((g)->p.y + (g)->p.cy > (g)->clipy1) (g)->p.cy = (g)->clipy1 - (g)->p.y; \
+ if ((g)->p.cx > 0 && (g)->p.cy > 0)
+#endif
-#if GDISP_NEED_ASYNC
- static DECLARE_THREAD_FUNCTION(GDISPThreadHandler, arg) {
- (void)arg;
- gdisp_lld_msg_t *pmsg;
+/*==========================================================================*/
+/* Internal functions. */
+/*==========================================================================*/
- while(1) {
- /* Wait for msg with work to do. */
- pmsg = (gdisp_lld_msg_t *)gfxQueueGet(&gdispQueue, TIME_INFINITE);
+#if GDISP_HARDWARE_STREAM_POS && GDISP_HARDWARE_STREAM_WRITE
+ static INLINE void setglobalwindow(GDisplay *g) {
+ coord_t x, y;
+ x = g->p.x; y = g->p.y;
+ g->p.x = g->p.y = 0;
+ g->p.cx = g->g.Width; g->p.cy = g->g.Height;
+ gdisp_lld_write_start(g);
+ g->p.x = x; g->p.y = y;
+ g->flags |= GDISP_FLG_SCRSTREAM;
+ }
+#endif
- /* OK - we need to obtain the mutex in case a synchronous operation is occurring */
- gfxMutexEnter(&gdispMutex);
+#if GDISP_NEED_AUTOFLUSH && GDISP_HARDWARE_FLUSH == HARDWARE_AUTODETECT
+ #define autoflush_stopdone(g) if (g->vmt->flush) gdisp_lld_flush(g)
+#elif GDISP_NEED_AUTOFLUSH && GDISP_HARDWARE_FLUSH
+ #define autoflush_stopdone(g) gdisp_lld_flush(g)
+#else
+ #define autoflush_stopdone(g)
+#endif
- gdisp_lld_msg_dispatch(pmsg);
+#if GDISP_HARDWARE_STREAM_POS && GDISP_HARDWARE_STREAM_WRITE
+ #define autoflush(g) \
+ { \
+ if ((g->flags & GDISP_FLG_SCRSTREAM)) { \
+ gdisp_lld_write_stop(g); \
+ g->flags &= ~GDISP_FLG_SCRSTREAM; \
+ } \
+ autoflush_stopdone(g); \
+ }
+#else
+ #define autoflush(g) autoflush_stopdone(g)
+#endif
- /* Mark the message as free */
- pmsg->action = GDISP_LLD_MSG_NOP;
+// drawpixel(g)
+// Parameters: x,y
+// Alters: cx, cy (if using streaming)
+// Does not clip
+static INLINE void drawpixel(GDisplay *g) {
- gfxMutexExit(&gdispMutex);
+ // Best is hardware accelerated pixel draw
+ #if GDISP_HARDWARE_DRAWPIXEL
+ #if GDISP_HARDWARE_DRAWPIXEL == HARDWARE_AUTODETECT
+ if (g->vmt->pixel)
+ #endif
+ {
+ gdisp_lld_draw_pixel(g);
+ return;
}
- return 0;
- }
+ #endif
+
+ // Next best is cursor based streaming
+ #if GDISP_HARDWARE_DRAWPIXEL != TRUE && GDISP_HARDWARE_STREAM_POS && GDISP_HARDWARE_STREAM_WRITE
+ #if GDISP_HARDWARE_STREAM_POS == HARDWARE_AUTODETECT
+ if (g->vmt->writepos)
+ #endif
+ {
+ if (!(g->flags & GDISP_FLG_SCRSTREAM))
+ setglobalwindow(g);
+ gdisp_lld_write_pos(g);
+ gdisp_lld_write_color(g);
+ return;
+ }
+ #endif
- static gdisp_lld_msg_t *gdispAllocMsg(gdisp_msgaction_t action) {
- gdisp_lld_msg_t *p;
+ // Worst is general streaming
+ #if GDISP_HARDWARE_DRAWPIXEL != TRUE && GDISP_HARDWARE_STREAM_POS != TRUE && GDISP_HARDWARE_STREAM_WRITE
+ // The following test is unneeded because we are guaranteed to have streaming if we don't have drawpixel
+ //#if GDISP_HARDWARE_STREAM_WRITE == HARDWARE_AUTODETECT
+ // if (g->vmt->writestart)
+ //#endif
+ {
+ g->p.cx = g->p.cy = 1;
+ gdisp_lld_write_start(g);
+ gdisp_lld_write_color(g);
+ gdisp_lld_write_stop(g);
+ return;
+ }
+ #endif
+}
- while(1) { /* To be sure, to be sure */
+// drawpixel_clip(g)
+// Parameters: x,y
+// Alters: cx, cy (if using streaming)
+#if NEED_CLIPPING
+ static INLINE void drawpixel_clip(GDisplay *g) {
+ #if GDISP_HARDWARE_CLIP == HARDWARE_AUTODETECT
+ if (!g->vmt->setclip)
+ #endif
+ {
+ if (g->p.x < g->clipx0 || g->p.x >= g->clipx1 || g->p.y < g->clipy0 || g->p.y >= g->clipy1)
+ return;
+ }
+ drawpixel(g);
+ }
+#else
+ #define drawpixel_clip(g) drawpixel(g)
+#endif
- /* Wait for a slot */
- gfxSemWait(&gdispMsgsSem, TIME_INFINITE);
+// fillarea(g)
+// Parameters: x,y cx,cy and color
+// Alters: nothing
+// Note: This is not clipped
+// Resets the streaming area if GDISP_HARDWARE_STREAM_WRITE and GDISP_HARDWARE_STREAM_POS is set.
+static INLINE void fillarea(GDisplay *g) {
+
+ // Best is hardware accelerated area fill
+ #if GDISP_HARDWARE_FILLS
+ #if GDISP_HARDWARE_FILLS == HARDWARE_AUTODETECT
+ if (g->vmt->fill)
+ #endif
+ {
+ gdisp_lld_fill_area(g);
+ return;
+ }
+ #endif
- /* Find the slot */
- gfxMutexEnter(&gdispMsgsMutex);
- for(p=gdispMsgs; p < &gdispMsgs[GDISP_QUEUE_SIZE]; p++) {
- if (p->action == GDISP_LLD_MSG_NOP) {
- /* Allocate it */
- p->action = action;
- gfxMutexExit(&gdispMsgsMutex);
- return p;
+ // Next best is hardware streaming
+ #if GDISP_HARDWARE_FILLS != TRUE && GDISP_HARDWARE_STREAM_WRITE
+ #if GDISP_HARDWARE_STREAM_WRITE == HARDWARE_AUTODETECT
+ if (g->vmt->writestart)
+ #endif
+ {
+ uint32_t area;
+
+ #if GDISP_HARDWARE_STREAM_POS
+ if ((g->flags & GDISP_FLG_SCRSTREAM)) {
+ gdisp_lld_write_stop(g);
+ g->flags &= ~GDISP_FLG_SCRSTREAM;
}
- }
- gfxMutexExit(&gdispMsgsMutex);
+ #endif
+
+ area = (uint32_t)g->p.cx * g->p.cy;
+ gdisp_lld_write_start(g);
+ #if GDISP_HARDWARE_STREAM_POS
+ #if GDISP_HARDWARE_STREAM_POS == HARDWARE_AUTODETECT
+ if (g->vmt->writepos)
+ #endif
+ gdisp_lld_write_pos(g);
+ #endif
+ for(; area; area--)
+ gdisp_lld_write_color(g);
+ gdisp_lld_write_stop(g);
+ return;
+ }
+ #endif
- /* Oops - none found, try again */
- gfxSemSignal(&gdispMsgsSem);
+ // Worst is pixel drawing
+ #if GDISP_HARDWARE_FILLS != TRUE && GDISP_HARDWARE_STREAM_WRITE != TRUE && GDISP_HARDWARE_DRAWPIXEL
+ // The following test is unneeded because we are guaranteed to have draw pixel if we don't have streaming
+ //#if GDISP_HARDWARE_DRAWPIXEL == HARDWARE_AUTODETECT
+ // if (g->vmt->pixel)
+ //#endif
+ {
+ coord_t x0, y0, x1, y1;
+
+ x0 = g->p.x;
+ y0 = g->p.y;
+ x1 = g->p.x + g->p.cx;
+ y1 = g->p.y + g->p.cy;
+ for(; g->p.y < y1; g->p.y++, g->p.x = x0)
+ for(; g->p.x < x1; g->p.x++)
+ gdisp_lld_draw_pixel(g);
+ g->p.y = y0;
+ return;
}
+ #endif
+}
+
+// Parameters: x,y and x1
+// Alters: x,y x1,y1 cx,cy
+// Assumes the window covers the screen and a write_stop() will occur later
+// if GDISP_HARDWARE_STREAM_WRITE and GDISP_HARDWARE_STREAM_POS is set.
+static void hline_clip(GDisplay *g) {
+ // Swap the points if necessary so it always goes from x to x1
+ if (g->p.x1 < g->p.x) {
+ g->p.cx = g->p.x; g->p.x = g->p.x1; g->p.x1 = g->p.cx;
}
-#endif
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
+ // Clipping
+ #if NEED_CLIPPING
+ #if GDISP_HARDWARE_CLIP == HARDWARE_AUTODETECT
+ if (!g->vmt->setclip)
+ #endif
+ {
+ if (g->p.y < g->clipy0 || g->p.y >= g->clipy1) return;
+ if (g->p.x < g->clipx0) g->p.x = g->clipx0;
+ if (g->p.x1 >= g->clipx1) g->p.x1 = g->clipx1 - 1;
+ if (g->p.x1 < g->p.x) return;
+ }
+ #endif
-/* Our module initialiser */
-#if GDISP_NEED_MULTITHREAD
- void _gdispInit(void) {
- /* Initialise Mutex */
- gfxMutexInit(&gdispMutex);
-
- /* Initialise driver */
- gfxMutexEnter(&gdispMutex);
- gdisp_lld_init();
- gfxMutexExit(&gdispMutex);
- }
-#elif GDISP_NEED_ASYNC
- void _gdispInit(void) {
- unsigned i;
- gfxThreadHandle hth;
-
- /* Mark all the Messages as free */
- for(i=0; i < GDISP_QUEUE_SIZE; i++)
- gdispMsgs[i].action = GDISP_LLD_MSG_NOP;
-
- /* Initialise our Queue, Mutex's and Counting Semaphore.
- * A Mutex is required as well as the Queue and Thread because some calls have to be synchronous.
- * Synchronous calls get handled by the calling thread, asynchronous by our worker thread.
- */
- gfxQueueInit(&gdispQueue);
- gfxMutexInit(&gdispMutex);
- gfxMutexInit(&gdispMsgsMutex);
- gfxSemInit(&gdispMsgsSem, GDISP_QUEUE_SIZE, GDISP_QUEUE_SIZE);
-
- hth = gfxThreadCreate(waGDISPThread, sizeof(waGDISPThread), GDISP_THREAD_PRIORITY, GDISPThreadHandler, NULL);
- if (hth) gfxThreadClose(hth);
-
- /* Initialise driver - synchronous */
- gfxMutexEnter(&gdispMutex);
- gdisp_lld_init();
- gfxMutexExit(&gdispMutex);
+ // This is an optimization for the point case. It is only worthwhile however if we
+ // have hardware fills or if we support both hardware pixel drawing and hardware streaming
+ #if GDISP_HARDWARE_FILLS || (GDISP_HARDWARE_DRAWPIXEL && GDISP_HARDWARE_STREAM_WRITE)
+ // Is this a point
+ if (g->p.x == g->p.x1) {
+ drawpixel(g);
+ return;
+ }
+ #endif
+
+ // Best is hardware accelerated area fill
+ #if GDISP_HARDWARE_FILLS
+ #if GDISP_HARDWARE_FILLS == HARDWARE_AUTODETECT
+ if (g->vmt->fill)
+ #endif
+ {
+ g->p.cx = g->p.x1 - g->p.x + 1;
+ g->p.cy = 1;
+ gdisp_lld_fill_area(g);
+ return;
+ }
+ #endif
+
+ // Next best is cursor based streaming
+ #if GDISP_HARDWARE_FILLS != TRUE && GDISP_HARDWARE_STREAM_POS && GDISP_HARDWARE_STREAM_WRITE
+ #if GDISP_HARDWARE_STREAM_POS == HARDWARE_AUTODETECT
+ if (g->vmt->writepos)
+ #endif
+ {
+ if (!(g->flags & GDISP_FLG_SCRSTREAM))
+ setglobalwindow(g);
+ g->p.cx = g->p.x1 - g->p.x + 1;
+ gdisp_lld_write_pos(g);
+ do { gdisp_lld_write_color(g); } while(--g->p.cx);
+ return;
+ }
+ #endif
+
+ // Next best is streaming
+ #if GDISP_HARDWARE_FILLS != TRUE && GDISP_HARDWARE_STREAM_POS != TRUE && GDISP_HARDWARE_STREAM_WRITE
+ #if GDISP_HARDWARE_STREAM_WRITE == HARDWARE_AUTODETECT
+ if (g->vmt->writestart)
+ #endif
+ {
+ g->p.cx = g->p.x1 - g->p.x + 1;
+ g->p.cy = 1;
+ gdisp_lld_write_start(g);
+ do { gdisp_lld_write_color(g); } while(--g->p.cx);
+ gdisp_lld_write_stop(g);
+ return;
+ }
+ #endif
+
+ // Worst is drawing pixels
+ #if GDISP_HARDWARE_FILLS != TRUE && GDISP_HARDWARE_STREAM_WRITE != TRUE && GDISP_HARDWARE_DRAWPIXEL
+ // The following test is unneeded because we are guaranteed to have draw pixel if we don't have streaming
+ //#if GDISP_HARDWARE_DRAWPIXEL == HARDWARE_AUTODETECT
+ // if (g->vmt->pixel)
+ //#endif
+ {
+ for(; g->p.x <= g->p.x1; g->p.x++)
+ gdisp_lld_draw_pixel(g);
+ return;
+ }
+ #endif
+}
+
+// Parameters: x,y and y1
+// Alters: x,y x1,y1 cx,cy
+static void vline_clip(GDisplay *g) {
+ // Swap the points if necessary so it always goes from y to y1
+ if (g->p.y1 < g->p.y) {
+ g->p.cy = g->p.y; g->p.y = g->p.y1; g->p.y1 = g->p.cy;
}
-#else
- void _gdispInit(void) {
- gdisp_lld_init();
+
+ // Clipping
+ #if NEED_CLIPPING
+ #if GDISP_HARDWARE_CLIP == HARDWARE_AUTODETECT
+ if (!g->vmt->setclip)
+ #endif
+ {
+ if (g->p.x < g->clipx0 || g->p.x >= g->clipx1) return;
+ if (g->p.y < g->clipy0) g->p.y = g->clipy0;
+ if (g->p.y1 >= g->clipy1) g->p.y1 = g->clipy1 - 1;
+ if (g->p.y1 < g->p.y) return;
+ }
+ #endif
+
+ // This is an optimization for the point case. It is only worthwhile however if we
+ // have hardware fills or if we support both hardware pixel drawing and hardware streaming
+ #if GDISP_HARDWARE_FILLS || (GDISP_HARDWARE_DRAWPIXEL && GDISP_HARDWARE_STREAM_WRITE) || (GDISP_HARDWARE_STREAM_POS && GDISP_HARDWARE_STREAM_WRITE)
+ // Is this a point
+ if (g->p.y == g->p.y1) {
+ drawpixel(g);
+ return;
+ }
+ #endif
+
+ // Best is hardware accelerated area fill
+ #if GDISP_HARDWARE_FILLS
+ #if GDISP_HARDWARE_FILLS == HARDWARE_AUTODETECT
+ if (g->vmt->fill)
+ #endif
+ {
+ g->p.cy = g->p.y1 - g->p.y + 1;
+ g->p.cx = 1;
+ gdisp_lld_fill_area(g);
+ return;
+ }
+ #endif
+
+ // Next best is streaming
+ #if GDISP_HARDWARE_FILLS != TRUE && GDISP_HARDWARE_STREAM_WRITE
+ #if GDISP_HARDWARE_STREAM_WRITE == HARDWARE_AUTODETECT
+ if (g->vmt->writestart)
+ #endif
+ {
+ #if GDISP_HARDWARE_STREAM_POS
+ if ((g->flags & GDISP_FLG_SCRSTREAM)) {
+ gdisp_lld_write_stop(g);
+ g->flags &= ~GDISP_FLG_SCRSTREAM;
+ }
+ #endif
+ g->p.cy = g->p.y1 - g->p.y + 1;
+ g->p.cx = 1;
+ gdisp_lld_write_start(g);
+ #if GDISP_HARDWARE_STREAM_POS
+ #if GDISP_HARDWARE_STREAM_POS == HARDWARE_AUTODETECT
+ if (g->vmt->writepos)
+ #endif
+ gdisp_lld_write_pos(g);
+ #endif
+ do { gdisp_lld_write_color(g); } while(--g->p.cy);
+ gdisp_lld_write_stop(g);
+ return;
+ }
+ #endif
+
+ // Worst is drawing pixels
+ #if GDISP_HARDWARE_FILLS != TRUE && GDISP_HARDWARE_STREAM_WRITE != TRUE && GDISP_HARDWARE_DRAWPIXEL
+ // The following test is unneeded because we are guaranteed to have draw pixel if we don't have streaming
+ //#if GDISP_HARDWARE_DRAWPIXEL == HARDWARE_AUTODETECT
+ // if (g->vmt->pixel)
+ //#endif
+ {
+ for(; g->p.y <= g->p.y1; g->p.y++)
+ gdisp_lld_draw_pixel(g);
+ return;
+ }
+ #endif
+}
+
+// Parameters: x,y and x1,y1
+// Alters: x,y x1,y1 cx,cy
+static void line_clip(GDisplay *g) {
+ int16_t dy, dx;
+ int16_t addx, addy;
+ int16_t P, diff, i;
+
+ // Is this a horizontal line (or a point)
+ if (g->p.y == g->p.y1) {
+ hline_clip(g);
+ return;
}
-#endif
-#if GDISP_NEED_MULTITHREAD
- bool_t gdispIsBusy(void) {
- return FALSE;
+ // Is this a vertical line (or a point)
+ if (g->p.x == g->p.x1) {
+ vline_clip(g);
+ return;
}
-#elif GDISP_NEED_ASYNC
- bool_t gdispIsBusy(void) {
- return !gfxQueueIsEmpty(&gdispQueue);
+
+ // Not horizontal or vertical
+
+ // Use Bresenham's line drawing algorithm.
+ // This should be replaced with fixed point slope based line drawing
+ // which is more efficient on modern processors as it branches less.
+ // When clipping is needed, all the clipping could also be done up front
+ // instead of on each pixel.
+
+ if (g->p.x1 >= g->p.x) {
+ dx = g->p.x1 - g->p.x;
+ addx = 1;
+ } else {
+ dx = g->p.x - g->p.x1;
+ addx = -1;
+ }
+ if (g->p.y1 >= g->p.y) {
+ dy = g->p.y1 - g->p.y;
+ addy = 1;
+ } else {
+ dy = g->p.y - g->p.y1;
+ addy = -1;
}
-#endif
-#if GDISP_NEED_MULTITHREAD
- void gdispClear(color_t color) {
- gfxMutexEnter(&gdispMutex);
- gdisp_lld_clear(color);
- gfxMutexExit(&gdispMutex);
+ if (dx >= dy) {
+ dy <<= 1;
+ P = dy - dx;
+ diff = P - dx;
+
+ for(i=0; i<=dx; ++i) {
+ drawpixel_clip(g);
+ if (P < 0) {
+ P += dy;
+ g->p.x += addx;
+ } else {
+ P += diff;
+ g->p.x += addx;
+ g->p.y += addy;
+ }
+ }
+ } else {
+ dx <<= 1;
+ P = dx - dy;
+ diff = P - dy;
+
+ for(i=0; i<=dy; ++i) {
+ drawpixel_clip(g);
+ if (P < 0) {
+ P += dx;
+ g->p.y += addy;
+ } else {
+ P += diff;
+ g->p.x += addx;
+ g->p.y += addy;
+ }
+ }
}
-#elif GDISP_NEED_ASYNC
- void gdispClear(color_t color) {
- gdisp_lld_msg_t *p = gdispAllocMsg(GDISP_LLD_MSG_CLEAR);
- p->clear.color = color;
- gfxQueuePut(&gdispQueue, &p->qi, TIME_IMMEDIATE);
+}
+
+#if GDISP_STARTUP_LOGO_TIMEOUT > 0
+ static void StatupLogoDisplay(GDisplay *g) {
+ coord_t x, y, w;
+ const coord_t * p;
+ static const coord_t blks[] = {
+ // u
+ 2, 6, 1, 10,
+ 3, 11, 4, 1,
+ 6, 6, 1, 6,
+ // G
+ 8, 0, 1, 12,
+ 9, 0, 6, 1,
+ 9, 11, 6, 1,
+ 14, 6, 1, 5,
+ 12, 6, 2, 1,
+ // F
+ 16, 0, 1, 12,
+ 17, 0, 6, 1,
+ 17, 6, 3, 1,
+ // X
+ 22, 6, 7, 1,
+ 24, 0, 1, 6,
+ 22, 7, 1, 5,
+ 28, 0, 1, 6,
+ 26, 7, 1, 5,
+ };
+
+ // Get a starting position and a scale
+ // Work on a 8x16 grid for each char, 4 chars (uGFX) in 1 line, using half the screen
+ w = g->g.Width/(8*4*2);
+ if (!w) w = 1;
+ x = (g->g.Width - (8*4)*w)/2;
+ y = (g->g.Height - (16*1)*w)/2;
+
+ // Simple but crude!
+ for(p = blks; p < blks+sizeof(blks)/sizeof(blks[0]); p+=4)
+ gdispGFillArea(g, x+p[0]*w, y+p[1]*w, p[2]*w, p[3]*w, Blue);
}
#endif
-#if GDISP_NEED_MULTITHREAD
- void gdispDrawPixel(coord_t x, coord_t y, color_t color) {
- gfxMutexEnter(&gdispMutex);
- gdisp_lld_draw_pixel(x, y, color);
- gfxMutexExit(&gdispMutex);
- }
-#elif GDISP_NEED_ASYNC
- void gdispDrawPixel(coord_t x, coord_t y, color_t color) {
- gdisp_lld_msg_t *p = gdispAllocMsg(GDISP_LLD_MSG_DRAWPIXEL);
- p->drawpixel.x = x;
- p->drawpixel.y = y;
- p->drawpixel.color = color;
- gfxQueuePut(&gdispQueue, &p->qi, TIME_IMMEDIATE);
+#if GDISP_NEED_TIMERFLUSH
+ static void FlushTimerFn(void *param) {
+ GDisplay * g;
+ (void) param;
+
+ for(g = GDisplayArray; g < &GDisplayArray[GDISP_TOTAL_DISPLAYS]; g++)
+ gdispGFlush(g);
}
#endif
-
-#if GDISP_NEED_MULTITHREAD
- void gdispDrawLine(coord_t x0, coord_t y0, coord_t x1, coord_t y1, color_t color) {
- gfxMutexEnter(&gdispMutex);
- gdisp_lld_draw_line(x0, y0, x1, y1, color);
- gfxMutexExit(&gdispMutex);
- }
-#elif GDISP_NEED_ASYNC
- void gdispDrawLine(coord_t x0, coord_t y0, coord_t x1, coord_t y1, color_t color) {
- gdisp_lld_msg_t *p = gdispAllocMsg(GDISP_LLD_MSG_DRAWLINE);
- p->drawline.x0 = x0;
- p->drawline.y0 = y0;
- p->drawline.x1 = x1;
- p->drawline.y1 = y1;
- p->drawline.color = color;
- gfxQueuePut(&gdispQueue, &p->qi, TIME_IMMEDIATE);
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/* Our module initialiser */
+void _gdispInit(void) {
+ GDisplay *g;
+ uint16_t i;
+ #if GDISP_TOTAL_CONTROLLERS > 1
+ uint16_t j;
+ #endif
+
+ /* Initialise driver */
+ #if GDISP_TOTAL_CONTROLLERS > 1
+ for(g = GDisplayArray, j=0; j < GDISP_TOTAL_CONTROLLERS; j++)
+ for(i = 0; i < DisplayCountList[j]; g++, i++) {
+ g->vmt = ControllerList[j];
+ g->systemdisplay = j*GDISP_TOTAL_CONTROLLERS+i;
+ g->controllerdisplay = i;
+ #else
+ for(g = GDisplayArray, i = 0; i < GDISP_TOTAL_DISPLAYS; g++, i++) {
+ g->systemdisplay = i;
+ g->controllerdisplay = i;
+ #endif
+ MUTEX_INIT(g);
+ MUTEX_ENTER(g);
+ g->flags = 0;
+ gdisp_lld_init(g);
+
+ #if defined(GDISP_DEFAULT_ORIENTATION) && GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL
+ g->p.x = GDISP_CONTROL_ORIENTATION;
+ g->p.ptr = (void *)GDISP_DEFAULT_ORIENTATION;
+ #if GDISP_HARDWARE_CONTROL == HARDWARE_AUTODETECT
+ if (g->vmt->control)
+ #endif
+ gdisp_lld_control(g);
+ #endif
+
+ // Set the initial clipping region
+ #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
+
+ // Best is hardware clipping
+ #if GDISP_HARDWARE_CLIP
+ #if GDISP_HARDWARE_CLIP == HARDWARE_AUTODETECT
+ if (g->vmt->setclip)
+ #endif
+ {
+ g->p.x = 0;
+ g->p.y = 0;
+ g->p.cx = g->g.Width;
+ g->p.cy = g->g.Height;
+ gdisp_lld_set_clip(g);
+ }
+ #if GDISP_HARDWARE_CLIP == HARDWARE_AUTODETECT
+ else
+ #endif
+ #endif
+
+ // Worst is software clipping
+ #if GDISP_HARDWARE_CLIP != TRUE
+ {
+ g->clipx0 = 0;
+ g->clipy0 = 0;
+ g->clipx1 = g->g.Width;
+ g->clipy1 = g->g.Height;
+ }
+ #endif
+ #endif
+ MUTEX_EXIT(g);
+ gdispGClear(g, GDISP_STARTUP_COLOR);
+ #if GDISP_STARTUP_LOGO_TIMEOUT > 0
+ StatupLogoDisplay(g);
+ #endif
+ #if !GDISP_NEED_AUTOFLUSH && GDISP_HARDWARE_FLUSH
+ gdispGFlush(g);
+ #endif
}
-#endif
+ #if GDISP_STARTUP_LOGO_TIMEOUT > 0
+ gfxSleepMilliseconds(GDISP_STARTUP_LOGO_TIMEOUT);
+ for(g = GDisplayArray, i = 0; i < GDISP_TOTAL_DISPLAYS; g++, i++) {
+ gdispGClear(g, GDISP_STARTUP_COLOR);
+ #if !GDISP_NEED_AUTOFLUSH && GDISP_HARDWARE_FLUSH
+ gdispGFlush(g);
+ #endif
+ }
+ #endif
-#if GDISP_NEED_MULTITHREAD
- void gdispFillArea(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
- gfxMutexEnter(&gdispMutex);
- gdisp_lld_fill_area(x, y, cx, cy, color);
- gfxMutexExit(&gdispMutex);
- }
-#elif GDISP_NEED_ASYNC
- void gdispFillArea(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
- gdisp_lld_msg_t *p = gdispAllocMsg(GDISP_LLD_MSG_FILLAREA);
- p->fillarea.x = x;
- p->fillarea.y = y;
- p->fillarea.cx = cx;
- p->fillarea.cy = cy;
- p->fillarea.color = color;
- gfxQueuePut(&gdispQueue, &p->qi, TIME_IMMEDIATE);
+ #if GDISP_NEED_TIMERFLUSH
+ gtimerInit(&FlushTimer);
+ gtimerStart(&FlushTimer, FlushTimerFn, 0, TRUE, GDISP_NEED_TIMERFLUSH);
+ #endif
+}
+
+GDisplay *gdispGetDisplay(unsigned display) {
+ if (display >= GDISP_TOTAL_DISPLAYS)
+ return 0;
+ return &GDisplayArray[display];
+}
+
+void gdispSetDisplay(GDisplay *g) {
+ if (g) GDISP = g;
+}
+
+void gdispGFlush(GDisplay *g) {
+ #if GDISP_HARDWARE_FLUSH
+ #if GDISP_HARDWARE_FLUSH == HARDWARE_AUTODETECT
+ if (g->vmt->flush)
+ #endif
+ {
+ MUTEX_ENTER(g);
+ gdisp_lld_flush(g);
+ MUTEX_EXIT(g);
+ }
+ #else
+ (void) g;
+ #endif
+}
+
+#if GDISP_NEED_STREAMING
+ void gdispGStreamStart(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy) {
+ MUTEX_ENTER(g);
+
+ #if NEED_CLIPPING
+ #if GDISP_HARDWARE_CLIP == HARDWARE_AUTODETECT
+ if (!g->vmt->setclip)
+ #endif
+ // Test if the area is valid - if not then exit
+ if (x < g->clipx0 || x+cx > g->clipx1 || y < g->clipy0 || y+cy > g->clipy1) {
+ MUTEX_EXIT(g);
+ return;
+ }
+ #endif
+
+ g->flags |= GDISP_FLG_INSTREAM;
+
+ // Best is hardware streaming
+ #if GDISP_HARDWARE_STREAM_WRITE
+ #if GDISP_HARDWARE_STREAM_WRITE == HARDWARE_AUTODETECT
+ if (g->vmt->writestart)
+ #endif
+ {
+ g->p.x = x;
+ g->p.y = y;
+ g->p.cx = cx;
+ g->p.cy = cy;
+ gdisp_lld_write_start(g);
+ #if GDISP_HARDWARE_STREAM_POS
+ #if GDISP_HARDWARE_STREAM_POS == HARDWARE_AUTODETECT
+ if (g->vmt->writepos)
+ #endif
+ gdisp_lld_write_pos(g);
+ #endif
+ return;
+ }
+ #endif
+
+ // Worst - save the parameters and use pixel drawing and/or area fills
+ #if GDISP_HARDWARE_STREAM_WRITE != TRUE && GDISP_HARDWARE_DRAWPIXEL
+ // The following test is unneeded because we are guaranteed to have draw pixel if we don't have streaming
+ //#if GDISP_HARDWARE_DRAWPIXEL == HARDWARE_AUTODETECT
+ // if (g->vmt->pixel)
+ //#endif
+ {
+ // Use x,y as the current position, x1,y1 as the save position and x2,y2 as the end position, cx = bufpos
+ g->p.x1 = g->p.x = x;
+ g->p.y1 = g->p.y = y;
+ g->p.x2 = x + cx;
+ g->p.y2 = y + cy;
+ #if (GDISP_LINEBUF_SIZE != 0 && GDISP_HARDWARE_BITFILLS) || GDISP_HARDWARE_FILLS
+ g->p.cx = 0;
+ g->p.cy = 1;
+ #endif
+ return;
+ }
+ #endif
+
+ // Don't release the mutex as gdispStreamEnd() will do that.
+ }
+
+ void gdispGStreamColor(GDisplay *g, color_t color) {
+ #if !GDISP_HARDWARE_STREAM_WRITE && GDISP_LINEBUF_SIZE != 0 && GDISP_HARDWARE_BITFILLS
+ coord_t sx1, sy1;
+ #endif
+
+ // Don't touch the mutex as we should already own it
+
+ // Ignore this call if we are not streaming
+ if (!(g->flags & GDISP_FLG_INSTREAM))
+ return;
+
+ // Best is hardware streaming
+ #if GDISP_HARDWARE_STREAM_WRITE
+ #if GDISP_HARDWARE_STREAM_WRITE == HARDWARE_AUTODETECT
+ if (g->vmt->writestart)
+ #endif
+ {
+ g->p.color = color;
+ gdisp_lld_write_color(g);
+ return;
+ }
+ #endif
+
+ // Next best is to use bitfills with our line buffer
+ #if GDISP_HARDWARE_STREAM_WRITE != TRUE && GDISP_LINEBUF_SIZE != 0 && GDISP_HARDWARE_BITFILLS
+ #if GDISP_HARDWARE_BITFILLS == HARDWARE_AUTODETECT
+ if (g->vmt->blit)
+ #endif
+ {
+ g->linebuf[g->p.cx++] = color;
+ if (g->p.cx >= GDISP_LINEBUF_SIZE) {
+ sx1 = g->p.x1;
+ sy1 = g->p.y1;
+ g->p.x1 = 0;
+ g->p.y1 = 0;
+ g->p.ptr = (void *)g->linebuf;
+ gdisp_lld_blit_area(g);
+ g->p.x1 = sx1;
+ g->p.y1 = sy1;
+ g->p.x += g->p.cx;
+ g->p.cx = 0;
+ }
+
+ // Just wrap at end-of-line and end-of-buffer
+ if (g->p.x+g->p.cx >= g->p.x2) {
+ if (g->p.cx) {
+ sx1 = g->p.x1;
+ sy1 = g->p.y1;
+ g->p.x1 = 0;
+ g->p.y1 = 0;
+ g->p.ptr = (void *)g->linebuf;
+ gdisp_lld_blit_area(g);
+ g->p.x1 = sx1;
+ g->p.y1 = sy1;
+ g->p.cx = 0;
+ }
+ g->p.x = g->p.x1;
+ if (++g->p.y >= g->p.y2)
+ g->p.y = g->p.y1;
+ }
+ }
+ #endif
+
+ // Only slightly better than drawing pixels is to look for runs and use fillarea
+ #if GDISP_HARDWARE_STREAM_WRITE != TRUE && (GDISP_LINEBUF_SIZE == 0 || GDISP_HARDWARE_BITFILLS != TRUE) && GDISP_HARDWARE_FILLS
+ // We don't need to test for auto-detect on drawpixel as we know we have it because we don't have streaming.
+ #if GDISP_HARDWARE_FILLS == HARDWARE_AUTODETECT
+ if (g->vmt->fill)
+ #endif
+ {
+ if (!g->p.cx || g->p.color == color) {
+ g->p.cx++;
+ g->p.color = color;
+ } else {
+ if (g->p.cx == 1)
+ gdisp_lld_draw_pixel(g);
+ else
+ gdisp_lld_fill_area(g);
+ g->p.x += g->p.cx;
+ g->p.color = color;
+ g->p.cx = 1;
+ }
+ // Just wrap at end-of-line and end-of-buffer
+ if (g->p.x+g->p.cx >= g->p.x2) {
+ if (g->p.cx) {
+ if (g->p.cx == 1)
+ gdisp_lld_draw_pixel(g);
+ else
+ gdisp_lld_fill_area(g);
+ g->p.cx = 0;
+ }
+ g->p.x = g->p.x1;
+ if (++g->p.y >= g->p.y2)
+ g->p.y = g->p.y1;
+ }
+ return;
+ }
+ #endif
+
+ // Worst is using pixel drawing
+ #if GDISP_HARDWARE_STREAM_WRITE != TRUE && (GDISP_LINEBUF_SIZE == 0 || GDISP_HARDWARE_BITFILLS != TRUE) && GDISP_HARDWARE_FILLS != TRUE && GDISP_HARDWARE_DRAWPIXEL
+ // The following test is unneeded because we are guaranteed to have draw pixel if we don't have streaming
+ //#if GDISP_HARDWARE_DRAWPIXEL == HARDWARE_AUTODETECT
+ // if (g->vmt->pixel)
+ //#endif
+ {
+ g->p.color = color;
+ gdisp_lld_draw_pixel(g);
+
+ // Just wrap at end-of-line and end-of-buffer
+ if (++g->p.x >= g->p.x2) {
+ g->p.x = g->p.x1;
+ if (++g->p.y >= g->p.y2)
+ g->p.y = g->p.y1;
+ }
+ return;
+ }
+ #endif
+ }
+
+ void gdispGStreamStop(GDisplay *g) {
+ // Only release the mutex and end the stream if we are actually streaming.
+ if (!(g->flags & GDISP_FLG_INSTREAM))
+ return;
+
+ // Clear the flag
+ g->flags &= ~GDISP_FLG_INSTREAM;
+
+ // The cleanup below must match the streaming code above.
+
+ #if GDISP_HARDWARE_STREAM_WRITE
+ #if GDISP_HARDWARE_STREAM_WRITE == HARDWARE_AUTODETECT
+ if (g->vmt->writestart)
+ #endif
+ {
+ gdisp_lld_write_stop(g);
+ autoflush_stopdone(g);
+ MUTEX_EXIT(g);
+ return;
+ }
+ #endif
+
+ #if GDISP_HARDWARE_STREAM_WRITE != TRUE && GDISP_LINEBUF_SIZE != 0 && GDISP_HARDWARE_BITFILLS
+ #if GDISP_HARDWARE_BITFILLS == HARDWARE_AUTODETECT
+ if (g->vmt->blit)
+ #endif
+ {
+ if (g->p.cx) {
+ g->p.x1 = 0;
+ g->p.y1 = 0;
+ g->p.ptr = (void *)g->linebuf;
+ gdisp_lld_blit_area(g);
+ }
+ autoflush_stopdone(g);
+ MUTEX_EXIT(g);
+ return;
+ }
+ #endif
+
+ #if GDISP_HARDWARE_STREAM_WRITE != TRUE && (GDISP_LINEBUF_SIZE == 0 || GDISP_HARDWARE_BITFILLS != TRUE) && GDISP_HARDWARE_FILLS
+ // We don't need to test for auto-detect on drawpixel as we know we have it because we don't have streaming.
+ #if GDISP_HARDWARE_FILLS == HARDWARE_AUTODETECT
+ if (g->vmt->fill)
+ #endif
+ {
+ if (g->p.cx) {
+ if (g->p.cx == 1)
+ gdisp_lld_draw_pixel(g);
+ else
+ gdisp_lld_fill_area(g);
+ }
+ autoflush_stopdone(g);
+ MUTEX_EXIT(g);
+ return;
+ }
+ #endif
+
+ #if GDISP_HARDWARE_STREAM_WRITE != TRUE && (GDISP_LINEBUF_SIZE == 0 || GDISP_HARDWARE_BITFILLS != TRUE) && GDISP_HARDWARE_FILLS != TRUE
+ {
+ autoflush_stopdone(g);
+ MUTEX_EXIT(g);
+ }
+ #endif
}
#endif
+
+void gdispGDrawPixel(GDisplay *g, coord_t x, coord_t y, color_t color) {
+ MUTEX_ENTER(g);
+ g->p.x = x;
+ g->p.y = y;
+ g->p.color = color;
+ drawpixel_clip(g);
+ autoflush(g);
+ MUTEX_EXIT(g);
+}
-#if GDISP_NEED_MULTITHREAD
- void gdispBlitAreaEx(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx, coord_t srcy, coord_t srccx, const pixel_t *buffer) {
- gfxMutexEnter(&gdispMutex);
- gdisp_lld_blit_area_ex(x, y, cx, cy, srcx, srcy, srccx, buffer);
- gfxMutexExit(&gdispMutex);
- }
-#elif GDISP_NEED_ASYNC
- void gdispBlitAreaEx(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx, coord_t srcy, coord_t srccx, const pixel_t *buffer) {
- gdisp_lld_msg_t *p = gdispAllocMsg(GDISP_LLD_MSG_BLITAREA);
- p->blitarea.x = x;
- p->blitarea.y = y;
- p->blitarea.cx = cx;
- p->blitarea.cy = cy;
- p->blitarea.srcx = srcx;
- p->blitarea.srcy = srcy;
- p->blitarea.srccx = srccx;
- p->blitarea.buffer = buffer;
- gfxQueuePut(&gdispQueue, &p->qi, TIME_IMMEDIATE);
+void gdispGDrawLine(GDisplay *g, coord_t x0, coord_t y0, coord_t x1, coord_t y1, color_t color) {
+ MUTEX_ENTER(g);
+ g->p.x = x0;
+ g->p.y = y0;
+ g->p.x1 = x1;
+ g->p.y1 = y1;
+ g->p.color = color;
+ line_clip(g);
+ autoflush(g);
+ MUTEX_EXIT(g);
+}
+
+void gdispGClear(GDisplay *g, color_t color) {
+ // Note - clear() ignores the clipping area. It clears the screen.
+ MUTEX_ENTER(g);
+
+ // Best is hardware accelerated clear
+ #if GDISP_HARDWARE_CLEARS
+ #if GDISP_HARDWARE_CLEARS == HARDWARE_AUTODETECT
+ if (g->vmt->clear)
+ #endif
+ {
+ g->p.color = color;
+ gdisp_lld_clear(g);
+ autoflush_stopdone(g);
+ MUTEX_EXIT(g);
+ return;
+ }
+ #endif
+
+ // Next best is hardware accelerated area fill
+ #if GDISP_HARDWARE_CLEARS != TRUE && GDISP_HARDWARE_FILLS
+ #if GDISP_HARDWARE_FILLS == HARDWARE_AUTODETECT
+ if (g->vmt->fill)
+ #endif
+ {
+ g->p.x = g->p.y = 0;
+ g->p.cx = g->g.Width;
+ g->p.cy = g->g.Height;
+ g->p.color = color;
+ gdisp_lld_fill_area(g);
+ autoflush_stopdone(g);
+ MUTEX_EXIT(g);
+ return;
+ }
+ #endif
+
+ // Next best is streaming
+ #if GDISP_HARDWARE_CLEARS != TRUE && GDISP_HARDWARE_FILLS != TRUE && GDISP_HARDWARE_STREAM_WRITE
+ #if GDISP_HARDWARE_STREAM_WRITE == HARDWARE_AUTODETECT
+ if (g->vmt->writestart)
+ #endif
+ {
+ uint32_t area;
+
+ g->p.x = g->p.y = 0;
+ g->p.cx = g->g.Width;
+ g->p.cy = g->g.Height;
+ g->p.color = color;
+ area = (uint32_t)g->p.cx * g->p.cy;
+
+ gdisp_lld_write_start(g);
+ #if GDISP_HARDWARE_STREAM_POS
+ #if GDISP_HARDWARE_STREAM_POS == HARDWARE_AUTODETECT
+ if (g->vmt->writepos)
+ #endif
+ gdisp_lld_write_pos(g);
+ #endif
+ for(; area; area--)
+ gdisp_lld_write_color(g);
+ gdisp_lld_write_stop(g);
+ autoflush_stopdone(g);
+ MUTEX_EXIT(g);
+ return;
+ }
+ #endif
+
+ // Worst is drawing pixels
+ #if GDISP_HARDWARE_CLEARS != TRUE && GDISP_HARDWARE_FILLS != TRUE && GDISP_HARDWARE_STREAM_WRITE != TRUE && GDISP_HARDWARE_DRAWPIXEL
+ // The following test is unneeded because we are guaranteed to have draw pixel if we don't have streaming
+ //#if GDISP_HARDWARE_DRAWPIXEL == HARDWARE_AUTODETECT
+ // if (g->vmt->pixel)
+ //#endif
+ {
+ g->p.color = color;
+ for(g->p.y = 0; g->p.y < g->g.Height; g->p.y++)
+ for(g->p.x = 0; g->p.x < g->g.Width; g->p.x++)
+ gdisp_lld_draw_pixel(g);
+ autoflush_stopdone(g);
+ MUTEX_EXIT(g);
+ return;
+ }
+ #endif
+}
+
+void gdispGFillArea(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
+ MUTEX_ENTER(g);
+ g->p.x = x;
+ g->p.y = y;
+ g->p.cx = cx;
+ g->p.cy = cy;
+ g->p.color = color;
+ TEST_CLIP_AREA(g) {
+ fillarea(g);
}
-#endif
+ autoflush_stopdone(g);
+ MUTEX_EXIT(g);
+}
+
+void gdispGBlitArea(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx, coord_t srcy, coord_t srccx, const pixel_t *buffer) {
+ MUTEX_ENTER(g);
+
+ #if NEED_CLIPPING
+ #if GDISP_HARDWARE_CLIP == HARDWARE_AUTODETECT
+ if (!g->vmt->setclip)
+ #endif
+ {
+ // This is a different clipping to fillarea(g) as it needs to take into account srcx,srcy
+ if (x < g->clipx0) { cx -= g->clipx0 - x; srcx += g->clipx0 - x; x = g->clipx0; }
+ if (y < g->clipy0) { cy -= g->clipy0 - y; srcy += g->clipy0 - x; y = g->clipy0; }
+ if (x+cx > g->clipx1) cx = g->clipx1 - x;
+ if (y+cy > g->clipy1) cy = g->clipy1 - y;
+ if (srcx+cx > srccx) cx = srccx - srcx;
+ if (cx <= 0 || cy <= 0) { MUTEX_EXIT(g); return; }
+ }
+ #endif
+
+ // Best is hardware bitfills
+ #if GDISP_HARDWARE_BITFILLS
+ #if GDISP_HARDWARE_BITFILLS == HARDWARE_AUTODETECT
+ if (g->vmt->blit)
+ #endif
+ {
+ g->p.x = x;
+ g->p.y = y;
+ g->p.cx = cx;
+ g->p.cy = cy;
+ g->p.x1 = srcx;
+ g->p.y1 = srcy;
+ g->p.x2 = srccx;
+ g->p.ptr = (void *)buffer;
+ gdisp_lld_blit_area(g);
+ autoflush_stopdone(g);
+ MUTEX_EXIT(g);
+ return;
+ }
+ #endif
+
+ // Next best is hardware streaming
+ #if GDISP_HARDWARE_BITFILLS != TRUE && GDISP_HARDWARE_STREAM_WRITE
+ #if GDISP_HARDWARE_STREAM_WRITE == HARDWARE_AUTODETECT
+ if (g->vmt->writestart)
+ #endif
+ {
+ // Translate buffer to the real image data, use srcx,srcy as the end point, srccx as the buffer line gap
+ buffer += srcy*srccx+srcx;
+ srcx = x + cx;
+ srcy = y + cy;
+ srccx -= cx;
+
+ g->p.x = x;
+ g->p.y = y;
+ g->p.cx = cx;
+ g->p.cy = cy;
+ gdisp_lld_write_start(g);
+ #if GDISP_HARDWARE_STREAM_POS
+ #if GDISP_HARDWARE_STREAM_POS == HARDWARE_AUTODETECT
+ if (g->vmt->writepos)
+ #endif
+ gdisp_lld_write_pos(g);
+ #endif
+ for(g->p.y = y; g->p.y < srcy; g->p.y++, buffer += srccx) {
+ for(g->p.x = x; g->p.x < srcx; g->p.x++) {
+ g->p.color = *buffer++;
+ gdisp_lld_write_color(g);
+ }
+ }
+ gdisp_lld_write_stop(g);
+ autoflush_stopdone(g);
+ MUTEX_EXIT(g);
+ return;
+ }
+ #endif
+
+ // Only slightly better than drawing pixels is to look for runs and use fill area
+ #if GDISP_HARDWARE_BITFILLS != TRUE && GDISP_HARDWARE_STREAM_WRITE != TRUE && GDISP_HARDWARE_FILLS
+ // We don't need to test for auto-detect on drawpixel as we know we have it because we don't have streaming.
+ #if GDISP_HARDWARE_FILLS == HARDWARE_AUTODETECT
+ if (g->vmt->fill)
+ #endif
+ {
+ // Translate buffer to the real image data, use srcx,srcy as the end point, srccx as the buffer line gap
+ buffer += srcy*srccx+srcx;
+ srcx = x + cx;
+ srcy = y + cy;
+ srccx -= cx;
+
+ g->p.cy = 1;
+ for(g->p.y = y; g->p.y < srcy; g->p.y++, buffer += srccx) {
+ for(g->p.x=x; g->p.x < srcx; g->p.x += g->p.cx) {
+ g->p.cx=1;
+ g->p.color = *buffer++;
+ while(g->p.x+g->p.cx < srcx && *buffer == g->p.color) {
+ g->p.cx++;
+ buffer++;
+ }
+ if (g->p.cx == 1) {
+ gdisp_lld_draw_pixel(g);
+ } else {
+ gdisp_lld_fill_area(g);
+ }
+ }
+ }
+ autoflush_stopdone(g);
+ MUTEX_EXIT(g);
+ return;
+ }
+ #endif
+
+ // Worst is drawing pixels
+ #if GDISP_HARDWARE_BITFILLS != TRUE && GDISP_HARDWARE_STREAM_WRITE != TRUE && GDISP_HARDWARE_FILLS != TRUE && GDISP_HARDWARE_DRAWPIXEL
+ // The following test is unneeded because we are guaranteed to have draw pixel if we don't have streaming
+ //#if GDISP_HARDWARE_DRAWPIXEL == HARDWARE_AUTODETECT
+ // if (g->vmt->pixel)
+ //#endif
+ {
+ // Translate buffer to the real image data, use srcx,srcy as the end point, srccx as the buffer line gap
+ buffer += srcy*srccx+srcx;
+ srcx = x + cx;
+ srcy = y + cy;
+ srccx -= cx;
+
+ for(g->p.y = y; g->p.y < srcy; g->p.y++, buffer += srccx) {
+ for(g->p.x=x; g->p.x < srcx; g->p.x++) {
+ g->p.color = *buffer++;
+ gdisp_lld_draw_pixel(g);
+ }
+ }
+ autoflush_stopdone(g);
+ MUTEX_EXIT(g);
+ return;
+ }
+ #endif
+}
-#if (GDISP_NEED_CLIP && GDISP_NEED_MULTITHREAD)
- void gdispSetClip(coord_t x, coord_t y, coord_t cx, coord_t cy) {
- gfxMutexEnter(&gdispMutex);
- gdisp_lld_set_clip(x, y, cx, cy);
- gfxMutexExit(&gdispMutex);
- }
-#elif GDISP_NEED_CLIP && GDISP_NEED_ASYNC
- void gdispSetClip(coord_t x, coord_t y, coord_t cx, coord_t cy) {
- gdisp_lld_msg_t *p = gdispAllocMsg(GDISP_LLD_MSG_SETCLIP);
- p->setclip.x = x;
- p->setclip.y = y;
- p->setclip.cx = cx;
- p->setclip.cy = cy;
- gfxQueuePut(&gdispQueue, &p->qi, TIME_IMMEDIATE);
+#if GDISP_NEED_CLIP
+ void gdispGSetClip(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy) {
+ MUTEX_ENTER(g);
+
+ // Best is using hardware clipping
+ #if GDISP_HARDWARE_CLIP
+ #if GDISP_HARDWARE_CLIP == HARDWARE_AUTODETECT
+ if (g->vmt->setclip)
+ #endif
+ {
+ g->p.x = x;
+ g->p.y = y;
+ g->p.cx = cx;
+ g->p.cy = cy;
+ gdisp_lld_set_clip(g);
+ }
+ #if GDISP_HARDWARE_CLIP == HARDWARE_AUTODETECT
+ else
+ #endif
+ #endif
+
+ // Worst is using software clipping
+ #if GDISP_HARDWARE_CLIP != TRUE
+ {
+ if (x < 0) { cx += x; x = 0; }
+ if (y < 0) { cy += y; y = 0; }
+ if (cx <= 0 || cy <= 0 || x >= g->g.Width || y >= g->g.Height) { MUTEX_EXIT(g); return; }
+ g->clipx0 = x;
+ g->clipy0 = y;
+ g->clipx1 = x+cx; if (g->clipx1 > g->g.Width) g->clipx1 = g->g.Width;
+ g->clipy1 = y+cy; if (g->clipy1 > g->g.Height) g->clipy1 = g->g.Height;
+ }
+ #endif
+ MUTEX_EXIT(g);
}
#endif
-#if (GDISP_NEED_CIRCLE && GDISP_NEED_MULTITHREAD)
- void gdispDrawCircle(coord_t x, coord_t y, coord_t radius, color_t color) {
- gfxMutexEnter(&gdispMutex);
- gdisp_lld_draw_circle(x, y, radius, color);
- gfxMutexExit(&gdispMutex);
- }
-#elif GDISP_NEED_CIRCLE && GDISP_NEED_ASYNC
- void gdispDrawCircle(coord_t x, coord_t y, coord_t radius, color_t color) {
- gdisp_lld_msg_t *p = gdispAllocMsg(GDISP_LLD_MSG_DRAWCIRCLE);
- p->drawcircle.x = x;
- p->drawcircle.y = y;
- p->drawcircle.radius = radius;
- p->drawcircle.color = color;
- gfxQueuePut(&gdispQueue, &p->qi, TIME_IMMEDIATE);
+#if GDISP_NEED_CIRCLE
+ void gdispGDrawCircle(GDisplay *g, coord_t x, coord_t y, coord_t radius, color_t color) {
+ coord_t a, b, P;
+
+ MUTEX_ENTER(g);
+
+ // Calculate intermediates
+ a = 1;
+ b = radius;
+ P = 4 - radius;
+ g->p.color = color;
+
+ // Away we go using Bresenham's circle algorithm
+ // Optimized to prevent double drawing
+ g->p.x = x; g->p.y = y + b; drawpixel_clip(g);
+ g->p.x = x; g->p.y = y - b; drawpixel_clip(g);
+ g->p.x = x + b; g->p.y = y; drawpixel_clip(g);
+ g->p.x = x - b; g->p.y = y; drawpixel_clip(g);
+ do {
+ g->p.x = x + a; g->p.y = y + b; drawpixel_clip(g);
+ g->p.x = x + a; g->p.y = y - b; drawpixel_clip(g);
+ g->p.x = x + b; g->p.y = y + a; drawpixel_clip(g);
+ g->p.x = x - b; g->p.y = y + a; drawpixel_clip(g);
+ g->p.x = x - a; g->p.y = y + b; drawpixel_clip(g);
+ g->p.x = x - a; g->p.y = y - b; drawpixel_clip(g);
+ g->p.x = x + b; g->p.y = y - a; drawpixel_clip(g);
+ g->p.x = x - b; g->p.y = y - a; drawpixel_clip(g);
+ if (P < 0)
+ P += 3 + 2*a++;
+ else
+ P += 5 + 2*(a++ - b--);
+ } while(a < b);
+ g->p.x = x + a; g->p.y = y + b; drawpixel_clip(g);
+ g->p.x = x + a; g->p.y = y - b; drawpixel_clip(g);
+ g->p.x = x - a; g->p.y = y + b; drawpixel_clip(g);
+ g->p.x = x - a; g->p.y = y - b; drawpixel_clip(g);
+
+ autoflush(g);
+ MUTEX_EXIT(g);
}
#endif
-
-#if (GDISP_NEED_CIRCLE && GDISP_NEED_MULTITHREAD)
- void gdispFillCircle(coord_t x, coord_t y, coord_t radius, color_t color) {
- gfxMutexEnter(&gdispMutex);
- gdisp_lld_fill_circle(x, y, radius, color);
- gfxMutexExit(&gdispMutex);
- }
-#elif GDISP_NEED_CIRCLE && GDISP_NEED_ASYNC
- void gdispFillCircle(coord_t x, coord_t y, coord_t radius, color_t color) {
- gdisp_lld_msg_t *p = gdispAllocMsg(GDISP_LLD_MSG_FILLCIRCLE);
- p->fillcircle.x = x;
- p->fillcircle.y = y;
- p->fillcircle.radius = radius;
- p->fillcircle.color = color;
- gfxQueuePut(&gdispQueue, &p->qi, TIME_IMMEDIATE);
+
+#if GDISP_NEED_CIRCLE
+ void gdispGFillCircle(GDisplay *g, coord_t x, coord_t y, coord_t radius, color_t color) {
+ coord_t a, b, P;
+
+ MUTEX_ENTER(g);
+
+ // Calculate intermediates
+ a = 1;
+ b = radius;
+ P = 4 - radius;
+ g->p.color = color;
+
+ // Away we go using Bresenham's circle algorithm
+ // This is optimized to prevent overdrawing by drawing a line only when a variable is about to change value
+ g->p.y = y; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g);
+ g->p.y = y+b; g->p.x = x; drawpixel_clip(g);
+ g->p.y = y-b; g->p.x = x; drawpixel_clip(g);
+ do {
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g);
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g);
+ if (P < 0) {
+ P += 3 + 2*a++;
+ } else {
+ g->p.y = y+b; g->p.x = x-a; g->p.x1 = x+a; hline_clip(g);
+ g->p.y = y-b; g->p.x = x-a; g->p.x1 = x+a; hline_clip(g);
+ P += 5 + 2*(a++ - b--);
+ }
+ } while(a < b);
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g);
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g);
+
+ autoflush(g);
+ MUTEX_EXIT(g);
}
#endif
-#if (GDISP_NEED_ELLIPSE && GDISP_NEED_MULTITHREAD)
- void gdispDrawEllipse(coord_t x, coord_t y, coord_t a, coord_t b, color_t color) {
- gfxMutexEnter(&gdispMutex);
- gdisp_lld_draw_ellipse(x, y, a, b, color);
- gfxMutexExit(&gdispMutex);
- }
-#elif GDISP_NEED_ELLIPSE && GDISP_NEED_ASYNC
- void gdispDrawEllipse(coord_t x, coord_t y, coord_t a, coord_t b, color_t color) {
- gdisp_lld_msg_t *p = gdispAllocMsg(GDISP_LLD_MSG_DRAWELLIPSE);
- p->drawellipse.x = x;
- p->drawellipse.y = y;
- p->drawellipse.a = a;
- p->drawellipse.b = b;
- p->drawellipse.color = color;
- gfxQueuePut(&gdispQueue, &p->qi, TIME_IMMEDIATE);
+#if GDISP_NEED_ELLIPSE
+ void gdispGDrawEllipse(GDisplay *g, coord_t x, coord_t y, coord_t a, coord_t b, color_t color) {
+ coord_t dx, dy;
+ int32_t a2, b2;
+ int32_t err, e2;
+
+ MUTEX_ENTER(g);
+
+ // Calculate intermediates
+ dx = 0;
+ dy = b;
+ a2 = a*a;
+ b2 = b*b;
+ err = b2-(2*b-1)*a2;
+ g->p.color = color;
+
+ // Away we go using Bresenham's ellipse algorithm
+ do {
+ g->p.x = x + dx; g->p.y = y + dy; drawpixel_clip(g);
+ g->p.x = x - dx; g->p.y = y + dy; drawpixel_clip(g);
+ g->p.x = x - dx; g->p.y = y - dy; drawpixel_clip(g);
+ g->p.x = x + dx; g->p.y = y - dy; drawpixel_clip(g);
+
+ e2 = 2*err;
+ if(e2 < (2*dx+1)*b2) {
+ dx++;
+ err += (2*dx+1)*b2;
+ }
+ if(e2 > -(2*dy-1)*a2) {
+ dy--;
+ err -= (2*dy-1)*a2;
+ }
+ } while(dy >= 0);
+
+ autoflush(g);
+ MUTEX_EXIT(g);
}
#endif
-#if (GDISP_NEED_ELLIPSE && GDISP_NEED_MULTITHREAD)
- void gdispFillEllipse(coord_t x, coord_t y, coord_t a, coord_t b, color_t color) {
- gfxMutexEnter(&gdispMutex);
- gdisp_lld_fill_ellipse(x, y, a, b, color);
- gfxMutexExit(&gdispMutex);
- }
-#elif GDISP_NEED_ELLIPSE && GDISP_NEED_ASYNC
- void gdispFillEllipse(coord_t x, coord_t y, coord_t a, coord_t b, color_t color) {
- gdisp_lld_msg_t *p = gdispAllocMsg(GDISP_LLD_MSG_FILLELLIPSE);
- p->fillellipse.x = x;
- p->fillellipse.y = y;
- p->fillellipse.a = a;
- p->fillellipse.b = b;
- p->fillellipse.color = color;
- gfxQueuePut(&gdispQueue, &p->qi, TIME_IMMEDIATE);
+#if GDISP_NEED_ELLIPSE
+ void gdispGFillEllipse(GDisplay *g, coord_t x, coord_t y, coord_t a, coord_t b, color_t color) {
+ coord_t dx, dy;
+ int32_t a2, b2;
+ int32_t err, e2;
+
+ MUTEX_ENTER(g);
+
+ // Calculate intermediates
+ dx = 0;
+ dy = b;
+ a2 = a*a;
+ b2 = b*b;
+ err = b2-(2*b-1)*a2;
+ g->p.color = color;
+
+ // Away we go using Bresenham's ellipse algorithm
+ // This is optimized to prevent overdrawing by drawing a line only when a y is about to change value
+ do {
+ e2 = 2*err;
+ if(e2 < (2*dx+1)*b2) {
+ dx++;
+ err += (2*dx+1)*b2;
+ }
+ if(e2 > -(2*dy-1)*a2) {
+ g->p.y = y + dy; g->p.x = x - dx; g->p.x1 = x + dx; hline_clip(g);
+ if (y) { g->p.y = y - dy; g->p.x = x - dx; g->p.x1 = x + dx; hline_clip(g); }
+ dy--;
+ err -= (2*dy-1)*a2;
+ }
+ } while(dy >= 0);
+
+ autoflush(g);
+ MUTEX_EXIT(g);
}
#endif
-#if (GDISP_NEED_ARC && GDISP_NEED_MULTITHREAD)
- void gdispDrawArc(coord_t x, coord_t y, coord_t radius, coord_t start, coord_t end, color_t color) {
- gfxMutexEnter(&gdispMutex);
- gdisp_lld_draw_arc(x, y, radius, start, end, color);
- gfxMutexExit(&gdispMutex);
- }
-#elif GDISP_NEED_ARC && GDISP_NEED_ASYNC
- void gdispDrawArc(coord_t x, coord_t y, coord_t radius, coord_t start, coord_t end, color_t color) {
- gdisp_lld_msg_t *p = gdispAllocMsg(GDISP_LLD_MSG_DRAWARC);
- p->drawarc.x = x;
- p->drawarc.y = y;
- p->drawarc.radius = radius;
- p->drawarc.start = start;
- p->drawarc.end = end;
- p->drawarc.color = color;
- gfxQueuePut(&gdispQueue, &p->qi, TIME_IMMEDIATE);
+#if GDISP_NEED_ARC
+ #if !GMISC_NEED_FIXEDTRIG && !GMISC_NEED_FASTTRIG
+ #include <math.h>
+ #endif
+
+ void gdispGDrawArc(GDisplay *g, coord_t x, coord_t y, coord_t radius, coord_t start, coord_t end, color_t color) {
+ coord_t a, b, P, sedge, eedge;
+ uint8_t full, sbit, ebit, tbit;
+
+ // Normalize the angles
+ if (start < 0)
+ start -= (start/360-1)*360;
+ else if (start >= 360)
+ start %= 360;
+ if (end < 0)
+ end -= (end/360-1)*360;
+ else if (end >= 360)
+ end %= 360;
+
+ sbit = 1<<(start/45);
+ ebit = 1<<(end/45);
+ full = 0;
+ if (start == end) {
+ full = 0xFF;
+ } else if (end < start) {
+ for(tbit=sbit<<1; tbit; tbit<<=1) full |= tbit;
+ for(tbit=ebit>>1; tbit; tbit>>=1) full |= tbit;
+ } else if (sbit < 0x80) {
+ for(tbit=sbit<<1; tbit < ebit; tbit<<=1) full |= tbit;
+ }
+
+ MUTEX_ENTER(g);
+ g->p.color = color;
+
+ if (full) {
+ // Draw full sectors
+ // Optimized to prevent double drawing
+ a = 1;
+ b = radius;
+ P = 4 - radius;
+ if (full & 0x60) { g->p.y = y+b; g->p.x = x; drawpixel_clip(g); }
+ if (full & 0x06) { g->p.y = y-b; g->p.x = x; drawpixel_clip(g); }
+ if (full & 0x81) { g->p.y = y; g->p.x = x+b; drawpixel_clip(g); }
+ if (full & 0x18) { g->p.y = y; g->p.x = x-b; drawpixel_clip(g); }
+ do {
+ if (full & 0x01) { g->p.x = x+b; g->p.y = y-a; drawpixel_clip(g); }
+ if (full & 0x02) { g->p.x = x+a; g->p.y = y-b; drawpixel_clip(g); }
+ if (full & 0x04) { g->p.x = x-a; g->p.y = y-b; drawpixel_clip(g); }
+ if (full & 0x08) { g->p.x = x-b; g->p.y = y-a; drawpixel_clip(g); }
+ if (full & 0x10) { g->p.x = x-b; g->p.y = y+a; drawpixel_clip(g); }
+ if (full & 0x20) { g->p.x = x-a; g->p.y = y+b; drawpixel_clip(g); }
+ if (full & 0x40) { g->p.x = x+a; g->p.y = y+b; drawpixel_clip(g); }
+ if (full & 0x80) { g->p.x = x+b; g->p.y = y+a; drawpixel_clip(g); }
+ if (P < 0)
+ P += 3 + 2*a++;
+ else
+ P += 5 + 2*(a++ - b--);
+ } while(a < b);
+ if (full & 0xC0) { g->p.x = x+a; g->p.y = y+b; drawpixel_clip(g); }
+ if (full & 0x0C) { g->p.x = x-a; g->p.y = y-b; drawpixel_clip(g); }
+ if (full & 0x03) { g->p.x = x+a; g->p.y = y-b; drawpixel_clip(g); }
+ if (full & 0x30) { g->p.x = x-a; g->p.y = y+b; drawpixel_clip(g); }
+ if (full == 0xFF) {
+ autoflush(g);
+ MUTEX_EXIT;
+ return;
+ }
+ }
+
+ #if GFX_USE_GMISC && GMISC_NEED_FIXEDTRIG
+ sedge = NONFIXED(radius * ((sbit & 0x99) ? ffsin(start) : ffcos(start)) + FIXED0_5);
+ eedge = NONFIXED(radius * ((ebit & 0x99) ? ffsin(end) : ffcos(end)) + FIXED0_5);
+ #elif GFX_USE_GMISC && GMISC_NEED_FASTTRIG
+ sedge = round(radius * ((sbit & 0x99) ? fsin(start) : fcos(start)));
+ eedge = round(radius * ((ebit & 0x99) ? fsin(end) : fcos(end)));
+ #else
+ sedge = round(radius * ((sbit & 0x99) ? sin(start*M_PI/180) : cos(start*M_PI/180)));
+ eedge = round(radius * ((ebit & 0x99) ? sin(end*M_PI/180) : cos(end*M_PI/180)));
+ #endif
+ if (sbit & 0xB4) sedge = -sedge;
+ if (ebit & 0xB4) eedge = -eedge;
+
+ if (sbit != ebit) {
+ // Draw start and end sectors
+ // Optimized to prevent double drawing
+ a = 1;
+ b = radius;
+ P = 4 - radius;
+ if ((sbit & 0x20) || (ebit & 0x40)) { g->p.x = x; g->p.y = y+b; drawpixel_clip(g); }
+ if ((sbit & 0x02) || (ebit & 0x04)) { g->p.x = x; g->p.y = y-b; drawpixel_clip(g); }
+ if ((sbit & 0x80) || (ebit & 0x01)) { g->p.x = x+b; g->p.y = y; drawpixel_clip(g); }
+ if ((sbit & 0x08) || (ebit & 0x10)) { g->p.x = x-b; g->p.y = y; drawpixel_clip(g); }
+ do {
+ if (((sbit & 0x01) && a >= sedge) || ((ebit & 0x01) && a <= eedge)) { g->p.x = x+b; g->p.y = y-a; drawpixel_clip(g); }
+ if (((sbit & 0x02) && a <= sedge) || ((ebit & 0x02) && a >= eedge)) { g->p.x = x+a; g->p.y = y-b; drawpixel_clip(g); }
+ if (((sbit & 0x04) && a >= sedge) || ((ebit & 0x04) && a <= eedge)) { g->p.x = x-a; g->p.y = y-b; drawpixel_clip(g); }
+ if (((sbit & 0x08) && a <= sedge) || ((ebit & 0x08) && a >= eedge)) { g->p.x = x-b; g->p.y = y-a; drawpixel_clip(g); }
+ if (((sbit & 0x10) && a >= sedge) || ((ebit & 0x10) && a <= eedge)) { g->p.x = x-b; g->p.y = y+a; drawpixel_clip(g); }
+ if (((sbit & 0x20) && a <= sedge) || ((ebit & 0x20) && a >= eedge)) { g->p.x = x-a; g->p.y = y+b; drawpixel_clip(g); }
+ if (((sbit & 0x40) && a >= sedge) || ((ebit & 0x40) && a <= eedge)) { g->p.x = x+a; g->p.y = y+b; drawpixel_clip(g); }
+ if (((sbit & 0x80) && a <= sedge) || ((ebit & 0x80) && a >= eedge)) { g->p.x = x+b; g->p.y = y+a; drawpixel_clip(g); }
+ if (P < 0)
+ P += 3 + 2*a++;
+ else
+ P += 5 + 2*(a++ - b--);
+ } while(a < b);
+ if (((sbit & 0x40) && a >= sedge) || ((ebit & 0x40) && a <= eedge) || ((sbit & 0x80) && a <= sedge) || ((ebit & 0x80) && a >= eedge))
+ { g->p.x = x+a; g->p.y = y+b; drawpixel_clip(g); }
+ if (((sbit & 0x04) && a >= sedge) || ((ebit & 0x04) && a <= eedge) || ((sbit & 0x08) && a <= sedge) || ((ebit & 0x08) && a >= eedge))
+ { g->p.x = x-a; g->p.y = y-b; drawpixel_clip(g); }
+ if (((sbit & 0x01) && a >= sedge) || ((ebit & 0x01) && a <= eedge) || ((sbit & 0x02) && a <= sedge) || ((ebit & 0x02) && a >= eedge))
+ { g->p.x = x+a; g->p.y = y-b; drawpixel_clip(g); }
+ if (((sbit & 0x10) && a >= sedge) || ((ebit & 0x10) && a <= eedge) || ((sbit & 0x20) && a <= sedge) || ((ebit & 0x20) && a >= eedge))
+ { g->p.x = x-a; g->p.y = y+b; drawpixel_clip(g); }
+ } else if (end < start) {
+ // Draw start/end sector where it is a non-internal angle
+ // Optimized to prevent double drawing
+ a = 1;
+ b = radius;
+ P = 4 - radius;
+ if (sbit & 0x60) { g->p.x = x; g->p.y = y+b; drawpixel_clip(g); }
+ if (sbit & 0x06) { g->p.x = x; g->p.y = y-b; drawpixel_clip(g); }
+ if (sbit & 0x81) { g->p.x = x+b; g->p.y = y; drawpixel_clip(g); }
+ if (sbit & 0x18) { g->p.x = x-b; g->p.y = y; drawpixel_clip(g); }
+ do {
+ if ((sbit & 0x01) && (a >= sedge || a <= eedge)) { g->p.x = x+b; g->p.y = y-a; drawpixel_clip(g); }
+ if ((sbit & 0x02) && (a <= sedge || a >= eedge)) { g->p.x = x+a; g->p.y = y-b; drawpixel_clip(g); }
+ if ((sbit & 0x04) && (a >= sedge || a <= eedge)) { g->p.x = x-a; g->p.y = y-b; drawpixel_clip(g); }
+ if ((sbit & 0x08) && (a <= sedge || a >= eedge)) { g->p.x = x-b; g->p.y = y-a; drawpixel_clip(g); }
+ if ((sbit & 0x10) && (a >= sedge || a <= eedge)) { g->p.x = x-b; g->p.y = y+a; drawpixel_clip(g); }
+ if ((sbit & 0x20) && (a <= sedge || a >= eedge)) { g->p.x = x-a; g->p.y = y+b; drawpixel_clip(g); }
+ if ((sbit & 0x40) && (a >= sedge || a <= eedge)) { g->p.x = x+a; g->p.y = y+b; drawpixel_clip(g); }
+ if ((sbit & 0x80) && (a <= sedge || a >= eedge)) { g->p.x = x+b; g->p.y = y+a; drawpixel_clip(g); }
+ if (P < 0)
+ P += 3 + 2*a++;
+ else
+ P += 5 + 2*(a++ - b--);
+ } while(a < b);
+ if (((sbit & 0x04) && (a >= sedge || a <= eedge)) || ((sbit & 0x08) && (a <= sedge || a >= eedge)))
+ { g->p.x = x-a; g->p.y = y-b; drawpixel_clip(g); }
+ if (((sbit & 0x40) && (a >= sedge || a <= eedge)) || ((sbit & 0x80) && (a <= sedge || a >= eedge)))
+ { g->p.x = x+a; g->p.y = y+b; drawpixel_clip(g); }
+ if (((sbit & 0x01) && (a >= sedge || a <= eedge)) || ((sbit & 0x02) && (a <= sedge || a >= eedge)))
+ { g->p.x = x+a; g->p.y = y-b; drawpixel_clip(g); }
+ if (((sbit & 0x10) && (a >= sedge || a <= eedge)) || ((sbit & 0x20) && (a <= sedge || a >= eedge)))
+ { g->p.x = x-a; g->p.y = y+b; drawpixel_clip(g); }
+ } else {
+ // Draw start/end sector where it is a internal angle
+ // Optimized to prevent double drawing
+ a = 1;
+ b = radius;
+ P = 4 - radius;
+ if (((sbit & 0x20) && !eedge) || ((sbit & 0x40) && !sedge)) { g->p.x = x; g->p.y = y+b; drawpixel_clip(g); }
+ if (((sbit & 0x02) && !eedge) || ((sbit & 0x04) && !sedge)) { g->p.x = x; g->p.y = y-b; drawpixel_clip(g); }
+ if (((sbit & 0x80) && !eedge) || ((sbit & 0x01) && !sedge)) { g->p.x = x+b; g->p.y = y; drawpixel_clip(g); }
+ if (((sbit & 0x08) && !eedge) || ((sbit & 0x10) && !sedge)) { g->p.x = x-b; g->p.y = y; drawpixel_clip(g); }
+ do {
+ if (((sbit & 0x01) && a >= sedge && a <= eedge)) { g->p.x = x+b; g->p.y = y-a; drawpixel_clip(g); }
+ if (((sbit & 0x02) && a <= sedge && a >= eedge)) { g->p.x = x+a; g->p.y = y-b; drawpixel_clip(g); }
+ if (((sbit & 0x04) && a >= sedge && a <= eedge)) { g->p.x = x-a; g->p.y = y-b; drawpixel_clip(g); }
+ if (((sbit & 0x08) && a <= sedge && a >= eedge)) { g->p.x = x-b; g->p.y = y-a; drawpixel_clip(g); }
+ if (((sbit & 0x10) && a >= sedge && a <= eedge)) { g->p.x = x-b; g->p.y = y+a; drawpixel_clip(g); }
+ if (((sbit & 0x20) && a <= sedge && a >= eedge)) { g->p.x = x-a; g->p.y = y+b; drawpixel_clip(g); }
+ if (((sbit & 0x40) && a >= sedge && a <= eedge)) { g->p.x = x+a; g->p.y = y+b; drawpixel_clip(g); }
+ if (((sbit & 0x80) && a <= sedge && a >= eedge)) { g->p.x = x+b; g->p.y = y+a; drawpixel_clip(g); }
+ if (P < 0)
+ P += 3 + 2*a++;
+ else
+ P += 5 + 2*(a++ - b--);
+ } while(a < b);
+ if (((sbit & 0x04) && a >= sedge && a <= eedge) || ((sbit & 0x08) && a <= sedge && a >= eedge))
+ { g->p.x = x-a; g->p.y = y-b; drawpixel_clip(g); }
+ if (((sbit & 0x40) && a >= sedge && a <= eedge) || ((sbit & 0x80) && a <= sedge && a >= eedge))
+ { g->p.x = x+a; g->p.y = y+b; drawpixel_clip(g); }
+ if (((sbit & 0x01) && a >= sedge && a <= eedge) || ((sbit & 0x02) && a <= sedge && a >= eedge))
+ { g->p.x = x+a; g->p.y = y-b; drawpixel_clip(g); }
+ if (((sbit & 0x10) && a >= sedge && a <= eedge) || ((sbit & 0x20) && a <= sedge && a >= eedge))
+ { g->p.x = x-a; g->p.y = y+b; drawpixel_clip(g); }
+ }
+
+ autoflush(g);
+ MUTEX_EXIT(g);
}
#endif
-#if (GDISP_NEED_ARC && GDISP_NEED_MULTITHREAD)
- void gdispFillArc(coord_t x, coord_t y, coord_t radius, coord_t start, coord_t end, color_t color) {
- gfxMutexEnter(&gdispMutex);
- gdisp_lld_fill_arc(x, y, radius, start, end, color);
- gfxMutexExit(&gdispMutex);
- }
-#elif GDISP_NEED_ARC && GDISP_NEED_ASYNC
- void gdispFillArc(coord_t x, coord_t y, coord_t radius, coord_t start, coord_t end, color_t color) {
- gdisp_lld_msg_t *p = gdispAllocMsg(GDISP_LLD_MSG_FILLARC);
- p->fillarc.x = x;
- p->fillarc.y = y;
- p->fillarc.radius = radius;
- p->fillarc.start = start;
- p->fillarc.end = end;
- p->fillarc.color = color;
- gfxQueuePut(&gdispQueue, &p->qi, TIME_IMMEDIATE);
+#if GDISP_NEED_ARC
+ void gdispGFillArc(GDisplay *g, coord_t x, coord_t y, coord_t radius, coord_t start, coord_t end, color_t color) {
+ coord_t a, b, P;
+ coord_t sy, ey;
+ fixed sxa, sxb, sxd, exa, exb, exd;
+ uint8_t qtr;
+
+ MUTEX_ENTER(g);
+
+ // Do the trig to get the formulas for the start and end lines.
+ sxa = exa = FIXED(x)+FIXED0_5;
+ #if GFX_USE_GMISC && GMISC_NEED_FIXEDTRIG
+ sxb = radius*ffcos(start); sy = -NONFIXED(radius*ffsin(start) + FIXED0_5);
+ exb = radius*ffcos(end); ey = -NONFIXED(radius*ffsin(end) + FIXED0_5);
+ #elif GFX_USE_GMISC && GMISC_NEED_FASTTRIG
+ sxb = FP2FIXED(radius*fcos(start)); sy = -round(radius*fsin(start));
+ exb = FP2FIXED(radius*fcos(end)); ey = -round(radius*fsin(end));
+ #else
+ sxb = FP2FIXED(radius*cos(start*M_PI/180)); sy = -round(radius*sin(start*M_PI/180));
+ exb = FP2FIXED(radius*cos(end*M_PI/180)); ey = -round(radius*sin(end*M_PI/180));
+ #endif
+ sxd = sy ? sxb/sy : sxb;
+ exd = ey ? exb/ey : exb;
+
+ // Calculate which quarters and which direction we are traveling
+ qtr = 0;
+ if (sxb > 0) qtr |= 0x01; // S1=0001(1), S2=0000(0), S3=0010(2), S4=0011(3)
+ if (sy > 0) qtr |= 0x02;
+ if (exb > 0) qtr |= 0x04; // E1=0100(4), E2=0000(0), E3=1000(8), E4=1100(12)
+ if (ey > 0) qtr |= 0x08;
+ if (sy > ey) qtr |= 0x10; // order of start and end lines
+
+ // Calculate intermediates
+ a = 1;
+ b = radius;
+ P = 4 - radius;
+ g->p.color = color;
+ sxb += sxa;
+ exb += exa;
+
+ // Away we go using Bresenham's circle algorithm
+ // This is optimized to prevent overdrawing by drawing a line only when a variable is about to change value
+
+ switch(qtr) {
+ case 0: // S2E2 sy <= ey
+ case 1: // S1E2 sy <= ey
+ if (ey && sy) {
+ g->p.x = x; g->p.x1 = x; // E2S
+ sxa -= sxd; exa -= exd;
+ } else if (sy) {
+ g->p.x = x-b; g->p.x1 = x; // C2S
+ sxa -= sxd;
+ } else if (ey) {
+ g->p.x = x; g->p.x1 = x+b; // E2C
+ exa -= exd;
+ } else {
+ g->p.x = x-b; g->p.x1 = x+b; // C2C
+ }
+ g->p.y = y;
+ hline_clip(g);
+ do {
+ if (-a >= ey) {
+ g->p.y = y-a; g->p.x = NONFIXED(exa); g->p.x1 = NONFIXED(sxa); hline_clip(g); // E2S
+ sxa -= sxd; exa -= exd;
+ } else if (-a >= sy) {
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = NONFIXED(sxa); hline_clip(g); // C2S
+ sxa -= sxd;
+ } else if (qtr & 1) {
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
+ }
+ if (P < 0) {
+ P += 3 + 2*a++;
+ } else {
+ if (-b >= ey) {
+ g->p.y = y-b; g->p.x = NONFIXED(exb); g->p.x1 = NONFIXED(sxb); hline_clip(g); // E2S
+ sxb += sxd; exb += exd;
+ } else if (-b >= sy) {
+ g->p.y = y-b; g->p.x = x-a; g->p.x1 = NONFIXED(sxb); hline_clip(g); // C2S
+ sxb += sxd;
+ } else if (qtr & 1) {
+ g->p.y = y-b; g->p.x = x-a; g->p.x1 = x+a; hline_clip(g); // C2C
+ }
+ P += 5 + 2*(a++ - b--);
+ }
+ } while(a < b);
+ if (-a >= ey) {
+ g->p.y = y-a; g->p.x = NONFIXED(exa); g->p.x1 = NONFIXED(sxa); hline_clip(g); // E2S
+ } else if (-a >= sy) {
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = NONFIXED(sxa); hline_clip(g); // C2S
+ } else if (qtr & 1) {
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
+ }
+ break;
+
+ case 2: // S3E2 sy <= ey
+ case 3: // S4E2 sy <= ey
+ case 6: // S3E1 sy <= ey
+ case 7: // S4E1 sy <= ey
+ case 18: // S3E2 sy > ey
+ case 19: // S4E2 sy > ey
+ case 22: // S3E1 sy > ey
+ case 23: // S4E1 sy > ey
+ g->p.y = y; g->p.x = x; g->p.x1 = x+b; hline_clip(g); // SE2C
+ sxa += sxd; exa -= exd;
+ do {
+ if (-a >= ey) {
+ g->p.y = y-a; g->p.x = NONFIXED(exa); g->p.x1 = x+b; hline_clip(g); // E2C
+ exa -= exd;
+ } else if (!(qtr & 4)) {
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
+ }
+ if (a <= sy) {
+ g->p.y = y+a; g->p.x = NONFIXED(sxa); g->p.x1 = x+b; hline_clip(g); // S2C
+ sxa += sxd;
+ } else if (!(qtr & 1)) {
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
+ }
+ if (P < 0) {
+ P += 3 + 2*a++;
+ } else {
+ if (-b >= ey) {
+ g->p.y = y-b; g->p.x = NONFIXED(exb); g->p.x1 = x+a; hline_clip(g); // E2C
+ exb += exd;
+ } else if (!(qtr & 4)) {
+ g->p.y = y-b; g->p.x = x-a; g->p.x1 = x+a; hline_clip(g); // C2C
+ }
+ if (b <= sy) {
+ g->p.y = y+b; g->p.x = NONFIXED(sxb); g->p.x1 = x+a; hline_clip(g); // S2C
+ sxb -= sxd;
+ } else if (!(qtr & 1)) {
+ g->p.y = y+b; g->p.x = x-a; g->p.x1 = x+a; hline_clip(g); // C2C
+ }
+ P += 5 + 2*(a++ - b--);
+ }
+ } while(a < b);
+ if (-a >= ey) {
+ g->p.y = y-a; g->p.x = NONFIXED(exa); g->p.x1 = x+b; hline_clip(g); // E2C
+ } else if (!(qtr & 4)) {
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
+ }
+ if (a <= sy) {
+ g->p.y = y+a; g->p.x = NONFIXED(sxa); g->p.x1 = x+a; hline_clip(g); // S2C
+ } else if (!(qtr & 1)) {
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = x+a; hline_clip(g); // C2C
+ }
+ break;
+
+ case 4: // S2E1 sy <= ey
+ case 5: // S1E1 sy <= ey
+ g->p.y = y; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
+ do {
+ if (-a >= ey) {
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = NONFIXED(sxa); hline_clip(g); // C2S
+ g->p.y = y-a; g->p.x = NONFIXED(exa); g->p.x1 = x+b; hline_clip(g); // E2C
+ sxa -= sxd; exa -= exd;
+ } else if (-a >= sy) {
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = NONFIXED(sxa); hline_clip(g); // C2S
+ sxa -= sxd;
+ } else if (qtr & 1) {
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
+ }
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
+ if (P < 0) {
+ P += 3 + 2*a++;
+ } else {
+ if (-b >= ey) {
+ g->p.y = y-b; g->p.x = x-a; g->p.x1 = NONFIXED(sxb); hline_clip(g); // C2S
+ g->p.y = y-b; g->p.x = NONFIXED(exb); g->p.x1 = x+a; hline_clip(g); // E2C
+ sxb += sxd; exb += exd;
+ } else if (-b >= sy) {
+ g->p.y = y-b; g->p.x = x-a; g->p.x1 = NONFIXED(sxb); hline_clip(g); // C2S
+ sxb += sxd;
+ } else if (qtr & 1) {
+ g->p.y = y-b; g->p.x = x-a; g->p.x1 = x+a; hline_clip(g); // C2C
+ }
+ g->p.y = y+b; g->p.x = x-a; g->p.x1 = x+a; hline_clip(g); // C2C
+ P += 5 + 2*(a++ - b--);
+ }
+ } while(a < b);
+ if (-a >= ey) {
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = NONFIXED(sxa); hline_clip(g); // C2S
+ g->p.y = y-a; g->p.x = NONFIXED(exa); g->p.x1 = x+b; hline_clip(g); // E2C
+ } else if (-a >= sy) {
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = NONFIXED(sxa); hline_clip(g); // C2S
+ } else if (qtr & 1) {
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
+ }
+ g->p.y = y+b; g->p.x = x-a; g->p.x1 = x+a; hline_clip(g); // C2C
+ break;
+
+ case 8: // S2E3 sy <= ey
+ case 9: // S1E3 sy <= ey
+ case 12: // S2E4 sy <= ey
+ case 13: // S1E4 sy <= ey
+ case 24: // S2E3 sy > ey
+ case 25: // S1E3 sy > ey
+ case 28: // S2E3 sy > ey
+ case 29: // S1E3 sy > ey
+ g->p.y = y; g->p.x = x-b; g->p.x1 = x; hline_clip(g); // C2SE
+ sxa -= sxd; exa += exd;
+ do {
+ if (-a >= sy) {
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = NONFIXED(sxa); hline_clip(g); // C2S
+ sxa -= sxd;
+ } else if (qtr & 1) {
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
+ }
+ if (a <= ey) {
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = NONFIXED(exa); hline_clip(g); // C2E
+ exa += exd;
+ } else if (qtr & 4) {
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
+ }
+ if (P < 0) {
+ P += 3 + 2*a++;
+ } else {
+ if (-b >= sy) {
+ g->p.y = y-b; g->p.x = x-a; g->p.x1 = NONFIXED(sxb); hline_clip(g); // C2S
+ sxb += sxd;
+ } else if (qtr & 1) {
+ g->p.y = y-b; g->p.x = x-a; g->p.x1 = x+a; hline_clip(g); // C2C
+ }
+ if (b <= ey) {
+ g->p.y = y+b; g->p.x = x-a; g->p.x1 = NONFIXED(exb); hline_clip(g); // C2E
+ exb -= exd;
+ } else if (qtr & 4) {
+ g->p.y = y+b; g->p.x = x-a; g->p.x1 = x+a; hline_clip(g); // C2C
+ }
+ P += 5 + 2*(a++ - b--);
+ }
+ } while(a < b);
+ if (-a >= sy) {
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = NONFIXED(sxa); hline_clip(g); // C2S
+ } else if (qtr & 1) {
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
+ }
+ if (a <= ey) {
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = NONFIXED(exa); hline_clip(g); // C2E
+ } else if (qtr & 4) {
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = x+a; hline_clip(g); // C2C
+ }
+ break;
+
+ case 10: // S3E3 sy <= ey
+ case 14: // S3E4 sy <= ey
+ g->p.y = y; g->p.x = x; drawpixel_clip(g); // S2E
+ sxa += sxd; exa += exd;
+ do {
+ if (a <= sy) {
+ g->p.y = y+a; g->p.x = NONFIXED(sxa); g->p.x1 = NONFIXED(exa); hline_clip(g); // S2E
+ sxa += sxd; exa += exd;
+ } else if (a <= ey) {
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = NONFIXED(exa); hline_clip(g); // C2E
+ exa += exd;
+ } else if (qtr & 4) {
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
+ }
+ if (P < 0) {
+ P += 3 + 2*a++;
+ } else {
+ if (b <= sy) {
+ g->p.y = y+b; g->p.x = NONFIXED(sxb); g->p.x1 = NONFIXED(exb); hline_clip(g); // S2E
+ sxb -= sxd; exb -= exd;
+ } else if (b <= ey) {
+ g->p.y = y+b; g->p.x = x-a; g->p.x1 = NONFIXED(exb); hline_clip(g); // C2E
+ exb -= exd;
+ } else if (qtr & 4) {
+ g->p.y = y+b; g->p.x = x-a; g->p.x1 = x+a; hline_clip(g); // C2C
+ }
+ P += 5 + 2*(a++ - b--);
+ }
+ } while(a < b);
+ if (a <= sy) {
+ g->p.y = y+a; g->p.x = NONFIXED(sxa); g->p.x1 = NONFIXED(exa); hline_clip(g); // S2E
+ } else if (a <= ey) {
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = NONFIXED(exa); hline_clip(g); // C2E
+ } else if (qtr & 4) {
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
+ }
+ break;
+
+ case 11: // S4E3 sy <= ey
+ case 15: // S4E4 sy <= ey
+ g->p.y = y; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
+ do {
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
+ if (a <= sy) {
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = NONFIXED(exa); hline_clip(g); // C2E
+ g->p.y = y+a; g->p.x = NONFIXED(sxa); g->p.x1 = x+b; hline_clip(g); // S2C
+ sxa += sxd; exa += exd;
+ } else if (a <= ey) {
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = NONFIXED(exa); hline_clip(g); // C2E
+ exa += exd;
+ } else if (qtr & 4) {
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
+ }
+ if (P < 0) {
+ P += 3 + 2*a++;
+ } else {
+ g->p.y = y-b; g->p.x = x-a; g->p.x1 = x+a; hline_clip(g); // C2C
+ if (b <= sy) {
+ g->p.y = y+b; g->p.x = x-a; g->p.x1 = NONFIXED(exb); hline_clip(g); // C2E
+ g->p.y = y+b; g->p.x = NONFIXED(sxb); g->p.x1 = x+a; hline_clip(g); // S2C
+ sxb -= sxd; exb -= exd;
+ } else if (b <= ey) {
+ g->p.y = y+b; g->p.x = x-a; g->p.x1 = NONFIXED(exb); hline_clip(g); // C2E
+ exb -= exd;
+ } else if (qtr & 4) {
+ g->p.y = y+b; g->p.x = x-a; g->p.x1 = x+a; hline_clip(g); // C2C
+ }
+ P += 5 + 2*(a++ - b--);
+ }
+ } while(a < b);
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
+ if (a <= sy) {
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = NONFIXED(exa); hline_clip(g); // C2E
+ g->p.y = y+a; g->p.x = NONFIXED(sxa); g->p.x1 = x+b; hline_clip(g); // S2C
+ } else if (a <= ey) {
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = NONFIXED(exa); hline_clip(g); // C2E
+ } else if (qtr & 4) {
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
+ }
+ break;
+
+ case 16: // S2E2 sy > ey
+ case 20: // S2E1 sy > ey
+ g->p.y = y; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
+ sxa -= sxd; exa -= exd;
+ do {
+ if (-a >= sy) {
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = NONFIXED(sxa); hline_clip(g); // C2S
+ g->p.y = y-a; g->p.x = NONFIXED(exa); g->p.x1 = x+b; hline_clip(g); // E2C
+ sxa -= sxd; exa -= exd;
+ } else if (-a >= ey) {
+ g->p.y = y-a; g->p.x = NONFIXED(exa); g->p.x1 = x+b; hline_clip(g); // E2C
+ exa -= exd;
+ } else if (!(qtr & 4)){
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
+ }
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
+ if (P < 0) {
+ P += 3 + 2*a++;
+ } else {
+ if (-b >= sy) {
+ g->p.y = y-b; g->p.x = x-a; g->p.x1 = NONFIXED(sxb); hline_clip(g); // C2S
+ g->p.y = y-b; g->p.x = NONFIXED(exb); g->p.x1 = x+a; hline_clip(g); // E2C
+ sxb += sxd; exb += exd;
+ } else if (-b >= ey) {
+ g->p.y = y-b; g->p.x = NONFIXED(exb); g->p.x1 = x+a; hline_clip(g); // E2C
+ exb += exd;
+ } else if (!(qtr & 4)){
+ g->p.y = y-b; g->p.x = x-a; g->p.x1 = x+a; hline_clip(g); // C2C
+ }
+ g->p.y = y+b; g->p.x = x-a; g->p.x1 = x+a; hline_clip(g); // C2C
+ P += 5 + 2*(a++ - b--);
+ }
+ } while(a < b);
+ if (-a >= sy) {
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = NONFIXED(sxa); hline_clip(g); // C2S
+ g->p.y = y-a; g->p.x = NONFIXED(exa); g->p.x1 = x+b; hline_clip(g); // E2C
+ } else if (-a >= ey) {
+ g->p.y = y-a; g->p.x = NONFIXED(exa); g->p.x1 = x+b; hline_clip(g); // E2C
+ } else if (!(qtr & 4)){
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
+ }
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
+ break;
+
+ case 17: // S1E2 sy > ey
+ case 21: // S1E1 sy > ey
+ if (sy) {
+ g->p.x = x; g->p.x1 = x; // E2S
+ sxa -= sxd; exa -= exd;
+ } else {
+ g->p.x = x; g->p.x1 = x+b; // E2C
+ exa -= exd;
+ }
+ g->p.y = y;
+ hline_clip(g);
+ do {
+ if (-a >= sy) {
+ g->p.y = y-a; g->p.x = NONFIXED(exa); g->p.x1 = NONFIXED(sxa); hline_clip(g); // E2S
+ sxa -= sxd; exa -= exd;
+ } else if (-a >= ey) {
+ g->p.y = y-a; g->p.x = NONFIXED(exa); g->p.x1 = x+b; hline_clip(g); // E2C
+ exa -= exd;
+ } else if (!(qtr & 4)) {
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
+ }
+ if (P < 0) {
+ P += 3 + 2*a++;
+ } else {
+ if (-b >= sy) {
+ g->p.y = y-b; g->p.x = NONFIXED(exb); g->p.x1 = NONFIXED(sxb); hline_clip(g); // E2S
+ sxb += sxd; exb += exd;
+ } else if (-b >= ey) {
+ g->p.y = y-b; g->p.x = NONFIXED(exb); g->p.x1 = x+a; hline_clip(g); // E2C
+ exb += exd;
+ } else if (!(qtr & 4)) {
+ g->p.y = y-b; g->p.x = x-a; g->p.x1 = x+a; hline_clip(g); // C2C
+ }
+ P += 5 + 2*(a++ - b--);
+ }
+ } while(a < b);
+ if (-a >= sy) {
+ g->p.y = y-a; g->p.x = NONFIXED(exa); g->p.x1 = NONFIXED(sxa); hline_clip(g); // E2S
+ } else if (-a >= ey) {
+ g->p.y = y-a; g->p.x = NONFIXED(exa); g->p.x1 = x+b; hline_clip(g); // E2C
+ } else if (!(qtr & 4)) {
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
+ }
+ break;
+
+ case 26: // S3E3 sy > ey
+ case 27: // S4E3 sy > ey
+ g->p.y = y; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
+ do {
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
+ if (a <= ey) {
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = NONFIXED(exa); hline_clip(g); // C2E
+ g->p.y = y+a; g->p.x = NONFIXED(sxa); g->p.x1 = x+b; hline_clip(g); // S2C
+ sxa += sxd; exa += exd;
+ } else if (a <= sy) {
+ g->p.y = y+a; g->p.x = NONFIXED(sxa); g->p.x1 = x+b; hline_clip(g); // S2C
+ sxa += sxd;
+ } else if (!(qtr & 1)) {
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
+ }
+ if (P < 0) {
+ P += 3 + 2*a++;
+ } else {
+ g->p.y = y-b; g->p.x = x-a; g->p.x1 = x+a; hline_clip(g); // C2C
+ if (b <= ey) {
+ g->p.y = y+b; g->p.x = x-a; g->p.x1 = NONFIXED(exb); hline_clip(g); // C2E
+ g->p.y = y+b; g->p.x = NONFIXED(sxb); g->p.x1 = x+a; hline_clip(g); // S2C
+ sxb -= sxd; exb -= exd;
+ } else if (b <= sy) {
+ g->p.y = y+b; g->p.x = NONFIXED(sxb); g->p.x1 = x+a; hline_clip(g); // S2C
+ sxb -= sxd;
+ } else if (!(qtr & 1)) {
+ g->p.y = y+b; g->p.x = x-a; g->p.x1 = x+a; hline_clip(g); // C2C
+ }
+ P += 5 + 2*(a++ - b--);
+ }
+ } while(a < b);
+ g->p.y = y-a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
+ if (a <= ey) {
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = NONFIXED(exa); hline_clip(g); // C2E
+ g->p.y = y+a; g->p.x = NONFIXED(sxa); g->p.x1 = x+b; hline_clip(g); // S2C
+ } else if (a <= sy) {
+ g->p.y = y+a; g->p.x = NONFIXED(sxa); g->p.x1 = x+b; hline_clip(g); // S2C
+ } else if (!(qtr & 4)) {
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
+ }
+ break;
+
+ case 30: // S3E4 sy > ey
+ case 31: // S4E4 sy > ey
+ do {
+ if (a <= ey) {
+ g->p.y = y+a; g->p.x = NONFIXED(sxa); g->p.x1 = NONFIXED(exa); hline_clip(g); // S2E
+ sxa += sxd; exa += exd;
+ } else if (a <= sy) {
+ g->p.y = y+a; g->p.x = NONFIXED(sxa); g->p.x1 = x+b; hline_clip(g); // S2C
+ sxa += sxd;
+ } else if (!(qtr & 1)) {
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
+ }
+ if (P < 0) {
+ P += 3 + 2*a++;
+ } else {
+ if (b <= ey) {
+ g->p.y = y+b; g->p.x = NONFIXED(sxb); g->p.x1 = NONFIXED(exb); hline_clip(g); // S2E
+ sxb -= sxd; exb -= exd;
+ } else if (b <= sy) {
+ g->p.y = y+b; g->p.x = NONFIXED(sxb); g->p.x1 = x+a; hline_clip(g); // S2C
+ sxb -= sxd;
+ } else if (!(qtr & 1)) {
+ g->p.y = y+b; g->p.x = x-a; g->p.x1 = x+a; hline_clip(g); // C2C
+ }
+ P += 5 + 2*(a++ - b--);
+ }
+ } while(a < b);
+ if (a <= ey) {
+ g->p.y = y+a; g->p.x = NONFIXED(sxa); g->p.x1 = x+b; hline_clip(g); // S2C
+ } else if (a <= sy) {
+ g->p.y = y+a; g->p.x = NONFIXED(sxa); g->p.x1 = x+b; hline_clip(g); // S2C
+ } else if (!(qtr & 4)) {
+ g->p.y = y+a; g->p.x = x-b; g->p.x1 = x+b; hline_clip(g); // C2C
+ }
+ break;
+ }
+
+ autoflush(g);
+ MUTEX_EXIT(g);
}
+
#endif
#if GDISP_NEED_ARC
-void gdispDrawRoundedBox(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t radius, color_t color) {
- if (2*radius > cx || 2*radius > cy) {
- gdispDrawBox(x, y, cx, cy, color);
- return;
+ void gdispGDrawRoundedBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t radius, color_t color) {
+ if (2*radius > cx || 2*radius > cy) {
+ gdispDrawBox(x, y, cx, cy, color);
+ return;
+ }
+ gdispDrawArc(x+radius, y+radius, radius, 90, 180, color);
+ gdispDrawLine(x+radius+1, y, x+cx-2-radius, y, color);
+ gdispDrawArc(x+cx-1-radius, y+radius, radius, 0, 90, color);
+ gdispDrawLine(x+cx-1, y+radius+1, x+cx-1, y+cy-2-radius, color);
+ gdispDrawArc(x+cx-1-radius, y+cy-1-radius, radius, 270, 360, color);
+ gdispDrawLine(x+radius+1, y+cy-1, x+cx-2-radius, y+cy-1, color);
+ gdispDrawArc(x+radius, y+cy-1-radius, radius, 180, 270, color);
+ gdispDrawLine(x, y+radius+1, x, y+cy-2-radius, color);
}
- gdispDrawArc(x+radius, y+radius, radius, 90, 180, color);
- gdispDrawLine(x+radius+1, y, x+cx-2-radius, y, color);
- gdispDrawArc(x+cx-1-radius, y+radius, radius, 0, 90, color);
- gdispDrawLine(x+cx-1, y+radius+1, x+cx-1, y+cy-2-radius, color);
- gdispDrawArc(x+cx-1-radius, y+cy-1-radius, radius, 270, 360, color);
- gdispDrawLine(x+radius+1, y+cy-1, x+cx-2-radius, y+cy-1, color);
- gdispDrawArc(x+radius, y+cy-1-radius, radius, 180, 270, color);
- gdispDrawLine(x, y+radius+1, x, y+cy-2-radius, color);
-}
#endif
#if GDISP_NEED_ARC
-void gdispFillRoundedBox(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t radius, color_t color) {
- coord_t radius2;
+ void gdispGFillRoundedBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t radius, color_t color) {
+ coord_t radius2;
- radius2 = radius*2;
- if (radius2 > cx || radius2 > cy) {
- gdispFillArea(x, y, cx, cy, color);
- return;
+ radius2 = radius*2;
+ if (radius2 > cx || radius2 > cy) {
+ gdispFillArea(x, y, cx, cy, color);
+ return;
+ }
+ gdispFillArc(x+radius, y+radius, radius, 90, 180, color);
+ gdispFillArea(x+radius+1, y, cx-radius2, radius, color);
+ gdispFillArc(x+cx-1-radius, y+radius, radius, 0, 90, color);
+ gdispFillArc(x+cx-1-radius, y+cy-1-radius, radius, 270, 360, color);
+ gdispFillArea(x+radius+1, y+cy-radius, cx-radius2, radius, color);
+ gdispFillArc(x+radius, y+cy-1-radius, radius, 180, 270, color);
+ gdispFillArea(x, y+radius, cx, cy-radius2, color);
}
- gdispFillArc(x+radius, y+radius, radius, 90, 180, color);
- gdispFillArea(x+radius+1, y, cx-radius2, radius, color);
- gdispFillArc(x+cx-1-radius, y+radius, radius, 0, 90, color);
- gdispFillArc(x+cx-1-radius, y+cy-1-radius, radius, 270, 360, color);
- gdispFillArea(x+radius+1, y+cy-radius, cx-radius2, radius, color);
- gdispFillArc(x+radius, y+cy-1-radius, radius, 180, 270, color);
- gdispFillArea(x, y+radius, cx, cy-radius2, color);
-}
#endif
-#if (GDISP_NEED_PIXELREAD && (GDISP_NEED_MULTITHREAD || GDISP_NEED_ASYNC))
- color_t gdispGetPixelColor(coord_t x, coord_t y) {
+#if GDISP_NEED_PIXELREAD
+ color_t gdispGGetPixelColor(GDisplay *g, coord_t x, coord_t y) {
color_t c;
/* Always synchronous as it must return a value */
- gfxMutexEnter(&gdispMutex);
- c = gdisp_lld_get_pixel_color(x, y);
- gfxMutexExit(&gdispMutex);
-
- return c;
+ MUTEX_ENTER(g);
+ #if GDISP_HARDWARE_PIXELREAD
+ #if GDISP_HARDWARE_PIXELREAD == HARDWARE_AUTODETECT
+ if (g->vmt->get)
+ #endif
+ {
+ // Best is direct pixel read
+ g->p.x = x;
+ g->p.y = y;
+ c = gdisp_lld_get_pixel_color(g);
+ MUTEX_EXIT(g);
+ return c;
+ }
+ #endif
+ #if GDISP_HARDWARE_PIXELREAD != TRUE && GDISP_HARDWARE_STREAM_READ
+ #if GDISP_HARDWARE_STREAM_READ == HARDWARE_AUTODETECT
+ if (g->vmt->readcolor)
+ #endif
+ {
+ // Next best is hardware streaming
+ g->p.x = x;
+ g->p.y = y;
+ g->p.cx = 1;
+ g->p.cy = 1;
+ gdisp_lld_read_start(g);
+ c = gdisp_lld_read_color(g);
+ gdisp_lld_read_stop(g);
+ MUTEX_EXIT(g);
+ return c;
+ }
+ #endif
+ #if GDISP_HARDWARE_PIXELREAD != TRUE && GDISP_HARDWARE_STREAM_READ != TRUE
+ #if !GDISP_HARDWARE_PIXELREAD && !GDISP_HARDWARE_STREAM_READ
+ // Worst is "not possible"
+ #error "GDISP: GDISP_NEED_PIXELREAD has been set but there is no hardware support for reading the display"
+ #endif
+ MUTEX_EXIT(g);
+ return 0;
+ #endif
}
#endif
-#if (GDISP_NEED_SCROLL && GDISP_NEED_MULTITHREAD)
- void gdispVerticalScroll(coord_t x, coord_t y, coord_t cx, coord_t cy, int lines, color_t bgcolor) {
- gfxMutexEnter(&gdispMutex);
- gdisp_lld_vertical_scroll(x, y, cx, cy, lines, bgcolor);
- gfxMutexExit(&gdispMutex);
- }
-#elif GDISP_NEED_SCROLL && GDISP_NEED_ASYNC
- void gdispVerticalScroll(coord_t x, coord_t y, coord_t cx, coord_t cy, int lines, color_t bgcolor) {
- gdisp_lld_msg_t *p = gdispAllocMsg(GDISP_LLD_MSG_VERTICALSCROLL);
- p->verticalscroll.x = x;
- p->verticalscroll.y = y;
- p->verticalscroll.cx = cx;
- p->verticalscroll.cy = cy;
- p->verticalscroll.lines = lines;
- p->verticalscroll.bgcolor = bgcolor;
- gfxQueuePut(&gdispQueue, &p->qi, TIME_IMMEDIATE);
- }
-#endif
+#if GDISP_NEED_SCROLL
+ void gdispGVerticalScroll(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, int lines, color_t bgcolor) {
+ coord_t abslines;
+ #if GDISP_HARDWARE_SCROLL != TRUE
+ coord_t fy, dy, ix, fx, i, j;
+ #endif
-#if (GDISP_NEED_CONTROL && GDISP_NEED_MULTITHREAD)
- void gdispControl(unsigned what, void *value) {
- gfxMutexEnter(&gdispMutex);
- gdisp_lld_control(what, value);
- gfxMutexExit(&gdispMutex);
- }
-#elif GDISP_NEED_CONTROL && GDISP_NEED_ASYNC
- void gdispControl(unsigned what, void *value) {
- gdisp_lld_msg_t *p = gdispAllocMsg(GDISP_LLD_MSG_CONTROL);
- p->control.what = what;
- p->control.value = value;
- gfxQueuePut(&gdispQueue, &p->qi, TIME_IMMEDIATE);
+ MUTEX_ENTER(g);
+ #if NEED_CLIPPING
+ #if GDISP_HARDWARE_CLIP == HARDWARE_AUTODETECT
+ if (!g->vmt->setclip)
+ #endif
+ {
+ if (x < g->clipx0) { cx -= g->clipx0 - x; x = g->clipx0; }
+ if (y < g->clipy0) { cy -= g->clipy0 - y; y = g->clipy0; }
+ if (!lines || cx <= 0 || cy <= 0 || x >= g->clipx1 || y >= g->clipy1) { MUTEX_EXIT(g); return; }
+ if (x+cx > g->clipx1) cx = g->clipx1 - x;
+ if (y+cy > g->clipy1) cy = g->clipy1 - y;
+ }
+ #endif
+
+ abslines = lines < 0 ? -lines : lines;
+ if (abslines >= cy) {
+ abslines = cy;
+ cy = 0;
+ } else {
+ // Best is hardware scroll
+ #if GDISP_HARDWARE_SCROLL
+ #if GDISP_HARDWARE_SCROLL == HARDWARE_AUTODETECT
+ if (g->vmt->vscroll)
+ #endif
+ {
+ g->p.x = x;
+ g->p.y = y;
+ g->p.cx = cx;
+ g->p.cy = cy;
+ g->p.y1 = lines;
+ g->p.color = bgcolor;
+ gdisp_lld_vertical_scroll(g);
+ cy -= abslines;
+ }
+ #if GDISP_HARDWARE_SCROLL == HARDWARE_AUTODETECT
+ else
+ #endif
+ #elif GDISP_LINEBUF_SIZE == 0
+ #error "GDISP: GDISP_NEED_SCROLL is set but there is no hardware support and GDISP_LINEBUF_SIZE is zero."
+ #endif
+
+ // Scroll Emulation
+ #if GDISP_HARDWARE_SCROLL != TRUE
+ {
+ cy -= abslines;
+ if (lines < 0) {
+ fy = y+cy-1;
+ dy = -1;
+ } else {
+ fy = y;
+ dy = 1;
+ }
+ // Move the screen - one line at a time
+ for(i = 0; i < cy; i++, fy += dy) {
+
+ // Handle where the buffer is smaller than a line
+ for(ix=0; ix < cx; ix += GDISP_LINEBUF_SIZE) {
+
+ // Calculate the data we can move in one operation
+ fx = cx - ix;
+ if (fx > GDISP_LINEBUF_SIZE)
+ fx = GDISP_LINEBUF_SIZE;
+
+ // Read one line of data from the screen
+
+ // Best line read is hardware streaming
+ #if GDISP_HARDWARE_STREAM_READ
+ #if GDISP_HARDWARE_STREAM_READ == HARDWARE_AUTODETECT
+ if (g->vmt->readstart)
+ #endif
+ {
+ g->p.x = x+ix;
+ g->p.y = fy+lines;
+ g->p.cx = fx;
+ g->p.cy = 1;
+ gdisp_lld_read_start(g);
+ for(j=0; j < fx; j++)
+ g->linebuf[j] = gdisp_lld_read_color(g);
+ gdisp_lld_read_stop(g);
+ }
+ #if GDISP_HARDWARE_STREAM_READ == HARDWARE_AUTODETECT
+ else
+ #endif
+ #endif
+
+ // Next best line read is single pixel reads
+ #if GDISP_HARDWARE_STREAM_READ != TRUE && GDISP_HARDWARE_PIXELREAD
+ #if GDISP_HARDWARE_PIXELREAD == HARDWARE_AUTODETECT
+ if (g->vmt->get)
+ #endif
+ {
+ for(j=0; j < fx; j++) {
+ g->p.x = x+ix+j;
+ g->p.y = fy+lines;
+ g->linebuf[j] = gdisp_lld_get_pixel_color(g);
+ }
+ }
+ #if GDISP_HARDWARE_PIXELREAD == HARDWARE_AUTODETECT
+ else {
+ // Worst is "not possible"
+ MUTEX_EXIT(g);
+ return;
+ }
+ #endif
+ #endif
+
+ // Worst is "not possible"
+ #if !GDISP_HARDWARE_STREAM_READ && !GDISP_HARDWARE_PIXELREAD
+ #error "GDISP: GDISP_NEED_SCROLL is set but there is no hardware support for scrolling or reading pixels."
+ #endif
+
+ // Write that line to the new location
+
+ // Best line write is hardware bitfills
+ #if GDISP_HARDWARE_BITFILLS
+ #if GDISP_HARDWARE_BITFILLS == HARDWARE_AUTODETECT
+ if (g->vmt->blit)
+ #endif
+ {
+ g->p.x = x+ix;
+ g->p.y = fy;
+ g->p.cx = fx;
+ g->p.cy = 1;
+ g->p.x1 = 0;
+ g->p.y1 = 0;
+ g->p.x2 = fx;
+ g->p.ptr = (void *)g->linebuf;
+ gdisp_lld_blit_area(g);
+ }
+ #if GDISP_HARDWARE_BITFILLS == HARDWARE_AUTODETECT
+ else
+ #endif
+ #endif
+
+ // Next best line write is hardware streaming
+ #if GDISP_HARDWARE_BITFILLS != TRUE && GDISP_HARDWARE_STREAM_WRITE
+ #if GDISP_HARDWARE_STREAM_WRITE == HARDWARE_AUTODETECT
+ if (g->vmt->writestart)
+ #endif
+ {
+ g->p.x = x+ix;
+ g->p.y = fy;
+ g->p.cx = fx;
+ g->p.cy = 1;
+ gdisp_lld_write_start(g);
+ #if GDISP_HARDWARE_STREAM_POS
+ gdisp_lld_write_pos(g);
+ #endif
+ for(j = 0; j < fx; j++) {
+ g->p.color = g->linebuf[j];
+ gdisp_lld_write_color(g);
+ }
+ gdisp_lld_write_stop(g);
+ }
+ #if GDISP_HARDWARE_STREAM_WRITE == HARDWARE_AUTODETECT
+ else
+ #endif
+ #endif
+
+ // Next best line write is drawing pixels in combination with filling
+ #if GDISP_HARDWARE_BITFILLS != TRUE && GDISP_HARDWARE_STREAM_WRITE != TRUE && GDISP_HARDWARE_FILLS && GDISP_HARDWARE_DRAWPIXEL
+ // We don't need to test for auto-detect on drawpixel as we know we have it because we don't have streaming.
+ #if GDISP_HARDWARE_FILLS == HARDWARE_AUTODETECT
+ if (g->vmt->fill)
+ #endif
+ {
+ g->p.y = fy;
+ g->p.cy = 1;
+ g->p.x = x+ix;
+ g->p.cx = 1;
+ for(j = 0; j < fx; ) {
+ g->p.color = g->linebuf[j];
+ if (j + g->p.cx < fx && g->linebuf[j] == g->linebuf[j + g->p.cx])
+ g->p.cx++;
+ else if (g->p.cx == 1) {
+ gdisp_lld_draw_pixel(g);
+ j++;
+ g->p.x++;
+ } else {
+ gdisp_lld_fill_area(g);
+ j += g->p.cx;
+ g->p.x += g->p.cx;
+ g->p.cx = 1;
+ }
+ }
+ }
+ #if GDISP_HARDWARE_FILLS == HARDWARE_AUTODETECT
+ else
+ #endif
+ #endif
+
+ // Worst line write is drawing pixels
+ #if GDISP_HARDWARE_BITFILLS != TRUE && GDISP_HARDWARE_STREAM_WRITE != TRUE && GDISP_HARDWARE_FILLS != TRUE && GDISP_HARDWARE_DRAWPIXEL
+ // The following test is unneeded because we are guaranteed to have draw pixel if we don't have streaming
+ //#if GDISP_HARDWARE_DRAWPIXEL == HARDWARE_AUTODETECT
+ // if (g->vmt->pixel)
+ //#endif
+ {
+ g->p.y = fy;
+ for(g->p.x = x+ix, j = 0; j < fx; g->p.x++, j++) {
+ g->p.color = g->linebuf[j];
+ gdisp_lld_draw_pixel(g);
+ }
+ }
+ #endif
+ }
+ }
+ }
+ #endif
+ }
+
+ /* fill the remaining gap */
+ g->p.x = x;
+ g->p.y = lines > 0 ? (y+cy) : y;
+ g->p.cx = cx;
+ g->p.cy = abslines;
+ g->p.color = bgcolor;
+ fillarea(g);
+ autoflush_stopdone(g);
+ MUTEX_EXIT(g);
}
#endif
-#if (GDISP_NEED_MULTITHREAD || GDISP_NEED_ASYNC) && GDISP_NEED_QUERY
- void *gdispQuery(unsigned what) {
- void *res;
+#if GDISP_NEED_CONTROL
+ #if GDISP_HARDWARE_CONTROL
+ void gdispGControl(GDisplay *g, unsigned what, void *value) {
+ #if GDISP_HARDWARE_CONTROL == HARDWARE_AUTODETECT
+ if (!g->vmt->control)
+ return;
+ #endif
+ MUTEX_ENTER(g);
+ g->p.x = what;
+ g->p.ptr = value;
+ if (what == GDISP_CONTROL_ORIENTATION) {
+ switch ((orientation_t) value) {
+ case GDISP_ROTATE_LANDSCAPE:
+ g->p.ptr = g->g.Width >= g->g.Height ? (void *)GDISP_ROTATE_0 : (void *)GDISP_ROTATE_90;
+ break;
+ case GDISP_ROTATE_PORTRAIT:
+ g->p.ptr = g->g.Width >= g->g.Height ? (void *)GDISP_ROTATE_90 : (void *)GDISP_ROTATE_0;
+ break;
+ default:
+ break;
+ }
+ }
+ gdisp_lld_control(g);
+ #if GDISP_NEED_CLIP || GDISP_NEED_VALIDATION
+ if (what == GDISP_CONTROL_ORIENTATION) {
+ // Best is hardware clipping
+ #if GDISP_HARDWARE_CLIP
+ #if GDISP_HARDWARE_CLIP == HARDWARE_AUTODETECT
+ if (g->vmt->setclip)
+ #endif
+ {
+ g->p.x = 0;
+ g->p.y = 0;
+ g->p.cx = g->g.Width;
+ g->p.cy = g->g.Height;
+ gdisp_lld_set_clip(g);
+ }
+ #if GDISP_HARDWARE_CLIP == HARDWARE_AUTODETECT
+ else
+ #endif
+ #endif
+
+ // Worst is software clipping
+ #if GDISP_HARDWARE_CLIP != TRUE
+ {
+ g->clipx0 = 0;
+ g->clipy0 = 0;
+ g->clipx1 = g->g.Width;
+ g->clipy1 = g->g.Height;
+ }
+ #endif
+ }
+ #endif
+ MUTEX_EXIT(g);
+ }
+ #else
+ void gdispGControl(GDisplay *g, unsigned what, void *value) {
+ (void)g;
+ (void)what;
+ (void)value;
+ /* Ignore everything */
+ }
+ #endif
+#endif
- gfxMutexEnter(&gdispMutex);
- res = gdisp_lld_query(what);
- gfxMutexExit(&gdispMutex);
- return res;
- }
+#if GDISP_NEED_QUERY
+ #if GDISP_HARDWARE_QUERY
+ void *gdispGQuery(GDisplay *g, unsigned what) {
+ void *res;
+
+ #if GDISP_HARDWARE_QUERY == HARDWARE_AUTODETECT
+ if (!g->vmt->query)
+ return -1;
+ #endif
+ MUTEX_ENTER(g);
+ g->p.x = (coord_t)what;
+ res = gdisp_lld_query(g);
+ MUTEX_EXIT(g);
+ return res;
+ }
+ #else
+ void *gdispGQuery(GDisplay *g, unsigned what) {
+ (void) what;
+ return (void *)-1;
+ }
+ #endif
#endif
/*===========================================================================*/
/* High Level Driver Routines. */
/*===========================================================================*/
-void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
- /* No mutex required as we only call high level functions which have their own mutex */
- coord_t x1, y1;
+void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
+ if (cx <= 0 || cy <= 0) return;
+ cx = x+cx-1; cy = y+cy-1; // cx, cy are now the end point.
- x1 = x+cx-1;
- y1 = y+cy-1;
+ MUTEX_ENTER(g);
- if (cx > 2) {
- if (cy >= 1) {
- gdispDrawLine(x, y, x1, y, color);
- if (cy >= 2) {
- gdispDrawLine(x, y1, x1, y1, color);
- if (cy > 2) {
- gdispDrawLine(x, y+1, x, y1-1, color);
- gdispDrawLine(x1, y+1, x1, y1-1, color);
- }
+ g->p.color = color;
+
+ if (cx - x > 2) {
+ g->p.x = x; g->p.y = y; g->p.x1 = cx; hline_clip(g);
+ if (y != cy) {
+ g->p.x = x; g->p.y = cy; g->p.x1 = cx; hline_clip(g);
+ if (cy - y > 2) {
+ y++; cy--;
+ g->p.x = x; g->p.y = y; g->p.y1 = cy; vline_clip(g);
+ g->p.x = cx; g->p.y = y; g->p.y1 = cy; vline_clip(g);
}
}
- } else if (cx == 2) {
- gdispDrawLine(x, y, x, y1, color);
- gdispDrawLine(x1, y, x1, y1, color);
- } else if (cx == 1) {
- gdispDrawLine(x, y, x, y1, color);
+ } else {
+ g->p.x = x; g->p.y = y; g->p.y1 = cy; vline_clip(g);
+ if (x != cx) {
+ g->p.x = cx; g->p.y = y; g->p.y1 = cy; vline_clip(g);
+ }
}
+
+ autoflush(g);
+ MUTEX_EXIT(g);
}
#if GDISP_NEED_CONVEX_POLYGON
- void gdispDrawPoly(coord_t tx, coord_t ty, const point *pntarray, unsigned cnt, color_t color) {
+ void gdispGDrawPoly(GDisplay *g, coord_t tx, coord_t ty, const point *pntarray, unsigned cnt, color_t color) {
const point *epnt, *p;
epnt = &pntarray[cnt-1];
- for(p = pntarray; p < epnt; p++)
- gdispDrawLine(tx+p->x, ty+p->y, tx+p[1].x, ty+p[1].y, color);
- gdispDrawLine(tx+p->x, ty+p->y, tx+pntarray->x, ty+pntarray->y, color);
+
+ MUTEX_ENTER(g);
+ g->p.color = color;
+ for(p = pntarray; p < epnt; p++) {
+ g->p.x=tx+p->x; g->p.y=ty+p->y; g->p.x1=tx+p[1].x; g->p.y1=ty+p[1].y; line_clip(g);
+ }
+ g->p.x=tx+p->x; g->p.y=ty+p->y; g->p.x1=tx+pntarray->x; g->p.y1=ty+pntarray->y; line_clip(g);
+
+ autoflush(g);
+ MUTEX_EXIT(g);
}
- void gdispFillConvexPoly(coord_t tx, coord_t ty, const point *pntarray, unsigned cnt, color_t color) {
+ void gdispGFillConvexPoly(GDisplay *g, coord_t tx, coord_t ty, const point *pntarray, unsigned cnt, color_t color) {
const point *lpnt, *rpnt, *epnts;
fixed lx, rx, lk, rk;
coord_t y, ymax, lxc, rxc;
@@ -510,21 +2521,21 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
y = rpnt->y;
/* Work out the slopes of the two attached line segs */
- lpnt = rpnt <= pntarray ? epnts : rpnt-1;
- while (lpnt->y == y) {
+ for (lpnt = rpnt <= pntarray ? epnts : rpnt-1; lpnt->y == y; cnt--) {
+ if (!cnt) return;
lx = FIXED(lpnt->x);
lpnt = lpnt <= pntarray ? epnts : lpnt-1;
- if (!cnt--) return;
}
- rpnt = rpnt >= epnts ? pntarray : rpnt+1;
- while (rpnt->y == y) {
- rx = rpnt->x<<16;
+ for (rpnt = rpnt >= epnts ? pntarray : rpnt+1; rpnt->y == y; cnt--) {
+ if (!cnt) return;
+ rx = FIXED(rpnt->x);
rpnt = rpnt >= epnts ? pntarray : rpnt+1;
- if (!cnt--) return;
}
lk = (FIXED(lpnt->x) - lx) / (lpnt->y - y);
rk = (FIXED(rpnt->x) - rx) / (rpnt->y - y);
+ MUTEX_ENTER(g);
+ g->p.color = color;
while(1) {
/* Determine our boundary */
ymax = rpnt->y < lpnt->y ? rpnt->y : lpnt->y;
@@ -539,38 +2550,43 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
* of pixels.
*/
if (lxc < rxc) {
- if (rxc - lxc == 1)
- gdispDrawPixel(tx+lxc, ty+y, color);
- else
- gdispDrawLine(tx+lxc, ty+y, tx+rxc-1, ty+y, color);
+ g->p.x=tx+lxc; g->p.y=ty+y; g->p.x1=tx+rxc-1; hline_clip(g);
} else if (lxc > rxc) {
- if (lxc - rxc == 1)
- gdispDrawPixel(tx+rxc, ty+y, color);
- else
- gdispDrawLine(tx+rxc, ty+y, tx+lxc-1, ty+y, color);
+ g->p.x=tx+rxc; g->p.y=ty+y; g->p.x1=tx+lxc-1; hline_clip(g);
}
lx += lk;
rx += rk;
}
- if (!cnt--) return;
+ if (!cnt) {
+ autoflush(g);
+ MUTEX_EXIT(g);
+ return;
+ }
+ cnt--;
/* Replace the appropriate point */
if (ymax == lpnt->y) {
- lpnt = lpnt <= pntarray ? epnts : lpnt-1;
- while (lpnt->y == y) {
+ for (lpnt = lpnt <= pntarray ? epnts : lpnt-1; lpnt->y == y; cnt--) {
+ if (!cnt) {
+ autoflush(g);
+ MUTEX_EXIT(g);
+ return;
+ }
lx = FIXED(lpnt->x);
lpnt = lpnt <= pntarray ? epnts : lpnt-1;
- if (!cnt--) return;
}
lk = (FIXED(lpnt->x) - lx) / (lpnt->y - y);
} else {
- rpnt = rpnt >= epnts ? pntarray : rpnt+1;
- while (rpnt->y == y) {
+ for (rpnt = rpnt >= epnts ? pntarray : rpnt+1; rpnt->y == y; cnt--) {
+ if (!cnt) {
+ autoflush(g);
+ MUTEX_EXIT(g);
+ return;
+ }
rx = FIXED(rpnt->x);
rpnt = rpnt >= epnts ? pntarray : rpnt+1;
- if (!cnt--) return;
}
rk = (FIXED(rpnt->x) - rx) / (rpnt->y - y);
}
@@ -581,178 +2597,142 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
#if GDISP_NEED_TEXT
#include "mcufont.h"
- #if GDISP_NEED_ANTIALIAS && GDISP_NEED_PIXELREAD
- static void text_draw_char_callback(int16_t x, int16_t y, uint8_t count, uint8_t alpha, void *state) {
+ #if GDISP_NEED_ANTIALIAS && GDISP_HARDWARE_PIXELREAD
+ static void drawcharline(int16_t x, int16_t y, uint8_t count, uint8_t alpha, void *state) {
+ #define GD ((GDisplay *)state)
+ if (y < GD->t.clipy0 || y >= GD->t.clipy1 || x < GD->t.clipx0 || x+count > GD->t.clipx1) return;
if (alpha == 255) {
- if (count == 1)
- gdispDrawPixel(x, y, ((color_t *)state)[0]);
- else
- gdispFillArea(x, y, count, 1, ((color_t *)state)[0]);
+ GD->p.x = x; GD->p.y = y; GD->p.x1 = x+count-1; GD->p.color = GD->t.color;
+ hline_clip(GD);
} else {
- while (count--) {
- gdispDrawPixel(x, y, gdispBlendColor(((color_t *)state)[0], gdispGetPixelColor(x, y), alpha));
- x++;
+ for (; count; count--, x++) {
+ GD->p.x = x; GD->p.y = y;
+ GD->p.color = gdispBlendColor(GD->t.color, gdisp_lld_get_pixel_color(GD), alpha);
+ drawpixel_clip(GD);
}
}
+ #undef GD
}
#else
- static void text_draw_char_callback(int16_t x, int16_t y, uint8_t count, uint8_t alpha, void *state) {
+ static void drawcharline(int16_t x, int16_t y, uint8_t count, uint8_t alpha, void *state) {
+ #define GD ((GDisplay *)state)
+ if (y < GD->t.clipy0 || y >= GD->t.clipy1 || x < GD->t.clipx0 || x+count > GD->t.clipx1) return;
if (alpha > 0x80) { // A best approximation when using anti-aliased fonts but we can't actually draw them anti-aliased
- if (count == 1)
- gdispDrawPixel(x, y, ((color_t *)state)[0]);
- else
- gdispFillArea(x, y, count, 1, ((color_t *)state)[0]);
+ GD->p.x = x; GD->p.y = y; GD->p.x1 = x+count-1; GD->p.color = GD->t.color;
+ hline_clip(GD);
}
+ #undef GD
}
#endif
- void gdispDrawChar(coord_t x, coord_t y, uint16_t c, font_t font, color_t color) {
- /* No mutex required as we only call high level functions which have their own mutex */
- mf_render_character(font, x, y, c, text_draw_char_callback, &color);
- }
-
#if GDISP_NEED_ANTIALIAS
- static void text_fill_char_callback(int16_t x, int16_t y, uint8_t count, uint8_t alpha, void *state) {
+ static void fillcharline(int16_t x, int16_t y, uint8_t count, uint8_t alpha, void *state) {
+ #define GD ((GDisplay *)state)
+ if (y < GD->t.clipy0 || y >= GD->t.clipy1 || x < GD->t.clipx0 || x+count > GD->t.clipx1) return;
if (alpha == 255) {
- if (count == 1)
- gdispDrawPixel(x, y, ((color_t *)state)[0]);
- else
- gdispFillArea(x, y, count, 1, ((color_t *)state)[0]);
+ GD->p.color = GD->t.color;
} else {
- while (count--) {
- gdispDrawPixel(x, y, gdispBlendColor(((color_t *)state)[0], ((color_t *)state)[1], alpha));
- x++;
- }
+ GD->p.color = gdispBlendColor(GD->t.color, GD->t.bgcolor, alpha);
}
+ GD->p.x = x; GD->p.y = y; GD->p.x1 = x+count-1;
+ hline_clip(GD);
+ #undef GD
}
#else
- #define text_fill_char_callback text_draw_char_callback
+ #define fillcharline drawcharline
#endif
- void gdispFillChar(coord_t x, coord_t y, uint16_t c, font_t font, color_t color, color_t bgcolor) {
- /* No mutex required as we only call high level functions which have their own mutex */
- color_t state[2];
+ /* Callback to render characters. */
+ static uint8_t drawcharglyph(int16_t x, int16_t y, mf_char ch, void *state) {
+ #define GD ((GDisplay *)state)
+ return mf_render_character(GD->t.font, x, y, ch, drawcharline, state);
+ #undef GD
+ }
- state[0] = color;
- state[1] = bgcolor;
+ /* Callback to render characters. */
+ static uint8_t fillcharglyph(int16_t x, int16_t y, mf_char ch, void *state) {
+ #define GD ((GDisplay *)state)
+ return mf_render_character(GD->t.font, x, y, ch, fillcharline, state);
+ #undef GD
+ }
- gdispFillArea(x, y, mf_character_width(font, c) + font->baseline_x, font->height, bgcolor);
- mf_render_character(font, x, y, c, text_fill_char_callback, state);
+ void gdispGDrawChar(GDisplay *g, coord_t x, coord_t y, uint16_t c, font_t font, color_t color) {
+ MUTEX_ENTER(g);
+ g->t.font = font;
+ g->t.clipx0 = x;
+ g->t.clipy0 = y;
+ g->t.clipx1 = x + mf_character_width(font, c) + font->baseline_x;
+ g->t.clipy1 = y + font->height;
+ g->t.color = color;
+ mf_render_character(font, x, y, c, drawcharline, g);
+ autoflush(g);
+ MUTEX_EXIT(g);
}
- typedef struct
- {
- font_t font;
- color_t color;
- coord_t x, y;
- coord_t cx, cy;
- } gdispDrawString_state_t;
+ void gdispGFillChar(GDisplay *g, coord_t x, coord_t y, uint16_t c, font_t font, color_t color, color_t bgcolor) {
+ MUTEX_ENTER(g);
+ g->p.cx = mf_character_width(font, c) + font->baseline_x;
+ g->p.cy = font->height;
+ g->t.font = font;
+ g->t.clipx0 = g->p.x = x;
+ g->t.clipy0 = g->p.y = y;
+ g->t.clipx1 = g->p.x+g->p.cx;
+ g->t.clipy1 = g->p.y+g->p.cy;
+ g->t.color = color;
+ g->t.bgcolor = g->p.color = bgcolor;
+
+ TEST_CLIP_AREA(g) {
+ fillarea(g);
+ mf_render_character(font, x, y, c, fillcharline, g);
+ }
+ autoflush(g);
+ MUTEX_EXIT(g);
+ }
- /* Callback to render characters. */
- static uint8_t gdispDrawString_callback(int16_t x, int16_t y, mf_char character, void *state)
- {
- gdispDrawString_state_t *s = state;
- uint8_t w;
-
- w = mf_character_width(s->font, character);
- if (x >= s->x && x+w < s->x + s->cx && y >= s->y && y+s->font->height <= s->y + s->cy)
- mf_render_character(s->font, x, y, character, text_draw_char_callback, &s->color);
- return w;
- }
-
- void gdispDrawString(coord_t x, coord_t y, const char *str, font_t font, color_t color) {
- /* No mutex required as we only call high level functions which have their own mutex */
- gdispDrawString_state_t state;
-
- state.font = font;
- state.color = color;
- state.x = x;
- state.y = y;
- state.cx = GDISP.Width - x;
- state.cy = GDISP.Height - y;
-
- x += font->baseline_x;
- mf_render_aligned(font, x, y, MF_ALIGN_LEFT, str, 0, gdispDrawString_callback, &state);
- }
-
- typedef struct
- {
- font_t font;
- color_t color[2];
- coord_t x, y;
- coord_t cx, cy;
- } gdispFillString_state_t;
+ void gdispGDrawString(GDisplay *g, coord_t x, coord_t y, const char *str, font_t font, color_t color) {
+ MUTEX_ENTER(g);
+ g->t.font = font;
+ g->t.clipx0 = x;
+ g->t.clipy0 = y;
+ g->t.clipx1 = x + mf_get_string_width(font, str, 0, 0);
+ g->t.clipy1 = y + font->height;
+ g->t.color = color;
+
+ mf_render_aligned(font, x+font->baseline_x, y, MF_ALIGN_LEFT, str, 0, drawcharglyph, g);
+ autoflush(g);
+ MUTEX_EXIT(g);
+ }
- /* Callback to render characters. */
- static uint8_t gdispFillString_callback(int16_t x, int16_t y, mf_char character, void *state)
- {
- gdispFillString_state_t *s = state;
- uint8_t w;
-
- w = mf_character_width(s->font, character);
- if (x >= s->x && x+w < s->x + s->cx && y >= s->y && y+s->font->height <= s->y + s->cy)
- mf_render_character(s->font, x, y, character, text_fill_char_callback, s->color);
- return w;
- }
-
- void gdispFillString(coord_t x, coord_t y, const char *str, font_t font, color_t color, color_t bgcolor) {
- /* No mutex required as we only call high level functions which have their own mutex */
- gdispFillString_state_t state;
-
- state.font = font;
- state.color[0] = color;
- state.color[1] = bgcolor;
- state.x = x;
- state.y = y;
- state.cx = mf_get_string_width(font, str, 0, 0);
- state.cy = font->height;
-
- gdispFillArea(x, y, state.cx, state.cy, bgcolor);
- mf_render_aligned(font, x+font->baseline_x, y, MF_ALIGN_LEFT, str, 0, gdispFillString_callback, &state);
- }
-
- void gdispDrawStringBox(coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, font_t font, color_t color, justify_t justify) {
- /* No mutex required as we only call high level functions which have their own mutex */
- gdispDrawString_state_t state;
-
- state.font = font;
- state.color = color;
- state.x = x;
- state.y = y;
- state.cx = cx;
- state.cy = cy;
-
- /* Select the anchor position */
- switch(justify) {
- case justifyCenter:
- x += (cx + 1) / 2;
- break;
- case justifyRight:
- x += cx;
- break;
- default: // justifyLeft
- x += font->baseline_x;
- break;
+ void gdispGFillString(GDisplay *g, coord_t x, coord_t y, const char *str, font_t font, color_t color, color_t bgcolor) {
+ MUTEX_ENTER(g);
+ g->p.cx = mf_get_string_width(font, str, 0, 0);
+ g->p.cy = font->height;
+ g->t.font = font;
+ g->t.clipx0 = g->p.x = x;
+ g->t.clipy0 = g->p.y = y;
+ g->t.clipx1 = g->p.x+g->p.cx;
+ g->t.clipy1 = g->p.y+g->p.cy;
+ g->t.color = color;
+ g->t.bgcolor = g->p.color = bgcolor;
+
+ TEST_CLIP_AREA(g) {
+ fillarea(g);
+ mf_render_aligned(font, x+font->baseline_x, y, MF_ALIGN_LEFT, str, 0, fillcharglyph, g);
}
- y += (cy+1 - font->height)/2;
- mf_render_aligned(font, x, y, justify, str, 0, gdispDrawString_callback, &state);
+ autoflush(g);
+ MUTEX_EXIT(g);
}
- void gdispFillStringBox(coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, font_t font, color_t color, color_t bgcolor, justify_t justify) {
- /* No mutex required as we only call high level functions which have their own mutex */
- gdispFillString_state_t state;
-
- state.font = font;
- state.color[0] = color;
- state.color[1] = bgcolor;
- state.x = x;
- state.y = y;
- state.cx = cx;
- state.cy = cy;
+ void gdispGDrawStringBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, font_t font, color_t color, justify_t justify) {
+ MUTEX_ENTER(g);
+ g->t.font = font;
+ g->t.clipx0 = x;
+ g->t.clipy0 = y;
+ g->t.clipx1 = x+cx;
+ g->t.clipy1 = y+cy;
+ g->t.color = color;
- gdispFillArea(x, y, cx, cy, bgcolor);
-
/* Select the anchor position */
switch(justify) {
case justifyCenter:
@@ -766,9 +2746,50 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
break;
}
y += (cy+1 - font->height)/2;
-
- /* Render */
- mf_render_aligned(font, x, y, justify, str, 0, gdispFillString_callback, &state);
+
+ mf_render_aligned(font, x, y, justify, str, 0, drawcharglyph, g);
+
+ autoflush(g);
+ MUTEX_EXIT(g);
+ }
+
+ void gdispGFillStringBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, font_t font, color_t color, color_t bgcolor, justify_t justify) {
+ MUTEX_ENTER(g);
+ g->p.cx = cx;
+ g->p.cy = cy;
+ g->t.font = font;
+ g->t.clipx0 = g->p.x = x;
+ g->t.clipy0 = g->p.y = y;
+ g->t.clipx1 = x+cx;
+ g->t.clipy1 = y+cy;
+ g->t.color = color;
+ g->t.bgcolor = g->p.color = bgcolor;
+
+ TEST_CLIP_AREA(g) {
+
+ // background fill
+ fillarea(g);
+
+ /* Select the anchor position */
+ switch(justify) {
+ case justifyCenter:
+ x += (cx + 1) / 2;
+ break;
+ case justifyRight:
+ x += cx;
+ break;
+ default: // justifyLeft
+ x += font->baseline_x;
+ break;
+ }
+ y += (cy+1 - font->height)/2;
+
+ /* Render */
+ mf_render_aligned(font, x, y, justify, str, 0, fillcharglyph, g);
+ }
+
+ autoflush(g);
+ MUTEX_EXIT(g);
}
coord_t gdispGetFontMetric(font_t font, fontmetric_t metric) {
@@ -831,5 +2852,6 @@ color_t gdispBlendColor(color_t fg, color_t bg, uint8_t alpha)
}
#endif
+
#endif /* GFX_USE_GDISP */
/** @} */
diff --git a/src/gdisp/image.c b/src/gdisp/image.c
index 1e9ac3d6..62af0aeb 100644
--- a/src/gdisp/image.c
+++ b/src/gdisp/image.c
@@ -23,7 +23,8 @@ typedef struct gdispImageHandlers {
gdispImageError (*open)(gdispImage *img); /* The open function */
void (*close)(gdispImage *img); /* The close function */
gdispImageError (*cache)(gdispImage *img); /* The cache function */
- gdispImageError (*draw)(gdispImage *img,
+ gdispImageError (*draw)(GDisplay *g,
+ gdispImage *img,
coord_t x, coord_t y,
coord_t cx, coord_t cy,
coord_t sx, coord_t sy); /* The draw function */
@@ -33,27 +34,27 @@ typedef struct gdispImageHandlers {
static gdispImageHandlers ImageHandlers[] = {
#if GDISP_NEED_IMAGE_NATIVE
{ gdispImageOpen_NATIVE, gdispImageClose_NATIVE,
- gdispImageCache_NATIVE, gdispImageDraw_NATIVE, gdispImageNext_NATIVE,
+ gdispImageCache_NATIVE, gdispGImageDraw_NATIVE, gdispImageNext_NATIVE,
},
#endif
#if GDISP_NEED_IMAGE_GIF
{ gdispImageOpen_GIF, gdispImageClose_GIF,
- gdispImageCache_GIF, gdispImageDraw_GIF, gdispImageNext_GIF,
+ gdispImageCache_GIF, gdispGImageDraw_GIF, gdispImageNext_GIF,
},
#endif
#if GDISP_NEED_IMAGE_BMP
{ gdispImageOpen_BMP, gdispImageClose_BMP,
- gdispImageCache_BMP, gdispImageDraw_BMP, gdispImageNext_BMP,
+ gdispImageCache_BMP, gdispGImageDraw_BMP, gdispImageNext_BMP,
},
#endif
#if GDISP_NEED_IMAGE_JPG
{ gdispImageOpen_JPG, gdispImageClose_JPG,
- gdispImageCache_JPG, gdispImageDraw_JPG, gdispImageNext_JPG,
+ gdispImageCache_JPG, gdispGImageDraw_JPG, gdispImageNext_JPG,
},
#endif
#if GDISP_NEED_IMAGE_PNG
{ gdispImageOpen_PNG, gdispImageClose_PNG,
- gdispImageCache_PNG, gdispImageDraw_PNG, gdispImageNext_PNG,
+ gdispImageCache_PNG, gdispGImageDraw_PNG, gdispImageNext_PNG,
},
#endif
};
@@ -205,9 +206,9 @@ gdispImageError gdispImageCache(gdispImage *img) {
return img->fns->cache(img);
}
-gdispImageError gdispImageDraw(gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy) {
+gdispImageError gdispGImageDraw(GDisplay *g, gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy) {
if (!img->fns) return GDISP_IMAGE_ERR_BADFORMAT;
- return img->fns->draw(img, x, y, cx, cy, sx, sy);
+ return img->fns->draw(g, img, x, y, cx, cy, sx, sy);
}
delaytime_t gdispImageNext(gdispImage *img) {
diff --git a/src/gdisp/image_bmp.c b/src/gdisp/image_bmp.c
index e23d0fb1..158d6edc 100644
--- a/src/gdisp/image_bmp.c
+++ b/src/gdisp/image_bmp.c
@@ -828,7 +828,7 @@ gdispImageError gdispImageCache_BMP(gdispImage *img) {
return GDISP_IMAGE_ERR_OK;
}
-gdispImageError gdispImageDraw_BMP(gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy) {
+gdispImageError gdispGImageDraw_BMP(GDisplay *g, gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy) {
gdispImagePrivate * priv;
coord_t mx, my;
coord_t pos, len, st;
@@ -842,7 +842,7 @@ gdispImageError gdispImageDraw_BMP(gdispImage *img, coord_t x, coord_t y, coord_
/* Draw from the image cache - if it exists */
if (priv->frame0cache) {
- gdispBlitAreaEx(x, y, cx, cy, sx, sy, img->width, priv->frame0cache);
+ gdispGBlitArea(g, x, y, cx, cy, sx, sy, img->width, priv->frame0cache);
return GDISP_IMAGE_ERR_OK;
}
@@ -864,9 +864,9 @@ gdispImageError gdispImageDraw_BMP(gdispImage *img, coord_t x, coord_t y, coord_
len = pos-st;
if (mx+st+len > sx+cx) len = sx+cx-mx-st;
if (len == 1)
- gdispDrawPixel(x+mx+st-sx, y+my-sy, priv->buf[st]);
+ gdispGDrawPixel(g, x+mx+st-sx, y+my-sy, priv->buf[st]);
else
- gdispBlitAreaEx(x+mx+st-sx, y+my-sy, len, 1, st, 0, pos, priv->buf);
+ gdispGBlitArea(g, x+mx+st-sx, y+my-sy, len, 1, st, 0, pos, priv->buf);
}
mx += pos;
}
@@ -882,9 +882,9 @@ gdispImageError gdispImageDraw_BMP(gdispImage *img, coord_t x, coord_t y, coord_
len = pos-st;
if (mx+st+len > sx+cx) len = sx+cx-mx-st;
if (len == 1)
- gdispDrawPixel(x+mx+st-sx, y+my-sy, priv->buf[st]);
+ gdispGDrawPixel(g, x+mx+st-sx, y+my-sy, priv->buf[st]);
else
- gdispBlitAreaEx(x+mx+st-sx, y+my-sy, len, 1, st, 0, pos, priv->buf);
+ gdispGBlitArea(g, x+mx+st-sx, y+my-sy, len, 1, st, 0, pos, priv->buf);
}
mx += pos;
}
diff --git a/src/gdisp/image_gif.c b/src/gdisp/image_gif.c
index d067bd0f..1ff72ff0 100644
--- a/src/gdisp/image_gif.c
+++ b/src/gdisp/image_gif.c
@@ -820,7 +820,7 @@ baddatacleanup:
return GDISP_IMAGE_ERR_BADDATA;
}
-gdispImageError gdispImageDraw_GIF(gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy) {
+gdispImageError gdispGImageDraw_GIF(GDisplay *g, gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy) {
gdispImagePrivate * priv;
imgdecode * decode;
uint8_t * q = 0;
@@ -847,9 +847,9 @@ gdispImageError gdispImageDraw_GIF(gdispImage *img, coord_t x, coord_t y, coord_
// The spec says to restore the backgound color (priv->bgcolor) but in practice if there is transparency
// image decoders tend to assume that a restore to the transparent color is required instead
if (((priv->dispose.flags & GIFL_TRANSPARENT) /*&& priv->dispose.paltrans == priv->bgcolor*/) || priv->bgcolor >= priv->palsize)
- gdispFillArea(x+mx-sx, y+my-sy, fx-mx, fy-my, img->bgcolor);
+ gdispGFillArea(g, x+mx-sx, y+my-sy, fx-mx, fy-my, img->bgcolor);
else
- gdispFillArea(x+mx-sx, y+my-sy, fx-mx, fy-my, priv->palette[priv->bgcolor]);
+ gdispGFillArea(g, x+mx-sx, y+my-sy, fx-mx, fy-my, priv->palette[priv->bgcolor]);
}
}
@@ -881,23 +881,23 @@ gdispImageError gdispImageDraw_GIF(gdispImage *img, coord_t x, coord_t y, coord_
// We have a transparent pixel - dump the buffer to the display
switch(gcnt) {
case 0: break;
- case 1: gdispDrawPixel(x+mx-sx-gcnt, y+my-sy, priv->buf[0]); gcnt = 0; break;
- default: gdispBlitAreaEx(x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); gcnt = 0; break;
+ case 1: gdispGDrawPixel(g, x+mx-sx-gcnt, y+my-sy, priv->buf[0]); gcnt = 0; break;
+ default: gdispGBlitArea(g, x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); gcnt = 0; break;
}
continue;
}
priv->buf[gcnt++] = cache->palette[col];
if (gcnt >= BLIT_BUFFER_SIZE) {
// We have run out of buffer - dump it to the display
- gdispBlitAreaEx(x+mx-sx-gcnt+1, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf);
+ gdispGBlitArea(g, x+mx-sx-gcnt+1, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf);
gcnt = 0;
}
}
// We have finished the line - dump the buffer to the display
switch(gcnt) {
- case 0: break;
- case 1: gdispDrawPixel(x+mx-sx-gcnt, y+my-sy, priv->buf[0]); break;
- default: gdispBlitAreaEx(x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); break;
+ case 0: break;
+ case 1: gdispGDrawPixel(g, x+mx-sx-gcnt, y+my-sy, priv->buf[0]); break;
+ default: gdispGBlitArea(g, x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); break;
}
}
@@ -935,15 +935,15 @@ gdispImageError gdispImageDraw_GIF(gdispImage *img, coord_t x, coord_t y, coord_
// We have a transparent pixel - dump the buffer to the display
switch(gcnt) {
case 0: break;
- case 1: gdispDrawPixel(x+mx-sx-gcnt, y+my-sy, priv->buf[0]); gcnt = 0; break;
- default: gdispBlitAreaEx(x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); gcnt = 0; break;
+ case 1: gdispGDrawPixel(g, x+mx-sx-gcnt, y+my-sy, priv->buf[0]); gcnt = 0; break;
+ default: gdispGBlitArea(g, x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); gcnt = 0; break;
}
continue;
}
priv->buf[gcnt++] = decode->palette[col];
if (gcnt >= BLIT_BUFFER_SIZE) {
// We have run out of buffer - dump it to the display
- gdispBlitAreaEx(x+mx-sx-gcnt+1, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf);
+ gdispGBlitArea(g, x+mx-sx-gcnt+1, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf);
gcnt = 0;
}
continue;
@@ -951,15 +951,15 @@ gdispImageError gdispImageDraw_GIF(gdispImage *img, coord_t x, coord_t y, coord_
// We have finished the visible area - dump the buffer to the display
switch(gcnt) {
case 0: break;
- case 1: gdispDrawPixel(x+mx-sx-gcnt, y+my-sy, priv->buf[0]); gcnt = 0; break;
- default: gdispBlitAreaEx(x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); gcnt = 0; break;
+ case 1: gdispGDrawPixel(g, x+mx-sx-gcnt, y+my-sy, priv->buf[0]); gcnt = 0; break;
+ default: gdispGBlitArea(g, x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); gcnt = 0; break;
}
}
// We have finished the line - dump the buffer to the display
switch(gcnt) {
- case 0: break;
- case 1: gdispDrawPixel(x+mx-sx-gcnt, y+my-sy, priv->buf[0]); break;
- default: gdispBlitAreaEx(x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); break;
+ case 0: break;
+ case 1: gdispGDrawPixel(g, x+mx-sx-gcnt, y+my-sy, priv->buf[0]); break;
+ default: gdispGBlitArea(g, x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); break;
}
}
// Every 8th row starting at row 4
@@ -981,15 +981,15 @@ gdispImageError gdispImageDraw_GIF(gdispImage *img, coord_t x, coord_t y, coord_
// We have a transparent pixel - dump the buffer to the display
switch(gcnt) {
case 0: break;
- case 1: gdispDrawPixel(x+mx-sx-gcnt, y+my-sy, priv->buf[0]); gcnt = 0; break;
- default: gdispBlitAreaEx(x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); gcnt = 0; break;
+ case 1: gdispGDrawPixel(g, x+mx-sx-gcnt, y+my-sy, priv->buf[0]); gcnt = 0; break;
+ default: gdispGBlitArea(g, x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); gcnt = 0; break;
}
continue;
}
priv->buf[gcnt++] = decode->palette[col];
if (gcnt >= BLIT_BUFFER_SIZE) {
// We have run out of buffer - dump it to the display
- gdispBlitAreaEx(x+mx-sx-gcnt+1, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf);
+ gdispGBlitArea(g, x+mx-sx-gcnt+1, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf);
gcnt = 0;
}
continue;
@@ -997,15 +997,15 @@ gdispImageError gdispImageDraw_GIF(gdispImage *img, coord_t x, coord_t y, coord_
// We have finished the visible area - dump the buffer to the display
switch(gcnt) {
case 0: break;
- case 1: gdispDrawPixel(x+mx-sx-gcnt, y+my-sy, priv->buf[0]); gcnt = 0; break;
- default: gdispBlitAreaEx(x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); gcnt = 0; break;
+ case 1: gdispGDrawPixel(g, x+mx-sx-gcnt, y+my-sy, priv->buf[0]); gcnt = 0; break;
+ default: gdispGBlitArea(g, x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); gcnt = 0; break;
}
}
// We have finished the line - dump the buffer to the display
switch(gcnt) {
- case 0: break;
- case 1: gdispDrawPixel(x+mx-sx-gcnt, y+my-sy, priv->buf[0]); break;
- default: gdispBlitAreaEx(x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); break;
+ case 0: break;
+ case 1: gdispGDrawPixel(g, x+mx-sx-gcnt, y+my-sy, priv->buf[0]); break;
+ default: gdispGBlitArea(g, x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); break;
}
}
// Every 4th row starting at row 2
@@ -1027,15 +1027,15 @@ gdispImageError gdispImageDraw_GIF(gdispImage *img, coord_t x, coord_t y, coord_
// We have a transparent pixel - dump the buffer to the display
switch(gcnt) {
case 0: break;
- case 1: gdispDrawPixel(x+mx-sx-gcnt, y+my-sy, priv->buf[0]); gcnt = 0; break;
- default: gdispBlitAreaEx(x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); gcnt = 0; break;
+ case 1: gdispGDrawPixel(g, x+mx-sx-gcnt, y+my-sy, priv->buf[0]); gcnt = 0; break;
+ default: gdispGBlitArea(g, x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); gcnt = 0; break;
}
continue;
}
priv->buf[gcnt++] = decode->palette[col];
if (gcnt >= BLIT_BUFFER_SIZE) {
// We have run out of buffer - dump it to the display
- gdispBlitAreaEx(x+mx-sx-gcnt+1, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf);
+ gdispGBlitArea(g, x+mx-sx-gcnt+1, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf);
gcnt = 0;
}
continue;
@@ -1043,15 +1043,15 @@ gdispImageError gdispImageDraw_GIF(gdispImage *img, coord_t x, coord_t y, coord_
// We have finished the visible area - dump the buffer to the display
switch(gcnt) {
case 0: break;
- case 1: gdispDrawPixel(x+mx-sx-gcnt, y+my-sy, priv->buf[0]); gcnt = 0; break;
- default: gdispBlitAreaEx(x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); gcnt = 0; break;
+ case 1: gdispGDrawPixel(g, x+mx-sx-gcnt, y+my-sy, priv->buf[0]); gcnt = 0; break;
+ default: gdispGBlitArea(g, x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); gcnt = 0; break;
}
}
// We have finished the line - dump the buffer to the display
switch(gcnt) {
- case 0: break;
- case 1: gdispDrawPixel(x+mx-sx-gcnt, y+my-sy, priv->buf[0]); break;
- default: gdispBlitAreaEx(x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); break;
+ case 0: break;
+ case 1: gdispGDrawPixel(g, x+mx-sx-gcnt, y+my-sy, priv->buf[0]); break;
+ default: gdispGBlitArea(g, x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); break;
}
}
// Every 2nd row starting at row 1
@@ -1073,15 +1073,15 @@ gdispImageError gdispImageDraw_GIF(gdispImage *img, coord_t x, coord_t y, coord_
// We have a transparent pixel - dump the buffer to the display
switch(gcnt) {
case 0: break;
- case 1: gdispDrawPixel(x+mx-sx-gcnt, y+my-sy, priv->buf[0]); gcnt = 0; break;
- default: gdispBlitAreaEx(x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); gcnt = 0; break;
+ case 1: gdispGDrawPixel(g, x+mx-sx-gcnt, y+my-sy, priv->buf[0]); gcnt = 0; break;
+ default: gdispGBlitArea(g, x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); gcnt = 0; break;
}
continue;
}
priv->buf[gcnt++] = decode->palette[col];
if (gcnt >= BLIT_BUFFER_SIZE) {
// We have run out of buffer - dump it to the display
- gdispBlitAreaEx(x+mx-sx-gcnt+1, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf);
+ gdispGBlitArea(g, x+mx-sx-gcnt+1, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf);
gcnt = 0;
}
continue;
@@ -1089,15 +1089,15 @@ gdispImageError gdispImageDraw_GIF(gdispImage *img, coord_t x, coord_t y, coord_
// We have finished the visible area - dump the buffer to the display
switch(gcnt) {
case 0: break;
- case 1: gdispDrawPixel(x+mx-sx-gcnt, y+my-sy, priv->buf[0]); gcnt = 0; break;
- default: gdispBlitAreaEx(x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); gcnt = 0; break;
+ case 1: gdispGDrawPixel(g, x+mx-sx-gcnt, y+my-sy, priv->buf[0]); gcnt = 0; break;
+ default: gdispGBlitArea(g, x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); gcnt = 0; break;
}
}
// We have finished the line - dump the buffer to the display
switch(gcnt) {
- case 0: break;
- case 1: gdispDrawPixel(x+mx-sx-gcnt, y+my-sy, priv->buf[0]); break;
- default: gdispBlitAreaEx(x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); break;
+ case 0: break;
+ case 1: gdispGDrawPixel(g, x+mx-sx-gcnt, y+my-sy, priv->buf[0]); break;
+ default: gdispGBlitArea(g, x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); break;
}
}
} else {
@@ -1120,15 +1120,15 @@ gdispImageError gdispImageDraw_GIF(gdispImage *img, coord_t x, coord_t y, coord_
// We have a transparent pixel - dump the buffer to the display
switch(gcnt) {
case 0: break;
- case 1: gdispDrawPixel(x+mx-sx-gcnt, y+my-sy, priv->buf[0]); gcnt = 0; break;
- default: gdispBlitAreaEx(x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); gcnt = 0; break;
+ case 1: gdispGDrawPixel(g, x+mx-sx-gcnt, y+my-sy, priv->buf[0]); gcnt = 0; break;
+ default: gdispGBlitArea(g, x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); gcnt = 0; break;
}
continue;
}
priv->buf[gcnt++] = decode->palette[col];
if (gcnt >= BLIT_BUFFER_SIZE) {
// We have run out of buffer - dump it to the display
- gdispBlitAreaEx(x+mx-sx-gcnt+1, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf);
+ gdispGBlitArea(g, x+mx-sx-gcnt+1, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf);
gcnt = 0;
}
continue;
@@ -1136,15 +1136,15 @@ gdispImageError gdispImageDraw_GIF(gdispImage *img, coord_t x, coord_t y, coord_
// We have finished the visible area - dump the buffer to the display
switch(gcnt) {
case 0: break;
- case 1: gdispDrawPixel(x+mx-sx-gcnt, y+my-sy, priv->buf[0]); gcnt = 0; break;
- default: gdispBlitAreaEx(x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); gcnt = 0; break;
+ case 1: gdispGDrawPixel(g, x+mx-sx-gcnt, y+my-sy, priv->buf[0]); gcnt = 0; break;
+ default: gdispGBlitArea(g, x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); gcnt = 0; break;
}
}
// We have finished the line - dump the buffer to the display
switch(gcnt) {
- case 0: break;
- case 1: gdispDrawPixel(x+mx-sx-gcnt, y+my-sy, priv->buf[0]); break;
- default: gdispBlitAreaEx(x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); break;
+ case 0: break;
+ case 1: gdispGDrawPixel(g, x+mx-sx-gcnt, y+my-sy, priv->buf[0]); break;
+ default: gdispGBlitArea(g, x+mx-sx-gcnt, y+my-sy, gcnt, 1, 0, 0, gcnt, priv->buf); break;
}
}
}
diff --git a/src/gdisp/image_native.c b/src/gdisp/image_native.c
index 24aed81f..72ae8b61 100644
--- a/src/gdisp/image_native.c
+++ b/src/gdisp/image_native.c
@@ -91,7 +91,7 @@ gdispImageError gdispImageCache_NATIVE(gdispImage *img) {
return GDISP_IMAGE_ERR_OK;
}
-gdispImageError gdispImageDraw_NATIVE(gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy) {
+gdispImageError gdispImageGDraw_NATIVE(GDisplay *g, gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy) {
coord_t mx, mcx;
size_t pos, len;
@@ -102,7 +102,7 @@ gdispImageError gdispImageDraw_NATIVE(gdispImage *img, coord_t x, coord_t y, coo
/* Draw from the image cache - if it exists */
if (img->priv->frame0cache) {
- gdispBlitAreaEx(x, y, cx, cy, sx, sy, img->width, img->priv->frame0cache);
+ gdispGBlitArea(g, x, y, cx, cy, sx, sy, img->width, img->priv->frame0cache);
return GDISP_IMAGE_ERR_OK;
}
@@ -125,7 +125,7 @@ gdispImageError gdispImageDraw_NATIVE(gdispImage *img, coord_t x, coord_t y, coo
return GDISP_IMAGE_ERR_BADDATA;
/* Blit the chunk of data */
- gdispBlitAreaEx(mx, y, len, 1, 0, 0, len, img->priv->buf);
+ gdispGBlitArea(g, mx, y, len, 1, 0, 0, len, img->priv->buf);
}
/* Get the position for the start of the next line */
diff --git a/src/gfx.c b/src/gfx.c
index 92533937..09d0798b 100644
--- a/src/gfx.c
+++ b/src/gfx.c
@@ -71,7 +71,6 @@ void gfxInit(void) {
#endif
#if GFX_USE_GDISP
_gdispInit();
- gdispClear(Black);
#endif
#if GFX_USE_GWIN
_gwinInit();
diff --git a/src/ginput/mouse.c b/src/ginput/mouse.c
index 74b5a990..80a4ed20 100644
--- a/src/ginput/mouse.c
+++ b/src/ginput/mouse.c
@@ -65,35 +65,37 @@ static struct MouseConfig_t {
#define FLG_CAL_OK 0x0020
#define FLG_CAL_SAVED 0x0040
#define FLG_CAL_FREE 0x0080
+ #define FLG_CAL_RAW 0x0100
#if GINPUT_MOUSE_NEED_CALIBRATION
GMouseCalibrationSaveRoutine fnsavecal;
GMouseCalibrationLoadRoutine fnloadcal;
Calibration caldata;
#endif
+ GDisplay * display;
} MouseConfig;
#if GINPUT_MOUSE_NEED_CALIBRATION
static inline void _tsDrawCross(const MousePoint *pp) {
- gdispDrawLine(pp->x-15, pp->y, pp->x-2, pp->y, White);
- gdispDrawLine(pp->x+2, pp->y, pp->x+15, pp->y, White);
- gdispDrawLine(pp->x, pp->y-15, pp->x, pp->y-2, White);
- gdispDrawLine(pp->x, pp->y+2, pp->x, pp->y+15, White);
+ gdispGDrawLine(MouseConfig.display, pp->x-15, pp->y, pp->x-2, pp->y, White);
+ gdispGDrawLine(MouseConfig.display, pp->x+2, pp->y, pp->x+15, pp->y, White);
+ gdispGDrawLine(MouseConfig.display, pp->x, pp->y-15, pp->x, pp->y-2, White);
+ gdispGDrawLine(MouseConfig.display, pp->x, pp->y+2, pp->x, pp->y+15, White);
- gdispDrawLine(pp->x-15, pp->y+15, pp->x-7, pp->y+15, RGB2COLOR(184,158,131));
- gdispDrawLine(pp->x-15, pp->y+7, pp->x-15, pp->y+15, RGB2COLOR(184,158,131));
+ gdispGDrawLine(MouseConfig.display, pp->x-15, pp->y+15, pp->x-7, pp->y+15, RGB2COLOR(184,158,131));
+ gdispGDrawLine(MouseConfig.display, pp->x-15, pp->y+7, pp->x-15, pp->y+15, RGB2COLOR(184,158,131));
- gdispDrawLine(pp->x-15, pp->y-15, pp->x-7, pp->y-15, RGB2COLOR(184,158,131));
- gdispDrawLine(pp->x-15, pp->y-7, pp->x-15, pp->y-15, RGB2COLOR(184,158,131));
+ gdispGDrawLine(MouseConfig.display, pp->x-15, pp->y-15, pp->x-7, pp->y-15, RGB2COLOR(184,158,131));
+ gdispGDrawLine(MouseConfig.display, pp->x-15, pp->y-7, pp->x-15, pp->y-15, RGB2COLOR(184,158,131));
- gdispDrawLine(pp->x+7, pp->y+15, pp->x+15, pp->y+15, RGB2COLOR(184,158,131));
- gdispDrawLine(pp->x+15, pp->y+7, pp->x+15, pp->y+15, RGB2COLOR(184,158,131));
+ gdispGDrawLine(MouseConfig.display, pp->x+7, pp->y+15, pp->x+15, pp->y+15, RGB2COLOR(184,158,131));
+ gdispGDrawLine(MouseConfig.display, pp->x+15, pp->y+7, pp->x+15, pp->y+15, RGB2COLOR(184,158,131));
- gdispDrawLine(pp->x+7, pp->y-15, pp->x+15, pp->y-15, RGB2COLOR(184,158,131));
- gdispDrawLine(pp->x+15, pp->y-15, pp->x+15, pp->y-7, RGB2COLOR(184,158,131));
+ gdispGDrawLine(MouseConfig.display, pp->x+7, pp->y-15, pp->x+15, pp->y-15, RGB2COLOR(184,158,131));
+ gdispGDrawLine(MouseConfig.display, pp->x+15, pp->y-15, pp->x+15, pp->y-7, RGB2COLOR(184,158,131));
}
static inline void _tsClearCross(const MousePoint *pp) {
- gdispFillArea(pp->x - 15, pp->y - 15, 42, 42, Blue);
+ gdispGFillArea(MouseConfig.display, pp->x - 15, pp->y - 15, 42, 42, Blue);
}
static inline void _tsTransform(MouseReading *pt, const Calibration *c) {
@@ -169,8 +171,8 @@ static void get_calibrated_reading(MouseReading *pt) {
get_raw_reading(pt);
#if GINPUT_MOUSE_NEED_CALIBRATION || GDISP_NEED_CONTROL
- w = gdispGetWidth();
- h = gdispGetHeight();
+ w = gdispGGetWidth(MouseConfig.display);
+ h = gdispGGetHeight(MouseConfig.display);
#endif
#if GINPUT_MOUSE_NEED_CALIBRATION
@@ -178,14 +180,14 @@ static void get_calibrated_reading(MouseReading *pt) {
#endif
#if GDISP_NEED_CONTROL
- switch(gdispGetOrientation()) {
+ switch(gdispGGetOrientation(MouseConfig.display)) {
case GDISP_ROTATE_0:
break;
case GDISP_ROTATE_90:
{
- coord_t t = pt->y;
- pt->y = h - 1 - pt->x;
- pt->x = t;
+ coord_t t = pt->x;
+ pt->x = w - 1 - pt->y;
+ pt->y = t;
}
break;
case GDISP_ROTATE_180:
@@ -194,19 +196,23 @@ static void get_calibrated_reading(MouseReading *pt) {
break;
case GDISP_ROTATE_270:
{
- coord_t t = pt->x;
- pt->x = w - 1 - pt->y;
- pt->y = t;
+ coord_t t = pt->y;
+ pt->y = h - 1 - pt->x;
+ pt->x = t;
}
break;
+ default:
+ break;
}
#endif
#if GINPUT_MOUSE_NEED_CALIBRATION
+ if (!(MouseConfig.flags & FLG_CAL_RAW)) {
if (pt->x < 0) pt->x = 0;
else if (pt->x >= w) pt->x = w-1;
if (pt->y < 0) pt->y = 0;
else if (pt->y >= h) pt->y = h-1;
+ }
#endif
}
@@ -303,6 +309,7 @@ static void MousePoll(void *param) {
pe->meta |= psl->srcflags;
psl->srcflags = 0;
}
+ pe->display = MouseConfig.display;
geventSendEvent(psl);
}
}
@@ -319,6 +326,10 @@ GSourceHandle ginputGetMouse(uint16_t instance) {
if (instance && instance != 9999)
return 0;
+ // Make sure we have a valid mouse display
+ if (!MouseConfig.display)
+ MouseConfig.display = GDISP;
+
// Do we need to initialise the mouse subsystem?
if (!(MouseConfig.flags & FLG_INIT_DONE)) {
ginput_lld_mouse_init();
@@ -344,7 +355,7 @@ GSourceHandle ginputGetMouse(uint16_t instance) {
MouseConfig.caldata.ay = 0;
MouseConfig.caldata.by = 1;
MouseConfig.caldata.cy = 0;
- MouseConfig.flags |= (FLG_CAL_OK|FLG_CAL_SAVED);
+ MouseConfig.flags |= (FLG_CAL_OK|FLG_CAL_SAVED|FLG_CAL_RAW);
} else
ginputCalibrateMouse(instance);
#endif
@@ -362,6 +373,20 @@ GSourceHandle ginputGetMouse(uint16_t instance) {
return (GSourceHandle)&MouseConfig;
}
+void ginputSetMouseDisplay(uint16_t instance, GDisplay *g) {
+ if (instance)
+ return;
+
+ MouseConfig.display = g ? g : GDISP;
+}
+
+GDisplay *ginputGetMouseDisplay(uint16_t instance) {
+ if (instance)
+ return 0;
+
+ return MouseConfig.display;
+}
+
bool_t ginputGetMouseStatus(uint16_t instance, GEventMouse *pe) {
// Win32 threads don't seem to recognise priority and/or pre-emption
// so we add a sleep here to prevent 100% polled applications from locking up.
@@ -393,8 +418,8 @@ bool_t ginputCalibrateMouse(uint16_t instance) {
return FALSE;
#else
- const coord_t height = gdispGetHeight();
- const coord_t width = gdispGetWidth();
+ const coord_t height = gdispGGetHeight(MouseConfig.display);
+ const coord_t width = gdispGGetWidth(MouseConfig.display);
const MousePoint cross[] = {{(width / 4), (height / 4)},
{(width - (width / 4)) , (height / 4)},
{(width - (width / 4)) , (height - (height / 4))},
@@ -417,22 +442,22 @@ bool_t ginputCalibrateMouse(uint16_t instance) {
MouseConfig.flags |= FLG_IN_CAL;
gtimerStop(&MouseTimer);
- MouseConfig.flags &= ~(FLG_CAL_OK|FLG_CAL_SAVED);
+ MouseConfig.flags &= ~(FLG_CAL_OK|FLG_CAL_SAVED|FLG_CAL_RAW);
#if GDISP_NEED_CONTROL
- gdispSetOrientation(GDISP_ROTATE_0);
+ gdispGSetOrientation(MouseConfig.display, GDISP_ROTATE_0);
#endif
#if GDISP_NEED_CLIP
- gdispSetClip(0, 0, width, height);
+ gdispGSetClip(MouseConfig.display, 0, 0, width, height);
#endif
#if GINPUT_MOUSE_MAX_CALIBRATION_ERROR >= 0
while(1) {
#endif
- gdispClear(Blue);
+ gdispGClear(MouseConfig.display, Blue);
- gdispFillStringBox(0, 5, width, 30, GINPUT_MOUSE_CALIBRATION_TEXT, font1, White, Blue, justifyCenter);
+ gdispGFillStringBox(MouseConfig.display, 0, 5, width, 30, GINPUT_MOUSE_CALIBRATION_TEXT, font1, White, Blue, justifyCenter);
for(i = 0, pt = points, pc = cross; i < GINPUT_MOUSE_CALIBRATION_POINTS; i++, pt++, pc++) {
_tsDrawCross(pc);
@@ -461,9 +486,9 @@ bool_t ginputCalibrateMouse(uint16_t instance) {
_tsClearCross(pc);
if (i >= 1 && pt->x == (pt-1)->x && pt->y == (pt-1)->y) {
- gdispFillStringBox(0, 35, width, 40, GINPUT_MOUSE_CALIBRATION_SAME_TEXT, font2, Red, Yellow, justifyCenter);
+ gdispGFillStringBox(MouseConfig.display, 0, 35, width, 40, GINPUT_MOUSE_CALIBRATION_SAME_TEXT, font2, Red, Yellow, justifyCenter);
gfxSleepMilliseconds(5000);
- gdispFillArea(0, 35, width, 40, Blue);
+ gdispGFillArea(MouseConfig.display, 0, 35, width, 40, Blue);
}
}
@@ -489,7 +514,7 @@ bool_t ginputCalibrateMouse(uint16_t instance) {
if (err <= GINPUT_MOUSE_MAX_CALIBRATION_ERROR * GINPUT_MOUSE_MAX_CALIBRATION_ERROR)
break;
- gdispFillStringBox(0, 35, width, 40, GINPUT_MOUSE_CALIBRATION_ERROR_TEXT, font2, Red, Yellow, justifyCenter);
+ gdispGFillStringBox(MouseConfig.display, 0, 35, width, 40, GINPUT_MOUSE_CALIBRATION_ERROR_TEXT, font2, Red, Yellow, justifyCenter);
gfxSleepMilliseconds(5000);
}
#endif
@@ -512,9 +537,9 @@ bool_t ginputCalibrateMouse(uint16_t instance) {
// Clear the screen using the GWIN default background color
#if GFX_USE_GWIN
- gdispClear(gwinGetDefaultBgColor());
+ gdispGClear(MouseConfig.display, gwinGetDefaultBgColor());
#else
- gdispClear(Black);
+ gdispGClear(MouseConfig.display, Black);
#endif
return TRUE;
@@ -523,8 +548,8 @@ bool_t ginputCalibrateMouse(uint16_t instance) {
/* Set the routines to save and fetch calibration data.
* This function should be called before first calling ginputGetMouse() for a particular instance
- * as the gdispGetMouse() routine may attempt to fetch calibration data and perform a startup calibration if there is no way to get it.
- * If this is called after gdispGetMouse() has been called and the driver requires calibration storage, it will immediately save the data is has already obtained.
+ * as the ginputGetMouse() routine may attempt to fetch calibration data and perform a startup calibration if there is no way to get it.
+ * If this is called after ginputGetMouse() has been called and the driver requires calibration storage, it will immediately save the data is has already obtained.
* The 'requireFree' parameter indicates if the fetch buffer must be free()'d to deallocate the buffer provided by the Fetch routine.
*/
void ginputSetMouseCalibrationRoutines(uint16_t instance, GMouseCalibrationSaveRoutine fnsave, GMouseCalibrationLoadRoutine fnload, bool_t requireFree) {
diff --git a/src/gmisc/trig.c b/src/gmisc/trig.c
index 510ee597..3c6dd461 100644
--- a/src/gmisc/trig.c
+++ b/src/gmisc/trig.c
@@ -142,5 +142,49 @@
#endif
+#if GMISC_NEED_INVSQRT
+ // Algorithm based on Quake code.
+ #if GMISC_INVSQRT_REAL_SLOW
+ #include <math.h>
+ float invsqrt(float n) {
+ return 1.0/sqrt(n);
+ }
+ #else
+ float invsqrt(float n) {
+ int32_t i;
+ float x2;
+
+ x2 = n * 0.5F;
+
+ // Convert into an int32 (no binary format conversion)
+ #if GMISC_INVSQRT_MIXED_ENDIAN
+ ((char *)&i)[0] = ((char *)&n)[3];
+ ((char *)&i)[1] = ((char *)&n)[2];
+ ((char *)&i)[2] = ((char *)&n)[1];
+ ((char *)&i)[3] = ((char *)&n)[0];
+ #else
+ i = *(int32_t *)&n;
+ #endif
+
+ // evil floating point bit level hacking
+ i = 0x5F375A86 - (i >> 1); // The quake code used 0x5F3759DF but this is better.
+
+ // Convert back to a float (no binary format conversion)
+ #if GMISC_INVSQRT_MIXED_ENDIAN
+ ((char *)&n)[0] = ((char *)&i)[3];
+ ((char *)&n)[1] = ((char *)&i)[2];
+ ((char *)&n)[2] = ((char *)&i)[1];
+ ((char *)&n)[3] = ((char *)&i)[0];
+ #else
+ n = *(float *)&i;
+ #endif
+
+ n = n * (1.5F - (x2 * n * n)); // 1st iteration
+ //n = n * (1.5F - (x2 * n * n)); // 2nd iteration for extra precision, this can be removed
+ return n;
+ }
+ #endif
+#endif
+
#endif /* GFX_USE_GMISC */
/** @} */
diff --git a/src/gwin/button.c b/src/gwin/button.c
index 4e4e67ee..b0fd973a 100644
--- a/src/gwin/button.c
+++ b/src/gwin/button.c
@@ -136,8 +136,8 @@ static const gwidgetVMT buttonVMT = {
#endif
};
-GHandle gwinButtonCreate(GButtonObject *gw, const GWidgetInit *pInit) {
- if (!(gw = (GButtonObject *)_gwidgetCreate(&gw->w, pInit, &buttonVMT)))
+GHandle gwinGButtonCreate(GDisplay *g, GButtonObject *gw, const GWidgetInit *pInit) {
+ if (!(gw = (GButtonObject *)_gwidgetCreate(g, &gw->w, pInit, &buttonVMT)))
return 0;
#if GINPUT_NEED_TOGGLE
@@ -171,9 +171,9 @@ void gwinButtonDraw_3D(GWidgetObject *gw, void *param) {
if (gw->g.vmt != (gwinVMT *)&buttonVMT) return;
pcol = getDrawColors(gw);
- gdispFillStringBox(gw->g.x, gw->g.y, gw->g.width-1, gw->g.height-1, gw->text, gw->g.font, pcol->text, pcol->fill, justifyCenter);
- gdispDrawLine(gw->g.x+gw->g.width-1, gw->g.y, gw->g.x+gw->g.width-1, gw->g.y+gw->g.height-1, pcol->edge);
- gdispDrawLine(gw->g.x, gw->g.y+gw->g.height-1, gw->g.x+gw->g.width-2, gw->g.y+gw->g.height-1, pcol->edge);
+ gdispGFillStringBox(gw->g.display, gw->g.x, gw->g.y, gw->g.width-1, gw->g.height-1, gw->text, gw->g.font, pcol->text, pcol->fill, justifyCenter);
+ gdispGDrawLine(gw->g.display, gw->g.x+gw->g.width-1, gw->g.y, gw->g.x+gw->g.width-1, gw->g.y+gw->g.height-1, pcol->edge);
+ gdispGDrawLine(gw->g.display, gw->g.x, gw->g.y+gw->g.height-1, gw->g.x+gw->g.width-2, gw->g.y+gw->g.height-1, pcol->edge);
}
#if GDISP_NEED_ARC
@@ -184,14 +184,14 @@ void gwinButtonDraw_3D(GWidgetObject *gw, void *param) {
if (gw->g.vmt != (gwinVMT *)&buttonVMT) return;
pcol = getDrawColors(gw);
- gdispFillArea(gw->g.x, gw->g.y, gw->g.width, gw->g.height, gw->pstyle->background);
+ gdispGFillArea(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, gw->pstyle->background);
if (gw->g.width >= 2*RND_CNR_SIZE+10) {
- gdispFillRoundedBox(gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, RND_CNR_SIZE-1, pcol->fill);
- gdispDrawStringBox(gw->g.x+1, gw->g.y+RND_CNR_SIZE, gw->g.width-2, gw->g.height-(2*RND_CNR_SIZE), gw->text, gw->g.font, pcol->text, justifyCenter);
- gdispDrawRoundedBox(gw->g.x, gw->g.y, gw->g.width, gw->g.height, RND_CNR_SIZE, pcol->edge);
+ gdispGFillRoundedBox(gw->g.display, gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, RND_CNR_SIZE-1, pcol->fill);
+ gdispGDrawStringBox(gw->g.display, gw->g.x+1, gw->g.y+RND_CNR_SIZE, gw->g.width-2, gw->g.height-(2*RND_CNR_SIZE), gw->text, gw->g.font, pcol->text, justifyCenter);
+ gdispGDrawRoundedBox(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, RND_CNR_SIZE, pcol->edge);
} else {
- gdispFillStringBox(gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->text, gw->g.font, pcol->text, pcol->fill, justifyCenter);
- gdispDrawBox(gw->g.x, gw->g.y, gw->g.width, gw->g.height, pcol->edge);
+ gdispGFillStringBox(gw->g.display, gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->text, gw->g.font, pcol->text, pcol->fill, justifyCenter);
+ gdispGDrawBox(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, pcol->edge);
}
}
#endif
@@ -204,10 +204,10 @@ void gwinButtonDraw_3D(GWidgetObject *gw, void *param) {
if (gw->g.vmt != (gwinVMT *)&buttonVMT) return;
pcol = getDrawColors(gw);
- gdispFillArea(gw->g.x, gw->g.y, gw->g.width, gw->g.height, gw->pstyle->background);
- gdispFillEllipse(gw->g.x+1, gw->g.y+1, gw->g.width/2-1, gw->g.height/2-1, pcol->fill);
- gdispDrawStringBox(gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->text, gw->g.font, pcol->text, justifyCenter);
- gdispDrawEllipse(gw->g.x, gw->g.y, gw->g.width/2, gw->g.height/2, pcol->edge);
+ gdispGFillArea(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, gw->pstyle->background);
+ gdispGFillEllipse(gw->g.display, gw->g.x+1, gw->g.y+1, gw->g.width/2-1, gw->g.height/2-1, pcol->fill);
+ gdispGDrawStringBox(gw->g.display, gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->text, gw->g.font, pcol->text, justifyCenter);
+ gdispGDrawEllipse(gw->g.display, gw->g.x, gw->g.y, gw->g.width/2, gw->g.height/2, pcol->edge);
}
#endif
@@ -228,10 +228,10 @@ void gwinButtonDraw_3D(GWidgetObject *gw, void *param) {
arw[5].x = (gw->g.width - gw->g.width/ARROWBODY_DIVIDER)/2; arw[5].y = gw->g.height/ARROWHEAD_DIVIDER;
arw[6].x = 0; arw[6].y = gw->g.height/ARROWHEAD_DIVIDER;
- gdispFillArea(gw->g.x, gw->g.y, gw->g.width, gw->g.height, gw->pstyle->background);
- gdispFillConvexPoly(gw->g.x, gw->g.y, arw, 7, pcol->fill);
- gdispDrawPoly(gw->g.x, gw->g.y, arw, 7, pcol->edge);
- gdispDrawStringBox(gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->text, gw->g.font, pcol->text, justifyCenter);
+ gdispGFillArea(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, gw->pstyle->background);
+ gdispGFillConvexPoly(gw->g.display, gw->g.x, gw->g.y, arw, 7, pcol->fill);
+ gdispGDrawPoly(gw->g.display, gw->g.x, gw->g.y, arw, 7, pcol->edge);
+ gdispGDrawStringBox(gw->g.display, gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->text, gw->g.font, pcol->text, justifyCenter);
}
void gwinButtonDraw_ArrowDown(GWidgetObject *gw, void *param) {
@@ -250,10 +250,10 @@ void gwinButtonDraw_3D(GWidgetObject *gw, void *param) {
arw[5].x = (gw->g.width - gw->g.width/ARROWBODY_DIVIDER)/2; arw[5].y = gw->g.height-1-gw->g.height/ARROWHEAD_DIVIDER;
arw[6].x = 0; arw[6].y = gw->g.height-1-gw->g.height/ARROWHEAD_DIVIDER;
- gdispFillArea(gw->g.x, gw->g.y, gw->g.width, gw->g.height, gw->pstyle->background);
- gdispFillConvexPoly(gw->g.x, gw->g.y, arw, 7, pcol->fill);
- gdispDrawPoly(gw->g.x, gw->g.y, arw, 7, pcol->edge);
- gdispDrawStringBox(gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->text, gw->g.font, pcol->text, justifyCenter);
+ gdispGFillArea(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, gw->pstyle->background);
+ gdispGFillConvexPoly(gw->g.display, gw->g.x, gw->g.y, arw, 7, pcol->fill);
+ gdispGDrawPoly(gw->g.display, gw->g.x, gw->g.y, arw, 7, pcol->edge);
+ gdispGDrawStringBox(gw->g.display, gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->text, gw->g.font, pcol->text, justifyCenter);
}
void gwinButtonDraw_ArrowLeft(GWidgetObject *gw, void *param) {
@@ -272,10 +272,10 @@ void gwinButtonDraw_3D(GWidgetObject *gw, void *param) {
arw[5].x = gw->g.width/ARROWHEAD_DIVIDER; arw[5].y = (gw->g.height + gw->g.height/ARROWBODY_DIVIDER)/2;
arw[6].x = gw->g.width/ARROWHEAD_DIVIDER; arw[6].y = gw->g.height-1;
- gdispFillArea(gw->g.x, gw->g.y, gw->g.width, gw->g.height, gw->pstyle->background);
- gdispFillConvexPoly(gw->g.x, gw->g.y, arw, 7, pcol->fill);
- gdispDrawPoly(gw->g.x, gw->g.y, arw, 7, pcol->edge);
- gdispDrawStringBox(gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->text, gw->g.font, pcol->text, justifyCenter);
+ gdispGFillArea(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, gw->pstyle->background);
+ gdispGFillConvexPoly(gw->g.display, gw->g.x, gw->g.y, arw, 7, pcol->fill);
+ gdispGDrawPoly(gw->g.display, gw->g.x, gw->g.y, arw, 7, pcol->edge);
+ gdispGDrawStringBox(gw->g.display, gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->text, gw->g.font, pcol->text, justifyCenter);
}
void gwinButtonDraw_ArrowRight(GWidgetObject *gw, void *param) {
@@ -294,10 +294,10 @@ void gwinButtonDraw_3D(GWidgetObject *gw, void *param) {
arw[5].x = gw->g.width-1-gw->g.width/ARROWHEAD_DIVIDER; arw[5].y = (gw->g.height + gw->g.height/ARROWBODY_DIVIDER)/2;
arw[6].x = gw->g.width-1-gw->g.width/ARROWHEAD_DIVIDER; arw[6].y = gw->g.height-1;
- gdispFillArea(gw->g.x, gw->g.y, gw->g.width, gw->g.height, gw->pstyle->background);
- gdispFillConvexPoly(gw->g.x, gw->g.y, arw, 7, pcol->fill);
- gdispDrawPoly(gw->g.x, gw->g.y, arw, 7, pcol->edge);
- gdispDrawStringBox(gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->text, gw->g.font, pcol->text, justifyCenter);
+ gdispGFillArea(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, gw->pstyle->background);
+ gdispGFillConvexPoly(gw->g.display, gw->g.x, gw->g.y, arw, 7, pcol->fill);
+ gdispGDrawPoly(gw->g.display, gw->g.x, gw->g.y, arw, 7, pcol->edge);
+ gdispGDrawStringBox(gw->g.display, gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->text, gw->g.font, pcol->text, justifyCenter);
}
#endif
@@ -317,8 +317,8 @@ void gwinButtonDraw_3D(GWidgetObject *gw, void *param) {
sy = 0;
}
- gdispImageDraw((gdispImage *)param, gw->g.x, gw->g.y, gw->g.width, gw->g.height, 0, sy);
- gdispDrawStringBox(gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->text, gw->g.font, pcol->text, justifyCenter);
+ gdispGImageDraw(gw->g.display, (gdispImage *)param, gw->g.x, gw->g.y, gw->g.width, gw->g.height, 0, sy);
+ gdispGDrawStringBox(gw->g.display, gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->text, gw->g.font, pcol->text, justifyCenter);
}
#endif
diff --git a/src/gwin/checkbox.c b/src/gwin/checkbox.c
index 7a6198de..13730d50 100644
--- a/src/gwin/checkbox.c
+++ b/src/gwin/checkbox.c
@@ -108,8 +108,8 @@ static const gwidgetVMT checkboxVMT = {
#endif
};
-GHandle gwinCheckboxCreate(GCheckboxObject *gb, const GWidgetInit *pInit) {
- if (!(gb = (GCheckboxObject *)_gwidgetCreate(&gb->w, pInit, &checkboxVMT)))
+GHandle gwinGCheckboxCreate(GDisplay *g, GCheckboxObject *gb, const GWidgetInit *pInit) {
+ if (!(gb = (GCheckboxObject *)_gwidgetCreate(g, &gb->w, pInit, &checkboxVMT)))
return 0;
#if GINPUT_NEED_TOGGLE
@@ -161,14 +161,14 @@ void gwinCheckboxDraw_CheckOnLeft(GWidgetObject *gw, void *param) {
pcol = getDrawColors(gw);
ld = gw->g.width < gw->g.height ? gw->g.width : gw->g.height;
- gdispFillArea(gw->g.x+1, gw->g.y+1, ld, ld-2, gw->pstyle->background);
- gdispDrawBox(gw->g.x, gw->g.y, ld, ld, pcol->edge);
+ gdispGFillArea(gw->g.display, gw->g.x+1, gw->g.y+1, ld, ld-2, gw->pstyle->background);
+ gdispGDrawBox(gw->g.display, gw->g.x, gw->g.y, ld, ld, pcol->edge);
df = ld < 4 ? 1 : 2;
if (gw->g.flags & GCHECKBOX_FLG_CHECKED)
- gdispFillArea(gw->g.x+df, gw->g.y+df, ld-2*df, ld-2*df, pcol->fill);
+ gdispGFillArea(gw->g.display, gw->g.x+df, gw->g.y+df, ld-2*df, ld-2*df, pcol->fill);
- gdispFillStringBox(gw->g.x+ld+1, gw->g.y, gw->g.width-ld-1, gw->g.height, gw->text, gw->g.font, pcol->text, gw->pstyle->background, justifyLeft);
+ gdispGFillStringBox(gw->g.display, gw->g.x+ld+1, gw->g.y, gw->g.width-ld-1, gw->g.height, gw->text, gw->g.font, pcol->text, gw->pstyle->background, justifyLeft);
#undef gcw
}
@@ -183,14 +183,14 @@ void gwinCheckboxDraw_CheckOnRight(GWidgetObject *gw, void *param) {
ld = gw->g.width < gw->g.height ? gw->g.width : gw->g.height;
ep = gw->g.width-ld-1;
- gdispFillArea(gw->g.x+ep-1, gw->g.y+1, ld, ld-2, gw->pstyle->background);
- gdispDrawBox(gw->g.x+ep, gw->g.y, ld, ld, pcol->edge);
+ gdispGFillArea(gw->g.display, gw->g.x+ep-1, gw->g.y+1, ld, ld-2, gw->pstyle->background);
+ gdispGDrawBox(gw->g.display, gw->g.x+ep, gw->g.y, ld, ld, pcol->edge);
df = ld < 4 ? 1 : 2;
if (gw->g.flags & GCHECKBOX_FLG_CHECKED)
- gdispFillArea(gw->g.x+ep+df, gw->g.y+df, ld-2*df, ld-2*df, pcol->fill);
+ gdispGFillArea(gw->g.display, gw->g.x+ep+df, gw->g.y+df, ld-2*df, ld-2*df, pcol->fill);
- gdispFillStringBox(gw->g.x, gw->g.y, ep-1, gw->g.height, gw->text, gw->g.font, pcol->text, gw->pstyle->background, justifyRight);
+ gdispGFillStringBox(gw->g.display, gw->g.x, gw->g.y, ep-1, gw->g.height, gw->text, gw->g.font, pcol->text, gw->pstyle->background, justifyRight);
#undef gcw
}
diff --git a/src/gwin/console.c b/src/gwin/console.c
index b6a20dea..1be18662 100644
--- a/src/gwin/console.c
+++ b/src/gwin/console.c
@@ -66,8 +66,8 @@ static const gwinVMT consoleVMT = {
AfterClear, // The after-clear routine
};
-GHandle gwinConsoleCreate(GConsoleObject *gc, const GWindowInit *pInit) {
- if (!(gc = (GConsoleObject *)_gwindowCreate(&gc->g, pInit, &consoleVMT, 0)))
+GHandle gwinGConsoleCreate(GDisplay *g, GConsoleObject *gc, const GWindowInit *pInit) {
+ if (!(gc = (GConsoleObject *)_gwindowCreate(g, &gc->g, pInit, &consoleVMT, 0)))
return 0;
#if GFX_USE_OS_CHIBIOS && GWIN_CONSOLE_USE_BASESTREAM
gc->stream.vmt = &GWindowConsoleVMT;
@@ -97,7 +97,7 @@ void gwinPutChar(GHandle gh, char c) {
fp = gdispGetFontMetric(gh->font, fontCharPadding);
#if GDISP_NEED_CLIP
- gdispSetClip(gh->x, gh->y, gh->width, gh->height);
+ gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
#endif
if (c == '\n') {
@@ -116,13 +116,13 @@ void gwinPutChar(GHandle gh, char c) {
if (gcw->cy + fy > gh->height) {
#if GDISP_NEED_SCROLL
/* scroll the console */
- gdispVerticalScroll(gh->x, gh->y, gh->width, gh->height, fy, gh->bgcolor);
+ gdispGVerticalScroll(gh->display, gh->x, gh->y, gh->width, gh->height, fy, gh->bgcolor);
/* reset the cursor to the start of the last line */
gcw->cx = 0;
gcw->cy = (((coord_t)(gh->height/fy))-1)*fy;
#else
/* clear the console */
- gdispFillArea(gh->x, gh->y, gh->width, gh->height, gh->bgcolor);
+ gdispGFillArea(gh->display, gh->x, gh->y, gh->width, gh->height, gh->bgcolor);
/* reset the cursor to the top of the window */
gcw->cx = 0;
gcw->cy = 0;
@@ -132,12 +132,12 @@ void gwinPutChar(GHandle gh, char c) {
#if GWIN_CONSOLE_USE_CLEAR_LINES
/* clear to the end of the line */
if (gcw->cx == 0)
- gdispFillArea(gh->x, gh->y + gcw->cy, gh->width, fy, gh->bgcolor);
+ gdispGFillArea(gh->display, gh->x, gh->y + gcw->cy, gh->width, fy, gh->bgcolor);
#endif
#if GWIN_CONSOLE_USE_FILLED_CHARS
- gdispFillChar(gh->x + gcw->cx, gh->y + gcw->cy, c, gh->font, gh->color, gh->bgcolor);
+ gdispGFillChar(gh->display, gh->x + gcw->cx, gh->y + gcw->cy, c, gh->font, gh->color, gh->bgcolor);
#else
- gdispDrawChar(gh->x + gcw->cx, gh->y + gcw->cy, c, gh->font, gh->color);
+ gdispGDrawChar(gh->display, gh->x + gcw->cx, gh->y + gcw->cy, c, gh->font, gh->color);
#endif
/* update cursor */
diff --git a/src/gwin/gimage.c b/src/gwin/gimage.c
index 8eed3ac7..b1f8e078 100644
--- a/src/gwin/gimage.c
+++ b/src/gwin/gimage.c
@@ -51,7 +51,7 @@ static void _redraw(GHandle gh) {
// If the image isn't open just clear the area
if (!gdispImageIsOpen(&widget(gh)->image)) {
- gdispFillArea(x, y, w, h, bg);
+ gdispGFillArea(gh->display, x, y, w, h, bg);
return;
}
@@ -61,8 +61,8 @@ static void _redraw(GHandle gh) {
dx = (gh->width-w)/2;
x += dx;
if (dx)
- gdispFillArea(gh->x, y, dx, h, bg);
- gdispFillArea(x+w, y, gh->width-dx-w, h, bg);
+ gdispGFillArea(gh->display, gh->x, y, dx, h, bg);
+ gdispGFillArea(gh->display, x+w, y, gh->width-dx-w, h, bg);
dx = 0;
}
@@ -77,8 +77,8 @@ static void _redraw(GHandle gh) {
dy = (gh->height-h)/2;
y += dy;
if (dy)
- gdispFillArea(x, gh->y, w, dy, bg);
- gdispFillArea(x, y+h, w, gh->height-dy-h, bg);
+ gdispGFillArea(gh->display, x, gh->y, w, dy, bg);
+ gdispGFillArea(gh->display, x, y+h, w, gh->height-dy-h, bg);
dy = 0;
}
@@ -91,7 +91,7 @@ static void _redraw(GHandle gh) {
gdispImageSetBgColor(&widget(gh)->image, bg);
// Display the image
- gdispImageDraw(&widget(gh)->image, x, y, w, h, dx, dy);
+ gdispGImageDraw(gh->display, &widget(gh)->image, x, y, w, h, dx, dy);
#if GWIN_NEED_IMAGE_ANIMATION
// read the delay for the next frame
@@ -122,8 +122,8 @@ static const gwinVMT imageVMT = {
0, // The after-clear routine
};
-GHandle gwinImageCreate(GImageObject *gobj, GWindowInit *pInit) {
- if (!(gobj = (GImageObject *)_gwindowCreate(&gobj->g, pInit, &imageVMT, 0)))
+GHandle gwinGImageCreate(GDisplay *g, GImageObject *gobj, GWindowInit *pInit) {
+ if (!(gobj = (GImageObject *)_gwindowCreate(g, &gobj->g, pInit, &imageVMT, 0)))
return 0;
// Ensure the gdispImageIsOpen() gives valid results
@@ -153,7 +153,7 @@ bool_t gwinImageOpenMemory(GHandle gh, const void* memory) {
// Setting the clip here shouldn't be necessary if the redraw doesn't overdraw
// but we put it in for safety anyway
#if GDISP_NEED_CLIP
- gdispSetClip(gh->x, gh->y, gh->width, gh->height);
+ gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
#endif
_redraw(gh);
}
@@ -176,7 +176,7 @@ bool_t gwinImageOpenFile(GHandle gh, const char* filename) {
// Setting the clip here shouldn't be necessary if the redraw doesn't overdraw
// but we put it in for safety anyway
#if GDISP_NEED_CLIP
- gdispSetClip(gh->x, gh->y, gh->width, gh->height);
+ gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
#endif
_redraw(gh);
}
@@ -200,7 +200,7 @@ bool_t gwinImageOpenStream(GHandle gh, void *streamPtr) {
// Setting the clip here shouldn't be necessary if the redraw doesn't overdraw
// but we put it in for safety anyway
#if GDISP_NEED_CLIP
- gdispSetClip(gh->x, gh->y, gh->width, gh->height);
+ gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
#endif
_redraw(gh);
}
diff --git a/src/gwin/graph.c b/src/gwin/graph.c
index 8cab05a4..1d513290 100644
--- a/src/gwin/graph.c
+++ b/src/gwin/graph.c
@@ -46,22 +46,22 @@ static void pointto(GGraphObject *gg, coord_t x, coord_t y, const GGraphPointSty
y = gg->g.y + gg->g.height - 1 - gg->yorigin - y;
if (style->size <= 1) {
- gdispDrawPixel(x, y, style->color);
+ gdispGDrawPixel(gg->g.display, x, y, style->color);
return;
}
switch(style->type) {
case GGRAPH_POINT_SQUARE:
- gdispDrawBox(x-style->size, y-style->size, 2*style->size, 2*style->size, style->color);
+ gdispGDrawBox(gg->g.display, x-style->size, y-style->size, 2*style->size, 2*style->size, style->color);
break;
#if GDISP_NEED_CIRCLE
case GGRAPH_POINT_CIRCLE:
- gdispDrawCircle(x, y, style->size, style->color);
+ gdispGDrawCircle(gg->g.display, x, y, style->size, style->color);
break;
#endif
case GGRAPH_POINT_DOT:
default:
- gdispDrawPixel(x, y, style->color);
+ gdispGDrawPixel(gg->g.display, x, y, style->color);
break;
}
}
@@ -83,7 +83,7 @@ static void lineto(GGraphObject *gg, coord_t x0, coord_t y0, coord_t x1, coord_t
if (style->size <= 0) {
// Use the driver to draw a solid line
- gdispDrawLine(x0, y0, x1, y1, style->color);
+ gdispGDrawLine(gg->g.display, x0, y0, x1, y1, style->color);
return;
}
@@ -101,7 +101,7 @@ static void lineto(GGraphObject *gg, coord_t x0, coord_t y0, coord_t x1, coord_t
case GGRAPH_LINE_SOLID:
default:
// Use the driver to draw a solid line
- gdispDrawLine(x0, y0, x1, y1, style->color);
+ gdispGDrawLine(gg->g.display, x0, y0, x1, y1, style->color);
return;
}
@@ -131,7 +131,7 @@ static void lineto(GGraphObject *gg, coord_t x0, coord_t y0, coord_t x1, coord_t
if (run++ >= 0) {
if (run >= run_on)
run = run_off;
- gdispDrawPixel(x0, y0, style->color);
+ gdispGDrawPixel(gg->g.display, x0, y0, style->color);
}
if (P < 0) {
P += dy;
@@ -151,7 +151,7 @@ static void lineto(GGraphObject *gg, coord_t x0, coord_t y0, coord_t x1, coord_t
if (run++ >= 0) {
if (run >= run_on)
run = run_off;
- gdispDrawPixel(x0, y0, style->color);
+ gdispGDrawPixel(gg->g.display, x0, y0, style->color);
}
if (P < 0) {
P += dx;
@@ -165,8 +165,8 @@ static void lineto(GGraphObject *gg, coord_t x0, coord_t y0, coord_t x1, coord_t
}
}
-GHandle gwinGraphCreate(GGraphObject *gg, const GWindowInit *pInit) {
- if (!(gg = (GGraphObject *)_gwindowCreate(&gg->g, pInit, &graphVMT, 0)))
+GHandle gwinGGraphCreate(GDisplay *g, GGraphObject *gg, const GWindowInit *pInit) {
+ if (!(gg = (GGraphObject *)_gwindowCreate(g, &gg->g, pInit, &graphVMT, 0)))
return 0;
gg->xorigin = gg->yorigin = 0;
gg->lastx = gg->lasty = 0;
diff --git a/src/gwin/gwidget.c b/src/gwin/gwidget.c
index 111777a2..db9dc9fa 100644
--- a/src/gwin/gwidget.c
+++ b/src/gwin/gwidget.c
@@ -102,6 +102,10 @@ static void gwidgetEvent(void *param, GEvent *pe) {
// Cycle through all windows
for(qi = gfxQueueASyncPeek(&_GWINList); qi; qi = gfxQueueASyncNext(qi)) {
+ // check if the widget matches this display
+ if (gh->display != pme->display)
+ continue;
+
// check if it a widget that is enabled and visible
if ((gh->flags & (GWIN_FLG_WIDGET|GWIN_FLG_ENABLED|GWIN_FLG_VISIBLE)) != (GWIN_FLG_WIDGET|GWIN_FLG_ENABLED|GWIN_FLG_VISIBLE))
continue;
@@ -225,8 +229,8 @@ void _gwidgetInit(void) {
geventRegisterCallback(&gl, gwidgetEvent, 0);
}
-GHandle _gwidgetCreate(GWidgetObject *pgw, const GWidgetInit *pInit, const gwidgetVMT *vmt) {
- if (!(pgw = (GWidgetObject *)_gwindowCreate(&pgw->g, &pInit->g, &vmt->g, GWIN_FLG_WIDGET|GWIN_FLG_ENABLED)))
+GHandle _gwidgetCreate(GDisplay *g, GWidgetObject *pgw, const GWidgetInit *pInit, const gwidgetVMT *vmt) {
+ if (!(pgw = (GWidgetObject *)_gwindowCreate(g, &pgw->g, &pInit->g, &vmt->g, GWIN_FLG_WIDGET|GWIN_FLG_ENABLED)))
return 0;
pgw->text = pInit->text ? pInit->text : "";
@@ -281,7 +285,7 @@ void _gwidgetRedraw(GHandle gh) {
return;
#if GDISP_NEED_CLIP
- gdispSetClip(gh->x, gh->y, gh->width, gh->height);
+ gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
#endif
gw->fnDraw(gw, gw->fnParam);
diff --git a/src/gwin/gwin.c b/src/gwin/gwin.c
index 44d4143c..bb425e0f 100644
--- a/src/gwin/gwin.c
+++ b/src/gwin/gwin.c
@@ -90,7 +90,7 @@ void _gwinInit(void) {
// Internal routine for use by GWIN components only
// Initialise a window creating it dynamically if required.
-GHandle _gwindowCreate(GWindowObject *pgw, const GWindowInit *pInit, const gwinVMT *vmt, uint16_t flags) {
+GHandle _gwindowCreate(GDisplay *g, GWindowObject *pgw, const GWindowInit *pInit, const gwinVMT *vmt, uint16_t flags) {
// Allocate the structure if necessary
if (!pgw) {
if (!(pgw = (GWindowObject *)gfxAlloc(vmt->size)))
@@ -100,6 +100,7 @@ GHandle _gwindowCreate(GWindowObject *pgw, const GWindowInit *pInit, const gwinV
pgw->flags = flags;
// Initialise all basic fields
+ pgw->display = g;
pgw->vmt = vmt;
pgw->color = defaultFgColor;
pgw->bgcolor = defaultBgColor;
@@ -154,8 +155,8 @@ color_t gwinGetDefaultBgColor(void) {
* The GWindow Routines
*-----------------------------------------------*/
-GHandle gwinWindowCreate(GWindowObject *pgw, const GWindowInit *pInit) {
- if (!(pgw = _gwindowCreate(pgw, pInit, &basegwinVMT, 0)))
+GHandle gwinGWindowCreate(GDisplay *g, GWindowObject *pgw, const GWindowInit *pInit) {
+ if (!(pgw = _gwindowCreate(g, pgw, pInit, &basegwinVMT, 0)))
return 0;
gwinSetVisible(pgw, pInit->show);
return pgw;
@@ -213,7 +214,7 @@ void gwinSetEnabled(GHandle gh, bool_t enabled) {
gh->flags |= GWIN_FLG_ENABLED;
if ((gh->flags & GWIN_FLG_VISIBLE) && gh->vmt->Redraw) {
#if GDISP_NEED_CLIP
- gdispSetClip(gh->x, gh->y, gh->width, gh->height);
+ gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
#endif
gh->vmt->Redraw(gh);
}
@@ -223,7 +224,7 @@ void gwinSetEnabled(GHandle gh, bool_t enabled) {
gh->flags &= ~GWIN_FLG_ENABLED;
if ((gh->flags & GWIN_FLG_VISIBLE) && gh->vmt->Redraw) {
#if GDISP_NEED_CLIP
- gdispSetClip(gh->x, gh->y, gh->width, gh->height);
+ gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
#endif
gh->vmt->Redraw(gh);
}
@@ -271,9 +272,9 @@ void gwinClear(GHandle gh) {
return;
#if GDISP_NEED_CLIP
- gdispSetClip(gh->x, gh->y, gh->width, gh->height);
+ gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
#endif
- gdispFillArea(gh->x, gh->y, gh->width, gh->height, gh->bgcolor);
+ gdispGFillArea(gh->display, gh->x, gh->y, gh->width, gh->height, gh->bgcolor);
if (gh->vmt->AfterClear)
gh->vmt->AfterClear(gh);
}
@@ -283,9 +284,9 @@ void gwinDrawPixel(GHandle gh, coord_t x, coord_t y) {
return;
#if GDISP_NEED_CLIP
- gdispSetClip(gh->x, gh->y, gh->width, gh->height);
+ gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
#endif
- gdispDrawPixel(gh->x+x, gh->y+y, gh->color);
+ gdispGDrawPixel(gh->display, gh->x+x, gh->y+y, gh->color);
}
void gwinDrawLine(GHandle gh, coord_t x0, coord_t y0, coord_t x1, coord_t y1) {
@@ -293,9 +294,9 @@ void gwinDrawLine(GHandle gh, coord_t x0, coord_t y0, coord_t x1, coord_t y1) {
return;
#if GDISP_NEED_CLIP
- gdispSetClip(gh->x, gh->y, gh->width, gh->height);
+ gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
#endif
- gdispDrawLine(gh->x+x0, gh->y+y0, gh->x+x1, gh->y+y1, gh->color);
+ gdispGDrawLine(gh->display, gh->x+x0, gh->y+y0, gh->x+x1, gh->y+y1, gh->color);
}
void gwinDrawBox(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy) {
@@ -303,9 +304,9 @@ void gwinDrawBox(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy) {
return;
#if GDISP_NEED_CLIP
- gdispSetClip(gh->x, gh->y, gh->width, gh->height);
+ gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
#endif
- gdispDrawBox(gh->x+x, gh->y+y, cx, cy, gh->color);
+ gdispGDrawBox(gh->display, gh->x+x, gh->y+y, cx, cy, gh->color);
}
void gwinFillArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy) {
@@ -313,9 +314,9 @@ void gwinFillArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy) {
return;
#if GDISP_NEED_CLIP
- gdispSetClip(gh->x, gh->y, gh->width, gh->height);
+ gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
#endif
- gdispFillArea(gh->x+x, gh->y+y, cx, cy, gh->color);
+ gdispGFillArea(gh->display, gh->x+x, gh->y+y, cx, cy, gh->color);
}
void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx, coord_t srcy, coord_t srccx, const pixel_t *buffer) {
@@ -323,9 +324,9 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor
return;
#if GDISP_NEED_CLIP
- gdispSetClip(gh->x, gh->y, gh->width, gh->height);
+ gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
#endif
- gdispBlitAreaEx(gh->x+x, gh->y+y, cx, cy, srcx, srcy, srccx, buffer);
+ gdispGBlitArea(gh->display, gh->x+x, gh->y+y, cx, cy, srcx, srcy, srccx, buffer);
}
#if GDISP_NEED_CIRCLE
@@ -334,9 +335,9 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor
return;
#if GDISP_NEED_CLIP
- gdispSetClip(gh->x, gh->y, gh->width, gh->height);
+ gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
#endif
- gdispDrawCircle(gh->x+x, gh->y+y, radius, gh->color);
+ gdispGDrawCircle(gh->display, gh->x+x, gh->y+y, radius, gh->color);
}
void gwinFillCircle(GHandle gh, coord_t x, coord_t y, coord_t radius) {
@@ -344,9 +345,9 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor
return;
#if GDISP_NEED_CLIP
- gdispSetClip(gh->x, gh->y, gh->width, gh->height);
+ gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
#endif
- gdispFillCircle(gh->x+x, gh->y+y, radius, gh->color);
+ gdispGFillCircle(gh->display, gh->x+x, gh->y+y, radius, gh->color);
}
#endif
@@ -356,9 +357,9 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor
return;
#if GDISP_NEED_CLIP
- gdispSetClip(gh->x, gh->y, gh->width, gh->height);
+ gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
#endif
- gdispDrawEllipse(gh->x+x, gh->y+y, a, b, gh->color);
+ gdispGDrawEllipse(gh->display, gh->x+x, gh->y+y, a, b, gh->color);
}
void gwinFillEllipse(GHandle gh, coord_t x, coord_t y, coord_t a, coord_t b) {
@@ -366,9 +367,9 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor
return;
#if GDISP_NEED_CLIP
- gdispSetClip(gh->x, gh->y, gh->width, gh->height);
+ gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
#endif
- gdispFillEllipse(gh->x+x, gh->y+y, a, b, gh->color);
+ gdispGFillEllipse(gh->display, gh->x+x, gh->y+y, a, b, gh->color);
}
#endif
@@ -378,9 +379,9 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor
return;
#if GDISP_NEED_CLIP
- gdispSetClip(gh->x, gh->y, gh->width, gh->height);
+ gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
#endif
- gdispDrawArc(gh->x+x, gh->y+y, radius, startangle, endangle, gh->color);
+ gdispGDrawArc(gh->display, gh->x+x, gh->y+y, radius, startangle, endangle, gh->color);
}
void gwinFillArc(GHandle gh, coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle) {
@@ -388,9 +389,9 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor
return;
#if GDISP_NEED_CLIP
- gdispSetClip(gh->x, gh->y, gh->width, gh->height);
+ gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
#endif
- gdispFillArc(gh->x+x, gh->y+y, radius, startangle, endangle, gh->color);
+ gdispGFillArc(gh->display, gh->x+x, gh->y+y, radius, startangle, endangle, gh->color);
}
#endif
@@ -400,9 +401,9 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor
return defaultBgColor;
#if GDISP_NEED_CLIP
- gdispSetClip(gh->x, gh->y, gh->width, gh->height);
+ gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
#endif
- return gdispGetPixelColor(gh->x+x, gh->y+y);
+ return gdispGGetPixelColor(gh->display, gh->x+x, gh->y+y);
}
#endif
@@ -412,9 +413,9 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor
return;
#if GDISP_NEED_CLIP
- gdispSetClip(gh->x, gh->y, gh->width, gh->height);
+ gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
#endif
- gdispDrawChar(gh->x+x, gh->y+y, c, gh->font, gh->color);
+ gdispGDrawChar(gh->display, gh->x+x, gh->y+y, c, gh->font, gh->color);
}
void gwinFillChar(GHandle gh, coord_t x, coord_t y, char c) {
@@ -422,9 +423,9 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor
return;
#if GDISP_NEED_CLIP
- gdispSetClip(gh->x, gh->y, gh->width, gh->height);
+ gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
#endif
- gdispFillChar(gh->x+x, gh->y+y, c, gh->font, gh->color, gh->bgcolor);
+ gdispGFillChar(gh->display, gh->x+x, gh->y+y, c, gh->font, gh->color, gh->bgcolor);
}
void gwinDrawString(GHandle gh, coord_t x, coord_t y, const char *str) {
@@ -432,9 +433,9 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor
return;
#if GDISP_NEED_CLIP
- gdispSetClip(gh->x, gh->y, gh->width, gh->height);
+ gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
#endif
- gdispDrawString(gh->x+x, gh->y+y, str, gh->font, gh->color);
+ gdispGDrawString(gh->display, gh->x+x, gh->y+y, str, gh->font, gh->color);
}
void gwinFillString(GHandle gh, coord_t x, coord_t y, const char *str) {
@@ -442,9 +443,9 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor
return;
#if GDISP_NEED_CLIP
- gdispSetClip(gh->x, gh->y, gh->width, gh->height);
+ gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
#endif
- gdispFillString(gh->x+x, gh->y+y, str, gh->font, gh->color, gh->bgcolor);
+ gdispGFillString(gh->display, gh->x+x, gh->y+y, str, gh->font, gh->color, gh->bgcolor);
}
void gwinDrawStringBox(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, justify_t justify) {
@@ -452,9 +453,9 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor
return;
#if GDISP_NEED_CLIP
- gdispSetClip(gh->x, gh->y, gh->width, gh->height);
+ gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
#endif
- gdispDrawStringBox(gh->x+x, gh->y+y, cx, cy, str, gh->font, gh->color, justify);
+ gdispGDrawStringBox(gh->display, gh->x+x, gh->y+y, cx, cy, str, gh->font, gh->color, justify);
}
void gwinFillStringBox(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, justify_t justify) {
@@ -462,9 +463,9 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor
return;
#if GDISP_NEED_CLIP
- gdispSetClip(gh->x, gh->y, gh->width, gh->height);
+ gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
#endif
- gdispFillStringBox(gh->x+x, gh->y+y, cx, cy, str, gh->font, gh->color, gh->bgcolor, justify);
+ gdispGFillStringBox(gh->display, gh->x+x, gh->y+y, cx, cy, str, gh->font, gh->color, gh->bgcolor, justify);
}
#endif
@@ -474,9 +475,9 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor
return;
#if GDISP_NEED_CLIP
- gdispSetClip(gh->x, gh->y, gh->width, gh->height);
+ gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
#endif
- gdispDrawPoly(tx+gh->x, ty+gh->y, pntarray, cnt, gh->color);
+ gdispGDrawPoly(gh->display, tx+gh->x, ty+gh->y, pntarray, cnt, gh->color);
}
void gwinFillConvexPoly(GHandle gh, coord_t tx, coord_t ty, const point *pntarray, unsigned cnt) {
@@ -484,9 +485,9 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor
return;
#if GDISP_NEED_CLIP
- gdispSetClip(gh->x, gh->y, gh->width, gh->height);
+ gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
#endif
- gdispFillConvexPoly(tx+gh->x, ty+gh->y, pntarray, cnt, gh->color);
+ gdispGFillConvexPoly(gh->display, tx+gh->x, ty+gh->y, pntarray, cnt, gh->color);
}
#endif
@@ -496,9 +497,9 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor
return GDISP_IMAGE_ERR_OK;
#if GDISP_NEED_CLIP
- gdispSetClip(gh->x, gh->y, gh->width, gh->height);
+ gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
#endif
- return gdispImageDraw(img, gh->x+x, gh->y+y, cx, cy, sx, sy);
+ return gdispGImageDraw(gh->display, img, gh->x+x, gh->y+y, cx, cy, sx, sy);
}
#endif
diff --git a/src/gwin/gwm.c b/src/gwin/gwm.c
index a8654089..d05a8177 100644
--- a/src/gwin/gwm.c
+++ b/src/gwin/gwm.c
@@ -119,7 +119,7 @@ static void WM_Delete(GHandle gh) {
// Make the window invisible and clear the area underneath
if ((gh->flags & GWIN_FLG_VISIBLE)) {
gh->flags &= ~GWIN_FLG_VISIBLE;
- gdispFillArea(gh->x, gh->y, gh->width, gh->height, gwinGetDefaultBgColor());
+ gdispGFillArea(gh->display, gh->x, gh->y, gh->width, gh->height, gwinGetDefaultBgColor());
}
// Remove it from the queue
@@ -128,16 +128,16 @@ static void WM_Delete(GHandle gh) {
static void WM_Visible(GHandle gh) {
#if GDISP_NEED_CLIP
- gdispSetClip(gh->x, gh->y, gh->width, gh->height);
+ gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
#endif
if ((gh->flags & GWIN_FLG_VISIBLE)) {
if (gh->vmt->Redraw)
gh->vmt->Redraw(gh);
else
- gdispFillArea(gh->x, gh->y, gh->width, gh->height, gh->bgcolor);
+ gdispGFillArea(gh->display, gh->x, gh->y, gh->width, gh->height, gh->bgcolor);
// A real window manager would also redraw the borders here
} else
- gdispFillArea(gh->x, gh->y, gh->width, gh->height, gwinGetDefaultBgColor());
+ gdispGFillArea(gh->display, gh->x, gh->y, gh->width, gh->height, gwinGetDefaultBgColor());
}
static void WM_Redim(GHandle gh, coord_t x, coord_t y, coord_t w, coord_t h) {
@@ -145,12 +145,12 @@ static void WM_Redim(GHandle gh, coord_t x, coord_t y, coord_t w, coord_t h) {
// If it won't fit on the screen move it around until it does.
if (x < 0) { w += x; x = 0; }
if (y < 0) { h += y; y = 0; }
- if (x > gdispGetWidth()-MIN_WIN_WIDTH) x = gdispGetWidth()-MIN_WIN_WIDTH;
- if (y > gdispGetHeight()-MIN_WIN_HEIGHT) y = gdispGetHeight()-MIN_WIN_HEIGHT;
+ if (x > gdispGGetWidth(gh->display)-MIN_WIN_WIDTH) x = gdispGGetWidth(gh->display)-MIN_WIN_WIDTH;
+ if (y > gdispGGetHeight(gh->display)-MIN_WIN_HEIGHT) y = gdispGGetHeight(gh->display)-MIN_WIN_HEIGHT;
if (w < MIN_WIN_WIDTH) { w = MIN_WIN_WIDTH; }
if (h < MIN_WIN_HEIGHT) { h = MIN_WIN_HEIGHT; }
- if (x+w > gdispGetWidth()) w = gdispGetWidth() - x;
- if (y+h > gdispGetHeight()) h = gdispGetHeight() - y;
+ if (x+w > gdispGGetWidth(gh->display)) w = gdispGGetWidth(gh->display) - x;
+ if (y+h > gdispGGetHeight(gh->display)) h = gdispGGetHeight(gh->display) - y;
// If there has been no resize just exit
if (gh->x == x && gh->y == y && gh->width == w && gh->height == h)
@@ -158,7 +158,7 @@ static void WM_Redim(GHandle gh, coord_t x, coord_t y, coord_t w, coord_t h) {
// Clear the old area
if ((gh->flags & GWIN_FLG_VISIBLE))
- gdispFillArea(gh->x, gh->y, gh->width, gh->height, gwinGetDefaultBgColor());
+ gdispGFillArea(gh->display, gh->x, gh->y, gh->width, gh->height, gwinGetDefaultBgColor());
// Set the new size
gh->x = x; gh->y = y;
@@ -168,7 +168,7 @@ static void WM_Redim(GHandle gh, coord_t x, coord_t y, coord_t w, coord_t h) {
if ((gh->flags & GWIN_FLG_VISIBLE)) {
if (gh->vmt->Redraw) {
#if GDISP_NEED_CLIP
- gdispSetClip(gh->x, gh->y, gh->width, gh->height);
+ gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
#endif
gh->vmt->Redraw(gh);
}
@@ -190,7 +190,7 @@ static void WM_Raise(GHandle gh) {
if ((gh->flags & GWIN_FLG_VISIBLE)) {
if (gh->vmt->Redraw) {
#if GDISP_NEED_CLIP
- gdispSetClip(gh->x, gh->y, gh->width, gh->height);
+ gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
#endif
gh->vmt->Redraw(gh);
}
diff --git a/src/gwin/label.c b/src/gwin/label.c
index 65afff7e..5619761a 100644
--- a/src/gwin/label.c
+++ b/src/gwin/label.c
@@ -48,8 +48,8 @@ static void gwinLabelDefaultDraw(GWidgetObject *gw, void *param) {
coord_t w, h;
(void) param;
- w = (gw->g.flags & GLABEL_FLG_WAUTO) ? getwidth(gw->text, gw->g.font, gdispGetWidth() - gw->g.x) : gw->g.width;
- h = (gw->g.flags & GLABEL_FLG_HAUTO) ? getheight(gw->text, gw->g.font, gdispGetWidth() - gw->g.x) : gw->g.height;
+ w = (gw->g.flags & GLABEL_FLG_WAUTO) ? getwidth(gw->text, gw->g.font, gdispGGetWidth(gw->g.display) - gw->g.x) : gw->g.width;
+ h = (gw->g.flags & GLABEL_FLG_HAUTO) ? getheight(gw->text, gw->g.font, gdispGGetWidth(gw->g.display) - gw->g.x) : gw->g.height;
if (gw->g.width != w || gw->g.height != h) {
gwinResize(&gw->g, w, h);
@@ -58,13 +58,13 @@ static void gwinLabelDefaultDraw(GWidgetObject *gw, void *param) {
}
// render the text
- gdispFillStringBox(gw->g.x, gw->g.y, gw->g.width, gw->g.height, gw->text, gw->g.font,
+ gdispGFillStringBox(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, gw->text, gw->g.font,
(gw->g.flags & GWIN_FLG_ENABLED) ? gw->pstyle->enabled.text : gw->pstyle->disabled.text, gw->pstyle->background,
justifyLeft);
// render the border (if any)
if (gw->g.flags & GLABEL_FLG_BORDER)
- gdispDrawBox(gw->g.x, gw->g.y, gw->g.width, gw->g.height, (gw->g.flags & GWIN_FLG_ENABLED) ? gw->pstyle->enabled.edge : gw->pstyle->disabled.edge);
+ gdispGDrawBox(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, (gw->g.flags & GWIN_FLG_ENABLED) ? gw->pstyle->enabled.edge : gw->pstyle->disabled.edge);
}
static const gwidgetVMT labelVMT = {
@@ -102,23 +102,23 @@ static const gwidgetVMT labelVMT = {
#endif
};
-GHandle gwinLabelCreate(GLabelObject *widget, GWidgetInit *pInit) {
+GHandle gwinGLabelCreate(GDisplay *g, GLabelObject *widget, GWidgetInit *pInit) {
uint16_t flags = 0;
// auto assign width
if (pInit->g.width <= 0) {
flags |= GLABEL_FLG_WAUTO;
- pInit->g.width = getwidth(pInit->text, gwinGetDefaultFont(), gdispGetWidth() - pInit->g.x);
+ pInit->g.width = getwidth(pInit->text, gwinGetDefaultFont(), gdispGGetWidth(g) - pInit->g.x);
}
// auto assign height
if (pInit->g.height <= 0) {
flags |= GLABEL_FLG_HAUTO;
- pInit->g.height = getheight(pInit->text, gwinGetDefaultFont(), gdispGetWidth() - pInit->g.x);
+ pInit->g.height = getheight(pInit->text, gwinGetDefaultFont(), gdispGGetWidth(g) - pInit->g.x);
}
- if (!(widget = (GLabelObject *)_gwidgetCreate(&widget->w, pInit, &labelVMT)))
+ if (!(widget = (GLabelObject *)_gwidgetCreate(g, &widget->w, pInit, &labelVMT)))
return 0;
// no borders by default
diff --git a/src/gwin/list.c b/src/gwin/list.c
index 57046102..1662277d 100644
--- a/src/gwin/list.c
+++ b/src/gwin/list.c
@@ -96,15 +96,15 @@ static void gwinListDefaultDraw(GWidgetObject* gw, void* param) {
// the scroll area
if ((gw2obj->cnt > (gw->g.height-2) / iheight) || (gw->g.flags & GLIST_FLG_SCROLLALWAYS)) {
iwidth = gw->g.width - (SCROLLWIDTH+3);
- gdispFillArea(gw->g.x+iwidth+2, gw->g.y+1, SCROLLWIDTH, gw->g.height-2, gdispBlendColor(ps->fill, gw->pstyle->background, 128));
- gdispDrawLine(gw->g.x+iwidth+1, gw->g.y+1, gw->g.x+iwidth+1, gw->g.y+gw->g.height-2, ps->edge);
+ gdispGFillArea(gw->g.display, gw->g.x+iwidth+2, gw->g.y+1, SCROLLWIDTH, gw->g.height-2, gdispBlendColor(ps->fill, gw->pstyle->background, 128));
+ gdispGDrawLine(gw->g.display, gw->g.x+iwidth+1, gw->g.y+1, gw->g.x+iwidth+1, gw->g.y+gw->g.height-2, ps->edge);
#if GDISP_NEED_CONVEX_POLYGON
- gdispFillConvexPoly(gw->g.x+iwidth+((SCROLLWIDTH-ARROW)/2+2), gw->g.y+(ARROW/2+1), upArrow, 3, ps->fill);
- gdispFillConvexPoly(gw->g.x+iwidth+((SCROLLWIDTH-ARROW)/2+2), gw->g.y+gw->g.height-(ARROW+ARROW/2+1), downArrow, 3, ps->fill);
+ gdispGFillConvexPoly(gw->g.display, gw->g.x+iwidth+((SCROLLWIDTH-ARROW)/2+2), gw->g.y+(ARROW/2+1), upArrow, 3, ps->fill);
+ gdispGFillConvexPoly(gw->g.display, gw->g.x+iwidth+((SCROLLWIDTH-ARROW)/2+2), gw->g.y+gw->g.height-(ARROW+ARROW/2+1), downArrow, 3, ps->fill);
#else
#warning "GWIN: Lists display better when GDISP_NEED_CONVEX_POLGON is turned on"
- gdispFillArea(gw->g.x+iwidth+((SCROLLWIDTH-ARROW)/2+2), gw->g.y+(ARROW/2+1), ARROW, ARROW, ps->fill);
- gdispFillArea(gw->g.x+iwidth+((SCROLLWIDTH-ARROW)/2+2), gw->g.y+gw->g.height-(ARROW+ARROW/2+1), ARROW, ARROW, ps->fill);
+ gdispGFillArea(gw->g.display, gw->g.x+iwidth+((SCROLLWIDTH-ARROW)/2+2), gw->g.y+(ARROW/2+1), ARROW, ARROW, ps->fill);
+ gdispGFillArea(gw->g.display, gw->g.x+iwidth+((SCROLLWIDTH-ARROW)/2+2), gw->g.y+gw->g.height-(ARROW+ARROW/2+1), ARROW, ARROW, ps->fill);
#endif
} else
iwidth = gw->g.width - 2;
@@ -126,7 +126,7 @@ static void gwinListDefaultDraw(GWidgetObject* gw, void* param) {
#if GWIN_NEED_LIST_IMAGES
if ((gw->g.flags & GLIST_FLG_HASIMAGES)) {
// Clear the image area
- gdispFillArea(gw->g.x+1, gw->g.y+y, x-1, iheight, fill);
+ gdispGFillArea(gw->g.display, gw->g.x+1, gw->g.y+y, x-1, iheight, fill);
if (qi2li->pimg && gdispImageIsOpen(qi2li->pimg)) {
// Calculate which image
sy = (qi2li->flags & GLIST_FLG_SELECTED) ? 0 : (iheight-TEXTGAP);
@@ -136,19 +136,19 @@ static void gwinListDefaultDraw(GWidgetObject* gw, void* param) {
sy -= iheight-TEXTGAP;
// Draw the image
gdispImageSetBgColor(qi2li->pimg, fill);
- gdispImageDraw(qi2li->pimg, gw->g.x+1, gw->g.y+y, iheight-TEXTGAP, iheight-TEXTGAP, 0, sy);
+ gdispGImageDraw(gw->g.display, qi2li->pimg, gw->g.x+1, gw->g.y+y, iheight-TEXTGAP, iheight-TEXTGAP, 0, sy);
}
}
#endif
- gdispFillStringBox(gw->g.x+x, gw->g.y+y, iwidth, iheight, qi2li->text, gw->g.font, ps->text, fill, justifyLeft);
+ gdispGFillStringBox(gw->g.display, gw->g.x+x, gw->g.y+y, iwidth, iheight, qi2li->text, gw->g.font, ps->text, fill, justifyLeft);
}
// Fill any remaining item space
if (y < gw->g.height-1)
- gdispFillArea(gw->g.x+1, gw->g.y+y, iwidth, gw->g.height-1-y, gw->pstyle->background);
+ gdispGFillArea(gw->g.display, gw->g.x+1, gw->g.y+y, iwidth, gw->g.height-1-y, gw->pstyle->background);
// the list frame
- gdispDrawBox(gw->g.x, gw->g.y, gw->g.width, gw->g.height, ps->edge);
+ gdispGDrawBox(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, ps->edge);
}
#if GINPUT_NEED_MOUSE
@@ -318,8 +318,8 @@ static const gwidgetVMT listVMT = {
#endif
};
-GHandle gwinListCreate(GListObject* gobj, GWidgetInit* pInit, bool_t multiselect) {
- if (!(gobj = (GListObject *)_gwidgetCreate(&gobj->w, pInit, &listVMT)))
+GHandle gwinGListCreate(GDisplay *g, GListObject* gobj, GWidgetInit* pInit, bool_t multiselect) {
+ if (!(gobj = (GListObject *)_gwidgetCreate(g, &gobj->w, pInit, &listVMT)))
return 0;
// initialize the item queue
diff --git a/src/gwin/radio.c b/src/gwin/radio.c
index c9d089b0..7507634c 100644
--- a/src/gwin/radio.c
+++ b/src/gwin/radio.c
@@ -108,8 +108,8 @@ static const gwidgetVMT radioVMT = {
#endif
};
-GHandle gwinRadioCreate(GRadioObject *gw, const GWidgetInit *pInit, uint16_t group) {
- if (!(gw = (GRadioObject *)_gwidgetCreate(&gw->w, pInit, &radioVMT)))
+GHandle gwinGRadioCreate(GDisplay *g, GRadioObject *gw, const GWidgetInit *pInit, uint16_t group) {
+ if (!(gw = (GRadioObject *)_gwidgetCreate(g, &gw->w, pInit, &radioVMT)))
return 0;
#if GINPUT_NEED_TOGGLE
@@ -177,21 +177,21 @@ void gwinRadioDraw_Radio(GWidgetObject *gw, void *param) {
#if GDISP_NEED_CIRCLE
df = (ld-1)/2;
- gdispFillArea(gw->g.x, gw->g.y, ld, ld, gw->pstyle->background);
- gdispDrawCircle(gw->g.x+df, gw->g.y+df, df, pcol->edge);
+ gdispGFillArea(gw->g.display, gw->g.x, gw->g.y, ld, ld, gw->pstyle->background);
+ gdispGDrawCircle(gw->g.display, gw->g.x+df, gw->g.y+df, df, pcol->edge);
if (gw->g.flags & GRADIO_FLG_PRESSED)
- gdispFillCircle(gw->g.x+df, gw->g.y+df, df <= 2 ? 1 : (df-2), pcol->fill);
+ gdispGFillCircle(gw->g.display, gw->g.x+df, gw->g.y+df, df <= 2 ? 1 : (df-2), pcol->fill);
#else
- gdispFillArea(gw->g.x+1, gw->g.y+1, ld, ld-2, gw->pstyle->background);
- gdispDrawBox(gw->g.x, gw->g.y, ld, ld, pcol->edge);
+ gdispGFillArea(gw->g.display, gw->g.x+1, gw->g.y+1, ld, ld-2, gw->pstyle->background);
+ gdispGDrawBox(gw->g.display, gw->g.x, gw->g.y, ld, ld, pcol->edge);
df = ld < 4 ? 1 : 2;
if (gw->g.flags & GRADIO_FLG_PRESSED)
- gdispFillArea(gw->g.x+df, gw->g.y+df, ld-2*df, ld-2*df, pcol->fill);
+ gdispGFillArea(gw->g.display, gw->g.x+df, gw->g.y+df, ld-2*df, ld-2*df, pcol->fill);
#endif
- gdispFillStringBox(gw->g.x+ld+1, gw->g.y, gw->g.width-ld-1, gw->g.height, gw->text, gw->g.font, pcol->text, gw->pstyle->background, justifyLeft);
+ gdispGFillStringBox(gw->g.display, gw->g.x+ld+1, gw->g.y, gw->g.width-ld-1, gw->g.height, gw->text, gw->g.font, pcol->text, gw->pstyle->background, justifyLeft);
#undef gcw
}
@@ -202,9 +202,9 @@ void gwinRadioDraw_Button(GWidgetObject *gw, void *param) {
if (gw->g.vmt != (gwinVMT *)&radioVMT) return;
pcol = getDrawColors(gw);
- gdispFillStringBox(gw->g.x, gw->g.y, gw->g.width-1, gw->g.height-1, gw->text, gw->g.font, pcol->text, pcol->fill, justifyCenter);
- gdispDrawLine(gw->g.x+gw->g.width-1, gw->g.y, gw->g.x+gw->g.width-1, gw->g.y+gw->g.height-1, pcol->edge);
- gdispDrawLine(gw->g.x, gw->g.y+gw->g.height-1, gw->g.x+gw->g.width-2, gw->g.y+gw->g.height-1, pcol->edge);
+ gdispGFillStringBox(gw->g.display, gw->g.x, gw->g.y, gw->g.width-1, gw->g.height-1, gw->text, gw->g.font, pcol->text, pcol->fill, justifyCenter);
+ gdispGDrawLine(gw->g.display, gw->g.x+gw->g.width-1, gw->g.y, gw->g.x+gw->g.width-1, gw->g.y+gw->g.height-1, pcol->edge);
+ gdispGDrawLine(gw->g.display, gw->g.x, gw->g.y+gw->g.height-1, gw->g.x+gw->g.width-2, gw->g.y+gw->g.height-1, pcol->edge);
}
void gwinRadioDraw_Tab(GWidgetObject *gw, void *param) {
@@ -215,12 +215,12 @@ void gwinRadioDraw_Tab(GWidgetObject *gw, void *param) {
pcol = getDrawColors(gw);
if ((gw->g.flags & GRADIO_FLG_PRESSED)) {
- gdispDrawBox(gw->g.x, gw->g.y, gw->g.width, gw->g.height, pcol->edge);
- gdispFillStringBox(gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-1, gw->text, gw->g.font, pcol->text, pcol->fill, justifyCenter);
+ gdispGDrawBox(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, pcol->edge);
+ gdispGFillStringBox(gw->g.display, gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-1, gw->text, gw->g.font, pcol->text, pcol->fill, justifyCenter);
} else {
- gdispFillStringBox(gw->g.x, gw->g.y, gw->g.width-1, gw->g.height-1, gw->text, gw->g.font, pcol->text, pcol->fill, justifyCenter);
- gdispDrawLine(gw->g.x+gw->g.width-1, gw->g.y, gw->g.x+gw->g.width-1, gw->g.y+gw->g.height-1, pcol->edge);
- gdispDrawLine(gw->g.x, gw->g.y+gw->g.height-1, gw->g.x+gw->g.width-2, gw->g.y+gw->g.height-1, pcol->edge);
+ gdispGFillStringBox(gw->g.display, gw->g.x, gw->g.y, gw->g.width-1, gw->g.height-1, gw->text, gw->g.font, pcol->text, pcol->fill, justifyCenter);
+ gdispGDrawLine(gw->g.display, gw->g.x+gw->g.width-1, gw->g.y, gw->g.x+gw->g.width-1, gw->g.y+gw->g.height-1, pcol->edge);
+ gdispGDrawLine(gw->g.display, gw->g.x, gw->g.y+gw->g.height-1, gw->g.x+gw->g.width-2, gw->g.y+gw->g.height-1, pcol->edge);
}
}
diff --git a/src/gwin/slider.c b/src/gwin/slider.c
index fdc31ead..a4ac5d95 100644
--- a/src/gwin/slider.c
+++ b/src/gwin/slider.c
@@ -223,8 +223,8 @@ static const gwidgetVMT sliderVMT = {
#endif
};
-GHandle gwinSliderCreate(GSliderObject *gs, const GWidgetInit *pInit) {
- if (!(gs = (GSliderObject *)_gwidgetCreate(&gs->w, pInit, &sliderVMT)))
+GHandle gwinGSliderCreate(GDisplay *g, GSliderObject *gs, const GWidgetInit *pInit) {
+ if (!(gs = (GSliderObject *)_gwidgetCreate(g, &gs->w, pInit, &sliderVMT)))
return 0;
#if GINPUT_NEED_TOGGLE
gs->t_dn = GWIDGET_NO_INSTANCE;
@@ -294,35 +294,35 @@ void gwinSliderDraw_Std(GWidgetObject *gw, void *param) {
if (gw->g.width < gw->g.height) { // Vertical slider
if (gsw->dpos != gw->g.height-1)
- gdispFillArea(gw->g.x, gw->g.y+gsw->dpos, gw->g.width, gw->g.height - gsw->dpos, pcol->progress); // Active Area
+ gdispGFillArea(gw->g.display, gw->g.x, gw->g.y+gsw->dpos, gw->g.width, gw->g.height - gsw->dpos, pcol->progress); // Active Area
if (gsw->dpos != 0)
- gdispFillArea(gw->g.x, gw->g.y, gw->g.width, gsw->dpos, gw->pstyle->enabled.progress); // Inactive area
- gdispDrawBox(gw->g.x, gw->g.y, gw->g.width, gw->g.height, pcol->edge); // Edge
- gdispDrawLine(gw->g.x, gw->g.y+gsw->dpos, gw->g.x+gw->g.width-1, gw->g.y+gsw->dpos, pcol->edge); // Thumb
+ gdispGFillArea(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gsw->dpos, gw->pstyle->enabled.progress); // Inactive area
+ gdispGDrawBox(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, pcol->edge); // Edge
+ gdispGDrawLine(gw->g.display, gw->g.x, gw->g.y+gsw->dpos, gw->g.x+gw->g.width-1, gw->g.y+gsw->dpos, pcol->edge); // Thumb
if (gsw->dpos >= 2)
- gdispDrawLine(gw->g.x, gw->g.y+gsw->dpos-2, gw->g.x+gw->g.width-1, gw->g.y+gsw->dpos-2, pcol->edge); // Thumb
+ gdispGDrawLine(gw->g.display, gw->g.x, gw->g.y+gsw->dpos-2, gw->g.x+gw->g.width-1, gw->g.y+gsw->dpos-2, pcol->edge); // Thumb
if (gsw->dpos <= gw->g.height-2)
- gdispDrawLine(gw->g.x, gw->g.y+gsw->dpos+2, gw->g.x+gw->g.width-1, gw->g.y+gsw->dpos+2, pcol->edge); // Thumb
+ gdispGDrawLine(gw->g.display, gw->g.x, gw->g.y+gsw->dpos+2, gw->g.x+gw->g.width-1, gw->g.y+gsw->dpos+2, pcol->edge); // Thumb
// Horizontal slider
} else {
if (gsw->dpos != gw->g.width-1)
- gdispFillArea(gw->g.x+gsw->dpos, gw->g.y, gw->g.width-gsw->dpos, gw->g.height, gw->pstyle->enabled.progress); // Inactive area
+ gdispGFillArea(gw->g.display, gw->g.x+gsw->dpos, gw->g.y, gw->g.width-gsw->dpos, gw->g.height, gw->pstyle->enabled.progress); // Inactive area
if (gsw->dpos != 0)
- gdispFillArea(gw->g.x, gw->g.y, gsw->dpos, gw->g.height, pcol->progress); // Active Area
- gdispDrawBox(gw->g.x, gw->g.y, gw->g.width, gw->g.height, pcol->edge); // Edge
- gdispDrawLine(gw->g.x+gsw->dpos, gw->g.y, gw->g.x+gsw->dpos, gw->g.y+gw->g.height-1, pcol->edge); // Thumb
+ gdispGFillArea(gw->g.display, gw->g.x, gw->g.y, gsw->dpos, gw->g.height, pcol->progress); // Active Area
+ gdispGDrawBox(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, pcol->edge); // Edge
+ gdispGDrawLine(gw->g.display, gw->g.x+gsw->dpos, gw->g.y, gw->g.x+gsw->dpos, gw->g.y+gw->g.height-1, pcol->edge); // Thumb
if (gsw->dpos >= 2)
- gdispDrawLine(gw->g.x+gsw->dpos-2, gw->g.y, gw->g.x+gsw->dpos-2, gw->g.y+gw->g.height-1, pcol->edge); // Thumb
+ gdispGDrawLine(gw->g.display, gw->g.x+gsw->dpos-2, gw->g.y, gw->g.x+gsw->dpos-2, gw->g.y+gw->g.height-1, pcol->edge); // Thumb
if (gsw->dpos <= gw->g.width-2)
- gdispDrawLine(gw->g.x+gsw->dpos+2, gw->g.y, gw->g.x+gsw->dpos+2, gw->g.y+gw->g.height-1, pcol->edge); // Thumb
+ gdispGDrawLine(gw->g.display, gw->g.x+gsw->dpos+2, gw->g.y, gw->g.x+gsw->dpos+2, gw->g.y+gw->g.height-1, pcol->edge); // Thumb
}
- gdispDrawStringBox(gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->text, gw->g.font, pcol->text, justifyCenter);
+ gdispGDrawStringBox(gw->g.display, gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->text, gw->g.font, pcol->text, justifyCenter);
#undef gsw
}
-#if GDISP_NEED_IMAGE || defined(__DOXYGEN__)
+#if GDISP_NEED_IMAGE
void gwinSliderDraw_Image(GWidgetObject *gw, void *param) {
#define gsw ((GSliderObject *)gw)
#define gi ((gdispImage *)param)
@@ -339,7 +339,7 @@ void gwinSliderDraw_Image(GWidgetObject *gw, void *param) {
if (gw->g.width < gw->g.height) { // Vertical slider
if (gsw->dpos != 0) // The unfilled area
- gdispFillArea(gw->g.x, gw->g.y, gw->g.width, gsw->dpos, gw->pstyle->enabled.progress); // Inactive area
+ gdispGFillArea(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gsw->dpos, gw->pstyle->enabled.progress); // Inactive area
if (gsw->dpos != gw->g.height-1) { // The filled area
for(z=gw->g.height, v=gi->height; z > gsw->dpos;) {
z -= v;
@@ -347,27 +347,27 @@ void gwinSliderDraw_Image(GWidgetObject *gw, void *param) {
v -= gsw->dpos - z;
z = gsw->dpos;
}
- gdispImageDraw(gi, gw->g.x, gw->g.y+z, gw->g.width, v, 0, gi->height-v);
+ gdispGImageDraw(gw->g.display, gi, gw->g.x, gw->g.y+z, gw->g.width, v, 0, gi->height-v);
}
}
- gdispDrawBox(gw->g.x, gw->g.y, gw->g.width, gw->g.height, pcol->edge); // Edge
- gdispDrawLine(gw->g.x, gw->g.y+gsw->dpos, gw->g.x+gw->g.width-1, gw->g.y+gsw->dpos, pcol->edge); // Thumb
+ gdispGDrawBox(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, pcol->edge); // Edge
+ gdispGDrawLine(gw->g.display, gw->g.x, gw->g.y+gsw->dpos, gw->g.x+gw->g.width-1, gw->g.y+gsw->dpos, pcol->edge); // Thumb
// Horizontal slider
} else {
if (gsw->dpos != gw->g.width-1) // The unfilled area
- gdispFillArea(gw->g.x+gsw->dpos, gw->g.y, gw->g.width-gsw->dpos, gw->g.height, gw->pstyle->enabled.progress); // Inactive area
+ gdispGFillArea(gw->g.display, gw->g.x+gsw->dpos, gw->g.y, gw->g.width-gsw->dpos, gw->g.height, gw->pstyle->enabled.progress); // Inactive area
if (gsw->dpos != 0) { // The filled area
for(z=0, v=gi->width; z < gsw->dpos; z += v) {
if (z+v > gsw->dpos)
v -= z+v - gsw->dpos;
- gdispImageDraw(gi, gw->g.x+z, gw->g.y, v, gw->g.height, 0, 0);
+ gdispGImageDraw(gw->g.display, gi, gw->g.x+z, gw->g.y, v, gw->g.height, 0, 0);
}
}
- gdispDrawBox(gw->g.x, gw->g.y, gw->g.width, gw->g.height, pcol->edge); // Edge
- gdispDrawLine(gw->g.x+gsw->dpos, gw->g.y, gw->g.x+gsw->dpos, gw->g.y+gw->g.height-1, pcol->edge); // Thumb
+ gdispGDrawBox(gw->g.display, gw->g.x, gw->g.y, gw->g.width, gw->g.height, pcol->edge); // Edge
+ gdispGDrawLine(gw->g.display, gw->g.x+gsw->dpos, gw->g.y, gw->g.x+gsw->dpos, gw->g.y+gw->g.height-1, pcol->edge); // Thumb
}
- gdispDrawStringBox(gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->text, gw->g.font, pcol->text, justifyCenter);
+ gdispGDrawStringBox(gw->g.display, gw->g.x+1, gw->g.y+1, gw->g.width-2, gw->g.height-2, gw->text, gw->g.font, pcol->text, justifyCenter);
#undef gsw
}