andyvand / arduino

Automatically exported from code.google.com/p/arduino
Other
0 stars 0 forks source link

Pin defines for hardware independent libraries and sketches #59

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What change would like to see?

Add a header file that defines all of the board's pin assignments.  One
possible implementation is attached.  The proposed naming convention is
documented in the comments.

This request is ONLY to add the header.  Later, libraries and other files
can be patched to make use of these definitions.  But first the definitions
need to be created, which is the scope of this request.

Why?

Libraries and sketches that wish to make direct use of the hardware or use
hardware features not supported by the core (such as the SPI port) must
make board-specific assumptions about the pin assignments.  For example,
the Ethernet library contains definitions such as:

#define SPI0_MOSI_BIT                   BIT3

#define SPI0_MOSI_DDR                   DDRB

#define SPI0_MOSI_PORT                  PORTB

When used on a board with different pin assignments, such as the Arduino
Mega, this code fails.  This can be solved by using #ifdef to test for the
CPU type.  However, that leads to placing a lot of board-specific
definitions inside libraries, which must be updated when new boards are
added.  It also allows only a single board pinout assignment per processor.
 Ideally, the libraries would contain no assumptions about board-specific
pinouts.

Instead, this feature request would create a header within the core
directory which defines the pinout used by the board.  The library may then
include the header and become hardware independent.  For example:

#define SPI0_MOSI_BIT                   CORE_BITMASK(CORE_MOSI0_PIN)

#define SPI0_MOSI_DDR                   CORE_DDRREG(CORE_MOSI0_PIN)
#define SPI0_MOSI_PORT                  CORE_PORTREG(CORE_MOSI0_PIN)

The attached definitions envision symbols such as CORE_MOSI0_PIN which
translate desired hardware pin features into Arduino pin numbers that are
compatible with pinMode(), digitialRead() and digitialWrite().  A second
set of symbols and macros allow translating the Arduino pin numbers
directly into register names, in cases where direct register access is
necessary.  However, using the normal functions is preferred.

Would this cause any incompatibilities with previous versions?  If so, how
can these be mitigated?

This feature request only adds a header file with definitions.  No actual
code is changed in any way.

Once added, each library that current hard-codes pinout information can be
changed to use these definitions.  However, that is outside the scope of
this initial request to simply add the definitions.

In the future, this header will allow the development of new libraries that
are compatible with all boards that have the required hardware, regardless
of the pin number assignments.  Also, as new boards or cores are added,
this header will allow them to work automatically with all libraries and
sketches that make use of these definitions.

But for now, the scope of this request is merely to add the header which
defines and documents naming convention and provides definitions for the
existing boards.

Original issue reported on code.google.com by paul.sto...@gmail.com on 19 Jul 2009 at 7:52

Attachments:

GoogleCodeExporter commented 9 years ago
I prefer const int xxx = 0 over #defines.
I need this kind of pin naming abstraction to do a good job on a complete OSC 
library for Arduino.

Original comment by newsfr...@gmail.com on 26 Aug 2009 at 4:18

GoogleCodeExporter commented 9 years ago
Looking over this header file, it seems to have both too much information (e.g. 
the pin number to port/bit 
mappings which are already in the pins_arduino files - albeit in a less useful 
form) and too little (e.g. register 
and bit names).  What do you think about starting with the existing Arduino 
libraries?  That is, refactoring them 
so they work on multiple processors, and then checking which constants are 
needed to do so?

Original comment by dmel...@gmail.com on 6 Sep 2009 at 7:35

GoogleCodeExporter commented 9 years ago
Here is a specific usage case for the Ethernet library.

Index: utility/spi.h
===================================================================
--- utility/spi.h   (revision 784)
+++ utility/spi.h   (working copy)
@@ -9,23 +9,6 @@
 #define BIT6                           0x40
 #define BIT7                           0x80

-#define SPI0_SS_BIT                        BIT2
-#define SPI0_SS_DDR                        DDRB
-#define SPI0_SS_PORT                   PORTB
-
-#define SPI0_SCLK_BIT                  BIT5
-#define SPI0_SCLK_DDR                  DDRB
-#define SPI0_SCLK_PORT                 PORTB
-
-#define    SPI0_MOSI_BIT                   BIT3
-#define SPI0_MOSI_DDR                  DDRB
-#define SPI0_MOSI_PORT                 PORTB
-
-#define    SPI0_MISO_BIT                   BIT4
-#define SPI0_MISO_DDR                  DDRB
-#define SPI0_MISO_PORT                 PORTB
-
-
 #define SPI0_WaitForReceive()              
 #define SPI0_RxData()                  (SPDR)

@@ -36,9 +19,14 @@
 #define SPI0_RecvBute()                    SPI0_RxData()

 // PB4(MISO), PB3(MOSI), PB5(SCK), PB2(/SS)         // CS=1, waiting for SPI start
// SPI mode 0, 4MHz
-#define SPI0_Init()                        DDRB  |= SPI0_SS_BIT|SPI0_SCLK_BIT|SPI0_MOSI_BIT;\
-                                       PORTB |= SPI0_SS_BIT; PORTB &= ~(SPI0_SCLK_BIT|SPI0_MOSI_BIT);\
-                                       SPCR  = 0x50  
+#define SPI0_Init()                pinMode(CORE_SS0_PIN, OUTPUT); \
+                       pinMode(CORE_SCLK_PIN, OUTPUT); \
+                       pinMode(CORE_MOSI_PIN, OUTPUT); \
+                       digitalWrite(CORE_SS0_PIN, HIGH); \
+                       digitalWrite(CORE_SCLK_PIN, LOW); \
+                       digitalWrite(CORE_MOSI_PIN, LOW); \
+                       SPCR = 0x50  
+
 //-----------------------------------------------------------------------------

 //-----------------------------------------------------------------------------
@@ -47,12 +35,7 @@
 #define IINCHIP_SpiSendData                SPI0_SendByte   
 #define IINCHIP_SpiRecvData                SPI0_RxData

-
-#define IINCHIP_CS_BIT                 BIT2
-#define IINCHIP_CS_DDR                 DDRB
-#define IINCHIP_CS_PORT                    PORTB
-
-#define IINCHIP_CSInit()                   (IINCHIP_CS_DDR |= IINCHIP_CS_BIT)
-#define IINCHIP_CSon()                 (IINCHIP_CS_PORT |= IINCHIP_CS_BIT)
-#define IINCHIP_CSoff()                    (IINCHIP_CS_PORT &= ~IINCHIP_CS_BIT)
+#define IINCHIP_CSInit()               pinMode(CORE_SS0_PIN, OUTPUT)
+#define IINCHIP_CSon()                 CORE_PORTREG(CORE_SS0_PIN) |= 
CORE_BITMASK(CORE_SS0_PIN)
+#define IINCHIP_CSoff()                    CORE_PORTREG(CORE_SS0_PIN) &= 
~CORE_BITMASK(CORE_SS0_PIN)
 //-----------------------------------------------------------------------------

Original comment by paul.sto...@gmail.com on 5 Nov 2009 at 7:31

Attachments:

GoogleCodeExporter commented 9 years ago
This header has all the redundant register definitions removed.  These will not 
be
needed when digitialWrite() can compile to a single instruction when the input 
is a
compile time constant.

Original comment by paul.sto...@gmail.com on 7 Nov 2009 at 3:24

Attachments:

GoogleCodeExporter commented 9 years ago
Initial implementation of macros to optimize digitalWrite() when both inputs are
compile-time constants.

Original comment by paul.sto...@gmail.com on 13 Nov 2009 at 1:53

Attachments:

GoogleCodeExporter commented 9 years ago
Updated spi.h for Ethernet, using these symbols.  No #ifdef checks.  All pin
manipulation is by pinMode() and digitalWrite().  Written for issue #203.

#include "wiring.h"

//-----------------------------------------------------------------------------
//AVR SPI HAL

#define SPI0_WaitForReceive()                           
#define SPI0_RxData()           (SPDR)

#define SPI0_TxData(Data)       (SPDR = Data)
#define SPI0_WaitForSend()      while( (SPSR & 0x80)==0x00 )

#define SPI0_SendByte(Data)     SPI0_TxData(Data);SPI0_WaitForSend()
#define SPI0_RecvBute()         SPI0_RxData()

#define SPI0_Init()             pinMode(CORE_SS0_PIN, OUTPUT); \
                                pinMode(CORE_SCLK0_PIN, OUTPUT); \
                                pinMode(CORE_MOSI0_PIN, OUTPUT); \
                                digitalWrite(CORE_SS0_PIN, HIGH); \
                                digitalWrite(CORE_SCLK0_PIN, LOW); \
                                digitalWrite(CORE_MOSI0_PIN, LOW); \
                                SPCR = 0x50 

//-----------------------------------------------------------------------------
//IInChip SPI HAL
#define IINCHIP_SpiInit         SPI0_Init
#define IINCHIP_SpiSendData     SPI0_SendByte   
#define IINCHIP_SpiRecvData     SPI0_RxData

#define IINCHIP_CSInit()        pinMode(CORE_SS0_PIN, OUTPUT)
#define IINCHIP_CSon()          digitalWrite(CORE_SS0_PIN, HIGH)
#define IINCHIP_CSoff()         digitalWrite(CORE_SS0_PIN, LOW)
//-----------------------------------------------------------------------------

Original comment by paul.sto...@gmail.com on 11 Mar 2010 at 3:26

Attachments:

GoogleCodeExporter commented 9 years ago
The ethernet and SD libraries still contain their own pin mapping details 
rather than using pins_arduino.h. What needs to be done so that all the pin 
mapping information is held in pins_arduino.h, and no processor or board 
specific assumptions are made by the main libraries? Then 3rd party hardware 
(my own included) can be supported without requiring changes to the standard 
library functions.

Original comment by stevemar...@googlemail.com on 20 Nov 2011 at 10:13