Skip to content

Commit d3ecf87

Browse files
authored
Merge pull request #4 from cparata/master
improve stability
2 parents 878c035 + 57593c5 commit d3ecf87

File tree

5 files changed

+198
-94
lines changed

5 files changed

+198
-94
lines changed

library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=STM32duino S2-LP
2-
version=1.0.1
2+
version=1.1.0
33
author=SRA
44
maintainer=stm32duino
55
sentence=This library includes drivers for ST S2-LP sub-1GHz transceiver.

src/S2LP.cpp

Lines changed: 173 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,6 @@
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

Comments
 (0)