MCUFRIEND 2.8 inch shield, with NUCLEO-STM32G071

Hi. I have a MCUFRIEND 2.8 inch LCD shield with the ILI9341 that I have used
in the past, but now I want to use it with my newer NUCLEO-STM32G071 board.
I noticed that the G071 is not supported so I began to look into changing the
macro definitions to make it work.

I have gotten this far, and have included my work below, but I thing I'm stuck in the weeds and would appreciated anyone with detailed knowledge to find out what else do I have to edit.

David Prentice comes to mind, he's always providing solutions.

Also sorry for the dump of macro code, but I'm still trying to work out how to format this.

Thanks.
kv.

#define WR_ACTIVE2 {WR_ACTIVE; WR_ACTIVE;}
#define WR_ACTIVE4 {WR_ACTIVE2; WR_ACTIVE2;}
#define WR_ACTIVE8 {WR_ACTIVE4; WR_ACTIVE4;}
#define RD_ACTIVE2 {RD_ACTIVE; RD_ACTIVE;}
#define RD_ACTIVE4 {RD_ACTIVE2; RD_ACTIVE2;}
#define RD_ACTIVE8 {RD_ACTIVE4; RD_ACTIVE4;}
#define RD_ACTIVE16 {RD_ACTIVE8; RD_ACTIVE8;}
#define WR_IDLE2 {WR_IDLE; WR_IDLE;}
#define WR_IDLE4 {WR_IDLE2; WR_IDLE2;}
#define RD_IDLE2 {RD_IDLE; RD_IDLE;}
#define RD_IDLE4 {RD_IDLE2; RD_IDLE2;}

#define REGS(x) x
#define PIN_HIGH(port, pin) (port)-> REGS(BSRR) = (1<<(pin))
#define PIN_LOW(port, pin) (port)-> REGS(BSRR) = (1<<((pin)+16))
#define PIN_MODE2(reg, pin, mode) reg=(reg&~(0x3<<((pin)<<1)))|(mode<<((pin)<<1))
#define GROUP_MODE(port, reg, mask, val) {port->REGS(reg) = (port->REGS(reg) & ~(mask)) | ((mask)&(val)); }

// mod this for starters STM32F091xC
#define WRITE_DELAY { }
#define READ_DELAY { RD_ACTIVE; }
#define GPIO_INIT() { RCC->AHBENR |= RCC_IOPENR_GPIOAEN | RCC_IOPENR_GPIOBEN | RCC_IOPENR_GPIOCEN; }
#define PIN_OUTPUT(port, pin) PIN_MODE2((port)->MODER, pin, 0x1)

// Uno Shield on NUCLEO-64 STM32G071
#define RD_PORT GPIOA //PA0
#define RD_PIN 0
#define WR_PORT GPIOA //PA1
#define WR_PIN 1
#define CD_PORT GPIOA //PA4
#define CD_PIN 4
#define CS_PORT GPIOB //PB1
#define CS_PIN 1
#define RESET_PORT GPIOB //PB11
#define RESET_PIN 11

#define AMASK ((1<<9)|(1<<10)|(1<<8)) // Data Bus bit positions: #0, #2, #7
#define BMASK ((1<<3)|(1<<5)|(1<<4)|(1<<14)) // Data Bus bit positions: #3, #4, #5, #6
#define CMASK ((1<<7)) // Data Bus bit positions: #1

#define write_8(d) {
GPIOA->REGS(BSRR) = AMASK << 16;
GPIOB->REGS(BSRR) = BMASK << 16;
GPIOC->REGS(BSRR) = CMASK << 16;
GPIOA->REGS(BSRR) = ( ((d) & (1<<0)) << 9)
| (((d) & (1<<2)) << 8)
| (((d) & (1<<7)) << 1);
GPIOB->REGS(BSRR) = ( ((d) & (1<<3)) << 0)
| (((d) & (1<<4)) << 1)
| (((d) & (1<<5)) >> 1)
| (((d) & (1<<6)) << 8);
GPIOC->REGS(BSRR) = ( ((d) & (1<<1)) << 6);
}

#define read_8() ( ( ( (GPIOA->REGS(IDR) & (1<<9)) >> 9)
| ((GPIOC->REGS(IDR) & (1<<7)) >> 6)
| ((GPIOA->REGS(IDR) & (1<<10)) >> 8)
| ((GPIOB->REGS(IDR) & (1<<3)) >> 0)
| ((GPIOB->REGS(IDR) & (1<<5)) >> 1)
| ((GPIOB->REGS(IDR) & (1<<4)) << 1)
| ((GPIOB->REGS(IDR) & (1<<14)) >> 8)
| ((GPIOA->REGS(IDR) & (1<<8)) >> 1)))

