Atmega 1284p and TFT 3.5" Screen

I´m planning to use a standar 3.5" Touch TFT LCD Shield 480x320 with a Atmega1284p (Mightycore and standar pinout) (on a breadboard) with the aim of creating a control panel for a smal injection moulding machine.

I´m aware that other people have experienced issues with Adafruit_GFX.h, MCUFRIEND_kbv.h and TouchScreen.h mainly because those libraries were intended for the Atmega328p. Has anyone had any luck getting this screens to work? Or should I use a standar LCD 20x4 to reduce the complexity?

I also read in others posts that using the bobduino pinout could probably work? Is that feasible?

Since MCUFRIEND_bkv already has a section supporting the 1284, as long as you observe the pin mappings it uses, you shouldn't have any major problems.

#elif defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644P__) //UNO shield on BOBUINO
#warning regular UNO shield on BOBUINO

//LCD pins  |D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 | |RD |WR |RS |CS |RST|
//AVR   pin |PB3|PB2|PB1|PB0|PD3|PD2|PD6|PD5| |PA7|PA6|PA5|PA4|PA3|

#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

#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))

THANKSS. I tested right now using the Bobuino pin distribution that MightyCore includes and that allowed me to run graphictest_kbv without issues. I´ll se what problems does the touchscreen.h throw at me in a few minutes. I will also test using the standar pin mappings just to confirm it works.

So, the next issue I encountered is this error when compiling the button_simple file in MCUFRIEND_kbv.

\Adafruit_TouchScreen\TouchScreen.cpp: In constructor 'TouchScreen::TouchScreen(uint8_t, uint8_t, uint8_t, uint8_t, uint16_t)':

AppData\Local\Arduino15\packages\MightyCore\hardware\avr\3.0.3\cores\MCUdude_corefiles/Arduino.h:218:97: error: cannot convert 'volatile uint8_t* {aka volatile unsigned char*}' to 'RwReg* {aka volatile long unsigned int*}' in assignment
 #define portOutputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_output_PGM + (P))) )
                                                                                                 ^
Documents\Arduino\libraries\Adafruit_TouchScreen\TouchScreen.cpp:205:13: note: in expansion of macro 'portOutputRegister'
   xp_port = portOutputRegister(digitalPinToPort(_xp));
             ^~~~~~~~~~~~~~~~~~
\Local\Arduino15\packages\MightyCore\hardware\avr\3.0.3\cores\MCUdude_corefiles/Arduino.h:218:97: error: cannot convert 'volatile uint8_t* {aka volatile unsigned char*}' to 'RwReg* {aka volatile long unsigned int*}' in assignment
 #define portOutputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_output_PGM + (P))) )
                                                                                                 ^
Documents\Arduino\libraries\Adafruit_TouchScreen\TouchScreen.cpp:206:13: note: in expansion of macro 'portOutputRegister'
   yp_port = portOutputRegister(digitalPinToPort(_yp));
             ^~~~~~~~~~~~~~~~~~
AppData\Local\Arduino15\packages\MightyCore\hardware\avr\3.0.3\cores\MCUdude_corefiles/Arduino.h:218:97: error: cannot convert 'volatile uint8_t* {aka volatile unsigned char*}' to 'RwReg* {aka volatile long unsigned int*}' in assignment
 #define portOutputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_output_PGM + (P))) )
                                                                                                 ^
Documents\Arduino\libraries\Adafruit_TouchScreen\TouchScreen.cpp:207:13: note: in expansion of macro 'portOutputRegister'
   xm_port = portOutputRegister(digitalPinToPort(_xm));
             ^~~~~~~~~~~~~~~~~~
AppData\Local\Arduino15\packages\MightyCore\hardware\avr\3.0.3\cores\MCUdude_corefiles/Arduino.h:218:97: error: cannot convert 'volatile uint8_t* {aka volatile unsigned char*}' to 'RwReg* {aka volatile long unsigned int*}' in assignment
 #define portOutputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_output_PGM + (P))) )
                                                                                                 ^
Documents\Arduino\libraries\Adafruit_TouchScreen\TouchScreen.cpp:208:13: note: in expansion of macro 'portOutputRegister'
   ym_port = portOutputRegister(digitalPinToPort(_ym));
             ^~~~~~~~~~~~~~~~~~

exit status 1

Compilation error: exit status 1

I assume this is related to using the port registers for the Atmega328p which are different from the ones in the Atmega1284p. I imagine it is required to modify the library directly to change the way those pins are put to a particular state.

I asked ChatGPT (I know, just to see if something usefully is provided) and it gave me the following answer:

"The Adafruit_TouchScreen library was originally written for Arduino AVR boards using the standard core (like the one used for the official Arduino Uno). It uses the RwReg* type internally, which is defined on 32-bit platforms (like SAM or SAMD) — not 8-bit AVR.

But in your case, you're compiling with MightyCore, and the Arduino core files define portOutputRegister(...) as a pointer to uint8_t, not RwReg (which is typically uint32_t or uint16_t)."

It kind of makes sense to me, although I´m still learning about this topics related to AVR programming. Further down the generated answer I get this:

"If you must use MightyCore, you can patch the TouchScreen.cpp file:

Find the lines like:

RwReg *xp_port = portOutputRegister(digitalPinToPort(_xp));

Replace RwReg * with volatile uint8_t *, like so:

volatile uint8_t *xp_port = portOutputRegister(digitalPinToPort(_xp));

Do the same for yp_port, xm_port, and ym_port.

This makes it compatible with the 8-bit AVR core MightyCore uses.

⚠️ Make sure to also check the TouchScreen.h file if RwReg is declared there too — you may need to replace other instances. "

Is it reasonable for me to make another library and make those changes? This AI even provides the corrected code so I can copy and paste, but it seems too easy to be the real solution.

Well just for the sake of it I tried making the new library replacing touchscreen.h and to my surprise the code compiled and uploaded successfully. If it is of any use here they are the two files generated by ChatGPT, beware they may actually be trash, I will test them right away.

TouchScreen.cpp (2.6 KB)
TouchScreen.h (903 Bytes)

Well it seems that the screen is unresponsive. I tried running TouchScreen_Calibr_native and it actually detects when I touch the screen, so I know the library fix actually did something. I noticed that for the first crosshair of the test (top left) I need to press to the other side (bottom right) for it to continue. The rest of the crosshairs are detected If I press over them. Perhaps it just requires changing those TS_LEFT, TS_RT, TS_TOP and TS_BOT values? Or maybe swap them here in the button_simple test code?

if (pressed) {
        pixel_x = map(p.x, TS_LEFT, TS_RT, 0, tft.width()); //.kbv makes sense to me
        pixel_y = map(p.y, TS_TOP, TS_BOT, 0, tft.height());
    }

SOLVED Atmega1284p and TFT 3.5" Touchscreen Work As Expected.

After several hours of trial and error I actually found out what was the root of the issue.

Firstly, to make pin assignment easy I recommend everyone to switch the pinout for the Atmega1284p to bobuino, which is provided by Mightycore. Using the diagram found on its git hub make the connections MCU to Shield taking into account which pins are the equivalent to the uno (the bobuino arranges everything so the pins on the 1248p are now compatible to most of the common arduino libraries). Having the correct connections will allow you to use the MCUFRIEND and Adafruit GFX, but not adafruit´s touchscreen.

To make touchscreen work it is necessary to modify it. This library expects the analog pins of the 1284p provided by Mightycore to be stated as A0,A1,A2, etc and not as digital pins 24, 25, etc. This generates an error where it is not using correct analog pin constants in the constructor TouchScreen(XP, YP, XM, YM, RX). Which causes USE_FAST_PINIO to have its port pins incorrectly assigned.

At least that´s my theory of the origin of the issue, I´m probably missing something but I´m sure my solutions works.

First, you´ll need the modded version of the library I made with some help of ChatGPT (I know I know, but I ran out of options). They should be attached to this post. The main change is a slight tweak on the header file that allows the identification of the 1284p and in the main file it removes completely the use of FAST PINIO. Some comments on the original library would probably make more sense, but I´m thinking about that just now. I just deleted the original library from my lib folder and pasted the new folder with the two files.

Make sure your hardware is well connected, it is not necessary to power at the same time 3V and 5V. With 5V is enough for both the screen and the touchscreen to work. Also, you can leave the SD pins alone for this purpose. I have tested uploading the code using a USBasp and an Arduino UNO board (without the IC) so i can debug using the serial monitor and both work.
library.properties.txt (334 Bytes)
TouchScreen.cpp (4.0 KB)
TouchScreen.h (804 Bytes)

I´ll add the testing file I used with the two buttons so you can confirm it works.
Cal_Test_Vertical_Working.ino (2.5 KB)

Proof this thing works:

I hope this was not me just going in circles around a problem I made. In the best case someone will find this post usefully and may save themselves a bad headache.

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