6868 * @param csn the spi chip select pin
6969 * @param sdn the shutdown pin
7070 * @param irqn the pin to receive IRQ event
71- * @param irq_gpio the S2-LP gpio used to receive the IRQ events
7271 * @param frequency the base carrier frequency in Hz
72+ * @param xtalFrequency the crystal oscillator frequency
73+ * @param paInfo information about external power amplifier
74+ * @param irq_gpio the S2-LP gpio used to receive the IRQ events
75+ * @param my_addr address of the device
76+ * @param multicast_addr multicast address
77+ * @param broadcast_addr broadcast address
7378 */
7479S2LP::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)
7580{
@@ -80,8 +85,11 @@ S2LP::S2LP(SPIClass *spi, int csn, int sdn, int irqn, uint32_t frequency, uint32
8085 current_event_callback = NULL ;
8186 nr_of_irq_disabled = 0 ;
8287 xTxDoneFlag = RESET;
83- memset ((void *)vectcRxBuff, FIFO_SIZE, sizeof (uint8_t ));
88+ memset ((void *)vectcRxBuff, 0 , FIFO_SIZE*sizeof (uint8_t ));
89+ memset ((void *)vectcTxBuff, 0 , FIFO_SIZE*sizeof (uint8_t ));
8490 cRxData = 0 ;
91+ is_waiting_for_read = false ;
92+ is_tx_done_before_read = false ;
8593}
8694
8795/* *
@@ -106,40 +114,21 @@ void S2LP::begin(void)
106114 S2LPCmdStrobeSres ();
107115
108116 SGpioInit xGpioIRQ={
109- S2LP_GPIO_3 ,
117+ irq_gpio_selected ,
110118 S2LP_GPIO_MODE_DIGITAL_OUTPUT_LP,
111119 S2LP_GPIO_DIG_OUT_IRQ
112120 };
113121
114- switch (irq_gpio_selected)
115- {
116- case S2LP_GPIO_0:
117- xGpioIRQ.xS2LPGpioPin = S2LP_GPIO_0;
118- break ;
119- case S2LP_GPIO_1:
120- xGpioIRQ.xS2LPGpioPin = S2LP_GPIO_1;
121- break ;
122- case S2LP_GPIO_2:
123- xGpioIRQ.xS2LPGpioPin = S2LP_GPIO_2;
124- break ;
125- case S2LP_GPIO_3:
126- xGpioIRQ.xS2LPGpioPin = S2LP_GPIO_3;
127- default :
128- break ;
129- }
130-
131122 S2LPGpioInit (&xGpioIRQ);
132123
133124 SRadioInit xRadioInit = {
134- 868000000 , /* base carrier frequency */
135- MOD_2FSK, /* modulation type */
136- DATARATE, /* data rate */
137- 20000 , /* frequency deviation */
138- 100000 /* bandwidth */
125+ lFrequencyBase, /* base carrier frequency */
126+ MOD_2FSK, /* modulation type */
127+ DATARATE, /* data rate */
128+ 20000 , /* frequency deviation */
129+ 100000 /* bandwidth */
139130 };
140131
141- xRadioInit.lFrequencyBase = lFrequencyBase;
142-
143132 S2LPRadioInit (&xRadioInit);
144133
145134 S2LPRadioSetMaxPALevel (S_DISABLE);
@@ -278,8 +267,11 @@ void S2LP::end(void)
278267 current_event_callback = NULL ;
279268 nr_of_irq_disabled = 0 ;
280269 xTxDoneFlag = RESET;
281- memset ((void *)vectcRxBuff, FIFO_SIZE, sizeof (uint8_t ));
270+ memset ((void *)vectcRxBuff, 0 , FIFO_SIZE*sizeof (uint8_t ));
271+ memset ((void *)vectcTxBuff, 0 , FIFO_SIZE*sizeof (uint8_t ));
282272 cRxData = 0 ;
273+ is_waiting_for_read = false ;
274+ is_tx_done_before_read = false ;
283275}
284276
285277/* *
@@ -314,7 +306,11 @@ uint8_t S2LP::send(uint8_t *payload, uint8_t payload_len, uint8_t dest_addr, boo
314306 disableS2LPIrq ();
315307
316308 /* Go to Ready mode */
317- S2LPSetReadyState ();
309+ if (S2LPSetReadyState ())
310+ {
311+ enableS2LPIrq ();
312+ return 1 ;
313+ }
318314
319315 /* Disable LDC */
320316 S2LPTimerLdcrMode (S_DISABLE);
@@ -349,7 +345,7 @@ uint8_t S2LP::send(uint8_t *payload, uint8_t payload_len, uint8_t dest_addr, boo
349345 do
350346 {
351347 current_time = millis ();
352- } while (!xTxDoneFlag && (current_time - start_time) <= 3000 );
348+ } while (!xTxDoneFlag && (current_time - start_time) <= 1000 );
353349
354350 if (use_csma_ca)
355351 {
@@ -360,8 +356,14 @@ uint8_t S2LP::send(uint8_t *payload, uint8_t payload_len, uint8_t dest_addr, boo
360356 S2LPTimerLdcrMode (S_ENABLE);
361357 S2LpTimerFastRxTermTimer (S_ENABLE);
362358
363- /* Return to RX state */
364- S2LPCmdStrobeCommand (CMD_RX);
359+ if (is_waiting_for_read)
360+ {
361+ is_tx_done_before_read = true ;
362+ } else
363+ {
364+ /* Return to RX state */
365+ S2LPCmdStrobeCommand (CMD_RX);
366+ }
365367
366368 disableS2LPIrq ();
367369
@@ -411,14 +413,25 @@ uint8_t S2LP::read(uint8_t *payload, uint8_t payload_len)
411413
412414 cRxData = 0 ;
413415
414- /* Return to Sleep state */
415- S2LPCmdStrobeCommand (CMD_SLEEP);
416+ is_waiting_for_read = false ;
417+
418+ if (is_tx_done_before_read)
419+ {
420+ is_tx_done_before_read = false ;
416421
417- if (S2LPManagementGetCut ()==S2LP_CUT_2_0)
422+ /* Return to RX state */
423+ S2LPCmdStrobeCommand (CMD_RX);
424+ } else
418425 {
419- /* apply the workaround to exit from SLEEP (2nd part) */
420- delay (6 );
421- S2LPTimerLdcIrqWa (S_DISABLE);
426+ /* Return to Sleep state */
427+ S2LPCmdStrobeCommand (CMD_SLEEP);
428+
429+ if (S2LPManagementGetCut ()==S2LP_CUT_2_0)
430+ {
431+ /* apply the workaround to exit from SLEEP (2nd part) */
432+ delay (6 );
433+ S2LPTimerLdcIrqWa (S_DISABLE);
434+ }
422435 }
423436
424437 enableS2LPIrq ();
@@ -429,24 +442,39 @@ uint8_t S2LP::read(uint8_t *payload, uint8_t payload_len)
429442/* *
430443* @brief Set the Ready state.
431444* @param None.
432- * @retval None .
445+ * @retval zero in case of success, non-zero error code otherwise .
433446*/
434- void S2LP::S2LPSetReadyState (void )
447+ uint8_t S2LP::S2LPSetReadyState (void )
435448{
436- S2LPRefreshStatus ();
449+ uint8_t ret_val = 0 ;
450+ uint32_t start_time;
451+ uint32_t current_time;
437452
438- if (g_xStatus.MC_STATE == MC_STATE_RX || g_xStatus.MC_STATE == MC_STATE_TX)
439- {
440- S2LPCmdStrobeCommand (CMD_SABORT);
441- } else
442- {
443- S2LPCmdStrobeCommand (CMD_READY);
444- }
453+ start_time = millis ();
445454
446455 do
447456 {
448457 S2LPRefreshStatus ();
449- } while (g_xStatus.MC_STATE != MC_STATE_READY);
458+
459+ if (g_xStatus.MC_STATE == MC_STATE_RX || g_xStatus.MC_STATE == MC_STATE_TX)
460+ {
461+ S2LPCmdStrobeCommand (CMD_SABORT);
462+ } else
463+ {
464+ S2LPCmdStrobeCommand (CMD_READY);
465+ }
466+
467+ S2LPRefreshStatus ();
468+
469+ current_time = millis ();
470+ } while (g_xStatus.MC_STATE != MC_STATE_READY && (current_time - start_time) <= 1000 );
471+
472+ if ((current_time - start_time) > 1000 )
473+ {
474+ ret_val = 1 ;
475+ }
476+
477+ return ret_val;
450478}
451479
452480S2LPCutType S2LP::S2LPManagementGetCut (void )
@@ -494,6 +522,8 @@ void S2LP::S2LPIrqHandler(void)
494522 /* Flush the RX FIFO */
495523 S2LPCmdStrobeFlushRxFifo ();
496524
525+ is_waiting_for_read = true ;
526+
497527 /* Call application callback */
498528 if (current_event_callback)
499529 {
0 commit comments