Hi everyone,
first time posting here for me, let me know if i'm doing it wrong.
I'm currently developing a "modem module" built around nrf9160 and working with AWS using NBIoT. The module will be added to a device which will communicate with it through I2C. The nrf9160 will be the slave device on the bus and will receive data to publish on AWS using MQTT.
I tested the"aws IoT" example and it's working correctly.
I build a sample code to receive the data on I2C using TWIS library since Zephyr doesn't support Slave I2C with its drivers. This code is working fine and i'm able to receive the data into a buffer and work on them. Here the interesting part of the code i used for the I2C slave:
Here the prj.conf sed to test the i2c:
CONFIG_NRFX_TWIS=y CONFIG_NRFX_TWIS2=y
Here the overlay used to test the I2C:
&i2c2 { compatible = "nordic,nrf-twis"; status = "okay"; sda-pin = <30>; scl-pin = <31>; clock-frequency = <I2C_BITRATE_STANDARD>; };
Here the actual code used to test the i2c:
#include <zephyr.h> #include <device.h> #include <devicetree.h> #include <nrfx_twis.h> #include <irq.h> #define NBIOT_MODULE_SLAVE_ADDR (0x60) #define JSON_BUFFER_SIZE 600 #define DATA_TRANSFER_BLOCK_SIZE 64 typedef nrfx_twis_t nrf_drv_twis_t; static const nrfx_twis_t m_twis = NRFX_TWIS_INSTANCE(2); char data_received[DATA_TRANSFER_BLOCK_SIZE + 1]; int received_amount = 0; static struct k_work_delayable print_data; static void twis_event_handler(nrfx_twis_evt_t const *const p_event) { printk("I2C Slave interrupt event\n"); switch (p_event->type) { case NRFX_TWIS_EVT_READ_REQ: if (p_event->data.buf_req) { // do something } break; case NRFX_TWIS_EVT_READ_DONE: break; case NRFX_TWIS_EVT_WRITE_REQ: if (p_event->data.buf_req) { printk("Write Operation requested \n"); nrfx_twis_rx_prepare(&m_twis, data_received, DATA_TRANSFER_BLOCK_SIZE + 1); } break; case NRFX_TWIS_EVT_WRITE_DONE: printk("Write Operation concluded \n"); received_amount = nrfx_twis_rx_amount(&m_twis); break; case NRFX_TWIS_EVT_READ_ERROR: case NRFX_TWIS_EVT_WRITE_ERROR: case NRFX_TWIS_EVT_GENERAL_ERROR: break; default: break; } } void main(void) { IRQ_CONNECT(DT_IRQN(DT_NODELABEL(i2c2)), DT_IRQ(DT_NODELABEL(i2c2), priority), nrfx_isr, nrfx_twis_2_irq_handler, 0); nrfx_twis_config_t config; config.addr[0] = NBIOT_MODULE_SLAVE_ADDR; config.addr[1] = 0; config.scl = 31; // PIN_SCL; config.scl_pull = NRF_GPIO_PIN_PULLUP; config.sda = 30; // PIN_SDA; config.sda_pull = NRF_GPIO_PIN_PULLUP; config.interrupt_priority = 2; ret = nrfx_twis_init(&m_twis, &config, twis_event_handler); nrfx_twis_enable(&m_twis); while (1) { // Do something } }
This code works perfectly.
The problem arises when I try to add the i2c part to the aws IoT example. Just by inserting the same code and performing the same initialization, the system is not able to enter the twis_event_handler function nor the system is providing ACK on the I2C bus.
I checked the return value of the nrfx_twis_init function and i'm getting NRFX_SUCCESS so the peripheral should be initalized correctly
Here is the prj.conf of the complete code (mainly the same as for aws IoT example with I2C and some APN configuration added):
# General config CONFIG_NCS_SAMPLES_DEFAULTS=y CONFIG_REBOOT=y # NEWLIB C CONFIG_NEWLIB_LIBC=y CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y # Network CONFIG_NETWORKING=y CONFIG_NET_NATIVE=n # LTE link control CONFIG_LTE_LINK_CONTROL=y CONFIG_LTE_NETWORK_MODE_LTE_M=n CONFIG_LTE_NETWORK_MODE_NBIOT=y CONFIG_LTE_AUTO_INIT_AND_CONNECT=n CONFIG_PDN=y CONFIG_PDN_DEFAULTS_OVERRIDE=y CONFIG_PDN_SYS_INIT=y # Note: "ip" is set by PDN_DEFAULT_FAM kconfig's # example: # AT+CGDCONT=1,"ip","apn" - below only sets APN field CONFIG_PDN_DEFAULT_APN="*********" # Modem library CONFIG_NRF_MODEM_LIB=y # AT Host CONFIG_UART_INTERRUPT_DRIVEN=y CONFIG_AT_HOST_LIBRARY=y # AWS IoT library CONFIG_AWS_IOT=y CONFIG_AWS_IOT_CLIENT_ID_STATIC="********" CONFIG_AWS_IOT_BROKER_HOST_NAME="a240h9vg29hlh9-ats.iot.us-east-1.amazonaws.com" CONFIG_AWS_IOT_SEC_TAG=********* CONFIG_AWS_IOT_APP_SUBSCRIPTION_LIST_COUNT=1 CONFIG_AWS_IOT_TOPIC_UPDATE_DELTA_SUBSCRIBE=y CONFIG_AWS_IOT_LAST_WILL=y CONFIG_AWS_IOT_TOPIC_GET_ACCEPTED_SUBSCRIBE=y CONFIG_AWS_IOT_TOPIC_GET_REJECTED_SUBSCRIBE=y CONFIG_AWS_IOT_MQTT_RX_TX_BUFFER_LEN=2048 CONFIG_AWS_IOT_MQTT_PAYLOAD_BUFFER_LEN=2048 # MQTT - Maximum MQTT keepalive timeout specified by AWS IoT Core CONFIG_MQTT_KEEPALIVE=1200 # Date Time library CONFIG_DATE_TIME=y # Modem information CONFIG_MODEM_INFO=y # Heap and stacks CONFIG_HEAP_MEM_POOL_SIZE=8192 CONFIG_MAIN_STACK_SIZE=4096 CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 # MCUBOOT CONFIG_BOOTLOADER_MCUBOOT=y CONFIG_MCUBOOT_IMG_MANAGER=y # Image manager CONFIG_IMG_MANAGER=y CONFIG_FLASH=y CONFIG_IMG_ERASE_PROGRESSIVELY=y # AWS FOTA CONFIG_AWS_FOTA=y CONFIG_FOTA_DOWNLOAD=y CONFIG_DFU_TARGET=y # CJSON CONFIG_CJSON_LIB=y # TWIS CONFIG_NRFX_TWIS=y CONFIG_NRFX_TWIS2=y # Download client (needed by AWS FOTA) CONFIG_DOWNLOAD_CLIENT=y CONFIG_DOWNLOAD_CLIENT_STACK_SIZE=4096
The overlay file is the same as before.
Am I missing some configuration that has to be done? Are there any conflicts between peripherals that are blocking the I2C?
Thank you in advance for any help
Nicolò