#include "bl0939.h" #include "string.h" #include "utils.h" // #include "ModbusS.h" #include "config.h" #include #include #include #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_system.h" #include "driver/spi_master.h" #include "driver/gpio.h" #include "esp_log.h" #define TAG "BL0939" #define BL0939_HOST SPI3_HOST #define SPI1_PIN_NUM_MISO 37 #define SPI1_PIN_NUM_MOSI 36 #define SPI1_PIN_NUM_CLK 35 #define SPI1_PIN_NUM_CS 40 extern move_t *pMoveCtx; // To speed up transfers, every SPI transfer sends a bunch of lines. This define specifies how many. More means more memory use, // but less overhead for setting up / finishing transfers. Make sure 240 is dividable by this. #define PARALLEL_LINES 16 static spi_device_handle_t spi1; static void SPI1_Init(void) { esp_err_t ret; spi_bus_config_t buscfg1 = { .miso_io_num = SPI1_PIN_NUM_MISO, .mosi_io_num = SPI1_PIN_NUM_MOSI, .sclk_io_num = SPI1_PIN_NUM_CLK, .quadwp_io_num = -1, .quadhd_io_num = -1, .max_transfer_sz = PARALLEL_LINES * 320 * 2 + 8}; spi_device_interface_config_t devcfg1 = { #ifdef CONFIG_LCD_OVERCLOCK .clock_speed_hz = 26 * 1000 * 1000, // Clock out at 26 MHz #else .clock_speed_hz = 8 * 100 * 1000, // Clock out at 800kHz #endif .mode = 1, // SPI mode 1 .spics_io_num = SPI1_PIN_NUM_CS, // CS pin .queue_size = 7, // We want to be able to queue 7 transactions at a time // .command_bits = 8, // .pre_cb = lcd_spi_pre_transfer_callback, // Specify pre-transfer callback to handle D/C line }; // Initialize the SPI bus ret = spi_bus_initialize(BL0939_HOST, &buscfg1, SPI_DMA_CH_AUTO); ESP_ERROR_CHECK(ret); // Attach the ADS1220 to the SPI bus ret = spi_bus_add_device(BL0939_HOST, &devcfg1, &spi1); ESP_ERROR_CHECK(ret); } void bl0939_spi_reset(void); static void BL0939_SPI_TransmitReceive(uint8_t *tbuff, uint8_t *rbuff, uint16_t len) { esp_err_t ret; spi_transaction_t t; memset(&t, 0, sizeof(t)); // Zero out the transaction t.tx_buffer = tbuff; t.rx_buffer = rbuff; t.length = len * 8; // Command is 16 bits ret = spi_device_polling_transmit(spi1, &t); // Transmit! assert(ret == ESP_OK); } static uint32_t bl0939_read_reg(uint8_t reg) { uint8_t tx_buf[6] = {0x55, reg, 0, 0, 0, 0}; uint8_t rx_buf[6] = {0}; // bl0939_spi_reset(); BL0939_SPI_TransmitReceive(tx_buf, rx_buf, 6); if (rx_buf[5] == (uint8_t) ~(0x55 + reg + rx_buf[2] + rx_buf[3] + rx_buf[4])) { return (uint32_t)rx_buf[2] << 16 | (uint32_t)rx_buf[3] << 8 | (uint32_t)rx_buf[4] << 0; } return 0; } uint32_t r_temp = 0; static int bl0939_write_reg(uint8_t reg, uint32_t val, int check) { int i = 5; uint8_t h = val >> 16; uint8_t m = val >> 8; uint8_t l = val >> 0; do { i--; vTaskDelay(5); // bl0939_spi_reset(); uint8_t tx_buf[6] = {0xA5, reg, h, m, l, ~(0XA5 + reg + h + m + l)}; uint8_t rx_buf[6] = {0}; BL0939_SPI_TransmitReceive(tx_buf, rx_buf, 6); vTaskDelay(10); if (0 == check) return 0; r_temp = bl0939_read_reg(reg); if (r_temp == val) return 0; } while (i > 0); return 1; } void bl0939_spi_reset(void) { uint8_t tx_buf[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; uint8_t rx_buf[6] = {0}; BL0939_SPI_TransmitReceive(tx_buf, rx_buf, 6); } uint32_t comp_threshold(float mA) { return (uint32_t)(mA * 1 * 324004 * 0.00140625f * 0.95f / (600 * 1.218f)); } void bl0939_reset(void) { bl0939_spi_reset(); bl0939_write_reg(0x19, 0x005a5a5a, 0); // ��λ�û��Ĵ��� bl0939_write_reg(0x1a, 0x00000055, 1); // ���д���� bl0939_write_reg(0x10, 0xffff, 0); // Threshold A bl0939_write_reg(0x1E, 0xffff, 1); // Threshold B bl0939_write_reg(0x18, 0x00002000, 1); // cf bl0939_write_reg(0x1B, 0x000047ff, 0); // cf bl0939_write_reg(0x1a, 0x00000000, 1); // д���� } // T = 40ms int bl0939_get_current_A() { bl0939_spi_reset(); uint32_t Ia = bl0939_read_reg(0x00); // return Ia * 1.218f / (float) ( 324004 * 1 ); return Ia; } // T = 40ms int bl0939_get_current_B() { bl0939_spi_reset(); uint32_t Ib = bl0939_read_reg(0x07); // return Ib * 1.218f / (float) ( 324004 * 1 ); return Ib; } // T = 400ms int bl0939_get_voltage() { bl0939_spi_reset(); uint32_t v = bl0939_read_reg(0x06); // return v * 1.218f * ( 2 + 2000 ) / (float) ( 79931 * 2 * 1000 ); return v; } /// @brief 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}; int check_sum_ch(uint8_t *buf, int offset) { uint8_t sum = ~(0x55 + bl0939_cmd[offset - 1] + buf[offset] + buf[offset + 1] + buf[offset + 2]); if (buf[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]; } // __IO uint8_t bl0939_Transfer_done = 0; uint8_t bl0939_Transfer_done = 0; void bl0939_init(void) { bl0939_reset(); } 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[2][36]; int32_t ac_ad_values[3] = {0}; int move_time = 0; int move_req = 0; extern uint16_t gWordVar[]; int move_status = 0; void BL0939_task() { int index = 0; while (1) { vTaskDelay(10); // ESP_LOGI(TAG, "BL0939_SPI_TransmitReceive before\n "); bl0939_Transfer_done = 1; BL0939_SPI_TransmitReceive(bl0939_cmd, bl0939_rxbuf[index & 1], 36); if (!memcmp(bl0939_rxbuf[0], bl0939_rxbuf[1], sizeof(bl0939_rxbuf[0]))) { index++; bl0939_Transfer_done = 0; // continue; } // ESP_LOGI(TAG, "BL0939_SPI_TransmitReceive after\n "); if (bl0939_Transfer_done) { int ch; // ESP_LOGI(TAG, "bl0939_Transfer_done \n "); bl0939_Transfer_done = 0; for (ch = 0; ch < 3; ch++) { if (check_sum_ch(bl0939_rxbuf[index & 1], 8 + ch * 12)) { ac_ad_values[ch] = readUint24BE(bl0939_rxbuf[index & 1], 8 + ch * 12); // ESP_LOGI(TAG, "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]; } // 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]); } if (pMoveCtx->status == 0) { // 停止状态,等待启动 int move_current_channel = depth_config->move_current_channel; if (move_current_channel > 2 || move_current_channel < 0) { move_current_channel = 2; } if (gWordVar[AC_CURRENT_REG_ADDR + move_current_channel] > depth_config->current_on_threshold) { if (++pMoveCtx->time_count > depth_config->move_on_duratino) { pMoveCtx->status = 1; pMoveCtx->time_count = 0; pMoveCtx->pile_inc_req = 1; } } } else if (pMoveCtx->status == 1) { int move_current_channel = depth_config->move_current_channel; if (move_current_channel > 2 || move_current_channel < 0) { move_current_channel = 2; } if (gWordVar[AC_CURRENT_REG_ADDR + 2] < depth_config->current_off_threshold) { if (++pMoveCtx->time_count > depth_config->move_off_duration) { pMoveCtx->status = 0; pMoveCtx->time_count = 0; } } } } } } void BL0939_init(void) { SPI1_Init(); bl0939_init(); xTaskCreate(BL0939_task, "BL0939_task", 4096, NULL, 10, NULL); }