活动介绍

i2c err ret:4是啥意思

时间: 2025-08-10 15:10:23 浏览: 1
<think>嗯,用户现在问的是I2C错误代码ret:4的具体含义和可能的解决方案。首先,我需要确定这个错误代码的来源。不同的硬件厂商或驱动程序可能会有不同的错误代码定义,所以需要结合具体的上下文来分析。用户之前的问题可能涉及到PX4的GPS驱动,引用[1]提到了处理消息的函数,可能和I2C通信有关。比如,在解析数据时出现错误,导致返回ret>0的情况。这时候错误代码4可能对应某种特定的通信故障,比如ACK信号未收到。接下来,我需要回忆I2C协议的基本原理。I2C通信中常见的错误包括ACK缺失、总线忙、时钟拉伸、电压不匹配等。错误代码4可能对应其中一个情况。例如,ACK缺失通常发生在从设备没有正确响应主设备的地址或数据,这时候主设备会检测到SDA线保持高电平,从而触发错误。可能的解决方案需要分步骤考虑。首先检查硬件连接,确保SDA和SCL线接触良好,没有松动或短路。然后测量电压,确认主从设备的电平兼容。接着检查上拉电阻的阻值是否合适,通常4.7kΩ左右。如果硬件没问题,再检查软件配置,比如时钟频率是否过高,导致从设备无法响应。此外,查看设备的地址配置是否正确,是否有冲突。 还需要考虑总线上是否有其他设备干扰,比如多个从设备同时响应导致冲突。这时候可以逐一断开设备,排查问题。另外,电源噪声也可能影响通信稳定性,加入滤波电容可能有帮助。如果用户提供的代码中有相关的I2C初始化或通信部分,可能需要检查代码中的超时设置或错误处理逻辑,是否有重试机制。例如,引用[2]中的优化器和损失函数设置可能不直接相关,但错误处理机制可以参考,比如增加重试次数或调整时序。最后,建议用户查阅具体硬件或驱动文档,确认错误代码4的官方解释,这能更精准地定位问题。同时,提供日志分析的方法,帮助用户进一步诊断。</think>### I2C错误代码ret:4的含义与解决方案 #### 一、错误代码ret:4的常见含义 在嵌入式系统中,I2C错误代码`ret:4`通常表示**通信过程中未收到从设备的应答信号(ACK)**[^1]。具体可能原因包括: 1. **硬件连接问题**:SDA/SCL线路接触不良或未正确上拉。 2. **从设备地址错误**:主设备发送的从设备地址与实际地址不匹配。 3. **时序冲突**:总线时钟频率过高或信号畸变导致通信失败。 4. **电源问题**:从设备未正常供电或电压不稳定。 #### 二、分步解决方案 1. **硬件检查** - 使用万用表测量SDA/SCL线路的电压,确认电平符合规范(通常3.3V/5V)。 - 检查I2C总线上拉电阻值(推荐4.7kΩ-10kΩ),确保信号上升沿陡峭。 - 排查线路短路/断路问题,尤其是多设备共享总线时的干扰[^1]。 2. **软件调试** - 验证从设备地址是否正确(例如7位地址需左移1位后加读写位)。 - 降低I2C时钟频率(如从400kHz降至100kHz),观察是否恢复正常。 - 添加总线复位逻辑:在超时后发送`STOP`信号并重新初始化总线。 ```c // 示例:I2C通信重试机制 int retry = 0; while (retry < 3) { int ret = i2c_transfer(dev_addr, data); if (ret == 4) { i2c_reset(); // 硬件复位I2C控制器 delay_ms(10); retry++; } else break; } ``` 3. **设备端排查** - 单独测试从设备是否正常工作(如通过逻辑分析仪抓取波形)。 - 检查从设备供电是否稳定,必要时添加去耦电容(如100nF陶瓷电容)。 #### 三、进阶排查工具 1. **逻辑分析仪**:捕获I2C波形,确认ACK缺失发生的具体阶段(地址/数据阶段)。 2. **示波器**:检测总线上的噪声干扰或信号振铃现象。 3. **热插拔测试**:逐个断开从设备,定位故障设备。
阅读全文

相关推荐

E (1153) I2C_BUS: D:/ESP32/esp-adf/components/esp_peripherals/driver/i2c_bus/i2c_bus.c:115 (i2c_bus_write_bytes):I2C Bus WriteReg Error E (1165) I2C_BUS: D:/ESP32/esp-adf/components/esp_peripherals/driver/i2c_bus/i2c_bus.c:115 (i2c_bus_write_bytes):I2C Bus WriteReg Error E (1178) I2C_BUS: D:/ESP32/esp-adf/components/esp_peripherals/driver/i2c_bus/i2c_bus.c:115 (i2c_bus_write_bytes):I2C Bus WriteReg Error E (1191) I2C_BUS: D:/ESP32/esp-adf/components/esp_peripherals/driver/i2c_bus/i2c_bus.c:115 (i2c_bus_write_bytes):I2C Bus WriteReg Error E (1204) I2C_BUS: D:/ESP32/esp-adf/components/esp_peripherals/driver/i2c_bus/i2c_bus.c:115 (i2c_bus_write_bytes):I2C Bus WriteReg Error E (1217) I2C_BUS: D:/ESP32/esp-adf/components/esp_peripherals/driver/i2c_bus/i2c_bus.c:115 (i2c_bus_write_bytes):I2C Bus WriteReg Error E (1229) I2C_BUS: D:/ESP32/esp-adf/components/esp_peripherals/driver/i2c_bus/i2c_bus.c:115 (i2c_bus_write_bytes):I2C Bus WriteReg Error E (1236) tca9554: write_direction_reg(129): Write direction reg failed E (1241) I2C_BUS: D:/ESP32/esp-adf/components/esp_peripherals/driver/i2c_bus/i2c_bus.c:115 (i2c_bus_write_bytes):I2C Bus WriteReg Error E (1248) tca9554: reset(146): Write dir reg failed E (1261) I2C_BUS: D:/ESP32/esp-adf/components/esp_peripherals/driver/i2c_bus/i2c_bus.c:115 (i2c_bus_write_bytes):I2C Bus WriteReg Error E (1266) tca9554: esp_io_expander_new_i2c_tca9554(79): Reset failed E (1279) I2C_BUS: D:/ESP32/esp-adf/components/esp_peripherals/driver/i2c_bus/i2c_bus.c:115 (i2c_bus_write_bytes):I2C Bus WriteReg Error E (1286) tca9554: write_direction_reg(129): Write direction reg failed E (1299) I2C_BUS: D:/ESP32/esp-adf/components/esp_peripherals/driver/i2c_bus/i2c_bus.c:115 (i2c_bus_write_bytes):I2C Bus WriteReg Error E (1306) tca9554: reset(146): Write dir reg failed E (1319) I2C_BUS: D:/ESP32/esp-adf/components/esp_peripherals/driver/i2c_bus/i2c_bus.c:115 (i2c_bus_write_bytes):I2C Bus WriteReg Error E (1324) tca9554: esp_io_expander_new_i2c_tca9554(79): Reset failed ESP_ERROR_CHECK failed: esp_err_t 0xffffffff (ESP_FAIL) at 0x42012a32 --- 0x42012a32: lvgl_init at C:/Users/zengk/Desktop/esp_scan_5.4/main/uiinit.c:268 (discriminator 1) file: "./main/uiinit.c" line 268 func: lvgl_init expression: esp_io_expander_new_i2c_tca9554(TOUCH_HOST, ESP_IO_EXPANDER_I2C_TCA9554_ADDRESS_000, &io_expander) abort() was called at PC 0x4038747f on core 0 --- 0x4038747f: _esp_error_check_failed at D:/ESP32/esp_idf/v5.4/esp-idf/components/esp_system/esp_err.c:49 怎么解决

#include <stdio.h> #include <string.h> #include <math.h> #include "esp_log.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/event_groups.h" #include "freertos/semphr.h" #include "driver/rmt_tx.h" #include "led_ws2812.h" #include "driver/gpio.h" #include "driver/adc.h" #include "driver/i2c.h" #include "nvs_flash.h" #include "mqtt_client.h" #include "simple_wifi_sta.h" // 网络配置 #define MQTT_ADDRESS "114.55.64.216" // MQTT连接地址 #define MQTT_PORT 1863 // MQTT连接端口号 #define MQTT_CLIENT "soil_0001" // Client ID #define MQTT_USERNAME "devname" // MQTT用户名 #define MQTT_PASSWORD "devpwd" // MQTT密码 #define MQTT_PUBLIC_TOPIC "/gws/soil_0001" // 推送消息主题 #define MQTT_SUBSCRIBE_TOPIC "/gws/soil_0001" // 订阅主题 // 定义事件组,用于通知WIFI连接成功 #define WIFI_CONNECT_BIT BIT0 static EventGroupHandle_t s_wifi_ev = NULL; // MQTT客户端操作句柄 static esp_mqtt_client_handle_t s_mqtt_client = NULL; // MQTT连接标志 static bool s_is_mqtt_connected = false; // 灯带配置 #define WS2812_GPIO_NUM GPIO_NUM_45 #define WS2812_LED_NUM 6 TaskHandle_t RgbTaskHandle = NULL; // 添加RGB任务控制事件组 static EventGroupHandle_t rgb_event_group; #define RGB_RUN_BIT BIT0 // RGB任务运行标志位 // 雷达配置 #define LED_GPIO GPIO_NUM_16 #define LEIDA_GPIO GPIO_NUM_4 TaskHandle_t RadarTaskHandle = NULL; // ADC配置 #define ADC_GPIO GPIO_NUM_8 // IO8对应ADC1通道7 #define ADC_CHANNEL ADC1_CHANNEL_7 TaskHandle_t AdcTaskHandle = NULL; // I2C参数配置 #define I2C_MASTER_SCL_IO 2 // SCL引脚 #define I2C_MASTER_SDA_IO 1 // SDA引脚 #define I2C_MASTER_NUM I2C_NUM_0 // I2C控制器编号 #define I2C_MASTER_FREQ_HZ 100000 // I2C频率100kHz #define I2C_MASTER_TX_BUF_DISABLE 0 // 禁用发送缓冲区 #define I2C_MASTER_RX_BUF_DISABLE 0 // 禁用接收缓冲区 TaskHandle_t IicTaskHandle = NULL; // 传感器地址 #define BH1750_ADDR 0x23 // BH1750地址 #define SHT20_ADDR 0x40 // SHT20温湿度传感器地址 #define BMP280_ADDR 0x76 // BMP280 I2C地址 // BH1750寄存器定义 #define BH1750_POWER_DOWN 0x00 #define BH1750_POWER_ON 0x01 #define BH1750_RESET 0x07 #define BH1750_CONTINUOUS_HIGH_RES_MODE 0x10 // SHT20寄存器定义 #define SHT20_TRIGGER_TEMP_MEASUREMENT 0xF3 #define SHT20_TRIGGER_HUMIDITY_MEASUREMENT 0xF5 #define SHT20_SOFT_RESET 0xFE // BMP280相关定义 #define BMP280_REG_ID 0xD0 #define BMP280_REG_RESET 0xE0 #define BMP280_REG_STATUS 0xF3 #define BMP280_REG_CTRL_MEAS 0xF4 #define BMP280_REG_CONFIG 0xF5 #define BMP280_REG_PRESS_MSB 0xF7 #define BMP280_REG_TEMP_MSB 0xFA #define BMP280_REG_CALIB 0x88 // BMP280校准参数结构体 typedef struct { uint16_t dig_T1; int16_t dig_T2; int16_t dig_T3; uint16_t dig_P1; int16_t dig_P2; int16_t dig_P3; int16_t dig_P4; int16_t dig_P5; int16_t dig_P6; int16_t dig_P7; int16_t dig_P8; int16_t dig_P9; } bmp280_calib_t; // 传感器数据结构体(全局共享) typedef struct { float temp; // 温度(°C) float humi; // 湿度(%) float press; // 气压(Pa) float lux; // 光照(lx) float adc_voltage;// ADC电压(V) float adc_resist; // 土壤电阻(Ω) } sensor_data_t; // 全局传感器数据及互斥锁 static sensor_data_t g_sensor_data = { 0 }; static SemaphoreHandle_t g_sensor_mutex; static const char* TAG = "main"; static const char* TAG2 = "adc_radar"; static const char* TAG_ADC = "adc"; static const char* TAG_I2C = "I2C_Sensors"; /** * mqtt连接事件处理函数 */ static void aliot_mqtt_event_handler(void* event_handler_arg, esp_event_base_t event_base, int32_t event_id, void* event_data) { esp_mqtt_event_handle_t event = event_data; esp_mqtt_client_handle_t client = event->client; switch ((esp_mqtt_event_id_t)event_id) { case MQTT_EVENT_CONNECTED: // 连接成功 ESP_LOGI(TAG, "mqtt connected"); s_is_mqtt_connected = true; // 连接成功后订阅主题 esp_mqtt_client_subscribe_single(s_mqtt_client, MQTT_SUBSCRIBE_TOPIC, 1); break; case MQTT_EVENT_DISCONNECTED: // 连接断开 ESP_LOGI(TAG, "mqtt disconnected"); s_is_mqtt_connected = false; break; case MQTT_EVENT_SUBSCRIBED: // 收到订阅ACK ESP_LOGI(TAG, "mqtt subscribed ack, msg_id=%d", event->msg_id); break; case MQTT_EVENT_DATA: // 收到订阅消息 printf("TOPIC=%.*s\r\n", event->topic_len, event->topic); printf("DATA=%.*s\r\n", event->data_len, event->data); break; case MQTT_EVENT_ERROR: ESP_LOGI(TAG, "MQTT_EVENT_ERROR"); break; default: break; } } /** 启动mqtt连接 */ void mqtt_start(void) { esp_mqtt_client_config_t mqtt_cfg = { 0 }; mqtt_cfg.broker.address.transport = MQTT_TRANSPORT_OVER_TCP; mqtt_cfg.broker.address.hostname = MQTT_ADDRESS; mqtt_cfg.broker.address.port = MQTT_PORT; mqtt_cfg.credentials.client_id = MQTT_CLIENT; mqtt_cfg.credentials.username = MQTT_USERNAME; mqtt_cfg.credentials.authentication.password = MQTT_PASSWORD; ESP_LOGI(TAG, "mqtt connect->clientId:%s,username:%s", mqtt_cfg.credentials.client_id, mqtt_cfg.credentials.username); s_mqtt_client = esp_mqtt_client_init(&mqtt_cfg); esp_mqtt_client_register_event(s_mqtt_client, ESP_EVENT_ANY_ID, aliot_mqtt_event_handler, s_mqtt_client); esp_mqtt_client_start(s_mqtt_client); } /** wifi事件通知 */ void wifi_event_handler(WIFI_EV_e ev) { if (ev == WIFI_CONNECTED) { xEventGroupSetBits(s_wifi_ev, WIFI_CONNECT_BIT); } } /** I2C主控制器初始化 */ static esp_err_t i2c_master_init(void) { i2c_config_t conf = { .mode = I2C_MODE_MASTER, .sda_io_num = I2C_MASTER_SDA_IO, .scl_io_num = I2C_MASTER_SCL_IO, .sda_pullup_en = GPIO_PULLUP_ENABLE, .scl_pullup_en = GPIO_PULLUP_ENABLE, .master.clk_speed = I2C_MASTER_FREQ_HZ, }; ESP_ERROR_CHECK(i2c_param_config(I2C_MASTER_NUM, &conf)); return i2c_driver_install(I2C_MASTER_NUM, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0); } /** 初始化BH1750环境光传感器 */ bool bh1750_init(void) { ESP_LOGI(TAG_I2C, "Initializing BH1750..."); // 软复位 i2c_cmd_handle_t cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, (BH1750_ADDR << 1) | I2C_MASTER_WRITE, true); i2c_master_write_byte(cmd, BH1750_RESET, true); i2c_master_stop(cmd); esp_err_t ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, pdMS_TO_TICKS(100)); i2c_cmd_link_delete(cmd); if (ret != ESP_OK) { ESP_LOGE(TAG_I2C, "BH1750 reset failed: 0x%x", ret); return false; } vTaskDelay(pdMS_TO_TICKS(10)); // 启动连续高分辨率模式 cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, (BH1750_ADDR << 1) | I2C_MASTER_WRITE, true); i2c_master_write_byte(cmd, BH1750_CONTINUOUS_HIGH_RES_MODE, true); i2c_master_stop(cmd); ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, pdMS_TO_TICKS(100)); i2c_cmd_link_delete(cmd); if (ret != ESP_OK) { ESP_LOGE(TAG_I2C, "BH1750 mode set failed: 0x%x", ret); return false; } ESP_LOGI(TAG_I2C, "BH1750 initialized successfully"); return true; } /** 读取BH1750环境光强度 */ float bh1750_read_light(void) { uint8_t data[2] = { 0 }; i2c_cmd_handle_t cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, (BH1750_ADDR << 1) | I2C_MASTER_READ, true); i2c_master_read_byte(cmd, &data[0], I2C_MASTER_ACK); i2c_master_read_byte(cmd, &data[1], I2C_MASTER_NACK); i2c_master_stop(cmd); esp_err_t ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, pdMS_TO_TICKS(100)); i2c_cmd_link_delete(cmd); if (ret != ESP_OK) { ESP_LOGE(TAG_I2C, "BH1750 read failed: 0x%x", ret); return -1; } // 计算光照强度(lx) uint16_t light = (data[0] << 8) | data[1]; return light / 1.2; // 根据数据手册计算 } /** 初始化SHT20温湿度传感器 */ bool sht20_init(void) { ESP_LOGI(TAG_I2C, "Initializing SHT20..."); // 软复位 i2c_cmd_handle_t cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, (SHT20_ADDR << 1) | I2C_MASTER_WRITE, true); i2c_master_write_byte(cmd, SHT20_SOFT_RESET, true); i2c_master_stop(cmd); esp_err_t ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, pdMS_TO_TICKS(100)); i2c_cmd_link_delete(cmd); if (ret != ESP_OK) { ESP_LOGE(TAG_I2C, "SHT20 reset failed: 0x%x", ret); return false; } vTaskDelay(pdMS_TO_TICKS(15)); // 等待复位完成 ESP_LOGI(TAG_I2C, "SHT20 initialized successfully"); return true; } /** 读取SHT20测量值 */ static bool sht20_read_measurement(uint8_t command, float* value, bool is_temperature) { // 发送测量命令 i2c_cmd_handle_t cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, (SHT20_ADDR << 1) | I2C_MASTER_WRITE, true); i2c_master_write_byte(cmd, command, true); i2c_master_stop(cmd); esp_err_t ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, pdMS_TO_TICKS(100)); i2c_cmd_link_delete(cmd); if (ret != ESP_OK) { ESP_LOGE(TAG_I2C, "SHT20 measurement trigger failed: 0x%x", ret); return false; } // 等待测量完成(温度100ms,湿度40ms) vTaskDelay(pdMS_TO_TICKS(is_temperature ? 100 : 40)); // 读取测量结果(3字节:MSB, LSB, CRC) uint8_t data[3] = { 0 }; cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, (SHT20_ADDR << 1) | I2C_MASTER_READ, true); i2c_master_read_byte(cmd, &data[0], I2C_MASTER_ACK); i2c_master_read_byte(cmd, &data[1], I2C_MASTER_ACK); i2c_master_read_byte(cmd, &data[2], I2C_MASTER_NACK); i2c_master_stop(cmd); ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, pdMS_TO_TICKS(100)); i2c_cmd_link_delete(cmd); if (ret != ESP_OK) { ESP_LOGE(TAG_I2C, "SHT20 read failed: 0x%x", ret); return false; } // 提取原始值(清除状态位) uint16_t raw_value = (data[0] << 8) | data[1]; raw_value &= 0xFFFC; // 清除最后两位状态位 // 计算实际值 if (is_temperature) { *value = -46.85 + (175.72 * raw_value) / 65536.0; } else { *value = -6.0 + (125.0 * raw_value) / 65536.0; } return true; } /** 读取SHT20温度 */ float sht20_read_temperature(void) { float temperature = 0.0; if (!sht20_read_measurement(SHT20_TRIGGER_TEMP_MEASUREMENT, &temperature, true)) { ESP_LOGE(TAG_I2C, "Failed to read SHT20 temperature"); return -1; } return temperature; } /** 读取SHT20湿度 */ float sht20_read_humidity(void) { float humidity = 0.0; if (!sht20_read_measurement(SHT20_TRIGGER_HUMIDITY_MEASUREMENT, &humidity, false)) { ESP_LOGE(TAG_I2C, "Failed to read SHT20 humidity"); return -1; } return humidity; } /** 初始化BMP280气压传感器 */ bool bmp280_init(bmp280_calib_t* calib) { ESP_LOGI(TAG_I2C, "Initializing BMP280..."); // 重置设备 i2c_cmd_handle_t cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, (BMP280_ADDR << 1) | I2C_MASTER_WRITE, true); i2c_master_write_byte(cmd, BMP280_REG_RESET, true); i2c_master_write_byte(cmd, 0xB6, true); // 复位值 i2c_master_stop(cmd); esp_err_t ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, pdMS_TO_TICKS(100)); i2c_cmd_link_delete(cmd); if (ret != ESP_OK) { ESP_LOGE(TAG_I2C, "BMP280 reset failed: 0x%x", ret); return false; } vTaskDelay(pdMS_TO_TICKS(10)); // 等待复位完成 // 检查设备ID uint8_t id = 0; cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, (BMP280_ADDR << 1) | I2C_MASTER_WRITE, true); i2c_master_write_byte(cmd, BMP280_REG_ID, true); i2c_master_start(cmd); i2c_master_write_byte(cmd, (BMP280_ADDR << 1) | I2C_MASTER_READ, true); i2c_master_read_byte(cmd, &id, I2C_MASTER_NACK); i2c_master_stop(cmd); ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, pdMS_TO_TICKS(100)); i2c_cmd_link_delete(cmd); if (ret != ESP_OK || id != 0x58) { // BMP280 ID为0x58 ESP_LOGE(TAG_I2C, "BMP280 ID check failed: 0x%02X", id); return false; } // 读取校准参数 uint8_t calib_data[24] = { 0 }; cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, (BMP280_ADDR << 1) | I2C_MASTER_WRITE, true); i2c_master_write_byte(cmd, BMP280_REG_CALIB, true); i2c_master_start(cmd); i2c_master_write_byte(cmd, (BMP280_ADDR << 1) | I2C_MASTER_READ, true); i2c_master_read(cmd, calib_data, sizeof(calib_data), I2C_MASTER_LAST_NACK); i2c_master_stop(cmd); ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, pdMS_TO_TICKS(100)); i2c_cmd_link_delete(cmd); if (ret != ESP_OK) { ESP_LOGE(TAG_I2C, "BMP280 calibration read failed: 0x%x", ret); return false; } // 解析校准参数 calib->dig_T1 = (calib_data[1] << 8) | calib_data[0]; calib->dig_T2 = (calib_data[3] << 8) | calib_data[2]; calib->dig_T3 = (calib_data[5] << 8) | calib_data[4]; calib->dig_P1 = (calib_data[7] << 8) | calib_data[6]; calib->dig_P2 = (calib_data[9] << 8) | calib_data[8]; calib->dig_P3 = (calib_data[11] << 8) | calib_data[10]; calib->dig_P4 = (calib_data[13] << 8) | calib_data[12]; calib->dig_P5 = (calib_data[15] << 8) | calib_data[14]; calib->dig_P6 = (calib_data[17] << 8) | calib_data[16]; calib->dig_P7 = (calib_data[19] << 8) | calib_data[18]; calib->dig_P8 = (calib_data[21] << 8) | calib_data[20]; calib->dig_P9 = (calib_data[23] << 8) | calib_data[22]; // 配置传感器 (温度x2 + 气压x16,正常模式) cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, (BMP280_ADDR << 1) | I2C_MASTER_WRITE, true); i2c_master_write_byte(cmd, BMP280_REG_CTRL_MEAS, true); i2c_master_write_byte(cmd, 0b10110111, true); // 温度x2,气压x16,正常模式 i2c_master_stop(cmd); ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, pdMS_TO_TICKS(100)); i2c_cmd_link_delete(cmd); if (ret != ESP_OK) { ESP_LOGE(TAG_I2C, "BMP280 config failed: 0x%x", ret); return false; } ESP_LOGI(TAG_I2C, "BMP280 initialized successfully"); return true; } /** 读取BMP280温度和气压原始值 */ static bool bmp280_read_raw(int32_t* temp_raw, int32_t* press_raw) { uint8_t data[6] = { 0 }; i2c_cmd_handle_t cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, (BMP280_ADDR << 1) | I2C_MASTER_WRITE, true); i2c_master_write_byte(cmd, BMP280_REG_PRESS_MSB, true); i2c_master_start(cmd); i2c_master_write_byte(cmd, (BMP280_ADDR << 1) | I2C_MASTER_READ, true); i2c_master_read(cmd, data, sizeof(data), I2C_MASTER_LAST_NACK); i2c_master_stop(cmd); esp_err_t ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, pdMS_TO_TICKS(100)); i2c_cmd_link_delete(cmd); if (ret != ESP_OK) { ESP_LOGE(TAG_I2C, "BMP280 read raw failed: 0x%x", ret); return false; } *press_raw = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4); *temp_raw = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4); return true; } /** 计算实际温度和气压值 */ static void bmp280_compensate(const bmp280_calib_t* calib, int32_t adc_T, int32_t adc_P, float* temperature, float* pressure) { // 补偿温度 int32_t var1, var2, T; var1 = (((double)adc_T) / 16384.0 - ((double)calib->dig_T1) / 1024.0) * ((double)calib->dig_T2); var2 = (((double)adc_T) / 131072.0 - ((double)calib->dig_T1) / 8192.0) * (((double)adc_T) / 131072.0 - ((double)calib->dig_T1) / 8192.0) * ((double)calib->dig_T3); int32_t t_fine = (int32_t)(var1 + var2); T = (var1 + var2) / 5120.0; // 温度补偿值 *temperature = (float)T * 100; // 单位:°C // 补偿气压 int64_t p, var3, var4; var1 = ((double)t_fine / 2.0) - 64000.0; var2 = var1 * var1 * (double)calib->dig_P6 / 32768.0; var2 = var2 + ((var1 * (double)calib->dig_P5) * 2.0); var2 = (var2 / 4.0) + (((double)calib->dig_P4) * 65536.0); var1 = (((double)calib->dig_P3) * var1 * var1 / 524288.0 + ((double)calib->dig_P2) * var1) / 524288.0; var1 = (1.0 + var1 / 32768.0) * ((double)calib->dig_P1); p = 1048576 - (double)adc_P; p = (p - (var2 / 4096.0)) * 6250.0 / var1; var1 = ((double)calib->dig_P9) * p * p / 2147483648.0; var2 = p * ((double)calib->dig_P8) / 32768.0; p = p + (var1 + var2 + ((double)calib->dig_P7)) / 16.0; *pressure = (float)p; // 单位:Pa } /** 读取BMP280温度和气压 */ bool bmp280_read(const bmp280_calib_t* calib, float* temperature, float* pressure) { int32_t temp_raw, press_raw; if (!bmp280_read_raw(&temp_raw, &press_raw)) { return false; } bmp280_compensate(calib, temp_raw, press_raw, temperature, pressure); *temperature /= 100.0; // 转换为°C return true; } /** I2C传感器任务(处理BH1750、SHT20和BMP280) */ void task_i2c_sensors(void* pvParameters) { // 初始化I2C ESP_ERROR_CHECK(i2c_master_init()); // 初始化传感器 bool bh1750_initialized = bh1750_init(); bool sht20_initialized = sht20_init(); bmp280_calib_t bmp280_calib; bool bmp280_initialized = bmp280_init(&bmp280_calib); vTaskDelay(pdMS_TO_TICKS(150)); // 等待传感器初始化完成 while (1) { // 读取传感器数据 float temp = -1, humi = -1, press = -1, lux = -1; float bmp_temp = -1; if (sht20_initialized) { temp = sht20_read_temperature(); humi = sht20_read_humidity(); } if (bmp280_initialized) { if (bmp280_read(&bmp280_calib, &bmp_temp, &press) && temp < 0) { temp = bmp_temp; // 若SHT20温度读取失败,使用BMP280温度 } } if (bh1750_initialized) { lux = bh1750_read_light(); } // 打印传感器数据 ESP_LOGI(TAG_I2C, "Temp: %.2f°C, Humi: %.2f%%, Press: %.2fPa, Lux: %.2flx, bmp280_temp: %.2f°C", temp, humi, press, lux, bmp_temp); // 更新全局传感器数据(加锁保护) if (xSemaphoreTake(g_sensor_mutex, pdMS_TO_TICKS(100)) == pdTRUE) { g_sensor_data.temp = temp; g_sensor_data.humi = humi; g_sensor_data.press = press; g_sensor_data.lux = lux; xSemaphoreGive(g_sensor_mutex); } // 读取间隔 vTaskDelay(pdMS_TO_TICKS(1500)); } } /** 全局亮度控制变量 */ float global_brightness = 0.2f; // 默认亮度为50% /** * 设置全局亮度 * @param brightness 亮度值 (0.0-1.0) */ void set_global_brightness(float brightness) { // 限制亮度范围 if (brightness < 0.0f) brightness = 0.0f; if (brightness > 1.0f) brightness = 1.0f; global_brightness = brightness; ESP_LOGI(TAG, "Brightness set to: %.2f", global_brightness); } /** * HSV转RGB颜色空间并调整亮度 * @param h 色相 (0.0-360.0) * @param s 饱和度 (0.0-1.0) * @param v 明度 (0.0-1.0) * @param brightness 亮度调整因子 (0.0-1.0) * @param r 输出红色值 (0-255) * @param g 输出绿色值 (0-255) * @param b 输出蓝色值 (0-255) */ void hsv_to_rgb(float h, float s, float v, float brightness, uint8_t *r, uint8_t *g, uint8_t *b) { int i; float f, p, q, t; // 应用亮度调整(使用非线性曲线增强暗部细节) v *= brightness * brightness; // 平方曲线使暗部更细腻 if (s == 0) { // 无饱和度(灰色) *r = *g = *b = (uint8_t)(v * 255); return; } h /= 60.0f; // 转换为0-6范围 i = (int)floor(h) % 6; f = h - floor(h); // 小数部分 p = v * (1 - s); q = v * (1 - s * f); t = v * (1 - s * (1 - f)); // 使用更精确的浮点数计算和舍入 switch (i) { case 0: *r = (uint8_t)(v*255.0f + 0.5f); *g = (uint8_t)(t*255.0f + 0.5f); *b = (uint8_t)(p*255.0f + 0.5f); break; case 1: *r = (uint8_t)(q*255.0f + 0.5f); *g = (uint8_t)(v*255.0f + 0.5f); *b = (uint8_t)(p*255.0f + 0.5f); break; case 2: *r = (uint8_t)(p*255.0f + 0.5f); *g = (uint8_t)(v*255.0f + 0.5f); *b = (uint8_t)(t*255.0f + 0.5f); break; case 3: *r = (uint8_t)(p*255.0f + 0.5f); *g = (uint8_t)(q*255.0f + 0.5f); *b = (uint8_t)(v*255.0f + 0.5f); break; case 4: *r = (uint8_t)(t*255.0f + 0.5f); *g = (uint8_t)(p*255.0f + 0.5f); *b = (uint8_t)(v*255.0f + 0.5f); break; default: *r = (uint8_t)(v*255.0f + 0.5f); *g = (uint8_t)(p*255.0f + 0.5f); *b = (uint8_t)(q*255.0f + 0.5f); break; } } /** RGB任务(平滑波浪彩虹效果) */ void task_rgb(void* pvParameters) { gpio_reset_pin(WS2812_GPIO_NUM); ws2812_strip_handle_t ws2812_handle = NULL; ws2812_init(WS2812_GPIO_NUM, WS2812_LED_NUM, &ws2812_handle); // 初始化熄灭所有LED for (int index = 0; index < WS2812_LED_NUM; index++) { ws2812_write(ws2812_handle, index, 0, 0, 0); } // 色相偏移量(控制彩虹波浪移动) - 使用浮点数提高精度 float hue_offset = 0.0f; // 波浪速度控制(数值越小速度越快) const float wave_speed = 0.5f; // 每个LED的色相间隔(减小步长使颜色过渡更平滑) const float hue_step = 8.0f; // 帧率控制(减少延迟提高帧率) const TickType_t frame_delay = pdMS_TO_TICKS(30); ESP_LOGI(TAG, "RGB task initialized with smooth rainbow wave effect"); while (1) { // 等待RGB运行标志 xEventGroupWaitBits(rgb_event_group, RGB_RUN_BIT, pdFALSE, // 不自动清除位 pdTRUE, // 等待位被设置 portMAX_DELAY); ESP_LOGI(TAG, "Smooth rainbow wave effect started"); // 持续运行彩虹效果,直到标志位被清除 while ((xEventGroupGetBits(rgb_event_group) & RGB_RUN_BIT) != 0) { // 为每个LED设置颜色 for (int index = 0; index < WS2812_LED_NUM; index++) { // 使用浮点数计算色相,避免整数截断 float hue = fmodf(hue_offset + index * hue_step, 360.0f); uint8_t r, g, b; // 转换HSV到RGB,使用全局亮度控制 hsv_to_rgb(hue, 1.0f, 0.9f, global_brightness, &r, &g, &b); // 设置LED颜色 ws2812_write(ws2812_handle, index, r, g, b); } // 更新色相偏移(使用浮点数提高精度) hue_offset = fmodf(hue_offset + wave_speed, 360.0f); // 减少延迟,提高帧率,使动画更流畅 vTaskDelay(frame_delay); } // 标志位被清除,熄灭所有LED for (int index = 0; index < WS2812_LED_NUM; index++) { ws2812_write(ws2812_handle, index, 0, 0, 0); } ESP_LOGI(TAG, "Smooth rainbow wave effect stopped"); } } /** 雷达任务 */ void task_radar(void* pvParameters) { gpio_reset_pin(LED_GPIO); gpio_reset_pin(LEIDA_GPIO); gpio_set_direction(LED_GPIO, GPIO_MODE_OUTPUT); gpio_set_level(LED_GPIO, 1); // 初始熄灭 gpio_config_t radar_cfg = { .pin_bit_mask = (1ULL << LEIDA_GPIO), .mode = GPIO_MODE_INPUT, .pull_up_en = GPIO_PULLUP_DISABLE, .pull_down_en = GPIO_PULLDOWN_DISABLE, .intr_type = GPIO_INTR_DISABLE }; gpio_config(&radar_cfg); ESP_LOGI(TAG2, "Radar task started"); static TickType_t rgb_start_tick = 0; const TickType_t rgb_duration = pdMS_TO_TICKS(50000); // 50秒 while (1) { bool detected = gpio_get_level(LEIDA_GPIO); gpio_set_level(LED_GPIO, !detected); // 检测到物体时点亮LED if (detected) { // 设置RGB运行标志 if ((xEventGroupGetBits(rgb_event_group) & RGB_RUN_BIT) == 0) { xEventGroupSetBits(rgb_event_group, RGB_RUN_BIT); ESP_LOGI(TAG2, "RGB activated by radar"); } rgb_start_tick = xTaskGetTickCount(); // 更新启动时间 } // 超时检查:50秒无检测则关闭RGB if ((xEventGroupGetBits(rgb_event_group) & RGB_RUN_BIT) && (xTaskGetTickCount() - rgb_start_tick > rgb_duration)) { xEventGroupClearBits(rgb_event_group, RGB_RUN_BIT); ESP_LOGI(TAG2, "RGB deactivated by timeout"); } vTaskDelay(pdMS_TO_TICKS(10)); } } /** ADC任务(土壤传感器) */ void task_adc(void* pvParameters) { // 配置ADC adc1_config_width(ADC_WIDTH_BIT_12); adc1_config_channel_atten(ADC_CHANNEL, ADC_ATTEN_DB_11); const float vref = 3.3f; // 参考电压 const float adc_max = 4095.0f; // 12位ADC最大值 while (1) { int adc_value = adc1_get_raw(ADC_CHANNEL); float voltage = adc_value * vref / adc_max; float I_value = voltage / 1000.0f; // 电流计算 float V_value = 3.3f - voltage; // 土壤两侧电压 float R_value = (I_value > 0) ? (V_value / I_value) : -1; // 电阻计算 ESP_LOGI(TAG_ADC, "ADC: %d, Voltage: %.2fV, Resist: %.2fΩ", adc_value, voltage, R_value); // 更新全局ADC数据 if (xSemaphoreTake(g_sensor_mutex, pdMS_TO_TICKS(100)) == pdTRUE) { g_sensor_data.adc_voltage = voltage; g_sensor_data.adc_resist = R_value; xSemaphoreGive(g_sensor_mutex); } vTaskDelay(pdMS_TO_TICKS(1500)); } } /** MQTT发送任务 */ static void task_wifi_mqtt(void* pvParameters) { // 初始化NVS esp_err_t ret = nvs_flash_init(); if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { ESP_ERROR_CHECK(nvs_flash_erase()); ESP_ERROR_CHECK(nvs_flash_init()); } s_wifi_ev = xEventGroupCreate(); EventBits_t ev = 0; // 初始化WIFI wifi_sta_init(wifi_event_handler); // 等待WIFI连接成功 ev = xEventGroupWaitBits(s_wifi_ev, WIFI_CONNECT_BIT, pdTRUE, pdFALSE, portMAX_DELAY); if (ev & WIFI_CONNECT_BIT) { mqtt_start(); } static char mqtt_json[512]; sensor_data_t temp_data; // 临时存储数据 while (1) { // 每5秒发送一次数据 if (s_is_mqtt_connected) { // 读取全局传感器数据(加锁保护) if (xSemaphoreTake(g_sensor_mutex, pdMS_TO_TICKS(100)) == pdTRUE) { temp_data = g_sensor_data; xSemaphoreGive(g_sensor_mutex); } // 构建JSON格式数据 snprintf(mqtt_json, sizeof(mqtt_json), "{\"opt\":\"dev_sta\",\"val\":{" "\"temp\":%.2f," "\"humi\":%.2f," "\"press\":%.2f," "\"light\":%.2f," "\"adc_voltage\":%.2f," "\"adc_resist\":%.2f" "}}", temp_data.temp, temp_data.humi, temp_data.press, temp_data.lux, temp_data.adc_voltage, temp_data.adc_resist); // 发送MQTT消息 int msg_id = esp_mqtt_client_publish(s_mqtt_client, MQTT_PUBLIC_TOPIC, mqtt_json, strlen(mqtt_json), 1, // QoS=1 0); // 不保留 ESP_LOGI(TAG, "MQTT published: %s (msg_id=%d)", mqtt_json, msg_id); } vTaskDelay(pdMS_TO_TICKS(3000)); // 2.5秒发送一次 } } void app_main(void) { // 初始化互斥锁保护传感器数据 g_sensor_mutex = xSemaphoreCreateMutex(); configASSERT(g_sensor_mutex); // 初始化RGB控制事件组 rgb_event_group = xEventGroupCreate(); // 启动各任务 xTaskCreate(task_adc, "adc_task", 4096, NULL, 8, &AdcTaskHandle); xTaskCreate(task_i2c_sensors, "i2c_sensors_task", 8192, NULL, 10, &IicTaskHandle); xTaskCreate(task_rgb, "rgb_task", 4096, NULL, 9, &RgbTaskHandle); xTaskCreate(task_radar, "radar_task", 4096, NULL, 9, &RadarTaskHandle); // 启动WIFI和MQTT任务 xTaskCreate(task_wifi_mqtt, "wifi_mqtt_task", 8192, NULL, 10, NULL); }在此基础上增加蓝牙配网功能

