MCUFRIEND_kbv - Reassignment of Control and Digital Pins

David,

Thank you for your help last time in applying your code to the ST7789v to the 240x320 display (KD024QVRMA041) with an Atmega1284p. I've been successful in getting it to work using an 8-bit setup by translating the original Uno/Shield pins to where they're located on the Crossroads 1284MINI. Board setup is MightyCore 1284 (Bobuino) at 3v3 with 16mhz ext xtal.

For the purpose of my project and making a custom PCB, I need to reassign the display pins. I've been reading through your code files to try and understand how the original assignments are done and can use your help. Again, while I'm comfortable with a certain degree of coding, I still have a lot to learn.

From what I can tell (and I'm probably way off :slight_smile: ) the assignments for the Control and Data pins are made in "mcufriend_shield.h". Specifically for my setup the section "UNO SHIELD on BOBUINO" seems to be where the assignments are made. Is that correct?

Thanks and Very much appreciated.

Yes. It is easy to re-assign control pins to different port and bit.

It is the data bus that becomes hairy when it uses random ports and pins.

David.

Easy is a relative term!! :slight_smile: Going to first try just the control pin reassignments.

I found a similar question in another post that you had responded. https://forum.arduino.cc/index.php?topic=507694.0

I gave it a try taking from what you provided in that post, but couldn’t get it working. Here is the control pin assignments I’d like to have.

sketch code

// Custom Digital Connections
#define USE_CUSTOM
#define LCD_RD 25     //CROSSROADS D25 (PC3)
#define LCD_WR 26    //CROSSROADS D26 (PC4)
#define LCD_CD 27    //CROSSROADS D27 (PC5)
#define LCD_CS 28     //CROSSROADS D28 (PC6)
#define LCD_RESET 29[u][/u]  //CROSSROADS D29 (PC7)

Here’s what I added in mcufriend_shield.h:

//################################### CUSTOM SETUP USING BOBUINO DIGITAL #############
#elif defined(__AVR_ATmega1284P__) && defined(USE_CUSTOM)
#warning using USE_CUSTOM
#define RD_PORT PORTC  //PC3 is CROSSROADS 1284MINI - D25
#define RD_PIN  3
#define WR_PORT PORTC  //PC4 is CROSSROADS 1284MINI - D26
#define WR_PIN  4
#define CD_PORT PORTC  //PC5 is CROSSROADS 1284MINI - D27
#define CD_PIN  5
#define CS_PORT PORTC  //PC6 is CROSSROADS 1284MINI - D28
#define CS_PIN  6
#define RESET_PORT PORTC //PC7 is CROSSROADS 1284MINI - D29
#define RESET_PIN  7

//THIS SECTION IS UNCHANGED FROM THE BOBUINO CODE
#define BMASK         0x0F              //
#define DMASK         0x6C              //
#define write_8(x)    { PORTB = (PORTB & ~BMASK) | ((x) >> 4); \
        PORTD = (PORTD & ~DMASK) | ((x) & 0x0C) | (((x) & 0x03) << 5); }
#define read_8()      ( (PINB << 4) | (PIND & 0x0C) | ((PIND & 0x60) >> 5) )
#define setWriteDir() { DDRB |=  BMASK; DDRD |=  DMASK; }
#define setReadDir()  { DDRB &= ~BMASK; DDRD &= ~DMASK; }
#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)        (p) &= ~(1<<(b))
#define PIN_HIGH(p, b)       (p) |= (1<<(b))
#define PIN_OUTPUT(p, b)     *(&p-1) |= (1<<(b))

What am I doing wrong?

Thanks!

GOT IT... well at least the control pins. Forgot to put the "D" in front of the pins.

// Custom Digital Connections
#define LCD_RD D25     //D25 CROSSROADS
#define LCD_WR D26     //D26 CROSSROADS
#define LCD_CD D27     //D27 CROSSROADS
#define LCD_CS D28     //D28 CROSSROADS
#define LCD_RESET D29  //D29 CROSSROADS

NEXT DIGITAL reassignment! This'll be fun!

David,

