16 x SSD1306 GLCDs on STM32F4

Hi

i want to extend my project with 16 GLCD’s. i found several threads about it but i’m still unsure how to connect the additional CS lines.

the first 8 GLCD’s work perfect connected to J15A… now i need to know how to connect the other 8 lines.

found this wiki where it’s stated how to connect additional lines from a J28 named connector. but on a “normal” STM32F4 the J28 isn’t available…

I read on an other  that several lines are available on connector J10B. If I look at the schematic J10B is a normal GPIO against the J28 is a audio DAC.

Can I use the GPIO’s directly as they are to make 8 additional CS lines? if yes, do I need 220 ohm resistors on it? do I need an other boot loader configuration as the one described here in the MBNG manual?

if no, how to use a SN74HC595N IC to generate additional lines? Where do i get the clocks (RCK and SCK, Pin 11/12 on 74HC595) and where comes the DISP SER IN (Pin 14 on 74HC595) from?

 

thanks for some enlightenment, roberto

41 minutes ago, roberto said:

found this wiki where it’s stated how to connect additional lines from a J28 named connector. but on a “normal” STM32F4 the J28 isn’t available…

I read on an other  that several lines are available on connector J10B. If I look at the schematic J10B is a normal GPIO against the J28 is a audio DAC.

J10B is correct for STM32F4

 

41 minutes ago, roberto said:

Can I use the GPIO’s directly as they are to make 8 additional CS lines?

Yes. I haven’t done it myself, but the next 8 are there.

41 minutes ago, roberto said:

if yes, do I need 220 ohm resistors on it?

No.

41 minutes ago, roberto said:

do I need an other boot loader configuration as the one described here in the MBNG manual?

Should work with n=16. 8 From J15, 8 from J10B

41 minutes ago, roberto said:

if no, how to use a SN74HC595N IC to generate additional lines? Where do i get the clocks (RCK and SCK, Pin 11/12 on 74HC595) and where comes the DISP SER IN (Pin 14 on 74HC595) from?

For example:
http://www.midibox.org/dokuwiki/doku.php?id=display_driver

I have PCBs if you need. It’s possible to get 16 CS lines from the Core, my version is a bit neater.

 

 

oh, cool, many thanks latigid on, as always fast and competent answers! 

i will try the J10B version, if ist not working then i go with SN74s. thanks for the display driver link, did’t saw it ntill now…

 

other question: i do have the alientek OLED’s, the dual color version (blue/yellow). now it’s displaying in blue… how to change the color?

 

best roberto 

nice! works… 

 

http://www.midibox.org/dokuwiki/doku.php?id=display_driver

i have 2 off your boards assambled, right now i need 18x SSD1306 in my project,

but the wiki is a bit rare about how to connect the displays from there - I would expand a “how to connect Oleds to the board” if you explain it to me. thx!

-mike

You have the pinouts in the wiki and it basically follows the “J15” layout. There are 4x /CS signals per IDC10 header.

I think you need to configure the MIOS bootloader for the number of displays that you require (x,y), then connect J10B to the core GPIO to generate a pseudo SRIO/SPI to derive the CS signals with MB_NG or your custom code. The “J15” SI/SO/SC signals are simply buffered and routed to the headers as shown.

just saw this, I am working on a controller and would like to bump it upto 16 displays, when i go into bootlader and enter the number of displays as " set lcd_num_x 16 " does this mean that i can pick up the extra Cs lines from J10B without changing anything else and still use the standard control surface on J10A

Just hook the displays up as i have on the first 8? each display having its own cs line.

 

Thanks

 

In theory yes I think you can, but there is a post from  saying that it didn’t work when he tried, so maybe it needs code changes (at least for character LCDs).

Thanks for the heads up , hopefully can give me some more info, I can add it to my thread along with some pics.  I am just using the ssd1306 oleds.  But at some point a controller with several clcd’s will be on the cards

u use custom code? or ng script? I dont have any knowledge of NG-Script nor offical apps…  i program my own based on MIOS.

 

in my memory… to get 8 additional only this is needet: (used in my filterbox - in my app.c in the init routine on startup…)

