I’m trying use the pcf85063a driver in a Zephyr v3.2.99-ncs1 build. The driver reports that it failed to get the pointer and Zephyr reports that the device is not ready. How can I properly initialize this device?

prj.conf

CONFIG_DEBUG=y

# Using C
CONFIG_NEWLIB_LIBC=y

# Enable NRF Modem
# CONFIG_NRF_MODEM_LIB=y
# CONFIG_NRF_MODEM_LIB_SYS_INIT=y

# Setup networking
# CONFIG_NETWORKING=y
# CONFIG_NET_NATIVE=n
# CONFIG_NET_SOCKETS=y
# CONFIG_NET_SOCKETS_OFFLOAD=y
# CONFIG_NET_SOCKETS_POSIX_NAMES=y

# Config Heap and Stack size
CONFIG_MAIN_STACK_SIZE=4096
CONFIG_HEAP_MEM_POOL_SIZE=40960

# Setup LTE
# CONFIG_MODEM_KEY_MGMT=y
# CONFIG_LTE_LINK_CONTROL=y
# CONFIG_LTE_AUTO_INIT_AND_CONNECT=n

# AT host library
# CONFIG_AT_HOST_LIBRARY=y
# CONFIG_UART_INTERRUPT_DRIVEN=y

# Bootloader
CONFIG_BOOTLOADER_MCUBOOT=y
#CONFIG_MCUBOOT_IMG_MANAGER=y

# Enable I2C
CONFIG_I2C=y
CONFIG_I2C_NRFX=y

# Enable CJSON
#CONFIG_CJSON_LIB=y

# Enable Counter
#CONFIG_COUNTER=y

# Date Time library
#CONFIG_DATE_TIME=y

# Enable External RTC
CONFIG_COUNTER=y
CONFIG_PCF85063A=y

# Enable Logging
CONFIG_LOG=y
CONFIG_LOG_MODE_IMMEDIATE=y

overlay

&i2c1 {
	compatible = "nordic,nrf-twim";
	status = "okay";
  zephyr,concat-buf-size = <256>;

	pinctrl-0 = <&i2c1_default>;
	pinctrl-1 = <&i2c1_sleep>;
	pinctrl-names = "default", "sleep";
	pcf85063a: pcf85063a@51 {
		compatible = "nxp,pcf85063a";
		reg = <0x51>;
	};

	lis2dh: lis2dh@18 {
		compatible = "st,lis2dh";
		reg = <0x18>;
		irq-gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>;
		disconnect-sdo-sa0-pull-up;
	};
};

main.c

#include <stdlib.h>
#include <stdio.h>
#include <inttypes.h>

#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/sys/util.h>
#include <zephyr/drivers/counter.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/i2c.h>
#include <zephyr/logging/log.h>

#include <drivers/counter/pcf85063a.h>

#define I2C1_NODE DT_NODELABEL(i2c1)
#define I2C1_NAME DEVICE_DT_NAME(I2C1_NODE)
#define I2C1 DEVICE_DT_GET(I2C1_NODE)
#define RTC_NODE DT_NODELABEL(pcf85063a)
#define RTC_NAME DEVICE_DT_NAME(RTC_NODE)
#define RTC DEVICE_DT_GET(RTC_NODE)

LOG_MODULE_REGISTER(main, LOG_LEVEL_DBG);

//#define MY_I2C "I2C_1"
//const struct device *i2c_dev;
const struct device *rtc;

static void rtc_init() {

	/* Get the device */
	rtc = device_get_binding("pcf85063a_51");
  LOG_INF(I2C1_NAME);
  LOG_INF("i2c1 status: %s", DT_PROP(I2C1_NODE, status));
  LOG_WRN("i2c1 is ready: %s", device_is_ready(I2C1) ? "true" : "false");
  LOG_INF(RTC_NAME);
  LOG_WRN("pcf85063a is ready: %s", device_is_ready(RTC) ? "true" : "false");
	if (rtc == NULL) {
		LOG_ERR("Failed to get RTC device binding");
		return;
	}

	LOG_INF("device is %p, name is %s", rtc, rtc->name);

	int err = counter_start(rtc);
	if (err) {
		LOG_ERR("Unable to start RTC. Err: %i", err);
	}
}


