1 //<MStar Software>
2 //******************************************************************************
3 // MStar Software
4 // Copyright (c) 2010 - 2012 MStar Semiconductor, Inc. All rights reserved.
5 // All software, firmware and related documentation herein ("MStar Software") are
6 // intellectual property of MStar Semiconductor, Inc. ("MStar") and protected by
7 // law, including, but not limited to, copyright law and international treaties.
8 // Any use, modification, reproduction, retransmission, or republication of all
9 // or part of MStar Software is expressly prohibited, unless prior written
10 // permission has been granted by MStar.
11 //
12 // By accessing, browsing and/or using MStar Software, you acknowledge that you
13 // have read, understood, and agree, to be bound by below terms ("Terms") and to
14 // comply with all applicable laws and regulations:
15 //
16 // 1. MStar shall retain any and all right, ownership and interest to MStar
17 // Software and any modification/derivatives thereof.
18 // No right, ownership, or interest to MStar Software and any
19 // modification/derivatives thereof is transferred to you under Terms.
20 //
21 // 2. You understand that MStar Software might include, incorporate or be
22 // supplied together with third party`s software and the use of MStar
23 // Software may require additional licenses from third parties.
24 // Therefore, you hereby agree it is your sole responsibility to separately
25 // obtain any and all third party right and license necessary for your use of
26 // such third party`s software.
27 //
28 // 3. MStar Software and any modification/derivatives thereof shall be deemed as
29 // MStar`s confidential information and you agree to keep MStar`s
30 // confidential information in strictest confidence and not disclose to any
31 // third party.
32 //
33 // 4. MStar Software is provided on an "AS IS" basis without warranties of any
34 // kind. Any warranties are hereby expressly disclaimed by MStar, including
35 // without limitation, any warranties of merchantability, non-infringement of
36 // intellectual property rights, fitness for a particular purpose, error free
37 // and in conformity with any international standard. You agree to waive any
38 // claim against MStar for any loss, damage, cost or expense that you may
39 // incur related to your use of MStar Software.
40 // In no event shall MStar be liable for any direct, indirect, incidental or
41 // consequential damages, including without limitation, lost of profit or
42 // revenues, lost or damage of data, and unauthorized system use.
43 // You agree that this Section 4 shall still apply without being affected
44 // even if MStar Software has been modified by MStar in accordance with your
45 // request or instruction for your use, except otherwise agreed by both
46 // parties in writing.
47 //
48 // 5. If requested, MStar may from time to time provide technical supports or
49 // services in relation with MStar Software to you for your use of
50 // MStar Software in conjunction with your or your customer`s product
51 // ("Services").
52 // You understand and agree that, except otherwise agreed by both parties in
53 // writing, Services are provided on an "AS IS" basis and the warranty
54 // disclaimer set forth in Section 4 above shall apply.
55 //
56 // 6. Nothing contained herein shall be construed as by implication, estoppels
57 // or otherwise:
58 // (a) conferring any license or right to use MStar name, trademark, service
59 // mark, symbol or any other identification;
60 // (b) obligating MStar or any of its affiliates to furnish any person,
61 // including without limitation, you and your customers, any assistance
62 // of any kind whatsoever, or any information; or
63 // (c) conferring any license or right under any intellectual property right.
64 //
65 // 7. These terms shall be governed by and construed in accordance with the laws
66 // of Taiwan, R.O.C., excluding its conflict of law rules.
67 // Any and all dispute arising out hereof or related hereto shall be finally
68 // settled by arbitration referred to the Chinese Arbitration Association,
69 // Taipei in accordance with the ROC Arbitration Law and the Arbitration
70 // Rules of the Association by three (3) arbitrators appointed in accordance
71 // with the said Rules.
72 // The place of arbitration shall be in Taipei, Taiwan and the language shall
73 // be English.
74 // The arbitration award shall be final and binding to both parties.
75 //
76 //******************************************************************************
77 //<MStar Software>
78 ////////////////////////////////////////////////////////////////////////////////
79 //
80 // Copyright (c) 2006-2009 MStar Semiconductor, Inc.
81 // All rights reserved.
82 //
83 // Unless otherwise stipulated in writing, any and all information contained
84 // herein regardless in any format shall remain the sole proprietary of
85 // MStar Semiconductor Inc. and be kept in strict confidence
86 // (¡§MStar Confidential Information¡¨) by the recipient.
87 // Any unauthorized act including without limitation unauthorized disclosure,
88 // copying, use, reproduction, sale, distribution, modification, disassembling,
89 // reverse engineering and compiling of the contents of MStar Confidential
90 // Information is unlawful and strictly prohibited. MStar hereby reserves the
91 // rights to any and all damages, losses, costs and expenses resulting therefrom.
92 //
93 ////////////////////////////////////////////////////////////////////////////////
94 #define _API_SWI2C_C_
95
96 #include "MsCommon.h"
97 #include "MsVersion.h"
98 #include "apiSWI2C.h"
99 #include "drvGPIO.h"
100 #include "drvMMIO.h"
101 #include "drvCPU.h"
102 #include "drvSYS.h"
103 #include "drvSEM.h"
104 #include "ULog.h"
105
106 //-------------------------------------------------------------------------------------------------
107 // Local Defines
108 //-------------------------------------------------------------------------------------------------
109 #define __I2C_BUS(scl, sda, dly) scl, sda, dly
110 #define I2C_BUS( bus ) __I2C_BUS( bus )
111 #define COUNTOF( array ) (sizeof(array) / sizeof((array)[0]))
112 #define IIC_BUS_MAX 16
113
114 #define PULL_HIGH 1
115 #define PULL_LOW 0
116 #define BIT0 0x0001
117 #define SWI2C_READ 0
118 #define SWI2C_WRITE 1
119 #define I2C_CHECK_PIN_DUMMY 5000
120 #define I2C_ACKNOWLEDGE PULL_LOW
121 #define I2C_NON_ACKNOWLEDGE PULL_HIGH
122 #define I2C_ACCESS_DUMMY_TIME 7
123
124 #define HIBYTE(value) ((MS_U8)((value) / 0x100))
125 #define LOBYTE(value) ((MS_U8)(value))
126
127 static MS_S32 g_s32SWI2CMutex[IIC_BUS_MAX] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
128 const char gu8SWI2CMutexName[IIC_BUS_MAX][13] = { \
129 "SWI2CMTXBUS0","SWI2CMTXBUS1","SWI2CMTXBUS2","SWI2CMTXBUS3","SWI2CMTXBUS4","SWI2CMTXBUS5","SWI2CMTXBUS6","SWI2CMTXBUS7", \
130 "SWI2CMTXBUS8","SWI2CMTXBUS9","SWI2CMTXBUSA","SWI2CMTXBUSB","SWI2CMTXBUSC","SWI2CMTXBUSD","SWI2CMTXBUSE","SWI2CMTXBUSF" };
131 #define IIC_MUTEX_CREATE(_P_) g_s32SWI2CMutex[_P_] = MsOS_CreateMutex(E_MSOS_FIFO, (char*)gu8SWI2CMutexName[_P_] , MSOS_PROCESS_SHARED)
132 #define IIC_MUTEX_LOCK(_P_) OS_OBTAIN_MUTEX(g_s32SWI2CMutex[_P_],MSOS_WAIT_FOREVER)
133 #define IIC_MUTEX_UNLOCK(_P_) OS_RELEASE_MUTEX(g_s32SWI2CMutex[_P_])
134 #define IIC_MUTEX_DELETE(_P_) OS_DELETE_MUTEX(g_s32SWI2CMutex[_P_])
135 //For ISP Programming
136 static MS_S32 g_s32I2CMutexS = -1;
137 #define IIC_MUTEX_S_CREATE() g_s32I2CMutexS = MsOS_CreateMutex(E_MSOS_FIFO, (char*)"OS_SWI2C_Mutex", MSOS_PROCESS_SHARED)
138 #define IIC_MUTEX_S_LOCK() OS_OBTAIN_MUTEX(g_s32I2CMutexS,MSOS_WAIT_FOREVER)
139 #define IIC_MUTEX_S_UNLOCK() OS_RELEASE_MUTEX(g_s32I2CMutexS)
140 #define IIC_MUTEX_S_DELETE() OS_DELETE_MUTEX(g_s32I2CMutexS)
141 #define LOCK_HW_SEM() {\
142 }
143 #define UNLOCK_HW_SEM() {\
144 }
145 //-------------------------------------------------------------------------------------------------
146 // Local Structures
147 //-------------------------------------------------------------------------------------------------
148
149
150 //-------------------------------------------------------------------------------------------------
151 // Global Variables
152 //-------------------------------------------------------------------------------------------------
153
154
155 //-------------------------------------------------------------------------------------------------
156 // Local Variables
157 //-------------------------------------------------------------------------------------------------
158 static SWI2C_DbgLvl _gSWI2CDbgLevel = E_SWI2C_DBGLVL_ERROR;
159 static MSIF_Version _api_swi2c_version = {
160 .DDI = { SWI2C_API_VERSION },
161 };
162
163 static SWI2C_BusCfg g_I2CBus[IIC_BUS_MAX];
164 static MS_U8 u8BusAllocNum = 0;
165 static MS_U8 u8BusSel = 0;
166 static SWI2C_ReadMode g_I2CReadMode[IIC_BUS_MAX];
167
168 static MS_U32 u32DelayCount[IIC_BUS_MAX];
169 static MS_U32 u32CpuSpeedMHz;
170 static SWI2C_BusCfg g_SWI2CCBusCfg[IIC_BUS_MAX];
171 static MS_U8 g_u8CfgBusNum = 0;
172
173 //-------------------------------------------------------------------------------------------------
174 // Debug Functions
175 //-------------------------------------------------------------------------------------------------
176 #define SWI2C_DBG_FUNC() do { if (_gSWI2CDbgLevel >= E_SWI2C_DBGLVL_ALL) \
177 {MS_DEBUG_MSG(ULOGI("SWIIC", "\t==== %s ====\n", __FUNCTION__));} } while(0)
178 #define SWI2C_DBG_INFO(x, args...) do { if (_gSWI2CDbgLevel >= E_SWI2C_DBGLVL_INFO ) \
179 {MS_DEBUG_MSG(ULOGI("SWIIC", "[%s]: ", __FUNCTION__); printf(x, ##args));} } while(0)
180 #define SWI2C_DBG_ERR(x, args...) do { if (_gSWI2CDbgLevel >= E_SWI2C_DBGLVL_ERROR) \
181 {MS_DEBUG_MSG(ULOGE("SWIIC", "[%s]: ", __FUNCTION__); printf(x, ##args);)} } while(0)
182 #define SWI2C_DBG_WARN(x, args...) do { if (_gSWI2CDbgLevel >= E_SWI2C_DBGLVL_WARNING) \
183 {MS_DEBUG_MSG(ULOGW("SWIIC", "[%s]: ", __FUNCTION__); printf(x, ##args);)} } while(0)
184
185 //-------------------------------------------------------------------------------------------------
186 // Local Functions
187 //-------------------------------------------------------------------------------------------------
iic_delay(MS_U8 u8BusNum)188 static void iic_delay(MS_U8 u8BusNum)
189 {
190 MS_U32 volatile u32Loop=u32DelayCount[u8BusNum];
191
192 while(u32Loop--)
193 {
194 #ifdef __mips__
195 __asm__ __volatile__ ("nop");
196 #endif
197
198 #ifdef __AEONR2__
199 __asm__ __volatile__ ("l.nop");
200 #endif
201
202 #ifdef __arm__
203 __asm__ __volatile__ ("mov r0, r0");
204 #endif
205 }
206 }
207
pin_scl_set_input(MS_U8 u8BusNum)208 static void pin_scl_set_input(MS_U8 u8BusNum)
209 {
210 mdrv_gpio_set_input( g_I2CBus[u8BusNum].padSCL );
211 }
212
pin_scl_set_high(MS_U8 u8BusNum)213 static void pin_scl_set_high(MS_U8 u8BusNum)
214 {
215 mdrv_gpio_set_input( g_I2CBus[u8BusNum].padSCL );
216 }
217
pin_scl_set_low(MS_U8 u8BusNum)218 static void pin_scl_set_low(MS_U8 u8BusNum)
219 {
220 mdrv_gpio_set_low( g_I2CBus[u8BusNum].padSCL );
221 }
222
pin_scl_get_level(MS_U8 u8BusNum)223 static int pin_scl_get_level(MS_U8 u8BusNum)
224 {
225 return mdrv_gpio_get_level( g_I2CBus[u8BusNum].padSCL ) ? PULL_HIGH : PULL_LOW;
226 }
227
pin_scl_check_high(MS_U8 u8BusNum)228 static void pin_scl_check_high(MS_U8 u8BusNum)
229 {
230 MS_U16 u16Dummy;
231
232 pin_scl_set_high(u8BusNum);
233 u16Dummy = I2C_CHECK_PIN_DUMMY;
234 while (u16Dummy--)
235 {
236 if(pin_scl_get_level(u8BusNum) == PULL_HIGH)
237 break;
238 }
239 }
240
pin_sda_set_input(MS_U8 u8BusNum)241 static void pin_sda_set_input(MS_U8 u8BusNum)
242 {
243 mdrv_gpio_set_input( g_I2CBus[u8BusNum].padSDA );
244 }
245
pin_sda_set_high(MS_U8 u8BusNum)246 static void pin_sda_set_high(MS_U8 u8BusNum)
247 {
248 mdrv_gpio_set_input( g_I2CBus[u8BusNum].padSDA );
249 }
250
pin_sda_set_low(MS_U8 u8BusNum)251 static void pin_sda_set_low(MS_U8 u8BusNum)
252 {
253 mdrv_gpio_set_low( g_I2CBus[u8BusNum].padSDA );
254 }
255
pin_sda_get_level(MS_U8 u8BusNum)256 static int pin_sda_get_level(MS_U8 u8BusNum)
257 {
258 return mdrv_gpio_get_level( g_I2CBus[u8BusNum].padSDA ) ? PULL_HIGH : PULL_LOW;
259 }
260
pin_sda_check_high(MS_U8 u8BusNum)261 static void pin_sda_check_high(MS_U8 u8BusNum)
262 {
263 MS_U16 u16Dummy;
264
265 pin_sda_set_high(u8BusNum);
266 u16Dummy = I2C_CHECK_PIN_DUMMY;
267 while (u16Dummy--)
268 {
269 if(pin_sda_get_level(u8BusNum) == PULL_HIGH)
270 break;
271 }
272 }
273
pin_scl_check_low(MS_U8 u8BusNum)274 static void pin_scl_check_low(MS_U8 u8BusNum)
275 {
276 MS_U16 u16Dummy = I2C_CHECK_PIN_DUMMY;
277
278 pin_scl_set_low(u8BusNum);
279 while (u16Dummy--)
280 {
281 if(pin_scl_get_level(u8BusNum) == PULL_LOW)
282 break;
283 }
284 }
285
286 /******************************************************************************/
287 ////////////////////////////////////////////////////////////////////////////////
288 // I2C start signal.
289 // <comment>
290 // SCL ________
291 // \_________
292 // SDA _____
293 // \____________
294 //
295 // Return value: None
296 ////////////////////////////////////////////////////////////////////////////////
297 /******************************************************************************/
IIC_Start(MS_U8 u8BusNum)298 static MS_BOOL IIC_Start(MS_U8 u8BusNum)
299 {
300 MS_BOOL bStatus = TRUE; // success status
301
302 pin_sda_check_high(u8BusNum);
303 iic_delay(u8BusNum);
304
305 pin_scl_check_high(u8BusNum);
306 iic_delay(u8BusNum);
307
308 // check pin error
309 pin_scl_set_input(u8BusNum);
310 pin_sda_set_input(u8BusNum);
311
312 if ((pin_scl_get_level(u8BusNum) == PULL_LOW) || (pin_sda_get_level(u8BusNum) == PULL_LOW))
313 {
314 pin_scl_set_high(u8BusNum);
315 pin_sda_set_high(u8BusNum);
316 bStatus = FALSE;
317 }
318 else // success
319 {
320 pin_sda_set_low(u8BusNum);
321 iic_delay(u8BusNum);
322 pin_scl_set_low(u8BusNum);
323 }
324
325 return bStatus; //vain
326 }
327
328 ////////////////////////////////////////////////////////////////////////////////
329 // I2C stop signal.
330 // <comment>
331 // ____________
332 // SCL _______/
333 // _________
334 // SDA __________/
335 ////////////////////////////////////////////////////////////////////////////////
IIC_Stop(MS_U8 u8BusNum)336 static void IIC_Stop(MS_U8 u8BusNum)
337 {
338 pin_scl_set_low(u8BusNum);
339 iic_delay(u8BusNum);
340 pin_sda_set_low(u8BusNum);
341
342 iic_delay(u8BusNum);
343 pin_scl_set_input(u8BusNum);
344 iic_delay(u8BusNum);
345 pin_sda_set_input(u8BusNum);
346 iic_delay(u8BusNum);
347 }
348
349 /******************************************************************************/
350 ///Send 1 bytes data
351 ///@param u8dat \b IN: 1 byte data to send
352 /******************************************************************************/
SendByte(MS_U8 u8BusNum,MS_U8 u8dat)353 static MS_BOOL SendByte(MS_U8 u8BusNum, MS_U8 u8dat) // Be used int IIC_SendByte
354 {
355 MS_U8 u8Mask = 0x80;
356 int bAck; // acknowledge bit
357
358 while ( u8Mask )
359 {
360 if (u8dat & u8Mask)
361 {
362 pin_sda_check_high(u8BusNum);
363 }
364 else
365 {
366 pin_sda_set_low(u8BusNum);
367 }
368
369 iic_delay(u8BusNum);
370 pin_scl_check_high(u8BusNum);
371 iic_delay(u8BusNum);
372 pin_scl_set_low(u8BusNum);
373
374 u8Mask >>= 1; // next
375 }
376
377 // recieve acknowledge
378 pin_sda_set_input(u8BusNum);
379 iic_delay(u8BusNum);
380 pin_scl_check_high(u8BusNum);
381
382 iic_delay(u8BusNum);
383 bAck = pin_sda_get_level(u8BusNum); // recieve acknowlege
384 pin_scl_set_low(u8BusNum);
385
386 iic_delay(u8BusNum);
387
388 //for I2c waveform sharp
389 if (bAck)
390 pin_sda_set_high(u8BusNum);
391 else
392 pin_sda_set_low(u8BusNum);
393
394 pin_sda_set_input(u8BusNum);
395
396 iic_delay(u8BusNum);
397 iic_delay(u8BusNum);
398 iic_delay(u8BusNum);
399 iic_delay(u8BusNum);
400
401 return (bAck)? TRUE: FALSE;
402 }
403
404 /******************************************************************************/
405 ///Send 1 bytes data, this function will retry 5 times until success.
406 ///@param u8dat \b IN: 1 byte data to send
407 ///@return MS_BOOL:
408 ///- TRUE: Success
409 ///- FALSE: Fail
410 /******************************************************************************/
IIC_SendByte(MS_U8 u8BusNum,MS_U8 u8dat)411 static MS_BOOL IIC_SendByte(MS_U8 u8BusNum, MS_U8 u8dat)
412 {
413 MS_U8 i;
414
415 for(i=0;i<1;i++)
416 {
417 if (SendByte(u8BusNum,u8dat)==I2C_ACKNOWLEDGE)
418 return TRUE;
419 }
420
421 SWI2C_DBG_INFO("IIC[%d] write byte 0x%x fail!!\n",u8BusNum, u8dat);
422 return FALSE;
423 }
424
425 ////////////////////////////////////////////////////////////////////////////////
426 // I2C access start.
427 //
428 // Arguments: u8SlaveID - Slave ID (Address)
429 // trans_t - I2C_TRANS_WRITE/I2C_TRANS_READ
430 ////////////////////////////////////////////////////////////////////////////////
IIC_AccessStart(MS_U8 u8BusNum,MS_U8 u8SlaveID,MS_U8 trans_t)431 static MS_BOOL IIC_AccessStart(MS_U8 u8BusNum, MS_U8 u8SlaveID, MS_U8 trans_t)
432 {
433 MS_U8 u8Dummy; // loop dummy
434
435 SWI2C_DBG_FUNC();
436
437 if (trans_t == SWI2C_READ) // check i2c read or write
438 {
439 u8SlaveID |= BIT0;
440 }
441 else
442 {
443 u8SlaveID &= ~BIT0;
444 }
445
446 u8Dummy = I2C_ACCESS_DUMMY_TIME;
447
448 while (u8Dummy--)
449 {
450 if ( IIC_Start(u8BusNum) == FALSE)
451 {
452 continue;
453 }
454
455 if ( IIC_SendByte(u8BusNum,u8SlaveID) == TRUE ) // check acknowledge
456 {
457 return TRUE;
458 }
459
460 IIC_Stop(u8BusNum);
461 }
462
463 return FALSE;
464 }
465 /******************************************************************************/
466 ///Get 1 bytes data, this function will retry 5 times until success.
467 ///@param *u8dat \b IN: pointer to 1 byte data buffer for getting data
468 ///@return MS_BOOL:
469 ///- TRUE: Success
470 ///- FALSE: Fail
471 /******************************************************************************///
472 //static MS_BOOL IIC_GetByte(MS_U8* pu8data) // Auto generate ACK
IIC_GetByte(MS_U8 u8BusNum,MS_U16 bAck)473 static MS_U8 IIC_GetByte (MS_U8 u8BusNum, MS_U16 bAck)
474 {
475 MS_U8 ucReceive = 0;
476 MS_U8 ucMask = 0x80;
477
478 pin_sda_set_input(u8BusNum);
479
480 while ( ucMask )
481 {
482 iic_delay(u8BusNum);
483 pin_scl_check_high(u8BusNum);
484 iic_delay(u8BusNum);
485
486 if (pin_sda_get_level(u8BusNum) == PULL_HIGH)
487 {
488 ucReceive |= ucMask;
489 }
490 ucMask >>= 1; // next
491
492 pin_scl_set_low(u8BusNum);
493 pin_scl_check_low(u8BusNum);
494 }
495 if (bAck)
496 {
497 pin_sda_set_low(u8BusNum); // acknowledge
498 }
499 else
500 {
501 pin_sda_check_high(u8BusNum); // non-acknowledge
502 }
503 iic_delay(u8BusNum);
504 pin_scl_check_high(u8BusNum);
505 iic_delay(u8BusNum);
506 pin_scl_set_low(u8BusNum);
507 iic_delay(u8BusNum);
508 iic_delay(u8BusNum);
509 iic_delay(u8BusNum);
510 return ucReceive;
511 }
512
IIC_CfgSpeedParam(MS_U8 u8BusNum,MS_U32 u32Speed_K)513 static MS_BOOL IIC_CfgSpeedParam(MS_U8 u8BusNum, MS_U32 u32Speed_K)
514 {
515 #define DELAY_CNT(SpeedKHz) ((u32FactorDelay/(SpeedKHz))-((u32Parameter1+u32AdjParam)-((SpeedKHz)/u32AdjParam))+((1<<((u32Parameter2-SpeedKHz)/40))))
516
517 MS_U32 u32FactorDelay = 50400UL;
518 MS_U32 u32FactorAdjust = 11040UL;
519 MS_U32 u32ParamBase1 = 130UL;
520 MS_U32 u32Parameter1 = 130UL;
521 MS_U32 u32Parameter2 = 440UL;
522 MS_U32 u32AdjParam;
523
524 //(1) assign primary parameters
525 u32FactorDelay = u32CpuSpeedMHz * 100;
526 u32FactorAdjust = (u32CpuSpeedMHz>=312)? 10000UL :13000UL;
527 if (u32CpuSpeedMHz > 0)
528 {
529 u32AdjParam = u32FactorAdjust/u32CpuSpeedMHz;
530 }
531 else
532 {
533 SWI2C_DBG_ERR("%s, Error parameter u32CpuSpeedMHz=%ld",__FUNCTION__, u32CpuSpeedMHz);
534 return FALSE;
535 }
536 u32Parameter2 = 440UL;
537 //(2) assign base for parameter 1
538 if(u32CpuSpeedMHz>=1000) u32ParamBase1 = 150UL;
539 else if(u32CpuSpeedMHz>=900) u32ParamBase1 = 140UL;
540 else if(u32CpuSpeedMHz>=780) u32ParamBase1 = 135UL;
541 else if(u32CpuSpeedMHz>=720) u32ParamBase1 = 130UL;
542 else if(u32CpuSpeedMHz>=650) u32ParamBase1 = 125UL;
543 else if(u32CpuSpeedMHz>=600) u32ParamBase1 = 110UL;
544 else if(u32CpuSpeedMHz>=560) u32ParamBase1 = 100UL;
545 else if(u32CpuSpeedMHz>=530) u32ParamBase1 = 95UL;
546 else if(u32CpuSpeedMHz>=500) u32ParamBase1 = 90UL;
547 else if(u32CpuSpeedMHz>=480) u32ParamBase1 = 85UL;
548 else if(u32CpuSpeedMHz>=430) u32ParamBase1 = 80UL;
549 else if(u32CpuSpeedMHz>=400) u32ParamBase1 = 75UL;
550 else if(u32CpuSpeedMHz>=384) u32ParamBase1 = 70UL;
551 else if(u32CpuSpeedMHz>=360) u32ParamBase1 = 65UL;
552 else if(u32CpuSpeedMHz>=336) u32ParamBase1 = 60UL;
553 else if(u32CpuSpeedMHz>=312) u32ParamBase1 = 40UL;
554 else if(u32CpuSpeedMHz>=240) u32ParamBase1 = 10UL;
555 else if(u32CpuSpeedMHz>=216) u32ParamBase1 = 0UL;
556 else u32ParamBase1 = 0UL;
557 //(3) compute parameter 1 by base
558 if(u32Speed_K>=350) u32Parameter1 = u32ParamBase1; //400K level
559 else if(u32Speed_K>=250) u32Parameter1 = u32ParamBase1 + 10; //300K evel
560 else if(u32Speed_K>=150) u32Parameter1 = u32ParamBase1 + 60; //200K level
561 else if(u32Speed_K>=75) u32Parameter1 = u32ParamBase1 + 250; //100K level //160
562 else u32Parameter1 = u32ParamBase1 + 560; //50K level
563 //(4) compute delay counts
564 if ((u32Speed_K>0) && (u32AdjParam>0))
565 {
566 u32DelayCount[u8BusNum] = DELAY_CNT(u32Speed_K);
567 }
568 else
569 {
570 SWI2C_DBG_ERR("%s, Error parameter u32Speed_K=%ld , u32AdjParam=%ld",__FUNCTION__, u32Speed_K, u32AdjParam);
571 return FALSE;
572 }
573
574 return TRUE;
575 }
576
577 /******************************************************************************/
578 ///I2C Initialize: set I2C Clock and enable I2C
579 /******************************************************************************/
IIC_ConfigBus(MS_U8 u8BusNum,SWI2C_BusCfg * pSWI2CBusCfg)580 static MS_BOOL IIC_ConfigBus(MS_U8 u8BusNum,SWI2C_BusCfg* pSWI2CBusCfg)
581 {
582 SWI2C_DBG_FUNC();
583
584 //check resources
585 if((u8BusAllocNum>IIC_BUS_MAX)||(u8BusNum>=IIC_BUS_MAX))
586 return FALSE;
587 if(!pSWI2CBusCfg)
588 return FALSE;
589 //config IIC bus settings
590 g_I2CBus[u8BusNum].padSCL = pSWI2CBusCfg->padSCL;
591 g_I2CBus[u8BusNum].padSDA = pSWI2CBusCfg->padSDA;
592 g_I2CBus[u8BusNum].defDelay = pSWI2CBusCfg->defDelay;
593 u8BusAllocNum++;
594 SWI2C_DBG_INFO("[IIC_ConfigBus]: g_I2CBus[%d].padSCL = %d\n",u8BusNum, g_I2CBus[u8BusNum].padSCL);
595 SWI2C_DBG_INFO("[IIC_ConfigBus]: g_I2CBus[%d].padSDA = %d\n",u8BusNum, g_I2CBus[u8BusNum].padSDA);
596 SWI2C_DBG_INFO("[IIC_ConfigBus]: g_I2CBus[%d].defDelay = %d\n",u8BusNum, g_I2CBus[u8BusNum].defDelay);
597 SWI2C_DBG_INFO("[IIC_ConfigBus]: u8BusAllocNum = %d\n",u8BusAllocNum);
598 return TRUE;
599 }
600
IIC_UseBus(MS_U8 u8BusNum)601 static MS_BOOL IIC_UseBus( MS_U8 u8BusNum )
602 {
603 MS_BOOL bReturn = FALSE;
604 if ( u8BusNum < COUNTOF( g_I2CBus ) )
605 {
606 u8BusSel = u8BusNum;
607 bReturn = IIC_CfgSpeedParam(u8BusNum, g_I2CBus[u8BusNum].defDelay);
608 SWI2C_DBG_INFO("[IIC_UseBus]: u8BusSel = %d\n",u8BusSel);
609 }
610 return bReturn;
611 }
612
IIC_UnuseBus(MS_U8 u8BusNum)613 static void IIC_UnuseBus( MS_U8 u8BusNum )
614 {
615 u8BusNum = u8BusNum;
616 }
617
618 //-------------------------------------------------------------------------------------------------
619 // Global Functions
620 //-------------------------------------------------------------------------------------------------
MApi_SWI2C_GetMaxBuses(void)621 MS_U8 MApi_SWI2C_GetMaxBuses(void)
622 {
623 SWI2C_DBG_FUNC();
624 return (MS_U8)IIC_BUS_MAX;
625 }
626
MApi_SWI2C_Speed_Setting(MS_U8 u8BusNum,MS_U32 u32Speed_K)627 MS_U32 MApi_SWI2C_Speed_Setting(MS_U8 u8BusNum, MS_U32 u32Speed_K)
628 {
629 MS_U32 u32OriginalValue;
630
631 LOCK_HW_SEM();
632 IIC_MUTEX_LOCK(u8BusNum);
633 SWI2C_DBG_FUNC();
634
635 u32OriginalValue = g_I2CBus[u8BusNum].defDelay;
636 g_I2CBus[u8BusNum].defDelay = u32Speed_K;
637 if (IIC_UseBus(u8BusNum) == FALSE)
638 {
639 g_I2CBus[u8BusNum].defDelay = (MS_U8) u32OriginalValue;
640 }
641 SWI2C_DBG_INFO("[MApi_SWI2C_Speed_Setting]: u8BusNum = %d, u32Speed_K = %ld\n",u8BusNum,u32Speed_K);
642 IIC_MUTEX_UNLOCK(u8BusNum);
643 UNLOCK_HW_SEM();
644 return u32OriginalValue;
645 }
646
MApi_SWI2C_SetReadMode(SWI2C_ReadMode eReadMode)647 MS_BOOL MApi_SWI2C_SetReadMode(SWI2C_ReadMode eReadMode)
648 {
649 SWI2C_DBG_FUNC();
650
651 if(eReadMode>=E_SWI2C_READ_MODE_MAX)
652 return FALSE;
653 g_I2CReadMode[u8BusSel] = eReadMode;
654 return TRUE;
655 }
656
MApi_SWI2C_SetBusReadMode(MS_U8 u8BusNum,SWI2C_ReadMode eReadMode)657 MS_BOOL MApi_SWI2C_SetBusReadMode(MS_U8 u8BusNum, SWI2C_ReadMode eReadMode)
658 {
659 SWI2C_DBG_FUNC();
660
661 if(eReadMode>=E_SWI2C_READ_MODE_MAX)
662 return FALSE;
663 g_I2CReadMode[u8BusNum] = eReadMode;
664 return TRUE;
665 }
666
MApi_SWI2C_Init(SWI2C_BusCfg SWI2CCBusCfg[],MS_U8 u8CfgBusNum)667 void MApi_SWI2C_Init(SWI2C_BusCfg SWI2CCBusCfg[],MS_U8 u8CfgBusNum)
668 {
669 MS_U8 u8Bus;
670
671 SWI2C_DBG_FUNC();
672 // Store SWI2CCBusCfg for FastBoot Resume
673 g_u8CfgBusNum = u8CfgBusNum;
674 for(u8Bus=0;u8Bus<u8CfgBusNum;u8Bus++)
675 {
676 g_SWI2CCBusCfg[u8Bus] = SWI2CCBusCfg[u8Bus];
677 }
678
679 u8BusAllocNum = 0;
680
681 //Get CPU clock & delay parameters
682 MDrv_COPRO_GetBase();
683 u32CpuSpeedMHz = (MS_U32)(MDrv_CPU_QueryClock()/1000000UL);
684 SWI2C_DBG_INFO("@@@@@@ u32CpuSpeedMHz= %d MHz\n",(int)u32CpuSpeedMHz);
685 if (u32CpuSpeedMHz == 0)
686 {
687 MS_ASSERT(0);
688 }
689
690 //config iic buses
691 for(u8Bus=0;u8Bus<u8CfgBusNum;u8Bus++)
692 {
693 IIC_MUTEX_CREATE(u8Bus);
694 }
695 // create mutex to protect access specially for ISP Programming
696 IIC_MUTEX_S_CREATE();
697
698 for(u8Bus=0;u8Bus<u8CfgBusNum;u8Bus++)
699 {
700 IIC_ConfigBus(u8Bus,&SWI2CCBusCfg[u8Bus]);
701 MApi_SWI2C_Speed_Setting(u8Bus,SWI2CCBusCfg[u8Bus].defDelay);
702 MApi_SWI2C_SetBusReadMode(u8Bus,E_SWI2C_READ_MODE_DIRECTION_CHANGE);
703 }
704
705 MDrv_SYS_RegisterIoProc(E_SYS_IO_SWI2C_READ, MApi_SWI2C_ReadBytes);
706 MDrv_SYS_RegisterIoProc(E_SYS_IO_SWI2C_WRITE, MApi_SWI2C_WriteBytes);
707 }
708
709 /******************************************************************************/
710 ///Write bytes, be able to write 1 byte or several bytes to several register offsets in same slave address.
711 ///@param u16BusNumSlaveID \b IN: Bus Number (high byte) and Slave ID (Address) (low byte)
712 ///@param u8addrcount \b IN: register NO to write, this parameter is the NO of register offsets in pu8addr buffer,
713 ///it should be 0 when *pu8addr = NULL.
714 ///@param *pu8addr \b IN: pointer to a buffer containing target register offsets to write
715 ///@param u16size \b IN: Data length (in byte) to write
716 ///@param *pu8data \b IN: pointer to the data buffer for write
717 ///@return MS_BOOL:
718 ///- TRUE: Success
719 ///- FALSE: Fail
720 /******************************************************************************/
MApi_SWI2C_WriteBytes(MS_U16 u16BusNumSlaveID,MS_U8 AddrCnt,MS_U8 * pu8addr,MS_U16 u16size,MS_U8 * pBuf)721 MS_BOOL MApi_SWI2C_WriteBytes(MS_U16 u16BusNumSlaveID, MS_U8 AddrCnt, MS_U8* pu8addr, MS_U16 u16size, MS_U8* pBuf)
722 {
723 MS_U8 u8Dummy = I2C_ACCESS_DUMMY_TIME; //I2C_ACCESS_DUMMY_TIME; // loop dummy
724 MS_U8 u8BusNum = HIBYTE(u16BusNumSlaveID);
725 MS_U8 u8SlaveID = LOBYTE(u16BusNumSlaveID);
726 MS_BOOL bRet = FALSE;
727 MS_U8 AddrCnt_temp=0;
728 MS_U16 u16size_temp=0;
729 MS_U8* pu8addr_temp=(MS_U8*)NULL;
730 MS_U8* pBuf_temp=(MS_U8*)NULL;
731
732 SWI2C_DBG_FUNC();
733
734 if(u8BusAllocNum==0)
735 return FALSE;
736
737 LOCK_HW_SEM();
738 IIC_MUTEX_S_LOCK();
739 IIC_MUTEX_LOCK(u8BusNum);
740 if (IIC_UseBus(u8BusNum) == FALSE)
741 {
742 IIC_MUTEX_UNLOCK(u8BusNum);
743 IIC_MUTEX_S_UNLOCK();
744 UNLOCK_HW_SEM();
745 return FALSE;
746 }
747
748 while (u8Dummy--)
749 {
750 AddrCnt_temp = AddrCnt;
751 u16size_temp = u16size;
752 pu8addr_temp = (MS_U8*)pu8addr;
753 pBuf_temp = (MS_U8*)pBuf;
754 if (IIC_AccessStart(u8BusNum, u8SlaveID, SWI2C_WRITE) == FALSE)
755 {
756 if( u8Dummy )
757 continue;
758 else
759 goto fail;
760 }
761
762 while (AddrCnt_temp)
763 {
764 AddrCnt_temp--;
765 if (IIC_SendByte(u8BusNum,*pu8addr_temp) == FALSE)
766 {
767 goto fail;
768 }
769 pu8addr_temp++;
770 }
771 while (u16size_temp) // loop of writting data
772 {
773 u16size_temp-- ;
774 if (IIC_SendByte(u8BusNum,*pBuf_temp) == FALSE)
775 {
776 goto fail;
777 }
778 pBuf_temp++; // next byte pointer
779 }
780 bRet = TRUE;
781 break;
782 fail:
783 IIC_Stop(u8BusNum);
784 bRet = FALSE;
785 }
786
787 IIC_Stop(u8BusNum);
788 IIC_UnuseBus(u8BusNum);
789 IIC_MUTEX_UNLOCK(u8BusNum);
790 IIC_MUTEX_S_UNLOCK();
791 UNLOCK_HW_SEM();
792
793 return bRet;
794 }
795
796 /******************************************************************************/
797 ///Write bytes with Stop control
798 ///@param u16BusNumSlaveID \b IN: Bus Number (high byte) and Slave ID (Address) (low byte)
799 ///@param AddrCnt \b IN: register NO to write, this parameter is the NO of register offsets in pu8addr buffer,
800 ///it should be 0 when *pu8addr = NULL.
801 ///@param *pu8addr \b IN: pointer to a buffer containing target register offsets to write
802 ///@param u16size \b IN: Data length (in byte) to write
803 ///@param *pu8data \b IN: pointer to the data buffer for write
804 ///@param bGenStop \b IN: control stop to be generated by result
805 ///@return MS_BOOL:
806 ///- TRUE: Success
807 ///- FALSE: Fail
808 /******************************************************************************/
MApi_SWI2C_WriteBytesStop(MS_U16 u16BusNumSlaveID,MS_U8 AddrCnt,MS_U8 * pu8addr,MS_U16 u16size,MS_U8 * pBuf,MS_BOOL bGenStop)809 MS_BOOL MApi_SWI2C_WriteBytesStop(MS_U16 u16BusNumSlaveID, MS_U8 AddrCnt, MS_U8* pu8addr, MS_U16 u16size, MS_U8* pBuf,MS_BOOL bGenStop)
810 {
811 MS_U8 u8Dummy = I2C_ACCESS_DUMMY_TIME; //I2C_ACCESS_DUMMY_TIME; // loop dummy
812 MS_U8 u8BusNum = HIBYTE(u16BusNumSlaveID);
813 MS_U8 u8SlaveID = LOBYTE(u16BusNumSlaveID);
814 MS_BOOL bRet = FALSE;
815 MS_U8 AddrCnt_temp=0;
816 MS_U16 u16size_temp=0;
817 MS_U8* pu8addr_temp=(MS_U8*)NULL;
818 MS_U8* pBuf_temp=(MS_U8*)NULL;
819 SWI2C_DBG_FUNC();
820
821 if(u8BusAllocNum==0)
822 return FALSE;
823
824 LOCK_HW_SEM();
825 IIC_MUTEX_S_LOCK();
826 IIC_MUTEX_LOCK(u8BusNum);
827 if (IIC_UseBus(u8BusNum) == FALSE)
828 {
829 IIC_MUTEX_UNLOCK(u8BusNum);
830 IIC_MUTEX_S_UNLOCK();
831 UNLOCK_HW_SEM();
832 return FALSE;
833 }
834
835 while (u8Dummy--)
836 {
837 AddrCnt_temp = AddrCnt;
838 u16size_temp = u16size;
839 pu8addr_temp = (MS_U8*)pu8addr;
840 pBuf_temp = (MS_U8*)pBuf;
841 if (IIC_AccessStart(u8BusNum, u8SlaveID, SWI2C_WRITE) == FALSE)
842 {
843 if( u8Dummy )
844 continue;
845 else
846 goto fail;
847 }
848
849 while (AddrCnt_temp)
850 {
851 AddrCnt_temp--;
852 if (IIC_SendByte(u8BusNum,*pu8addr_temp) == FALSE)
853 {
854 goto fail;
855 }
856 pu8addr_temp++;
857 }
858 while (u16size_temp) // loop of writting data
859 {
860 u16size_temp-- ;
861 if (IIC_SendByte(u8BusNum,*pBuf_temp) == FALSE)
862 {
863 goto fail;
864 }
865 pBuf_temp++; // next byte pointer
866 }
867
868 break;
869 fail:
870 IIC_Stop(u8BusNum);
871 }
872 bRet = TRUE;
873
874
875 if (bRet==TRUE)
876 {
877 if (bGenStop == TRUE)
878 {
879 IIC_Stop(u8BusNum);
880 }
881 }
882 else
883 {
884 IIC_Stop(u8BusNum);
885 }
886 IIC_UnuseBus(u8BusNum);
887 IIC_MUTEX_UNLOCK(u8BusNum);
888 IIC_MUTEX_S_UNLOCK();
889 UNLOCK_HW_SEM();
890
891 return bRet;
892 }
893
894
895 /******************************************************************************/
896 ///Read bytes, be able to read 1 byte or several bytes in thru mode, like ISDB demod TC90527
897 ///@param u16BusNumSlaveID \b IN: Bus Number (high byte) and Slave ID (Address) (low byte)
898 ///@param u8AddrNum \b IN: register NO to read, this parameter is the NO of register offsets in pu8addr buffer,
899 ///it should be 0 when *paddr = NULL.
900 ///@param *paddr \b IN: pointer to a buffer containing target register offsets to read
901 ///@param u16size \b IN: Data length (in byte) to read
902 ///@param *pu8data \b IN: pointer to retun data buffer.
903 ///@return MS_BOOL:
904 ///- TRUE: Success
905 ///- FALSE: Fail
906 /******************************************************************************/
MApi_SWI2C_ReadBytes_ThruMode(MS_U16 u16BusNumSlaveID,MS_U8 ucSubAdr,MS_U8 * paddr,MS_U16 ucBufLen,MS_U8 * pBuf)907 MS_BOOL MApi_SWI2C_ReadBytes_ThruMode(MS_U16 u16BusNumSlaveID, MS_U8 ucSubAdr, MS_U8* paddr, MS_U16 ucBufLen, MS_U8* pBuf)
908 {
909 MS_U8 u8Dummy = I2C_ACCESS_DUMMY_TIME; // loop dummy
910 MS_U8 u8BusNum = HIBYTE(u16BusNumSlaveID);
911 MS_U8 u8SlaveID = LOBYTE(u16BusNumSlaveID);
912 MS_BOOL bRet = FALSE;
913 MS_U8 *pAddr_bk = paddr;
914
915 SWI2C_DBG_FUNC();
916
917 if(u8BusAllocNum==0)
918 return FALSE;
919
920 LOCK_HW_SEM();
921 IIC_MUTEX_S_LOCK();
922 IIC_MUTEX_LOCK(u8BusNum);
923 if (IIC_UseBus(u8BusNum) == FALSE)
924 {
925 IIC_MUTEX_UNLOCK(u8BusNum);
926 IIC_MUTEX_S_UNLOCK();
927 UNLOCK_HW_SEM();
928 return FALSE;
929 }
930
931 while (u8Dummy--)
932 {
933 // step1
934 if((g_I2CReadMode[u8BusNum]!=E_SWI2C_READ_MODE_DIRECT) && (ucSubAdr>0) && (paddr))
935 {
936 if (IIC_AccessStart(u8BusNum, u8SlaveID, SWI2C_WRITE) == FALSE)
937 {
938 if( u8Dummy )
939 continue;
940 else
941 goto fail;
942 }
943
944 while (ucSubAdr)
945 {
946 ucSubAdr--;
947 if (IIC_SendByte(u8BusNum,*paddr) == FALSE)
948 {
949 goto fail;
950 }
951 paddr++;
952 }
953
954 if(g_I2CReadMode[u8BusNum]==E_SWI2C_READ_MODE_DIRECTION_CHANGE_STOP_START)
955 {
956 IIC_Stop(u8BusNum);
957 }
958 }
959
960 //step 2
961 if (IIC_AccessStart(u8BusNum, u8SlaveID, SWI2C_WRITE) == FALSE)
962 {
963 if( u8Dummy )
964 continue;
965 else
966 goto fail;
967 }
968 if (IIC_SendByte(u8BusNum,pAddr_bk[0]) == FALSE)
969 {
970 goto fail;
971 }
972 if (IIC_SendByte(u8BusNum,pAddr_bk[1]+1) == FALSE)
973 {
974 goto fail;
975 }
976
977 //step3
978 if (IIC_AccessStart(u8BusNum, u8SlaveID, SWI2C_READ) == FALSE)
979 {
980 if( u8Dummy )
981 continue;
982 else
983 goto fail;
984 }
985 while (ucBufLen--) // loop to burst read
986 {
987 *pBuf = IIC_GetByte(u8BusNum,ucBufLen); // receive byte
988 pBuf++; // next byte pointer
989 }
990 break;
991 fail:
992 IIC_Stop(u8BusNum);
993 }
994 bRet = TRUE;
995
996 IIC_Stop(u8BusNum);
997 IIC_UnuseBus(u8BusNum);
998 IIC_MUTEX_UNLOCK(u8BusNum);
999 IIC_MUTEX_S_UNLOCK();
1000 UNLOCK_HW_SEM();
1001
1002 return bRet;
1003 }
1004 /******************************************************************************/
1005 ///Read bytes, be able to read 1 byte or several bytes from several register offsets in same slave address.
1006 ///@param u16BusNumSlaveID \b IN: Bus Number (high byte) and Slave ID (Address) (low byte)
1007 ///@param u8AddrNum \b IN: register NO to read, this parameter is the NO of register offsets in pu8addr buffer,
1008 ///it should be 0 when *paddr = NULL.
1009 ///@param *paddr \b IN: pointer to a buffer containing target register offsets to read
1010 ///@param u16size \b IN: Data length (in byte) to read
1011 ///@param *pu8data \b IN: pointer to retun data buffer.
1012 ///@return MS_BOOL:
1013 ///- TRUE: Success
1014 ///- FALSE: Fail
1015 /******************************************************************************/
MApi_SWI2C_ReadBytes(MS_U16 u16BusNumSlaveID,MS_U8 ucSubAdr,MS_U8 * paddr,MS_U16 ucBufLen,MS_U8 * pBuf)1016 MS_BOOL MApi_SWI2C_ReadBytes(MS_U16 u16BusNumSlaveID, MS_U8 ucSubAdr, MS_U8* paddr, MS_U16 ucBufLen, MS_U8* pBuf)
1017 {
1018 MS_U8 u8Dummy = I2C_ACCESS_DUMMY_TIME; // loop dummy
1019 MS_U8 u8BusNum = HIBYTE(u16BusNumSlaveID);
1020 MS_U8 u8SlaveID = LOBYTE(u16BusNumSlaveID);
1021 MS_BOOL bRet = FALSE;
1022 MS_U8* pu8addr_temp=(MS_U8*)NULL;
1023 MS_U8* paddr_temp=(MS_U8*)NULL;
1024 MS_U16 ucBufLen_temp=0;
1025 MS_U8 ucSubAdr_temp=0;
1026
1027
1028 SWI2C_DBG_FUNC();
1029
1030 if(u8BusAllocNum==0)
1031 return FALSE;
1032
1033 LOCK_HW_SEM();
1034 IIC_MUTEX_S_LOCK();
1035 IIC_MUTEX_LOCK(u8BusNum);
1036 if (IIC_UseBus(u8BusNum) == FALSE)
1037 {
1038 IIC_MUTEX_UNLOCK(u8BusNum);
1039 IIC_MUTEX_S_UNLOCK();
1040 UNLOCK_HW_SEM();
1041 return FALSE;
1042 }
1043
1044 while (u8Dummy--)
1045 {
1046 ucBufLen_temp = ucBufLen;
1047 ucSubAdr_temp = ucSubAdr;
1048 pu8addr_temp = (MS_U8*)pBuf;
1049 paddr_temp = (MS_U8*)paddr;
1050 if((g_I2CReadMode[u8BusNum]!=E_SWI2C_READ_MODE_DIRECT) && (ucSubAdr_temp>0) && (paddr_temp))
1051 {
1052 if (IIC_AccessStart(u8BusNum, u8SlaveID, SWI2C_WRITE) == FALSE)
1053 {
1054 if( u8Dummy )
1055 continue;
1056 else
1057 goto fail;
1058 }
1059
1060 while (ucSubAdr_temp)
1061 {
1062 ucSubAdr_temp--;
1063 if (IIC_SendByte(u8BusNum,*paddr_temp) == FALSE)
1064 {
1065 goto fail;
1066 }
1067 paddr_temp++;
1068 }
1069
1070 if(g_I2CReadMode[u8BusNum]==E_SWI2C_READ_MODE_DIRECTION_CHANGE_STOP_START)
1071 {
1072 IIC_Stop(u8BusNum);
1073 }
1074 }
1075
1076 if (IIC_AccessStart(u8BusNum, u8SlaveID, SWI2C_READ) == FALSE)
1077 {
1078 if( u8Dummy )
1079 continue;
1080 else
1081 goto fail;
1082 }
1083
1084 while (ucBufLen_temp--) // loop to burst read
1085 {
1086 *pu8addr_temp = IIC_GetByte(u8BusNum,ucBufLen_temp); // receive byte
1087 pu8addr_temp++; // next byte pointer
1088 }
1089 bRet = TRUE;
1090 break;
1091 fail:
1092
1093 IIC_Stop(u8BusNum);
1094 bRet = FALSE;
1095 }
1096
1097 IIC_Stop(u8BusNum);
1098 IIC_UnuseBus(u8BusNum);
1099 IIC_MUTEX_UNLOCK(u8BusNum);
1100 IIC_MUTEX_S_UNLOCK();
1101 UNLOCK_HW_SEM();
1102
1103 return bRet;
1104 }
1105
1106 /******************************************************************************/
1107 ///Read 1 byte through IIC
1108 ///@param u16BusNumSlaveID \b IN: Bus Number (high byte) and Slave ID (Address) (low byte)
1109 ///@param u8RegAddr \b IN: Target register offset to read
1110 ///@param *pu8Data \b IN: pointer to 1 byte return data.
1111 ///@return MS_BOOL:
1112 ///- TRUE: Success
1113 ///- FALSE: Fail
1114 /******************************************************************************/
MApi_SWI2C_ReadByte(MS_U16 u16BusNumSlaveID,MS_U8 u8RegAddr,MS_U8 * pu8Data)1115 MS_BOOL MApi_SWI2C_ReadByte(MS_U16 u16BusNumSlaveID, MS_U8 u8RegAddr, MS_U8 *pu8Data)
1116 {
1117 MS_BOOL Result;
1118
1119 SWI2C_DBG_FUNC();
1120
1121 Result=MApi_SWI2C_ReadBytes(u16BusNumSlaveID, 1, &u8RegAddr,1, pu8Data);
1122 return Result;
1123 }
1124
1125 /******************************************************************************/
1126 ///Write 1 byte through IIC
1127 ///@param u16BusNumSlaveID \b IN: Bus Number (high byte) and Slave ID (Address) (low byte)
1128 ///@param u8RegAddr \b IN: Target register offset to write
1129 ///@param u8Data \b IN: 1 byte data to write
1130 ///@return MS_BOOL:
1131 ///- TRUE: Success
1132 ///- FALSE: Fail
1133 /******************************************************************************/
MApi_SWI2C_WriteByte(MS_U16 u16BusNumSlaveID,MS_U8 u8RegAddr,MS_U8 u8Data)1134 MS_BOOL MApi_SWI2C_WriteByte(MS_U16 u16BusNumSlaveID, MS_U8 u8RegAddr, MS_U8 u8Data)
1135 {
1136 SWI2C_DBG_FUNC();
1137
1138 return( MApi_SWI2C_WriteBytes(u16BusNumSlaveID, 1, &u8RegAddr, 1, &u8Data) );
1139 }
1140 //------------------------------------------------------------------------
MApi_SWI2C_Write2Bytes(MS_U16 u16BusNumSlaveID,MS_U8 u8addr,MS_U16 u16data)1141 MS_BOOL MApi_SWI2C_Write2Bytes(MS_U16 u16BusNumSlaveID, MS_U8 u8addr, MS_U16 u16data)
1142 {
1143 MS_U8 u8Data[2];
1144
1145 SWI2C_DBG_FUNC();
1146
1147 u8Data[0] = (u16data>>8) & 0xFF;
1148 u8Data[1] = (u16data) & 0xFF;
1149 return (MApi_SWI2C_WriteBytes(u16BusNumSlaveID, 1, &u8addr, 2, u8Data));
1150 }
1151
MApi_SWI2C_Read2Bytes(MS_U16 u16BusNumSlaveID,MS_U8 u8addr)1152 MS_U16 MApi_SWI2C_Read2Bytes(MS_U16 u16BusNumSlaveID, MS_U8 u8addr)
1153 {
1154 SWI2C_DBG_FUNC();
1155
1156 MS_U8 u8Data[2]={0,0};
1157 MApi_SWI2C_ReadBytes(u16BusNumSlaveID, 1, &u8addr, 2, u8Data);
1158 return ( (((MS_U16)u8Data[0])<<8)|u8Data[1] );
1159 }
1160
MApi_SWI2C_WriteByteDirectly(MS_U16 u16BusNumSlaveID,MS_U8 u8Data)1161 MS_BOOL MApi_SWI2C_WriteByteDirectly(MS_U16 u16BusNumSlaveID, MS_U8 u8Data)
1162 {
1163 MS_U8 u8BusNum = HIBYTE(u16BusNumSlaveID);
1164 MS_U8 u8SlaveID = LOBYTE(u16BusNumSlaveID);
1165 MS_BOOL bRet = FALSE;
1166
1167 SWI2C_DBG_FUNC();
1168
1169 if(u8BusAllocNum==0)
1170 return FALSE;
1171
1172 LOCK_HW_SEM();
1173 IIC_MUTEX_S_LOCK();
1174 IIC_MUTEX_LOCK(u8BusNum);
1175 if (IIC_UseBus(u8BusNum) == FALSE)
1176 {
1177 IIC_MUTEX_UNLOCK(u8BusNum);
1178 IIC_MUTEX_S_UNLOCK();
1179 UNLOCK_HW_SEM();
1180 return FALSE;
1181 }
1182
1183 IIC_Start(u8BusNum);
1184 if (IIC_SendByte(u8BusNum,(u8SlaveID&~BIT0)) == FALSE)
1185 goto fail;
1186 if (IIC_SendByte(u8BusNum,u8Data)==FALSE)
1187 goto fail;
1188 bRet = TRUE;
1189
1190 fail:
1191
1192 IIC_Stop(u8BusNum);
1193 IIC_UnuseBus(u8BusNum);
1194 IIC_MUTEX_UNLOCK(u8BusNum);
1195 IIC_MUTEX_S_UNLOCK();
1196 UNLOCK_HW_SEM();
1197
1198 return bRet;
1199 }
1200
1201
MApi_SWI2C_Write4Bytes(MS_U16 u16BusNumSlaveID,MS_U32 u32Data,MS_U8 u8EndData)1202 MS_BOOL MApi_SWI2C_Write4Bytes(MS_U16 u16BusNumSlaveID, MS_U32 u32Data, MS_U8 u8EndData)
1203 {
1204 MS_U8 u8BusNum = HIBYTE(u16BusNumSlaveID);
1205 MS_U8 u8SlaveID = LOBYTE(u16BusNumSlaveID);
1206 MS_BOOL bRet = FALSE;
1207
1208 SWI2C_DBG_FUNC();
1209
1210 if (u8BusAllocNum==0)
1211 return FALSE;
1212
1213 LOCK_HW_SEM();
1214 IIC_MUTEX_S_LOCK();
1215 IIC_MUTEX_LOCK(u8BusNum);
1216 if (IIC_UseBus(u8BusNum) == FALSE)
1217 {
1218 IIC_MUTEX_UNLOCK(u8BusNum);
1219 IIC_MUTEX_S_UNLOCK();
1220 UNLOCK_HW_SEM();
1221 return FALSE;
1222 }
1223
1224 IIC_Start(u8BusNum);
1225 if(IIC_SendByte(u8BusNum,(u8SlaveID&~BIT0))==FALSE)
1226 goto fail;
1227 if(IIC_SendByte(u8BusNum,(MS_U8)(((MS_U32)u32Data)>>24) ) == FALSE )
1228 goto fail;
1229 if(IIC_SendByte(u8BusNum,(MS_U8)(((MS_U32)u32Data)>>16) ) == FALSE )
1230 goto fail;
1231 if(IIC_SendByte(u8BusNum,(MS_U8)(((MS_U32)u32Data)>>8) ) == FALSE )
1232 goto fail;
1233 if(IIC_SendByte(u8BusNum,(MS_U8)(((MS_U32)u32Data)>>0) ) == FALSE )
1234 goto fail;
1235 if(IIC_SendByte(u8BusNum,u8EndData)==FALSE)
1236 goto fail;
1237 bRet = TRUE;
1238
1239 fail:
1240
1241 IIC_Stop(u8BusNum);
1242 IIC_UnuseBus(u8BusNum);
1243 IIC_MUTEX_UNLOCK(u8BusNum);
1244 IIC_MUTEX_S_UNLOCK();
1245 UNLOCK_HW_SEM();
1246
1247 return bRet;
1248 }
1249
MApi_SWI2C_WriteGroupBytes(MS_U16 u16BusNumSlaveID,MS_U8 u8SubGroup,MS_U16 u16Addr,MS_U16 u16Data)1250 MS_BOOL MApi_SWI2C_WriteGroupBytes(MS_U16 u16BusNumSlaveID, MS_U8 u8SubGroup, MS_U16 u16Addr, MS_U16 u16Data)
1251 {
1252 MS_U8 u8BusNum = HIBYTE(u16BusNumSlaveID);
1253 MS_U8 u8SlaveID = LOBYTE(u16BusNumSlaveID);
1254 MS_BOOL bRet = FALSE;
1255
1256 SWI2C_DBG_FUNC();
1257
1258 if(u8BusAllocNum==0)
1259 return FALSE;
1260
1261 LOCK_HW_SEM();
1262 IIC_MUTEX_LOCK(u8BusNum);
1263 if (IIC_UseBus(u8BusNum) == FALSE)
1264 {
1265 IIC_MUTEX_UNLOCK(u8BusNum);
1266 UNLOCK_HW_SEM();
1267 return FALSE;
1268 }
1269
1270 IIC_Start(u8BusNum);
1271 if(IIC_SendByte(u8BusNum,(u8SlaveID&~BIT0))==FALSE)
1272 goto fail;
1273 if(IIC_SendByte(u8BusNum,u8SubGroup)==FALSE)
1274 goto fail;
1275 if(IIC_SendByte(u8BusNum,(u16Addr>>8)&0xFF)==FALSE)
1276 goto fail;
1277 if(IIC_SendByte(u8BusNum,u16Addr&0xFF)==FALSE)
1278 goto fail;
1279 if(IIC_SendByte(u8BusNum,(u16Data>>8)&0xFF)==FALSE)
1280 goto fail;
1281 if(IIC_SendByte(u8BusNum,u16Data&0xFF)==FALSE)
1282 goto fail;
1283 bRet = TRUE;
1284
1285 fail:
1286
1287 IIC_Stop(u8BusNum);
1288 IIC_UnuseBus(u8BusNum);
1289 IIC_MUTEX_UNLOCK(u8BusNum);
1290 UNLOCK_HW_SEM();
1291
1292 return bRet;
1293 }
1294
MApi_SWI2C_ReadGroupBytes(MS_U16 u16BusNumSlaveID,MS_U8 u8SubGroup,MS_U16 u16Addr)1295 MS_U16 MApi_SWI2C_ReadGroupBytes(MS_U16 u16BusNumSlaveID, MS_U8 u8SubGroup, MS_U16 u16Addr)
1296 {
1297 MS_U16 u16Data = 0; // Modified it by coverity_507
1298 MS_U8 u8Address[3];
1299
1300 SWI2C_DBG_FUNC();
1301
1302 u8Address[0] = u8SubGroup;
1303 u8Address[1] = (u16Addr>>8)&0xFF;
1304 u8Address[2] = u16Addr&0xFF;
1305
1306 MApi_SWI2C_ReadBytes(u16BusNumSlaveID, 3, u8Address, 2, (MS_U8 *)&u16Data);
1307
1308 return u16Data;
1309 }
1310
MApi_SWI2C_GetLibVer(const MSIF_Version ** ppVersion)1311 MS_BOOL MApi_SWI2C_GetLibVer(const MSIF_Version **ppVersion)
1312 {
1313 SWI2C_DBG_FUNC();
1314
1315 if (!ppVersion)
1316 {
1317 return FALSE;
1318 }
1319
1320 *ppVersion = &_api_swi2c_version;
1321 return TRUE;
1322 }
1323
1324 //-------------------------------------------------------------------------------------------------
1325 /// Set SWI2C debug function level.
1326 /// @param eLevel \b IN: E_SWI2C_DBGLVL_NONE/E_SWI2C_DBGLVL_WARNING/E_SWI2C_DBGLVL_ERROR/E_SWI2C_DBGLVL_INFO/E_SWI2C_DBGLVL_ALL
1327 /// @return E_SWI2C_OK: Success
1328 /// @return E_SWI2C_FAIL or other values: Failure
1329 //-------------------------------------------------------------------------------------------------
MApi_SWI2C_SetDbgLevel(SWI2C_DbgLvl eLevel)1330 SWI2C_Result MApi_SWI2C_SetDbgLevel(SWI2C_DbgLvl eLevel)
1331 {
1332 SWI2C_DBG_INFO("Debug level: %u\n", eLevel);
1333
1334 _gSWI2CDbgLevel = eLevel;
1335 return E_SWI2C_OK;
1336 }
1337
1338 /******************************************************************************/
1339 ///
1340 /// The following API functions are packed for special usage in ISP programming
1341 ///
1342 /******************************************************************************/
1343
1344 ////////////////////////////////////////////////////////////////////////////////
1345 /// Packed I2C MUTEX Lock.
1346 ///
1347 /// Arguments:
1348 /// @ None
1349 /// return:
1350 /// @ None:
1351 ////////////////////////////////////////////////////////////////////////////////
MApi_SWI2C_MutexLock(void)1352 void MApi_SWI2C_MutexLock(void)
1353 {
1354 IIC_MUTEX_S_LOCK();
1355 }
1356
1357 ////////////////////////////////////////////////////////////////////////////////
1358 /// Packed I2C MUTEX Unlock.
1359 ///
1360 /// Arguments:
1361 /// @ None
1362 /// return:
1363 /// @ None:
1364 ////////////////////////////////////////////////////////////////////////////////
MApi_SWI2C_MutexUnlock(void)1365 void MApi_SWI2C_MutexUnlock(void)
1366 {
1367 IIC_MUTEX_S_UNLOCK();
1368 }
1369
1370 ////////////////////////////////////////////////////////////////////////////////
1371 /// Packed I2C Bus Use.
1372 ///
1373 /// Arguments:
1374 /// @ None
1375 /// return:
1376 /// @ None:
1377 ////////////////////////////////////////////////////////////////////////////////
MApi_SWI2C_UseBus(MS_U8 u8BusChn)1378 void MApi_SWI2C_UseBus( MS_U8 u8BusChn )
1379 {
1380 LOCK_HW_SEM();
1381 IIC_MUTEX_LOCK(u8BusChn);
1382 IIC_UseBus(u8BusChn);
1383 IIC_MUTEX_UNLOCK(u8BusChn);
1384 UNLOCK_HW_SEM();
1385 }
1386
1387 ////////////////////////////////////////////////////////////////////////////////
1388 /// Packed I2C Bus Unuse.
1389 ///
1390 /// Arguments:
1391 /// @ None
1392 /// return:
1393 /// @ None:
1394 ////////////////////////////////////////////////////////////////////////////////
MApi_SWI2C_UnuseBus(void)1395 void MApi_SWI2C_UnuseBus(void)
1396 {
1397 IIC_UnuseBus(u8BusSel);
1398 }
1399
1400 ////////////////////////////////////////////////////////////////////////////////
1401 /// Packed I2C access start.
1402 ///
1403 /// Arguments:
1404 /// @u8SlaveID - Slave ID (Address)
1405 /// @trans_t - I2C_TRANS_WRITE/I2C_TRANS_READ
1406 /// @return MS_BOOL:
1407 /// - TRUE: Success
1408 /// - FALSE: Fail
1409 ////////////////////////////////////////////////////////////////////////////////
MApi_SWI2C_AccessStart(MS_U8 u8SlaveID,MS_U8 trans_t)1410 MS_BOOL MApi_SWI2C_AccessStart(MS_U8 u8SlaveID, MS_U8 trans_t)
1411 {
1412 MS_BOOL bRet;
1413 bRet = IIC_AccessStart(u8BusSel, u8SlaveID, trans_t);
1414 return bRet;
1415 }
1416
1417 ////////////////////////////////////////////////////////////////////////////////
1418 /// Packed I2C access stop.
1419 ///
1420 /// Arguments:
1421 /// @ None
1422 /// return:
1423 /// @ None
1424 ////////////////////////////////////////////////////////////////////////////////
MApi_SWI2C_Stop(void)1425 void MApi_SWI2C_Stop(void)
1426 {
1427 IIC_Stop(u8BusSel);
1428 }
1429
1430 ////////////////////////////////////////////////////////////////////////////////
1431 /// Packed I2C access start.
1432 ///
1433 /// Arguments:
1434 /// @ None
1435 /// return:
1436 /// @ MS_BOOL:
1437 /// - TRUE: Success
1438 /// - FALSE: Fail
1439 ////////////////////////////////////////////////////////////////////////////////
MApi_SWI2C_Start(void)1440 MS_BOOL MApi_SWI2C_Start(void)
1441 {
1442 return IIC_Start(u8BusSel);
1443 }
1444
1445 ////////////////////////////////////////////////////////////////////////////////
1446 /// Packed I2C send byte.
1447 ///
1448 /// Arguments:
1449 /// @ u8Data : one-byte data for sending
1450 /// @return MS_BOOL:
1451 /// - TRUE: Success
1452 /// - FALSE: Fail
1453 ////////////////////////////////////////////////////////////////////////////////
MApi_SWI2C_SendByte(MS_U8 u8Data)1454 MS_BOOL MApi_SWI2C_SendByte(MS_U8 u8Data)
1455 {
1456 MS_BOOL bRet;
1457
1458 bRet = IIC_SendByte(u8BusSel, u8Data);
1459 return bRet;
1460 }
1461
1462 ////////////////////////////////////////////////////////////////////////////////
1463 /// Packed I2C send byte.
1464 ///
1465 /// Arguments:
1466 /// @ u16Ack :
1467 /// None 0 : get next byte and request next byte from slave device,
1468 /// 0 : get next byte and inform of slave device not to send data anymore.
1469 /// @return MS_U8:
1470 /// return one-byte data from slave device
1471 ////////////////////////////////////////////////////////////////////////////////
MApi_SWI2C_GetByte(MS_U16 u16Ack)1472 MS_U8 MApi_SWI2C_GetByte(MS_U16 u16Ack)
1473 {
1474 MS_U8 u8Ret;
1475
1476 u8Ret = IIC_GetByte(u8BusSel, u16Ack);
1477 return u8Ret;
1478 }
1479
MApi_SWI2C_SetPowerState(EN_POWER_MODE u16PowerState)1480 MS_U16 MApi_SWI2C_SetPowerState(EN_POWER_MODE u16PowerState)
1481 {
1482 static EN_POWER_MODE _prev_u16PowerState = E_POWER_MECHANICAL;
1483 MS_U16 u16Return = FALSE;
1484
1485 if (u16PowerState == E_POWER_SUSPEND)
1486 {
1487 _prev_u16PowerState = u16PowerState;
1488 u16Return = 2;//SUSPEND_OK;
1489 }
1490 else if (u16PowerState == E_POWER_RESUME)
1491 {
1492 if (_prev_u16PowerState == E_POWER_SUSPEND)
1493 {
1494 MApi_SWI2C_Init(g_SWI2CCBusCfg,g_u8CfgBusNum);
1495 _prev_u16PowerState = u16PowerState;
1496 u16Return = 1;//RESUME_OK;
1497 }
1498 else
1499 {
1500 SWI2C_DBG_INFO("[%s,%5d]It is not suspended yet. We shouldn't resume\n",__FUNCTION__,__LINE__);
1501 u16Return = 3;//SUSPEND_FAILED;
1502 }
1503 }
1504 else
1505 {
1506 SWI2C_DBG_INFO("[%s,%5d]Do Nothing: %d\n",__FUNCTION__,__LINE__,u16PowerState);
1507 u16Return = FALSE;
1508 }
1509 return u16Return;// for success
1510 }
1511
1512 #undef _API_SWI2C_C_
1513
1514