// Set GPIO @ J10A for (x=0; x\<16; ++x) {// Turn on all PINS --- activate Bypass Relais ssm2044 MIOS32\_BOARD\_J10\_PinInit(x, MIOS32\_BOARD\_PIN\_MODE\_OUTPUT\_PP); MIOS32\_BOARD\_J10\_PinSet (x, 1); } // LCD xLCDSemaphore = xSemaphoreCreateRecursiveMutex();// create Mutex for LCD access MIOS32\_LCD\_DeviceSet(0); MIOS32\_LCD\_Init(0); MIOS32\_LCD\_DeviceSet(1); MIOS32\_LCD\_Init(0); MIOS32\_LCD\_DeviceSet(2); MIOS32\_LCD\_Init(0); MIOS32\_LCD\_DeviceSet(3); MIOS32\_LCD\_Init(0); MIOS32\_LCD\_DeviceSet(4); MIOS32\_LCD\_Init(0); MIOS32\_LCD\_DeviceSet(5); MIOS32\_LCD\_Init(0); MIOS32\_LCD\_DeviceSet(6); MIOS32\_LCD\_Init(0); MIOS32\_LCD\_DeviceSet(7); MIOS32\_LCD\_Init(0); MIOS32\_LCD\_DeviceSet(8); MIOS32\_LCD\_Init(0); MIOS32\_LCD\_DeviceSet(9); MIOS32\_LCD\_Init(0); MIOS32\_LCD\_DeviceSet(10); MIOS32\_LCD\_Init(0); MIOS32\_LCD\_DeviceSet(11); MIOS32\_LCD\_Init(0); MIOS32\_LCD\_DeviceSet(12); MIOS32\_LCD\_Init(0); MIOS32\_LCD\_DeviceSet(13); MIOS32\_LCD\_Init(0); MIOS32\_LCD\_DeviceSet(14); MIOS32\_LCD\_Init(0); MIOS32\_LCD\_DeviceSet(15); MIOS32\_LCD\_Init(0);

 

 

exotics:

example triggermatrix has 9 SSD1306 Displays so i needet one more the J15 can deliever the “Menue-LCD” … my solution was to adapt the app_lcd.c (and .h) and includet it locally (in my project folder and changed the build path for it…)

Since i did not know what was going on, i reduce the code as much i can (deletet all not “universal” LCD code, all Rotated-Display - and non SSD1306 variants) - so i had the change to understand the “need to know”   -   i cant remember why i did it that way…dont ask - but maybe it helps

