Appiko
S2LP_PktStack.c
Go to the documentation of this file.
1 
24 /* Includes ------------------------------------------------------------------*/
25 #include "S2LP_PktStack.h"
26 #include "MCU_Interface.h"
27 #include "S2LP_PktWMbus.h"
28 
29 
45 #define PKT_FORMAT_STACK_CODE (uint8_t)3
46 
58 #define IS_STACK_PREAMBLE_LENGTH IS_PREAMBLE_LEN
59 #define IS_STACK_SYNC_LENGTH IS_SYNC_LEN
60 #define IS_STACK_PKT_LEN_FIELD_WID IS_PKT_LEN_FIELD_WID
61 #define IS_STACK_CRC_MODE IS_PKT_CRC_MODE
62 #define IS_STACK_NMAX_RETX(NRETX) (NRETX<=15)
63 #define IS_STACK_SEQNUM_RELOAD_VAL(VAL) (VAL<=3)
64 
83 void S2LPPktStackInit(PktStackInit* pxPktStackInit)
84 {
85  uint8_t tmpBuffer[6];
86 
87  /* Check the parameters */
88  s_assert_param(IS_STACK_PREAMBLE_LENGTH(pxPktStackInit->xPreambleLength));
89  s_assert_param(IS_STACK_SYNC_LENGTH(pxPktStackInit->xSyncLength));
90  s_assert_param(IS_STACK_CRC_MODE(pxPktStackInit->xCrcMode));
91  s_assert_param(IS_SFUNCTIONAL_STATE(pxPktStackInit->cExtendedPktLenField));
92  s_assert_param(IS_SFUNCTIONAL_STATE(pxPktStackInit->xFixVarLength));
93  s_assert_param(IS_SFUNCTIONAL_STATE(pxPktStackInit->xFec));
94  s_assert_param(IS_SFUNCTIONAL_STATE(pxPktStackInit->xDataWhitening));
95 
97 
98  /* Always set the automatic packet filtering */
99  S2LPSpiReadRegisters(PROTOCOL1_ADDR, 1, &tmpBuffer[0]);
100  tmpBuffer[0] |= AUTO_PCKT_FLT_REGMASK;
101  S2LPSpiWriteRegisters(PROTOCOL1_ADDR, 1, &tmpBuffer[0]);
102 
103  tmpBuffer[0] = ((pxPktStackInit->xSyncLength)<<2) | (uint8_t)((pxPktStackInit->xPreambleLength)>>8);
104  tmpBuffer[1] = (uint8_t)(pxPktStackInit->xPreambleLength);
105  tmpBuffer[2] = ((uint8_t)pxPktStackInit->cExtendedPktLenField)<<7 | ADDRESS_LEN_REGMASK;
106 
107  S2LPSpiReadRegisters(PCKTCTRL3_ADDR, 1, &tmpBuffer[3]);
108  tmpBuffer[3] &= ~(PCKT_FRMT_REGMASK | RX_MODE_REGMASK);
109  tmpBuffer[3] |= PKT_FORMAT_STACK_CODE<<6;
110 
111  S2LPSpiReadRegisters(PCKTCTRL2_ADDR, 2, &tmpBuffer[4]);
112 
113  if(pxPktStackInit->xFixVarLength == S_ENABLE) {
114  tmpBuffer[4] |= FIX_VAR_LEN_REGMASK;
115  }
116  else {
117  tmpBuffer[4] &= ~FIX_VAR_LEN_REGMASK;
118  }
119  tmpBuffer[4] &= ~(MANCHESTER_EN_REGMASK | MBUS_3OF6_EN_REGMASK);
120 
121  tmpBuffer[5] &= ~(CRC_MODE_REGMASK | TXSOURCE_REGMASK);
122  tmpBuffer[5] |= (uint8_t)pxPktStackInit->xCrcMode;
123 
124  if(pxPktStackInit->xDataWhitening == S_ENABLE) {
125  tmpBuffer[5] |= WHIT_EN_REGMASK;
126  }
127  else {
128  tmpBuffer[5] &= ~WHIT_EN_REGMASK;
129  }
130 
131  if(pxPktStackInit->xFec == S_ENABLE) {
132  tmpBuffer[5] |= FEC_EN_REGMASK;
133  }
134  else {
135  tmpBuffer[5] &= ~FEC_EN_REGMASK;
136  }
137 
138  S2LPSpiWriteRegisters(PCKTCTRL6_ADDR, 6, tmpBuffer);
139 
140  /* SYNC word */
141  for(uint8_t i=0 ; i<4 ; i++) {
142  tmpBuffer[i] = (uint8_t)(pxPktStackInit->lSyncWords>>(8*i));
143  }
144  g_xStatus = S2LPSpiWriteRegisters(SYNC3_ADDR, 4, tmpBuffer);
145 
146  /* Sets CRC check bit */
147  if(pxPktStackInit->xCrcMode == PKT_NO_CRC) {
148  S2LPPktStackFilterOnCrc(S_DISABLE);
149  }
150  else {
151  S2LPPktStackFilterOnCrc(S_ENABLE);
152  }
153  /* Constellation map setting */
154  S2LPSpiReadRegisters(MOD1_ADDR, 1, tmpBuffer);
155  tmpBuffer[0] &= ~G4FSK_CONST_MAP_REGMASK;
156  S2LPSpiWriteRegisters(MOD1_ADDR, 1, tmpBuffer);
157 }
158 
159 
166 void S2LPPktStackGetInfo(PktStackInit* pxPktStackInit)
167 {
168  uint8_t tmpBuffer[6];
169 
170  S2LPSpiReadRegisters(PCKTCTRL6_ADDR, 6, tmpBuffer);
171 
172  /* Sync length */
173  pxPktStackInit->xSyncLength = ((tmpBuffer[0] & SYNC_LEN_REGMASK)>>2);
174 
175  /* Preamble length */
176  pxPktStackInit->xPreambleLength = (((uint16_t)(tmpBuffer[0] & PREAMBLE_LEN_9_8_REGMASK))<<8) | ((uint16_t)tmpBuffer[1]);
177 
178  /* Length width */
179  pxPktStackInit->cExtendedPktLenField = (SFunctionalState)((tmpBuffer[2] & LEN_WID_REGMASK)>>7);
180 
181  /* FIX or VAR bit */
182  pxPktStackInit->xFixVarLength = (SFunctionalState)(tmpBuffer[4] & FIX_VAR_LEN_REGMASK);
183 
184  /* CRC mode */
185  pxPktStackInit->xCrcMode = (StackCrcMode)(tmpBuffer[5] & CRC_MODE_REGMASK);
186 
187  /* Whitening */
188  pxPktStackInit->xDataWhitening = (SFunctionalState)((tmpBuffer[5] & WHIT_EN_REGMASK)>> 4);
189 
190  /* FEC */
191  pxPktStackInit->xFec = (SFunctionalState)(tmpBuffer[5] & FEC_EN_REGMASK);
192 
193  g_xStatus = S2LPSpiReadRegisters(SYNC3_ADDR, 4, tmpBuffer);
194 
195  /* SYNC word */
196  pxPktStackInit->lSyncWords = 0;
197  for(uint8_t i=0 ; i<4 ; i++) {
198  pxPktStackInit->lSyncWords |= ((uint32_t)tmpBuffer[i])<<(8*i);
199  }
200 
201 }
202 
203 
212 {
213  uint8_t tmpBuffer[3];
214  s_assert_param(IS_SFUNCTIONAL_STATE(pxPktStackAddresses->xFilterOnMyAddress));
215  s_assert_param(IS_SFUNCTIONAL_STATE(pxPktStackAddresses->xFilterOnMulticastAddress));
216  s_assert_param(IS_SFUNCTIONAL_STATE(pxPktStackAddresses->xFilterOnBroadcastAddress));
217 
218  /* Reads the PCKT_FLT_OPTIONS ragister */
219  S2LPSpiReadRegisters(PCKT_FLT_OPTIONS_ADDR, 1, &tmpBuffer[0]);
220 
221  /* Enables or disables filtering on my address */
222  if(pxPktStackAddresses->xFilterOnMyAddress == S_ENABLE) {
223  tmpBuffer[0] |= DEST_VS_SOURCE_ADDR_REGMASK;
224  }
225  else {
226  tmpBuffer[0] &= ~DEST_VS_SOURCE_ADDR_REGMASK;
227  }
228 
229  /* Enables or disables filtering on multicast address */
230  if(pxPktStackAddresses->xFilterOnMulticastAddress == S_ENABLE) {
231  tmpBuffer[0] |= DEST_VS_MULTICAST_ADDR_REGMASK;
232  }
233  else {
234  tmpBuffer[0] &= ~DEST_VS_MULTICAST_ADDR_REGMASK;
235  }
236 
237  /* Enables or disables filtering on broadcast address */
238  if(pxPktStackAddresses->xFilterOnBroadcastAddress == S_ENABLE) {
239  tmpBuffer[0] |= DEST_VS_BROADCAST_ADDR_REGMASK;
240  }
241  else {
242  tmpBuffer[0] &= ~DEST_VS_BROADCAST_ADDR_REGMASK;
243  }
244 
245  S2LPSpiWriteRegisters(PCKT_FLT_OPTIONS_ADDR, 1, &tmpBuffer[0]);
246 
247  /* Fills the array with the addresses passed in the structure */
248  tmpBuffer[2] = pxPktStackAddresses->cMyAddress;
249  tmpBuffer[0] = pxPktStackAddresses->cBroadcastAddress;
250  tmpBuffer[1] = pxPktStackAddresses->cMulticastAddress;
251  g_xStatus = S2LPSpiWriteRegisters(PCKT_FLT_GOALS2_ADDR, 3, tmpBuffer);
252 }
253 
254 
263 {
264  uint8_t tmpBuffer[3];
265 
266  S2LPSpiReadRegisters(PCKT_FLT_GOALS3_ADDR, 3, tmpBuffer);
267  pxPktStackAddresses->cMyAddress = tmpBuffer[0];
268  pxPktStackAddresses->cBroadcastAddress = tmpBuffer[1];
269  pxPktStackAddresses->cMulticastAddress = tmpBuffer[2];
270 
271  g_xStatus = S2LPSpiReadRegisters(PCKT_FLT_OPTIONS_ADDR, 1, &tmpBuffer[0]);
272  pxPktStackAddresses->xFilterOnBroadcastAddress = (SFunctionalState)((tmpBuffer[0] & DEST_VS_BROADCAST_ADDR_REGMASK) >> 3);
273  pxPktStackAddresses->xFilterOnMulticastAddress = (SFunctionalState)((tmpBuffer[0] & DEST_VS_MULTICAST_ADDR_REGMASK) >> 2);
274  pxPktStackAddresses->xFilterOnMyAddress = (SFunctionalState)((tmpBuffer[0] & DEST_VS_SOURCE_ADDR_REGMASK) >> 1);
275 }
276 
277 
284 {
285  uint8_t tmp;
286 
287  S2LPSpiReadRegisters(PCKTCTRL3_ADDR, 1, &tmp);
288 
289  /* Build the new value. Also set to 0 the direct RX mode bits */
290  tmp &= ~(PCKT_FRMT_REGMASK | RX_MODE_REGMASK);
291  tmp |= PKT_FORMAT_STACK_CODE;
292  S2LPSpiWriteRegisters(PCKTCTRL3_ADDR, 1, &tmp);
293 
294  S2LPSpiReadRegisters(PCKTCTRL1_ADDR, 1, &tmp);
295 
296  /* Set to 0 the direct TX mode bits */
297  tmp &= ~TXSOURCE_REGMASK;
298  g_xStatus = S2LPSpiWriteRegisters(PCKTCTRL1_ADDR, 1, &tmp);
299 
301 }
302 
303 
304 
314 void S2LPPktStackSetPayloadLength(uint16_t nPayloadLength)
315 {
316  uint8_t tmpBuffer[2];
317 
318  nPayloadLength+=2;
319  tmpBuffer[0] = (uint8_t)(nPayloadLength>>8);
320  tmpBuffer[1] = (uint8_t)nPayloadLength;
321  g_xStatus = S2LPSpiWriteRegisters(PCKTLEN1_ADDR, 2, tmpBuffer);
322 }
323 
324 
335 {
336  uint8_t tmpBuffer[2];
337  uint16_t nPayloadLength;
338 
339  g_xStatus = S2LPSpiReadRegisters(PCKTLEN1_ADDR, 2, tmpBuffer);
340  nPayloadLength = (((uint16_t)tmpBuffer[0])<<8) | ((uint16_t)tmpBuffer[1]);
341  nPayloadLength-=2;
342 
343  return nPayloadLength;
344 }
345 
346 
353 {
354  uint8_t tmpBuffer[2];
355  uint16_t nPayloadLength;
356 
357  g_xStatus = S2LPSpiReadRegisters(RX_PCKT_LEN1_ADDR, 2, tmpBuffer);
358  nPayloadLength = (((uint16_t)tmpBuffer[0])<<8) | ((uint16_t)tmpBuffer[1]);
359  nPayloadLength--;
360 
361  return nPayloadLength;
362 }
363 
364 
371 {
372  uint8_t tmp;
373  s_assert_param(IS_SFUNCTIONAL_STATE(xNewState));
374 
375  S2LPSpiReadRegisters(PROTOCOL0_ADDR, 1, &tmp);
376  if(xNewState == S_ENABLE) {
377  tmp |= AUTO_ACK_REGMASK;
378  }
379  else {
380  tmp &= ~AUTO_ACK_REGMASK;
381  }
382  g_xStatus = S2LPSpiWriteRegisters(PROTOCOL0_ADDR, 1, &tmp);
383 
384 }
385 
386 
392 void S2LPPktStackNRetx(uint8_t nRetx)
393 {
394  uint8_t tmp;
395  s_assert_param(IS_STACK_NMAX_RETX(nRetx));
396 
397  S2LPSpiReadRegisters(PROTOCOL0_ADDR, 1, &tmp);
398  tmp &= ~NMAX_RETX_REGMASK;
399  tmp |= (nRetx<<4);
400  g_xStatus = S2LPSpiWriteRegisters(PROTOCOL0_ADDR, 1, &tmp);
401 
402 }
403 
404 
411 {
412  uint8_t tmp;
413 
414  S2LPSpiReadRegisters(RX_PCKT_INFO_ADDR, 1, &tmp);
415  tmp &= NACK_RX_REGMASK;
416  tmp >>= 2;
417  return (SFlagStatus)tmp;
418 }
419 
427 {
428  uint8_t tmp;
429  s_assert_param(IS_SFUNCTIONAL_STATE(xNewState));
430 
431  S2LPSpiReadRegisters(PROTOCOL0_ADDR, 1, &tmp);
432  if(xNewState == S_ENABLE) {
433  tmp &= ~NACK_TX_REGMASK;
434  }
435  else {
436  tmp |= NACK_TX_REGMASK;
437  }
438  g_xStatus = S2LPSpiWriteRegisters(PROTOCOL0_ADDR, 1, &tmp);
439 
440 }
441 
442 
449 {
450  uint8_t tmp;
451  s_assert_param(IS_SFUNCTIONAL_STATE(xNewState));
452 
453  S2LPSpiReadRegisters(PROTOCOL1_ADDR, 1, &tmp);
454  if(xNewState == S_ENABLE) {
455  tmp |= PIGGYBACKING_REGMASK;
456  }
457  else {
458  tmp &= ~PIGGYBACKING_REGMASK;
459  }
460  g_xStatus = S2LPSpiWriteRegisters(PROTOCOL1_ADDR, 1, &tmp);
461 
462 }
463 
464 
471 void S2LPPktStackSeqNumForReload(uint8_t cReloadValue)
472 {
473  uint8_t tmp;
474  s_assert_param(IS_STACK_SEQNUM_RELOAD_VAL(cReloadValue));
475 
476  S2LPSpiReadRegisters(PROTOCOL2_ADDR, 1, &tmp);
477  tmp &= ~TX_SEQ_NUM_RELOAD_REGMASK;
478  tmp |= (cReloadValue<<3);
479  g_xStatus = S2LPSpiWriteRegisters(PROTOCOL2_ADDR, 1, &tmp);
480 }
481 
487 uint8_t S2LPPktStackGetNReTx(void)
488 {
489  uint8_t tempRetValue;
490 
491  /* Reads the TX_PCKT_INFO register value */
492  g_xStatus = S2LPSpiReadRegisters(TX_PCKT_INFO_ADDR, 1, &tempRetValue);
493 
494  /* Obtains and returns the number of retransmission done */
495  return (tempRetValue & 0x0F);
496 
497 }
498 
499 
515 /******************* (C) COPYRIGHT 2016 STMicroelectronics *****END OF FILE****/
#define TX_PCKT_INFO_ADDR
TX_PCKT_INFO register.
Definition: S2LP_Regs.h:1585
SFunctionalState xFilterOnMulticastAddress
void S2LPPktStackAutoAck(SFunctionalState xNewState)
Se the AUTO_ACK bit on the receiver .
#define PROTOCOL2_ADDR
PROTOCOL2 register.
Definition: S2LP_Regs.h:660
#define MOD1_ADDR
MOD1 register.
Definition: S2LP_Regs.h:263
SFunctionalState
S2LP Functional state. Used to enable or disable a specific option.
Definition: S2LP_Types.h:67
void S2LPPktStackInit(PktStackInit *pxPktStackInit)
Initialize the S2LP STack packet according to the specified parameters in the PktStackInit.
Definition: S2LP_PktStack.c:83
#define PROTOCOL1_ADDR
PROTOCOL1 register.
Definition: S2LP_Regs.h:685
SFunctionalState xFec
StackCrcMode xCrcMode
#define PCKTCTRL6_ADDR
PCKTCTRL6 register.
Definition: S2LP_Regs.h:437
void S2LPPktStackPiggybacking(SFunctionalState xNewState)
Enable or Disable the piggybacking.
#define S2LPPktStackFilterOnCrc(xNewState)
Enables or Disables the CRC filtering.
SFlagStatus
S2LP Flag status. Used to control the state of a flag.
Definition: S2LP_Types.h:76
S2LP STack packet address structure definition. This structure allows users to specify the node/multi...
SFunctionalState xFilterOnBroadcastAddress
#define PCKTCTRL2_ADDR
PCKTCTRL2 register.
Definition: S2LP_Regs.h:508
void S2LPPktStackSeqNumForReload(uint8_t cReloadValue)
Set the reload value of the sequence number.
#define SYNC3_ADDR
SYNC3 register.
Definition: S2LP_Regs.h:573
void S2LPPktStackAckRequest(SFunctionalState xNewState)
This function will set the NO_ACK bit or reset it.
SFunctionalState xFilterOnMyAddress
PktCrcMode StackCrcMode
CRC length in bytes enumeration.
void S2LPPktStackNRetx(uint8_t nRetx)
Set the number of retransmissions to be done in case of ACK loss.
Configuration and management of S2-LP WMbus packets.
uint32_t lSyncWords
uint8_t xSyncLength
void S2LPPktStackAddressesInit(PktStackAddressesInit *pxPktStackAddresses)
Initialize the S2LP STack packet addresses according to the specified parameters in the PktStackAddre...
void S2LPPktStackSetFormat(void)
Configure the STack packet format for S2LP.
#define PCKTCTRL1_ADDR
PCKTCTRL1 register.
Definition: S2LP_Regs.h:530
#define PCKTLEN1_ADDR
PCKTLEN1 register.
Definition: S2LP_Regs.h:547
SFlagStatus S2LPPktStackGetTXAckRequest(void)
Get the NO_ACK bit.
uint16_t S2LPPktStackGetPayloadLength(void)
Return the payload length for S2LP STack packets. Since the packet length depends from the address an...
SFunctionalState xDataWhitening
uint16_t S2LPPktStackGetReceivedPktLength(void)
Return the packet length field of the received packet.
void S2LPPktWMbusSetSubmode(WMbusSubmode xWMbusSubmode)
Set the W-MBus submode.
#define PROTOCOL0_ADDR
PROTOCOL0 register.
Definition: S2LP_Regs.h:709
void S2LPPktStackSetPayloadLength(uint16_t nPayloadLength)
Set the payload length for S2LP STack packets. Since the packet length depends from the address (alwa...
SFunctionalState xFixVarLength
#define RX_PCKT_LEN1_ADDR
RX_PCKT_LEN1 register.
Definition: S2LP_Regs.h:1669
volatile S2LPStatus g_xStatus
S2LP Status global variable. This global variable of S2LPStatus type is updated on every SPI transact...
Definition: S2LP_Types.c:82
#define PCKTCTRL3_ADDR
PCKTCTRL3 register.
Definition: S2LP_Regs.h:485
#define PCKT_FLT_GOALS3_ADDR
PCKT_FLT_GOALS3 register.
Definition: S2LP_Regs.h:819
#define PCKT_FLT_GOALS2_ADDR
PCKT_FLT_GOALS2 register.
Definition: S2LP_Regs.h:832
SFunctionalState cExtendedPktLenField
void S2LPPktStackGetAddressesInfo(PktStackAddressesInit *pxPktStackAddresses)
Return the S2LP STack packet addresses structure according to the specified parameters in the registe...
#define PCKT_FLT_OPTIONS_ADDR
PCKT_FLT_OPTIONS register.
Definition: S2LP_Regs.h:788
Header file for low level S2LP SPI driver.
#define RX_PCKT_INFO_ADDR
RX_PCKT_INFO register.
Definition: S2LP_Regs.h:1601
S2LP STack Packet Init structure definition.
Configuration and management of S2-LP STack packets.
uint8_t S2LPPktStackGetNReTx(void)
Returns the number of retransmission done on the transmitted packet.
void S2LPPktStackGetInfo(PktStackInit *pxPktStackInit)
Return the S2LP STack packet structure according to the specified parameters in the registers.
uint16_t xPreambleLength