Jump to content

Help with ili9325 and stm32f1


david1982

Recommended Posts

Hello All,

I am trying to get my LCD to work but my data is sent via GPIOC 0...7 and GPIOB 8...15 and for the life of me I cannot get it to work.

All I am trying to do is get the gdisp circle demo going..

Below are my board file and driver file..

Please just a kick in the right direction would be appreciated.

board.h

#ifndef _BOARD_H_
#define _BOARD_H_

/*
* Setup for the ST INEMO-M1 Discovery board.
*/

/*
* Board identifier.
*/
#define BOARD_OLIMEX_STM32_LCD
#define BOARD_NAME "Olimex STM32-LCD"

/*
* Board frequencies.
*/
#define STM32_LSECLK 32768
#define STM32_HSECLK 8000000


/*
* MCU type, supported types are defined in ./os/hal/platforms/hal_lld.h.
*/
#define STM32F10X_MD

/*
* IO pins assignments.
*/
#define GPIOA_KEY1 0
#define GPIOA_KEY2 1
#define GPIOA_LED1 2
#define GPIOA_LED2 3
#define GPIOA_SPI1_NSS 4
#define GPIOA_SPI1_SCK 5
#define GPIOA_SPI1_MISO 6
#define GPIOA_SPI1_MOSI 7
#define GPIOA_PA8 8 /* FREE PA8/USART1_CK/TIM1_CH1/MCO */
#define GPIOA_USART1_TX 9
#define GPIOA_USART1_RX 10
#define GPIOA_PA11 11
#define GPIOA_PA12 12
#define GPIOA_SWDIO 13
#define GPIOA_SWCLK 14
#define GPIOA_PA15 15

#define GPIOB_PB0 0 /* VR */
#define GPIOB_PB1 1 /* FREE PB1/ADC12_IN9/TIM2_CH4/TIM1_CH3N */
#define GPIOB_PB2 2 /* BOOT */
#define GPIOB_PB3 3 /* JTAG JTDO */
#define GPIOB_PB4 4 /* JTAG JNTRST */
#define GPIOB_LE 5
#define GPIOB_F_CS 6
#define GPIOB_SD_CS 7
#define GPIOB_DB08 8
#define GPIOB_DB09 9
#define GPIOB_DB10 10
#define GPIOB_DB11 11
#define GPIOB_DB12 12
#define GPIOB_DB13 13
#define GPIOB_DB14 14
#define GPIOB_DB15 15

#define GPIOC_DB00 0
#define GPIOC_DB01 1
#define GPIOC_DB02 2
#define GPIOC_DB03 3
#define GPIOC_DB04 4
#define GPIOC_DB05 5
#define GPIOC_DB06 6
#define GPIOC_DB07 7
#define GPIOC_CS 8
#define GPIOC_RS 9
#define GPIOC_WR 10
#define GPIOC_RD 11
#define GPIOC_BL_EN 12
#define GPIOC_TP_INT 13
#define GPIOC_PC14 14
#define GPIOC_PC15 15

#define GPIOD_OSC_IN 0
#define GPIOD_OSC_OUT 1
#define GPIOD_PD2 2

/*
* I/O ports initial setup, this configuration is established soon after reset
* in the initialization code.
*
* The digits have the following meaning:
* 0 - Analog input.
* 1 - Push Pull output 10MHz.
* 2 - Push Pull output 2MHz.
* 3 - Push Pull output 50MHz.
* 4 - Digital input.
* 5 - Open Drain output 10MHz.
* 6 - Open Drain output 2MHz.
* 7 - Open Drain output 50MHz.
* 8 - Digital input with PullUp or PullDown resistor depending on ODR.
* 9 - Alternate Push Pull output 10MHz.
* A - Alternate Push Pull output 2MHz.
* B - Alternate Push Pull output 50MHz.
* C - Reserved.
* D - Alternate Open Drain output 10MHz.
* E - Alternate Open Drain output 2MHz.
* F - Alternate Open Drain output 50MHz.
* Please refer to the STM32 Reference Manual for details.
*/

#define VAL_GPIOACRL 0x88384B88 /* PA7...PA0 */
#define VAL_GPIOACRH 0x88888883 /* PA15...PA8 */
#define VAL_GPIOAODR 0xFFFFBFDF

/*
* Port B setup.
* Everything input with pull-up except:
* PB3 - Pull-up input (GPIOA_SWO).
*/
#define VAL_GPIOBCRL 0x88388888 /* PB7...PB0 */
#define VAL_GPIOBCRH 0xBBBBBBBB /* PB15...PB8 */
#define VAL_GPIOBODR 0xFFFFFFFF