// LCD driver for 9x SSD1306 // MIOS32\_LCD environment variable set to "universal" // reduced by Michael Sigl #include \<mios32.h\> #include \<glcd\_font.h\> #include \<string.h\> #include "app\_lcd.h" static unsigned long long display\_available = 0; static u8 prev\_glcd\_selection = 0xfe; // the previous mios32\_lcd\_device, 0xff: all CS were activated, 0xfe: will force the update // pin initialisation \>\> Additonal CS-Line for the One MENUE-LCD inline static s32 APP\_LCD\_ExtPort\_Init(void) { MIOS32\_BOARD\_J10\_PinInit(8, MIOS32\_BOARD\_PIN\_MODE\_OUTPUT\_PP); return 0; } ///////////////////////////////////////////////////////////////////////////// // Initializes the CS pins for GLCDs with serial port // - 8 CS lines are available at J15 // - additional lines are available J10 ///////////////////////////////////////////////////////////////////////////// static s32 APP\_LCD\_SERGLCD\_CS\_Init(void){ APP\_LCD\_ExtPort\_Init(); int num\_lcds = mios32\_lcd\_parameters.num\_x \* mios32\_lcd\_parameters.num\_y; display\_available |= (1 \<\< num\_lcds)-1; return 0; // no error } ///////////////////////////////////////////////////////////////////////////// // Sets the CS line of a serial GLCDs depending on mios32\_lcd\_device // if "all" flag is set, commands are sent to all segments ///////////////////////////////////////////////////////////////////////////// static s32 APP\_LCD\_SERGLCD\_CS\_Set(u8 value, u8 all){ // Note: assume that CS lines are low-active! if( all ) { if( prev\_glcd\_selection != 0xff ) { prev\_glcd\_selection = 0xff; MIOS32\_BOARD\_J15\_DataSet(value ? 0x00 : 0xff); MIOS32\_BOARD\_J10\_PinSet(8, value ? 0 : 1); } } else { if( prev\_glcd\_selection != mios32\_lcd\_device ) { prev\_glcd\_selection = mios32\_lcd\_device; u32 mask = value ? ~(1 \<\< mios32\_lcd\_device) : 0xffffffff; MIOS32\_BOARD\_J15\_DataSet(mask); MIOS32\_BOARD\_J10\_PinSet(8,(mask \>\> (8)) & 1); } } return 0; // no error } ///////////////////////////////////////////////////////////////////////////// // Initializes application specific LCD driver ///////////////////////////////////////////////////////////////////////////// s32 APP\_LCD\_Init(u32 mode){ if( mios32\_lcd\_device \>= 9 ){ return -2; } // unsupported LCD device number // enable display by default display\_available |= (1ULL \<\< mios32\_lcd\_device); // the OLED works at 3.3V, level shifting (and open drain mode) not required if( MIOS32\_BOARD\_J15\_PortInit(0) \< 0 ){ return -2; } // failed to initialize J15 display\_available |= 0xff; APP\_LCD\_SERGLCD\_CS\_Init(); // will also enhance display\_available depending on total number of LCDs // wait 500 mS to ensure that the reset is released { int i; for(i=0; i\<500; ++i) MIOS32\_DELAY\_Wait\_uS(1000); } // initialize LCDs APP\_LCD\_Cmd(0xa8); // Set MUX Ratio APP\_LCD\_Cmd(0x3f); APP\_LCD\_Cmd(0xd3); // Set Display Offset APP\_LCD\_Cmd(0x00); APP\_LCD\_Cmd(0x40); // Set Display Start Line APP\_LCD\_Cmd(0xa1); // Set Segment re-map: rotated APP\_LCD\_Cmd(0xc8); // Set COM Output Scan Direction: rotated APP\_LCD\_Cmd(0xda); // Set COM Pins hardware configuration APP\_LCD\_Cmd(0x12); APP\_LCD\_Cmd(0x81); // Set Contrast Control APP\_LCD\_Cmd(0x7f); // middle APP\_LCD\_Cmd(0xa4); // Disable Entiere Display On APP\_LCD\_Cmd(0xa6); // Set Normal Display APP\_LCD\_Cmd(0xd5); // Set OSC Frequency APP\_LCD\_Cmd(0x80); APP\_LCD\_Cmd(0x8d); // Enable charge pump regulator APP\_LCD\_Cmd(0x14); APP\_LCD\_Cmd(0xaf); // Display On APP\_LCD\_Cmd(0x20); // Enable Page mode APP\_LCD\_Cmd(0x02); return (display\_available & (1ULL \<\< mios32\_lcd\_device)) ? 0 : -1; // return -1 if display not available } ///////////////////////////////////////////////////////////////////////////// // Sends data byte to LCD // IN: data byte in \<data\> // OUT: returns \< 0 if display not available or timed out ///////////////////////////////////////////////////////////////////////////// s32 APP\_LCD\_Data(u8 data) { // check if if display already has been disabled if( !(display\_available & (1ULL \<\< mios32\_lcd\_device)) ){ return -1; } // chip select and DC APP\_LCD\_SERGLCD\_CS\_Set(1, 0); MIOS32\_BOARD\_J15\_RS\_Set(1); // RS pin used to control DC // send data MIOS32\_BOARD\_J15\_SerDataShift(data); // increment graphical cursor ++mios32\_lcd\_x; // if end of display segment reached: set X position of all segments to 0 if( (mios32\_lcd\_x % mios32\_lcd\_parameters.width) == 0 ) { APP\_LCD\_Cmd(0x00); // set X=0 APP\_LCD\_Cmd(0x10);} return 0; // no error } ///////////////////////////////////////////////////////////////////////////// // Sends command byte to LCD // IN: command byte in \<cmd\> ///////////////////////////////////////////////////////////////////////////// s32 APP\_LCD\_Cmd(u8 cmd){ // check if if display already has been disabled if( !(display\_available & (1ULL \<\< mios32\_lcd\_device)) ){ return -1; } // select all LCDs APP\_LCD\_SERGLCD\_CS\_Set(1, 1); MIOS32\_BOARD\_J15\_RS\_Set(0); // RS pin used to control DC MIOS32\_BOARD\_J15\_SerDataShift(cmd); return 0; } ///////////////////////////////////////////////////////////////////////////// // Clear Screen // IN: - // OUT: returns \< 0 on errors ///////////////////////////////////////////////////////////////////////////// s32 APP\_LCD\_Clear(void){ s32 error = 0; u8 x, y; // use default font MIOS32\_LCD\_FontInit((u8 \*)GLCD\_FONT\_NORMAL); // send data for(y=0; y\<mios32\_lcd\_parameters.height/8; ++y) { error |= MIOS32\_LCD\_CursorSet(0, y); // select all LCDs APP\_LCD\_SERGLCD\_CS\_Set(1, 1); MIOS32\_BOARD\_J15\_RS\_Set(1); // RS pin used to control DC for(x=0; x\<mios32\_lcd\_parameters.width; ++x) MIOS32\_BOARD\_J15\_SerDataShift(0x00); } // set X=0, Y=0 error |= MIOS32\_LCD\_CursorSet(0, 0); return error; } ///////////////////////////////////////////////////////////////////////////// // Sets cursor to given position ///////////////////////////////////////////////////////////////////////////// s32 APP\_LCD\_CursorSet(u16 column, u16 line){return APP\_LCD\_GCursorSet(mios32\_lcd\_x, mios32\_lcd\_y);} ///////////////////////////////////////////////////////////////////////////// // Sets graphical cursor to given position ///////////////////////////////////////////////////////////////////////////// s32 APP\_LCD\_GCursorSet(u16 x, u16 y){ s32 error = 0; // set X position error |= APP\_LCD\_Cmd(0x00 | (x & 0xf)); error |= APP\_LCD\_Cmd(0x10 | ((x\>\>4) & 0xf)); // set Y position error |= APP\_LCD\_Cmd(0xb0 | ((y\>\>3) & 7)); return error; } ///////////////////////////////////////////////////////////////////////////// // Initializes a single special character // only for Character-LCDs ///////////////////////////////////////////////////////////////////////////// s32 APP\_LCD\_SpecialCharInit(u8 num, u8 table[8]){return -3; }// not supported ///////////////////////////////////////////////////////////////////////////// // Sets the background colour // Only relevant for colour GLCDs ///////////////////////////////////////////////////////////////////////////// s32 APP\_LCD\_BColourSet(u32 rgb) { return -3; }// not supported ///////////////////////////////////////////////////////////////////////////// // Sets the foreground colour // Only relevant for colour GLCDs ///////////////////////////////////////////////////////////////////////////// s32 APP\_LCD\_FColourSet(u32 rgb){ return -3; } // not supported ///////////////////////////////////////////////////////////////////////////// // Sets a pixel in the bitmap // IN: bitmap, x/y position and colour value (value range depends on APP\_LCD\_COLOUR\_DEPTH) ///////////////////////////////////////////////////////////////////////////// s32 APP\_LCD\_BitmapPixelSet(mios32\_lcd\_bitmap\_t bitmap, u16 x, u16 y, u32 colour){ if( x \>= bitmap.width || y \>= bitmap.height ) return -1; // pixel is outside bitmap // all GLCDs support the same bitmap scrambling u8 \*pixel = (u8 \*)&bitmap.memory[bitmap.line\_offset\*(y / 8) + x]; u8 mask = 1 \<\< (y % 8); \*pixel &= ~mask; if( colour ) \*pixel |= mask; return -3; // not supported } ///////////////////////////////////////////////////////////////////////////// // Transfers a Bitmap within given boundaries to the LCD // IN: bitmap ///////////////////////////////////////////////////////////////////////////// s32 APP\_LCD\_BitmapPrint(mios32\_lcd\_bitmap\_t bitmap) { // abort if max. width reached if( mios32\_lcd\_x \>= mios32\_lcd\_parameters.width ){ return -2; } // all GLCDs support the same bitmap scrambling int line; int y\_lines = (bitmap.height \>\> 3); u16 initial\_x = mios32\_lcd\_x; u16 initial\_y = mios32\_lcd\_y; for(line=0; line\<y\_lines; ++line) { // calculate pointer to bitmap line u8 \*memory\_ptr = bitmap.memory + line \* bitmap.line\_offset; // set graphical cursor after second line has reached if( line \> 0 ) { mios32\_lcd\_x = initial\_x; mios32\_lcd\_y += 8; APP\_LCD\_GCursorSet(mios32\_lcd\_x, mios32\_lcd\_y); } // transfer character int x; for(x=0; x\<bitmap.width; ++x) APP\_LCD\_Data(\*memory\_ptr++); } // fix graphical cursor if more than one line has been print if( y\_lines \>= 1 ) { mios32\_lcd\_y = initial\_y; APP\_LCD\_GCursorSet(mios32\_lcd\_x, mios32\_lcd\_y); } return 0; // no error }

 

