david1982 Posted May 9, 2015 Report Posted May 9, 2015 Hello all,Can some one please just help me with my multiple display set-up.I understand the basics of using the multiple displays from the examples but how do I set-up my board file as the only difference between the two displays is the chip select (SPI).Thanks.
inmarket Posted May 9, 2015 Report Posted May 9, 2015 Where you are using the same controller chip with two displays you can use the board member of the gdisplay structure to work out which chip select pin to activate. This member is for your board files private use.Your list of boards will then contain the same controller twice (or rather GDISP_TOTAL_DISPLAYS will be set to 2 if they use the same controller I think). It will then get initialised twice with a different display number each time. The init routine sets up the board member and thereafter that is used to distinguish the displays.
david1982 Posted May 9, 2015 Author Report Posted May 9, 2015 I think that what I am doing ..and sorry yes both displays use the same controller.I have set the following in my ugfxconf..#define GDISP_TOTAL_DISPLAYS 2#define GDISP_TOTAL_CONTROLLERS 1#define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_RGB565My board int looks like..static inline void init_board(GDisplay *g) { (void) g; //Set up the pins.. palSetPadMode(GPIOB, 0, PAL_MODE_OUTPUT_PUSHPULL);//cs 2 palSetPadMode(SPI_PORT, CS_PAD, PAL_MODE_OUTPUT_PUSHPULL);//cs 1 palSetPadMode(SPI_PORT, SCK_PAD, PAL_MODE_STM32_ALTERNATE_PUSHPULL); palSetPadMode(SPI_PORT, MISO_PAD, PAL_MODE_STM32_ALTERNATE_PUSHPULL); palSetPadMode(SPI_PORT, MOSI_PAD, PAL_MODE_STM32_ALTERNATE_PUSHPULL); palSetPadMode(RESET_PORT, RESET_PAD, PAL_MODE_OUTPUT_PUSHPULL ); palSetPadMode(DNC_PORT, DNC_PAD, PAL_MODE_OUTPUT_PUSHPULL); switch(g->controllerdisplay) { case 0: //Set pins. palSetPad(CS_PORT, CS_PAD); palSetPad(RESET_PORT, RESET_PAD); palClearPad(DNC_PORT, DNC_PAD); break; //Start SPI1 with our config. spiStart(SPI_DRIVER, &spi_cfg); spiSelectI(SPI_DRIVER); /* Slave Select assertion. */ case 1: //Set pins. palSetPad(GPIOB, 0); palSetPad(RESET_PORT, RESET_PAD); palClearPad(DNC_PORT, DNC_PAD); //Start SPI1 with our config. spiStart(SPI_DRIVER, &spi_cfg2); spiSelectI(SPI_DRIVER); break; } }But when I draw to each display only the second display works..I am switching between displays like so..coord_t displayA,displayB; displayA = 0; displayB = 1; gdispSetDisplay(gdispGetDisplay(displayA));///Do some drawing This does not show gdispSetDisplay(gdispGetDisplay(displayB));///Do some drawing This does show
inmarket Posted May 9, 2015 Report Posted May 9, 2015 Your application code looks fine. Can you please post your entire board file. I suspect the problem is in the aquirebus/releasebus and the write calls.To give you more detail...You are configuring both boards (including their chip select lines) in the init call. Once you have init the spi for cs2 it will maintain that for all writes and thus only the 2nd display gets written to.In practice the chibios experience of storing the chip select in the spi port means it is assuming a single slave device. There are two solutions, 1/ do your own chip select manipulation or 2/ re initialise the chibios spi port during each aquirebus operation.
inmarket Posted May 9, 2015 Report Posted May 9, 2015 Also, with the current version of ugfx the setting gdisp _ total _ controllers is no longer needed.Similarly you shouldn't need to set the pixel format - it should auto detect as there is one controller type.
david1982 Posted May 10, 2015 Author Report Posted May 10, 2015 Yes you where right inmarket..I have it working now, you don’t do anything with the spi in int board but you do all spi work in acquire bus.Below is my board file for 2 ILI9341 displays running on a STM32F1 via spi.It my help others as an example. #ifndef _GDISP_LLD_BOARD_H #define _GDISP_LLD_BOARD_H //**** ILI9341 on SPI1. TESTED on STM32L1, STM32F1 AND STM32F4. // Pin & SPI setup #define SPI_METHOD_IRQ 1 #define SPI_METHOD_POLLING 2 #define SPI_METHOD SPI_METHOD_POLLING // SPI1 #define SPI_DRIVER (&SPID1) #define SPI_PORT GPIOA #define SCK_PAD 5 //PA5 #define MISO_PAD 6 //PA6 #define MOSI_PAD 7 //PA7 #define CS_PORT GPIOA #define CS2_PORT GPIOB #define RESET_PORT GPIOA #define DNC_PORT GPIOA #define CS_PAD 4 // PA4 -- 0 = chip selected #define CS2_PAD 0 // PB0 -- 0 = chip selected #define RESET_PAD 1 // PA1 -- 0 = reset #define DNC_PAD 0 // PA0 -- control=0, data=1 -- DNC or D/C // SPI setup ajust " SPI_BaudRatePrescaler_X" to set SPI speed. // Peripherial Clock 42MHz SPI2 SPI3 // Peripherial Clock 84MHz SPI1 SPI1 SPI2/3 #define SPI_BaudRatePrescaler_2 ((uint16_t)0x0000) // 42 MHz 21 MHZ #define SPI_BaudRatePrescaler_4 ((uint16_t)0x0008) // 21 MHz 10.5 MHz #define SPI_BaudRatePrescaler_8 ((uint16_t)0x0010) // 10.5 MHz 5.25 MHz #define SPI_BaudRatePrescaler_16 ((uint16_t)0x0018) // 5.25 MHz 2.626 MHz #define SPI_BaudRatePrescaler_32 ((uint16_t)0x0020) // 2.626 MHz 1.3125 MHz #define SPI_BaudRatePrescaler_64 ((uint16_t)0x0028) // 1.3125 MHz 656.25 KHz #define SPI_BaudRatePrescaler_128 ((uint16_t)0x0030) // 656.25 KHz 328.125 KHz #define SPI_BaudRatePrescaler_256 ((uint16_t)0x0038) // 328.125 KHz 164.06 KHz static SPIConfig spi_cfg = { NULL, CS_PORT, CS_PAD, SPI_BaudRatePrescaler_2 //AJUST SPEED HERE.. }; static SPIConfig spi_cfg2 = { NULL, CS2_PORT, CS2_PAD, SPI_BaudRatePrescaler_2 //AJUST SPEED HERE.. }; static inline void init_board(GDisplay *g) { (void) g; //Set up the pins.. palSetPadMode(GPIOB, 0, PAL_MODE_OUTPUT_PUSHPULL);//cs 2 palSetPadMode(SPI_PORT, CS_PAD, PAL_MODE_OUTPUT_PUSHPULL);//cs 1 palSetPadMode(SPI_PORT, SCK_PAD, PAL_MODE_STM32_ALTERNATE_PUSHPULL); palSetPadMode(SPI_PORT, MISO_PAD, PAL_MODE_STM32_ALTERNATE_PUSHPULL); palSetPadMode(SPI_PORT, MOSI_PAD, PAL_MODE_STM32_ALTERNATE_PUSHPULL); palSetPadMode(RESET_PORT, RESET_PAD, PAL_MODE_OUTPUT_PUSHPULL ); palSetPadMode(DNC_PORT, DNC_PAD, PAL_MODE_OUTPUT_PUSHPULL); //Select both displays palSetPad(CS_PORT, CS_PAD); palSetPad(CS2_PORT, CS2_PAD); //Reset both displays palSetPad(RESET_PORT, RESET_PAD); palClearPad(DNC_PORT, DNC_PAD); //Unselect both displays palClearPad(CS_PORT, CS_PAD); palClearPad(CS2_PORT, CS2_PAD);} static inline void post_init_board(GDisplay *g) { (void) g; } static inline void setpin_reset(GDisplay *g, bool_t state) { (void) g; palWritePad(RESET_PORT, RESET_PAD, !state); } static inline void set_backlight(GDisplay *g, uint8_t percent) { (void) g; (void) percent; } //This is where we select each display static inline void acquire_bus(GDisplay *g) { (void) g; switch(g->controllerdisplay) { case 0: spiStart(SPI_DRIVER, &spi_cfg); spiSelectI(SPI_DRIVER); break; case 1: spiStart(SPI_DRIVER, &spi_cfg2); spiSelectI(SPI_DRIVER); break; } } static inline void release_bus(GDisplay *g) { (void) g; switch(g->controllerdisplay) { case 0: spiUnselectI(SPI_DRIVER); break; case 1: spiUnselectI(SPI_DRIVER); break; } } static inline void write_index(GDisplay *g, uint8_t index) { (void) g; palClearPad(DNC_PORT, DNC_PAD); #if SPI_METHOD == SPI_METHOD_IRQ spiSend(SPI_DRIVER, 1, &index); #elif SPI_METHOD == SPI_METHOD_POLLING spiPolledExchange(SPI_DRIVER, index); #endif palSetPad(DNC_PORT, DNC_PAD); } static inline void write_data(GDisplay *g, uint8_t data) { (void) g; #if SPI_METHOD == SPI_METHOD_IRQ spiSend(SPI_DRIVER, 1, &data); #elif SPI_METHOD == SPI_METHOD_POLLING spiPolledExchange(SPI_DRIVER, data); #endif } 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 0; } #endif /* _GDISP_LLD_BOARD_H */
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