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