ICM20600_i2c.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632
  1. #include "ICM20600_i2c.h"
  2. /* STM32 I2C 快速模式 */
  3. #define I2C_Speed 400000 //*
  4. #define I2Cx_OWN_ADDRESS7 0X0A
  5. static __IO uint32_t I2CTimeout = I2CT_LONG_TIMEOUT;
  6. static unsigned short RETRY_IN_MLSEC = 5;
  7. //若定义了这个宏,使用硬件iic,否则使用软件iic。这个宏在bsp_i2c.h文件定义
  8. //使用硬件IIC时不能与液晶屏共用,因为FSMC的NADV与IIC1的SDA 是同一个引脚,互相影响了
  9. #ifdef HARD_IIC
  10. /********************************* Prototypes *********************************/
  11. unsigned long ST_Hard_Sensors_I2C_WriteRegister(unsigned char Address, unsigned char RegisterAddr, unsigned short RegisterLen, const unsigned char *RegisterValue);
  12. unsigned long ST_Hard_Sensors_I2C_ReadRegister(unsigned char Address, unsigned char RegisterAddr, unsigned short RegisterLen, unsigned char *RegisterValue);
  13. /******************************* Function ************************************/
  14. #define ST_Sensors_I2C_WriteRegister ST_Hard_Sensors_I2C_WriteRegister
  15. #define ST_Sensors_I2C_ReadRegister ST_Hard_Sensors_I2C_ReadRegister
  16. static uint8_t I2C_TIMEOUT_UserCallback(uint8_t errorCode);
  17. #else
  18. #define Soft_I2C_SDA_STATE HAL_GPIO_ReadPin(Soft_I2C_PORT, Soft_I2C_SDA)
  19. #define Soft_I2C_DELAY Soft_I2C_Delay(100000)
  20. #define Soft_I2C_NOP Soft_I2C_Delay(10)
  21. #define Soft_I2C_READY 0x00
  22. #define Soft_I2C_BUS_BUSY 0x01
  23. #define Soft_I2C_BUS_ERROR 0x02
  24. #define Soft_I2C_NACK 0x00
  25. #define Soft_I2C_ACK 0x01
  26. static void Soft_I2C_Configuration(void);
  27. static void Soft_I2C_Delay(uint32_t dly);
  28. static uint8_t Soft_I2C_START(void);
  29. static void Soft_I2C_STOP(void);
  30. static void Soft_I2C_SendACK(void);
  31. static void Soft_I2C_SendNACK(void);
  32. static uint8_t Soft_I2C_SendByte(uint8_t anbt_i2c_data);
  33. static uint8_t Soft_I2C_ReceiveByte_WithACK(void);
  34. static uint8_t Soft_I2C_ReceiveByte_WithNACK(void);
  35. static uint8_t Soft_DMP_I2C_Write(uint8_t soft_dev_addr, uint8_t soft_reg_addr, uint8_t soft_i2c_len,uint8_t *soft_i2c_data_buf);
  36. // static uint8_t Soft_DMP_I2C_Read(uint8_t soft_dev_addr, uint8_t soft_reg_addr, uint8_t soft_i2c_len,uint8_t *soft_i2c_data_buf);
  37. uint8_t Soft_DMP_I2C_Read(uint8_t soft_dev_addr, uint8_t soft_reg_addr, uint8_t soft_i2c_len,uint8_t *soft_i2c_data_buf);
  38. #define ST_Sensors_I2C_WriteRegister Soft_DMP_I2C_Write
  39. #define ST_Sensors_I2C_ReadRegister Soft_DMP_I2C_Read
  40. #endif
  41. /**
  42. * @brief 向IIC设备的寄存器连续写入数据,带超时重试设置,供mpu接口调用
  43. * @param Address: IIC设备地址
  44. * @param RegisterAddr: 寄存器地址
  45. * @param RegisterLen: 要写入数据的长度
  46. * @param RegisterValue: 要指向写入数据的指针
  47. * @retval 0正常,非0异常
  48. */
  49. void Sensors_I2C_WriteRegister(uint8_t slave_addr,
  50. uint8_t reg_addr,
  51. uint8_t len,
  52. uint8_t *data_ptr)
  53. {
  54. char retries=0;
  55. int ret = 0;
  56. unsigned short retry_in_mlsec = Get_I2C_Retry();
  57. tryWriteAgain:
  58. ret = 0;
  59. ret = ST_Sensors_I2C_WriteRegister( slave_addr, reg_addr, len, ( uint8_t *)data_ptr);
  60. if(ret && retry_in_mlsec)
  61. {
  62. if( retries++ > 4 )
  63. return ;
  64. HAL_Delay(retry_in_mlsec);
  65. goto tryWriteAgain;
  66. }
  67. return ;
  68. }
  69. /**
  70. * @brief 向IIC设备的寄存器连续读出数据,带超时重试设置,供mpu接口调用
  71. * @param Address: IIC设备地址
  72. * @param RegisterAddr: 寄存器地址
  73. * @param RegisterLen: 要读取的数据长度
  74. * @param RegisterValue: 指向存储读出数据的指针
  75. * @retval 0正常,非0异常
  76. */
  77. void Sensors_I2C_ReadRegister(uint8_t slave_addr,
  78. uint8_t reg_addr,
  79. uint8_t len,
  80. uint8_t *data_ptr)
  81. {
  82. char retries=0;
  83. int ret = 0;
  84. unsigned short retry_in_mlsec = Get_I2C_Retry();
  85. tryReadAgain:
  86. ret = 0;
  87. ret = ST_Sensors_I2C_ReadRegister( slave_addr, reg_addr, len, ( unsigned char *)data_ptr);
  88. if(ret && retry_in_mlsec)
  89. {
  90. if( retries++ > 4 )
  91. return ;
  92. HAL_Delay(retry_in_mlsec);
  93. goto tryReadAgain;
  94. }
  95. return ;
  96. }
  97. void I2C_Bus_Init(void)
  98. {
  99. Set_I2C_Retry(5);
  100. #ifdef HARD_IIC
  101. I2C_GPIO_Config();
  102. I2C_Mode_Configu();
  103. #else
  104. Soft_I2C_Configuration();
  105. #endif
  106. }
  107. /**
  108. * @brief 设置iic重试时间
  109. * @param ml_sec:重试的时间,单位毫秒
  110. * @retval 重试的时间,单位毫秒
  111. */
  112. void Set_I2C_Retry(unsigned short ml_sec)
  113. {
  114. RETRY_IN_MLSEC = ml_sec;
  115. }
  116. /**
  117. * @brief 获取设置的iic重试时间
  118. * @param none
  119. * @retval none
  120. */
  121. unsigned short Get_I2C_Retry(void)
  122. {
  123. return RETRY_IN_MLSEC;
  124. }
  125. #ifdef HARD_IIC
  126. static void I2C_GPIO_Config(void)
  127. {
  128. GPIO_InitTypeDef GPIO_InitStructure;
  129. /* 使能与 I2C1 有关的时钟 */
  130. SENSORS_I2C_APBxClock_FUN ( SENSORS_I2C_CLK, ENABLE );
  131. SENSORS_I2C_GPIO_APBxClock_FUN ( SENSORS_I2C_GPIO_CLK, ENABLE );
  132. /* PB6-I2C1_SCL、PB7-I2C1_SDA*/
  133. GPIO_InitStructure.GPIO_Pin = SENSORS_I2C_SCL_PIN;
  134. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  135. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; // 开漏输出
  136. GPIO_Init(SENSORS_I2C_SCL_PORT, &GPIO_InitStructure);
  137. GPIO_InitStructure.GPIO_Pin = SENSORS_I2C_SDA_PIN;
  138. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  139. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; // 开漏输出
  140. GPIO_Init(SENSORS_I2C_SDA_PORT, &GPIO_InitStructure);
  141. }
  142. static void I2C_Mode_Configu(void)
  143. {
  144. I2C_InitTypeDef I2C_InitStructure;
  145. /* I2C 配置 */
  146. I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
  147. /* 高电平数据稳定,低电平数据变化 SCL 时钟线的占空比 */
  148. I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
  149. I2C_InitStructure.I2C_OwnAddress1 =I2Cx_OWN_ADDRESS7;
  150. I2C_InitStructure.I2C_Ack = I2C_Ack_Enable ;
  151. /* I2C的寻址模式 */
  152. I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
  153. /* 通信速率 */
  154. I2C_InitStructure.I2C_ClockSpeed = I2C_Speed;
  155. /* I2C1 初始化 */
  156. I2C_Init(SENSORS_I2Cx, &I2C_InitStructure);
  157. /* 使能 I2C1 */
  158. I2C_Cmd(SENSORS_I2Cx, ENABLE);
  159. }
  160. /**
  161. * @brief 向IIC设备的寄存器连续写入数据
  162. * @param Address: IIC设备地址
  163. * @param RegisterAddr: 寄存器地址
  164. * @param RegisterLen: 要写入数据的长度
  165. * @param RegisterValue: 要指向写入数据的指针
  166. * @retval 0正常,非0异常
  167. */
  168. unsigned long ST_Hard_Sensors_I2C_WriteRegister(unsigned char Address, unsigned char RegisterAddr, unsigned short RegisterLen, const unsigned char *RegisterValue)
  169. {
  170. uint32_t i=0;
  171. /* Send STRAT condition */
  172. I2C_GenerateSTART(SENSORS_I2Cx, ENABLE);
  173. I2CTimeout = I2CT_FLAG_TIMEOUT;
  174. /* Test on EV5 and clear it */
  175. while(!I2C_CheckEvent(SENSORS_I2Cx, I2C_EVENT_MASTER_MODE_SELECT))
  176. {
  177. if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(0);
  178. }
  179. /* Send slave address for write */
  180. I2C_Send7bitAddress(SENSORS_I2Cx, (Address<<1), I2C_Direction_Transmitter);
  181. I2CTimeout = I2CT_FLAG_TIMEOUT;
  182. /* Test on EV6 and clear it */
  183. while(!I2C_CheckEvent(SENSORS_I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
  184. {
  185. if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(1);
  186. }
  187. /* Send the slave's internal address to write to */
  188. I2C_SendData(SENSORS_I2Cx, RegisterAddr);
  189. I2CTimeout = I2CT_FLAG_TIMEOUT;
  190. /* Test on EV8 and clear it */
  191. while(!I2C_CheckEvent(SENSORS_I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
  192. {
  193. if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(2);
  194. }
  195. /* Send the byte to be written */
  196. for( i=0; i<(RegisterLen); i++)
  197. {
  198. I2CTimeout = I2CT_FLAG_TIMEOUT;
  199. /* Test on EV8 and clear it */
  200. while(!I2C_CheckEvent(SENSORS_I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
  201. {
  202. if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(3);
  203. }
  204. /* Prepare the register value to be sent */
  205. I2C_SendData(SENSORS_I2Cx, RegisterValue[i]);
  206. }
  207. I2CTimeout = I2CT_FLAG_TIMEOUT;
  208. /* Test on EV8 and clear it */
  209. while(!I2C_CheckEvent(SENSORS_I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
  210. {
  211. if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(4);
  212. }
  213. /* Send STOP condition */
  214. I2C_GenerateSTOP(SENSORS_I2Cx, ENABLE);
  215. return 0; //正常返回0
  216. }
  217. /**
  218. * @brief 向IIC设备的寄存器连续读出数据
  219. * @param Address: IIC设备地址
  220. * @param RegisterAddr: 寄存器地址
  221. * @param RegisterLen: 要读取的数据长度
  222. * @param RegisterValue: 指向存储读出数据的指针
  223. * @retval 0正常,非0异常
  224. */
  225. unsigned long ST_Hard_Sensors_I2C_ReadRegister(unsigned char Address, unsigned char RegisterAddr, unsigned short RegisterLen, unsigned char *RegisterValue)
  226. {
  227. I2CTimeout = I2CT_LONG_TIMEOUT;
  228. while(I2C_GetFlagStatus(SENSORS_I2Cx, I2C_FLAG_BUSY)) // Added by Najoua 27/08/2008
  229. {
  230. if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(5);
  231. }
  232. I2C_GenerateSTART(SENSORS_I2Cx, ENABLE);
  233. I2CTimeout = I2CT_FLAG_TIMEOUT;
  234. /* Test on EV5 and clear it */
  235. while(!I2C_CheckEvent(SENSORS_I2Cx, I2C_EVENT_MASTER_MODE_SELECT))
  236. {
  237. if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(6);
  238. }
  239. /* Send slave address for write */
  240. I2C_Send7bitAddress(SENSORS_I2Cx, (Address<<1), I2C_Direction_Transmitter);
  241. I2CTimeout = I2CT_FLAG_TIMEOUT;
  242. /* Test on EV6 and clear it */
  243. while(!I2C_CheckEvent(SENSORS_I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
  244. {
  245. if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(7);
  246. }
  247. /* Clear EV6 by setting again the PE bit */
  248. I2C_Cmd(SENSORS_I2Cx, ENABLE);
  249. /* Send the slave's internal address to write to */
  250. I2C_SendData(SENSORS_I2Cx, RegisterAddr);
  251. I2CTimeout = I2CT_FLAG_TIMEOUT;
  252. /* Test on EV8 and clear it */
  253. while(!I2C_CheckEvent(SENSORS_I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
  254. {
  255. if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(8);
  256. }
  257. /* Send STRAT condition a second time */
  258. I2C_GenerateSTART(SENSORS_I2Cx, ENABLE);
  259. I2CTimeout = I2CT_FLAG_TIMEOUT;
  260. /* Test on EV5 and clear it */
  261. while(!I2C_CheckEvent(SENSORS_I2Cx, I2C_EVENT_MASTER_MODE_SELECT))
  262. {
  263. if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(9);
  264. }
  265. /* Send slave address for read */
  266. I2C_Send7bitAddress(SENSORS_I2Cx, (Address<<1), I2C_Direction_Receiver);
  267. I2CTimeout = I2CT_FLAG_TIMEOUT;
  268. /* Test on EV6 and clear it */
  269. while(!I2C_CheckEvent(SENSORS_I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
  270. {
  271. if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(10);
  272. }
  273. /* While there is data to be read */
  274. while(RegisterLen)
  275. {
  276. if(RegisterLen == 1)
  277. {
  278. /* Disable Acknowledgement */
  279. I2C_AcknowledgeConfig(SENSORS_I2Cx, DISABLE);
  280. /* Send STOP Condition */
  281. I2C_GenerateSTOP(SENSORS_I2Cx, ENABLE);
  282. }
  283. I2CTimeout = I2CT_LONG_TIMEOUT;
  284. while(!I2C_CheckEvent(SENSORS_I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED))
  285. {
  286. if((I2CTimeout--) == 0)
  287. {
  288. return I2C_TIMEOUT_UserCallback(10);
  289. }
  290. }
  291. {
  292. /* Read a byte from the slave */
  293. *RegisterValue = I2C_ReceiveData(SENSORS_I2Cx);
  294. /* Point to the next location where the byte read will be saved */
  295. RegisterValue++;
  296. /* Decrement the read bytes counter */
  297. RegisterLen--;
  298. }
  299. }
  300. /* Enable Acknowledgement to be ready for another reception */
  301. I2C_AcknowledgeConfig(SENSORS_I2Cx, ENABLE);
  302. return 0; //正常,返回0
  303. }
  304. /**
  305. * @brief Basic management of the timeout situation.
  306. * @param None.
  307. * @retval None.
  308. */
  309. static uint8_t I2C_TIMEOUT_UserCallback(uint8_t errorCode)
  310. {
  311. /*重置IIC*/
  312. I2C_GenerateSTOP(SENSORS_I2Cx, ENABLE);
  313. I2C_SoftwareResetCmd(SENSORS_I2Cx, ENABLE);
  314. I2C_SoftwareResetCmd(SENSORS_I2Cx, DISABLE);
  315. I2C_Bus_Init();
  316. /* Block communication and all processes */
  317. MPU_ERROR("I2C Timeout error! error code = %d",errorCode);
  318. return 1;
  319. }
  320. #endif //endof #ifdef HARD_IIC
  321. /************************软件IIC驱动函数****************************************/
  322. #ifndef HARD_IIC
  323. static void Soft_I2C_Configuration(void)
  324. {
  325. GPIO_InitTypeDef GPIO_InitStructure;
  326. __HAL_RCC_GPIOB_CLK_ENABLE();
  327. //
  328. GPIO_InitStructure.Pin = Soft_I2C_SCL | Soft_I2C_SDA; //配置使用的I2C口
  329. GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW; //设置I2C口最大允许输出速度
  330. GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_OD; //设置I2C为开漏输出
  331. HAL_GPIO_Init(Soft_I2C_PORT, &GPIO_InitStructure);
  332. //
  333. Soft_I2C_SCL_1;
  334. Soft_I2C_SDA_1;
  335. Soft_I2C_DELAY;
  336. }
  337. static void Soft_I2C_Delay(uint32_t dly)
  338. {
  339. while(--dly); //dly=10: 8.75us; dly=100: 85.58 us (SYSCLK=72MHz)
  340. }
  341. static uint8_t Soft_I2C_START(void) //40us
  342. {
  343. Soft_I2C_SDA_1;
  344. Soft_I2C_SCL_1;
  345. Soft_I2C_Delay(7);
  346. if(!Soft_I2C_SDA_STATE) return Soft_I2C_BUS_BUSY;
  347. Soft_I2C_SDA_0;
  348. Soft_I2C_Delay(7);
  349. Soft_I2C_SCL_0;
  350. // Soft_I2C_Delay(2);
  351. if(Soft_I2C_SDA_STATE) return Soft_I2C_BUS_ERROR;
  352. return Soft_I2C_READY;
  353. }
  354. static void Soft_I2C_STOP(void) //30us
  355. {
  356. Soft_I2C_SDA_0;
  357. Soft_I2C_SCL_1;
  358. Soft_I2C_Delay(7);
  359. Soft_I2C_SDA_1;
  360. Soft_I2C_Delay(7);
  361. }
  362. static void Soft_I2C_SendACK(void) //30us
  363. {
  364. Soft_I2C_SDA_0;
  365. Soft_I2C_Delay(2);
  366. Soft_I2C_SCL_1;
  367. Soft_I2C_Delay(7);
  368. Soft_I2C_SCL_0;
  369. // Soft_I2C_Delay(2);
  370. }
  371. static void Soft_I2C_SendNACK(void) //30us
  372. {
  373. Soft_I2C_SDA_1;
  374. Soft_I2C_Delay(2);
  375. Soft_I2C_SCL_1;
  376. Soft_I2C_Delay(7);
  377. Soft_I2C_SCL_0;
  378. // Soft_I2C_Delay(2);
  379. }
  380. /**
  381. * @brief 等待应答信号到来
  382. * @retval 返回值:1,接收应答失败
  383. * 0,接收应答成功
  384. */
  385. uint8_t Soft_I2C_Wait_Ack(void) //20us
  386. {
  387. uint8_t ucErrTime=0;
  388. Soft_I2C_SDA_1;
  389. Soft_I2C_Delay(2);
  390. Soft_I2C_SCL_1;
  391. Soft_I2C_Delay(2);
  392. while(Soft_I2C_SDA_STATE)
  393. {
  394. ucErrTime++;
  395. if(ucErrTime>250)
  396. {
  397. Soft_I2C_STOP();
  398. return Soft_I2C_BUS_ERROR;
  399. }
  400. }
  401. Soft_I2C_SCL_0;//时钟输出0
  402. return 0;
  403. }
  404. static uint8_t Soft_I2C_SendByte(uint8_t soft_i2c_data) //260us
  405. {
  406. uint8_t i;
  407. Soft_I2C_SCL_0;
  408. for(i=0;i<8;i++)
  409. {
  410. if(soft_i2c_data&0x80) Soft_I2C_SDA_1;
  411. else Soft_I2C_SDA_0;
  412. soft_i2c_data<<=1;
  413. // Soft_I2C_Delay(2);
  414. // Soft_I2C_NOP;
  415. Soft_I2C_SCL_1;
  416. Soft_I2C_Delay(2);
  417. // Soft_I2C_NOP;
  418. Soft_I2C_SCL_0;
  419. Soft_I2C_Delay(2);
  420. // Soft_I2C_NOP;
  421. }
  422. return Soft_I2C_Wait_Ack();
  423. }
  424. static uint8_t Soft_I2C_ReceiveByte_WithNACK(void) //200us
  425. {
  426. uint8_t i,soft_i2c_data;
  427. //
  428. Soft_I2C_SDA_1;
  429. Soft_I2C_SCL_0;
  430. soft_i2c_data=0;
  431. //
  432. for(i=0;i<8;i++)
  433. {
  434. Soft_I2C_SCL_1;
  435. Soft_I2C_Delay(2);
  436. soft_i2c_data<<=1;
  437. //
  438. if(Soft_I2C_SDA_STATE) soft_i2c_data|=0x01;
  439. Soft_I2C_SCL_0;
  440. Soft_I2C_Delay(2);
  441. }
  442. Soft_I2C_SendNACK();
  443. return soft_i2c_data;
  444. }
  445. static uint8_t Soft_I2C_ReceiveByte_WithACK(void) //200us
  446. {
  447. uint8_t i,soft_i2c_data;
  448. //
  449. Soft_I2C_SDA_1;
  450. Soft_I2C_SCL_0;
  451. soft_i2c_data=0;
  452. //
  453. for(i=0;i<8;i++)
  454. {
  455. Soft_I2C_SCL_1;
  456. Soft_I2C_Delay(2);
  457. soft_i2c_data<<=1;
  458. //
  459. if(Soft_I2C_SDA_STATE) soft_i2c_data|=0x01;
  460. Soft_I2C_SCL_0;
  461. Soft_I2C_Delay(2);
  462. }
  463. Soft_I2C_SendACK();
  464. return soft_i2c_data;
  465. }
  466. static uint8_t Soft_DMP_I2C_Write(uint8_t soft_dev_addr, uint8_t soft_reg_addr, uint8_t soft_i2c_len,uint8_t *soft_i2c_data_buf) //850us
  467. {
  468. uint8_t i, result=0;
  469. Soft_I2C_START();
  470. result = Soft_I2C_SendByte(soft_dev_addr << 1 | 0x00);
  471. if(result != 0) return result;
  472. result = Soft_I2C_SendByte(soft_reg_addr);
  473. if(result != 0) return result;
  474. for (i=0;i<soft_i2c_len;i++)
  475. {
  476. result = Soft_I2C_SendByte(soft_i2c_data_buf[i]);
  477. if (result != 0) return result;
  478. }
  479. Soft_I2C_STOP();
  480. return 0x00;
  481. }
  482. uint8_t Soft_DMP_I2C_Read(uint8_t soft_dev_addr, uint8_t soft_reg_addr, uint8_t soft_i2c_len,uint8_t *soft_i2c_data_buf)
  483. {
  484. uint8_t result;
  485. Soft_I2C_START();
  486. result = Soft_I2C_SendByte(soft_dev_addr << 1 | 0x00);
  487. if(result != 0) return result;
  488. result = Soft_I2C_SendByte(soft_reg_addr);
  489. if(result != 0) return result;
  490. Soft_I2C_START();
  491. result = Soft_I2C_SendByte(soft_dev_addr << 1 | 0x01);
  492. if(result != 0) return result;
  493. //
  494. while (soft_i2c_len)
  495. {
  496. if (soft_i2c_len==1) *soft_i2c_data_buf =Soft_I2C_ReceiveByte_WithNACK();
  497. else *soft_i2c_data_buf =Soft_I2C_ReceiveByte_WithACK();
  498. soft_i2c_data_buf++;
  499. soft_i2c_len--;
  500. }
  501. Soft_I2C_STOP();
  502. return 0x00;
  503. }
  504. #endif //endof #ifndef HARD_IIC
  505. /*********************************************END OF FILE**********************/