- /*******************************************************************************
- * Function Name : PD_PHY_ISR(void)
- * Description : PD中断处理函数
- * Input : None
- * Output : None
- * Return : None
- *******************************************************************************/
- void PD_PHY_ISR(void) interrupt INT_NO_USBPD using 1
- {
- /*接收到复位信息中断*/
- if ( PIF_RX_RST ) {
- PD_PHY_HRST_ISR(); //收到HRST
- PD_PHY_RX_INIT();
- }
- /*数据包接受完成中断*/
- if ( PIF_RX_ACT ){
- PIF_RX_ACT = 0;
- if ( (UPD_INT_FG & MASK_PD_STAT) == PD_RX_SOP0 ) { //收到HRST或SOP数据
- Union_Header = (_Union_Header *)PD_RX_BUF; //强制转化
- if ( PD_PHY_STAT.WaitingGoodCRC ) { //是否在等待GoodCRC
- if(Union_Header->HeaderStruct.MsgType == GoodCRC){ //判断收到的消息是否为GOODCRC
- PD_PHY_STAT.WaitingGoodCRC = 0;
- PD_PHY_Clear_Flag(); //清除标志函数
- PD_PROT_ISR();
- }
- }else {
- switch(Union_Header->HeaderStruct.MsgType)
- {
- case SourceCap:
- memcpy(PDO_BUF,PD_RX_BUF,sizeof(PD_RX_BUF));
- Versions = Union_Header->HeaderStruct.SpecRev;
- SourceCapNDO = Union_Header->HeaderStruct.NDO;
- RecvPDOFlag = 1; //修改RecvPDOFlag = 1 开启解析PDO,为0则关闭,若开启后本次回复GOODCRC时间会适当延长,此处默认开启
- PD_PHY_STAT.SendingRequest = 1;
- break;
- case Accept:
- break;
- case Reject:
- break;
- case PS_RDY:
- RecvPS_RDYFlag = 1;
- break;
- case GetSinkCap:
- MsgID++;
- PD_PHY_STAT.SendingSinkCap = 1;
- break;
- case SourceCap_VDM:
- MsgID++;
- PD_PHY_STAT.SendingNotSup = 1;
- break;
- default :
- break;
- }
- mDelayuS(10);
- PD_PHY_STAT.SendingGoodCRC = 1; //置发送GoodCRC标志位
- PD_PHY_TX_GoodCRC(); //回复GoodCRC
- }
- }else PD_PHY_RX_INIT();
- }
- /*数据包发送完成中断 */
- if ( PIF_TX_END ) {
- PIF_TX_END = 0;
- if(CCSel == 1){ //发送完成关闭低压
- CC1_CTRL &= ~bCC_LVO;
- }else if(CCSel == 2){
- CC2_CTRL &= ~bCC_LVO;
- }
- if ( PD_PHY_STAT.SendingGoodCRC ==1 ) {
- PD_PHY_STAT.SendingGoodCRC = 0;
- PD_PROT_ISR(); //GoodCRC发送完成,向Prot转交数据
- }else { /*开始接收GoodCRC*/
- PD_PHY_STAT.WaitingGoodCRC = 1;
- Timer_Counter = Save_Counter;
- PD_PHY_RX_INIT();
- }
- }
- }
本段用来解析Source支持PD协议的具体档位,发生在一次PD协商结束时,此时RecvPS_RDYFlag = 1,解析上述缓存在PDO_BUF中的SourceCap包,并显示在屏幕(后续会精简优化代码):
- /*******************************************************************************
- * Function Name : Analysis_PDO(void)
- * Description : 解析PDO、PPS函数
- * Input : None
- * Output : None
- * Return : None
- *******************************************************************************/
- void Analysis_PDO(void)
- {
- UINT8 Temp;
- UINT16 PDO_Value = 0;
- if(RecvPDOFlag == 1){
- LCD_Fill(0,0,159,12,CYAN);
- LCD_DrawLine(0,0,159,0,CYAN);
- LCD_DrawLine(0,0,0,127,CYAN);
- LCD_DrawLine(159,0,159,127,CYAN);
- LCD_DrawLine(0,127,159,127,CYAN);
- if(Versions == 2) //判断PD版本
- {
- LCD_ShowString(3,0,"Power Delivery 3.0",BLACK,CYAN,12,0);
- }else{
- LCD_ShowString(3,0,"Power Delivery 2.0",BLACK,CYAN,12,0);
- }
-
- Union_Header = (_Union_Header *)PDO_BUF; //解析SourceCap
- for(Temp=0;Temp<SourceCapNDO;Temp++)//pdo的档位
- {
- Union_SrcCap = (_Union_SrcCap*)(&PDO_BUF[2+(Temp*4)]);
- if((Union_SrcCap->SrcCapStruct.DataH8>>6)== 0x00) //表示固定档
- {
- PDO_Value =((((Union_SrcCap->SrcCapStruct.VoltH4<<6)+( Union_SrcCap->SrcCapStruct.VoltL6))*50)/100);
- if( PDO_Value/10 >= 10) //电压
- {
- LCD_ShowFloatNum1(108-7*6,(Temp+1)*12,(float)PDO_Value/10,4,CYAN,BLACK,12);
- }else{
- LCD_ShowFloatNum1(108-6*6,(Temp+1)*12,(float)PDO_Value/10,3,CYAN,BLACK,12);
- }
- PDO_Value=((((Union_SrcCap->SrcCapStruct.CurrentH2<<8)+( Union_SrcCap->SrcCapStruct.CurrentL8))*10)/10); //电流
- LCD_ShowFloatNum1(120,(Temp+1)*12,(float)PDO_Value/100,3,CYAN,BLACK,12);
-
- LCD_ShowString(108,(Temp+1)*12,"@",CYAN,BLACK,12,0);
- LCD_ShowString(3,(Temp+1)*12,"< > Fix",CYAN,BLACK,12,0);
- LCD_ShowIntNum(10,(Temp+1)*12,Temp+1,1,CYAN,BLACK,12);
- LCD_ShowString(108-2*6,(Temp+1)*12,"V",CYAN,BLACK,12,0);
- LCD_ShowString(145,(Temp+1)*12,"A",CYAN,BLACK,12,0);
-
- }else if((Union_SrcCap->SrcCapStruct.DataH8>>6)== 0x03){//表示PPS
- Union_PPS_SrcCap = (_Union_PPS_SrcCap*)(&PDO_BUF[2+(Temp*4)]); //转换为PPS
-
- PDO_Value = (Union_PPS_SrcCap->SRC_Cap_PPS_Struct.VoltMin);
- if(PDO_Value/10 >= 10)
- {
- LCD_ShowFloatNum1(111-10*6,(Temp+1)*12,(float)PDO_Value/10,4,CYAN,BLACK,12);
-
- }else{
- LCD_ShowFloatNum1(111-9*6,(Temp+1)*12,(float)PDO_Value/10,3,CYAN,BLACK,12);
- }
-
- PDO_Value = ((Union_PPS_SrcCap->SRC_Cap_PPS_Struct.VoltMaxH1<<7) + (Union_PPS_SrcCap->SRC_Cap_PPS_Struct.VoltMaxL7));
- LCD_ShowString(75,(Temp+1)*12,"-",CYAN,BLACK,12,0);
- if(PDO_Value/10 >= 10)
- {
- LCD_ShowFloatNum1(108-4*6,(Temp+1)*12,(float)PDO_Value/10,4,CYAN,BLACK,12);
- }else{
- LCD_ShowFloatNum1(108-3*6,(Temp+1)*12,(float)PDO_Value/10,3,CYAN,BLACK,12);
- }
- PDO_Value = ((Union_PPS_SrcCap->SRC_Cap_PPS_Struct.Current)*50)/10;
- LCD_ShowFloatNum1(120,(Temp+1)*12,(float)PDO_Value/100,3,CYAN,BLACK,12);
- LCD_ShowString(3,(Temp+1)*12,"< > PPS",CYAN,BLACK,12,0);
- LCD_ShowIntNum(10,(Temp+1)*12,Temp+1,1,CYAN,BLACK,12);
- LCD_ShowString(108,(Temp+1)*12,"V",CYAN,BLACK,12,0);
- LCD_ShowString(145,(Temp+1)*12,"A",CYAN,BLACK,12,0);
- }
- }
- LCD_ShowString(44,(Temp+2)*12-6,"Fixed",BLACK,CYAN,12,0);
- LCD_ShowString(92,(Temp+2)*12-6,"PPS",CYAN,BLACK,12,0);
- RecvPDOFlag = 0;
- }
- }
因A口协议属于未公开状态,本次将不进行讲解。有兴趣的小伙伴可以多了解一下,附送一张QC2.0的协议规范。
附件后续会上传,目前需要进行优化一些功能。