Skip to content

Commit a526ee5

Browse files
committed
Merge branch 'zero' of github.com:arduino/ArduinoZero into zero
Conflicts: hardware/arduino/samd/variants/arduino_zero/variant.cpp
2 parents 8109cf8 + 0f32476 commit a526ee5

File tree

16 files changed

+545
-306
lines changed

16 files changed

+545
-306
lines changed

cores/arduino/Arduino.h

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -53,23 +53,6 @@ void yield( void ) ;
5353
void setup( void ) ;
5454
void loop( void ) ;
5555

56-
#define NOT_AN_INTERRUPT -1
57-
58-
typedef enum _EExt_Interrupts
59-
{
60-
EXTERNAL_INT_0=0,
61-
EXTERNAL_INT_1=1,
62-
EXTERNAL_INT_2=2,
63-
EXTERNAL_INT_3=3,
64-
EXTERNAL_INT_4=4,
65-
EXTERNAL_INT_5=5,
66-
EXTERNAL_INT_6=6,
67-
EXTERNAL_INT_7=7,
68-
EXTERNAL_NUM_INTERRUPTS
69-
} EExt_Interrupts ;
70-
71-
typedef void (*voidFuncPtr)( void ) ;
72-
7356
#include "WVariant.h"
7457

7558
#ifdef __cplusplus

cores/arduino/SERCOM.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -266,9 +266,9 @@ void SERCOM::writeDataSPI(uint8_t data)
266266
sercom->SPI.DATA.bit.DATA = data;
267267
}
268268

269-
uint8_t SERCOM::readDataSPI()
269+
uint16_t SERCOM::readDataSPI()
270270
{
271-
return sercom->SPI.DATA.bit.DATA;
271+
return sercom->SPI.DATA.reg;
272272
}
273273

274274
bool SERCOM::isBufferOverflowErrorSPI()

cores/arduino/SERCOM.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ class SERCOM
157157
void setBaudrateSPI(uint8_t divider);
158158
void setClockModeSPI(SercomSpiClockMode clockMode);
159159
void writeDataSPI(uint8_t data);
160-
uint8_t readDataSPI();
160+
uint16_t readDataSPI();
161161
bool isBufferOverflowErrorSPI();
162162
bool isDataRegisterEmptySPI();
163163
bool isTransmitCompleteSPI();

