forked from lowRISC/opentitan
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdif_spi_host.h
210 lines (193 loc) · 6.02 KB
/
dif_spi_host.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
204
205
206
207
208
209
210
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
#ifndef OPENTITAN_SW_DEVICE_LIB_DIF_DIF_SPI_HOST_H_
#define OPENTITAN_SW_DEVICE_LIB_DIF_DIF_SPI_HOST_H_
/**
* @file
* @brief <a href="/hw/ip/spi_host/doc/">SPI Host</a> Device Interface Functions
*/
#include <stdint.h>
#include "sw/device/lib/dif/autogen/dif_spi_host_autogen.h"
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
/**
* Runtime configuration for SPI Host.
*
* This struct describes (SOFTWARE) runtime information for one-time
* configuration of the hardware.
*/
typedef struct dif_spi_host_config {
/** Desired SPI clock frequency (SCK). */
uint32_t spi_clock;
/** Peripheral clock frequency (ie: kClockFreqPeripheralHz). */
uint32_t peripheral_clock_freq_hz;
struct {
/** Minimum idle time between commands in SCK half-cycles. */
uint8_t idle;
/** Chip-select trailing time in SCK half-cycles. */
uint8_t trail;
/** Chip-select leading time in SCK half-cycles. */
uint8_t lead;
} chip_select;
/** Full-cycle sampling mode. */
bool full_cycle;
/** SPI clock phase. */
bool cpha;
/** SPI clock polarity. */
bool cpol;
} dif_spi_host_config_t;
/**
* Width of SPI operations.
*/
typedef enum dif_spi_host_width {
/** Standard SPI mode (single lanes for send and recv). */
kDifSpiHostWidthStandard = 0,
/** Dual SPI mode (use two lanes for send and recv). */
kDifSpiHostWidthDual = 1,
/** Quad SPI mode (use four lanes for send and recv). */
kDifSpiHostWidthQuad = 2,
} dif_spi_host_width_t;
/**
* Direction of SPI operations.
*
* This describes which direction a given SPI operation will use.
*/
typedef enum dif_spi_host_direction {
/** The SPI host neither transmits or receives. */
kDifSpiHostDirectionDummy = 0,
/** The SPI host receives data. */
kDifSpiHostDirectionRx = 1,
/** The SPI host transmits data. */
kDifSpiHostDirectionTx = 2,
/** The SPI host transmits and receives data. */
kDifSpiHostDirectionBidirectional = 3,
} dif_spi_host_direction_t;
/**
* Segment types for segments in a transaction.
*/
typedef enum dif_spi_host_segment_type {
/** The segment is a SPI opcode. */
kDifSpiHostSegmentTypeOpcode,
/** The segment is a SPI address. */
kDifSpiHostSegmentTypeAddress,
/** The segment is a SPI dummy cycle. */
kDifSpiHostSegmentTypeDummy,
/** The segment is a SPI transmit (from a memory buffer). */
kDifSpiHostSegmentTypeTx,
/** The segment is a SPI receive (into a memory buffer). */
kDifSpiHostSegmentTypeRx,
/** The segment is a simultaneous transmit and receieve. */
kDifSpiHostSegmentTypeBidirectional,
} dif_spi_host_segment_type_t;
/**
* Address mode for the address segment in a transaction.
*/
typedef enum dif_spi_host_addr_mode {
/** The address is a 3-byte address. */
kDifSpiHostAddrMode3b,
/** The address is a 4-byte address. */
kDifSpiHostAddrMode4b,
} dif_spi_host_addr_mode_t;
/**
* Segment descriptor for each segment in a transaction.
*
* This struct is a tagged union: the `type` field determines
* which field of the union is relevant.
*/
typedef struct dif_spi_host_segment {
/** The segment type for this segment. */
dif_spi_host_segment_type_t type;
union {
uint8_t opcode;
struct {
dif_spi_host_width_t width;
dif_spi_host_addr_mode_t mode;
uint32_t address;
} address;
struct {
dif_spi_host_width_t width;
size_t length;
} dummy;
struct {
dif_spi_host_width_t width;
const void *buf;
size_t length;
} tx;
struct {
dif_spi_host_width_t width;
void *buf;
size_t length;
} rx;
struct {
dif_spi_host_width_t width;
const void *txbuf;
void *rxbuf;
size_t length;
} bidir;
};
} dif_spi_host_segment_t;
/**
* Configures SPI Host with runtime information.
*
* This function should only need to be called once for the lifetime of
* `handle`.
*
* @param spi_host A SPI Host handle.
* @param config Runtime configuration parameters.
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
dif_result_t dif_spi_host_configure(const dif_spi_host_t *spi_host,
dif_spi_host_config_t config);
/**
* Sets the enablement of the SPI host output buffers.
*
* @param spi_host A SPI Host handle.
* @param enabled Enable or disable the output buffers.
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
dif_result_t dif_spi_host_output_set_enabled(const dif_spi_host_t *spi_host,
bool enabled);
/**
* Write to the SPI Host transmit FIFO.
*
* @param spi_host A SPI Host handle.
* @param src A pointer to the buffer to transmit.
* @param len The length of the transmit buffer.
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
dif_result_t dif_spi_host_fifo_write(const dif_spi_host_t *spi_host,
const void *src, uint16_t len);
/**
* Read from the SPI Host receive FIFO.
*
* @param spi_host A SPI Host handle.
* @param dst A pointer to the buffer to receive the data.
* @param len The length of the receive buffer.
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
dif_result_t dif_spi_host_fifo_read(const dif_spi_host_t *spi_host, void *dst,
uint16_t len);
/**
* Begins a SPI Host transaction.
*
* @param spi_host A SPI Host handle.
* @param csid The chip-select ID of the SPI target.
* @param segments The SPI segments to send in this transaction.
* @param length The number of SPI segments in this transaction.
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
dif_result_t dif_spi_host_transaction(const dif_spi_host_t *spi_host,
uint32_t csid,
dif_spi_host_segment_t *segments,
size_t length);
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
#endif // OPENTITAN_SW_DEVICE_LIB_DIF_DIF_SPI_HOST_H_