The ADC pins were fairly straight forward; however, I'm going to need help with the Digital pin reassignment. Here's the assignment I'd like to have:

D0 > PC2
D1 > PD7
D2 > PD6
D3 > PD5
D4 > PD4
D5 > PD3
D6 > PD1
D7 > PD0

How do I approach this?

Thanks so much!

No, you should look up the relevant PORT and PIN e.g.

#define RD_PORT PORTA
#define RD_PIN  7
#define WR_PORT PORTA
#define WR_PIN  6
#define CD_PORT PORTA
#define CD_PIN  5
#define CS_PORT PORTA
#define CS_PIN  4
#define RESET_PORT PORTA
#define RESET_PIN  3

Your choice of data pins is PAINFUL. If you are using PD0-PD1, PD3-PD7, PC2 it would be wise to use PD0 for LCD_D0, PD1 for LCD_D1, PC2 for LCD_D2, ...

David.

Pardon… I’ve been successful in the control pin assignment and did put the following in the mcufriend_shield.h file. For some reason I couldn’t get it to work in the mcufriend_special.h, so I just edited the shield.h file directly.

#define RD_PORT PORTC
#define RD_PIN  3
#define WR_PORT PORTC
#define WR_PIN 	4
#define CD_PORT PORTC
#define CD_PIN  5
#define CS_PORT PORTC
#define CS_PIN  6
#define RESET_PORT PORTC
#define RESET_PIN  7

The sketch code is what I was showing. I don’t think I was clear about how all I got it to work.

Moving on to the Digital Pin assignments.

David,

Taking a closer look at your data assignments, the only pin that I think is causing a serial upload issue is D2 to PD1 (TXD0). Is it easier to just re-assign this to another pin? say, PD4 ? I'm getting 'avrdude' sync errors and am guessing the TXD0 assignment is causing that issue?

Current MCUFRIEND_kbv assignments:
D0 > PD6
D1 > PD5
D2 > PD1 change to PD4
D3 > PD3
D4 > PB0
D5 > PB1
D6 > PB2
D7 > PB3

Make your mind up for the choice of pins for the data bus.

Life is easiest (and most efficient) with a single PORT e.g. PORTC if you don't use JTAG
mixing two PORTs is ok if you line the bits up. e.g. Uno has DB0, DB1 on PB0, PB1 with DB2-DB7 on PD2-PD7.

Random pins on random ports "works" but is SLOW. THat is why the Mega2560 does not work very well.

David.

david_prentice:
Make your mind up for the choice of pins for the data bus.

Life is easiest (and most efficient) with a single PORT e.g. PORTC if you don't use JTAG
mixing two PORTs is ok if you line the bits up. e.g. Uno has DB0, DB1 on PB0, PB1 with DB2-DB7 on PD2-PD7.

Random pins on random ports "works" but is SLOW. THat is why the Mega2560 does not work very well.

David.

Yeah, I did change my mind :frowning: sorry about that. Thank you for the information on efficiency. I hadn't realized the random bits would be slow, but it does make sense.

Kinda figured a single PORT would be easier for the 8 data bits, but wasn't sure. Chock it up to inexperience on my part. Didn't mean to vacillate and especially didn't want to be a burden on your time.

Here were my thoughts on using a single PORT:
PORTA - Not good as this provides the ADC's I need for the range of sensors the project is using.
PORTB - Good candidate, but don't know if it'll interfere with the ICSP Uploading process?
PORTC - Almost, but need SCL/SDA for I2C interface with sensors and TouchScreen
PORTD - Almost, but need RXD/TXD for Serial interface

Based on what you're saying then it seems like one of two approaches might be the most efficient:

  1. Reassign D2 and use 4 consecutive bits in each of PORTB (0-3) and PORTD (3-6)
  2. Reassign all 8 bits to consecutive in PORTB (0-7) -> IF it won't conflict with ICSP Uploading

I can work with either of these two approaches on the PCB... whichever is easier for you would be greatly appreciated!

Again, thanks for all the information and assistance! I'm much better at designing PCBs and electronic circuits than I am at the MCU interface coding.