Jump to content

Problem with SSD1289


iccp

Recommended Posts

HI everybody,

First of all, congratulations to everybody for all the work done with this package.

I'm trying to make it work on a Open103Z Devboard and a SSD1289 LCD on a FSMC bus using Chibios.

The bus comes with an extra address decoder.

board_SSD1289.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 *) 0x6F000000)[0] /* RS = 0 */
#define GDISP_RAM ((volatile uint16_t *) 0x6F010000)[0] /* RS = 1 */
//#define GDISP_DMA_STREAM STM32_DMA2_STREAM6
#define FSMC_BANK 6

/* 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. */
0,
{
{PWM_OUTPUT_DISABLED, 0},
{PWM_OUTPUT_DISABLED, 0},
{PWM_OUTPUT_ACTIVE_HIGH, 0},
{PWM_OUTPUT_DISABLED, 0}
},
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)
*/

rccEnableAHB(RCC_AHBENR_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 << 2) | (1 << 7) | (1 << 8) | (1 << 9) | (1 << 10) | (1 << 11) | (1 << 12) |
(1 << 13) | (1 << 14) | (1 << 15), 0};

IOBus busG = {GPIOG, (1 << 12) | (1 << 13) | (1<<5), 0};

palSetBusMode(&busD, PAL_MODE_STM32_ALTERNATE_PUSHPULL);
palSetBusMode(&busE, PAL_MODE_STM32_ALTERNATE_PUSHPULL);
palSetBusMode(&busG, PAL_MODE_STM32_ALTERNATE_PUSHPULL);

palSetPadMode(GPIOB, 1, PAL_MODE_OUTPUT_PUSHPULL);