cores/arduino/WInterrupts.c

Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
/*
2+
Copyright (c) 2014 Arduino. All right reserved.
3+
4+
This library is free software; you can redistribute it and/or
5+
modify it under the terms of the GNU Lesser General Public
6+
License as published by the Free Software Foundation; either
7+
version 2.1 of the License, or (at your option) any later version.
8+
9+
This library is distributed in the hope that it will be useful,
10+
but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12+
See the GNU Lesser General Public License for more details.
13+
14+
You should have received a copy of the GNU Lesser General Public
15+
License along with this library; if not, write to the Free Software
16+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17+
*/
18+
19+
#include "WInterrupts.h"
20+
#include "variant.h"
21+
#include "wiring_digital.h"
22+
23+
#include <string.h>
24+
25+
#ifdef __cplusplus
26+
extern "C" {
27+
#endif
28+
29+
static struct
30+
{
31+
uint32_t _ulPin ;
32+
voidFuncPtr _callback ;
33+
} callbacksInt[EXTERNAL_NUM_INTERRUPTS] ;
34+
35+
/* Configure I/O interrupt sources */
36+
static void __initialize()
37+
{
38+
#if 0
39+
int i ;
40+
41+
for ( i = 0 ; i < EXTERNAL_NUM_INTERRUPTS ; i++ )
42+
{
43+
callbacksInt[i]._callback = NULL ;
44+
}
45+
#else
46+
memset( callbacksInt, 0, sizeof( callbacksInt ) ) ;
47+
#endif
48+
49+
NVIC_DisableIRQ( EIC_IRQn ) ;
50+
NVIC_ClearPendingIRQ( EIC_IRQn ) ;
51+
NVIC_SetPriority( EIC_IRQn, 0 ) ;
52+
NVIC_EnableIRQ( EIC_IRQn ) ;
53+
54+
// Enable GCLK for IEC (External Interrupt Controller)
55+
GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( GCM_EIC )) ;
56+
57+
/* Shall we do that?
58+
// Do a software reset on EIC
59+
EIC->CTRL.SWRST.bit = 1 ;
60+
61+
while ( (EIC->CTRL.SWRST.bit == 1) && (EIC->STATUS.SYNCBUSY.bit == 1) )
62+
{
63+
// Wait for synchronisation
64+
}
65+
*/
66+
}
67+
68+
/*
69+
* \brief Specifies a named Interrupt Service Routine (ISR) to call when an interrupt occurs.
70+
* Replaces any previous function that was attached to the interrupt.
71+
*/
72+
//void attachInterrupt( uint32_t ulPin, void (*callback)(void), EExt_IntMode mode )
73+
//void attachInterrupt( uint32_t ulPin, voidFuncPtr callback, EExt_IntMode mode )
74+
void attachInterrupt( uint32_t ulPin, voidFuncPtr callback, uint32_t ulMode )
75+
{
76+
static int enabled = 0 ;
77+
uint32_t ulConfig ;
78+
uint32_t ulPos ;
79+
80+
if ( digitalPinToInterrupt( ulPin ) == NOT_AN_INTERRUPT )
81+
{
82+
return ;
83+
}
84+
85+
if ( !enabled )
86+
{
87+
__initialize() ;
88+
enabled = 1 ;
89+
}
90+
91+
// Assign pin to EIC
92+
pinPeripheral( ulPin, PIO_EXTINT ) ;
93+
94+
// Assign callback to interrupt
95+
callbacksInt[digitalPinToInterrupt( ulPin )]._ulPin = ulPin ;
96+
callbacksInt[digitalPinToInterrupt( ulPin )]._callback = callback ;
97+
98+
// Check if normal interrupt or NMI
99+
if ( ulPin != 2 )
100+
{
101+
// Look for right CONFIG register to be addressed
102+
if ( digitalPinToInterrupt( ulPin ) > EXTERNAL_INT_7 )
103+
{
104+
ulConfig = 1 ;
105+
}
106+
else
107+
{
108+
ulConfig = 0 ;
109+
}
110+
111+
// Configure the interrupt mode
112+
ulPos = ((digitalPinToInterrupt( ulPin ) >> ulConfig ) << 2) ;
113+
switch ( ulMode )
114+
{
115+
case LOW:
116+
EIC->CONFIG[ulConfig].reg = EIC_CONFIG_SENSE0_LOW_Val << ulPos ;
117+
break ;
118+
119+
case HIGH:
120+
EIC->CONFIG[ulConfig].reg = EIC_CONFIG_SENSE0_HIGH_Val << ((digitalPinToInterrupt( ulPin ) >> ulConfig ) << 2) ;
121+
break ;
122+
123+
case CHANGE:
124+
EIC->CONFIG[ulConfig].reg = EIC_CONFIG_SENSE0_BOTH_Val << ((digitalPinToInterrupt( ulPin ) >> ulConfig ) << 2) ;
125+
break ;
126+
127+
case FALLING:
128+
EIC->CONFIG[ulConfig].reg = EIC_CONFIG_SENSE0_FALL_Val << ((digitalPinToInterrupt( ulPin ) >> ulConfig ) << 2) ;
129+
break ;
130+
131+
case RISING:
132+
EIC->CONFIG[ulConfig].reg = EIC_CONFIG_SENSE0_RISE_Val << ((digitalPinToInterrupt( ulPin ) >> ulConfig ) << 2) ;
133+
break ;
134+
}
135+
136+
// Enable the interrupt
137+
EIC->INTENSET.reg = EIC_INTENSET_EXTINT( 1 << digitalPinToInterrupt( ulPin ) ) ;
138+
}
139+
else // Handles NMI on pin 2
140+
{
141+
// Configure the interrupt mode
142+
switch ( ulMode )
143+
{
144+
case LOW:
145+
EIC->NMICTRL.reg = EIC_NMICTRL_NMISENSE_LOW ;
146+
break ;
147+
148+
case HIGH:
149+
EIC->NMICTRL.reg = EIC_NMICTRL_NMISENSE_HIGH ;
150+
break ;
151+
152+
case CHANGE:
153+
EIC->NMICTRL.reg = EIC_NMICTRL_NMISENSE_BOTH ;
154+
break ;
155+
156+
case FALLING:
157+
EIC->NMICTRL.reg = EIC_NMICTRL_NMISENSE_FALL ;
158+
break ;
159+
160+
case RISING:
161+
EIC->NMICTRL.reg= EIC_NMICTRL_NMISENSE_RISE ;
162+
break ;
163+
}
164+
165+
// Enable the interrupt
166+
EIC->INTENSET.reg = EIC_INTENSET_EXTINT( 1 << digitalPinToInterrupt( ulPin ) ) ;
167+
}
168+
}
169+
170+
/*
171+
* \brief Turns off the given interrupt.
172+
*/
173+
void detachInterrupt( uint32_t ulPin )
174+
{
175+
/*
176+
// Retrieve pin information
177+
Pio *pio = g_APinDescription[pin].pPort;
178+
uint32_t mask = g_APinDescription[pin].ulPin;
179+
180+
// Disable interrupt
181+
pio->PIO_IDR = mask;
182+
*/
183+
if ( digitalPinToInterrupt( ulPin ) == NOT_AN_INTERRUPT )
184+
{
185+
return ;
186+
}
187+
188+
EIC->INTENCLR.reg = EIC_INTENCLR_EXTINT( 1 << digitalPinToInterrupt( ulPin ) ) ;
189+
}
190+
191+
/*
192+
* External Interrupt Controller NVIC Interrupt Handler
193+
*/
194+
void EIC_Handler( void )
195+
{
196+
uint32_t ul ;
197+
198+
// Test NMI first
199+
if ( (EIC->NMIFLAG.reg & EIC_NMIFLAG_NMI) == EIC_NMIFLAG_NMI )
200+
{
201+
// Call the callback function if assigned
202+
if ( callbacksInt[EXTERNAL_INT_NMI]._callback != NULL )
203+
{
204+
callbacksInt[EXTERNAL_INT_NMI]._callback() ;
205+
}
206+
207+
// Clear the interrupt
208+
EIC->NMIFLAG.reg = EIC_NMIFLAG_NMI ;
209+
}
210+
211+
// Test the 16 normal interrupts
212+
for ( ul = EXTERNAL_INT_0 ; ul < EXTERNAL_INT_15 ; ul++ )
213+
{
214+
if ( (EIC->INTFLAG.reg & 1 << ul) != 0 )
215+
{
216+
// Call the callback function if assigned
217+
if ( callbacksInt[ul]._callback != NULL )
218+
{
219+
callbacksInt[ul]._callback() ;
220+
}
221+
222+
// Clear the interrupt
223+
EIC->INTFLAG.reg = 1 << ul ;
224+
}
225+
}
226+
}
227+
228+
#ifdef __cplusplus
229+
}
230+
#endif

0 commit comments

Comments
 (0)