[范例教程]

【M0】 MG32F02A 学习笔记 21 CRC校验

[复制链接]
1360|2
手机看帖
扫描二维码
随时随地手机跟帖
noctor|  楼主 | 2018-11-29 10:36 | 显示全部楼层 |阅读模式
     上回我们说到了MG32F02A的IIC从机的使用。帖子详情:https://bbs.21ic.com/icview-2590026-1-1.html

      这次来讲一下我们MG32F02A特别好用的东西:硬件CRC校验
      CRC校验大家都知道,在欧洲的电器中必须使用CRC校验,而CRC校验的运算量很大,需要比较多的时间,而我们硬件逻辑处理器就有处理的能力,并且带有DMA功能,那就好呀,拿来直接用。

以下是携带了DMA功能的CRC校验功能代码:


#include "MG32x02z_DRV.H"
#include <stdio.h>


typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;

#define URTX URT0

#define GPL_InputDataEndian_LITTLE      GPL_CR0_BEND_EN_disable_w
#define GPL_InputDataEndian_BIG         GPL_CR0_BEND_EN_mask_w

#define IS_GPL_InputDataEndian_MODE(MODE)     (((MODE) == GPL_InputDataEndian_LITTLE) || \
                                               ((MODE) == GPL_InputDataEndian_BIG))



#define GPL_InputDataInverse_DISABLE    GPL_CR0_IN_INV_disable_w

#define GPL_InputDataInverse_ENABLE     GPL_CR0_IN_INV_mask_w

#define IS_GPL_InputDataInverse_MODE(MODE)    (((MODE) == GPL_InputDataInverse_ENABLE) || \
                                               ((MODE) == GPL_InputDataInverse_DISABLE))


#define GPL_InputDataReverse_NONE       GPL_CR0_BREV_MDS_disable_w
#define GPL_InputDataReverse_BYTE       GPL_CR0_BREV_MDS_8bit_w
#define GPL_InputDataReverse_HALFWORD   GPL_CR0_BREV_MDS_16bit_w
#define GPL_InputDataReverse_WORD       GPL_CR0_BREV_MDS_32bit_w

#define IS_GPL_InputDataReverse_MODE(MODE)    (((MODE) == GPL_InputDataReverse_NONE) || \
                                               ((MODE) == GPL_InputDataReverse_BYTE) || \
                                               ((MODE) == GPL_InputDataReverse_HALFWORD) || \
                                               ((MODE) == GPL_InputDataReverse_WORD))



#define GPL_OutputDataReverse_NONE      GPL_CR1_CRC_BREV_disable_w
#define GPL_OutputDataReverse_BYTE      GPL_CR1_CRC_BREV_8bit_w
#define GPL_OutputDataReverse_HALFWORD  GPL_CR1_CRC_BREV_16bit_w
#define GPL_OutputDataReverse_WORD      GPL_CR1_CRC_BREV_32bit_w

#define IS_GPL_OutputDataReverse_MODE(MODE)    (((MODE) == GPL_OutputDataReverse_NONE) || \
                                                ((MODE) == GPL_OutputDataReverse_BYTE) || \
                                                ((MODE) == GPL_OutputDataReverse_HALFWORD) || \
                                                ((MODE) == GPL_OutputDataReverse_WORD))



#define GPL_CRC_Polynomial_0x1021       GPL_CR1_CRC_MDS_ccitt16_w
#define GPL_CRC_Polynomial_0x07         GPL_CR1_CRC_MDS_crc8_w
#define GPL_CRC_Polynomial_0x8005       GPL_CR1_CRC_MDS_crc16_w
#define GPL_CRC_Polynomial_0x4C11DB7    GPL_CR1_CRC_MDS_crc32_w

#define IS_GPL_CRC_Polynomial_MODE(MODE)    (((MODE) == GPL_CRC_Polynomial_0x1021) || \
                                             ((MODE) == GPL_CRC_Polynomial_0x07) || \
                                             ((MODE) == GPL_CRC_Polynomial_0x8005) || \
                                             ((MODE) == GPL_CRC_Polynomial_0x4C11DB7))



#define GPL_CRC_InputDataWidth_8bit     GPL_CR1_CRC_DSIZE_8bit_w
#define GPL_CRC_InputDataWidth_16bi     GPL_CR1_CRC_DSIZE_16bit_w
#define GPL_CRC_InputDataWidth_32bit    GPL_CR1_CRC_DSIZE_32bit_w

