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

nRF52840 TWIM

First try to create a TWIM driver from scratch without any DMA. Following the steps in the OPS I get mixed behavior and only the chapter with DMA generates any clock and data on the interface. Without setting Master enable bit nothing will start and there is no reference in the non DMA flow diagram. Anyhow when using Master bit I get all TXD data on the bus but not RXD.

I use Prev-DK board with SDOF Stick connected to P0.27/P0.26 at 100kHz.

This is my flow right now:

// ***** INIT *****
#define USED_I2C_BLOCK 0x40003000

output_32( USED_I2C_BLOCK+I2C_TXD_MAXCNT_REG, 2 );

// enable master mode
output_32( USED_I2C_BLOCK+I2C_ENABLE_REG, 1 );

// ***** TRANSMITT *****

// send start condition
output_32( USED_I2C_BLOCK+I2C_STARTTX_REG, 1  );

// wait for int

// write data (slave address)
output_32( USED_I2C_BLOCK+I2C_TXD_REG, (SlaveAddress<<1) );

// wait for int

// write data (register address)
output_32( USED_I2C_BLOCK+I2C_TXD_REG, RegAddr );

// wait for int

// send stop bit
output_32( USED_I2C_BLOCK+I2C_STOP_REG, 1 );

// wait for int

// ***** RECEIVE *****

output_32( USED_I2C_BLOCK+I2C_RXD_MAXCNT_REG, DataBufferSize );

// enable master mode
output_32( USED_I2C_BLOCK+I2C_ENABLE_REG, 1 );

// send start condition
output_32( USED_I2C_BLOCK+I2C_STARTRX_REG, 1 );

// wait for int

// send read slave address
output_32( USED_I2C_BLOCK+I2C_TXD_REG, (SlaveAddress<<1)+1 );

// wait for int

while ( DataBufferSize-- )
{
	if ( DataBufferSize == 0 )
	{
		// send stop bit
		output_32( USED_I2C_BLOCK+I2C_STOP_REG, 1 );
	}

	// wait for int

	// read data
	*DataByte++ = input_32( USED_I2C_BLOCK+I2C_RXD_REG );
}
Parents
  • Yes the output/input works (used for 20 years, no change ;)

    I’m not using DMA and I guess that you do not need to set the pointer to TX/RX and directly read from the TXD/RXD. Also the chapter without DMA do not describe this part.

    No the controller do not add the READ bit so I have to add it. I shift the slave address because it’s an 7-bit address.

    I will try your approach because it’s more simple then my more complex implementation. If everything are handle in hardware I do not have to do it manually that I’m currently doing now.

    If you need more info or missing defines I can add them to the thread.

  • It did not work. The interface pins goes low when master mode is enabled and that’s it, nothing more.

    Just to make sure I did it right I give you the change below including the defines.

    // register map
    #define I2C_STARTRX_REG		0x0000
    #define I2C_STARTTX_REG		0x0008
    #define I2C_STOP_REG		0x0014
    #define I2C_SUSPEND_REG		0x001C
    #define I2C_RESUME_REG		0x0020
    #define I2C_STOPPED_REG		0x0104
    #define I2C_RXDREADY_REG	0x0108
    #define I2C_TXSENT_REG		0x010C
    #define I2C_ERROR_REG		0x0124
    #define I2C_BB_REG			0x0138
    #define I2C_SUSPENDED_REG	0x0148
    #define I2C_RXSTARTED_REG	0x014C
    #define I2C_TXSTARTED_REG	0x0150
    #define I2C_LASTRX_REG		0x015C
    #define I2C_LASTTX_REG		0x0160
    #define I2C_SHORT_REG		0x0200
    #define I2C_INTENSET_REG	0x0304
    #define I2C_INTENCLR_REG	0x0308
    #define I2C_ERRORSRC_REG	0x04C4
    #define I2C_ENABLE_REG		0x0500
    #define I2C_PSEL_SCL_REG	0x0508
    #define I2C_PSEL_SDA_REG	0x050C
    #define I2C_RXD_REG		0x0518
    #define I2C_TXD_REG		0x051C
    #define I2C_FREQUENCY_REG	0x0524
    #define I2C_RXD_PTR_REG		0x0534
    #define I2C_RXD_MAXCNT_REG	0x0538
    #define I2C_RXD_AMOUNT_REG	0x053C
    #define I2C_RXD_LIST_REG	0x0540
    #define I2C_TXD_PTR_REG		0x0544
    #define I2C_TXD_MAXCNT_REG	0x0548
    #define I2C_TXD_AMOUNT_REG	0x054C
    #define I2C_TXD_LIST_REG	0x0550
    #define I2C_ADDRESS_REG		0x0588
    
    output_32( USED_I2C_BLOCK+I2C_ENABLE_REG, 0 );
    
    output_32( USED_I2C_BLOCK+I2C_SHORT_REG, (1<<12) | (1<<9) );
    
    output_32( USED_I2C_BLOCK+I2C_ADDRESS_REG, (SlaveAddress<<1) );
    
    output_32( USED_I2C_BLOCK+I2C_TXD_PTR_REG, 0x20021000 );
    output_32( USED_I2C_BLOCK+I2C_TXD_MAXCNT_REG, 1 );
    
    output_32( USED_I2C_BLOCK+I2C_RXD_PTR_REG, 0x20020000 );
    output_32( USED_I2C_BLOCK+I2C_RXD_MAXCNT_REG, DataBufferSize );
    
    output_32( USED_I2C_BLOCK+I2C_ENABLE_REG, 1 );
    
    output_32( USED_I2C_BLOCK+I2C_LASTTX_REG, 1 );
    
    output_32( USED_I2C_BLOCK+I2C_STARTTX_REG, 1 );
    
    // Wait for TX to complete
    TIMER_Timer_Delay( 100000 );
    
    output_32( USED_I2C_BLOCK+I2C_STARTRX_REG, 1 );
    
