Go Down

Topic: Arduino variant, how do I add more pins (Read 2893 times) previous topic - next topic

bluscape

I've made a custom board based on the Arduino Mega 2560. I've used pins on my board that is not used on the Arduino board (for example all the pins on PORT J)

How do I add the PORT J pins to the Arduino code?

I looked at the pins_arduino.h file but is not 100% sure if this is the correct place. I'm not sure what to do.

Any help will be appreciated.

Thank you


Tom Carpenter

#1
Jul 16, 2012, 10:03 pm Last Edit: Jul 16, 2012, 10:08 pm by TCWORLD Reason: 1
Code: [Select]
#ifdef ARDUINO_MAIN

const uint16_t PROGMEM port_to_mode_PGM[] = {
NOT_A_PORT,
(uint16_t) &DDRA,
(uint16_t) &DDRB,
(uint16_t) &DDRC,
(uint16_t) &DDRD,
(uint16_t) &DDRE,
(uint16_t) &DDRF,
(uint16_t) &DDRG,
(uint16_t) &DDRH,
NOT_A_PORT;
(uint16_t) &DDRJ, // ddr J is already defined
(uint16_t) &DDRK,
(uint16_t) &DDRL,
};

const uint16_t PROGMEM port_to_output_PGM[] = {
NOT_A_PORT,
(uint16_t) &PORTA,
(uint16_t) &PORTB,
(uint16_t) &PORTC,
(uint16_t) &PORTD,
(uint16_t) &PORTE,
(uint16_t) &PORTF,
(uint16_t) &PORTG,
(uint16_t) &PORTH,
NOT_A_PORT,
(uint16_t) &PORTJ, // port J is already defined
(uint16_t) &PORTK,
(uint16_t) &PORTL,
};

const uint16_t PROGMEM port_to_input_PGM[] = {
NOT_A_PIN,
(uint16_t) &PINA,
(uint16_t) &PINB,
(uint16_t) &PINC,
(uint16_t) &PIND,
(uint16_t) &PINE,
(uint16_t) &PINF,
(uint16_t) &PING,
(uint16_t) &PINH,
NOT_A_PIN,
(uint16_t) &PINJ, // pin J is already defined
(uint16_t) &PINK,
(uint16_t) &PINL,
};


Say you wanted J2 to J7 to be digital 70 to digital 75, you would change the following:
Code: [Select]



#define NUM_DIGITAL_PINS            76

...
...

const uint8_t PROGMEM digital_pin_to_port_PGM[] = {
// PORTLIST
// -------------------------------------------
...
PK , // PK 6 ** 68 ** A14
PK , // PK 7 ** 69 ** A15
PJ , // PJ 2 ** 70 ** D70
PJ , // PJ 3 ** 71 ** D71
PJ , // PJ 4 ** 72 ** D72
PJ , // PJ 5 ** 73 ** D73
PJ , // PJ 6 ** 74 ** D74
PJ , // PJ 7 ** 75 ** D75
};

const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = {
// PIN IN PORT
// -------------------------------------------
...
_BV( 5 ) , // PK 5 ** 67 ** A13
_BV( 6 ) , // PK 6 ** 68 ** A14
_BV( 7 ) , // PK 7 ** 69 ** A15
_BV( 2 ) , // PJ 2 ** 70 ** D70
_BV( 3 ) , // PJ 3 ** 71 ** D71
_BV( 4 ) , // PJ 4 ** 72 ** D72
_BV( 5 ) , // PJ 5 ** 73 ** D73
_BV( 6 ) , // PJ 6 ** 74 ** D74
_BV( 7 ) , // PJ 7 ** 75 ** D75
};

const uint8_t PROGMEM digital_pin_to_timer_PGM[] = {
// TIMERS
// -------------------------------------------
...
NOT_ON_TIMER , // PK 4 ** 66 ** A12
NOT_ON_TIMER , // PK 5 ** 67 ** A13
NOT_ON_TIMER , // PK 6 ** 68 ** A14
NOT_ON_TIMER , // PK 7 ** 69 ** A15
NOT_ON_TIMER , // PJ 2 ** 70 ** D70
NOT_ON_TIMER , // PJ 3 ** 71 ** D71
NOT_ON_TIMER , // PJ 4 ** 72 ** D72
NOT_ON_TIMER , // PJ 5 ** 73 ** D73
NOT_ON_TIMER , // PJ 6 ** 74 ** D74
NOT_ON_TIMER , // PJ 7 ** 75 ** D75
};
~Tom~

CrossRoads

Take a look at the overallstructure, and create yourself a new Variant.
Copy the 2560 files there.
In pins_arduino.h, there are several arrays where the pins are defined.
One array lists the ports used, these will be the pins, listed in what ends up as D0 to Dxx.
Next is the pins within the ports.
Next is whether the pins have timers associated with them.

There might be more. I haven't dug into the 1.0 format in a while, and then maniacbug was able to get the files finished up for a 1284 chip.

You'll probably need a new entry for boards.txt also to call out your new variant to map in your new pins_arduino.h. And possiby a new entry on avrdude.conf, altho maybe not if boards.txt calls out the same chip type.

Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.


