pybi2c.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531
  1. /*
  2. * This file is part of the MicroPython project, http://micropython.org/
  3. *
  4. * The MIT License (MIT)
  5. *
  6. * Copyright (c) 2013, 2014 Damien P. George
  7. * Copyright (c) 2015 Daniel Campora
  8. *
  9. * Permission is hereby granted, free of charge, to any person obtaining a copy
  10. * of this software and associated documentation files (the "Software"), to deal
  11. * in the Software without restriction, including without limitation the rights
  12. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  13. * copies of the Software, and to permit persons to whom the Software is
  14. * furnished to do so, subject to the following conditions:
  15. *
  16. * The above copyright notice and this permission notice shall be included in
  17. * all copies or substantial portions of the Software.
  18. *
  19. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  20. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  22. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  23. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  24. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  25. * THE SOFTWARE.
  26. */
  27. #include <stdio.h>
  28. #include <string.h>
  29. #include "py/runtime.h"
  30. #include "py/mperrno.h"
  31. #include "py/mphal.h"
  32. #include "bufhelper.h"
  33. #include "inc/hw_types.h"
  34. #include "inc/hw_i2c.h"
  35. #include "inc/hw_ints.h"
  36. #include "inc/hw_memmap.h"
  37. #include "rom_map.h"
  38. #include "pin.h"
  39. #include "prcm.h"
  40. #include "i2c.h"
  41. #include "pybi2c.h"
  42. #include "mpexception.h"
  43. #include "pybsleep.h"
  44. #include "utils.h"
  45. #include "pybpin.h"
  46. #include "pins.h"
  47. /// \moduleref pyb
  48. /// \class I2C - a two-wire serial protocol
  49. typedef struct _pyb_i2c_obj_t {
  50. mp_obj_base_t base;
  51. uint baudrate;
  52. } pyb_i2c_obj_t;
  53. /******************************************************************************
  54. DEFINE CONSTANTS
  55. ******************************************************************************/
  56. #define PYBI2C_MIN_BAUD_RATE_HZ (50000)
  57. #define PYBI2C_MAX_BAUD_RATE_HZ (400000)
  58. #define PYBI2C_TRANSC_TIMEOUT_MS (20)
  59. #define PYBI2C_TRANSAC_WAIT_DELAY_US (10)
  60. #define PYBI2C_TIMEOUT_TO_COUNT(to_us, baud) (((baud) * to_us) / 16000000)
  61. #define RET_IF_ERR(Func) { \
  62. if (!Func) { \
  63. return false; \
  64. } \
  65. }
  66. /******************************************************************************
  67. DECLARE PRIVATE DATA
  68. ******************************************************************************/
  69. STATIC pyb_i2c_obj_t pyb_i2c_obj = {.baudrate = 0};
  70. /******************************************************************************
  71. DECLARE PRIVATE FUNCTIONS
  72. ******************************************************************************/
  73. STATIC bool pyb_i2c_write(byte addr, byte *data, uint len, bool stop);
  74. /******************************************************************************
  75. DEFINE PRIVATE FUNCTIONS
  76. ******************************************************************************/
  77. // only master mode is available for the moment
  78. STATIC void i2c_init (pyb_i2c_obj_t *self) {
  79. // Enable the I2C Peripheral
  80. MAP_PRCMPeripheralClkEnable(PRCM_I2CA0, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
  81. MAP_PRCMPeripheralReset(PRCM_I2CA0);
  82. // Configure I2C module with the specified baudrate
  83. MAP_I2CMasterInitExpClk(I2CA0_BASE, self->baudrate);
  84. }
  85. STATIC bool pyb_i2c_transaction(uint cmd) {
  86. // Convert the timeout to microseconds
  87. int32_t timeout = PYBI2C_TRANSC_TIMEOUT_MS * 1000;
  88. // Sanity check, t_timeout must be between 1 and 255
  89. uint t_timeout = MIN(PYBI2C_TIMEOUT_TO_COUNT(timeout, pyb_i2c_obj.baudrate), 255);
  90. // Clear all interrupts
  91. MAP_I2CMasterIntClearEx(I2CA0_BASE, MAP_I2CMasterIntStatusEx(I2CA0_BASE, false));
  92. // Set the time-out in terms of clock cycles. Not to be used with breakpoints.
  93. MAP_I2CMasterTimeoutSet(I2CA0_BASE, t_timeout);
  94. // Initiate the transfer.
  95. MAP_I2CMasterControl(I2CA0_BASE, cmd);
  96. // Wait until the current byte has been transferred.
  97. // Poll on the raw interrupt status.
  98. while ((MAP_I2CMasterIntStatusEx(I2CA0_BASE, false) & (I2C_MASTER_INT_DATA | I2C_MASTER_INT_TIMEOUT)) == 0) {
  99. if (timeout < 0) {
  100. // the peripheral is not responding, so stop
  101. return false;
  102. }
  103. // wait for a few microseconds
  104. UtilsDelay(UTILS_DELAY_US_TO_COUNT(PYBI2C_TRANSAC_WAIT_DELAY_US));
  105. timeout -= PYBI2C_TRANSAC_WAIT_DELAY_US;
  106. }
  107. // Check for any errors in the transfer
  108. if (MAP_I2CMasterErr(I2CA0_BASE) != I2C_MASTER_ERR_NONE) {
  109. switch(cmd) {
  110. case I2C_MASTER_CMD_BURST_SEND_START:
  111. case I2C_MASTER_CMD_BURST_SEND_CONT:
  112. case I2C_MASTER_CMD_BURST_SEND_STOP:
  113. MAP_I2CMasterControl(I2CA0_BASE, I2C_MASTER_CMD_BURST_SEND_ERROR_STOP);
  114. break;
  115. case I2C_MASTER_CMD_BURST_RECEIVE_START:
  116. case I2C_MASTER_CMD_BURST_RECEIVE_CONT:
  117. case I2C_MASTER_CMD_BURST_RECEIVE_FINISH:
  118. MAP_I2CMasterControl(I2CA0_BASE, I2C_MASTER_CMD_BURST_RECEIVE_ERROR_STOP);
  119. break;
  120. default:
  121. break;
  122. }
  123. return false;
  124. }
  125. return true;
  126. }
  127. STATIC void pyb_i2c_check_init(pyb_i2c_obj_t *self) {
  128. // not initialized
  129. if (!self->baudrate) {
  130. mp_raise_OSError(MP_EPERM);
  131. }
  132. }
  133. STATIC bool pyb_i2c_scan_device(byte devAddr) {
  134. bool ret = false;
  135. // Set the I2C slave address
  136. MAP_I2CMasterSlaveAddrSet(I2CA0_BASE, devAddr, true);
  137. // Initiate the transfer.
  138. if (pyb_i2c_transaction(I2C_MASTER_CMD_SINGLE_RECEIVE)) {
  139. ret = true;
  140. }
  141. // Send the stop bit to cancel the read transaction
  142. MAP_I2CMasterControl(I2CA0_BASE, I2C_MASTER_CMD_BURST_SEND_ERROR_STOP);
  143. if (!ret) {
  144. uint8_t data = 0;
  145. if (pyb_i2c_write(devAddr, &data, sizeof(data), true)) {
  146. ret = true;
  147. }
  148. }
  149. return ret;
  150. }
  151. STATIC bool pyb_i2c_mem_addr_write (byte addr, byte *mem_addr, uint mem_addr_len) {
  152. // Set I2C codec slave address
  153. MAP_I2CMasterSlaveAddrSet(I2CA0_BASE, addr, false);
  154. // Write the first byte to the controller.
  155. MAP_I2CMasterDataPut(I2CA0_BASE, *mem_addr++);
  156. // Initiate the transfer.
  157. RET_IF_ERR(pyb_i2c_transaction(I2C_MASTER_CMD_BURST_SEND_START));
  158. // Loop until the completion of transfer or error
  159. while (--mem_addr_len) {
  160. // Write the next byte of data
  161. MAP_I2CMasterDataPut(I2CA0_BASE, *mem_addr++);
  162. // Transact over I2C to send the next byte
  163. RET_IF_ERR(pyb_i2c_transaction(I2C_MASTER_CMD_BURST_SEND_CONT));
  164. }
  165. return true;
  166. }
  167. STATIC bool pyb_i2c_mem_write (byte addr, byte *mem_addr, uint mem_addr_len, byte *data, uint data_len) {
  168. if (pyb_i2c_mem_addr_write (addr, mem_addr, mem_addr_len)) {
  169. // Loop until the completion of transfer or error
  170. while (data_len--) {
  171. // Write the next byte of data
  172. MAP_I2CMasterDataPut(I2CA0_BASE, *data++);
  173. // Transact over I2C to send the byte
  174. RET_IF_ERR(pyb_i2c_transaction(I2C_MASTER_CMD_BURST_SEND_CONT));
  175. }
  176. // send the stop bit
  177. RET_IF_ERR(pyb_i2c_transaction(I2C_MASTER_CMD_BURST_SEND_STOP));
  178. return true;
  179. }
  180. return false;
  181. }
  182. STATIC bool pyb_i2c_write(byte addr, byte *data, uint len, bool stop) {
  183. // Set I2C codec slave address
  184. MAP_I2CMasterSlaveAddrSet(I2CA0_BASE, addr, false);
  185. // Write the first byte to the controller.
  186. MAP_I2CMasterDataPut(I2CA0_BASE, *data++);
  187. // Initiate the transfer.
  188. RET_IF_ERR(pyb_i2c_transaction(I2C_MASTER_CMD_BURST_SEND_START));
  189. // Loop until the completion of transfer or error
  190. while (--len) {
  191. // Write the next byte of data
  192. MAP_I2CMasterDataPut(I2CA0_BASE, *data++);
  193. // Transact over I2C to send the byte
  194. RET_IF_ERR(pyb_i2c_transaction(I2C_MASTER_CMD_BURST_SEND_CONT));
  195. }
  196. // If a stop bit is to be sent, do it.
  197. if (stop) {
  198. RET_IF_ERR(pyb_i2c_transaction(I2C_MASTER_CMD_BURST_SEND_STOP));
  199. }
  200. return true;
  201. }
  202. STATIC bool pyb_i2c_read(byte addr, byte *data, uint len) {
  203. // Initiate a burst or single receive sequence
  204. uint cmd = --len > 0 ? I2C_MASTER_CMD_BURST_RECEIVE_START : I2C_MASTER_CMD_SINGLE_RECEIVE;
  205. // Set I2C codec slave address
  206. MAP_I2CMasterSlaveAddrSet(I2CA0_BASE, addr, true);
  207. // Initiate the transfer.
  208. RET_IF_ERR(pyb_i2c_transaction(cmd));
  209. // Loop until the completion of reception or error
  210. while (len) {
  211. // Receive the byte over I2C
  212. *data++ = MAP_I2CMasterDataGet(I2CA0_BASE);
  213. if (--len) {
  214. // Continue with reception
  215. RET_IF_ERR(pyb_i2c_transaction(I2C_MASTER_CMD_BURST_RECEIVE_CONT));
  216. } else {
  217. // Complete the last reception
  218. RET_IF_ERR(pyb_i2c_transaction(I2C_MASTER_CMD_BURST_RECEIVE_FINISH));
  219. }
  220. }
  221. // Receive the last byte over I2C
  222. *data = MAP_I2CMasterDataGet(I2CA0_BASE);
  223. return true;
  224. }
  225. STATIC void pyb_i2c_read_into (mp_arg_val_t *args, vstr_t *vstr) {
  226. pyb_i2c_check_init(&pyb_i2c_obj);
  227. // get the buffer to receive into
  228. pyb_buf_get_for_recv(args[1].u_obj, vstr);
  229. // receive the data
  230. if (!pyb_i2c_read(args[0].u_int, (byte *)vstr->buf, vstr->len)) {
  231. mp_raise_OSError(MP_EIO);
  232. }
  233. }
  234. STATIC void pyb_i2c_readmem_into (mp_arg_val_t *args, vstr_t *vstr) {
  235. pyb_i2c_check_init(&pyb_i2c_obj);
  236. // get the buffer to receive into
  237. pyb_buf_get_for_recv(args[2].u_obj, vstr);
  238. // get the addresses
  239. mp_uint_t i2c_addr = args[0].u_int;
  240. mp_uint_t mem_addr = args[1].u_int;
  241. // determine the width of mem_addr (1 or 2 bytes)
  242. mp_uint_t mem_addr_size = args[3].u_int >> 3;
  243. // write the register address to be read from
  244. if (pyb_i2c_mem_addr_write (i2c_addr, (byte *)&mem_addr, mem_addr_size)) {
  245. // Read the specified length of data
  246. if (!pyb_i2c_read (i2c_addr, (byte *)vstr->buf, vstr->len)) {
  247. mp_raise_OSError(MP_EIO);
  248. }
  249. } else {
  250. mp_raise_OSError(MP_EIO);
  251. }
  252. }
  253. /******************************************************************************/
  254. /* MicroPython bindings */
  255. /******************************************************************************/
  256. STATIC void pyb_i2c_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
  257. pyb_i2c_obj_t *self = self_in;
  258. if (self->baudrate > 0) {
  259. mp_printf(print, "I2C(0, baudrate=%u)", self->baudrate);
  260. } else {
  261. mp_print_str(print, "I2C(0)");
  262. }
  263. }
  264. STATIC mp_obj_t pyb_i2c_init_helper(pyb_i2c_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
  265. enum { ARG_scl, ARG_sda, ARG_freq };
  266. static const mp_arg_t allowed_args[] = {
  267. { MP_QSTR_scl, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
  268. { MP_QSTR_sda, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
  269. { MP_QSTR_freq, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 100000} },
  270. };
  271. mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
  272. mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
  273. // make sure the baudrate is between the valid range
  274. self->baudrate = MIN(MAX(args[ARG_freq].u_int, PYBI2C_MIN_BAUD_RATE_HZ), PYBI2C_MAX_BAUD_RATE_HZ);
  275. // assign the pins
  276. mp_obj_t pins[2] = {&pin_GP13, &pin_GP23}; // default (SDA, SCL) pins
  277. if (args[ARG_scl].u_obj != MP_OBJ_NULL) {
  278. pins[1] = args[ARG_scl].u_obj;
  279. }
  280. if (args[ARG_sda].u_obj != MP_OBJ_NULL) {
  281. pins[0] = args[ARG_sda].u_obj;
  282. }
  283. pin_assign_pins_af(pins, 2, PIN_TYPE_STD_PU, PIN_FN_I2C, 0);
  284. // init the I2C bus
  285. i2c_init(self);
  286. // register it with the sleep module
  287. pyb_sleep_add ((const mp_obj_t)self, (WakeUpCB_t)i2c_init);
  288. return mp_const_none;
  289. }
  290. STATIC mp_obj_t pyb_i2c_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
  291. // check the id argument, if given
  292. if (n_args > 0) {
  293. if (all_args[0] != MP_OBJ_NEW_SMALL_INT(0)) {
  294. mp_raise_OSError(MP_ENODEV);
  295. }
  296. --n_args;
  297. ++all_args;
  298. }
  299. // parse args
  300. mp_map_t kw_args;
  301. mp_map_init_fixed_table(&kw_args, n_kw, all_args + n_args);
  302. // setup the object
  303. pyb_i2c_obj_t *self = &pyb_i2c_obj;
  304. self->base.type = &pyb_i2c_type;
  305. // start the peripheral
  306. pyb_i2c_init_helper(self, n_args, all_args, &kw_args);
  307. return (mp_obj_t)self;
  308. }
  309. STATIC mp_obj_t pyb_i2c_init(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
  310. return pyb_i2c_init_helper(pos_args[0], n_args - 1, pos_args + 1, kw_args);
  311. }
  312. STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_i2c_init_obj, 1, pyb_i2c_init);
  313. STATIC mp_obj_t pyb_i2c_deinit(mp_obj_t self_in) {
  314. // disable the peripheral
  315. MAP_I2CMasterDisable(I2CA0_BASE);
  316. MAP_PRCMPeripheralClkDisable(PRCM_I2CA0, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
  317. // invalidate the baudrate
  318. pyb_i2c_obj.baudrate = 0;
  319. // unregister it with the sleep module
  320. pyb_sleep_remove ((const mp_obj_t)self_in);
  321. return mp_const_none;
  322. }
  323. STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_i2c_deinit_obj, pyb_i2c_deinit);
  324. STATIC mp_obj_t pyb_i2c_scan(mp_obj_t self_in) {
  325. pyb_i2c_check_init(&pyb_i2c_obj);
  326. mp_obj_t list = mp_obj_new_list(0, NULL);
  327. for (uint addr = 0x08; addr <= 0x77; addr++) {
  328. for (int i = 0; i < 3; i++) {
  329. if (pyb_i2c_scan_device(addr)) {
  330. mp_obj_list_append(list, mp_obj_new_int(addr));
  331. break;
  332. }
  333. }
  334. }
  335. return list;
  336. }
  337. STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_i2c_scan_obj, pyb_i2c_scan);
  338. STATIC mp_obj_t pyb_i2c_readfrom(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
  339. STATIC const mp_arg_t pyb_i2c_readfrom_args[] = {
  340. { MP_QSTR_addr, MP_ARG_REQUIRED | MP_ARG_INT, },
  341. { MP_QSTR_nbytes, MP_ARG_REQUIRED | MP_ARG_OBJ, },
  342. };
  343. // parse args
  344. mp_arg_val_t args[MP_ARRAY_SIZE(pyb_i2c_readfrom_args)];
  345. mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(args), pyb_i2c_readfrom_args, args);
  346. vstr_t vstr;
  347. pyb_i2c_read_into(args, &vstr);
  348. // return the received data
  349. return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
  350. }
  351. STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_i2c_readfrom_obj, 3, pyb_i2c_readfrom);
  352. STATIC mp_obj_t pyb_i2c_readfrom_into(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
  353. STATIC const mp_arg_t pyb_i2c_readfrom_into_args[] = {
  354. { MP_QSTR_addr, MP_ARG_REQUIRED | MP_ARG_INT, },
  355. { MP_QSTR_buf, MP_ARG_REQUIRED | MP_ARG_OBJ, },
  356. };
  357. // parse args
  358. mp_arg_val_t args[MP_ARRAY_SIZE(pyb_i2c_readfrom_into_args)];
  359. mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(args), pyb_i2c_readfrom_into_args, args);
  360. vstr_t vstr;
  361. pyb_i2c_read_into(args, &vstr);
  362. // return the number of bytes received
  363. return mp_obj_new_int(vstr.len);
  364. }
  365. STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_i2c_readfrom_into_obj, 1, pyb_i2c_readfrom_into);
  366. STATIC mp_obj_t pyb_i2c_writeto(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
  367. STATIC const mp_arg_t pyb_i2c_writeto_args[] = {
  368. { MP_QSTR_addr, MP_ARG_REQUIRED | MP_ARG_INT, },
  369. { MP_QSTR_buf, MP_ARG_REQUIRED | MP_ARG_OBJ, },
  370. { MP_QSTR_stop, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} },
  371. };
  372. // parse args
  373. mp_arg_val_t args[MP_ARRAY_SIZE(pyb_i2c_writeto_args)];
  374. mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(args), pyb_i2c_writeto_args, args);
  375. pyb_i2c_check_init(&pyb_i2c_obj);
  376. // get the buffer to send from
  377. mp_buffer_info_t bufinfo;
  378. uint8_t data[1];
  379. pyb_buf_get_for_send(args[1].u_obj, &bufinfo, data);
  380. // send the data
  381. if (!pyb_i2c_write(args[0].u_int, bufinfo.buf, bufinfo.len, args[2].u_bool)) {
  382. mp_raise_OSError(MP_EIO);
  383. }
  384. // return the number of bytes written
  385. return mp_obj_new_int(bufinfo.len);
  386. }
  387. STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_i2c_writeto_obj, 1, pyb_i2c_writeto);
  388. STATIC mp_obj_t pyb_i2c_readfrom_mem(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
  389. STATIC const mp_arg_t pyb_i2c_readfrom_mem_args[] = {
  390. { MP_QSTR_addr, MP_ARG_REQUIRED | MP_ARG_INT, },
  391. { MP_QSTR_memaddr, MP_ARG_REQUIRED | MP_ARG_INT, },
  392. { MP_QSTR_nbytes, MP_ARG_REQUIRED | MP_ARG_OBJ, },
  393. { MP_QSTR_addrsize, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} },
  394. };
  395. // parse args
  396. mp_arg_val_t args[MP_ARRAY_SIZE(pyb_i2c_readfrom_mem_args)];
  397. mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(args), pyb_i2c_readfrom_mem_args, args);
  398. vstr_t vstr;
  399. pyb_i2c_readmem_into (args, &vstr);
  400. return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
  401. }
  402. STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_i2c_readfrom_mem_obj, 1, pyb_i2c_readfrom_mem);
  403. STATIC const mp_arg_t pyb_i2c_readfrom_mem_into_args[] = {
  404. { MP_QSTR_addr, MP_ARG_REQUIRED | MP_ARG_INT, },
  405. { MP_QSTR_memaddr, MP_ARG_REQUIRED | MP_ARG_INT, },
  406. { MP_QSTR_buf, MP_ARG_REQUIRED | MP_ARG_OBJ, },
  407. { MP_QSTR_addrsize, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} },
  408. };
  409. STATIC mp_obj_t pyb_i2c_readfrom_mem_into(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
  410. // parse args
  411. mp_arg_val_t args[MP_ARRAY_SIZE(pyb_i2c_readfrom_mem_into_args)];
  412. mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(args), pyb_i2c_readfrom_mem_into_args, args);
  413. // get the buffer to read into
  414. vstr_t vstr;
  415. pyb_i2c_readmem_into (args, &vstr);
  416. return mp_const_none;
  417. }
  418. STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_i2c_readfrom_mem_into_obj, 1, pyb_i2c_readfrom_mem_into);
  419. STATIC mp_obj_t pyb_i2c_writeto_mem(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
  420. // parse args
  421. mp_arg_val_t args[MP_ARRAY_SIZE(pyb_i2c_readfrom_mem_into_args)];
  422. mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(pyb_i2c_readfrom_mem_into_args), pyb_i2c_readfrom_mem_into_args, args);
  423. pyb_i2c_check_init(&pyb_i2c_obj);
  424. // get the buffer to write from
  425. mp_buffer_info_t bufinfo;
  426. uint8_t data[1];
  427. pyb_buf_get_for_send(args[2].u_obj, &bufinfo, data);
  428. // get the addresses
  429. mp_uint_t i2c_addr = args[0].u_int;
  430. mp_uint_t mem_addr = args[1].u_int;
  431. // determine the width of mem_addr (1 or 2 bytes)
  432. mp_uint_t mem_addr_size = args[3].u_int >> 3;
  433. // write the register address to write to.
  434. if (pyb_i2c_mem_write (i2c_addr, (byte *)&mem_addr, mem_addr_size, bufinfo.buf, bufinfo.len)) {
  435. return mp_const_none;
  436. }
  437. mp_raise_OSError(MP_EIO);
  438. }
  439. STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_i2c_writeto_mem_obj, 1, pyb_i2c_writeto_mem);
  440. STATIC const mp_rom_map_elem_t pyb_i2c_locals_dict_table[] = {
  441. // instance methods
  442. { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&pyb_i2c_init_obj) },
  443. { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&pyb_i2c_deinit_obj) },
  444. { MP_ROM_QSTR(MP_QSTR_scan), MP_ROM_PTR(&pyb_i2c_scan_obj) },
  445. { MP_ROM_QSTR(MP_QSTR_readfrom), MP_ROM_PTR(&pyb_i2c_readfrom_obj) },
  446. { MP_ROM_QSTR(MP_QSTR_readfrom_into), MP_ROM_PTR(&pyb_i2c_readfrom_into_obj) },
  447. { MP_ROM_QSTR(MP_QSTR_writeto), MP_ROM_PTR(&pyb_i2c_writeto_obj) },
  448. { MP_ROM_QSTR(MP_QSTR_readfrom_mem), MP_ROM_PTR(&pyb_i2c_readfrom_mem_obj) },
  449. { MP_ROM_QSTR(MP_QSTR_readfrom_mem_into), MP_ROM_PTR(&pyb_i2c_readfrom_mem_into_obj) },
  450. { MP_ROM_QSTR(MP_QSTR_writeto_mem), MP_ROM_PTR(&pyb_i2c_writeto_mem_obj) },
  451. };
  452. STATIC MP_DEFINE_CONST_DICT(pyb_i2c_locals_dict, pyb_i2c_locals_dict_table);
  453. const mp_obj_type_t pyb_i2c_type = {
  454. { &mp_type_type },
  455. .name = MP_QSTR_I2C,
  456. .print = pyb_i2c_print,
  457. .make_new = pyb_i2c_make_new,
  458. .locals_dict = (mp_obj_t)&pyb_i2c_locals_dict,
  459. };