Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
A
arduino-nRF5
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Analytics
Analytics
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
xpstem
arduino-nRF5
Commits
9a7fa4f8
Commit
9a7fa4f8
authored
Mar 26, 2016
by
Sandeep Mistry
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Functional SPI
parent
941bacc7
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
608 additions
and
0 deletions
+608
-0
libraries/SPI/SPI.cpp
libraries/SPI/SPI.cpp
+188
-0
libraries/SPI/SPI.h
libraries/SPI/SPI.h
+166
-0
libraries/SPI/examples/BarometricPressureSensor/BarometricPressureSensor.ino
...les/BarometricPressureSensor/BarometricPressureSensor.ino
+143
-0
libraries/SPI/examples/DigitalPotControl/DigitalPotControl.ino
...ries/SPI/examples/DigitalPotControl/DigitalPotControl.ino
+71
-0
libraries/SPI/keywords.txt
libraries/SPI/keywords.txt
+31
-0
libraries/SPI/library.properties
libraries/SPI/library.properties
+9
-0
No files found.
libraries/SPI/SPI.cpp
0 → 100644
View file @
9a7fa4f8
/*
* SPI Master library for Arduino Zero.
* Copyright (c) 2015 Arduino LLC
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "SPI.h"
#include <Arduino.h>
#include <wiring_private.h>
#include <assert.h>
#define SPI_IMODE_NONE 0
#define SPI_IMODE_EXTINT 1
#define SPI_IMODE_GLOBAL 2
const
SPISettings
DEFAULT_SPI_SETTINGS
=
SPISettings
();
SPIClass
::
SPIClass
(
NRF_SPI_Type
*
p_spi
,
uint8_t
uc_pinMISO
,
uint8_t
uc_pinSCK
,
uint8_t
uc_pinMOSI
)
{
initialized
=
false
;
assert
(
p_spi
!=
NULL
);
_p_spi
=
p_spi
;
// pins
_uc_pinMiso
=
uc_pinMISO
;
_uc_pinSCK
=
uc_pinSCK
;
_uc_pinMosi
=
uc_pinMOSI
;
_dataMode
=
NRF_SPI_MODE_0
;
_bitOrder
=
NRF_SPI_BIT_ORDER_MSB_FIRST
;
}
void
SPIClass
::
begin
()
{
init
();
nrf_spi_pins_set
(
_p_spi
,
_uc_pinSCK
,
_uc_pinMosi
,
_uc_pinMiso
);
config
(
DEFAULT_SPI_SETTINGS
);
}
void
SPIClass
::
init
()
{
if
(
initialized
)
return
;
interruptMode
=
SPI_IMODE_NONE
;
interruptSave
=
0
;
interruptMask
=
0
;
initialized
=
true
;
}
void
SPIClass
::
config
(
SPISettings
settings
)
{
nrf_spi_disable
(
_p_spi
);
nrf_spi_configure
(
_p_spi
,
settings
.
dataMode
,
settings
.
bitOrder
);
nrf_spi_frequency_set
(
_p_spi
,
settings
.
clockFreq
);
nrf_spi_enable
(
_p_spi
);
}
void
SPIClass
::
end
()
{
nrf_spi_disable
(
_p_spi
);
initialized
=
false
;
}
void
SPIClass
::
usingInterrupt
(
int
/*interruptNumber*/
)
{
}
void
SPIClass
::
beginTransaction
(
SPISettings
settings
)
{
config
(
settings
);
}
void
SPIClass
::
endTransaction
(
void
)
{
}
void
SPIClass
::
setBitOrder
(
BitOrder
order
)
{
if
(
order
==
LSBFIRST
)
{
nrf_spi_configure
(
_p_spi
,
_dataMode
,
NRF_SPI_BIT_ORDER_LSB_FIRST
);
}
else
{
nrf_spi_configure
(
_p_spi
,
_dataMode
,
NRF_SPI_BIT_ORDER_MSB_FIRST
);
}
}
void
SPIClass
::
setDataMode
(
uint8_t
mode
)
{
switch
(
mode
)
{
case
SPI_MODE0
:
nrf_spi_configure
(
_p_spi
,
NRF_SPI_MODE_0
,
_bitOrder
);
break
;
case
SPI_MODE1
:
nrf_spi_configure
(
_p_spi
,
NRF_SPI_MODE_1
,
_bitOrder
);
break
;
case
SPI_MODE2
:
nrf_spi_configure
(
_p_spi
,
NRF_SPI_MODE_2
,
_bitOrder
);
break
;
case
SPI_MODE3
:
nrf_spi_configure
(
_p_spi
,
NRF_SPI_MODE_3
,
_bitOrder
);
break
;
default:
break
;
}
}
void
SPIClass
::
setClockDivider
(
uint8_t
div
)
{
nrf_spi_frequency_t
clockFreq
;
if
(
div
>=
SPI_CLOCK_DIV128
)
{
clockFreq
=
NRF_SPI_FREQ_125K
;
}
else
if
(
div
>=
SPI_CLOCK_DIV64
)
{
clockFreq
=
NRF_SPI_FREQ_250K
;
}
else
if
(
div
>=
SPI_CLOCK_DIV32
)
{
clockFreq
=
NRF_SPI_FREQ_500K
;
}
else
if
(
div
>=
SPI_CLOCK_DIV16
)
{
clockFreq
=
(
nrf_spi_frequency_t
)
SPI_FREQUENCY_FREQUENCY_M1
;
}
else
if
(
div
>=
SPI_CLOCK_DIV8
)
{
clockFreq
=
(
nrf_spi_frequency_t
)
SPI_FREQUENCY_FREQUENCY_M2
;
}
else
if
(
div
>=
SPI_CLOCK_DIV4
)
{
clockFreq
=
(
nrf_spi_frequency_t
)
SPI_FREQUENCY_FREQUENCY_M4
;
}
else
{
clockFreq
=
(
nrf_spi_frequency_t
)
SPI_FREQUENCY_FREQUENCY_M8
;
}
nrf_spi_frequency_set
(
_p_spi
,
clockFreq
);
}
byte
SPIClass
::
transfer
(
uint8_t
data
)
{
nrf_spi_txd_set
(
_p_spi
,
data
);
while
(
!
nrf_spi_event_check
(
_p_spi
,
NRF_SPI_EVENT_READY
));
data
=
nrf_spi_rxd_get
(
_p_spi
);
nrf_spi_event_clear
(
_p_spi
,
NRF_SPI_EVENT_READY
);
return
data
;
}
uint16_t
SPIClass
::
transfer16
(
uint16_t
data
)
{
union
{
uint16_t
val
;
struct
{
uint8_t
lsb
;
uint8_t
msb
;
};
}
t
;
t
.
val
=
data
;
if
(
_bitOrder
==
NRF_SPI_BIT_ORDER_LSB_FIRST
)
{
t
.
lsb
=
transfer
(
t
.
lsb
);
t
.
msb
=
transfer
(
t
.
msb
);
}
else
{
t
.
msb
=
transfer
(
t
.
msb
);
t
.
lsb
=
transfer
(
t
.
lsb
);
}
return
t
.
val
;
}
void
SPIClass
::
attachInterrupt
()
{
// Should be enableInterrupt()
}
void
SPIClass
::
detachInterrupt
()
{
// Should be disableInterrupt()
}
SPIClass
SPI
(
NRF_SPI0
,
24
,
25
,
23
);
libraries/SPI/SPI.h
0 → 100644
View file @
9a7fa4f8
/*
* SPI Master library for Arduino Zero.
* Copyright (c) 2015 Arduino LLC
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _SPI_H_INCLUDED
#define _SPI_H_INCLUDED
#include "nrf_spi.h"
#include <Arduino.h>
// SPI_HAS_TRANSACTION means SPI has
// - beginTransaction()
// - endTransaction()
// - usingInterrupt()
// - SPISetting(clock, bitOrder, dataMode)
#define SPI_HAS_TRANSACTION 1
#define SPI_MODE0 0x02
#define SPI_MODE1 0x00
#define SPI_MODE2 0x03
#define SPI_MODE3 0x01
class
SPISettings
{
public:
SPISettings
(
uint32_t
clock
,
BitOrder
bitOrder
,
uint8_t
dataMode
)
{
if
(
__builtin_constant_p
(
clock
))
{
init_AlwaysInline
(
clock
,
bitOrder
,
dataMode
);
}
else
{
init_MightInline
(
clock
,
bitOrder
,
dataMode
);
}
}
// Default speed set to 4MHz, SPI mode set to MODE 0 and Bit order set to MSB first.
SPISettings
()
{
init_AlwaysInline
(
4000000
,
MSBFIRST
,
SPI_MODE0
);
}
private:
void
init_MightInline
(
uint32_t
clock
,
BitOrder
bitOrder
,
uint8_t
dataMode
)
{
init_AlwaysInline
(
clock
,
bitOrder
,
dataMode
);
}
void
init_AlwaysInline
(
uint32_t
clock
,
BitOrder
bitOrder
,
uint8_t
dataMode
)
__attribute__
((
__always_inline__
))
{
if
(
clock
<=
125000
)
{
this
->
clockFreq
=
NRF_SPI_FREQ_125K
;
}
else
if
(
clock
<=
250000
)
{
this
->
clockFreq
=
NRF_SPI_FREQ_250K
;
}
else
if
(
clock
<=
500000
)
{
this
->
clockFreq
=
NRF_SPI_FREQ_500K
;
}
else
if
(
clock
<=
1000000
)
{
this
->
clockFreq
=
(
nrf_spi_frequency_t
)
SPI_FREQUENCY_FREQUENCY_M1
;
}
else
if
(
clock
<=
2000000
)
{
this
->
clockFreq
=
(
nrf_spi_frequency_t
)
SPI_FREQUENCY_FREQUENCY_M2
;
}
else
if
(
clock
<=
4000000
)
{
this
->
clockFreq
=
(
nrf_spi_frequency_t
)
SPI_FREQUENCY_FREQUENCY_M4
;
}
else
{
this
->
clockFreq
=
(
nrf_spi_frequency_t
)
SPI_FREQUENCY_FREQUENCY_M8
;
}
this
->
bitOrder
=
(
bitOrder
==
MSBFIRST
?
NRF_SPI_BIT_ORDER_MSB_FIRST
:
NRF_SPI_BIT_ORDER_LSB_FIRST
);
switch
(
dataMode
)
{
case
SPI_MODE0
:
this
->
dataMode
=
NRF_SPI_MODE_0
;
break
;
case
SPI_MODE1
:
this
->
dataMode
=
NRF_SPI_MODE_1
;
break
;
case
SPI_MODE2
:
this
->
dataMode
=
NRF_SPI_MODE_2
;
break
;
case
SPI_MODE3
:
this
->
dataMode
=
NRF_SPI_MODE_3
;
break
;
default:
this
->
dataMode
=
NRF_SPI_MODE_0
;
break
;
}
}
nrf_spi_frequency_t
clockFreq
;
nrf_spi_mode_t
dataMode
;
nrf_spi_bit_order_t
bitOrder
;
friend
class
SPIClass
;
};
class
SPIClass
{
public:
SPIClass
(
NRF_SPI_Type
*
p_spi
,
uint8_t
uc_pinMISO
,
uint8_t
uc_pinSCK
,
uint8_t
uc_pinMOSI
);
byte
transfer
(
uint8_t
data
);
uint16_t
transfer16
(
uint16_t
data
);
inline
void
transfer
(
void
*
buf
,
size_t
count
);
// Transaction Functions
void
usingInterrupt
(
int
interruptNumber
);
void
beginTransaction
(
SPISettings
settings
);
void
endTransaction
(
void
);
// SPI Configuration methods
void
attachInterrupt
();
void
detachInterrupt
();
void
begin
();
void
end
();
void
setBitOrder
(
BitOrder
order
);
void
setDataMode
(
uint8_t
uc_mode
);
void
setClockDivider
(
uint8_t
uc_div
);
private:
void
init
();
void
config
(
SPISettings
settings
);
NRF_SPI_Type
*
_p_spi
;
uint8_t
_uc_pinMiso
;
uint8_t
_uc_pinMosi
;
uint8_t
_uc_pinSCK
;
nrf_spi_mode_t
_dataMode
;
nrf_spi_bit_order_t
_bitOrder
;
bool
initialized
;
uint8_t
interruptMode
;
char
interruptSave
;
uint32_t
interruptMask
;
};
void
SPIClass
::
transfer
(
void
*
buf
,
size_t
count
)
{
// TODO: Optimize for faster block-transfer
uint8_t
*
buffer
=
reinterpret_cast
<
uint8_t
*>
(
buf
);
for
(
size_t
i
=
0
;
i
<
count
;
i
++
)
buffer
[
i
]
=
transfer
(
buffer
[
i
]);
}
extern
SPIClass
SPI
;
extern
SPIClass
SPI1
;
extern
SPIClass
SPI2
;
// For compatibility with sketches designed for AVR @ 16 MHz
// New programs should use SPI.beginTransaction to set the SPI clock
#if F_CPU == 16000000
#define SPI_CLOCK_DIV2 2
#define SPI_CLOCK_DIV4 4
#define SPI_CLOCK_DIV8 8
#define SPI_CLOCK_DIV16 16
#define SPI_CLOCK_DIV32 32
#define SPI_CLOCK_DIV64 64
#define SPI_CLOCK_DIV128 128
#endif
#endif
\ No newline at end of file
libraries/SPI/examples/BarometricPressureSensor/BarometricPressureSensor.ino
0 → 100755
View file @
9a7fa4f8
/*
SCP1000 Barometric Pressure Sensor Display
Shows the output of a Barometric Pressure Sensor on a
Uses the SPI library. For details on the sensor, see:
http://www.sparkfun.com/commerce/product_info.php?products_id=8161
http://www.vti.fi/en/support/obsolete_products/pressure_sensors/
This sketch adapted from Nathan Seidle's SCP1000 example for PIC:
http://www.sparkfun.com/datasheets/Sensors/SCP1000-Testing.zip
Circuit:
SCP1000 sensor attached to pins 6, 7, 10 - 13:
DRDY: pin 6
CSB: pin 7
MOSI: pin 11
MISO: pin 12
SCK: pin 13
created 31 July 2010
modified 14 August 2010
by Tom Igoe
*/
// the sensor communicates using SPI, so include the library:
#include <SPI.h>
//Sensor's memory register addresses:
const
int
PRESSURE
=
0x1F
;
//3 most significant bits of pressure
const
int
PRESSURE_LSB
=
0x20
;
//16 least significant bits of pressure
const
int
TEMPERATURE
=
0x21
;
//16 bit temperature reading
const
byte
READ
=
0b11111100
;
// SCP1000's read command
const
byte
WRITE
=
0b00000010
;
// SCP1000's write command
// pins used for the connection with the sensor
// the other you need are controlled by the SPI library):
const
int
dataReadyPin
=
6
;
const
int
chipSelectPin
=
7
;
void
setup
()
{
Serial
.
begin
(
9600
);
// start the SPI library:
SPI
.
begin
();
// initalize the data ready and chip select pins:
pinMode
(
dataReadyPin
,
INPUT
);
pinMode
(
chipSelectPin
,
OUTPUT
);
//Configure SCP1000 for low noise configuration:
writeRegister
(
0x02
,
0x2D
);
writeRegister
(
0x01
,
0x03
);
writeRegister
(
0x03
,
0x02
);
// give the sensor time to set up:
delay
(
100
);
}
void
loop
()
{
//Select High Resolution Mode
writeRegister
(
0x03
,
0x0A
);
// don't do anything until the data ready pin is high:
if
(
digitalRead
(
dataReadyPin
)
==
HIGH
)
{
//Read the temperature data
int
tempData
=
readRegister
(
0x21
,
2
);
// convert the temperature to celsius and display it:
float
realTemp
=
(
float
)
tempData
/
20.0
;
Serial
.
print
(
"Temp[C]="
);
Serial
.
print
(
realTemp
);
//Read the pressure data highest 3 bits:
byte
pressure_data_high
=
readRegister
(
0x1F
,
1
);
pressure_data_high
&=
0b00000111
;
//you only needs bits 2 to 0
//Read the pressure data lower 16 bits:
unsigned
int
pressure_data_low
=
readRegister
(
0x20
,
2
);
//combine the two parts into one 19-bit number:
long
pressure
=
((
pressure_data_high
<<
16
)
|
pressure_data_low
)
/
4
;
// display the temperature:
Serial
.
println
(
"
\t
Pressure [Pa]="
+
String
(
pressure
));
}
}
//Read from or write to register from the SCP1000:
unsigned
int
readRegister
(
byte
thisRegister
,
int
bytesToRead
)
{
byte
inByte
=
0
;
// incoming byte from the SPI
unsigned
int
result
=
0
;
// result to return
Serial
.
print
(
thisRegister
,
BIN
);
Serial
.
print
(
"
\t
"
);
// SCP1000 expects the register name in the upper 6 bits
// of the byte. So shift the bits left by two bits:
thisRegister
=
thisRegister
<<
2
;
// now combine the address and the command into one byte
byte
dataToSend
=
thisRegister
&
READ
;
Serial
.
println
(
thisRegister
,
BIN
);
// take the chip select low to select the device:
digitalWrite
(
chipSelectPin
,
LOW
);
// send the device the register you want to read:
SPI
.
transfer
(
dataToSend
);
// send a value of 0 to read the first byte returned:
result
=
SPI
.
transfer
(
0x00
);
// decrement the number of bytes left to read:
bytesToRead
--
;
// if you still have another byte to read:
if
(
bytesToRead
>
0
)
{
// shift the first byte left, then get the second byte:
result
=
result
<<
8
;
inByte
=
SPI
.
transfer
(
0x00
);
// combine the byte you just got with the previous one:
result
=
result
|
inByte
;
// decrement the number of bytes left to read:
bytesToRead
--
;
}
// take the chip select high to de-select:
digitalWrite
(
chipSelectPin
,
HIGH
);
// return the result:
return
(
result
);
}
//Sends a write command to SCP1000
void
writeRegister
(
byte
thisRegister
,
byte
thisValue
)
{
// SCP1000 expects the register address in the upper 6 bits
// of the byte. So shift the bits left by two bits:
thisRegister
=
thisRegister
<<
2
;
// now combine the register address and the command into one byte:
byte
dataToSend
=
thisRegister
|
WRITE
;
// take the chip select low to select the device:
digitalWrite
(
chipSelectPin
,
LOW
);
SPI
.
transfer
(
dataToSend
);
//Send register location
SPI
.
transfer
(
thisValue
);
//Send value to record into register
// take the chip select high to de-select:
digitalWrite
(
chipSelectPin
,
HIGH
);
}
libraries/SPI/examples/DigitalPotControl/DigitalPotControl.ino
0 → 100755
View file @
9a7fa4f8
/*
Digital Pot Control
This example controls an Analog Devices AD5206 digital potentiometer.
The AD5206 has 6 potentiometer channels. Each channel's pins are labeled
A - connect this to voltage
W - this is the pot's wiper, which changes when you set it
B - connect this to ground.
The AD5206 is SPI-compatible,and to command it, you send two bytes,
one with the channel number (0 - 5) and one with the resistance value for the
channel (0 - 255).
The circuit:
* All A pins of AD5206 connected to +5V
* All B pins of AD5206 connected to ground
* An LED and a 220-ohm resisor in series connected from each W pin to ground
* CS - to digital pin 10 (SS pin)
* SDI - to digital pin 11 (MOSI pin)
* CLK - to digital pin 13 (SCK pin)
created 10 Aug 2010
by Tom Igoe
Thanks to Heather Dewey-Hagborg for the original tutorial, 2005
*/
// inslude the SPI library:
#include <SPI.h>
// set pin 10 as the slave select for the digital pot:
const
int
slaveSelectPin
=
10
;
void
setup
()
{
// set the slaveSelectPin as an output:
pinMode
(
slaveSelectPin
,
OUTPUT
);
// initialize SPI:
SPI
.
begin
();
}
void
loop
()
{
// go through the six channels of the digital pot:
for
(
int
channel
=
0
;
channel
<
6
;
channel
++
)
{
// change the resistance on this channel from min to max:
for
(
int
level
=
0
;
level
<
255
;
level
++
)
{
digitalPotWrite
(
channel
,
level
);
delay
(
10
);
}
// wait a second at the top:
delay
(
100
);
// change the resistance on this channel from max to min:
for
(
int
level
=
0
;
level
<
255
;
level
++
)
{
digitalPotWrite
(
channel
,
255
-
level
);
delay
(
10
);
}
}
}
void
digitalPotWrite
(
int
address
,
int
value
)
{
// take the SS pin low to select the chip:
digitalWrite
(
slaveSelectPin
,
LOW
);
// send in the address and value via SPI:
SPI
.
transfer
(
address
);
SPI
.
transfer
(
value
);
// take the SS pin high to de-select the chip:
digitalWrite
(
slaveSelectPin
,
HIGH
);
}
libraries/SPI/keywords.txt
0 → 100644
View file @
9a7fa4f8
#######################################
# Syntax Coloring Map SPI
#######################################
#######################################
# Datatypes (KEYWORD1)
#######################################
SPI KEYWORD1
#######################################
# Methods and Functions (KEYWORD2)
#######################################
begin KEYWORD2
end KEYWORD2
transfer KEYWORD2
#setBitOrder KEYWORD2
setDataMode KEYWORD2
setClockDivider KEYWORD2
#######################################
# Constants (LITERAL1)
#######################################
SPI_MODE0 LITERAL1
SPI_MODE1 LITERAL1
SPI_MODE2 LITERAL1
SPI_MODE3 LITERAL1
SPI_CONTINUE LITERAL1
SPI_LAST LITERAL1
libraries/SPI/library.properties
0 → 100644
View file @
9a7fa4f8
name
=
SPI
version
=
1.0
author
=
maintainer
=
sentence
=
Enables the communication with devices that use the Serial Peripheral Interface (SPI) Bus. Specific implementation for nRF52.
paragraph
=
category
=
Communication
url
=
http://www.arduino.cc/en/Reference/SPI
architectures
=
nRF52
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment