drv_iic.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501
  1. /******************************************************************//**
  2. * @file drv_iic.c
  3. * @brief Serial API of RT-Thread RTOS for EFM32
  4. * COPYRIGHT (C) 2011, RT-Thread Development Team
  5. * @author onelife
  6. * @version 0.4 beta
  7. **********************************************************************
  8. * @section License
  9. * The license and distribution terms for this file may be found in the file LICENSE in this
  10. * distribution or at http://www.rt-thread.org/license/LICENSE
  11. **********************************************************************
  12. * @section Change Logs
  13. * Date Author Notes
  14. * 2011-01-06 onelife Initial creation for EFM32
  15. *********************************************************************/
  16. /******************************************************************//**
  17. * @addtogroup efm32
  18. * @{
  19. *********************************************************************/
  20. /* Includes -------------------------------------------------------------------*/
  21. #include "board.h"
  22. #include "drv_iic.h"
  23. /* Private typedef -------------------------------------------------------------*/
  24. /* Private define --------------------------------------------------------------*/
  25. /* Private macro --------------------------------------------------------------*/
  26. /* Private variables ------------------------------------------------------------*/
  27. #ifdef RT_USING_IIC0
  28. #if (RT_USING_IIC0 > 3)
  29. #error "The location number range of IIC is 0~3"
  30. #endif
  31. struct rt_device iic0_device;
  32. #endif
  33. #ifdef RT_USING_IIC1
  34. #if (RT_USING_IIC1 > 3)
  35. #error "The location number range of IIC is 0~3"
  36. #endif
  37. struct rt_device iic1_device;
  38. #endif
  39. /* Private function prototypes ---------------------------------------------------*/
  40. /* Private functions ------------------------------------------------------------*/
  41. /******************************************************************//**
  42. * @brief
  43. * Initialize IIC device
  44. *
  45. * @details
  46. *
  47. * @note
  48. *
  49. * @param[in] dev
  50. * Pointer to device descriptor
  51. *
  52. * @return
  53. * Error code
  54. *********************************************************************/
  55. static rt_err_t rt_iic_init (rt_device_t dev)
  56. {
  57. struct efm32_iic_device_t* iic;
  58. iic = (struct efm32_iic_device_t*)dev->user_data;
  59. if (!(dev->flag & RT_DEVICE_FLAG_ACTIVATED))
  60. {
  61. /* Enable IIC */
  62. I2C_Enable(iic->iic_device, true);
  63. dev->flag |= RT_DEVICE_FLAG_ACTIVATED;
  64. }
  65. return RT_EOK;
  66. }
  67. /******************************************************************//**
  68. * @brief
  69. * Read from IIC device
  70. *
  71. * @details
  72. *
  73. * @note
  74. *
  75. * @param[in] dev
  76. * Pointer to device descriptor
  77. *
  78. * @param[in] pos
  79. * Offset
  80. *
  81. * @param[in] buffer
  82. * Poniter to the buffer
  83. *
  84. * @param[in] size
  85. * Buffer size in byte
  86. *
  87. * @return
  88. * Error code
  89. *********************************************************************/
  90. static rt_size_t rt_iic_read (
  91. rt_device_t dev,
  92. rt_off_t pos,
  93. void* buffer,
  94. rt_size_t size)
  95. {
  96. rt_err_t err_code;
  97. rt_size_t read_size;
  98. struct efm32_iic_device_t* iic;
  99. I2C_TransferSeq_TypeDef seq;
  100. I2C_TransferReturn_TypeDef ret;
  101. rt_uint8_t data[1];
  102. if (!size)
  103. {
  104. return 0;
  105. }
  106. err_code = RT_EOK;
  107. read_size = 0;
  108. iic = (struct efm32_iic_device_t*)dev->user_data;
  109. data[0] = (rt_uint8_t)(pos & 0x000000FF);
  110. if (iic->is_master)
  111. {
  112. seq.addr = iic->slave_address;
  113. seq.flags = I2C_FLAG_WRITE_READ;
  114. /* Select register to be read */
  115. seq.buf[0].data = data;
  116. seq.buf[0].len = 1;
  117. /* Select location/length of data to be read */
  118. seq.buf[1].data = (rt_uint8_t *)buffer;
  119. seq.buf[1].len = size;
  120. }
  121. else
  122. {
  123. //TODO
  124. }
  125. /* Do a polled transfer */
  126. ret = I2C_TransferInit(iic->iic_device, &seq);
  127. while (ret == i2cTransferInProgress)
  128. {
  129. ret = I2C_Transfer(iic->iic_device);
  130. }
  131. if (ret != i2cTransferDone)
  132. {
  133. #ifdef RT_IIC_DEBUG
  134. rt_kprintf("IIC0 read error: %x\n", ret);
  135. rt_kprintf("IIC0 read address: %x\n", seq.addr);
  136. rt_kprintf("IIC0 read data0: %x -> %x\n", seq.buf[0].data, *seq.buf[0].data);
  137. rt_kprintf("IIC0 read len0: %x\n", seq.buf[0].len);
  138. rt_kprintf("IIC0 read data1: %x -> %x\n", seq.buf[1].data, *seq.buf[1].data);
  139. rt_kprintf("IIC0 read len1: %x\n", seq.buf[1].len);
  140. #endif
  141. err_code = (rt_err_t)ret;
  142. }
  143. else
  144. {
  145. #ifdef RT_IIC_DEBUG
  146. rt_kprintf("IIC0 read size: %d\n", size);
  147. #endif
  148. read_size = size;
  149. }
  150. /* set error code */
  151. rt_set_errno(err_code);
  152. return read_size;
  153. }
  154. /******************************************************************//**
  155. * @brief
  156. * Write to IIC device
  157. *
  158. * @details
  159. *
  160. * @note
  161. *
  162. * @param[in] dev
  163. * Pointer to device descriptor
  164. *
  165. * @param[in] pos
  166. * Offset
  167. *
  168. * @param[in] buffer
  169. * Poniter to the buffer
  170. *
  171. * @param[in] size
  172. * Buffer size in byte
  173. *
  174. * @return
  175. * Error code
  176. *********************************************************************/
  177. static rt_size_t rt_iic_write (
  178. rt_device_t dev,
  179. rt_off_t pos,
  180. const void* buffer,
  181. rt_size_t size)
  182. {
  183. rt_err_t err_code;
  184. rt_size_t write_size;
  185. struct efm32_iic_device_t* iic;
  186. I2C_TransferSeq_TypeDef seq;
  187. I2C_TransferReturn_TypeDef ret;
  188. //rt_uint8_t data[1];
  189. if (!size)
  190. {
  191. return 0;
  192. }
  193. err_code = RT_EOK;
  194. write_size = 0;
  195. iic = (struct efm32_iic_device_t*)dev->user_data;
  196. //data[0] = (rt_uint8_t)(pos & 0x000000FF);
  197. if (iic->is_master)
  198. {
  199. seq.addr = iic->slave_address;
  200. if (pos != (rt_off_t)(-1))
  201. {
  202. seq.flags = I2C_FLAG_WRITE_WRITE;
  203. /* Select register to be write */
  204. seq.buf[0].data = (rt_uint8_t *)(pos & 0x000000FF);
  205. seq.buf[0].len = 1;
  206. /* Select location/length of data to be write */
  207. seq.buf[1].data = (rt_uint8_t *)buffer;
  208. seq.buf[1].len = size;
  209. }
  210. else
  211. {
  212. seq.flags = I2C_FLAG_WRITE;
  213. /* Select location/length of data to be write */
  214. seq.buf[0].data = (rt_uint8_t *)buffer;
  215. seq.buf[0].len = size;
  216. }
  217. }
  218. else
  219. {
  220. //TODO
  221. }
  222. /* Do a polled transfer */
  223. ret = I2C_TransferInit(iic->iic_device, &seq);
  224. while (ret == i2cTransferInProgress)
  225. {
  226. ret = I2C_Transfer(iic->iic_device);
  227. }
  228. if (ret != i2cTransferDone)
  229. {
  230. err_code = (rt_err_t)ret;
  231. }
  232. else
  233. {
  234. write_size = size;
  235. }
  236. /* set error code */
  237. rt_set_errno(err_code);
  238. return write_size;
  239. }
  240. /******************************************************************//**
  241. * @brief
  242. * Configure IIC device
  243. *
  244. * @details
  245. *
  246. * @note
  247. *
  248. * @param[in] dev
  249. * Pointer to device descriptor
  250. *
  251. * @param[in] cmd
  252. * IIC control command
  253. *
  254. * @param[in] args
  255. * Arguments
  256. *
  257. * @return
  258. * Error code
  259. *********************************************************************/
  260. static rt_err_t rt_iic_control (
  261. rt_device_t dev,
  262. rt_uint8_t cmd,
  263. void *args)
  264. {
  265. RT_ASSERT(dev != RT_NULL);
  266. struct efm32_iic_device_t *iic;
  267. iic = (struct efm32_iic_device_t*)dev->user_data;
  268. switch (cmd)
  269. {
  270. case RT_DEVICE_CTRL_SUSPEND:
  271. /* suspend device */
  272. dev->flag |= RT_DEVICE_FLAG_SUSPENDED;
  273. I2C_Enable(iic->iic_device, false);
  274. break;
  275. case RT_DEVICE_CTRL_RESUME:
  276. /* resume device */
  277. dev->flag &= ~RT_DEVICE_FLAG_SUSPENDED;
  278. I2C_Enable(iic->iic_device, true);
  279. break;
  280. case RT_DEVICE_CTRL_IIC_SETTING:
  281. {
  282. /* change device setting */
  283. struct efm32_iic_control_t *control;
  284. control = (struct efm32_iic_control_t *)args;
  285. iic->is_master = control->is_master;
  286. iic->master_address = control->master_address << 1;
  287. iic->slave_address = control->slave_address << 1;
  288. }
  289. break;
  290. }
  291. return RT_EOK;
  292. }
  293. /******************************************************************//**
  294. * @brief
  295. * Register IIC device
  296. *
  297. * @details
  298. *
  299. * @note
  300. *
  301. * @param[in] device
  302. * Pointer to device descriptor
  303. *
  304. * @param[in] name
  305. * Device name
  306. *
  307. * @param[in] flag
  308. * Configuration flags
  309. *
  310. * @param[in] iic
  311. * Pointer to IIC device descriptor
  312. *
  313. * @return
  314. * Error code
  315. *********************************************************************/
  316. rt_err_t rt_hw_iic_register(
  317. rt_device_t device,
  318. const char *name,
  319. rt_uint32_t flag,
  320. struct efm32_iic_device_t *iic)
  321. {
  322. RT_ASSERT(device != RT_NULL);
  323. if ((flag & RT_DEVICE_FLAG_DMA_TX) || (flag & RT_DEVICE_FLAG_DMA_RX) ||
  324. (flag & RT_DEVICE_FLAG_INT_TX) || (flag & RT_DEVICE_FLAG_INT_RX))
  325. {
  326. RT_ASSERT(0);
  327. }
  328. device->type = RT_Device_Class_Char;
  329. device->rx_indicate = RT_NULL;
  330. device->tx_complete = RT_NULL;
  331. device->init = rt_iic_init;
  332. device->open = RT_NULL;
  333. device->close = RT_NULL;
  334. device->read = rt_iic_read;
  335. device->write = rt_iic_write;
  336. device->control = rt_iic_control;
  337. device->user_data = iic;
  338. /* register a character device */
  339. return rt_device_register(device, name, RT_DEVICE_FLAG_RDWR | flag);
  340. }
  341. /******************************************************************//**
  342. * @brief
  343. * Initialize the specified IIC unit
  344. *
  345. * @details
  346. *
  347. * @note
  348. *
  349. * @param[in] unitNumber
  350. * Unit number
  351. *
  352. * @param[in] location
  353. * Pin location number
  354. *********************************************************************/
  355. static void rt_hw_iic_unit_init(
  356. rt_uint8_t unitNumber,
  357. rt_uint8_t location)
  358. {
  359. I2C_TypeDef *iic;
  360. CMU_Clock_TypeDef iicClock;
  361. I2C_Init_TypeDef init = I2C_INIT_DEFAULT;
  362. switch (unitNumber)
  363. {
  364. case 0:
  365. iic = I2C0;
  366. iicClock = (CMU_Clock_TypeDef)cmuClock_I2C0;
  367. break;
  368. #if (I2C_COUNT > 1)
  369. case 1:
  370. iic = I2C1;
  371. iicClock = (CMU_Clock_TypeDef)cmuClock_I2C1;
  372. break;
  373. #endif
  374. default:
  375. return;
  376. }
  377. /* Enabling clock */
  378. CMU_ClockEnable(iicClock, true);
  379. /* Reset */
  380. I2C_Reset(iic);
  381. /* Config GPIO */
  382. GPIO_PinModeSet(
  383. (GPIO_Port_TypeDef)AF_PORT(AF_I2C_SCL(unitNumber), location),
  384. AF_PIN(AF_I2C_SCL(unitNumber), location),
  385. gpioModeWiredAndPullUpFilter,
  386. 1);
  387. GPIO_PinModeSet(
  388. (GPIO_Port_TypeDef)AF_PORT(AF_I2C_SDA(unitNumber), location),
  389. AF_PIN(AF_I2C_SDA(unitNumber), location),
  390. gpioModeWiredAndPullUpFilter,
  391. 1);
  392. /* Enable SDZ and SCL pins and set location */
  393. iic->ROUTE = I2C_ROUTE_SDAPEN | I2C_ROUTE_SCLPEN | \
  394. (location << _I2C_ROUTE_LOCATION_SHIFT);
  395. /* Initializing IIC */
  396. init.enable = false;
  397. I2C_Init(iic, &init);
  398. /* Abort current TX data and clear TX buffers */
  399. iic->CMD = I2C_CMD_ABORT | I2C_CMD_CLEARPC | I2C_CMD_CLEARTX;
  400. /* Clear previous interrupts */
  401. iic->IFC = _I2C_IFC_MASK;
  402. }
  403. /******************************************************************//**
  404. * @brief
  405. * Initialize all IIC module related hardware and register IIC device to kernel
  406. *
  407. * @details
  408. *
  409. * @note
  410. *********************************************************************/
  411. void rt_hw_iic_init(void)
  412. {
  413. struct efm32_iic_device_t *iic;
  414. rt_uint32_t flag;
  415. flag = RT_DEVICE_FLAG_RDWR;
  416. /* register iic0 */
  417. #ifdef RT_USING_IIC0
  418. iic = rt_malloc(sizeof(struct efm32_iic_device_t));
  419. if (iic == RT_NULL)
  420. {
  421. rt_kprintf("no memory for IIC0 driver\n");
  422. return;
  423. }
  424. iic->iic_device = I2C0;
  425. iic->is_master = true;
  426. iic->master_address = 0x0000;
  427. iic->slave_address = 0x0000;
  428. rt_hw_iic_unit_init(0, RT_USING_IIC0);
  429. rt_hw_iic_register(&iic0_device, RT_IIC0_NAME, flag, iic);
  430. #endif
  431. /* register iic1 */
  432. #ifdef RT_USING_IIC1
  433. iic = rt_malloc(sizeof(struct efm32_iic_device_t));
  434. if (iic == RT_NULL)
  435. {
  436. rt_kprintf("no memory for IIC1 driver\n");
  437. return;
  438. }
  439. iic->iic_device = I2C1;
  440. iic->is_master = true;
  441. iic->master_address = 0x0000;
  442. iic->slave_address = 0x0000;
  443. rt_hw_iic_unit_init(1, RT_USING_IIC1);
  444. rt_hw_iic_register(&iic1_device, RT_IIC1_NAME, flag, iic);
  445. #endif
  446. }
  447. /******************************************************************//**
  448. * @}
  449. *********************************************************************/