summaryrefslogtreecommitdiffstatsabout
path: root/SylixOS
diff options
context:
space:
mode:
authorHanhui <hanhui@acoinfo.com>2021-01-11 05:57:44 (GMT)
committer Hanhui <hanhui@acoinfo.com>2021-01-11 05:57:44 (GMT)
commit2cbb8916b59d97eff7d027ae19dbea63c07f5ebd (patch)
tree6ff963eff30d41aa3821f8f3b257829e2f5971e1 /SylixOS
parenta2a66ea40da08a260d930f9f21962c927025711d (diff)
downloadlibsylixos-2cbb8916b59d97eff7d027ae19dbea63c07f5ebd.zip
libsylixos-2cbb8916b59d97eff7d027ae19dbea63c07f5ebd.tar.gz
libsylixos-2cbb8916b59d97eff7d027ae19dbea63c07f5ebd.tar.bz2
Optimized sja1000 bus error handling.
Diffstat (limited to 'SylixOS')
-rw-r--r--SylixOS/driver/can/sja1000.c37
1 files changed, 32 insertions, 5 deletions
diff --git a/SylixOS/driver/can/sja1000.c b/SylixOS/driver/can/sja1000.c
index 9803811..120eeaa 100644
--- a/SylixOS/driver/can/sja1000.c
+++ b/SylixOS/driver/can/sja1000.c
@@ -694,17 +694,44 @@ static INT sja1000Ioctl (SJA1000_CHAN *pcanchan, INT cmd, LONG arg)
*********************************************************************************************************/
VOID sja1000Isr (SJA1000_CHAN *pcanchan)
{
- int i;
- volatile UINT8 ir, temp;
- SJA1000_FRAME frame;
- CAN_FRAME canframe;
+ int i;
+ INTREG intreg;
+ volatile UINT8 ir, temp;
+ SJA1000_FRAME frame;
+ CAN_FRAME canframe;
ir = GET_REG(pcanchan, IR);
- if (ir & IR_BEI) { /* bus error int */
+ if (ir & IR_EI) { /* error int */
pcanchan->pcbSetBusState(pcanchan->pvSetBusStateArg, CAN_DEV_BUS_OFF);
return;
}
+ if (ir & IR_BEI) { /* bus error int */
+ if (GET_REG(pcanchan, MOD) & MOD_RM) {
+ pcanchan->pcbSetBusState(pcanchan->pvSetBusStateArg,
+ CAN_DEV_BUS_ERROR_NONE);
+
+ intreg = KN_INT_DISABLE();
+
+ sja1000InitChip(pcanchan);
+ sja1000SetMode(pcanchan, MOD_RM, 0); /* goto normal mode */
+
+ KN_INT_ENABLE(intreg);
+
+ /*
+ * if have data in send queue, start transmit
+ */
+ sja1000TxStartup(pcanchan);
+
+ } else { /* normal mode */
+ /*
+ * The controller will continue to record the number of errors,
+ * more than 255 will generate IR_EI error.
+ */
+ }
+ return;
+ }
+
if (ir & IR_RI) { /* recv int */
while (1) {
temp = GET_REG(pcanchan, SR);