pile_com_stm32/main/stm32/bl0939.c
2024-04-15 18:04:26 +08:00

302 lines
8.1 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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"
#include "pile_id.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}; // 软复位SPI接口
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); // 0x5a5a5a软件复位用户寄存器区
bl0939_write_reg(0x1a, 0x00000055, 1); // 寄存器写保护0x55可以写其他值不能写
bl0939_write_reg(0x10, 0xffff, 0); // Threshold A 电流通道快速有效值控制寄存器
bl0939_write_reg(0x1E, 0xffff, 1); // Threshold B
bl0939_write_reg(0x18, 0x00002000, 1); // 用户模式选择寄存器
bl0939_write_reg(0x1B, 0x000047ff, 0); // 温度模式控制寄存器
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, // A通道快速有效值无符号 24bit
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x55, 0x07, 0, 0, 0, 0, // B通道快速有效值无符号 24bit
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x55, 0x06, 0, 0, 0, 0}; // 电压有效值寄存器,无符号 24bit
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(pdMS_TO_TICKS(100));
// 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) // 时间单位和采样时间有关100ms
{
pMoveCtx->status = 1;
pMoveCtx->time_count = 0;
pMoveCtx->work_time = 0;
pMoveCtx->pile_inc_req = 1;
pMoveCtx->work_stop_state_flag = 0;
// ESP_LOGI(TAG, "cur > th, status trun to on");
}
}
}
else if (pMoveCtx->status == 1)
{
// ESP_LOGI(TAG, "mov status is on");
pMoveCtx->work_time++;
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_off_threshold)
{
if (++pMoveCtx->time_count > depth_config->move_off_duration)
{
pMoveCtx->status = 0;
pMoveCtx->time_count = 0;
if (pMoveCtx->work_time >= CURRENT2_TIMEOUT_TH)
{
pMoveCtx->work_stop_state_flag = 1;
}
// 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);
}