another example where i had to define CS pins, because i used Dipcore - with limitaded IO:

/\* \* fixed Hardcoded for 4x \>\>\> SSD1306! \> CV1 Project \> DIPCORE F4! \* ========================================================================== \* Changed Version - Michael Sigl \* ========================================================================== \*/ #include \<mios32.h\> #include "glcd\_font.h" #include \<string.h\> #include "app\_lcd.h" ///////////////////////////////////////////////////////////////////////////// // pin mapping ///////////////////////////////////////////////////////////////////////////// #define SCLK\_PORT GPIOD #define SCLK\_PIN GPIO\_Pin\_6 #define SER\_PORT GPIOD // used as DC (data/command select) for serial interfaces #define SER\_PIN GPIO\_Pin\_2 #define E1\_PORT GPIOC // used to control SCLK of serial interfaces #define E1\_PIN GPIO\_Pin\_1 #define E2\_PORT GPIOC #define E2\_PIN GPIO\_Pin\_9 #define RW\_PORT GPIOC // used to control data output of serial interfaces #define RW\_PIN GPIO\_Pin\_12 #define CS1\_PORT GPIOB // used to control SCLK of serial interfaces #define CS1\_PIN GPIO\_Pin\_12 #define CS2\_PORT GPIOC #define CS2\_PIN GPIO\_Pin\_0 #define CS3\_PORT GPIOC // LED 0 - Extra CS-Line on Dipcore #define CS3\_PIN GPIO\_Pin\_6 #define CS4\_PORT GPIOC // LED 1 - Extra CS-Line on Dipcore #define CS4\_PIN GPIO\_Pin\_7 // you could define here more CS PINS! but be sure to deactivate the "Orginal" function of it... // following macros simplify the access to the pins #define PIN\_SER(b) MIOS32\_SYS\_STM\_PINSET(SER\_PORT, SER\_PIN, b) #define PIN\_E1(b) MIOS32\_SYS\_STM\_PINSET(E1\_PORT, E1\_PIN, b) #define PIN\_RW(b) MIOS32\_SYS\_STM\_PINSET(RW\_PORT, RW\_PIN, b) #define PIN\_CS1(b) MIOS32\_SYS\_STM\_PINSET(CS1\_PORT, CS1\_PIN, b) #define PIN\_CS2(b) MIOS32\_SYS\_STM\_PINSET(CS2\_PORT, CS2\_PIN, b) #define PIN\_CS3(b) MIOS32\_SYS\_STM\_PINSET(CS3\_PORT, CS3\_PIN, b) #define PIN\_CS4(b) MIOS32\_SYS\_STM\_PINSET(CS4\_PORT, CS4\_PIN, b) // you could define here more CS PINS! but be sure to deactivate the "Orginal" function of it... #define PIN\_SERLCD\_DATAOUT(b) MIOS32\_SYS\_STM\_PINSET(RW\_PORT, RW\_PIN, b) #define PIN\_SERLCD\_SCLK\_0 { MIOS32\_SYS\_STM\_PINSET\_0(E1\_PORT, E1\_PIN); MIOS32\_SYS\_STM\_PINSET\_0(E2\_PORT, E2\_PIN); } #define PIN\_SERLCD\_SCLK\_1 { MIOS32\_SYS\_STM\_PINSET\_1(E1\_PORT, E1\_PIN); MIOS32\_SYS\_STM\_PINSET\_1(E2\_PORT, E2\_PIN); } /// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// // PINS for Additonl LCD 4 & 5 DIPCORE if needet // MIOS32\_SYS\_STM\_PINSET(GPIOC, GPIO\_Pin\_13, data & 1); // J10B.D8 = ser // MIOS32\_SYS\_STM\_PINSET\_0(GPIOC, GPIO\_Pin\_14); // J10B.D9 = 0 (Clk) ////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////////////////////////////////////// // Initializes the Ports/Pins (aka J15) (which was once J15 in MIOS32\_BOARD.c but now integrated in this Program directly) /////////////////////////////////////////////////////////////////////////////////////////////////////////// s32 PortInit(u32 mode) { // configure push-pull pins GPIO\_InitTypeDef GPIO\_InitStructure; GPIO\_StructInit(&GPIO\_InitStructure); GPIO\_InitStructure.GPIO\_Mode = GPIO\_Mode\_OUT; GPIO\_InitStructure.GPIO\_OType = GPIO\_OType\_PP; GPIO\_InitStructure.GPIO\_Speed = GPIO\_Speed\_50MHz; // 25 is weak driver to reduce transients GPIO\_InitStructure.GPIO\_Pin = CS1\_PIN; GPIO\_Init(CS1\_PORT, &GPIO\_InitStructure); GPIO\_InitStructure.GPIO\_Pin = CS2\_PIN; GPIO\_Init(CS2\_PORT, &GPIO\_InitStructure); GPIO\_InitStructure.GPIO\_Pin = CS3\_PIN;// Extra CS-Lines GPIO\_Init(CS3\_PORT, &GPIO\_InitStructure); GPIO\_InitStructure.GPIO\_Pin = CS4\_PIN;// Extra CS-Lines GPIO\_Init(CS4\_PORT, &GPIO\_InitStructure); GPIO\_InitStructure.GPIO\_Pin = SER\_PIN; GPIO\_Init(SER\_PORT, &GPIO\_InitStructure); GPIO\_InitStructure.GPIO\_Pin = E1\_PIN; GPIO\_Init(E1\_PORT, &GPIO\_InitStructure); GPIO\_InitStructure.GPIO\_Pin = RW\_PIN; GPIO\_Init(RW\_PORT, &GPIO\_InitStructure); // Activate all CS Lines PIN\_CS1(0);// J15 CS1 Line PIN\_CS2(0);// J15 CS2 Line PIN\_CS3(0);// CS-Extra Line PIN\_CS4(0);// CS-Extra Line PIN\_RW(0); PIN\_E1(0); return 0; // no error } ///////////////////////////////////////////////////////////////////////////// // shift an 8bit data value to LCDs with serial interface //! (SCLK connected to J15A:E, Data line connected to J15A:RW) //! \param[in] data the 8bit value ///////////////////////////////////////////////////////////////////////////// s32 SerDataShift(u8 data) { MIOS32\_IRQ\_Disable(); int i; for(i=0; i\<8; ++i, data \<\<= 1) { PIN\_SERLCD\_DATAOUT(data & 0x80); PIN\_SERLCD\_SCLK\_0; PIN\_SERLCD\_SCLK\_0; PIN\_SERLCD\_SCLK\_1; PIN\_SERLCD\_SCLK\_1; } PIN\_SERLCD\_SCLK\_0; PIN\_SERLCD\_DATAOUT(0); MIOS32\_IRQ\_Enable(); return 0; // no error } ///////////////////////////////////////////////////////////////////////////// // to set the RS pin // \param[in] rs state of the RS pin ///////////////////////////////////////////////////////////////////////////// s32 RS\_Set(u8 rs) { PIN\_SER(rs);return 0; } ///////////////////////////////////////////////////////////////////////////// // Select a LCD / Select CS LINE ///////////////////////////////////////////////////////////////////////////// static s32 APP\_LCD\_SERGLCD\_CS\_Set(u8 value, u8 all){ // Activate ALL Screens @ once if( all ) { PIN\_CS1(0); PIN\_CS2(0); PIN\_CS3(0); PIN\_CS4(0);} else {switch (mios32\_lcd\_device) {case 0: PIN\_CS1(0);// the active Screen PIN\_CS2(1);// deactivate PIN\_CS3(1);// deactivate PIN\_CS4(1); break;// deactivate case 1: PIN\_CS1(1);// deactivate PIN\_CS2(0);// the active Screen PIN\_CS3(1);// deactivate PIN\_CS4(1); break;// deactivate case 2: PIN\_CS1(1);// deactivate PIN\_CS2(1);// deactivate PIN\_CS3(0);// the active Screen PIN\_CS4(1); break;// deactivate case 3: PIN\_CS1(1);// deactivate PIN\_CS2(1);// deactivate PIN\_CS3(1);// deactivate PIN\_CS4(0); break;// the active Screen break; } } return 0; // no error } ///////////////////////////////////////////////////////////////////////////// // Initializes LCD driver ///////////////////////////////////////////////////////////////////////////// s32 APP\_LCD\_Init(u32 mode){ PortInit(0); // Init the Ports & Pins (aka J15 + extra CS-Pins) // wait 500 mS to ensure that the reset is released { int i; for(i=0; i\<500; ++i) MIOS32\_DELAY\_Wait\_uS(1000);} // initialize LCDs APP\_LCD\_Cmd(0xa8); // Set MUX Ratio APP\_LCD\_Cmd(0x3f); APP\_LCD\_Cmd(0xd3); // Set Display Offset APP\_LCD\_Cmd(0x00); APP\_LCD\_Cmd(0x40); // Set Display Start Line APP\_LCD\_Cmd(0xa1);// Set Segment re-map: rotated APP\_LCD\_Cmd(0xc8);// Set COM Output Scan Direction: rotated APP\_LCD\_Cmd(0xda); // Set COM Pins hardware configuration APP\_LCD\_Cmd(0x12); APP\_LCD\_Cmd(0x81); // Set Contrast Control APP\_LCD\_Cmd(0x7f); // middle APP\_LCD\_Cmd(0xa4); // Disable Entiere Display On APP\_LCD\_Cmd(0xa6); // Set Normal Display APP\_LCD\_Cmd(0xd5); // Set OSC Frequency APP\_LCD\_Cmd(0x80); APP\_LCD\_Cmd(0x8d); // Enable charge pump regulator APP\_LCD\_Cmd(0x14); APP\_LCD\_Cmd(0xaf); // Display On APP\_LCD\_Cmd(0x20); // Enable Page mode APP\_LCD\_Cmd(0x02); return 0; } ///////////////////////////////////////////////////////////////////////////// // Sends data byte to LCD // IN: data byte in \<data\> ///////////////////////////////////////////////////////////////////////////// s32 APP\_LCD\_Data(u8 data){ APP\_LCD\_SERGLCD\_CS\_Set(1, 0); // RS pin used to control DC RS\_Set(1);//1: Data at D7 is treated as DISPLAY data, // written to Graphic Display Ram (GDDRAM) //0: Data at D7:0 is transfaired to the command register - treated as command // send data SerDataShift(data); // increment graphical cursor ++mios32\_lcd\_x; // if end of display segment reached: set X position of all segments to 0 if( mios32\_lcd\_x \>= 128 ) { APP\_LCD\_Cmd(0x00); // set X=0 APP\_LCD\_Cmd(0x10);} return 0; // no error } ///////////////////////////////////////////////////////////////////////////// // Sends data byte to LCD --- Specially for Solid Oscilloscope Waves // IN: data byte in \<data\> ///////////////////////////////////////////////////////////////////////////// s32 APP\_LCD\_SCOPE(u8 h, u8 v, u8 pix){ // h=x, v=y, pix is 0 or 1 to activate a single pixel APP\_LCD\_SERGLCD\_CS\_Set(1, 0); //mios32\_lcd\_x = h; //mios32\_lcd\_y = v; // RS pin used to control DC RS\_Set(1); // send data SerDataShift(pix); // increment graphical cursor // ++mios32\_lcd\_x; // if end of display segment reached: set X position of all segments to 0 //if( (mios32\_lcd\_x % mios32\_lcd\_parameters.width) == 0 ) { APP\_LCD\_Cmd(0x00); // set X=0 //APP\_LCD\_Cmd(0x10); } return 0; // no error } ///////////////////////////////////////////////////////////////////////////// // Sends command byte to LCD // IN: command byte in \<cmd\> // OUT: returns \< 0 if display not available or timed out ///////////////////////////////////////////////////////////////////////////// s32 APP\_LCD\_Cmd(u8 cmd){ APP\_LCD\_SERGLCD\_CS\_Set(1, 1);// select all LCDs RS\_Set(0);// RS pin used to control DC SerDataShift(cmd); return 0; } ///////////////////////////////////////////////////////////////////////////// // Clear Screen ///////////////////////////////////////////////////////////////////////////// s32 APP\_LCD\_Clear() { s32 error = 0; u8 x, y; // use default font MIOS32\_LCD\_FontInit((u8 \*)GLCD\_FONT\_NORMAL); // select all LCDs APP\_LCD\_SERGLCD\_CS\_Set(1, 1); // send data for(y=0; y\<mios32\_lcd\_parameters.height/8; ++y) { error |= MIOS32\_LCD\_CursorSet(0, y); RS\_Set(1); // RS pin used to control DC for(x=0; x\<mios32\_lcd\_parameters.width; ++x) SerDataShift(0x00); } // set X=0, Y=0 error |= MIOS32\_LCD\_CursorSet(0, 0); return 0; } ///////////////////////////////////////////////////////////////////////////// // Clear Screen --- Special Variant which clear only the current selected Screen ///////////////////////////////////////////////////////////////////////////// s32 LCD\_Clear(void) { s32 error = 0; u8 x, y; // Select the actually Selected LCD ONLY! APP\_LCD\_SERGLCD\_CS\_Set(1, 0); // send data for(y=0; y\<mios32\_lcd\_parameters.height/8; ++y) { error |= MIOS32\_LCD\_CursorSet(0, y); RS\_Set(1); // RS pin used to control DC for(x=0; x\<mios32\_lcd\_parameters.width; ++x) SerDataShift(0x00); } // set X=0, Y=0 error |= MIOS32\_LCD\_CursorSet(0, 0); return 0; } ///////////////////////////////////////////////////////////////////////////// // Sets cursor to given position // IN: \<column\> and \<line\> ///////////////////////////////////////////////////////////////////////////// s32 APP\_LCD\_CursorSet(u16 column, u16 line){ // mios32\_lcd\_x/y set by MIOS32\_LCD\_CursorSet() function return APP\_LCD\_GCursorSet(mios32\_lcd\_x, mios32\_lcd\_y); } ///////////////////////////////////////////////////////////////////////////// // Sets graphical cursor to given position // IN: \<x\> and \<y\> // OUT: returns \< 0 on errors ///////////////////////////////////////////////////////////////////////////// s32 APP\_LCD\_GCursorSet(u16 x, u16 y){ s32 error = 0; // set X position error |= APP\_LCD\_Cmd(0x00 | (x & 0xf)); error |= APP\_LCD\_Cmd(0x10 | ((x\>\>4) & 0xf)); // set Y position error |= APP\_LCD\_Cmd(0xb0 | ((y\>\>3) & 7)); return error; } ///////////////////////////////////////////////////////////////////////////// // Initializes a single special character // IN: character number (0-7) in \<num\>, pattern in \<table[8]\> // OUT: returns \< 0 on errors ///////////////////////////////////////////////////////////////////////////// s32 APP\_LCD\_SpecialCharInit(u8 num, u8 table[8]) { s32 i; // send character number APP\_LCD\_Cmd(((num&7)\<\<3) | 0x40); // send 8 data bytes for(i=0; i\<8; ++i)if( APP\_LCD\_Data(table[i]) \< 0 )return -1; // error during sending character // set cursor to original position return APP\_LCD\_CursorSet(mios32\_lcd\_column, mios32\_lcd\_line); } ///////////////////////////////////////////////////////////////////////////// // Sets the background colour // Only relevant for colour GLCDs ///////////////////////////////////////////////////////////////////////////// s32 APP\_LCD\_BColourSet(u32 rgb) {return -3; }// not supported ///////////////////////////////////////////////////////////////////////////// // Sets the foreground colour // Only relevant for colour GLCDs ///////////////////////////////////////////////////////////////////////////// s32 APP\_LCD\_FColourSet(u32 rgb) { return -3;}// not supported ///////////////////////////////////////////////////////////////////////////// // Sets a pixel in the bitmap // IN: bitmap, x/y position and colour value (value range depends on APP\_LCD\_COLOUR\_DEPTH) // OUT: returns \< 0 on errors ///////////////////////////////////////////////////////////////////////////// s32 APP\_LCD\_BitmapPixelSet(mios32\_lcd\_bitmap\_t bitmap, u16 x, u16 y, u32 colour) { if( x \>= bitmap.width || y \>= bitmap.height ) return -1; // pixel is outside bitmap // all GLCDs support the same bitmap scrambling u8 \*pixel = (u8 \*)&bitmap.memory[bitmap.line\_offset\*(y / 8) + x]; u8 mask = 1 \<\< (y % 8); \*pixel &= ~mask; if( colour ) \*pixel |= mask; return -3; // not supported } ///////////////////////////////////////////////////////////////////////////// // Transfers a Bitmap within given boundaries to the LCD // IN: bitmap // OUT: returns \< 0 on errors ///////////////////////////////////////////////////////////////////////////// s32 APP\_LCD\_BitmapPrint(mios32\_lcd\_bitmap\_t bitmap){ // abort if max. width reached if( mios32\_lcd\_x \>= mios32\_lcd\_parameters.width ) return -2; // all GLCDs support the same bitmap scrambling int line; int y\_lines = (bitmap.height \>\> 3); u16 initial\_x = mios32\_lcd\_x; u16 initial\_y = mios32\_lcd\_y; for(line=0; line\<y\_lines; ++line) {// calculate pointer to bitmap line u8 \*memory\_ptr = bitmap.memory + line \* bitmap.line\_offset; // set graphical cursor after second line has reached if( line \> 0 ) { mios32\_lcd\_x = initial\_x; mios32\_lcd\_y += 8; APP\_LCD\_GCursorSet(mios32\_lcd\_x, mios32\_lcd\_y); } // transfer character int x; for(x=0; x\<bitmap.width; ++x) APP\_LCD\_Data(\*memory\_ptr++); } // fix graphical cursor if more than one line has been print if( y\_lines \>= 1 ) { mios32\_lcd\_y = initial\_y; APP\_LCD\_GCursorSet(mios32\_lcd\_x, mios32\_lcd\_y); } return 0; // no error }

 

 

Thanks for the reply, thats a little beyond my scope messing with mios, I am good with the ng code structure. It is a shame that the MB_NG user manual section on hooking up the ssd displays was not updated in relation to the discovery boards.

The reference of using J28 being the older lpc17 MB and not relating to the discovery pcbs most are now using.

Perhaps it’s something could give us some info about when he has time to do so, I understand he is in here very little these days but hopefully, this is one of the outstanding issues that can be resolved.

 

Thanks again for your help both most appreciated