Skip to content
Commits on Source (2)
...@@ -831,52 +831,111 @@ static int si4463_packetconfig(FAR struct si4463_dev_s *dev) ...@@ -831,52 +831,111 @@ static int si4463_packetconfig(FAR struct si4463_dev_s *dev)
_info("Configuring packet handler\n"); _info("Configuring packet handler\n");
/* Configure CRC */ do
ret = si4463_setprop_byte(dev, SI4463_PROP_PKT_CRC_CONFIG, {
PKT_CRC_CONFIG_SEED_FFFF | /* Configure CRC */
PKT_CRC_CONFIG_POLY_CCITT_16);
ret = si4463_setprop_byte(dev, SI4463_PROP_PKT_CONFIG1, ret = si4463_setprop_byte(dev, SI4463_PROP_PKT_CRC_CONFIG,
PKT_CONFIG1_CRC_INVERT); 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 ) #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 ) || \ #elif defined( CONFIG_GENERICRADIO_SI4463_FRAMING_L2B ) || \
defined( CONFIG_GENERICRADIO_SI4463_FRAMING_L2L ) 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 #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_CONFIG, 0);
ret = si4463_setprop_byte(dev, SI4463_PROP_PKT_FIELD_1_CRC_CONFIG, if(ret != 0)
PKT_FIELD_CRC_CONFIG_START | {
PKT_FIELD_CRC_CONFIG_ENABLE ); 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 */ /* 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_short(dev, SI4463_PROP_PKT_FIELD_2_LENGTH_0, 1);
ret = si4463_setprop_byte(dev, SI4463_PROP_PKT_FIELD_2_CONFIG, 0); if(ret != 0)
ret = si4463_setprop_byte(dev, SI4463_PROP_PKT_FIELD_2_CRC_CONFIG, {
PKT_FIELD_CRC_CONFIG_ENABLE | break;
PKT_FIELD_CRC_CONFIG_CHECK | }
PKT_FIELD_CRC_CONFIG_SEND);
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 */ /* 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. */ /* Configure rx length: in field 1, defines length of field 2. */
#if defined( CONFIG_GENERICRADIO_SI4463_FRAMING_L1 ) #if defined( CONFIG_GENERICRADIO_SI4463_FRAMING_L1 )
ret = si4463_setprop_byte(dev, SI4463_PROP_PKT_LEN, 2 | PKT_LEN_IN_FIFO | ret = si4463_setprop_byte(dev, SI4463_PROP_PKT_LEN, 2 | PKT_LEN_IN_FIFO |
PKT_LEN_SIZE_1); PKT_LEN_SIZE_1);
#elif defined( CONFIG_GENERICRADIO_SI4463_FRAMING_L2B ) #elif defined( CONFIG_GENERICRADIO_SI4463_FRAMING_L2B )
ret = si4463_setprop_byte(dev, SI4463_PROP_PKT_LEN, 2 | PKT_LEN_IN_FIFO | ret = si4463_setprop_byte(dev, SI4463_PROP_PKT_LEN, 2 | PKT_LEN_IN_FIFO |
PKT_LEN_SIZE_2 | PKT_LEN_ENDIAN_BIG); PKT_LEN_SIZE_2 | PKT_LEN_ENDIAN_BIG);
#elif defined( CONFIG_GENERICRADIO_SI4463_FRAMING_L2L ) #elif defined( CONFIG_GENERICRADIO_SI4463_FRAMING_L2L )
ret = si4463_setprop_byte(dev, SI4463_PROP_PKT_LEN, 2 | PKT_LEN_IN_FIFO | ret = si4463_setprop_byte(dev, SI4463_PROP_PKT_LEN, 2 | PKT_LEN_IN_FIFO |
PKT_LEN_SIZE_2 | PKT_LEN_ENDIAN_LIL); PKT_LEN_SIZE_2 | PKT_LEN_ENDIAN_LIL);
#endif #endif
ret = si4463_setprop_byte(dev, SI4463_PROP_PKT_LEN_FIELD_SOURCE, 1); if(ret != 0)
ret = si4463_setprop_byte(dev, SI4463_PROP_PKT_LEN_ADJUST, 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; return ret;
} }
...@@ -897,10 +956,10 @@ static int si4463_initialize(FAR struct si4463_dev_s *dev, ...@@ -897,10 +956,10 @@ static int si4463_initialize(FAR struct si4463_dev_s *dev,
int ret; int ret;
#ifndef CONFIG_GENERICRADIO_SI4463_USE_WDS_CONFIG #ifndef CONFIG_GENERICRADIO_SI4463_USE_WDS_CONFIG
uint8_t regs[2]; uint8_t regs[2];
struct si4463_cmdrsp_gpiopincfg_s gpio;
struct si4463_cmd_pwrup_s pwrup; struct si4463_cmd_pwrup_s pwrup;
int i;
#endif #endif
int i;
struct si4463_cmdrsp_gpiopincfg_s gpio;
struct si4463_rsp_partinfo_s part; struct si4463_rsp_partinfo_s part;
struct si4463_rsp_funcinfo_s func; struct si4463_rsp_funcinfo_s func;
uint16_t vbat, temp; uint16_t vbat, temp;
...@@ -1026,6 +1085,7 @@ static int si4463_initialize(FAR struct si4463_dev_s *dev, ...@@ -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); _err("Could not define GLOBAL XO TUNE (errno %d)\n", ret);
return ret; return ret;
} }
//#endif //CONFIG_GENERICRADIO_SI4463_USE_WDS_CONFIG
/* Configure PA/LNA pins and IRQ line */ /* Configure PA/LNA pins and IRQ line */
...@@ -1033,8 +1093,8 @@ static int si4463_initialize(FAR struct si4463_dev_s *dev, ...@@ -1033,8 +1093,8 @@ static int si4463_initialize(FAR struct si4463_dev_s *dev,
{ {
gpio.gpio[i] = PINCFG_DONOTHING; gpio.gpio[i] = PINCFG_DONOTHING;
} }
gpio.gpio[papin ] = PINCFG_EN_PA; gpio.gpio[papin ] = PINCFG_EN_PA | PINCFG_PULL_EN;
gpio.gpio[lnapin] = PINCFG_EN_LNA; gpio.gpio[lnapin] = PINCFG_EN_LNA | PINCFG_PULL_EN;
gpio.nirq = PINCFG_NIRQ_NIRQ; gpio.nirq = PINCFG_NIRQ_NIRQ;
gpio.sdo = PINCFG_DONOTHING; gpio.sdo = PINCFG_DONOTHING;
gpio.genconfig = DRV_STRENGTH_HIGH; gpio.genconfig = DRV_STRENGTH_HIGH;
...@@ -1053,6 +1113,7 @@ static int si4463_initialize(FAR struct si4463_dev_s *dev, ...@@ -1053,6 +1113,7 @@ static int si4463_initialize(FAR struct si4463_dev_s *dev,
return ret; return ret;
} }
//#ifndef CONFIG_GENERICRADIO_SI4463_USE_WDS_CONFIG
/* Setup global config */ /* Setup global config */
_info("global config...\n"); _info("global config...\n");
...@@ -1115,13 +1176,51 @@ static int si4463_initialize(FAR struct si4463_dev_s *dev, ...@@ -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); ret = si4463_setprop_byte(dev, SI4463_PROP_FRR_CTL_A_MODE, FRR_INT_PH_PEND);
_info("Configure Interrupts\n"); _info("Configure Interrupts\n");
#if 1
/* Setup IRQs: TX complete, data received, RX complete, RX error. */ /* 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_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_RX_FIFO_ALMOST_FULL |
INT_CTL_PH_PACKET_RX | INT_CTL_PH_PACKET_RX |
INT_CTL_PH_PACKET_SENT | INT_CTL_PH_PACKET_SENT |
INT_CTL_PH_CRC_ERROR); 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 */ return ret; /* OK */
} }
...@@ -1977,13 +2076,28 @@ static int si4463_rxenable(FAR struct genradio_dev_s *dev, int state) ...@@ -1977,13 +2076,28 @@ static int si4463_rxenable(FAR struct genradio_dev_s *dev, int state)
/* enable RX interrupts */ /* 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 */ /* Go to RX state */
cmd_rx.channel = dev->channel; cmd_rx.channel = dev->channel;
cmd_rx.condition = STARTRX_CONDITION_IMMEDIATE; cmd_rx.condition = STARTRX_CONDITION_IMMEDIATE;
cmd_rx.rx_len = 0; cmd_rx.rx_len = 0;
#if 1
cmd_rx.next_state1 = STARTRX_STATE_READY; cmd_rx.next_state1 = STARTRX_STATE_READY;
cmd_rx.next_state2 = STARTRX_STATE_READY; cmd_rx.next_state2 = STARTRX_STATE_READY;
cmd_rx.next_state3 = 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)*/ /* Prepare reception state: no bytes received yet (in public and private states)*/
dev ->rxdone = 0; dev ->rxdone = 0;
...@@ -2015,37 +2129,33 @@ static int si4463_rxenable(FAR struct genradio_dev_s *dev, int state) ...@@ -2015,37 +2129,33 @@ static int si4463_rxenable(FAR struct genradio_dev_s *dev, int state)
static void si4463_irqworker(FAR void *arg) static void si4463_irqworker(FAR void *arg)
{ {
struct si4463_dev_s *priv = (struct si4463_dev_s*)arg; struct si4463_dev_s *priv = (struct si4463_dev_s*)arg;
uint8_t ph; uint8_t ph,mo,ch;
volatile int ret; volatile int ret;
/* Get IRQ status */ /* Get IRQ status */
ret = si4463_getintstatus(priv, &ph, NULL, NULL); ret = si4463_getintstatus(priv, &ph, &mo, &ch);
if(ret != 0) if(ret != 0)
{ {
_err("CRITICAL: Could not read interrupt flags\n"); _err("CRITICAL: Could not read interrupt flags\n");
goto done; goto done;
} }
_info("!%02X %02X %02X\n", ph,mo,ch);
/* Dispatch */ /* Dispatch */
if( (ph & INTSTATUS_PH_PACKET_SENT) == INTSTATUS_PH_PACKET_SENT) if( (ph & INTSTATUS_PH_PACKET_SENT) == INTSTATUS_PH_PACKET_SENT)
{ {
int val,ret;
_info("!txc\n"); _info("!txc\n");
priv->genradio.txstatus = 0; 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) 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*/ /* RX data is available, take it from fifo and store in target buf*/
...@@ -2125,11 +2235,87 @@ lrxdone: ...@@ -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) if( (ph & INTSTATUS_PH_CRC_ERROR) == INTSTATUS_PH_CRC_ERROR)
{ {
int val,ret;
_info("!crc\n"); _info("!crc\n");
priv->genradio.rxlen = -EIO; 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: done:
...@@ -2227,6 +2413,7 @@ static void si4463_transmit(FAR struct genradio_dev_s *dev, ...@@ -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. */ /* Special CW mode is now managed, now manage normal packet transmission. */
/* Process is: /* Process is:
* While packet is not complete: * While packet is not complete:
* Get room in tx fifo * Get room in tx fifo
...@@ -2238,7 +2425,7 @@ static void si4463_transmit(FAR struct genradio_dev_s *dev, ...@@ -2238,7 +2425,7 @@ static void si4463_transmit(FAR struct genradio_dev_s *dev,
/* First of all go to the READY state */ /* First of all go to the READY state */
//_info("tx start: channel %d\n", dev->channel); //_info("tx start: channel %d\n", dev->channel);
ret = si4463_changestate(priv, NEWSTATE_SPI_ACTIVE); ret = si4463_changestate(priv, NEWSTATE_READY);
if (ret != 0) if (ret != 0)
{ {
_err("change state failed: %d\n", ret); _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, ...@@ -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 */ /* these wrappers can be used to initialize radio modules with known xtals */
static inline FAR struct genradio_dev_s * 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) 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);
} }
......