/*
* Port C setup.
* Everything input with pull-up except:
* PC13 - Normal input (GPIOC_BUTTON).
*/
#define VAL_GPIOCCRL 0xBBBBBBBB /* PC7...PC0 */
#define VAL_GPIOCCRH 0x8847BBBB /* PC15...PC8 */
#define VAL_GPIOCODR 0xFFFFFFFF

/*
* Port D setup.
* Everything input with pull-up except:
* PD0 - Normal input (GPIOD_OSC_IN).
* PD1 - Normal input (GPIOD_OSC_OUT).
*/
#define VAL_GPIODCRL 0x88888844 /* PD7...PD0 */
#define VAL_GPIODCRH 0x88888888 /* PD15...PD8 */
#define VAL_GPIODODR 0xFFFFFFFF

/*
* Port E setup.
* Everything input with pull-up except:
*/
#define VAL_GPIOECRL 0x88888888 /* PE7...PE0 */
#define VAL_GPIOECRH 0x88888888 /* PE15...PE8 */
#define VAL_GPIOEODR 0xFFFFFFFF

/*
* USB bus activation macro, required by the USB driver.
*/
#define usb_lld_connect_bus(usbp)

/*
* USB bus de-activation macro, required by the USB driver.
*/
#define usb_lld_disconnect_bus(usbp)

#if !defined(_FROM_ASM_)
#ifdef __cplusplus
extern "C" {
#endif
void boardInit(void);
#ifdef __cplusplus
}
#endif
#endif /* _FROM_ASM_ */

#endif /* _BOARD_H_ */

board_ILI9325.h

#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) {

(void) 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 busC = {GPIOC, (1 << 0) | (1 << 1) | (1 << 4) | (1 << 5) | (1 << 7), 0};
IOBus busB = {GPIOB, (1 << 8) | (1 << 9) | (1 << 10) | (1 << 11) | (1 << 12) | (1 << 13) | (1 << 14) | (1 << 15), 0};
palSetBusMode(&busC, PAL_MODE_STM32_ALTERNATE_PUSHPULL);
palSetBusMode(&busB, PAL_MODE_STM32_ALTERNATE_PUSHPULL);
//palSetPadMode(GPIOC, GPIOC_TFT_RST, PAL_MODE_OUTPUT_PUSHPULL);
palSetPadMode(GPIOC, GPIOC_BL_EN, PAL_MODE_OUTPUT_PUSHPULL);

const unsigned char FSMC_Bank = 0;

/* FSMC timing */
FSMC_Bank1->BTCR[FSMC_Bank+1] = (9) | (10 << 7) | (10 << 15);

/* 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;

}

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 */

Edited by Guest
Link to comment
Share on other sites

Hello david!

Can you please give us some information about your actual hardware setup? Do you use a well known development board with an e-bay display attached? Is it a custom board?

You mention that you're using GPIOC 0 to 7 and GPIOB 8 to 15. I don't know the pin out of the STM32F1 that you're using but most likely this won't be the FSMC interface of the chip. This would mean that you have to implement your own board file so the data is being put on the right pins. There should be a template file in the drivers directory that you can copy to start.

The board file that you show in your forum post is using the FSMC peripheral.

~ Tectu

Link to comment
Share on other sites

Sorry my mistake I am using board_ILI9325 I just mislabeled it in the post.

The above board.h file is one I have modified to suit my board I just used the "Olimex STM32-LCD" board file as a base as it compiled/worked with the blinking led example.

Also rccEnableAHB(RCC_AHBENR_FSMCEN, 0); in the driver file causes a error..

'RCC_AHBENR_FSMCEN' undeclared (first use in this function)

Below are some pics and the board schematic.

Images..

https://drive.google.com/file/d/0B_B2fQCYwJRiRkJFdGNLUHcySWs/view?usp=sharing

https://drive.google.com/file/d/0B_B2fQCYwJRibWhkWVRZTEk4eGM/view?usp=sharing

MINI_STM32-V3.0_SCH.pdf.zip

Link to comment
Share on other sites

@inmarket: Those jumper wires that you can see in the photo are from the programmer / JTAG. The display itself is wired on the PCB to the microcontroller that you can see on the back side of the PCB.

@david: I checked and your display is definitely not connected via FSMC. It is simply bit-banged using GPIO. This is quite typical for those chinese boards. We will try to write up a board file for you this evening.

~ Tectu

Link to comment
Share on other sites

We wrote a board file which should be working. However, we had no hardware to actually test it:


/*
* 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

// 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(GPIOC, 8);
#define CLR_CS palClearPad(GPIOC, 8);
#define SET_RS palSetPad(GPIOC, 9);
#define CLR_RS palClearPad(GPIOC, 9);
#define SET_WR palSetPad(GPIOC, 10);
#define CLR_WR palClearPad(GPIOC, 10);
#define SET_RD palSetPad(GPIOC, 11);
#define CLR_RD palClearPad(GPIOC, 11);

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:

// Bus setup
IOBus busC = {GPIOC, (1<< 0)|(1<< 1)|(1<< 2)|(1<< 3)|(1<< 4)|(1<< 5)|(1<< 6)|(1<< 7), 0};
IOBus busB = {GPIOB, (1<< 8)|(1<< 9)|(1<<10)|(1<<11)|(1<<12)|(1<<13)|(1<<14)|(1<<15), 0};

// Pin configuration
palSetBusMode(&busC, PAL_MODE_OUTPUT_PUSHPULL); // DB0 - DB7
palSetBusMode(&busB, PAL_MODE_OUTPUT_PUSHPULL); // DB8 - DB15
palSetPadMode(GPIOC, 8, PAL_MODE_OUTPUT_PUSHPULL); // CS
palSetPadMode(GPIOC, 9, PAL_MODE_OUTPUT_PUSHPULL); // RS
palSetPadMode(GPIOC, 10, PAL_MODE_OUTPUT_PUSHPULL); // WR
palSetPadMode(GPIOC, 11, PAL_MODE_OUTPUT_PUSHPULL); // RD

// 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 connected to NRST */
}

static inline void set_backlight(GDisplay *g, uint8_t percent)
{
(void) g;
(void) percent;

/* Implement PWM here - Always 100% for testing purposes */
palSetPad(GPIOC, 12);
}

static inline void acquire_bus(GDisplay *g)
{
(void) g;

CLR_CS;
}

static inline void release_bus(GDisplay *g)
{
(void) g;

SET_CS;
}

static inline void write_index(GDisplay *g, uint16_t index)
{
(void) g;

palWriteBus(&busC, index & 0x00FF)
palWriteBus(&busB, index & 0xFF00);
CLR_RS;
CLR_WR;
SET_WR;
SET_RS;
}

static inline void write_data(GDisplay *g, uint16_t data)
{
(void) g;

palWriteBus(&busC, index & 0x00FF)
palWriteBus(&busB, index & 0xFF00);
CLR_WR;
SET_WR;
}

static inline void setreadmode(GDisplay *g)
{
(void) g;

// change pin mode to digital input
palSetBusMode(&busC, PAL_MODE_INPUT);
palSetBusMode(&busB, PAL_MODE_INPUT);
CLR_RD;
}

static inline void setwritemode(GDisplay *g)
{
(void) g;

// change pin mode back to digital output
SET_RD;
palSetBusMode(&busC, PAL_MODE_OUTPUT_PUSHPULL);
palSetBusMode(&busB, PAL_MODE_OUTPUT_PUSHPULL);
}

static inline uint16_t read_data(GDisplay *g) {
(void) g;

uint16_t ret;

ret |= ((uint16_t)palReadBus(&busC) & 0x00FF);
ret |= ((uint16_t)palReadBus(&busD) & 0xFF00);

return ret;
}

#if defined(GDISP_USE_DMA)
#error "GDISP - ILI9325: The GPIO interface does not support DMA"
#endif

#endif /* _GDISP_LLD_BOARD_H */

Can you please test the board file and let us know when you have any problems?

~ Tectu

Link to comment
Share on other sites

Ok I tryed your borad_ILI9325.h and now i get these errors

'busC' undeclared (first use in this function) board_ILI9325.h

'busB' undeclared (first use in this function) board_ILI9325.h

'index' undeclared (first use in this function) board_ILI9325.h

a label can only be part of a statement and a declaration is not a statement board_ILI9325.h line 31

expected expression before 'IOBus' board_ILI9325.h line 32

Link to comment
Share on other sites

Sorry, I was on the road and I couldn't try to compile it myself. This one here should now at least compile correctly:

/*
* 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

// 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(GPIOC, 8);
#define CLR_CS palClearPad(GPIOC, 8);
#define SET_RS palSetPad(GPIOC, 9);
#define CLR_RS palClearPad(GPIOC, 9);
#define SET_WR palSetPad(GPIOC, 10);
#define CLR_WR palClearPad(GPIOC, 10);
#define SET_RD palSetPad(GPIOC, 11);
#define CLR_RD palClearPad(GPIOC, 11);

// The ChibiOS/RT bus groups
IOBus busC;
IOBus busB;

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:

// Bus setup
busC.portid = GPIOC;
busC.mask = (1<< 0)|(1<< 1)|(1<< 2)|(1<< 3)|(1<< 4)|(1<< 5)|(1<< 6)|(1<< 7);
busC.offset = 0;
busB.portid = GPIOB;
busB.mask = (1<< 8)|(1<< 9)|(1<<10)|(1<<11)|(1<<12)|(1<<13)|(1<<14)|(1<<15);
busB.offset = 0;

// Pin configuration
palSetBusMode(&busC, PAL_MODE_OUTPUT_PUSHPULL); // DB0 - DB7
palSetBusMode(&busB, PAL_MODE_OUTPUT_PUSHPULL); // DB8 - DB15
palSetPadMode(GPIOC, 8, PAL_MODE_OUTPUT_PUSHPULL); // CS
palSetPadMode(GPIOC, 9, PAL_MODE_OUTPUT_PUSHPULL); // RS
palSetPadMode(GPIOC, 10, PAL_MODE_OUTPUT_PUSHPULL); // WR
palSetPadMode(GPIOC, 11, PAL_MODE_OUTPUT_PUSHPULL); // RD

// 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 connected to NRST */
}

