5555
5656#define LINEAR_FIFO_ADDRESS 0xFF /* !< Linear FIFO address*/
5757
58- #define XTAL_FREQUENCY 50000000U
59-
60- #define PREAMBLE_LENGTH (64 *4 )
61- #define DATARATE 38400
62- #define MIN_PERIOD_WAKEUP ((8000 *((PREAMBLE_LENGTH/4 )-2 ))/DATARATE)
63-
6458/* Class Implementation ------------------------------------------------------*/
6559
6660/* * Constructor
@@ -89,7 +83,7 @@ S2LP::S2LP(SPIClass *spi, int csn, int sdn, int irqn, uint32_t frequency, uint32
8983 memset ((void *)vectcTxBuff, 0 , FIFO_SIZE*sizeof (uint8_t ));
9084 cRxData = 0 ;
9185 is_waiting_for_read = false ;
92- is_tx_done_before_read = false ;
86+ is_bypass_enabled = false ;
9387}
9488
9589/* *
@@ -124,7 +118,7 @@ void S2LP::begin(void)
124118 SRadioInit xRadioInit = {
125119 lFrequencyBase, /* base carrier frequency */
126120 MOD_2FSK, /* modulation type */
127- DATARATE, /* data rate */
121+ 38400 , /* data rate */
128122 20000 , /* frequency deviation */
129123 100000 /* bandwidth */
130124 };
@@ -146,16 +140,21 @@ void S2LP::begin(void)
146140
147141 if (s_paInfo.paRfRangeExtender == RANGE_EXT_SKYWORKS_SE2435L)
148142 {
149- S2LPGpioInit (&s_paInfo.paSignalCSD );
150- S2LPGpioInit (&s_paInfo.paSignalCPS );
151- S2LPGpioInit (&s_paInfo.paSignalCTX );
143+ S2LPGpioInit (&s_paInfo.paSignalCSD_S2LP );
144+ S2LPGpioInit (&s_paInfo.paSignalCPS_S2LP );
145+ S2LPGpioInit (&s_paInfo.paSignalCTX_S2LP );
146+ } else if (s_paInfo.paRfRangeExtender == RANGE_EXT_SKYWORKS_SKY66420)
147+ {
148+ pinMode (s_paInfo.paSignalCSD_MCU , OUTPUT);
149+ pinMode (s_paInfo.paSignalCPS_MCU , OUTPUT);
150+ pinMode (s_paInfo.paSignalCTX_MCU , OUTPUT);
152151 }
153152 }
154153
155154 S2LPRadioSetPALevelMaxIndex (7 );
156155
157156 PktBasicInit xBasicInit={
158- PREAMBLE_LENGTH, /* Preamble length */
157+ 16 , /* Preamble length */
159158 32 , /* Sync length */
160159 0x88888888 , /* Sync word */
161160 S_ENABLE, /* Variable length */
@@ -180,7 +179,7 @@ void S2LP::begin(void)
180179 S2LPPktBasicAddressesInit (&xAddressInit);
181180
182181 SCsmaInit xCsmaInit={
183- S_DISABLE, /* Persistent mode enable/disable */
182+ S_ENABLE, /* Persistent mode enable/disable */
184183 CSMA_PERIOD_64TBIT, /* CS Period */
185184 3 , /* CS Timeout */
186185 5 , /* Max number of backoffs */
@@ -209,26 +208,23 @@ void S2LP::begin(void)
209208 S2LPGpioIrqConfig (RX_DATA_READY,S_ENABLE);
210209 S2LPGpioIrqConfig (TX_DATA_SENT , S_ENABLE);
211210
212- /* IRQ registers blanking */
213- S2LPGpioIrqClearStatus ();
214-
215211 /* clear FIFO if needed */
216212 S2LPCmdStrobeFlushRxFifo ();
217213
218- /* set the LDC mode wkup */
219- S2LPTimerSetWakeUpTimerUs (1000 *MIN_PERIOD_WAKEUP);
214+ /* Set infinite Timeout */
215+ S2LPTimerSetRxTimerCounter (0 );
216+ S2LPTimerSetRxTimerStopCondition (ANY_ABOVE_THRESHOLD);
220217
221- /* set the rx timeout */
222- S2LPTimerSetRxTimerUs (30000 );
223-
224- /* use SLEEP_A mode (default) */
225- S2LPTimerSleepB (S_DISABLE);
218+ /* IRQ registers blanking */
219+ S2LPGpioIrqClearStatus ();
226220
227- /* enable LDC mode, FAST RX TERM and start Rx */
228- S2LPTimerLdcrMode (S_ENABLE );
221+ uint8_t tmp = 0x90 ;
222+ S2LPSpiWriteRegisters ( 0x76 , 1 , &tmp );
229223
230- /* enable the fast rx timer */
231- S2LpTimerFastRxTermTimer (S_ENABLE);
224+ if (s_paInfo.paRfRangeExtender == RANGE_EXT_SKYWORKS_SKY66420)
225+ {
226+ FEM_Operation_SKY66420 (FEM_RX);
227+ }
232228
233229 /* the RX command triggers the LDC in fast RX termination mode */
234230 S2LPCmdStrobeCommand (CMD_RX);
@@ -261,6 +257,14 @@ void S2LP::end(void)
261257 /* Reset SDN pin */
262258 pinMode (sdn_pin, INPUT);
263259
260+ /* Reset CSD, CPS and CTX if it is needed */
261+ if (s_paInfo.paRfRangeExtender == RANGE_EXT_SKYWORKS_SKY66420)
262+ {
263+ pinMode (s_paInfo.paSignalCSD_MCU , INPUT);
264+ pinMode (s_paInfo.paSignalCPS_MCU , INPUT);
265+ pinMode (s_paInfo.paSignalCTX_MCU , INPUT);
266+ }
267+
264268 /* Reset all internal variables */
265269 memset ((void *)&g_xStatus, 0 , sizeof (S2LPStatus));
266270 s_cWMbusSubmode = WMBUS_SUBMODE_NOT_CONFIGURED;
@@ -271,7 +275,7 @@ void S2LP::end(void)
271275 memset ((void *)vectcTxBuff, 0 , FIFO_SIZE*sizeof (uint8_t ));
272276 cRxData = 0 ;
273277 is_waiting_for_read = false ;
274- is_tx_done_before_read = false ;
278+ is_bypass_enabled = false ;
275279}
276280
277281/* *
@@ -312,10 +316,6 @@ uint8_t S2LP::send(uint8_t *payload, uint8_t payload_len, uint8_t dest_addr, boo
312316 return 1 ;
313317 }
314318
315- /* Disable LDC */
316- S2LPTimerLdcrMode (S_DISABLE);
317- S2LpTimerFastRxTermTimer (S_DISABLE);
318-
319319 S2LPPktBasicSetPayloadLength (payload_len);
320320
321321 S2LPSetRxSourceReferenceAddress (dest_addr);
@@ -337,6 +337,14 @@ uint8_t S2LP::send(uint8_t *payload, uint8_t payload_len, uint8_t dest_addr, boo
337337
338338 enableS2LPIrq ();
339339
340+ uint8_t tmp=0x9C ;
341+ S2LPSpiWriteRegisters (0x76 ,1 ,&tmp);
342+
343+ if (s_paInfo.paRfRangeExtender == RANGE_EXT_SKYWORKS_SKY66420)
344+ {
345+ FEM_Operation_SKY66420 (FEM_TX);
346+ }
347+
340348 S2LPCmdStrobeCommand (CMD_TX);
341349
342350 start_time = millis ();
@@ -352,15 +360,16 @@ uint8_t S2LP::send(uint8_t *payload, uint8_t payload_len, uint8_t dest_addr, boo
352360 S2LPCsma (S_DISABLE);
353361 }
354362
355- /* Enable LDC */
356- S2LPTimerLdcrMode (S_ENABLE);
357- S2LpTimerFastRxTermTimer (S_ENABLE);
358-
359- if (is_waiting_for_read)
360- {
361- is_tx_done_before_read = true ;
362- } else
363+ if (!is_waiting_for_read)
363364 {
365+ uint8_t tmp = 0x90 ;
366+ S2LPSpiWriteRegisters (0x76 , 1 , &tmp);
367+
368+ if (s_paInfo.paRfRangeExtender == RANGE_EXT_SKYWORKS_SKY66420)
369+ {
370+ FEM_Operation_SKY66420 (FEM_RX);
371+ }
372+
364373 /* Return to RX state */
365374 S2LPCmdStrobeCommand (CMD_RX);
366375 }
@@ -415,30 +424,64 @@ uint8_t S2LP::read(uint8_t *payload, uint8_t payload_len)
415424
416425 is_waiting_for_read = false ;
417426
418- if (is_tx_done_before_read)
419- {
420- is_tx_done_before_read = false ;
427+ uint8_t tmp = 0x90 ;
428+ S2LPSpiWriteRegisters (0x76 , 1 , &tmp);
421429
422- /* Return to RX state */
423- S2LPCmdStrobeCommand (CMD_RX);
424- } else
430+ if (s_paInfo.paRfRangeExtender == RANGE_EXT_SKYWORKS_SKY66420)
425431 {
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- }
432+ FEM_Operation_SKY66420 (FEM_RX);
435433 }
436434
435+ /* Return to RX state */
436+ S2LPCmdStrobeCommand (CMD_RX);
437+
437438 enableS2LPIrq ();
438439
439440 return ret_val;
440441}
441442
443+ /* *
444+ * @brief Sets the channel number.
445+ * @param cChannel the channel number.
446+ * @retval None.
447+ */
448+ void S2LP::setRadioChannel (uint8_t cChannel)
449+ {
450+ return S2LPRadioSetChannel (cChannel);
451+ }
452+
453+ /* *
454+ * @brief Returns the actual channel number.
455+ * @param None.
456+ * @retval uint8_t Actual channel number.
457+ */
458+ uint8_t S2LP::getRadioChannel (void )
459+ {
460+ return S2LPRadioGetChannel ();
461+ }
462+
463+ /* *
464+ * @brief Set the channel space factor in channel space register.
465+ * The channel spacing step is computed as F_Xo/32768.
466+ * @param fChannelSpace the channel space expressed in Hz.
467+ * @retval None.
468+ */
469+ void S2LP::setRadioChannelSpace (uint32_t lChannelSpace)
470+ {
471+ return S2LPRadioSetChannelSpace (lChannelSpace);
472+ }
473+
474+ /* *
475+ * @brief Return the channel space register.
476+ * @param None.
477+ * @retval uint32_t Channel space. The channel space is: CS = channel_space_factor x XtalFrequency/2^15
478+ * where channel_space_factor is the CHSPACE register value.
479+ */
480+ uint32_t S2LP::getRadioChannelSpace (void )
481+ {
482+ return S2LPRadioGetChannelSpace ();
483+ }
484+
442485/* *
443486* @brief Set the Ready state.
444487* @param None.
@@ -450,22 +493,14 @@ uint8_t S2LP::S2LPSetReadyState(void)
450493 uint32_t start_time;
451494 uint32_t current_time;
452495
496+ S2LPCmdStrobeCommand (CMD_SABORT);
497+
453498 start_time = millis ();
454499
455500 do
456501 {
457502 S2LPRefreshStatus ();
458503
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-
469504 current_time = millis ();
470505 } while (g_xStatus.MC_STATE != MC_STATE_READY && (current_time - start_time) <= 1000 );
471506
@@ -508,11 +543,6 @@ void S2LP::S2LPIrqHandler(void)
508543 /* Check the S2LP RX_DATA_READY IRQ flag */
509544 if (xIrqStatus.IRQ_RX_DATA_READY )
510545 {
511- if (S2LPManagementGetCut ()==S2LP_CUT_2_0)
512- {/* apply the workaround to exit from SLEEP (1st part) */
513- S2LPTimerLdcIrqWa (S_ENABLE);
514- }
515-
516546 /* Get the RX FIFO size */
517547 cRxData = S2LPFifoReadNumberBytesRxFifo ();
518548
@@ -560,6 +590,79 @@ void S2LP::enableS2LPIrq(void)
560590 }
561591}
562592
593+ /* *
594+ * @brief Commands for external PA of type SKY66420.
595+ * @param operation the command to be executed.
596+ * @retval None.
597+ */
598+ void S2LP::FEM_Operation_SKY66420 (FEM_OperationType operation)
599+ {
600+ switch (operation)
601+ {
602+ case FEM_SHUTDOWN:
603+ {
604+ /* Puts CSD high to turn on PA */
605+ digitalWrite (s_paInfo.paSignalCSD_MCU , LOW);
606+
607+ /* Puts CTX high to go in TX state DON'T CARE */
608+ digitalWrite (s_paInfo.paSignalCTX_MCU , HIGH);
609+
610+ /* No Bypass mode select DON'T CARE */
611+ digitalWrite (s_paInfo.paSignalCPS_MCU , HIGH);
612+
613+ break ;
614+ }
615+ case FEM_TX_BYPASS:
616+ {
617+ /* Puts CSD high to turn on PA */
618+ digitalWrite (s_paInfo.paSignalCSD_MCU , HIGH);
619+
620+ /* Puts CTX high to go in TX state */
621+ digitalWrite (s_paInfo.paSignalCTX_MCU , HIGH);
622+
623+ /* Bypass mode select */
624+ digitalWrite (s_paInfo.paSignalCPS_MCU , LOW);
625+
626+ break ;
627+ }
628+ case FEM_TX:
629+ {
630+ /* Puts CSD high to turn on PA */
631+ digitalWrite (s_paInfo.paSignalCSD_MCU , HIGH);
632+
633+ /* Puts CTX high to go in TX state */
634+ digitalWrite (s_paInfo.paSignalCTX_MCU , HIGH);
635+
636+ /* No Bypass mode select DON'T CARE */
637+ digitalWrite (s_paInfo.paSignalCPS_MCU , HIGH);
638+
639+ break ;
640+ }
641+ case FEM_RX:
642+ {
643+ /* Puts CSD high to turn on PA */
644+ digitalWrite (s_paInfo.paSignalCSD_MCU , HIGH);
645+
646+ /* Puts CTX low */
647+ digitalWrite (s_paInfo.paSignalCTX_MCU , LOW);
648+
649+ /* Check Bypass mode */
650+ if (is_bypass_enabled)
651+ {
652+ digitalWrite (s_paInfo.paSignalCPS_MCU , LOW);
653+ } else
654+ {
655+ digitalWrite (s_paInfo.paSignalCPS_MCU , HIGH);
656+ }
657+
658+ break ;
659+ }
660+ default :
661+ /* Error */
662+ break ;
663+ }
664+ }
665+
563666/* *
564667* @brief Write single or multiple registers.
565668* @param cRegAddress: base register's address to be write
0 commit comments