From 99f3f6b5de567c1bdf04259d2c8322681755c732 Mon Sep 17 00:00:00 2001 From: danicampora Date: Tue, 10 Feb 2015 13:11:27 +0100 Subject: [PATCH] cc3200: Add I2C module. Only master mode is currently supported. --- cc3200/application.mk | 2 + cc3200/fatfs/src/drivers/sflash_diskio.c | 5 +- cc3200/hal/i2c.c | 20 +- cc3200/hal/i2c.h | 3 +- cc3200/hal/rom_patch.h | 1 + cc3200/misc/pin_named_pins.c | 10 + cc3200/mods/modpyb.c | 23 +- cc3200/mods/pybextint.c | 4 +- cc3200/mods/pybi2c.c | 637 +++++++++++++++++++++++ cc3200/mods/pybi2c.h | 32 ++ cc3200/mods/pybpin.c | 23 +- cc3200/mods/pybpin.h | 1 + cc3200/mods/pybuart.c | 13 +- cc3200/mpconfigport.h | 1 + cc3200/mptask.c | 11 +- cc3200/qstrdefsport.h | 21 + 16 files changed, 761 insertions(+), 46 deletions(-) create mode 100644 cc3200/mods/pybi2c.c create mode 100644 cc3200/mods/pybi2c.h diff --git a/cc3200/application.mk b/cc3200/application.mk index fb6756fc09..73c84efa46 100644 --- a/cc3200/application.mk +++ b/cc3200/application.mk @@ -18,6 +18,7 @@ APP_INC += -Iutil APP_INC += -Ibootmgr APP_INC += -I$(PY_SRC) APP_INC += -I$(BUILD) +APP_INC += -I$(BUILD)/genhdr APP_INC += -I../lib/fatfs APP_INC += -I../lib/mp-readline APP_INC += -I../stmhal @@ -89,6 +90,7 @@ APP_MODS_SRC_C = $(addprefix mods/,\ modutime.c \ modwlan.c \ pybextint.c \ + pybi2c.c \ pybpin.c \ pybrtc.c \ pybsystick.c \ diff --git a/cc3200/fatfs/src/drivers/sflash_diskio.c b/cc3200/fatfs/src/drivers/sflash_diskio.c index cb28913bfd..a2f61b7d66 100644 --- a/cc3200/fatfs/src/drivers/sflash_diskio.c +++ b/cc3200/fatfs/src/drivers/sflash_diskio.c @@ -112,7 +112,7 @@ DRESULT sflash_disk_read(BYTE *buff, DWORD sector, UINT count) { return STA_NOINIT; } - if (sector + count > SFLASH_SECTOR_COUNT || count == 0) { + if ((sector + count > SFLASH_SECTOR_COUNT) || (count == 0)) { return RES_PARERR; } @@ -145,7 +145,8 @@ DRESULT sflash_disk_write(const BYTE *buff, DWORD sector, UINT count) { return STA_NOINIT; } - if (sector + count > SFLASH_SECTOR_COUNT || count == 0) { + if ((sector + count > SFLASH_SECTOR_COUNT) || (count == 0)) { + sflash_disk_flush(); return RES_PARERR; } diff --git a/cc3200/hal/i2c.c b/cc3200/hal/i2c.c index 5208687674..487f93cc26 100644 --- a/cc3200/hal/i2c.c +++ b/cc3200/hal/i2c.c @@ -169,10 +169,8 @@ _I2CIntNumberGet(uint32_t ui32Base) // //***************************************************************************** void -I2CMasterInitExpClk(uint32_t ui32Base, uint32_t ui32I2CClk, - bool bFast) +I2CMasterInitExpClk(uint32_t ui32Base, uint32_t ui32SCLFreq) { - uint32_t ui32SCLFreq; uint32_t ui32TPR; // @@ -185,25 +183,13 @@ I2CMasterInitExpClk(uint32_t ui32Base, uint32_t ui32I2CClk, // I2CMasterEnable(ui32Base); - // - // Get the desired SCL speed. - // - if(bFast == true) - { - ui32SCLFreq = 400000; - } - else - { - ui32SCLFreq = 100000; - } - // // Compute the clock divider that achieves the fastest speed less than or // equal to the desired speed. The numerator is biased to favor a larger // clock divider so that the resulting clock is always less than or equal // to the desired clock, never greater. // - ui32TPR = ((ui32I2CClk + (2 * 10 * ui32SCLFreq) - 1) / + ui32TPR = ((80000000 + (2 * 10 * ui32SCLFreq) - 1) / (2 * 10 * ui32SCLFreq)) - 1; HWREG(ui32Base + I2C_O_MTPR) = ui32TPR; @@ -213,7 +199,7 @@ I2CMasterInitExpClk(uint32_t ui32Base, uint32_t ui32I2CClk, // if(HWREG(ui32Base + I2C_O_PP) & I2C_PP_HS) { - ui32TPR = ((ui32I2CClk + (2 * 3 * 3400000) - 1) / + ui32TPR = ((80000000 + (2 * 3 * 3400000) - 1) / (2 * 3 * 3400000)) - 1; HWREG(ui32Base + I2C_O_MTPR) = I2C_MTPR_HS | ui32TPR; } diff --git a/cc3200/hal/i2c.h b/cc3200/hal/i2c.h index 67f77fa9a5..d966dbf56a 100644 --- a/cc3200/hal/i2c.h +++ b/cc3200/hal/i2c.h @@ -309,8 +309,7 @@ extern void I2CMasterDataPut(uint32_t ui32Base, uint8_t ui8Data); extern void I2CMasterDisable(uint32_t ui32Base); extern void I2CMasterEnable(uint32_t ui32Base); extern uint32_t I2CMasterErr(uint32_t ui32Base); -extern void I2CMasterInitExpClk(uint32_t ui32Base, uint32_t ui32I2CClk, - bool bFast); +extern void I2CMasterInitExpClk(uint32_t ui32Base, uint32_t ui32SCLFreq); extern void I2CMasterIntClear(uint32_t ui32Base); extern void I2CMasterIntDisable(uint32_t ui32Base); extern void I2CMasterIntEnable(uint32_t ui32Base); diff --git a/cc3200/hal/rom_patch.h b/cc3200/hal/rom_patch.h index 4df44bd5d0..6ca366b0f6 100644 --- a/cc3200/hal/rom_patch.h +++ b/cc3200/hal/rom_patch.h @@ -84,4 +84,5 @@ #undef ROM_SPIConfigSetExpClk #undef ROM_GPIODirModeGet #undef ROM_GPIOIntTypeGet +#undef ROM_I2CMasterInitExpClk diff --git a/cc3200/misc/pin_named_pins.c b/cc3200/misc/pin_named_pins.c index 5ed4896fec..1b3505b0d7 100644 --- a/cc3200/misc/pin_named_pins.c +++ b/cc3200/misc/pin_named_pins.c @@ -60,3 +60,13 @@ const pin_obj_t *pin_find_named_pin(const mp_obj_dict_t *named_pins, mp_obj_t na } return NULL; } + +const pin_obj_t *pin_find_pin(const mp_obj_dict_t *named_pins, uint pin_num) { + mp_map_t *named_map = mp_obj_dict_get_map((mp_obj_t)named_pins); + for (uint i = 0; i < named_map->used; i++) { + if (((pin_obj_t *)named_map->table[i].value)->pin_num == pin_num) { + return named_map->table[i].value; + } + } + return NULL; +} diff --git a/cc3200/mods/modpyb.c b/cc3200/mods/modpyb.c index 869adc761c..86c726587b 100644 --- a/cc3200/mods/modpyb.c +++ b/cc3200/mods/modpyb.c @@ -62,6 +62,8 @@ #include "mpexception.h" #include "random.h" #include "pybextint.h" +#include "pybi2c.h" +#include "utils.h" #ifdef DEBUG @@ -218,10 +220,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_delay_obj, pyb_delay); STATIC mp_obj_t pyb_udelay(mp_obj_t usec_in) { mp_int_t usec = mp_obj_get_int(usec_in); if (usec > 0) { - uint32_t count = 0; - const uint32_t utime = ((HAL_FCPU_HZ / 1000000) * (usec / 4)); - while (++count <= utime) { - } + UtilsDelay(UTILS_DELAY_US_TO_COUNT(usec)); } return mp_const_none; } @@ -261,6 +260,17 @@ STATIC mp_obj_t pyb_repl_uart(uint n_args, const mp_obj_t *args) { } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_repl_uart_obj, 0, 1, pyb_repl_uart); +/// \function mkdisk('path') +/// Formats the selected drive, useful when the filesystem has been damaged beyond repair +STATIC mp_obj_t pyb_mkdisk(mp_obj_t path_o) { + const char *path = mp_obj_str_get_str(path_o); + if (FR_OK != f_mkfs(path, 1, 0)) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed)); + } + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_mkdisk_obj, pyb_mkdisk); + MP_DECLARE_CONST_FUN_OBJ(pyb_main_obj); // defined in main.c STATIC const mp_map_elem_t pyb_module_globals_table[] = { @@ -291,8 +301,7 @@ STATIC const mp_map_elem_t pyb_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_delay), (mp_obj_t)&pyb_delay_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_udelay), (mp_obj_t)&pyb_udelay_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_sync), (mp_obj_t)&pyb_sync_obj }, - - //{ MP_OBJ_NEW_QSTR(MP_QSTR_Timer), (mp_obj_t)&pyb_timer_type }, + { MP_OBJ_NEW_QSTR(MP_QSTR_mkdisk), (mp_obj_t)&pyb_mkdisk_obj }, #if MICROPY_HW_ENABLE_RNG { MP_OBJ_NEW_QSTR(MP_QSTR_rng), (mp_obj_t)&pyb_rng_get_obj }, @@ -304,7 +313,7 @@ STATIC const mp_map_elem_t pyb_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_Pin), (mp_obj_t)&pin_type }, { MP_OBJ_NEW_QSTR(MP_QSTR_ExtInt), (mp_obj_t)&extint_type }, - + { MP_OBJ_NEW_QSTR(MP_QSTR_I2C), (mp_obj_t)&pyb_i2c_type }, { MP_OBJ_NEW_QSTR(MP_QSTR_UART), (mp_obj_t)&pyb_uart_type }, }; diff --git a/cc3200/mods/pybextint.c b/cc3200/mods/pybextint.c index df55d88612..bc4f5a82b8 100644 --- a/cc3200/mods/pybextint.c +++ b/cc3200/mods/pybextint.c @@ -283,7 +283,7 @@ extint_obj_t* extint_register(mp_obj_t pin_obj, uint32_t intmode, uint32_t pull, intmode != GPIO_BOTH_EDGES && intmode != GPIO_LOW_LEVEL && intmode != GPIO_HIGH_LEVEL) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_value_invalid_arguments)); + nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments)); } if (pull != PIN_TYPE_STD && pull != PIN_TYPE_STD_PU && @@ -291,7 +291,7 @@ extint_obj_t* extint_register(mp_obj_t pin_obj, uint32_t intmode, uint32_t pull, pull != PIN_TYPE_OD && pull != PIN_TYPE_OD_PU && pull != PIN_TYPE_OD_PD) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_value_invalid_arguments)); + nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments)); } if (NULL == (self = extint_find(pin->port, pin->bit))) { diff --git a/cc3200/mods/pybi2c.c b/cc3200/mods/pybi2c.c new file mode 100644 index 0000000000..5b3c53f5fe --- /dev/null +++ b/cc3200/mods/pybi2c.c @@ -0,0 +1,637 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2015 Daniel Campora + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include + +#include "py/mpstate.h" +#include "mpconfig.h" +#include MICROPY_HAL_H +#include "nlr.h" +#include "misc.h" +#include "qstr.h" +#include "obj.h" +#include "runtime.h" +#include "bufhelper.h" +#include "inc/hw_types.h" +#include "inc/hw_i2c.h" +#include "inc/hw_ints.h" +#include "inc/hw_memmap.h" +#include "rom_map.h" +#include "pin.h" +#include "prcm.h" +#include "i2c.h" +#include "pybi2c.h" +#include "mpexception.h" + +/// \moduleref pyb +/// \class I2C - a two-wire serial protocol +/// +/// I2C is a two-wire protocol for communicating between devices. At the physical +/// level it consists of 2 wires: SCL and SDA, the clock and data lines respectively. +/// +/// I2C objects are created attached to a specific bus. They can be initialised +/// when created, or initialised later on: +/// +/// from pyb import I2C +/// +/// i2c = I2C() # create +/// i2c = I2C(I2C.MASTER) # create and init as a master +/// i2c.init(I2C.MASTER, baudrate=20000) # init as a master +/// i2c.deinit() # turn off the peripheral +/// +/// Printing the i2c object gives you information about its configuration. +/// +/// Basic methods for slave are send and recv: +/// +/// i2c.send('abc') # send 3 bytes +/// i2c.send(0x42) # send a single byte, given by the number +/// data = i2c.recv(3) # receive 3 bytes +/// +/// To receive inplace, first create a bytearray: +/// +/// data = bytearray(3) # create a buffer +/// i2c.recv(data) # receive 3 bytes, writing them into data +/// +/// You can specify a timeout (in ms): +/// +/// i2c.send(b'123', timeout=20) # timout after 20ms if the other end is not responding +/// +/// A master must specify the recipient's address: +/// +/// i2c.init(I2C.MASTER) +/// i2c.send('123', 0x42) # send 3 bytes to slave with address 0x42 +/// i2c.send(b'456', addr=0x42) # keyword for address +/// +/// Master also has other methods: +/// +/// i2c.is_ready(0x42) # check if slave 0x42 is ready +/// i2c.scan() # scan for slaves on the bus, returning +/// # a list of valid addresses +/// i2c.mem_read(3, 0x42, 2) # read 3 bytes from memory of slave 0x42, +/// # starting at address 2 in the slave +/// i2c.mem_write('abc', 0x42, 2, timeout=10) + + +/****************************************************************************** + DEFINE CONSTANTS + ******************************************************************************/ +#define PYBI2C_MODE_DISABLED (-1) +#define PYBI2C_MODE_MASTER (0) +#define PYBI2C_MODE_SLAVE (1) + +#define PYBI2C_DEF_TIMEOUT_MS (7) + +#define PYBI2C_TIMEOUT_TO_COUNT(to_ms, baud) (((baud) * to_ms) / 16000) + +#define RET_IF_ERR(Func) { \ + if (!Func) { \ + return false; \ + } \ + } + +/****************************************************************************** + DEFINE PUBLIC FUNCTIONS + ******************************************************************************/ +void i2c_init0(void) { + MP_STATE_PORT(pyb_i2c_obj) = NULL; +} + +// only master mode is available for the moment +void i2c_init (uint mode, uint slvaddr, uint baudrate) { + // Enable the I2C Peripheral + MAP_PRCMPeripheralClkEnable(PRCM_I2CA0, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK); + MAP_PRCMPeripheralReset(PRCM_I2CA0); + + // Configure I2C module with the specified baudrate + MAP_I2CMasterInitExpClk(I2CA0_BASE, baudrate); +} + +void i2c_deinit(void) { + MAP_I2CMasterDisable(I2CA0_BASE); + MAP_PRCMPeripheralClkDisable(PRCM_I2CA0, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK); +} + +/******************************************************************************/ +/* Micro Python bindings */ +/******************************************************************************/ +typedef struct _pyb_i2c_obj_t { + mp_obj_base_t base; + int mode; + union { + uint baudrate; + byte slvaddr; + }; +} pyb_i2c_obj_t; + +STATIC bool pybI2C_transaction(uint cmd, uint timeout) { + // Clear all interrupts + MAP_I2CMasterIntClearEx(I2CA0_BASE, MAP_I2CMasterIntStatusEx(I2CA0_BASE, false)); + // Set the time-out. Not to be used with breakpoints. + MAP_I2CMasterTimeoutSet(I2CA0_BASE, timeout); + // Initiate the transfer. + MAP_I2CMasterControl(I2CA0_BASE, cmd); + // Wait until the current byte has been transferred. + // Poll on the raw interrupt status. + while ((MAP_I2CMasterIntStatusEx(I2CA0_BASE, false) & (I2C_MASTER_INT_DATA | I2C_MASTER_INT_TIMEOUT)) == 0); + + // Check for any errors in transfer + if (MAP_I2CMasterErr(I2CA0_BASE) != I2C_MASTER_ERR_NONE) { + switch(cmd) { + case I2C_MASTER_CMD_BURST_SEND_START: + case I2C_MASTER_CMD_BURST_SEND_CONT: + case I2C_MASTER_CMD_BURST_SEND_STOP: + MAP_I2CMasterControl(I2CA0_BASE, I2C_MASTER_CMD_BURST_SEND_ERROR_STOP); + break; + case I2C_MASTER_CMD_BURST_RECEIVE_START: + case I2C_MASTER_CMD_BURST_RECEIVE_CONT: + case I2C_MASTER_CMD_BURST_RECEIVE_FINISH: + MAP_I2CMasterControl(I2CA0_BASE, I2C_MASTER_CMD_BURST_RECEIVE_ERROR_STOP); + break; + default: + break; + } + return false; + } + + return true; +} + +STATIC bool pybI2C_Write(byte devAddr, byte *data, uint len, bool stop, uint timeout) { + + // Set I2C codec slave address + MAP_I2CMasterSlaveAddrSet(I2CA0_BASE, devAddr, false); + // Write the first byte to the controller. + MAP_I2CMasterDataPut(I2CA0_BASE, *data++); + // Initiate the transfer. + RET_IF_ERR(pybI2C_transaction(I2C_MASTER_CMD_BURST_SEND_START, timeout)); + + // Loop until the completion of transfer or error + while (--len) { + // Write the next byte of data + MAP_I2CMasterDataPut(I2CA0_BASE, *data++); + // Transact over I2C to send the byte + RET_IF_ERR(pybI2C_transaction(I2C_MASTER_CMD_BURST_SEND_CONT, timeout)); + } + + // If a stop bit is to be sent, send it. + if (stop) { + RET_IF_ERR(pybI2C_transaction(I2C_MASTER_CMD_BURST_SEND_STOP, timeout)); + } + + return true; +} + +STATIC bool pybI2C_Read(byte devAddr, byte *data, uint len, uint timeout) { + uint cmd; + + // Set I2C codec slave address + MAP_I2CMasterSlaveAddrSet(I2CA0_BASE, devAddr, true); + + // Check if its a single receive or burst receive + if (len > 1) { + // Initiate a burst receive sequence + cmd = I2C_MASTER_CMD_BURST_RECEIVE_START; + } + else { + // Configure for a single receive + cmd = I2C_MASTER_CMD_SINGLE_RECEIVE; + } + + // Initiate the transfer. + RET_IF_ERR(pybI2C_transaction(cmd, timeout)); + // Decrement the count + len--; + // Loop until the completion of reception or error + while (len) { + // Receive the byte over I2C + *data++ = MAP_I2CMasterDataGet(I2CA0_BASE); + if (--len) { + // Continue with reception + RET_IF_ERR(pybI2C_transaction(I2C_MASTER_CMD_BURST_RECEIVE_CONT, timeout)); + } + else { + // Complete the last reception + RET_IF_ERR(pybI2C_transaction(I2C_MASTER_CMD_BURST_RECEIVE_FINISH, timeout)); + } + } + + // Receive the last byte over I2C + *data = MAP_I2CMasterDataGet(I2CA0_BASE); + + return true; +} + +STATIC bool pybI2C_ScanDevice(byte devAddr, uint timeout) { + // Set I2C codec slave address + MAP_I2CMasterSlaveAddrSet(I2CA0_BASE, devAddr, true); + // Initiate the transfer. + RET_IF_ERR(pybI2C_transaction(I2C_MASTER_CMD_SINGLE_RECEIVE, timeout)); + // Since this is a hack, send the stop bit anyway + MAP_I2CMasterControl(I2CA0_BASE, I2C_MASTER_CMD_BURST_SEND_ERROR_STOP); + + return true; +} + +STATIC void pyb_i2c_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) { + pyb_i2c_obj_t *self = self_in; + + print(env, "I2C0"); + if (self->mode == PYBI2C_MODE_MASTER) { + print(env, ", I2C.MASTER, baudrate=%u)", self->baudrate); + } else if (self->mode == PYBI2C_MODE_SLAVE) { + print(env, ", I2C.SLAVE, addr=0x%02x)", self->slvaddr); + } +} + +/// \method init(mode, *, addr=0x12, baudrate=400000) +/// +/// Initialise the I2C bus with the given parameters: +/// +/// - `mode` must be either `I2C.MASTER` or `I2C.SLAVE` +/// - `addr` is the 7-bit address (only sensible for a slave) +/// - `baudrate` is the SCL clock rate (only sensible for a master) +STATIC const mp_arg_t pyb_i2c_init_args[] = { + { MP_QSTR_mode, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = PYBI2C_MODE_MASTER} }, + { MP_QSTR_addr, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_baudrate, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 400000} }, +}; +#define PYB_I2C_INIT_NUM_ARGS MP_ARRAY_SIZE(pyb_i2c_init_args) + +STATIC mp_obj_t pyb_i2c_init_helper(pyb_i2c_obj_t *self_in, mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + pyb_i2c_obj_t *self = self_in; + + // parse args + mp_arg_val_t vals[PYB_I2C_INIT_NUM_ARGS]; + mp_arg_parse_all(n_args, args, kw_args, PYB_I2C_INIT_NUM_ARGS, pyb_i2c_init_args, vals); + + self->mode = vals[0].u_int; + if (self->mode != PYBI2C_MODE_MASTER) { + // thrown an exception since only master mode is supported for now + nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments)); + } + + if (self->mode == PYBI2C_MODE_SLAVE) { + self->slvaddr = vals[1].u_int; + } + else { + self->baudrate = MIN(vals[2].u_int, 400000); + } + + // init the I2C bus + i2c_init(self->mode, self->slvaddr, self->baudrate); + + return mp_const_none; +} + +/// \classmethod \constructor(bus, ...) +/// +/// Construct an I2C object on the given bus. `bus` can be 1. +/// With no additional parameters, the I2C object is created but not +/// initialised (it has the settings from the last initialisation of +/// the bus, if any). If extra arguments are given, the bus is initialised. +/// See `init` for parameters of initialisation. +STATIC mp_obj_t pyb_i2c_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) { + // check arguments + mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true); + + // get i2c number + mp_int_t i2c_id = mp_obj_get_int(args[0]) - 1; + + // check i2c number + if (i2c_id != 0) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments)); + } + + // setup the object + pyb_i2c_obj_t *self; + if (MP_STATE_PORT(pyb_i2c_obj) == NULL) { + // create a new I2C object + self = m_new_obj(pyb_i2c_obj_t); + self->base.type = &pyb_i2c_type; + self->mode = PYBI2C_MODE_DISABLED; + MP_STATE_PORT(pyb_i2c_obj) = self; + } else { + // reference the existing I2C object + self = MP_STATE_PORT(pyb_i2c_obj); + } + + if (n_args > 1 || n_kw > 0) { + // start the peripheral + mp_map_t kw_args; + mp_map_init_fixed_table(&kw_args, n_kw, args + n_args); + pyb_i2c_init_helper(self, n_args - 1, args + 1, &kw_args); + } + + return (mp_obj_t)self; +} + +STATIC mp_obj_t pyb_i2c_init(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + return pyb_i2c_init_helper(args[0], n_args - 1, args + 1, kw_args); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_i2c_init_obj, 1, pyb_i2c_init); + +/// \method deinit() +/// Turn off the I2C bus. +STATIC mp_obj_t pyb_i2c_deinit(mp_obj_t self_in) { + i2c_deinit(); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_i2c_deinit_obj, pyb_i2c_deinit); + +/// \method is_ready(addr) +/// Check if an I2C device responds to the given address. Only valid when in master mode. +STATIC mp_obj_t pyb_i2c_is_ready(mp_obj_t self_in, mp_obj_t i2c_addr_o) { + pyb_i2c_obj_t *self = self_in; + + if (self->mode != PYBI2C_MODE_MASTER) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible)); + } + + mp_uint_t i2c_addr = mp_obj_get_int(i2c_addr_o); + + for (int i = 0; i < 10; i++) { + if (pybI2C_ScanDevice(i2c_addr, PYBI2C_TIMEOUT_TO_COUNT(PYBI2C_DEF_TIMEOUT_MS, self->baudrate))) { + return mp_const_true; + } + } + + return mp_const_false; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(pyb_i2c_is_ready_obj, pyb_i2c_is_ready); + +/// \method scan() +/// Scan all I2C addresses from 0x01 to 0x7f and return a list of those that respond. +/// Only valid when in master mode. +STATIC mp_obj_t pyb_i2c_scan(mp_obj_t self_in) { + pyb_i2c_obj_t *self = self_in; + + if (self->mode != PYBI2C_MODE_MASTER) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible)); + } + + mp_obj_t list = mp_obj_new_list(0, NULL); + + for (uint addr = 1; addr <= 127; addr++) { + for (int i = 0; i < 10; i++) { + if (pybI2C_ScanDevice(addr, PYBI2C_TIMEOUT_TO_COUNT(PYBI2C_DEF_TIMEOUT_MS, self->baudrate))) { + mp_obj_list_append(list, mp_obj_new_int(addr)); + break; + } + } + } + + return list; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_i2c_scan_obj, pyb_i2c_scan); + +/// \method send(send, addr=0x00) +/// Send data on the bus: +/// +/// - `send` is the data to send (an integer to send, or a buffer object) +/// - `addr` is the address to send to (only required in master mode) +/// - `timeout` is the timeout in milliseconds to wait for the other end to respond +/// Return value: `None`. +STATIC const mp_arg_t pyb_i2c_send_args[] = { + { MP_QSTR_send, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_addr, MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 5} }, +}; +#define PYB_I2C_SEND_NUM_ARGS MP_ARRAY_SIZE(pyb_i2c_send_args) + +STATIC mp_obj_t pyb_i2c_send(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + pyb_i2c_obj_t *self = args[0]; + + // parse args + mp_arg_val_t vals[PYB_I2C_SEND_NUM_ARGS]; + mp_arg_parse_all(n_args - 1, args + 1, kw_args, PYB_I2C_SEND_NUM_ARGS, pyb_i2c_send_args, vals); + + // get the buffer to send from + mp_buffer_info_t bufinfo; + uint8_t data[1]; + pyb_buf_get_for_send(vals[0].u_obj, &bufinfo, data); + + // send the data + if (self->mode == PYBI2C_MODE_MASTER) { + uint timeout = MIN(PYBI2C_TIMEOUT_TO_COUNT(vals[2].u_int, self->baudrate), 255); + if (!pybI2C_Write(vals[1].u_int, bufinfo.buf, bufinfo.len, true, timeout)) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed)); + } + } else { + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible)); + } + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_i2c_send_obj, 1, pyb_i2c_send); + +/// \method recv(recv, addr=0x00, timeout=10) +/// +/// Receive data on the bus: +/// +/// - `recv` can be an integer, which is the number of bytes to receive, +/// or a mutable buffer, which will be filled with received bytes +/// - `addr` is the address to receive from (only required in master mode) +/// - `timeout` is the timeout in milliseconds to wait for the other end to respond +/// +/// Return value: if `recv` is an integer then a new buffer of the bytes received, +/// otherwise the same buffer that was passed in to `recv`. +STATIC const mp_arg_t pyb_i2c_recv_args[] = { + { MP_QSTR_recv, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_addr, MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 5} }, +}; +#define PYB_I2C_RECV_NUM_ARGS MP_ARRAY_SIZE(pyb_i2c_recv_args) + +STATIC mp_obj_t pyb_i2c_recv(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + pyb_i2c_obj_t *self = args[0]; + + // parse args + mp_arg_val_t vals[PYB_I2C_RECV_NUM_ARGS]; + mp_arg_parse_all(n_args - 1, args + 1, kw_args, PYB_I2C_RECV_NUM_ARGS, pyb_i2c_recv_args, vals); + + // get the buffer to receive into + vstr_t vstr; + mp_obj_t o_ret = pyb_buf_get_for_recv(vals[0].u_obj, &vstr); + + // receive the data + if (self->mode == PYBI2C_MODE_MASTER) { + uint timeout = MIN(PYBI2C_TIMEOUT_TO_COUNT(vals[2].u_int, self->baudrate), 255); + if (!pybI2C_Read(vals[1].u_int, (byte *)vstr.buf, vstr.len, timeout)) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed)); + } + } else { + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible)); + } + + // return the received data + if (o_ret != MP_OBJ_NULL) { + return o_ret; + } else { + return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); + } +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_i2c_recv_obj, 1, pyb_i2c_recv); + +/// \method mem_read(data, addr, memaddr, timeout=10, addr_size=8) +/// +/// Read from the memory of an I2C device: +/// +/// - `data` can be an integer or a buffer to read into +/// - `addr` is the I2C device address +/// - `memaddr` is the memory location within the I2C device +/// - `timeout` is the timeout in milliseconds to wait for the other end to respond +/// - `addr_size` selects width of memaddr: 8 or 16 bits +/// +/// Returns the read data. +/// This is only valid in master mode. +STATIC const mp_arg_t pyb_i2c_mem_read_args[] = { + { MP_QSTR_data, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_addr, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_memaddr, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 5} }, + { MP_QSTR_addr_size, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} }, +}; +#define PYB_I2C_MEM_READ_NUM_ARGS MP_ARRAY_SIZE(pyb_i2c_mem_read_args) + +STATIC mp_obj_t pyb_i2c_mem_read(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + pyb_i2c_obj_t *self = args[0]; + + if (self->mode != PYBI2C_MODE_MASTER) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible)); + } + + // parse args + mp_arg_val_t vals[PYB_I2C_MEM_READ_NUM_ARGS]; + mp_arg_parse_all(n_args - 1, args + 1, kw_args, PYB_I2C_MEM_READ_NUM_ARGS, pyb_i2c_mem_read_args, vals); + + // get the buffer to read into + vstr_t vstr; + mp_obj_t o_ret = pyb_buf_get_for_recv(vals[0].u_obj, &vstr); + + // get the addresses + mp_uint_t i2c_addr = vals[1].u_int; + mp_uint_t mem_addr = vals[2].u_int; + // determine width of mem_addr (1 or 2 bytes) + mp_uint_t mem_addr_size = vals[4].u_int >> 3; + + // Write the register address to be read from. + uint timeout = MIN(PYBI2C_TIMEOUT_TO_COUNT(vals[3].u_int, self->baudrate), 255); + if (pybI2C_Write (i2c_addr, (byte *)&mem_addr, mem_addr_size, false, timeout)) { + // Read the specified length of data + if (pybI2C_Read (i2c_addr, (byte *)vstr.buf, vstr.len, timeout)) { + // return the read data + if (o_ret != MP_OBJ_NULL) { + return o_ret; + } else { + return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); + } + } + } + + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed)); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_i2c_mem_read_obj, 1, pyb_i2c_mem_read); + +/// \method mem_write(data, addr, memaddr, timeout=10, addr_size=8) +/// +/// Write to the memory of an I2C device: +/// +/// - `data` can be an integer or a buffer to write from +/// - `addr` is the I2C device address +/// - `memaddr` is the memory location within the I2C device +/// - `timeout` is the timeout in milliseconds to wait for the other end to respond +/// - `addr_size` selects width of memaddr: 8 or 16 bits +/// +/// Returns `None`. +/// This is only valid in master mode. +STATIC mp_obj_t pyb_i2c_mem_write(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + pyb_i2c_obj_t *self = args[0]; + + if (self->mode != PYBI2C_MODE_MASTER) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible)); + } + + // parse args (same as mem_read) + mp_arg_val_t vals[PYB_I2C_MEM_READ_NUM_ARGS]; + mp_arg_parse_all(n_args - 1, args + 1, kw_args, PYB_I2C_MEM_READ_NUM_ARGS, pyb_i2c_mem_read_args, vals); + + // get the buffer to write from + mp_buffer_info_t bufinfo; + uint8_t data[1]; + pyb_buf_get_for_send(vals[0].u_obj, &bufinfo, data); + + // get the addresses + mp_uint_t i2c_addr = vals[1].u_int; + mp_uint_t mem_addr = vals[2].u_int; + // determine width of mem_addr (1 or 2 bytes) + mp_uint_t mem_addr_size = vals[4].u_int >> 3; + + // Write the register address to be write to. + uint timeout = MIN(PYBI2C_TIMEOUT_TO_COUNT(vals[2].u_int, self->baudrate), 255); + if (pybI2C_Write (i2c_addr, (byte *)&mem_addr, mem_addr_size, false, timeout)) { + // Write the specified length of data + if (pybI2C_Write (i2c_addr, bufinfo.buf, bufinfo.len, true, timeout)) { + return mp_const_none; + } + } + + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed)); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_i2c_mem_write_obj, 1, pyb_i2c_mem_write); + +STATIC const mp_map_elem_t pyb_i2c_locals_dict_table[] = { + // instance methods + { MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&pyb_i2c_init_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_deinit), (mp_obj_t)&pyb_i2c_deinit_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_is_ready), (mp_obj_t)&pyb_i2c_is_ready_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_scan), (mp_obj_t)&pyb_i2c_scan_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_send), (mp_obj_t)&pyb_i2c_send_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_recv), (mp_obj_t)&pyb_i2c_recv_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_mem_read), (mp_obj_t)&pyb_i2c_mem_read_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_mem_write), (mp_obj_t)&pyb_i2c_mem_write_obj }, + + // class constants + /// \constant MASTER - for initialising the bus to master mode + /// \constant SLAVE - for initialising the bus to slave mode + { MP_OBJ_NEW_QSTR(MP_QSTR_MASTER), MP_OBJ_NEW_SMALL_INT(PYBI2C_MODE_MASTER) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SLAVE), MP_OBJ_NEW_SMALL_INT(PYBI2C_MODE_SLAVE) }, +}; + +STATIC MP_DEFINE_CONST_DICT(pyb_i2c_locals_dict, pyb_i2c_locals_dict_table); + +const mp_obj_type_t pyb_i2c_type = { + { &mp_type_type }, + .name = MP_QSTR_I2C, + .print = pyb_i2c_print, + .make_new = pyb_i2c_make_new, + .locals_dict = (mp_obj_t)&pyb_i2c_locals_dict, +}; diff --git a/cc3200/mods/pybi2c.h b/cc3200/mods/pybi2c.h new file mode 100644 index 0000000000..75f09c09f2 --- /dev/null +++ b/cc3200/mods/pybi2c.h @@ -0,0 +1,32 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2015 Daniel Campora + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +extern const mp_obj_type_t pyb_i2c_type; + +void i2c_init0(void); +void i2c_init (uint mode, uint slvaddr, uint baudrate); +void i2c_deinit(void); diff --git a/cc3200/mods/pybpin.c b/cc3200/mods/pybpin.c index 6acd3082bf..5be329163e 100644 --- a/cc3200/mods/pybpin.c +++ b/cc3200/mods/pybpin.c @@ -71,11 +71,16 @@ /// /// g = pyb.Pin('GPIO9', 0) /// +/// And finally, you can also pass a pin number directly: +/// +/// g = pyb.Pin(64, 0) +/// /// To summarise, the following order determines how things get mapped into /// an ordinal pin number: /// /// 1. Directly specify a Pin object -/// 2. Supply a string which matches a CPU port/pin +/// 2. Supply a string which matches a CPU pin name +/// 3. Provide a pin number void pin_init0(void) { } @@ -96,6 +101,16 @@ const pin_obj_t *pin_find(mp_obj_t user_obj) { return pin_obj; } + // See if the pin number matches a cpu pin + mp_int_t pin_num; + if (mp_obj_get_int_maybe(user_obj, &pin_num)) { + // The Pins dictionary has pin indexes, so we must substract one from the value passed + pin_obj = pin_find_pin(&pin_cpu_pins_locals_dict, (pin_num - 1)); + if (pin_obj) { + return pin_obj; + } + } + nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments)); } @@ -218,9 +233,9 @@ STATIC mp_obj_t pin_make_new(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw, /// - `Pin.OD_PD` - open drain with pull-down resistor. /// - `Pin.ANALOG` - configured in analog (adc) mode /// - `strength` can be one of: -/// - `Pin.2MA` - 2ma drive strength; -/// - `Pin.4MA` - 4ma drive strength; -/// - `Pin.6MA` - 6ma drive strength; +/// - `Pin.S2MA` - 2ma drive strength; +/// - `Pin.S4MA` - 4ma drive strength; +/// - `Pin.S6MA` - 6ma drive strength; /// /// Returns: `None`. STATIC const mp_arg_t pin_init_args[] = { diff --git a/cc3200/mods/pybpin.h b/cc3200/mods/pybpin.h index 9b4f2e7874..2ab7a507db 100644 --- a/cc3200/mods/pybpin.h +++ b/cc3200/mods/pybpin.h @@ -60,6 +60,7 @@ void pin_init0(void); void pin_config(const pin_obj_t *self, uint af, uint mode, uint type, uint strength); const pin_obj_t *pin_find(mp_obj_t user_obj); const pin_obj_t *pin_find_named_pin(const mp_obj_dict_t *named_pins, mp_obj_t name); +const pin_obj_t *pin_find_pin(const mp_obj_dict_t *named_pins, uint pin_num); uint32_t pin_get_mode(const pin_obj_t *self); uint32_t pin_get_type(const pin_obj_t *self); uint32_t pin_get_strenght(const pin_obj_t *self); diff --git a/cc3200/mods/pybuart.c b/cc3200/mods/pybuart.c index b612295c3b..21daecf9f9 100644 --- a/cc3200/mods/pybuart.c +++ b/cc3200/mods/pybuart.c @@ -41,22 +41,18 @@ #include "runtime.h" #include "stream.h" #include "inc/hw_types.h" -#include "inc/hw_gpio.h" #include "inc/hw_ints.h" #include "inc/hw_memmap.h" #include "inc/hw_uart.h" #include "rom_map.h" #include "interrupt.h" #include "prcm.h" -#include "gpio.h" #include "uart.h" -#include "pin.h" #include "pybuart.h" #include "pybioctl.h" #include "mpexception.h" #include "osi.h" - /// \moduleref pyb /// \class UART - duplex serial communication bus /// @@ -90,8 +86,6 @@ /// /// uart.any() # returns True if any characters waiting - - /****************************************************************************** DECLARE PRIVATE FUNCTIONS ******************************************************************************/ @@ -150,16 +144,12 @@ bool uart_init2(pyb_uart_obj_t *self) { case PYB_UART_1: self->reg = UARTA0_BASE; uartPerh = PRCM_UARTA0; - MAP_PinTypeUART(PIN_55, PIN_MODE_3); - MAP_PinTypeUART(PIN_57, PIN_MODE_3); MAP_UARTIntRegister(UARTA0_BASE, UART0IntHandler); MAP_IntPrioritySet(INT_UARTA0, INT_PRIORITY_LVL_7); break; case PYB_UART_2: self->reg = UARTA1_BASE; uartPerh = PRCM_UARTA1; - MAP_PinTypeUART(PIN_58, PIN_MODE_6); - MAP_PinTypeUART(PIN_59, PIN_MODE_6); MAP_UARTIntRegister(UARTA1_BASE, UART1IntHandler); MAP_IntPrioritySet(INT_UARTA1, INT_PRIORITY_LVL_7); break; @@ -469,9 +459,10 @@ STATIC mp_obj_t pyb_uart_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t pyb_uart_obj_t *self; if (MP_STATE_PORT(pyb_uart_obj_all)[uart_id - 1] == NULL) { // create new UART object - self = m_new0(pyb_uart_obj_t, 1); + self = m_new_obj(pyb_uart_obj_t); self->base.type = &pyb_uart_type; self->uart_id = uart_id; + self->read_buf = NULL; self->enabled = false; MP_STATE_PORT(pyb_uart_obj_all)[uart_id - 1] = self; } else { diff --git a/cc3200/mpconfigport.h b/cc3200/mpconfigport.h index a29bce26d4..fa17eca64f 100644 --- a/cc3200/mpconfigport.h +++ b/cc3200/mpconfigport.h @@ -123,6 +123,7 @@ extern const struct _mp_obj_module_t mp_module_network; mp_obj_list_t pyb_extint_list; \ struct _pyb_uart_obj_t *pyb_stdio_uart; \ struct _pyb_uart_obj_t *pyb_uart_obj_all[2]; \ + struct _pyb_i2c_obj_t *pyb_i2c_obj; \ mp_obj_list_t mod_network_nic_list; \ diff --git a/cc3200/mptask.c b/cc3200/mptask.c index 78eaa76f00..77b45859f6 100644 --- a/cc3200/mptask.c +++ b/cc3200/mptask.c @@ -41,6 +41,8 @@ #include "runtime.h" #include "repl.h" #include "inc/hw_memmap.h" +#include "inc/hw_types.h" +#include "pin.h" #include "pybuart.h" #include "pybpin.h" #include "pybrtc.h" @@ -64,6 +66,8 @@ #include "mpexception.h" #include "random.h" #include "pybextint.h" +#include "pybi2c.h" +#include "pins.h" /****************************************************************************** DECLARE PRIVATE CONSTANTS @@ -142,7 +146,13 @@ soft_reset: mpexception_init0(); uart_init0(); + pin_init0(); + i2c_init0(); + // configure stdio uart pins with the correct af + // param 3 ("mode") is DON'T CARE" for AFs others than GPIO + pin_config(&pin_GPIO1, PIN_MODE_3, 0, PIN_TYPE_STD, PIN_STRENGTH_2MA); + pin_config(&pin_GPIO2, PIN_MODE_3, 0, PIN_TYPE_STD, PIN_STRENGTH_2MA); // Instantiate the stdio uart mp_obj_t args[2] = { mp_obj_new_int(MICROPY_STDIO_UART), @@ -151,7 +161,6 @@ soft_reset: MP_STATE_PORT(pyb_stdio_uart) = pyb_uart_type.make_new((mp_obj_t)&pyb_uart_type, MP_ARRAY_SIZE(args), 0, args); readline_init0(); - pin_init0(); extint_init0(); mod_network_init(); wlan_init0(); diff --git a/cc3200/qstrdefsport.h b/cc3200/qstrdefsport.h index 9ea8c24d37..a764a61206 100644 --- a/cc3200/qstrdefsport.h +++ b/cc3200/qstrdefsport.h @@ -58,6 +58,7 @@ Q(chdir) Q(getcwd) Q(listdir) Q(mkdir) +Q(mkdisk) Q(remove) Q(rmdir) Q(unlink) @@ -135,6 +136,26 @@ Q(FLOW_TX) Q(FLOW_RX) Q(FLOW_TXRX) +// for I2C class +Q(I2C) +Q(mode) +Q(addr) +Q(baudrate) +Q(data) +Q(memaddr) +Q(addr_size) +Q(timeout) +Q(init) +Q(deinit) +Q(is_ready) +Q(scan) +Q(send) +Q(recv) +Q(mem_read) +Q(mem_write) +Q(MASTER) +Q(SLAVE) + // for RTC class Q(RTC) Q(datetime)