C:/TPC/IOT/LVGL_test/LVGLtest_inv_iic/ESP32_Project/main/lvgl_init.c: In function 'lvgl_init': C:/TPC/IOT/LVGL_test/LVGLtest_inv_iic/ESP32_Project/main/lvgl_init.c:285:62: error: 'bus_rtc_handle' undeclared (first use in this function); did you mean 'dev_rtc_handle'? 285 | ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_mst_rtc_config, &bus_rtc_handle)); | ^~~~~~~~~~~~~~ C:/Espressif/frameworks/esp-idf-v5.4/components/esp_common/include/esp_err.h:116:30: note: in definition of macro 'ESP_ERROR_CHECK' 116 | esp_err_t err_rc_ = (x); \ | ^ C:/TPC/IOT/LVGL_test/LVGLtest_inv_iic/ESP32_Project/main/lvgl_init.c:285:62: note: each undeclared identifier is reported only once for each function it appears in 285 | ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_mst_rtc_config, &bus_rtc_handle)); | ^~~~~~~~~~~~~~ C:/Espressif/frameworks/esp-idf-v5.4/components/esp_common/include/esp_err.h:116:30: note: in definition of macro 'ESP_ERROR_CHECK' 116 | esp_err_t err_rc_ = (x); \ | ^ C:/TPC/IOT/LVGL_test/LVGLtest_inv_iic/ESP32_Project/main/lvgl_init.c:296:77: error: passing argument 3 of 'i2c_master_bus_add_device' from incompatible pointer type [-Wincompatible-pointer-types] 296 | ESP_ERROR_CHECK(i2c_master_bus_add_device(bus_rtc_handle, &dev_rtc_cfg, &dev_rtc_handle)); | ^~~~~~~~~~~~~~~ | | | struct i2c_master_bus_t ** C:/Espressif/frameworks/esp-idf-v5.4/components/esp_common/include/esp_err.h:116:30: note: in definition of macro 'ESP_ERROR_CHECK' 116 | esp_err_t err_rc_ = (x); \ | ^ In file included from C:/TPC/IOT/LVGL_test/LVGLtest_inv_iic/ESP32_Project/main/lvgl_init.c:13: C:/Espressif/frameworks/esp-idf-v5.4/components/esp_driver_i2c/include/driver/i2c_master.h:97:137: note: expected 'struct i2c_master_dev_t **' but argument is of type 'struct i2c_master_bus_t **' 97 | esp_err_t i2c_master_bus_add_device(i2c_master_bus_handle_t bus_handle, const i2c_device_config_t *dev_config, i2c_master_dev_handle_t *ret_handle); | ~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~ C:/TPC/IOT/LVGL_test/LVGLtest_inv_iic/ESP32_Project/main/lvgl_init.c:299:24: error: passing argument 1 of 'i2c_master_receive' from incompatible pointer type [-Wincompatible-pointer-types] 299 | i2c_master_receive(dev_rtc_handle, data_rd, 1, -1); | ^~~~~~~~~~~~~~ | | | i2c_master_bus_handle_t {aka struct i2c_master_bus_t *} C:/Espressif/frameworks/esp-idf-v5.4/components/esp_driver_i2c/include/driver/i2c_master.h:193:54: note: expected 'i2c_master_dev_handle_t' {aka 'struct i2c_master_dev_t *'} but argument is of type 'i2c_master_bus_handle_t' {aka 'struct i2c_master_bus_t *'} 193 | esp_err_t i2c_master_receive(i2c_master_dev_handle_t i2c_dev, uint8_t *read_buffer, size_t read_size, int xfer_timeout_ms); | ~~~~~~~~~~~~~~~~~~~~~~~~^

