Skip to content

Commit fcb1a6a

Browse files
committed
libraries: Add SPI communication library
Signed-off-by: Ajay Bhargav <[email protected]>
1 parent fe63ec9 commit fcb1a6a

File tree

8 files changed

+536
-2
lines changed

8 files changed

+536
-2
lines changed

cores/siwigsm/wiring_constants.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ extern "C"{
4444
#define DISPLAY 0x1
4545

4646
enum BitOrder {
47-
LSBFIRST = 0,
48-
MSBFIRST = 1
47+
MSBFIRST = 0,
48+
LSBFIRST = 1,
4949
};
5050

5151
// moved to WInterrupts.h

libraries/SPI/SPI.cpp

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
/*
2+
* SPI Master library for SIWI GSM Modules
3+
* Copyright (c) 2015 Arduino LLC
4+
*
5+
* This library is free software; you can redistribute it and/or
6+
* modify it under the terms of the GNU Lesser General Public
7+
* License as published by the Free Software Foundation; either
8+
* version 2.1 of the License, or (at your option) any later version.
9+
*
10+
* This library is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
* Lesser General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Lesser General Public
16+
* License along with this library; if not, write to the Free Software
17+
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18+
*
19+
* Modified by Ajay Bhargav <[email protected]>
20+
*
21+
*/
22+
23+
#include <Arduino.h>
24+
#include <assert.h>
25+
#include "SPI.h"
26+
27+
SPIClass::SPIClass(void) : settings(SPISettings(10000000, MSBFIRST, SPI_MODE0))
28+
{
29+
initialized = false;
30+
}
31+
32+
void SPIClass::begin()
33+
{
34+
init();
35+
config(settings);
36+
}
37+
38+
void SPIClass::init()
39+
{
40+
if (initialized)
41+
return;
42+
43+
spi_hw_init(FALSE);
44+
45+
initialized = true;
46+
}
47+
48+
void SPIClass::config(SPISettings settings)
49+
{
50+
if (this->settings != settings)
51+
{
52+
this->settings = settings;
53+
54+
spi_hw_setclock(settings.clockFreq);
55+
spi_hw_setmode(settings.dataMode);
56+
spi_hw_setbyteorder(settings.bitOrder == MSBFIRST ? SPI_BYTE_MSB_FIRST : SPI_BYTE_LSB_FIRST);
57+
}
58+
}
59+
60+
void SPIClass::end()
61+
{
62+
if (initialized) {
63+
spi_hw_free();
64+
initialized = false;
65+
}
66+
}
67+
68+
void SPIClass::beginTransaction(SPISettings settings)
69+
{
70+
config(settings);
71+
}
72+
73+
void SPIClass::endTransaction(void)
74+
{
75+
}
76+
77+
void SPIClass::setBitOrder(BitOrder order)
78+
{
79+
settings.bitOrder = order;
80+
spi_hw_setbyteorder(order == MSBFIRST ? SPI_BYTE_MSB_FIRST : SPI_BYTE_LSB_FIRST);
81+
}
82+
83+
void SPIClass::setDataMode(uint8_t mode)
84+
{
85+
settings.dataMode = mode;
86+
spi_hw_setmode(mode);
87+
}
88+
89+
void SPIClass::setClockDivider(uint8_t div)
90+
{
91+
spi_hw_setclock(SPI_MAX_SPEED / div);
92+
}
93+
94+
byte SPIClass::transfer(uint8_t data)
95+
{
96+
uint32_t out_byte;
97+
98+
spi_hw_transfer(&data, (unsigned char *)&out_byte, 1);
99+
100+
return out_byte;
101+
}
102+
103+
uint16_t SPIClass::transfer16(uint16_t data)
104+
{
105+
union {
106+
uint16_t val;
107+
struct
108+
{
109+
uint8_t lsb;
110+
uint8_t msb;
111+
};
112+
} t;
113+
114+
t.val = data;
115+
116+
if (settings.bitOrder == LSBFIRST)
117+
{
118+
t.lsb = transfer(t.lsb);
119+
t.msb = transfer(t.msb);
120+
}
121+
else
122+
{
123+
t.msb = transfer(t.msb);
124+
t.lsb = transfer(t.lsb);
125+
}
126+
127+
return t.val;
128+
}
129+
130+
void SPIClass::transfer(void *buf, size_t count)
131+
{
132+
uint8_t *buffer = reinterpret_cast<uint8_t *>(buf);
133+
for (size_t i = 0; i < count; i++)
134+
{
135+
*buffer = transfer(*buffer);
136+
buffer++;
137+
}
138+
}
139+
140+
SPIClass SPI = SPIClass();

libraries/SPI/SPI.h

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
/*
2+
* SPI Master library for SIWI GSM Modules
3+
* Copyright (c) 2015 Arduino LLC
4+
*
5+
* This library is free software; you can redistribute it and/or
6+
* modify it under the terms of the GNU Lesser General Public
7+
* License as published by the Free Software Foundation; either
8+
* version 2.1 of the License, or (at your option) any later version.
9+
*
10+
* This library is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
* Lesser General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Lesser General Public
16+
* License along with this library; if not, write to the Free Software
17+
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18+
*
19+
* Modified by Ajay Bhargav <[email protected]>
20+
*
21+
*/
22+
23+
#ifndef _SPI_H_INCLUDED
24+
#define _SPI_H_INCLUDED
25+
26+
#include <Arduino.h>
27+
28+
/*
29+
* SPI_HAS_TRANSACTION means SPI has
30+
* - beginTransaction()
31+
* - endTransaction()
32+
* - SPISetting(clock, bitOrder, dataMode)
33+
*/
34+
#define SPI_HAS_TRANSACTION 1
35+
36+
#define SPI_MODE0 0
37+
#define SPI_MODE1 1
38+
#define SPI_MODE2 2
39+
#define SPI_MODE3 3
40+
41+
#define SPI_CLOCK_DIV2 2
42+
#define SPI_CLOCK_DIV4 4
43+
#define SPI_CLOCK_DIV8 8
44+
#define SPI_CLOCK_DIV16 16
45+
#define SPI_CLOCK_DIV32 32
46+
#define SPI_CLOCK_DIV64 64
47+
#define SPI_CLOCK_DIV128 128
48+
49+
class SPISettings
50+
{
51+
public:
52+
SPISettings(uint32_t clock, BitOrder bitOrder, uint8_t dataMode)
53+
{
54+
this->clockFreq = clock;
55+
this->bitOrder = bitOrder;
56+
this->dataMode = dataMode;
57+
}
58+
59+
/* Default speed set to 10MHz, SPI mode set to MODE 0 and Bit order set to MSB first. */
60+
SPISettings()
61+
{
62+
this->clockFreq = 10000000;
63+
this->bitOrder = MSBFIRST;
64+
this->dataMode = SPI_MODE0;
65+
}
66+
67+
bool operator==(const SPISettings &rhs) const
68+
{
69+
if ((this->clockFreq == rhs.clockFreq) &&
70+
(this->bitOrder == rhs.bitOrder) &&
71+
(this->dataMode == rhs.dataMode))
72+
{
73+
return true;
74+
}
75+
return false;
76+
}
77+
78+
bool operator!=(const SPISettings &rhs) const
79+
{
80+
return !(*this == rhs);
81+
}
82+
83+
void operator=(const SPISettings &rhs)
84+
{
85+
this->clockFreq = rhs.clockFreq;
86+
this->bitOrder = rhs.bitOrder;
87+
this->dataMode = rhs.dataMode;
88+
}
89+
90+
uint32_t getClockFreq() const { return clockFreq; }
91+
uint8_t getDataMode() const { return dataMode; }
92+
BitOrder getBitOrder() const { return bitOrder; }
93+
94+
private:
95+
uint32_t clockFreq;
96+
uint8_t dataMode;
97+
BitOrder bitOrder;
98+
99+
friend class SPIClass;
100+
};
101+
102+
const SPISettings DEFAULT_SPI_SETTINGS = SPISettings();
103+
104+
class SPIClass
105+
{
106+
public:
107+
SPIClass();
108+
109+
byte transfer(uint8_t data);
110+
uint16_t transfer16(uint16_t data);
111+
void transfer(void *buf, size_t count);
112+
113+
/* Transaction Functions */
114+
void usingInterrupt(int interruptNumber);
115+
void notUsingInterrupt(int interruptNumber);
116+
void beginTransaction(SPISettings settings);
117+
void endTransaction(void);
118+
119+
void begin();
120+
void end();
121+
122+
void setBitOrder(BitOrder order);
123+
void setDataMode(uint8_t uc_mode);
124+
void setClockDivider(uint8_t uc_div);
125+
126+
private:
127+
void init();
128+
void config(SPISettings settings);
129+
130+
SPISettings settings;
131+
bool initialized;
132+
int chip_select;
133+
};
134+
135+
extern SPIClass SPI;
136+
137+
#endif

0 commit comments

Comments
 (0)