/** * \file b_drv_ltc2662iuh_12.c * \version v0.0.1 * \date 2024-02-19 * \author miniminiminini (405553848@qq.com) * \brief LTC2662IUH_12���� * * Copyright (c) 2024 by miniminiminini. All Rights Reserved. */ /* Includes ----------------------------------------------*/ #include <math.h> #include "drivers/inc/b_drv_ltc2662iuh_12.h" /** * \defgroup LTC2662IUH_12_Private_FunctionPrototypes * \{ */ /** * } */ /** * \defgroup LTC2662IUH_12_Exported_Variables * \{ */ /** * } */ /** * \defgroup LTC2662IUH_12_Private_Defines * \{ */ #define DRIVER_NAME LTC2662IUH_12 #define DAC0 0X00 #define DAC1 0X01 #define DAC2 0X02 #define DAC3 0X03 #define DAC4 0X04 // #define L2B_B2L_16b(n) ((((n) & 0xff) << 8) | (((n) & 0xff00) >> 8)) /** * } */ /** * \defgroup LTC2662IUH_12_Private_TypesDefinitions * \{ */ /** * } */ /** * \defgroup LTC2662IUH_12_Private_Macros * \{ */ /** * } */ /** * \defgroup LTC2662IUH_12_Private_Variables * \{ */ bDRIVER_HALIF_TABLE(bLTC2662IUH_12_HalIf_t, DRIVER_NAME); bLTC2662IUH_12Private_t bLTC2662IUH_12RunInfo[bDRIVER_HALIF_NUM(bLTC2662IUH_12_HalIf_t, DRIVER_NAME)]; /** * } */ /** * \defgroup LTC2662IUH_12_Private_Functions * \{ */ static int _bLTC2662_Send(bDriverInterface_t *pdrv, uint8_t *pbuf, uint16_t len) { bDRIVER_GET_HALIF(_if, bLTC2662IUH_12_HalIf_t, pdrv); return bHalSpiSend(_if, pbuf, len); } static int _bLTC2662_Recv(bDriverInterface_t *pdrv, uint8_t *pbuf, uint16_t len) { bDRIVER_GET_HALIF(_if, bLTC2662IUH_12_HalIf_t, pdrv); return bHalSpiReceive(_if, pbuf, len); } /** * @brief ͨ����Ӧdacͨ����expect_current������span��span_value * * @param pdrv * @param dac_x * @return LTC2662_SPAN_t */ static int _bLTC2662_DACX_Updata_Span(bDriverInterface_t *pdrv, LTC2662_DAC_t dac_x) { bDRIVER_GET_PRIVATE(_priv, bLTC2662IUH_12Private_t, pdrv); float current = _priv->dac_attribute[dac_x].expect_current; if (dac_x >= LTC_DAC_MAX) { b_log_e("Invalid DAC channel"); return -1; } if (current <= LTC_SPAN_3_125) { _priv->dac_attribute[dac_x].span = LTC_SPAN_3_125mA; _priv->dac_attribute[dac_x].span_value = LTC_SPAN_3_125; _priv->dac_attribute[dac_x].span_div = LTC_SPAN_3_125 / 4095; } else if (current <= LTC_SPAN_6_25) { _priv->dac_attribute[dac_x].span = LTC_SPAN_6_25mA; _priv->dac_attribute[dac_x].span_value = LTC_SPAN_6_25; _priv->dac_attribute[dac_x].span_div = LTC_SPAN_6_25 / 4095; } else if (current <= LTC_SPAN_12_5) { _priv->dac_attribute[dac_x].span = LTC_SPAN_12_5mA; _priv->dac_attribute[dac_x].span_value = LTC_SPAN_12_5; _priv->dac_attribute[dac_x].span_div = LTC_SPAN_12_5 / 4095; } else if (current <= LTC_SPAN_25) { _priv->dac_attribute[dac_x].span = LTC_SPAN_25mA; _priv->dac_attribute[dac_x].span_value = LTC_SPAN_25; _priv->dac_attribute[dac_x].span_div = LTC_SPAN_25 / 4095; } else if (current <= LTC_SPAN_50) { _priv->dac_attribute[dac_x].span = LTC_SPAN_50mA; _priv->dac_attribute[dac_x].span_value = LTC_SPAN_50; _priv->dac_attribute[dac_x].span_div = LTC_SPAN_50 / 4095; } else if (current <= LTC_SPAN_100) { _priv->dac_attribute[dac_x].span = LTC_SPAN_100mA; _priv->dac_attribute[dac_x].span_value = LTC_SPAN_100; _priv->dac_attribute[dac_x].span_div = LTC_SPAN_100 / 4095; } else if (current <= LTC_SPAN_200) { _priv->dac_attribute[dac_x].span = LTC_SPAN_200mA; _priv->dac_attribute[dac_x].span_value = LTC_SPAN_200; _priv->dac_attribute[dac_x].span_div = LTC_SPAN_200 / 4095; } else if (current <= LTC_SPAN_300) { _priv->dac_attribute[dac_x].span = LTC_SPAN_300mA; _priv->dac_attribute[dac_x].span_value = LTC_SPAN_300; _priv->dac_attribute[dac_x].span_div = LTC_SPAN_300 / 4095; } else { b_log_e("Invalid current value"); return -2; } if ((dac_x == LTC_DAC_0)) { // b_log("$$$ DAC4 current: %.2f, span: %d, span_value: %.2f, span_div: %.2f\r\n", current, // _priv->dac_attribute[dac_x].span, _priv->dac_attribute[dac_x].span_value, // _priv->dac_attribute[dac_x].span_div); } return 0; } /** * @brief ���ڴ������仯ʱ����ijһ��ͨ����DAC����ֵ * * @param pdrv * @param dac_x * @return int */ static int _bLTC2662_DACX_Attribute_Updata(bDriverInterface_t *pdrv, LTC2662_DAC_t dac_x) { bDRIVER_GET_PRIVATE(_priv, bLTC2662IUH_12Private_t, pdrv); if (dac_x >= LTC_DAC_MAX) { b_log_e("Invalid DAC channel"); return -1; } if (_bLTC2662_DACX_Updata_Span(pdrv, dac_x) < 0) { b_log_e("Invalid current value"); return -2; } _priv->dac_attribute[dac_x].set_value = round(_priv->dac_attribute[dac_x].expect_current / _priv->dac_attribute[dac_x].span_div); if ((dac_x == LTC_DAC_0)) { // b_log("^^^ set_value:%d", _priv->dac_attribute[dac_x].set_value); } _priv->dac_attribute[dac_x].set_value = _priv->dac_attribute[dac_x].set_value > 4095 ? 4095 : _priv->dac_attribute[dac_x].set_value; _priv->dac_attribute[dac_x].real_current = _priv->dac_attribute[dac_x].set_value * _priv->dac_attribute[dac_x].span_div; _priv->dac_attribute[dac_x].err_current = _priv->dac_attribute[dac_x].expect_current - _priv->dac_attribute[dac_x].real_current; _priv->dac_attribute[dac_x].err_percentage_current = _priv->dac_attribute[dac_x].err_current / _priv->dac_attribute[dac_x].expect_current; if ((dac_x == LTC_DAC_0)) { // b_log("^^^ set_value:%d real_current=%.2f\r\n", _priv->dac_attribute[dac_x].set_value, // _priv->dac_attribute[dac_x].real_current); } return 0; } /** * \brief д�뷶Χ��n * \param pdrv * \param dac_x * \param range * \return int */ static int _bLTC2662_WriteSpanToN(bDriverInterface_t *pdrv, LTC2662_DAC_t dac_x) { uint8_t send_buf[3] = {0, 0, 0}; U_LT_Write data; bDRIVER_GET_HALIF(_if, bLTC2662IUH_12_HalIf_t, pdrv); bDRIVER_GET_PRIVATE(_priv, bLTC2662IUH_12Private_t, pdrv); if (dac_x >= LTC_DAC_MAX) { b_log_e("Invalid DAC channel"); return -1; } // 0 1 1 0 Write Span to n if (dac_x == LTC_DAC_0) { send_buf[0] = WRITE_SPAN_TO_N | DAC0; } else if (dac_x == LTC_DAC_1) { send_buf[0] = WRITE_SPAN_TO_N | DAC1; } else if (dac_x == LTC_DAC_2) { send_buf[0] = WRITE_SPAN_TO_N | DAC2; } else if (dac_x == LTC_DAC_3) { send_buf[0] = WRITE_SPAN_TO_N | DAC3; } else if (dac_x == LTC_DAC_4) { send_buf[0] = WRITE_SPAN_TO_N | DAC4; } if (_priv->dac_attribute[dac_x].span == LTC_SPAN_3_125mA) { data.LT_uint16 = LTC_SPAN_VALUE_3_125mA; } else if (_priv->dac_attribute[dac_x].span == LTC_SPAN_6_25mA) { data.LT_uint16 = LTC_SPAN_VALUE_6_25mA; } else if (_priv->dac_attribute[dac_x].span == LTC_SPAN_12_5mA) { data.LT_uint16 = LTC_SPAN_VALUE_12_5mA; } else if (_priv->dac_attribute[dac_x].span == LTC_SPAN_25mA) { data.LT_uint16 = LTC_SPAN_VALUE_25mA; } else if (_priv->dac_attribute[dac_x].span == LTC_SPAN_50mA) { data.LT_uint16 = LTC_SPAN_VALUE_50mA; } else if (_priv->dac_attribute[dac_x].span == LTC_SPAN_100mA) { data.LT_uint16 = LTC_SPAN_VALUE_100mA; } else if (_priv->dac_attribute[dac_x].span == LTC_SPAN_200mA) { data.LT_uint16 = LTC_SPAN_VALUE_200mA; } else if (_priv->dac_attribute[dac_x].span == LTC_SPAN_300mA) { data.LT_uint16 = LTC_SPAN_VALUE_300mA; } uint8_t temp_data = data.LT_byte[0]; data.LT_byte[0] = data.LT_byte[1]; data.LT_byte[1] = temp_data; send_buf[1] = data.LT_byte[0]; send_buf[2] = data.LT_byte[1]; uint8_t tmp_send_buf[4] = {0, 0, 0, 0}; memcpy(&tmp_send_buf[1], &send_buf[0], 3); // spi���� bHalGpioWritePin(_if->cs.port, _if->cs.pin, 0); _bLTC2662_Send(pdrv, tmp_send_buf, 4); bHalGpioWritePin(_if->cs.port, _if->cs.pin, 1); bHalGpioWritePin(_if->_if.simulating_spi.mosi.port, _if->_if.simulating_spi.mosi.pin, 1); if ((dac_x == LTC_DAC_0)) { b_log("%d###%02x %02X %02X %02X\r\n", _priv->dac_attribute[dac_x].span, tmp_send_buf[0], tmp_send_buf[1], tmp_send_buf[2], tmp_send_buf[3]); } return 0; } /** * \brief д������� n������ n���ϵ磩 * \param pdrv * \param dac_x * \param range * \return int */ static int _bLTC2662_WriteCodeToNUpdateN(bDriverInterface_t *pdrv, LTC2662_DAC_t dac_x) { uint8_t send_buf[3] = {0, 0, 0}; U_LT_Write data; bDRIVER_GET_HALIF(_if, bLTC2662IUH_12_HalIf_t, pdrv); bDRIVER_GET_PRIVATE(_priv, bLTC2662IUH_12Private_t, pdrv); if (dac_x >= LTC_DAC_MAX) { b_log_e("Invalid DAC channel"); return -1; } // 0 0 1 1 if (dac_x == LTC_DAC_0) { send_buf[0] = WRITE_CODE_TO_N_UPDATE_N | DAC0; } else if (dac_x == LTC_DAC_1) { send_buf[0] = WRITE_CODE_TO_N_UPDATE_N | DAC1; } else if (dac_x == LTC_DAC_2) { send_buf[0] = WRITE_CODE_TO_N_UPDATE_N | DAC2; } else if (dac_x == LTC_DAC_3) { send_buf[0] = WRITE_CODE_TO_N_UPDATE_N | DAC3; } else if (dac_x == LTC_DAC_4) { send_buf[0] = WRITE_CODE_TO_N_UPDATE_N | DAC4; } // ��set_value��16bitת��Ϊ12bit,���ĸ���λ,���ҽ���MSB-TO-LSB data.LT_uint16 = _priv->dac_attribute[dac_x].set_value; uint8_t temp_data = data.LT_byte[0]; data.LT_byte[0] = data.LT_byte[1]; data.LT_byte[1] = temp_data; send_buf[1] = data.LT_byte[0] << 4 | data.LT_byte[1] >> 4; send_buf[2] = data.LT_byte[1] << 4; uint8_t tmp_send_buf[4] = {0, 0, 0, 0}; memcpy(&tmp_send_buf[1], &send_buf[0], 3); // spi���� bHalGpioWritePin(_if->cs.port, _if->cs.pin, 0); _bLTC2662_Send(pdrv, tmp_send_buf, 4); bHalGpioWritePin(_if->cs.port, _if->cs.pin, 1); bHalGpioWritePin(_if->_if.simulating_spi.mosi.port, _if->_if.simulating_spi.mosi.pin, 1); if ((dac_x == LTC_DAC_0)) { b_log("%d %.2f||| %02X %02X %02X %02X\r\n", _priv->dac_attribute[dac_x].set_value, _priv->dac_attribute[dac_x].real_current, tmp_send_buf[0], tmp_send_buf[1], tmp_send_buf[2], tmp_send_buf[3]); } return 0; } static int _bLTC2662_DACX_Exec(bDriverInterface_t *pdrv, LTC2662_DAC_t dac_x) { bDRIVER_GET_PRIVATE(_priv, bLTC2662IUH_12Private_t, pdrv); if (dac_x >= LTC_DAC_MAX) { b_log_e("Invalid DAC channel"); return -1; } if (_bLTC2662_WriteSpanToN(pdrv, dac_x) < 0) { b_log_e("_bLTC2662_WriteSpanToN chx=%d err!!!\r\n", dac_x); return -2; } if (_bLTC2662_WriteCodeToNUpdateN(pdrv, dac_x) < 0) { b_log_e("_bLTC2662_WriteCodeToNUpdateN chx=%d err!!!\r\n", dac_x); return -3; } _priv->dac_attribute[dac_x].status = 1; // b_log_i("\r\n%d\t%10.3f\t%10.3f\t%10.3f\t%10.3f\t\r\n", dac_x, // _priv->dac_attribute[dac_x].expect_current, _priv->dac_attribute[dac_x].real_current, // _priv->dac_attribute[dac_x].err_current, // _priv->dac_attribute[dac_x].err_percentage_current); return 0; } // Power Down n static int _bLTC2662_DACX_Stop(bDriverInterface_t *pdrv, LTC2662_DAC_t dac_x) { uint8_t send_buf[3] = {0, 0, 0}; bDRIVER_GET_HALIF(_if, bLTC2662IUH_12_HalIf_t, pdrv); bDRIVER_GET_PRIVATE(_priv, bLTC2662IUH_12Private_t, pdrv); if (dac_x >= LTC_DAC_MAX) { b_log_e("Invalid DAC channel"); return -1; } // 0 1 0 0 Power Down N if (dac_x == LTC_DAC_0) { send_buf[0] = POWER_DOWN_N | DAC0; } else if (dac_x == LTC_DAC_1) { send_buf[0] = POWER_DOWN_N | DAC1; } else if (dac_x == LTC_DAC_2) { send_buf[0] = POWER_DOWN_N | DAC2; } else if (dac_x == LTC_DAC_3) { send_buf[0] = POWER_DOWN_N | DAC3; } else if (dac_x == LTC_DAC_4) { send_buf[0] = POWER_DOWN_N | DAC4; } send_buf[1] = 0; send_buf[2] = 0; uint8_t tmp_send_buf[4] = {0, 0, 0, 0}; memcpy(&tmp_send_buf[1], &send_buf[0], 3); // spi���� bHalGpioWritePin(_if->cs.port, _if->cs.pin, 0); _bLTC2662_Send(pdrv, tmp_send_buf, 4); bHalGpioWritePin(_if->cs.port, _if->cs.pin, 1); _priv->dac_attribute[dac_x].status = 0; _priv->dac_attribute[dac_x].expect_current = 0; // b_log_i("\r\n%d\t%d\t\r\n", dac_x, _priv->dac_attribute[dac_x].status); return 0; } static int _bLTC2662_GET_DACX_FR(bDriverInterface_t *pdrv, LTC2662_DAC_t dac_x) { int ret = -1; uint8_t recv_buf[3] = {0, 0, 0}; bDRIVER_GET_HALIF(_if, bLTC2662IUH_12_HalIf_t, pdrv); if (dac_x >= LTC_DAC_MAX) { b_log_e("Invalid DAC channel"); return -1; } // spi���� bHalGpioWritePin(_if->cs.port, _if->cs.pin, 0); _bLTC2662_Recv(pdrv, recv_buf, 3); bHalGpioWritePin(_if->cs.port, _if->cs.pin, 1); switch (dac_x) { case LTC_DAC_0: ret = recv_buf[0] & 0x01; break; case LTC_DAC_1: ret = recv_buf[0] & 0x02; break; case LTC_DAC_2: ret = recv_buf[0] & 0x04; break; case LTC_DAC_3: ret = recv_buf[0] & 0x08; break; case LTC_DAC_4: ret = recv_buf[0] & 0x10; break; default: break; } return ret; } static int _bLTC2662IUH_12Ctl(bDriverInterface_t *pdrv, uint8_t cmd, void *param) { bDRIVER_GET_PRIVATE(_priv, bLTC2662IUH_12Private_t, pdrv); bLTC2662_CONFIG_t *p = (bLTC2662_CONFIG_t *)param; bLTC2662_STATUS_t *q = (bLTC2662_STATUS_t *)param; switch (cmd) { case bCMD_LTC_GET_DACX_STATUS: if (param == NULL) { b_log_e("bCMD_LTC_GET_DACX_STATUS param err!!!\r\n"); return -1; } if (q->dac_channel >= LTC_DAC_MAX) { b_log_e("bCMD_LTC_GET_DACX_STATUS dac_channel err!!!\r\n"); return -2; } q->status = _priv->dac_attribute[q->dac_channel].status; break; case bCMD_LTC_SET_CURRENT: if (param == NULL) { b_log_e("bCMD_LTC_SET_CURRENT param err!!!\r\n"); return -1; } if (p->dac_channel >= LTC_DAC_MAX) { b_log_e("bCMD_LTC_SET_CURRENT dac_channel err!!!\r\n"); return -2; } _priv->dac_attribute[p->dac_channel].expect_current = p->current; break; case bCMD_LTC_GET_CURRENT: if (param == NULL) { b_log_e("bCMD_LTC_GET_CURRENT param err!!!\r\n"); return -1; } if (p->dac_channel >= LTC_DAC_MAX) { b_log_e("bCMD_LTC_GET_CURRENT dac_channel err!!!\r\n"); return -2; } p->current = _priv->dac_attribute[p->dac_channel].real_current; break; case bCMD_LTC_EXEC_DACX: if (param == NULL) { b_log_e("bCMD_LTC_EXEC_DACX param err!!!\r\n"); return -1; } if (p->dac_channel >= LTC_DAC_MAX) { b_log_e("bCMD_LTC_EXEC_DACX dac_channel err!!!\r\n"); return -2; } if (p->current < 0) { b_log_e("bCMD_LTC_EXEC_DACX current err!!!\r\n"); return -3; } if (p->current == _priv->dac_attribute[p->dac_channel].expect_current) { // b_log_i("bCMD_LTC_EXEC_DACX current is equal to expect_current, no need to // exec!!!\r\n"); return 0; } else { _priv->dac_attribute[p->dac_channel].expect_current = p->current; } if (_bLTC2662_DACX_Attribute_Updata(pdrv, p->dac_channel) < 0) { b_log_e("_bLTC2662_DACX_Attribute_Updata chx=%d err!!!\r\n", p->dac_channel); return -4; } if (_bLTC2662_DACX_Exec(pdrv, p->dac_channel) < 0) { b_log_e("_bLTC2662_DACX_Exec chx=%d err!!!\r\n", p->dac_channel); return -5; } break; case bCMD_LTC_STOP_DACX: if (param == NULL) { b_log_e("bCMD_LTC_STOP_DACX param err!!!\r\n"); return -1; } if (p->dac_channel >= LTC_DAC_MAX) { b_log_e("bCMD_LTC_STOP_DACX dac_channel err!!!\r\n"); return -2; } if (_bLTC2662_DACX_Stop(pdrv, p->dac_channel) < 0) { b_log_e("_bLTC2662_DACX_Stop chx=%d err!!!\r\n", p->dac_channel); return -3; } break; case bCMD_LTC_GET_DACX_FR: if (param == NULL) { b_log_e("bCMD_LTC_GET_DACX_FR param err!!!\r\n"); return -1; } if (q->dac_channel >= LTC_DAC_MAX) { b_log_e("bCMD_LTC_GET_DACX_FR dac_channel err!!!\r\n"); return -2; } q->status = _priv->dac_attribute[q->dac_channel].status; q->open_circuit_fault = _bLTC2662_GET_DACX_FR(pdrv, q->dac_channel); break; default: break; } return 0; } /** * \brief �ض�ģʽ * \param pdrv * \return int */ static int _bLTC2662IUH_12Close(bDriverInterface_t *pdrv) { for (uint8_t i = 0; i < LTC_DAC_MAX; i++) { _bLTC2662_DACX_Stop(pdrv, (LTC2662_DAC_t)i); } return 0; } /** * } */ /** * \defgroup LTC2662IUH_12_Exported_Functions * \{ */ int bLTC2662IUH_12_Init(bDriverInterface_t *pdrv) { bDRIVER_STRUCT_INIT(pdrv, DRIVER_NAME, bLTC2662IUH_12_Init); pdrv->ctl = _bLTC2662IUH_12Ctl; pdrv->close = _bLTC2662IUH_12Close; pdrv->_private._p = &bLTC2662IUH_12RunInfo[pdrv->drv_no]; _bLTC2662IUH_12Close(pdrv); return 0; } #ifdef BSECTION_NEED_PRAGMA #pragma section driver_init #endif bDRIVER_REG_INIT(B_DRIVER_LTC2662IUH_12, bLTC2662IUH_12_Init); #ifdef BSECTION_NEED_PRAGMA #pragma section #endif /** * } */ /** * } */ /** * } */ /** * } */ /***** Copyright (c) 2024 miniminiminini *****END OF FILE*****/