void main(void) {
  k_msleep(1000);
  rtc_init();
}

Output

Connected to /dev/ttyUSB0!
[00:00:00.411,499] <err> pcf85063a: Failed to get pointer to i2c@9000 device!
[00:00:00.419,311] <inf> regulator_fixed: nrf-ps-en sync: 0
*** Booting Zephyr OS build v3.2.99-ncs1 ***
[00:00:01.429,351] <inf> main: i2c@9000
[00:00:01.433,563] <inf> main: i2c1 status: okay
[00:00:01.438,629] <wrn> main: i2c1 is ready: true
[00:00:01.444,091] <inf> main: pcf85063a@51
[00:00:01.448,699] <wrn> main: pcf85063a is ready: false
[00:00:01.454,681] <err> main: Failed to get RTC device binding

I believe I’m including the driver correctly. This is my west.yml:

# Import requirements for nRF9160 Feather Examples and Drivers
manifest:
  remotes:
    - name: nrfconnect
      url-base: https://github.com/nrfconnect
  projects:
    - name: nrf
      repo-path: sdk-nrf
      remote: nrfconnect
      revision: v2.2.0
      import:
        name-blocklist:
          - matter
          - nrf-802154
          - cjson
          - openthread
          - cmock
          - unity
          - cddl-gen
          - homekit
          - loramac-node
          - lz4
          - lvgl
          - mipi-sys-t
    # RTC Driver
    - name: pcf85063a
      url: https://github.com/circuitdojo/pcf85063a
      revision: master
      path: pcf85063a
  self:
    path: app

Initialing the device like this:

#define RTC_NAME DEVICE_DT_NAME(RTC_NODE)
#define RTC DEVICE_DT_GET(RTC_NODE)
const struct device *const rtc = RTC;

static void rtc_init() {
	if (rtc == NULL) {
		LOG_ERR("Failed to get RTC device binding");
		return;
	}

	LOG_INF("device is %p, name is %s", rtc, rtc->name);

	int err = counter_start(rtc);
	if (err) {
		LOG_ERR("Unable to start RTC. Err: %i", err);
	}
}

gives me this:

[00:00:00.411,590] [1;31m<err> pcf85063a: Failed to get pointer to i2c@9000 device![0m
[00:00:00.419,372] [0m<inf> regulator_fixed: nrf-ps-en sync: 0[0m
*** Booting Zephyr OS build v3.2.99-ncs1 ***
[00:00:01.429,412] [0m<inf> main: device is 0x2a288, name is pcf85063a@51[0m

It seems like there might be an issue with the driver bindings?

I should mention I’m using the rev. 4 feather with the B0 modem. I thought the pin assignment stayed the same for rev 5, but maybe I was wrong about that.

Voxorin interesting. I haven’t run into the initialization issues you mention. As I mentioned in your pull request if you can use DEVICE_DT_GET that would be more inline with typical device usage in Zephyr these days.

Thanks for your feedback. 😃

    jaredwolff it gets more interesting the closer I look. I peeked at a couple of Zephyr’s included modules and quite a few of them seem to use CONFIG_I2C_INIT_PRIORITY in the DEVICE_DT_INST_DEFINE.

    I’m pretty new to Zephyr, so that makes me wonder if there’s a better solution than the one I proposed.

    Hmm yea. Could it be because you’re getting the binding at runtime? I’d be curious if you used DEVICE_DT_GET if that made any difference. To my understanding it shouldn’t make a difference.

      jaredwolff I’m using DEVICE_DT_GET. Both device_is_ready(data->i2c.bus) and device_is_ready(rtc) still return false. Weirdly though, the device seems to initialize anyways and I can get/set the time.

        Voxorin using NCS 2.20 here I can replicate the issue you were seeing. Not sure what happened since it was working not too long ago. Maybe Nordic changed up their tags for that particular release. Nevertheless, I merged your changes. I appreciate your help!

        Terms and Conditions | Privacy Policy