/* 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_STM32_ALTERNATE_PUSHPULL);
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;
if(state)
palClearPad(GPIOB, 1);
else
palSetPad(GPIOB, 1);


}

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;
}

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;
}

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

And main.c:

#include 
#include



#ifndef __NO_SYSTEM_INIT
void SystemInit()
{}
#endif

#include
#include
#include
#include
#include
#include

#define STM32F1XX
#define STM32F103
#define STM32F10x_HD

//uint8_t percent;



int main(void)
{

halInit();
chSysInit();

coord_t width, height;
coord_t i, j;
//struct GDisplay *g;
struct GDISPControl Control;
Control.Width=320;
Control.Height=240;
Control.Orientation=GDISP_ROTATE_90;
Control.Backlight=25;
Control.Contrast=50;
Control.Powermode=powerOn;
// g.board="SSD1289";
// g.rotation=GDISP_ROTATE_90;
// g.controllerdisplay="SSD1289";


palClearPad(GPIOF,6);

// Initialize and clear the display
gfxInit();

palClearPad(GPIOF,7);

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

gdispClear(Green);

palClearPad(GPIOF,8);

// Code Here

gdispDrawBox(10, 10, width/2, height/2, Yellow);
gdispFillArea(width/2, height/2, width/2-10, height/2-10, Blue);
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);
palTogglePad(GPIOF,6);
palTogglePad(GPIOF,7);
palTogglePad(GPIOF,8);
palTogglePad(GPIOF,9);

}
}

And uses NE4 (FSMC_BANK=6)

After a lot o research on the forums about ugfx and Chibios, finaly I've found how to configure the board and compile without errors, but when it comes to work, I only get a screen full of coloured noise.

By the moment I havent any debugger, so I use the leds on the devboard as light markers on the code.

When I try to make a gDispClear() the board freezes.

Any clue about this?

Thanks!

Link to comment
Share on other sites

Hello iccp and welcome to the community,

You say that the display is connected to Bank4 but out of my mind it looks like you try to initialize Bank0. This could lead to a hardfault and therefore freeze everything. I haven't taken a closer look to the reference manual but please check this to be sure. Back the days I've written this little guide leading you through the process of using FSMC with ChibiOS/RT. Probably that is of any help.

The next thing I've noticed is that you actually touch the GDISPControl struct. This is a very bad thing to do. You're not supposed to ever come into contact with that struct and that's why it's nowhere documented nor listed in any examples. Please use the official API to change stuff like the orientation, backlight, contrast and so on to prevent anything bad from happening.

I recommend you to use the demo you can find under /demos/modules/gdisp/basic until you get your display working.

One more recommendation: Until you have a debugger, modify the hardfault routine of ChibiOS/RT in order to flash an LED for example very fast. This way you at least know whether it is stuck somewhere or something bad happened.

~ Tectu

Link to comment
Share on other sites

Thanks for the fast reply.

That guide was the first document I read. You're right, I'm using bank 1 (NOR/PSRAM), subbank 4 (NE4), I misspelled it.

The freezing ocurred even before I tried to modify the GDISPControl struct, that was a desperate try out thinking that was some config missing. In fact, the main routine is based in the basic example...

I'm going to try to modify the hardfault routine to display errors on the leds.

The freezing could be caused by misconfigured timming? I've tried the one in the cortex-m4 example and the one described in an old post: http://forum.chibios.org/phpbb/viewtopic.php?f=11&t=725&sid=43ba3b809d2faef81c4924edfbd588be with the same results. The board in that old post is the same I've bought, but the config seems to be invalid.

iccp

Link to comment
Share on other sites

Still working on it. I've tryied to change some of the gfxconf; after that I get a half clear coloured screen, and a system freeze again, without a hardfault.

gfxconf.h:

#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 TRUE
//#define GFX_USE_OS_WIN32 TRUE
//#define GFX_USE_OS_LINUX TRUE
//#define GFX_USE_OS_OSX TRUE


///////////////////////////////////////////////////////////////////////////
// GDISP //
///////////////////////////////////////////////////////////////////////////
#define GFX_USE_GDISP TRUE

#define GDISP_NEED_AUTOFLUSH TRUE
#define GDISP_NEED_TIMERFLUSH TRUE
#define GDISP_NEED_VALIDATION TRUE
#define GDISP_NEED_CLIP TRUE
#define GDISP_NEED_CIRCLE FALSE
#define GDISP_NEED_ELLIPSE FALSE
#define GDISP_NEED_ARC FALSE
#define GDISP_NEED_CONVEX_POLYGON TRUE
#define GDISP_NEED_SCROLL FALSE
#define GDISP_NEED_PIXELREAD FALSE
#define GDISP_NEED_CONTROL TRUE
#define GDISP_NEED_QUERY FALSE
#define GDISP_NEED_MULTITHREAD FALSE
#define GDISP_NEED_STREAMING FALSE
#define GDISP_NEED_TEXT FALSE
#define GDISP_NEED_ANTIALIAS FALSE
#define GDISP_NEED_UTF8 FALSE
#define GDISP_NEED_TEXT_KERNING FALSE
#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
#define GDISP_INCLUDE_FONT_DEJAVUSANS24 FALSE
#define GDISP_INCLUDE_FONT_DEJAVUSANS32 FALSE
#define GDISP_INCLUDE_FONT_DEJAVUSANSBOLD12 FALSE
#define GDISP_INCLUDE_FONT_FIXED_10X20 FALSE
#define GDISP_INCLUDE_FONT_FIXED_7X14 FALSE
#define GDISP_INCLUDE_FONT_FIXED_5X8 FALSE
#define GDISP_INCLUDE_FONT_DEJAVUSANS12_AA FALSE
#define GDISP_INCLUDE_FONT_DEJAVUSANS16_AA FALSE
#define GDISP_INCLUDE_FONT_DEJAVUSANS24_AA FALSE
#define GDISP_INCLUDE_FONT_DEJAVUSANS32_AA FALSE
#define GDISP_INCLUDE_FONT_DEJAVUSANSBOLD12_AA FALSE
#define GDISP_INCLUDE_USER_FONTS FALSE

#define GDISP_NEED_IMAGE FALSE
#define GDISP_NEED_IMAGE_NATIVE FALSE
#define GDISP_NEED_IMAGE_GIF FALSE
#define GDISP_NEED_IMAGE_BMP FALSE
#define GDISP_NEED_IMAGE_BMP_1 FALSE
#define GDISP_NEED_IMAGE_BMP_4 FALSE
#define GDISP_NEED_IMAGE_BMP_4_RLE FALSE
#define GDISP_NEED_IMAGE_BMP_8 FALSE
#define GDISP_NEED_IMAGE_BMP_8_RLE FALSE
#define GDISP_NEED_IMAGE_BMP_16 FALSE
#define GDISP_NEED_IMAGE_BMP_24 FALSE
#define GDISP_NEED_IMAGE_BMP_32 FALSE
#define GDISP_NEED_IMAGE_JPG FALSE
#define GDISP_NEED_IMAGE_PNG FALSE
#define GDISP_NEED_IMAGE_ACCOUNTING FALSE

#define GDISP_NEED_STARTUP_LOGO FALSE

#define GDISP_DEFAULT_ORIENTATION GDISP_ROTATE_LANDSCAPE
#define GDISP_LINEBUF_SIZE 128

#define GDISP_TOTAL_DISPLAYS 1
#if GDISP_TOTAL_DISPLAYS > 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
#endif

#define GDISP_TOTAL_CONTROLLERS 1
#if GDISP_TOTAL_CONTROLLERS > 1
#define GDISP_CONTROLLER_LIST GDISPVMT_Win32, GDISPVMT_Win32
#define GDISP_CONTROLLER_DISPLAYS 1, 1
#define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_RGB888
#endif

#define GDISP_USE_GFXNET FALSE
#define GDISP_GFXNET_PORT 13001
#define GDISP_GFXNET_CUSTOM_LWIP_STARTUP FALSE
#define GDISP_DONT_WAIT_FOR_NET_DISPLAY FALSE
#define GDISP_GFXNET_UNSAFE_SOCKETS FALSE


///////////////////////////////////////////////////////////////////////////
// GWIN //
///////////////////////////////////////////////////////////////////////////
#define GFX_USE_GWIN FALSE

#define GWIN_NEED_WINDOWMANAGER FALSE

#define GWIN_NEED_CONSOLE FALSE
#define GWIN_CONSOLE_USE_HISTORY FALSE
#define GWIN_CONSOLE_HISTORY_AVERAGING FALSE
#define GWIN_CONSOLE_HISTORY_ATCREATE FALSE
#define GWIN_CONSOLE_ESCSEQ FALSE
#define GWIN_CONSOLE_USE_BASESTREAM FALSE
#define GWIN_CONSOLE_USE_FLOAT FALSE
#define GWIN_NEED_GRAPH FALSE

#define GWIN_NEED_WIDGET FALSE
#define GWIN_NEED_HIERARCHY FALSE
#define GWIN_NEED_LABEL FALSE
#define GWIN_LABEL_ATTRIBUTE FALSE
#define GWIN_NEED_BUTTON FALSE
#define GWIN_BUTTON_LAZY_RELEASE FALSE
#define GWIN_NEED_SLIDER FALSE
#define GWIN_NEED_CHECKBOX FALSE
#define GWIN_NEED_IMAGE FALSE
#define GWIN_NEED_IMAGE_ANIMATION FALSE
#define GWIN_NEED_RADIO FALSE
#define GWIN_NEED_LIST FALSE
#define GWIN_NEED_LIST_IMAGES FALSE
#define GWIN_NEED_PROGRESSBAR FALSE
#define GWIN_NEED_FRAME FALSE


///////////////////////////////////////////////////////////////////////////
// GEVENT //
///////////////////////////////////////////////////////////////////////////
#define GFX_USE_GEVENT FALSE

#define GEVENT_ASSERT_NO_RESOURCE FALSE
#define GEVENT_MAXIMUM_SIZE 32
#define GEVENT_MAX_SOURCE_LISTENERS 32


///////////////////////////////////////////////////////////////////////////
// GTIMER //
///////////////////////////////////////////////////////////////////////////
#define GFX_USE_GTIMER FALSE

#define GTIMER_THREAD_PRIORITY HIGH_PRIORITY
#define GTIMER_THREAD_WORKAREA_SIZE 2048


///////////////////////////////////////////////////////////////////////////
// GQUEUE //
///////////////////////////////////////////////////////////////////////////
#define GFX_USE_GQUEUE FALSE

#define GQUEUE_NEED_ASYNC FALSE
#define GQUEUE_NEED_GSYNC FALSE
#define GQUEUE_NEED_FSYNC FALSE
#define GQUEUE_NEED_BUFFERS FALSE

///////////////////////////////////////////////////////////////////////////
// GINPUT //
///////////////////////////////////////////////////////////////////////////
#define GFX_USE_GINPUT FALSE

#define GINPUT_NEED_MOUSE FALSE
#define GINPUT_NEED_KEYBOARD FALSE
#define GINPUT_NEED_TOGGLE FALSE
#define GINPUT_NEED_DIAL FALSE


///////////////////////////////////////////////////////////////////////////
// GFILE //
///////////////////////////////////////////////////////////////////////////
#define GFX_USE_GFILE FALSE

#define GFILE_NEED_PRINTG FALSE
#define GFILE_NEED_SCANG FALSE
#define GFILE_NEED_STRINGS FALSE
#define GFILE_NEED_STDIO FALSE
#define GFILE_ALLOW_FLOATS FALSE
#define GFILE_ALLOW_DEVICESPECIFIC FALSE
#define GFILE_MAX_GFILES 3

#define GFILE_NEED_MEMFS FALSE
#define GFILE_NEED_ROMFS FALSE
#define GFILE_NEED_RAMFS FALSE
#define GFILE_NEED_FATFS FALSE
#define GFILE_NEED_NATIVEFS FALSE
#define GFILE_NEED_CHBIOSFS FALSE


///////////////////////////////////////////////////////////////////////////
// GADC //
///////////////////////////////////////////////////////////////////////////
#define GFX_USE_GADC FALSE

#define GADC_MAX_LOWSPEED_DEVICES 4


///////////////////////////////////////////////////////////////////////////
// GAUDIO //
///////////////////////////////////////////////////////////////////////////
#define GFX_USE_GAUDIO FALSE
#define GAUDIO_NEED_PLAY FALSE
#define GAUDIO_NEED_RECORD FALSE


///////////////////////////////////////////////////////////////////////////
// GMISC //
///////////////////////////////////////////////////////////////////////////
#define GFX_USE_GMISC FALSE

#define GMISC_NEED_ARRAYOPS FALSE
#define GMISC_NEED_FASTTRIG FALSE
#define GMISC_NEED_FIXEDTRIG FALSE
#define GMISC_NEED_INVSQRT FALSE
#define GMISC_INVSQRT_MIXED_ENDIAN FALSE
#define GMISC_INVSQRT_REAL_SLOW FALSE


#endif /* _GFXCONF_H */

