CAN IoT Card driver

Hello,
I got this CAN module
http://www.taloncom.com/images/Talon%20mangOH%20CAN%20Bus%20Module%20Brief%202016.pdf

Is this the right tutorial for MangOH Red in order to get this CAN module to work?
https://github.com/mangOH/mangOH/wiki/How-to-build-MCP2515-CAN-drivers-for-mangOH-for-mangOH-Red

Yes, it is.
Let us know if you have any issues

The link in step one is broken
"1. Download Legato Distribution Source Package from Sierra Wireless website:
Yocto Source (Around 3 GB)"

Thanks. Fixed the link. You need to pick the latest toolchain package

I have this «module. Do you have the schematic ? Not found on the web site.

Nope, same problem…

The link on the wiki is https://source.sierrawireless.com/resources/legato/downloads/

Is this the problem?

Sorry Asyal, the link is ok, I ment the CAN module electrical schematic

I have builded the new yocto image to support the CAN IoT card. I not see in menu config a way to add can-utils. For example candump is very good utility to monitor can message. Any way to add it in yocto ??? Thanks

Hello

I have connected the CAN Iot card TALON to a can viewer.

I meet a problem.

I can send 1 can message only. The next message are not sent.
Any idea ??

This is my code (using socket CAN). Very basic…
Hello message is send but not the second message…

int can_loop(void)
{
struct ifreq ifr;
struct sockaddr_can addr;
struct can_frame frame;
int s;
memset(&ifr, 0x0, sizeof(ifr));
memset(&addr, 0x0, sizeof(addr));
memset(&frame, 0x0, sizeof(frame));
/* open CAN_RAW socket /
s = socket(PF_CAN, SOCK_RAW, CAN_RAW);
/
convert interface sting “can0” into interface index /
strcpy(ifr.ifr_name, “can0”);
ioctl(s, SIOCGIFINDEX, &ifr);
/
setup address for bind /
addr.can_ifindex = ifr.ifr_ifindex;
addr.can_family = PF_CAN;
/
bind socket to the can0 interface */
bind(s, (struct sockaddr )&addr, sizeof(addr));
/
first fill, then send the CAN frame */
frame.can_id = 0x23;
strcpy((char )frame.data, “hello”);
frame.can_dlc = 5;
write(s, &frame, sizeof(frame));
/
first fill, then send the CAN frame */
frame.can_id = 0x24;
strcpy((char *)frame.data, “iCC2012”);
frame.can_dlc = 7;
write(s, &frame, sizeof(frame));
close(s);
return 0;
}

COMPONENT_INIT
{

// Run the can-init.sh before advertising the service to ensure that the CAN device is
// available before we allow it to be used.
char line[256];
FILE* fp = popen("can_init.sh 2>&1", "r");
LE_ASSERT(fp != NULL);
while (fgets(line, sizeof(line), fp) != NULL)
{
	LE_INFO("can_init.sh output: %s", line);
}
int canInitResult = pclose(fp);
LE_FATAL_IF(!WIFEXITED(canInitResult), "Could not run can_init.sh");
const int canInitExitCode = WEXITSTATUS(canInitResult);
LE_FATAL_IF(canInitExitCode != 0, "can_init.sh failed with exit code %d", canInitExitCode);

can_loop();

}

I suspect a patch problem. I not use the patch for the Mangoh Red…
I must rebuild the yocto linux distro…

All is good now with the correct patch :slight_smile:

hey,
can you suggest links related LoRa expansion card ?
Not found any useful data related to it?
any documentation releted to it will be really useful

Is that CAN driver tutorial only for wp85?
I have wp7502, is it ok to follow it until the end or do I need to change some of the commands along the way?

I think it’s the same for wp7502.
For wp76 I m in progress for the patch.

Did you get your wp76 to work according to described steps?

I have rebuild the Linux yocto to add can support and mcp2515 driver.
I use R7 firmware with kernel 3.18 and yocto 2.2.

For the moment it doesn’t work. I have modified the board file 9607.c to add the patch but the mcp2515 seems not detected.

Tommorow I will connect my scope to look if the gpio and spi bus work correctly.

In the patch file, can you change #define MSM_WIFI_IRQ_GPIO 80 to be #define MSM_WIFI_IRQ_GPIO 79?
I havent tried it but let me know if that works.

This is my source code of board-9607.c

Tell me if you see a error.

/*

  • Copyright © 2015, The Linux Foundation. All rights reserved.
  • This program is free software; you can redistribute it and/or modify
  • it under the terms of the GNU General Public License version 2 and
  • only version 2 as published by the Free Software Foundation.
  • This program is distributed in the hope that it will be useful,
  • but WITHOUT ANY WARRANTY; without even the implied warranty of
  • MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  • GNU General Public License for more details.
    */

