1 /**
2 *
3 * \file
4 *
5 * \brief This module contains NMC1000 I2C protocol bus APIs implementation.
6 *
7 * Copyright (c) 2016 Atmel Corporation. All rights reserved.
8 *
9 * \asf_license_start
10 *
11 * \page License
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions are met:
15 *
16 * 1. Redistributions of source code must retain the above copyright notice,
17 * this list of conditions and the following disclaimer.
18 *
19 * 2. Redistributions in binary form must reproduce the above copyright notice,
20 * this list of conditions and the following disclaimer in the documentation
21 * and/or other materials provided with the distribution.
22 *
23 * 3. The name of Atmel may not be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
27 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
28 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
29 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
30 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
34 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
35 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 *
38 * \asf_license_stop
39 *
40 */
41
42 #include "common/include/nm_common.h"
43
44 #ifdef CONF_WINC_USE_I2C
45
46 #include "nmi2c.h"
47 #include "bus_wrapper/include/nm_bus_wrapper.h"
48
49
50 /*
51 * @fn nm_i2c_read_reg_with_ret
52 * @brief Read register with error code return
53 * @param [in] u32Addr
54 * Register address
55 * @param [out] pu32RetVal
56 * Pointer to u32 variable used to return the read value
57 * @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
58 * @author M. Abdelmawla
59 * @date 11 July 2012
60 * @version 1.0
61 */
nm_i2c_read_reg_with_ret(uint32 u32Addr,uint32 * pu32RetVal)62 sint8 nm_i2c_read_reg_with_ret(uint32 u32Addr, uint32* pu32RetVal)
63 {
64 uint8 b[6];
65 uint8 rsz;
66 tstrNmI2cDefault strI2c;
67 sint8 s8Ret = M2M_SUCCESS;
68
69 if(u32Addr < 0xff) { /* clockless i2c */
70 b[0] = 0x09;
71 b[1] = (uint8)(u32Addr);
72 rsz = 1;
73 strI2c.u16Sz = 2;
74 } else {
75 b[0] = 0x80;
76 b[1] = (uint8)(u32Addr >> 24);
77 b[2] = (uint8)(u32Addr >> 16);
78 b[3] = (uint8)(u32Addr >> 8);
79 b[4] = (uint8)(u32Addr);
80 b[5] = 0x04;
81 rsz = 4;
82 strI2c.u16Sz = 6;
83 }
84
85 strI2c.pu8Buf = b;
86
87 if(M2M_SUCCESS == nm_bus_ioctl(NM_BUS_IOCTL_W, &strI2c))
88 {
89 strI2c.u16Sz = rsz;
90 if(M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_R, &strI2c))
91 {
92 //M2M_ERR("read error\n");
93 s8Ret = M2M_ERR_BUS_FAIL;
94 }
95 }
96 else
97 {
98 M2M_ERR("failed to send cfg bytes\n");
99 s8Ret = M2M_ERR_BUS_FAIL;
100 }
101
102 if (rsz == 1) {
103 *pu32RetVal = b[0];
104 } else {
105 *pu32RetVal = b[0] | ((uint32)b[1] << 8) | ((uint32)b[2] << 16) | ((uint32)b[3] << 24);
106 }
107 return s8Ret;
108 }
109
110 /*
111 * @fn nm_i2c_read_reg
112 * @brief Read register
113 * @param [in] u32Addr
114 * Register address
115 * @return Register value
116 * @author M. Abdelmawla
117 * @date 11 July 2012
118 * @version 1.0
119 */
nm_i2c_read_reg(uint32 u32Addr)120 uint32 nm_i2c_read_reg(uint32 u32Addr)
121 {
122 uint32 val;
123 nm_i2c_read_reg_with_ret(u32Addr, &val);
124 return val;
125 }
126
127 /*
128 * @fn nm_i2c_write_reg
129 * @brief write register
130 * @param [in] u32Addr
131 * Register address
132 * @param [in] u32Val
133 * Value to be written to the register
134 * @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
135 * @author M. Abdelmawla
136 * @date 11 July 2012
137 * @version 1.0
138 */
nm_i2c_write_reg(uint32 u32Addr,uint32 u32Val)139 sint8 nm_i2c_write_reg(uint32 u32Addr, uint32 u32Val)
140 {
141 tstrNmI2cDefault strI2c;
142 uint8 b[16];
143 sint8 s8Ret = M2M_SUCCESS;
144
145 if(u32Addr < 0xff) { /* clockless i2c */
146 b[0] = 0x19;
147 b[1] = (uint8)(u32Addr);
148 b[2] = (uint8)(u32Val);
149 strI2c.u16Sz = 3;
150 } else {
151 b[0] = 0x90;
152 b[1] = (uint8)(u32Addr >> 24);
153 b[2] = (uint8)(u32Addr >> 16);
154 b[3] = (uint8)(u32Addr >> 8);
155 b[4] = (uint8)u32Addr;
156 b[5] = 0x04;
157 b[6] = (uint8)u32Val;
158 b[7] = (uint8)(u32Val >> 8);
159 b[8] = (uint8)(u32Val >> 16);
160 b[9] = (uint8)(u32Val >> 24);
161 strI2c.u16Sz = 10;
162 }
163
164 strI2c.pu8Buf = b;
165
166 if(M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_W, &strI2c))
167 {
168 M2M_ERR("write error\n");
169 s8Ret = M2M_ERR_BUS_FAIL;
170 }
171
172 return s8Ret;
173 }
174
175 /*
176 * @fn nm_i2c_read_block
177 * @brief Read block of data
178 * @param [in] u32Addr
179 * Start address
180 * @param [out] puBuf
181 * Pointer to a buffer used to return the read data
182 * @param [in] u16Sz
183 * Number of bytes to read. The buffer size must be >= u16Sz
184 * @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
185 * @author M. Abdelmawla
186 * @date 11 July 2012
187 * @version 1.0
188 */
nm_i2c_read_block(uint32 u32Addr,uint8 * pu8Buf,uint16 u16Sz)189 sint8 nm_i2c_read_block(uint32 u32Addr, uint8 *pu8Buf, uint16 u16Sz)
190 {
191 tstrNmI2cDefault strI2c;
192 uint8 au8Buf[7];
193 sint8 s8Ret = M2M_SUCCESS;
194
195 au8Buf[0] = 0x02;
196 au8Buf[1] = (uint8)(u32Addr >> 24);
197 au8Buf[2] = (uint8)(u32Addr >> 16);
198 au8Buf[3] = (uint8)(u32Addr >> 8);
199 au8Buf[4] = (uint8)(u32Addr >> 0);
200 au8Buf[5] = (uint8)(u16Sz >> 8);
201 au8Buf[6] = (uint8)(u16Sz);
202
203 strI2c.pu8Buf = au8Buf;
204 strI2c.u16Sz = sizeof(au8Buf);
205
206 if(M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_W, &strI2c))
207 {
208 M2M_ERR("write error\n");
209 s8Ret = M2M_ERR_BUS_FAIL;
210 }
211 else
212 {
213 strI2c.pu8Buf = pu8Buf;
214 strI2c.u16Sz = u16Sz;
215
216 if(M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_R, &strI2c))
217 {
218 M2M_ERR("read error\n");
219 s8Ret = M2M_ERR_BUS_FAIL;
220 }
221 }
222
223 return s8Ret;
224 }
225
226 /*
227 * @fn nm_i2c_write_block
228 * @brief Write block of data
229 * @param [in] u32Addr
230 * Start address
231 * @param [in] puBuf
232 * Pointer to the buffer holding the data to be written
233 * @param [in] u16Sz
234 * Number of bytes to write. The buffer size must be >= u16Sz
235 * @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure
236 * @author M. Abdelmawla
237 * @date 11 July 2012
238 * @version 1.0
239 */
nm_i2c_write_block(uint32 u32Addr,uint8 * pu8Buf,uint16 u16Sz)240 sint8 nm_i2c_write_block(uint32 u32Addr, uint8 *pu8Buf, uint16 u16Sz)
241 {
242 uint8 au8Buf[7];
243 tstrNmI2cSpecial strI2c;
244 sint8 s8Ret = M2M_SUCCESS;
245
246 au8Buf[0] = 0x12;
247 au8Buf[1] = (uint8)(u32Addr >> 24);
248 au8Buf[2] = (uint8)(u32Addr >> 16);
249 au8Buf[3] = (uint8)(u32Addr >> 8);
250 au8Buf[4] = (uint8)(u32Addr);
251 au8Buf[5] = (uint8)(u16Sz >> 8);
252 au8Buf[6] = (uint8)(u16Sz);
253
254 strI2c.pu8Buf1 = au8Buf;
255 strI2c.pu8Buf2 = pu8Buf;
256 strI2c.u16Sz1 = sizeof(au8Buf);
257 strI2c.u16Sz2 = u16Sz;
258
259 if(M2M_SUCCESS != nm_bus_ioctl(NM_BUS_IOCTL_W_SPECIAL, &strI2c))
260 {
261 M2M_ERR("write error\n");
262 s8Ret = M2M_ERR_BUS_FAIL;
263 }
264
265 return s8Ret;
266 }
267
268 #endif
269 /* EOF */
270