JoVM Posted July 13, 2015 Report Posted July 13, 2015 This is a rudimentary hardware driver for the KS0108 controller./* * 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#include "pal.h"#define KS0108_PORT GPIOA#define KS0108_RS GPIOA_PIN8#define KS0108_RW GPIOA_PIN9#define KS0108_EN GPIOA_PIN10#define KS0108_CS1 GPIOA_CS1#define KS0108_CS2 GPIOA_CS2#define KS0108_CS3 GPIOA_CS3#define KS0108_D0 0#define DISPLAY_STATUS_BUSY 0x80unsigned char screen_x;unsigned char screen_y;//#define KS0108_PAGE_PREFIX 0x40//-------------------------------------------------------------------------------------------------// Delay function /for 8MHz///-------------------------------------------------------------------------------------------------static inline void GLCD_Delay(void){ asm("nop");asm("nop");asm("nop");asm("nop");}//-------------------------------------------------------------------------------------------------// Enalbe Controller (0-2)//-------------------------------------------------------------------------------------------------static inline void GLCD_EnableController(unsigned char controller){switch(controller){ case 0 : palClearPad(KS0108_PORT, KS0108_CS1); break; case 1 : palClearPad(KS0108_PORT, KS0108_CS2); break; case 2 : palClearPad(KS0108_PORT, KS0108_CS3); break; }}//-------------------------------------------------------------------------------------------------// Disable Controller (0-2)//-------------------------------------------------------------------------------------------------static inline void GLCD_DisableController(unsigned char controller){switch(controller){ case 0 : palSetPad(KS0108_PORT, KS0108_CS1); break; case 1 : palSetPad(KS0108_PORT, KS0108_CS2); break; case 2 : palSetPad(KS0108_PORT, KS0108_CS3); break; }}//-------------------------------------------------------------------------------------------------// Read Status byte from specified controller (0-2)//-------------------------------------------------------------------------------------------------static inline uint8_t read_data(uint8_t controller){ uint8_t status; palSetPadMode(KS0108_PORT, 0, PAL_MODE_INPUT_PULLUP); palSetPadMode(KS0108_PORT, 1, PAL_MODE_INPUT_PULLUP); palSetPadMode(KS0108_PORT, 2, PAL_MODE_INPUT_PULLUP); palSetPadMode(KS0108_PORT, 3, PAL_MODE_INPUT_PULLUP); palSetPadMode(KS0108_PORT, 4, PAL_MODE_INPUT_PULLUP); palSetPadMode(KS0108_PORT, 5, PAL_MODE_INPUT_PULLUP); palSetPadMode(KS0108_PORT, 6, PAL_MODE_INPUT_PULLUP); palSetPadMode(KS0108_PORT, 7, PAL_MODE_INPUT_PULLUP); palSetPad(KS0108_PORT, KS0108_RW); palClearPad(KS0108_PORT, KS0108_RS); GLCD_EnableController(controller); GLCD_Delay(); palSetPad(KS0108_PORT, KS0108_EN); GLCD_Delay(); status = ((palReadPort(KS0108_PORT) >> KS0108_D0) & 0xFF); palClearPad(KS0108_PORT, KS0108_EN); GLCD_DisableController(controller); return status;}static inline void init_board(GDisplay *g) { (void) g;}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;}static inline void release_bus(GDisplay *g) { (void) g;}static inline void write_cmd(GDisplay *g, uint8_t cmd, uint8_t controller) { (void) g; //(void) cmd; while(read_data(controller)&DISPLAY_STATUS_BUSY); palSetPadMode(KS0108_PORT, 0, PAL_MODE_OUTPUT_PUSHPULL); palSetPadMode(KS0108_PORT, 1, PAL_MODE_OUTPUT_PUSHPULL); palSetPadMode(KS0108_PORT, 2, PAL_MODE_OUTPUT_PUSHPULL); palSetPadMode(KS0108_PORT, 3, PAL_MODE_OUTPUT_PUSHPULL); palSetPadMode(KS0108_PORT, 4, PAL_MODE_OUTPUT_PUSHPULL); palSetPadMode(KS0108_PORT, 5, PAL_MODE_OUTPUT_PUSHPULL); palSetPadMode(KS0108_PORT, 6, PAL_MODE_OUTPUT_PUSHPULL); palSetPadMode(KS0108_PORT, 7, PAL_MODE_OUTPUT_PUSHPULL); palClearPad(KS0108_PORT, KS0108_RS | KS0108_RW); GLCD_Delay(); GLCD_EnableController(controller); GLCD_Delay(); palSetPad(KS0108_PORT, (cmd << KS0108_D0)); cmd ^= 0xFF; palClearPad(KS0108_PORT, (cmd << KS0108_D0)); GLCD_Delay(); palSetPad(KS0108_PORT, KS0108_EN); GLCD_Delay(); palClearPad(KS0108_PORT, KS0108_EN); GLCD_Delay(); GLCD_DisableController(controller);}static inline void write_data(GDisplay *g, uint8_t* data, uint16_t length) { (void) g; (void) data; (void) length; while(read_data(screen_x / 64)&DISPLAY_STATUS_BUSY); palSetPadMode(KS0108_PORT, 0, PAL_MODE_OUTPUT_PUSHPULL); palSetPadMode(KS0108_PORT, 1, PAL_MODE_OUTPUT_PUSHPULL); palSetPadMode(KS0108_PORT, 2, PAL_MODE_OUTPUT_PUSHPULL); palSetPadMode(KS0108_PORT, 3, PAL_MODE_OUTPUT_PUSHPULL); palSetPadMode(KS0108_PORT, 4, PAL_MODE_OUTPUT_PUSHPULL); palSetPadMode(KS0108_PORT, 5, PAL_MODE_OUTPUT_PUSHPULL); palSetPadMode(KS0108_PORT, 6, PAL_MODE_OUTPUT_PUSHPULL); palSetPadMode(KS0108_PORT, 7, PAL_MODE_OUTPUT_PUSHPULL); palClearPad(KS0108_PORT, KS0108_RW); GLCD_Delay(); palSetPad(KS0108_PORT, KS0108_RS); GLCD_Delay(); palSetPad(KS0108_PORT, (*data << KS0108_D0)); *data ^= 0xFF; palClearPad(KS0108_PORT, (*data << KS0108_D0)); GLCD_Delay(); GLCD_EnableController(screen_x / 64); GLCD_Delay(); palSetPad(KS0108_PORT, KS0108_EN); GLCD_Delay(); palClearPad(KS0108_PORT, KS0108_EN); GLCD_Delay(); GLCD_DisableController(screen_x / 64); screen_x++;}#endif /* _GDISP_LLD_BOARD_H */I do a HARDWARE_FLUSH on the data pins. read_status and enable- disablecontroller() needs to go in driver code. Please your review.
Joel Bodenmann Posted July 13, 2015 Report Posted July 13, 2015 Hello JoVM and welcome to the community!Thank you for sharing your driver, we will take a look at it as soon as possible.Can you please, just for completeness, also add your drivers config file and the board file template so we can take a look at the whole picture?~ Tectu
JoVM Posted July 14, 2015 Author Report Posted July 14, 2015 board config file:/* * 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_CONFIG_H#define _GDISP_LLD_CONFIG_H#if GFX_USE_GDISP/*===========================================================================*//* Driver hardware support. *//*===========================================================================*/#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_FILLS TRUE#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 */#endif /* _GDISP_LLD_CONFIG_H */
JoVM Posted July 14, 2015 Author Report Posted July 14, 2015 This parts can be optimized:palSetPadMode(KS0108_PORT, 0, PAL_MODE_INPUT_PULLUP); palSetPadMode(KS0108_PORT, 1, PAL_MODE_INPUT_PULLUP); palSetPadMode(KS0108_PORT, 2, PAL_MODE_INPUT_PULLUP); palSetPadMode(KS0108_PORT, 3, PAL_MODE_INPUT_PULLUP); palSetPadMode(KS0108_PORT, 4, PAL_MODE_INPUT_PULLUP); palSetPadMode(KS0108_PORT, 5, PAL_MODE_INPUT_PULLUP); palSetPadMode(KS0108_PORT, 6, PAL_MODE_INPUT_PULLUP); palSetPadMode(KS0108_PORT, 7, PAL_MODE_INPUT_PULLUP);palSetPadMode(KS0108_PORT, 0, PAL_MODE_OUTPUT_PUSHPULL); palSetPadMode(KS0108_PORT, 1, PAL_MODE_OUTPUT_PUSHPULL); palSetPadMode(KS0108_PORT, 2, PAL_MODE_OUTPUT_PUSHPULL); palSetPadMode(KS0108_PORT, 3, PAL_MODE_OUTPUT_PUSHPULL); palSetPadMode(KS0108_PORT, 4, PAL_MODE_OUTPUT_PUSHPULL); palSetPadMode(KS0108_PORT, 5, PAL_MODE_OUTPUT_PUSHPULL); palSetPadMode(KS0108_PORT, 6, PAL_MODE_OUTPUT_PUSHPULL); palSetPadMode(KS0108_PORT, 7, PAL_MODE_OUTPUT_PUSHPULL);with: IOBus Databus = { KS0108_PORT, (1 << 0) | (1 << 1) | (1 <<2) | (1 <<3) | \ (1 << 4) | (1 << 5) | (1 << 6) | (1 << 7), 0 };/*respectively*/ palSetBusMode(&Databus , PAL_MODE_INPUT_PULLUP); palSetBusMode(&Databus , PAL_MODE_OUTPUT_PUSHPULL);
Joel Bodenmann Posted July 15, 2015 Report Posted July 15, 2015 Hello JoVM,I took a look at your files and things don't seem quite right. In order to use the uGFX library you need to write a GDISP driver. The GDISP driver knows how to talk to the KS0108 controller.The next thing you need is the board file. The board file is what your driver uses to actually talk to the display controller through the microcontroller's peripheral interface. This is what you posted in your first post.Please have a look at some of the existing GDISP drivers. You can find them under /drivers/gdisp/. Furthermore, this article contains a few informations about the different GDISP driver models.Don't hesitate to ask when you have some questions. We are happy to help where we can. Just have a look at the existing drivers first ~ Tectu
JoVM Posted July 15, 2015 Author Report Posted July 15, 2015 Hi Tectu,I follow the Window model. The display surface gets loaded into RAM and then flushed to the controller? I think the HW driver(board file) fitts(is ready) for the KS0108.
JoVM Posted July 17, 2015 Author Report Posted July 17, 2015 Tnx inmarket,What functions are mandatory(should be included) in a gdisp driver? imho I would exclude draw_pixel(), ...
JoVM Posted July 18, 2015 Author Report Posted July 18, 2015 Hi guys,This part://-------------------------------------------------------------------------------------------------// Delay function /for 8MHz///-------------------------------------------------------------------------------------------------static inline void GLCD_Delay(void){ asm("nop");asm("nop");asm("nop");asm("nop");}is ofcourse obselete. This is for an AVR at 8MHz.For the STM32F4 you could use gfxSleepMilliseconds() but I prefer to set up a gpt and use gptPolledDelay() for short delays.
Joel Bodenmann Posted July 19, 2015 Report Posted July 19, 2015 Hello JoVM,I am very sorry for my previous stupid forum post. I was sitting in the waiting hall in the airport and I wanted to look at your drivers before I take off and loose the internet for couple of days. One should not review any code when there are only five minutes left. Please ignore it, your driver obviously uses the other GDISp driver model.We will take a look at this and let you know.~ Tectu
JoVM Posted July 19, 2015 Author Report Posted July 19, 2015 No prob Tectu, my code is still under production. The datasheet states strict timings for the command and data pins so basically I'm still optimizing this part. I will post the full driver s.a.p.
Joel Bodenmann Posted July 21, 2015 Report Posted July 21, 2015 JoVM, I found an unused KS0108 module in my drawer. However, as you mentioned you are still working on the driver. Can you let us know when you have finished tweaking everything?In the meantime we keep yourselves busy working on the uGFX-Studio and the F7 Discovery board support.~ Tectu
JoVM Posted July 22, 2015 Author Report Posted July 22, 2015 Hi Tectu, code is tested with the LogicAnalyzer and found working. My GLCD is broken so can't get live test. grt!
Joel Bodenmann Posted July 22, 2015 Report Posted July 22, 2015 My GLCD is broken so can't get live test. grt!Whoops... I am happy to test it with my GLCD when I find some time. I hope that mine will work. I bought it like 5 years ago and never tested it.I looked at the zip that you attached to your previous post and everything looks good on first glance. However, what happened in KS0108.h? ~ Tectu
Joel Bodenmann Posted July 22, 2015 Report Posted July 22, 2015 Whoops. I just realize that the KS0108 requires 5V logic and everything I have here is 3.3V based.Will you get a new display soon to make sure that the driver performs as expected or should I just add the driver to the repository straight away?~ Tectu
JoVM Posted July 22, 2015 Author Report Posted July 22, 2015 It would be nice if you could test the driver if you find the time. The datasheet states min 2.0V at the logic pins except RTS. I hooked my display on a BIGPIC5 board to test it but nothing shows only BL is on. At his maiden I reversed polarised the displays +5V supply. Could be it is damaged. :shock:Me no, I'm going to order a 128x64 SPI or I2C based controller.The KS0108.h is very minimalistic. #define KS0108_SCREEN_WIDTH 128#define KS0108_SCREEN_HEIGHT 64#define DISPLAY_SET_Y 0x40#define DISPLAY_SET_X 0xB8#define DISPLAY_START_LINE 0xC0#define DISPLAY_ON_CMD 0x3E#define ON 0x01#define OFF 0x00#define DISPLAY_STATUS_BUSY 0x80
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now