/* * sp0821.c sp0821 yuv module * * Author: Bruce <[email protected]> * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "sp_sp0821_yuv.h" #include "../../../aw37004/aw37004.h" #include <soc/oplus/system/oplus_project.h> #include #include #include #include extern void ISP_MCLK3_EN (bool En); extern int aw37004_camera_power_up(int out_iotype, unsigned int out_val); #define kal_uint16 unsigned short #define kal_uint32 unsigned int /***************************************************************** * sp0821 marco ******************************************************************/ #define SP0821_DRIVER_VERSION "V2.0" #define SP0821_PRODUCT_NUM 4 #define SP0821_PRODUCT_NAME_LEN 8 #define SP0821_SENSOR_ID 0x3a6c #define SP0821_MCLK_ON "sp0821_mclk_on" #define SP0821_MCLK_OFF "sp0821_mclk_off" /***************************************************************** * sp0821 global global variable ******************************************************************/ static unsigned char read_reg_id = 0; static unsigned char read_reg_value = 0; static int read_reg_flag = 0; static int driver_flag = 0; struct sp0821 *g_sp0821 = NULL; /********************************************************** * i2c write and read **********************************************************/ static void sp0821_i2c_write(struct sp0821 *sp0821, int address, int data) { u8 i2c_buf[8]; struct i2c_client *client = sp0821->i2c_client; struct i2c_msg msg[1]; msg[0].flags = !I2C_M_RD; msg[0].addr = client->addr; msg[0].len = 3; msg[0].buf = i2c_buf; i2c_buf[0] = (address & 0xff00)>>8; i2c_buf[1] = (address & 0xff); i2c_buf[2] = data; i2c_transfer(client->adapter, msg, 1); //printk("write sp0821 addr: 0x%4X val:0x%4X\n", address, data); } static unsigned char sp0821_i2c_read(struct sp0821 *sp0821, int address) { unsigned char rxdata = 0x00; unsigned char i2c_buf[4]; int ret = 0; int retry = 2; u8 i2c_addr[2]; struct i2c_client *client = sp0821->i2c_client; struct i2c_msg msgs[2]; i2c_addr[0] = (address & 0xff00)>>8; i2c_addr[1] = (address & 0xff); msgs[0].flags = 0; msgs[0].addr = (client->addr); msgs[0].len = 2; msgs[0].buf = i2c_addr; msgs[1].flags = I2C_M_RD; msgs[1].addr = (client->addr); msgs[1].len = 1; msgs[1].buf = i2c_buf; while (retry > 0) { ret = i2c_transfer(client->adapter, msgs, 2); //qvga_dev_err(&client->dev, "%s: read step1 ret:%d msgs[1].addr=%x\n", __func__, ret, msgs[1].addr); if (retry >0) { mdelay(20); if (ret == 0) { return 0; } } retry--; mdelay(2); } rxdata = i2c_buf[0]; return rxdata; } static struct sp0821 *sp0821_malloc_init(struct i2c_client *client) { struct sp0821 *sp0821 = devm_kzalloc(&client->dev, sizeof(struct sp0821), GFP_KERNEL); if (sp0821 == NULL) { qvga_dev_err(&client->dev, "%s: devm_kzalloc failed.\n", __func__); return NULL; } sp0821->i2c_client = client; pr_info("%s enter , client_addr = 0x%02x\n", __func__, sp0821->i2c_client->addr); return sp0821; } #if 1 void sp0821_Init(struct sp0821 *sp0821) { /*SYS MCLK=24MHZ*/ sp0821_i2c_write(sp0821, 0x0103,0x01); sp0821_i2c_write(sp0821, 0x0100,0x00); sp0821_i2c_write(sp0821, 0x309b,0xf0); sp0821_i2c_write(sp0821, 0x30b0,0x0a); sp0821_i2c_write(sp0821, 0x30b8,0x21); sp0821_i2c_write(sp0821, 0x320c,0x01); sp0821_i2c_write(sp0821, 0x320d,0x6a); sp0821_i2c_write(sp0821, 0x320e,0x01); sp0821_i2c_write(sp0821, 0x320f,0xba); sp0821_i2c_write(sp0821, 0x3301,0x04); sp0821_i2c_write(sp0821, 0x3304,0x0c); sp0821_i2c_write(sp0821, 0x3305,0x00); sp0821_i2c_write(sp0821, 0x3306,0x10); sp0821_i2c_write(sp0821, 0x3307,0x02); sp0821_i2c_write(sp0821, 0x3308,0x04); sp0821_i2c_write(sp0821, 0x330a,0x00); sp0821_i2c_write(sp0821, 0x330b,0x30); sp0821_i2c_write(sp0821, 0x330e,0x01); sp0821_i2c_write(sp0821, 0x330f,0x01); sp0821_i2c_write(sp0821, 0x3310,0x01); sp0821_i2c_write(sp0821, 0x331e,0x09); sp0821_i2c_write(sp0821, 0x3333,0x10); sp0821_i2c_write(sp0821, 0x3334,0x40); sp0821_i2c_write(sp0821, 0x334c,0x01); sp0821_i2c_write(sp0821, 0x33b3,0x3e); sp0821_i2c_write(sp0821, 0x349f,0x02); sp0821_i2c_write(sp0821, 0x34a6,0x01); sp0821_i2c_write(sp0821, 0x34a7,0x07); sp0821_i2c_write(sp0821, 0x34a8,0x3a); sp0821_i2c_write(sp0821, 0x34a9,0x38); sp0821_i2c_write(sp0821, 0x34e9,0x38); sp0821_i2c_write(sp0821, 0x34f8,0x07); sp0821_i2c_write(sp0821, 0x3630,0x65); sp0821_i2c_write(sp0821, 0x3637,0x47); sp0821_i2c_write(sp0821, 0x363a,0xe0); sp0821_i2c_write(sp0821, 0x3670,0x03); sp0821_i2c_write(sp0821, 0x3674,0x75); sp0821_i2c_write(sp0821, 0x3675,0x65); sp0821_i2c_write(sp0821, 0x3676,0x65); sp0821_i2c_write(sp0821, 0x367c,0x01); sp0821_i2c_write(sp0821, 0x367d,0x03); sp0821_i2c_write(sp0821, 0x3690,0xe0); sp0821_i2c_write(sp0821, 0x3691,0xe1); sp0821_i2c_write(sp0821, 0x3692,0xe1); sp0821_i2c_write(sp0821, 0x3693,0xe1); sp0821_i2c_write(sp0821, 0x3694,0x03); sp0821_i2c_write(sp0821, 0x3695,0x07); sp0821_i2c_write(sp0821, 0x3696,0x07); sp0821_i2c_write(sp0821, 0x37f9,0x29); sp0821_i2c_write(sp0821, 0x3900,0x91); sp0821_i2c_write(sp0821, 0x3904,0x0f); sp0821_i2c_write(sp0821, 0x3908,0x00); sp0821_i2c_write(sp0821, 0x391b,0x07); sp0821_i2c_write(sp0821, 0x391c,0x0a); sp0821_i2c_write(sp0821, 0x391d,0x15); sp0821_i2c_write(sp0821, 0x391e,0x28); sp0821_i2c_write(sp0821, 0x391f,0x41); sp0821_i2c_write(sp0821, 0x3948,0x00);//blc sp0821_i2c_write(sp0821, 0x4509,0x10); sp0821_i2c_write(sp0821, 0x470b,0x0a); sp0821_i2c_write(sp0821, 0x470d,0x06); sp0821_i2c_write(sp0821, 0x5000,0xc2); sp0821_i2c_write(sp0821, 0x5001,0x01); sp0821_i2c_write(sp0821, 0x5170,0x2c); sp0821_i2c_write(sp0821, 0x5172,0xc1); sp0821_i2c_write(sp0821, 0x518b,0x00);//again sp0821_i2c_write(sp0821, 0x518c,0x20); sp0821_i2c_write(sp0821, 0x518d,0x01);//shutter sp0821_i2c_write(sp0821, 0x518e,0x7c); sp0821_i2c_write(sp0821, 0x518f,0x00); sp0821_i2c_write(sp0821, 0x519e,0x10); sp0821_i2c_write(sp0821, 0x300a,0x00);//SIP input sp0821_i2c_write(sp0821, 0x0100,0x01); /*shutter gain must write after stream on */ sp0821_i2c_write(sp0821, 0x518b,0x03);//again=4x sp0821_i2c_write(sp0821, 0x518c,0x20); sp0821_i2c_write(sp0821, 0x518d,0x01);//shutter=20ms sp0821_i2c_write(sp0821, 0x518e,0xb0); sp0821_i2c_write(sp0821, 0x518f,0x00); sp0821_i2c_write(sp0821, 0x519e,0x10); } /* sensor_init */ #endif int sp0821_GetSensorID(struct sp0821 *sp0821) { int retry = 2; unsigned char reg_data = 0x00; //check if sensor ID correct do { reg_data = sp0821_i2c_read(sp0821, 0x3107)<<8|sp0821_i2c_read(sp0821, 0x3108); qvga_dev_err(sp0821->dev, "drv-%s: Read MSB Sensor ID = 0x%02x\n", __func__, reg_data); // if (reg_data == SP0821_SENSOR_ID) { if (1) { qvga_dev_err(sp0821->dev, "drv-%s: Read Sensor ID sucess = 0x%02x\n", __func__, reg_data); driver_flag = 1; return 0; } else { qvga_dev_err(sp0821->dev, "rv-%s: Read Sensor ID Fail = 0x%02x\n", __func__, reg_data); driver_flag = 0; } mdelay(10); retry--; } while (retry > 0); return -1; } static void sp0821_vcam_control(struct sp0821 *sp0821, bool flag) { // struct regulator *vcama; struct regulator *vcamio; struct regulator *vcamd; int ret; int ret1; qvga_dev_info(sp0821->dev, "%s enter\n", __func__); vcamd = regulator_get(sp0821->dev,"vcamd"); if (IS_ERR(vcamd)) { qvga_dev_err(sp0821->dev, "%s get regulator vcamd failed\n", __func__); regulator_put(vcamd); return; } else { qvga_dev_err(sp0821->dev, "%s get regulator vcamd success\n", __func__); } if (flag) { regulator_set_voltage(vcamd, 1200000, 1200000); ret = regulator_enable(vcamd); } else { regulator_disable(vcamd); } // vcama = regulator_get(sp0821->dev,"vcama"); // if (IS_ERR(vcama)) { // qvga_dev_err(sp0821->dev, "%s get regulator vcama failed\n", __func__); // regulator_put(vcama); // return; // } // if (flag) { // regulator_set_voltage(vcama, 2800000, 2800000); // ret = regulator_enable(vcama); // } else { // regulator_disable(vcama); // } if (flag) { ret1 = aw37004_camera_power_up(2, 2800); if (ret1 == 0) { qvga_dev_err(sp0821->dev, "%s get regulator vcama success\n", __func__); } else { qvga_dev_err(sp0821->dev, "%s get regulator vcama failed\n", __func__); } } vcamio = regulator_get(sp0821->dev,"vcamio"); if (IS_ERR(vcamio)) { qvga_dev_err(sp0821->dev, "%s get regulator vcamio failed\n", __func__); regulator_put(vcamio); return; } else { qvga_dev_err(sp0821->dev, "%s get regulator vcamio success\n", __func__); } if (flag) { regulator_set_voltage(vcamio, 1800000, 1800000); ret = regulator_enable(vcamio); } else { regulator_disable(vcamio); } return; } static void sp0821_hw_on_reset(struct sp0821 *sp0821) { qvga_dev_info(sp0821->dev, "%s enter\n", __func__); if (gpio_is_valid(sp0821->reset_gpio)) { gpio_set_value_cansleep(sp0821->reset_gpio, 1); } } static void sp0821_hw_on_reset1(struct sp0821 *sp0821) { qvga_dev_info(sp0821->dev, "%s enter\n", __func__); if (gpio_is_valid(sp0821->reset_gpio1)) { gpio_set_value_cansleep(sp0821->reset_gpio1, 1); } } static void sp0821_hw_off_reset(struct sp0821 *sp0821) { qvga_dev_info(sp0821->dev, "%s enter\n", __func__); if (gpio_is_valid(sp0821->reset_gpio)) { gpio_set_value_cansleep(sp0821->reset_gpio, 0); udelay(50); gpio_set_value_cansleep(sp0821->reset_gpio, 1); udelay(50); gpio_set_value_cansleep(sp0821->reset_gpio, 0); } } static void sp0821_hw_off_reset1(struct sp0821 *sp0821) { qvga_dev_info(sp0821->dev, "%s enter\n", __func__); if (gpio_is_valid(sp0821->reset_gpio1)) { gpio_set_value_cansleep(sp0821->reset_gpio1, 0); } } static void sp0821_hw_on(struct sp0821 *sp0821) { sp0821_hw_on_reset1(sp0821); sp0821_hw_on_reset(sp0821); sp0821_Init(sp0821); sp0821->hwen_flag = 1; } static void sp0821_hw_off(struct sp0821 *sp0821) { sp0821_hw_off_reset(sp0821); sp0821->hwen_flag = 0; } static ssize_t sp0821_get_reg(struct device *dev, struct device_attribute *attr, char *buf) { ssize_t len = 0; if (read_reg_flag) { len += snprintf(buf + len, PAGE_SIZE - len, "The reg 0x%02X value is 0x%02X\n", read_reg_id, read_reg_value); read_reg_flag = 0; read_reg_id = 0; read_reg_value = 0; } else { len += snprintf(buf + len, PAGE_SIZE - len, "Please echo reg id into reg\n"); } return len; } static ssize_t sp0821_set_reg(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { unsigned int databuf[2] = { 0 }; unsigned char reg_data = 0x00; if (sscanf(buf, "%x %x", &databuf[0], &databuf[1]) == 2) { sp0821_i2c_write(g_sp0821, databuf[0], databuf[1]); } else if (sscanf(buf, "%x %x", &databuf[0], &databuf[1]) == 1) { reg_data = sp0821_i2c_read(g_sp0821, databuf[0]); read_reg_id = databuf[0]; read_reg_value = reg_data; read_reg_flag = 1; } return len; } static ssize_t sp0821_get_name(struct device *dev, struct device_attribute *attr, char *buf) { ssize_t len = 0; if (driver_flag) { len += snprintf(buf + len, PAGE_SIZE - len, "%s\n", "sp_sp0821_yuv"); } else { len += snprintf(buf + len, PAGE_SIZE - len, "%s\n", "none"); } return len; } static ssize_t sp0821_get_light(struct device *dev, struct device_attribute *attr, char *buf) { ssize_t len = 0; unsigned char reg_data1 = 0x00; //unsigned char reg_data2 = 0x00; u16 light = 0; reg_data1 = sp0821_i2c_read(g_sp0821, 0x5160); //reg_data2 = sp0821_i2c_read(g_sp0821, 0x516b); //light = (reg_data1<<8) + reg_data2; light = reg_data1; qvga_dev_err(g_sp0821->dev, "%s: sp0821 light=%d, %d\n", __func__, light, reg_data1); len += snprintf(buf + len, PAGE_SIZE - len, "%d\n", light); return len; } static ssize_t sp0821_set_light(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { ssize_t ret; unsigned int state; ret = kstrtouint(buf, 10, &state); if (ret) { qvga_dev_err(g_sp0821->dev, "%s: fail to change str to int\n", __func__); return ret; } if (state == 0) sp0821_hw_off(g_sp0821); /*OFF*/ else sp0821_hw_on(g_sp0821); /*ON*/ return len; } static DEVICE_ATTR(reg, S_IWUSR | S_IRUGO, sp0821_get_reg, sp0821_set_reg); static DEVICE_ATTR(cam_name, S_IWUSR | S_IRUGO, sp0821_get_name, NULL); static DEVICE_ATTR(light, S_IWUSR | S_IRUGO, sp0821_get_light, sp0821_set_light); static struct attribute *sp0821_attributes[] = { &dev_attr_reg.attr, &dev_attr_cam_name.attr, &dev_attr_light.attr, NULL }; static struct attribute_group sp0821_attribute_group = { .attrs = sp0821_attributes }; static void sp0821_parse_gpio_dt(struct sp0821 *sp0821, struct device_node *np) { qvga_dev_info(sp0821->dev, "%s enter, dev_i2c%d@0x%02X\n", __func__, sp0821->i2c_seq, sp0821->i2c_addr); sp0821->reset_gpio = of_get_named_gpio(np, "reset-gpio", 0); if (sp0821->reset_gpio < 0) { qvga_dev_err(sp0821->dev, "%s: no reset gpio provided, hardware reset unavailable\n", __func__); sp0821->reset_gpio = -1; } else { qvga_dev_info(sp0821->dev, "%s: reset gpio provided ok\n", __func__); } sp0821->reset_gpio1 = of_get_named_gpio(np, "reset-gpio1", 0); if (sp0821->reset_gpio1 < 0) { qvga_dev_err(sp0821->dev, "%s: no reset gpio1 provided, hardware reset unavailable\n", __func__); sp0821->reset_gpio1 = -1; } else { qvga_dev_info(sp0821->dev, "%s: reset gpio1 provided ok\n", __func__); } } static void sp0821_parse_dt(struct sp0821 *sp0821, struct device_node *np) { qvga_dev_info(sp0821->dev, "%s enter, dev_i2c%d@0x%02X\n", __func__, sp0821->i2c_seq, sp0821->i2c_addr); sp0821_parse_gpio_dt(sp0821, np); } /**************************************************************************** * sp0821 i2c driver *****************************************************************************/ static int sp0821_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct device_node *np = client->dev.of_node; struct pinctrl *sp0821_pinctrl = NULL; struct pinctrl_state *set_state = NULL; struct pinctrl_state *sp0821_mclk_on = NULL; struct pinctrl_state *sp0821_mclk_off = NULL; struct sp0821 *sp0821 = NULL; struct class *qvga_class; struct device *dev; int ret = -1; pr_err("scw %s enter , i2c%d@0x%02x\n", __func__, client->adapter->nr, client->addr); if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { qvga_dev_err(&client->dev, "%s: check_functionality failed\n", __func__); ret = -ENODEV; goto exit_check_functionality_failed; } sp0821 = sp0821_malloc_init(client); g_sp0821 = sp0821; sp0821->i2c_seq = sp0821->i2c_client->adapter->nr; sp0821->i2c_addr = sp0821->i2c_client->addr; if (sp0821 == NULL) { dev_err(&client->dev, "%s: failed to parse device tree node\n", __func__); ret = -ENOMEM; goto exit_devm_kzalloc_failed; } sp0821->dev = &client->dev; i2c_set_clientdata(client, sp0821); sp0821_parse_dt(sp0821, np); if (gpio_is_valid(sp0821->reset_gpio)) { ret = devm_gpio_request_one(&client->dev, sp0821->reset_gpio, GPIOF_OUT_INIT_LOW, "sp0821_rst"); if (ret) { qvga_dev_err(&client->dev, "%s: rst request failed\n", __func__); goto exit_gpio_request_failed; } } if (gpio_is_valid(sp0821->reset_gpio1)) { ret = devm_gpio_request_one(&client->dev, sp0821->reset_gpio1, GPIOF_OUT_INIT_LOW, "sp0821_rst1"); if (ret) { qvga_dev_err(&client->dev, "%s: rst1 request failed\n", __func__); goto exit_gpio_request_failed; } } sp0821_pinctrl = devm_pinctrl_get(&client->dev); if (IS_ERR_OR_NULL(sp0821_pinctrl)) { qvga_dev_err(&client->dev, "%s: sp0821_pinctrl not defined\n", __func__); } else { set_state = pinctrl_lookup_state(sp0821_pinctrl, SP0821_MCLK_ON); if (IS_ERR_OR_NULL(set_state)) { qvga_dev_err(&client->dev, "%s: sp0821_pinctrl lookup failed for mclk on\n", __func__); } else { sp0821_mclk_on = set_state; } set_state = pinctrl_lookup_state(sp0821_pinctrl, SP0821_MCLK_OFF); if (IS_ERR_OR_NULL(set_state)) { qvga_dev_err(&client->dev, "%s: sp0821_pinctrl lookup failed for mclk off\n", __func__); } else { sp0821_mclk_off = set_state; } ret = pinctrl_select_state(sp0821_pinctrl, sp0821_mclk_off); if (ret < 0) { qvga_dev_err(&client->dev, "%s: sp0821_pinctrl select failed for mclk off\n", __func__); } } //power on camera sp0821_hw_off_reset1(sp0821); mdelay(5); sp0821_vcam_control(sp0821, true); mdelay(1); ret = pinctrl_select_state(sp0821_pinctrl, sp0821_mclk_on); if (ret < 0) { qvga_dev_err(&client->dev, "%s: sp0821_pinctrl select failed for mclk on\n", __func__); } sp0821_hw_on_reset1(sp0821); sp0821_hw_on_reset(sp0821); mdelay(5); // sp0821->hwen_flag = 1; /* sp0821 sensor id */ ret = sp0821_GetSensorID(sp0821); if (ret < 0) { qvga_dev_err(&client->dev, "%s: sp0821read_sensorid failed ret=%d\n", __func__, ret); goto exit_i2c_check_id_failed; } //power off camera sp0821_vcam_control(sp0821, false); sp0821_hw_off_reset1(sp0821); // sp0821_Init(sp0821); qvga_class = class_create(THIS_MODULE, "qvga_cam"); dev = device_create(qvga_class, NULL, client->dev.devt, NULL, "qvga_depth"); ret = sysfs_create_group(&dev->kobj, &sp0821_attribute_group); if (ret < 0) { qvga_dev_err(&client->dev, "%s failed to create sysfs nodes\n", __func__); } return 0; exit_i2c_check_id_failed: sp0821_vcam_control(sp0821, false); sp0821_hw_off_reset1(sp0821); if (gpio_is_valid(sp0821->reset_gpio)) devm_gpio_free(&client->dev, sp0821->reset_gpio); exit_gpio_request_failed: devm_kfree(&client->dev, sp0821); sp0821 = NULL; exit_devm_kzalloc_failed: exit_check_functionality_failed: return ret; } static int sp0821_i2c_remove(struct i2c_client *client) { struct sp0821 *sp0821 = i2c_get_clientdata(client); if (gpio_is_valid(sp0821->reset_gpio)) devm_gpio_free(&client->dev, sp0821->reset_gpio); if (gpio_is_valid(sp0821->reset_gpio1)) devm_gpio_free(&client->dev, sp0821->reset_gpio1); devm_kfree(&client->dev, sp0821); sp0821 = NULL; return 0; } static const struct of_device_id sp0821_of_match[] = { {.compatible = "sc,sp_sp0821_yuv"}, {}, }; static struct i2c_driver sp0821_i2c_driver = { .driver = { .owner = THIS_MODULE, .name = "sp_sp0821_yuv", .of_match_table = sp0821_of_match, }, .probe = sp0821_i2c_probe, .remove = sp0821_i2c_remove, }; static int __init sp0821_yuv_init(void) { int ret; pr_info("%s: driver version: %s\n", __func__, SP0821_DRIVER_VERSION); ret = i2c_add_driver(&sp0821_i2c_driver); if (ret) { pr_info("****[%s] Unable to register driver (%d)\n", __func__, ret); return ret; } return 0; } static void __exit sp0821_yuv_exit(void) { pr_info("%s enter\n", __func__); i2c_del_driver(&sp0821_i2c_driver); } module_init(sp0821_yuv_init); module_exit(sp0821_yuv_exit); MODULE_AUTHOR("[email protected]>"); MODULE_DESCRIPTION("sp0821 yuv driver"); MODULE_LICENSE("GPL v2"); 这个代码哪里有问题可能会导致编译报错的?

#include "sht21.h" struct { sint16 value; uint16 raw; uint8 crc; } aTemperature, aHumidity; esp_err_t i2c_master_init(void) { int i2c_master_port = I2C_MASTER_NUM; i2c_config_t conf = { .mode = I2C_MODE_MASTER, .sda_io_num = I2C_MASTER_SDA_IO, .sda_pullup_en = GPIO_PULLUP_ENABLE, .scl_io_num = I2C_MASTER_SCL_IO, .scl_pullup_en = GPIO_PULLUP_ENABLE, .master.clk_speed = I2C_MASTER_FREQ_HZ, // .clk_flags = 0, /*!< Optional, you can use I2C_SCLK_SRC_FLAG_* flags to choose i2c source clock here. */ }; esp_err_t err = i2c_param_config(i2c_master_port, &conf); if (err != ESP_OK) { return err; } return i2c_driver_install(i2c_master_port, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0); } // fT = 175.72*u16T/65536.0 - 46.85; // fRH = 125.0*u16RH/65536.0 - 6.0; // ------------------------------------------------------------------- sint16 sht21_calcRH(uint16 u16RH) { sint16 humidityRH; // variable for result u16RH &= ~0x0003; // clear bits [1..0] (status bits) //-- calculate relative humidity [%RH] -- humidityRH = (sint16)(-600 + (12500*(sint32)u16RH)/65536 ); // RH = -6 + 125 * SRH/2^16 return humidityRH; // Return RH*100 } // ------------------------------------------------------------------- sint16 sht21_calcTemperature(uint16 u16T) { sint16 temperature; // variable for result u16T &= ~0x0003; // clear bits [1..0] (status bits) //-- calculate temperature [癈] -- temperature= (sint16)(-4685 + (17572*(sint32)u16T)/65536); //T = -46.85 + 175.72 * ST/2^16 return temperature; //return T*100 } // 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_stop(cmd); // ret = i2c_master_cmd_begin(i2c_num, cmd, 1000 / portTICK_RATE_MS); // i2c_cmd_link_delete(cmd); esp_err_t SHT2X_THMeasure(i2c_port_t i2c_num){ // uint8 u8Ack; int ret; uint8 t_value[3]; uint8 h_value[3]; #if (SHT2X_RESOLUTION != 0x00) // only needed if used resolution other than default // i2c_start(); // send start sequence (S) // u8Ack = i2c_write((SHT2X_SLAVEADDRESS<<1)|I2C_WRITE); // write to slave 0x40 // u8Ack = (u8Ack<<1)|i2c_write(SHT2X_CMD_RD_REG); // request to read from user register // i2c_start(); // send start sequence (S) // u8Ack = (u8Ack<<1)|i2c_write((SHT2X_SLAVEADDRESS<<1)|I2C_READ); // read from slave 0x40 // u8UserReg = i2c_read(I2C_NACK); // read user register // i2c_start(); // send start sequence (S) // u8Ack = i2c_write((SHT2X_SLAVEADDRESS<<1)|I2C_WRITE); // write to slave 0x40 // u8Ack = (u8Ack<<1)|i2c_write(SHT2X_CMD_WR_REG); // request to write user register // u8Ack = (u8Ack<<1)|i2c_write(SHT2X_RESOLUTION | (u8UserReg & ~0x81)); // write new user register data i2c_cmd_handle_t cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, SHT2X_SLAVEADDRESS<<1 | WRITE_BIT, ACK_CHECK_EN); i2c_master_write_byte(cmd, SHT2X_CMD_WR_REG, ACK_CHECK_EN); i2c_master_stop(cmd); ret = i2c_master_cmd_begin(i2c_num, cmd, 500 / portTICK_RATE_MS); i2c_cmd_link_delete(cmd); if (ret != ESP_OK) { return ret; } #endif//(SHT2X_RESOLUTION != 0x00) // -------------------- // measure temperature // -------------------- // i2c_start(); // send start sequence (S) // u8Ack = i2c_write((SHT2X_SLAVEADDRESS<<1)|I2C_WRITE);//----IIC???(8?)???7??IIC????0x80(???HT2X_SLAVEADDRESS=0x40)???DATA???(?R:1 ,?WRITE?0) //a write to slave 0x40 // u8Ack = (u8Ack<<1)|i2c_write(SHT2X_CMD_MEAS_T); //----SHT2X_CMD_MEAS_T=0xF3(??????,???)//request to measure temperature // i2c_stop(); i2c_cmd_handle_t cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, SHT2X_SLAVEADDRESS<<1 | WRITE_BIT, ACK_CHECK_EN); i2c_master_write_byte(cmd, SHT2X_CMD_MEAS_T, ACK_CHECK_EN); i2c_master_stop(cmd); ret = i2c_master_cmd_begin(i2c_num, cmd, 500 / portTICK_RATE_MS); i2c_cmd_link_delete(cmd); if (ret != ESP_OK) { return ret; } vTaskDelay(SHT2X_TEMP_MEAS_TIME / portTICK_RATE_MS); // shortTermSleep(SHT2X_TEMP_MEAS_TIME); // HAL_Delay(SHT2X_TEMP_MEAS_TIME); // time_wait(SHT2X_TEMP_MEAS_TIME); // i2c_start(); // send start sequence (SR) // u8Ack = i2c_write((SHT2X_SLAVEADDRESS<<1)|I2C_READ); //----IIC???(8?)???7??IIC????0x80(???HT2X_SLAVEADDRESS=0x40)???DATA???(?R:1 ,?WRITE?0) // a read from slave 0x40 cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, SHT2X_SLAVEADDRESS << 1 | READ_BIT, ACK_CHECK_EN); i2c_master_read_byte(cmd, &t_value[0], ACK_VAL); i2c_master_read_byte(cmd, &t_value[1], ACK_VAL); i2c_master_read_byte(cmd, &t_value[2], NACK_VAL); i2c_master_stop(cmd); ret = i2c_master_cmd_begin(i2c_num, cmd, 500 / portTICK_RATE_MS); i2c_cmd_link_delete(cmd); // if(u8Ack==I2C_ACK) { // aTemperature.raw = i2c_read(I2C_ACK)<<8; // read hi byte // aTemperature.raw |= i2c_read(I2C_ACK); // read lo byte // aTemperature.crc = i2c_read(I2C_NACK); // read check sum and finish transfere // }else { // aTemperature.raw = 0; // } // i2c_stop(); aTemperature.raw = t_value[0]<<8; aTemperature.raw |= t_value[1]; aTemperature.crc = t_value[2]; // ------------------------- // Humidity Measure // ------------------------- // i2c_start(); // send start sequence (S) // u8Ack = i2c_write((SHT2X_SLAVEADDRESS<<1)|I2C_WRITE); // a write to slave 0x40 1000 0000 // u8Ack = (u8Ack<<1)|i2c_write(SHT2X_CMD_MEAS_RH); // request to measure humidity F5 1110 0101 // i2c_stop(); cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, SHT2X_SLAVEADDRESS<<1 | WRITE_BIT, ACK_CHECK_EN); i2c_master_write_byte(cmd, SHT2X_CMD_MEAS_RH, ACK_CHECK_EN); i2c_master_stop(cmd); ret = i2c_master_cmd_begin(i2c_num, cmd, 500 / portTICK_RATE_MS); i2c_cmd_link_delete(cmd); if (ret != ESP_OK) { return ret; } // shortTermSleep(SHT2X_HUMI_MEAS_TIME); // HAL_Delay(SHT2X_HUMI_MEAS_TIME); vTaskDelay(SHT2X_HUMI_MEAS_TIME / portTICK_RATE_MS); // i2c_start(); // send start sequence (SR) // u8Ack = i2c_write((SHT2X_SLAVEADDRESS<<1)|I2C_READ); // read from slave 0x40 1000 0001 cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, SHT2X_SLAVEADDRESS << 1 | READ_BIT, ACK_CHECK_EN); i2c_master_read_byte(cmd, &h_value[0], ACK_VAL); i2c_master_read_byte(cmd, &h_value[1], ACK_VAL); i2c_master_read_byte(cmd, &h_value[2], NACK_VAL); i2c_master_stop(cmd); ret = i2c_master_cmd_begin(i2c_num, cmd, 500 / portTICK_RATE_MS); i2c_cmd_link_delete(cmd); // if(u8Ack==I2C_ACK) { // timeout // aHumidity.raw = i2c_read(I2C_ACK)<<8; // read hi byte // aHumidity.raw |= i2c_read(I2C_ACK); // read lo byte // aHumidity.crc = i2c_read(I2C_NACK); // read check sum and finish transfere // }else{ // aHumidity.raw = 0; // } // i2c_stop(); // PowerOff(); aHumidity.raw = h_value[0] <<8; // read hi byte aHumidity.raw |= h_value[1]; // read lo byte aHumidity.crc = h_value[2]; // read check sum and finish transfere aTemperature.value = sht21_calcTemperature(aTemperature.raw); aHumidity.value = sht21_calcRH(aHumidity.raw); // signed value, temperature = aTemperature.value * 0.01? if(aTemperature.crc!= sht21_CRC((uint8*)&aTemperature.raw, 2)) {} if(aHumidity.crc!= sht21_CRC((uint8*)&aHumidity.raw, 2)) {} if(aTemperature.value>5100) aTemperature.value=5100; //prevent temperature over-/underflow else if(aTemperature.value<0) aTemperature.value=0; if(aHumidity.value>10000) aTemperature.value=10000; //prevent temperature over-/underflow else if(aTemperature.value<0) aTemperature.value=0; return ret; } uint16_t getTemperature() { return aTemperature.value; } uint16_t getHumidity() { return aHumidity.value; } //============================================================================== uint8 sht21_CRC(uint8 value[], uint8 u8Bytes) { // CRC const uint16 POLYNOMIAL = 0x131; //P(x)=x^8+x^5+x^4+1 = 100110001 uint8 crc = 0; uint8 byteCtr; uint8 bitCtr; //calculates 8-Bit checksum with given polynomial for (byteCtr = 0; byteCtr < u8Bytes; ++byteCtr) { crc ^= (value[byteCtr]); for (bitCtr = 8; bitCtr > 0; --bitCtr) { if (crc & 0x80) crc = (crc << 1) ^ POLYNOMIAL; else crc = (crc << 1); } } return crc; } 我需要sht21.h的代码