Link to comment
Share on other sites

Don't worry about time, I'm working on it on my spare time...

Do you mean to set a bigger divider on ADD_SET, DATAST, BUSTURN? If you mean that, I've been playing around with this, even tried to set all 4 bits in all three vars with no luck

Thanks

iccp

Link to comment
Share on other sites

Hello iccp,

I'll have some time tonight and/or tomorrow afternoon to digg into the reference manual again. It has been quite some time since I last used the FSMC peripheral from scratch.

You mentioned some external address decoder, did you make sure that you handle it properly?

Also, have you ever run the official example provided by the board supplier to make sure that it's no hardware issue? I know, this is not very likely but just in case...

~ Tectu

Link to comment
Share on other sites

Hello, Tectu.

The official examples works fine on the board. I used it to be sure of the chipset, as this display can be provided with the SSD1289 or the ILI9320 chipset and is not marked on it.

About the address decoder, I'm pretty sure the adrdess is correct. Is a 74LVC139, using as input NE4, and lines A23 and A24. The address needed for de LCD is the fourth one: A23 and A24 set (11).

I tryied to change the address and in the other cases the LCD didn't response. I'll check it again against the example code.

Thanks for your time

iccp

Link to comment
Share on other sites

Today I've had some spare time to work on it again.

I've digged on the example's source code, and this is the configuration part:

FSMC_NORSRAMInitTypeDef  FSMC_NORSRAMInitStructure;
FSMC_NORSRAMTimingInitTypeDef FSMC_NORSRAMTimingInitStructure;
/* FSMC Read/Write Timing */
FSMC_NORSRAMTimingInitStructure.FSMC_AddressSetupTime = 5; /* Address Setup Time */
FSMC_NORSRAMTimingInitStructure.FSMC_AddressHoldTime = 0;
FSMC_NORSRAMTimingInitStructure.FSMC_DataSetupTime = 5; /* Data Setup Time */
FSMC_NORSRAMTimingInitStructure.FSMC_BusTurnAroundDuration = 0x00;
FSMC_NORSRAMTimingInitStructure.FSMC_CLKDivision = 0x00;
FSMC_NORSRAMTimingInitStructure.FSMC_DataLatency = 0x00;
FSMC_NORSRAMTimingInitStructure.FSMC_AccessMode = FSMC_AccessMode_A; /* FSMC Access Mode */

FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM4;
FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM;
FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable;
FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &FSMC_NORSRAMTimingInitStructure;
FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);
/* FSMC Write Timing */
FSMC_NORSRAMTimingInitStructure.FSMC_AddressSetupTime = 15;//2;//1; /* Address Setup Time */
FSMC_NORSRAMTimingInitStructure.FSMC_AddressHoldTime = 0;
FSMC_NORSRAMTimingInitStructure.FSMC_DataSetupTime = 15;//2;//1; /* Data Setup Time */
FSMC_NORSRAMTimingInitStructure.FSMC_BusTurnAroundDuration = 0x00;
FSMC_NORSRAMTimingInitStructure.FSMC_CLKDivision = 0x00;
FSMC_NORSRAMTimingInitStructure.FSMC_DataLatency = 0x00;
FSMC_NORSRAMTimingInitStructure.FSMC_AccessMode = FSMC_AccessMode_A; /* FSMC Access Mode */
FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &FSMC_NORSRAMTimingInitStructure;

FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);

/* Enable FSMC Bank4_SRAM Bank */
FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM4, ENABLE);

By now, I'm translating it to Chibios

iccp

Link to comment
Share on other sites

After some work, I've managed to translate the FSMC config from the example to ugfx, but still doesn'nt work.

That's my board_SSD1289.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 *) 0x6F000000)[0] /* RS = 0 */
#define GDISP_RAM ((volatile uint16_t *) 0x6F010000)[0] /* RS = 1 */
//#define GDISP_DMA_STREAM STM32_DMA2_STREAM6
#define FSMC_BANK 6

/* 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. */
0,
{
{PWM_OUTPUT_DISABLED, 0},
{PWM_OUTPUT_DISABLED, 0},
{PWM_OUTPUT_ACTIVE_HIGH, 0},
{PWM_OUTPUT_DISABLED, 0}
},
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)
*/

rccEnableAHB(RCC_AHBENR_FSMCEN, 0);

/* set pins to FSMC mode */
IOBus busD = {GPIOD, (1 << 0) | (1 << 1) | (1 << 4) | (1 << 5) | (1 << 8) |
(1 << 9) | (1 << 10) | (1 << 14) | (1 << 15), 0};

IOBus busE = {GPIOE, (1 << 2) | (1 << 7) | (1 << 8) | (1 << 9) | (1 << 10) | (1 << 11) | (1 << 12) |
(1 << 13) | (1 << 14) | (1 << 15), 0};

IOBus busG = {GPIOG, (1 << 12) | (1 << 13) | (1<<5), 0};

palSetBusMode(&busD, PAL_MODE_STM32_ALTERNATE_PUSHPULL);
palSetBusMode(&busE, PAL_MODE_STM32_ALTERNATE_PUSHPULL);
palSetBusMode(&busG, PAL_MODE_STM32_ALTERNATE_PUSHPULL);

palSetPadMode(GPIOB, 1, PAL_MODE_OUTPUT_PUSHPULL);


/* FSMC timing */
//FSMC_Bank1->BTCR[FSMC_BANK+1] = FSMC_BTR1_ADDSET_3 | FSMC_BTR1_ADDSET_2 | FSMC_BTR1_ADDSET_1 | FSMC_BTR1_ADDSET_0 | FSMC_BTR1_DATAST_3 | FSMC_BTR1_DATAST_2 | FSMC_BTR1_DATAST_1 | FSMC_BTR1_DATAST_0 ;
//(FSMC_Bank1->BTCR[FSMC_BANK+1] = (6) | (10 << 8) | (10 << 16);