Reply
  • It did not work. The interface pins goes low when master mode is enabled and that’s it, nothing more.

    Just to make sure I did it right I give you the change below including the defines.

    // register map
    #define I2C_STARTRX_REG		0x0000
    #define I2C_STARTTX_REG		0x0008
    #define I2C_STOP_REG		0x0014
    #define I2C_SUSPEND_REG		0x001C
    #define I2C_RESUME_REG		0x0020
    #define I2C_STOPPED_REG		0x0104
    #define I2C_RXDREADY_REG	0x0108
    #define I2C_TXSENT_REG		0x010C
    #define I2C_ERROR_REG		0x0124
    #define I2C_BB_REG			0x0138
    #define I2C_SUSPENDED_REG	0x0148
    #define I2C_RXSTARTED_REG	0x014C
    #define I2C_TXSTARTED_REG	0x0150
    #define I2C_LASTRX_REG		0x015C
    #define I2C_LASTTX_REG		0x0160
    #define I2C_SHORT_REG		0x0200
    #define I2C_INTENSET_REG	0x0304
    #define I2C_INTENCLR_REG	0x0308
    #define I2C_ERRORSRC_REG	0x04C4
    #define I2C_ENABLE_REG		0x0500
    #define I2C_PSEL_SCL_REG	0x0508
    #define I2C_PSEL_SDA_REG	0x050C
    #define I2C_RXD_REG		0x0518
    #define I2C_TXD_REG		0x051C
    #define I2C_FREQUENCY_REG	0x0524
    #define I2C_RXD_PTR_REG		0x0534
    #define I2C_RXD_MAXCNT_REG	0x0538
    #define I2C_RXD_AMOUNT_REG	0x053C
    #define I2C_RXD_LIST_REG	0x0540
    #define I2C_TXD_PTR_REG		0x0544
    #define I2C_TXD_MAXCNT_REG	0x0548
    #define I2C_TXD_AMOUNT_REG	0x054C
    #define I2C_TXD_LIST_REG	0x0550
    #define I2C_ADDRESS_REG		0x0588
    
    output_32( USED_I2C_BLOCK+I2C_ENABLE_REG, 0 );
    
    output_32( USED_I2C_BLOCK+I2C_SHORT_REG, (1<<12) | (1<<9) );
    
    output_32( USED_I2C_BLOCK+I2C_ADDRESS_REG, (SlaveAddress<<1) );
    
    output_32( USED_I2C_BLOCK+I2C_TXD_PTR_REG, 0x20021000 );
    output_32( USED_I2C_BLOCK+I2C_TXD_MAXCNT_REG, 1 );
    
    output_32( USED_I2C_BLOCK+I2C_RXD_PTR_REG, 0x20020000 );
    output_32( USED_I2C_BLOCK+I2C_RXD_MAXCNT_REG, DataBufferSize );
    
    output_32( USED_I2C_BLOCK+I2C_ENABLE_REG, 1 );
    
    output_32( USED_I2C_BLOCK+I2C_LASTTX_REG, 1 );
    
    output_32( USED_I2C_BLOCK+I2C_STARTTX_REG, 1 );
    
    // Wait for TX to complete
    TIMER_Timer_Delay( 100000 );
    
    output_32( USED_I2C_BLOCK+I2C_STARTRX_REG, 1 );
    
Children
No Data
Related