#include #include #include #include // single_open #include // kfree kzalloc #include // proc_creat #include // copy_from_user #include #include "kdrv_pmbus_api.h" static int pmbus_test_show(struct seq_file *seq, void *arg) { return 0; } static int pmbus_test_open(struct inode *pnode, struct file *pfile) { return single_open(pfile, pmbus_test_show, NULL); } int test_kdrv_pmbus_write_block_data(u32 bus_id, u32 slave_addr, u32 cmd, u32 len) { u8 *buf = NULL; int i; u32 ret; buf = (u8 *)kzalloc(len, GFP_KERNEL); if (buf == NULL) { pr_err("kzalloc err!\r\n"); return -ENOMEM; } buf[0] = len - 1; for (i = 1; i < len; i++) { buf[i] = i; } ret = kdrv_pmbus_write_block_data(bus_id, slave_addr, cmd, buf, len); if (ret) { pr_err("kdrv_pmbus_write_block_data fail\r\n"); kfree(buf); return ret; } kfree(buf); return 0; } int test_kdrv_pmbus_read_block_data(u32 bus_id, u32 slave_addr, u32 cmd, u32 len) { int ret; int i; u8 *buf = NULL; buf = (u8 *)kzalloc(len, GFP_KERNEL); if (buf == NULL) { pr_err("kzalloc err!\r\n"); return -ENOMEM; } ret = kdrv_pmbus_read_block_data(bus_id, slave_addr, cmd, buf, len); if (ret) { pr_err("kdrv_pmbus_read_block_data fail bus_id:%#x, addr:%#x, cmd:%#x\n", bus_id, slave_addr, cmd); kfree(buf); return ret; } for (i = 0; i < len; i++) { pr_info("read: bus_id:%#x, addr:%#x, cmd:%#x, buf[%d]:[0x%02x], len:%u\n", bus_id, slave_addr, cmd, i, buf[i], len); } kfree(buf); return 0; } int test_kdrv_pmbus_read_byte(u32 bus_id, u32 slave_addr, u32 cmd) { int ret; u8 data; ret = kdrv_pmbus_read_byte(bus_id, slave_addr, cmd, &data); if (ret) { pr_err("kdrv_pmbus_read_byte fail bus_id:%u, addr:%#x, cmd:%#x\n", bus_id, slave_addr, cmd); return ret; } pr_info("read: bus_id:%#x, addr:%#x, cmd:%#x, data:%#x\n", bus_id, slave_addr, cmd, data); return 0; } int test_kdrv_pmbus_read_word(u32 bus_id, u32 slave_addr, u32 cmd) { int ret; u16 data; ret = kdrv_pmbus_read_word(bus_id, slave_addr, cmd, &data); if (ret) { pr_err("kdrv_pmbus_read_word fail bus_id:%u, addr:%#x, cmd:%#x\n", bus_id, slave_addr, cmd); return ret; } pr_info("read: bus_id:%#x, addr:%#x, cmd:%#x, data:%#x\n", bus_id, slave_addr, cmd, data); return 0; } int test_kdrv_pmbus_write_byte(u32 bus_id, u32 slave_addr, u32 cmd, u32 data) { int ret; ret = kdrv_pmbus_write_byte(bus_id, slave_addr, cmd, (u8)data); if (ret) { pr_err("kdrv_pmbus_write_byte fail bus_id:%u, addr:%#x, cmd:%#x\n", bus_id, slave_addr, cmd); return ret; } pr_info("write byte: bus_id:%#x, addr:%#x, cmd:%#x, data:%#x\n", bus_id, slave_addr, cmd, data); return 0; } int test_kdrv_pmbus_write_word(u32 bus_id, u32 slave_addr, u32 cmd, u32 data) { int ret; ret = kdrv_pmbus_write_word(bus_id, slave_addr, cmd, (u16)data); if (ret) { pr_err("kdrv_pmbus_write_word fail bus_id:%u, addr:%#x, cmd:%#x\n", bus_id, slave_addr, cmd); return ret; } pr_info("write word: bus_id:%#x, addr:%#x, cmd:%#x, data:%#x\n", bus_id, slave_addr, cmd, data); return 0; } int test_kdrv_pmbus_write_cmd(u32 bus_id, u32 slave_addr, u32 cmd) { int ret; ret = kdrv_pmbus_write_cmd(bus_id, slave_addr, cmd); if (ret) { pr_err("kdrv_pmbus_write_cmd fail bus_id:%u, addr:%#x, cmd:%#x\n", bus_id, slave_addr, cmd); return ret; } pr_info("write word: bus_id:%#x, addr:%#x, cmd:%#x\n", bus_id, slave_addr, cmd); return 0; } #define PMBUS_CMD_READ_BYTE 0 #define PMBUS_CMD_READ_WORD 1 #define PMBUS_CMD_WRITE_BYTE 2 #define PMBUS_CMD_WRITE_WORD 3 #define PMBUS_CMD_READ_BLOCK 4 #define PMBUS_CMD_WRITE_BLOCK 5 #define PMBUS_CMD_WRITE_CMD 6 #define PMBUS_CMD_RESET 7 #define PMBUS_CMD_INIT 8 #define CFG_LINE_SIZE 120 static ssize_t pmbus_test_write(struct file *file, const char __user *buf, size_t len, loff_t *ppos) { u32 cmd; u32 bus_id; u32 command; u32 data; u32 slave_addr; char *next = NULL; char line[CFG_LINE_SIZE] = {0}; if (len > (CFG_LINE_SIZE - 1)) { return -E2BIG; } if (copy_from_user(line, buf, len)) { return -EINVAL; } /* usage: echo <cmd> [bus_id][slave_addr] [cmd] > pmbus_test */ cmd = simple_strtoul(line, &next, 0); bus_id = simple_strtoul(next + 1, &next, 0); switch (cmd) { case PMBUS_CMD_READ_BYTE: slave_addr = simple_strtoul(next + 1, &next, 0); command = simple_strtoul(next + 1, &next, 0); (void)test_kdrv_pmbus_read_byte(bus_id, slave_addr, command); break; case PMBUS_CMD_READ_WORD: slave_addr = simple_strtoul(next + 1, &next, 0); command = simple_strtoul(next + 1, &next, 0); (void)test_kdrv_pmbus_read_word(bus_id, slave_addr, command); break; case PMBUS_CMD_WRITE_BYTE: slave_addr = simple_strtoul(next + 1, &next, 0); command = simple_strtoul(next + 1, &next, 0); data = simple_strtoul(next + 1, &next, 0); (void)test_kdrv_pmbus_write_byte(bus_id, slave_addr, command, (u8)data); break; case PMBUS_CMD_WRITE_WORD: slave_addr = simple_strtoul(next + 1, &next, 0); command = simple_strtoul(next + 1, &next, 0); data = simple_strtoul(next + 1, &next, 0); (void)test_kdrv_pmbus_write_word(bus_id, slave_addr, command, (u16)data); break; case PMBUS_CMD_READ_BLOCK: slave_addr = simple_strtoul(next + 1, &next, 0); command = simple_strtoul(next + 1, &next, 0); data = simple_strtoul(next + 1, &next, 0); (void)test_kdrv_pmbus_read_block_data(bus_id, slave_addr, command, data); break; case PMBUS_CMD_WRITE_BLOCK: slave_addr = simple_strtoul(next + 1, &next, 0); command = simple_strtoul(next + 1, &next, 0); data = simple_strtoul(next + 1, &next, 0); (void)test_kdrv_pmbus_write_block_data(bus_id, slave_addr, command, data); break; case PMBUS_CMD_WRITE_CMD: slave_addr = simple_strtoul(next + 1, &next, 0); command = simple_strtoul(next + 1, &next, 0); (void)test_kdrv_pmbus_write_cmd(bus_id, slave_addr, command); break; case PMBUS_CMD_RESET: (void)kdrv_pmbus_reset(bus_id); break; case PMBUS_CMD_INIT: data = simple_strtoul(next + 1, &next, 0); (void)kdrv_pmbus_init(bus_id, data); break; default: break; } return len; } #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0) static const struct proc_ops g_pmbus_operations = { .proc_open = pmbus_test_open, .proc_read = seq_read, .proc_write = pmbus_test_write, .proc_lseek = seq_lseek, .proc_release = single_release, }; #else static const struct file_operations g_pmbus_operations = { .open = pmbus_test_open, .read = seq_read, .write = pmbus_test_write, .llseek = seq_lseek, .release = single_release, }; #endif int __init pmbus_test_mod_init(void) { (void)proc_create("pmbus_test", S_IRUSR, NULL, &g_pmbus_operations); printk("pmbus_test_mod_init\r\n"); return 0; } void __exit pmbus_test_mod_exit(void) { (void)remove_proc_entry("pmbus_test", NULL); printk("pmbus_test_mod_exit\r\n"); } module_init(pmbus_test_mod_init); module_exit(pmbus_test_mod_exit); MODULE_DESCRIPTION("udrv pmbus api test"); MODULE_LICENSE("GPL");" #include #include #include #include #include #include #include #include "hisi_pmbus.h" #define STANDARD_MODE 1 #define FAST_MODE 2 #define GPIO_LEVEL_LOW 0 #define GPIO_LEVEL_HIGH 1 #define SET_LOW_HIGH_TIMES 9 #define AVS_WR_OPEN_REG 0x0004 #define AVS_INT_STATUS_REG 0x0008 #define AVS_INT_CLEAR_REG 0x0020 #define TRIGGER_CFG_REG 0x00B8 #define PMBUS_DISABLE 0x00 #define PMBUS_ENABLE 0x01 /* PMBUSIF_REG_GEN Base address of Module's Register */ #define PMBUSIF_REG_GEN_BASE (0x800) #define I2C_CON_REG (PMBUSIF_REG_GEN_BASE + 0x0) /* I2C控制寄存器。 */ #define I2C_CON_MASTER_ENABLE BIT(0) #define I2C_CON_SPEED_MASK (0x6U) #define I2C_CON_RESTART_EN BIT(5) #define I2C_CON_SLAVE_DISABLE BIT(6) #define I2C_DATA_CMD_REG (PMBUSIF_REG_GEN_BASE + 0x10) /* I2C数据操作寄存器。 */ #define I2C_SS_SCL_HCNT_REG (PMBUSIF_REG_GEN_BASE + 0x14) /* I2C标准速度模式SCL高电平配置寄存器。 */ #define I2C_SS_SCL_LCNT_REG (PMBUSIF_REG_GEN_BASE + 0x18) /* I2C标准速度模式SCL低电平配置寄存器。 */ #define I2C_FS_SCL_HCNT_REG (PMBUSIF_REG_GEN_BASE + 0x1C) /* I2C快速模式SCL高电平配置寄存器。 */ #define I2C_FS_SCL_LCNT_REG (PMBUSIF_REG_GEN_BASE + 0x20) /* I2C快速模式SCL低电平配置寄存器。 */ #define I2C_INTR_STAT_REG (PMBUSIF_REG_GEN_BASE + 0x2C) /* I2C屏蔽后中断状态寄存器。 */ #define I2C_INTR_MASK_REG (PMBUSIF_REG_GEN_BASE + 0x30) /* I2C中断屏蔽寄存器。 */ #define I2C_INTR_RAW_REG (PMBUSIF_REG_GEN_BASE + 0x34) /* I2C原始中断状态寄存器。 */ #define I2C_INTR_RAW_TX_ABRT BIT(6) #define I2C_INTR_RAW_ALERT_DET BIT(12) #define I2C_INTR_RAW_SCL_LOW_TOUT BIT(15) #define I2C_INTR_RAW_PMBUS_CMD_FINISH BIT(17) #define I2C_ENABLE_REG (PMBUSIF_REG_GEN_BASE + 0x6C) /* I2C工作使能寄存器。 */ #define I2C_STATUS_REG (PMBUSIF_REG_GEN_BASE + 0x70) /* I2C状态寄存器。 */ #define I2C_RXFLR_REG (PMBUSIF_REG_GEN_BASE + 0x78) /* RX_FIFO有效数据指示寄存器。 */ #define I2C_SDA_HOLD_REG (PMBUSIF_REG_GEN_BASE + 0x7C) /* SDA保持时间配置寄存器。 */ #define I2C_ENABLE_STATUS_REG (PMBUSIF_REG_GEN_BASE + 0x9C) /* I2C状态寄存器。 */ #define I2C_SCL_SWITCH_REG (PMBUSIF_REG_GEN_BASE + 0xA0) /* I2C防挂死SCL使能寄存器。 */ #define I2C_SCL_SIM_REG (PMBUSIF_REG_GEN_BASE + 0xA4) /* I2C防挂死SCL模拟寄存器。 */ #define I2C_LOCK_REG (PMBUSIF_REG_GEN_BASE + 0xAC) /* I2C lock寄存器。 */ #define I2C_SDA_SWITCH_REG (PMBUSIF_REG_GEN_BASE + 0xB0) /* I2C防挂死SDA使能寄存器。 */ #define I2C_SDA_SIM_REG (PMBUSIF_REG_GEN_BASE + 0xB4) /* I2C防挂死SDA模拟寄存器。 */ #define I2C_PMBUS_CTRL_REG (PMBUSIF_REG_GEN_BASE + 0x104) /* PMBUS全局控制寄存器。 */ #define I2C_PMBUS_CTRL_PEC_EN BIT(2) #define I2C_PMBUS_CTRL_ALERT_EN BIT(1) #define I2C_LOW_TIMEOUT_REG (PMBUSIF_REG_GEN_BASE + 0x108) /* SCL低电平超时值配置寄存器。 */ #define I2C_PMBUS_SCL_DET_REG (PMBUSIF_REG_GEN_BASE + 0x12C) /* PMBUS SCL检测寄存器。 */ #define I2C_PMBUS_SCL_DET_IDLE_DET_EN BIT(0) #define I2C_PMBUS_SCL_DET_TIMEOUT_EN BIT(1) #define I2C_PMBUS_IDLECNT_REG (PMBUSIF_REG_GEN_BASE + 0x130) /* SCL高电平空闲值配置寄存器。 */ #define I2C_PMBUS_RST_REG (PMBUSIF_REG_GEN_BASE + 0x134) /* 软件复位配置寄存器。 */ /* PMBUS_PROC_REG_GEN Base address of Module's Register */ #define PMBUS_PROC_REG_GEN_BASE (0xA00) #define PMBUS_WR_OPEN_REG (PMBUS_PROC_REG_GEN_BASE + 0x4) /* PMBUS全局参数保护寄存器。 */ #define PMBUS_INT_CLR_REG (PMBUS_PROC_REG_GEN_BASE + 0x10) /* PMBUS中断清除寄存器 */ #define PMBUS_WAIT_CNT 30000 /* PMU CMD */ #define STOP_EN (1U << 10) #define ADDR_EN (1U << 9) #define CMD_READ (1U << 8) #define SDA_IN BIT(9) #define PMBUS_I2C_RECOVERY_CYCLE_CNT 10 static inline void pmbus_reg_write(struct io_region *reg_region, u32 reg, u32 val) { pr_debug("[iWare][Debug] %s reg=%#x val =%#x\r\n", __FUNCTION__, reg, val); iowrite32(val, reg_region->io_base + reg); } static inline u32 pmbus_reg_read(struct io_region *reg_region, u32 reg) { u32 val; val = ioread32(reg_region->io_base + reg); pr_debug("[iWare][Debug] %s reg=%#x val =%#x\r\n", __FUNCTION__, reg, val); return val; } /* try to recovery the bus if sda locked to low level */ static void pmbus_recovery_bus(struct io_region *reg_region) { int i; u32 status; status = pmbus_reg_read(reg_region, I2C_STATUS_REG); /* if SDA keep low, assume the bus hang up */ if ((status & SDA_IN) == 0) { /* disable pmbus */ pmbus_reg_write(reg_region, I2C_ENABLE_REG, 0x0); /* enable output software simulaition */ pmbus_reg_write(reg_region, I2C_SCL_SWITCH_REG, 0x1); pmbus_reg_write(reg_region, I2C_SDA_SWITCH_REG, 0x1); /* output at least 9 clocks to try to recover the bus */ for (i = 0; i < PMBUS_I2C_RECOVERY_CYCLE_CNT; i++) { pmbus_reg_write(reg_region, I2C_SCL_SIM_REG, 0x0); udelay(50); // 延时50us pmbus_reg_write(reg_region, I2C_SCL_SIM_REG, 0x1); udelay(50); // 延时50us } /* disable output software simulaition */ pmbus_reg_write(reg_region, I2C_SCL_SWITCH_REG, 0x0); pmbus_reg_write(reg_region, I2C_SDA_SWITCH_REG, 0x0); /* enable pmbus */ pmbus_reg_write(reg_region, I2C_ENABLE_REG, 0x1); pr_info("[iWare][Info] pmbus hang recovery done\n"); } } static int pmbus_wait_write_finish(struct io_region *reg_region) { int i; u32 status = 0; for (i = 0; i < PMBUS_WAIT_CNT; i++) { status = pmbus_reg_read(reg_region, I2C_INTR_RAW_REG); if (((status & I2C_INTR_RAW_SCL_LOW_TOUT) == 0) && ((status & I2C_INTR_RAW_TX_ABRT) == 0) && ((status & I2C_INTR_RAW_PMBUS_CMD_FINISH) != 0)) { // 清除所有中断 pmbus_reg_write(reg_region, I2C_INTR_RAW_REG, 0xffffffff); return 0; } udelay(1); } pr_err("[iWare][Error] pmbus_write timeout! raw_int_status:0x%x\n", status); // 清除所有中断 pmbus_reg_write(reg_region, I2C_INTR_RAW_REG, 0xffffffff); pmbus_recovery_bus(reg_region); return -EBUSY; } static int pmbus_send_byte_v200(struct io_region *reg_region, struct pmbus_msg *msg) { pmbus_reg_write(reg_region, I2C_DATA_CMD_REG, ADDR_EN | msg->slave_addr); if ((msg->type & PMBUS_FLAG_EXT) != 0) { pmbus_reg_write(reg_region, I2C_DATA_CMD_REG, STOP_EN | msg->command); pmbus_reg_write(reg_region, I2C_DATA_CMD_REG, STOP_EN | msg->command_ext); } else { pmbus_reg_write(reg_region, I2C_DATA_CMD_REG, STOP_EN | msg->command); } return pmbus_wait_write_finish(reg_region); } static int pmbus_write_bytes_v200(struct io_region *reg_region, struct pmbus_msg *msg) { unsigned int i; pmbus_reg_write(reg_region, I2C_DATA_CMD_REG, ADDR_EN | msg->slave_addr); pmbus_reg_write(reg_region, I2C_DATA_CMD_REG, msg->command); if ((msg->type & PMBUS_FLAG_EXT) != 0) { pmbus_reg_write(reg_region, I2C_DATA_CMD_REG, msg->command_ext); } for (i = 0; i < msg->data_len - 1; i++) { pmbus_reg_write(reg_region, I2C_DATA_CMD_REG, msg->data[i]); } pmbus_reg_write(reg_region, I2C_DATA_CMD_REG, STOP_EN | msg->data[msg->data_len - 1]); return pmbus_wait_write_finish(reg_region); } #define PMBUS_READ_WAIT_TIMEOUT 1000000ULL #define PMUBS_READ_WAIT_DELAY_US 1UL static int pmbus_wait_read_finish(struct io_region *reg_region, u8 read_len) { int ret; u32 data_num; ret = readl_poll_timeout(reg_region->io_base + I2C_RXFLR_REG, data_num, (data_num >= read_len), PMUBS_READ_WAIT_DELAY_US, PMBUS_READ_WAIT_TIMEOUT); if (ret != 0) { pr_err("[iWare][Error] wait read_finish timeout!! read_len[%u] fifo num[%u], raw_int_status:0x%x\n", read_len, data_num, pmbus_reg_read(reg_region, I2C_INTR_RAW_REG)); // 清除所有中断 pmbus_reg_write(reg_region, I2C_INTR_RAW_REG, 0xffffffff); pmbus_recovery_bus(reg_region); return ret; } return 0; } static void pmbus_clear_rx_fifo(struct io_region *reg_region) { u8 rx_fifo_data_num; u8 i; u32 tmp; /* clean rx fifo */ rx_fifo_data_num = (u8)pmbus_reg_read(reg_region, I2C_RXFLR_REG); for (i = 0; i < rx_fifo_data_num; i++) { tmp = pmbus_reg_read(reg_region, I2C_DATA_CMD_REG); // 把fifo读清 } } static int pmbus_read_bytes_v200(struct io_region *reg_region, struct pmbus_msg *msg) { int ret; unsigned int i; u32 status; /* 先把rx fifo读清 */ pmbus_clear_rx_fifo(reg_region); pmbus_reg_write(reg_region, I2C_DATA_CMD_REG, ADDR_EN | msg->slave_addr); pmbus_reg_write(reg_region, I2C_DATA_CMD_REG, msg->command); if ((msg->type & PMBUS_FLAG_EXT) != 0) { // 扩展16bit 命令 pmbus_reg_write(reg_region, I2C_DATA_CMD_REG, msg->command_ext); } pmbus_reg_write(reg_region, I2C_DATA_CMD_REG, ADDR_EN | CMD_READ | msg->slave_addr); for (i = 0; i < msg->data_len - 1; i++) { pmbus_reg_write(reg_region, I2C_DATA_CMD_REG, CMD_READ); } pmbus_reg_write(reg_region, I2C_DATA_CMD_REG, STOP_EN | CMD_READ); ret = pmbus_wait_read_finish(reg_region, msg->data_len); if (ret != 0) { pr_err("[iWare][Error] %s slave_addr(0x%x), cmd(0x%x), time out\n", __func__, msg->slave_addr, msg->command); pmbus_recovery_bus(reg_region); return -EAGAIN; } for (i = 0; i < msg->data_len; i++) { msg->data[i] = (u8)pmbus_reg_read(reg_region, I2C_DATA_CMD_REG); } /* for block read, first read code is data length */ if ((msg->type & PMBUS_FLAG_BLOCK) != 0) { if (msg->data[0] > msg->data_len) { pr_info("[iWare][Info] pmbus read slave[0x%02x] command[0x%02x] block data may lossed, toalLen[%u]\n", msg->slave_addr, msg->command, msg->data[0]); } } // 清中断 status = pmbus_reg_read(reg_region, I2C_INTR_RAW_REG); pmbus_reg_write(reg_region, I2C_INTR_RAW_REG, status); return 0; } static int pmbus_reset_v200(struct io_region *reg_region) { pmbus_reg_write(reg_region, I2C_PMBUS_RST_REG, 1); udelay(1); pmbus_reg_write(reg_region, I2C_PMBUS_RST_REG, 0); udelay(1); return 0; } /* 不同soc解锁码不同, chip dtsi里配置 309a 1260 avs_wr_unlock_key 0x5a5a5a5a 0x1ACCE551 pmbus_wr_unlock_key 0x5a5a5a5a 0x1ACCE551 i2c_unlock_key 0x5a5a5a5a 0x36313832 */ static void pmbus_unlock_reg(struct io_region *reg_region, struct pmbus_unlock_key *key) { /* unlock avs wr */ pmbus_reg_write(reg_region, AVS_WR_OPEN_REG, key->avs_wr_unlock_key); /* unlock pmbus wr */ pmbus_reg_write(reg_region, PMBUS_WR_OPEN_REG, key->pmbus_wr_unlock_key); /* unlock pmbus i2c wr */ pmbus_reg_write(reg_region, I2C_LOCK_REG, key->i2c_unlock_key); } static void pmbus_config_timing_cnt(struct io_region *reg_region, u8 speed_mode, struct pmbus_timings_cfg *pmbus_cfg) { if (speed_mode == STANDARD_MODE) { // 标准模式 pmbus_reg_write(reg_region, I2C_SS_SCL_LCNT_REG, pmbus_cfg->lcnt); pmbus_reg_write(reg_region, I2C_SS_SCL_HCNT_REG, pmbus_cfg->hcnt); } else { // 快速模式 pmbus_reg_write(reg_region, I2C_FS_SCL_LCNT_REG, pmbus_cfg->lcnt); pmbus_reg_write(reg_region, I2C_FS_SCL_HCNT_REG, pmbus_cfg->hcnt); } // 屏蔽所有中断 pmbus_reg_write(reg_region, I2C_INTR_MASK_REG, 0xFFFFFFFF); pmbus_reg_write(reg_region, I2C_SDA_HOLD_REG, pmbus_cfg->hold_cnt); // PMBus的SCL低电平超时值(PMBus协议规定为25~35ms) pmbus_reg_write(reg_region, I2C_LOW_TIMEOUT_REG, pmbus_cfg->timeout_cnt); // 默认30ms // PMBus的SCL高电平空闲值(PMBus协议规定为>50us) pmbus_reg_write(reg_region, I2C_PMBUS_IDLECNT_REG, pmbus_cfg->idle_cnt); // 默认100us } static int pmbus_init_v200(struct io_region *reg_region, u32 pec_en, u32 bus_freq_hz, struct pmbus_timings_cfg *cfg, struct pmbus_unlock_key *key) { u32 val = 0; u8 speed_mode; int ret; if (bus_freq_hz > PMBUS_MAX_FAST_MODE_FREQ) { pr_err("[iWare][Error] invalid para bus_freq_hz =%u\r\n", bus_freq_hz); return -EINVAL; } ret = pmbus_reset_v200(reg_region); if (ret != 0) { return ret; } /* unlock */ pmbus_unlock_reg(reg_region, key); /* stop triger */ pmbus_reg_write(reg_region, TRIGGER_CFG_REG, 0x0); /* disable pmbus */ pmbus_reg_write(reg_region, I2C_ENABLE_REG, PMBUS_DISABLE); speed_mode = (bus_freq_hz <= PMBUS_MAX_STANDARD_MODE_FREQ) ? STANDARD_MODE : FAST_MODE; val |= I2C_CON_MASTER_ENABLE | I2C_CON_SLAVE_DISABLE | I2C_CON_RESTART_EN; val |= (u32)FIELD_PREP(I2C_CON_SPEED_MASK, speed_mode); pmbus_reg_write(reg_region, I2C_CON_REG, val); pmbus_config_timing_cnt(reg_region, speed_mode, cfg); /* config scl detect */ pmbus_reg_write(reg_region, I2C_PMBUS_SCL_DET_REG, I2C_PMBUS_SCL_DET_IDLE_DET_EN | I2C_PMBUS_SCL_DET_TIMEOUT_EN); /* enable pec and alert */ val = I2C_PMBUS_CTRL_ALERT_EN; if (pec_en != 0) { pr_info("[iWare][Info] pmbus enable pec \r\n"); val |= I2C_PMBUS_CTRL_PEC_EN; } pmbus_reg_write(reg_region, I2C_PMBUS_CTRL_REG, val); /* enable pmbus */ pmbus_reg_write(reg_region, I2C_ENABLE_REG, PMBUS_ENABLE); // 清中断 pmbus_reg_write(reg_region, AVS_INT_CLEAR_REG, 0xFFFFFFFF); pmbus_reg_write(reg_region, PMBUS_INT_CLR_REG, 0xFFFFFFFF); pmbus_reg_write(reg_region, I2C_INTR_RAW_REG, 0xFFFFFFFF); return 0; } const struct hisi_pmbus_ops hisi_pmbus_v200_ops = { .init = pmbus_init_v200, .reset = pmbus_reset_v200, .send_byte = pmbus_send_byte_v200, .read_bytes = pmbus_read_bytes_v200, .write_bytes = pmbus_write_bytes_v200, }; const struct hisi_pmbus_ops *hisi_pmbus_get_ops(void) { return &hisi_pmbus_v200_ops; }" #include #include #include "hisi_pmbus.h" #include "kdrv_pmbus_api.h" #define PMBUS_BLOCK_MAX 32 static void hisi_pmbus_fill_msg(struct pmbus_msg *msg, u8 type, u8 slave_addr, u16 command) { u8 cmd; cmd = (u8)(command >> 0x8); // 高8位为extended cmd 指示这是一条扩展命令 if ((cmd == PMBUS_MFR_SPECIFIC_COMMAND_EXT || cmd == PMBUS_COMMAND_EXT)) { msg->type = type | PMBUS_FLAG_EXT; msg->command = cmd; msg->command_ext = (u8)command; } else { msg->type = type; msg->command = (u8)command; } msg->slave_addr = slave_addr; } static int hisi_pmbus_xfer(struct hisi_pmbus_data *pmbus, struct pmbus_msg *msg) { int ret; if ((msg->data == NULL) && (msg->data_len > 0)) { dev_err(pmbus->dev, "[iWare][Error] msg->data = NULL, msg.data_len %zu\r\n", msg->data_len); return -EINVAL; } if ((msg->type & PMBUS_FLAG_NO_DATA) != 0) { ret = pmbus->ops->send_byte(&pmbus->reg_region, msg); } else if ((msg->type & PMBUS_FLAG_READ) != 0) { ret = pmbus->ops->read_bytes(&pmbus->reg_region, msg); } else { /* pmbus write */ ret = pmbus->ops->write_bytes(&pmbus->reg_region, msg); } return ret; } int kdrv_pmbus_reset(u32 bus_id) { struct hisi_pmbus_data *pmbus = NULL; pmbus = hisi_pmbus_data_get_by_id(bus_id); if (pmbus == NULL) { pr_err("[iWare][Error] get pmbus data fail: pmbus_id=%u,\n", bus_id); return -EPERM; } mutex_lock(&pmbus->lock); pmbus->ops->reset(&pmbus->reg_region); mutex_unlock(&pmbus->lock); return 0; } EXPORT_SYMBOL(kdrv_pmbus_reset); int kdrv_pmbus_init(u32 bus_id, u32 bus_freq_hz) { struct hisi_pmbus_data *pmbus = NULL; int ret; u32 total_cnt; pmbus = hisi_pmbus_data_get_by_id(bus_id); if (pmbus == NULL) { pr_err("[iWare][Error] get pmbus data fail: pmbus_id=%u,\n", bus_id); return -EPERM; } if (bus_freq_hz > PMBUS_MAX_FAST_MODE_FREQ || bus_freq_hz == 0) { pr_err("[iWare][Error] invalid para bus_freq_hz =%u \r\n", bus_freq_hz); return -EINVAL; } mutex_lock(&pmbus->lock); pmbus->timing.bus_freq_hz = bus_freq_hz; total_cnt = (u32)DIV_ROUND_UP_ULL(pmbus->timing.clk_freq_mhz * HZ_PER_MHZ, bus_freq_hz); pmbus->timing_cfg.hcnt = (pmbus->timing.scl_high_ratio * total_cnt) / 100; // 占空比放大了100倍 这里除以100 pmbus->timing_cfg.lcnt = total_cnt - pmbus->timing_cfg.hcnt; pr_info("[iWare][Info] %s bus_freq_hz %u, total_cnt %u, hcnt %u lcnt %u\n", __func__, bus_freq_hz, total_cnt, pmbus->timing_cfg.hcnt, pmbus->timing_cfg.lcnt); ret = pmbus->ops->init(&pmbus->reg_region, pmbus->pec_en, pmbus->timing.bus_freq_hz, &pmbus->timing_cfg, &pmbus->key); if (ret != 0) { mutex_unlock(&pmbus->lock); pr_err("[iWare][Error] kdrv_pmbus_init failed ret=%d\n", ret); return ret; } mutex_unlock(&pmbus->lock); return 0; } EXPORT_SYMBOL(kdrv_pmbus_init); int kdrv_pmbus_write_word(u32 bus_id, u8 slave_addr, u16 command, u16 data) { struct hisi_pmbus_data *pmbus = NULL; struct pmbus_msg msg = { 0 }; int ret; pmbus = hisi_pmbus_data_get_by_id(bus_id); if (pmbus == NULL) { pr_err("[iWare][Error] kdrv_pmbus_write_word,get pmbus data fail: pmbus_id=%u,\n", bus_id); return -EPERM; } mutex_lock(&pmbus->lock); msg.data = (u8 *)&data; msg.data_len = sizeof(u16); hisi_pmbus_fill_msg(&msg, PMBUS_WRITE_WORD, slave_addr, command); ret = hisi_pmbus_xfer(pmbus, &msg); if (ret != 0) { mutex_unlock(&pmbus->lock); return ret; } mutex_unlock(&pmbus->lock); return 0; } EXPORT_SYMBOL(kdrv_pmbus_write_word); int kdrv_pmbus_write_byte(u32 bus_id, u8 slave_addr, u16 command, u8 data) { struct hisi_pmbus_data *pmbus = NULL; struct pmbus_msg msg = { 0 }; int ret; pmbus = hisi_pmbus_data_get_by_id(bus_id); if (pmbus == NULL) { pr_err("[iWare][Error] kdrv_pmbus_write_byte, get pmbus data fail: pmbus_id=%u,\n", bus_id); return -EPERM; } mutex_lock(&pmbus->lock); msg.data = &data; msg.data_len = sizeof(u8); hisi_pmbus_fill_msg(&msg, PMBUS_WRITE_BYTE, slave_addr, command); ret = hisi_pmbus_xfer(pmbus, &msg); if (ret != 0) { mutex_unlock(&pmbus->lock); return ret; } mutex_unlock(&pmbus->lock); return 0; } EXPORT_SYMBOL(kdrv_pmbus_write_byte); int kdrv_pmbus_write_cmd(u32 bus_id, u8 slave_addr, u16 command) { struct hisi_pmbus_data *pmbus = NULL; struct pmbus_msg msg = { 0 }; int ret; pmbus = hisi_pmbus_data_get_by_id(bus_id); if (pmbus == NULL) { pr_err("[iWare][Error] kdrv_pmbus_write_cmd, get pmbus data fail: pmbus_id=%u,\n", bus_id); return -EPERM; } mutex_lock(&pmbus->lock); hisi_pmbus_fill_msg(&msg, PMBUS_SEND_BYTE, slave_addr, command); ret = hisi_pmbus_xfer(pmbus, &msg); if (ret != 0) { mutex_unlock(&pmbus->lock); return ret; } mutex_unlock(&pmbus->lock); return 0; } EXPORT_SYMBOL(kdrv_pmbus_write_cmd); int kdrv_pmbus_read_byte(u32 bus_id, u8 slave_addr, u16 command, u8 *data) { struct hisi_pmbus_data *pmbus = NULL; struct pmbus_msg msg = { 0 }; int ret; if (data == NULL) { pr_err("[iWare][Error] ivalid para, data is null point,\n"); return -EINVAL; } pmbus = hisi_pmbus_data_get_by_id(bus_id); if (pmbus == NULL) { pr_err("[iWare][Error] get pmbus data fail: pmbus_id=%u,\n", bus_id); return -EPERM; } mutex_lock(&pmbus->lock); msg.data = data; msg.data_len = sizeof(u8); hisi_pmbus_fill_msg(&msg, PMBUS_READ_BYTE, slave_addr, command); ret = hisi_pmbus_xfer(pmbus, &msg); if (ret != 0) { mutex_unlock(&pmbus->lock); return ret; } mutex_unlock(&pmbus->lock); return 0; } EXPORT_SYMBOL(kdrv_pmbus_read_byte); int kdrv_pmbus_read_word(u32 bus_id, u8 slave_addr, u16 command, u16 *data) { struct hisi_pmbus_data *pmbus = NULL; struct pmbus_msg msg = { 0 }; int ret; u8 tmp[2] = {0}; // 2个字节 if (data == NULL) { pr_err("[iWare][Error] ivalid para, data is null point,\n"); return -EINVAL; } pmbus = hisi_pmbus_data_get_by_id(bus_id); if (pmbus == NULL) { pr_err("[iWare][Error] get pmbus data fail: pmbus_id=%u,\n", bus_id); return -EPERM; } mutex_lock(&pmbus->lock); msg.data = tmp; msg.data_len = sizeof(u16); hisi_pmbus_fill_msg(&msg, PMBUS_READ_WORD, slave_addr, command); ret = hisi_pmbus_xfer(pmbus, &msg); if (ret != 0) { mutex_unlock(&pmbus->lock); return ret; } *data = (((u16)tmp[1]) << 8) + ((u16)tmp[0]); // 高8位 mutex_unlock(&pmbus->lock); return 0; } EXPORT_SYMBOL(kdrv_pmbus_read_word); int kdrv_pmbus_write_block_data(u32 bus_id, u8 slave_addr, u16 command, u8 *pbuf, u32 len) { struct hisi_pmbus_data *pmbus = NULL; struct pmbus_msg msg = { 0 }; int ret; if ((pbuf == NULL) || (len == 0)) { pr_err("[iWare][Error] para err: bus_id(%d),slave_addr(0x%x), len(%u)\n", bus_id, slave_addr, len); return -EINVAL; } if (len > PMBUS_BLOCK_MAX) { pr_err("[iWare][Error] para err: len(%u) exceed PMBUS_BLOCK_MAX(32)\n", len); return -EINVAL; } pmbus = hisi_pmbus_data_get_by_id(bus_id); if (pmbus == NULL) { pr_err("[iWare][Error] get pmbus data fail: pmbus_id=%u,\n", bus_id); return -EPERM; } mutex_lock(&pmbus->lock); msg.data = pbuf; msg.data_len = (u8)len; hisi_pmbus_fill_msg(&msg, PMBUS_WRITE_BLOCK, slave_addr, command); ret = hisi_pmbus_xfer(pmbus, &msg); if (ret != 0) { mutex_unlock(&pmbus->lock); return ret; } mutex_unlock(&pmbus->lock); return 0; } EXPORT_SYMBOL(kdrv_pmbus_write_block_data); int kdrv_pmbus_read_block_data(u32 bus_id, u8 slave_addr, u16 command, u8 *pbuf, u32 len) { struct hisi_pmbus_data *pmbus = NULL; struct pmbus_msg msg = { 0 }; int ret; if ((pbuf == NULL) || (len == 0)) { pr_err("[iWare][Error] para err: bus_id(%d),slave_addr(0x%x), len(%u)\n", bus_id, slave_addr, len); return -EINVAL; } if (len > PMBUS_BLOCK_MAX) { pr_err("[iWare][Error] para err: len(%u) exceed PMBUS_BLOCK_MAX(32)\n", len); return -EINVAL; } pmbus = hisi_pmbus_data_get_by_id(bus_id); if (pmbus == NULL) { pr_err("[iWare][Error] get pmbus data fail: pmbus_id=%u,\n", bus_id); return -EPERM; } mutex_lock(&pmbus->lock); msg.data = pbuf; msg.data_len = (u8)len; hisi_pmbus_fill_msg(&msg, PMBUS_READ_BLOCK, slave_addr, command); ret = hisi_pmbus_xfer(pmbus, &msg); if (ret != 0) { mutex_unlock(&pmbus->lock); return ret; } mutex_unlock(&pmbus->lock); return 0; } EXPORT_SYMBOL(kdrv_pmbus_read_block_data); " “测试步骤为 ”insmod /lib/udrivers/hi309a_pmbus_api_test.ko devmem 0xfa860204 w 0 devmem 0xfa860220 w 0 echo 3 1 0x70 0x21 0xf4 > /proc/pmbus_test (设置输出电压) “ 然后再设置输出电压之后报以下错误 [60585.219727] [iWare][Error] pmbus_write timeout! raw_int_status:0x10 [60585.227034] [iWare][Info] pmbus hang recovery done [60585.231848] kdrv_pmbus_write_word fail bus_id:1, addr:0x70, cmd:0x21 hi309a /lib/udrivers # cat /proc/interrupts | grep i2c 87: 0 0 0 0 0 0 0 0 GICv3 294 Level hisi-i2c 88: 0 0 0 0 0 0 0 0 GICv3 295 Level hisi-i2c 89: 0 0 0 0 0 0 0 0 GICv3 297 Level hisi-i2c 90: 0 0 0 0 0 0 0 0 GICv3 298 Level hisi-i2c 91: 0 0 0 0 0 0 0 0 GICv3 299 Level hisi-i2c 92: 0 0 0 0 0 0 0 0 GICv3 300 Level hisi-i2c 93: 0 0 0 0 0 0 0 0 GICv3 301 Level hisi-i2c 94: 0 0 0 0 0 0 0 0 GICv3 686 Level hisi-i2c 95: 0 0 0 0 0 0 0 0 GICv3 687 Level hisi-i2c hi309a /lib/udrivers # dmesg | grep -e "iWare" -e "PMBUS" [ 10.511319] [iWare][Info] IOMUX register size (4 bytes) [ 10.519453] hgpio fa540000.gpio: [iWare][Info] hisi_gpio_probe: start [ 10.526277] hgpio fa550000.gpio: [iWare][Info] hisi_gpio_probe: start [ 10.533075] hgpio fa560000.gpio: [iWare][Info] hisi_gpio_probe: start [ 10.539847] hgpio fa570000.gpio: [iWare][Info] hisi_gpio_probe: start [ 10.546656] hgpio fa580000.gpio: [iWare][Info] hisi_gpio_probe: start [ 10.553439] hgpio fa590000.gpio: [iWare][Info] hisi_gpio_probe: start [ 10.560210] hgpio fa5a0000.gpio: [iWare][Info] hisi_gpio_probe: start [ 10.567034] hgpio fa5b0000.gpio: [iWare][Info] hisi_gpio_probe: start [ 10.573814] hgpio faa90000.gpio: [iWare][Info] hisi_gpio_probe: start [ 10.580559] hgpio faaa0000.gpio: [iWare][Info] hisi_gpio_probe: start [ 10.590111] hisi_spi_drv fa400000.spi: [iWare] can't get clk-freq, use default value [ 10.597941] hisi_spi_drv fa400000.spi: [iWare][Info] [hisi spi_get_clk_rst_info] get rst clk success [ 10.607234] hisi_spi_drv fa400000.spi: [iWare][Info] spi reset success [ 10.614459] hisi_spi_drv fa410000.spi: [iWare] can't get clk-freq, use default value [ 10.622295] hisi_spi_drv fa410000.spi: [iWare][Info] [hisi spi_get_clk_rst_info] get rst clk success [ 10.631589] hisi_spi_drv fa410000.spi: [iWare][Info] spi reset success [ 10.638791] hisi_spi_drv fa420000.spi: [iWare] can't get clk-freq, use default value [ 10.646633] hisi_spi_drv fa420000.spi: [iWare][Info] [hisi spi_get_clk_rst_info] get rst clk success [ 10.655934] hisi_spi_drv fa420000.spi: [iWare][Info] spi reset success [ 10.663149] hisi_spi_drv fa430000.spi: [iWare] can't get clk-freq, use default value [ 10.670998] hisi_spi_drv fa430000.spi: [iWare][Info] [hisi spi_get_clk_rst_info] get rst clk success [ 10.680292] hisi_spi_drv fa430000.spi: [iWare][Info] spi reset success [ 10.690479] hisi-i2c fa380000.i2c: [iWare][Info] hisi_i2c_probe start [ 10.697006] hisi-i2c fa380000.i2c: [iWare][Info] i2c scl_high_ratio no cfg [ 10.703944] hisi-i2c fa380000.i2c: [iWare][Info] get rst and clk from dts [ 10.719963] [iWare][Info] hisi_i2c_calcu_cfg_cnt bus_freq_hz 100000, scl_fall_cnt 60 scl_rise_cnt 60 total_cnt 2000 scl_hcnt 920 scl_lcnt 1080 [ 10.732890] [iWare][Info] hisi_i2c_calcu_cfg_cnt sda_hold_cnt 80 spk_len 5 scl_hcnt 848 scl_lcnt 1019 [ 10.742442] hisi-i2c fa380000.i2c: [iWare][Info] hisi_i2c_probe end [ 10.749010] hisi-i2c fa390000.i2c: [iWare][Info] hisi_i2c_probe start [ 10.755526] hisi-i2c fa390000.i2c: [iWare][Info] i2c scl_high_ratio no cfg [ 10.762448] hisi-i2c fa390000.i2c: [iWare][Info] get rst and clk from dts [ 10.778437] [iWare][Info] hisi_i2c_calcu_cfg_cnt bus_freq_hz 100000, scl_fall_cnt 60 scl_rise_cnt 60 total_cnt 2000 scl_hcnt 920 scl_lcnt 1080 [ 10.791367] [iWare][Info] hisi_i2c_calcu_cfg_cnt sda_hold_cnt 80 spk_len 5 scl_hcnt 848 scl_lcnt 1019 [ 10.800891] hisi-i2c fa390000.i2c: [iWare][Info] hisi_i2c_probe end [ 10.807415] hisi-i2c fa3b0000.i2c: [iWare][Info] hisi_i2c_probe start [ 10.813923] hisi-i2c fa3b0000.i2c: [iWare][Info] i2c scl_high_ratio no cfg [ 10.820847] hisi-i2c fa3b0000.i2c: [iWare][Info] get rst and clk from dts [ 10.836836] [iWare][Info] hisi_i2c_calcu_cfg_cnt bus_freq_hz 100000, scl_fall_cnt 60 scl_rise_cnt 60 total_cnt 2000 scl_hcnt 920 scl_lcnt 1080 [ 10.849764] [iWare][Info] hisi_i2c_calcu_cfg_cnt sda_hold_cnt 80 spk_len 5 scl_hcnt 848 scl_lcnt 1019 [ 10.859275] hisi-i2c fa3b0000.i2c: [iWare][Info] hisi_i2c_probe end [ 10.865787] hisi-i2c fa3c0000.i2c: [iWare][Info] hisi_i2c_probe start [ 10.872298] hisi-i2c fa3c0000.i2c: [iWare][Info] i2c scl_high_ratio no cfg [ 10.879223] hisi-i2c fa3c0000.i2c: [iWare][Info] get rst and clk from dts [ 10.895207] [iWare][Info] hisi_i2c_calcu_cfg_cnt bus_freq_hz 100000, scl_fall_cnt 60 scl_rise_cnt 60 total_cnt 2000 scl_hcnt 920 scl_lcnt 1080 [ 10.908133] [iWare][Info] hisi_i2c_calcu_cfg_cnt sda_hold_cnt 80 spk_len 5 scl_hcnt 848 scl_lcnt 1019 [ 10.917641] hisi-i2c fa3c0000.i2c: [iWare][Info] hisi_i2c_probe end [ 10.924135] hisi-i2c fa3d0000.i2c: [iWare][Info] hisi_i2c_probe start [ 10.930644] hisi-i2c fa3d0000.i2c: [iWare][Info] i2c scl_high_ratio no cfg [ 10.937559] hisi-i2c fa3d0000.i2c: [iWare][Info] get rst and clk from dts [ 10.953538] [iWare][Info] hisi_i2c_calcu_cfg_cnt bus_freq_hz 100000, scl_fall_cnt 60 scl_rise_cnt 60 total_cnt 2000 scl_hcnt 920 scl_lcnt 1080 [ 10.966464] [iWare][Info] hisi_i2c_calcu_cfg_cnt sda_hold_cnt 80 spk_len 5 scl_hcnt 848 scl_lcnt 1019 [ 10.975986] hisi-i2c fa3d0000.i2c: [iWare][Info] hisi_i2c_probe end [ 10.982483] hisi-i2c fa3e0000.i2c: [iWare][Info] hisi_i2c_probe start [ 10.988993] hisi-i2c fa3e0000.i2c: [iWare][Info] i2c scl_high_ratio no cfg [ 10.995908] hisi-i2c fa3e0000.i2c: [iWare][Info] get rst and clk from dts [ 11.011896] [iWare][Info] hisi_i2c_calcu_cfg_cnt bus_freq_hz 100000, scl_fall_cnt 60 scl_rise_cnt 60 total_cnt 2000 scl_hcnt 920 scl_lcnt 1080 [ 11.024821] [iWare][Info] hisi_i2c_calcu_cfg_cnt sda_hold_cnt 80 spk_len 5 scl_hcnt 848 scl_lcnt 1019 [ 11.034336] hisi-i2c fa3e0000.i2c: [iWare][Info] hisi_i2c_probe end [ 11.040848] hisi-i2c fa3f0000.i2c: [iWare][Info] hisi_i2c_probe start [ 11.047359] hisi-i2c fa3f0000.i2c: [iWare][Info] i2c scl_high_ratio no cfg [ 11.054275] hisi-i2c fa3f0000.i2c: [iWare][Info] get rst and clk from dts [ 11.070263] [iWare][Info] hisi_i2c_calcu_cfg_cnt bus_freq_hz 100000, scl_fall_cnt 60 scl_rise_cnt 60 total_cnt 2000 scl_hcnt 920 scl_lcnt 1080 [ 11.083190] [iWare][Info] hisi_i2c_calcu_cfg_cnt sda_hold_cnt 80 spk_len 5 scl_hcnt 848 scl_lcnt 1019 [ 11.092704] hisi-i2c fa3f0000.i2c: [iWare][Info] hisi_i2c_probe end [ 11.099221] hisi-i2c faab0000.i2c: [iWare][Info] hisi_i2c_probe start [ 11.105733] hisi-i2c faab0000.i2c: [iWare][Info] i2c scl_high_ratio no cfg [ 11.112649] hisi-i2c faab0000.i2c: [iWare][Info] get rst and clk from dts [ 11.128636] [iWare][Info] hisi_i2c_calcu_cfg_cnt bus_freq_hz 100000, scl_fall_cnt 60 scl_rise_cnt 60 total_cnt 2000 scl_hcnt 920 scl_lcnt 1080 [ 11.141563] [iWare][Info] hisi_i2c_calcu_cfg_cnt sda_hold_cnt 80 spk_len 5 scl_hcnt 848 scl_lcnt 1019 [ 11.151068] hisi-i2c faab0000.i2c: [iWare][Info] hisi_i2c_probe end [ 11.157580] hisi-i2c faac0000.i2c: [iWare][Info] hisi_i2c_probe start [ 11.164093] hisi-i2c faac0000.i2c: [iWare][Info] i2c scl_high_ratio no cfg [ 11.171009] hisi-i2c faac0000.i2c: [iWare][Info] get rst and clk from dts [ 11.186998] [iWare][Info] hisi_i2c_calcu_cfg_cnt bus_freq_hz 100000, scl_fall_cnt 60 scl_rise_cnt 60 total_cnt 2000 scl_hcnt 920 scl_lcnt 1080 [ 11.199925] [iWare][Info] hisi_i2c_calcu_cfg_cnt sda_hold_cnt 80 spk_len 5 scl_hcnt 848 scl_lcnt 1019 [ 11.209444] hisi-i2c faac0000.i2c: [iWare][Info] hisi_i2c_probe end [ 11.218700] pmbus_drv fa870000.pmbus0: [iWare][Info] hisi_pmbus_probe:start [ 11.225815] pmbus_drv fa870000.pmbus0: [iWare][Info] clk_freq 200 bus_freq 100000 scl_high_ratio 50, timeout_ms 35 high_idle_us 100 hold_time_ns 625 [ 11.239267] pmbus_drv fa870000.pmbus0: [iWare][Info] avs_wr_unlock_key 0x5a5a5a5a pmbus_wr_unlock_key 0x5a5a5a5a i2c_unlock_key 0x5a5a5a5a [ 11.251844] [iWare][Info] total_cnt 2000, hcnt=1000, lcnt=1000 hold_cnt=125, timeout_cnt=7000000, idle_cnt=20000, [ 11.262158] pmbus_drv fa870000.pmbus0: [iWare][Info] hisi_pmbus_probe: end [ 11.269205] pmbus_drv fa880000.pmbus1: [iWare][Info] hisi_pmbus_probe:start [ 11.276309] pmbus_drv fa880000.pmbus1: [iWare][Info] clk_freq 200 bus_freq 100000 scl_high_ratio 50, timeout_ms 35 high_idle_us 100 hold_time_ns 625 [ 11.289760] pmbus_drv fa880000.pmbus1: [iWare][Info] avs_wr_unlock_key 0x5a5a5a5a pmbus_wr_unlock_key 0x5a5a5a5a i2c_unlock_key 0x5a5a5a5a [ 11.302337] [iWare][Info] total_cnt 2000, hcnt=1000, lcnt=1000 hold_cnt=125, timeout_cnt=7000000, idle_cnt=20000, [ 11.312651] pmbus_drv fa880000.pmbus1: [iWare][Info] hisi_pmbus_probe: end [ 11.319689] pmbus_drv fa890000.pmbus2: [iWare][Info] hisi_pmbus_probe:start [ 11.326788] pmbus_drv fa890000.pmbus2: [iWare][Info] clk_freq 200 bus_freq 100000 scl_high_ratio 50, timeout_ms 35 high_idle_us 100 hold_time_ns 625 [ 11.340247] pmbus_drv fa890000.pmbus2: [iWare][Info] avs_wr_unlock_key 0x5a5a5a5a pmbus_wr_unlock_key 0x5a5a5a5a i2c_unlock_key 0x5a5a5a5a [ 11.352823] [iWare][Info] total_cnt 2000, hcnt=1000, lcnt=1000 hold_cnt=125, timeout_cnt=7000000, idle_cnt=20000, [ 11.363138] pmbus_drv fa890000.pmbus2: [iWare][Info] hisi_pmbus_probe: end [ 11.370173] pmbus_drv fa8a0000.pmbus3: [iWare][Info] hisi_pmbus_probe:start [ 11.377269] pmbus_drv fa8a0000.pmbus3: [iWare][Info] clk_freq 200 bus_freq 100000 scl_high_ratio 50, timeout_ms 35 high_idle_us 100 hold_time_ns 625 [ 11.390720] pmbus_drv fa8a0000.pmbus3: [iWare][Info] avs_wr_unlock_key 0x5a5a5a5a pmbus_wr_unlock_key 0x5a5a5a5a i2c_unlock_key 0x5a5a5a5a [ 11.403295] [iWare][Info] total_cnt 2000, hcnt=1000, lcnt=1000 hold_cnt=125, timeout_cnt=7000000, idle_cnt=20000, [ 11.413609] pmbus_drv fa8a0000.pmbus3: [iWare][Info] hisi_pmbus_probe: end [ 11.423408] sfc_drv fa5c0000.sfc0: [iWare][Info]sfc skip_host_reset 0, 0, 0, 0 [ 11.430719] sfc_drv fa5c0000.sfc0: [iWare][Info]clk_div= 2, hsfc->dummy_cnt= 4! 0, 0 [ 11.438504] sfc_drv fa5c0000.sfc0: [iWare][Info]hisi_sfc_register_nor! 0, 0, 0, 0 [ 11.446026] sfc_drv fa5c0000.sfc0: [iWare][Info]sfc-rx-bus-width = 1, 0, 0, 0 [ 11.453193] sfc_drv fa5c0000.sfc0: [iWare][Info]sfc-tx-bus-width = 1, 0, 0, 0 [ 11.466267] sfc_drv fa5c0000.sfc0: [iWare][Info]after spi_nor_scan read_proto(0x10101),write_proto(0x10101)addr_width(0x4),erase_op(0x21) [ 11.478678] sfc_drv fa5c0000.sfc0: [iWare][Info]read_op(0x13), dummy(0x0),pp_op(0x12),erasesize 4096 [ 11.520738] sfc_drv fa5c0000.sfc0: [iWare][Info]hisi_sfc_register_nor! 0, 0, 0, 0 [ 11.528272] sfc_drv fa5c0000.sfc0: [iWare][Info]sfc-rx-bus-width = 1, 0, 0, 0 [ 11.535443] sfc_drv fa5c0000.sfc0: [iWare][Info]sfc-tx-bus-width = 1, 0, 0, 0 [ 11.550161] sfc_drv fa5c0000.sfc0: [iWare][Error]cs 1 spi_nor_scan fail! 0, 0, 0 [ 11.557594] sfc_drv fa5c0000.sfc0: [iWare][Error]hisi_sfc_register_nor fail! 0, 0, 0, 0 [ 11.565636] sfc_drv fa5c0000.sfc0: [iWare][Info]total_blk_num =16384, 0, 0, 0 [ 11.572806] [iWare][Info]hisi_sfc_dfx_count_init, use malloc mem! 0, 0, 0, 0 [ 11.579930] [iWare][Info]init_mem_area inited success! 0, 0, 0, 0 [ 11.586324] [iWare][Info]init_mem_area inited success! 0, 0, 0, 0 [ 11.600428] hilink serdes: [iWare][Info]clock_route_mode not config, use default mode 0, 0000 [ 11.609108] hilink serdes: [iWare][Info]lane 0 dfe_param not cfg! defalut dfe = <1 1> 000 [ 11.617414] hilink serdes: [iWare][Info]lane 1 dfe_param not cfg! defalut dfe = <1 1> 000 [ 11.625717] hilink serdes: [iWare][Info]lane 8 dfe_param not cfg! defalut dfe = <1 1> 000 [ 11.634020] hilink serdes: [iWare][Info]lane 9 dfe_param not cfg! defalut dfe = <1 1> 000 [ 11.649135] hilink serdes: [iWare][Info]hserdes->reset_mode 0, 000 [ 11.655377] [iWare][Info]chip0 sema_wr init ... pass! [ 11.655383] [iWare][Info]chip_serdes_hardware_init ok [ 11.665533] [iWare][Info]Serdes init from dts, lane_mask = 0x3ff pcie_gen4_link_mode=0 00 [ 11.673748] [iWare][Info]macro_id=2, pcie_cnt=2, sata_cnt=0, 0 [ 11.679699] [iWare][Info]macro_id=2 serdes_reinit, 000 [ 11.684948] [iWare][Info]serdes_reinit:macro_id=2 lane_id=0, mac_id 5 rate:11 pcie_mode 2, pcie_width 2 [ 11.694474] [iWare][Info]serdes_reinit:macro_id=2 lane_id=1, mac_id 5 rate:11 pcie_mode 2, pcie_width 2 [ 11.704009] [iWare][Info]hisds_cs_init_det match, sds_id 6 cs need init [ 11.710658] [iWare][Info]hisds_cs_init_det match, sds_id 7 cs need init [ 11.717325] [iWare][Info]chip30_serdes_par_init_process line 142 macro 2 powerup [ 11.766898] [iWare][Info][macro_fw_init_calibration]Macro calibration success [ 11.776892] [iWare][Info]Adapt Config success! [ 11.776897] [iWare][Info]serdes_macro_init, macro_id=2 single_lane_init_mask=0xc 00 [ 11.789225] [iWare][Info]macro_id:2, lane:2,serdes_single_lane_init 00 [ 11.795875] [iWare][Info]chip_serdes_lane_init phy_sds_id 8 cs need init [ 11.802699] [iWare][Info]csinfo: macro_id = 2, pll_id = 0, rate = 6, refclk = 156250, refclk_sel = 0, vco_freq = 15000000, hs_clk = 10000000, use_mode = 64 [ 11.821475] [iWare][Info]Clockslice calibration success! [ 11.827123] [iWare][Info]ds 2 firmware reset success! [ 11.840429] [iWare][Info]macro_id:2, lane:3,serdes_single_lane_init 00 [ 11.852146] [iWare][Info]chip_serdes_lane_init phy_sds_id 9 cs no need init [ 11.859238] [iWare][Info]ds 3 firmware reset success! [ 11.873344] [iWare][Info]macro_id=0, pcie_cnt=0, sata_cnt=0, 0 [ 11.884364] [iWare][Info]macro_id=0 serdes_reinit, 000 [ 11.889613] [iWare][Info]serdes_reinit:macro_id=0 lane_id=0, mac_id 4 rate:2 pcie_mode 0, pcie_width 0 [ 11.899048] [iWare][Info]serdes_reinit:macro_id=0 lane_id=1, mac_id 5 rate:2 pcie_mode 0, pcie_width 0 [ 11.908483] [iWare][Info]serdes_reinit:macro_id=0 lane_id=2, mac_id 0 rate:18 pcie_mode 0, pcie_width 0 [ 11.918006] [iWare][Info]serdes_reinit:macro_id=0 lane_id=3, mac_id 1 rate:18 pcie_mode 0, pcie_width 0 [ 11.927536] [iWare][Info]hisds_cs_init_det match, sds_id 0 cs need init [ 11.934183] [iWare][Info]hisds_cs_init_det match, sds_id 1 cs need init [ 11.940830] [iWare][Info]hisds_cs_init_det match, sds_id 2 cs need init [ 11.947476] [iWare][Info]hisds_cs_init_det match, sds_id 3 cs need init [ 11.954142] [iWare][Info]chip30_serdes_par_init_process line 142 macro 0 powerup [ 12.008900] [iWare][Info][macro_fw_init_calibration]Macro calibration success [ 12.018886] [iWare][Info]Adapt Config success! [ 12.018890] [iWare][Info]serdes_macro_init, macro_id=0 single_lane_init_mask=0x0 00 [ 12.031220] [iWare][Info]macro_id=1, pcie_cnt=1, sata_cnt=1, 0 [ 12.037168] [iWare][Info]macro_id=1 serdes_reinit, 000 [ 12.042417] [iWare][Info]serdes_reinit:macro_id=1 lane_id=1, mac_id 0 rate:13 pcie_mode 2, pcie_width 1 [ 12.051947] [iWare][Info]hisds_cs_init_det match, sds_id 5 cs need init [ 12.058614] [iWare][Info]chip30_serdes_par_init_process line 142 macro 1 powerup [ 12.109900] [iWare][Info][macro_fw_init_calibration]Macro calibration success [ 12.119886] [iWare][Info]Adapt Config success! [ 12.119890] [iWare][Info]serdes_macro_init, macro_id=1 single_lane_init_mask=0x1 00 [ 12.132220] [iWare][Info]macro_id:1, lane:0,serdes_single_lane_init 00 [ 12.138866] [iWare][Info]chip_serdes_lane_init phy_sds_id 4 cs need init [ 12.145690] [iWare][Info]csinfo: macro_id = 1, pll_id = 0, rate = 17, refclk = 100000, refclk_sel = 1, vco_freq = 12000000, hs_clk = 6000000, use_mode = 2 [ 12.164643] [iWare][Info]Clockslice calibration success! [ 12.170081] [iWare][Info]ds 0 firmware reset success! [ 12.181352] [iWare][Info]serdes_ds_dfe_init: macro(0) ds(0) dfe init 1 1 [ 12.193266] [iWare][Info]serdes_ds_dfe_init: macro(0) ds(1) dfe init 1 1 [ 12.200006] [iWare][Info]serdes_ds_dfe_init: macro(2) ds(2) dfe init 1 1 [ 12.206846] [iWare][Info]serdes_ds_dfe_init: macro(2) ds(3) dfe init 1 1 [ 12.217692] udrv-pcie b00000000.pcie: [iWare] no declare type support, default rp mode [ 12.240709] [iWare][Info] host_id: 0x0 [ 12.244913] [iWare][Info] host_support_type_mask: 0x2 [ 12.249989] [iWare][Info] core_version: 0x0 [ 12.254190] [iWare][Info] msi_irq: 0x45 [ 12.258479] [iWare][Info] clk_num: 0x2 [ 12.262681] [iWare][Info] rst_num: 0x1 [ 12.266884] [iWare][Info] port_id: 0x0 [ 12.271085] [iWare][Info] port_type: 0x1 [ 12.275286] [iWare][Info] lport_id: 0x0 [ 12.279487] [iWare][Info] idr: 0x0 [ 12.283689] [iWare][Info] core_id: 0x0 [ 12.287891] [iWare][Info] lane_num: 0x1 [ 12.292092] [iWare][Info] target_speed: 0x1 [ 12.296294] [iWare][Info] max_lanes: 0x1 [ 12.300495] [iWare][Info] max_speed: 0x3 [ 12.304697] [iWare][Info] is_probe: 0x1 [ 12.308898] [iWare][Info] size = 0x1f800000 atu_mode = 0x0 [ 12.424354] udrv-pcie b00000000.pcie: [iWare][Info] msi#0 address_hi 0x0 address_lo 0x700000 [ 12.432847] udrv-pcie b00000000.pcie: [iWare][Info] msi#1 address_hi 0x0 address_lo 0x700000 [ 12.441324] udrv-pcie b00000000.pcie: [iWare][Info] msi#2 address_hi 0x0 address_lo 0x700000 [ 12.449801] udrv-pcie b00000000.pcie: [iWare][Info] msi#3 address_hi 0x0 address_lo 0x700000 [ 12.458278] udrv-pcie b00000000.pcie: [iWare][Info] msi#4 address_hi 0x0 address_lo 0x700000 [ 12.466755] udrv-pcie b00000000.pcie: [iWare][Info] msi#5 address_hi 0x0 address_lo 0x700000 [ 12.475232] udrv-pcie b00000000.pcie: [iWare][Info] msi#6 address_hi 0x0 address_lo 0x700000 [ 12.483708] udrv-pcie b00000000.pcie: [iWare][Info] msi#7 address_hi 0x0 address_lo 0x700000 [ 12.492185] udrv-pcie b00000000.pcie: [iWare][Info] msi#8 address_hi 0x0 address_lo 0x700000 [ 12.500662] udrv-pcie b00000000.pcie: [iWare][Info] msi#9 address_hi 0x0 address_lo 0x700000 [ 12.509139] udrv-pcie b00000000.pcie: [iWare][Info] msi#10 address_hi 0x0 address_lo 0x700000 [ 12.517703] udrv-pcie b00000000.pcie: [iWare][Info] msi#11 address_hi 0x0 address_lo 0x700000 [ 12.526267] udrv-pcie b00000000.pcie: [iWare][Info] msi#12 address_hi 0x0 address_lo 0x700000 [ 12.534830] udrv-pcie b00000000.pcie: [iWare][Info] msi#13 address_hi 0x0 address_lo 0x700000 [ 12.543394] udrv-pcie b00000000.pcie: [iWare][Info] msi#14 address_hi 0x0 address_lo 0x700000 [ 12.551958] udrv-pcie b00000000.pcie: [iWare][Info] msi#15 address_hi 0x0 address_lo 0x700000 [ 12.560521] udrv-pcie b00000000.pcie: [iWare][Info] msi#16 address_hi 0x0 address_lo 0x700000 [ 12.569085] udrv-pcie b00000000.pcie: [iWare][Info] msi#17 address_hi 0x0 address_lo 0x700000 [ 12.577648] udrv-pcie b00000000.pcie: [iWare][Info] msi#18 address_hi 0x0 address_lo 0x700000 [ 12.586212] udrv-pcie b00000000.pcie: [iWare][Info] msi#19 address_hi 0x0 address_lo 0x700000 [ 12.594775] udrv-pcie b00000000.pcie: [iWare][Info] msi#20 address_hi 0x0 address_lo 0x700000 [ 12.603349] udrv-pcie b00000000.pcie: [iWare][Info] msi#21 address_hi 0x0 address_lo 0x700000 [ 12.611914] udrv-pcie b00000000.pcie: [iWare][Info] msi#22 address_hi 0x0 address_lo 0x700000 [ 12.620478] udrv-pcie b00000000.pcie: [iWare][Info] msi#23 address_hi 0x0 address_lo 0x700000 [ 12.629042] udrv-pcie b00000000.pcie: [iWare][Info] msi#24 address_hi 0x0 address_lo 0x700000 [ 12.637606] udrv-pcie b00000000.pcie: [iWare][Info] msi#25 address_hi 0x0 address_lo 0x700000 [ 12.646170] udrv-pcie b00000000.pcie: [iWare][Info] msi#26 address_hi 0x0 address_lo 0x700000 [ 12.654734] udrv-pcie b00000000.pcie: [iWare][Info] msi#27 address_hi 0x0 address_lo 0x700000 [ 12.663297] udrv-pcie b00000000.pcie: [iWare][Info] msi#28 address_hi 0x0 address_lo 0x700000 [ 12.671860] udrv-pcie b00000000.pcie: [iWare][Info] msi#29 address_hi 0x0 address_lo 0x700000 [ 12.680423] udrv-pcie b00000000.pcie: [iWare][Info] msi#30 address_hi 0x0 address_lo 0x700000 [ 12.688987] udrv-pcie b00000000.pcie: [iWare][Info] msi#31 address_hi 0x0 address_lo 0x700000 [ 12.698007] udrv-pcie b00000000.pcie: [iWare][Info] msi#0 address_hi 0x0 address_lo 0x700000 [ 12.732152] udrv-pcie b20000000.pcie: [iWare] no declare type support, default rp mode [ 12.755170] [iWare][Info] host_id: 0x1 [ 12.759376] [iWare][Info] host_support_type_mask: 0x2 [ 12.764450] [iWare][Info] core_version: 0x0 [ 12.768651] [iWare][Info] msi_irq: 0x46 [ 12.772941] [iWare][Info] clk_num: 0x2 [ 12.777142] [iWare][Info] rst_num: 0x1 [ 12.781345] [iWare][Info] port_id: 0x0 [ 12.785546] [iWare][Info] port_type: 0x1 [ 12.789749] [iWare][Info] lport_id: 0x1 [ 12.793951] [iWare][Info] idr: 0x1 [ 12.798153] [iWare][Info] core_id: 0x0 [ 12.802355] [iWare][Info] lane_num: 0x1 [ 12.806558] [iWare][Info] target_speed: 0x1 [ 12.810759] [iWare][Info] max_lanes: 0x1 [ 12.814962] [iWare][Info] max_speed: 0x3 [ 12.819163] [iWare][Info] is_probe: 0x0 [ 12.823366] [iWare][Info] size = 0x1f800000 atu_mode = 0x0 [ 12.861135] udrv-pcie b40000000.pcie: [iWare] no declare type support, default rp mode [ 12.884117] [iWare][Info] host_id: 0x2 [ 12.888323] [iWare][Info] host_support_type_mask: 0x2 [ 12.893399] [iWare][Info] core_version: 0x0 [ 12.897601] [iWare][Info] msi_irq: 0x47 [ 12.901891] [iWare][Info] clk_num: 0x2 [ 12.906092] [iWare][Info] rst_num: 0x1 [ 12.910295] [iWare][Info] port_id: 0x0 [ 12.914496] [iWare][Info] port_type: 0x1 [ 12.918699] [iWare][Info] lport_id: 0x2 [ 12.922901] [iWare][Info] idr: 0x2 [ 12.927103] [iWare][Info] core_id: 0x0 [ 12.931305] [iWare][Info] lane_num: 0x1 [ 12.935507] [iWare][Info] target_speed: 0x1 [ 12.939708] [iWare][Info] max_lanes: 0x1 [ 12.943911] [iWare][Info] max_speed: 0x3 [ 12.948114] [iWare][Info] is_probe: 0x0 [ 12.952317] [iWare][Info] size = 0x1f800000 atu_mode = 0x0 [ 12.990050] udrv-pcie b60000000.pcie: [iWare] no declare type support, default rp mode [ 13.013032] [iWare][Info] host_id: 0x3 [ 13.017238] [iWare][Info] host_support_type_mask: 0x2 [ 13.022313] [iWare][Info] core_version: 0x0 [ 13.026515] [iWare][Info] msi_irq: 0x48 [ 13.030804] [iWare][Info] clk_num: 0x2 [ 13.035006] [iWare][Info] rst_num: 0x1 [ 13.039209] [iWare][Info] port_id: 0x0 [ 13.043410] [iWare][Info] port_type: 0x1 [ 13.047611] [iWare][Info] lport_id: 0x3 [ 13.051813] [iWare][Info] idr: 0x3 [ 13.056015] [iWare][Info] core_id: 0x0 [ 13.060217] [iWare][Info] lane_num: 0x1 [ 13.064420] [iWare][Info] target_speed: 0x1 [ 13.068622] [iWare][Info] max_lanes: 0x1 [ 13.072825] [iWare][Info] max_speed: 0x3 [ 13.077027] [iWare][Info] is_probe: 0x0 [ 13.081230] [iWare][Info] size = 0x1f800000 atu_mode = 0x0 [ 13.118957] udrv-pcie b80000000.pcie: [iWare] no declare type support, default rp mode [ 13.141928] [iWare][Info] host_id: 0x4 [ 13.146133] [iWare][Info] host_support_type_mask: 0x2 [ 13.151208] [iWare][Info] core_version: 0x0 [ 13.155410] [iWare][Info] msi_irq: 0x49 [ 13.159700] [iWare][Info] clk_num: 0x2 [ 13.163903] [iWare][Info] rst_num: 0x1 [ 13.168105] [iWare][Info] port_id: 0x0 [ 13.172308] [iWare][Info] port_type: 0x1 [ 13.176511] [iWare][Info] lport_id: 0x4 [ 13.180713] [iWare][Info] idr: 0x4 [ 13.184915] [iWare][Info] core_id: 0x0 [ 13.189118] [iWare][Info] lane_num: 0x2 [ 13.193320] [iWare][Info] target_speed: 0x1 [ 13.197522] [iWare][Info] max_lanes: 0x1 [ 13.201724] [iWare][Info] max_speed: 0x3 [ 13.205927] [iWare][Info] is_probe: 0x0 [ 13.210130] [iWare][Info] size = 0x1f800000 atu_mode = 0x0 [ 13.247854] udrv-pcie ba0000000.pcie: [iWare] no declare type support, default rp mode [ 13.270833] [iWare][Info] host_id: 0x5 [ 13.275037] [iWare][Info] host_support_type_mask: 0x2 [ 13.280112] [iWare][Info] core_version: 0x0 [ 13.284315] [iWare][Info] msi_irq: 0x4a [ 13.288605] [iWare][Info] clk_num: 0x2 [ 13.292807] [iWare][Info] rst_num: 0x1 [ 13.297010] [iWare][Info] port_id: 0x0 [ 13.301213] [iWare][Info] port_type: 0x1 [ 13.305415] [iWare][Info] lport_id: 0x5 [ 13.309617] [iWare][Info] idr: 0x5 [ 13.313820] [iWare][Info] core_id: 0x0 [ 13.318021] [iWare][Info] lane_num: 0x2 [ 13.322224] [iWare][Info] target_speed: 0x3 [ 13.326426] [iWare][Info] max_lanes: 0x2 [ 13.330629] [iWare][Info] max_speed: 0x3 [ 13.334832] [iWare][Info] is_probe: 0x1 [ 13.339034] [iWare][Info] size = 0x1f800000 atu_mode = 0x0 [ 13.454261] udrv-pcie ba0000000.pcie: [iWare][Info] msi#0 address_hi 0x0 address_lo 0x700000 [ 13.462754] udrv-pcie ba0000000.pcie: [iWare][Info] msi#1 address_hi 0x0 address_lo 0x700000 [ 13.471233] udrv-pcie ba0000000.pcie: [iWare][Info] msi#2 address_hi 0x0 address_lo 0x700000 [ 13.479711] udrv-pcie ba0000000.pcie: [iWare][Info] msi#3 address_hi 0x0 address_lo 0x700000 [ 13.488189] udrv-pcie ba0000000.pcie: [iWare][Info] msi#4 address_hi 0x0 address_lo 0x700000 [ 13.496666] udrv-pcie ba0000000.pcie: [iWare][Info] msi#5 address_hi 0x0 address_lo 0x700000 [ 13.505144] udrv-pcie ba0000000.pcie: [iWare][Info] msi#6 address_hi 0x0 address_lo 0x700000 [ 13.513622] udrv-pcie ba0000000.pcie: [iWare][Info] msi#7 address_hi 0x0 address_lo 0x700000 [ 13.522099] udrv-pcie ba0000000.pcie: [iWare][Info] msi#8 address_hi 0x0 address_lo 0x700000 [ 13.530577] udrv-pcie ba0000000.pcie: [iWare][Info] msi#9 address_hi 0x0 address_lo 0x700000 [ 13.539054] udrv-pcie ba0000000.pcie: [iWare][Info] msi#10 address_hi 0x0 address_lo 0x700000 [ 13.547619] udrv-pcie ba0000000.pcie: [iWare][Info] msi#11 address_hi 0x0 address_lo 0x700000 [ 13.556183] udrv-pcie ba0000000.pcie: [iWare][Info] msi#12 address_hi 0x0 address_lo 0x700000 [ 13.564748] udrv-pcie ba0000000.pcie: [iWare][Info] msi#13 address_hi 0x0 address_lo 0x700000 [ 13.573312] udrv-pcie ba0000000.pcie: [iWare][Info] msi#14 address_hi 0x0 address_lo 0x700000 [ 13.581877] udrv-pcie ba0000000.pcie: [iWare][Info] msi#15 address_hi 0x0 address_lo 0x700000 [ 13.590446] udrv-pcie ba0000000.pcie: [iWare][Info] msi#16 address_hi 0x0 address_lo 0x700000 [ 13.599010] udrv-pcie ba0000000.pcie: [iWare][Info] msi#17 address_hi 0x0 address_lo 0x700000 [ 13.607575] udrv-pcie ba0000000.pcie: [iWare][Info] msi#18 address_hi 0x0 address_lo 0x700000 [ 13.616139] udrv-pcie ba0000000.pcie: [iWare][Info] msi#19 address_hi 0x0 address_lo 0x700000 [ 13.624703] udrv-pcie ba0000000.pcie: [iWare][Info] msi#20 address_hi 0x0 address_lo 0x700000 [ 13.633268] udrv-pcie ba0000000.pcie: [iWare][Info] msi#21 address_hi 0x0 address_lo 0x700000 [ 13.641832] udrv-pcie ba0000000.pcie: [iWare][Info] msi#22 address_hi 0x0 address_lo 0x700000 [ 13.650397] udrv-pcie ba0000000.pcie: [iWare][Info] msi#23 address_hi 0x0 address_lo 0x700000 [ 13.658961] udrv-pcie ba0000000.pcie: [iWare][Info] msi#24 address_hi 0x0 address_lo 0x700000 [ 13.667525] udrv-pcie ba0000000.pcie: [iWare][Info] msi#25 address_hi 0x0 address_lo 0x700000 [ 13.676090] udrv-pcie ba0000000.pcie: [iWare][Info] msi#26 address_hi 0x0 address_lo 0x700000 [ 13.684654] udrv-pcie ba0000000.pcie: [iWare][Info] msi#27 address_hi 0x0 address_lo 0x700000 [ 13.693219] udrv-pcie ba0000000.pcie: [iWare][Info] msi#28 address_hi 0x0 address_lo 0x700000 [ 13.701783] udrv-pcie ba0000000.pcie: [iWare][Info] msi#29 address_hi 0x0 address_lo 0x700000 [ 13.710348] udrv-pcie ba0000000.pcie: [iWare][Info] msi#30 address_hi 0x0 address_lo 0x700000 [ 13.718913] udrv-pcie ba0000000.pcie: [iWare][Info] msi#31 address_hi 0x0 address_lo 0x700000 [ 13.727925] udrv-pcie ba0000000.pcie: [iWare][Info] msi#0 address_hi 0x0 address_lo 0x700000 [ 13.762078] udrv-pcie bc0000000.pcie: [iWare] no declare type support, default rp mode [ 13.785069] [iWare][Info] host_id: 0x6 [ 13.789272] [iWare][Info] host_support_type_mask: 0x2 [ 13.794348] [iWare][Info] core_version: 0x0 [ 13.798549] [iWare][Info] msi_irq: 0x4b [ 13.802839] [iWare][Info] clk_num: 0x2 [ 13.807040] [iWare][Info] rst_num: 0x1 [ 13.811242] [iWare][Info] port_id: 0x0 [ 13.815443] [iWare][Info] port_type: 0x1 [ 13.819644] [iWare][Info] lport_id: 0x6 [ 13.823845] [iWare][Info] idr: 0x6 [ 13.828047] [iWare][Info] core_id: 0x0 [ 13.832248] [iWare][Info] lane_num: 0x1 [ 13.836450] [iWare][Info] target_speed: 0x1 [ 13.840651] [iWare][Info] max_lanes: 0x1 [ 13.844852] [iWare][Info] max_speed: 0x3 [ 13.849053] [iWare][Info] is_probe: 0x0 [ 13.853256] [iWare][Info] size = 0x1f800000 atu_mode = 0x0 [ 13.891008] udrv-pcie be0000000.pcie: [iWare] no declare type support, default rp mode [ 13.913979] [iWare][Info] host_id: 0x7 [ 13.918183] [iWare][Info] host_support_type_mask: 0x2 [ 13.923257] [iWare][Info] core_version: 0x0 [ 13.927458] [iWare][Info] msi_irq: 0x4c [ 13.931747] [iWare][Info] clk_num: 0x2 [ 13.935948] [iWare][Info] rst_num: 0x1 [ 13.940149] [iWare][Info] port_id: 0x0 [ 13.944350] [iWare][Info] port_type: 0x1 [ 13.948551] [iWare][Info] lport_id: 0x7 [ 13.952753] [iWare][Info] idr: 0x7 [ 13.956955] [iWare][Info] core_id: 0x0 [ 13.961156] [iWare][Info] lane_num: 0x1 [ 13.965357] [iWare][Info] target_speed: 0x1 [ 13.969558] [iWare][Info] max_lanes: 0x1 [ 13.973758] [iWare][Info] max_speed: 0x3 [ 13.977961] [iWare][Info] is_probe: 0x0 [ 13.982163] [iWare][Info] size = 0x1f800000 atu_mode = 0x0 [ 14.022852] sata_hisi d8500000.sata_dfx: [iWare][Info] get rst and clk from dts [ 14.030355] [iWare][Info]set tx_bitorder 0 , rx_bitorder 1 [ 14.038323] [iWare][Info] udrv log init ok [ 14.093780] usb_hisi usb_hisi_0: [iWare] no misc base [ 14.099241] usb_hisi usb_hisi_1: [iWare] no misc base [ 371.687427] [iWare][Error] pmbus_write timeout! raw_int_status:0x10 [ 371.694731] [iWare][Info] pmbus hang recovery done [ 2064.422683] [iWare][Error] pmbus_write timeout! raw_int_status:0x10 [ 2064.429992] [iWare][Info] pmbus hang recovery done [ 2069.219986] [iWare][Error] wait read_finish timeout!! read_len[2] fifo num[0], raw_int_status:0x10 [ 2069.229992] [iWare][Info] pmbus hang recovery done [ 2069.234807] [iWare][Error] pmbus_read_bytes_v200 slave_addr(0x70), cmd(0x8b), time out [ 2069.243769] [iWare][Info] pmbus hang recovery done [ 2085.989229] [iWare][Error] pmbus_write timeout! raw_int_status:0x10 [ 2085.996530] [iWare][Info] pmbus hang recovery done hi309a /lib/udrivers # timed out waiting for input: auto-logoutprocess '/sbin/getty 115200 ttyS0' (pid 670) exited. Scheduling for restart. starting pid 692, tty '/dev/ttyS0': '/sbin/getty 115200 ttyS0' openEuler Embedded(openEuler Embedded Reference Distro) 24.03-LTS hi309a /dev/ttyS0 ______ _ | ____| | | ___ ____ ___ _____| |__ _ _| | ___ _ __ / _ \| _ \ / _ \ _ | __|| | | | |/ _ \ '__| | (_) | |_) | __/ | | | |___| |_| | | __/ | \___/| __/ \___|_| |_|______\____|_|\___|_| | | _____ _ _ _ _ |_| | __|_____| |_ ___ _| |_| |___ _| | | __| | . | -_| . | . | -_| . | |_____|_|_|_|___|___|___|___|___|___| Authorized uses only. All activity may be monitored and reported. 监控总线状态打印如上 请根据以上几段代码,帮我分析我出现kdrv_pmbus_write_word fail bus_id:1, addr:0x70, cmd:0x21的原因可能是什么,并给出完整解决方案”

