px-fwlib 0.10.0
Cross-platform embedded library and documentation for 8/16/32-bit microcontrollers generated with Doxygen 1.9.2
px_i2c.h
1#ifndef __PX_I2C_H__
2#define __PX_I2C_H__
3/* =============================================================================
4 ____ ___ ____ ___ _ _ ___ __ __ ___ __ __ TM
5 | _ \ |_ _| / ___| / _ \ | \ | | / _ \ | \/ | |_ _| \ \/ /
6 | |_) | | | | | | | | | | \| | | | | | | |\/| | | | \ /
7 | __/ | | | |___ | |_| | | |\ | | |_| | | | | | | | / \
8 |_| |___| \____| \___/ |_| \_| \___/ |_| |_| |___| /_/\_\
9
10 Copyright (c) 2018 Pieter Conradie <https://piconomix.com>
11
12 License: MIT
13 https://github.com/piconomix/px-fwlib/blob/master/LICENSE.md
14
15 Title: px_i2c.h : I2C peripheral driver
16 Author(s): Pieter Conradie
17 Creation Date: 2018-03-15
18
19============================================================================= */
20
21/**
22 * @ingroup STM32
23 * @defgroup STM32_I2C px_i2c.h : I2C peripheral driver
24 *
25 * Driver to communicate with I2C slaves.
26 *
27 * File(s):
28 * - arch/arm/stm32/inc/px_i2c.h
29 * - arch/arm/stm32/inc/px_i2c_cfg_template.h
30 * - arch/arm/stm32/src/px_i2c.c
31 *
32 * The driver must be configured by supplying a project specific "px_i2c_cfg.h".
33 * "px_i2c_cfg_template.h" can be copied, renamed and modified to supply
34 * compile time options.
35 *
36 * @par Example:
37 * @include arch/arm/stm32/test/px_i2c_test.c
38 *
39 * @{
40 */
41
42/* _____STANDARD INCLUDES____________________________________________________ */
43
44/* _____PROJECT INCLUDES_____________________________________________________ */
45#include "px_defs.h"
46
47// Include project specific configuration. See "px_i2c_cfg_template.h"
48#include "px_i2c_cfg.h"
49
50// Check that all project specific options have been specified in "px_i2c_cfg.h"
51#if ( !defined(PX_I2C_CFG_I2C1_EN ) \
52 || !defined(PX_I2C_CFG_I2C2_EN ) \
53 || !defined(PX_I2C_CFG_TIMINGR) )
54#error "One or more options not defined in 'px_i2c_cfg.h'"
55#endif
56#if ( (PX_I2C_CFG_I2C1_EN > 1) \
57 || (PX_I2C_CFG_I2C2_EN > 1) )
58#error "PX_I2C_CFG_I2Cx_EN must be 0 or 1"
59#endif
60
61/// Number of enabled peripherals
62#define PX_I2C_CFG_PER_COUNT ( PX_I2C_CFG_I2C1_EN \
63 + PX_I2C_CFG_I2C2_EN )
64#if (PX_I2C_CFG_PER_COUNT == 0)
65#error "No peripherals enabled"
66#endif
67
68#ifdef __cplusplus
69extern "C" {
70#endif
71/* _____DEFINITIONS__________________________________________________________ */
72
73/* _____TYPE DEFINITIONS_____________________________________________________ */
74/// Specify I2C peripheral
75typedef enum
76{
77 PX_I2C_NR_1 = 1,
78 PX_I2C_NR_2 = 2,
80
81/// @name I2C bit flags to demarcate the start and end of a transaction
82/// @{
83
84/// Begin I2C transaction with a START condition
85#define PX_I2C_FLAG_START (1 << 0)
86/// Finish I2C transaction with a STOP condition
87#define PX_I2C_FLAG_STOP (1 << 1)
88/// Signal END of current I2C transaction for REP_START to follow
89#define PX_I2C_FLAG_END (1 << 2)
90/// Begin I2C transaction with a REPEATED START condition
91#define PX_I2C_FLAG_REP_START (1 << 3)
92/// Begin and finish an I2C transaction with a START and STOP condition
93#define PX_I2C_FLAG_START_AND_STOP (PX_I2C_FLAG_START + PX_I2C_FLAG_STOP)
94/// Begin and finish an I2C transaction with a START and END condition
95#define PX_I2C_FLAG_START_AND_END (PX_I2C_FLAG_START + PX_I2C_FLAG_END)
96/// Begin and finish an I2C transaction with a REP START and STOP condition
97#define PX_I2C_FLAG_REP_START_AND_STOP (PX_I2C_FLAG_REP_START + PX_I2C_FLAG_STOP)
98/// Begin and finish an I2C transaction with a REP START and END condition
99#define PX_I2C_FLAG_REP_START_AND_END (PX_I2C_FLAG_REP_START + PX_I2C_FLAG_END)
100/// @}
101
102/// Define I2C handle for a slave
103typedef struct
104{
105 struct px_i2c_per_s * i2c_per; ///< I2C peripheral data
106 uint8_t slave_adr; ///< 7-bit I2C slave address
108
109/* _____GLOBAL VARIABLES_____________________________________________________ */
110
111/* _____GLOBAL FUNCTION DECLARATIONS_________________________________________ */
112/**
113 * Initialise I2C driver.
114 */
115void px_i2c_init(void);
116
117/**
118 * Open I2C slave handle.
119 *
120 * @param handle Pointer to handle data structure
121 * @param i2c_nr I2C peripheral number
122 * @param slave_adr 7-bit I2C slave address
123 *
124 * @retval false Error - handle was not opened
125 * @retval true Success - handle was opened
126 */
127bool px_i2c_open(px_i2c_handle_t * handle,
128 px_i2c_nr_t i2c_nr,
129 uint8_t slave_adr);
130
131/**
132 * Close specified handle.
133 *
134 * @param handle Pointer to handle data structure
135 *
136 * @retval true Success
137 * @retval false Specified handle was already closed (or not opened)
138 */
139bool px_i2c_close(px_i2c_handle_t * handle);
140
141/**
142 * Perform an I2C write transaction with an I2C slave.
143 *
144 * With the use of flags this function allows concatenation of one or more
145 * writes to an I2C slave to form one big write transaction. It is also
146 * possible to generate a REPEATED START (RESTART) condition by not generating
147 * an intervening STOP condition.
148 *
149 * If the PX_I2C_FLAG_START flag is specified, a START condition is generated
150 * and the 7-bit slave address and WRITE bit is sent on the bus (SLA+W). If a
151 * NAK is received, a STOP condition is generated to return the I2C bus to idle
152 * state.
153 *
154 * The specified number of bytes is sent with the slave supposed to ACK each
155 * byte. If a NAK is received, a STOP condition is generated to return the I2C
156 * bus to idle state.
157 *
158 * If the PX_I2C_FLAG_STOP flag is specified, a STOP condition is generated to
159 * complete the transaction and return the I2C bus to the idle state.
160 *
161 * More than one I2C transaction may be concatenated without releasing the I2C
162 * bus by using a REPEATED START condition. This is acheived by signalling the
163 * end of the current transaction with the PX_I2C_FLAG_END flag and starting
164 * the next transaction with a PX_I2C_FLAG_REP_START flag.
165 *
166 * @param handle Pointer to handle data structure
167 * @param data Buffer containing data to write
168 * @param nr_of_bytes Number of bytes to write to the slave
169 * @param flags Bit combination of PX_I2C_FLAG_START,
170 * PX_I2C_FLAG_STOP, PX_I2C_FLAG_REP_START, PX_I2C_FLAG_END
171 * or nothing (0)
172 *
173 * @retval true Slave ACK'd all bytes written to it
174 * @retval false Received a NAK or bus error
175 */
176bool px_i2c_wr(px_i2c_handle_t * handle,
177 const void * data,
178 size_t nr_of_bytes,
179 uint8_t flags);
180
181/**
182 * Perform an I2C read transaction with an I2C slave.
183 *
184 * With the use of flags this function allows concatenation of one or more
185 * reads from an I2C slave to form one big read transaction. It is also
186 * possible to generate a REPEATED START (RESTART) condition by not generating
187 * an intervening STOP condition.
188 *
189 * If the PX_I2C_FLAG_START flag is specified, A START condition is generated
190 * and the 7-bit slave address and READ bit is sent on the bus (SLA+R).
191 * If a NAK is received, a STOP condition is generated to return the I2C bus to
192 * idle state.
193 *
194 * The specified number of bytes is read from the slave and each byte is
195 * ACKed, except the last one. If the PX_I2C_FLAG_STOP or PX_I2C_FLAG_END flag
196 * is specified, the last byte is NAKed to indicate to the I2C slave that this
197 * is the end of the read transaction, otherwise it is also ACKed to allow the
198 * read transaction to continue.
199 *
200 * If the PX_I2C_FLAG_STOP flag is specified, a STOP condition is generated to
201 * complete the transaction and return the I2C bus to the idle state.
202 *
203 * More than one I2C transaction may be concatenated without releasing the I2C
204 * bus by using a REPEATED START condition. This is acheived by signalling the
205 * end of the current transaction with the PX_I2C_FLAG_END flag and starting
206 * the next transaction with a PX_I2C_FLAG_REP_START flag.
207 *
208 * @param handle Pointer to handle data structure
209 * @param data Pointer to a buffer where the received data must be
210 * stored
211 * @param nr_of_bytes Number of bytes to read from slave
212 * @param flags Bit combination of PX_I2C_FLAG_START,
213 * PX_I2C_FLAG_STOP, PX_I2C_FLAG_REP_START,
214 * PX_I2C_FLAG_END or nothing (0)
215 *
216 * @retval true Byte(s) succesfully read
217 * @retval false Received NAK or bus error
218 */
219bool px_i2c_rd(px_i2c_handle_t * handle,
220 void * data,
221 size_t nr_of_bytes,
222 uint8_t flags);
223
224/**
225 * Change I2C slave address.
226 *
227 * @param handle Pointer to handle data structure
228 * @param slave_adr New 7-bit I2C slave address
229 */
231 uint8_t slave_adr);
232
233/* _____MACROS_______________________________________________________________ */
234
235#ifdef __cplusplus
236}
237#endif
238
239/// @}
240#endif
uint8_t slave_adr
7-bit I2C slave address
Definition: px_i2c.h:106
struct px_i2c_per_s * i2c_per
I2C peripheral data.
Definition: px_i2c.h:105
bool px_i2c_close(px_i2c_handle_t *handle)
Close specified handle.
Definition: px_i2c.c:184
void px_i2c_init(void)
Initialise I2C driver.
Definition: px_i2c.c:107
bool px_i2c_open(px_i2c_handle_t *handle, px_i2c_nr_t i2c_nr, uint8_t slave_adr)
Open I2C slave handle.
Definition: px_i2c.c:118
px_i2c_nr_t
Specify I2C peripheral.
Definition: px_i2c.h:76
bool px_i2c_rd(px_i2c_handle_t *handle, void *data, size_t nr_of_bytes, uint8_t flags)
Perform an I2C read transaction with an I2C slave.
Definition: px_i2c.c:430
void px_i2c_change_slave_adr(px_i2c_handle_t *handle, uint8_t slave_adr)
Change I2C slave address.
Definition: px_i2c.c:615
bool px_i2c_wr(px_i2c_handle_t *handle, const void *data, size_t nr_of_bytes, uint8_t flags)
Perform an I2C write transaction with an I2C slave.
Definition: px_i2c.c:240
Define I2C handle for a slave.
Definition: px_i2c.h:104