#include <
stm32f0xx_gpio.h
>
#include <
stm32f0xx_rcc.h
>
#include <
stm32f0xx_i2c.h
>
#include <
stm32f0xx.h
>
#include <
stm32f0xx_adc.h
>
#include <
stm32f0xx_exti.h
>
#include <
stm32f0xx_syscfg.h
>
#define BAT_PLUGIN_PIN GPIO_Pin_7
#define LI_CHARGE_STATUS_PIN GPIO_Pin_0
#define LI_BAT_OUT_STM_PIN GPIO_Pin_1
#define AC_ADAPT_STATUS_PIN GPIO_Pin_2
#define SMBUS_CLK_PIN GPIO_Pin_9
#define SMBUS_DATA_PIN GPIO_Pin_10
#define LI_CHRG_SHUTDOWN_PIN GPIO_Pin_5
#define LI_PRECHARGE_CHARGE_PIN GPIO_Pin_11 // 6 jauna , 7 vecajaa
#define BATTERY_STATUS_GOOD_LED GPIO_Pin_8
#define BATTERY_STATUS_BAD_LED GPIO_Pin_4
#define CHARGING_STATUS_LED GPIO_Pin_12
int m;
int x;
int ciklu_skaits;
unsigned int t;
unsigned int i;
int temp_mode;
unsigned char volt_A;
unsigned char volt_B;
float voltage;
int volti_desmiti;
int volti_vieni;
int volti_desmitdalas;
int volti_simtdalas;
int maska;
unsigned char cycle_A;
unsigned char cycle_B;
int cycle;
int cycle_1;
int cycle_2;
int cycle_3;
int cycle_4;
int cycle_5;
int aizture = 1;
int laiks;
unsigned char current_A;
unsigned char current_B;
float current;
int current_int;
int current_int_5;
int current_int_4;
int current_int_3;
int current_int_2;
int current_int_1;
uint32_t current_HEX;
int relative_SOC;
int SOC_desmiti;
int SOC_vieni;
unsigned char temp_A;
unsigned char temp_B;
float temp;
int temp_desmiti;
int temp_vieni;
int temp_desmitdalas;
int temp_simtdalas;
unsigned char time_to_full_A;
unsigned char time_to_full_B;
int time_to_full;
int time_to_full_5;
int time_to_full_4;
int time_to_full_3;
int time_to_full_2;
int time_to_full_1;
int time_to_empty;
unsigned char time_to_empty_A;
unsigned char time_to_empty_B;
int time_to_empty_5;
int time_to_empty_4;
int time_to_empty_3;
int time_to_empty_2;
int time_to_empty_1;
float dalitajs_10 = 10;
float dalitajs_100 = 100;
float dalitajs_1000 = 1000;
int current_mode;
// visi bija int a-dh
char a;
char ah;
char b;
char bh;
char c;
char ch;
char d;
char dh;
int plugin_time;
int state;
float LI_bat_node;
float LI_bat_adc_value;
void SMBUS_FLAG_BUSY() // when SMBus is busy nothing is being done, if it is busy too long then I2C is reseted
{
while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY))
{
t++; // vnk ; te bija bez nekaa
if (t == 100000)
{
RCC->APB1RSTR |= 0x200000; // resets i2c2 400000 , i2c1 200000
for (aizture = 1;aizture <
10000
;aizture++)
{
m++;
}
m
=
0
;
RCC->APB1RSTR &= 0xFFDFFFFF; // iesledz i2c2 FFBFFFFF
//I2C_TimeoutAConfig(I2C1, 0x63);// 0x61(TIDLE =0 , TIMEOUTEN=1) vai 0x63(TIDLE =1 , TIMEOUTEN=1)
//I2C_TimeoutBConfig(I2C1, 0x1F); // TEXTEN=1
}
}
t = 0;
}
void read_SMBus() // waits for message in SMBus , if nothing is being read for too long time, it breaks this waiting cycle
{
while (I2C_GetFlagStatus(I2C1, I2C_FLAG_RXNE) == 0)
{
i++;
if (i == 10000)
{
i = 0;
break;
}
}
i = 0;
}
void PIN_CONFIGURATION(void) // GPIO, I2C config
{
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure;
//RCC_ClocksTypeDef RCC_InitStructure;
EXTI_InitTypeDef EXTI_InitStruct;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
// reset i2c1
RCC->APB1RSTR |= 0x200000; // resets i2c2 400000 , i2c1 200000
for (aizture = 1;aizture <
10000
;aizture++)
{
m++;
}
m
=
0
;
RCC->APB1RSTR &= 0xFFDFFFFF; //
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
//OUTPUTI uz GPIOA
GPIO_InitStructure.GPIO_Pin = LI_PRECHARGE_CHARGE_PIN | BATTERY_STATUS_GOOD_LED | CHARGING_STATUS_LED;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// DIGITAL INPUTS GPIOA
GPIO_InitStructure.GPIO_Pin = BAT_PLUGIN_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// INTERUPTI PRIEKS BAT PLUGIN INPUTA
/* Tell system that you will use PA0 for EXTI_Line_0 */
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, BAT_PLUGIN_PIN); // EXTI_PinSource0 var rakstit BAT_PLUGIN_PIN
/* PA0 is connected to EXTI_Line0 */
EXTI_InitStruct.EXTI_Line = EXTI_Line7;
/* Enable interrupt */
EXTI_InitStruct.EXTI_LineCmd = ENABLE;
/* Interrupt mode */
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
/* Triggers on rising and falling edge */
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling;
/* Add to EXTI */
EXTI_Init(&EXTI_InitStruct);
NVIC_SetPriority(EXTI4_15_IRQn, 0);
NVIC_EnableIRQ(EXTI4_15_IRQn);
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_1;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_Pin = SMBUS_DATA_PIN;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = SMBUS_CLK_PIN;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure the I2C clock source. The clock is derived from the HSI */
RCC_I2CCLKConfig(RCC_I2C1CLK_SYSCLK);// vai HSI/ SYSCLK
/* AF - alternate function */
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_4); // vai SMBUS_DATA_PIN
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_4); // vai SMBUS_CLK_PIN
// I2C configuration
I2C_DeInit(I2C1);
I2C_Cmd(I2C1, DISABLE);
I2C_InitStructure.I2C_Timing = 0xB0420F13; //B0420F13 vai moshk sitā 0x00901D23
I2C_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Enable;// analogaistroksnu filtrs ieslegts
I2C_InitStructure.I2C_DigitalFilter = 0x00; // digitalais troksnu filtrs izslegts
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; // pec tam buus siten I2c uz SMBus modi janomaina
I2C_InitStructure.I2C_OwnAddress1 = 0x40;// kaa tiek izveeleeta adrese
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; // sitam jaabut bus ieslegtam ari tad kad SMBus buus laikam
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_Cmd(I2C1, ENABLE);
I2C_Init(I2C1, &I2C_InitStructure);
I2C_TimeoutAConfig(I2C1, 0x63);
I2C_TimeoutBConfig(I2C1, 0x1F);
}
extern "C"
{
void EXTI4_15_IRQHandler(void)
{
/* Make sure that interrupt flag is set */
if (EXTI_GetITStatus(EXTI_Line7) != RESET) {
/* Do your stuff when PA0 is changed */
while (state == 0)
{
if ((GPIOA->IDR & BAT_PLUGIN_PIN) == 0) // vai baterija ir piesprausta
{
plugin_time++;
}
if ((GPIOA->IDR & BAT_PLUGIN_PIN) != 0) // vai baterija ir norauta
{
plugin_time--;
}
if (plugin_time == 10000)
{
state = 1;
}
if (plugin_time == -10000)
{
state = 1;
current_mode = 2;
GPIOB->BRR = LI_CHRG_SHUTDOWN_PIN;
}
}
plugin_time = 0;
state = 0;
/*
for (delay_laiks = 1;delay_laiks <
100000
;delay_laiks++) // 0.25s
{
}
current_mode
=
2
;
*/
/* Clear interrupt flag */
EXTI_ClearITPendingBit(EXTI_Line7);
}
}
}
int main(void)
{
PIN_CONFIGURATION();
while (1)
{
GPIOA->BSRR = PRECHARGE_BULKCHARGE_PIN;
GPIOA->BSRR = CHARGER_SHUTDOWN_PIN;
while (1)
{
while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET)
;
LI_bat_adc_value = (ADC_GetConversionValue(ADC1));
LI_bat_node = (LI_bat_adc_value * 3.3) / 4096;
}
*/
while (1)
{
if ((GPIOA->IDR & BAT_PLUGIN_PIN) == 0) // parbauda vai baterija piesprausta
{
/// NOLASA NO BATERIJAS NEPIECIESAMOS DATUS/////
//////////////////////////// SPRIEGUMS //////////////////////////////
SMBUS_FLAG_BUSY();
I2C_TransferHandling(I2C1, 0x16, 1, I2C_SoftEnd_Mode, I2C_Generate_Start_Write);
//while ((I2C1->CR2 & 0x200) == 0x200) { ;}
//while (I2C_GetFlagStatus(I2C1, I2C_FLAG_TXE) == 0) {;}
I2C_SendData(I2C1, 0x9);
I2C_ExtendedClockTimeoutCmd(I2C1, ENABLE);
SMBUS_FLAG_BUSY();
//while (I2C_GetFlagStatus(I2C1, I2C_FLAG_TXE) == 0) { ;}
I2C_TransferHandling(I2C1, 0x16, 2, I2C_SoftEnd_Mode, I2C_Generate_Start_Read);
//while ((I2C1->CR2 & 0x200) == 0x200) {;}
I2C_SlaveByteControlCmd(I2C1, ENABLE);// In order to allow byte ACK control in slave reception mode, Slave Byte Control mode must be enabled by setting the SBC bit in the I2C_CR1 register. This is required to be compliant with SMBus standards.
while (I2C_GetFlagStatus(I2C1, I2C_FLAG_RXNE) == 0) // tas pats kas read_SMBus, bet pievienots klaa tas ka vertibas tiek nomestas uz 0. nomeshanu uz 0 var likt 1 funkcijaa, jo izies cauri visiem while loopiem tapat
{
i++;
if (i == 10000)
{
i = 0;
volt_A = 0;
volt_B = 0;
temp_A = 0;
temp_B = 0;
temp = 0;
relative_SOC = 0;
time_to_full_A = 0;
time_to_full_B = 0;
time_to_empty_A = 0;
time_to_empty_B = 0;
current_A = 0;
current_B = 0;
cycle_A = 0;
cycle_B = 0;
break;
}
}
i = 0;
volt_A = I2C_ReceiveData(I2C1);
read_SMBus();
volt_B = I2C_ReceiveData(I2C1);
//////////////////////////////// TEMPERATURA ///////////////////////////////
SMBUS_FLAG_BUSY();
I2C_TransferHandling(I2C1, 0x16, 1, I2C_SoftEnd_Mode, I2C_Generate_Start_Write);
//while ((I2C1->CR2 & 0x200) == 0x200) { ;}
//while (I2C_GetFlagStatus(I2C1, I2C_FLAG_TXE) == 0) { ;}
I2C_SendData(I2C1, 0x8);
I2C_ExtendedClockTimeoutCmd(I2C1, ENABLE);
SMBUS_FLAG_BUSY();
//while (I2C_GetFlagStatus(I2C1, I2C_FLAG_TXE) == 0) { ;}
I2C_TransferHandling(I2C1, 0x16, 2, I2C_SoftEnd_Mode, I2C_Generate_Start_Read);
//while ((I2C1->CR2 & 0x200) == 0x200) { ;}
I2C_SlaveByteControlCmd(I2C1, ENABLE);// In order to allow byte ACK control in slave reception mode, Slave Byte Control mode must be enabled by setting the SBC bit in the I2C_CR1 register. This is required to be compliant with SMBus standards.
read_SMBus();
temp_A = I2C_ReceiveData(I2C1);
read_SMBus();
temp_B = I2C_ReceiveData(I2C1);
///////////////////////////////// STATE OF CHARGE ////////////////
SMBUS_FLAG_BUSY();
I2C_TransferHandling(I2C1, 0x16, 1, I2C_SoftEnd_Mode, I2C_Generate_Start_Write);
//while ((I2C1->CR2 & 0x200) == 0x200) { ;}
//while (I2C_GetFlagStatus(I2C1, I2C_FLAG_TXE) == 0) { ;}
I2C_SendData(I2C1, 0x0d);
I2C_ExtendedClockTimeoutCmd(I2C1, ENABLE);
SMBUS_FLAG_BUSY();
// while (I2C_GetFlagStatus(I2C1, I2C_FLAG_TXE) == 0) { ;}
I2C_TransferHandling(I2C1, 0x16, 1, I2C_SoftEnd_Mode, I2C_Generate_Start_Read);
//while ((I2C1->CR2 & 0x200) == 0x200) {;}
I2C_SlaveByteControlCmd(I2C1, ENABLE);// In order to allow byte ACK control in slave reception mode, Slave Byte Control mode must be enabled by setting the SBC bit in the I2C_CR1 register. This is required to be compliant with SMBus standards.
read_SMBus();
relative_SOC = I2C_ReceiveData(I2C1);
//////////////////////////// current //////////////////////////////
SMBUS_FLAG_BUSY();
I2C_TransferHandling(I2C1, 0x16, 1, I2C_SoftEnd_Mode, I2C_Generate_Start_Write);
//while ((I2C1->CR2 & 0x200) == 0x200) {;}
//while (I2C_GetFlagStatus(I2C1, I2C_FLAG_TXE) == 0) { ;}
I2C_SendData(I2C1, 0x0a);
I2C_ExtendedClockTimeoutCmd(I2C1, ENABLE);
SMBUS_FLAG_BUSY();
//while (I2C_GetFlagStatus(I2C1, I2C_FLAG_TXE) == 0) {;}
I2C_TransferHandling(I2C1, 0x16, 2, I2C_SoftEnd_Mode, I2C_Generate_Start_Read);
//while ((I2C1->CR2 & 0x200) == 0x200) { ;}
I2C_SlaveByteControlCmd(I2C1, ENABLE);// In order to allow byte ACK control in slave reception mode, Slave Byte Control mode must be enabled by setting the SBC bit in the I2C_CR1 register. This is required to be compliant with SMBus standards.
read_SMBus();
current_A = I2C_ReceiveData(I2C1);
read_SMBus();
current_B = I2C_ReceiveData(I2C1);
//////////////////////////// cycle count //////////////////////////////
SMBUS_FLAG_BUSY();
I2C_TransferHandling(I2C1, 0x16, 1, I2C_SoftEnd_Mode, I2C_Generate_Start_Write);
//while ((I2C1->CR2 & 0x200) == 0x200) {;}
//while (I2C_GetFlagStatus(I2C1, I2C_FLAG_TXE) == 0) {;}
I2C_SendData(I2C1, 0x17);
I2C_ExtendedClockTimeoutCmd(I2C1, ENABLE);
SMBUS_FLAG_BUSY();
//while (I2C_GetFlagStatus(I2C1, I2C_FLAG_TXE) == 0) {;}
I2C_TransferHandling(I2C1, 0x16, 2, I2C_SoftEnd_Mode, I2C_Generate_Start_Read);
//while ((I2C1->CR2 & 0x200) == 0x200) {;}
I2C_SlaveByteControlCmd(I2C1, ENABLE);// In order to allow byte ACK control in slave reception mode, Slave Byte Control mode must be enabled by setting the SBC bit in the I2C_CR1 register. This is required to be compliant with SMBus standards.
read_SMBus();
cycle_A = I2C_ReceiveData(I2C1);
read_SMBus();
cycle_B = I2C_ReceiveData(I2C1);
}
else
{
GPIOB->BRR = LI_CHRG_SHUTDOWN_PIN; // izsleedz chargeri
current_mode = 2; // unplugged mode
// Nav piesprausta baterija, deg sarkans LEDs
GPIOA->BRR = BATTERY_STATUS_GOOD_LED;
GPIOB->BSRR = BATTERY_STATUS_BAD_LED;
GPIOA->BSRR = CHARGING_STATUS_LED;
}
}
}