I'm completely new to the nRF and have been trying to set up the nRF as a master for I2C communication with a dsPIC(slave device), the nRF is supposed to always read data from the dsPIC but since the nRF doesn't support being operated as a slave device the nRF is the bus master and the dsPIC is the slave.
I have gone through the reference manual and written the code provided below. The code is free from errors in terms of c language (but correct me if I'm wrong), however, nRF51882 never initiates a start condition. As I mentioned I have never worked with nRF devices before so there might be a very small mistake I'm missing so any help or hints are appreciated.
If any more information is required let me know.
#include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include <stdint.h> #include <string.h> #include <nrf.h> #define GPIO ((GPIO_REGS *)0x50000000) #define I2C ((I2C_REGS *)0x40003000) //TWI instance 0 typedef struct { volatile unsigned int aDummy0[321]; volatile unsigned int OUT; // 0x504 Write GPIO port volatile unsigned int OUTSET; // Set individual bits in GPIO port volatile unsigned int OUTCLR; // Clear individual bits in GPIO port volatile unsigned int IN; // 0x510 Read GPIO port volatile unsigned int DIR; // Direction of GPIO pins volatile unsigned int DIRSET; // Setting DIR register volatile unsigned int DIRCLR; // Clearing DIR register volatile unsigned int aDummy1[120]; // 0x600 Reserved volatile unsigned int PIN_CNF[31]; // 0x700 Configuration of pin 0-31 } GPIO_REGS; typedef struct { //Tasks volatile unsigned int STARTRX; // 0x000 Start TWI receive sequence volatile unsigned int aDummy0[1]; //all dummy vars are for alligning structure elements with actual register address volatile unsigned int STARTTX; // 0x008 Start TWI transmit sequence volatile unsigned int aDummy1[2]; volatile unsigned int STOP; // 0x014 Stop TWI transaction volatile unsigned int aDummy2[1]; volatile unsigned int SUSPEND; // 0x01C Suspend TWI transaction volatile unsigned int RESUME; // 0x020 Resume TWI transaction //Events volatile unsigned int aDummy4[56]; volatile unsigned int STOPPED; // 0x104 TWI stopped volatile unsigned int RXDREADY; // 0x108 TWI RXD byte received volatile unsigned int aDummy5[4]; volatile unsigned int TXDSENT; // 0x11C TWI TXD byte sent volatile unsigned int aDummy6[1]; volatile unsigned int ERROR; // 0x124 TWI error volatile unsigned int aDummy7[4]; volatile unsigned int BB; // 0x138 TWI byte boundary, generated before each byte that is sent or received //Registers volatile unsigned int aDummy8[49]; volatile unsigned int SHORTS; // 0x200 Shortcut register volatile unsigned int aDummy9[63]; volatile unsigned int INTEN; // 0x300 Enable or disable interrupt volatile unsigned int INTENSET; // 0x304 Enable interrupt volatile unsigned int INTENCLR; // 0x308 Disable interrupt volatile unsigned int aDummy10[110]; volatile unsigned int ERRORSRC; // 0x4C4 Error source volatile unsigned int aDummy11[14]; volatile unsigned int ENABLE; // 0x500 Enable TWI volatile unsigned int aDummy12[1]; volatile unsigned int PSELSCL; // 0x508 Pin select for SCL volatile unsigned int PSELSDA; // 0x50C Pin select for SDA volatile unsigned int aDummy13[2]; volatile unsigned int RXD; // 0x518 RXD register volatile unsigned int TXD; // 0x51C TXD register volatile unsigned int aDummy14[1]; volatile unsigned int FREQUENCY; // 0x524 TWI frequency volatile unsigned int aDummy15[24]; volatile unsigned int ADDRESS; // 0x588 Address used in the TWI transfer } I2C_REGS; #define SDA_PIN 30 #define SCL_PIN 0 static void _InitI2C(void) { //Set the I2C SDA and SCL pins to inputs GPIO->DIRCLR = (1uL << SCL_PIN); GPIO->DIRCLR = (1uL << SDA_PIN); //Configure the SDA and SCL pins I2C->PSELSCL = SCL_PIN; I2C->PSELSDA = SDA_PIN; I2C->FREQUENCY = 0x06680000; //400 kbps baud rate I2C->ADDRESS = 0x70; //I2C address of bootloader I2C->ENABLE = 5; //Enable the module } int main(void) { _InitI2C(); int digitisedAN = 0; while(1) { //I2C->SUSPEND = 1; //Suspend the I2C Bus //I2C->TXD=0X70; I2C->RXDREADY = 0; //Clear RXDREADY I2C->STARTRX = 1; //Start the I2C Read sequence while (I2C->RXDREADY == 0);//While there is no message to read //I2C->SUSPEND=1; digitisedAN = I2C->RXD; //Retrieve first BYTE I2C->RXDREADY = 0; //Clear RXDREADY FOR NEXT BYTE I2C->RESUME = 1; //Resume I2C Bus I2C->STOP = 1; //Stop before reading the last byte while (I2C->RXDREADY == 0); //While there is no message to read I2C->RXDREADY = 0; //Clear RXDREADY flag for next time digitisedAN=digitisedAN + I2C->RXD; //Retrieve the 2nd byte while (I2C->STOPPED == 0); //While the bus has not stopped I2C->STOPPED = 0; //Clear STOPPED flag for next time } }