/*---------------------------------------------------------------------------------------------------- INCLUDE HEADE FILES ----------------------------------------------------------------------------------------------------*/ #include "Includes.h" #include "bsp_2_4G.h" #define AON_RF_AONREG ((volatile unsigned *)0x40002430) #define RF_ANA02 ((volatile unsigned *)(0X4002F000 + 0x008)) #define RF_ANA03 ((volatile unsigned *)(0X4002F000 + 0x00C)) #define RF_ANA08 ((volatile unsigned *)(0X4002F000 + 0x020)) #define RF_ANA15 ((volatile unsigned *)(0X4002F000 + 0x03C)) #define RF_ANA21 ((volatile unsigned *)(0X4002F000 + 0x054)) #define RF_ANA26 ((volatile unsigned *)(0X4002F000 + 0x068)) #define RF_ANA27 ((volatile unsigned *)(0X4002F000 + 0x06C)) #define RF_ANA28 ((volatile unsigned *)(0X4002F000 + 0x070)) #define RF_ANA29 ((volatile unsigned *)(0X4002F000 + 0x074)) #define BT_RF_CTRL_SEL ((volatile unsigned *)(0X4002F000 + 0x0B8)) #define CPR_RF_REG0 ((volatile unsigned *)(0x40000000 + 0x1B0)) #define CPR_RF_REG1 ((volatile unsigned *)(0x40000000 + 0x1B4)) void delay_cn(uint32_t cn) { while (cn--) __NOP(); } /*! ******************************************************** * @name wbit * @desc wbit * *********************************************************/ static void wbit(uint16_t reg_addr, int end, int start, char *bit_str) { uint16_t reg_val = 0; char ch = 0; uint16_t i = 0; uint16_t s_len = 0; while (*(bit_str + s_len)) s_len++; if (s_len != (end - start + 1)) while (1) ; reg_val = *(uint16_t *)(0X4002F000 + reg_addr); for (i = start; i <= end; i++) { int bit_idx = i - start; ch = bit_str[(end - start) - bit_idx] - '0'; if (ch == 1) setbit(reg_val, i); else if (ch == 0) clrbit(reg_val, i); } *(uint16_t *)(0X4002F000 + reg_addr) = reg_val; } /*! ******************************************************** * @name wbit * @desc wbit * *********************************************************/ static uint16_t rbit(uint16_t reg_addr) { return *(uint16_t *)(0X4002F000 + reg_addr); } /*! ******************************************************** * @name rf_rccali * @desc rf rc filter calib * *********************************************************/ void rf_rccalib(void) { static uint8_t rccalib_flag = 0; if (rccalib_flag) return; uint32_t timeout = 0; uint16_t val = 0; wbit(0x0080, 10, 8, "111"); // RG_RCCAL_CTRL(Rccal 输出码值控制) def"100" wbit(0x0080, 5, 5, "1"); // RG_RCCAL_RESETN=1 wbit(0x0080, 3, 3, "0"); // RG_RCCAL_SEL =0 wbit(0x0080, 2, 2, "1"); // RG_RCCAL_EN=1 wbit(0x0080, 4, 4, "1"); // RG_RCCAL_START=1 while (!(rbit(0x0084) & 0x8000)) { // 等待AD_RCCAL_FINISH拉高 得出校准值 AD_RCCAL_CTRIM if ((timeout++) > 0x10000) break; } val = rbit(0x0084); val = (val & 0x7FFF) >> 10; // 将校准值AD_RCCAL_CTRIM保存 wbit(0x0080, 3, 3, "1"); // RG_RCCAL_SEL =1 wbit(0x0080, 2, 2, "0"); // RG_RCCAL_EN=0 wbit(0x0080, 4, 4, "0"); // RG_RCCAL_START=0 char tb[6] = {0}; // 将保存的校准值转换成字符串 tb[4] = ((val & 0x01) ? '1' : '0'); tb[3] = ((val & 0x02) ? '1' : '0'); tb[2] = ((val & 0x04) ? '1' : '0'); tb[1] = ((val & 0x08) ? '1' : '0'); tb[0] = ((val & 0x10) ? '1' : '0'); wbit(0x0080, 15, 11, tb); rccalib_flag = 1; // printf("\nRG_RCCAL_CC:%X \n",rbit(0x80)); } /*! ******************************************************** * @name reset_2_4g_modem * @desc reset 2.4g modem * *********************************************************/ void reset_2_4g_modem(void) { *CPR_RF_REG1 &= (~(1 << 21)); // reset delay_cn(200); *CPR_RF_REG1 |= (1 << 21); // unreset delay_cn(200); } /*! ******************************************************** * @name _Ctune_Set * @desc frequency offset tune * *********************************************************/ void freq_tune(uint8_t tu) { *AON_RF_AONREG = (*AON_RF_AONREG & (~(0x3f << 20))) | ((tu & 0x3f) << 20); //- frequency offset } /** * Copyright (c) 2022 - 2025, XinChip * * All rights reserved. * * Author : * */ void config_2_4g_rf(void) { // uint32_t val; // *((uint32_t volatile*)0x40000070) = 0x4000400; //- bt_pclk // *((uint32_t volatile*)0x40002450)|= 0x1; //- open rf digital // // freq_tune(0x36); //- frequency offset #if 1 *BT_RF_CTRL_SEL |= 0xE000; //- sel_24G_rfchan sel_24G_rfldoen sel_24G_rampout use 2.4G signal /*2.4 ack ana8<9:6> 0001 to 0000 ana15<3:1> 010 to 100 ana21<5:2> 1000 to 1011 ana2<12> 1 to 0 */ *RF_ANA08 = *RF_ANA08 & (~0x3C0); *RF_ANA15 = (*RF_ANA15 & (~0xE)) | 0x8; *RF_ANA21 = (*RF_ANA21 & (~0x3c)) | 0x2c; *RF_ANA02 &= (~0x1000); #if _24G_CLK_SOURCE == CLK_BBPLL64M // bbpll 64M *RF_ANA26 |= 0xF000; *RF_ANA27 |= 0x02; *RF_ANA26 = (*RF_ANA26 & (~0x3F)) | 0x04; #elif _24G_CLK_SOURCE == CLK_BBPLL96M // bbpll 96M *RF_ANA26 |= 0xF000; *RF_ANA27 |= 0x02; *RF_ANA26 = (*RF_ANA26 & (~0x3F)) | 0x06; #endif #if (TRANS_RATE == RATE_1M) *RF_ANA21 = (*RF_ANA21 & (0xFFFF8FFF)) | 0x3000; //- tx dac gc def110 Optimization #elif (TRANS_RATE == RATE_2M) *RF_ANA21 = (*RF_ANA21 & (0xFFFF8FFF)) | 0x2000; //- tx dac gc def110 Optimization #else *RF_ANA21 = (*RF_ANA21 & (0xFFFF8FFF)) | 0x6000; //- tx dac gc def110 Optimization #endif #if (TRANS_RATE == RATE_2M) *RF_ANA03 |= 0x01; #endif *RF_ANA29 |= 0x02; //- manual afc *RF_ANA28 |= 0x01; //- afc pulse reset_2_4g_modem(); #if _24G_CLK_SOURCE == CLK_BBPLL64M *CPR_RF_REG1 = (*CPR_RF_REG1 & 0xFFFF3F0F) | 0x00C030; // enable 2.4G_mclk 2.4G_hclk 4div //*CPR_RF_REG1 =(*CPR_RF_REG1&0xFFFF3F0F)|0x00C070;//enable 2.4G_mclk 2.4G_hclk 8div #elif _24G_CLK_SOURCE == CLK_BBPLL96M *CPR_RF_REG1 = (*CPR_RF_REG1 & 0xFFFF3F0F) | 0x00C050; // enable 2.4G_mclk 2.4G_hclk 6div #endif *CPR_RF_REG0 |= 0x600; // set 2.4G agc and iq from 2.4 modem #endif } /** * Copyright (c) 2022 - 2025, XinChip * * All rights reserved. * * Author : * */ void set_power(uint8_t txgm) { *RF_ANA21 = (*RF_ANA21 & (~0xfc0)) | ((txgm & 0x3f) << 6); } /** * Copyright (c) 2022 - 2025, XinChip * * All rights reserved. * * Author : * */ void set_channel(uint16_t channel) { printf("%x\n", *RF_CH); #if (TRANS_RATE == RATE_2M) *RF_CH = ((*CFG_TOP & 0x01) ? (channel - 2) : channel); #else *RF_CH = ((*CFG_TOP & 0x01) ? (channel - 1) : channel); #endif printf("%x\n", *RF_CH); delay_cn(200); *RF_ANA28 &= (~0x1); //- afc pulse delay_cn(200); *RF_ANA28 |= 0x1; //- afc pulse delay_cn(200); } /** * Copyright (c) 2022 - 2025, XinChip * * All rights reserved. * * Author : * */ void set_txaddr(uint32_t txaddr_l, uint32_t txaddr_h) { uint32_t val; __write_hw_reg32(TX_ADDR_L, txaddr_l); __read_hw_reg32(TX_ADDR_H, val); __write_hw_reg32(TX_ADDR_H, (txaddr_h & 0xff) | (val & 0xffffff00)); } /** * Copyright (c) 2022 - 2025, XinChip * * All rights reserved. * * Author : * */ void set_pipe0_rxaddr(uint32_t rxaddr_l, uint32_t rxaddr_h) { __write_hw_reg32(RX_ADDR_P0_L, rxaddr_l); __write_hw_reg32(RX_ADDR_P0_H, rxaddr_h & 0xff); } /** * Copyright (c) 2022 - 2025, XinChip * * All rights reserved. * * Author : * */ void set_trx_addr_len(uint8_t len) { switch (len) { case 3: __write_hw_reg32(SETUP_AW, 0xa5); break; case 4: __write_hw_reg32(SETUP_AW, 0xaa); break; case 5: __write_hw_reg32(SETUP_AW, 0xaf); break; } } /** * Copyright (c) 2022 - 2025, XinChip * * All rights reserved. * * Author : * */ void set_rate(uint8_t rate) { __write_hw_reg32(SETUP_RF, rate); } /** * Copyright (c) 2022 - 2025, XinChip * * All rights reserved. * * Author : * */ void set_feature(uint8_t long_pld, uint8_t fec, uint8_t whiten, uint8_t dpl, uint8_t ack_pay) { __write_hw_reg32(FEATURE, (long_pld << 5) | (fec << 4) | (whiten << 3) | (dpl << 2) | (ack_pay << 1)); } /** * Copyright (c) 2022 - 2025, XinChip * * All rights reserved. * * Author : * */ void set_mode(uint8_t mode) { uint32_t val; __read_hw_reg32(CFG_TOP, val); // #if (TRANS_RATE == RATE_2M) __write_hw_reg32(CFG_TOP, (val & (~0x1ffff3)) | (mode & 0x01) | 0x1b8672); #else __write_hw_reg32(CFG_TOP, (val & (~0x1ffff3)) | (mode & 0x01) | 0x0b8272); #endif } /** * Copyright (c) 2022 - 2025, XinChip * * All rights reserved. * * Author : * */ void set_crc(uint8_t enable, uint8_t crc_bit) { uint32_t val; __read_hw_reg32(CFG_TOP, val); // if (enable) { if (crc_bit == CRC_1BIT) { __write_hw_reg32(CFG_TOP, (val | (~0x0C)) | 0x08); } else { __write_hw_reg32(CFG_TOP, val | 0x0C); } } else { __write_hw_reg32(CFG_TOP, val & (~0x08)); } } /** * Copyright (c) 2022 - 2025, XinChip * * All rights reserved. * * Author : * */ void set_p012345_revlen(uint32_t p0123len, uint32_t p45len) { __write_hw_reg32(RX_PW_PX_L, p0123len); __write_hw_reg32(RX_PW_PX_H, p45len); } /** * Copyright (c) 2022 - 2025, XinChip * * All rights reserved. * * Author : * */ void set_pipe0_revlen(uint8_t p0len) { *RX_PW_PX_L = (*RX_PW_PX_L & (~0xff)) | p0len; } void set_retry_cnt(uint8_t cnt) { *SETUP_RETR = (*SETUP_RETR & (~0x0f)) | cnt; } /** * Copyright (c) 2022 - 2025, XinChip * * All rights reserved. * * Author : * */ void send_cmd(uint8_t cmd) { nop(); __write_hw_reg32(CMD_BYTE, cmd | CMD_DONE); nop(); } /** * Copyright (c) 2022 - 2025, XinChip * * All rights reserved. * * Author : * */ void XC_AckPayload(uint8_t *txbuf, uint8_t len) { send_cmd(FLUSH_TX); if (!((*STATUS_FIFO) & TX_FULL)) // tx FIFO is not full { send_cmd(W_ACK_PLOAD); for (int i = 0; i < len; i++) { *TXFIFO_WDATA = txbuf[i]; nop(); } } } void XC_TxPacket(uint8_t *txbuf, uint8_t len) // r { send_cmd(FLUSH_TX); __write_hw_reg32(STATUS, ALL_IRQ_STATUS); if (!((*STATUS_FIFO) & TX_FULL)) // tx FIFO is not full { send_cmd(W_TX_PLOAD); for (int i = 0; i < len; i++) { *TXFIFO_WDATA = txbuf[i]; nop(); } CE_High; for (int i = 0; i < 0x1000; i++) ; // delay us CE_Low; } } /** * Copyright (c) 2022 - 2025, XinChip * * All rights reserved. * * Author : * */ uint8_t XC_RxPacket(uint8_t en_ack_pay, uint8_t *ack_pay_buf, uint8_t ack_len, uint8_t *rxbuf) // r { static uint8_t cnt = 0x01; uint32_t status = 0, len = 0; __read_hw_reg32(STATUS, status); // read status if ((status & 0x0e) != 0x0e) { send_cmd(R_RX_PL_WID); len = *RXFIFO_LEN & 0xFF; // pipe = (status & 0xe) >> 1; for (int i = 0; i < 4; i++) send_cmd(R_RX_PLOAD); for (int i = 0; i < len; i++) *(rxbuf + i) = *RXFIFO_RDTA; ack_pay_buf[0] = cnt++; switch (rxbuf[2]) { case 1: // match packet ack_pay_buf[4] = 0x02; ack_pay_buf[5] = STATUS_OK; break; case 3: // bin info packet ack_pay_buf[4] = 0x04; // ack_pay_buf[5]=STATUS_OK; ack_pay_buf[5] = info_24g.DataStatus; break; case 5: // bin packet ack_pay_buf[4] = 0x05; ack_pay_buf[5] = STATUS_OK; break; case 6: // ota result ack_pay_buf[4] = 0x07; ack_pay_buf[5] = info_24g.CheckStatus; // ack_pay_buf[5]=STATUS_OK; break; case 8: // ready ack_pay_buf[4] = 0x09; ack_pay_buf[5] = STATUS_READY; break; default: break; } if (en_ack_pay) XC_AckPayload(ack_pay_buf, ack_len); // // if(en_ack_pay) XC_AckPayload(ack_pay_buf,5);//250K payload max 5 // if(en_ack_pay) XC_AckPayload(ack_pay_buf,32);//1M payload max 32 } __write_hw_reg32(STATUS, ALL_IRQ_STATUS); // clear all status inter send_cmd(FLUSH_RX); return len; } /** * Copyright (c) 2022 - 2025, XinChip * * All rights reserved. * * Author : * */ void set_dynpd(uint8_t val) { __write_hw_reg32(DYNPD, val); } /** * Copyright (c) 2022 - 2025, XinChip * * All rights reserved. * * Author : * */ void go_rx(uint16_t ch) { uint8_t tv = *STATUS_FIFO; if (((tv & 0x2) && (tv & 0x0C))) { printf("reset_2_4g_modem\n"); reset_2_4g_modem(); init_24G(RX_MODE); } else { send_cmd(FLUSH_RX); set_mode(RX_MODE); } set_channel(ch); } void go_tx(uint16_t ch) { send_cmd(FLUSH_TX); set_mode(TX_MODE); set_channel(ch); } /** * Copyright (c) 2022 - 2025, XinChip * * All rights reserved. * * Author : * */ uint8_t wait_ack(uint8_t *ack_pay_buf, uint8_t *len, uint32_t timeout) { while (timeout--) { if ((*STATUS) & XC_TX_DS) { if (len != NULL) *len = XC_RxPacket(0, NULL, 0, ack_pay_buf); return 1; // rev ack } if ((*STATUS) & XC_MAX_RT) { return 0; // no rev ack } } return 0; // no rev ack } /** * Copyright (c) 2022 - 2025, XinChip * * All rights reserved. * * Author : * */ void init_adv(uint8_t mode) { set_txaddr(0x71917d6b, 0); // tx addr 4byte set_pipe0_rxaddr(0x71917d6b, 0); // rx pipe0 addr 4byte set_trx_addr_len(4); // set trx addrlen is 4byte set_rate(TRANS_RATE); // set rate set_crc(DIS_CRC, CRC_2BIT); set_feature(EN_LONG_PLD, DIS_FEC, DIS_WHITEN, DIS_DPL, DIS_ACK_PAY); set_pipe0_revlen(BUFF_ADV_LENGTH); // set_p012345_revlen(0x2A2A2A2A,0x2A2A);//pipe0-1-2-3-4-pipe5 payload 42byte set_mode(mode); // set tx or rx set_power(POWER_LEVEL); rf_rccalib(); // Initialization finally performs the calibration rc filter,This function is executed only once internally } /** * Copyright (c) 2022 - 2025, XinChip * * All rights reserved. * * Author : * */ void init_24G(uint8_t mode) { // set_retry_cnt(3);//set auto retransmit count set_dynpd(0x3f); // enable dynamic payload set_txaddr(0xE7E7C2E6, 0xC2); // tx addr 5byte set_pipe0_rxaddr(0xE7E7C2E6, 0xC2); // rx pipe0 addr 5byte set_trx_addr_len(5); // set trx addrlen is 5byte set_rate(TRANS_RATE); // set rate set_crc(EN_CRC, CRC_2BIT); set_feature(DIS_LONG_PLD, EN_FEC, EN_WHITEN, EN_DPL, EN_ACK_PAY); set_pipe0_revlen(BUFF_24G_LENGTH); // set_p012345_revlen(0x20202020,0x2020); //pipe0-1-2-3-4-pipe5 payload 32byte set_mode(mode); // set tx or rx set_power(POWER_LEVEL); rf_rccalib(); // Initialization finally performs the calibration rc filter,This function is executed only once internally } /*******************************adv**********************************/ /** * Copyright (c) 2022 - 2025, XinChip * * All rights reserved. * * Author : * */ uint8_t reverseBits(uint8_t input) { uint8_t i = 0, temp = 0; for (; i < 8; i++) { temp <<= 1; temp = ((input >> i) & 0x01) ? (temp | 0x01) : (temp | 0x00); } return temp; } /** * Copyright (c) 2022 - 2025, XinChip * * All rights reserved. * * Author : * */ uint8_t bleWhitenStart(uint16_t Fre) { uint8_t chan = (Fre == RF_ADV_CHANNELS_38) ? 38 : ((Fre == RF_ADV_CHANNELS_37) ? 37 : 39); return reverseBits(chan) | 2; } /** * Copyright (c) 2022 - 2025, XinChip * * All rights reserved. * * Author : * */ /*白化,LFSR的方式进行白化*/ void bleWhiten(uint8_t *data, uint8_t len, uint8_t whitenCoeff) { uint8_t m; while (len--) { for (m = 1; m; m <<= 1) { if (whitenCoeff & 0x80) { whitenCoeff ^= 0x11; (*data) ^= m; } whitenCoeff <<= 1; } *data = reverseBits(*data); // 新增 -- 翻转变量 data++; } } /** * Copyright (c) 2022 - 2025, XinChip * * All rights reserved. * * Author : * */ void BLEcrc(const uint8_t *data, uint8_t dataLen, uint8_t *outputCRC) { // calculating the CRC based on a LFSR uint8_t i, temp, tempData; while (dataLen--) { tempData = *data++; for (i = 0; i < 8; i++, tempData >>= 1) { temp = outputCRC[0] >> 7; outputCRC[0] <<= 1; if (outputCRC[1] & 0x80) { outputCRC[0] |= 1; } outputCRC[1] <<= 1; if (outputCRC[2] & 0x80) { outputCRC[1] |= 1; } outputCRC[2] <<= 1; if (temp != (tempData & 1)) { outputCRC[2] ^= 0x5B; outputCRC[1] ^= 0x06; } } } outputCRC[2] = reverseBits(outputCRC[2]); outputCRC[1] = reverseBits(outputCRC[1]); outputCRC[0] = reverseBits(outputCRC[0]); }