#define IS_GPL_CRC_InputDataWidth_MODE(MODE)    (((MODE) == GPL_CRC_InputDataWidth_8bit) || \
                                                 ((MODE) == GPL_CRC_InputDataWidth_16bi) || \
                                                 ((MODE) == GPL_CRC_InputDataWidth_32bit))

#define CRC_8                                                                                                         0
#define CRC_8_ITU                                                                                         1
#define CRC_8_ROHC                                                                                        2
#define CRC16_BUYPASS                                                                         3
#define CRC16_ARC                                                                                         4
#define CRC16_MAXIM                                                                                 5
#define CRC16_DDS110                                                                                 6
#define CRC16_CMS                                                                                         7
#define CRC16_USB                                                                                         8
#define CRC16_MODBUS                                                                                 9
#define CRC16_XMODEM                                                                                 10
#define CRC16_GSM                                                                                         11
#define CRC16_KERMIT                                                                                 12
#define CRC16_AUG_CCITT                                                                 13
#define CRC16_TMS37157                                                                         14
#define CRC16_RIELLO                                                                                 15
#define CRC16_A                                                                                                 16
#define CRC16_CCITT_FALSE                                                         17
#define CRC16_GENIBUS                                                                         18
#define CRC16_MCRF4XX                                                                         19
#define CRC16_X25                                                                                         20
#define CRC32_POSIX                                                                                 21
#define CRC32_MPEG2                                                                                 22
#define CRC32                                                                                                         23
#define CRC32_BZIP2                                                                                 24
#define CRC32_JAMCRC                                                                                 25

typedef struct{
    uint32_t InputDataInverse;
    uint32_t InputDataEndian;
    uint32_t InputDataReverse;
    uint32_t CRC_Polynomial;
    uint32_t CRC_InputDataWidth;
    uint32_t OutputDataReverse;
    uint32_t CRC_InitialValue;
                uint32_t CRC_Type;
}GPL_CRC_InitTypedef;



void GPL_CRC_Config(GPL_CRC_InitTypedef * GPL_CRC)
{
    GPL->CR1.W = 0;
    GPL->CR0.W = 0;
    GPL->DIN.W = 0;
    GPL->CR0.W = GPL_CRC->InputDataInverse |
                 GPL_CRC->InputDataEndian |
                 GPL_CRC->InputDataReverse;

    GPL->CRCINIT.W = GPL_CRC->CRC_InitialValue;

    GPL->CR1.W = GPL_CRC->CRC_Polynomial |
                 GPL_CRC->CRC_InputDataWidth |
                 GPL_CRC->OutputDataReverse;

    GPL->CR1.B[0] |= GPL_CR1_CRC_EN_mask_b0;   
}


uint8_t DataPattern[] = {0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39};//


void CSC_Init (void)
{
        CSC_PLL_TyprDef CSC_PLL_CFG;
   
  UnProtectModuleReg(MEMprotect);             // Setting flash wait state
  MEM_SetFlashWaitState(MEM_FWAIT_ONE);        // 50MHz> Sysclk >=25MHz
  ProtectModuleReg(MEMprotect);

  UnProtectModuleReg(CSCprotect);
        CSC_CK_APB_Divider_Select(APB_DIV_1);        // Modify CK_APB divider        APB=CK_MAIN/1
        CSC_CK_AHB_Divider_Select(AHB_DIV_1);        // Modify CK_AHB divider        AHB=APB/1

       
        /* CK_HS selection */
        CSC_IHRCO_Select(IHRCO_12MHz);                        // IHRCO Sel 12MHz
        CSC_IHRCO_Cmd(ENABLE);
        while(CSC_GetSingleFlagStatus(CSC_IHRCOF) == DRV_Normal);
        CSC_ClearFlag(CSC_IHRCOF);
        CSC_CK_HS_Select(HS_CK_IHRCO);                        // CK_HS select IHRCO


        /* PLL */
        /**********************************************************/
        CSC_PLL_CFG.InputDivider=PLLI_DIV_2;        // 12M/2=6M
        CSC_PLL_CFG.Multiplication=PLLIx16;                // 6M*16=96M
        CSC_PLL_CFG.OutputDivider=PLLO_DIV_2;        // PLLO=96M/2=48M
        CSC_PLL_Config(&CSC_PLL_CFG);
        CSC_PLL_Cmd(ENABLE);
        while(CSC_GetSingleFlagStatus(CSC_PLLF) == DRV_Normal);
        CSC_ClearFlag(CSC_PLLF);
        /**********************************************************/

       
        /* CK_MAIN */
        CSC_CK_MAIN_Select(MAIN_CK_HS);       


        /* Configure ICKO function */
               
        /* Configure peripheral clock */
        CSC_PeriphProcessClockSource_Config(CSC_I2C0_CKS, CK_APB);
        CSC_PeriphProcessClockSource_Config(CSC_UART0_CKS, CK_APB);
        CSC_PeriphOnModeClock_Config(CSC_ON_GPL,ENABLE);
        CSC_PeriphOnModeClock_Config(CSC_ON_UART0,ENABLE);
        CSC_PeriphOnModeClock_Config(CSC_ON_DMA,ENABLE);
        CSC_PeriphOnModeClock_Config(CSC_ON_PortB,ENABLE);
        CSC_PeriphOnModeClock_Config(CSC_ON_PortE,ENABLE);
       
       
  ProtectModuleReg(CSCprotect);
   
}