cam_sensor_core_power_up+0x22c/0xb38 行 1223: [ 11.508309] cam_sensor_power_up+0x54/0x168 行 1224: [ 11.508312] cam_sensor_driver_cmd+0x35c/0x1378 行 1225: [ 11.508315] cam_sensor_subdev_ioctl+0x28/0x70 行 1240: [ 11.567112] qcom,camera 5c1b000.qcom,cci0:qcom,cam-sensor0: Linked as a consumer to regulator.1 行 1242: [ 11.591634] CAM_ERR: CAM-CCI: cam_cci_irq: 237 Base:0000000000000000, M0_Q1 NACK ERROR: 0x10000000 行 1293: [ 13.088134] CAM_ERR: CAM-CCI: cam_cci_read: 1305 wait_for_completion_timeout rc = -110 FIFO buf_lvl: 0x0 行 1294: [ 13.088186] CAM_ERR: CAM-CCI: cam_cci_read_bytes_v_1_2: 1575 failed to read rc:-110 行 1295: [ 13.088189] CAM_ERR: CAM-SENSOR: cam_cci_i2c_read: 35 rc = -110 行 1296: [ 13.088194] CAM_WARN: CAM-SENSOR: cam_sensor_match_id: 639 read id: 0x0 expected id 0x258: 行 1324: [ 13.088347] cam_sensor_util_power_down+0x118/0x4e8 行 1325: [ 13.088351] cam_sensor_power_down+0x30/0x128 行 1326: [ 13.088354] cam_sensor_driver_cmd+0x378/0x1378 行 1327: [ 13.088357] cam_sensor_subdev_ioctl+0x28/0x70 行 1339: [ 13.092161] qcom,camera 5c1b000.qcom,cci0:qcom,cam-sensor0: Dropping the link to regulator.1 行 1341: [ 13.120815] NOT CAMERA 0 行 1342: [ 13.144152] qcom,camera 5c1b000.qcom,cci0:qcom,cam-sensor2: Linked as a consumer to regulator.1 行 1343: [ 13.171095] CAM_ERR: CAM-CCI: cam_cci_irq: 265 Base:0000000000000000, M1_Q1 NACK ERROR: 0x40000000 行 1366: [ 14.688167] CAM_ERR: CAM-CCI: cam_cci_read: 1305 wait_for_completion_timeout rc = -110 FIFO buf_lvl: 0x0 行 1367: [ 14.688318] CAM_ERR: CAM-CCI: cam_cci_read_bytes_v_1_2: 1575 failed to read rc:-110 行 1368: [ 14.688322] CAM_ERR: CAM-SENSOR: cam_cci_i2c_read: 35 rc = -110 行 1369: [ 14.688326] CAM_WARN: CAM-SENSOR: cam_sensor_match_id: 639 read id: 0x0 expected id 0x30a: 行 1370: [ 14.688329] NOT CAMERA 0 行 1371: [ 14.694628] qcom,camera 5c1b000.qcom,cci0:qcom,cam-sensor2: Dropping the link to regulator.1 行 1373: [ 14.732853] NOT CAMERA 0 行 1374: [ 14.732904] qcom,camera 5c1b000.qcom,cci0:qcom,cam-sensor2: Linked as a consumer to regulator.1 行 1385: [ 14.755707] CAM_ERR: CAM-CCI: cam_cci_irq: 265 Base:0000000000000000, M1_Q1 NACK ERROR: 0x40000000 行 1440: [ 16.256086] CAM_ERR: CAM-CCI: cam_cci_read: 1305 wait_for_completion_timeout rc = -110 FIFO buf_lvl: 0x0 行 1441: [ 16.256135] CAM_ERR: CAM-CCI: cam_cci_read_bytes_v_1_2: 1575 failed to read rc:-110 行 1442: [ 16.256138] CAM_ERR: CAM-SENSOR: cam_cci_i2c_read: 35 rc = -110 行 1443: [ 16.256142] CAM_WARN: CAM-SENSOR: cam_sensor_match_id: 639 read id: 0x0 expected id 0x2680: 行 1444: [ 16.256146] NOT CAMERA 0 行 1445: [ 16.260207] qcom,camera 5c1b000.qcom,cci0:qcom,cam-sensor2: Dropping the link to regulator.1 行 1446: [ 16.284806] NOT CAMERA 0 行 1448: [ 16.337408] qcom,camera 5c1b000.qcom,cci0:qcom,cam-sensor1: Linked as a consumer to regulator.1 行 1449: [ 16.357108] CAM_ERR: CAM-CCI: cam_cci_irq: 265 Base:0000000000000000, M1_Q1 NACK ERROR: 0x40000000 行 1461: [ 17.856144] CAM_ERR: CAM-CCI: cam_cci_read: 1305 wait_for_completion_timeout rc = -110 FIFO buf_lvl: 0x0 行 1462: [ 17.856433] CAM_ERR: CAM-CCI: cam_cci_read_bytes_v_1_2: 1575 failed to read rc:-110 行 1463: [ 17.856439] CAM_ERR: CAM-SENSOR: cam_cci_i2c_read: 35 rc = -110 行 1464: [ 17.856444] CAM_WARN: CAM-SENSOR: cam_sensor_match_id: 639 read id: 0x0 expected id 0x258: 行 1465: [ 17.856447] NOT CAMERA 0 行 1466: [ 17.860380] qcom,camera 5c1b000.qcom,cci0:qcom,cam-sensor1: Dropping the link to regulator.1 行 1467: [ 17.892789] NOT CAMERA 0 行 1468: [ 17.916968] qcom,camera 5c1b000.qcom,cci0:qcom,cam-sensor1: Linked as a consumer to regulator.1 行 1469: [ 17.929590] CAM_ERR: CAM-CCI: cam_cci_irq: 265 Base:0000000000000000, M1_Q1 NACK ERROR: 0x40000000 行 1471: [ 19.456119] CAM_ERR: CAM-CCI: cam_cci_read: 1305 wait_for_completion_timeout rc = -110 FIFO buf_lvl: 0x0 行 1472: [ 19.456153] CAM_ERR: CAM-CCI: cam_cci_read_bytes_v_1_2: 1575 failed to read rc:-110 行 1473: [ 19.456156] CAM_ERR: CAM-SENSOR: cam_cci_i2c_read: 35 rc = -110 行 1474: [ 19.456160] CAM_WARN: CAM-SENSOR: cam_sensor_match_id: 639 read id: 0x0 expected id 0x5035: 行 1475: [ 19.456164] NOT CAMERA 0 行 1476: [ 19.460186] qcom,camera 5c1b000.qcom,cci0:qcom,cam-sensor1: Dropping the link to regulator.1

hiview init success. Write test to 0x68 failed, error: -2147479167 Write test to 0x69 failed, error: -2147479167 Both addresses failed, check hardware MPU6050 initialization failed, error: -1根据以上串口助手显示的问题分析以下代码哪里产生了此问题#ifndef BSP_MPU6050_H #define BSP_MPU6050_H #include “cmsis_os2.h” #include “hi_io.h” #include “hi_gpio.h” #include “hi_i2c.h” #define MPU6050_I2C_IDX 0 // 模块的I2C总线号 #define MPU6050_I2C_SPEED 100000 // 100KHz // MPU6050寄存器地址定义 #define MPU6050_ADDR_DEFAULT 0x68 #define MPU6050_ADDR_ALTERNATE 0x69 #define MPU6050_ADDR 0x68 // MPU6050 I2C地址 #define MPU6050_PWR_MGMT_1 0x6B // 电源管理寄存器1 #define MPU6050_PWR_MGMT_2 0x6C // 电源管理寄存器2 #define MPU6050_ACCEL_XOUT_H 0x3B // 加速度计X轴高字节 #define MPU6050_ACCEL_XOUT_L 0x3C // 加速度计X轴低字节 #define MPU6050_ACCEL_YOUT_H 0x3D // 加速度计Y轴高字节 #define MPU6050_ACCEL_YOUT_L 0x3E // 加速度计Y轴低字节 #define MPU6050_ACCEL_ZOUT_H 0x3F // 加速度计Z轴高字节 #define MPU6050_ACCEL_ZOUT_L 0x40 // 加速度计Z轴低字节 #define MPU6050_TEMP_OUT_H 0x41 // 温度输出高字节 #define MPU6050_TEMP_OUT_L 0x42 // 温度输出低字节 #define MPU6050_GYRO_XOUT_H 0x43 // 陀螺仪X轴高字节 #define MPU6050_GYRO_XOUT_L 0x44 // 陀螺仪X轴低字节 #define MPU6050_GYRO_YOUT_H 0x45 // 陀螺仪Y轴高字节 #define MPU6050_GYRO_YOUT_L 0x46 // 陀螺仪Y轴低字节 #define MPU6050_GYRO_ZOUT_H 0x47 // 陀螺仪Z轴高字节 #define MPU6050_GYRO_ZOUT_L 0x48 // 陀螺仪Z轴低字节 #define MPU6050_CONFIG 0x1A // 配置寄存器 #define MPU6050_GYRO_CONFIG 0x1B // 陀螺仪配置寄存器 #define MPU6050_ACCEL_CONFIG 0x1C // 加速度计配置寄存器 #define MPU6050_SMPLRT_DIV 0x19 #define MPU6050_WHO_AM_I 0x75 // 设备ID寄存器 // MODIFIED: 添加全局设备地址 extern hi_u8 g_mpu6050_addr; hi_s32 MPU6050_Init(hi_i2c_idx id) ; hi_s32 MPU6050_WriteReg(hi_i2c_idx id, hi_u8 reg_addr, hi_u8 data) ; hi_s32 MPU6050_ReadReg(hi_i2c_idx id, hi_u8 reg_addr, hi_u8 *data) ; hi_s32 mpu6050_read_accel(hi_i2c_idx i2c_id, hi_s16 *ax, hi_s16 *ay, hi_s16 *az) ; hi_s32 mpu6050_read_gyro(hi_i2c_idx i2c_id, hi_s16 *gx, hi_s16 *gy, hi_s16 *gz) ; hi_s32 MPU6050_ScanI2C(hi_i2c_idx id) ; #endif#include “bsp_mpu6050.h” #include “hi_i2c.h” #include <stdio.h> #include <unistd.h> #include “ohos_init.h” #include “cmsis_os2.h” #include “hi_errno.h” hi_u8 whoami; hi_s32 test_mpu6050_address(hi_i2c_idx id, hi_u8 addr_7bit) { hi_s32 ret; hi_u8 who_am_i; hi_u16 i2c_addr = (hi_u16)(addr_7bit << 1); // 生成8位写地址 // 写操作测试 ret = hi_i2c_write(id, i2c_addr, NULL); if (ret != 0) { printf("Write test to 0x%02X failed, error: %ld\n", addr_7bit, ret); return ret; } // 读WHO_AM_I寄存器测试 ret = MPU6050_ReadReg(id, MPU6050_WHO_AM_I, &who_am_i); if (ret != 0) { printf("Read test failed, error: %ld\n", ret); return ret; } if (who_am_i == 0x68) { printf("MPU6050 found at 0x%02X, WHO_AM_I=0x%02X\n", addr_7bit, who_am_i); return 0; } else { printf("Device at 0x%02X is not MPU6050 (ID=0x%02X)\n", addr_7bit, who_am_i); return -1; } } // I2C设备扫描函数,用于检测MPU6050地址 hi_s32 MPU6050_ScanI2C(hi_i2c_idx id) { hi_s32 ret; hi_i2c_data i2c_data; hi_u8 deviceFound = 0; hi_u8 addr; hi_u16 i2c_addr; // 8位I2C地址 printf("Scanning I2C bus for MPU6050...\n"); i2c_data.send_buf = NULL; i2c_data.send_len = 0; i2c_data.receive_buf = NULL; i2c_data.receive_len = 0; for (addr = 0x08; addr <= 0xD1; addr++) { i2c_addr = (hi_u16)(addr << 1); // 7位地址左移1位,生成8位地址 ret = hi_i2c_write(id, i2c_addr, &i2c_data); if (ret == 0) { printf("Device found at address 0x%02X (I2C addr: 0x%02X)\n", addr, i2c_addr); deviceFound = 1; } } if (!deviceFound) { printf("No devices found on I2C bus\n"); return -1; } return 0; } // 使用 hi_i2c_write 实现的 MPU6050 写寄存器函数 hi_s32 MPU6050_WriteReg(hi_i2c_idx id, hi_u8 reg_addr, hi_u8 data) { hi_s32 ret; hi_i2c_data i2c_data; hi_u8 tx_buffer[2]; tx_buffer[0] = reg_addr; // 寄存器地址 tx_buffer[1] = data; // 要写入的数据 i2c_data.send_buf = tx_buffer; i2c_data.send_len = 2; i2c_data.receive_buf = NULL; i2c_data.receive_len = 0; ret = hi_i2c_write(id, MPU6050_ADDR, &i2c_data); if (ret != 0) { printf("Failed to write register 0x%02X, error: %ld\n", reg_addr, ret); } return ret; } // 使用 hi_i2c_write 实现的 MPU6050 读寄存器函数 hi_s32 MPU6050_ReadReg(hi_i2c_idx id, hi_u8 reg_addr, hi_u8 *data) { hi_s32 ret; hi_i2c_data i2c_data; // 发送要读取的寄存器地址 i2c_data.send_buf = ®_addr; i2c_data.send_len = 1; i2c_data.receive_buf = NULL; i2c_data.receive_len = 0; ret = hi_i2c_write(id, MPU6050_ADDR, &i2c_data); if (ret != 0) { printf("Failed to send register address, error: %ld\n", ret); return ret; } // 读取数据 i2c_data.send_buf = NULL; i2c_data.send_len = 0; i2c_data.receive_buf = data; i2c_data.receive_len = 1; ret = hi_i2c_read(id, MPU6050_ADDR, &i2c_data); if (ret != 0) { printf("Failed to read data, error: %ld\n", ret); } return ret; } // 基于 hi_i2c_write 的 MPU6050 初始化函数 hi_s32 MPU6050_Init(hi_i2c_idx id) { hi_s32 ret; // 初始化GPIO hi_gpio_init(); // 配置SCL和SDA引脚 hi_io_set_pull(HI_IO_NAME_GPIO_9, HI_IO_PULL_UP); hi_io_set_func(HI_IO_NAME_GPIO_9, HI_IO_FUNC_GPIO_9_I2C0_SCL); hi_io_set_pull(HI_IO_NAME_GPIO_10, HI_IO_PULL_UP); hi_io_set_func(HI_IO_NAME_GPIO_10, HI_IO_FUNC_GPIO_10_I2C0_SDA); // 初始化I2C,降低频率到10kHz ret = hi_i2c_init(id, 10000); if (ret != 0) { printf("Failed to initialize I2C, error: %ld\n", ret); return ret; } usleep(100 * 1000); // 100ms延时,确保I2C初始化完成 ret = test_mpu6050_address(id, 0x68); if (ret != 0) { ret = test_mpu6050_address(id, 0x69); if (ret != 0) { printf("Both addresses failed, check hardware\n"); return -1; } } // 扫描I2C总线,确认MPU6050地址 ret = MPU6050_ScanI2C(id); if (ret != 0) { return ret; } // 读取WHO_AM_I寄存器 ret = MPU6050_ReadReg(id, MPU6050_WHO_AM_I, &whoami); if (ret != 0) { printf("Failed to read WHO_AM_I register, error: %ld\n", ret); return ret; } // 验证设备ID(支持0x68和0x69) if (whoami != 0x68 && whoami != 0x69) { printf("Invalid device ID: 0x%02X (expected 0x68 or 0x69)\n", whoami); return -1; } printf("MPU6050 ID verified: 0x%02X\n", whoami); // 电源管理寄存器1:取消睡眠模式,选择X轴陀螺仪时钟源 ret = MPU6050_WriteReg(id, MPU6050_PWR_MGMT_1, 0x01); if (ret != 0) { return ret; } usleep(10000); // 10ms延时,确保传感器退出睡眠模式 // 电源管理寄存器2:保持默认值0,所有轴均不待机 ret = MPU6050_WriteReg(id, MPU6050_PWR_MGMT_2, 0x00); if (ret != 0) { return ret; } // 采样率分频寄存器:配置采样率为800Hz ret = MPU6050_WriteReg(id, MPU6050_SMPLRT_DIV, 0x09); if (ret != 0) { return ret; } // 配置寄存器:DLPF带宽5Hz ret = MPU6050_WriteReg(id, MPU6050_CONFIG, 0x06); if (ret != 0) { return ret; } // 陀螺仪配置:±2000°/s量程 ret = MPU6050_WriteReg(id, MPU6050_GYRO_CONFIG, 0x18); if (ret != 0) { return ret; } // 加速度计配置:±16g量程 ret = MPU6050_WriteReg(id, MPU6050_ACCEL_CONFIG, 0x18); if (ret != 0) { return ret; } usleep(100000); // 等待传感器稳定100ms printf("MPU6050 initialized successfully\n"); return 0; } // 读取 MPU6050 的加速度数据 hi_s32 mpu6050_read_accel(hi_i2c_idx id, hi_s16 *ax, hi_s16 *ay, hi_s16 *az) { hi_s32 ret; hi_i2c_data i2c_data; hi_u8 reg_addr = MPU6050_ACCEL_XOUT_H; hi_u8 buffer[6]; // 发送要读取的寄存器地址 i2c_data.send_buf = ®_addr; i2c_data.send_len = 1; i2c_data.receive_buf = NULL; i2c_data.receive_len = 0; ret = hi_i2c_write(id, MPU6050_ADDR, &i2c_data); if (ret != 0) { printf("Failed to send register address, error: %ld\n", ret); return ret; } // 连续读取6字节加速度数据 i2c_data.send_buf = NULL; i2c_data.send_len = 0; i2c_data.receive_buf = buffer; i2c_data.receive_len = 6; ret = hi_i2c_read(id, MPU6050_ADDR, &i2c_data); if (ret != 0) { printf("Failed to read accelerometer data, error: %ld\n", ret); return ret; } // 合并高低字节(注意字节序) *ax = (buffer[0] << 8) | buffer[1]; *ay = (buffer[2] << 8) | buffer[3]; *az = (buffer[4] << 8) | buffer[5]; return 0; } // 读取 MPU6050 的陀螺仪数据 hi_s32 mpu6050_read_gyro(hi_i2c_idx id, hi_s16 *gx, hi_s16 *gy, hi_s16 *gz) { hi_s32 ret; hi_i2c_data i2c_data; hi_u8 reg_addr = MPU6050_GYRO_XOUT_H; hi_u8 buffer[6]; // 发送要读取的寄存器地址 i2c_data.send_buf = ®_addr; i2c_data.send_len = 1; i2c_data.receive_buf = NULL; i2c_data.receive_len = 0; ret = hi_i2c_write(id, MPU6050_ADDR, &i2c_data); if (ret != 0) { printf("Failed to send register address, error: %ld\n", ret); return ret; } // 连续读取6字节陀螺仪数据 i2c_data.send_buf = NULL; i2c_data.send_len = 0; i2c_data.receive_buf = buffer; i2c_data.receive_len = 6; ret = hi_i2c_read(id, MPU6050_ADDR, &i2c_data); if (ret != 0) { printf("Failed to read gyroscope data, error: %ld\n", ret); return ret; } // 合并高低字节 *gx = (buffer[0] << 8) | buffer[1]; *gy = (buffer[2] << 8) | buffer[3]; *gz = (buffer[4] << 8) | buffer[5]; return 0; }

#ifndef BSP_MPU6050_H #define BSP_MPU6050_H #include "cmsis_os2.h" #include "hi_io.h" #include "hi_gpio.h" #include "hi_i2c.h" #define MPU6050_I2C_ADDR 0x78 // 器件的I2C从机地址 #define MPU6050_I2C_IDX 0 // 模块的I2C总线号 #define MPU6050_I2C_SPEED 100000 // 100KHz // MPU6050寄存器地址定义 #define MPU6050_ADDR_DEFAULT 0x68 #define MPU6050_ADDR_ALTERNATE 0x69 #define MPU6050_ADDR 0x68 // MPU6050 I2C地址 #define MPU6050_PWR_MGMT_1 0x6B // 电源管理寄存器1 #define MPU6050_PWR_MGMT_2 0x6C // 电源管理寄存器2 #define MPU6050_ACCEL_XOUT_H 0x3B // 加速度计X轴高字节 #define MPU6050_ACCEL_XOUT_L 0x3C // 加速度计X轴低字节 #define MPU6050_ACCEL_YOUT_H 0x3D // 加速度计Y轴高字节 #define MPU6050_ACCEL_YOUT_L 0x3E // 加速度计Y轴低字节 #define MPU6050_ACCEL_ZOUT_H 0x3F // 加速度计Z轴高字节 #define MPU6050_ACCEL_ZOUT_L 0x40 // 加速度计Z轴低字节 #define MPU6050_TEMP_OUT_H 0x41 // 温度输出高字节 #define MPU6050_TEMP_OUT_L 0x42 // 温度输出低字节 #define MPU6050_GYRO_XOUT_H 0x43 // 陀螺仪X轴高字节 #define MPU6050_GYRO_XOUT_L 0x44 // 陀螺仪X轴低字节 #define MPU6050_GYRO_YOUT_H 0x45 // 陀螺仪Y轴高字节 #define MPU6050_GYRO_YOUT_L 0x46 // 陀螺仪Y轴低字节 #define MPU6050_GYRO_ZOUT_H 0x47 // 陀螺仪Z轴高字节 #define MPU6050_GYRO_ZOUT_L 0x48 // 陀螺仪Z轴低字节 #define MPU6050_CONFIG 0x1A // 配置寄存器 #define MPU6050_GYRO_CONFIG 0x1B // 陀螺仪配置寄存器 #define MPU6050_ACCEL_CONFIG 0x1C // 加速度计配置寄存器 #define MPU6050_SMPLRT_DIV 0x19 #define MPU6050_WHO_AM_I 0x75 // 设备ID寄存器 // MODIFIED: 添加全局设备地址 extern hi_u8 g_mpu6050_addr; hi_s32 MPU6050_Init(hi_i2c_idx id) ; hi_s32 MPU6050_WriteReg(hi_i2c_idx id, hi_u8 reg_addr, hi_u8 data) ; hi_s32 MPU6050_ReadReg(hi_i2c_idx id, hi_u8 reg_addr, hi_u8 *data) ; hi_s32 mpu6050_read_accel(hi_i2c_idx i2c_id, hi_s16 *ax, hi_s16 *ay, hi_s16 *az) ; hi_s32 mpu6050_read_gyro(hi_i2c_idx i2c_id, hi_s16 *gx, hi_s16 *gy, hi_s16 *gz) ; hi_s32 MPU6050_ScanI2C(hi_i2c_idx id) ; #endif// bsp_mpu6050.c 模块函数修改 #include "bsp_mpu6050.h" #include "hi_i2c.h" #include <stdio.h> #include <unistd.h> #include "ohos_init.h" #include "cmsis_os2.h" #include "hi_errno.h" hi_u8 whoami; // MODIFIED: 全局设备地址变量 hi_u8 g_mpu6050_addr = MPU6050_ADDR_DEFAULT; // I2C设备扫描函数,用于检测MPU6050地址 hi_s32 MPU6050_ScanI2C(hi_i2c_idx id) { hi_s32 ret; hi_i2c_data i2c_data; hi_u8 deviceFound = 0; printf("Scanning I2C bus for MPU6050...\n"); // 尝试默认地址0x68 i2c_data.send_buf = NULL; i2c_data.send_len = 0; i2c_data.receive_buf = NULL; i2c_data.receive_len = 0; ret = hi_i2c_write( MPU6050_I2C_IDX , MPU6050_ADDR_DEFAULT, &i2c_data); if (ret == 0) { printf("MPU6050 found at address 0x%02X\n", MPU6050_ADDR_DEFAULT); g_mpu6050_addr = MPU6050_ADDR_DEFAULT; // 更新全局地址 deviceFound = 1; } // 尝试备用地址0x69 ret = hi_i2c_write( MPU6050_I2C_IDX , MPU6050_ADDR_ALTERNATE, &i2c_data); if (ret == 0) { printf("MPU6050 found at address 0x%02X\n", MPU6050_ADDR_ALTERNATE); g_mpu6050_addr = MPU6050_ADDR_ALTERNATE; // 更新全局地址 deviceFound = 1; } if (!deviceFound) { printf("MPU6050 not found on I2C bus\n"); return -1; } printf("Using I2C address: 0x%02X\n", g_mpu6050_addr); return 0; } // 使用 hi_i2c_write 实现的 MPU6050 写寄存器函数 hi_s32 MPU6050_WriteReg(hi_i2c_idx id, hi_u8 reg_addr, hi_u8 data) { hi_s32 ret; hi_i2c_data i2c_data; hi_u8 tx_buffer[2]; tx_buffer[0] = reg_addr; // 寄存器地址 tx_buffer[1] = data; // 要写入的数据 i2c_data.send_buf = tx_buffer; i2c_data.send_len = 2; i2c_data.receive_buf = NULL; i2c_data.receive_len = 0; ret = hi_i2c_write(id, g_mpu6050_addr, &i2c_data); if (ret != 0) { printf("Failed to write register 0x%02X, error: %ld\n", reg_addr, ret); } return ret; } // 使用 hi_i2c_write 实现的 MPU6050 读寄存器函数 hi_s32 MPU6050_ReadReg(hi_i2c_idx id, hi_u8 reg_addr, hi_u8 *data) { hi_s32 ret; hi_i2c_data i2c_data; // 发送要读取的寄存器地址 i2c_data.send_buf = ®_addr; i2c_data.send_len = 1; i2c_data.receive_buf = NULL; i2c_data.receive_len = 0; ret = hi_i2c_write(id, g_mpu6050_addr, &i2c_data); if (ret != 0) { printf("Failed to send register address, error: %ld\n", ret); return ret; } // 读取数据 i2c_data.send_buf = NULL; i2c_data.send_len = 0; i2c_data.receive_buf = data; i2c_data.receive_len = 1; ret = hi_i2c_read(id, g_mpu6050_addr, &i2c_data); if (ret != 0) { printf("Failed to read data, error: %ld\n", ret); } return ret; } // 基于 hi_i2c_write 的 MPU6050 初始化函数 hi_s32 MPU6050_Init(hi_i2c_idx id) { hi_s32 ret; // 初始化GPIO hi_gpio_init(); // 配置SCL和SDA引脚 hi_io_set_pull(HI_IO_NAME_GPIO_13, HI_IO_PULL_UP); hi_io_set_func(HI_IO_NAME_GPIO_13, HI_IO_FUNC_GPIO_13_I2C0_SDA); hi_io_set_pull(HI_IO_NAME_GPIO_14, HI_IO_PULL_UP); hi_io_set_func(HI_IO_NAME_GPIO_14, HI_IO_FUNC_GPIO_14_I2C0_SCL); ret = hi_i2c_init(id, 100000); if (ret != 0) { printf("Failed to initialize I2C, error: %ld\n", ret); return ret; } usleep(100 * 1000); // 100ms延时,确保I2C初始化完成 // 扫描I2C总线,确认MPU6050地址 ret = MPU6050_ScanI2C(id); if (ret != 0) { return ret; } // 读取WHO_AM_I寄存器 ret = MPU6050_ReadReg(id, MPU6050_WHO_AM_I, &whoami); if (ret != 0) { printf("Failed to read WHO_AM_I register, error: %ld\n", ret); return ret; } // 验证设备ID= if (whoami != 0x68 && whoami != 0x69) { printf("Invalid device ID: 0x%02X (expected 0x68 or 0x69)\n", whoami); return -1; } printf("MPU6050 ID verified: 0x%02X\n", whoami); // 电源管理寄存器1:取消睡眠模式,选择X轴陀螺仪时钟源 ret = MPU6050_WriteReg(id, MPU6050_PWR_MGMT_1, 0x01); if (ret != 0) { return ret; } usleep(150000); // 10ms延时,确保传感器退出睡眠模式 // 电源管理寄存器2:保持默认值0,所有轴均不待机 ret = MPU6050_WriteReg(id, MPU6050_PWR_MGMT_2, 0x00); if (ret != 0) { return ret; } // 采样率分频寄存器:配置采样率为800Hz ret = MPU6050_WriteReg(id, MPU6050_SMPLRT_DIV, 0x09); if (ret != 0) { return ret; } // 配置寄存器:DLPF带宽5Hz ret = MPU6050_WriteReg(id, MPU6050_CONFIG, 0x06); if (ret != 0) { return ret; } // 陀螺仪配置:±2000°/s量程 ret = MPU6050_WriteReg(id, MPU6050_GYRO_CONFIG, 0x18); if (ret != 0) { return ret; } // 加速度计配置:±16g量程 ret = MPU6050_WriteReg(id, MPU6050_ACCEL_CONFIG, 0x18); if (ret != 0) { return ret; } usleep(50000); // 等待传感器稳定100ms printf("MPU6050 initialized successfully\n"); return 0; } // 读取 MPU6050 的加速度数据 hi_s32 mpu6050_read_accel(hi_i2c_idx id, hi_s16 *ax, hi_s16 *ay, hi_s16 *az) { hi_s32 ret; hi_i2c_data i2c_data; hi_u8 reg_addr = MPU6050_ACCEL_XOUT_H; hi_u8 buffer[6]; // 发送要读取的寄存器地址 i2c_data.send_buf = ®_addr; i2c_data.send_len = 1; i2c_data.receive_buf = NULL; i2c_data.receive_len = 0; ret = hi_i2c_write(id,g_mpu6050_addr, &i2c_data); if (ret != 0) { printf("Failed to send register address, error: %ld\n", ret); return ret; } // 连续读取6字节加速度数据 i2c_data.send_buf = NULL; i2c_data.send_len = 0; i2c_data.receive_buf = buffer; i2c_data.receive_len = 6; ret = hi_i2c_read(id, g_mpu6050_addr, &i2c_data); if (ret != 0) { printf("Failed to read accelerometer data, error: %ld\n", ret); return ret; } // 合并高低字节(注意字节序) *ax = (buffer[0] << 8) | buffer[1]; *ay = (buffer[2] << 8) | buffer[3]; *az = (buffer[4] << 8) | buffer[5]; return 0; } // 读取 MPU6050 的陀螺仪数据 hi_s32 mpu6050_read_gyro(hi_i2c_idx id, hi_s16 *gx, hi_s16 *gy, hi_s16 *gz) { hi_s32 ret; hi_i2c_data i2c_data; hi_u8 reg_addr = MPU6050_GYRO_XOUT_H; hi_u8 buffer[6]; // 发送要读取的寄存器地址 i2c_data.send_buf = ®_addr; i2c_data.send_len = 1; i2c_data.receive_buf = NULL; i2c_data.receive_len = 0; ret = hi_i2c_write(id, g_mpu6050_addr, &i2c_data); if (ret != 0) { printf("Failed to send register address, error: %ld\n", ret); return ret; } // 连续读取6字节陀螺仪数据 i2c_data.send_buf = NULL; i2c_data.send_len = 0; i2c_data.receive_buf = buffer; i2c_data.receive_len = 6; ret = hi_i2c_read(id, g_mpu6050_addr, &i2c_data); if (ret != 0) { printf("Failed to read gyroscope data, error: %ld\n", ret); return ret; } // 合并高低字节 *gx = (buffer[0] << 8) | buffer[1]; *gy = (buffer[2] << 8) | buffer[3]; *gz = (buffer[4] << 8) | buffer[5]; return 0; }#include <stdio.h> #include <unistd.h> #include "ohos_init.h" #include "cmsis_os2.h" #include <hi_i2c.h> #include "hi_gpio.h" #include "hi_io.h" #include "hi_errno.h" #include "bsp_oled.h" #include "bsp_mpu6050.h" hi_s16 ax, ay, az; // 加速度值 hi_s16 gx, gy, gz; // 陀螺仪值 osThreadId_t MPU6050_Task_ID; // MPU6050任务ID osMutexId_t dataMutex; // 数据互斥锁 // MPU6050任务 - 负责读取传感器数据 void MPU6050_Task(void* arg) { hi_u32 ret; // 增加初始化前延时 usleep(500000); // 500ms确保系统稳定 // 初始化MPU6050(只执行一次) ret = MPU6050_Init(HI_I2C_IDX_0); if (ret != 0) { printf("MPU6050 initialization failed, error: %d\n", ret); return; } // 增加初始化后延时 usleep(200000); // 200ms确保传感器稳定 printf("MPU6050 initialized successfully\n"); // 循环读取传感器数据 while (1) { // 读取加速度数据 ret = mpu6050_read_accel(HI_I2C_IDX_0, &ax, &ay, &az); if (ret != 0) { printf("Failed to read accelerometer data, error code: %d\n", ret); } // 读取陀螺仪数据 ret = mpu6050_read_gyro(HI_I2C_IDX_0, &gx, &gy, &gz); if (ret != 0) { printf("Failed to read gyroscope data, error code: %d\n", ret); } printf("ax=%d, ay=%d, gx=%d, gy=%d\n", ax, ay, gx, gy); // 延时100ms,控制采样频率 usleep(100000); // 100ms } } // 创建任务 void create_tasks(void) { osThreadAttr_t taskOptions; osMutexAttr_t mutexAttr; // 初始化互斥锁 mutexAttr.name = "DataMutex"; mutexAttr.attr_bits = 0U; mutexAttr.cb_mem = NULL; mutexAttr.cb_size = 0U; dataMutex = osMutexNew(&mutexAttr); if (dataMutex == NULL) { printf("Failed to create data mutex!\n"); return; } // 创建MPU6050任务 taskOptions.name = "MPU6050Task"; taskOptions.attr_bits = 0; taskOptions.cb_mem = NULL; taskOptions.cb_size = 0; taskOptions.stack_mem = NULL; taskOptions.stack_size = 1024; taskOptions.priority = osPriorityNormal; MPU6050_Task_ID = osThreadNew((osThreadFunc_t)MPU6050_Task, NULL, &taskOptions); if (MPU6050_Task_ID == NULL) { printf("Failed to create MPU6050 task!\n"); } else { printf("MPU6050 Task created, ID: %p\n", MPU6050_Task_ID); } } // 应用入口函数 static void template_demo(void){ printf("Starting MPU6050 display application...\n"); create_tasks(); } SYS_RUN(template_demo); 请分析该VScode代码为什么会识别不 出I方C出现MPU6050 not found on I2C bus\n,mpu6050和海思hi3861硬件都没有问题,且无引脚复用情况

