Skip to content

Commit 1ff3520

Browse files
committed
Revert "SPI library to new format"
1 parent 9279a16 commit 1ff3520

File tree

5 files changed

+456
-0
lines changed

5 files changed

+456
-0
lines changed

libraries/SPI/SPI.cpp

+139
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
/*
2+
* Copyright (c) 2010 by Cristian Maglie <[email protected]>
3+
* SPI Master library for arduino.
4+
*
5+
* This file is free software; you can redistribute it and/or modify
6+
* it under the terms of either the GNU General Public License version 2
7+
* or the GNU Lesser General Public License version 2.1, both as
8+
* published by the Free Software Foundation.
9+
*/
10+
11+
#include "SPI.h"
12+
13+
SPIClass::SPIClass(Spi *_spi, uint32_t _id, void(*_initCb)(void)) :
14+
spi(_spi), id(_id), initCb(_initCb), initialized(false)
15+
{
16+
// Empty
17+
}
18+
19+
void SPIClass::begin() {
20+
init();
21+
22+
// NPCS control is left to the user
23+
24+
// Default speed set to 4Mhz
25+
setClockDivider(BOARD_SPI_DEFAULT_SS, 21);
26+
setDataMode(BOARD_SPI_DEFAULT_SS, SPI_MODE0);
27+
setBitOrder(BOARD_SPI_DEFAULT_SS, MSBFIRST);
28+
}
29+
30+
void SPIClass::begin(uint8_t _pin) {
31+
init();
32+
33+
uint32_t spiPin = BOARD_PIN_TO_SPI_PIN(_pin);
34+
PIO_Configure(
35+
g_APinDescription[spiPin].pPort,
36+
g_APinDescription[spiPin].ulPinType,
37+
g_APinDescription[spiPin].ulPin,
38+
g_APinDescription[spiPin].ulPinConfiguration);
39+
40+
// Default speed set to 4Mhz
41+
setClockDivider(_pin, 21);
42+
setDataMode(_pin, SPI_MODE0);
43+
setBitOrder(_pin, MSBFIRST);
44+
}
45+
46+
void SPIClass::init() {
47+
if (initialized)
48+
return;
49+
initCb();
50+
SPI_Configure(spi, id, SPI_MR_MSTR | SPI_MR_PS | SPI_MR_MODFDIS);
51+
SPI_Enable(spi);
52+
initialized = true;
53+
}
54+
55+
void SPIClass::end(uint8_t _pin) {
56+
uint32_t spiPin = BOARD_PIN_TO_SPI_PIN(_pin);
57+
// Setting the pin as INPUT will disconnect it from SPI peripheral
58+
pinMode(spiPin, INPUT);
59+
}
60+
61+
void SPIClass::end() {
62+
SPI_Disable(spi);
63+
initialized = false;
64+
}
65+
66+
void SPIClass::setBitOrder(uint8_t _pin, BitOrder _bitOrder) {
67+
uint32_t ch = BOARD_PIN_TO_SPI_CHANNEL(_pin);
68+
bitOrder[ch] = _bitOrder;
69+
}
70+
71+
void SPIClass::setDataMode(uint8_t _pin, uint8_t _mode) {
72+
uint32_t ch = BOARD_PIN_TO_SPI_CHANNEL(_pin);
73+
mode[ch] = _mode | SPI_CSR_CSAAT;
74+
// SPI_CSR_DLYBCT(1) keeps CS enabled for 32 MCLK after a completed
75+
// transfer. Some device needs that for working properly.
76+
SPI_ConfigureNPCS(spi, ch, mode[ch] | SPI_CSR_SCBR(divider[ch]) | SPI_CSR_DLYBCT(1));
77+
}
78+
79+
void SPIClass::setClockDivider(uint8_t _pin, uint8_t _divider) {
80+
uint32_t ch = BOARD_PIN_TO_SPI_CHANNEL(_pin);
81+
divider[ch] = _divider;
82+
// SPI_CSR_DLYBCT(1) keeps CS enabled for 32 MCLK after a completed
83+
// transfer. Some device needs that for working properly.
84+
SPI_ConfigureNPCS(spi, ch, mode[ch] | SPI_CSR_SCBR(divider[ch]) | SPI_CSR_DLYBCT(1));
85+
}
86+
87+
byte SPIClass::transfer(byte _pin, uint8_t _data, SPITransferMode _mode) {
88+
uint32_t ch = BOARD_PIN_TO_SPI_CHANNEL(_pin);
89+
// Reverse bit order
90+
if (bitOrder[ch] == LSBFIRST)
91+
_data = __REV(__RBIT(_data));
92+
uint32_t d = _data | SPI_PCS(ch);
93+
if (_mode == SPI_LAST)
94+
d |= SPI_TDR_LASTXFER;
95+
96+
// SPI_Write(spi, _channel, _data);
97+
while ((spi->SPI_SR & SPI_SR_TDRE) == 0)
98+
;
99+
spi->SPI_TDR = d;
100+
101+
// return SPI_Read(spi);
102+
while ((spi->SPI_SR & SPI_SR_RDRF) == 0)
103+
;
104+
d = spi->SPI_RDR;
105+
// Reverse bit order
106+
if (bitOrder[ch] == LSBFIRST)
107+
d = __REV(__RBIT(d));
108+
return d & 0xFF;
109+
}
110+
111+
void SPIClass::attachInterrupt(void) {
112+
// Should be enableInterrupt()
113+
}
114+
115+
void SPIClass::detachInterrupt(void) {
116+
// Should be disableInterrupt()
117+
}
118+
119+
#if SPI_INTERFACES_COUNT > 0
120+
static void SPI_0_Init(void) {
121+
PIO_Configure(
122+
g_APinDescription[PIN_SPI_MOSI].pPort,
123+
g_APinDescription[PIN_SPI_MOSI].ulPinType,
124+
g_APinDescription[PIN_SPI_MOSI].ulPin,
125+
g_APinDescription[PIN_SPI_MOSI].ulPinConfiguration);
126+
PIO_Configure(
127+
g_APinDescription[PIN_SPI_MISO].pPort,
128+
g_APinDescription[PIN_SPI_MISO].ulPinType,
129+
g_APinDescription[PIN_SPI_MISO].ulPin,
130+
g_APinDescription[PIN_SPI_MISO].ulPinConfiguration);
131+
PIO_Configure(
132+
g_APinDescription[PIN_SPI_SCK].pPort,
133+
g_APinDescription[PIN_SPI_SCK].ulPinType,
134+
g_APinDescription[PIN_SPI_SCK].ulPin,
135+
g_APinDescription[PIN_SPI_SCK].ulPinConfiguration);
136+
}
137+
138+
SPIClass SPI(SPI_INTERFACE, SPI_INTERFACE_ID, SPI_0_Init);
139+
#endif