void Sample_URT0_Init(void)
{
    URT_BRG_TypeDef  URT_BRG;
    URT_Data_TypeDef DataDef;
            PIN_InitTypeDef PINX_InitStruct;
    //==Set CSC init
    //MG32x02z_CSC_Init.h(Configuration Wizard)
    //Select CK_HS source = CK_IHRCO
    //Select IHRCO = 11.0592M
    //Select CK_MAIN Source = CK_HS
    //Configure PLL->Select APB Prescaler = CK_MAIN/1
    //Configure Peripheral On Mode Clock->Port B/URT0 = Enable
    //Configure Peripheral On Mode Clock->URT0->Select URT0_PR Source = CK_APB(11.0592)
   
    //==Set GPIO init
    //MG32x02z_GPIO_Init.h(Configuration Wizard)->Use GPIOB->Pin8/9
    //GPIO port initial is 0xFFFF
    //Pin8 mode is PPO/Pin9 mode is ODO
    //Pin8/9 pull-up resister Enable
    //Pin8/9 function URT0_TX/RX
  PINX_InitStruct.PINX_Mode                                 = PINX_Mode_PushPull_O;                  // Pin select Push Pull mode
        PINX_InitStruct.PINX_PUResistant                 = PINX_PUResistant_Enable;          // Enable pull up resistor
        PINX_InitStruct.PINX_Speed                                   = PINX_Speed_Low;                         
        PINX_InitStruct.PINX_OUTDrive                         = PINX_OUTDrive_Level0;                 // Pin output driver full strength.
        PINX_InitStruct.PINX_FilterDivider                   = PINX_FilterDivider_Bypass;        // Pin input deglitch filter clock divider bypass
        PINX_InitStruct.PINX_Inverse                         = PINX_Inverse_Disable;                 // Pin input data not inverse
        PINX_InitStruct.PINX_Alternate_Function  = 3;                                // Pin AFS = URT0_TX
        GPIO_PinMode_Config(PINB(8),&PINX_InitStruct);                                                          // TXD at PB8

        PINX_InitStruct.PINX_Mode                                 = PINX_Mode_OpenDrain_O;                 // Pin select Open Drain mode
        PINX_InitStruct.PINX_Alternate_Function  = 3;                                // Pin AFS = URT0_RX
        GPIO_PinMode_Config(PINB(9),&PINX_InitStruct);                                                          // RXD at PB9  
       
       
   
    //=====Set Clock=====//
    //---Set BaudRate---//
    URT_BRG.URT_InteranlClockSource = URT_BDClock_PROC;
    URT_BRG.URT_BaudRateMode = URT_BDMode_Separated;
    URT_BRG.URT_PrescalerCounterReload = 0;                        //Set PSR
    URT_BRG.URT_BaudRateCounterReload = 3;                        //Set RLR
    URT_BaudRateGenerator_Config(URTX, &URT_BRG);                    //BR115200 = f(CK_URTx)/(PSR+1)/(RLR+1)/(OS_NUM+1)
    URT_BaudRateGenerator_Cmd(URTX, ENABLE);                    //Enable BaudRateGenerator
    //---TX/RX Clock---//
    URT_TXClockSource_Select(URTX, URT_TXClock_Internal);        //URT_TX use BaudRateGenerator
    URT_RXClockSource_Select(URTX, URT_RXClock_Internal);        //URT_RX use BaudRateGenerator
    URT_TXOverSamplingSampleNumber_Select(URTX, 25);                //Set TX OS_NUM
    URT_RXOverSamplingSampleNumber_Select(URTX, 25);                //Set RX OS_NUM
    URT_RXOverSamplingMode_Select(URTX, URT_RXSMP_3TIME);
    URT_TX_Cmd(URTX, ENABLE);                                    //Enable TX
    URT_RX_Cmd(URTX, ENABLE);                                    //Enable RX
   
   

    //=====Set Mode=====//
    //---Set Data character config---//
    DataDef.URT_TX_DataLength  = URT_DataLength_8;
    DataDef.URT_RX_DataLength  = URT_DataLength_8;
    DataDef.URT_TX_DataOrder   = URT_DataTyped_LSB;
    DataDef.URT_RX_DataOrder   = URT_DataTyped_LSB;
    DataDef.URT_TX_Parity      = URT_Parity_No;
    DataDef.URT_RX_Parity      = URT_Parity_No;
    DataDef.URT_TX_StopBits    = URT_StopBits_1_0;
    DataDef.URT_RX_StopBits    = URT_StopBits_1_0;
    DataDef.URT_TX_DataInverse = DISABLE;
    DataDef.URT_RX_DataInverse = DISABLE;
    URT_DataCharacter_Config(URTX, &DataDef);
    //---Set Mode Select---//
    URT_Mode_Select(URTX, URT_URT_mode);
    //---Set DataLine Select---//
    URT_DataLine_Select(URTX, URT_DataLine_2);
   
    //=====Set Error Control=====//
    // to do...
   
    //=====Set Bus Status Detect Control=====//
    // to do...
   
    //=====Set Data Control=====//
    URT_RXShadowBufferThreshold_Select(URTX, URT_RXTH_1BYTE);
    URT_IdlehandleMode_Select(URTX, URT_IDLEMode_No);
    URT_TXGaudTime_Select(URTX, 0);
   
    //=====Enable URT Interrupt=====//
    URT_IT_Cmd(URTX, URT_IT_RX, ENABLE);
    URT_ITEA_Cmd(URTX, ENABLE);
    NVIC_EnableIRQ(URT0_IRQn);

    //=====Enable URT=====//
    URT_Cmd(URTX, ENABLE);
               
        //==See MG32x02z_URT0_IRQ.c when interrupt in
}