#define setWriteDir() { setReadDir();
GPIOA->MODER |= 0x150000; GPIOB->MODER |= 0x10000540; GPIOC->MODER |= 0x4000; }
#define setReadDir() { GPIOA->MODER &= ~0x3F0000; GPIOB->MODER &= ~0x30000fc0; GPIOC->MODER &= ~0xC000; }

#ifndef IDLE_DELAY
#define IDLE_DELAY { WR_IDLE; }
#endif

#define write8(x) { write_8(x); WRITE_DELAY; WR_STROBE; IDLE_DELAY; }
#define write16(x) { uint8_t h = (x)>>8, l = x; write8(h); write8(l); }
#define READ_8(dst) { RD_STROBE; READ_DELAY; dst = read_8(); RD_IDLE2; RD_IDLE; }
#define READ_16(dst) { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); }

#define RD_ACTIVE PIN_LOW(RD_PORT, RD_PIN)
#define RD_IDLE PIN_HIGH(RD_PORT, RD_PIN)
#define RD_OUTPUT PIN_OUTPUT(RD_PORT, RD_PIN)
#define WR_ACTIVE PIN_LOW(WR_PORT, WR_PIN)
#define WR_IDLE PIN_HIGH(WR_PORT, WR_PIN)
#define WR_OUTPUT PIN_OUTPUT(WR_PORT, WR_PIN)
#define CD_COMMAND PIN_LOW(CD_PORT, CD_PIN)
#define CD_DATA PIN_HIGH(CD_PORT, CD_PIN)
#define CD_OUTPUT PIN_OUTPUT(CD_PORT, CD_PIN)
#define CS_ACTIVE PIN_LOW(CS_PORT, CS_PIN)
#define CS_IDLE PIN_HIGH(CS_PORT, CS_PIN)
#define CS_OUTPUT PIN_OUTPUT(CS_PORT, CS_PIN)
#define RESET_ACTIVE PIN_LOW(RESET_PORT, RESET_PIN)
#define RESET_IDLE PIN_HIGH(RESET_PORT, RESET_PIN)
#define RESET_OUTPUT PIN_OUTPUT(RESET_PORT, RESET_PIN)

// General macros. IOCLR registers are 1 cycle when optimised.
#define WR_STROBE { WR_ACTIVE; WR_IDLE; } //PWLW=TWRL=50ns
#define RD_STROBE RD_IDLE, RD_ACTIVE, RD_ACTIVE, RD_ACTIVE //PWLR=TRDL=150ns, tDDR=100ns

#if !defined(GPIO_INIT)
#define GPIO_INIT()
#endif
#define CTL_INIT() { GPIO_INIT(); RD_OUTPUT; WR_OUTPUT; CD_OUTPUT; CS_OUTPUT; RESET_OUTPUT; }
#define WriteCmd(x) { CD_COMMAND; write16(x); CD_DATA; }
#define WriteData(x) { write16(x); }Use code tags to format code for the forum

I'm not going to make any attempt to make heads or tails out of that unformatted block of text. There's a perfectly code <CODE/> tool in the message composition toolbar.

All I will say is that the Q&D way is to add an #else block at the end of the various board blocks in mcufriend_shield.h that uses bog standard Arduino I/O. It'll be slower than molasses in winter, but it'll give you something to build on.

Replace:

//############################# END OF BLOCKS ############################
#else
#error MCU unsupported
#endif  

with

//############################# END OF BLOCKS ############################
#else
// Try to use the standard Arduino commands - test code for Renesas
//LCD pins  |D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 | |RD |WR |RS |CS |RST|
//AVR   pin |PD7|PD6|PD5|PD4|PD3|PD2|PB1|PB0| |PC0|PC1|PC2|PC3|PC4|
//UNO pins  |7  |6  |5  |4  |3  |2  |9  |8  | |A0 |A1 |A2 |A3 |A4 |

#define RD_PORT 0
#define RD_PIN  A0
#define WR_PORT 0
#define WR_PIN  A1
#define CD_PORT 0
#define CD_PIN  A2
#define CS_PORT 0
#define CS_PIN  A3
#define RESET_PORT 0
#define RESET_PIN  A4

#define write_8(x)    { digitalWrite(8, (x&0b00000001)); \
                        digitalWrite(9, (x&0b00000010)>>1); \
                        digitalWrite(2, (x&0b00000100)>>2); \
                        digitalWrite(3, (x&0b00001000)>>3); \
                        digitalWrite(4, (x&0b00010000)>>4); \
                        digitalWrite(5, (x&0b00100000)>>5); \
                        digitalWrite(6, (x&0b01000000)>>6); \
                        digitalWrite(7, (x&0b10000000)>>7); \
                       }

#define read_8()      ( digitalRead(8)|(digitalRead(9)<<1)|(digitalRead(2)<<2)|(digitalRead(3)<<3)|(digitalRead(4)<<4)| \
                        (digitalRead(5)<<5)|(digitalRead(6)<<6)|(digitalRead(7)<<7) )

#define setWriteDir() { pinMode(8, OUTPUT);  pinMode(9, OUTPUT); pinMode(2, OUTPUT);  pinMode(3, OUTPUT); \
                        pinMode(4, OUTPUT);  pinMode(5, OUTPUT); pinMode(6, OUTPUT);  pinMode(7, OUTPUT); } 
#define setReadDir()  { pinMode(8, INPUT);  pinMode(9, INPUT); pinMode(2, INPUT);  pinMode(3, INPUT); \
                        pinMode(4, INPUT);  pinMode(5, INPUT); pinMode(6, INPUT);  pinMode(7, INPUT); }  

#define write8(x)     { write_8(x); WR_STROBE; }
#define write16(x)    { uint8_t h = (x)>>8, l = x; write8(h); write8(l); }
#define READ_8(dst)   { RD_STROBE; dst = read_8(); RD_IDLE; }
#define READ_16(dst)  { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); }

#define PIN_LOW(p, b) digitalWrite(b, 0) 
#define PIN_HIGH(p, b) digitalWrite(b, 1)
#define PIN_OUTPUT(p, b) pinMode(b, OUTPUT)
#endif  

See how much easier code is to read and copy when you use the <CODE/> tool?

Oh, and apparently David Prentice is no longer with us IIRC.

#define WR_ACTIVE2  {WR_ACTIVE; WR_ACTIVE;}
#define WR_ACTIVE4  {WR_ACTIVE2; WR_ACTIVE2;}
#define WR_ACTIVE8  {WR_ACTIVE4; WR_ACTIVE4;}
#define RD_ACTIVE2  {RD_ACTIVE; RD_ACTIVE;}
#define RD_ACTIVE4  {RD_ACTIVE2; RD_ACTIVE2;}
#define RD_ACTIVE8  {RD_ACTIVE4; RD_ACTIVE4;}
#define RD_ACTIVE16 {RD_ACTIVE8; RD_ACTIVE8;}
#define WR_IDLE2  {WR_IDLE; WR_IDLE;}
#define WR_IDLE4  {WR_IDLE2; WR_IDLE2;}
#define RD_IDLE2  {RD_IDLE; RD_IDLE;}
#define RD_IDLE4  {RD_IDLE2; RD_IDLE2;}

#define REGS(x) x
#define PIN_HIGH(port, pin)   (port)-> REGS(BSRR) = (1<<(pin))
#define PIN_LOW(port, pin)    (port)-> REGS(BSRR) = (1<<((pin)+16))
#define PIN_MODE2(reg, pin, mode) reg=(reg&~(0x3<<((pin)<<1)))|(mode<<((pin)<<1))
#define GROUP_MODE(port, reg, mask, val)  {port->REGS(reg) = (port->REGS(reg) & ~(mask)) | ((mask)&(val)); }


// mod this for starters STM32F091xC
#define WRITE_DELAY { }
#define READ_DELAY  { RD_ACTIVE; }
#define GPIO_INIT()   { RCC->AHBENR |= RCC_IOPENR_GPIOAEN | RCC_IOPENR_GPIOBEN | RCC_IOPENR_GPIOCEN; }
#define PIN_OUTPUT(port, pin) PIN_MODE2((port)->MODER, pin, 0x1)


// Uno Shield on NUCLEO-64 STM32G071
#define RD_PORT GPIOA    //PA0
#define RD_PIN  0
#define WR_PORT GPIOA    //PA1
#define WR_PIN  1
#define CD_PORT GPIOA    //PA4
#define CD_PIN  4
#define CS_PORT GPIOB    //PB1
#define CS_PIN  1
#define RESET_PORT GPIOB //PB11
#define RESET_PIN  11

#define AMASK ((1<<9)|(1<<10)|(1<<8))        // Data Bus bit positions: #0, #2, #7
#define BMASK ((1<<3)|(1<<5)|(1<<4)|(1<<14)) // Data Bus bit positions: #3, #4, #5, #6
#define CMASK ((1<<7))                       // Data Bus bit positions: #1

