This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

TWI problem with SoftDevice S340

Hello,

I am using nrf52840 to communicate with PAC 1710 sensor via TWI interface. The nrf52840 is the master device and the PAC chip is the slave device. Without SoftDevice (s340) enabled, I am able to do this without a problem. However, when I enabled the SoftDevice, the TWI communication did not work. The signal on my logic analyzer dissapeared. I have noticed that the code gets stuck in the while loop of I2C read function (found out by debugging). This is probably because I am manipulating the registers of TWI directly. So now I need an example of TWI master device code that works with SoftDevice (s340). Can anybody show me an example or point me to one? This are my TWI functions that work when I do not enable SoftDevice:

#include <nrf.h>
#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>
#include "nrf.h"
#include "nrf_drv_timer.h"
#include "app_error.h"
#include "app_util_platform.h"
#include "app_error.h"
#include "boards.h"
#include "bsp.h"
#include "nrf_drv_gpiote.h"
#include "nrf_drv_clock.h"
#include "nrf_delay.h"
#include "nrf_gpio.h"

#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"
#include "SEGGER_RTT.h"


/*DATA TYPES*/

#define uchar 						uint8_t
#define ushort 						uint16_t
#define uint   						uint32_t

/*DEVICE ADDRESS*/

#define PAC_ADDRESS 				(0x4A)

/*I2C PINS*/

#define PIN_SCL        				(27)
#define PIN_SDA        				(26)

/*I2C TX and RX array indexes*/

#define TX_REGISTER_ADDRESS_INDEX		0
#define TX_DATA_INDEX					1
#define RX_DATA_INDEX					0

void I2C_initialize(void){ 				//This function initializes the I2C protocol.

	NRF_TWIM0->PSEL.SCL = PIN_SCL;
	NRF_TWIM0->PSEL.SDA = PIN_SDA;

	NRF_TWIM0->ADDRESS = PAC_ADDRESS;
	NRF_TWIM0->FREQUENCY = TWIM_FREQUENCY_FREQUENCY_K400 << TWIM_FREQUENCY_FREQUENCY_Pos;
		
	NRF_TWIM0->SHORTS = 0;

	NRF_TWIM0->ENABLE = TWIM_ENABLE_ENABLE_Enabled << TWIM_ENABLE_ENABLE_Pos;
}


uchar I2C_read(uchar ucRegister_address){				//This function reades one byte from from a register with the address ucRegister_address.
	
	uchar ucTX_buffer[1] = {0};   //Zero element is just for initialization.
	uchar ucRX_buffer[1] = {0};   //Zero element is just for initialization.
  
	NRF_TWIM0->SHORTS = TWIM_SHORTS_LASTTX_STARTRX_Msk | TWIM_SHORTS_LASTRX_STOP_Msk;

	ucTX_buffer[TX_REGISTER_ADDRESS_INDEX] = ucRegister_address;
  
	NRF_TWIM0->TXD.MAXCNT = sizeof(ucTX_buffer);
	NRF_TWIM0->TXD.PTR = (uint)&ucTX_buffer[TX_REGISTER_ADDRESS_INDEX];

	NRF_TWIM0->RXD.MAXCNT = 1;
	NRF_TWIM0->RXD.PTR = (uint)&ucRX_buffer[RX_DATA_INDEX];

	NRF_TWIM0->EVENTS_STOPPED = 0;
	NRF_TWIM0->TASKS_STARTTX = 1;
  
	while (NRF_TWIM0->EVENTS_STOPPED == 0);  //Waiting for I2C read operation to finish.
	
	return ucRX_buffer[RX_DATA_INDEX]; 		//Returning the read data byte.
}

void I2C_write(uchar ucRegister_address, uchar ucData){  //This function writes one byte (ucData) to register with address ucRegister_address.
	
    uchar ucTX_buffer[2] = {0, 0};  //Zero elements are just for initialization.
  
    NRF_TWIM0->SHORTS = TWIM_SHORTS_LASTTX_STOP_Msk;

    ucTX_buffer[TX_REGISTER_ADDRESS_INDEX] = ucRegister_address;
    ucTX_buffer[TX_DATA_INDEX] = ucData;
  
	NRF_TWIM0->TXD.MAXCNT = sizeof(ucTX_buffer);
	NRF_TWIM0->TXD.PTR = (uint)&ucTX_buffer[TX_REGISTER_ADDRESS_INDEX];

	NRF_TWIM0->EVENTS_STOPPED = 0;
	NRF_TWIM0->TASKS_STARTTX = 1;
	
	while(NRF_TWIM0->EVENTS_STOPPED == 0);	//Waiting for I2C write operation to finish.
}

Related