int fputc(int ch,FILE *f)
{
       
        URT_SetTXData(URTX,1,ch);
        while(URT_GetITSingleFlagStatus(URTX,URT_IT_TC)==DRV_UnHappened);
        URT_ClearITFlag(URTX,URT_IT_TC);
       
        return ch;
}

void UartSendByte(int ch)
{
       
        URT_SetTXData(URTX,1,ch);
        while(URT_GetITSingleFlagStatus(URTX,URT_IT_TC)==DRV_UnHappened);
        URT_ClearITFlag(URTX,URT_IT_TC);
       
}

void DMA_Init(void)
{
         DMA_BaseInitTypeDef DMATestPattern;

    // ------------------------------------------------------------------------
    // 1.Enable DMA
    DMA_Cmd(ENABLE);
   
    // ------------------------------------------------------------------------
    // 2.Enable Channel0
    DMA_Channel_Cmd(DMAChannel0, ENABLE);
   
    // ------------------------------------------------------------------------
    DMA_BaseInitStructure_Init(&DMATestPattern);
   
    // 3.initial & modify parameter
      
        // DMA channel select
        DMATestPattern.DMAChx = DMAChannel0;
        
        // channel x source/destination auto increase address
        DMATestPattern.SrcSINCSel = ENABLE;
        DMATestPattern.DestDINCSel = DISABLE;
        
        // DMA source peripheral config
        DMATestPattern.SrcSymSel = DMA_MEM_Read;
        
        // DMA destination peripheral config
        DMATestPattern.DestSymSel = DMA_GPL_Write;
        
        // DMA Burst size config
        DMATestPattern.BurstDataSize = DMA_BurstSize_1Byte;
        
        // DMA transfer data count initial number
        DMATestPattern.DMATransferNUM = 9;
   
        // source/destination config
        DMATestPattern.DMASourceAddr = &DataPattern;
//                                DMATestPattern.DMADestinationAddr = &GPL->DIN;
                               
                                DMA_Channel_Cmd(DMAChannel0, ENABLE);
                                DMA_Base_Init(&DMATestPattern);
}

