302 lines
8.4 KiB
C
302 lines
8.4 KiB
C
/********************************** (C) COPYRIGHT *******************************
|
|
* File Name : CH223.c
|
|
* Author : WCH
|
|
* Version : V1.0.1
|
|
* Date : 2025/10/27
|
|
* Description : This file provides all the CH223 functions
|
|
*********************************************************************************
|
|
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
|
* Attention: This software (modified or not) and binary are used for
|
|
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
|
*******************************************************************************/
|
|
|
|
/******************************************************************************/
|
|
#include "debug.h"
|
|
#include "CH223.h"
|
|
#include "string.h"
|
|
|
|
u32 Buffer[7] = {0};//NDO raw data in SRCCAP
|
|
u16 BufferV[SIZE] = {0};//Analyzing voltage data in SRCCAP
|
|
u16 BufferI[SIZE] = {0};//Analyzing Current Data in SRCCAP
|
|
u16 BufferVPPS[SIZE] = {0};//Parsing PPS data in SRCCAP
|
|
|
|
/*********************************************************************
|
|
* @fn IIC_Init
|
|
*
|
|
* @brief Initializes the IIC peripheral.
|
|
*
|
|
* PB11------SDA
|
|
* PB10------SCL
|
|
*
|
|
* @return none
|
|
*/
|
|
void IIC_Init(u32 bound, u16 address)
|
|
{
|
|
GPIO_InitTypeDef GPIO_InitStructure={0};
|
|
I2C_InitTypeDef I2C_InitTSturcture={0};
|
|
|
|
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE );
|
|
RCC_APB1PeriphClockCmd( RCC_APB1Periph_I2C2, ENABLE );
|
|
|
|
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
|
|
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
|
|
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
|
GPIO_Init( GPIOB, &GPIO_InitStructure );
|
|
|
|
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
|
|
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
|
|
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
|
GPIO_Init( GPIOB, &GPIO_InitStructure );
|
|
|
|
I2C_InitTSturcture.I2C_ClockSpeed = bound;
|
|
I2C_InitTSturcture.I2C_Mode = I2C_Mode_I2C;
|
|
I2C_InitTSturcture.I2C_DutyCycle = I2C_DutyCycle_16_9;
|
|
I2C_InitTSturcture.I2C_OwnAddress1 = address;
|
|
I2C_InitTSturcture.I2C_Ack = I2C_Ack_Enable;
|
|
I2C_InitTSturcture.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
|
|
I2C_Init( I2C2, &I2C_InitTSturcture );
|
|
|
|
I2C_Cmd( I2C2, ENABLE );
|
|
}
|
|
|
|
/*********************************************************************
|
|
* @fn CH223_Init
|
|
*
|
|
* @brief Initializes CH223.
|
|
*
|
|
* @return none
|
|
*/
|
|
void CH223_Init()
|
|
{
|
|
IIC_Init(100000, 0XA0);
|
|
}
|
|
|
|
/*********************************************************************
|
|
* @fn CH223_ReadOneByte
|
|
*
|
|
* @brief Read one data from CH223.
|
|
*
|
|
* @param ReadAddr - Read frist address.
|
|
*
|
|
* @return temp - Read data.
|
|
*/
|
|
u8 CH223_ReadOneByte(u16 ReadAddr)
|
|
{
|
|
u8 temp = 0;
|
|
while( I2C_GetFlagStatus( I2C2, I2C_FLAG_BUSY ) != RESET )
|
|
{
|
|
|
|
}
|
|
I2C_GenerateSTART( I2C2, ENABLE );
|
|
while( !I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_MODE_SELECT ) );
|
|
|
|
I2C_Send7bitAddress( I2C2, 0X44, I2C_Direction_Transmitter );
|
|
|
|
while( !I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED ) );
|
|
|
|
#if (Address_Lenth == Address_8bit)
|
|
I2C_SendData( I2C2, (u8)(ReadAddr&0x00FF) );
|
|
while( !I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED ) );
|
|
|
|
#elif (Address_Lenth == Address_16bit)
|
|
I2C_SendData( I2C2, (u8)(ReadAddr>>8) );
|
|
while( !I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED ) );
|
|
|
|
I2C_SendData( I2C2, (u8)(ReadAddr&0x00FF) );
|
|
while( !I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED ) );
|
|
|
|
#endif
|
|
|
|
I2C_GenerateSTART( I2C2, ENABLE );
|
|
|
|
while( !I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_MODE_SELECT ) );
|
|
I2C_Send7bitAddress( I2C2, 0X45, I2C_Direction_Receiver );
|
|
|
|
while( !I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED ) );
|
|
while( I2C_GetFlagStatus( I2C2, I2C_FLAG_RXNE ) == RESET )
|
|
I2C_AcknowledgeConfig( I2C2, DISABLE );
|
|
|
|
temp = I2C_ReceiveData( I2C2 );
|
|
I2C_GenerateSTOP( I2C2, ENABLE );
|
|
|
|
return temp;
|
|
}
|
|
|
|
/*********************************************************************
|
|
* @fn CH223_WriteOneByte
|
|
*
|
|
* @brief Write one data to CH223.
|
|
*
|
|
* @param WriteAddr - Write frist address.
|
|
*
|
|
* @return DataToWrite - Write data.
|
|
*/
|
|
void CH223_WriteOneByte(u16 WriteAddr, u8 DataToWrite)
|
|
{
|
|
while( I2C_GetFlagStatus( I2C2, I2C_FLAG_BUSY ) != RESET );
|
|
I2C_GenerateSTART( I2C2, ENABLE );
|
|
|
|
while( !I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_MODE_SELECT ) );
|
|
I2C_Send7bitAddress( I2C2, 0X45, I2C_Direction_Transmitter );
|
|
|
|
while( !I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED ) );
|
|
|
|
#if (Address_Lenth == Address_8bit)
|
|
I2C_SendData( I2C2, (u8)(WriteAddr&0x00FF) );
|
|
while( !I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED ) );
|
|
|
|
#elif (Address_Lenth == Address_16bit)
|
|
I2C_SendData( I2C2, (u8)(WriteAddr>>8) );
|
|
while( !I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED ) );
|
|
|
|
I2C_SendData( I2C2, (u8)(WriteAddr&0x00FF) );
|
|
while( !I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED ) );
|
|
|
|
#endif
|
|
|
|
if( I2C_GetFlagStatus( I2C2, I2C_FLAG_TXE ) != RESET )
|
|
{
|
|
I2C_SendData( I2C2, DataToWrite );
|
|
}
|
|
|
|
while( !I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED ) );
|
|
I2C_GenerateSTOP( I2C2, ENABLE );
|
|
}
|
|
|
|
/*********************************************************************
|
|
* @fn CH223_Read
|
|
*
|
|
* @brief Read multiple data from CH223.
|
|
*
|
|
* @param ReadAddr - Read frist address.
|
|
* pBuffer - Read data.
|
|
* NumToRead - Data number.
|
|
*
|
|
* @return none
|
|
*/
|
|
void CH223_Read(u16 ReadAddr, u32 *pBuffer, u16 NumToRead)
|
|
{
|
|
u8 t = 0;
|
|
u32 temp[4] = {0};
|
|
u32 temp1 = 0;
|
|
|
|
while(NumToRead)
|
|
{
|
|
temp[4] = 0;
|
|
for (t = 0; t < 4; t++)
|
|
{
|
|
temp[t] = CH223_ReadOneByte(ReadAddr++);
|
|
}
|
|
temp1 = (temp[0] + (temp[1] << 8) + (temp[2] << 16) + (temp[3] << 24));
|
|
*pBuffer++=temp1;
|
|
NumToRead--;
|
|
}
|
|
}
|
|
|
|
/*********************************************************************
|
|
* @fn CH223_Write
|
|
*
|
|
* @brief Write multiple data to CH223.
|
|
*
|
|
* @param WriteAddr - Write frist address.
|
|
* pBuffer - Write data.
|
|
* NumToWrite - Data number.
|
|
*
|
|
* @return none
|
|
*/
|
|
void CH223_Write(u16 WriteAddr, u8 *pBuffer, u16 NumToWrite)
|
|
{
|
|
while(NumToWrite--)
|
|
{
|
|
CH223_WriteOneByte(WriteAddr, *pBuffer);
|
|
WriteAddr++;
|
|
pBuffer++;
|
|
Delay_Ms(2);
|
|
}
|
|
}
|
|
|
|
/*********************************************************************
|
|
* @fn Buffer_Change
|
|
*
|
|
* @brief Analysis of SRCCAP message
|
|
*
|
|
* @param buffer[] - NDO data.
|
|
* n - NDO_Number.
|
|
*
|
|
* @return none
|
|
*/
|
|
void Buffer_Change(u32 buffer[], int n)
|
|
{
|
|
int i = 0;
|
|
u32 tempV = 0, tempI = 0, tempVmax = 0;
|
|
for(i = 0; i < n; i++)
|
|
{
|
|
tempV = buffer[i];
|
|
tempI = buffer[i];
|
|
if((tempV & 0xC0000000) == 0)
|
|
{
|
|
tempV >>= 10;
|
|
tempV &= 0x03FF;
|
|
BufferV[i] = tempV * 0.5;
|
|
|
|
tempI &= 0x03FF;
|
|
BufferI[i] = tempI * 0.1;
|
|
}
|
|
else {
|
|
tempV >>= 8;
|
|
tempVmax = tempV >> 9;
|
|
tempV &= 0x00FF;
|
|
BufferV[i] = tempV * 1;
|
|
tempVmax &= 0x00FF;
|
|
BufferVPPS[i] = tempVmax * 1;
|
|
|
|
tempI &= 0x00FF;
|
|
BufferI[i] = tempI * 0.5;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*********************************************************************
|
|
* @fn Current_VI
|
|
*
|
|
* @brief Read and display the current output voltage value
|
|
*
|
|
* @param ndo_select - NDO_Select.
|
|
*
|
|
*
|
|
* @return none
|
|
*/
|
|
void Current_VI(u8 ndo_select)
|
|
{
|
|
u8 tempV = 0, tempI = 0;
|
|
u8 current[2];
|
|
tempV = BufferV[ndo_select] % 10;
|
|
current[0] = BufferV[ndo_select] / 10;
|
|
|
|
tempI = BufferI[ndo_select] % 10;
|
|
current[1] = BufferI[ndo_select] / 10;
|
|
|
|
printf("The current regulating voltage is: %d.%dV,%d.%dA\t\r\n", current[0], tempV, current[1], tempI);
|
|
}
|
|
|
|
/*********************************************************************
|
|
* @fn User_Set_VI
|
|
*
|
|
* @brief Set VBUS voltage
|
|
*
|
|
* @param TargetData - Target voltage value.
|
|
* VBUS voltage=TargetData*200mv
|
|
*
|
|
* @return none
|
|
*/
|
|
void User_Set_VI(u8 TargetData)
|
|
{
|
|
u8 ndo_select = 0, state_flag = 0;
|
|
CH223_WriteOneByte(0xB6, TargetData);
|
|
Delay_Ms(5000);
|
|
state_flag = CH223_ReadOneByte(0xB5);
|
|
ndo_select = (state_flag >> 3) & 0x07;
|
|
printf("nod_select_user-->%d\r\n",ndo_select);
|
|
Current_VI(ndo_select - 1);
|
|
}
|