FSMC_Bank1->BTCR[FSMC_BANK+1] = FSMC_BTR1_ADDSET_2 | FSMC_BTR1_ADDSET_0 | FSMC_BTR1_DATAST_2 | FSMC_BTR1_DATAST_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; //| FSMC_BCR1_EXTMOD;

/* Display backlight control */
/* TIM3 is an alternate function 2 (AF2) */
pwmStart(&PWMD3, &pwmcfg);
palSetPadMode(GPIOB, 0,PAL_MODE_STM32_ALTERNATE_PUSHPULL);
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;
if(state)
palClearPad(GPIOB, 1);
else
palSetPad(GPIOB, 1);


}

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_ADDSET_2 | FSMC_BTR1_ADDSET_1 | FSMC_BTR1_ADDSET_0 | FSMC_BTR1_DATAST_3 | FSMC_BTR1_DATAST_2 | FSMC_BTR1_DATAST_1 | FSMC_BTR1_DATAST_0 ;
//FSMC_Bank1->BTCR[FSMC_BANK+1] = FSMC_BTR1_ADDSET_3 | FSMC_BTR1_DATAST_3 | FSMC_BTR1_BUSTURN_0;

FSMC_Bank1->BTCR[FSMC_BANK+1] = FSMC_BTR1_ADDSET_2 | FSMC_BTR1_ADDSET_0 | FSMC_BTR1_DATAST_2 | FSMC_BTR1_DATAST_0;

}

static inline void setwritemode(GDisplay *g) {
(void) g;
//FSMC_Bank1->BTCR[FSMC_BANK+1] = FSMC_BTR1_ADDSET_2 | FSMC_BTR1_ADDSET_0 | FSMC_BTR1_DATAST_2 | FSMC_BTR1_DATAST_0 ; /* FSMC timing */
//FSMC_Bank1->BTCR[FSMC_BANK+1] = FSMC_BTR1_ADDSET_0 | FSMC_BTR1_DATAST_2 | FSMC_BTR1_BUSTURN_0;

FSMC_Bank1->BTCR[FSMC_BANK+1] = FSMC_BTR1_ADDSET_3 | FSMC_BTR1_ADDSET_2 | FSMC_BTR1_ADDSET_1 | FSMC_BTR1_ADDSET_0|
FSMC_BTR1_DATAST_3 | FSMC_BTR1_DATAST_2 | FSMC_BTR1_DATAST_1 | FSMC_BTR1_DATAST_0;

}

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

I'll keep trying. maybe it's something misconfigured.

iccp

Link to comment
Share on other sites

Look in the reference manual for FSMC, you have the 4 BCRs in FSMC_Bank1->BTCR[0..3] followed by the 4 BTRs, they are not one after the other hence the index has to be 3 and 7 respectively for both cases.

FSMC_BANK=6 is actually incorrect, we would have to use

#define FSMC_BANK 3

For the correct addressing of BTR4 here, replace:

FSMC_Bank1->BTCR[FSMC_BANK+1] = FSMC_BTR1_ADDSET_2 | FSMC_BTR1_ADDSET_0 | FSMC_BTR1_DATAST_2 | FSMC_BTR1_DATAST_0;

by 4

Then to configure BCR4, so this line is left as is

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

.

That should lead to correct configuration of Bank 4, if all the switches in it are configured correctly.

Regards

Abhishek

Link to comment
Share on other sites

Thanks for your response Abhishek.

This was one of the first thoughts I had, but I think 6 is correct. For each subbank, you must define BTCR[n] and BTCR[n+1], so subbank 0, uses 0 and 1, subbank 1 uses 2 & 3, subbank 3 needs 4 & 5 and subbank 4 (which I'm using) should use 6 & 7.

Anyway, I've tried it again and it freezes even before finishing initgfx();

Thanks anyway for your time.

iccp

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...