void GPL_CRC_Check(void)
{
                GPL_CRC_InitTypedef lGPL_CRC;
       
                lGPL_CRC.CRC_Type = CRC32_POSIX; //Select type of CRC you want.
       
                switch(lGPL_CRC.CRC_Type)
                {
                        case CRC_8:// width=8 poly=0x07 init=0x00 refin=false refout=false xorout=0x00 check=0xf4 residue=0x00 name="CRC-8"
                                                        lGPL_CRC.InputDataInverse = GPL_InputDataInverse_DISABLE;
                                                        lGPL_CRC.InputDataEndian = GPL_InputDataEndian_LITTLE;
                                                        lGPL_CRC.InputDataReverse = GPL_InputDataReverse_NONE;
                                                        lGPL_CRC.CRC_InitialValue = 0UL;
                                                        lGPL_CRC.CRC_InputDataWidth = GPL_CRC_InputDataWidth_8bit;
                                                        lGPL_CRC.CRC_Polynomial = GPL_CRC_Polynomial_0x07;
                                                        lGPL_CRC.OutputDataReverse = GPL_OutputDataReverse_NONE;
                                                        GPL_CRC_Config(&lGPL_CRC);

/*                                                        lCount = 0;
                                                        do{
                                                                        GPL->DIN.B[0] = DataPattern[lCount];
                                                        }while(++ lCount < 9);
*/
                                                       
                                                        GPL_DMAN_Cmd(ENABLE);
                                                  while (DMA_GetSingleFlagStatus(DMA, DMA_FLAG_CH0_TCF) == DRV_UnHappened);
                                                        DMA_ClearFlag(DMA, DMA_FLAG_CH0_TCF);

                                                        if(GPL->DOUT.B[0] != 0xF4)
                                                                        printf("Error CRC8 0x07 not equal is 0xF4, Now is 0x%2X Fail.\n\r", GPL->DOUT.B[0]);
                                                        else
                                                                        printf("Error CRC8 0x07 Check OK\n\r");
                                                        break;
                                                       
                        case CRC_8_ITU:// width=8 poly=0x07 init=0x00 refin=false refout=false xorout=0x55 check=0xa1 residue=0xac name="CRC-8/ITU"
                                                        lGPL_CRC.InputDataInverse = GPL_InputDataInverse_DISABLE;
                                                        lGPL_CRC.InputDataEndian = GPL_InputDataEndian_LITTLE;
                                                        lGPL_CRC.InputDataReverse = GPL_InputDataReverse_NONE;
                                                        lGPL_CRC.CRC_InitialValue = 0UL;
                                                        lGPL_CRC.CRC_InputDataWidth = GPL_CRC_InputDataWidth_8bit;
                                                        lGPL_CRC.CRC_Polynomial = GPL_CRC_Polynomial_0x07;
                                                        lGPL_CRC.OutputDataReverse = GPL_OutputDataReverse_NONE;
                                                        GPL_CRC_Config(&lGPL_CRC);

/*                                                        lCount = 0;
                                                        do{
                                                                        GPL->DIN.B[0] = DataPattern[lCount];
                                                        }while(++ lCount < 9);
*/
                                                        GPL_DMAN_Cmd(ENABLE);
                                                  while (DMA_GetSingleFlagStatus(DMA, DMA_FLAG_CH0_TCF) == DRV_UnHappened);
                                                        DMA_ClearFlag(DMA, DMA_FLAG_CH0_TCF);
                                                       
                                                        if((GPL->DOUT.B[0] ^ 0x55) != 0xA1)
                                                                        printf("Error CRC8 0x07 ITU not equal is 0xA1, Now is 0x%2X Fail.\n\r", (GPL->DOUT.B[0] ^ 0x55));  
                                                        else
                                                                        printf("Error CRC8 0x07 ITU Check OK\n\r");
                                                        break;

                        case CRC32_JAMCRC:// width=32 poly=0x04c11db7 init=0xffffffff refin=true refout=true xorout=0x00000000 check=0x340bc6d9 residue=0x00000000 name="JAMCRC"
                                                        lGPL_CRC.InputDataInverse = GPL_InputDataInverse_DISABLE;
                                                        lGPL_CRC.InputDataEndian = GPL_InputDataEndian_LITTLE;
                                                        lGPL_CRC.CRC_InputDataWidth = GPL_CRC_InputDataWidth_8bit;
                                                        lGPL_CRC.CRC_Polynomial = GPL_CRC_Polynomial_0x4C11DB7;
                                                        lGPL_CRC.CRC_InitialValue = 0xFFFFFFFFUL;
                                                        lGPL_CRC.InputDataReverse = GPL_InputDataReverse_BYTE;
                                                        lGPL_CRC.OutputDataReverse = GPL_OutputDataReverse_WORD;
                                                        GPL_CRC_Config(&lGPL_CRC);

                                        /*    lCount = 0;
                                                        do{
                                                                        GPL->DIN.B[0] = DataPattern[lCount];
                                                        }while(++ lCount < 9);
                                        */
                                                               
                                                        GPL_DMAN_Cmd(ENABLE);
                                                  while (DMA_GetSingleFlagStatus(DMA, DMA_FLAG_CH0_TCF) == DRV_UnHappened);
                                                        DMA_ClearFlag(DMA, DMA_FLAG_CH0_TCF);
                                                               
                                                        if((GPL->DOUT.W ^ 0x00000000) != 0x340BC6D9UL)
                                                                        printf("Error CRC32 0x04c11db7 JAMCRC not equal 0x340BC6D9, Now is 0x%8X Fail.\n\r", (GPL->DOUT.W ^ 0x00000000));                               
                                                        else
                                                                        printf("Error CRC32 0x04c11db7 JAMCRC Check OK\n\r");       
                                                        break;                                                                                               
                }

}


