Updating the mighty-1284p core

bperrybap:
My suggestion at this point would be target 1.x first, then move it over to 1.5x

Excellent suggestion.

That does seem to be the case.

So first, I wanted to understand the changes that were made to 1.0 in order to produce the current 1284p core.

The diffs against 1.0.5 are fairly small (few lines here; dozen there) and seem to be low risk (minor bug fixes; add support for another processor) so I suggest working against 1.0.5.

I made some space on Google Code to track issues...
https://code.google.com/p/mighty-1284p-port-to-1-0-5/issues/list

Right, I was aware of LED_BUILTIN and surprised to see the mighty-1284p standard variant had "LED" not "LED_BUILTIN":

static const uint8_t LED = 7;

Seems that #define would be better in this case, to facilitate compile time decisions. @bperrybap mentioned const/macro issues earlier, but I see that Arduino v1.0.5 uses const.

Very interesting, it appears that at least some of maniacbug's changes to 1.0 have made it into 1.0.5.

I tried something that I thought was totally mad. I cloned the mighty-1284p core, created a new branch, copied in the core files from a vanilla copy of 1.0.5, then ran a merge to bring in the 1284p changes. Surprisingly, git did the merge without conflicts. I've been running a somewhat complex sketch with it that includes Ethernet client, UDP (for NTP), an LCD display, an RTC, and one or two other small things. So far it runs fine.

So I'm thinking that I may have a 1.0.5 version of the mighty-1284p core at this point. I've started the process of reviewing the changes between 1.0, mighty-1284p, 1.0.5, and the new 1284p that I produced. So far things look reasonable but I have a ways to go yet.

