Skip to content
Commits on Source (2)
......@@ -831,52 +831,111 @@ static int si4463_packetconfig(FAR struct si4463_dev_s *dev)
_info("Configuring packet handler\n");
/* Configure CRC */
ret = si4463_setprop_byte(dev, SI4463_PROP_PKT_CRC_CONFIG,
PKT_CRC_CONFIG_SEED_FFFF |
PKT_CRC_CONFIG_POLY_CCITT_16);
do
{
/* Configure CRC */
ret = si4463_setprop_byte(dev, SI4463_PROP_PKT_CONFIG1,
PKT_CONFIG1_CRC_INVERT);
ret = si4463_setprop_byte(dev, SI4463_PROP_PKT_CRC_CONFIG,
PKT_CRC_CONFIG_SEED_FFFF |
PKT_CRC_CONFIG_POLY_CCITT_16);
if(ret != 0)
{
break;
}
ret = si4463_setprop_byte(dev, SI4463_PROP_PKT_CONFIG1,
PKT_CONFIG1_CRC_INVERT);
if(ret != 0)
{
break;
}
/* Configure field 1 as a one or two bytes length field */
/* Configure field 1 as a one or two bytes length field */
#if defined( CONFIG_GENERICRADIO_SI4463_FRAMING_L1 )
ret = si4463_setprop_short(dev, SI4463_PROP_PKT_FIELD_1_LENGTH_0, 1);
ret = si4463_setprop_short(dev, SI4463_PROP_PKT_FIELD_1_LENGTH_0, 1);
#elif defined( CONFIG_GENERICRADIO_SI4463_FRAMING_L2B ) || \
defined( CONFIG_GENERICRADIO_SI4463_FRAMING_L2L )
ret = si4463_setprop_short(dev, SI4463_PROP_PKT_FIELD_1_LENGTH_0, 2);
ret = si4463_setprop_short(dev, SI4463_PROP_PKT_FIELD_1_LENGTH_0, 2);
#endif
if(ret != 0)
{
break;
}
ret = si4463_setprop_byte(dev, SI4463_PROP_PKT_FIELD_1_CONFIG, 0);
ret = si4463_setprop_byte(dev, SI4463_PROP_PKT_FIELD_1_CRC_CONFIG,
PKT_FIELD_CRC_CONFIG_START |
PKT_FIELD_CRC_CONFIG_ENABLE );
ret = si4463_setprop_byte(dev, SI4463_PROP_PKT_FIELD_1_CONFIG, 0);
if(ret != 0)
{
break;
}
ret = si4463_setprop_byte(dev, SI4463_PROP_PKT_FIELD_1_CRC_CONFIG,
PKT_FIELD_CRC_CONFIG_START |
PKT_FIELD_CRC_CONFIG_ENABLE );
if(ret != 0)
{
break;
}
/* Configure field 2 - length will be set before tx */
ret = si4463_setprop_short(dev, SI4463_PROP_PKT_FIELD_2_LENGTH_0, 1);
ret = si4463_setprop_byte(dev, SI4463_PROP_PKT_FIELD_2_CONFIG, 0);
ret = si4463_setprop_byte(dev, SI4463_PROP_PKT_FIELD_2_CRC_CONFIG,
PKT_FIELD_CRC_CONFIG_ENABLE |
PKT_FIELD_CRC_CONFIG_CHECK |
PKT_FIELD_CRC_CONFIG_SEND);
ret = si4463_setprop_short(dev, SI4463_PROP_PKT_FIELD_2_LENGTH_0, 1);
if(ret != 0)
{
break;
}
ret = si4463_setprop_byte(dev, SI4463_PROP_PKT_FIELD_2_CONFIG, 0);
if(ret != 0)
{
break;
}
ret = si4463_setprop_byte(dev, SI4463_PROP_PKT_FIELD_2_CRC_CONFIG,
PKT_FIELD_CRC_CONFIG_ENABLE |
PKT_FIELD_CRC_CONFIG_CHECK |
PKT_FIELD_CRC_CONFIG_SEND);
if(ret != 0)
{
break;
}
/* Disable fields 3-5 */
ret = si4463_setprop_short(dev, SI4463_PROP_PKT_FIELD_3_LENGTH_0, 0);
ret = si4463_setprop_short(dev, SI4463_PROP_PKT_FIELD_3_LENGTH_0, 0);
if(ret != 0)
{
break;
}
/* Configure rx length: in field 1, defines length of field 2. */
#if defined( CONFIG_GENERICRADIO_SI4463_FRAMING_L1 )
ret = si4463_setprop_byte(dev, SI4463_PROP_PKT_LEN, 2 | PKT_LEN_IN_FIFO |
PKT_LEN_SIZE_1);
ret = si4463_setprop_byte(dev, SI4463_PROP_PKT_LEN, 2 | PKT_LEN_IN_FIFO |
PKT_LEN_SIZE_1);
#elif defined( CONFIG_GENERICRADIO_SI4463_FRAMING_L2B )
ret = si4463_setprop_byte(dev, SI4463_PROP_PKT_LEN, 2 | PKT_LEN_IN_FIFO |
PKT_LEN_SIZE_2 | PKT_LEN_ENDIAN_BIG);
ret = si4463_setprop_byte(dev, SI4463_PROP_PKT_LEN, 2 | PKT_LEN_IN_FIFO |
PKT_LEN_SIZE_2 | PKT_LEN_ENDIAN_BIG);
#elif defined( CONFIG_GENERICRADIO_SI4463_FRAMING_L2L )
ret = si4463_setprop_byte(dev, SI4463_PROP_PKT_LEN, 2 | PKT_LEN_IN_FIFO |
PKT_LEN_SIZE_2 | PKT_LEN_ENDIAN_LIL);
ret = si4463_setprop_byte(dev, SI4463_PROP_PKT_LEN, 2 | PKT_LEN_IN_FIFO |
PKT_LEN_SIZE_2 | PKT_LEN_ENDIAN_LIL);
#endif
ret = si4463_setprop_byte(dev, SI4463_PROP_PKT_LEN_FIELD_SOURCE, 1);
ret = si4463_setprop_byte(dev, SI4463_PROP_PKT_LEN_ADJUST, 0);
if(ret != 0)
{
break;
}
ret = si4463_setprop_byte(dev, SI4463_PROP_PKT_LEN_FIELD_SOURCE, 1);
if(ret != 0)
{
break;
}
ret = si4463_setprop_byte(dev, SI4463_PROP_PKT_LEN_ADJUST, 0);
}
while(0);
if(ret != 0)
{
_err("something failed\n", ret);
}
return ret;
}
......@@ -897,10 +956,10 @@ static int si4463_initialize(FAR struct si4463_dev_s *dev,
int ret;
#ifndef CONFIG_GENERICRADIO_SI4463_USE_WDS_CONFIG
uint8_t regs[2];
struct si4463_cmdrsp_gpiopincfg_s gpio;
struct si4463_cmd_pwrup_s pwrup;
int i;
#endif
int i;
struct si4463_cmdrsp_gpiopincfg_s gpio;
struct si4463_rsp_partinfo_s part;
struct si4463_rsp_funcinfo_s func;
uint16_t vbat, temp;
......@@ -1026,6 +1085,7 @@ static int si4463_initialize(FAR struct si4463_dev_s *dev,
_err("Could not define GLOBAL XO TUNE (errno %d)\n", ret);
return ret;
}
//#endif //CONFIG_GENERICRADIO_SI4463_USE_WDS_CONFIG
/* Configure PA/LNA pins and IRQ line */
......@@ -1033,8 +1093,8 @@ static int si4463_initialize(FAR struct si4463_dev_s *dev,
{
gpio.gpio[i] = PINCFG_DONOTHING;
}
gpio.gpio[papin ] = PINCFG_EN_PA;
gpio.gpio[lnapin] = PINCFG_EN_LNA;
gpio.gpio[papin ] = PINCFG_EN_PA | PINCFG_PULL_EN;
gpio.gpio[lnapin] = PINCFG_EN_LNA | PINCFG_PULL_EN;
gpio.nirq = PINCFG_NIRQ_NIRQ;
gpio.sdo = PINCFG_DONOTHING;
gpio.genconfig = DRV_STRENGTH_HIGH;
......@@ -1053,6 +1113,7 @@ static int si4463_initialize(FAR struct si4463_dev_s *dev,
return ret;
}
//#ifndef CONFIG_GENERICRADIO_SI4463_USE_WDS_CONFIG
/* Setup global config */
_info("global config...\n");
......@@ -1115,13 +1176,51 @@ static int si4463_initialize(FAR struct si4463_dev_s *dev,
ret = si4463_setprop_byte(dev, SI4463_PROP_FRR_CTL_A_MODE, FRR_INT_PH_PEND);
_info("Configure Interrupts\n");
#if 1
/* Setup IRQs: TX complete, data received, RX complete, RX error. */
ret = si4463_setprop_byte(dev, SI4463_PROP_INT_CTL_ENABLE, INT_CTL_PH_INT);
ret = si4463_setprop_byte(dev, SI4463_PROP_INT_CTL_PH_ENABLE,
if(ret != 0)
{
_err("SI4463_PROP_INT_CTL_ENABLE failed\n", ret);
return ret;
}
ret = si4463_setprop_byte(dev, SI4463_PROP_INT_CTL_PH_ENABLE,
INT_CTL_PH_RX_FIFO_ALMOST_FULL |
INT_CTL_PH_PACKET_RX |
INT_CTL_PH_PACKET_SENT |
INT_CTL_PH_CRC_ERROR);
if(ret != 0)
{
_err("SI4463_PROP_INT_CTL_PH_ENABLE failed\n", ret);
return ret;
}
#else
ret = si4463_setprop_byte(dev, SI4463_PROP_INT_CTL_ENABLE, INT_CTL_PH_INT | INT_CTL_CHIP_INT | INT_CTL_MODEM_INT);
if(ret != 0)
{
_err("SI4463_PROP_INT_CTL_ENABLE failed\n", ret);
return ret;
}
ret = si4463_setprop_byte(dev, SI4463_PROP_INT_CTL_PH_ENABLE, 0xFB);
if(ret != 0)
{
_err("SI4463_PROP_INT_CTL_PH_ENABLE failed\n", ret);
return ret;
}
ret = si4463_setprop_byte(dev, SI4463_PROP_INT_CTL_MODEM_ENABLE, 0xFF);
if(ret != 0)
{
_err("SI4463_PROP_INT_CTL_MODEM_ENABLE failed\n", ret);
return ret;
}
ret = si4463_setprop_byte(dev, SI4463_PROP_INT_CTL_CHIP_ENABLE, 0x7F);
if(ret != 0)
{
_err("SI4463_PROP_INT_CTL_CHIP_ENABLE failed\n", ret);
return ret;
}
#endif
return ret; /* OK */
}
......@@ -1977,13 +2076,28 @@ static int si4463_rxenable(FAR struct genradio_dev_s *dev, int state)
/* enable RX interrupts */
/* Setup field 2 length to the MAX receivable length */
ret = si4463_setprop_short(priv, SI4463_PROP_PKT_FIELD_2_LENGTH_0, 0x1FFF);
if(ret != 0)
{
_err("failed to set field 2 to max length\n");
return ret;
}
/* Go to RX state */
cmd_rx.channel = dev->channel;
cmd_rx.condition = STARTRX_CONDITION_IMMEDIATE;
cmd_rx.rx_len = 0;
#if 1
cmd_rx.next_state1 = STARTRX_STATE_READY;
cmd_rx.next_state2 = STARTRX_STATE_READY;
cmd_rx.next_state3 = STARTRX_STATE_READY;
#else
cmd_rx.next_state1 = STARTRX_STATE_RX;
cmd_rx.next_state2 = STARTRX_STATE_READY;
cmd_rx.next_state3 = STARTRX_STATE_READY;
#endif
/* Prepare reception state: no bytes received yet (in public and private states)*/
dev ->rxdone = 0;
......@@ -2015,37 +2129,33 @@ static int si4463_rxenable(FAR struct genradio_dev_s *dev, int state)
static void si4463_irqworker(FAR void *arg)
{
struct si4463_dev_s *priv = (struct si4463_dev_s*)arg;
uint8_t ph;
uint8_t ph,mo,ch;
volatile int ret;
/* Get IRQ status */
ret = si4463_getintstatus(priv, &ph, NULL, NULL);
ret = si4463_getintstatus(priv, &ph, &mo, &ch);
if(ret != 0)
{
_err("CRITICAL: Could not read interrupt flags\n");
goto done;
}
_info("!%02X %02X %02X\n", ph,mo,ch);
/* Dispatch */
if( (ph & INTSTATUS_PH_PACKET_SENT) == INTSTATUS_PH_PACKET_SENT)
{
int val,ret;
_info("!txc\n");
priv->genradio.txstatus = 0;
nxsem_post(&priv->genradio.txsem);
ret = nxsem_getvalue(&priv->genradio.txsem, &val);
if (ret == OK && val <= 0)
{
nxsem_post(&priv->genradio.txsem);
}
}
if( (ph & INTSTATUS_PH_PACKET_RX) == INTSTATUS_PH_PACKET_RX)
{
/* Packet reception is complete */
_info("!rxc\n");
priv->genradio.rxlen = priv->genradio.rxdone;
lrxdone:
nxsem_post(&priv->genradio.rxsem);
ret = si4463_changestate(priv, NEWSTATE_READY);
}
if( (ph & INTSTATUS_PH_RX_FIFO_ALMOST_FULL) == INTSTATUS_PH_RX_FIFO_ALMOST_FULL)
{
/* RX data is available, take it from fifo and store in target buf*/
......@@ -2125,11 +2235,87 @@ lrxdone:
}
}
if( (ph & INTSTATUS_PH_PACKET_RX) == INTSTATUS_PH_PACKET_RX)
{
int val,ret;
/* Packet reception is complete. TODO read RSSI */
_info("!rxc\n");
priv->genradio.rxlen = priv->genradio.rxdone;
/* Signal the RX waiter semaphore ONLY if it's locked */
ret = nxsem_getvalue(&priv->genradio.rxsem, &val);
if (ret == OK && val <= 0)
{
nxsem_post(&priv->genradio.rxsem);
}
ret = si4463_changestate(priv, NEWSTATE_READY);
}
if( (ph & INTSTATUS_PH_CRC_ERROR) == INTSTATUS_PH_CRC_ERROR)
{
int val,ret;
_info("!crc\n");
priv->genradio.rxlen = -EIO;
goto lrxdone;
/* Signal the RX waiter semaphore ONLY if it's locked */
ret = nxsem_getvalue(&priv->genradio.rxsem, &val);
if (ret == OK && val <= 0)
{
nxsem_post(&priv->genradio.rxsem);
}
ret = si4463_changestate(priv, NEWSTATE_READY);
}
//modem ints
if( (mo & INTSTATUS_MODEM_SYNC_DETECT) == INTSTATUS_MODEM_SYNC_DETECT)
{
_info("!sync\n");
}
if( (mo & INTSTATUS_MODEM_PREAMBLE_DETECT) == INTSTATUS_MODEM_PREAMBLE_DETECT)
{
_info("!pre\n");
}
if( (mo & INTSTATUS_MODEM_INVALID_PREAMBLE) == INTSTATUS_MODEM_INVALID_PREAMBLE)
{
_info("!badpre\n");
}
if( (mo & INTSTATUS_MODEM_RSSI) == INTSTATUS_MODEM_RSSI)
{
_info("!rssi\n");
}
if( (mo & INTSTATUS_MODEM_RSSI_JUMP) == INTSTATUS_MODEM_RSSI_JUMP)
{
_info("!rssijmp\n");
}
if( (mo & INTSTATUS_MODEM_INVALID_SYNC) == INTSTATUS_MODEM_INVALID_SYNC)
{
_info("!badsync\n");
}
if( (mo & INTSTATUS_MODEM_POSTAMBLE_DETECT) == INTSTATUS_MODEM_POSTAMBLE_DETECT)
{
_info("!post\n");
}
//chip ints
if( (ch & INTSTATUS_CHIP_CAL) == INTSTATUS_CHIP_CAL)
{
_info("!cal\n");
}
if( (ch & INTSTATUS_CHIP_FIFO_UNDEROVERFLOW) == INTSTATUS_CHIP_FIFO_UNDEROVERFLOW)
{
_info("!fiflow\n");
}
if( (ch & INTSTATUS_CHIP_STATE_CHANGE) == INTSTATUS_CHIP_STATE_CHANGE)
{
_info("!state change\n");
}
if( (ch & INTSTTAUS_CHIP_CMD_ERROR) == INTSTTAUS_CHIP_CMD_ERROR)
{
_info("!cmderr\n");
}
if( (ch & INTSTATUS_CHIP_READY) == INTSTATUS_CHIP_READY)
{
_info("!rdy\n");
}
done:
......@@ -2227,6 +2413,7 @@ static void si4463_transmit(FAR struct genradio_dev_s *dev,
}
/* Special CW mode is now managed, now manage normal packet transmission. */
/* Process is:
* While packet is not complete:
* Get room in tx fifo
......@@ -2238,7 +2425,7 @@ static void si4463_transmit(FAR struct genradio_dev_s *dev,
/* First of all go to the READY state */
//_info("tx start: channel %d\n", dev->channel);
ret = si4463_changestate(priv, NEWSTATE_SPI_ACTIVE);
ret = si4463_changestate(priv, NEWSTATE_READY);
if (ret != 0)
{
_err("change state failed: %d\n", ret);
......
......@@ -112,10 +112,10 @@ FAR struct genradio_dev_s *si4463_init(FAR struct spi_dev_s *spi, int devnum,
/* these wrappers can be used to initialize radio modules with known xtals */
static inline FAR struct genradio_dev_s *
RFM26_init(FAR struct spi_dev_s *spi, int devnum, int txpin, int rxpin,
RFM26_init(FAR struct spi_dev_s *spi, int devnum, int papin, int lnapin,
FAR const struct si4463_lower_s *lower)
{
return si4463_init(spi, devnum, 30000000, txpin, rxpin, lower);
return si4463_init(spi, devnum, 30000000, papin, lnapin, lower);
}
......