Reputation: 1
I have a ST7580 Power line communication modem connected to a BeagleBone Black device running Debian Linux, kernel v4.19. I am trying to communicate with the modem using a custom serial driver (using the SERDEV model) which is based on some samples. I have compiled it as a kernel module named st7580km.ko and used modprobe
to insert it into the kernel. Since I want to use a DeviceTree overlay to load the driver for this peripheral device, I have copied and modified the BONE-UART1.dts and named it as BONE-ST7580.dts with the following content:
/dts-v1/;
/plugin/;
#include <dt-bindings/pinctrl/am33xx.h>
&{/chosen} {
overlays {
BONE-ST7580 = __TIMESTAMP__;
};
};
&ocp {
P9_24_pinmux { pinctrl-0 = <&P9_24_uart_pin>; }; /* UART TX*/
P9_26_pinmux { pinctrl-0 = <&P9_26_uart_pin>; }; /* UART RX*/
};
&bone_uart1 {
//compatible = "st7580, st7580km, uart, omap3-uart";
compatible = "st7580, st7580km";
status = "okay";
};
I have compiled the dts file to dtbo and placed the dtbo in /lib/firmware and also in /boot/dtbs/4.19.94-ti-r73/
The kernel module source:
#include <asm/unaligned.h>
#include <linux/completion.h>
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/iio/buffer.h>
#include <linux/iio/iio.h>
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/triggered_buffer.h>
#include <linux/jiffies.h>
#include <linux/kernel.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/serdev.h>
#define ST7580_DRIVER_NAME "st7580"
#define ST7580_DRIVER_VERSION "0.1.0"
#define ST7580_DEFAULT_BAUD_RATE 57600
#define ST7580_CHECKSUM_LENGTH 2
#define ST7580_MAX_DATA_LENGTH (3 + 255 + ST7580_CHECKSUM_LENGTH )
#define ST7580_TX_ACK_TIMEOUT msecs_to_jiffies(40)
static void st7580_write_wakeup(struct serdev_device *serdev)
{
dev_info(&serdev->dev, "\nst7580_write_wakeup: pull down RTS\n");
/* Pull down RTS */
serdev_device_set_tiocm(serdev, TIOCMBIS, TIOCM_RTS);
}
static int st7580_receive_buf(struct serdev_device *serdev,
const unsigned char *buf, size_t size)
{
dev_info(&serdev->dev, "\nst7580_receive_buf: Received %u bytes\n", size);
return serdev_controller_receive_buf(serdev, buf, size);
}
static const struct serdev_device_ops st7580_serdev_ops = {
.receive_buf = st7580_receive_buf, /* default */
.write_wakeup = st7580_write_wakeup,
};
static int st7580_probe(struct serdev_device *serdev)
{
int uart_flags;
int ret;
dev_info(&serdev->dev, "\nst7580_probe started...");
serdev_device_set_client_ops(serdev, &st7580_serdev_ops);
ret = devm_serdev_device_open(&serdev->dev, serdev);
if (ret) {
_dev_err(&serdev->dev, "unable to open the device\n");
return ret;
}
serdev_device_set_baudrate(serdev, ST7580_DEFAULT_BAUD_RATE);
serdev_device_set_flow_control(serdev, false);
ret = serdev_device_set_parity(serdev, SERDEV_PARITY_NONE);
uart_flags = 0;
uart_flags &= ~PARENB;
uart_flags &= ~CSTOPB;
uart_flags &= ~CSIZE;
uart_flags |= CS8;
uart_flags &= ~CRTSCTS;
uart_flags |= CREAD | CLOCAL;
//uart_settings.c_iflag &= ~(IXON | IXOFF | IXANY);
//uart_settings.c_iflag &= ~(ICANON | ECHO | ECHOE | ISIG);
//uart_settings.c_iflag &= ~IGNBRK;
serdev_device_set_tiocm(serdev, TIOCMSET, uart_flags);
serdev_device_set_rts(serdev, 0);
serdev_device_set_tiocm(serdev, TIOCMSET, TIOCM_RTS);
dev_info(&serdev->dev, "\nDriver name is %s, loaded successsfully\n", ST7580_DRIVER_NAME);
return ret;
}
static const struct of_device_id st7580_of_match[] = {
{ .compatible = "st7580, st7580km" },
{ .compatible = "st, st7580" },
{ .compatible = "st, st7580km" },
{ }
};
MODULE_DEVICE_TABLE(of, st7580_of_match);
static struct serdev_device_driver st7580_driver = {
.driver = {
.name = ST7580_DRIVER_NAME,
.of_match_table = st7580_of_match,
},
.probe = st7580_probe,
};
module_serdev_device_driver(st7580_driver);
I have also modified the /boot/uEnv.txt and added this line to load the DeviceTree overlay.
optargs=quiet drm.debug=7 capemgr.enable_partno=BB-ST7580
When I reboot I expect that my driver will be loaded using which I can communicate to the modem from a userspace app. I have placed some debug messages in the code which I expect to see in the dmesg output like below:
dev_info(&serdev->dev, "\nDriver name is %s, loaded successsfully\n", ST7580_DRIVER_NAME);
So far I do dont see any of the messages and am not sure if the kernel is using my driver for this peripheral. Can any one tell me what I have missed or any errors?
I have SD card enabled and the device boots from that not the eMMC. In the boot logs I dont see the kernel even trying to load the BONE-ST7580.dtbo that is specified in uEnv.txt. I also have CONFIG_SERIAL_DEV_BUS=y CONFIG_SERIAL_DEV_CTRL_TTYPORT=y enabled in the /usr/src/linux-headers-4.19.94-ti-r73/.config file that I used to build the driver as suggested in another post.
Upvotes: 0
Views: 486
Reputation: 2890
Step one is to hook up to the debug UART on the Beaglebone. It gives you the necessary low level information to figure out what is happening during the U-Boot phase and early Kernel boot.
For embedded (Linux) work there is no excuse from hooking up to a UART. It's an essential tool.
Things to check for in this case is if you have more than one U-Boot in play (eMMC vs SD) and if you're working with the right one. Also if there are any error messages from U-Boot, etc. It should be quite easy to tell from the UART output.
Upvotes: 0