[quote author=Coding Badly link=topic=235521.msg1705296#msg1705296 date=1399003039]
In which case 38400 and 76800 are far better choices [/quote]

from the standpoint of divisor error thats true. unfortunately few (none) of the official boards use those so not an option for me because i like same baud for all projects. 1m or, for that matter, anything over 115k also ruled out because not available on most computer/os. mostly i like 57k because its much friendlier from a hardware standpoint (cable capacitance, jitter, etc) and no big download time gain beyond that.

auto adjust baud so same rate for different crystals, bios table so user can call useful boot routines (ie serial and specially flash write which cant be done from app), osccal calibrate for internal rc clk, debug monitor to dump and poke memory, and a few other less useful ones that dont come to mind atm.

A 1 M baud, no LED, serial 0 bootloader for the m1284.

The boards.txt entry I'm using...

##############################################################

bobuino.name=Bobuino
bobuino.upload.protocol=arduino
bobuino.upload.maximum_size=130048
# bobuino.upload.speed=115200
bobuino.upload.speed=1000000

# bobuino.bootloader.low_fuses=0xff
# bobuino.bootloader.high_fuses=0xde
# bobuino.bootloader.extended_fuses=0xfd

# Full Swing Oscillator; Start-up time: 16K CK + 65 ms; Crystal Osc.; slowly rising power; [CKSEL=0111 SUT=11]
# Boot Reset vector Enabled (default address=$0000); [BOOTRST=0]
# Boot Flash section size=512 words Boot start address=$FE00; [BOOTSZ=11]
# Preserve EEPROM memory through the Chip Erase cycle; [EESAVE=0]
# Serial program downloading (SPI) enabled; [SPIEN=0]
# Brown-out detection level at VCC=2.7 V; [BODLEVEL=101]

bobuino.bootloader.low_fuses=0xF7
bobuino.bootloader.high_fuses=0xD6
bobuino.bootloader.extended_fuses=0xFD

bobuino.bootloader.path=optiboot
bobuino.bootloader.file=optiboot_atmega1284p.hex
bobuino.bootloader.unlock_bits=0x3F
bobuino.bootloader.lock_bits=0x0F
bobuino.build.mcu=atmega1284p
bobuino.build.f_cpu=16000000L
#bobuino.build.core=arduino:arduino
bobuino.build.core=standard
bobuino.build.variant=bobuino

##############################################################

optiboot_atmega1284p.hex (1.29 KB)

447 bytes. amazing. i didnt think it could be trimmed down that small with c. i had to go asm route to get there. guess the led stuff takes up more room than i thought.

What is that conflict?

We may be able to do better than that. I spent a fair amount of time today reviewing 1.0 (upon which the current mighty-1284p core was built) vs. mighty-1284p vs. 1.0.5 vs. the new 1284p core I built (reply #44).

I came to a startling conclusion. Namely, the current 1.0.5 core (cores) files (i.e. arduino-1.0.5\hardware\arduino\cores\arduino) are sufficient to support the ATmega1284P the same as the current mighty-1284p core. I think all the necessary changes have worked their way into the cores files since 1.0.

I think all that is needed to program an ATmega1284P with v1.0.5 is a bootloader, pins file, and a boards.txt entry. I wouldn't be surprised if ATmega644/A/P/PA worked as well.

Next would be to test this.

As the quickest way to test this,

  1. I used my current mighty-1284p installation. I deleted all the files from sketchbook\hardware\mighty-1284p\cores\standard

  2. Into the now empty folder, I copied the files from v1.0.5, arduino-1.0.5\hardware\arduino\cores\arduino

Initial testing found no problems and included trying:

Various digital I/O
The eight analog inputs
The eight PWM outputs
External interrupts 0, 1, 2
My sketch with Ethernet/UDP/LCD/RTC

Well played! I followed your instructions and then uploaded this:

void setup() {
  // put your setup code here, to run once:
pinMode(13, INPUT_PULLUP);
}

void loop() {
  // put your main code here, to run repeatedly: 
  
}

And was rewarded with a dimmily lit pin 13. So INPUT_PULLUP appears to work.

Lefty

retrolefty:
So INPUT_PULLUP appears to work.

Thanks for testing that! I did verify that it compiled but then in all the excitement forgot to actually try it :smiley:

Looking over the IDE release notes, I see some references to the 1284P in ARDUINO 1.0.1 - 2012.05.21, but nothing new mentioned after that.

Great detective work! ++Karma.

It is surprising, if indeed this has been slipstreamed in, that there isn't any record of it, as suggested by RetroLefty. Who got the changes in, I wonder? These things don't just "happen"!

Anyway, all will become clear in due course, I imagine.

In the meantime, I was testing this out using the SPI library's example sketches, and I came across this bug in bobuino/pins_arduino.h (lines 36-38):

extern const uint8_t digital_pin_to_pcint[NUM_DIGITAL_PINS];
extern const uint16_t __pcmsk[];
extern const uint8_t digital_pin_to_timer_PGM[NUM_DIGITAL_PINS];

Not sure if if I am using the latest version of the bobuino files, but these lines caused the linker to complain:

In file included from C:\arduino\Arduino ERW 1.0.5\libraries\SPI\/SPI.h:15,
                 from C:\arduino\Arduino ERW 1.0.5\libraries\SPI\SPI.cpp:12:
C:\arduino\Arduino ERW 1.0.5\hardware\mighty-1284p\variants\bobuino/pins_arduino.h:38: error: previous declaration of 'const uint8_t digital_pin_to_timer_PGM [32]' with 'C++' linkage
C:\arduino\Arduino ERW 1.0.5\hardware\arduino\cores\arduino/Arduino.h:134: error: conflicts with new declaration with 'C' linkage

when using the standard Arduino 1.0.5 core files (which is what I was testing), but also complained equally loudly when using the original 1234p "standard" core.

Having a quick look though bobuino/pins_arduino.h showed the extern declarations simply shouldn't have been there, as the actual arrays were actually defined later in that file.

Anyway, the easy fix is just to delete those three lines, of course.

I had a look at the standard/pins_arduino.h to see if the bug was also there, but it wasn't.

Is this an old bug, and I am using outdated files?

I've been using this one, has a couple tweaks (commented) that seems to fix the SPI problem.
http://www.crossroadsfencing.com/BobuinoRev17/pins_arduino.h

CrossRoads:
I've been using this one, has a couple tweaks (commented) that seems to fix the SPI problem.
http://www.crossroadsfencing.com/BobuinoRev17/pins_arduino.h

extern const uint8_t digital_pin_to_pcint[NUM_DIGITAL_PINS];
extern const uint16_t __pcmsk[];
// comment next line to solve SPI problem?
//extern const uint8_t digital_pin_to_timer_PGM[NUM_DIGITAL_PINS];

Yes, I can see it comments out one of the three lines I mention above.

The SPI lib only trips on the first one, but the other two will cause similar problems if the linker has cause to try to resolve those symbols.

The proper fix is just delete all three. Those extern declarations shouldn't be there if the actual array definitions are in the same file. "extern" is to tell the compiler that the actual definitions are in a different source file, but don't worry, I promise the linker will sort it all out later. I Cross my heart! :slight_smile:

Edit:

Noticed the bug fix a few lines later:

// #define analogPinToChannel(p)	    ( (p) < NUM_ANALOG_INPUTS ? NUM_ANALOG_INPUTS - (p) : -1 )
#define analogPinToChannel(p)       ( (p) < NUM_ANALOG_INPUTS ? (NUM_ANALOG_INPUTS-1) - (p) : -1 ) // test to see if A0-A7 are off by 1

yep, that commented version is definitely incorrect, as 0 would map to 8, rather than 7.

the new version looks the real deal. I'll fix this in my file.

Is this file currently in/going to be in to version control somewhere?

Just noticed this line:

#define analogInputToDigitalPin(p)  ((p < NUM_ANALOG_INPUTS) ? 21 - (p) : -1)

This looks like it may be incorrect.

If p = 0, it returns 21, which is PA0 (or A7), but I suspect it should be returning 14, which is PA7 (or A0)

if so, the macro should be

#define analogInputToDigitalPin(p)  ((p < NUM_ANALOG_INPUTS) ? 14 + (p) : -1)

which would make it consistent with this macro

#define digitalPinToAnalogPin(p)    ( (p) >= 14 && (p) <= 21 ? (p) - 14 : -1 )

which does what I'd expect.

pico:
Great detective work! ++Karma.

It is surprising, if indeed this has been slipstreamed in, that there isn't any record of it, as suggested by RetroLefty. Who got the changes in, I wonder? These things don't just "happen"!

Thank you! As lefty found in the release notes, it appears that the changes were made in 1.0.1 and submitted by maniacbug. I think the actual changes to the core files were quite minimal, and consisted mainly of adding INT2, and maybe some fixes for analogRead(). Some changes in the maniacbug core seem unrelated to the 1284p, e.g. changes to Wstring.cpp, and I wonder if some improvements weren't developed in parallel and maybe independently to some extent.

Then there were a couple changes that I couldn't make much sense of and didn't dig into, for example removal of the PROGMEM attribute in the following declarations in Arduino.h -- 1.0.5 still has PROGMEM.

diff --git a/arduino-1.0/hardware/arduino/cores/arduino/Arduino.h b/mighty-1284p/cores/standard/Arduino.h
index ebd374a..2e35a35 100644
--- a/arduino-1.0/hardware/arduino/cores/arduino/Arduino.h
+++ b/mighty-1284p/cores/standard/Arduino.h
@@ -123,14 +123,14 @@ void loop(void);
 
 // On the ATmega1280, the addresses of some of the port registers are
 // greater than 255, so we can't store them in uint8_t's.
-extern const uint16_t PROGMEM port_to_mode_PGM[];
-extern const uint16_t PROGMEM port_to_input_PGM[];
-extern const uint16_t PROGMEM port_to_output_PGM[];
+extern const uint16_t port_to_mode_PGM[];
+extern const uint16_t port_to_input_PGM[];
+extern const uint16_t port_to_output_PGM[];
 
-extern const uint8_t PROGMEM digital_pin_to_port_PGM[];
-// extern const uint8_t PROGMEM digital_pin_to_bit_PGM[];
-extern const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[];
-extern const uint8_t PROGMEM digital_pin_to_timer_PGM[];
+extern const uint8_t digital_pin_to_port_PGM[];
+// extern const uint8_t digital_pin_to_bit_PGM[];
+extern const uint8_t digital_pin_to_bit_mask_PGM[];
+extern const uint8_t digital_pin_to_timer_PGM[];
 
 // Get the bit location within the hardware port of the given virtual pin.
 // This comes from the pins_*.c file for the active board configuration.

I may be learning some things the hard way here, and I may not be the first to have come this way. I just noticed that all the entries in maniacbug's boards.txt file have something similar to

#mighty_opt.build.core=arduino:arduino
mighty_opt.build.core=standard

It looks like if the first line above is un-commented and the second is commented, then the sketchbook\hardware\mighty-1284p\cores directory can just be deleted and this will cause the cores files from the Arduino distribution to be used.

My guess would be the arrays were changed form progmem to sram storage because the larger 1284p memory available made it less important to preserve sram, and probably the tradeoff being a performance boost in functions that used those table values for look-ups. Debatable in its merits, but not unjustifiable. It would be interesting to see if there is a material performance benefit in some situations.

That's what I was doing to test using the Arduino 1.0.5 core with the bobuino/pins_arduino.h. Seems to work fine so far.