static inline void set_backlight(GDisplay *g, uint8_t percent)
{
(void) g;
(void) percent;

/* Implement PWM here - Always 100% for testing purposes */
palSetPad(GPIOC, 12);
}

static inline void acquire_bus(GDisplay *g)
{
(void) g;

CLR_CS;
}

static inline void release_bus(GDisplay *g)
{
(void) g;

SET_CS;
}

static inline void write_index(GDisplay *g, uint16_t index)
{
(void) g;

palWriteBus(&busC, index & 0x00FF);
palWriteBus(&busB, index & 0xFF00);
CLR_RS;
CLR_WR;
SET_WR;
SET_RS;
}

static inline void write_data(GDisplay *g, uint16_t data)
{
(void) g;

palWriteBus(&busC, data & 0x00FF);
palWriteBus(&busB, data & 0xFF00);
CLR_WR;
SET_WR;
}

static inline void setreadmode(GDisplay *g)
{
(void) g;

// change pin mode to digital input
palSetBusMode(&busC, PAL_MODE_INPUT);
palSetBusMode(&busB, PAL_MODE_INPUT);
CLR_RD;
}

static inline void setwritemode(GDisplay *g)
{
(void) g;

// change pin mode back to digital output
SET_RD;
palSetBusMode(&busC, PAL_MODE_OUTPUT_PUSHPULL);
palSetBusMode(&busB, PAL_MODE_OUTPUT_PUSHPULL);
}

static inline uint16_t read_data(GDisplay *g) {
(void) g;

uint16_t ret = 0;

ret |= ((uint16_t)palReadBus(&busC) & 0x00FF);
ret |= ((uint16_t)palReadBus(&busB) & 0xFF00);

return ret;
}

#if defined(GDISP_USE_DMA)
#error "GDISP - ILI9325: The GPIO interface does not support DMA"
#endif

#endif /* _GDISP_LLD_BOARD_H */

~ Tectu

Link to comment
Share on other sites

First thing to check is to make sure that the backlight is actually on. It happens very often that the display is actually working but people can't see it because the backlight is off. Please make sure that the backlight is always set to 100% on in the board file.

If that is not the problem, can you please tell us what you're seeing? Do you see a white screen or noise? Can you verify the signals using an oscilloscope or a logic analyzer?

About the pin configuration: The pin configuration is done inside of the init_board(). This way you don't have to worry about your chibios board file. When you add the backlight, make sure that you also add this pin configuration to the board file.

~ Tectu

Link to comment
Share on other sites

Yes the backlight is working.

White screen with no noise.

So I tested the pins with a scope and pressed reset on each pin test.

DB08 8 /NOTHING

DB09 9 /NOTHING

DB10 10 /NOTHING

DB11 11 /NOTHING

DB12 12 /NOTHING

DB13 13 /NOTHING

DB14 14 /NOTHING

DB15 15 /NOTHING

DB00 0 /NOTHING

DB01 1 /NOTHING

DB02 2 /NOTHING

DB03 3 /NOTHING

DB04 4 /NOTHING

DB05 5 /NOTHING

DB06 6 /NOTHING

DB07 7 /NOTHING

CS 8 /3 PULSE'S ON RESET

RS 9 /NOTHING

WR 10 /3 BURST'S OF PULSE'S

RD 11 /NOTHING

Thanks

Link to comment
Share on other sites

From the looks of this the individual pins are being toggled correctly. It looks like the bus definition however is not working and therefore no data is getting to the display.

Can you please check the chibios bus definition api calls and verify that the code Tectu provided is correct In that area. Unfortunately we can't be experts at everything and the chibios bus definition are not something we regularly use. The chibios forum may also be able to help in this area if you get stuck.

Once the data lines are toggling, if the display still doesn't work then please add another post here.

When doing your testing it would be useful to use a demo that is constantly updating the display. Try using the gdisp/streaming demo as it should keep the display pins very busy.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...