pile_com_stm32/main/stm32/bl0939.c
2024-02-23 17:21:13 +08:00

295 lines
7.5 KiB
C
Raw Blame History

#include "bl0939.h"
#include "string.h"
#include "utils.h"
// #include "ModbusS.h"
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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;
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 = 128
};
spi_device_interface_config_t devcfg1 = {
.clock_speed_hz = 8 * 100 * 1000, // Clock out at 800kHz
.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); // <20><>λ<EFBFBD>û<EFBFBD><C3BB>Ĵ<EFBFBD><C4B4><EFBFBD>
bl0939_write_reg(0x1a, 0x00000055, 1); // <20><><EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD>
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); // д<><D0B4><EFBFBD><EFBFBD>
}
// 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;
// ESP_LOGI(TAG, "bl0939 data not change");
// 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, "bl0939 channel:%d ac_ad_values:%d", ch, ac_ad_values[ch]);
gWordVar[AC_CURRENT_REG_ADDR + ch] = ac_ad_values[ch] * ac_current_coef[ch];
// ESP_LOGI(TAG, "bl0939 channel:%d value:%d", ch, gWordVar[AC_CURRENT_REG_ADDR + 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)
{ // 停止状态,等待启动
// ESP_LOGI(TAG, "mov status is off");
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;
// ESP_LOGI(TAG, "cur > th, status trun to on");
}
}
}
else if (pMoveCtx->status == 1)
{
// ESP_LOGI(TAG, "mov status is on");
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;
// ESP_LOGI(TAG, "cur > th, status trun to off");
}
}
}
}
}
}
void BL0939_init(void)
{
SPI1_Init();
bl0939_init();
xTaskCreate(BL0939_task, "BL0939_task", 4096, NULL, 10, NULL);
}