samples: drivers: CAN: reworked sample code
The CAN sample is rewritten to be board independent. The CAN controller and LED is determined automatically and the button is removed. Signed-off-by: Alexander Wachter <alexander.wachter@student.tugraz.at>
This commit is contained in:
parent
85ef00deb4
commit
f19dd97517
7 changed files with 120 additions and 286 deletions
|
@ -8,36 +8,6 @@
|
||||||
|
|
||||||
mainmenu "Controller Area Network sample application"
|
mainmenu "Controller Area Network sample application"
|
||||||
|
|
||||||
config CAN_DEV
|
|
||||||
string "Name of the CAN device"
|
|
||||||
default "CAN_1"
|
|
||||||
help
|
|
||||||
Name of the can device used for send an receive.
|
|
||||||
|
|
||||||
config GPIO_LED_DEV
|
|
||||||
string "Name of the LED GPIO port"
|
|
||||||
default "GPIOC"
|
|
||||||
help
|
|
||||||
Name of the LED port for signaling message reception.
|
|
||||||
|
|
||||||
config GPIO_BUTTON_DEV
|
|
||||||
string "Name of the button GPIO port"
|
|
||||||
default "GPIOA"
|
|
||||||
help
|
|
||||||
Name of the button port for triggering messages.
|
|
||||||
|
|
||||||
config PIN_USER_BUTTON
|
|
||||||
int "Pin User Button"
|
|
||||||
default 0
|
|
||||||
help
|
|
||||||
Pin number of the user Button.
|
|
||||||
|
|
||||||
config PIN_LED_1
|
|
||||||
int "Pin LED 1"
|
|
||||||
default 6
|
|
||||||
help
|
|
||||||
Pin number of the first LED.
|
|
||||||
|
|
||||||
config LOOPBACK_MODE
|
config LOOPBACK_MODE
|
||||||
bool "Loopback LOOPBACK_MODE"
|
bool "Loopback LOOPBACK_MODE"
|
||||||
default y
|
default y
|
||||||
|
@ -45,5 +15,4 @@ config LOOPBACK_MODE
|
||||||
Set the controller to loopback mode.
|
Set the controller to loopback mode.
|
||||||
This allows testing without a second board.
|
This allows testing without a second board.
|
||||||
|
|
||||||
|
|
||||||
source "Kconfig.zephyr"
|
source "Kconfig.zephyr"
|
||||||
|
|
|
@ -7,10 +7,9 @@ Overview
|
||||||
********
|
********
|
||||||
|
|
||||||
This sample demonstrates how to use the Controller Area Network (CAN) API.
|
This sample demonstrates how to use the Controller Area Network (CAN) API.
|
||||||
Messages with standard and extended identifiers are sent over the bus, triggered
|
Messages with standard and extended identifiers are sent over the bus.
|
||||||
by a button event.
|
Messages are received using message-queues and work-queues.
|
||||||
Messages are received using message queues and ISRs.
|
Reception is indicated by blinking the LED (if present) and output to the console.
|
||||||
Reception is indicated by blink LEDs and output to the console.
|
|
||||||
|
|
||||||
Building and Running
|
Building and Running
|
||||||
********************
|
********************
|
||||||
|
@ -19,25 +18,20 @@ In loopback mode, the board receives its own messages. This could be used for
|
||||||
standalone testing.
|
standalone testing.
|
||||||
|
|
||||||
The sample can be built and executed on boards supporting CAN.
|
The sample can be built and executed on boards supporting CAN.
|
||||||
The output ports and pins of the LEDs can be configured by Kconfig.
|
The LED output pin is defined in the board's device tre.
|
||||||
|
|
||||||
Sample output
|
Sample output
|
||||||
=============
|
=============
|
||||||
|
|
||||||
.. code-block:: console
|
.. code-block:: console
|
||||||
|
|
||||||
Finished init. waiting for Interrupts
|
Change LED filter ID: 0
|
||||||
TX thread is running.
|
Finished init.
|
||||||
filter id: 1
|
Counter filter id: 4
|
||||||
Button pressed! Send message 1
|
|
||||||
Button pressed 1 times
|
uart:~$ Counter received: 0
|
||||||
Button pressed! Send message 0
|
Counter received: 1
|
||||||
Button pressed 2 times
|
Counter received: 2
|
||||||
String sent over CAN
|
Counter received: 3
|
||||||
Button pressed! Send message 1
|
|
||||||
Button pressed 3 times
|
|
||||||
Button pressed! Send message 0
|
|
||||||
Button pressed 4 times
|
|
||||||
String sent over CAN
|
|
||||||
|
|
||||||
.. note:: The values shown above might differ.
|
.. note:: The values shown above might differ.
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
CONFIG_CAN_DEV="CAN_0"
|
|
||||||
CONFIG_GPIO_LED_DEV="GPIO_4"
|
|
||||||
CONFIG_GPIO_BUTTON_DEV="GPIO_2"
|
|
||||||
CONFIG_PIN_USER_BUTTON=6
|
|
||||||
CONFIG_PIN_LED_1=26
|
|
||||||
|
|
||||||
CONFIG_LOG=y
|
|
||||||
CONFIG_LOG_BUFFER_SIZE=2048
|
|
||||||
|
|
||||||
CONFIG_CAN_0=y
|
|
||||||
CONFIG_CAN_1=n
|
|
|
@ -1,11 +0,0 @@
|
||||||
CONFIG_CAN_DEV="CAN_0"
|
|
||||||
CONFIG_GPIO_LED_DEV="GPIO_2"
|
|
||||||
CONFIG_GPIO_BUTTON_DEV="GPIO_3"
|
|
||||||
CONFIG_PIN_USER_BUTTON=3
|
|
||||||
CONFIG_PIN_LED_1=13
|
|
||||||
|
|
||||||
CONFIG_LOG=y
|
|
||||||
CONFIG_LOG_BUFFER_SIZE=2048
|
|
||||||
|
|
||||||
CONFIG_CAN_0=y
|
|
||||||
CONFIG_CAN_1=n
|
|
|
@ -1,6 +1,5 @@
|
||||||
CONFIG_CAN=y
|
CONFIG_CAN=y
|
||||||
CONFIG_CAN_INIT_PRIORITY=80
|
CONFIG_CAN_INIT_PRIORITY=80
|
||||||
CONFIG_CAN_1=y
|
|
||||||
CONFIG_CAN_MAX_FILTER=5
|
CONFIG_CAN_MAX_FILTER=5
|
||||||
|
|
||||||
CONFIG_SHELL=y
|
CONFIG_SHELL=y
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
# CAN + MCP2515 config
|
|
||||||
CONFIG_SPI=y
|
|
||||||
CONFIG_CAN=y
|
|
||||||
CONFIG_CAN_INIT_PRIORITY=80
|
|
||||||
CONFIG_CAN_1=y
|
|
||||||
CONFIG_CAN_STM32=n
|
|
||||||
CONFIG_CAN_MCP2515=y
|
|
||||||
CONFIG_GPIO_LED_DEV="GPIOB"
|
|
||||||
CONFIG_PIN_LED_1=3
|
|
||||||
CONFIG_GPIO_BUTTON_DEV="GPIOB"
|
|
||||||
CONFIG_PIN_USER_BUTTON=4
|
|
||||||
CONFIG_LOG=y
|
|
||||||
CONFIG_CAN_LOG_LEVEL=4
|
|
|
@ -10,195 +10,124 @@
|
||||||
#include <device.h>
|
#include <device.h>
|
||||||
#include <drivers/can.h>
|
#include <drivers/can.h>
|
||||||
#include <drivers/gpio.h>
|
#include <drivers/gpio.h>
|
||||||
|
#include <misc/byteorder.h>
|
||||||
|
|
||||||
#define TX_THREAD_STACK_SIZE 512
|
#define RX_THREAD_STACK_SIZE 512
|
||||||
#define LED_THREAD_STACK_SIZE 512
|
#define RX_THREAD_PRIORITY 2
|
||||||
#define RX_STR_THREAD_STACK_SIZE 512
|
#define LED_MSG_ID 0x10
|
||||||
#define TX_THREAD_PRIORITY 2
|
#define COUNTER_MSG_ID 0x12345
|
||||||
#define LED_MSG_ID (0x10)
|
#define SET_LED 1
|
||||||
#define BUTTON_MSG_ID (0x01)
|
#define RESET_LED 0
|
||||||
#define STR_MSG_ID (0x12345)
|
#define SLEEP_TIME K_MSEC(250)
|
||||||
|
|
||||||
#define SET_LED 0
|
K_THREAD_STACK_DEFINE(rx_thread_stack, RX_THREAD_STACK_SIZE);
|
||||||
#define RESET_LED 1
|
|
||||||
|
|
||||||
|
struct k_thread rx_thread_data;
|
||||||
|
struct zcan_work rx_work;
|
||||||
|
|
||||||
#define NUM_LEDS_STR STRINGIFY(NUM_LEDS)
|
CAN_DEFINE_MSGQ(counter_msgq, 2);
|
||||||
|
|
||||||
K_THREAD_STACK_DEFINE(tx_thread_stack, TX_THREAD_STACK_SIZE);
|
|
||||||
K_THREAD_STACK_DEFINE(led_thread_stack, LED_THREAD_STACK_SIZE);
|
|
||||||
K_THREAD_STACK_DEFINE(rx_str_thread_stack, RX_STR_THREAD_STACK_SIZE);
|
|
||||||
struct k_thread tx_thread_data;
|
|
||||||
struct k_thread led_thread_data;
|
|
||||||
struct k_thread rx_str_thread_data;
|
|
||||||
struct k_sem tx_sem;
|
|
||||||
static struct gpio_callback gpio_cb;
|
|
||||||
CAN_DEFINE_MSGQ(led_msgq, 2);
|
|
||||||
CAN_DEFINE_MSGQ(str_msgq, 5);
|
|
||||||
|
|
||||||
void tx_irq_callback(u32_t error_flags, void *arg)
|
void tx_irq_callback(u32_t error_flags, void *arg)
|
||||||
{
|
{
|
||||||
char *sender = (char *)arg;
|
char *sender = (char *)arg;
|
||||||
|
|
||||||
if (error_flags) {
|
if (error_flags) {
|
||||||
printk("Callback! error-code: %d\nSender: %s\n",
|
printk("Callback! error-code: %d\nSender: %s\n",
|
||||||
error_flags, sender);
|
error_flags, sender);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void button_callback(struct device *port,
|
void rx_thread(void *can_dev_param, void *arg1, void *arg2)
|
||||||
struct gpio_callback *cb, u32_t pins)
|
|
||||||
{
|
{
|
||||||
k_sem_give(&tx_sem);
|
ARG_UNUSED(arg1);
|
||||||
}
|
ARG_UNUSED(arg2);
|
||||||
|
|
||||||
void send_string(char *string, struct device *can_dev)
|
|
||||||
{
|
|
||||||
struct zcan_frame msg;
|
|
||||||
int str_len;
|
|
||||||
|
|
||||||
msg.ext_id = STR_MSG_ID;
|
|
||||||
msg.id_type = CAN_EXTENDED_IDENTIFIER;
|
|
||||||
msg.dlc = 0U;
|
|
||||||
msg.rtr = CAN_DATAFRAME;
|
|
||||||
|
|
||||||
for (str_len = strlen(string); str_len; ) {
|
|
||||||
msg.dlc = str_len >= 8 ? 8 : str_len;
|
|
||||||
str_len -= msg.dlc;
|
|
||||||
memcpy(msg.data, string, msg.dlc);
|
|
||||||
string += msg.dlc;
|
|
||||||
can_send(can_dev, &msg, 10, tx_irq_callback, "send_string");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void tx_thread(void *can_dev_param, void *unused2, void *unused3)
|
|
||||||
{
|
|
||||||
u8_t toggle = SET_LED;
|
|
||||||
u16_t button_press_cnt = 0U;
|
|
||||||
struct zcan_frame msg;
|
|
||||||
struct zcan_frame msg_button_cnt;
|
|
||||||
struct device *can_dev = can_dev_param;
|
|
||||||
|
|
||||||
msg.std_id = LED_MSG_ID;
|
|
||||||
msg.id_type = CAN_STANDARD_IDENTIFIER;
|
|
||||||
msg.dlc = 1U;
|
|
||||||
msg.rtr = CAN_DATAFRAME;
|
|
||||||
msg.data[0] = 0U;
|
|
||||||
|
|
||||||
msg_button_cnt.std_id = BUTTON_MSG_ID;
|
|
||||||
msg_button_cnt.id_type = CAN_STANDARD_IDENTIFIER;
|
|
||||||
msg_button_cnt.dlc = 2U;
|
|
||||||
msg_button_cnt.rtr = CAN_DATAFRAME;
|
|
||||||
msg_button_cnt.data[0] = 0U;
|
|
||||||
msg_button_cnt.data[1] = 0U;
|
|
||||||
|
|
||||||
printk("TX thread is running.\n");
|
|
||||||
while (1) {
|
|
||||||
k_sem_take(&tx_sem, K_FOREVER);
|
|
||||||
button_press_cnt++;
|
|
||||||
toggle = (toggle == SET_LED) ? RESET_LED : SET_LED;
|
|
||||||
printk("Button pressed! Send message %u\n", toggle);
|
|
||||||
msg.data[0] = toggle;
|
|
||||||
msg_button_cnt.data[0] = button_press_cnt & 0xFF;
|
|
||||||
msg_button_cnt.data[1] = (button_press_cnt >> 8) & 0xFF;
|
|
||||||
can_send(can_dev, &msg, 10, tx_irq_callback, "LED msg");
|
|
||||||
can_send(can_dev, &msg_button_cnt, 10, NULL, "Button count");
|
|
||||||
if (toggle == SET_LED) {
|
|
||||||
send_string("String sent over CAN\n", can_dev);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void rx_str_thread(void *msgq, void *can_dev_param, void *unused)
|
|
||||||
{
|
|
||||||
struct zcan_frame msg;
|
|
||||||
int filter_id;
|
|
||||||
const struct zcan_filter filter = {
|
const struct zcan_filter filter = {
|
||||||
.id_type = CAN_EXTENDED_IDENTIFIER,
|
.id_type = CAN_EXTENDED_IDENTIFIER,
|
||||||
.rtr = CAN_DATAFRAME,
|
.rtr = CAN_DATAFRAME,
|
||||||
.ext_id = STR_MSG_ID,
|
.ext_id = COUNTER_MSG_ID,
|
||||||
.rtr_mask = 1,
|
.rtr_mask = 1,
|
||||||
.ext_id_mask = CAN_EXT_ID_MASK
|
.ext_id_mask = CAN_EXT_ID_MASK
|
||||||
};
|
};
|
||||||
struct device *can_dev = can_dev_param;
|
struct device *can_dev = can_dev_param;
|
||||||
|
struct zcan_frame msg;
|
||||||
|
int filter_id;
|
||||||
|
|
||||||
filter_id = can_attach_msgq(can_dev, msgq, &filter);
|
filter_id = can_attach_msgq(can_dev, &counter_msgq, &filter);
|
||||||
printk("filter id: %d\n", filter_id);
|
printk("Counter filter id: %d\n", filter_id);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
k_msgq_get((struct k_msgq *)msgq, &msg, K_FOREVER);
|
k_msgq_get(&counter_msgq, &msg, K_FOREVER);
|
||||||
for (int i = 0; i < msg.dlc; i++) {
|
|
||||||
printk("%c", msg.data[i]);
|
if (msg.dlc != 2U) {
|
||||||
|
printk("Wrong data length: %u\n", msg.dlc);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printk("Counter received: %u\n",
|
||||||
|
sys_be16_to_cpu(UNALIGNED_GET((u16_t *)&msg.data)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void led_thread(void *msgq, void *can_dev_param, void *gpio_dev_param)
|
void change_led(struct zcan_frame *msg, void *led_dev_param)
|
||||||
{
|
{
|
||||||
const struct zcan_filter filter = {
|
struct device *led_dev = (struct device *)led_dev_param;
|
||||||
|
|
||||||
|
#if defined(DT_ALIAS_LED0_GPIOS_PIN) && defined(DT_ALIAS_LED0_GPIOS_CONTROLLER)
|
||||||
|
|
||||||
|
if (!led_dev_param) {
|
||||||
|
printk("No LED GPIO device\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (msg->data[0]) {
|
||||||
|
case SET_LED:
|
||||||
|
gpio_pin_write(led_dev, DT_ALIAS_LED0_GPIOS_PIN, 1);
|
||||||
|
break;
|
||||||
|
case RESET_LED:
|
||||||
|
gpio_pin_write(led_dev, DT_ALIAS_LED0_GPIOS_PIN, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
printk("LED %s\n", msg->data[0] == SET_LED ? "ON" : "OFF");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
const struct zcan_filter change_led_filter = {
|
||||||
.id_type = CAN_STANDARD_IDENTIFIER,
|
.id_type = CAN_STANDARD_IDENTIFIER,
|
||||||
.rtr = CAN_DATAFRAME,
|
.rtr = CAN_DATAFRAME,
|
||||||
.std_id = LED_MSG_ID,
|
.std_id = LED_MSG_ID,
|
||||||
.rtr_mask = 1,
|
.rtr_mask = 1,
|
||||||
.std_id_mask = CAN_STD_ID_MASK
|
.std_id_mask = CAN_STD_ID_MASK
|
||||||
};
|
};
|
||||||
struct device *can_dev = can_dev_param;
|
struct zcan_frame change_led_frame = {
|
||||||
struct device *gpio_dev = gpio_dev_param;
|
|
||||||
struct zcan_frame msg;
|
|
||||||
int ret;
|
|
||||||
int filter_id;
|
|
||||||
|
|
||||||
ret = gpio_pin_configure(gpio_dev, CONFIG_PIN_LED_1, GPIO_DIR_OUT);
|
|
||||||
gpio_pin_write(gpio_dev, CONFIG_PIN_LED_1, 0);
|
|
||||||
|
|
||||||
if (ret) {
|
|
||||||
printk("ERROR configure pins\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
filter_id = can_attach_msgq(can_dev, msgq, &filter);
|
|
||||||
printk("filter id: %d\n", filter_id);
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
k_msgq_get((struct k_msgq *)msgq, &msg, K_FOREVER);
|
|
||||||
|
|
||||||
if (msg.dlc != 1U) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (msg.data[0]) {
|
|
||||||
case SET_LED:
|
|
||||||
gpio_pin_write(gpio_dev, CONFIG_PIN_LED_1, 1);
|
|
||||||
|
|
||||||
break;
|
|
||||||
case RESET_LED:
|
|
||||||
gpio_pin_write(gpio_dev, CONFIG_PIN_LED_1, 0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void rx_button_isr(struct zcan_frame *msg, void *arg)
|
|
||||||
{
|
|
||||||
u16_t cnt = msg->data[0] | (msg->data[1] << 8);
|
|
||||||
|
|
||||||
ARG_UNUSED(arg);
|
|
||||||
|
|
||||||
printk("Button pressed %d times\n", cnt);
|
|
||||||
}
|
|
||||||
|
|
||||||
void main(void)
|
|
||||||
{
|
|
||||||
const struct zcan_filter filter = {
|
|
||||||
.id_type = CAN_STANDARD_IDENTIFIER,
|
.id_type = CAN_STANDARD_IDENTIFIER,
|
||||||
.rtr = CAN_DATAFRAME,
|
.rtr = CAN_DATAFRAME,
|
||||||
.std_id = BUTTON_MSG_ID,
|
.std_id = LED_MSG_ID,
|
||||||
.rtr_mask = 1,
|
.dlc = 1
|
||||||
.std_id_mask = CAN_STD_ID_MASK
|
|
||||||
};
|
};
|
||||||
struct device *can_dev, *led_gpio_dev, *button_gpio_dev;
|
struct zcan_frame counter_frame = {
|
||||||
|
.id_type = CAN_EXTENDED_IDENTIFIER,
|
||||||
|
.rtr = CAN_DATAFRAME,
|
||||||
|
.ext_id = COUNTER_MSG_ID,
|
||||||
|
.dlc = 2
|
||||||
|
};
|
||||||
|
u8_t toggle = 1;
|
||||||
|
u16_t counter = 0;
|
||||||
|
struct device *led_gpio_dev = NULL;
|
||||||
|
struct device *can_dev;
|
||||||
|
k_tid_t rx_tid;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
can_dev = device_get_binding(CONFIG_CAN_DEV);
|
/* Usually the CAN device is either called CAN_0 or CAN_1, depending
|
||||||
|
* on the SOC. Let's check both and take the first valid one.
|
||||||
|
*/
|
||||||
|
can_dev = device_get_binding("CAN_0");
|
||||||
|
if (!can_dev) {
|
||||||
|
can_dev = device_get_binding("CAN_1");
|
||||||
|
}
|
||||||
|
|
||||||
if (!can_dev) {
|
if (!can_dev) {
|
||||||
printk("CAN: Device driver not found.\n");
|
printk("CAN: Device driver not found.\n");
|
||||||
return;
|
return;
|
||||||
|
@ -208,73 +137,51 @@ void main(void)
|
||||||
can_configure(can_dev, CAN_LOOPBACK_MODE, 250000);
|
can_configure(can_dev, CAN_LOOPBACK_MODE, 250000);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
led_gpio_dev = device_get_binding(CONFIG_GPIO_LED_DEV);
|
#if defined(DT_ALIAS_LED0_GPIOS_PIN) && defined(DT_ALIAS_LED0_GPIOS_CONTROLLER)
|
||||||
|
led_gpio_dev = device_get_binding(DT_ALIAS_LED0_GPIOS_CONTROLLER);
|
||||||
if (!led_gpio_dev) {
|
if (!led_gpio_dev) {
|
||||||
printk("LED: Device driver not found.\n");
|
printk("LED: Device driver not found.\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
k_sem_init(&tx_sem, 0, INT_MAX);
|
ret = gpio_pin_configure(led_gpio_dev, DT_ALIAS_LED0_GPIOS_PIN,
|
||||||
|
GPIO_DIR_OUT);
|
||||||
button_gpio_dev = device_get_binding(CONFIG_GPIO_BUTTON_DEV);
|
if (ret < 0) {
|
||||||
if (!button_gpio_dev) {
|
printk("Error setting LED pin to output mode [%d]", ret);
|
||||||
printk("Button: Device driver not found.\n");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
ret = gpio_pin_configure(button_gpio_dev, CONFIG_PIN_USER_BUTTON,
|
ret = can_attach_workq(can_dev, &k_sys_work_q, &rx_work, change_led,
|
||||||
(GPIO_DIR_IN | GPIO_INT | GPIO_INT_EDGE |
|
led_gpio_dev, &change_led_filter);
|
||||||
GPIO_INT_ACTIVE_HIGH | GPIO_INT_DEBOUNCE));
|
|
||||||
if (ret) {
|
|
||||||
printk("Error configuring button pin\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
gpio_init_callback(&gpio_cb, button_callback,
|
|
||||||
BIT(CONFIG_PIN_USER_BUTTON));
|
|
||||||
|
|
||||||
ret = gpio_add_callback(button_gpio_dev, &gpio_cb);
|
|
||||||
if (ret) {
|
|
||||||
printk("Cannot setup callback!\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = gpio_pin_enable_callback(button_gpio_dev, CONFIG_PIN_USER_BUTTON);
|
|
||||||
if (ret) {
|
|
||||||
printk("Error enabling callback!\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = can_attach_isr(can_dev, rx_button_isr, 0, &filter);
|
|
||||||
if (ret == CAN_NO_FREE_FILTER) {
|
if (ret == CAN_NO_FREE_FILTER) {
|
||||||
printk("Error, no filter available!\n");
|
printk("Error, no filter available!\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
k_tid_t tx_tid = k_thread_create(&tx_thread_data, tx_thread_stack,
|
printk("Change LED filter ID: %d\n", ret);
|
||||||
K_THREAD_STACK_SIZEOF(tx_thread_stack),
|
|
||||||
tx_thread,
|
rx_tid = k_thread_create(&rx_thread_data, rx_thread_stack,
|
||||||
can_dev, NULL, NULL,
|
K_THREAD_STACK_SIZEOF(rx_thread_stack),
|
||||||
TX_THREAD_PRIORITY, 0, K_NO_WAIT);
|
rx_thread, can_dev, NULL, NULL,
|
||||||
if (!tx_tid) {
|
RX_THREAD_PRIORITY, 0, K_NO_WAIT);
|
||||||
printk("ERROR spawning tx_thread\n");
|
if (!rx_tid) {
|
||||||
|
printk("ERROR spawning rx thread\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
k_tid_t led_tid = k_thread_create(&led_thread_data, led_thread_stack,
|
printk("Finished init.\n");
|
||||||
K_THREAD_STACK_SIZEOF(led_thread_stack),
|
|
||||||
led_thread,
|
|
||||||
&led_msgq, can_dev, led_gpio_dev,
|
|
||||||
TX_THREAD_PRIORITY, 0, K_NO_WAIT);
|
|
||||||
if (!led_tid) {
|
|
||||||
printk("ERROR spawning led_thread\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
k_tid_t str_tid = k_thread_create(&rx_str_thread_data,
|
while (1) {
|
||||||
rx_str_thread_stack,
|
change_led_frame.data[0] = toggle++ & 0x01 ? SET_LED : RESET_LED;
|
||||||
K_THREAD_STACK_SIZEOF(rx_str_thread_stack),
|
/* This sending call is none blocking. */
|
||||||
rx_str_thread,
|
can_send(can_dev, &change_led_frame, K_FOREVER, tx_irq_callback,
|
||||||
&str_msgq, can_dev, NULL,
|
"LED change");
|
||||||
TX_THREAD_PRIORITY, 0, K_NO_WAIT);
|
k_sleep(SLEEP_TIME);
|
||||||
if (!str_tid) {
|
|
||||||
printk("ERROR spawning str_thread\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
printk("Finished init. waiting for Interrupts\n");
|
UNALIGNED_PUT(sys_cpu_to_be16(counter),
|
||||||
|
(u16_t *)&counter_frame.data[0]);
|
||||||
|
counter++;
|
||||||
|
/* This sending call is blocking until the message is sent. */
|
||||||
|
can_send(can_dev, &counter_frame, K_MSEC(100), NULL, NULL);
|
||||||
|
k_sleep(SLEEP_TIME);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue