Grove LCD - Grove LCD: Device not ready.

Hi,

I am running the standard Grove LCD code, as below but am getting an error, "Grove LCD: Device not ready.'

the code is

/*
 * Copyright (c) 2012-2014 Wind River Systems, Inc.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr.h>
#include <device.h>
//#include <display/cfb.h>
#include <stdio.h>
#include <drivers/display.h>
#include <nrf-pinctrl.h>
#include <drivers/i2c.h>
#include <sys/printk.h>

#include <zephyr/drivers/sensor.h>
#include <zephyr/sys/printk.h>
#include <zephyr/sys/util.h>

#include <drivers/misc/grove_lcd/grove_lcd.h>
#include <string.h>

/**
 * @file Display a counter through I2C and Grove LCD.
 */

/* sleep time in msec */
#define SLEEPTIME  100

uint8_t clamp_rgb(int val)
{
	if (val > 255) {
		return 255;
	} else if (val < 0) {
		return 0;
	} else {
		return val;
	}
}

void main(void)
{
	const struct device *glcd = DEVICE_DT_GET(DT_NODELABEL(glcd));
	char str[20];
	int rgb[] = { 0x0, 0x0, 0x0 };
	uint8_t rgb_chg[3];
	const uint8_t rgb_step = 16U;
	uint8_t set_config;
	int i, j, m;
	int cnt;


	if (!device_is_ready(glcd)) {
		printk("Grove LCD: Device not ready.\n");
		return;
	}

	/* Now configure the LCD the way we want it */

	set_config = GLCD_FS_ROWS_2
		     | GLCD_FS_DOT_SIZE_LITTLE
		     | GLCD_FS_8BIT_MODE;

	glcd_function_set(glcd, set_config);

	set_config = GLCD_DS_DISPLAY_ON | GLCD_DS_CURSOR_ON | GLCD_DS_BLINK_ON;

	glcd_display_state_set(glcd, set_config);

	/* Setup variables /*/
	for (i = 0; i < sizeof(str); i++) {
		str[i] = '\0';
	}

	/* Starting counting */
	cnt = 0;

	while (1) {
		glcd_cursor_pos_set(glcd, 0, 0);

		/* RGB values are from 0 - 511.
		 * First half means incrementally brighter.
		 * Second half is opposite (i.e. goes darker).
		 */

		/* Update the RGB values for backlight */
		m = (rgb[2] > 255) ? (512 - rgb[2]) : (rgb[2]);
		rgb_chg[2] = clamp_rgb(m);

		m = (rgb[1] > 255) ? (512 - rgb[1]) : (rgb[1]);
		rgb_chg[1] = clamp_rgb(m);

		m = (rgb[0] > 255) ? (512 - rgb[0]) : (rgb[0]);
		rgb_chg[0] = clamp_rgb(m);

		glcd_color_set(glcd, rgb_chg[0], rgb_chg[1], rgb_chg[2]);

		/* Display the counter
		 *
		 * well... sprintf() might be easier,
		 * but this is more fun.
		 */
		m = cnt;
		i = 1000000000;
		j = 0;
		while (i > 0) {
			str[j] = '0' + (m / i);

			m = m % i;
			i = i / 10;
			j++;
		}
		cnt++;

		glcd_print(glcd, str, j);

		/* Rotate RGB values */
		rgb[2] += rgb_step;
		if (rgb[2] > 511) {
			rgb[2] = 0;
			rgb[1] += rgb_step;
		}
		if (rgb[1] > 511) {
			rgb[1] = 0;
			rgb[0] += rgb_step;
		}
		if (rgb[0] > 511) {
			rgb[0] = 0;
		}

		/* wait a while */
		k_msleep(SLEEPTIME);
	}
}

my overlay file is

/ {
        chosen {
		zephyr,display = &glcd;
        };
};

&pinctrl {
	uart0_default_alt: uart0_default_alt {
		group0 {
			psels = <NRF_PSEL(UART_TX, 0, 24)>, <NRF_PSEL(UART_RX, 0, 22)>;
		};
	};

	uart0_sleep_alt: uart0_sleep_alt {
		group1 {
			psels = <NRF_PSEL(UART_TX, 0, 24)>, <NRF_PSEL(UART_RX, 0, 22)>;
			low-power-enable;
		};
	};

	i2c0_default_alt: i2c0_default_alt {
       		group2 {
          		psels = <NRF_PSEL(TWIM_SDA, 0, 17)>,
                  		<NRF_PSEL(TWIM_SCL, 0, 20)>;
       			};
    		};
};

&uart0 {
	pinctrl-0 = <&uart0_default_alt>;
	pinctrl-1 = <&uart0_sleep_alt>;	
	pinctrl-names = "default", "sleep";
	compatible = "nordic,nrf-uart";
	current-speed = <115200>;
	status = "okay";
};

&i2c0 {
	status = "okay";
	compatible = "nordic,nrf-twim";	
	pinctrl-0 = <&i2c0_default>;
	pinctrl-1 = <&i2c0_sleep>;
	pinctrl-names = "default", "sleep";
    	clock-frequency = <I2C_BITRATE_STANDARD>;  
//	clock-frequency = <I2C_BITRATE_FAST>;  
	zephyr,concat-buf-size = <520>;

	glcd: glcd@3e {
		compatible = "seeed,grove-lcd-rgb";
		label = "GLCD";
		reg = <0x3e>;
	};

};


&i2c0 {
/delete-property/sda-gpios;
/delete-property/scl-gpios;
};

and my proj file

# General config
CONFIG_BOARD_HAS_NRF5_BOOTLOADER=n
CONFIG_ASSERT=y
CONFIG_TEST_RANDOM_GENERATOR=y
CONFIG_GPIO=y
CONFIG_SERIAL=y
CONFIG_UART_INTERRUPT_DRIVEN=y
CONFIG_TEST_RANDOM_GENERATOR=y
CONFIG_NEWLIB_LIBC=y
CONFIG_CONSOLE_SUBSYS=y
CONFIG_CONSOLE_GETCHAR=y
CONFIG_STDOUT_CONSOLE=y
CONFIG_CONSOLE=y

CONFIG_CPLUSPLUS=y
CONFIG_LOG=y
CONFIG_SHELL=y
CONFIG_REBOOT=y
CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y
CONFIG_UART_CONSOLE=y

CONFIG_GPIO=y
CONFIG_STDOUT_CONSOLE=y
CONFIG_PRINTK=y

CONFIG_PINCTRL=y
CONFIG_PM_DEVICE=y

CONFIG_I2C=y
CONFIG_I2C_NRFX=y
CONFIG_SENSOR=y

CONFIG_BOOT_BANNER=n

#Display
CONFIG_DISPLAY=y
CONFIG_CHARACTER_FRAMEBUFFER=y
CONFIG_SHELL=y
CONFIG_CHARACTER_FRAMEBUFFER_SHELL=y
CONFIG_HEAP_MEM_POOL_SIZE=16384
CONFIG_GROVE_LCD_RGB=y