#include <linux/kernel.h>
#include <asm/mach/map.h>
#include <asm/mach/arch.h>
#include “board-dt.h”

#ifdef CONFIG_WL_TI
#include <linux/wl12xx.h>
#endif

#include <linux/irq.h>
#include <linux/can/platform/mcp251x.h>
#include <linux/gpio.h>

/*

  • CAN bus GPIO interrupt line uses kernel GPIO73 which maps to user space
  • GPIO42
    */
    #define MCP2515_CAN_IRQGPIO_PIN 79

static const char *mdm9607_dt_match[] __initconst = {
“qcom,mdm9607”,
NULL
};

static void __init mdm9607_init(void)
{
board_dt_populate(NULL);
}

/* CAN driver modification /
static struct mcp251x_platform_data msm_mcp2515_pdata = {
.oscillator_frequency = 16
1000*1000,
};

/* CAN driver modification /
static struct spi_board_info msm_spi_mcp2515_board_info[] = {
[0] = {
.modalias = “mcp2515”,
.platform_data = &msm_mcp2515_pdata,
.max_speed_hz = 2
1000*1000,
.mode = SPI_MODE_0,
.bus_num = 0,
.chip_select = 0,
},
};

static void __init msm9615_mcp2515_init(void)
{
if ((gpio_request(MCP2515_CAN_IRQGPIO_PIN, “can_irq”) == 0) &&
(gpio_direction_input(MCP2515_CAN_IRQGPIO_PIN) == 0)) {
gpio_export(MCP2515_CAN_IRQGPIO_PIN, 0);
irq_set_irq_type(gpio_to_irq(MCP2515_CAN_IRQGPIO_PIN), IRQ_TYPE_EDGE_FALLING);
} else {
printk(KERN_ERR “Could not obtain gpio for MCP251X CAN bus interrupt\n”);
return;
}
msm_spi_mcp2515_board_info[0].irq = gpio_to_irq(MCP2515_CAN_IRQGPIO_PIN);
pr_notice(
“msm9615_mcp2515_init init done(gpio:%d irq:%d).\n”,
MCP2515_CAN_IRQGPIO_PIN,
msm_spi_mcp2515_board_info[0].irq);
}

#ifdef CONFIG_WL_TI
#define MSM_WIFI_IRQ_GPIO 79
#endif
/* CAN driver modification */
static void __init msm9615_common_init(void)
{
pr_notice(“Kernel with CANBUS support initializing\n”);
msm9615_mcp2515_init();
spi_register_board_info(
msm_spi_mcp2515_board_info,
ARRAY_SIZE(msm_spi_mcp2515_board_info));

}

/* CAN driver modification */
static void __init msm9615_mtp_init(void)
{
msm9615_common_init();
}

#ifdef CONFIG_WL_TI
static void __init mdm9607_wl18xx_init(void)
{
struct wl12xx_platform_data msm_wl12xx_pdata;
int ret;

memset(&msm_wl12xx_pdata, 0, sizeof(msm_wl12xx_pdata));

msm_wl12xx_pdata.irq = gpio_to_irq(MSM_WIFI_IRQ_GPIO);
printk(KERN_ERR "wl12xx GPIO: %d\n", msm_wl12xx_pdata.irq);
if (msm_wl12xx_pdata.irq < 0)
	goto fail;

msm_wl12xx_pdata.use_eeprom = true;
msm_wl12xx_pdata.board_ref_clock = WL12XX_REFCLOCK_38;
msm_wl12xx_pdata.board_tcxo_clock = 0;

ret = wl12xx_set_platform_data(&msm_wl12xx_pdata);
if (ret < 0)
	goto fail;

pr_info("wl18xx board initialization done\n");
return;

fail:
pr_err("%s: wl12xx board initialisation failed\n", func);
}
#endif

DT_MACHINE_START(MDM9607_DT,
“Qualcomm Technologies, Inc. MDM 9607 (Flattened Device Tree)”)
.init_machine = mdm9607_init,
.dt_compat = mdm9607_dt_match,
.init_machine = msm9615_mtp_init, /* CAN driver modification */
#ifdef CONFIG_WL_TI
.init_late = mdm9607_wl18xx_init,
#endif
MACHINE_END

I use my scope to debug

  • echo 2 > /sys/class/gpio/export

  • echo out > /sys/class/gpio/gpio2/direction

  • echo 1 > /sys/class/gpio/gpio2/value

  • echo 13 > /sys/class/gpio/export

  • echo out > /sys/class/gpio/gpio13/direction

  • echo 1 > /sys/class/gpio/gpio13/value

level translator is enable and mcp2515 is out of reset

  • modprobe can
  • modprobe can-dev
  • modprobe can-raw
  • modprobe mcp251x

I see nothing appear on the SPI_CLK on the IOT slot.
It seems SPI is not working…

Any idea ?