Skip to content

Improve robustness of the library #3

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=STM32duino S2-LP
version=1.0.0
version=1.0.1
author=SRA
maintainer=stm32duino
sentence=This library includes drivers for ST S2-LP sub-1GHz transceiver.
Expand Down
128 changes: 79 additions & 49 deletions src/S2LP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,13 @@
* @param csn the spi chip select pin
* @param sdn the shutdown pin
* @param irqn the pin to receive IRQ event
* @param irq_gpio the S2-LP gpio used to receive the IRQ events
* @param frequency the base carrier frequency in Hz
* @param xtalFrequency the crystal oscillator frequency
* @param paInfo information about external power amplifier
* @param irq_gpio the S2-LP gpio used to receive the IRQ events
* @param my_addr address of the device
* @param multicast_addr multicast address
* @param broadcast_addr broadcast address
*/
S2LP::S2LP(SPIClass *spi, int csn, int sdn, int irqn, uint32_t frequency, uint32_t xtalFrequency, PAInfo_t paInfo, S2LPGpioPin irq_gpio, uint8_t my_addr, uint8_t multicast_addr, uint8_t broadcast_addr) : dev_spi(spi), csn_pin(csn), sdn_pin(sdn), irq_pin(irqn), lFrequencyBase(frequency), s_lXtalFrequency(xtalFrequency), s_paInfo(paInfo), irq_gpio_selected(irq_gpio), my_address(my_addr), multicast_address(multicast_addr), broadcast_address(broadcast_addr)
{
Expand All @@ -80,8 +85,11 @@ S2LP::S2LP(SPIClass *spi, int csn, int sdn, int irqn, uint32_t frequency, uint32
current_event_callback = NULL;
nr_of_irq_disabled = 0;
xTxDoneFlag = RESET;
memset((void *)vectcRxBuff, FIFO_SIZE, sizeof(uint8_t));
memset((void *)vectcRxBuff, 0, FIFO_SIZE*sizeof(uint8_t));
memset((void *)vectcTxBuff, 0, FIFO_SIZE*sizeof(uint8_t));
cRxData = 0;
is_waiting_for_read = false;
is_tx_done_before_read = false;
}

/**
Expand All @@ -106,40 +114,21 @@ void S2LP::begin(void)
S2LPCmdStrobeSres();

SGpioInit xGpioIRQ={
S2LP_GPIO_3,
irq_gpio_selected,
S2LP_GPIO_MODE_DIGITAL_OUTPUT_LP,
S2LP_GPIO_DIG_OUT_IRQ
};

switch(irq_gpio_selected)
{
case S2LP_GPIO_0:
xGpioIRQ.xS2LPGpioPin = S2LP_GPIO_0;
break;
case S2LP_GPIO_1:
xGpioIRQ.xS2LPGpioPin = S2LP_GPIO_1;
break;
case S2LP_GPIO_2:
xGpioIRQ.xS2LPGpioPin = S2LP_GPIO_2;
break;
case S2LP_GPIO_3:
xGpioIRQ.xS2LPGpioPin = S2LP_GPIO_3;
default:
break;
}

S2LPGpioInit(&xGpioIRQ);

SRadioInit xRadioInit = {
868000000, /* base carrier frequency */
MOD_2FSK, /* modulation type */
DATARATE, /* data rate */
20000, /* frequency deviation */
100000 /* bandwidth */
lFrequencyBase, /* base carrier frequency */
MOD_2FSK, /* modulation type */
DATARATE, /* data rate */
20000, /* frequency deviation */
100000 /* bandwidth */
};

xRadioInit.lFrequencyBase = lFrequencyBase;

S2LPRadioInit(&xRadioInit);

S2LPRadioSetMaxPALevel(S_DISABLE);
Expand Down Expand Up @@ -278,8 +267,11 @@ void S2LP::end(void)
current_event_callback = NULL;
nr_of_irq_disabled = 0;
xTxDoneFlag = RESET;
memset((void *)vectcRxBuff, FIFO_SIZE, sizeof(uint8_t));
memset((void *)vectcRxBuff, 0, FIFO_SIZE*sizeof(uint8_t));
memset((void *)vectcTxBuff, 0, FIFO_SIZE*sizeof(uint8_t));
cRxData = 0;
is_waiting_for_read = false;
is_tx_done_before_read = false;
}

/**
Expand Down Expand Up @@ -314,7 +306,11 @@ uint8_t S2LP::send(uint8_t *payload, uint8_t payload_len, uint8_t dest_addr, boo
disableS2LPIrq();

/* Go to Ready mode */
S2LPSetReadyState();
if(S2LPSetReadyState())
{
enableS2LPIrq();
return 1;
}