int main()
{

        PIN_InitTypeDef PINX_InitStruct;
        CSC_Init();
        PINX_InitStruct.PINX_Mode                                 = PINX_Mode_PushPull_O;          // Pin select digital input mode
        PINX_InitStruct.PINX_PUResistant                 = PINX_PUResistant_Enable;  // Enable pull up resistor
        PINX_InitStruct.PINX_Speed                                   = PINX_Speed_Low;                         
        PINX_InitStruct.PINX_OUTDrive                         = PINX_OUTDrive_Level0;         // Pin output driver full strength.
        PINX_InitStruct.PINX_FilterDivider                   = PINX_FilterDivider_Bypass;// Pin input deglitch filter clock divider bypass
        PINX_InitStruct.PINX_Inverse                         = PINX_Inverse_Disable;         // Pin input data not inverse
        PINX_InitStruct.PINX_Alternate_Function = 0;                                                 // Pin AFS = 0
        GPIO_PinMode_Config(PINE(15),&PINX_InitStruct);                                          // D6 setup at PE15
        Sample_URT0_Init();
        printf("hello\n");
        DMA_Init();
        DMA_ClearFlag(DMA, DMA_FLAG_CH0_TCF);
        DMA_StartRequest(DMAChannel0);
        GPL_CRC_Check();
        while(1);
}

        受帖子篇幅影响,我只贴出了几种CRC校验方案。
noctor|  楼主 | 2018-11-29 10:36 | 显示全部楼层
另外,我发现CRC的DMA驱动代码有误,需要进行以下修改才能使用DMA:
void GPL_DMA_Cmd(FunctionalState State)
{
    if(State == ENABLE)
       GPL->CR0.W |= GPL_DMA_ENABLE;// GPL->CR0.B[0] |= GPL_DMA_MASK;
    else
        GPL->CR0.W &= (~GPL_DMA_ENABLE);
}


然后GPL_DMA_ENABLE的定义应该是GPL_CR0_DMA_EN_mask_w 而不是GPL_CR0_DMA_EN_mask_b3

使用特权

评论回复
hotpower| | 2018-12-30 00:49 | 显示全部楼层

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

26

主题

82

帖子

3

粉丝