@@ -55,17 +55,17 @@ typedef struct crsfLinkState_s {
5555 uint32_t channelData [CRSF_MAX_CHANNEL ];
5656 timeUs_t frameStartAtUs ;
5757 uint8_t framePosition ;
58+ serialPort_t * port ;
59+ uint8_t telemetryBuf [CRSF_FRAME_SIZE_MAX ];
60+ uint8_t telemetryBufLen ;
61+ rxLink_e link ;
5862} crsfLinkState_t ;
5963
6064// Per-link parser and channel state so a primary and secondary CRSF receiver
6165// don't share frame/channel buffers. Primary is index 0, so the single-RX path
6266// is unchanged.
6367static crsfLinkState_t crsfLinkStates [RX_LINK_COUNT ];
6468
65- static serialPort_t * serialPort ;
66- static uint8_t telemetryBuf [CRSF_FRAME_SIZE_MAX ];
67- static uint8_t telemetryBufLen = 0 ;
68-
6969const uint16_t crsfTxPowerStatesmW [CRSF_POWER_COUNT ] = {0 , 10 , 25 , 100 , 500 , 1000 , 2000 , 250 , 50 };
7070
7171/*
@@ -186,8 +186,8 @@ STATIC_UNIT_TESTED void crsfDataReceive(uint16_t c, void *rxCallbackData)
186186 case CRSF_FRAMETYPE_MSP_WRITE : {
187187 if (link -> frame .frame .frameLength >= 4 ) {
188188 uint8_t * frameStart = (uint8_t * )& link -> frame .frame .payload + CRSF_FRAME_ORIGIN_DEST_SIZE ;
189- if (bufferCrsfMspFrame (frameStart , link -> frame .frame .frameLength - 4 )) {
190- crsfScheduleMspResponse (link -> frame .frame .payload [1 ]);
189+ if (bufferCrsfMspFrame (link -> link , frameStart , link -> frame .frame .frameLength - 4 )) {
190+ crsfScheduleMspResponse (link -> link , link -> frame .frame .payload [1 ]);
191191 }
192192 } else {
193193 link -> frameDone = false;
@@ -295,33 +295,60 @@ STATIC_UNIT_TESTED uint16_t crsfReadRawRC(const rxRuntimeConfig_t *rxRuntimeConf
295295
296296void crsfRxWriteTelemetryData (const void * data , int len )
297297{
298- len = MIN (len , (int )sizeof (telemetryBuf ));
299- memcpy (telemetryBuf , data , len );
300- telemetryBufLen = len ;
298+ for (rxLink_e link = RX_LINK_PRIMARY ; link < RX_LINK_COUNT ; link ++ ) {
299+ if (crsfLinkStates [link ].port ) {
300+ crsfRxWriteTelemetryDataForLink (link , data , len );
301+ }
302+ }
301303}
302304
303- void crsfRxSendTelemetryData ( void )
305+ void crsfRxWriteTelemetryDataForLink ( rxLink_e linkIndex , const void * data , int len )
304306{
305- // if there is telemetry data to write
306- if (telemetryBufLen > 0 ) {
307+ crsfLinkState_t * link = & crsfLinkStates [linkIndex ];
308+ len = MIN (len , (int )sizeof (link -> telemetryBuf ));
309+ memcpy (link -> telemetryBuf , data , len );
310+ link -> telemetryBufLen = len ;
311+ }
312+
313+ static void crsfRxSendTelemetryDataForLink (crsfLinkState_t * link )
314+ {
315+ if (link -> telemetryBufLen > 0 ) {
307316 // check that we are not in bi dir mode or that we are not currently receiving data (ie in the middle of an RX frame)
308317 // and that there is time to send the telemetry frame before the next RX frame arrives
309318 if (CRSF_PORT_OPTIONS & SERIAL_BIDIR ) {
310- // Telemetry shares the primary link's port, so pace against its frame timing.
311- const timeDelta_t timeSinceStartOfFrame = cmpTimeUs (micros (), crsfLinkStates [RX_LINK_PRIMARY ].frameStartAtUs );
319+ const timeDelta_t timeSinceStartOfFrame = cmpTimeUs (micros (), link -> frameStartAtUs );
312320 if ((timeSinceStartOfFrame < CRSF_TIME_NEEDED_PER_FRAME_US ) ||
313321 (timeSinceStartOfFrame > CRSF_TIME_BETWEEN_FRAMES_US - CRSF_TIME_NEEDED_PER_FRAME_US )) {
314322 return ;
315323 }
316324 }
317- serialWriteBuf (serialPort , telemetryBuf , telemetryBufLen );
318- telemetryBufLen = 0 ; // reset telemetry buffer
325+ serialWriteBuf (link -> port , link -> telemetryBuf , link -> telemetryBufLen );
326+ link -> telemetryBufLen = 0 ;
319327 }
320328}
321329
322- bool crsfRxIsTelemetryBufEmpty (void )
330+ void crsfRxSendTelemetryData (void )
323331{
324- return telemetryBufLen == 0 ;
332+ for (rxLink_e link = RX_LINK_PRIMARY ; link < RX_LINK_COUNT ; link ++ ) {
333+ if (crsfLinkStates [link ].port ) {
334+ crsfRxSendTelemetryDataForLink (& crsfLinkStates [link ]);
335+ }
336+ }
337+ }
338+
339+ bool crsfRxIsTelemetryBufEmpty (rxLink_e link )
340+ {
341+ return crsfLinkStates [link ].telemetryBufLen == 0 ;
342+ }
343+
344+ bool crsfRxAreTelemetryBufsEmpty (void )
345+ {
346+ for (rxLink_e link = RX_LINK_PRIMARY ; link < RX_LINK_COUNT ; link ++ ) {
347+ if (crsfLinkStates [link ].port && !crsfRxIsTelemetryBufEmpty (link )) {
348+ return false;
349+ }
350+ }
351+ return true;
325352}
326353
327354bool crsfRxInit (const rxConfig_t * rxConfig , rxRuntimeConfig_t * rxRuntimeConfig , serialPortFunction_e portFunction )
@@ -331,6 +358,8 @@ bool crsfRxInit(const rxConfig_t *rxConfig, rxRuntimeConfig_t *rxRuntimeConfig,
331358
332359 link -> frameDone = false;
333360 link -> framePosition = 0 ;
361+ link -> telemetryBufLen = 0 ;
362+ link -> link = linkIndex ;
334363 for (int ii = 0 ; ii < CRSF_MAX_CHANNEL ; ++ ii ) {
335364 link -> channelData [ii ] = (16 * PWM_RANGE_MIDDLE ) / 10 - 1408 ;
336365 }
@@ -345,7 +374,7 @@ bool crsfRxInit(const rxConfig_t *rxConfig, rxRuntimeConfig_t *rxRuntimeConfig,
345374 return false;
346375 }
347376
348- serialPort_t * port = openSerialPort (portConfig -> identifier ,
377+ link -> port = openSerialPort (portConfig -> identifier ,
349378 portFunction ,
350379 crsfDataReceive ,
351380 link ,
@@ -354,23 +383,18 @@ bool crsfRxInit(const rxConfig_t *rxConfig, rxRuntimeConfig_t *rxRuntimeConfig,
354383 CRSF_PORT_OPTIONS | (tristateWithDefaultOffIsActive (rxConfig -> halfDuplex ) ? SERIAL_BIDIR : 0 )
355384 );
356385
357- // Telemetry replies go out the primary link's port.
358- if (linkIndex == RX_LINK_PRIMARY ) {
359- serialPort = port ;
360- }
361-
362- return port != NULL ;
386+ return link -> port != NULL ;
363387}
364388
365389bool crsfRxIsActive (void )
366390{
367- return serialPort != NULL ;
391+ return crsfLinkStates [ RX_LINK_PRIMARY ]. port || crsfLinkStates [ RX_LINK_SECONDARY ]. port ;
368392}
369393
370394
371395void crsfBind (void )
372396{
373- if (serialPort != NULL ) {
397+ if (crsfLinkStates [ RX_LINK_PRIMARY ]. port ) {
374398 uint8_t bindFrame [] = {
375399 CRSF_SYNC_BYTE ,
376400 0x07 , // frame length
@@ -382,7 +406,7 @@ void crsfBind(void)
382406 0x9E , // Command CRC8
383407 0xE8 , // Packet CRC8
384408 };
385- serialWriteBuf (serialPort , bindFrame , 9 );
409+ serialWriteBuf (crsfLinkStates [ RX_LINK_PRIMARY ]. port , bindFrame , 9 );
386410 }
387411}
388412
0 commit comments