最新推荐

recommend-type

三菱FX3U三轴伺服电机与威纶通触摸屏组合程序详解:轴点动、回零与定位控制及全流程解析

三菱FX3U三轴伺服电机与威纶通触摸屏的程序编写方法及其应用。主要内容涵盖伺服电机主控程序、触摸屏程序、轴点动、回零及定位程序、通讯模块程序以及威纶显示器程序的分析。通过对各个模块的深入探讨,帮助读者理解每个部分的功能和实现方式,确保机械运动控制的准确性、高效性和稳定性。此外,文章还提供了关于程序编写过程中可能遇到的问题及解决方案。 适合人群:从事自动化控制领域的工程师和技术人员,尤其是对三菱FX3U三轴伺服电机和威纶通触摸屏有实际操作需求的专业人士。 使用场景及目标:适用于工业自动化项目中,旨在提高对三菱FX3U三轴伺服电机和威纶通触摸屏的理解和应用能力,掌握模块化编程技巧,解决实际工程中的编程难题。 其他说明:文中不仅讲解了各模块的具体实现细节,还强调了程序的安全性和可靠性,为项目的成功实施提供了有力的支持。
recommend-type

Pansophica开源项目:智能Web搜索代理的探索

Pansophica开源项目是一个相对较新且具有创新性的智能Web搜索代理,它突破了传统搜索引擎的界限,提供了一种全新的交互方式。首先,我们来探讨“智能Web搜索代理”这一概念。智能Web搜索代理是一个软件程序或服务,它可以根据用户的查询自动执行Web搜索,并尝试根据用户的兴趣、历史搜索记录或其他输入来提供个性化的搜索结果。 Pansophica所代表的不仅仅是搜索结果的展示,它还强调了一个交互式的体验,在动态和交互式虚拟现实中呈现搜索结果。这种呈现方式与现有的搜索体验有着根本的不同。目前的搜索引擎,如Google、Bing和Baidu等,多以静态文本和链接列表的形式展示结果。而Pansophica通过提供一个虚拟现实环境,使得搜索者可以“扭转”视角,进行“飞行”探索,以及“弹网”来浏览不同的内容。这种多维度的交互方式使得信息的浏览变得更加快速和直观,有望改变用户与网络信息互动的方式。 接着,我们关注Pansophica的“开源”属性。所谓开源,指的是软件的源代码可以被公众获取,任何个人或组织都可以自由地使用、学习、修改和分发这些代码。开源软件通常由社区进行开发和维护,这样的模式鼓励了协作创新并减少了重复性劳动,因为全世界的开发者都可以贡献自己的力量。Pansophica项目作为开源软件,意味着其他开发者可以访问和使用其源代码,进一步改进和扩展其功能,甚至可以为Pansophica构建新的应用或服务。 最后,文件名称“Pansophica-src-1.3”表明了我们讨论的特定版本的Pansophica开源代码。数字“1.3”很可能指的是该版本号,表明这是Pansophica项目的第1.3个公开版本。这个版本号对于开发者来说很重要,因为它可以帮助他们追踪更新的进度、比较版本间的差异以及选择最适合其项目的版本。 综合以上信息,Pansophica开源项目不仅在搜索代理领域引入了创新的交互方式,而且通过开源的方式,提供了技术共享和协作的可能性。对于IT行业来说,开源项目是推动技术发展的重要力量,它激发了社区的活力,促进了知识的传播和技术的进步。通过构建一个开源社区,Pansophica可以吸引来自世界各地的开发者和研究人员,共同探索如何将搜索技术与交互式虚拟现实技术结合起来,为用户带来更加丰富和有效的信息检索体验。同时,Pansophica的开源性质也使其更容易适应未来技术的发展,随着社区的不断贡献和反馈,这一平台有望在功能和性能上得到持续的优化和增强。
recommend-type

跨平台内容提取无忧:coze工作流应对社交媒体挑战

# 1. 社交媒体内容提取的必要性与挑战 ## 1.1 内容提取的必要性 在数字时代,社交媒体内容是信息与数据流动的主干道,公司、个人和研究者都在寻求从这些信息中提取价值。无论是为了市场趋势分析、品牌监控、消费者洞察还是公共舆论监测,有效的社交媒体内容提取变得至关重要。这不仅有助于企业做出数据驱动的决策,也能使个人更好地理
recommend-type

vrrp主设备发送的免费arp

<think>好的,我现在需要回答用户关于VRRP主设备发送免费ARP的目的和工作原理的问题。首先,我得回忆一下VRRP的基本概念和工作机制。VRRP,虚拟路由冗余协议,主要用于在局域网中提供默认网关的冗余备份,确保网络的高可用性。主设备(Master)负责转发流量,而备用设备(Backup)则在主设备故障时接管工作。 用户的问题集中在主设备发送免费ARP的目的和机制上。根据引用[2],免费ARP用于通知下游设备虚拟MAC地址的变更。当主设备被选举出来后,它需要让局域网内的其他设备知道虚拟IP对应的MAC地址已经指向自己,这样流量才会被正确路由到主设备。免费ARP的作用应该就是更新这些设备的
recommend-type

为Ghost博客平台打造的Meteor流星包装使用指南

从给定文件信息中,我们可以提炼出以下IT知识点: ### 标题知识点:流星Ghost软件包 1. **流星Ghost软件包的用途**:流星Ghost软件包是专为Ghost博客平台设计的流星(Meteor)应用程序。流星是一个开源的全栈JavaScript平台,用于开发高性能和易于编写的Web应用程序。Ghost是一个开源博客平台,它提供了一个简单且专业的写作环境。 2. **软件包的作用**:流星Ghost软件包允许用户在流星平台上轻松集成Ghost博客。这样做的好处是可以利用流星的实时特性以及易于开发和部署的应用程序框架,同时还能享受到Ghost博客系统的便利和美观。 ### 描述知识点:流星Ghost软件包的使用方法 1. **软件包安装方式**:用户可以通过流星的命令行工具添加名为`mrt:ghost`的软件包。`mrt`是流星的一个命令行工具,用于添加、管理以及配置软件包。 2. **初始化Ghost服务器**:描述中提供了如何在服务器启动时运行Ghost的基本代码示例。这段代码使用了JavaScript的Promise异步操作,`ghost().then(function (ghostServer) {...})`这行代码表示当Ghost服务器初始化完成后,会在Promise的回调函数中提供一个Ghost服务器实例。 3. **配置Ghost博客**:在`then`方法中,首先会获取到Ghost服务器的配置对象`config`,用户可以在此处进行自定义设置,例如修改主题、配置等。 4. **启动Ghost服务器**:在配置完成之后,通过调用`ghostServer.start()`来启动Ghost服务,使其能够处理博客相关的请求。 5. **Web浏览器导航**:一旦流星服务器启动并运行,用户便可以通过Web浏览器访问Ghost博客平台。 ### 标签知识点:JavaScript 1. **JavaScript作为流星Ghost软件包的开发语言**:标签指出流星Ghost软件包是使用JavaScript语言开发的。JavaScript是一种在浏览器端广泛使用的脚本语言,它也是流星平台的基础编程语言。 2. **流星和Ghost共同使用的语言**:JavaScript同样也是Ghost博客平台的开发语言。这表明流星Ghost软件包可以无缝集成,因为底层技术栈相同。 ### 压缩包子文件的文件名称列表知识点:meteor-ghost-master 1. **版本控制和软件包结构**:文件名称`meteor-ghost-master`暗示了该软件包可能托管在像GitHub这样的版本控制系统上。文件名中的`master`通常指的是主分支或主版本。 2. **软件包的目录结构**:通过文件名称可以推断出该软件包可能拥有一个标准的流星软件包结构,包含了初始化、配置、运行等必要的模块和文件。 3. **软件包的维护状态**:由于文件名没有包含特定的版本号,我们无法直接得知软件包的最新更新情况。通常,软件包维护者会将最新的版本代码放在`master`分支上。 ### 总结 流星Ghost软件包提供了一个有效的解决方案,使得流星平台的开发者能够在他们的应用中添加Ghost博客功能。软件包的使用简便,通过流星的命令行工具安装,并通过JavaScript代码配置和启动Ghost服务。通过流星Ghost软件包,开发者能够享受流星的实时特性以及Ghost博客系统的便利性。此外,软件包的命名和结构也暗示了其维护和版本控制的模式,有助于开发者更好地理解如何使用和维护这一软件包。
recommend-type

抖音标题生成自动化:用coze工作流释放创意

# 1. 抖音标题生成自动化的重要性 随着社交媒体平台的崛起,内容的吸引力很大程度上取决于标题的创意与精准性。抖音作为一个日活亿级的短视频平台,高质量的标题能够有效提高视频的点击率,增加内容的传播。但是,人工撰写标题不仅耗时耗力,而且很难做到快速响应热点,自动化标题生成工具应运而生。coze工作流,作为一种实现自动化生成抖音标题的工具,其重要性不言而喻。它能够利用大数据分析和机器学习技术,提高标题的吸引
recommend-type

spss消费结构因子分析

<think>好的,我现在需要帮助用户在SPSS中进行消费结构的因子分析。首先,我要回忆一下因子分析的基本步骤和SPSS的操作流程。用户可能对SPSS不太熟悉,所以步骤要详细,同时需要结合他们提供的引用内容,特别是引用[2]中的适用条件和检验方法。 首先,用户提到了消费结构的数据,这可能包括多个变量,如食品、住房、交通等支出。因子分析适用于这种情况,可以降维并找出潜在因子。根据引用[2],需要检查样本量是否足够,变量间是否有相关性,以及KMO和Bartlett检验的结果。 接下来,我需要按照步骤组织回答:数据准备、适用性检验、因子提取、因子旋转、命名解释、计算得分。每个步骤都要简明扼要,说
recommend-type

OpenMediaVault的Docker映像:快速部署与管理指南

根据提供的文件信息,我们将详细讨论与标题和描述中提及的Docker、OpenMediaVault以及如何部署OpenMediaVault的Docker镜像相关的一系列知识点。 首先,Docker是一个开源的应用容器引擎,允许开发者打包应用及其依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app)。 OpenMediaVault是一个基于Debian的NAS(网络附加存储)解决方案。它专为家庭或小型办公室提供文件共享、网络附加存储以及打印服务。它提供了一个易用的Web界面,通过这个界面用户可以管理服务器配置、网络设置、用户权限、文件服务等。 在描述中提到了一些Docker命令行操作: 1. `git clone`:用于克隆仓库到本地,这里的仓库指的是“docker-images-openmedivault”。 2. `docker build -t omv`:这是一个构建Docker镜像的命令,其中`-t`参数用于标记镜像名称和标签,这里是标记为“omv”。 3. `docker run`:运行一个容器实例,`-t`参数用于分配一个伪终端,`-i`参数用于交互式操作,`-p 80:80`则是将容器的80端口映射到宿主机的80端口。 启动服务的部分涉及OpenMediaVault的配置和初始化: - ssh服务:用于远程登录到服务器的协议。 - php5-fpm:是PHP的一个FastCGI实现,用于加速PHP的运行。 - nginx:是一个高性能的HTTP和反向代理服务器,常用于优化静态内容的分发。 - openmediavault引擎:指的是OpenMediaVault的核心服务。 - rrdcached:用于收集和缓存性能数据,这些数据可以被rrdtool图形化工具读取。 - collectd:是一个守护进程,用于收集系统性能和提供各种存储方式和传输方式来存储所收集的数据。 为了访问服务,需要在浏览器中输入"http:// IP_OF_DOCKER",其中`IP_OF_DOCKER`指的是运行Docker容器的主机IP地址。 描述中还提到了一个步骤:“在System-> Network-> Interfaces中添加带有dhcp的eth0”,这指的是需要在OpenMediaVault的Web管理界面中配置网络接口。`eth0`是网络接口的名称,通常代表第一个以太网接口。DHCP(动态主机配置协议)是一种自动为网络中的设备分配IP地址的协议,这样设备就可以连接网络并开始通信,无需手动配置IP地址。 【压缩包子文件的文件名称列表】中的“docker-images-openmediavault-master”暗示了这是一个包含Docker镜像文件的代码仓库。通常,“master”分支是代码的主分支,包含了代码库中最新且通常是最稳定的版本。用户可以通过克隆该仓库到本地来获取所有相关的Dockerfile、配置脚本及依赖文件,以便能够自行构建和运行OpenMediaVault的Docker镜像。 综上所述,这些知识点涵盖了从基本的Docker概念、Docker命令行操作、OpenMediaVault服务启动和管理,到具体的网络配置及Docker仓库操作,都是进行Docker化OpenMediaVault部署的关键步骤。
recommend-type

小红书文案提取一步到位:coze工作流操作全攻略

# 1. coze工作流概述 工作流系统是企业信息化和数字化转型的核心组件之一,它通过自动化流程管理提升效率,确保业务流程的顺畅执行。coze工作流作为当前市场上较为先进的工作流解决方案,它不仅仅是一套软件工具,更是一个集成化的平台,旨在通过流程自动化和智能化提升企业运营效率。 coze工作流的引入不仅有助于标准化和优化企业的业务流程,还可以通过可配置的流程设计,满足不同部门的特定需求。在组织的业务流程中
recommend-type

戴尔R630设置来电自动开机

<think>嗯,用户需要设置Dell R630服务器在断电恢复后自动开机。这个问题很实用,特别是对于托管在机房或需要远程管理的服务器来说,电源恢复后自动启动能减少运维压力。 从用户提到的R630型号来看,这是Dell PowerEdge系列的主流机型,设置方法应该和其他同代服务器类似。用户可能遇到意外断电后需要手动开机的情况,这会影响服务可用性。 我回忆Dell服务器的电源管理逻辑:主要有两个关键设置点。首先是BIOS里的电源恢复策略,选项包括"保持关机"、"自动开机"和"恢复断电前状态"。其次是iDRAC远程管理卡里的设置,这个更灵活但需要配置网络。 用户可能不熟悉服务器管理,所以需