From ad3568c2cf1335fc56ae8650fcd02b395afcfb11 Mon Sep 17 00:00:00 2001 From: IOsetting Date: Mon, 1 Aug 2022 01:48:55 +0800 Subject: [PATCH] feat: add xl2400(wl2400) 2.4g rf demo --- demo/spi/xl2400/main.c | 140 ++++++++++++++ demo/spi/xl2400/xl2400.c | 401 +++++++++++++++++++++++++++++++++++++++ demo/spi/xl2400/xl2400.h | 143 ++++++++++++++ 3 files changed, 684 insertions(+) create mode 100644 demo/spi/xl2400/main.c create mode 100755 demo/spi/xl2400/xl2400.c create mode 100755 demo/spi/xl2400/xl2400.h diff --git a/demo/spi/xl2400/main.c b/demo/spi/xl2400/main.c new file mode 100644 index 0000000..21fd771 --- /dev/null +++ b/demo/spi/xl2400/main.c @@ -0,0 +1,140 @@ +// Copyright 2021 IOsetting +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/*** + * Demo: XL2400 / WL2400 SOP8 2.4GHz RF + * + * Pin connection: + * P35(SS, Ignored) => CSN + * P34(MOSI) => DATA + * P32(SPCLK) => SCK + * VDD1 => 3.3V + * XC1,XC2 => 16MHz OSC + * GND => GND + * + * test-board: Minimum System; test-MCU: STC8H1K08,STC8H3K64S2 + */ + +#include "fw_hal.h" +#include "xl2400.h" + +// 0:TX, 1:RX +#define XL2400_MODE 1 + +__CODE uint8_t TX_ADDRESS[5] = {0x11,0x33,0x33,0x33,0x11}; +__CODE uint8_t RX_ADDRESS[5] = {0x33,0x55,0x33,0x44,0x33}; +extern uint8_t *xbuf_data; + +uint8_t XL2400_PrintStatus(void); + +void SPI_Init(void) +{ + // SPI frequency + SPI_SetClockPrescaler(SPI_ClockPreScaler_16); + // Clock is low when idle + SPI_SetClockPolarity(HAL_State_OFF); + // Data transfer is driven by lower SS pin + SPI_SetClockPhase(SPI_ClockPhase_LeadingEdge); + // MSB first + SPI_SetDataOrder(SPI_DataOrder_MSB); + // Define the output pins + SPI_SetPort(SPI_AlterPort_P35_P34_P33_P32); + // Ignore SS pin, use MSTR to swith between master/slave mode + SPI_IgnoreSlaveSelect(HAL_State_ON); + // Master mode + SPI_SetMasterMode(HAL_State_ON); + // Start SPI + SPI_SetEnabled(HAL_State_ON); +} + +void GPIO_Init(void) +{ + // Configure GPIO pins before SPI and device + // MISO(P33) MOSI(P34) + GPIO_P3_SetMode(GPIO_Pin_4, GPIO_Mode_InOut_QBD); + // SCLK(P32) CSN(P35) CE(P37) + GPIO_P3_SetMode(GPIO_Pin_2|GPIO_Pin_5|GPIO_Pin_7, GPIO_Mode_Output_PP); +} + +int main(void) +{ + __CODE uint8_t tmp[] = { + 0x1F, 0x80, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x21, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x28, + 0x31, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x38, + 0x41, 0x12, 0x13, 0x14, 0x15, 0x16, 0x37, 0x48}; + uint8_t i, j, status; + + SYS_SetClock(); + GPIO_Init(); + + // UART1, baud 115200, baud source Timer1, 1T mode, no interrupt + UART1_Config8bitUart(UART1_BaudSource_Timer1, HAL_State_ON, 115200); + UART1_TxString("UART Initialized\r\n"); + + SPI_Init(); + UART1_TxString("SPI Initialized\r\n"); + + while (XL2400_SPI_Test() == HAL_ERROR) + { + UART1_TxString(" - check failed\r\n"); + SYS_Delay(1000); + } + UART1_TxString(" - check passed\r\n"); + + XL2400_Init(); + XL2400_SetPower(XL2400_RF_0DB); + + if (XL2400_MODE == 0) + { + // TX + XL2400_SetChannel(78); + XL2400_SetTxAddress(RX_ADDRESS); + XL2400_SetRxAddress(TX_ADDRESS); + XL2400_SetTxMode(); + UART1_TxString("XL2400 TX Initialized\r\n"); + + while(1) + { + //XL2400_PrintStatus(); + XL2400_Tx(tmp, XL2400_PLOAD_WIDTH); + SYS_Delay(100); + } + } + else + { + // RX + XL2400_SetChannel(77); + XL2400_SetTxAddress(RX_ADDRESS); + XL2400_SetRxAddress(TX_ADDRESS); + UART1_TxString("XL2400 RX Initialized\r\n"); + + while(1) + { + XL2400_WakeUp(); + XL2400_SetRxMode(); + while (--j) + { + status = XL2400_Rx(); + if (status & RX_DR_FLAG) + { + UART1_TxString(" <\r\n"); + } + } + //XL2400_PrintStatus(); + XL2400_Sleep(); + SYS_Delay(10); + } + } +} diff --git a/demo/spi/xl2400/xl2400.c b/demo/spi/xl2400/xl2400.c new file mode 100755 index 0000000..c3fd8e0 --- /dev/null +++ b/demo/spi/xl2400/xl2400.c @@ -0,0 +1,401 @@ +// Copyright 2021 IOsetting +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "xl2400.h" + +__IDATA uint8_t cbuf[2], xbuf[XL2400_PL_WIDTH_MAX + 1]; +uint8_t *xbuf_data = xbuf + 1; + +void XL2400_WriteReg(uint8_t reg, uint8_t value) +{ + XL2400_CSN = 0; + cbuf[0] = reg; + cbuf[1] = value; + SPI_TxRxBytes(cbuf, 2); + XL2400_CSN = 1; +} + +uint8_t XL2400_ReadReg(uint8_t reg) +{ + XL2400_CSN = 0; + cbuf[0] = reg; + cbuf[1] = XL2400_CMD_NOP; + SPI_TxRxBytes(cbuf, 2); + XL2400_CSN = 1; + return cbuf[1]; +} + +void XL2400_WriteFromBuf(uint8_t reg, const uint8_t *pBuf, uint8_t len) +{ + XL2400_CSN = 0; + xbuf[0] = reg; + memcpy(xbuf_data, pBuf, len); + SPI_TxRxBytes(xbuf, len + 1); + XL2400_CSN = 1; +} + +void XL2400_ReadToBuf(uint8_t reg, uint8_t len) +{ + XL2400_CSN = 0; + memset(xbuf, XL2400_CMD_NOP, XL2400_PL_WIDTH_MAX + 1); + xbuf[0] = reg; + SPI_TxRxBytes(xbuf, len + 1); + XL2400_CSN = 1; +} + +void XL2400_WriteBack(uint8_t reg, uint8_t len) +{ + XL2400_CSN = 0; + xbuf[0] = reg; + SPI_TxRxBytes(xbuf, len + 1); + XL2400_CSN = 1; +} + +void XL2400_CE_Low(void) +{ + XL2400_ReadToBuf(XL2400_CMD_R_REGISTER | XL2400_REG_CFG_TOP, 2); + *(xbuf_data + 1) &= 0xBF; + XL2400_WriteBack(XL2400_CMD_W_REGISTER | XL2400_REG_CFG_TOP, 2); +} + +void XL2400_CE_High(void) +{ + XL2400_ReadToBuf(XL2400_CMD_R_REGISTER | XL2400_REG_CFG_TOP, 2); + *(xbuf_data + 1) |= 0x40; + XL2400_WriteBack(XL2400_CMD_W_REGISTER | XL2400_REG_CFG_TOP, 2); +} + +uint8_t XL2400_SPI_Test(void) +{ + uint8_t i; + const uint8_t *ptr = (const uint8_t *)XL2400_TEST_ADDR; + XL2400_WriteFromBuf(XL2400_CMD_W_REGISTER | XL2400_REG_TX_ADDR, ptr, 5); + XL2400_ReadToBuf(XL2400_CMD_R_REGISTER | XL2400_REG_TX_ADDR, 5); + for (i = 0; i < 5; i++) { + UART1_TxHex(*(xbuf_data + i)); + if (*(xbuf_data + i) != *ptr++) return HAL_ERROR; + } + return HAL_OK; +} + +void XL2400_Init(void) +{ + // Analog config + XL2400_ReadToBuf(XL2400_CMD_R_REGISTER | XL2400_REG_ANALOG_CFG0, 13); + *(xbuf_data + 4) &= ~0x04; + *(xbuf_data + 12) |= 0x40; + XL2400_WriteBack(XL2400_CMD_W_REGISTER | XL2400_REG_ANALOG_CFG0, 13); + // Switch to software CE control, wake up RF + XL2400_WakeUp(); + // Enable Auto ACK Pipe 0 + XL2400_WriteReg(XL2400_CMD_W_REGISTER | XL2400_REG_EN_AA, 0x3F); + // Enable Pipe 0 + XL2400_WriteReg(XL2400_CMD_W_REGISTER | XL2400_REG_EN_RXADDR, 0x3F); + // Address Width, 5 bytes + XL2400_WriteReg(XL2400_CMD_W_REGISTER | XL2400_REG_SETUP_AW, 0xAF); + // Retries and interval + XL2400_WriteReg(XL2400_CMD_W_REGISTER | XL2400_REG_SETUP_RETR, 0x33); + // RF Data Rate 1Mbps + XL2400_WriteReg(XL2400_CMD_W_REGISTER | XL2400_REG_RF_SETUP, 0x22); + // Number of bytes in RX payload, pipe 0 and pipe 1 + *(xbuf_data + 0) = XL2400_PLOAD_WIDTH; + *(xbuf_data + 1) = XL2400_PLOAD_WIDTH; + XL2400_WriteBack(XL2400_CMD_W_REGISTER | XL2400_REG_RX_PW_PX, 2); + // Dynamic payload width: off + XL2400_WriteReg(XL2400_CMD_W_REGISTER | XL2400_REG_DYNPD, 0x00); + // Other features + //bit7&6=00 return status when send register address + //bit5=0 long data pack off + //bit4=1 FEC off + //bit3=1 FEATURE on + //bit2=0 Dynamic length off + //bit1=0 ACK without payload + //bit0=0 W_TX_PAYLOAD_NOACK off + XL2400_WriteReg(XL2400_CMD_W_REGISTER | XL2400_REG_FEATURE, 0x18); + // Enable RSSI + *(xbuf_data + 0) = 0x10; + *(xbuf_data + 1) = 0x00; + XL2400_WriteBack(XL2400_CMD_W_REGISTER | XL2400_REG_RSSI, 2); +} + +void XL2400_SetChannel(uint8_t channel) +{ + if (channel > 80) channel = 80; + // AFC reset + XL2400_WriteReg(XL2400_CMD_W_REGISTER | XL2400_REG_ANALOG_CFG0, 0x06); + // AFC on + XL2400_WriteReg(XL2400_CMD_W_REGISTER | XL2400_REG_ANALOG_CFG0, 0x0E); + // Frequency(MHz) 2400:0x960 -> 2480:0x9B0 + *(xbuf_data + 0) = 0x60 + channel; + *(xbuf_data + 1) = 0x09; + XL2400_WriteBack(XL2400_CMD_W_REGISTER | XL2400_REG_RF_CH, 2); + // AFC Locked + *(xbuf_data + 1) |= 0x20; + XL2400_WriteBack(XL2400_CMD_W_REGISTER | XL2400_REG_RF_CH, 2); +} + +void XL2400_SetTxAddress(uint8_t *address) +{ + XL2400_WriteFromBuf(XL2400_CMD_W_REGISTER | XL2400_REG_TX_ADDR, address, 5); + XL2400_WriteFromBuf(XL2400_CMD_W_REGISTER | XL2400_REG_RX_ADDR_P0, address, 5); +} + +void XL2400_SetRxAddress(uint8_t *address) +{ + XL2400_WriteFromBuf(XL2400_CMD_W_REGISTER | XL2400_REG_RX_ADDR_P1, address, 5); +} + +void XL2400_SetPower(uint8_t power) +{ + XL2400_ReadToBuf(XL2400_CMD_R_REGISTER | XL2400_REG_RF_CH, 3); + *(xbuf_data + 2) = power; + XL2400_WriteBack(XL2400_CMD_W_REGISTER | XL2400_REG_RF_CH, 3); +} + +void XL2400_Sleep(void) +{ + XL2400_CE_Low(); + XL2400_ClearStatus(); + + *(xbuf_data + 0) = 0x7C; + *(xbuf_data + 1) = 0x82; + *(xbuf_data + 2) = 0x03; + XL2400_WriteBack(XL2400_CMD_W_REGISTER | XL2400_REG_CFG_TOP, 3); +} + +void XL2400_WakeUp(void) +{ + *(xbuf_data + 0) = 0x7E; + *(xbuf_data + 1) = 0x82; + *(xbuf_data + 2) = 0x0B; + XL2400_WriteBack(XL2400_CMD_W_REGISTER | XL2400_REG_CFG_TOP, 3); + XL2400_CE_Low(); + XL2400_ClearStatus(); +} + +uint8_t XL2400_RxCalibrate(void) +{ + uint8_t i, j; + for (i = 0; i < 10; i++) + { + SYS_Delay(2); + XL2400_ReadToBuf(XL2400_CMD_R_REGISTER | XL2400_REG_ANALOG_CFG3, 2); + *(xbuf_data + 1) |= 0x90; + *(xbuf_data + 1) &= ~0x20; + XL2400_WriteBack(XL2400_CMD_W_REGISTER | XL2400_REG_ANALOG_CFG3, 2); + *(xbuf_data + 1) |= 0x40; + XL2400_WriteBack(XL2400_CMD_W_REGISTER | XL2400_REG_ANALOG_CFG3, 2); + SYS_Delay(1); + XL2400_ReadToBuf(XL2400_CMD_R_REGISTER | XL2400_REG_FIFO_STATUS, 2); + + if (*(xbuf_data + 1) & 0x20) + { + j = *(xbuf_data + 1) << 3; + XL2400_ReadToBuf(XL2400_CMD_R_REGISTER | XL2400_REG_ANALOG_CFG3, 2); + *(xbuf_data + 1) &= 0x8F; + *(xbuf_data + 1) |= 0x20; + *(xbuf_data + 0) &= 0x07; + *(xbuf_data + 0) |= j; + XL2400_WriteBack(XL2400_CMD_W_REGISTER | XL2400_REG_ANALOG_CFG3, 2); + return HAL_OK; + } + } + return HAL_ERROR; +} + +void XL2400_SetTxMode(void) +{ + XL2400_CE_Low(); + XL2400_ClearStatus(); + XL2400_WriteReg(XL2400_CMD_W_REGISTER | XL2400_REG_CFG_TOP, 0x7E); + XL2400_RxCalibrate(); + SYS_Delay(2); +} + +void XL2400_SetRxMode(void) +{ + XL2400_CE_Low(); + XL2400_ClearStatus(); + XL2400_WriteReg(XL2400_CMD_W_REGISTER | XL2400_REG_CFG_TOP, 0x7F); + XL2400_RxCalibrate(); + XL2400_CE_High(); + SYS_Delay(1); +} + +uint8_t XL2400_Tx(uint8_t *ucPayload, uint8_t length) +{ + uint8_t y = 100, status = 0; + XL2400_ClearStatus(); + XL2400_WriteFromBuf(XL2400_CMD_W_TX_PAYLOAD, ucPayload, length); + XL2400_CE_High(); + SYS_DelayUs(100); + // Retry until timeout + while (y--) + { + SYS_DelayUs(100); + status = XL2400_ReadStatus(); + // If TX successful or retry timeout, exit + if ((status & (MAX_RT_FLAG | TX_DS_FLAG)) != 0) + { + break; + } + } + XL2400_CE_Low(); + return status; +} + +uint8_t XL2400_Rx(void) +{ + uint8_t i, status, rxplWidth; + status = XL2400_ReadStatus(); + if (status & RX_DR_FLAG) + { + XL2400_CE_Low(); + rxplWidth = XL2400_ReadReg(XL2400_CMD_R_RX_PL_WID); + XL2400_ReadToBuf(XL2400_CMD_R_RX_PAYLOAD, rxplWidth); + XL2400_ClearStatus(); + UART1_TxChar('>'); + for (i = 0; i < rxplWidth; i++) + { + UART1_TxHex(*(xbuf_data + i)); + } + } + return status; +} + +uint8_t XL2400_ReadStatus(void) +{ + return XL2400_ReadReg(XL2400_CMD_R_REGISTER | XL2400_REG_STATUS); +} + +void XL2400_ClearStatus(void) +{ + XL2400_WriteReg(XL2400_CMD_FLUSH_TX, XL2400_CMD_NOP); + XL2400_WriteReg(XL2400_CMD_FLUSH_RX, XL2400_CMD_NOP); + XL2400_WriteReg(XL2400_CMD_W_REGISTER | XL2400_REG_STATUS, 0x70); +} + +void XL2400_FlushRxTX(void) +{ + XL2400_WriteReg(XL2400_CMD_FLUSH_TX, XL2400_CMD_NOP); + XL2400_WriteReg(XL2400_CMD_FLUSH_RX, XL2400_CMD_NOP); +} + +void XL2400_CarrierTest(void) +{ + XL2400_CE_Low(); + XL2400_ReadToBuf(XL2400_CMD_R_REGISTER | XL2400_REG_ANALOG_CFG0, 13); + *(xbuf_data + 12) |= 0x40; + *(xbuf_data + 4) &= ~0x04; + XL2400_WriteBack(XL2400_CMD_W_REGISTER | XL2400_REG_ANALOG_CFG0, 13); + XL2400_WriteReg(XL2400_CMD_W_REGISTER | XL2400_REG_TXPROC_CFG, 0x00); + *(xbuf_data + 0) = 0x01; + *(xbuf_data + 1) = 0x00; + XL2400_WriteBack(XL2400_CMD_W_REGISTER | XL2400_REG_RF_SETUP, 2); + XL2400_ClearStatus(); +} + +uint8_t XL2400_PrintStatus(void) +{ + uint8_t i, status; + + UART1_TxString("Bytes from low to high: 0,1,2,3,...\r\n[Config]"); + XL2400_ReadToBuf(XL2400_CMD_R_REGISTER | XL2400_REG_CFG_TOP, 3); + for (i = 0; i < 3; i++) { + UART1_TxHex(*(xbuf_data + i)); + } + + UART1_TxString(" [EN_AA]"); + UART1_TxHex(XL2400_ReadReg(XL2400_CMD_R_REGISTER | XL2400_REG_EN_AA)); + + UART1_TxString(" [EN_RxAddr]"); + UART1_TxHex(XL2400_ReadReg(XL2400_CMD_R_REGISTER | XL2400_REG_EN_RXADDR)); + + UART1_TxString(" [AddrWidth]"); + UART1_TxHex(XL2400_ReadReg(XL2400_CMD_R_REGISTER | XL2400_REG_SETUP_AW)); + + UART1_TxString(" [Retry]"); + XL2400_ReadToBuf(XL2400_CMD_R_REGISTER | XL2400_REG_SETUP_RETR, 4); + for (i = 0; i < 4; i++) { + UART1_TxHex(*(xbuf_data + i)); + } + + UART1_TxString("\r\n[RF_Channel]"); + XL2400_ReadToBuf(XL2400_CMD_R_REGISTER | XL2400_REG_RF_CH, 3); + for (i = 0; i < 3; i++) { + UART1_TxHex(*(xbuf_data + i)); + } + + UART1_TxString(" [RF_Setup]"); + XL2400_ReadToBuf(XL2400_CMD_R_REGISTER | XL2400_REG_RF_SETUP, 2); + for (i = 0; i < 2; i++) { + UART1_TxHex(*(xbuf_data + i)); + } + + UART1_TxString(" [Observe_Tx]"); + XL2400_ReadToBuf(XL2400_CMD_R_REGISTER | XL2400_REG_OBSERVE_TX, 4); + for (i = 0; i < 4; i++) { + UART1_TxHex(*(xbuf_data + i)); + } + + UART1_TxString(" [RSSI]"); + XL2400_ReadToBuf(XL2400_CMD_R_REGISTER | XL2400_REG_RSSI, 2); + for (i = 0; i < 2; i++) { + UART1_TxHex(*(xbuf_data + i)); + } + + UART1_TxString("\r\n[TxAddr] "); + XL2400_ReadToBuf(XL2400_CMD_R_REGISTER | XL2400_REG_TX_ADDR, 5); + for (i = 0; i < 5; i++) { + UART1_TxHex(*(xbuf_data + i)); + } + + UART1_TxString("\r\n[RxAddrP0]"); + XL2400_ReadToBuf(XL2400_CMD_R_REGISTER | XL2400_REG_RX_ADDR_P0, 5); + for (i = 0; i < 5; i++) { + UART1_TxHex(*(xbuf_data + i)); + } + UART1_TxString(" [RxAddrP1]"); + XL2400_ReadToBuf(XL2400_CMD_R_REGISTER | XL2400_REG_RX_ADDR_P1, 5); + for (i = 0; i < 5; i++) { + UART1_TxHex(*(xbuf_data + i)); + } + UART1_TxString(" [RxAddrP2-P5]"); + XL2400_ReadToBuf(XL2400_CMD_R_REGISTER | XL2400_REG_RX_ADDR_P2_P5, 4); + for (i = 0; i < 4; i++) { + UART1_TxHex(*(xbuf_data + i)); + } + + UART1_TxString("\r\n[RxPloadWidth_P0-P5]"); + XL2400_ReadToBuf(XL2400_CMD_R_REGISTER | XL2400_REG_RX_PW_PX, 6); + for (i = 0; i < 6; i++) { + UART1_TxHex(*(xbuf_data + i)); + } + + UART1_TxString("\r\n[FIFO_Status]"); + XL2400_ReadToBuf(XL2400_CMD_R_REGISTER | XL2400_REG_FIFO_STATUS, 3); + for (i = 0; i < 3; i++) { + UART1_TxHex(*(xbuf_data + i)); + } + UART1_TxString(" [DynPloadWidth]"); + UART1_TxHex(XL2400_ReadReg(XL2400_CMD_R_REGISTER | XL2400_REG_DYNPD)); + UART1_TxString(" [Feature]"); + UART1_TxHex(XL2400_ReadReg(XL2400_CMD_R_REGISTER | XL2400_REG_FEATURE)); + + status = XL2400_ReadStatus(); + UART1_TxString("\r\n[Status]"); + UART1_TxHex(status); + UART1_TxString("\r\n\r\n"); + return status; +} diff --git a/demo/spi/xl2400/xl2400.h b/demo/spi/xl2400/xl2400.h new file mode 100755 index 0000000..e741c12 --- /dev/null +++ b/demo/spi/xl2400/xl2400.h @@ -0,0 +1,143 @@ +// Copyright 2021 IOsetting +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef __FW_XL2400_H__ +#define __FW_XL2400_H__ + +#include "fw_hal.h" +#include "string.h" + +#define XL2400_CSN P35 +#define XL2400_SCK P32 +#define XL2400_MOSI P34 + +#define XL2400_PLOAD_WIDTH 32 // Payload width +/** + * REGISTER TABLE + */ +/****************** SPI REGISTER ********************/ +#define XL2400_CMD_R_REGISTER 0x00 // [000A AAAA] Register read +#define XL2400_CMD_W_REGISTER 0x20 // [001A AAAA] Register write +#define XL2400_CMD_R_RX_PAYLOAD 0x61 // Read RX payload +#define XL2400_CMD_W_TX_PAYLOAD 0xA0 // Write TX payload +#define XL2400_CMD_FLUSH_TX 0xE1 // Flush TX FIFO +#define XL2400_CMD_FLUSH_RX 0xE2 // Flush RX FIFO +#define XL2400_CMD_REUSE_TX_PL 0xE3 // Reuse TX Payload +#define XL2400_CMD_ACTIVATE 0x50 // ACTIVATE +#define XL2400_CMD_DEACTIVATE 0x50 // DEACTIVATE +#define XL2400_CMD_RST_FSPI 0x53 // RESET +#define XL2400_CMD_R_RX_PL_WID 0x60 // Read width of RX data +#define XL2400_CMD_W_ACK_PAYLOAD 0xA8 // Data with ACK +#define XL2400_CMD_W_TX_PAYLOAD_NOACK 0xB0 // TX Payload no ACK Request +#define XL2400_CMD_NOP 0xFF // No operation (used for reading status register) + +/******************CONTROL REGISTER ******************/ +#define XL2400_REG_CFG_TOP 0x00 // Configuration register, 20 bits +#define XL2400_REG_EN_AA 0x01 // Enable "Auto acknowledgment" +#define XL2400_REG_EN_RXADDR 0x02 // Enable RX addresses +#define XL2400_REG_SETUP_AW 0x03 // Setup of address widths +#define XL2400_REG_SETUP_RETR 0x04 // Setup of automatic re-transmit, 30 bits +#define XL2400_REG_RF_CH 0x05 // RF channel, 22 bits +#define XL2400_REG_RF_SETUP 0x06 // RF setup, 16 bits +#define XL2400_REG_STATUS 0x07 // Status +#define XL2400_REG_OBSERVE_TX 0x08 // Transmit observe register, 32 bits +#define XL2400_REG_RSSI 0x09 // Data output and RSSI, 14 bits +#define XL2400_REG_RX_ADDR_P0 0x0A // Receive address data pipe 0, 40 bits +#define XL2400_REG_RX_ADDR_P1 0x0B // Receive address data pipe 1, 40 bits +#define XL2400_REG_RX_ADDR_P2_P5 0x0C // Receive address data pipe 2~5, 32 bits +#define XL2400_REG_BER_RESULT 0x0D // BER(PN9) test result, 64 bits +#define XL2400_REG_AGC_SETTING 0x0E // AGC settings, 32 bits +#define XL2400_REG_PGA_SETTING 0x0F // PGA settings, 39 bits +#define XL2400_REG_TX_ADDR 0x10 // Transmit address, 40 bits +#define XL2400_REG_RX_PW_PX 0x11 // Number of bytes in RX payload in data pipe 0 ~ pipe 5, 48 bits +#define XL2400_REG_ANALOG_CFG0 0x12 // Analog config 0, 128 bits +#define XL2400_REG_ANALOG_CFG1 0x13 // Analog config 1, 128 bits +#define XL2400_REG_ANALOG_CFG2 0x14 // Analog config 2, 128 bits +#define XL2400_REG_ANALOG_CFG3 0x15 // Analog config 3, 128 bits +#define XL2400_REG_FIFO_STATUS 0x17 // FIFO status, 20 bits +#define XL2400_REG_RSSIREC 0x18 // RSSI recorder feature, 32 bits +#define XL2400_REG_TXPROC_CFG 0x19 // TX Process configuration, 29 bits +#define XL2400_REG_RXPROC_CFG 0x1A // RX Process configuration, 40 bits +#define XL2400_REG_DYNPD 0x1C // Enable dynamic payload length +#define XL2400_REG_FEATURE 0x1D // Feature config +#define XL2400_REG_RAMP_CFG 0x1E // PA Ramp Configuration, 88 bits + + +/**************************** CONFIGs ************************************/ + +#define XL2400_PL_WIDTH_MAX 64 // Max payload width +#define XL2400_RF_10DB 0x3F +#define XL2400_RF_9DB 0x38 +#define XL2400_RF_8DB 0x34 +#define XL2400_RF_7DB 0x30 +#define XL2400_RF_6DB 0x2C // 250Kbps Maximum +#define XL2400_RF_5DB 0x28 +#define XL2400_RF_4DB 0x24 +#define XL2400_RF_3DB 0x20 +#define XL2400_RF_2DB 0x14 +#define XL2400_RF_0DB 0x10 // 1Mbps Maximum +#define XL2400_RF__2DB 0x0C +#define XL2400_RF__6DB 0x08 +#define XL2400_RF__12DB 0x04 +#define XL2400_RF__18DB 0x02 +#define XL2400_RF__24DB 0x01 +#define XL2400_RF_DR_1M 0x02 // 1Mbps +#define XL2400_RF_DR_250K 0x22 // 250Kbps + +#define RX_DR_FLAG 0X40 // Data ready +#define TX_DS_FLAG 0X20 // Data sent +#define RX_TX_CMP_FLAG 0X60 // Data sent & acked +#define MAX_RT_FLAG 0X10 // Max retried + +#define XL2400_TEST_ADDR "XL240" + + +/******************* FUNCTION DECLARE *******************/ +void XL2400_WriteReg(uint8_t reg, uint8_t value); +uint8_t XL2400_ReadReg(uint8_t reg); + +void XL2400_WriteFromBuf(uint8_t reg, const uint8_t *pBuf, uint8_t len); +void XL2400_ReadToBuf(uint8_t reg, uint8_t len); +void XL2400_WriteBack(uint8_t reg, uint8_t len); + +void XL2400_CE_Low(void); +void XL2400_CE_High(void); + +uint8_t XL2400_SPI_Test(void); + +void XL2400_Init(void); +void XL2400_SetChannel(uint8_t channel); + +void XL2400_SetTxAddress(uint8_t *address); +void XL2400_SetRxAddress(uint8_t *address); +void XL2400_SetPower(uint8_t power); + +void XL2400_Sleep(void); +void XL2400_WakeUp(void); + +uint8_t XL2400_RxCalibrate(void); + +void XL2400_SetTxMode(void); +void XL2400_SetRxMode(void); + +uint8_t XL2400_Tx(uint8_t *ucPayload, uint8_t length); +uint8_t XL2400_Rx(void); + +uint8_t XL2400_ReadStatus(void); +void XL2400_ClearStatus(void); +void XL2400_FlushRxTX(void); +void XL2400_CarrierTest(void); +uint8_t XL2400_PrintStatus(void); + +#endif