> For the complete documentation index, see [llms.txt](https://amobile-solutions.gitbook.io/yocto-developer-guide/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://amobile-solutions.gitbook.io/yocto-developer-guide/test-and-use-the-interface/can/can-iot-800n-g420.md).

# CAN - IOT-800N-G420

## Overview

|                   |                                                   |
| ----------------- | ------------------------------------------------- |
| Controller        | Fintek F81604N                                    |
| Interface         | **USB**, behind the internal GL852G hub           |
| Transceiver       | Fintek F81252S, CAN FD capable                    |
| Driver            | `f81604`                                          |
| Network interface | `can0`                                            |
| Termination       | 120 Ω, software selectable                        |
| Connector         | 10-pin terminal block, shared with the digital IO |

The controller appears as a SocketCAN network device, so all the standard Linux CAN tooling works.

## Checking the controller

```
lsusb | grep -i 2c42
ip link show can0
```

```
dmesg | grep -i f81604
```

## Bringing the interface up

The bitrate has to be set while the interface is down:

```
ip link set can0 down
ip link set can0 type can bitrate 500000 termination 120
ip link set can0 up
```

```
ip -details link show can0
```

```
can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UP
    can state ERROR-ACTIVE (berr-counter tx 0 rx 0) restart-ms 0
          bitrate 500000 sample-point 0.875
          termination 120 [ 0, 120 ]
```

Three things to check in that output:

| Field       | Expected                   |
| ----------- | -------------------------- |
| `state`     | `UP`                       |
| `can state` | `ERROR-ACTIVE`             |
| `qdisc`     | anything other than `noop` |

{% hint style="info" %}
`qdisc noop` means the interface was never really brought up, and every frame sent will be discarded silently.
{% endhint %}

## Termination

The transceiver has a software-controlled 120 Ω terminator, so no external resistor is needed:

```
ip link set can0 type can bitrate 500000 termination 120
```

A CAN bus needs termination at each end. With two nodes connected directly, both ends set `termination 120`. On a longer bus with several nodes, only the two physical ends should be terminated.

## Sending and receiving

```
candump can0
```

```
cansend can0 123#DEADBEEF                  standard 11-bit frame
cansend can0 18EBFF81#0102030405060708     extended 29-bit frame
```

To generate traffic for a throughput test:

```
cangen can0 -g 10 -I 42 -L 8
```

## Two-board test

Wire CANH to CANH and CANL to CANL between the boards, and set the same bitrate on both.

```
candump can0
```

```
cansend can0 123#DEADBEEF
```

`can-utils` also provides a full-duplex test:

```
canfdtest -v can0          on one board
canfdtest -v -g can0       on the other
```

## Checking that frames actually left

`cansend` returning without error only means the frame was accepted into the socket, not that it reached the bus.

```
ip -details -statistics link show can0 | grep -A3 "TX:"
```

| Counters                                  | Meaning                                                       |
| ----------------------------------------- | ------------------------------------------------------------- |
| `packets` rising, `errors` 0              | Frames are being sent and acknowledged                        |
| `packets` 0, `berr-counter tx` rising     | Sent, but nothing acknowledged — check wiring and termination |
| `packets` 0, `errors` 0, `dropped` rising | Frames discarded before reaching the controller               |

{% hint style="info" %}
CAN requires at least one other node to acknowledge each frame. A single board on its own cannot transmit successfully, and the error counters will climb.
{% endhint %}

## Bitrate

| Bitrate | Typical use                             |
| ------- | --------------------------------------- |
| 250000  | J1939, most commercial vehicle networks |
| 500000  | OBD-II and general industrial use       |
| 1000000 | Short high-speed links                  |

Both ends of a bus must agree. A mismatch looks like one-way communication rather than an obvious failure.

## Making it persistent

```
ip link set can0 type can bitrate 500000 termination 120
ip link set can0 up
```

To apply at boot, use a systemd unit or a networkd `.network` file rather than relying on a login shell.

## Kernel driver

{% hint style="warning" %}
The mainline `f81604` driver in kernel 6.6 does not transmit correctly with this controller's firmware. Receive works, but transmitted frames are discarded before reaching the hardware, showing as `TX packets 0` with `dropped` rising and this in the log:

```
f81604 ...: f81604_read_int_callback: short int URB: 9 < 12
```

The driver and the firmware disagree about the interrupt packet length. The SDK ships the vendor driver from Fintek, which uses the correct value. If you rebuild the kernel from upstream sources, make sure the vendor version is the one being built.
{% endhint %}

## Troubleshooting

### can0 does not exist

The controller is behind the internal USB hub, which shares a supply with the serial port and the LTE module. If all three are missing at once, the hub is unpowered rather than the controller being faulty.

```
lsusb | grep -i 05e3      the GL852G hub
```

### The bus goes to BUS-OFF

```
ip -details link show can0 | grep "can state"
```

`BUS-OFF` means the controller gave up after too many errors. Usual causes are a bitrate mismatch, missing termination, or CANH and CANL swapped.

```
ip link set can0 down
ip link set can0 up
```

To recover automatically:

```
ip link set can0 type can restart-ms 100
```
