You've already forked Applications-cam
mirror of
https://github.com/m5stack/Applications-cam.git
synced 2026-05-20 10:25:12 -07:00
333 lines
12 KiB
C++
333 lines
12 KiB
C++
#include"iic.h"
|
|
|
|
SemaphoreHandle_t print_mux = NULL;
|
|
I2C::I2C(void)
|
|
{
|
|
//print_mux = NULL;
|
|
}
|
|
|
|
|
|
esp_err_t I2C::master_read_slave(i2c_port_t i2c_num, uint8_t* data_rd, size_t size)
|
|
{
|
|
if (size == 0) {
|
|
return ESP_OK;
|
|
}
|
|
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
|
i2c_master_start(cmd);
|
|
i2c_master_write_byte(cmd, ( ESP_SLAVE_ADDR << 1 ) | READ_BIT, ACK_CHECK_EN);
|
|
if (size > 1) {
|
|
i2c_master_read(cmd, data_rd, size - 1, I2C_MASTER_ACK); //ACK_VAL
|
|
}
|
|
i2c_master_read_byte(cmd, data_rd + size - 1,I2C_MASTER_NACK); //NACK_VAL
|
|
i2c_master_stop(cmd);
|
|
esp_err_t ret = i2c_master_cmd_begin(i2c_num, cmd, 1000 / portTICK_RATE_MS);
|
|
i2c_cmd_link_delete(cmd);
|
|
return ret;
|
|
}
|
|
|
|
esp_err_t I2C::master_write_slave(i2c_port_t i2c_num, uint8_t* data_wr, size_t size)
|
|
{
|
|
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
|
i2c_master_start(cmd);
|
|
i2c_master_write_byte(cmd, ( ESP_SLAVE_ADDR << 1 ) | WRITE_BIT, ACK_CHECK_EN);
|
|
i2c_master_write(cmd, data_wr, size, ACK_CHECK_EN);
|
|
i2c_master_stop(cmd);
|
|
esp_err_t ret = i2c_master_cmd_begin(i2c_num, cmd, 1000 / portTICK_RATE_MS);
|
|
i2c_cmd_link_delete(cmd);
|
|
return ret;
|
|
}
|
|
|
|
esp_err_t I2C::master_sensor_test(i2c_port_t i2c_num, uint8_t* data_h, uint8_t* data_l)
|
|
{
|
|
int ret;
|
|
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
|
i2c_master_start(cmd);
|
|
i2c_master_write_byte(cmd, BH1750_SENSOR_ADDR << 1 | WRITE_BIT, ACK_CHECK_EN);
|
|
i2c_master_write_byte(cmd, BH1750_CMD_START, ACK_CHECK_EN);
|
|
i2c_master_stop(cmd);
|
|
ret = i2c_master_cmd_begin(i2c_num, cmd, 1000 / portTICK_RATE_MS);
|
|
i2c_cmd_link_delete(cmd);
|
|
if (ret != ESP_OK) {
|
|
return ret;
|
|
}
|
|
vTaskDelay(30 / portTICK_RATE_MS);
|
|
cmd = i2c_cmd_link_create();
|
|
i2c_master_start(cmd);
|
|
i2c_master_write_byte(cmd, BH1750_SENSOR_ADDR << 1 | READ_BIT, ACK_CHECK_EN);
|
|
//i2c_master_read_byte(cmd, data_h, ACK_VAL);
|
|
//i2c_master_read_byte(cmd, data_l, NACK_VAL);
|
|
|
|
i2c_master_read_byte(cmd, data_h, I2C_MASTER_ACK);
|
|
i2c_master_read_byte(cmd, data_l, I2C_MASTER_NACK);
|
|
i2c_master_stop(cmd);
|
|
ret = i2c_master_cmd_begin(i2c_num, cmd, 1000 / portTICK_RATE_MS);
|
|
i2c_cmd_link_delete(cmd);
|
|
return ret;
|
|
}
|
|
|
|
void I2C::master_init()
|
|
{
|
|
i2c_port_t i2c_master_port = I2C_EXAMPLE_MASTER_NUM;
|
|
i2c_config_t conf;
|
|
conf.mode = I2C_MODE_MASTER;
|
|
conf.sda_io_num = I2C_EXAMPLE_MASTER_SDA_IO;
|
|
conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
|
|
conf.scl_io_num = I2C_EXAMPLE_MASTER_SCL_IO;
|
|
conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
|
|
conf.master.clk_speed = I2C_EXAMPLE_MASTER_FREQ_HZ;
|
|
i2c_param_config(i2c_master_port, &conf);
|
|
i2c_driver_install(i2c_master_port, conf.mode,
|
|
I2C_EXAMPLE_MASTER_RX_BUF_DISABLE,
|
|
I2C_EXAMPLE_MASTER_TX_BUF_DISABLE, 0);
|
|
}
|
|
|
|
void I2C::slave_init()
|
|
{
|
|
i2c_port_t i2c_slave_port = I2C_EXAMPLE_SLAVE_NUM;
|
|
i2c_config_t conf_slave;
|
|
conf_slave.sda_io_num = I2C_EXAMPLE_SLAVE_SDA_IO;
|
|
conf_slave.sda_pullup_en = GPIO_PULLUP_ENABLE;
|
|
conf_slave.scl_io_num = I2C_EXAMPLE_SLAVE_SCL_IO;
|
|
conf_slave.scl_pullup_en = GPIO_PULLUP_ENABLE;
|
|
conf_slave.mode = I2C_MODE_SLAVE;
|
|
conf_slave.slave.addr_10bit_en = 0;
|
|
conf_slave.slave.slave_addr = ESP_SLAVE_ADDR;
|
|
i2c_param_config(i2c_slave_port, &conf_slave);
|
|
i2c_driver_install(i2c_slave_port, conf_slave.mode,
|
|
I2C_EXAMPLE_SLAVE_RX_BUF_LEN,
|
|
I2C_EXAMPLE_SLAVE_TX_BUF_LEN, 0);
|
|
}
|
|
|
|
void I2C::disp_buf(uint8_t* buf, int len)
|
|
{
|
|
int i;
|
|
for (i = 0; i < len; i++) {
|
|
printf("%02x ", buf[i]);
|
|
if (( i + 1 ) % 16 == 0) {
|
|
printf("\n");
|
|
}
|
|
}
|
|
printf("\n");
|
|
}
|
|
|
|
void I2C::test_task(void* arg)
|
|
{
|
|
int i = 0;
|
|
int ret;
|
|
uint32_t task_idx = (uint32_t) arg;
|
|
uint8_t* data = (uint8_t*) malloc(DATA_LENGTH);
|
|
uint8_t* data_wr = (uint8_t*) malloc(DATA_LENGTH);
|
|
uint8_t* data_rd = (uint8_t*) malloc(DATA_LENGTH);
|
|
uint8_t sensor_data_h, sensor_data_l;
|
|
int cnt = 0;
|
|
while (1) {
|
|
printf("test cnt: %d\n", cnt++);
|
|
ret = master_sensor_test( I2C_EXAMPLE_MASTER_NUM, &sensor_data_h, &sensor_data_l);
|
|
xSemaphoreTake(print_mux, portMAX_DELAY);
|
|
if(ret == ESP_ERR_TIMEOUT) {
|
|
printf("I2C timeout\n");
|
|
} else if(ret == ESP_OK) {
|
|
printf("*******************\n");
|
|
printf("TASK[%d] MASTER READ SENSOR( BH1750 )\n", task_idx);
|
|
printf("*******************\n");
|
|
printf("data_h: %02x\n", sensor_data_h);
|
|
printf("data_l: %02x\n", sensor_data_l);
|
|
printf("sensor val: %f\n", (sensor_data_h << 8 | sensor_data_l) / 1.2);
|
|
} else {
|
|
printf("%s: No ack, sensor not connected...skip...\n", esp_err_to_name(ret));
|
|
}
|
|
xSemaphoreGive(print_mux);
|
|
vTaskDelay(( DELAY_TIME_BETWEEN_ITEMS_MS * ( task_idx + 1 ) ) / portTICK_RATE_MS);
|
|
//---------------------------------------------------
|
|
for (i = 0; i < DATA_LENGTH; i++) {
|
|
data[i] = i;
|
|
}
|
|
xSemaphoreTake(print_mux, portMAX_DELAY);
|
|
size_t d_size = i2c_slave_write_buffer(I2C_EXAMPLE_SLAVE_NUM, data, RW_TEST_LENGTH, 1000 / portTICK_RATE_MS);
|
|
if (d_size == 0) {
|
|
printf("i2c slave tx buffer full\n");
|
|
ret = master_read_slave(I2C_EXAMPLE_MASTER_NUM, data_rd, DATA_LENGTH);
|
|
} else {
|
|
ret = master_read_slave(I2C_EXAMPLE_MASTER_NUM, data_rd, RW_TEST_LENGTH);
|
|
}
|
|
|
|
if (ret == ESP_ERR_TIMEOUT) {
|
|
printf("I2C timeout\n");
|
|
printf("*********\n");
|
|
} else if (ret == ESP_OK) {
|
|
printf("*******************\n");
|
|
printf("TASK[%d] MASTER READ FROM SLAVE\n", task_idx);
|
|
printf("*******************\n");
|
|
printf("====TASK[%d] Slave buffer data ====\n", task_idx);
|
|
disp_buf(data, d_size);
|
|
printf("====TASK[%d] Master read ====\n", task_idx);
|
|
disp_buf(data_rd, d_size);
|
|
} else {
|
|
printf("%s: Master read slave error, IO not connected...\n", esp_err_to_name(ret));
|
|
}
|
|
xSemaphoreGive(print_mux);
|
|
vTaskDelay(( DELAY_TIME_BETWEEN_ITEMS_MS * ( task_idx + 1 ) ) / portTICK_RATE_MS);
|
|
//---------------------------------------------------
|
|
int size;
|
|
for (i = 0; i < DATA_LENGTH; i++) {
|
|
data_wr[i] = i + 10;
|
|
}
|
|
xSemaphoreTake(print_mux, portMAX_DELAY);
|
|
//we need to fill the slave buffer so that master can read later
|
|
ret = master_write_slave( I2C_EXAMPLE_MASTER_NUM, data_wr, RW_TEST_LENGTH);
|
|
if (ret == ESP_OK) {
|
|
size = i2c_slave_read_buffer( I2C_EXAMPLE_SLAVE_NUM, data, RW_TEST_LENGTH, 1000 / portTICK_RATE_MS);
|
|
}
|
|
if (ret == ESP_ERR_TIMEOUT) {
|
|
printf("I2C timeout\n");
|
|
} else if (ret == ESP_OK) {
|
|
printf("*******************\n");
|
|
printf("TASK[%d] MASTER WRITE TO SLAVE\n", task_idx);
|
|
printf("*******************\n");
|
|
printf("----TASK[%d] Master write ----\n", task_idx);
|
|
disp_buf(data_wr, RW_TEST_LENGTH);
|
|
printf("----TASK[%d] Slave read: [%d] bytes ----\n", task_idx, size);
|
|
disp_buf(data, size);
|
|
} else {
|
|
printf("TASK[%d] %s: Master write slave error, IO not connected....\n", task_idx, esp_err_to_name(ret));
|
|
}
|
|
xSemaphoreGive(print_mux);
|
|
vTaskDelay(( DELAY_TIME_BETWEEN_ITEMS_MS * ( task_idx + 1 ) ) / portTICK_RATE_MS);
|
|
}
|
|
}
|
|
|
|
void I2C::slave_task(void* arg)
|
|
{
|
|
int i = 0;
|
|
int ret;
|
|
uint32_t task_idx = (uint32_t) arg;
|
|
uint8_t* data = (uint8_t*) malloc(DATA_LENGTH);
|
|
uint8_t* data_wr = (uint8_t*) malloc(DATA_LENGTH);
|
|
uint8_t* data_rd = (uint8_t*) malloc(DATA_LENGTH);
|
|
uint8_t sensor_data_h, sensor_data_l;
|
|
int cnt = 0;
|
|
while (true) {
|
|
//printf("test cnt: %d\n", cnt++);
|
|
//---------------------------------------------------
|
|
for (i = 0; i < 9; i++) {
|
|
data[i] = sent_pp[i];
|
|
}
|
|
for (i = 9; i < 29; i++) {
|
|
data[i] = sent_e_pp[i - 9];
|
|
}
|
|
// printf("----TASK[%d] Slave read: [%d] bytes ----\n", task_idx, size);
|
|
disp_buf(data, 29);
|
|
//sent_pp[i] = pp[i]*100/(fb->len/18);
|
|
xSemaphoreTake(print_mux, portMAX_DELAY);
|
|
//i2c_reset_tx_fifo(I2C_EXAMPLE_SLAVE_NUM);
|
|
//i2c_reset_rx_fifo(I2C_EXAMPLE_SLAVE_NUM);
|
|
size_t d_size = i2c_slave_write_buffer(I2C_EXAMPLE_SLAVE_NUM, data, 29, 1 / portTICK_RATE_MS);
|
|
//size_t d_size;
|
|
if (d_size == 0) {
|
|
printf("i2c slave tx buffer full\n");
|
|
} else {
|
|
printf("d_size = %d\n",d_size);
|
|
}
|
|
xSemaphoreGive(print_mux);
|
|
//vTaskDelay(( DELAY_TIME_BETWEEN_ITEMS_MS * ( task_idx + 1 ) ) / portTICK_RATE_MS);
|
|
vTaskDelay(2 / portTICK_RATE_MS);
|
|
|
|
//---------------------------------------------------
|
|
/*
|
|
int size;
|
|
for (i = 0; i < DATA_LENGTH; i++) {
|
|
data_wr[i] = i + 10;
|
|
}
|
|
xSemaphoreTake(print_mux, portMAX_DELAY);
|
|
//we need to fill the slave buffer so that master can read later
|
|
//ret = master_write_slave( I2C_EXAMPLE_MASTER_NUM, data_wr, RW_TEST_LENGTH);
|
|
|
|
// if (ret == ESP_OK) {
|
|
size = i2c_slave_read_buffer( I2C_EXAMPLE_SLAVE_NUM, data, RW_TEST_LENGTH, 1000 / portTICK_RATE_MS);
|
|
printf("size %d\n",size);
|
|
// }
|
|
if (ret == ESP_ERR_TIMEOUT) {
|
|
printf("I2C timeout\n");
|
|
} else if (ret == ESP_OK) {
|
|
printf("*******************\n");
|
|
printf("TASK[%d] MASTER WRITE TO SLAVE\n", task_idx);
|
|
printf("*******************\n");
|
|
printf("----TASK[%d] Master write ----\n", task_idx);
|
|
disp_buf(data_wr, RW_TEST_LENGTH);
|
|
printf("----TASK[%d] Slave read: [%d] bytes ----\n", task_idx, size);
|
|
disp_buf(data, size);
|
|
} else {
|
|
printf("TASK[%d] %s: Master write slave error, IO not connected....\n", task_idx, esp_err_to_name(ret));
|
|
}
|
|
xSemaphoreGive(print_mux);
|
|
vTaskDelay(( DELAY_TIME_BETWEEN_ITEMS_MS * ( task_idx + 1 ) ) / portTICK_RATE_MS);
|
|
*/
|
|
}
|
|
}
|
|
|
|
|
|
void I2C::master_task(void* arg)
|
|
{
|
|
int i = 0;
|
|
int ret;
|
|
uint32_t task_idx = (uint32_t) arg;
|
|
uint8_t* data = (uint8_t*) malloc(DATA_LENGTH);
|
|
uint8_t* data_wr = (uint8_t*) malloc(DATA_LENGTH);
|
|
uint8_t* data_rd = (uint8_t*) malloc(DATA_LENGTH);
|
|
uint8_t sensor_data_h, sensor_data_l;
|
|
int cnt = 0;
|
|
while(true) {
|
|
printf("test cnt: %d\n", cnt++);
|
|
xSemaphoreTake(print_mux, portMAX_DELAY);
|
|
ret = master_read_slave(I2C_EXAMPLE_MASTER_NUM, data_rd, 9);
|
|
if (ret == ESP_ERR_TIMEOUT) {
|
|
printf("I2C timeout\n");
|
|
printf("*********\n");
|
|
} else if (ret == ESP_OK) {
|
|
printf("*******************\n");
|
|
printf("TASK[%d] MASTER READ FROM SLAVE\n", task_idx);
|
|
printf("*******************\n");
|
|
printf("====TASK[%d] Slave buffer data ====\n", task_idx);
|
|
//disp_buf(data, RW_TEST_LENGTH);
|
|
printf("====TASK[%d] Master read ====\n", task_idx);
|
|
disp_buf(data_rd, 9);
|
|
} else {
|
|
printf("%s: Master read slave error, IO not connected...\n", esp_err_to_name(ret));
|
|
}
|
|
xSemaphoreGive(print_mux);
|
|
vTaskDelay(( DELAY_TIME_BETWEEN_ITEMS_MS * ( task_idx + 1 ) ) / portTICK_RATE_MS);
|
|
//---------------------------------------------------
|
|
/*
|
|
int size;
|
|
for (i = 0; i < DATA_LENGTH; i++) {
|
|
data_wr[i] = i;
|
|
}
|
|
xSemaphoreTake(print_mux, portMAX_DELAY);
|
|
//we need to fill the slave buffer so that master can read later
|
|
ret = master_write_slave( I2C_EXAMPLE_MASTER_NUM, data_wr, RW_TEST_LENGTH);
|
|
|
|
xSemaphoreGive(print_mux);
|
|
vTaskDelay(( DELAY_TIME_BETWEEN_ITEMS_MS * ( task_idx + 1 ) ) / portTICK_RATE_MS);
|
|
*/
|
|
}
|
|
}
|
|
|
|
void I2C::test_start(){
|
|
print_mux = xSemaphoreCreateMutex();
|
|
slave_init();
|
|
master_init();
|
|
xTaskCreate(test_task, "i2c_test_task_0", 1024 * 2, (void* ) 0, 10, NULL);
|
|
xTaskCreate(test_task, "i2c_test_task_1", 1024 * 2, (void* ) 1, 10, NULL);
|
|
}
|
|
|
|
void I2C::master_start(){
|
|
print_mux = xSemaphoreCreateMutex();
|
|
master_init();
|
|
xTaskCreate(master_task, "master_task", 1024 * 2, (void* ) 0, 10, NULL);
|
|
}
|
|
void I2C::slave_start(){
|
|
print_mux = xSemaphoreCreateMutex();
|
|
slave_init();
|
|
xTaskCreate(slave_task, "slave_task", 1024 * 2, (void* ) 0, 10, NULL);
|
|
}
|