feat: add xl2400(wl2400) 2.4g rf demo
This commit is contained in:
parent
99ec59be12
commit
ad3568c2cf
140
demo/spi/xl2400/main.c
Normal file
140
demo/spi/xl2400/main.c
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
// Copyright 2021 IOsetting <iosetting(at)outlook.com>
|
||||||
|
//
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
401
demo/spi/xl2400/xl2400.c
Executable file
401
demo/spi/xl2400/xl2400.c
Executable file
@ -0,0 +1,401 @@
|
|||||||
|
// Copyright 2021 IOsetting <iosetting(at)outlook.com>
|
||||||
|
//
|
||||||
|
// 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;
|
||||||
|
}
|
143
demo/spi/xl2400/xl2400.h
Executable file
143
demo/spi/xl2400/xl2400.h
Executable file
@ -0,0 +1,143 @@
|
|||||||
|
// Copyright 2021 IOsetting <iosetting(at)outlook.com>
|
||||||
|
//
|
||||||
|
// 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
|
Loading…
Reference in New Issue
Block a user