/* Disable LDC */
S2LPTimerLdcrMode(S_DISABLE);
Expand Down Expand Up @@ -349,7 +345,7 @@ uint8_t S2LP::send(uint8_t *payload, uint8_t payload_len, uint8_t dest_addr, boo
do
{
current_time = millis();
} while(!xTxDoneFlag && (current_time - start_time) <= 3000);
} while(!xTxDoneFlag && (current_time - start_time) <= 1000);

if(use_csma_ca)
{
Expand All @@ -360,8 +356,14 @@ uint8_t S2LP::send(uint8_t *payload, uint8_t payload_len, uint8_t dest_addr, boo
S2LPTimerLdcrMode(S_ENABLE);
S2LpTimerFastRxTermTimer(S_ENABLE);

/* Return to RX state */
S2LPCmdStrobeCommand(CMD_RX);
if(is_waiting_for_read)
{
is_tx_done_before_read = true;
} else
{
/* Return to RX state */
S2LPCmdStrobeCommand(CMD_RX);
}

disableS2LPIrq();

Expand Down Expand Up @@ -411,14 +413,25 @@ uint8_t S2LP::read(uint8_t *payload, uint8_t payload_len)

cRxData = 0;

/* Return to Sleep state */
S2LPCmdStrobeCommand(CMD_SLEEP);
is_waiting_for_read = false;

if(is_tx_done_before_read)
{
is_tx_done_before_read = false;

if(S2LPManagementGetCut()==S2LP_CUT_2_0)
/* Return to RX state */
S2LPCmdStrobeCommand(CMD_RX);
} else
{
/* apply the workaround to exit from SLEEP (2nd part) */
delay(6);
S2LPTimerLdcIrqWa(S_DISABLE);
/* Return to Sleep state */
S2LPCmdStrobeCommand(CMD_SLEEP);

if(S2LPManagementGetCut()==S2LP_CUT_2_0)
{
/* apply the workaround to exit from SLEEP (2nd part) */
delay(6);
S2LPTimerLdcIrqWa(S_DISABLE);
}
}

enableS2LPIrq();
Expand All @@ -429,24 +442,39 @@ uint8_t S2LP::read(uint8_t *payload, uint8_t payload_len)
/**
* @brief Set the Ready state.
* @param None.
* @retval None.
* @retval zero in case of success, non-zero error code otherwise.
*/
void S2LP::S2LPSetReadyState(void)
uint8_t S2LP::S2LPSetReadyState(void)
{
S2LPRefreshStatus();
uint8_t ret_val = 0;
uint32_t start_time;
uint32_t current_time;

if(g_xStatus.MC_STATE == MC_STATE_RX || g_xStatus.MC_STATE == MC_STATE_TX)
{
S2LPCmdStrobeCommand(CMD_SABORT);
} else
{
S2LPCmdStrobeCommand(CMD_READY);
}
start_time = millis();

do
{
S2LPRefreshStatus();
} while(g_xStatus.MC_STATE != MC_STATE_READY);

if(g_xStatus.MC_STATE == MC_STATE_RX || g_xStatus.MC_STATE == MC_STATE_TX)
{
S2LPCmdStrobeCommand(CMD_SABORT);
} else
{
S2LPCmdStrobeCommand(CMD_READY);
}

S2LPRefreshStatus();

current_time = millis();
} while(g_xStatus.MC_STATE != MC_STATE_READY && (current_time - start_time) <= 1000);

if((current_time - start_time) > 1000)
{
ret_val = 1;
}

return ret_val;
}

S2LPCutType S2LP::S2LPManagementGetCut(void)
Expand Down Expand Up @@ -494,6 +522,8 @@ void S2LP::S2LPIrqHandler(void)
/* Flush the RX FIFO */
S2LPCmdStrobeFlushRxFifo();

is_waiting_for_read = true;

/* Call application callback */
if(current_event_callback)
{
Expand Down
4 changes: 3 additions & 1 deletion src/S2LP.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ class S2LP
uint8_t read(uint8_t *payload, uint8_t payload_len);

protected:
void S2LPSetReadyState(void);
uint8_t S2LPSetReadyState(void);
S2LPCutType S2LPManagementGetCut(void);
/** S2-LP Irq Callback */
void S2LPIrqHandler(void);
Expand Down Expand Up @@ -366,6 +366,8 @@ class S2LP
uint8_t vectcRxBuff[FIFO_SIZE];
uint8_t vectcTxBuff[FIFO_SIZE];
uint8_t cRxData;
volatile bool is_waiting_for_read;
volatile bool is_tx_done_before_read;
};

#endif /* __S2LP_H__ */