#define write_8(d) { \
        GPIOA->REGS(BSRR) = AMASK << 16; \
        GPIOB->REGS(BSRR) = BMASK << 16; \
        GPIOC->REGS(BSRR) = CMASK << 16; \
        GPIOA->REGS(BSRR) = (  ((d) & (1<<0)) << 9) \
                            | (((d) & (1<<2)) << 8) \
                            | (((d) & (1<<7)) << 1); \
        GPIOB->REGS(BSRR) = (  ((d) & (1<<3)) << 0) \
                            | (((d) & (1<<4)) << 1) \
                            | (((d) & (1<<5)) >> 1) \
                            | (((d) & (1<<6)) << 8); \
        GPIOC->REGS(BSRR) = (  ((d) & (1<<1)) << 6); \
    }

#define read_8() (       (  (  (GPIOA->REGS(IDR) & (1<<9)) >> 9) \
                            | ((GPIOC->REGS(IDR) & (1<<7)) >> 6) \
                            | ((GPIOA->REGS(IDR) & (1<<10)) >> 8) \
                            | ((GPIOB->REGS(IDR) & (1<<3)) >> 0) \
                            | ((GPIOB->REGS(IDR) & (1<<5)) >> 1) \
                            | ((GPIOB->REGS(IDR) & (1<<4)) << 1) \
                            | ((GPIOB->REGS(IDR) & (1<<14)) >> 8) \
                            | ((GPIOA->REGS(IDR) & (1<<8))  >> 1)))

#define setWriteDir() { setReadDir(); \
                        GPIOA->MODER |=  0x150000; GPIOB->MODER |=  0x10000540; GPIOC->MODER |=  0x4000; }
#define setReadDir()  { GPIOA->MODER &= ~0x3F0000; GPIOB->MODER &= ~0x30000fc0; GPIOC->MODER &= ~0xC000; }



#ifndef IDLE_DELAY
#define IDLE_DELAY    { WR_IDLE; }
#endif

#define write8(x)     { write_8(x); WRITE_DELAY; WR_STROBE; IDLE_DELAY; }
#define write16(x)    { uint8_t h = (x)>>8, l = x; write8(h); write8(l); }
#define READ_8(dst)   { RD_STROBE; READ_DELAY; dst = read_8(); RD_IDLE2; RD_IDLE; }
#define READ_16(dst)  { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); }

#define RD_ACTIVE  PIN_LOW(RD_PORT, RD_PIN)
#define RD_IDLE    PIN_HIGH(RD_PORT, RD_PIN)
#define RD_OUTPUT  PIN_OUTPUT(RD_PORT, RD_PIN)
#define WR_ACTIVE  PIN_LOW(WR_PORT, WR_PIN)
#define WR_IDLE    PIN_HIGH(WR_PORT, WR_PIN)
#define WR_OUTPUT  PIN_OUTPUT(WR_PORT, WR_PIN)
#define CD_COMMAND PIN_LOW(CD_PORT, CD_PIN)
#define CD_DATA    PIN_HIGH(CD_PORT, CD_PIN)
#define CD_OUTPUT  PIN_OUTPUT(CD_PORT, CD_PIN)
#define CS_ACTIVE  PIN_LOW(CS_PORT, CS_PIN)
#define CS_IDLE    PIN_HIGH(CS_PORT, CS_PIN)
#define CS_OUTPUT  PIN_OUTPUT(CS_PORT, CS_PIN)
#define RESET_ACTIVE  PIN_LOW(RESET_PORT, RESET_PIN)
#define RESET_IDLE    PIN_HIGH(RESET_PORT, RESET_PIN)
#define RESET_OUTPUT  PIN_OUTPUT(RESET_PORT, RESET_PIN)

 // General macros.   IOCLR registers are 1 cycle when optimised.
#define WR_STROBE { WR_ACTIVE; WR_IDLE; }       //PWLW=TWRL=50ns
#define RD_STROBE RD_IDLE, RD_ACTIVE, RD_ACTIVE, RD_ACTIVE      //PWLR=TRDL=150ns, tDDR=100ns

#if !defined(GPIO_INIT)
#define GPIO_INIT()
#endif
#define CTL_INIT()   { GPIO_INIT(); RD_OUTPUT; WR_OUTPUT; CD_OUTPUT; CS_OUTPUT; RESET_OUTPUT; }
#define WriteCmd(x)  { CD_COMMAND; write16(x); CD_DATA; }
#define WriteData(x) { write16(x); }

Hi van_der_decken, the G071 only has one pin different. PB14 instead of PB10.
Also the control pins are very easy to change, but I'm sure there's something I'm overlooking, probably something about the STM32 I don't know?? maybe?
Also I'm using ST Cube IDE.
Thanks.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.