STATIC void accel_start(void) { // start the I2C bus in master mode i2c_init(I2C1, MICROPY_HW_I2C1_SCL, MICROPY_HW_I2C1_SDA, 400000); // turn off AVDD, wait 30ms, turn on AVDD, wait 30ms again mp_hal_pin_low(MICROPY_HW_MMA_AVDD_PIN); // turn off mp_hal_delay_ms(30); mp_hal_pin_high(MICROPY_HW_MMA_AVDD_PIN); // turn on mp_hal_delay_ms(30); int ret; for (int i = 0; i < 4; i++) { ret = i2c_writeto(I2C1, MMA_ADDR, NULL, 0, true); if (ret == 0) { break; } } if (ret != 0) { mp_raise_msg(&mp_type_OSError, "accelerometer not found"); } // set MMA to active mode uint8_t data[2] = {MMA_REG_MODE, 1}; // active mode i2c_writeto(I2C1, MMA_ADDR, data, 2, true); // wait for MMA to become active mp_hal_delay_ms(30); }
/** * @brief used to write multiple bytes of data to DMP memory. * * @param sl_handle Unused, pass as NULL * @param slaveAddr I2C slave address of device. * @param memAddr The location in the memory to write to. 16 bits. * @param length Length of burst data. Must not cross 8-bit address boundary. * @param data Pointer to block of data. * * @return Zero if successful; an error code otherwise */ inv_error_t inv_serial_write_mem( void *sl_handle, unsigned char slaveAddr, unsigned short memAddr, unsigned short length, unsigned char const *data ) { inv_error_t result; unsigned char tmpAddr; unsigned char memAddress[1]; unsigned char i2cWrite[SERIAL_MAX_TRANSFER_SIZE]; uint_fast16_t bytesWritten = 0; if ((memAddr & 0xFF) + length > MPU_MEM_BANK_SIZE) { //_SerialDebug("inv_serial_write_mem: memory write length (%d B) " // "extends beyond its limits (%d)\n " // "if started at location %d\n", // length, MPU_MEM_BANK_SIZE, memAddr & 0xFF); return INV_ERROR_INVALID_PARAMETER; } /* Write bank - first time only */ tmpAddr = MPUREG_BANK_SEL; memAddress[0] = memAddr >> 8; result = i2c_writeto((uint16_t)slaveAddr, (uint8_t)tmpAddr, memAddress, 1 ); while (bytesWritten<length) { unsigned short thisLen = MIN(SERIAL_MAX_TRANSFER_SIZE, length-bytesWritten); /* Write address */ tmpAddr = MPUREG_MEM_START_ADDR; memAddress[0] = memAddr+bytesWritten; // valid because we don't allow going // beyond the MPU_MEM_BANK_SIZE boundary result = i2c_writeto((uint16_t)slaveAddr,(uint8_t)tmpAddr, memAddress, 1); /* Write memory contents from data */ memcpy (&i2cWrite[0], &data[bytesWritten], thisLen); result = i2c_writeto(slaveAddr, MPUREG_MEM_R_W, i2cWrite, thisLen); bytesWritten += thisLen; } return result; }
/** * @brief used to write multiple bytes of data to the fifo. * This should be sent by I2C. * * @param sl_handle Unused, pass as NULL * @param slaveAddr I2C slave address of device. * @param length Length of burst of data. * @param data Pointer to block of data. * * @return Zero if successful; an error code otherwise */ inv_error_t inv_serial_write_fifo( void *sl_handle, unsigned char slaveAddr, unsigned short length, unsigned char const *data ) { inv_error_t result; if (length>FIFO_HW_SIZE) { return INV_ERROR_INVALID_PARAMETER; } result = i2c_writeto(slaveAddr, MPUREG_FIFO_R_W, data, length); return INV_SUCCESS; }
/** * @brief used to write a single byte to a single register. * * @param sl_handle Unused, pass as NULL * @param slaveAddr I2C slave address of device. * @param registerAddr Register address to write. * @param data Single byte of data to write. * * @return INV_SUCCESS if successful, a non-zero error code otherwise. */ inv_error_t inv_serial_single_write(void *sl_handle, unsigned char slaveAddr, unsigned char registerAddr, unsigned char data) { inv_error_t result; // Copy the argument to this call stack. // In the past there have been compiler issues which prohibit // dereferencing arguments. unsigned char tempData[1]; tempData[0] = data; result = i2c_writeto((uint16_t)slaveAddr, (uint8_t)registerAddr, tempData, 1); return INV_SUCCESS; }
/** * @brief used as generic serial write. Does not accept a * register parameter like the rest of the MLSLSerial * functions - if used to write to a register, the register * address should be the first member of data * This should be sent by I2C. * * @param sl_handle Unused, pass as NULL * @param slaveAddr I2C slave address of device. * @param length Length of burst of data. * @param data Pointer to block of data. * * @return INV_SUCCESS if successful, a non-zero error code otherwise. */ inv_error_t inv_serial_write( void *sl_handle, unsigned char slaveAddr, unsigned short length, unsigned char const *data ) { inv_error_t result; // twim_write does follow the slaveAddr / slaveRegister convention // so we transform the inputs to follow this convention. uint8_t regAddr = data[0]; data = data + 1; length = length -1; //result = twim_write(slaveAddr, regAddr, data, (size_t)length); result = i2c_writeto(slaveAddr, regAddr, data, (size_t)length); return INV_SUCCESS; }
/// \method filtered_xyz() /// Get a 3-tuple of filtered x, y and z values. STATIC mp_obj_t pyb_accel_filtered_xyz(mp_obj_t self_in) { pyb_accel_obj_t *self = self_in; memmove(self->buf, self->buf + NUM_AXIS, NUM_AXIS * (FILT_DEPTH - 1) * sizeof(int16_t)); uint8_t data[NUM_AXIS] = { MMA_REG_X }; i2c_writeto(I2C1, MMA_ADDR, data, 1, false); i2c_readfrom(I2C1, MMA_ADDR, data, 3, true); mp_obj_t tuple[NUM_AXIS]; for (int i = 0; i < NUM_AXIS; i++) { self->buf[NUM_AXIS * (FILT_DEPTH - 1) + i] = MMA_AXIS_SIGNED_VALUE(data[i]); int32_t val = 0; for (int j = 0; j < FILT_DEPTH; j++) { val += self->buf[i + NUM_AXIS * j]; } tuple[i] = mp_obj_new_int(val); } return mp_obj_new_tuple(3, tuple); }
STATIC mp_obj_t pyb_accel_write(mp_obj_t self_in, mp_obj_t reg, mp_obj_t val) { uint8_t data[2] = { mp_obj_get_int(reg), mp_obj_get_int(val) }; i2c_writeto(I2C1, MMA_ADDR, data, 2, true); return mp_const_none; }
STATIC mp_obj_t pyb_accel_read(mp_obj_t self_in, mp_obj_t reg) { uint8_t data[1] = { mp_obj_get_int(reg) }; i2c_writeto(I2C1, MMA_ADDR, data, 1, false); i2c_writeto(I2C1, MMA_ADDR, data, 1, true); return mp_obj_new_int(data[0]); }
/// \method tilt() /// Get the tilt register. STATIC mp_obj_t pyb_accel_tilt(mp_obj_t self_in) { uint8_t data[1] = { MMA_REG_TILT }; i2c_writeto(I2C1, MMA_ADDR, data, 1, false); i2c_readfrom(I2C1, MMA_ADDR, data, 1, true); return mp_obj_new_int(data[0]); }
STATIC mp_obj_t read_axis(int axis) { uint8_t data[1] = { axis }; i2c_writeto(I2C1, MMA_ADDR, data, 1, false); i2c_readfrom(I2C1, MMA_ADDR, data, 1, true); return mp_obj_new_int(MMA_AXIS_SIGNED_VALUE(data[0])); }