Contiki-NG
Toggle main menu visibility
Loading...
Searching...
No Matches
spi-arch.c
Go to the documentation of this file.
1
/*
2
* Copyright (c) 2018, Texas Instruments Incorporated - http://www.ti.com/
3
* All rights reserved.
4
*
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions
7
* are met:
8
* 1. Redistributions of source code must retain the above copyright
9
* notice, this list of conditions and the following disclaimer.
10
* 2. Redistributions in binary form must reproduce the above copyright
11
* notice, this list of conditions and the following disclaimer in the
12
* documentation and/or other materials provided with the distribution.
13
* 3. Neither the name of the copyright holder nor the names of its
14
* contributors may be used to endorse or promote products derived
15
* from this software without specific prior written permission.
16
*
17
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28
* OF THE POSSIBILITY OF SUCH DAMAGE.
29
*/
30
/**
31
* \addtogroup cc13xx-cc26xx-cpu
32
* @{
33
*
34
* \defgroup cc13xx-cc26xx-spi CC13xx/CC26xx SPI HAL
35
*
36
* @{
37
* \file
38
* Implementation of the SPI HAL driver for CC13xx/CC26xx.
39
* \author
40
* Edvard Pettersen <e.pettersen@ti.com>
41
*/
42
/*---------------------------------------------------------------------------*/
43
#include "contiki.h"
44
#include "
sys/cc.h
"
45
#include "
dev/spi.h
"
46
/*---------------------------------------------------------------------------*/
47
#include <ti/drivers/SPI.h>
48
#include <ti/drivers/dpl/HwiP.h>
49
#include <ti/drivers/pin/PINCC26XX.h>
50
/*---------------------------------------------------------------------------*/
51
#include <stdbool.h>
52
#include <stddef.h>
53
#include <stdint.h>
54
/*---------------------------------------------------------------------------*/
55
typedef
struct
{
56
SPI_Handle handle;
57
const
spi_device_t
*owner;
58
} spi_arch_t;
59
/*---------------------------------------------------------------------------*/
60
#if (SPI_CONTROLLER_COUNT > 0)
61
static
spi_arch_t spi_arches[SPI_CONTROLLER_COUNT];
62
#else
63
static
spi_arch_t *spi_arches = NULL;
64
#endif
65
/*---------------------------------------------------------------------------*/
66
static
inline
spi_arch_t *
67
get_handle(uint8_t spi_controller)
68
{
69
if
(spi_controller < SPI_CONTROLLER_COUNT) {
70
return
&spi_arches[spi_controller];
71
}
else
{
72
return
NULL;
73
}
74
}
75
/*---------------------------------------------------------------------------*/
76
static
SPI_FrameFormat
77
convert_frame_format(uint8_t pol, uint8_t pha)
78
{
79
pol = (pol) ? 1 : 0;
80
pha = (pha) ? 1 : 0;
81
/*
82
* Convert pol/pha to a single byte on the following format:
83
* xxxA xxxB
84
* where A is the polarity bit and B is the phase bit.
85
* Note that any other value deviating from this format will
86
* default to the SPI_POL1_PHA1 format.
87
*/
88
uint8_t pol_pha = (pol << 4) | (pha << 0);
89
switch
(pol_pha) {
90
case
0x00:
return
SPI_POL0_PHA0;
91
case
0x01:
return
SPI_POL0_PHA1;
92
case
0x10:
return
SPI_POL1_PHA0;
93
default
:
/* fallthrough */
94
case
0x11:
return
SPI_POL1_PHA1;
95
}
96
}
97
/*---------------------------------------------------------------------------*/
98
bool
99
spi_arch_has_lock
(
const
spi_device_t
*dev)
100
{
101
/*
102
* The SPI device is the owner if the SPI controller returns a valid
103
* SPI arch object and the SPI device is owner of that object.
104
*/
105
spi_arch_t *spi_arch = get_handle(dev->spi_controller);
106
return
(spi_arch != NULL) && (spi_arch->owner == dev);
107
}
108
/*---------------------------------------------------------------------------*/
109
bool
110
spi_arch_is_bus_locked
(
const
spi_device_t
*dev)
111
{
112
/*
113
* The SPI controller is locked by any device if the SPI controller returns
114
* a valid SPI arch object and the SPI handle of that object is valid.
115
*/
116
spi_arch_t *spi_arch = get_handle(dev->spi_controller);
117
return
(spi_arch != NULL) && (spi_arch->handle != NULL);
118
}
119
/*---------------------------------------------------------------------------*/
120
spi_status_t
121
spi_arch_lock_and_open
(
const
spi_device_t
*dev)
122
{
123
uint_least8_t spi_index;
124
spi_arch_t *spi_arch;
125
SPI_Params spi_params;
126
127
const
uintptr_t hwi_key = HwiP_disable();
128
129
spi_index = dev->spi_controller;
130
spi_arch = get_handle(spi_index);
131
132
/* Ensure the provided SPI index is valid. */
133
if
(spi_arch == NULL) {
134
HwiP_restore(hwi_key);
135
return
SPI_DEV_STATUS_EINVAL;
136
}
137
138
/* Ensure the corresponding SPI interface is not already locked. */
139
if
(
spi_arch_is_bus_locked
(dev)) {
140
HwiP_restore(hwi_key);
141
return
SPI_DEV_STATUS_BUS_LOCKED;
142
}
143
144
SPI_Params_init(&spi_params);
145
146
spi_params.transferMode = SPI_MODE_BLOCKING;
147
spi_params.mode = SPI_MASTER;
148
spi_params.bitRate = dev->spi_bit_rate;
149
spi_params.dataSize = 8;
150
spi_params.frameFormat = convert_frame_format(dev->spi_pol, dev->spi_pha);
151
152
/*
153
* Try to open the SPI driver. Accessing the SPI driver also ensures
154
* atomic access to the SPI interface.
155
*/
156
spi_arch->handle = SPI_open(spi_index, &spi_params);
157
158
if
(spi_arch->handle == NULL) {
159
HwiP_restore(hwi_key);
160
return
SPI_DEV_STATUS_BUS_LOCKED;
161
}
162
163
spi_arch->owner = dev;
164
165
HwiP_restore(hwi_key);
166
return
SPI_DEV_STATUS_OK;
167
}
168
/*---------------------------------------------------------------------------*/
169
spi_status_t
170
spi_arch_close_and_unlock
(
const
spi_device_t
*dev)
171
{
172
spi_arch_t *spi_arch;
173
174
const
uintptr_t hwi_key = HwiP_disable();
175
176
/* Ensure the provided SPI index is valid. */
177
spi_arch = get_handle(dev->spi_controller);
178
if
(spi_arch == NULL) {
179
HwiP_restore(hwi_key);
180
return
SPI_DEV_STATUS_EINVAL;
181
}
182
183
/* Ensure the corresponding SPI device owns the SPI controller. */
184
if
(!
spi_arch_has_lock
(dev)) {
185
HwiP_restore(hwi_key);
186
return
SPI_DEV_STATUS_BUS_NOT_OWNED;
187
}
188
189
SPI_close(spi_arch->handle);
190
191
spi_arch->handle = NULL;
192
spi_arch->owner = NULL;
193
194
HwiP_restore(hwi_key);
195
return
SPI_DEV_STATUS_OK;
196
}
197
/*---------------------------------------------------------------------------*/
198
spi_status_t
199
spi_arch_transfer
(
const
spi_device_t
*dev,
200
const
uint8_t *write_buf,
int
wlen,
201
uint8_t *inbuf,
int
rlen,
int
ignore_len)
202
{
203
spi_arch_t *spi_arch;
204
size_t
totlen;
205
SPI_Transaction spi_transaction;
206
bool
transfer_ok;
207
208
/* Ensure the provided SPI index is valid. */
209
spi_arch = get_handle(dev->spi_controller);
210
if
(spi_arch == NULL) {
211
return
SPI_DEV_STATUS_EINVAL;
212
}
213
214
if
(!
spi_arch_has_lock
(dev)) {
215
return
SPI_DEV_STATUS_BUS_NOT_OWNED;
216
}
217
218
totlen = MAX((
size_t
)(rlen + ignore_len), (
size_t
)wlen);
219
220
if
(totlen == 0) {
221
/* Nothing to do */
222
return
SPI_DEV_STATUS_OK;
223
}
224
225
spi_transaction.count = totlen;
226
spi_transaction.txBuf = (
void
*)write_buf;
227
spi_transaction.rxBuf = (
void
*)inbuf;
228
229
transfer_ok = SPI_transfer(spi_arch->handle, &spi_transaction);
230
231
if
(!transfer_ok) {
232
return
SPI_DEV_STATUS_TRANSFER_ERR;
233
}
234
235
return
SPI_DEV_STATUS_OK;
236
}
237
/*---------------------------------------------------------------------------*/
238
/**
239
* @}
240
* @}
241
*/
cc.h
Default definitions of C compiler quirk work-arounds.
spi_device_t
struct spi_device spi_device_t
SPI Device Configuration.
spi_arch_close_and_unlock
spi_status_t spi_arch_close_and_unlock(const spi_device_t *dev)
Closes and unlocks an SPI controller.
Definition
spi-arch.c:268
spi_arch_transfer
spi_status_t spi_arch_transfer(const spi_device_t *dev, const uint8_t *write_buf, int wlen, uint8_t *inbuf, int rlen, int ignore_len)
Performs an SPI transfer.
Definition
spi-arch.c:286
spi_status_t
spi_status_t
SPI return codes.
Definition
spi.h:80
spi_arch_lock_and_open
spi_status_t spi_arch_lock_and_open(const spi_device_t *dev)
Locks and opens an SPI controller to the configuration specified.
Definition
spi-arch.c:171
spi_arch_has_lock
bool spi_arch_has_lock(const spi_device_t *dev)
Checks if a device has locked an SPI controller.
Definition
spi-arch.c:151
spi_arch_is_bus_locked
bool spi_arch_is_bus_locked(const spi_device_t *dev)
Checks if an SPI controller is locked by any device.
Definition
spi-arch.c:161
spi.h
Header file for the SPI HAL.
arch
cpu
simplelink-cc13xx-cc26xx
dev
spi-arch.c
Generated on
for Contiki-NG by
1.17.0