libraries/SPI/SPI.h

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
* Copyright (c) 2010 by Cristian Maglie <[email protected]>
3+
* SPI Master library for arduino.
4+
*
5+
* This file is free software; you can redistribute it and/or modify
6+
* it under the terms of either the GNU General Public License version 2
7+
* or the GNU Lesser General Public License version 2.1, both as
8+
* published by the Free Software Foundation.
9+
*/
10+
11+
#ifndef _SPI_H_INCLUDED
12+
#define _SPI_H_INCLUDED
13+
14+
#include "variant.h"
15+
#include <stdio.h>
16+
17+
#define SPI_MODE0 0x02
18+
#define SPI_MODE1 0x00
19+
#define SPI_MODE2 0x03
20+
#define SPI_MODE3 0x01
21+
22+
enum SPITransferMode {
23+
SPI_CONTINUE,
24+
SPI_LAST
25+
};
26+
27+
class SPIClass {
28+
public:
29+
SPIClass(Spi *_spi, uint32_t _id, void(*_initCb)(void));
30+
31+
byte transfer(uint8_t _data, SPITransferMode _mode = SPI_LAST) { return transfer(BOARD_SPI_DEFAULT_SS, _data, _mode); }
32+
byte transfer(byte _channel, uint8_t _data, SPITransferMode _mode = SPI_LAST);
33+
34+
// SPI Configuration methods
35+
36+
void attachInterrupt(void);
37+
void detachInterrupt(void);
38+
39+
void begin(void);
40+
void end(void);
41+
42+
// Attach/Detach pin to/from SPI controller
43+
void begin(uint8_t _pin);
44+
void end(uint8_t _pin);
45+
46+
// These methods sets a parameter on a single pin
47+
void setBitOrder(uint8_t _pin, BitOrder);
48+
void setDataMode(uint8_t _pin, uint8_t);
49+
void setClockDivider(uint8_t _pin, uint8_t);
50+
51+
// These methods sets the same parameters but on default pin BOARD_SPI_DEFAULT_SS
52+
void setBitOrder(BitOrder _order) { setBitOrder(BOARD_SPI_DEFAULT_SS, _order); };
53+
void setDataMode(uint8_t _mode) { setDataMode(BOARD_SPI_DEFAULT_SS, _mode); };
54+
void setClockDivider(uint8_t _div) { setClockDivider(BOARD_SPI_DEFAULT_SS, _div); };
55+
56+
private:
57+
void init();
58+
59+
Spi *spi;
60+
uint32_t id;
61+
BitOrder bitOrder[SPI_CHANNELS_NUM];
62+
uint32_t divider[SPI_CHANNELS_NUM];
63+
uint32_t mode[SPI_CHANNELS_NUM];
64+
void (*initCb)(void);
65+
bool initialized;
66+
};
67+
68+
#if SPI_INTERFACES_COUNT > 0
69+
extern SPIClass SPI;
70+
#endif
71+
72+
#endif
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
/*
2+
SCP1000 Barometric Pressure Sensor Display
3+
4+
Shows the output of a Barometric Pressure Sensor on a
5+
Uses the SPI library. For details on the sensor, see:
6+
http://www.sparkfun.com/commerce/product_info.php?products_id=8161
7+
http://www.vti.fi/en/support/obsolete_products/pressure_sensors/
8+
9+
This sketch adapted from Nathan Seidle's SCP1000 example for PIC:
10+
http://www.sparkfun.com/datasheets/Sensors/SCP1000-Testing.zip
11+
12+
Circuit:
13+
SCP1000 sensor attached to pins 6, 7, 10 - 13:
14+
DRDY: pin 6
15+
CSB: pin 7
16+
MOSI: pin 11
17+
MISO: pin 12
18+
SCK: pin 13
19+
20+
created 31 July 2010
21+
modified 14 August 2010
22+
by Tom Igoe
23+
*/
24+
25+
// the sensor communicates using SPI, so include the library:
26+
#include <SPI.h>
27+
28+
//Sensor's memory register addresses:
29+
const int PRESSURE = 0x1F; //3 most significant bits of pressure
30+
const int PRESSURE_LSB = 0x20; //16 least significant bits of pressure
31+
const int TEMPERATURE = 0x21; //16 bit temperature reading
32+
const byte READ = 0b11111100; // SCP1000's read command
33+
const byte WRITE = 0b00000010; // SCP1000's write command
34+
35+
// pins used for the connection with the sensor
36+
// the other you need are controlled by the SPI library):
37+
const int dataReadyPin = 6;
38+
const int chipSelectPin = 7;
39+
40+
void setup() {
41+
Serial.begin(9600);
42+
43+
// start the SPI library:
44+
SPI.begin();
45+
46+
// initalize the data ready and chip select pins:
47+
pinMode(dataReadyPin, INPUT);
48+
pinMode(chipSelectPin, OUTPUT);
49+
50+
//Configure SCP1000 for low noise configuration:
51+
writeRegister(0x02, 0x2D);
52+
writeRegister(0x01, 0x03);
53+
writeRegister(0x03, 0x02);
54+
// give the sensor time to set up:
55+
delay(100);
56+
}
57+
58+
void loop() {
59+
//Select High Resolution Mode
60+
writeRegister(0x03, 0x0A);
61+
62+
// don't do anything until the data ready pin is high:
63+
if (digitalRead(dataReadyPin) == HIGH) {
64+
//Read the temperature data
65+
int tempData = readRegister(0x21, 2);
66+
67+
// convert the temperature to celsius and display it:
68+
float realTemp = (float)tempData / 20.0;
69+
Serial.print("Temp[C]=");
70+
Serial.print(realTemp);
71+
72+
73+
//Read the pressure data highest 3 bits:
74+
byte pressure_data_high = readRegister(0x1F, 1);
75+
pressure_data_high &= 0b00000111; //you only needs bits 2 to 0
76+
77+
//Read the pressure data lower 16 bits:
78+
unsigned int pressure_data_low = readRegister(0x20, 2);
79+
//combine the two parts into one 19-bit number:
80+
long pressure = ((pressure_data_high << 16) | pressure_data_low) / 4;
81+
82+
// display the temperature:
83+
Serial.println("\tPressure [Pa]=" + String(pressure));
84+
}
85+
}
86+
87+
//Read from or write to register from the SCP1000:
88+
unsigned int readRegister(byte thisRegister, int bytesToRead ) {
89+
byte inByte = 0; // incoming byte from the SPI
90+
unsigned int result = 0; // result to return
91+
Serial.print(thisRegister, BIN);
92+
Serial.print("\t");
93+
// SCP1000 expects the register name in the upper 6 bits
94+
// of the byte. So shift the bits left by two bits:
95+
thisRegister = thisRegister << 2;
96+
// now combine the address and the command into one byte
97+
byte dataToSend = thisRegister & READ;
98+
Serial.println(thisRegister, BIN);
99+
// take the chip select low to select the device:
100+
digitalWrite(chipSelectPin, LOW);
101+
// send the device the register you want to read:
102+
SPI.transfer(dataToSend);
103+
// send a value of 0 to read the first byte returned:
104+
result = SPI.transfer(0x00);
105+
// decrement the number of bytes left to read:
106+
bytesToRead--;
107+
// if you still have another byte to read:
108+
if (bytesToRead > 0) {
109+
// shift the first byte left, then get the second byte:
110+
result = result << 8;
111+
inByte = SPI.transfer(0x00);
112+
// combine the byte you just got with the previous one:
113+
result = result | inByte;
114+
// decrement the number of bytes left to read:
115+
bytesToRead--;
116+
}
117+
// take the chip select high to de-select:
118+
digitalWrite(chipSelectPin, HIGH);
119+
// return the result:
120+
return(result);
121+
}
122+
123+
124+
//Sends a write command to SCP1000
125+
126+
void writeRegister(byte thisRegister, byte thisValue) {
127+
128+
// SCP1000 expects the register address in the upper 6 bits
129+
// of the byte. So shift the bits left by two bits:
130+
thisRegister = thisRegister << 2;
131+
// now combine the register address and the command into one byte:
132+
byte dataToSend = thisRegister | WRITE;
133+
134+
// take the chip select low to select the device:
135+
digitalWrite(chipSelectPin, LOW);
136+
137+
SPI.transfer(dataToSend); //Send register location
138+
SPI.transfer(thisValue); //Send value to record into register
139+
140+
// take the chip select high to de-select:
141+
digitalWrite(chipSelectPin, HIGH);
142+
}
143+

0 commit comments

Comments
 (0)