mirror of
https://github.com/Spritetm/minimacplus.git
synced 2025-01-19 10:30:57 +00:00
146 lines
4.5 KiB
C
146 lines
4.5 KiB
C
#include <stdio.h>
|
|
#include "driver/i2c.h"
|
|
#include "mpu6050.h"
|
|
|
|
#define I2C_MASTER_SCL_IO 26 /*!< gpio number for I2C master clock */
|
|
#define I2C_MASTER_SDA_IO 4 /*!< gpio number for I2C master data */
|
|
#define I2C_MASTER_NUM I2C_NUM_0 /*!< I2C port number for master dev */
|
|
|
|
#define MPU_ADDR 0x68
|
|
|
|
static esp_err_t setreg(int i2c_num, int reg, int val) {
|
|
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
|
i2c_master_start(cmd);
|
|
i2c_master_write_byte(cmd, ( (MPU_ADDR<<1) | I2C_MASTER_WRITE), true);
|
|
i2c_master_write_byte(cmd, reg, true);
|
|
i2c_master_write_byte(cmd, val, true);
|
|
i2c_master_stop(cmd);
|
|
esp_err_t ret = i2c_master_cmd_begin(i2c_num, cmd, 30 / portTICK_RATE_MS);
|
|
if (ret!=ESP_OK) printf("MPU6050: NACK setting reg 0x%X to val 0x%X\n", reg, val);
|
|
i2c_cmd_link_delete(cmd);
|
|
return ret;
|
|
}
|
|
|
|
static int getreg(int i2c_num, int reg) {
|
|
unsigned char byte;
|
|
esp_err_t ret;
|
|
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
|
i2c_master_start(cmd);
|
|
i2c_master_write_byte(cmd, ( (MPU_ADDR<<1) | I2C_MASTER_WRITE), true);
|
|
i2c_master_write_byte(cmd, reg, true);
|
|
ret=i2c_master_cmd_begin(i2c_num, cmd, 100 / portTICK_RATE_MS);
|
|
i2c_cmd_link_delete(cmd);
|
|
|
|
cmd = i2c_cmd_link_create();
|
|
i2c_master_start(cmd);
|
|
i2c_master_write_byte(cmd, ( (MPU_ADDR<<1) | I2C_MASTER_READ), true);
|
|
i2c_master_read_byte(cmd, &byte, true);
|
|
i2c_master_stop(cmd);
|
|
ret=i2c_master_cmd_begin(i2c_num, cmd, 100 / portTICK_RATE_MS);
|
|
i2c_cmd_link_delete(cmd);
|
|
if (ret!=ESP_OK) printf("MPU6050: NACK reading reg 0x%X\n", reg);
|
|
if (ret!=ESP_OK) {
|
|
return -1;
|
|
}
|
|
return byte;
|
|
}
|
|
|
|
|
|
esp_err_t mpu6050_start(int i2c_num, int samp_div) {
|
|
printf("Initializing MPU6050...\n");
|
|
setreg(i2c_num, 107, 0x80); //Reset
|
|
vTaskDelay(10);
|
|
int i=getreg(i2c_num, 0x75);
|
|
if (i!=0x68) {
|
|
printf("No MPU6050 detected at i2c addr %x! (%d) No mouse available.\n", MPU_ADDR, i);
|
|
return ESP_ERR_NOT_FOUND;
|
|
}
|
|
setreg(i2c_num, 107, 1); //Take out of sleep, gyro as clk
|
|
setreg(i2c_num, 108, 0); //Un-standby everything
|
|
setreg(i2c_num, 106, 0x0C); //reset more stuff
|
|
vTaskDelay(10);
|
|
setreg(i2c_num, 106, 0x0); //reset more stuff
|
|
setreg(i2c_num, 25, samp_div); //Sample divider
|
|
setreg(i2c_num, 26, (7<<3)|0); //fsync to accel_z[0], 260Hz bw (making Fsamp 8KHz)
|
|
setreg(i2c_num, 27, 0); //gyro def
|
|
setreg(i2c_num, 28, 0); //accel 2G
|
|
setreg(i2c_num, 35, 0x08); //fifo: emit accel data only
|
|
setreg(i2c_num, 36, 0x00); //no slave
|
|
setreg(i2c_num, 106, 0x40); //fifo: enable
|
|
printf("MPU6050 found and initialized.\n");
|
|
|
|
return ESP_OK;
|
|
}
|
|
|
|
|
|
int mpu6050_read_fifo(mpu6050_accel_tp *meas, int maxct) {
|
|
int i2c_num=I2C_MASTER_NUM;
|
|
int i;
|
|
int no;
|
|
uint8_t buf[6];
|
|
i2c_cmd_handle_t cmd;
|
|
esp_err_t ret;
|
|
no=(getreg(i2c_num, 114)<<8);
|
|
no|=getreg(i2c_num, 115);
|
|
if (no>0x8000) {
|
|
printf("Huh? Fifo has %x bytes.\n", no);
|
|
return 0; //huh?
|
|
}
|
|
// printf("FIFO: %d\n", no);
|
|
no=no/6; //bytes -> samples
|
|
if (no>maxct) no=maxct;
|
|
|
|
|
|
for (i=0; i<no; i++) {
|
|
cmd = i2c_cmd_link_create();
|
|
i2c_master_start(cmd);
|
|
i2c_master_write_byte(cmd, ( (MPU_ADDR<<1) | I2C_MASTER_WRITE), true);
|
|
i2c_master_write_byte(cmd, 116, true);
|
|
i2c_master_stop(cmd);
|
|
ret=i2c_master_cmd_begin(i2c_num, cmd, 100 / portTICK_RATE_MS);
|
|
i2c_cmd_link_delete(cmd);
|
|
|
|
cmd = i2c_cmd_link_create();
|
|
i2c_master_start(cmd);
|
|
i2c_master_write_byte(cmd, ( (MPU_ADDR<<1) | I2C_MASTER_READ), true);
|
|
i2c_master_read(cmd, buf, 5, 0);
|
|
i2c_master_read(cmd, buf+5, 1, 1);
|
|
i2c_master_stop(cmd);
|
|
ret=i2c_master_cmd_begin(i2c_num, cmd, 100 / portTICK_RATE_MS);
|
|
if (ret!=ESP_OK) {
|
|
printf("Error reading packet %d/%d\n", i, no);
|
|
return 0;
|
|
}
|
|
meas[i].accelx=(buf[0]<<8)|buf[1];
|
|
meas[i].accely=(buf[2]<<8)|buf[3];
|
|
meas[i].accelz=(buf[4]<<8)|buf[5];
|
|
i2c_cmd_link_delete(cmd);
|
|
}
|
|
return no;
|
|
}
|
|
|
|
//Actually initializes the i2c port, but atm there's nothing else connected to it... should put this
|
|
//into some io init routine or something tho'.
|
|
|
|
int mpu6050_init() {
|
|
i2c_config_t conf;
|
|
conf.mode = I2C_MODE_MASTER;
|
|
conf.scl_io_num = I2C_MASTER_SCL_IO;
|
|
conf.sda_io_num = I2C_MASTER_SDA_IO;
|
|
conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
|
|
conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
|
|
conf.master.clk_speed = 400000;
|
|
ESP_ERROR_CHECK(i2c_param_config(I2C_MASTER_NUM, &conf));
|
|
ESP_ERROR_CHECK(i2c_driver_install(I2C_MASTER_NUM, conf.mode, 1024, 1024, 0));
|
|
|
|
//MPU has sample rate of 8KHz. We have an 1K fifo where we put 6byte samples --> about 128 samples.
|
|
//We want to grab the data at about 10Hz -> sample rate of about 1KHz.
|
|
esp_err_t r=mpu6050_start(I2C_MASTER_NUM, 8);
|
|
if (r!=ESP_OK) {
|
|
i2c_driver_delete(I2C_MASTER_NUM);
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|