$ sudo apt-get install manpages-dev manpages-posix-dev
manpages-dev: Manual pages about using GNU/Linux for development
manpages-posix-dev: Manual pages about using a POSIX system for development
$ sudo apt-get install manpages-dev manpages-posix-dev
manpages-dev: Manual pages about using GNU/Linux for development
manpages-posix-dev: Manual pages about using a POSIX system for development
Three steps:
Add following line in /etc/default/capemgr
CAPE=BB-DCAN1
Add following lines in /etc/network/interfaces
auto can0 iface can0 inet manual pre-up /sbin/ip link set $IFACE type can bitrate 1000000 listen-only off up /sbin/ifconfig $IFACE up down /sbin/ifconfig $IFACE down
Setting the CAN interface to /etc/network/interface does not enable the CAN interface on startup for some reason. In order to workaround this problem, I installed a startup program as follows.
Following link was helpful:
Running a script on Beaglebone Black boot/ startup
The startup script to run on startup is as follows. This script also turns off wi-fi power management, thus I removed a cron entry I added before to disable the power management.
naoki@beaglebone:~$ cat /usr/bin/startup.sh #!/bin/sh ifup -a /sbin/iwconfig wlan0 power off
Following are the steps to create and enable a service that runs on startup.
vi /lib/systemd/startup.service
[Unit]
Description=runs startup script after startup
After=syslog.target network.target
[Service]
Type=simple
ExecStart=/usr/bin/startup.sh
[Install]
WantedBy=multi-user.target
cd /etc/systemd/system/
ln -s /lib/systemd/startup.service startup.service
systemctl daemon-reload
systemctl start scriptname.service
systemctl enable scriptname.service
reboot
The operating system is Debian. This is a dirty solution but it does work anyway.
root@beaglebone:~# cat /etc/pm/power.d/wlan0_pm_off #!/bin/bash [ -x /sbin/iwconfig ] || exit 0 [ -n "`/sbin/iwconfig 2>/dev/null | grep wlan0`" ] || exit 0 /sbin/iwconfig wlan0 power off root@beaglebone:~# crontab -l | grep -v "^#" */1 * * * * /etc/pm/power.d/wlan0_pm_off root@beaglebone:~# iwconfig wlan0 wlan0 IEEE 802.11abgn ESSID:"*****" ... Power Management:off ...
Following operations seem to be necessary every BeagleBone boot. TBD to setup auto configuration on startup.
root@beaglebone:~# echo BB-DCAN1 > /sys/devices/platform/bone_capemgr/slots root@beaglebone:~# ip link set can0 up type can bitrate 500000 root@beaglebone:~# ip link set can0 up type can bitrate 1000000 root@beaglebone:~# ifconfig can0 can0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 UP RUNNING NOARP MTU:16 Metric:1 RX packets:2 errors:0 dropped:2 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:10 RX bytes:16 (16.0 B) TX bytes:0 (0.0 B) Interrupt:192 root@beaglebone:~# ip -d -s link show can0 4: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UNKNOWN mode DEFAULT group default qlen 10 link/can promiscuity 0 can state ERROR-ACTIVE (berr-counter tx 0 rx 127) restart-ms 0 bitrate 1000000 sample-point 0.750 tq 83 prop-seg 4 phase-seg1 4 phase-seg2 3 sjw 1 c_can: tseg1 2..16 tseg2 1..8 sjw 1..4 brp 1..1024 brp-inc 1 clock 24000000 re-started bus-errors arbit-lost error-warn error-pass bus-off 0 0 0 1 1 0 RX: bytes packets errors dropped overrun mcast 16 2 0 2 0 0 TX: bytes packets errors dropped carrier collsns 0 0 0 0 0 0
Used MCP2551 for CAN transceiver.
Pin 24 -> CAN RX Pin 26 -> CAN TX Pin 2 -> GND Pin 6 -> VDD 5V
See the picture above.
naoki-macbook:~ naoki$ screen /dev/tty.usbmodem14244421
root@beaglebone:~# candump can0 can0 100 [3] 09 4A 46 can0 100 [3] 08 4A 00
Serial port monitor:
note on [ 01 00] 4a note off [ 01 00] 4a
I’ve tried to enable CAN on my BeagleBone Green board. I had to stop the work before verification, because my logic analyzer is unavailable now. I record what I did in this article to make things reproducible when the logic analyzer is back.
There are several helpful links:
http://www.embedded-things.com/bbb/enable-canbus-on-the-beaglebone-black/
http://electronics.stackexchange.com/questions/195416/beaglebone-black-can-bus-setup
Readings to understand device tree overlay:
Device Tree for Dummies:
http://events.linuxfoundation.jp/sites/events/files/slides/petazzoni-device-tree-dummies.pdf
Device Tree Overlays (in adafruit)
https://learn.adafruit.com/introduction-to-the-beaglebone-black-device-tree/device-tree-overlays
Here are what I did:
# make a workspace root@beaglebone:~# mkdir can root@beaglebone:~# cd can root@beaglebone:~/can# pwd /root/can # check if CAN is enabled ... no root@beaglebone:~/can# dmesg | grep can # take backup of the original device tree blob file for CAN root@beaglebone:~/can# cp /lib/firmware/BB-CAN1-00A0.dtbo BB-CAN1-00A0.dtbo.orig # make the device tree overlay root@beaglebone:~/can# vi BB-DCAN1-00A0.dts root@beaglebone:~/can# cat !$ cat BB-DCAN1-00A0.dts /dts-v1/; /plugin/; / { compatible = "ti,beaglebone", "ti,beaglebone-black"; /* identification */ part-number = "dcan1pinmux"; fragment@0 { target = <&am33xx_pinmux>; __overlay__ { dcan1_pins_s0: dcan1_pins_s0 { pinctrl-single,pins = < 0x180 0x12 /* d_can1_tx, SLEWCTRL_FAST | INPUT_PULLUP | MODE2 */ 0x184 0x32 /* d_can1_rx, SLEWCTRL_FAST | RECV_ENABLE | INPUT_PULLUP | MODE2 */ >; }; }; }; fragment@1 { target = <&dcan1>; __overlay__ { #address-cells = <1>; #size-cells = <0>; status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&dcan1_pins_s0>; }; }; }; # install the new device tree blob for CAN root@beaglebone:~/can# dtc -O dtb -o BB-DCAN1-00A0.dtbo -b 0 -@ BB-DCAN1-00A0.dts root@beaglebone:~/can# ls BB-CAN1-00A0.dtbo.orig BB-DCAN1-00A0.dtbo BB-DCAN1-00A0.dts root@beaglebone:~/can# cp BB-DCAN1-00A0.dtbo /lib/firmware/ root@beaglebone:~/can# cmp BB-DCAN1-00A0.dtbo /lib/firmware/BB-DCAN1-00A0.dtbo # add the device root@beaglebone:/lib/firmware# cat /sys/devices/platform/bone_capemgr/slots 0: PF---- -1 1: PF---- -1 2: PF---- -1 3: PF---- -1 root@beaglebone:~/can# echo BB-DCAN1 > /sys/devices/platform/bone_capemgr/slots root@beaglebone:~/can# cat !$ cat /sys/devices/platform/bone_capemgr/slots 0: PF---- -1 1: PF---- -1 2: PF---- -1 3: PF---- -1 4: P-O-L- 0 Override Board Name,00A0,Override Manuf,BB-DCAN1 # check dmesg ... looks fine root@beaglebone:~/can# dmesg | tail -n15 [ 25.499860] wlan0: send auth to 00:1d:73:33:47:a0 (try 1/3) [ 25.522620] wlan0: authenticated [ 25.524815] wl18xx_driver wl18xx.2.auto wlan0: disabling HT/VHT due to WEP/TKIP use [ 25.528911] wlan0: associate with 00:1d:73:33:47:a0 (try 1/3) [ 25.538576] wlan0: RX AssocResp from 00:1d:73:33:47:a0 (capab=0x431 status=0 aid=4) [ 25.764831] wlan0: associated [ 25.765114] IPv6: ADDRCONF(NETDEV_CHANGE): wlan0: link becomes ready [ 26.579282] wlcore: Association completed. [ 3395.588267] bone_capemgr bone_capemgr: part_number 'BB-DCAN1', version 'N/A' [ 3395.588337] bone_capemgr bone_capemgr: slot #4: override [ 3395.588380] bone_capemgr bone_capemgr: Using override eeprom data at slot 4 [ 3395.588425] bone_capemgr bone_capemgr: slot #4: 'Override Board Name,00A0,Override Manuf,BB-DCAN1' [ 3395.613523] bone_capemgr bone_capemgr: slot #4: dtbo 'BB-DCAN1-00A0.dtbo' loaded; overlay id #0 [ 3395.648848] CAN device driver interface [ 3395.689001] c_can_platform 481d0000.can: c_can_platform device registered (regs=fa1d0000, irq=192) # load CAN modules root@beaglebone:~/can# sudo modprobe can root@beaglebone:~/can# sudo modprobe can-dev root@beaglebone:~/can# sudo modprobe can-raw root@beaglebone:~/can# lsmod | grep can can_raw 5852 0 can 28397 1 can_raw c_can_platform 6602 0 c_can 9577 1 c_can_platform can_dev 11663 1 c_can # Startup the CAN interface. Set CAN channel rate 500kbps. root@beaglebone:~# ip link set can0 up type can bitrate 500000 root@beaglebone:~# ifconfig can0 can0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 UP RUNNING NOARP MTU:16 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:10 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) Interrupt:192 # Check the device status. Status UNKNOWN doesn't sound right... root@beaglebone:~/can# ip -d -s link show can0 4: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UNKNOWN mode DEFAULT group default qlen 10 link/can promiscuity 0 can state ERROR-ACTIVE (berr-counter tx 0 rx 0) restart-ms 0 bitrate 125000 sample-point 0.875 tq 500 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1 c_can: tseg1 2..16 tseg2 1..8 sjw 1..4 brp 1..1024 brp-inc 1 clock 24000000 re-started bus-errors arbit-lost error-warn error-pass bus-off 0 0 0 0 0 0 RX: bytes packets errors dropped overrun mcast 0 0 0 0 0 0 TX: bytes packets errors dropped carrier collsns 0 0 0 0 0 0
Then I have to stop here.
Use connmanctl as described in /etc/network/interfaces.
root@beaglebone:~# connmanctl
connmanctl> tether wifi disable
Error disabling wifi tethering: Already disabled
connmanctl> scan wifi
Scan completed for wifi
connmanctl> services
Analog20 wifi_xxxxxxxxxxxxxxxxxxxxxxxxxxx_managed_psk
connmanctl> agent on
Agent registered
connmanctl> connect wifi_xxxxxxxxxxxxxxxxxxxxxxxxxxx_managed_psk
… and so on
Following links give useful information:
http://xx-prime.hatenablog.com/entry/2016/08/13/012059 (in Japanese)
https://www.mail-archive.com/beagleboard@googlegroups.com/msg40785.html
The wlan0 device power management can be turned off by
# iwconfig wlan0 power off
TBD how to turn this off permanently.
Following link is helpful to know how to backup disks in several styles:
https://wiki.archlinux.org/index.php/disk_cloning
Useful when the SSH access has a problem:
$ ls /dev/tty.*
$ screen
For archival purpose:
http://can-bus.996267.n3.nabble.com/Anybody-ever-run-an-MCP2515-at-greater-than-1Mbps-td1859.html
you are certainly right about 1Mbps being the maximum speed of the official CAN spec. However, some of us like to break the rules :)
I do :)
I’m using CAN for a purpose different from controlling automobile so my breaking rule would not cause any death.
You need miniprog3 to program this, despite typical programming to this kit is via boot loader.
1. Put a SCB UART component. Change baud rate to 9600.
2. Assign pins as follows:
UART RX : P4[0]
UART TX : P4[1]
3. And then, here is the main.c source code
int main() { CyGlobalIntEnable; /* Enable global interrupts. */ /* Place your initialization/startup code here (e.g. MyInst_Start()) */ UART_1_Start(); UART_1_UartPutString("Hello world from CY8CKIT-049-42xx\r\n"); for(;;) { /* Place your application code here. */ } }
4. Build it, program it, and connect the CY8CKIT-049-42xx to the PC.
That’s it.
PSoC 42xx provides SPI component that supports up to 4MHz clock speed. Communicating with MCP2515 via this component, however, is not straightforward when you try the highest clock speed.
The problem is concept of ‘operation’ of MCP2515. An operation consists of multiple SPI bytes bundled by ‘enable’ signal on the CS pin. Lowering the CS pin initiates an operation and it must stay low during the data transmission. See following timing chart quoted from the MCP2515 datasheet.
The PSoC SPI component lacks direct control on the CS pin signal. The component automatically lowers the CS level when the write API puts a byte to Tx FIFO and the component’s internal logic raises the CS level when all FIFO values are consumed. But auto-generated API functions are not fast enough due to overhead to make the functions generic. Then, the CS signal may split during an operation when Tx FIFO becomes empty due to the API failing to catch up with the desired speed.
I wrote a function that generates a valid READ operation frame and retrieves returned bytes. The strategy is:
There are limitations to use this functions:
Here is the source code. In this example code, the SPI component name is ‘SPIM_CAN’ which is a master SPI component (non SCB).
#define CAN_CTL_READ 0x03 void mcp2515_read(uint8_t address, uint8_t data[], uint8_t length) { /* initialization */ uint8_t to_write = length; length += 2; /* flush rx buffer */ while (SPIM_CAN_GetRxBufferSize()) SPIM_CAN_ReadRxData(); /* wait until Tx FIFO becomes empty */ while (0u == (SPIM_CAN_TX_STATUS_REG & SPIM_CAN_STS_TX_FIFO_EMPTY)) {} CY_SET_REG8(SPIM_CAN_TXDATA_PTR, CAN_CTL_READ); // push instruction CY_SET_REG8(SPIM_CAN_TXDATA_PTR, address); // push address // loop until all bytes are retrieved while (length > 0) { // transmit 0 to receive a byte if (to_write > 0 && (SPIM_CAN_TX_STATUS_REG & SPIM_CAN_STS_TX_FIFO_NOT_FULL)) { CY_SET_REG8(SPIM_CAN_TXDATA_PTR, 0); --to_write; } // retrieve a byte if there is any in Rx FIFO if (SPIM_CAN_RX_STATUS_REG & SPIM_CAN_STS_RX_FIFO_NOT_EMPTY) { *data++ = CY_GET_REG8(SPIM_CAN_RXDATA_PTR); --length; } } }
Tried reading 16 bytes from MCP2515 using this read function from a 4MHz-clock SPI of a PSoC Pionner Kit. The CS (Enable) signal stays low during the operation, as expected.
I tried Google Protocol Buffers to describe and transfer modules’ schema before. This approach, however, did not work well because it required large amount of resources both in program and in RAM spaces of a PSoC processor. It limited available resources for module functionality. I finally gave up the approach.
I am trying another approach to describe a module using JSON and to compile it into a parameter table implemented using C macros. The module program does not have to include the schema. Sharing the JSON schema file by Analog 3 modules is good enough. It is nice if the module has the schema internally though. Google Protocol Buffer may help compressing the data in the case.
Here is an example of schema and generated table for MIDI Gateway module:
{ "name": "midigw", "type": "Module", "member": [ { "name": "MIDI channel", "type": "NumberSelector", "min": 1, "max": 16 }, { "name": "Voices", "type": "Selector", "choices": ["mono", "duo", "poly 4", "poly 5", "poly 6", "poly 8", "poly 10", "poly 16"] }, { "name": "Retrigger", "type": "Switch", "default": True } ] } #define P_N1_MIDI_CHANNEL_OFFSET 0 #define P_L_VOICES_OFFSET 1 #define P_B_RETRIGGER_OFFSET 2 #define P_BUFFER_SIZE 3 static uint8_t p_buffer[P_BUFFER_SIZE]; #define P_N1_MIDI_CHANNEL (*(uint8_t*)&p_buffer[P_N1_MIDI_CHANNEL_OFFSET]) #define P_N1_MIDI_CHANNEL_VALUE_OFFSET 1 #define P_L_VOICES (*(uint8_t*)&p_buffer[P_L_VOICES_OFFSET]) #define P_L_VOICES__MONO 0 #define P_L_VOICES__DUO 1 #define P_L_VOICES__POLY_4 2 #define P_L_VOICES__POLY_5 2 #define P_L_VOICES__POLY_6 2 #define P_L_VOICES__POLY_8 2 #define P_L_VOICES__POLY_10 2 #define P_L_VOICES__POLY_16 2 #define P_B_RETRIGGER (*(uint8_t*)&p_buffer[P_B_RETRIGGER_OFFSET])