Change in simtrace2[master]: card_emu: Fix USART timer, particularly in re-start situations

2021-04-08 Thread laforge
laforge has submitted this change. ( 
https://gerrit.osmocom.org/c/simtrace2/+/23643 )

Change subject: card_emu: Fix USART timer, particularly in re-start situations
..

card_emu: Fix USART timer, particularly in re-start situations

The existing code started the timer once (and expired once) but didn't
properly handle re-starting of the timer.  Neither did it handle
the 'half time expiration' case.  If we want to call a function after
half the WT expiring, we must of course program the hardware for half
the timeout, and not the full timeout...

Change-Id: Ia999d97f835c27597fcd1cf7ac78bac0ab9c98c1
Related: OS#1704
---
M firmware/libcommon/source/mode_cardemu.c
1 file changed, 40 insertions(+), 12 deletions(-)

Approvals:
  laforge: Looks good to me, approved
  Jenkins Builder: Verified



diff --git a/firmware/libcommon/source/mode_cardemu.c 
b/firmware/libcommon/source/mode_cardemu.c
index 8531eb5..14f62a6 100644
--- a/firmware/libcommon/source/mode_cardemu.c
+++ b/firmware/libcommon/source/mode_cardemu.c
@@ -212,6 +212,23 @@
return 1;
 }

+static uint16_t compute_next_timeout(struct cardem_inst *ci)
+{
+   uint32_t want_to_expire;
+
+   if (ci->wt.total == 0)
+   return 0;
+
+   if (!ci->wt.half_time_notified) {
+   /* we need to make sure to expire after half the total waiting 
time */
+   OSMO_ASSERT(ci->wt.remaining > (ci->wt.total / 2));
+   want_to_expire = ci->wt.remaining - (ci->wt.total / 2);
+   } else
+   want_to_expire = ci->wt.remaining;
+   TRACE_INFO("want_to_expire=%u (total=%u, remaining=%u)\r\n", 
want_to_expire, ci->wt.total, ci->wt.remaining);
+   /* if value exceeds the USART TO range, use the maximum possible value 
for one round */
+   return OSMO_MIN(want_to_expire, 0x);
+}

 /*! common handler if interrupt was received.
  *  \param[in] inst_num Instance number, range 0..1 (some boards only '0' 
permitted) */
@@ -254,6 +271,9 @@
 * how many etu have expired since we last sent a byte.  See section
 * 33.7.3.11 "Receiver Time-out" of the SAM3S8 Data Sheet */
if (csr & US_CSR_TIMEOUT) {
+   /* clear timeout flag (and stop timeout until next character is 
received) */
+   usart->US_CR |= US_CR_STTTO;
+
/* RX has been inactive for some time */
if (ci->wt.remaining <= (usart->US_RTOR & 0x)) {
/* waiting time is over; will stop the timer */
@@ -266,17 +286,26 @@
if (ci->wt.remaining == 0) {
/* let the FSM know that WT has expired */
card_emu_wtime_expired(ci->ch);
-   } else if (ci->wt.remaining <= ci->wt.total / 2 && 
!ci->wt.half_time_notified) {
-   /* let the FS know that half of the WT has expired */
-   card_emu_wtime_half_expired(ci->ch);
-   ci->wt.half_time_notified = true;
+   /* don't automatically re-start in this case */
+   } else {
+   bool half_time_just_reached = false;
+
+   if (ci->wt.remaining <= ci->wt.total / 2 && 
!ci->wt.half_time_notified) {
+   ci->wt.half_time_notified = true;
+   /* don't immediately call 
card_emu_wtime_half_expired(), as that
+* in turn may calls card_emu_uart_update_wt() 
which will change
+* the timeout but would be overridden 4 lines 
below */
+   half_time_just_reached = true;
+   }
+
+   /* update the counter no matter if we reached half time 
or not */
+   usart->US_RTOR = compute_next_timeout(ci);
+   /* restart the counter (if wt is 0, the timeout is not 
started) */
+   usart->US_CR |= US_CR_RETTO;
+
+   if (half_time_just_reached)
+   card_emu_wtime_half_expired(ci->ch);
}
-   /* if value exceeds the USART TO range, use the maximum for now 
*/
-   usart->US_RTOR = OSMO_MIN(ci->wt.remaining, 0x);
-   /* clear timeout flag (and stop timeout until next character is 
received) */
-   usart->US_CR |= US_CR_STTTO;
-   /* restart the counter (it wt is 0, the timeout is not started) 
*/
-   usart->US_CR |= US_CR_RETTO;
}
 }

