nRF52840 DK semaphore in uart callback does not work?

Hi,

I am using https://github.com/NordicDeveloperAcademy/nRF-Connect-SDK-Fundamentals lesson5/fund_less5_exer1 as base. I have set P0.26 as UART RX. Using the code below, I have received the correct UART data at uart callback, code currently commented out at uart_cb and it works. 

#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/devicetree.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/sys/printk.h>
#include <string.h>
/* STEP 3 - Include the header file of the UART driver in main.c */
#include <zephyr/drivers/uart.h>
#include "df2301q.h"


/* 1000 msec = 1 sec */
#define SLEEP_TIME_MS   200

/* STEP 10.1.1 - Define the size of the receive buffer */
#define RECEIVE_BUFF_SIZE 13

/* STEP 10.2 - Define the receiving timeout period */
#define RECEIVE_TIMEOUT 1000

#define CONSUMER_STACKSIZE       512
#define CONSUMER_PRIORITY        5 

K_SEM_DEFINE(sem, 0, 1);

/* STEP 5.1 - Get the device pointers of the LEDs through gpio_dt_spec */
/* The nRF7002dk has only 2 LEDs so this step uses a compile-time condition to reflect the DK you are building for */
#if defined (CONFIG_BOARD_NRF7002DK_NRF5340_CPUAPP)|| defined (CONFIG_BOARD_NRF7002DK_NRF5340_CPUAPP_NS)
static const struct gpio_dt_spec led0 = GPIO_DT_SPEC_GET(DT_ALIAS(led0), gpios);
static const struct gpio_dt_spec led1 = GPIO_DT_SPEC_GET(DT_ALIAS(led1), gpios);
#else
static const struct gpio_dt_spec led0 = GPIO_DT_SPEC_GET(DT_ALIAS(led0), gpios);
static const struct gpio_dt_spec led1 = GPIO_DT_SPEC_GET(DT_ALIAS(led1), gpios);
static const struct gpio_dt_spec led2 = GPIO_DT_SPEC_GET(DT_ALIAS(led2), gpios);
static const struct gpio_dt_spec led3 = GPIO_DT_SPEC_GET(DT_ALIAS(led3), gpios);
#endif

/* STEP 4.1 - Get the device pointer of the UART hardware */
const struct device *uart= DEVICE_DT_GET(DT_NODELABEL(uart0));


/* STEP 9.1 - Define the transmission buffer, which is a buffer to hold the data to be sent over UART */
static uint8_t tx_buf[] =   {"nRF Connect SDK Fundamentals Course\n\r"
                             "Press 1-3 on your keyboard to toggle LEDS 1-3 on your development kit\n\r"};

/* STEP 10.1.2 - Define the receive buffer */
static uint8_t rx_buf[RECEIVE_BUFF_SIZE] = {0};


/* STEP 7 - Define the callback function for UART */
static void uart_cb(const struct device *dev, struct uart_event *evt, void *user_data)
{
	switch (evt->type) {

	case UART_RX_RDY:
		
	k_sem_give(&sem);
	
/*
	uart_rx_disable(uart);	

	if((rx_buf[0] == 0xF4) && (rx_buf[1] == 0xF5))
	{
		if(rx_buf[2] == 0x03)
		{
			if(rx_buf[7] == 0x16)
			{
				gpio_pin_set_dt(&led0, 1);
				gpio_pin_set_dt(&led1, 0);
			}
			else if(rx_buf[7] == 0x17)
			{
				gpio_pin_set_dt(&led0, 0);
				gpio_pin_set_dt(&led1, 1);
			}			
		}
		else if(rx_buf[2] == 0x02)
		{
			gpio_pin_set_dt(&led0, 0);
			gpio_pin_set_dt(&led1, 0);
		}	
	}
 
	memset(rx_buf, 0, sizeof(rx_buf));	
	uart_rx_enable(dev ,rx_buf,sizeof rx_buf,RECEIVE_TIMEOUT);
*/
	break;

	case UART_RX_DISABLED:
		uart_rx_enable(dev ,rx_buf,sizeof rx_buf,RECEIVE_TIMEOUT);
		break;
		
	default:
		break;
	}
}

//int main(void)
int consumer(void)
{
	int ret;

/* STEP 4.2 - Verify that the UART device is ready */ 
	if (!device_is_ready(uart)){
		printk("UART device not ready\r\n");
		return 1 ;
	}
/* STEP 5.2 - Verify that the LED devices are ready */
	if (!device_is_ready(led0.port)){
		printk("GPIO device is not ready\r\n");
		return 1;
	}

	ret = gpio_pin_configure_dt(&led0, GPIO_OUTPUT_INACTIVE);
	if (ret < 0) {
		return 1 ; 
	}
	ret = gpio_pin_configure_dt(&led1, GPIO_OUTPUT_INACTIVE);
	if (ret < 0) {
		return 1 ;
	}
	ret = gpio_pin_configure_dt(&led2, GPIO_OUTPUT_INACTIVE);
	if (ret < 0) {
		return 1 ;
	}
	ret = gpio_pin_configure_dt(&led3, GPIO_OUTPUT_INACTIVE);
	if (ret < 0) {
		return 1 ;
	}

/* STEP 8 - Register the UART callback function */
	ret = uart_callback_set(uart, uart_cb, NULL);
	if (ret) {
		return 1;
	}
/* STEP 9.2 - Send the data over UART by calling uart_tx() */
	ret = uart_tx(uart, tx_buf, sizeof(tx_buf), SYS_FOREVER_MS);
	if (ret) {
		return 1;
	}

	while (1) {
		ret = uart_rx_enable(uart ,rx_buf,sizeof rx_buf,RECEIVE_TIMEOUT);
		if (ret) {			
			return 1;
		}

		k_sem_take(&sem, K_FOREVER);

		uart_rx_disable(uart);

		if((rx_buf[0] == 0xF4) && (rx_buf[1] == 0xF5))
		{			
			if(rx_buf[2] == 0x03)
			{				
				if(rx_buf[7] == 0x16)
				{					
					gpio_pin_set_dt(&led0, 1);
					gpio_pin_set_dt(&led1, 0);
				}
				else if(rx_buf[7] == 0x17)
				{
					gpio_pin_set_dt(&led0, 0);
					gpio_pin_set_dt(&led1, 1);
				}			
			}
			else if(rx_buf[2] == 0x02)
			{
				gpio_pin_set_dt(&led0, 0);
				gpio_pin_set_dt(&led1, 0);
			}	
			memset(rx_buf, 0, sizeof(rx_buf));				
		} 
		
		//k_msleep(SLEEP_TIME_MS);
	}

}

K_THREAD_DEFINE(consumer_id, CONSUMER_STACKSIZE, consumer, NULL, NULL, NULL,
				CONSUMER_PRIORITY, 0, 0);

I would like to process the received uart data at main thread while 1. So, I used semaphore with definition below.

K_SEM_DEFINE(sem, 0, 1);
at uart_cb() I call below.
case UART_RX_RDY:
k_sem_give(&sem);
in consumer thread I call below in while(1).
k_sem_take(&sem, K_FOREVER);
But, it does not work. How do I make this work?
Regards,
Markel
Parents Reply Children
No Data
Related