bluscape

1.) I've added the new pins in a custom header file "..\hardware\arduino\variants\custom\pins_arduino.h"
2.) I copied the board settings for the Arduino Mega 2560 and created a custom board entry
3.) I've updated the pin numbers in my sketch

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

custom2560.name=Custom 2560

custom2560.upload.protocol=stk500v2
custom2560.upload.maximum_size=258048
custom2560.upload.speed=115200

custom2560.bootloader.low_fuses=0xFF
custom2560.bootloader.high_fuses=0xD8
custom2560.bootloader.extended_fuses=0xFD
custom2560.bootloader.path=stk500v2
custom2560.bootloader.file=stk500boot_v2_mega2560.hex
custom2560.bootloader.unlock_bits=0x3F
custom2560.bootloader.lock_bits=0x0F

custom2560.build.mcu=atmega2560
custom2560.build.f_cpu=16000000L
custom2560.build.core=arduino
custom2560.build.variant=custom

But when I compile my sketch I get the following errors for each new pin:

error: 'DIO76_DDR' was not declared in this scope
error: 'DIO76_PIN' was not declared in this scope
error: 'DIO76_WPORT' was not declared in this scope

etc.

So somewhere there is a mapping from the arduino pins to the actual avr pins but I dont know where.

Any ideas?

bluscape

Ok, the mapping is located in fastio.h.


I had to add the following for each extra pin used on my device:

Code: [Select]

#if defined (__AVR_ATmega1280__) || defined (__AVR_ATmega2560__)
.
.
.
#define DIO70_PIN PINJ2
#define DIO70_RPORT         PINJ2
#define DIO70_WPORT         PORTJ
#define DIO70_DDR DDRJ
#define DIO70_PWM NULL
.
.
.


CrossRoads

yet another file.
I wonder if there is  a writeup somewhere explaining this whole variant's thing so its not so hit & miss.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

cyclegadget


Here is the link to maniacbug's files for the 1284 variant. You can use his files as a basis of how many and what files you will need for your board.

https://github.com/maniacbug/mighty-1284p
Good links: Eagle tutorial= http://www.youtube.com/playlist?list=PLDE1858BD83D19C70
General Arduion tutorials = http://tronixstuff.wordpress.com
http://www.gammon.com.au/forum/bbshowpost.php?bbtopic_id=123

CrossRoads

I think  that could be a good start.

I don't see a fastio.h anywhere. Might be some other subtleties involved too.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

Lami

Hello, I have related question. I use ATtiny 44/45/84/85 variants from http://hlt.media.mit.edu/?p=1695 - all works as expected. Although I would like to use SPI library. These chips have USI instead of SPI, by reading specs it is slightly different. I think I will be able to make version of SPI library working on these chips. My question is - where should I put files? It would be nice if standard Arduinos will use standard SPI and ATtiny USI variant of SPI.

I have ~/Arduino/hardware/attiny folder with "variants" and "boards.txt". I think I can redefine cores/standard/* to modify basic functionality. Is it possible to override extra libraries (as SPI) this way? In the system installation, libraries are above the "hardware" folder and offer no hint about hardware variants.

Other idea about how to achieve this is to create ~/Arduino/libraries/SPI version of the library, hoping it overrides system installation. And #ifdef it to oblivion.

What is the best, or most compatible way to do it?

CrossRoads

Looks like the  ATTiny25/45/85 hardware will support SPI:

Port B, Bit 2 - SCK/ADC1/T0/USCK/SCL/INT0/PCINT2
• SCK: Master Clock output, Slave Clock input pin for SPI channel. When the SPI is enabled as
a Slave, this pin is configured as an input regardless of the setting of DDB2. When the SPI is
enabled as a Master, the data direction of this pin is controlled by DDPB2. When the pin is
forced by the SPI to be an input, the pull-up can still be controlled by the PORTB2 bit.

Port B, Bit 1 - MISO/AIN1/OC0B/OC1A/DO/PCINT1
• MISO: Master Data input, Slave Data output pin for SPI channel. When the SPI is enabled as
a Master, this pin is configured as an input regardless of the setting of DDB1. When the SPI
is enabled as a Slave, the data direction of this pin is controlled by DDB1. When the pin is
forced by the SPI to be an input, the pull-up can still be controlled by the PORTB1 bit.

Port B, Bit 0 - MOSI/AIN0/OC0A/OC1A/DI/SDA/AREF/PCINT0
• MOSI: SPI Master Data output, Slave Data input for SPI channel. When the SPI is enabled as
a Slave, this pin is configured as an input regardless of the setting of DDB0. When the SPI is
enabled as a Master, the data direction of this pin is controlled by DDB0. When the pin is
forced by the SPI to be an input, the pull-up can still be controlled by the PORTB0 bit.

Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

Lami


Looks like the  ATTiny25/45/85 hardware will support SPI:


Yes it does, but the hardware is different. ATmega 328 has dedicated SPI hardware, ATtiny have USI, which can be configured as SPI (without !SS pin) or i2c. So 328's code for SPI will not work on these.

To code it should not be a problem. Just different port names and setup. My question is how to make the code most portable, so other can use it.

Go Up