Working on Atmega328P but not on Atmega1284

Good day,

I am building a project which uses a touchscreen including icons and other logica. On the Atmega 328P it uses already 99% of the flash memory, since i need more code than what it is now i am using an Atmega 1284 now.

I managed to install the bootloader and want to compile my code which works on the Atmega328P but i get the next error:

program.ino:302:11: warning: suggest parentheses around assignment used as truth value [-Wparentheses]

   while(c = pgm_read_byte(str++)) Serial.print(c);

           ^

What can cause this error? Does the Atmega328P support other things than the Atmega1284?

The code which is executed here is:

void progmemPrint(const char *str) {
  char c;
  while(c = pgm_read_byte(str++)) Serial.print(c);
}

Thanks for the help and a good 202!

while(c = pgm_read_byte(str++)) Serial.print(c);

Do you want to assign a value to c or test its value ?

To be honest, i have no idea, the code comes from the example of the MCUfriend display:

#define BUFFPIXEL      20
uint8_t showBMP(char *filename, int x, int y)
{
  File     bmpFile;
  int      bmpWidth, bmpHeight;   // W+H in pixels
  uint8_t  bmpDepth;              // Bit depth (currently must be 24)
  uint32_t bmpImageoffset;        // Start of image data in file
  uint32_t rowSize;               // Not always = bmpWidth; may have padding
  uint8_t  sdbuffer[3*BUFFPIXEL]; // pixel in buffer (R+G+B per pixel)
  uint16_t lcdbuffer[BUFFPIXEL];  // pixel out buffer (16-bit per pixel)
  uint8_t  buffidx = sizeof(sdbuffer); // Current position in sdbuffer
  boolean  goodBmp = false;       // Set to true on valid header parse
  boolean  flip    = true;        // BMP is stored bottom-to-top
  int      w, h, row, col;
  uint8_t  r, g, b;
  uint32_t pos = 0, startTime = millis();
  uint8_t  lcdidx = 0;
  boolean  first = true;

  if((x >= tft.width()) || (y >= tft.height())) return;

  Serial.println();
  progmemPrint(PSTR("Loading image '"));
  Serial.print(filename);
  Serial.println('\'');
  // Open requested file on SD card
  if ((bmpFile = SD.open(filename)) == NULL) {
    progmemPrintln(PSTR("File not found"));
    return;
  }

  // Parse BMP header
  if(read16(bmpFile) == 0x4D42) { // BMP signature
    progmemPrint(PSTR("File size: ")); Serial.println(read32(bmpFile));
    (void)read32(bmpFile); // Read & ignore creator bytes
    bmpImageoffset = read32(bmpFile); // Start of image data
    progmemPrint(PSTR("Image Offset: ")); Serial.println(bmpImageoffset, DEC);
    // Read DIB header
    progmemPrint(PSTR("Header size: ")); Serial.println(read32(bmpFile));
    bmpWidth  = read32(bmpFile);
    bmpHeight = read32(bmpFile);
    if(read16(bmpFile) == 1) { // # planes -- must be '1'
      bmpDepth = read16(bmpFile); // bits per pixel
      progmemPrint(PSTR("Bit Depth: ")); Serial.println(bmpDepth);
      if((bmpDepth == 24) && (read32(bmpFile) == 0)) { // 0 = uncompressed

        goodBmp = true; // Supported BMP format -- proceed!
        progmemPrint(PSTR("Image size: "));
        Serial.print(bmpWidth);
        Serial.print('x');
        Serial.println(bmpHeight);

        // BMP rows are padded (if needed) to 4-byte boundary
        rowSize = (bmpWidth * 3 + 3) & ~3;

        // If bmpHeight is negative, image is in top-down order.
        // This is not canon but has been observed in the wild.
        if(bmpHeight < 0) {
          bmpHeight = -bmpHeight;
          flip      = false;
        }

        // Crop area to be loaded
        w = bmpWidth;
        h = bmpHeight;
        if((x+w-1) >= tft.width())  w = tft.width()  - x;
        if((y+h-1) >= tft.height()) h = tft.height() - y;

        // Set TFT address window to clipped image bounds
        tft.setAddrWindow(x, y, x+w-1, y+h-1);

        for (row=0; row<h; row++) { // For each scanline...
          // Seek to start of scan line.  It might seem labor-
          // intensive to be doing this on every line, but this
          // method covers a lot of gritty details like cropping
          // and scanline padding.  Also, the seek only takes
          // place if the file position actually needs to change
          // (avoids a lot of cluster math in SD library).
          if(flip) // Bitmap is stored bottom-to-top order (normal BMP)
            pos = bmpImageoffset + (bmpHeight - 1 - row) * rowSize;
          else     // Bitmap is stored top-to-bottom
            pos = bmpImageoffset + row * rowSize;
          if(bmpFile.position() != pos) { // Need seek?
            bmpFile.seek(pos);
            buffidx = sizeof(sdbuffer); // Force buffer reload
          }

          for (col=0; col<w; col++) { // For each column...
            // Time to read more pixel data?
            if (buffidx >= sizeof(sdbuffer)) { // Indeed
              // Push LCD buffer to the display first
              if(lcdidx > 0) {
                tft.pushColors(lcdbuffer, lcdidx, first);
                lcdidx = 0;
                first  = false;
              }
              bmpFile.read(sdbuffer, sizeof(sdbuffer));
              buffidx = 0; // Set index to beginning
            }

            // Convert pixel from BMP to TFT format
            b = sdbuffer[buffidx++];
            g = sdbuffer[buffidx++];
            r = sdbuffer[buffidx++];
            lcdbuffer[lcdidx++] = tft.color565(r,g,b);
          } // end pixel
        } // end scanline
        // Write any remaining data to LCD
        if(lcdidx > 0) {
          tft.pushColors(lcdbuffer, lcdidx, first);
        } 
        progmemPrint(PSTR("Loaded in "));
        Serial.print(millis() - startTime);
        Serial.println(" ms");
      } // end goodBmp
    }
  }

  bmpFile.close();
  if(!goodBmp) progmemPrintln(PSTR("BMP format not recognized."));
}

