forked from bcmi-labs/arduino-core-stm32f4
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathSPI.h
203 lines (168 loc) · 6.23 KB
/
SPI.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
/*
* Copyright (c) 2010 by Cristian Maglie <[email protected]>
* Copyright (c) 2014 by Paul Stoffregen <[email protected]> (Transaction API)
* Copyright (c) 2014 by Matthijs Kooijman <[email protected]> (SPISettings AVR)
* Copyright (c) 2014 by Andrew J. Kroll <[email protected]> (atomicity fixes)
* SPI Master library for arduino.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of either the GNU General Public License version 2
* or the GNU Lesser General Public License version 2.1, both as
* published by the Free Software Foundation.
*/
/*
* Arduino srl - www.arduino.org
* 2016 Jun 9: Edited Francesco Alessi (alfran) - [email protected]
*/
#ifndef _SPI_H_INCLUDED
#define _SPI_H_INCLUDED
#include <Arduino.h>
#define SPI2_CLK_ENABLE() __HAL_RCC_SPI2_CLK_ENABLE()
#define SPI2_SCK_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE()
#define SPI2_MISO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
#define SPI2_MOSI_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE()
#define SPI2_FORCE_RESET() __HAL_RCC_SPI2_FORCE_RESET()
#define SPI2_RELEASE_RESET() __HAL_RCC_SPI2_RELEASE_RESET()
/* Definition for SPI2 Pins */
#define SPI2_SCK_PIN GPIO_PIN_3
#define SPI2_SCK_GPIO_PORT GPIOD
#define SPI2_SCK_AF GPIO_AF5_SPI2
#define SPI2_MISO_PIN GPIO_PIN_14
#define SPI2_MISO_GPIO_PORT GPIOB
#define SPI2_MISO_AF GPIO_AF5_SPI2
#define SPI2_MOSI_PIN GPIO_PIN_3
#define SPI2_MOSI_GPIO_PORT GPIOC
#define SPI2_MOSI_AF GPIO_AF5_SPI2
#define SPI1_CLK_ENABLE() __HAL_RCC_SPI1_CLK_ENABLE()
#define SPI1_SCK_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
#define SPI1_MISO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
#define SPI1_MOSI_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
#define SPI1_NSS_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
#define SPI1_FORCE_RESET() __HAL_RCC_SPI1_FORCE_RESET()
#define SPI1_RELEASE_RESET() __HAL_RCC_SPI1_RELEASE_RESET()
/* Definition for SPI2 Pins */
#define SPI1_SCK_PIN GPIO_PIN_3
#define SPI1_SCK_GPIO_PORT GPIOB
#define SPI1_SCK_AF GPIO_AF5_SPI1
#define SPI1_MISO_PIN GPIO_PIN_4
#define SPI1_MISO_GPIO_PORT GPIOB
#define SPI1_MISO_AF GPIO_AF5_SPI1
#define SPI1_MOSI_PIN GPIO_PIN_5
#define SPI1_MOSI_GPIO_PORT GPIOB
#define SPI1_MOSI_AF GPIO_AF5_SPI1
#define SPI1_NSS_PIN GPIO_PIN_15
#define SPI1_NSS_GPIO_PORT GPIOA
#define SPI1_NSS_AF GPIO_AF5_SPI1
#ifndef LSBFIRST
#define LSBFIRST 0
#endif
#ifndef MSBFIRST
#define MSBFIRST 1
#endif
#define SPI_CLOCK_DIV2 SPI_BAUDRATEPRESCALER_2
#define SPI_CLOCK_DIV4 SPI_BAUDRATEPRESCALER_4
#define SPI_CLOCK_DIV8 SPI_BAUDRATEPRESCALER_8
#define SPI_CLOCK_DIV16 SPI_BAUDRATEPRESCALER_16
#define SPI_CLOCK_DIV32 SPI_BAUDRATEPRESCALER_32
#define SPI_CLOCK_DIV64 SPI_BAUDRATEPRESCALER_64
#define SPI_CLOCK_DIV128 SPI_BAUDRATEPRESCALER_128
#define SPI_CLOCK_DIV256 SPI_BAUDRATEPRESCALER_256
#define SPI_MODE0 0x00
#define SPI_MODE1 0x04
#define SPI_MODE2 0x08
#define SPI_MODE3 0x0C
enum SPITransferMode {
SPI_CONTINUE,
SPI_LAST
};
class SPISettings {
public:
SPISettings(uint32_t clock, uint8_t bitOrder, uint8_t dataMode)
{
init_AlwaysInline(clock, bitOrder, dataMode);
}
SPISettings()
{
init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0);
}
private:
void init_AlwaysInline(uint32_t clock, uint8_t bitOrder, uint8_t dataMode)
__attribute__((__always_inline__)) {
/* Select the Bit Order */
if(bitOrder == LSBFIRST)
{
FirstBit = SPI_FIRSTBIT_LSB;
}
else
{
FirstBit = SPI_FIRSTBIT_MSB;
}
/* Select the SPI Communication Mode */
if(dataMode == SPI_MODE0)
{
CLKPhase = SPI_PHASE_1EDGE;
CLKPolarity = SPI_POLARITY_LOW;
}
else if(dataMode == SPI_MODE1)
{
CLKPhase = SPI_PHASE_2EDGE;
CLKPolarity = SPI_POLARITY_LOW;
}
else if(dataMode == SPI_MODE2)
{
CLKPhase = SPI_PHASE_1EDGE;
CLKPolarity = SPI_POLARITY_HIGH;
}
else
{
CLKPhase = SPI_PHASE_2EDGE;
CLKPolarity = SPI_POLARITY_HIGH;
}
/* Select the Clock Divider */
BaudRatePrescaler = (((HAL_RCC_GetPCLK1Freq()) / 2 ) < clock) ? SPI_CLOCK_DIV2
: (((HAL_RCC_GetPCLK1Freq()) / 4 ) < clock) ? SPI_CLOCK_DIV4
: (((HAL_RCC_GetPCLK1Freq()) / 8 ) < clock) ? SPI_CLOCK_DIV8
: (((HAL_RCC_GetPCLK1Freq()) / 16 ) < clock) ? SPI_CLOCK_DIV16
: (((HAL_RCC_GetPCLK1Freq()) / 32 ) < clock) ? SPI_CLOCK_DIV32
: (((HAL_RCC_GetPCLK1Freq()) / 64 ) < clock) ? SPI_CLOCK_DIV64
: (((HAL_RCC_GetPCLK1Freq()) / 128) < clock) ? SPI_CLOCK_DIV128
: SPI_CLOCK_DIV256;
}
uint32_t FirstBit;
uint32_t CLKPhase;
uint32_t CLKPolarity;
uint32_t BaudRatePrescaler;
friend class SPIClass;
};
class SPIClass {
public:
/* Constructor */
SPIClass(SPI_TypeDef *spiInstance);
/* Initialize the SPI peripheral */
void begin();
/* Initialize the SPI peripheral and SS pin */
void begin(uint8_t slaveSelectPin);
/* Initialize the SPI peripheral with settings */
void beginTransaction(SPISettings settings);
/* Initialize the SPI peripheral */
void endTransaction();
/* Begin the transfer */
uint8_t transfer(uint8_t data);
uint16_t transfer16(uint16_t data);
void transfer(void *buf, size_t count);
uint8_t transfer(uint8_t slaveSelectPin, uint8_t val, SPITransferMode transferMode);
/* End the transfer */
void end();
void end(uint8_t slaveSelectPin);
/* Set Bit Order */
void setBitOrder(uint8_t bitOrder);
/* Set Clock Divider */
void setClockDivider(uint8_t clockDiv);
/* Set Communication Mode */
void setDataMode(uint8_t dataMode);
private:
SPI_HandleTypeDef hSPIx;
};
extern SPIClass SPI;
extern SPIClass SPI7;
#endif