#include #include #include "osi_api.h" #include "ql_api_osi.h" #include "ql_api_spi.h" #include "osi_compiler.h" //#include "cfg.h" #include "../EC600U_t2n/include/t2n.h" #include "ql_log.h" #define AC_CURRENT_REG_ADDR 24 #define ENC_VALUE_REG_ADDR 28 // #define LOGD(msg, ...) QL_LOG(QL_LOG_LEVEL_DEBUG, "bl0939", msg, ##__VA_ARGS__) // #define LOGI(msg, ...) QL_LOG(QL_LOG_LEVEL_INFO, "bl0939", msg, ##__VA_ARGS__) // #define LOGW(msg, ...) QL_LOG(QL_LOG_LEVEL_WARN, "bl0939", msg, ##__VA_ARGS__) // #define LOGE(msg, ...) QL_LOG(QL_LOG_LEVEL_ERROR, "bl0939", msg, ##__VA_ARGS__) #define LOGD(msg, ...) QL_LOG(QL_LOG_LEVEL_VERBOSE, "bl0939", msg, ##__VA_ARGS__) #define LOGI(msg, ...) QL_LOG(QL_LOG_LEVEL_VERBOSE, "bl0939", msg, ##__VA_ARGS__) #define LOGW(msg, ...) QL_LOG(QL_LOG_LEVEL_WARN, "bl0939", msg, ##__VA_ARGS__) #define LOGE(msg, ...) QL_LOG(QL_LOG_LEVEL_ERROR, "bl0939", msg, ##__VA_ARGS__) extern int enc_value; // static ql_task_t *current_task_handle = NULL; #define BL0939_READ_TIMER 0x8000 osiThread_t *bl_thread_handle = NULL; osiTimer_t *bl_timer = NULL; static int spi_wait_write_read = 0; ql_sem_t spi_write_semaphore; ql_sem_t spi_read_semaphore; #define QL_SPI_WAIT_NONE 0 #define QL_SPI_WAIT_WRITE 1 #define QL_SPI_WAIT_READ 2 extern uint16_t gWordVar[]; static const uint8_t bl0939_cmd[36] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x55, 0x00, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x55, 0x07, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x55, 0x06, 0, 0, 0, 0}; static uint8_t spi_txbuf[36] OSI_CACHE_LINE_ALIGNED; static uint8_t spi_rxbuf[36] OSI_CACHE_LINE_ALIGNED; static void spi_cb_handler(ql_spi_irq_s cause) { if (cause.rx_dma_done == 1 && spi_wait_write_read == QL_SPI_WAIT_READ) { spi_wait_write_read = 0; ql_rtos_semaphore_release(spi_read_semaphore); } if (cause.tx_dma_done == 1 && spi_wait_write_read == QL_SPI_WAIT_WRITE) { spi_wait_write_read = 0; ql_rtos_semaphore_release(spi_write_semaphore); } LOGD("spi_cb_handler rx_dma_done=%d tx_dma_done=%d\r\n", cause.rx_dma_done, cause.tx_dma_done); } static int spi_write(int fd, uint8_t *inbuf, int len) { int ret; spi_wait_write_read = QL_SPI_WAIT_WRITE; ql_spi_request_sys_clk(fd); ret = ql_spi_write(fd, inbuf, len); ql_rtos_semaphore_wait(spi_write_semaphore, 10); LOGD("spi_write inbuf=%p,len=%d,ret=%d", inbuf, len, ret); return ret; } static int spi_write_read(int fd, uint8_t *outbuf, uint8_t *inbuf, int len) { int ret; spi_wait_write_read = QL_SPI_WAIT_READ; ret = ql_spi_write_read(fd, inbuf, outbuf, len); ql_rtos_semaphore_wait(spi_read_semaphore, 10); LOGD("spi_write_read inbuf=%p,outbuf=%p,len=%d,ret=%d", inbuf, outbuf, len, ret); return ret; } static int check_sum_ch(uint8_t *resp, uint8_t *cmd, int offset) { uint8_t sum = ~(0x55 + cmd[offset - 1] + resp[offset] + resp[offset + 1] + resp[offset + 2]); if (resp[offset + 3] == sum) { return 1; } return 0; } uint32_t readUint24LE(uint8_t *buf, int offset) { return buf[offset] | buf[offset + 1] << 8 | buf[offset + 2] << 16; } uint32_t readUint24BE(uint8_t *buf, int offset) { return buf[offset] << 16 | buf[offset + 1] << 8 | buf[offset + 2]; } float ac_current_coef[3] = { 1.218f / (324004.f * 0.225 * 1000 / 2000) * 100.f, 1.218f / (324004.f * 0.23 * 1000 / 2000) * 100.f, 1.218f / (79931.f * 0.002 * 500) * 100.f}; // uint8_t bl0939_rxbuf[36]; int32_t ac_ad_values[3] = {0}; static void bl_read_data_timer(void *parm) { osiTimerStart(bl_timer, 20); ql_event_t event; event.id = BL0939_READ_TIMER; if (bl_thread_handle) { ql_rtos_event_send(bl_thread_handle, &event); } // LOGD("bl_read_data_timer\r\n"); } static uint32_t bl0939_read_reg(int fd, uint8_t reg) { spi_txbuf[0] = 0x55; spi_txbuf[1] = reg; spi_txbuf[2] = 0; spi_txbuf[3] = 0; spi_txbuf[4] = 0; spi_txbuf[5] = 0; // bl0939_spi_reset(); spi_write_read(fd, spi_txbuf, spi_rxbuf, 6); spi_wait_write_read = QL_SPI_WAIT_READ; ql_rtos_semaphore_wait(spi_read_semaphore, 10); if (spi_rxbuf[5] == (uint8_t) ~(0x55 + reg + spi_rxbuf[2] + spi_rxbuf[3] + spi_rxbuf[4])) { return (uint32_t)spi_rxbuf[2] << 16 | (uint32_t)spi_rxbuf[3] << 8 | (uint32_t)spi_rxbuf[4] << 0; } return 0; } void bl0939_spi_reset(int fd) { spi_txbuf[0] = 0xff; spi_txbuf[1] = 0xff; spi_txbuf[2] = 0xff; spi_txbuf[3] = 0xff; spi_txbuf[4] = 0xff; spi_txbuf[5] = 0xff; spi_write(fd, spi_txbuf, 6); } uint32_t r_temp = 0; static int bl0939_write_reg(int fd, uint8_t reg, uint32_t val, int check) { int try_times = 0; uint8_t h = val >> 16; uint8_t m = val >> 8; uint8_t l = val >> 0; do { // bl0939_spi_reset(); spi_txbuf[0] = 0xA5; spi_txbuf[1] = reg; spi_txbuf[2] = h; spi_txbuf[3] = m; spi_txbuf[4] = l; spi_txbuf[5] = ~(0XA5 + reg + h + m + l); spi_write_read(fd, spi_txbuf, spi_rxbuf, 6); ql_rtos_semaphore_wait(spi_read_semaphore, 10); if (0 == check) return 0; r_temp = bl0939_read_reg(fd, reg); if (r_temp == val) return 0; ql_rtos_task_sleep_ms(100); } while (try_times++ < 5); return 1; } void bl0939_init(int fd) { bl0939_spi_reset(fd); bl0939_write_reg(fd, 0x19, 0x005a5a5a, 0); // ��λ�û��Ĵ��� bl0939_write_reg(fd, 0x1a, 0x00000055, 1); // ���д���� bl0939_write_reg(fd, 0x10, 0xffff, 0); // Threshold A bl0939_write_reg(fd, 0x1E, 0xffff, 1); // Threshold B bl0939_write_reg(fd, 0x18, 0x00002000, 1); // cf bl0939_write_reg(fd, 0x1B, 0x000047ff, 0); // cf bl0939_write_reg(fd, 0x1a, 0x00000000, 1); // д���� } void bl0939_task(void *data) { int ret; ql_spi_config_s spi_config = {0}; int spi_no = QL_SPI_PORT1; spi_config.port = spi_no; spi_config.spiclk = QL_SPI_CLK_781_25KHZ; spi_config.framesize = 8; spi_config.input_mode = QL_SPI_INPUT_TRUE; spi_config.cs_polarity0 = QL_SPI_CS_ACTIVE_LOW; spi_config.cs_polarity1 = QL_SPI_CS_ACTIVE_LOW; spi_config.cpol = QL_SPI_CPOL_LOW; spi_config.cpha = QL_SPI_CPHA_2Edge; // mode 1 spi_config.input_sel = QL_SPI_DI_1; spi_config.transmode = QL_SPI_DMA_IRQ; spi_config.cs = QL_SPI_CS0; spi_config.clk_delay = QL_SPI_CLK_DELAY_0; LOGD("bl0939_task entry"); ql_rtos_task_sleep_ms(5000); ql_spi_init_ext(spi_config); ql_spi_cs_auto(spi_no); // uint32_t addr = (uint32_t)__spi_dma_out_buf; // addr += 32 - addr % 32; // spi_txbuf = (uint8_t *)(addr); // LOGD("spi_txbuf=%p",spi_txbuf); // addr = (uint32_t)__spi_dma_in_buf; // addr += 32 - addr % 32; // spi_rxbuf = (uint8_t *)(addr); // LOGD("spi_rxbuf=%p", spi_rxbuf); LOGD("ql_spi_init done"); ql_rtos_semaphore_create(&spi_read_semaphore, 0); ql_rtos_semaphore_create(&spi_write_semaphore, 0); LOGD("semaphore create done"); ql_spi_irq_s mask = { .rx_dma_done = 1, .tx_dma_done = 1, }; ql_spi_set_irq(spi_no, mask, spi_cb_handler); LOGD("ql_spi_set_irq done"); bl0939_init(spi_no); bl_thread_handle = osiThreadCurrent(); bl_timer = osiTimerCreate(bl_thread_handle, bl_read_data_timer, (void *)spi_no); // 创建定时器 if (NULL == bl_timer) { LOGE("bl_timer create failed\n"); osiThreadExit(); } ret = osiTimerStart(bl_timer, 20); if (ret) { LOGE("osiTimerStart failed ret=%d\n", ret); } LOGD("bl0939_task init done"); ret = ql_pin_set_func(95, 5); // set pin 95 to gpio10 if (ret != QL_GPIO_SUCCESS) { LOGE("ql_pin_set_func 95 err ret=%d", ret); } ql_gpio_set_direction(GPIO_10, GPIO_INPUT); ret = ql_pin_set_func(98, 5); // set pin 95 to gpio9 if (ret != QL_GPIO_SUCCESS) { LOGE("ql_pin_set_func 98 err ret=%d", ret); } ql_gpio_set_direction(GPIO_9, GPIO_INPUT); ret = ql_pin_set_func(99, 5); // set pin 98 to gpio8 if (ret != QL_GPIO_SUCCESS) { LOGE("ql_pin_set_func 99 err ret=%d", ret); } ql_gpio_set_direction(GPIO_8, GPIO_OUTPUT); ret = ql_pin_set_func(100, 5); // set pin 95 to gpio12 if (ret != QL_GPIO_SUCCESS) { LOGE("ql_pin_set_func 100 err ret=%d", ret); } ql_gpio_set_direction(GPIO_8, GPIO_OUTPUT); while (1) { ql_event_t event; ret = ql_event_wait(&event, 1000); if (ret == 0) { switch (event.id) { case BL0939_READ_TIMER: memcpy(spi_txbuf, bl0939_cmd, sizeof(bl0939_cmd)); ret = spi_write_read(spi_no, spi_txbuf, spi_rxbuf, 36); if (ret == 0) { for (int ch = 0; ch < 3; ch++) { if (check_sum_ch(spi_rxbuf, spi_txbuf, 8 + ch * 12)) { ac_ad_values[ch] = readUint24BE(spi_rxbuf, 8 + ch * 12); LOGI("channel : %d ac_ad_values: %d\n ", ch, ac_ad_values[ch]); gWordVar[AC_CURRENT_REG_ADDR + ch] = ac_ad_values[ch] * ac_current_coef[ch]; } else { int value = readUint24BE(spi_rxbuf, 8 + ch * 12); LOGW("check bed ch: %d ac_ad_values: %d\n ", ch, value); } // ac_ad_values[ch] = readUint24BE(bl0939_rxbuf,8+ch*12); // ESP_LOGI(TAG, "channel : %d ac_ad_values: %d\n ", ch, ac_ad_values[ch]); } } else { LOGE("spi_write_read err ret=%d\r\n", ret); } gWordVar[ENC_VALUE_REG_ADDR] = enc_value & 0xffff; gWordVar[ENC_VALUE_REG_ADDR + 1] = enc_value >> 16; ql_LvlMode gpio_value9; ql_LvlMode gpio_value10; ql_gpio_get_level(GPIO_9, &gpio_value9); ql_gpio_get_level(GPIO_10, &gpio_value10); gWordVar[ENC_VALUE_REG_ADDR + 2] = gpio_value9 | (gpio_value10 << 1); break; } } else { LOGE("timer not work ??", ret); osiTimerStart(bl_timer, 20); } } }