I think I'm missing something obvious but can't see it :-(

Rod

Parents
  • Hi Rod

    To debug, add the following to your prj.conf:

    CONFIG_LOG=y
    CONFIG_GROVE_LCD_RGB_LOG_LEVEL_DBG=y
    
    

    Then you can add some custom debugging log to glcd_initialize(), which will be called automatically on startup.

    I guess this function does not finish somehow, and therefore your code reports that it is not ready yet.

    Regards,
    Sigurd Hellesvik

  • Hi Sigurd,

    I have enabled debug and added a couple of debug statements shown below.

    static int glcd_initialize(const struct device *dev)
    {
    	const struct glcd_config *config = dev->config;
    	uint8_t cmd;
    
    	LOG_DBG("initialize called");
    
    	LOG_DBG("Check if Device is Ready");
    
    	if (!device_is_ready(config->bus.bus)) {
    	LOG_DBG("Check if Device is Ready Failed");
    		return -ENODEV;
    	}
    

    This is what I see

    uart:~$ Grove LCD: Device not ready.
    
    [00:00:00.311,798] <dbg> grove_lcd: glcd_initialize: initialize called
    [00:00:00.311,798] <dbg> grove_lcd: glcd_initialize: Check if Device is Ready
    [00:00:00.311,828] <dbg> grove_lcd: glcd_initialize: Check if Device is Ready Failed
    uart:~$ 
    

    Rod

  • I am pretty sure I have had this working previously on this board with an older version of the SDK which makes me this its  a software config error. I will check

    Rod

  • Hi Sigurd,

    I went back to v1.3.0 of the SDK and can confirm that the LCD works as expected. I wanted to double check my pinout, my pull-ups and basic connectivity were all good which this test has done. So, this confirms the hardware is all good and the something had changed in moving to v2.0.0 in the SDK.

    So, Im guessing this point to a configuration error either in my overlay file or my pro file.

    I changed my overlay file to use I2C1 and I explicitly disabled some other peripherals.

    / {
            chosen {
    		zephyr,display = &glcd;
            };
    };
    
    &pinctrl {
    	uart0_default_alt: uart0_default_alt {
    		group0 {
    			psels = <NRF_PSEL(UART_TX, 0, 24)>, <NRF_PSEL(UART_RX, 0, 22)>;
    		};
    	};
    
    	uart0_sleep_alt: uart0_sleep_alt {
    		group1 {
    			psels = <NRF_PSEL(UART_TX, 0, 24)>, <NRF_PSEL(UART_RX, 0, 22)>;
    			low-power-enable;
    		};
    	};
    
    	i2c1_default_alt: i2c1_default_alt {
           		group2 {
              		psels = <NRF_PSEL(TWIM_SDA, 0, 17)>,
                      		<NRF_PSEL(TWIM_SCL, 0, 20)>;
           			};
        		};
    };
    
    &uart0 {
    	pinctrl-0 = <&uart0_default_alt>;
    	pinctrl-1 = <&uart0_sleep_alt>;	
    	pinctrl-names = "default", "sleep";
    
    	compatible = "nordic,nrf-uart";
    	current-speed = <115200>;
    	status = "okay";
    };
    
    &i2c1 {
    	status = "okay";
    	compatible = "nordic,nrf-twim";	
    	pinctrl-0 = <&i2c1_default>;
    	pinctrl-1 = <&i2c1_sleep>;
    	pinctrl-names = "default", "sleep";
    //    	clock-frequency = <I2C_BITRATE_STANDARD>;  
    	clock-frequency = <I2C_BITRATE_FAST>;  
    	zephyr,concat-buf-size = <520>;
    
    	bme680@77 {
    		compatible = "bosch,bme680";
    		reg = <0x77>;
    		label = "BME680";
    	};
    
    	glcd: glcd@3e {
    		compatible = "seeed,grove-lcd-rgb";
    		label = "GLCD";
    		reg = <0x3e>;
    	};
    };
    
    &i2c1 {
    /delete-property/sda-gpios;
    /delete-property/scl-gpios;
    };
    
    &uart1 {
        status = "disabled";
    };
    
    &spi0 {
        status = "disabled";
    };
    
    &spi1 {
        status = "disabled";
    };
    
    &spi2 {
        status = "disabled";
    };
    
    &spi3 {
        status = "disabled";
    };
    
     

    This got rid of the 0x0BAE0001 error I was seeing above but I am still seeing errors.

    [00:00:00.295,135] <dbg> grove_lcd: glcd_initialize: initialize called
    [00:00:00.295,166] <dbg> grove_lcd: glcd_initialize: Check if Device is Ready
    [00:00:00.295,196] <dbg> grove_lcd: glcd_initialize: Device is Ready
    [00:00:00.295,196] <dbg> grove_lcd: glcd_initialize: delay 50 ms while the VDD powers on
    [00:00:00.845,397] <err> i2c_nrfx_twim: Error on I2C line occurred for message 0
    [00:00:00.845,489] <dbg> grove_lcd: glcd_function_set: set function options, delay 5 ms
    [00:00:01.350,646] <err> i2c_nrfx_twim: Error on I2C line occurred for message 0
    [00:00:01.350,677] <dbg> grove_lcd: glcd_display_state_set: set display_state options, delay 5 ms

    Rod

  • Hi Rod,

    Since it seems to be an issue with the SDK, I have asked our developers if they have any advise. I will let you know when I hear from them.

    Regards,
    Sigurd Hellesvik

  • Thanks Sigurd,

    I will look forward to their update. As an aside, do you have a !2C scanner example that works out of the box? I found links to some examples, but  nothing that seems to work with the new SDK. 

    Rod

  • Hi Rod,

    I took an unofficial I2C scanner sample by crfosse I know worked for earlier versions of the nRF Connect SDK, and changed its overlay file to work with nrf52840dk with pinctrl, so it should work with v2.0.0.

    I do not have an I2C sensor handy at the moment, so I have not tested it yet.
    Can you try it first, and I will have another look at the sample if it does not work for you.

    1258.i2c_scanner.zip

    Regards,
    Sigurd Hellesvik

Reply Children
Related