Backup before error handling refactoring
This commit is contained in:
1428
USER/Ref/bmu-18s-firmware/HARDWARE/Old/ltc6813-1.c
Normal file
1428
USER/Ref/bmu-18s-firmware/HARDWARE/Old/ltc6813-1.c
Normal file
File diff suppressed because it is too large
Load Diff
180
USER/Ref/bmu-18s-firmware/HARDWARE/can.c
Normal file
180
USER/Ref/bmu-18s-firmware/HARDWARE/can.c
Normal file
@@ -0,0 +1,180 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* File Name : can.c
|
||||
* Description : This file provides code for the configuration
|
||||
* of CAN Port.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2021 Amogreentech Co., Ltd.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "sys.h"
|
||||
#include "delay.h"
|
||||
#include "can.h"
|
||||
#include "includes.h"
|
||||
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
#define RX_BUFFER_SIZE 32
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
typedef struct
|
||||
{
|
||||
CAN_TypeDef *can;
|
||||
volatile u16 RxInPos, RxOutPos;
|
||||
u16 TxInPos, TxOutPos;
|
||||
CanRxMsg RxBuf[RX_BUFFER_SIZE];
|
||||
} CAN_Info;
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
CAN_Info Can;
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
|
||||
// Initializes CAN Port
|
||||
// Bound: baud rate
|
||||
void can1_init(u32 buadrate)
|
||||
{
|
||||
//GPIO port settings
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
CAN_InitTypeDef CAN_InitStructure;
|
||||
CAN_FilterInitTypeDef CAN_FilterInitStructure;
|
||||
|
||||
Can.can = CAN1;
|
||||
|
||||
/* GPIO clock enable */
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //Enable GPIOA clock
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE); //Enable CAN1 clock
|
||||
|
||||
/* Configure CAN pin: RX */
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
|
||||
GPIO_Init(GPIOA, &GPIO_InitStructure);
|
||||
|
||||
/* Configure CAN pin: TX */
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_Init(GPIOA, &GPIO_InitStructure);
|
||||
|
||||
//CAN1 Initialization settings
|
||||
CAN_DeInit(Can.can);
|
||||
|
||||
CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
|
||||
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
|
||||
|
||||
switch (buadrate)
|
||||
{
|
||||
case 125000:
|
||||
CAN_InitStructure.CAN_BS1 = CAN_BS1_2tq;
|
||||
CAN_InitStructure.CAN_BS2 = CAN_BS2_5tq;
|
||||
CAN_InitStructure.CAN_Prescaler = 42;
|
||||
break;
|
||||
case 250000:
|
||||
CAN_InitStructure.CAN_BS1 = CAN_BS1_3tq;
|
||||
CAN_InitStructure.CAN_BS2 = CAN_BS2_4tq;
|
||||
CAN_InitStructure.CAN_Prescaler = 16;
|
||||
break;
|
||||
case 500000:
|
||||
CAN_InitStructure.CAN_BS1 = CAN_BS1_4tq;
|
||||
CAN_InitStructure.CAN_BS2 = CAN_BS2_7tq;
|
||||
CAN_InitStructure.CAN_Prescaler = 7;
|
||||
break;
|
||||
case 1000000:
|
||||
/* CAN Baudrate = 1MBps*/
|
||||
CAN_InitStructure.CAN_BS1 = CAN_BS1_3tq;
|
||||
CAN_InitStructure.CAN_BS2 = CAN_BS2_5tq;
|
||||
CAN_InitStructure.CAN_Prescaler = 4;
|
||||
break;
|
||||
}
|
||||
CAN_InitStructure.CAN_TTCM = DISABLE; //
|
||||
CAN_InitStructure.CAN_ABOM = DISABLE; //
|
||||
CAN_InitStructure.CAN_AWUM = DISABLE; //
|
||||
CAN_InitStructure.CAN_NART = DISABLE; //
|
||||
CAN_InitStructure.CAN_RFLM = DISABLE; //
|
||||
CAN_InitStructure.CAN_TXFP = ENABLE; //
|
||||
|
||||
/* CAN filter init */
|
||||
CAN_FilterInitStructure.CAN_FilterNumber = 0;
|
||||
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
|
||||
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
|
||||
CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
|
||||
CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
|
||||
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
|
||||
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
|
||||
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
|
||||
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
|
||||
|
||||
CAN_FilterInit(&CAN_FilterInitStructure);
|
||||
|
||||
CAN_Init(Can.can, &CAN_InitStructure); //Initialize CAN1 port
|
||||
|
||||
CAN_ITConfig(Can.can, CAN_IT_FMP0, ENABLE);
|
||||
}
|
||||
|
||||
void USB_LP_CAN1_RX0_IRQHandler(void) //CAN 1 interrupt service routine
|
||||
{
|
||||
CanRxMsg RxMessage;
|
||||
|
||||
CAN_ClearITPendingBit(Can.can, CAN_IT_FMP0);
|
||||
|
||||
CAN_Receive(Can.can, CAN_FIFO0, &RxMessage);
|
||||
|
||||
memcpy(&Can.RxBuf[Can.RxInPos++], &RxMessage, sizeof(CanRxMsg));
|
||||
Can.RxInPos %= RX_BUFFER_SIZE;
|
||||
|
||||
if (Can.RxInPos == Can.RxOutPos)
|
||||
{
|
||||
Can.RxOutPos++;
|
||||
Can.RxOutPos %= RX_BUFFER_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
u8 CAN_GetPacket(CanRxMsg *packet)
|
||||
{
|
||||
u8 result = ERROR;
|
||||
OS_ERR err;
|
||||
CPU_SR_ALLOC();
|
||||
|
||||
OS_CRITICAL_ENTER();
|
||||
if (Can.RxInPos != Can.RxOutPos)
|
||||
{
|
||||
memcpy(packet, &Can.RxBuf[Can.RxOutPos], sizeof(CanRxMsg));
|
||||
Can.RxOutPos++;
|
||||
Can.RxOutPos %= RX_BUFFER_SIZE;
|
||||
result = SUCCESS;
|
||||
}
|
||||
OS_CRITICAL_EXIT();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void CAN_SendPacket(CanTxMsg *packet)
|
||||
{
|
||||
u8 retMsgBox;
|
||||
uint8_t result;
|
||||
int i;
|
||||
|
||||
retMsgBox = CAN_Transmit(Can.can, packet);
|
||||
|
||||
if (retMsgBox != CAN_TxStatus_NoMailBox)
|
||||
{
|
||||
i = 0;
|
||||
result = CAN_TransmitStatus(CAN1, retMsgBox);
|
||||
|
||||
while (((result == CAN_TxStatus_Failed) || (result == CAN_TxStatus_Pending))&&(i < 0xFF))
|
||||
{
|
||||
result = CAN_TransmitStatus(CAN1, retMsgBox);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*******************(C)COPYRIGHT 2021 Amogreentech *********END OF FILE********/
|
||||
36
USER/Ref/bmu-18s-firmware/HARDWARE/can.h
Normal file
36
USER/Ref/bmu-18s-firmware/HARDWARE/can.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* File Name : can.h
|
||||
* Description : This file provides code for the configuration
|
||||
* of CAN Port.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2021 Amogreentech Co., Ltd.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef _CAN_H_
|
||||
#define _CAN_H_
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include <stm32f10x.h>
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/* Exported define -----------------------------------------------------------*/
|
||||
/* Exported variables ------------------------------------------------------- */
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
void can1_init(u32 buadrate);
|
||||
u8 CAN_GetPacket(CanRxMsg *packet);
|
||||
void CAN_SendPacket(CanTxMsg *packet);
|
||||
|
||||
#endif /* _CAN_H_ */
|
||||
|
||||
/*******************(C)COPYRIGHT 2021 Amogreentech *********END OF FILE********/
|
||||
|
||||
|
||||
57
USER/Ref/bmu-18s-firmware/HARDWARE/iwdg.c
Normal file
57
USER/Ref/bmu-18s-firmware/HARDWARE/iwdg.c
Normal file
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* File Name : iwdg.c
|
||||
* Description : This file provides code for the configuration
|
||||
* of the IWDG instances.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2021 Amogreentech Co., Ltd.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "iwdg.h"
|
||||
#include "stm32f10x_iwdg.h"
|
||||
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
|
||||
//Initialize watch-dog
|
||||
void IWDG_Init(void)
|
||||
{
|
||||
/* IWDG timeout equal to 250 ms (the timeout may varies due to LSI frequency
|
||||
dispersion) */
|
||||
/* Enable write access to IWDG_PR and IWDG_RLR registers */
|
||||
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
|
||||
|
||||
/* IWDG counter clock: 40KHz(LSI) / 128 = 312.5 Hz : 3.2ms */
|
||||
/* 0.8ms ~ 3276.8ms */
|
||||
// IWDG_Prescaler_4, 0, 0.1, 409.6
|
||||
// IWDG_Prescaler_8, 1, 0.2, 819.2
|
||||
// IWDG_Prescaler_16, 2, 0.4, 1638.4
|
||||
// IWDG_Prescaler_32, 3, 0.8, 3276.8
|
||||
// IWDG_Prescaler_64, 4, 1.6, 6553.6
|
||||
// IWDG_Prescaler_128 5, 3.2, 13107.2
|
||||
// IWDG_Prescaler_256 6, 6.4, 26214.4
|
||||
|
||||
/* IWDG counter clock: LSI/256 = 약 156.25 Hz */
|
||||
IWDG_SetPrescaler(IWDG_Prescaler_128);
|
||||
|
||||
/* Max reload value 4095 -> 약 26초의 여유 확보 */
|
||||
IWDG_SetReload(4095);
|
||||
|
||||
/* Reload IWDG counter */
|
||||
IWDG_ReloadCounter();
|
||||
|
||||
/* Enable IWDG (the LSI oscillator will be enabled by hardware) */
|
||||
IWDG_Enable();
|
||||
}
|
||||
|
||||
/*******************(C)COPYRIGHT 2021 Amogreentech *********END OF FILE********/
|
||||
33
USER/Ref/bmu-18s-firmware/HARDWARE/iwdg.h
Normal file
33
USER/Ref/bmu-18s-firmware/HARDWARE/iwdg.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* File Name : iwdg.h
|
||||
* Description : This file provides code for the configuration
|
||||
* of the IWDG instances.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2021 Amogreentech Co., Ltd.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef _IWDG_H_
|
||||
#define _IWDG_H_
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include <stm32f10x.h>
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/* Exported define -----------------------------------------------------------*/
|
||||
/* Exported variables ------------------------------------------------------- */
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
|
||||
void IWDG_Init(void); //Initialize
|
||||
|
||||
#endif /* _IWDG_H_ */
|
||||
|
||||
/*******************(C)COPYRIGHT 2021 Amogreentech *********END OF FILE********/
|
||||
121
USER/Ref/bmu-18s-firmware/HARDWARE/led.c
Normal file
121
USER/Ref/bmu-18s-firmware/HARDWARE/led.c
Normal file
@@ -0,0 +1,121 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* File Name : led.c
|
||||
* Description : This file provides code for the configuration
|
||||
* of the LED and Extra Safety output
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2021 Amogreentech Co., Ltd.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "led.h"
|
||||
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
|
||||
// LED class IO
|
||||
void DIO_Init(void)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
|
||||
/* GPIOA Periph clock enable */
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // GPIOA clock
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // GPIOA clock
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); // GPIOA clock
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE); // GPIOA clock
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
|
||||
|
||||
PWR_BackupAccessCmd(ENABLE);
|
||||
|
||||
//Serial port 1 pins reuse maps
|
||||
GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE);
|
||||
|
||||
/* Safety Signal Output */
|
||||
/* Configure PA4 in output pushpull mode */
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; // GPIO Line
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // GPIO Speed
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // GPIO In/Out
|
||||
GPIO_Init(GPIOA, &GPIO_InitStructure);
|
||||
|
||||
/* Board Run Led Output */
|
||||
/* Configure PA13 in output pushpull mode */
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; // GPIO Line
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // GPIO Speed
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // GPIO In/Out
|
||||
GPIO_Init(GPIOA, &GPIO_InitStructure);
|
||||
|
||||
GPIO_ResetBits(GPIOA, GPIO_Pin_4); // GPIOA line
|
||||
GPIO_ResetBits(GPIOA, GPIO_Pin_13); // GPIOA line
|
||||
|
||||
/* MP6242 Enable Output */
|
||||
/* Configure PA6, PA7 in output pushpull mode */
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_5; // GPIO Line
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // GPIO Speed
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // GPIO In/Out
|
||||
GPIO_Init(GPIOA, &GPIO_InitStructure);
|
||||
|
||||
GPIO_ResetBits(GPIOA, GPIO_Pin_0); // GPIOA line
|
||||
GPIO_ResetBits(GPIOA, GPIO_Pin_1); // GPIOA line
|
||||
GPIO_ResetBits(GPIOA, GPIO_Pin_2); // GPIOA line
|
||||
GPIO_ResetBits(GPIOA, GPIO_Pin_3); // GPIOA line
|
||||
GPIO_ResetBits(GPIOA, GPIO_Pin_5); // GPIOA line
|
||||
|
||||
/* MP6242 Enable Output */
|
||||
/* Configure PB in output pushpull mode */
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6
|
||||
| GPIO_Pin_7 | GPIO_Pin_10 | GPIO_Pin_11 ; // GPIO Line
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // GPIO Speed
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // GPIO In/Out
|
||||
GPIO_Init(GPIOB, &GPIO_InitStructure);
|
||||
|
||||
GPIO_ResetBits(GPIOB, GPIO_Pin_0); // GPIOB line
|
||||
GPIO_ResetBits(GPIOB, GPIO_Pin_1); // GPIOB line
|
||||
GPIO_ResetBits(GPIOB, GPIO_Pin_4); // GPIOB line
|
||||
GPIO_ResetBits(GPIOB, GPIO_Pin_5); // GPIOB line
|
||||
GPIO_ResetBits(GPIOB, GPIO_Pin_6); // GPIOB line
|
||||
GPIO_ResetBits(GPIOB, GPIO_Pin_7); // GPIOB line
|
||||
GPIO_ResetBits(GPIOB, GPIO_Pin_10); // GPIOB line
|
||||
GPIO_ResetBits(GPIOB, GPIO_Pin_11); // GPIOB line
|
||||
|
||||
/* MP6242 Enable Output */
|
||||
/* Configure PC in output pushpull mode */
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15; // GPIO Line
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; // GPIO Speed
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // GPIO In/Out
|
||||
GPIO_Init(GPIOC, &GPIO_InitStructure);
|
||||
|
||||
GPIO_ResetBits(GPIOC, GPIO_Pin_13); // GPIOC line
|
||||
GPIO_ResetBits(GPIOC, GPIO_Pin_14); // GPIOC line
|
||||
GPIO_ResetBits(GPIOC, GPIO_Pin_15); // GPIOC line
|
||||
|
||||
/* MP6242 Enable Output */
|
||||
/* Configure PD in output pushpull mode */
|
||||
GPIO_PinRemapConfig(GPIO_Remap_PD01, ENABLE);
|
||||
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; // GPIO Line
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // GPIO Speed
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // GPIO In/Out
|
||||
GPIO_Init(GPIOD, &GPIO_InitStructure);
|
||||
|
||||
GPIO_ResetBits(GPIOD, GPIO_Pin_1); // GPIOD line
|
||||
|
||||
/* Module Bal FET On/Off Output */
|
||||
/* Configure PB3 in output pushpull mode */
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; // GPIO Line
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // GPIO Speed
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // GPIO In/Out
|
||||
GPIO_Init(GPIOB, &GPIO_InitStructure);
|
||||
|
||||
GPIO_SetBits(GPIOB, GPIO_Pin_3); // GPIOB line
|
||||
}
|
||||
|
||||
/*******************(C)COPYRIGHT 2021 Amogreentech *********END OF FILE********/
|
||||
59
USER/Ref/bmu-18s-firmware/HARDWARE/led.h
Normal file
59
USER/Ref/bmu-18s-firmware/HARDWARE/led.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* File Name : led.h
|
||||
* Description : This file provides code for the configuration
|
||||
* of the LED and Extra Safety output
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2021 Amogreentech Co., Ltd.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef _LED_H_
|
||||
#define _LED_H_
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include <stm32f10x.h>
|
||||
#include "sys.h"
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/* Exported define -----------------------------------------------------------*/
|
||||
//LED port definitions
|
||||
#define BD_RUN_LED PAout(13)
|
||||
|
||||
#define MP2642_ENABLE_17 PBout(11)
|
||||
#define MP2642_ENABLE_16 PBout(10)
|
||||
#define MP2642_ENABLE_15 PBout(1)
|
||||
#define MP2642_ENABLE_14 PBout(0)
|
||||
#define MP2642_ENABLE_13 PAout(5)
|
||||
#define MP2642_ENABLE_12 PAout(3)
|
||||
#define MP2642_ENABLE_11 PAout(2)
|
||||
#define MP2642_ENABLE_10 PAout(1)
|
||||
#define MP2642_ENABLE_09 PAout(0)
|
||||
#define MP2642_ENABLE_08 PDout(1)
|
||||
#define MP2642_ENABLE_07 PCout(15)
|
||||
#define MP2642_ENABLE_06 PCout(14)
|
||||
#define MP2642_ENABLE_05 PCout(13)
|
||||
#define MP2642_ENABLE_04 PBout(7)
|
||||
#define MP2642_ENABLE_03 PBout(6)
|
||||
#define MP2642_ENABLE_02 PBout(5)
|
||||
#define MP2642_ENABLE_01 PBout(4)
|
||||
|
||||
#define SAFETY_SIGNAL PAout(4)
|
||||
|
||||
#define MD_BALANCE PBout(3)
|
||||
|
||||
/* Exported variables ------------------------------------------------------- */
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
|
||||
void DIO_Init(void); //Initialize
|
||||
|
||||
#endif /* _LED_H_ */
|
||||
|
||||
/*******************(C)COPYRIGHT 2021 Amogreentech *********END OF FILE********/
|
||||
947
USER/Ref/bmu-18s-firmware/HARDWARE/ltc6813.c
Normal file
947
USER/Ref/bmu-18s-firmware/HARDWARE/ltc6813.c
Normal file
@@ -0,0 +1,947 @@
|
||||
/*! LTC6813: Multicell Battery Monitors
|
||||
*
|
||||
*@verbatim
|
||||
*The LTC6813 is multicell battery stack monitor that measures up to 18 series
|
||||
*connected battery cells with a total measurement error of less than 2.2mV.
|
||||
*The cell measurement range of 0V to 5V makes the LTC6813 suitable for most
|
||||
*battery chemistries. All 18 cell voltages can be captured in 290uS, and lower
|
||||
*data acquisition rates can be selected for high noise reduction.
|
||||
*Using the LTC6813-1, multiple devices are connected in a daisy-chain with one
|
||||
*host processor connection for all devices, permitting simultaneous cell monitoring
|
||||
*of long, high voltage battery strings.
|
||||
*@endverbatim
|
||||
*
|
||||
* https://www.analog.com/en/products/ltc6813-1.html
|
||||
* https://www.analog.com/en/design-center/evaluation-hardware-and-software/evaluation-boards-kits/dc2350a-b.html
|
||||
*
|
||||
*********************************************************************************
|
||||
* Copyright 2019(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
//! @ingroup BMS
|
||||
//! @{
|
||||
//! @defgroup LTC6813-1 LTC6813-1: Multicell Battery Monitor
|
||||
//! @}
|
||||
|
||||
/*! @file
|
||||
@ingroup LTC6813-1
|
||||
Library for LTC6813-1 Multicell Battery Monitor
|
||||
*/
|
||||
|
||||
#include <includes.h>
|
||||
#include "stdint.h"
|
||||
#include "ltc681x.h"
|
||||
#include "ltc6813.h"
|
||||
#include "delay.h"
|
||||
|
||||
//Helper function to initialize register limits.
|
||||
void LTC6813_init_reg_limits(uint8_t total_ic, cell_asic *ic)
|
||||
{
|
||||
for (uint8_t cic = 0; cic < total_ic; cic++)
|
||||
{
|
||||
ic[cic].ic_reg.cell_channels = 18;
|
||||
ic[cic].ic_reg.stat_channels = 4;
|
||||
ic[cic].ic_reg.aux_channels = 9;
|
||||
ic[cic].ic_reg.num_cv_reg = 6;
|
||||
ic[cic].ic_reg.num_gpio_reg = 4;
|
||||
ic[cic].ic_reg.num_stat_reg = 2;
|
||||
}
|
||||
}
|
||||
|
||||
//Helper function to initialize CFG variables.
|
||||
void LTC6813_init_cfg(uint8_t total_ic, cell_asic *ic)
|
||||
{
|
||||
bool REFON = true;
|
||||
bool ADCOPT = false;
|
||||
uint8_t gpioBits = 0x1F; // {true, true, true, true, true};
|
||||
uint16_t dccBits = 0;
|
||||
|
||||
for (uint8_t current_ic = 0; current_ic < total_ic; current_ic++)
|
||||
{
|
||||
for (int j =0; j < 6; j++)
|
||||
{
|
||||
ic[current_ic].config.tx_data[j] = 0;
|
||||
ic[current_ic].configb.tx_data[j] = 0;
|
||||
}
|
||||
LTC6813_set_cfgr(current_ic , ic, REFON, ADCOPT, gpioBits, dccBits, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
//Helper function to set CFGR variable
|
||||
void LTC6813_set_cfgr(uint8_t nIC, cell_asic *ic, bool refon, bool adcopt, uint8_t gpio, uint16_t dcc, uint8_t dcto, uint16_t uv, uint16_t ov)
|
||||
{
|
||||
LTC6813_set_cfgr_refon (nIC, ic, refon );
|
||||
LTC6813_set_cfgr_adcopt(nIC, ic, adcopt);
|
||||
LTC6813_set_cfgr_gpio (nIC, ic, gpio );
|
||||
LTC6813_set_cfgr_dis (nIC, ic, dcc );
|
||||
LTC6813_set_cfgr_dcto (nIC, ic, dcto );
|
||||
LTC6813_set_cfgr_uv (nIC, ic, uv );
|
||||
LTC6813_set_cfgr_ov (nIC, ic, ov );
|
||||
}
|
||||
|
||||
//Helper function to set the REFON bit
|
||||
void LTC6813_set_cfgr_refon(uint8_t nIC, cell_asic *ic, bool refon)
|
||||
{
|
||||
if (refon) ic[nIC].config.tx_data[0] = ic[nIC].config.tx_data[0] | 0x04;
|
||||
else ic[nIC].config.tx_data[0] = ic[nIC].config.tx_data[0] & 0xFB;
|
||||
}
|
||||
|
||||
//Helper function to set the adcopt bit
|
||||
void LTC6813_set_cfgr_adcopt(uint8_t nIC, cell_asic *ic, bool adcopt)
|
||||
{
|
||||
if (adcopt) ic[nIC].config.tx_data[0] = ic[nIC].config.tx_data[0] | 0x01;
|
||||
else ic[nIC].config.tx_data[0] = ic[nIC].config.tx_data[0] & 0xFE;
|
||||
}
|
||||
|
||||
//Helper function to set GPIO bits
|
||||
void LTC6813_set_cfgr_gpio(uint8_t nIC, cell_asic *ic, uint8_t gpio)
|
||||
{
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
if ((gpio >> i) & 0x01) ic[nIC].config.tx_data[0] = ic[nIC].config.tx_data[0] | ( 0x01 << (i + 3));
|
||||
else ic[nIC].config.tx_data[0] = ic[nIC].config.tx_data[0] & (~(0x01 << (i + 3)));
|
||||
}
|
||||
}
|
||||
|
||||
//Helper function to control discharge
|
||||
void LTC6813_set_cfgr_dis(uint8_t nIC, cell_asic *ic, uint16_t dcc)
|
||||
{
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
if ((dcc >> i) & 0x0001) ic[nIC].config.tx_data[4] = ic[nIC].config.tx_data[4] | (0x01 << i);
|
||||
else ic[nIC].config.tx_data[4] = ic[nIC].config.tx_data[4] & (~(0x01 << i));
|
||||
}
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
if ((dcc >> (8 + i)) & 0x0001) ic[nIC].config.tx_data[5] = ic[nIC].config.tx_data[5] | (0x01 << i);
|
||||
else ic[nIC].config.tx_data[5] = ic[nIC].config.tx_data[5] & (~(0x01 << i));
|
||||
}
|
||||
}
|
||||
|
||||
//Helper Function to set dcto value in CFG register
|
||||
void LTC6813_set_cfgr_dcto(uint8_t nIC, cell_asic *ic, uint8_t dcto)
|
||||
{
|
||||
ic[nIC].config.tx_data[5] &= 0x0F;
|
||||
ic[nIC].config.tx_data[5] |= (uint8_t)((dcto << 4) & 0xF0);
|
||||
}
|
||||
|
||||
//Helper Function to set uv value in CFG register
|
||||
void LTC6813_set_cfgr_uv(uint8_t nIC, cell_asic *ic,uint16_t uv)
|
||||
{
|
||||
ic[nIC].config.tx_data[1] = (uint8_t)((uv >> 0) & 0xFF);
|
||||
ic[nIC].config.tx_data[2] &= 0xF0;
|
||||
ic[nIC].config.tx_data[2] |= (uint8_t)((uv >> 8) & 0x0F);
|
||||
}
|
||||
|
||||
//Helper function to set OV value in CFG register
|
||||
void LTC6813_set_cfgr_ov(uint8_t nIC, cell_asic *ic, uint16_t ov)
|
||||
{
|
||||
ic[nIC].config.tx_data[2] &= 0x0F;
|
||||
ic[nIC].config.tx_data[2] |= (uint8_t)((ov << 4) & 0xF0);
|
||||
ic[nIC].config.tx_data[3] = (uint8_t)((ov >> 4) & 0xFF);
|
||||
}
|
||||
|
||||
/***************************** CFGRB *********************************/
|
||||
|
||||
//Helper Function to initialize the CFGRB data structures
|
||||
void LTC6813_init_cfgb(uint8_t total_ic,cell_asic *ic)
|
||||
{
|
||||
for (uint8_t current_ic = 0; current_ic < total_ic; current_ic++)
|
||||
{
|
||||
for(int j = 0; j < 6; j++)
|
||||
{
|
||||
ic[current_ic].configb.tx_data[j] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Helper Function to set the configuration register B
|
||||
void LTC6813_set_cfgrb(uint8_t nIC, cell_asic *ic, bool fdrf, bool dtmen, bool ps[2], uint8_t gpiobits, uint16_t dccbits)
|
||||
{
|
||||
LTC6813_set_cfgrb_fdrf (nIC, ic, fdrf);
|
||||
LTC6813_set_cfgrb_dtmen (nIC, ic, dtmen);
|
||||
LTC6813_set_cfgrb_ps (nIC, ic, ps);
|
||||
LTC6813_set_cfgrb_gpio_b(nIC, ic, gpiobits);
|
||||
LTC6813_set_cfgrb_dcc_b (nIC, ic, dccbits);
|
||||
}
|
||||
|
||||
//Helper function to set the FDRF bit
|
||||
void LTC6813_set_cfgrb_fdrf(uint8_t nIC, cell_asic *ic, bool fdrf)
|
||||
{
|
||||
if(fdrf) ic[nIC].configb.tx_data[1] = ic[nIC].configb.tx_data[1]|0x40;
|
||||
else ic[nIC].configb.tx_data[1] = ic[nIC].configb.tx_data[1]&0xBF;
|
||||
}
|
||||
|
||||
//Helper function to set the DTMEN bit
|
||||
void LTC6813_set_cfgrb_dtmen(uint8_t nIC, cell_asic *ic, bool dtmen)
|
||||
{
|
||||
if(dtmen) ic[nIC].configb.tx_data[1] = ic[nIC].configb.tx_data[1]|0x08;
|
||||
else ic[nIC].configb.tx_data[1] = ic[nIC].configb.tx_data[1]&0xF7;
|
||||
}
|
||||
|
||||
//Helper function to set the PATH SELECT bit
|
||||
void LTC6813_set_cfgrb_ps(uint8_t nIC, cell_asic *ic, bool ps[])
|
||||
{
|
||||
for(int i =0;i<2;i++)
|
||||
{
|
||||
if(ps[i])ic[nIC].configb.tx_data[1] = ic[nIC].configb.tx_data[1]|(0x01<<(i+4));
|
||||
else ic[nIC].configb.tx_data[1] = ic[nIC].configb.tx_data[1]&(~(0x01<<(i+4)));
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to set the gpio bits in configb b register
|
||||
void LTC6813_set_cfgrb_gpio_b(uint8_t nIC, cell_asic *ic, uint8_t gpiobits)
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
if ((gpiobits >> 1) & 0x01) ic[nIC].configb.tx_data[0] = ic[nIC].configb.tx_data[0] | ( 0x01 << i);
|
||||
else ic[nIC].configb.tx_data[0] = ic[nIC].configb.tx_data[0] & (~(0x01 << i));
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to set the dcc bits in configb b register
|
||||
void LTC6813_set_cfgrb_dcc_b(uint8_t nIC, cell_asic *ic, uint16_t dccbits)
|
||||
{
|
||||
for (int i = 0; i < 7; i++)
|
||||
{
|
||||
if (i < 4)
|
||||
{
|
||||
// DCC 13, 14, 15, 16
|
||||
if ((dccbits >> i) & 0x0001) ic[nIC].configb.tx_data[0] = ic[nIC].configb.tx_data[0] | (0x01 << (i + 4));
|
||||
else ic[nIC].configb.tx_data[0] = ic[nIC].configb.tx_data[0] & (~(0x01 << (i + 4)));
|
||||
}
|
||||
if (i >= 4 && i < 6)
|
||||
{
|
||||
if ((dccbits >> i) & 0x0001) ic[nIC].configb.tx_data[1] = ic[nIC].configb.tx_data[1] | (0x01 << (i - 4));
|
||||
else ic[nIC].configb.tx_data[1] = ic[nIC].configb.tx_data[1] & (~(0x01 << (i - 4)));
|
||||
}
|
||||
if (i == 6)
|
||||
{
|
||||
if ((dccbits >> i) & 0x0001) ic[nIC].configb.tx_data[1] = ic[nIC].configb.tx_data[1] | 0x04;
|
||||
else ic[nIC].configb.tx_data[1] = ic[nIC].configb.tx_data[1] & (~0x04); //0xFB;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
This command will write the configuration registers of the LTC6813-1s
|
||||
connected in a daisy chain stack. The configuration is written in descending
|
||||
order so the last device's configuration is written first.
|
||||
*/
|
||||
void LTC6813_wrcfg(uint8_t total_ic, //The number of ICs being written to
|
||||
cell_asic *ic //A two dimensional array of the configuration data that will be written
|
||||
)
|
||||
{
|
||||
LTC681x_wrcfg(total_ic,ic);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
This command will write the configuration b registers of the LTC6813-1s
|
||||
connected in a daisy chain stack. The configuration is written in descending
|
||||
order so the last device's configuration is written first.
|
||||
*/
|
||||
void LTC6813_wrcfgb(uint8_t total_ic, //The number of ICs being written to
|
||||
cell_asic *ic //A two dimensional array of the configuration data that will be written
|
||||
)
|
||||
{
|
||||
LTC681x_wrcfgb(total_ic, ic);
|
||||
}
|
||||
|
||||
|
||||
// Reads configuration registers of a LTC6813 daisy chain
|
||||
int8_t LTC6813_rdcfg(uint8_t total_ic, //Number of ICs in the system
|
||||
cell_asic *ic //A two dimensional array that the function stores the read configuration data.
|
||||
)
|
||||
{
|
||||
uint8_t cmd[2] = {0x00, 0x02};
|
||||
uint8_t read_buffer[10];
|
||||
int8_t pec_error = 0;
|
||||
uint16_t data_pec;
|
||||
uint16_t calc_pec;
|
||||
uint8_t c_ic = 0;
|
||||
|
||||
pec_error = read_68(total_ic, cmd, read_buffer);
|
||||
|
||||
for (uint8_t current_ic = 0; current_ic < total_ic; current_ic++)
|
||||
{
|
||||
if (ic->isospi_reverse == false)
|
||||
{
|
||||
c_ic = current_ic;
|
||||
}
|
||||
else
|
||||
{
|
||||
c_ic = total_ic - current_ic - 1;
|
||||
}
|
||||
|
||||
for (int byte = 0; byte < 8; byte++)
|
||||
{
|
||||
ic[c_ic].config.rx_data[byte] = read_buffer[byte+(8*current_ic)];
|
||||
}
|
||||
calc_pec = pec15_calc(6,&read_buffer[8*current_ic]);
|
||||
data_pec = read_buffer[7+(8*current_ic)] | (read_buffer[6+(8*current_ic)]<<8);
|
||||
if (calc_pec != data_pec )
|
||||
{
|
||||
ic[c_ic].config.rx_pec_match = 1;
|
||||
}
|
||||
else ic[c_ic].config.rx_pec_match = 0;
|
||||
}
|
||||
LTC681x_check_pec(total_ic,CFGR,ic);
|
||||
|
||||
return(pec_error);
|
||||
}
|
||||
|
||||
//Reads configuration b registers of a LTC6813 daisy chain
|
||||
int8_t LTC6813_rdcfgb(uint8_t total_ic, //Number of ICs in the system
|
||||
cell_asic *ic //A two dimensional array that the function stores the read configuration data.
|
||||
)
|
||||
{
|
||||
uint8_t cmd[2]= {0x00 , 0x26};
|
||||
uint8_t read_buffer[256];
|
||||
int8_t pec_error = 0;
|
||||
uint16_t data_pec;
|
||||
uint16_t calc_pec;
|
||||
uint8_t c_ic = 0;
|
||||
|
||||
pec_error = read_68(total_ic, cmd, read_buffer);
|
||||
|
||||
for (uint8_t current_ic = 0; current_ic < total_ic; current_ic++)
|
||||
{
|
||||
if (ic->isospi_reverse == false)
|
||||
{
|
||||
c_ic = current_ic;
|
||||
}
|
||||
else
|
||||
{
|
||||
c_ic = total_ic - current_ic - 1;
|
||||
}
|
||||
|
||||
for (int byte = 0; byte < 8; byte++)
|
||||
{
|
||||
ic[c_ic].configb.rx_data[byte] = read_buffer[byte + (8 * current_ic)];
|
||||
}
|
||||
calc_pec = pec15_calc(6, &read_buffer[8 * current_ic]);
|
||||
data_pec = read_buffer[7 + (8 * current_ic)] | (read_buffer[6 + (8 * current_ic)] << 8);
|
||||
if (calc_pec != data_pec )
|
||||
{
|
||||
ic[c_ic].configb.rx_pec_match = 1;
|
||||
}
|
||||
else ic[c_ic].configb.rx_pec_match = 0;
|
||||
}
|
||||
LTC681x_check_pec(total_ic,CFGR,ic);
|
||||
|
||||
return(pec_error);
|
||||
}
|
||||
|
||||
|
||||
//Starts cell voltage conversion
|
||||
void LTC6813_adcv(uint8_t MD, //ADC Mode
|
||||
uint8_t DCP, //Discharge Permit
|
||||
uint8_t CH //Cell Channels to be measured
|
||||
)
|
||||
{
|
||||
uint8_t cmd[4];
|
||||
uint8_t md_bits;
|
||||
|
||||
md_bits = (MD & 0x02) >> 1;
|
||||
cmd[0] = md_bits + 0x02;
|
||||
md_bits = (MD & 0x01) << 7;
|
||||
cmd[1] = md_bits + 0x60 + (DCP << 4) + CH;
|
||||
cmd_68(cmd);
|
||||
}
|
||||
|
||||
// Reads and parses the LTC6813 cell voltage registers.
|
||||
uint8_t LTC6813_rdcv(uint8_t reg, // Controls which cell voltage register is read back.
|
||||
uint8_t total_ic, // the number of ICs in the system
|
||||
cell_asic *ic // Array of the parsed cell codes
|
||||
)
|
||||
{
|
||||
int8_t pec_error = 0;
|
||||
pec_error = LTC681x_rdcv(reg,total_ic,ic);
|
||||
return(pec_error);
|
||||
}
|
||||
|
||||
//Start a GPIO and Vref2 Conversion
|
||||
void LTC6813_adax(uint8_t MD, //ADC Mode
|
||||
uint8_t CHG //GPIO Channels to be measured)
|
||||
)
|
||||
{
|
||||
uint8_t cmd[4];
|
||||
uint8_t md_bits;
|
||||
|
||||
md_bits = (MD & 0x02) >> 1;
|
||||
cmd[0] = md_bits + 0x04;
|
||||
md_bits = (MD & 0x01) << 7;
|
||||
cmd[1] = md_bits + 0x60 + CHG ;
|
||||
cmd_68(cmd);
|
||||
}
|
||||
|
||||
/*
|
||||
The function is used
|
||||
to read the parsed GPIO codes of the LTC6813. This function will send the requested
|
||||
read commands parse the data and store the gpio voltages in aux_codes variable
|
||||
*/
|
||||
int8_t LTC6813_rdaux(uint8_t reg, //Determines which GPIO voltage register is read back.
|
||||
uint8_t total_ic,//the number of ICs in the system
|
||||
cell_asic *ic//A two dimensional array of the gpio voltage codes.
|
||||
)
|
||||
{
|
||||
uint8_t *data;
|
||||
int8_t pec_error = 0;
|
||||
uint8_t c_ic =0;
|
||||
data = (uint8_t *) malloc((NUM_RX_BYT * total_ic) * sizeof(uint8_t));
|
||||
|
||||
if (reg == 0)
|
||||
{
|
||||
for (uint8_t gpio_reg = 1; gpio_reg < ic[0].ic_reg.num_gpio_reg + 1; gpio_reg++) //executes once for each of the LTC6813 aux voltage registers
|
||||
{
|
||||
LTC681x_rdaux_reg(gpio_reg, total_ic, data); //Reads the raw auxiliary register data into the data[] array
|
||||
for (int current_ic = 0; current_ic < total_ic; current_ic++)
|
||||
{
|
||||
if (ic->isospi_reverse == false)
|
||||
{
|
||||
c_ic = current_ic;
|
||||
}
|
||||
else
|
||||
{
|
||||
c_ic = total_ic - current_ic - 1;
|
||||
}
|
||||
pec_error = parse_auxs(current_ic, gpio_reg, data,
|
||||
&ic[c_ic].aux.a_codes[0],
|
||||
&ic[c_ic].aux.pec_match[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LTC681x_rdaux_reg(reg, total_ic, data);
|
||||
|
||||
for (int current_ic = 0; current_ic<total_ic; current_ic++)
|
||||
{
|
||||
if (ic->isospi_reverse == false)
|
||||
{
|
||||
c_ic = current_ic;
|
||||
}
|
||||
else
|
||||
{
|
||||
c_ic = total_ic - current_ic - 1;
|
||||
}
|
||||
pec_error = parse_cells(current_ic,reg, data,
|
||||
&ic[c_ic].aux.a_codes[0],
|
||||
&ic[c_ic].aux.pec_match[0]);
|
||||
}
|
||||
|
||||
}
|
||||
LTC681x_check_pec(total_ic,AUX,ic);
|
||||
free(data);
|
||||
return (pec_error);
|
||||
}
|
||||
|
||||
//Start a Status ADC Conversion
|
||||
void LTC6813_adstat(uint8_t MD, //ADC Mode
|
||||
uint8_t CHST //GPIO Channels to be measured
|
||||
)
|
||||
{
|
||||
LTC681x_adstat(MD,CHST);
|
||||
}
|
||||
|
||||
/*
|
||||
Reads and parses the LTC6813 stat registers.
|
||||
The function is used
|
||||
to read the parsed stat codes of the LTC6813. This function will send the requested
|
||||
read commands parse the data and store the stat voltages in stat_codes variable
|
||||
*/
|
||||
int8_t LTC6813_rdstat(uint8_t reg, //Determines which Stat register is read back.
|
||||
uint8_t total_ic,//the number of ICs in the system
|
||||
cell_asic *ic
|
||||
)
|
||||
{
|
||||
int8_t pec_error = 0;
|
||||
pec_error = LTC681x_rdstat(reg,total_ic,ic);
|
||||
return (pec_error);
|
||||
}
|
||||
|
||||
// Starts cell voltage and GPIO 1&2 conversion
|
||||
void LTC6813_adcvax(uint8_t MD, //ADC Mode
|
||||
uint8_t DCP //Discharge Permit
|
||||
)
|
||||
{
|
||||
// LTC681x_adcvax(MD,DCP);
|
||||
}
|
||||
|
||||
//Starts cell voltage and SOC conversion
|
||||
void LTC6813_adcvsc( uint8_t MD, //ADC Mode
|
||||
uint8_t DCP //Discharge Permit
|
||||
)
|
||||
{
|
||||
// LTC681x_adcvsc(MD,DCP);
|
||||
}
|
||||
|
||||
//Starts the Mux Decoder diagnostic self test
|
||||
void LTC6813_diagn()
|
||||
{
|
||||
LTC681x_diagn();
|
||||
}
|
||||
|
||||
//Starts cell voltage self test conversion
|
||||
void LTC6813_cvst(uint8_t MD, //ADC Mode
|
||||
uint8_t ST //Self Test
|
||||
)
|
||||
{
|
||||
LTC681x_cvst(MD,ST);
|
||||
}
|
||||
|
||||
//Start an Auxiliary Register Self Test Conversion
|
||||
void LTC6813_axst(uint8_t MD, //ADC Mode
|
||||
uint8_t ST //Self Test
|
||||
)
|
||||
{
|
||||
LTC681x_axst(MD,ST);
|
||||
}
|
||||
|
||||
//Start a Status Register Self Test Conversion
|
||||
void LTC6813_statst(uint8_t MD, //ADC Mode
|
||||
uint8_t ST //Self Test
|
||||
)
|
||||
{
|
||||
LTC681x_statst(MD,ST);
|
||||
}
|
||||
|
||||
// Runs the Digital Filter Self Test
|
||||
int16_t LTC6813_run_cell_adc_st(uint8_t adc_reg,uint8_t total_ic, cell_asic *ic,uint8_t md,bool adcopt)
|
||||
{
|
||||
int16_t error = 0;
|
||||
// error = LTC681x_run_cell_adc_st(adc_reg,total_ic,ic,md,adcopt);
|
||||
return(error);
|
||||
}
|
||||
|
||||
//Starts cell voltage overlap conversion
|
||||
void LTC6813_adol(uint8_t MD, //ADC Mode
|
||||
uint8_t DCP //Discharge Permit
|
||||
)
|
||||
{
|
||||
LTC681x_adol(MD,DCP);
|
||||
}
|
||||
|
||||
// Runs the ADC overlap test for the IC
|
||||
uint16_t LTC6813_run_adc_overlap(uint8_t total_ic, cell_asic *ic)
|
||||
{
|
||||
uint16_t error = 0;
|
||||
int32_t measure_delta =0;
|
||||
int16_t failure_pos_limit = 20;
|
||||
int16_t failure_neg_limit = -20;
|
||||
uint32_t conv_time=0;
|
||||
wakeup_idle(total_ic);
|
||||
LTC681x_adol(MD_7KHZ_3KHZ, DCP_DISABLED);
|
||||
conv_time = LTC6813_pollAdc();
|
||||
conv_time = conv_time;
|
||||
|
||||
wakeup_idle(total_ic);
|
||||
error = LTC681x_rdcv(0, total_ic,ic);
|
||||
for (int cic = 0; cic<total_ic; cic++)
|
||||
{
|
||||
|
||||
|
||||
measure_delta = (int32_t)ic[cic].cells.c_codes[6]-(int32_t)ic[cic].cells.c_codes[7];
|
||||
if ((measure_delta>failure_pos_limit) || (measure_delta<failure_neg_limit))
|
||||
{
|
||||
error = error | (1<<(cic-1));
|
||||
}
|
||||
measure_delta = (int32_t)ic[cic].cells.c_codes[12]-(int32_t)ic[cic].cells.c_codes[13];
|
||||
if ((measure_delta>failure_pos_limit) || (measure_delta<failure_neg_limit))
|
||||
{
|
||||
error = error | (1<<(cic-1));
|
||||
}
|
||||
}
|
||||
return(error);
|
||||
}
|
||||
|
||||
//Start GPIOs open wire ADC conversion
|
||||
void LTC6813_axow(uint8_t MD, //ADC Mode
|
||||
uint8_t PUP //Discharge Permit
|
||||
)
|
||||
{
|
||||
// LTC681x_axow(MD, PUP);
|
||||
}
|
||||
|
||||
// Start an open wire Conversion
|
||||
void LTC6813_adow(uint8_t MD,uint8_t PUP,uint8_t CH,uint8_t DCP)
|
||||
{
|
||||
// LTC681x_adow(MD,PUP,CH,DCP);
|
||||
}
|
||||
|
||||
//Runs open wire for GPIOs
|
||||
void LTC6813_run_gpio_openwire(uint8_t total_ic,
|
||||
cell_asic *ic
|
||||
)
|
||||
{
|
||||
// LTC681x_run_gpio_openwire(total_ic, ic);
|
||||
}
|
||||
|
||||
//Runs the data sheet algorithm for open wire for single cell detection
|
||||
void LTC6813_run_openwire_single(uint8_t total_ic, cell_asic *ic)
|
||||
{
|
||||
// LTC681x_run_openwire_single(total_ic, ic);
|
||||
}
|
||||
|
||||
//Runs the data sheet algorithm for open wire for multiple cell and two consecutive cells detection
|
||||
void LTC6813_run_openwire_multi(uint8_t total_ic, cell_asic *ic)
|
||||
{
|
||||
// LTC681x_run_openwire_multi( total_ic, ic);
|
||||
}
|
||||
|
||||
//Start an GPIO Redundancy test
|
||||
void LTC6813_adaxd(uint8_t MD, //ADC Mode
|
||||
uint8_t CHG //GPIO Channels to be measured)
|
||||
)
|
||||
{
|
||||
LTC681x_adaxd(MD,CHG);
|
||||
}
|
||||
|
||||
// Start a Status register redundancy test Conversion
|
||||
void LTC6813_adstatd(uint8_t MD, //ADC Mode
|
||||
uint8_t CHST //GPIO Channels to be measured
|
||||
)
|
||||
{
|
||||
LTC681x_adstatd(MD,CHST);
|
||||
}
|
||||
|
||||
//Runs the redundancy self test
|
||||
int16_t LTC6813_run_adc_redundancy_st(uint8_t adc_mode, uint8_t adc_reg, uint8_t total_ic, cell_asic *ic)
|
||||
{
|
||||
int16_t error = 0;
|
||||
LTC681x_run_adc_redundancy_st(adc_mode,adc_reg,total_ic,ic);
|
||||
return(error);
|
||||
}
|
||||
|
||||
//Sends the poll ADC command
|
||||
uint8_t LTC6813_pladc()
|
||||
{
|
||||
// return(LTC681x_pladc());
|
||||
return(0);
|
||||
}
|
||||
|
||||
//This function will block operation until the ADC has finished it's conversion
|
||||
uint32_t LTC6813_pollAdc()
|
||||
{
|
||||
uint32_t counter = 0;
|
||||
uint8_t finished = 0;
|
||||
uint8_t current_time = 0;
|
||||
uint8_t cmd[4];
|
||||
uint16_t cmd_pec;
|
||||
|
||||
cmd[0] = 0x07;
|
||||
cmd[1] = 0x14;
|
||||
cmd_pec = pec15_calc(2, cmd);
|
||||
cmd[2] = (uint8_t)(cmd_pec >> 8);
|
||||
cmd[3] = (uint8_t)(cmd_pec);
|
||||
|
||||
CS_PIN = 0;
|
||||
spi_write_array(4,cmd);
|
||||
|
||||
while ((counter < 200000) && (finished == 0))
|
||||
{
|
||||
current_time = spi_read_byte(0xff);
|
||||
if (current_time > 0)
|
||||
finished = 1;
|
||||
else
|
||||
counter = counter + 10;
|
||||
|
||||
delay_os_ms(1);
|
||||
}
|
||||
CS_PIN = 1;
|
||||
|
||||
return(counter);
|
||||
}
|
||||
|
||||
/*
|
||||
The command clears the cell voltage registers and initializes
|
||||
all values to 1. The register will read back hexadecimal 0xFF
|
||||
after the command is sent.
|
||||
*/
|
||||
void LTC6813_clrcell()
|
||||
{
|
||||
LTC681x_clrcell();
|
||||
}
|
||||
|
||||
/*
|
||||
The command clears the Auxiliary registers and initializes
|
||||
all values to 1. The register will read back hexadecimal 0xFF
|
||||
after the command is sent.
|
||||
*/
|
||||
void LTC6813_clraux()
|
||||
{
|
||||
LTC681x_clraux();
|
||||
}
|
||||
|
||||
/*
|
||||
The command clears the Stat registers and initializes
|
||||
all values to 1. The register will read back hexadecimal 0xFF
|
||||
after the command is sent.
|
||||
*/
|
||||
void LTC6813_clrstat()
|
||||
{
|
||||
LTC681x_clrstat();
|
||||
}
|
||||
|
||||
//Writes the pwm registers of a LTC6813 daisy chain
|
||||
void LTC6813_wrpwm(uint8_t total_ic,
|
||||
uint8_t pwmReg, //The number of ICs being written to
|
||||
cell_asic *ic //A two dimensional array of the configuration data that will be written
|
||||
)
|
||||
{
|
||||
// LTC681x_wrpwm(total_ic,pwmReg,ic);
|
||||
}
|
||||
|
||||
//Reads pwm registers of a LTC6813 daisy chain
|
||||
int8_t LTC6813_rdpwm(uint8_t total_ic, //Number of ICs in the system
|
||||
uint8_t pwmReg,
|
||||
cell_asic *ic //A two dimensional array that the function stores the read configuration data.
|
||||
)
|
||||
{
|
||||
int8_t pec_error =0;
|
||||
// pec_error = LTC681x_rdpwm(total_ic,pwmReg,ic);
|
||||
return(pec_error);
|
||||
}
|
||||
|
||||
//Writes data in S control register the ltc6813-1 connected in a daisy chain stack.
|
||||
void LTC6813_wrsctrl(uint8_t total_ic, //< number of ICs in the daisy chain
|
||||
uint8_t sctrl_reg,
|
||||
cell_asic *ic
|
||||
)
|
||||
{
|
||||
// LTC681x_wrsctrl(total_ic, sctrl_reg, ic);
|
||||
}
|
||||
|
||||
// Reads sctrl registers of a ltc6812 daisy chain
|
||||
int8_t LTC6813_rdsctrl(uint8_t total_ic, //< number of ICs in the daisy chain
|
||||
uint8_t sctrl_reg,
|
||||
cell_asic *ic //< a two dimensional array that the function stores the read pwm data
|
||||
)
|
||||
{
|
||||
// LTC681x_rdsctrl( total_ic, sctrl_reg,ic );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Start Sctrl data communication
|
||||
This command will start the sctrl pulse communication over the spins
|
||||
*/
|
||||
void LTC6813_stsctrl()
|
||||
{
|
||||
// LTC681x_stsctrl();
|
||||
}
|
||||
|
||||
/*
|
||||
The command clears the Sctrl registers and initializes
|
||||
all values to 0. The register will read back hexadecimal 0x00
|
||||
after the command is sent.
|
||||
*/
|
||||
void LTC6813_clrsctrl()
|
||||
{
|
||||
// LTC681x_clrsctrl();
|
||||
}
|
||||
|
||||
//Writes the COMM registers of a LTC6813 daisy chain
|
||||
void LTC6813_wrcomm(uint8_t total_ic, //The number of ICs being written to
|
||||
cell_asic *ic //A two dimensional array of the comm data that will be written
|
||||
)
|
||||
{
|
||||
// LTC681x_wrcomm(total_ic,ic);
|
||||
}
|
||||
|
||||
// Reads COMM registers of a LTC6813 daisy chain
|
||||
int8_t LTC6813_rdcomm(uint8_t total_ic, //Number of ICs in the system
|
||||
cell_asic *ic //A two dimensional array that the function stores the read configuration data.
|
||||
)
|
||||
{
|
||||
int8_t pec_error = 0;
|
||||
// LTC681x_rdcomm(total_ic, ic);
|
||||
return(pec_error);
|
||||
}
|
||||
|
||||
// Shifts data in COMM register out over LTC6813 SPI/I2C port
|
||||
void LTC6813_stcomm()
|
||||
{
|
||||
// LTC681x_stcomm();
|
||||
}
|
||||
|
||||
//Helper function to set discharge bit in CFG register
|
||||
void LTC6813_set_discharge(int Cell, uint8_t total_ic, cell_asic *ic)
|
||||
{
|
||||
for (int i=0; i<total_ic; i++)
|
||||
{
|
||||
if (Cell==0)
|
||||
{
|
||||
ic[i].configb.tx_data[1] = ic[i].configb.tx_data[1] |(0x04);
|
||||
}
|
||||
else if (Cell<9)
|
||||
{
|
||||
ic[i].config.tx_data[4] = ic[i].config.tx_data[4] | (1<<(Cell-1));
|
||||
}
|
||||
else if (Cell < 13)
|
||||
{
|
||||
ic[i].config.tx_data[5] = ic[i].config.tx_data[5] | (1<<(Cell-9));
|
||||
}
|
||||
else if (Cell<17)
|
||||
{
|
||||
ic[i].configb.tx_data[0] = ic[i].configb.tx_data[0] | (1<<(Cell-9));
|
||||
}
|
||||
else if (Cell<19)
|
||||
{
|
||||
ic[i].configb.tx_data[1] = ic[i].configb.tx_data[1] | (1<<(Cell-17));
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Clears all of the DCC bits in the configuration registers
|
||||
void LTC6813_clear_discharge(uint8_t total_ic,
|
||||
cell_asic *ic)
|
||||
{
|
||||
// LTC681x_clear_discharge(total_ic,ic);
|
||||
|
||||
}
|
||||
|
||||
//Helper function that increments PEC counters
|
||||
void LTC6813_check_pec(uint8_t total_ic,uint8_t reg, cell_asic *ic)
|
||||
{
|
||||
LTC681x_check_pec(total_ic,reg,ic);
|
||||
}
|
||||
|
||||
//Helper Function to reset PEC counters
|
||||
void LTC6813_reset_crc_count(uint8_t total_ic, cell_asic *ic)
|
||||
{
|
||||
LTC681x_reset_crc_count(total_ic,ic);
|
||||
}
|
||||
|
||||
// Write the 6813 PWM/S ctrl Register B
|
||||
void LTC6813_wrpsb(uint8_t total_ic,cell_asic *ic)
|
||||
{
|
||||
uint8_t cmd[2];
|
||||
uint8_t write_buffer[256];
|
||||
uint8_t c_ic = 0;
|
||||
|
||||
cmd[0] = 0x00;
|
||||
cmd[1] = 0x1C;
|
||||
for(uint8_t current_ic = 0; current_ic<total_ic;current_ic++)
|
||||
{
|
||||
if(ic->isospi_reverse == true){c_ic = current_ic;}
|
||||
else{c_ic = total_ic - current_ic - 1;}
|
||||
|
||||
write_buffer[0] = ic[c_ic].pwmb.tx_data[0];
|
||||
write_buffer[1] = ic[c_ic].pwmb.tx_data[1];
|
||||
write_buffer[2]= ic[c_ic].pwmb.tx_data[2];
|
||||
write_buffer[3] = ic[c_ic].sctrlb.tx_data[3];
|
||||
write_buffer[4] = ic[c_ic].sctrlb.tx_data[4];
|
||||
write_buffer[5]= ic[c_ic].sctrlb.tx_data[5];
|
||||
}
|
||||
write_68(total_ic, cmd, write_buffer);
|
||||
}
|
||||
|
||||
//Reading pwm/s control register b
|
||||
uint8_t LTC6813_rdpsb(uint8_t total_ic, //< number of ICs in the daisy chain
|
||||
cell_asic *ic //< a two dimensional array that the function stores the read pwm data
|
||||
)
|
||||
{
|
||||
uint8_t cmd[4];
|
||||
uint8_t read_buffer[256];
|
||||
int8_t pec_error = 0;
|
||||
uint16_t data_pec;
|
||||
uint16_t calc_pec;
|
||||
uint8_t c_ic = 0;
|
||||
cmd[0] = 0x00;
|
||||
cmd[1] = 0x1E;
|
||||
pec_error = read_68(total_ic, cmd, read_buffer);
|
||||
|
||||
for(uint8_t current_ic =0; current_ic<total_ic; current_ic++)
|
||||
{
|
||||
if(ic->isospi_reverse == false){c_ic = current_ic;}
|
||||
else{c_ic = total_ic - current_ic - 1;}
|
||||
for(int byte=0; byte<3;byte++)
|
||||
{
|
||||
ic[c_ic].pwmb.rx_data[byte] = read_buffer[byte+(8*current_ic)];
|
||||
}
|
||||
|
||||
for(int byte=3; byte<6;byte++)
|
||||
{
|
||||
ic[c_ic].sctrlb.rx_data[byte] = read_buffer[byte+(8*current_ic)];
|
||||
}
|
||||
|
||||
for(int byte=6; byte<8;byte++)
|
||||
{
|
||||
ic[c_ic].pwmb.rx_data[byte] = read_buffer[byte+(8*current_ic)];
|
||||
ic[c_ic].sctrlb.rx_data[byte] = read_buffer[byte+(8*current_ic)];
|
||||
}
|
||||
|
||||
calc_pec = pec15_calc(6,&read_buffer[8*current_ic]);
|
||||
data_pec = read_buffer[7+(8*current_ic)] | (read_buffer[6+(8*current_ic)]<<8);
|
||||
if(calc_pec != data_pec )
|
||||
{
|
||||
ic[c_ic].pwmb.rx_pec_match = 1;
|
||||
ic[c_ic].sctrlb.rx_pec_match = 1;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
ic[c_ic].pwmb.rx_pec_match = 0;
|
||||
ic[c_ic].sctrlb.rx_pec_match = 0;
|
||||
|
||||
}
|
||||
}
|
||||
return(pec_error);
|
||||
}
|
||||
|
||||
//Mutes the LTC6813 discharge transistors
|
||||
void LTC6813_mute()
|
||||
{
|
||||
uint8_t cmd[2];
|
||||
|
||||
cmd[0] = 0x00;
|
||||
cmd[1] = 0x28;
|
||||
|
||||
cmd_68(cmd);
|
||||
}
|
||||
|
||||
//Clears the LTC6813 Mute Discharge
|
||||
void LTC6813_unmute()
|
||||
{
|
||||
uint8_t cmd[2];
|
||||
|
||||
cmd[0] = 0x00;
|
||||
cmd[1] = 0x29;
|
||||
cmd_68(cmd);
|
||||
}
|
||||
516
USER/Ref/bmu-18s-firmware/HARDWARE/ltc6813.h
Normal file
516
USER/Ref/bmu-18s-firmware/HARDWARE/ltc6813.h
Normal file
@@ -0,0 +1,516 @@
|
||||
/*! LTC6813: Multicell Battery Monitors
|
||||
*
|
||||
*@verbatim
|
||||
*The LTC6813 is multicell battery stack monitor that measures up to 18 series
|
||||
*connected battery cells with a total measurement error of less than 2.2mV.
|
||||
*The cell measurement range of 0V to 5V makes the LTC6813 suitable for most
|
||||
*battery chemistries. All 18 cell voltages can be captured in 290uS, and lower
|
||||
*data acquisition rates can be selected for high noise reduction.
|
||||
*Using the LTC6813-1, multiple devices are connected in a daisy-chain with one
|
||||
*host processor connection for all devices, permitting simultaneous cell monitoring
|
||||
*of long, high voltage battery strings.
|
||||
*@endverbatim
|
||||
*
|
||||
* https://www.analog.com/en/products/ltc6813-1.html
|
||||
* https://www.analog.com/en/design-center/evaluation-hardware-and-software/evaluation-boards-kits/dc2350a-b.html
|
||||
*
|
||||
*********************************************************************************
|
||||
* Copyright 2019(c) Analog Devices, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* - Neither the name of Analog Devices, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* - The use of this software may or may not infringe the patent rights
|
||||
* of one or more patent holders. This license does not release you
|
||||
* from the requirement that you obtain separate licenses from these
|
||||
* patent holders to use this software.
|
||||
* - Use of the software either in source or binary form, must be run
|
||||
* on or directly connected to an Analog Devices Inc. component.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*******************************************************************************/
|
||||
|
||||
/*! @file
|
||||
@ingroup LTC6813-1
|
||||
Header for LTC6813-1 Multicell Battery Monitor
|
||||
*/
|
||||
|
||||
#ifndef LTC6813_H
|
||||
#define LTC6813_H
|
||||
|
||||
#include "stdint.h"
|
||||
#include "ltc681x.h"
|
||||
|
||||
#define CELL 1
|
||||
#define AUX 2
|
||||
#define STAT 3
|
||||
|
||||
/*! Helper function to initialize register limits */
|
||||
//!@return void
|
||||
void LTC6813_init_reg_limits(uint8_t total_ic, //!< Number of ICs in the system
|
||||
cell_asic *ic //!< A two dimensional array that will store the data
|
||||
);
|
||||
|
||||
/*! Helper Function to initialize the CFGR data structures*/
|
||||
//!@return void
|
||||
void LTC6813_init_cfg(uint8_t total_ic, //!< Number of ICs in the system
|
||||
cell_asic *ic //!< A two dimensional array that will store the data
|
||||
);
|
||||
|
||||
/*! Helper function to set appropriate bits in CFGR register based on bit function*/
|
||||
//!@return void
|
||||
void LTC6813_set_cfgr(uint8_t nIC, //!< the number of ICs in the daisy chain
|
||||
cell_asic *ic, //!< A two dimensional array that will store the data
|
||||
bool refon, //!< the REFON bit
|
||||
bool adcopt, //!< the ADCOPT bit
|
||||
uint8_t gpio, //!< the GPIO bits
|
||||
uint16_t dcc, //!< the DCC bits
|
||||
uint8_t dcto, //!< the Dcto bits
|
||||
uint16_t uv, //!< the UV value
|
||||
uint16_t ov //!< the OV value
|
||||
);
|
||||
|
||||
/*! Helper function to turn the refon bit HIGH or LOW*/
|
||||
//!@return void
|
||||
void LTC6813_set_cfgr_refon(uint8_t nIC, //!< the number of ICs in the daisy chain
|
||||
cell_asic *ic, //!< A two dimensional array that will store the data
|
||||
bool refon //!< the REFON bit
|
||||
);
|
||||
|
||||
/*! Helper function to turn the ADCOPT bit HIGH or LOW*/
|
||||
//!@return void
|
||||
void LTC6813_set_cfgr_adcopt(uint8_t nIC, //!< the number of ICs in the daisy chain
|
||||
cell_asic *ic, //!< A two dimensional array that will store the data
|
||||
bool adcopt //!< the ADCOPT bit
|
||||
);
|
||||
|
||||
/*! Helper function to turn the GPIO bits HIGH or LOW*/
|
||||
//!@return void
|
||||
void LTC6813_set_cfgr_gpio(uint8_t nIC, //!< the number of ICs in the daisy chain
|
||||
cell_asic *ic, //!< A two dimensional array that will store the data
|
||||
uint8_t gpio //!< the GPIO bits
|
||||
);
|
||||
|
||||
/*! Helper function to turn the DCC bits HIGH or LOW*/
|
||||
//!@return void
|
||||
void LTC6813_set_cfgr_dis(uint8_t nIC, //!< the number of ICs in the daisy chain
|
||||
cell_asic *ic, //!< A two dimensional array that will store the data
|
||||
uint16_t dcc //!< the DCC bits
|
||||
);
|
||||
|
||||
/*! Helper function to set uv field in CFGRA register*/
|
||||
//!@return void
|
||||
void LTC6813_set_cfgr_uv(uint8_t nIC, //!< the number of ICs in the daisy chain
|
||||
cell_asic *ic, //!< A two dimensional array that will store the data
|
||||
uint16_t uv //!< the UV value
|
||||
);
|
||||
|
||||
/*! Helper function to set DCTO field in CFGRA register*/
|
||||
//!@return void
|
||||
void LTC6813_set_cfgr_dcto(uint8_t nIC, //!< the number of ICs in the daisy chain
|
||||
cell_asic *ic, //!< A two dimensional array that will store the data
|
||||
uint8_t dcto //!< the Dcto bits
|
||||
);
|
||||
|
||||
/*! Helper function to set ov field in CFGRA register*/
|
||||
//!@return void
|
||||
void LTC6813_set_cfgr_ov(uint8_t nIC, //!< the number of ICs in the daisy chain
|
||||
cell_asic *ic, //!< A two dimensional array that will store the data
|
||||
uint16_t ov //!< the OV value
|
||||
);
|
||||
|
||||
/*! Helper Function to initialize the CFGR B data structures*/
|
||||
//!@return void
|
||||
void LTC6813_init_cfgb(uint8_t total_ic, //!< Number of ICs in the system
|
||||
cell_asic *ic //!< A two dimensional array that will store the data
|
||||
);
|
||||
|
||||
/*! Helper function to set appropriate bits in CFGR register based on bit function*/
|
||||
//!@return void
|
||||
void LTC6813_set_cfgrb(uint8_t nIC, //!< the number of ICs in the daisy chain
|
||||
cell_asic *ic, //!< A two dimensional array that will store the data
|
||||
bool fdrf, //!< the FDRF bit
|
||||
bool dtmen, //!< the DTMEN bit
|
||||
bool ps[2], //!< Path selection bits
|
||||
uint8_t gpiobits, //!< the GPIO bits
|
||||
uint16_t dccbits //!< the DCC bits - 7bits
|
||||
);
|
||||
|
||||
/*! Helper function to turn the fdrf bit HIGH or LOW*/
|
||||
//!@return void
|
||||
void LTC6813_set_cfgrb_fdrf(uint8_t nIC, //!< the number of ICs in the daisy chain
|
||||
cell_asic *ic, //!< A two dimensional array that will store the data
|
||||
bool fdrf //!< the FDRF bit
|
||||
);
|
||||
|
||||
/*! Helper function to turn the DTMEN bit HIGH or LOW*/
|
||||
//!@return void
|
||||
void LTC6813_set_cfgrb_dtmen(uint8_t nIC, //!< the number of ICs in the daisy chain
|
||||
cell_asic *ic, //!< A two dimensional array that will store the data
|
||||
bool dtmen //!< the DTMEN bit
|
||||
);
|
||||
|
||||
/*! Helper function to turn the Path Select bit HIGH or LOW*/
|
||||
//!@return void
|
||||
void LTC6813_set_cfgrb_ps(uint8_t nIC, //!< the number of ICs in the daisy chain
|
||||
cell_asic *ic, //!< A two dimensional array that will store the data
|
||||
bool ps[] //!< Path selection bits
|
||||
);
|
||||
|
||||
/*! Helper function to turn the GPIO bit HIGH or LOW*/
|
||||
//!@return void
|
||||
void LTC6813_set_cfgrb_gpio_b(uint8_t nIC, //!< the number of ICs in the daisy chain
|
||||
cell_asic *ic, //!< A two dimensional array that will store the data
|
||||
uint8_t gpiobits //!< the GPIO bits
|
||||
);
|
||||
|
||||
/*! Helper function to turn the dcc bit HIGH or LOW*/
|
||||
//!@return void
|
||||
void LTC6813_set_cfgrb_dcc_b(uint8_t nIC, //!< the number of ICs in the daisy chain
|
||||
cell_asic *ic, //!< A two dimensional array that will store the data
|
||||
uint16_t dccbits //!< the DCC bits - 7bits
|
||||
);
|
||||
|
||||
/*! Write the LTC6813 configuration register A*/
|
||||
//!@return void
|
||||
void LTC6813_wrcfg(uint8_t nIC, //!< Number of ICs in the system
|
||||
cell_asic *ic //!< a two dimensional array of the configuration data that will be written
|
||||
);
|
||||
|
||||
/*! Write the LTC6813 configuration register B*/
|
||||
//!@return void
|
||||
void LTC6813_wrcfgb(uint8_t nIC, //!< Number of ICs in the system
|
||||
cell_asic *ic //!< a two dimensional array of the configuration data that will be written
|
||||
);
|
||||
|
||||
/*! Reads configuration register A of a LTC6813 daisy chain
|
||||
@return int8_t, PEC Status.
|
||||
0: Data read back has matching PEC
|
||||
-1: Data read back has incorrect PEC */
|
||||
int8_t LTC6813_rdcfg(uint8_t nIC, //!< Number of ICs in the system
|
||||
cell_asic *ic //!< a two dimensional array that the function stores the read configuration data
|
||||
);
|
||||
|
||||
/*! Reads configuration register B of a LTC6813 daisy chain
|
||||
@return int8_t, PEC Status.
|
||||
0: Data read back has matching PEC
|
||||
-1: Data read back has incorrect PEC */
|
||||
int8_t LTC6813_rdcfgb(uint8_t nIC, //!< Number of ICs in the system
|
||||
cell_asic *ic //!< a two dimensional array that the function stores the read configuration data
|
||||
);
|
||||
|
||||
/*! Starts cell voltage conversion */
|
||||
//!@return void
|
||||
void LTC6813_adcv(uint8_t MD, //!< ADC Conversion Mode
|
||||
uint8_t DCP, //!< Controls if Discharge is permitted during conversion
|
||||
uint8_t CH //!< Sets which Cell channels are converted
|
||||
);
|
||||
|
||||
/*! Reads and parses the LTC6813 cell voltage registers.
|
||||
@return uint8_t, PEC Status.
|
||||
0: No PEC error detected
|
||||
-1: PEC error detected, retry read
|
||||
*/
|
||||
uint8_t LTC6813_rdcv(uint8_t reg, //!< controls which cell voltage register is read back.
|
||||
uint8_t total_ic, //!< the number of ICs in the daisy chain(-1 only)
|
||||
cell_asic *ic //!< array of the parsed cell codes from lowest to highest.
|
||||
);
|
||||
|
||||
/*! Start a GPIO and Vref2 Conversion */
|
||||
//!@return void
|
||||
void LTC6813_adax(uint8_t MD, //!< ADC Conversion Mode
|
||||
uint8_t CHG //!< Sets which GPIO channels are converted
|
||||
);
|
||||
|
||||
/*! Reads and parses the LTC6813 auxiliary registers.
|
||||
@return int8_t, PEC Status
|
||||
0: No PEC error detected
|
||||
-1: PEC error detected, retry read
|
||||
*/
|
||||
int8_t LTC6813_rdaux(uint8_t reg, //!< controls which GPIO voltage register is read back
|
||||
uint8_t nIC, //!< the number of ICs in the daisy chain
|
||||
cell_asic *ic //!< A two dimensional array of the parsed gpio voltage codes
|
||||
);
|
||||
|
||||
/*! Start a Status ADC Conversion */
|
||||
//!@return void
|
||||
void LTC6813_adstat( uint8_t MD, //!< ADC Conversion Mode
|
||||
uint8_t CHST //!< Sets which Stat channels are converted
|
||||
);
|
||||
|
||||
/*! Reads and parses the LTC6813 stat registers.
|
||||
@return int8_t, PEC Status
|
||||
0: No PEC error detected
|
||||
-1: PEC error detected, retry read
|
||||
*/
|
||||
int8_t LTC6813_rdstat(uint8_t reg, //!< Determines which Stat register is read back.
|
||||
uint8_t total_ic,//!< Number of ICs in the system
|
||||
cell_asic *ic //!< A two dimensional array that will store the data
|
||||
);
|
||||
|
||||
/*! Starts cell voltage and GPIO 1&2 conversion */
|
||||
//!@return void
|
||||
void LTC6813_adcvax(uint8_t MD, //!< ADC Conversion Mode
|
||||
uint8_t DCP //!< Controls if Discharge is permitted during conversion
|
||||
);
|
||||
|
||||
/*! Starts cell voltage and SOC conversion */
|
||||
//!@return void
|
||||
void LTC6813_adcvsc(uint8_t MD, //!< ADC Conversion Mode
|
||||
uint8_t DCP //!< Controls if Discharge is permitted during conversion
|
||||
);
|
||||
|
||||
/*! Starts the Mux Decoder diagnostic self test
|
||||
Running this command will start the Mux Decoder Diagnostic Self Test
|
||||
This test takes roughly 1mS to complete. The MUXFAIL bit will be updated,
|
||||
the bit will be set to 1 for a failure and 0 if the test has been passed.
|
||||
*/
|
||||
//!@return void
|
||||
void LTC6813_diagn(void);
|
||||
|
||||
/*! Starts cell voltage self test conversion */
|
||||
//!@return void
|
||||
void LTC6813_cvst(uint8_t MD, //!< ADC Conversion Mode
|
||||
uint8_t ST //!< Self Test Mode
|
||||
);
|
||||
|
||||
/*! Start an Auxiliary Register Self Test Conversion */
|
||||
//!@return void
|
||||
void LTC6813_axst(uint8_t MD, //!< ADC Conversion Mode
|
||||
uint8_t ST //!< Sets if self test 1 or 2 is run
|
||||
);
|
||||
|
||||
/*! Start a Status Register Self Test Conversion */
|
||||
//!@return void
|
||||
void LTC6813_statst(uint8_t MD, //!< ADC Conversion Mode
|
||||
uint8_t ST //!< Sets if self test 1 or 2 is run
|
||||
);
|
||||
|
||||
/*! Helper function that runs the ADC Self Tests*/
|
||||
//!@return int16_t, error
|
||||
//! Number of errors detected.
|
||||
int16_t LTC6813_run_cell_adc_st(uint8_t adc_reg, //!< Type of register
|
||||
uint8_t total_ic, //!< Number of ICs in the system
|
||||
cell_asic *ic, //!< A two dimensional array that will store the data
|
||||
uint8_t md, //!< ADC Mode
|
||||
bool adcopt //!< the adcopt bit in the configuration register
|
||||
);
|
||||
|
||||
/*! Starts cell voltage overlap conversion */
|
||||
//!@return void
|
||||
void LTC6813_adol(uint8_t MD, //!< ADC Conversion Mode
|
||||
uint8_t DCP //!< Discharge permitted during conversion
|
||||
);
|
||||
|
||||
/*! Helper Function that runs the ADC Overlap test*/
|
||||
//!@return uint16_t, error
|
||||
//! 0: Pass
|
||||
//!-1: False, Error detected
|
||||
uint16_t LTC6813_run_adc_overlap(uint8_t total_ic, //!< Number of ICs in the system
|
||||
cell_asic *ic //!< A two dimensional array that will store the data
|
||||
);
|
||||
|
||||
/*! Start an open wire Conversion
|
||||
*/
|
||||
//!@return void
|
||||
void LTC6813_adow(uint8_t MD, //!< ADC Conversion Mode
|
||||
uint8_t PUP,//!< Controls if Discharge is permitted during
|
||||
uint8_t CH, //!< Sets which Cell channels are converted
|
||||
uint8_t DCP //!< Discharge permitted during conversion
|
||||
);
|
||||
|
||||
/*! start GPIOs open wire ADC conversion */
|
||||
//!@return void
|
||||
void LTC6813_axow(uint8_t MD, //!< ADC Mode
|
||||
uint8_t PUP //!< Discharge Permit
|
||||
);
|
||||
|
||||
/*! Runs open wire for GPIOs*/
|
||||
//!@return void
|
||||
void LTC6813_run_gpio_openwire(uint8_t total_ic, //!< Number of ICs in the system
|
||||
cell_asic *ic //!< A two dimensional array that will store the data
|
||||
);
|
||||
|
||||
/*! Helper function that runs the data sheet algorithm for open wire for single cell detection*/
|
||||
//!@return void
|
||||
void LTC6813_run_openwire_single(uint8_t total_ic, //!< Number of ICs in the system
|
||||
cell_asic *ic //!< A two dimensional array that will store the data
|
||||
);
|
||||
|
||||
/*! Helper function that runs open wire for multiple cell and two consecutive cells detection*/
|
||||
//!@return void
|
||||
void LTC6813_run_openwire_multi(uint8_t total_ic, //!< Number of ICs in the system
|
||||
cell_asic *ic //!< A two dimensional array that will store the data
|
||||
);
|
||||
|
||||
/*! Start an GPIO Redundancy test */
|
||||
//!@return void
|
||||
void LTC6813_adaxd(uint8_t MD, //!< ADC Conversion Mode
|
||||
uint8_t CHG //!< Sets which GPIO channels are converted
|
||||
);
|
||||
|
||||
/*! Start a Status register redundancy test Conversion */
|
||||
//!@return void
|
||||
void LTC6813_adstatd(uint8_t MD, //!< ADC Mode
|
||||
uint8_t CHST //!< Sets which Status channels are converted
|
||||
);
|
||||
|
||||
/*! Helper function that runs the ADC Digital Redundancy commands and checks output for errors*/
|
||||
//!@return int16_t, error
|
||||
int16_t LTC6813_run_adc_redundancy_st(uint8_t adc_mode, //!< ADC Mode
|
||||
uint8_t adc_reg, //!< Type of register
|
||||
uint8_t total_ic, //!< Number of ICs in the system
|
||||
cell_asic *ic //!< A two dimensional array that will store the data
|
||||
);
|
||||
|
||||
//! Sends the poll ADC command
|
||||
//! @returns 1 byte read back after a pladc command. If the byte is not 0xFF ADC conversion has completed
|
||||
uint8_t LTC6813_pladc(void);
|
||||
|
||||
//! This function will block operation until the ADC has finished it's conversion
|
||||
//! @returns the approximate time it took for the ADC function to complete.
|
||||
uint32_t LTC6813_pollAdc(void);
|
||||
|
||||
/*! Clears the LTC6813 cell voltage registers */
|
||||
//!@return void
|
||||
void LTC6813_clrcell(void);
|
||||
|
||||
/*! Clears the LTC6813 Auxiliary registers */
|
||||
//!@return void
|
||||
void LTC6813_clraux(void);
|
||||
|
||||
/*! Clears the LTC6813 Stat registers */
|
||||
//!@return void
|
||||
void LTC6813_clrstat(void);
|
||||
|
||||
/*! Write the LTC6813 PWM register */
|
||||
//!@return void
|
||||
void LTC6813_wrpwm(uint8_t nIC, //!< number of ICs in the daisy chain
|
||||
uint8_t pwmReg, //!< PWM Register A or B
|
||||
cell_asic *ic //!< A two dimensional array that will store the data
|
||||
);
|
||||
|
||||
/*! Reads pwm registers of a LTC6813 daisy chain */
|
||||
//!@return int8_t, PEC Status.
|
||||
//! 0: Data read back has matching PEC
|
||||
//! -1: Data read back has incorrect PEC
|
||||
int8_t LTC6813_rdpwm(uint8_t nIC, //!< number of ICs in the daisy chain
|
||||
uint8_t pwmReg, //! PWM Register A or B
|
||||
cell_asic *ic //!< A two dimensional array that will store the data
|
||||
);
|
||||
|
||||
/*! Write the LTC6813 Sctrl register */
|
||||
//!@return void
|
||||
void LTC6813_wrsctrl(uint8_t nIC, //!< number of ICs in the daisy chain
|
||||
uint8_t sctrl_reg,//! SCTRL Register A or B
|
||||
cell_asic *ic //!< A two dimensional array that will store the data
|
||||
);
|
||||
|
||||
/*! Reads sctrl registers of a LTC6813 daisy chain
|
||||
@return int8_t, PEC Status.
|
||||
0: Data read back has matching PEC
|
||||
-1: Data read back has incorrect PEC
|
||||
*/
|
||||
int8_t LTC6813_rdsctrl(uint8_t nIC, //!< number of ICs in the daisy chain
|
||||
uint8_t sctrl_reg,//! SCTRL Register A or B
|
||||
cell_asic *ic //!< A two dimensional array that will store the data
|
||||
);
|
||||
|
||||
/*! Start Sctrl data communication
|
||||
This command will start the sctrl pulse communication over the spins
|
||||
*/
|
||||
//!@return void
|
||||
void LTC6813_stsctrl(void);
|
||||
|
||||
/*! Clears the LTC6813 Sctrl registers */
|
||||
//!@return void
|
||||
void LTC6813_clrsctrl(void);
|
||||
|
||||
/*! Write the LTC6813 COMM register */
|
||||
//!@return void
|
||||
void LTC6813_wrcomm(uint8_t total_ic, //!< Number of ICs in the daisy chain
|
||||
cell_asic *ic //!< A two dimensional array of the comm data that will be written
|
||||
);
|
||||
|
||||
/*! Reads comm registers of a LTC6813 daisy chain
|
||||
@return int8_t, PEC Status.
|
||||
0: Data read back has matching PEC
|
||||
-1: Data read back has incorrect PEC
|
||||
*/
|
||||
int8_t LTC6813_rdcomm(uint8_t total_ic, //!< number of ICs in the daisy chain
|
||||
cell_asic *ic //!< Two dimensional array that the function stores the read comm data.
|
||||
);
|
||||
|
||||
/*! Issues a stcomm command and clocks data out of the COMM register */
|
||||
//!@return void
|
||||
void LTC6813_stcomm(void);
|
||||
|
||||
/*! Helper Function to Set DCC bits in the CFGR Registers*/
|
||||
//!@return void
|
||||
void LTC6813_set_discharge(int Cell, //!< The cell to be discharged
|
||||
uint8_t total_ic, //!< Number of ICs in the system
|
||||
cell_asic *ic //!< A two dimensional array that will store the data
|
||||
);
|
||||
|
||||
/*! Helper Function to clear DCC bits in the CFGR Registers*/
|
||||
//!@return void
|
||||
void LTC6813_clear_discharge(uint8_t total_ic, //!< Number of ICs in the system
|
||||
cell_asic *ic //!< A two dimensional array that will store the data
|
||||
);
|
||||
|
||||
/*! Helper Function that counts overall PEC errors and register/IC PEC errors*/
|
||||
//!@return void
|
||||
void LTC6813_check_pec(uint8_t total_ic, //!< Number of ICs in the system
|
||||
uint8_t reg, //!< Type of register
|
||||
cell_asic *ic //!< A two dimensional array that will store the data
|
||||
);
|
||||
|
||||
/*! Helper Function that resets the PEC error counters */
|
||||
//!@return void
|
||||
void LTC6813_reset_crc_count(uint8_t total_ic, //!< Number of ICs in the system
|
||||
cell_asic *ic //!< A two dimensional array that will store the data
|
||||
);
|
||||
|
||||
/*! Write the 6813 PWM/Sctrl Register B */
|
||||
//!@return void
|
||||
void LTC6813_wrpsb(uint8_t total_ic, //!< Number of ICs in the system
|
||||
cell_asic *ic //!< A two dimensional array that will store the data
|
||||
);
|
||||
|
||||
/*! Reading pwm/s control register B
|
||||
@return uint8_t, PEC Status.
|
||||
0: Data read back has matching PEC
|
||||
-1: Data read back has incorrect PEC
|
||||
*/
|
||||
uint8_t LTC6813_rdpsb(uint8_t total_ic, //!< number of ICs in the daisy chain
|
||||
cell_asic *ic //!< a two dimensional array that the function stores the read pwm data
|
||||
);
|
||||
|
||||
/*! Mutes the LTC6813 discharge transistors */
|
||||
//!@return void
|
||||
void LTC6813_mute(void);
|
||||
|
||||
/*! Clears the LTC6813 Mute Discharge */
|
||||
//!@return void
|
||||
void LTC6813_unmute(void);
|
||||
|
||||
#endif
|
||||
1319
USER/Ref/bmu-18s-firmware/HARDWARE/ltc681x.c
Normal file
1319
USER/Ref/bmu-18s-firmware/HARDWARE/ltc681x.c
Normal file
File diff suppressed because it is too large
Load Diff
521
USER/Ref/bmu-18s-firmware/HARDWARE/ltc681x.h
Normal file
521
USER/Ref/bmu-18s-firmware/HARDWARE/ltc681x.h
Normal file
@@ -0,0 +1,521 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* File Name : ltc681x.h
|
||||
* Description : This file provides code for the configuration
|
||||
* of ltc681x driver.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2021 Amogreentech Co., Ltd.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef _LTC681X_H_
|
||||
#define _LTC681X_H_
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include <stm32f10x.h>
|
||||
#include "sys.h"
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/* Exported define -----------------------------------------------------------*/
|
||||
#define IC_LTC6813
|
||||
|
||||
#define MD_422HZ_1KHZ 0
|
||||
#define MD_27KHZ_14KHZ 1
|
||||
#define MD_7KHZ_3KHZ 2
|
||||
#define MD_26HZ_2KHZ 3
|
||||
|
||||
#define ADC_OPT_ENABLED 1
|
||||
#define ADC_OPT_DISABLED 0
|
||||
|
||||
#define CELL_CH_ALL 0
|
||||
#define CELL_CH_1and7 1
|
||||
#define CELL_CH_2and8 2
|
||||
#define CELL_CH_3and9 3
|
||||
#define CELL_CH_4and10 4
|
||||
#define CELL_CH_5and11 5
|
||||
#define CELL_CH_6and12 6
|
||||
|
||||
#define SELFTEST_1 1
|
||||
#define SELFTEST_2 2
|
||||
|
||||
#define AUX_CH_ALL 0
|
||||
#define AUX_CH_GPIO1 1
|
||||
#define AUX_CH_GPIO2 2
|
||||
#define AUX_CH_GPIO3 3
|
||||
#define AUX_CH_GPIO4 4
|
||||
#define AUX_CH_GPIO5 5
|
||||
#define AUX_CH_VREF2 6
|
||||
|
||||
#define STAT_CH_ALL 0
|
||||
#define STAT_CH_SOC 1
|
||||
#define STAT_CH_ITEMP 2
|
||||
#define STAT_CH_VREGA 3
|
||||
#define STAT_CH_VREGD 4
|
||||
|
||||
#define DCP_DISABLED 0
|
||||
#define DCP_ENABLED 1
|
||||
|
||||
#define PULL_UP_CURRENT 1
|
||||
#define PULL_DOWN_CURRENT 0
|
||||
|
||||
#define NUM_RX_BYT 8
|
||||
#define CELL 1
|
||||
#define AUX 2
|
||||
#define STAT 3
|
||||
#define CFGR 0
|
||||
#define CFGRB 4
|
||||
|
||||
#define CS_PIN PBout(12) //The chip select signals
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
|
||||
//! Cell Voltage data structure.
|
||||
typedef struct
|
||||
{
|
||||
uint16_t c_codes[18]; //!< Cell Voltage Codes
|
||||
uint8_t pec_match[6]; //!< If a PEC error was detected during most recent read cmd
|
||||
} cv;
|
||||
|
||||
//! AUX Reg Voltage Data
|
||||
typedef struct
|
||||
{
|
||||
uint16_t a_codes[12]; //!< Aux Voltage Codes
|
||||
uint8_t pec_match[4]; //!< If a PEC error was detected during most recent read cmd
|
||||
} ax;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t stat_codes[4]; //!< A two dimensional array of the stat voltage codes.
|
||||
uint8_t flags[3]; //!< byte array that contains the uv/ov flag data
|
||||
uint8_t mux_fail[1]; //!< Mux self test status flag
|
||||
uint8_t thsd[1]; //!< Thermal shutdown status
|
||||
uint8_t pec_match[2]; //!< If a PEC error was detected during most recent read cmd
|
||||
} st;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t tx_data[6];
|
||||
uint8_t rx_data[8];
|
||||
uint8_t rx_pec_match; //!< If a PEC error was detected during most recent read cmd
|
||||
} ic_register;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t pec_count;
|
||||
uint16_t cfgr_pec;
|
||||
uint16_t cell_pec[6];
|
||||
uint16_t aux_pec[4];
|
||||
uint16_t stat_pec[2];
|
||||
} pec_counter;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t cell_channels;
|
||||
uint8_t stat_channels;
|
||||
uint8_t aux_channels;
|
||||
uint8_t num_cv_reg;
|
||||
uint8_t num_gpio_reg;
|
||||
uint8_t num_stat_reg;
|
||||
} register_cfg;
|
||||
|
||||
typedef uint8_t bool;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ic_register config;
|
||||
ic_register configb;
|
||||
cv cells;
|
||||
ax aux;
|
||||
st stat;
|
||||
ic_register com;
|
||||
ic_register pwm;
|
||||
ic_register pwmb;
|
||||
ic_register sctrl;
|
||||
ic_register sctrlb;
|
||||
bool isospi_reverse;
|
||||
pec_counter crc_count;
|
||||
register_cfg ic_reg;
|
||||
long system_open_wire;
|
||||
} cell_asic;
|
||||
|
||||
/* Exported variables ------------------------------------------------------- */
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
|
||||
/*! calculates and returns the CRC15
|
||||
@returns The calculated pec15 as an unsigned int
|
||||
*/
|
||||
uint16_t pec15_calc(uint8_t len, //!< the length of the data array being passed to the function
|
||||
uint8_t *data //!< the array of data that the PEC will be generated from
|
||||
);
|
||||
|
||||
/*! Wake isoSPI up from idle state */
|
||||
void wakeup_idle(uint8_t total_ic);//!< number of ICs in the daisy chain
|
||||
|
||||
/*! Wake the LTC6813 from the sleep state */
|
||||
void wakeup_sleep(uint8_t total_ic); //!< number of ICs in the daisy chain
|
||||
|
||||
/*! Sense a command to the bms IC. This code will calculate the PEC code for the transmitted command*/
|
||||
void cmd_68(uint8_t tx_cmd[2]); //!< 2 Byte array containing the BMS command to be sent
|
||||
|
||||
//! Writes an array of data to the daisy chain
|
||||
void write_68(uint8_t total_ic , //!< number of ICs in the daisy chain
|
||||
uint8_t tx_cmd[2], //!< 2 Byte array containing the BMS command to be sent
|
||||
uint8_t data[] //!< Array containing the data to be written to the BMS ICs
|
||||
);
|
||||
//! Issues a command onto the daisy chain and reads back 6*total_ic data in the rx_data array
|
||||
int8_t read_68( uint8_t total_ic, //!< number of ICs in the daisy chain
|
||||
uint8_t tx_cmd[2], //!< 2 Byte array containing the BMS command to be sent
|
||||
uint8_t *rx_data); //!< Array that the read back data will be stored.
|
||||
|
||||
/*! Starts the Mux Decoder diagnostic self test
|
||||
|
||||
Running this command will start the Mux Decoder Diagnostic Self Test
|
||||
This test takes roughly 1mS to complete. The MUXFAIL bit will be updated,
|
||||
the bit will be set to 1 for a failure and 0 if the test has been passed.
|
||||
*/
|
||||
void LTC681x_diagn(void);
|
||||
|
||||
/*! Starts cell voltage conversion
|
||||
|
||||
Starts ADC conversions of the LTC6811 Cpin inputs.
|
||||
The type of ADC conversion executed can be changed by setting the following parameters:
|
||||
*/
|
||||
void LTC681x_adcv(uint8_t MD, //!< ADC Conversion Mode
|
||||
uint8_t DCP, //!< Controls if Discharge is permitted during conversion
|
||||
uint8_t CH //!< Sets which Cell channels are converted
|
||||
);
|
||||
|
||||
/*! Starts cell voltage and GPIO 1&2 conversion
|
||||
*/
|
||||
void LTC681x_adcvax(
|
||||
uint8_t MD, //!< ADC Conversion Mode
|
||||
uint8_t DCP //!< Controls if Discharge is permitted during conversion
|
||||
);
|
||||
|
||||
|
||||
/*! Starts cell voltage self test conversion
|
||||
*/
|
||||
void LTC681x_cvst(
|
||||
uint8_t MD, //!< ADC Conversion Mode
|
||||
uint8_t ST //!< Self Test Mode
|
||||
);
|
||||
|
||||
/*! Starts cell voltage and SOC conversion
|
||||
*/
|
||||
void LTC681x_adcvsc(
|
||||
uint8_t MD, //!< ADC Conversion Mode
|
||||
uint8_t DCP //!< Controls if Discharge is permitted during conversion
|
||||
);
|
||||
/*! Starts cell voltage overlap conversion
|
||||
*/
|
||||
void LTC681x_adol(
|
||||
uint8_t MD, //!< ADC Conversion Mode
|
||||
uint8_t DCP //!< Discharge permitted during conversion
|
||||
);
|
||||
|
||||
/*! Start an open wire Conversion
|
||||
*/
|
||||
void LTC681x_adow(
|
||||
uint8_t MD, //!< ADC Conversion Mode
|
||||
uint8_t PUP //!< Controls if Discharge is permitted during conversion
|
||||
);
|
||||
|
||||
|
||||
/*! Start a GPIO and Vref2 Conversion
|
||||
*/
|
||||
void LTC681x_adax(
|
||||
uint8_t MD, //!< ADC Conversion Mode
|
||||
uint8_t CHG //!< Sets which GPIO channels are converted
|
||||
);
|
||||
|
||||
/*! Start an GPIO Redundancy test
|
||||
*/
|
||||
void LTC681x_adaxd(
|
||||
uint8_t MD, //!< ADC Conversion Mode
|
||||
uint8_t CHG //!< Sets which GPIO channels are converted
|
||||
);
|
||||
|
||||
/*! Start an Auxiliary Register Self Test Conversion
|
||||
*/
|
||||
void LTC681x_axst(
|
||||
uint8_t MD, //!< ADC Conversion Mode
|
||||
uint8_t ST //!< Sets if self test 1 or 2 is run
|
||||
);
|
||||
|
||||
|
||||
|
||||
/*! Start a Status ADC Conversion
|
||||
*/
|
||||
void LTC681x_adstat(
|
||||
uint8_t MD, //!< ADC Conversion Mode
|
||||
uint8_t CHST //!< Sets which Stat channels are converted
|
||||
);
|
||||
|
||||
/*! Start a Status register redundancy test Conversion
|
||||
*/
|
||||
void LTC681x_adstatd(
|
||||
uint8_t MD, //!< ADC Mode
|
||||
uint8_t CHST //!< Sets which Status channels are converted
|
||||
);
|
||||
|
||||
|
||||
/*! Start a Status Register Self Test Conversion
|
||||
*/
|
||||
void LTC681x_statst(
|
||||
uint8_t MD, //!< ADC Conversion Mode
|
||||
uint8_t ST //!< Sets if self test 1 or 2 is run
|
||||
);
|
||||
|
||||
void LTC681x_rdcv_reg(uint8_t reg, //!<Determines which cell voltage register is read back
|
||||
uint8_t total_ic, //!<the number of ICs in the
|
||||
uint8_t *data //!<An array of the unparsed cell codes
|
||||
);
|
||||
/*! helper function that parses voltage measurement registers
|
||||
*/
|
||||
int8_t parse_cells(uint8_t current_ic,
|
||||
uint8_t cell_reg,
|
||||
uint8_t cell_data[],
|
||||
uint16_t *cell_codes,
|
||||
uint8_t *ic_pec);
|
||||
|
||||
/*! helper function that parses aux volatge measurement registers
|
||||
*/
|
||||
int8_t parse_auxs(uint8_t current_ic,
|
||||
uint8_t aux_reg,
|
||||
uint8_t aux_data[],
|
||||
uint16_t *aux_codes,
|
||||
uint8_t *ic_pec);
|
||||
|
||||
/*! Read the raw data from the LTC681x auxiliary register
|
||||
|
||||
The function reads a single GPIO voltage register and stores thre read data
|
||||
in the *data point as a byte array. This function is rarely used outside of
|
||||
the LTC681x_rdaux(void) command.
|
||||
*/
|
||||
void LTC681x_rdaux_reg( uint8_t reg, //Determines which GPIO voltage register is read back
|
||||
uint8_t total_ic, //The number of ICs in the system
|
||||
uint8_t *data //Array of the unparsed auxiliary codes
|
||||
);
|
||||
/*! Read the raw data from the LTC681x stat register
|
||||
|
||||
The function reads a single GPIO voltage register and stores thre read data
|
||||
in the *data point as a byte array. This function is rarely used outside of
|
||||
the LTC681x_rdstat(void) command.
|
||||
*/
|
||||
void LTC681x_rdstat_reg(uint8_t reg, //Determines which stat register is read back
|
||||
uint8_t total_ic, //The number of ICs in the system
|
||||
uint8_t *data //Array of the unparsed stat codes
|
||||
);
|
||||
|
||||
/*! Clears the LTC681x cell voltage registers
|
||||
|
||||
The command clears the cell voltage registers and initializes
|
||||
all values to 1. The register will read back hexadecimal 0xFF
|
||||
after the command is sent.
|
||||
*/
|
||||
void LTC681x_clrcell(void);
|
||||
/*! Clears the LTC681x Auxiliary registers
|
||||
|
||||
The command clears the Auxiliary registers and initializes
|
||||
all values to 1. The register will read back hexadecimal 0xFF
|
||||
after the command is sent.
|
||||
*/
|
||||
void LTC681x_clraux(void);
|
||||
|
||||
/*! Clears the LTC681x Stat registers
|
||||
|
||||
The command clears the Stat registers and initializes
|
||||
all values to 1. The register will read back hexadecimal 0xFF
|
||||
after the command is sent.
|
||||
*/
|
||||
void LTC681x_clrstat(void);
|
||||
|
||||
/*! Clears the LTC681x SCTRL registers
|
||||
|
||||
The command clears the SCTRL registers and initializes
|
||||
all values to 0. The register will read back hexadecimal 0x00
|
||||
after the command is sent.
|
||||
*/
|
||||
void LTC681x_clrsctrl(void);
|
||||
|
||||
/*! Starts the Mux Decoder diagnostic self test
|
||||
|
||||
Running this command will start the Mux Decoder Diagnostic Self Test
|
||||
This test takes roughly 1mS to complete. The MUXFAIL bit will be updated,
|
||||
the bit will be set to 1 for a failure and 0 if the test has been passed.
|
||||
*/
|
||||
void LTC681x_diagn(void);
|
||||
|
||||
/*! Reads and parses the LTC681x cell voltage registers.
|
||||
|
||||
The function is used to read the cell codes of the LTC6811.
|
||||
This function will send the requested read commands parse the data
|
||||
and store the cell voltages in the cell_asic structure.
|
||||
*/
|
||||
uint8_t LTC681x_rdcv(uint8_t reg, // Controls which cell voltage register is read back.
|
||||
uint8_t total_ic, // the number of ICs in the system
|
||||
cell_asic ic[] // Array of the parsed cell codes
|
||||
);
|
||||
|
||||
/*! Reads and parses the LTC681x auxiliary registers.
|
||||
|
||||
The function is used to read the parsed GPIO codes of the LTC6811. This function will send the requested
|
||||
read commands parse the data and store the gpio voltages in the cell_asic structure.
|
||||
*/
|
||||
int8_t LTC681x_rdaux(uint8_t reg, //Determines which GPIO voltage register is read back.
|
||||
uint8_t total_ic,//the number of ICs in the system
|
||||
cell_asic ic[]//!< Measurement Data Structure
|
||||
);
|
||||
|
||||
/*! Reads and parses the LTC681x stat registers.
|
||||
|
||||
The function is used to read the parsed status codes of the LTC6811. This function will send the requested
|
||||
read commands parse the data and store the status voltages in the cell_asic structure
|
||||
*/
|
||||
int8_t LTC681x_rdstat( uint8_t reg, //!<Determines which Stat register is read back.
|
||||
uint8_t total_ic,//!<the number of ICs in the system
|
||||
cell_asic ic[]//!< Measurement Data Structure
|
||||
);
|
||||
/*! Write the LTC681x CFGRA
|
||||
|
||||
This command will write the configuration registers of the LTC681xs
|
||||
connected in a daisy chain stack. The configuration is written in descending
|
||||
order so the last device's configuration is written first.
|
||||
*/
|
||||
void LTC681x_wrcfg(uint8_t total_ic, //The number of ICs being written to
|
||||
cell_asic ic[] //A two dimensional array of the configuration data that will be written
|
||||
);
|
||||
|
||||
/*! Write the LTC681x CFGRB
|
||||
|
||||
This command will write the configuration registers of the LTC681xs
|
||||
connected in a daisy chain stack. The configuration is written in descending
|
||||
order so the last device's configuration is written first.
|
||||
*/
|
||||
void LTC681x_wrcfgb(uint8_t total_ic, //The number of ICs being written to
|
||||
cell_asic ic[] //A two dimensional array of the configuration data that will be written
|
||||
);
|
||||
|
||||
/*! Reads the LTC681x CFGRA register
|
||||
*/
|
||||
int8_t LTC681x_rdcfg(uint8_t total_ic, //Number of ICs in the system
|
||||
cell_asic ic[] //A two dimensional array that the function stores the read configuration data.
|
||||
);
|
||||
|
||||
/*! Reads the LTC681x CFGRB register
|
||||
*/
|
||||
int8_t LTC681x_rdcfgb(uint8_t total_ic, //Number of ICs in the system
|
||||
cell_asic ic[] //A two dimensional array that the function stores the read configuration data.
|
||||
);
|
||||
|
||||
/*! Selft Test Helper Function*/
|
||||
uint16_t LTC681x_st_lookup(
|
||||
uint8_t MD, //ADC Mode
|
||||
uint8_t ST //Self Test
|
||||
);
|
||||
|
||||
/*! Helper Function to clear DCC bits in the CFGR Registers*/
|
||||
void clear_discharge(uint8_t total_ic,
|
||||
cell_asic ic[]);
|
||||
|
||||
/*! Helper function that runs the ADC Self Tests*/
|
||||
int16_t LTC681x_run_cell_adc_st(uint8_t adc_reg,
|
||||
uint8_t total_ic,
|
||||
cell_asic ic[]);
|
||||
|
||||
/*! Helper function that runs the ADC Digital Redudancy commands and checks output for errors*/
|
||||
int16_t LTC681x_run_adc_redundancy_st(uint8_t adc_mode,
|
||||
uint8_t adc_reg,
|
||||
uint8_t total_ic,
|
||||
cell_asic ic[]);
|
||||
|
||||
/*! Helper function that runs the datasheet open wire algorithm*/
|
||||
void LTC681x_run_openwire(uint8_t total_ic,
|
||||
cell_asic ic[]);
|
||||
|
||||
/*! Helper Function that counts overall PEC errors and register/IC PEC errors*/
|
||||
void LTC681x_check_pec(uint8_t total_ic,
|
||||
uint8_t reg,
|
||||
cell_asic ic[]);
|
||||
|
||||
/*! Helper Function that resets the PEC error counters */
|
||||
void LTC681x_reset_crc_count(uint8_t total_ic,
|
||||
cell_asic ic[]);
|
||||
|
||||
/*! Helper Function to initialize the CFGR data structures*/
|
||||
void LTC681x_init_cfg(uint8_t total_ic,
|
||||
cell_asic ic[]);
|
||||
|
||||
/*! Helper function to set appropriate bits in CFGR register based on bit function*/
|
||||
void LTC681x_set_cfgr(uint8_t nIC,
|
||||
cell_asic ic[],
|
||||
bool refon,
|
||||
bool adcopt,
|
||||
bool gpio[5],
|
||||
uint16_t dcc);
|
||||
|
||||
/*! Helper function to turn the refon bit HIGH or LOW*/
|
||||
void LTC681x_set_cfgr_refon(uint8_t nIC,
|
||||
cell_asic ic[],
|
||||
bool refon);
|
||||
|
||||
/*! Helper function to turn the ADCOPT bit HIGH or LOW*/
|
||||
void LTC681x_set_cfgr_adcopt(uint8_t nIC,
|
||||
cell_asic ic[],
|
||||
bool adcopt);
|
||||
|
||||
/*! Helper function to turn the GPIO bits HIGH or LOW*/
|
||||
void LTC681x_set_cfgr_gpio(uint8_t nIC,
|
||||
cell_asic ic[],
|
||||
bool gpio[]);
|
||||
|
||||
/*! Helper function to turn the DCC bits HIGH or LOW*/
|
||||
void LTC681x_set_cfgr_dis(uint8_t nIC,
|
||||
cell_asic ic[],
|
||||
uint16_t dcc);
|
||||
/*! Helper function to turn the DCC bits HIGH or LOW*/
|
||||
void LTC681x_set_cfgr_dcto(uint8_t nIC,
|
||||
cell_asic ic[],
|
||||
uint8_t dcto);
|
||||
/*! Helper function to turn the DCC bits HIGH or LOW*/
|
||||
void LTC681x_set_cfgr_uv(uint8_t nIC,
|
||||
cell_asic ic[],
|
||||
uint16_t UV);
|
||||
|
||||
|
||||
//********************************** LTC6811 ******************************************//
|
||||
void LTC6811_init_reg_limits(uint8_t total_ic, cell_asic ic[]);
|
||||
|
||||
void LTC6811_set_discharge(int Cell,
|
||||
uint8_t total_ic,
|
||||
cell_asic ic[]);
|
||||
|
||||
//********************************** SPI ******************************************//
|
||||
/*
|
||||
Writes an array of bytes out of the SPI port
|
||||
*/
|
||||
void spi_write_array(uint8_t len, // Option: Number of bytes to be written on the SPI port
|
||||
uint8_t data[] //Array of bytes to be written on the SPI port
|
||||
);
|
||||
/*
|
||||
Writes and read a set number of bytes using the SPI port.
|
||||
|
||||
*/
|
||||
|
||||
void spi_write_read(uint8_t tx_Data[],//array of data to be written on SPI port
|
||||
uint8_t tx_len, //length of the tx data arry
|
||||
uint8_t *rx_data,//Input: array that will store the data read by the SPI port
|
||||
uint8_t rx_len //Option: number of bytes to be read from the SPI port
|
||||
);
|
||||
|
||||
uint8_t spi_read_byte(uint8_t tx_dat);//name conflicts with linduino also needs to take a byte as a parameter
|
||||
|
||||
#endif /* _LTC681X_H_ */
|
||||
|
||||
/*******************(C)COPYRIGHT 2021 Amogreentech *********END OF FILE********/
|
||||
90
USER/Ref/bmu-18s-firmware/HARDWARE/spi.c
Normal file
90
USER/Ref/bmu-18s-firmware/HARDWARE/spi.c
Normal file
@@ -0,0 +1,90 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* File Name : spi.c
|
||||
* Description : This file provides code for the configuration
|
||||
* of the SPI instances.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2021 Amogreentech Co., Ltd.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "spi.h"
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Private function ----------------------------------------------------------*/
|
||||
|
||||
// Following is the SPI module initialization code, and configured to master mode
|
||||
// SPI port initialization
|
||||
// Needle is SPI1 initialization
|
||||
void SPI2_Init(void)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
SPI_InitTypeDef SPI_InitStructure;
|
||||
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // Enable GPIOB clock
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2 , ENABLE); // Enable SPI2 clock
|
||||
|
||||
//GPIO B13, B14, B15 initialization settings
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13
|
||||
| GPIO_Pin_14
|
||||
| GPIO_Pin_15
|
||||
; // PB13~15 reuse function output
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // Multiplexing function
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 100MHz
|
||||
GPIO_Init(GPIOB, &GPIO_InitStructure); // Initialize
|
||||
|
||||
GPIO_SetBits(GPIOB, GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15);
|
||||
|
||||
//Here only for the SPI port initialization
|
||||
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; // Set SPI unidirectional or bi-directional data modes: SPI is set to two-lane bi-directional full-duplex
|
||||
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; // Set SPI mode: set master SPI
|
||||
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; // Set SPI data size: send receive 8-bit SPI frame structure
|
||||
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; // Serial synchronous clock idle high
|
||||
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; // Serial synchronous clocks second jump (increase or decrease) the data is sampled
|
||||
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; // NSS is set by hardware (NSS pins) or software (using SSI) management: internal NSS SSI signal level control
|
||||
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64; // Define baud rate predissociation spectrum of values: baud rate predissociation spectrum value of 64
|
||||
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; // Specifies the data transmission starting from MSB or LSB bit: data transmission starting from the MSB
|
||||
SPI_InitStructure.SPI_CRCPolynomial = 7; // CRC calculate polynomials
|
||||
SPI_Init(SPI2, &SPI_InitStructure); // According to the parameters specified in SPI_InitStruct to initialize peripherals SPIx register
|
||||
|
||||
SPI_Cmd(SPI2, ENABLE); // Make SPI peripherals
|
||||
|
||||
SPI2_ReadWriteByte(0xff); // To start the transfer
|
||||
}
|
||||
|
||||
// SPI1 speed setting function
|
||||
// SpeedSet:0~7
|
||||
// SPI speed =fAPB2/2^ (SpeedSet+1)
|
||||
// FAPB2 84Mhz
|
||||
void SPI2_SetSpeed(u8 SPI_BaudRatePrescaler)
|
||||
{
|
||||
assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler));
|
||||
SPI2->CR1 &= 0XFFC7;
|
||||
SPI2->CR1 |= SPI_BaudRatePrescaler; //Set SPI1 speed
|
||||
SPI_Cmd(SPI2, ENABLE);
|
||||
}
|
||||
|
||||
// SPI1 read and write bytes
|
||||
// TxData: the bytes to write
|
||||
// Return value: reads a byte
|
||||
u8 SPI2_ReadWriteByte(u8 TxData)
|
||||
{
|
||||
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET){}//Waiting to be sent
|
||||
|
||||
SPI_I2S_SendData(SPI2, TxData); //Send a byte data through peripheral SPIx
|
||||
|
||||
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET){} //Wait to receive a one byte
|
||||
|
||||
return SPI_I2S_ReceiveData(SPI2); //Returned by SPIx recently received data
|
||||
}
|
||||
|
||||
/*******************(C)COPYRIGHT 2021 Amogreentech *********END OF FILE********/
|
||||
36
USER/Ref/bmu-18s-firmware/HARDWARE/spi.h
Normal file
36
USER/Ref/bmu-18s-firmware/HARDWARE/spi.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* File Name : spi.h
|
||||
* Description : This file provides code for the configuration
|
||||
* of the SPI instances.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2021 Amogreentech Co., Ltd.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef _SPI_H_
|
||||
#define _SPI_H_
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include <stm32f10x.h>
|
||||
#include "sys.h"
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/* Exported define -----------------------------------------------------------*/
|
||||
/* Exported variables ------------------------------------------------------- */
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
|
||||
void SPI2_Init(void); // Initialize SPI1
|
||||
void SPI2_SetSpeed(u8 SpeedSet); // Set SPI1 speed
|
||||
u8 SPI2_ReadWriteByte(u8 TxData); // SPI1 bus read/write bytes
|
||||
|
||||
#endif /* _SPI_H_ */
|
||||
|
||||
/*******************(C)COPYRIGHT 2021 Amogreentech *********END OF FILE********/
|
||||
Reference in New Issue
Block a user