/******************************************************************************* * Copyright (C), 2000-2014, Sunsky Electronic Technology Co., Ltd. * 文件名: CCxx00_New.C * 作 者: 梁新平 * 版 本: * 日 期: 2014-5-26 * 说 明: * * * 修订历史: * * 1. 时间: 2014-5-26 * 修订者: 梁新平 * 修订内容: 创建 * 2. * 其它: *******************************************************************************/ #include "cc2500_1101.h" #include "platform.h" #include "function.h" #include "base_core_user.h" #if defined(CC1101) || defined(CC2500) //注意CC2500的CRC效验问题--CRCL=00时会指示CrcErr //PKTCTRL1=04,即WOR_AUTOSYNC=0,CRC_AUTOFLUSH=0,APPEND_STATUS=1,ADR_CHK=0 //PKTCTRL0=05,即WHITE_DATA=0,PKT_FORMAT=0 used fifo,CRC_EN=1,LENTH=variable //MCSM1=复位值0x30,即RXOFF_MODE和TXOFF_MODE均为IDLE, //但CCA_Mode=3 RSSI低而且没有在接收时才能从RX到TX状态,这是测试中1/10概率没有切换到TX状态的原因?改为0 //MDMCFG2从3改为0x13是由FSK转为GFSK模式,相对更好: //测试出现 按6.6版本76.8K设置时,近距离效果都不行,把FSK改为GFSK就好了 //MCSM0=0x18,即FS_AUTOCAL=Mode1 IDLE->TX,RX时校正 //2010.2.24屏蔽了接收时候直接bRcvOk=1 //2010.2.24可OEM定制无线同步码 //2010.4.8 //CC_PackStatus()读取CCA //MCSM1=复位值0x30 不再修改为0,使能CCA done //PKTLEN可以写少于64(原0xFF)避免FIFO溢出,虽然采用不定长包 done //使用CCA或CS必须要先RXON在接收状态?是的 CCA还必须使能CCA才能检测,CS不需要使能CCA //IOCFG2 设置为09可在GDO2脚看CCA信号输出 done //2010.4.16 //测试出CCA比接收完成慢1.7ms,CS载波检测能很快结束 //2010.4.24 //测试RX死机时候,状态还是1接收的,并不是RX溢出,但RXBUF为65字节,刚好比物理BUF多1字节 //重新IDLE再RXON可以退出死机状态,把PKTLEN限定为0x20可以提前结束错误包!!能避免RX死机的情况? //猜测是长度字节错误导致接收死机,因为GDO0脚一直为高(已经开始接收但没有结束) //CCA考虑检测时间,要计算发送时间,最末一个CCA后也能发送完整数据包 //因为Calibartion就要720us,及1ms后才能检测到CCA,或考虑去掉自动Calibration? //CCA的信号强度还可以设置AGCCTRL0-2 //存在能发射,但不能接收到情况?? //2010.5.12 433M增加修改了BAND2010配置高速无线通信 //2010.5.18 移植到M52时候,修正433M下的原文件,2.4G的配置并不对 --注意:CC_Init()中不同的无线中断打开不同 //5.19 加2.4G下新配置250K-Baud,MSK //2011.3 肖雪琦移植到STC平台下 //2011.4.9 pei修正sync0,sync1前面漏u8定义导致cc_init()中引导码不对 //2011.5.1 pei不使用SPI操作进行了测试,少许修改SPI1_ReadWriteByte() //注意:pei STC平台下,SPI操作,必须P1.6保持输出为高,MISO读入才能正确,或者通过P1M1干脆设置为输入 #define PAMAX 0xFE #define RSSI0 72 //Rssi Offset //#define PAMAX 0xFE #define PAMAX2 0xA9 //-4dBm #define PAMAX3 0x6E //-8dBm //#define PAMAX4 0xC6 //-12dBm #define PAMAX4 0x44 //-28dBm 配对时功率降低,最终使用了-28db的参数 //CC2500 BAND2010 // Chipcon // Product = CC2500 // Chip version = E (VERSION = 0x03) // Crystal accuracy = 10 ppm // X-tal frequency = 26 MHz // RF output power = 0 dBm // RX filterbandwidth = 541.666667 kHz // Phase = 0 // Datarate = 249.938965 kBaud // Modulation = (7) MSK // Manchester enable = (0) Manchester disabled // RF Frequency = 2401.999939 MHz // Channel spacing = 333.251953 kHz // Channel number = 0 // Optimization = Sensitivity // Sync mode = (3) 30/32 sync word bits detected // Format of RX/TX data = (0) Normal mode, use FIFOs for RX and TX // CRC operation = (1) CRC calculation in TX and CRC check in RX enabled // Forward Error Correction = (0) FEC disabled // Length configuration = (1) Variable length packets, packet length configured by the first received byte after sync word. // Packetlength = 255 // Preamble count = (2) 4 bytes // Append status = 1 // Address check = (0) No address check // FIFO autoflush = 0 // Device address = 0 // GDO0 signal selection = ( 6) Asserts when sync word has been sent / received, and de-asserts at the end of the packet // GDO2 signal selection = (41) CHIP_RDY static void DelayUs( unsigned short time ) { unsigned short i = 0; while( time-- ) { i = 6; //16M=2 while( i-- ) ; } } //等待芯片ready static void CC_Rdy(void) { unsigned char i; for (i=0;i<10;i++){ if (RF_READ ==0) return; DelayUs(20);// } } extern SPI_HandleTypeDef hspi1; static unsigned char SPI1_ReadWriteByte(unsigned char TxData) { // unsigned short retry=0; // while((SPI1->SR&1<<1)==0)// 等待发送空闲 ////while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET) // { // retry++; // if(retry>SPI1_BREAK)return 0; // } // SPI1->DR=TxData; //发送 // // retry=0; // while((SPI1->SR&1<<0)==0) //等待接收完成 ////while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET) // { // retry++; // if(retry>SPI1_BREAK)return 0; // } // return SPI1->DR; //返回接收到的数据 HAL_StatusTypeDef rlst; unsigned char rx_data; rlst =HAL_SPI_TransmitReceive(&hspi1,&TxData,&rx_data,1, 5); if(rlst == HAL_OK) return rx_data; else return 0; } //写命令 static unsigned char CC_Cmd(unsigned char Cmd) { unsigned char Status; RF_CS0; CC_Rdy(); Status=SPI1_ReadWriteByte(Cmd); RF_CS1; return Status; } //指定地址,写配置字 static unsigned char CC_WrReg(unsigned char Addr,unsigned char Data) { unsigned char Status; RF_CS0; CC_Rdy(); Status=SPI1_ReadWriteByte(Addr); SPI1_ReadWriteByte(Data); RF_CS1; return Status; } //指定地址,连续写配置 static unsigned char CC_WrRegs(unsigned char Addr,unsigned char *Buf,unsigned char Count) { unsigned char Status,i; RF_CS0; CC_Rdy(); Status=SPI1_ReadWriteByte(Addr|0x40); for (i=0;iFSCTRL1); CC_WrReg(CCxxx0_FSCTRL0, pRfSettings->FSCTRL0); CC_WrReg(CCxxx0_FREQ2, pRfSettings->FREQ2); CC_WrReg(CCxxx0_FREQ1, pRfSettings->FREQ1); CC_WrReg(CCxxx0_FREQ0, pRfSettings->FREQ0); CC_WrReg(CCxxx0_MDMCFG4, pRfSettings->MDMCFG4); CC_WrReg(CCxxx0_MDMCFG3, pRfSettings->MDMCFG3); CC_WrReg(CCxxx0_MDMCFG2, pRfSettings->MDMCFG2); CC_WrReg(CCxxx0_MDMCFG1, pRfSettings->MDMCFG1); CC_WrReg(CCxxx0_MDMCFG0, pRfSettings->MDMCFG0); CC_WrReg(CCxxx0_CHANNR, pRfSettings->CHANNR); CC_WrReg(CCxxx0_DEVIATN, pRfSettings->DEVIATN); CC_WrReg(CCxxx0_FREND1, pRfSettings->FREND1); CC_WrReg(CCxxx0_FREND0, pRfSettings->FREND0); CC_WrReg(CCxxx0_MCSM0 , pRfSettings->MCSM0 ); CC_WrReg(CCxxx0_FOCCFG, pRfSettings->FOCCFG); CC_WrReg(CCxxx0_BSCFG, pRfSettings->BSCFG); CC_WrReg(CCxxx0_AGCCTRL2, pRfSettings->AGCCTRL2); CC_WrReg(CCxxx0_AGCCTRL1, pRfSettings->AGCCTRL1); CC_WrReg(CCxxx0_AGCCTRL0, pRfSettings->AGCCTRL0); CC_WrReg(CCxxx0_FSCAL3, pRfSettings->FSCAL3); CC_WrReg(CCxxx0_FSCAL2, pRfSettings->FSCAL2); CC_WrReg(CCxxx0_FSCAL1, pRfSettings->FSCAL1); CC_WrReg(CCxxx0_FSCAL0, pRfSettings->FSCAL0); CC_WrReg(CCxxx0_FSTEST, pRfSettings->FSTEST); CC_WrReg(CCxxx0_TEST2, pRfSettings->TEST2); CC_WrReg(CCxxx0_TEST1, pRfSettings->TEST1); CC_WrReg(CCxxx0_TEST0, pRfSettings->TEST0); CC_WrReg(CCxxx0_IOCFG2, pRfSettings->IOCFG2); CC_WrReg(CCxxx0_IOCFG0, pRfSettings->IOCFG0); CC_WrReg(CCxxx0_PKTCTRL1, pRfSettings->PKTCTRL1); CC_WrReg(CCxxx0_PKTCTRL0, pRfSettings->PKTCTRL0); CC_WrReg(CCxxx0_ADDR, pRfSettings->ADDR); CC_WrReg(CCxxx0_PKTLEN, pRfSettings->PKTLEN); CC_WrReg(CCxxx0_FIFOTHR, pRfSettings->FIFOTHR); } #endif //================================================== #ifdef CC1101 //M433M RF_SETTINGS rfSettings76800 = { 0x08, // FSCTRL1 Frequency synthesizer control. 0x00, // FSCTRL0 Frequency synthesizer control. 0x10, // FREQ2 Frequency control word, high byte. 0xA9, // FREQ1 Frequency control word, middle byte. 0x5A, // FREQ0 Frequency control word, low byte. 0xAB, // MDMCFG4 Modem configuration. 0x83, // MDMCFG3 Modem configuration. 0x13, // MDMCFG2 Modem configuration. 0x20, // MDMCFG1 Modem configuration. 0xCF, // MDMCFG0 Modem configuration. CHANSPC_M 0x00, // CHANNR Channel number. 0x42, // DEVIATN Modem deviation setting (when FSK modulation is enabled). 0xB6, // FREND1 Front end RX configuration. 0x10, // FREND0 Front end RX configuration. 0x18, // MCSM0 Main Radio Control State Machine configuration. 0x1D, // FOCCFG Frequency Offset Compensation Configuration. 0x1C, // BSCFG Bit synchronization Configuration. 0xC7, // AGCCTRL2 AGC control. 0x00, // AGCCTRL1 AGC control. 0xB2, // AGCCTRL0 AGC control. 0xEA, // FSCAL3 Frequency synthesizer calibration. 0x2A, // FSCAL2 Frequency synthesizer calibration. 0x00, // FSCAL1 Frequency synthesizer calibration. 0x1F, // FSCAL0 Frequency synthesizer calibration. 0x59, // FSTEST Frequency synthesizer calibration. 0x81, // TEST2 Various test settings. 0x35, // TEST1 Various test settings. 0x09, // TEST0 Various test settings. 0x07, // FIFOTHR RXFIFO and TXFIFO thresholds. //add by Gavin 0x0E,//0x09,//0x29, // IOCFG2 GDO2 output pin configuration. 0x09=CCA输出 0x0E=CS输出 0x06, // IOCFG0D GDO0 output pin configuration. Refer to SmartRF Studio User Manual for detailed pseudo register explanation. 0x04, // PKTCTRL1 Packet automation control. 0x05, // PKTCTRL0 Packet automation control. 0x00, // ADDR Device address. 0x25,//0x20 // PKTLEN Packet length. }; //*------------------------------------------ //* 函数名称 : cc_rf_config //* 功能描述 : 无线模块配置 //* 入口参数 : 无 //* 出口参数 : 无 //*--------------------------------------------- static void cc_rf_config(RF_SETTINGS *rf_settings) { // Write register settings CC_WrReg(CCxxx0_FSCTRL1, rf_settings->FSCTRL1); CC_WrReg(CCxxx0_FSCTRL0, rf_settings->FSCTRL0); CC_WrReg(CCxxx0_FREQ2, rf_settings->FREQ2); CC_WrReg(CCxxx0_FREQ1, rf_settings->FREQ1); CC_WrReg(CCxxx0_FREQ0, rf_settings->FREQ0); CC_WrReg(CCxxx0_MDMCFG4, rf_settings->MDMCFG4); CC_WrReg(CCxxx0_MDMCFG3, rf_settings->MDMCFG3); CC_WrReg(CCxxx0_MDMCFG2, rf_settings->MDMCFG2); CC_WrReg(CCxxx0_MDMCFG1, rf_settings->MDMCFG1); CC_WrReg(CCxxx0_MDMCFG0, rf_settings->MDMCFG0); CC_WrReg(CCxxx0_CHANNR, rf_settings->CHANNR); CC_WrReg(CCxxx0_DEVIATN, rf_settings->DEVIATN); CC_WrReg(CCxxx0_FREND1, rf_settings->FREND1); CC_WrReg(CCxxx0_FREND0, rf_settings->FREND0); CC_WrReg(CCxxx0_MCSM0 , rf_settings->MCSM0 ); CC_WrReg(CCxxx0_FOCCFG, rf_settings->FOCCFG); CC_WrReg(CCxxx0_BSCFG, rf_settings->BSCFG); CC_WrReg(CCxxx0_AGCCTRL2, rf_settings->AGCCTRL2); CC_WrReg(CCxxx0_AGCCTRL1, rf_settings->AGCCTRL1); CC_WrReg(CCxxx0_AGCCTRL0, rf_settings->AGCCTRL0); CC_WrReg(CCxxx0_FSCAL3, rf_settings->FSCAL3); CC_WrReg(CCxxx0_FSCAL2, rf_settings->FSCAL2); CC_WrReg(CCxxx0_FSCAL1, rf_settings->FSCAL1); CC_WrReg(CCxxx0_FSCAL0, rf_settings->FSCAL0); CC_WrReg(CCxxx0_FSTEST, rf_settings->FSTEST); CC_WrReg(CCxxx0_TEST2, rf_settings->TEST2); CC_WrReg(CCxxx0_TEST1, rf_settings->TEST1); CC_WrReg(CCxxx0_TEST0, rf_settings->TEST0); CC_WrReg(CCxxx0_IOCFG2, rf_settings->IOCFG2); CC_WrReg(CCxxx0_IOCFG0, rf_settings->IOCFG0); CC_WrReg(CCxxx0_PKTCTRL1, rf_settings->PKTCTRL1); CC_WrReg(CCxxx0_PKTCTRL0, rf_settings->PKTCTRL0); CC_WrReg(CCxxx0_ADDR, rf_settings->ADDR); CC_WrReg(CCxxx0_PKTLEN, rf_settings->PKTLEN); //#ifdef BAND2010 CC_WrReg(CCxxx0_FIFOTHR, rf_settings->FIFOTHR); //#endif } #endif //#ifdef CC1101 //==================================================================== //u8 CC_Test(void) //{ // return CC_RdStatus(CCxxx0_VERSION);//0x03 //} //u8 CC_RssiCh(u8 rssi) //{//输出值是正值,但都是负的dBm,例如返回值是55是-55dBm // if (rssi>=128) // { return (128+RSSI0-(rssi>>1)); // }else // { return (RSSI0-(rssi>>1)); // } //} /* */ unsigned char cc2500_get_rssi(void) { unsigned char rssi =CC_RdStatus(CCxxx0_RSSI); if (rssi>=128) return (128+RSSI0-(rssi>>1)); else return (RSSI0-(rssi>>1)); } //u8 CC_PackStatus(void) //{ // return CC_RdStatus(CCxxx0_PKTSTATUS); // //bit0-bit7 GDO0,GDO1,GDO2,SYNC, CCA,PQT,CS,CRCOK // //如果MCSM1.CCA=0没有使用CCA的话,CCA指示位总为1, // //如果使用CCA,CCA和CS位就相反 //} void rf_set_PA_Mode(unsigned char mode) { switch (mode) { case 2: CC_PaTable(PAMAX2); break; case 3: CC_PaTable(PAMAX3); break; case 4: CC_PaTable(PAMAX4); break; default: CC_PaTable(PAMAX); break; } } void rf_SendPacket(unsigned char *txBuffer, unsigned char size) { LNA_EN0; PA_EN1; CC_ClrTx();//v1.1保证TxBYTES无以前字节 CC_WrReg(CCxxx0_TXFIFO, size);//len CC_WrRegs(CCxxx0_TXFIFO, txBuffer, size); CC_Cmd(CCxxx0_STX); //AdcBatt(); } //static void cc_freq(unsigned char freq, unsigned char rfpwr) //{ //// //换片选... ////#ifndef CHAN80 //// #ifdef CC1101 //// CC_Chan(freq-1); //add by Gavin //// #else //// CC_Chan(freq*6); //// #endif ////#else //// if (freq<41){ //// CC_Chan(freq*6);// 1-40是双数频点 2402-2480 //// } //// else{ //// freq=3+(freq-41)*6; // 41-80是奇数频点 2401-2479 //// CC_Chan(freq); //// } ////#endif //} void rf_setfreq(unsigned char freq) { #ifdef CC2500 if (freq<41){ CC_Chan(freq*6);// 1-40是双数频点 2402-2480 } else{ freq=3+(freq-41)*6; // 41-80是奇数频点 2401-2479 CC_Chan(freq); } #elif defined(CC1101) CC_Chan(freq-1); //add by Gavin #endif //cc_set_pa(rfpwr);//基站功率 CC_XCal(); } #define MAX_LEN 40 //从无线模块读取数据包 static unsigned char cc_rd_packet(unsigned char *buf) { volatile unsigned char crc_ok=0; // Read length byte buf[0]= CC_RdReg(CCxxx0_RXFIFO);//第一字节是Len if( (buf[0]==0)||(buf[0]>MAX_LEN) ) goto RXERR; // Read data from RX FIFO and store in rxBuffer CC_RdRegs(CCxxx0_RXFIFO, buf+1, buf[0]); // Read the 2 appended status bytes (status[0] = RSSI, status[1] = LQI) //rssi= CC_RdReg(CCxxx0_RXFIFO); //lqi=CC_RdReg(CCxxx0_RXFIFO); //if (lqi>0x80) if(CC_RdReg(CCxxx0_RXFIFO)>0x80) { crc_ok=1; // MSB of LQI is the CRC_OK bit } else crc_ok=0; // lqi=lqi&0x7F; //len= //CC_RdStatus(CCxxx0_RXBYTES) & 0x7f;//mask by Gavin // if (len==0) // return ; RXERR: //应该为0,不为0就不对,要清除RxFiFo CC_ClrRx(); return crc_ok; } //-------------------------------------------------------- //无线模块中断服务程序 void rf_Irq(void) { volatile unsigned char i; unsigned char tmp[64]; PA_EN0; LNA_EN1; //先处理模块错误情况 i=CC_RdStatus(0x35)&0x7f;//CCxxx0_MARCSTATE if (i==17) {CC_ClrRx();goto TRXRET;}//Rx_OverFlow错误 if (i==22) {CC_ClrTx();goto TRXRET;}//Tx_UnderFlow错误 //根据是否接收到数据,判断是发送完成中断还是接收中断 i=CC_RdStatus(0x3B)&0x7f;//CCxxx0_RXBYTES if(i==0){ //发送中断 //bs_kp.tx_kp_flag=1; } else{ if( cc_rd_packet(tmp) ) base_core.rf_data_fifo_in(tmp); //keypad_rf_data_save(tmp); } TRXRET: CC_RxOn(); //rx } /* 设置同步码 */ void rf_set_syncode(unsigned short sync) { // uint8_t addr[5] = {INIT_ADDR}; //#define INIT_ADDR 0x19,0x98,0xA4,0x25,0x01 // addr[2] = sync>>8; // addr[3] = sync; //修改无线地址码,缺省A425 // NRF24L01_Set_TxAddr( addr, 4 ); //设置TX地址 // NRF24L01_Set_RxAddr( 0,addr, 4 ); //设置RX地址 通道0 CC_WrReg(CCxxx0_SYNC1,sync); CC_WrReg(CCxxx0_SYNC0,sync>>8); } //************************ void rf_initial(void) { CC_RESET(); #ifdef CC1101 //add by Gavin cc_rf_config(&rfSettings76800); #else CC_RfConfig(&rfSettings250K); #endif rf_set_syncode(0x25A4);//actual test OK! CC_PaTable(PAMAX); CC_WrReg(CCxxx0_MCSM1,0x00 );//0x0f取消CCA,收发总回到RX 不能,否则不能自动校正频率 CC_WrReg(CCxxx0_MCSM0,0x38 );//MCSM).FS_AUTOCAL 0x18总Calibatre,0x28 IDLE时候,0x38 4次IDLE校正一次 CC_WHITE(1); #ifdef CC1101 CC_FEC(1); //add by Gavin #endif CC_RxOn(); //PA控制 LNA_EN1; PA_EN0; } //----------------------------------------- FCC CE ------------------------------------------------------------------ #ifdef FCCCE void FCC_Init() { TIM_ITConfig(TIM2,TIM_IT_Update,DISABLE);//关闭2.5ms中断 NVIC_DisableIRQ(EXTI3_IRQn);//关闭无线中断 } //认证需要的特殊测试模式 //1 连续发射模式(带调制) //2 连续收信模式(带调制) //3 无调制 连续发信模式 //4 无调制 连续收信模式 void FCC_Test(unsigned char mode) { //FccMode=mode; switch (mode) { case 1://连续MSK输出 CLI();//关中断 CC_Cmd(CCxxx0_SIDLE); //cc_write_reg(0x08,0x02 );//CCxxx0_PKTCTRL0 持续发射测试功率 CC_WrReg(0x08,0x22 ); //使用随机数据发送,保证有数据出去 //写回标准MSK CC_WrReg(0x12,0x73 );//CCxxx0_MDMCFG2 CC_WrReg(0x22,0x10 );//CCxxx0_FREND0 //cc_write_reg(0x11,0x7A ); //MDMCFG3 baud调高可以过500KHz LNA_EN0; PA_EN1; CC_Cmd(CCxxx0_STX); SEI(); //开中断 break; case 2://连续MSK接收 CLI(); //关中断 CC_Cmd(CCxxx0_SIDLE); CC_WrReg(0x08,0x02 );//CCxxx0_PKTCTRL0 持续发射测试功率 //写回标准MSK CC_WrReg(0x12,0x73 );//CCxxx0_MDMCFG2 CC_WrReg(0x22,0x10 );//CCxxx0_FREND0 PA_EN0; LNA_EN1; CC_Cmd(CCxxx0_SRX); SEI(); //开中断 break; case 3://连续载波输出,无调制 CLI(); //关中断 CC_Cmd(CCxxx0_SIDLE); //以下2行用于KCC测试,只出载波,未调制的---注意:SPAN设1M,VBW1M,但RBW设10K才能看到分开的2个波峰 CC_WrReg(0x12,0x33 );//CCxxx0_MDMCFG2 CC_WrReg(0x22,0x00 );//CCxxx0_FREND0 CC_WrReg(0x08,0x02 );//CCxxx0_PKTCTRL0 持续发射测试功率 LNA_EN0; PA_EN1; CC_Cmd(CCxxx0_STX); SEI(); //开中断 break; case 4://连续载波模式接收,无调制 CLI(); //关中断 CC_Cmd(CCxxx0_SIDLE); //以下2行用于KCC测试,只出载波,未调制的---注意:SPAN设1M,VBW1M,但RBW设10K才能看到分开的2个波峰 CC_WrReg(0x12,0x33 );//CCxxx0_MDMCFG2 CC_WrReg(0x22,0x00 );//CCxxx0_FREND0 CC_WrReg(0x08,0x02 );//CCxxx0_PKTCTRL0 持续发射测试功率 PA_EN0; LNA_EN1; CC_Cmd(CCxxx0_SRX); SEI(); //开中断 break; } } #endif #endif //CCxxxx