// These read 16- and 32-bit types from the SD card file.
// BMP data is stored little-endian, Arduino is little-endian too.
// May need to reverse subscript order if porting elsewhere.

uint16_t read16(File f) {
  uint16_t result;
  ((uint8_t *)&result)[0] = f.read(); // LSB
  ((uint8_t *)&result)[1] = f.read(); // MSB
  return result;
}

uint32_t read32(File f) {
  uint32_t result;
  ((uint8_t *)&result)[0] = f.read(); // LSB
  ((uint8_t *)&result)[1] = f.read();
  ((uint8_t *)&result)[2] = f.read();
  ((uint8_t *)&result)[3] = f.read(); // MSB
  return result;
}

I have also searched online and when i replace this:

while(c = pgm_read_byte(str++)) Serial.print(c);

to this:

while((c = pgm_read_byte(str++))) Serial.print(c);

I don't get an error there anymore, but now i get the error on every

return;

I can solve that by returning false:

return false;

But then i get the next error:

warning: control reaches end of non-void function [-Wreturn-type]

On the arduino nano (with Atmega328p) it works but i don't know how different the code for the Atmega1284 is

Thanks for your help already!

I'm sorry, i see that those are just warnings, the real error while it won't compile is because i am using the Adafruit touchscreen library, when i comment that out it compiles and uploads.

These are the errors i get from the library

\Arduino\libraries\Adafruit_TouchScreen/TouchScreen.h:51:12: error: 'RwReg' does not name a type

   volatile RwReg *xp_port, *yp_port, *xm_port, *ym_port;

            ^~~~~

\Arduino\libraries\Adafruit_TouchScreen/TouchScreen.h:52:3: error: 'RwReg' does not name a type

   RwReg xp_pin, xm_pin, yp_pin, ym_pin;

   ^~~~~

//edit

I found out that this code gives the problem:

#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega32U4__) || defined(TEENSYDUINO) || defined(__AVR_ATmega2560__)
typedef volatile uint8_t RwReg;

There is no definition for the ATmega1284, i can add || defined(AVR_ATMEGA1284) but that doesn't work, if u add "typedef volatile uint8_t RwReg;" above the if's it works for the atmega1284 and i can upload the code (haven't tested with the actual screen but uploading works so far).

Can i make the code correct? Is there a check for the ATmega1284?

Thanks!

The ATmega1284 (Sanguino?) core that you installed SHOULD provide a define for that processor. What core did you install that supports the ATmega1284?

I don't have a Sanguino, i use a Atmega1284 with 16mhz crystal and 22pF capacitors, i installed the bootloader with the Mighty 1284P core (example here: Technoblogy - Using the ATmega1284 with the Arduino IDE)

I want to connect a MCUFriend display to the Atmega1284 but i can't figure out how it should be connected, if i use the same pinout as i used on the Arduino Nano (which worked), the display stays white

I used a LM2937 to add the 3.3v pin

Based on the variable names it looks like the library wants to do direct register I/O to the four analog pins of the touch screen: X-Plus, X-Minus, Y-Plus, and Y-Minus. Are those analog pins on the same 1284 digital pins as on the Nano? If not you will have to figure out what port and pin each of the analog pins appears on.

Since that is just the touch screen it probably won't keep the display from working so there is likely a similar problem on the display pins. You will probably need to re-write parts of the library to work with your chosen processor.

On the arduino nano i had:

A0    -->    LCD_RD
A1    -->    LCD_WR
A2    -->    LCD_RS
A3    -->    LCD_CS
A4    -->    LCD_RST

On the Atmega1284 i have:

A7    -->    LCD_RD
A6    -->    LCD_WR
A5    -->    LCD_RS
A4    -->    LCD_CS
A3    -->    LCD_RST

Now the display works but the touchscreen doesn't work.
I have updated

const int XP = 6, XM = A2, YP = A1, YM = 7; //ID=0x9341

to

const int XP = 6, XM = A5, YP = A6, YM = 7; //ID=0x9341

But it also doesn't work like this

If you are using A5 and A6 for the LCD you probably can't also use them for XM and YP. Pick other pins.