@@ -336,8 +365,7 @@
/* FIXME: guard against race with interrupt handler */
ci->wt.remaining = ci->wt.total;
ci->wt.half_time_notified = false;
-   /* if value exceeds the USART TO range, use the maximum for now */
-   usart->US_RTOR = OSMO_MIN(ci->wt.remaining, 0x);
+   usart->US_RTOR = compute_next_timeout(ci);

Change in simtrace2[master]: card_emu: Fix USART timer, particularly in re-start situations

2021-04-08 Thread laforge
laforge has posted comments on this change. ( 
https://gerrit.osmocom.org/c/simtrace2/+/23643 )

Change subject: card_emu: Fix USART timer, particularly in re-start situations
..


Patch Set 2: Code-Review+2


--
To view, visit https://gerrit.osmocom.org/c/simtrace2/+/23643
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings

Gerrit-Project: simtrace2
Gerrit-Branch: master
Gerrit-Change-Id: Ia999d97f835c27597fcd1cf7ac78bac0ab9c98c1
Gerrit-Change-Number: 23643
Gerrit-PatchSet: 2
Gerrit-Owner: laforge 
Gerrit-Reviewer: Hoernchen 
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge 
Gerrit-Reviewer: tsaitgaist 
Gerrit-Comment-Date: Thu, 08 Apr 2021 21:28:30 +
Gerrit-HasComments: No
Gerrit-Has-Labels: Yes
Gerrit-MessageType: comment


Change in simtrace2[master]: card_emu: Fix USART timer, particularly in re-start situations

2021-04-06 Thread laforge
Hello Jenkins Builder,

I'd like you to reexamine a change. Please visit

https://gerrit.osmocom.org/c/simtrace2/+/23643

to look at the new patch set (#2).

Change subject: card_emu: Fix USART timer, particularly in re-start situations
..

card_emu: Fix USART timer, particularly in re-start situations

The existing code started the timer once (and expired once) but didn't
properly handle re-starting of the timer.  Neither did it handle
the 'half time expiration' case.  If we want to call a function after
half the WT expiring, we must of course program the hardware for half
the timeout, and not the full timeout...

Change-Id: Ia999d97f835c27597fcd1cf7ac78bac0ab9c98c1
Related: OS#1704
---
M firmware/libcommon/source/mode_cardemu.c
1 file changed, 40 insertions(+), 12 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/simtrace2 refs/changes/43/23643/2
--
To view, visit https://gerrit.osmocom.org/c/simtrace2/+/23643
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings

Gerrit-Project: simtrace2
Gerrit-Branch: master
Gerrit-Change-Id: Ia999d97f835c27597fcd1cf7ac78bac0ab9c98c1
Gerrit-Change-Number: 23643
Gerrit-PatchSet: 2
Gerrit-Owner: laforge 
Gerrit-Reviewer: Jenkins Builder
Gerrit-MessageType: newpatchset


Change in simtrace2[master]: card_emu: Fix USART timer, particularly in re-start situations

2021-04-05 Thread laforge
laforge has uploaded this change for review. ( 
https://gerrit.osmocom.org/c/simtrace2/+/23643 )


Change subject: card_emu: Fix USART timer, particularly in re-start situations
..

card_emu: Fix USART timer, particularly in re-start situations

The existing code started the timer once (and expired once) but didn't
properly handle re-starting of the timer.  Neither did it handle
the 'half time expiration' case.  If we want to call a function after
half the WT expiring, we must of course program the hardware for half
the timeout, and not the full timeout...

Change-Id: Ia999d97f835c27597fcd1cf7ac78bac0ab9c98c1
---
M firmware/libcommon/source/mode_cardemu.c
1 file changed, 40 insertions(+), 12 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/simtrace2 refs/changes/43/23643/1

diff --git a/firmware/libcommon/source/mode_cardemu.c 
b/firmware/libcommon/source/mode_cardemu.c
index 8531eb5..14f62a6 100644
--- a/firmware/libcommon/source/mode_cardemu.c
+++ b/firmware/libcommon/source/mode_cardemu.c
@@ -212,6 +212,23 @@
return 1;
 }

+static uint16_t compute_next_timeout(struct cardem_inst *ci)
+{
+   uint32_t want_to_expire;
+
+   if (ci->wt.total == 0)
+   return 0;
+
+   if (!ci->wt.half_time_notified) {
+   /* we need to make sure to expire after half the total waiting 
time */
+   OSMO_ASSERT(ci->wt.remaining > (ci->wt.total / 2));
+   want_to_expire = ci->wt.remaining - (ci->wt.total / 2);
+   } else
+   want_to_expire = ci->wt.remaining;
+   TRACE_INFO("want_to_expire=%u (total=%u, remaining=%u)\r\n", 
want_to_expire, ci->wt.total, ci->wt.remaining);
+   /* if value exceeds the USART TO range, use the maximum possible value 
for one round */
+   return OSMO_MIN(want_to_expire, 0x);
+}

 /*! common handler if interrupt was received.
  *  \param[in] inst_num Instance number, range 0..1 (some boards only '0' 
permitted) */
@@ -254,6 +271,9 @@
 * how many etu have expired since we last sent a byte.  See section
 * 33.7.3.11 "Receiver Time-out" of the SAM3S8 Data Sheet */
if (csr & US_CSR_TIMEOUT) {
+   /* clear timeout flag (and stop timeout until next character is 
received) */
+   usart->US_CR |= US_CR_STTTO;
+
/* RX has been inactive for some time */
if (ci->wt.remaining <= (usart->US_RTOR & 0x)) {
/* waiting time is over; will stop the timer */
@@ -266,17 +286,26 @@
if (ci->wt.remaining == 0) {
/* let the FSM know that WT has expired */
card_emu_wtime_expired(ci->ch);
-   } else if (ci->wt.remaining <= ci->wt.total / 2 && 
!ci->wt.half_time_notified) {
-   /* let the FS know that half of the WT has expired */
-   card_emu_wtime_half_expired(ci->ch);
-   ci->wt.half_time_notified = true;
+   /* don't automatically re-start in this case */
+   } else {
+   bool half_time_just_reached = false;
+
+   if (ci->wt.remaining <= ci->wt.total / 2 && 
!ci->wt.half_time_notified) {
+   ci->wt.half_time_notified = true;
+   /* don't immediately call 
card_emu_wtime_half_expired(), as that
+* in turn may calls card_emu_uart_update_wt() 
which will change
+* the timeout but would be overridden 4 lines 
below */
+   half_time_just_reached = true;
+   }
+
+   /* update the counter no matter if we reached half time 
or not */
+   usart->US_RTOR = compute_next_timeout(ci);
+   /* restart the counter (if wt is 0, the timeout is not 
started) */
+   usart->US_CR |= US_CR_RETTO;
+
+   if (half_time_just_reached)
+   card_emu_wtime_half_expired(ci->ch);
}
-   /* if value exceeds the USART TO range, use the maximum for now 
*/
-   usart->US_RTOR = OSMO_MIN(ci->wt.remaining, 0x);
-   /* clear timeout flag (and stop timeout until next character is 
received) */
-   usart->US_CR |= US_CR_STTTO;
-   /* restart the counter (it wt is 0, the timeout is not started) 
*/
-   usart->US_CR |= US_CR_RETTO;
}
 }

@@ -336,8 +365,7 @@
/* FIXME: guard against race with interrupt handler */
ci->wt.remaining = ci->wt.total;
ci->wt.half_time_notified = false;
-   /* if value exceeds the USART TO range, use the maximum for now */
-   usart->US_RTOR = OSMO_MIN(ci->wt.remaining, 0x);
+   usart->US_RTOR = compute_next_timeout(ci);
/*