Starting a simple TWI on SAM4S

Discussion around product based on ARM Cortex M4 core.
This forum will be discontinued soon.

Moderators: nferre, ncollot

Yaro
Posts: 13
Joined: Mon May 25, 2015 8:00 pm

Starting a simple TWI on SAM4S

Sat Dec 05, 2015 12:56 pm

Hi all,

I've a problem to setup TWI on SAM4S. I've serched a lot on forums and found a lot of people encountering this problem on SAM4S device and no one had a solution(or maybe yes but they didn't provide it).

My configuration is:
Atmel Studio 7
ASF version 3.28.1
ASF driver is TWI - Two-wire Interface (Driver)
Additional drivers loaded: PMC, IOPORT, System Clock Control, Delay.
SAM4S

TWI pins used on SAM4S:
TWI0 TWCK0 PA4
TWI0 TWD0 PA3

Mounted Pullups are 4.7kOhm
Pins was tested with IOPORT driver and result working, pullups also result working.

I've tryed two examples:
- ASF SAM3 Master TWI
- http://asf.atmel.com/docs/3.15.0/uc3a/h ... start.html

but with no success. I've also tryed a lot of user codes found online but nothing.

This is a basic configuration code I've used (no additional definition, no more settings in other files):

Code: Select all

src/config/conf_board.h

#define CONF_BOARD_TWI0

Code: Select all

main.c

    //CODE//
    ////////////////////////////////////////////////////////
    #define I2C_MODULE TWI0
    #define I2C_MODULE_ID ID_TWI0

    pmc_enable_periph_clk(I2C_MODULE_ID);

    /* Initialize config structure and software module. */
    struct twi_options config_i2c_master;

    config_i2c_master.master_clk = sysclk_get_main_hz();
    config_i2c_master.speed = 100000;
    config_i2c_master.chip = 0x00;
    config_i2c_master.smbus = 0;

    twi_enable_master_mode(I2C_MODULE);
    twi_master_init(I2C_MODULE, &config_i2c_master);

    const uint8_t test_pattern[] = {
    0x55,
    0xA5,
    0x5A,
    0x77,
    0x99};

    struct twi_packet packet = {
    .addr[0] = 0x10,
    .addr[1] = 0x20,
    .addr_length = sizeof (uint16_t),
    .buffer = (void *)test_pattern, // transfer data source buffer
    .length = sizeof(test_pattern), // transfer data size (bytes)
    .chip = 0x30,
    };
    twi_master_write(I2C_MODULE, &packet);

    //CODE//
    ////////////////////////////////////////////////////////


Error I've is that code stucks in an infinte loop when "twi_master_write" is called.

Loop is in "uint32_t twi_master_read(Twi *p_twi, twi_packet_t *p_packet)" function in "twi.c" driver file:

Code: Select all

 while (cnt > 0) {
    status = p_twi->TWI_SR;
    if (status & TWI_SR_NACK) {
    return TWI_RECEIVE_NACK;
    }

    if (!timeout--) {
    return TWI_ERROR_TIMEOUT;
    }

    /* Last byte ? */
    if (cnt == 1 && !stop_sent) {
    p_twi->TWI_CR = TWI_CR_STOP;
    stop_sent = 1;
    }

    if (!(status & TWI_SR_RXRDY)) {
    continue;
    }
    *buffer++ = p_twi->TWI_RHR;

    cnt--;
    timeout = TWI_TIMEOUT;
    }


I've also checked with digital analyzer TWI outputs, working good with IOPORT driver but no changes when running TWI module or sending packet.

Any tips to solve this problem are appreciated, also newbie tips.

Thank you!
BartOnAvr
Posts: 5
Joined: Mon Oct 19, 2015 4:36 pm

Re: Starting a simple TWI on SAM4S

Sat Dec 05, 2015 1:27 pm

Hi there,

Did you configure the GPIO pins as well? I scanned quickly through your code and could not see that.
The I2C initialization code doesn't do that for you.

I'm using the I2C interface myself on an ATSAM4S to load a few DSP's over I2C and it works fine.
Before I start using the I2C peripheral I call the function below.

Code: Select all

void voSetupTwiMaster1(void)
{
	uint32_t				u32RetVal;

	twi_master_options_t	sTwiMasterOptions =
	{
		BOARD_FREQ_MAINCK_XTAL,			//! MCK for TWI.
		BOARD_I2C1_CLK_FREQ,			//! The baud rate of the TWI bus.
		BOARD_I2C1_DSP1_ADAU1701_ADDR,	//! The desired address. (CAT24C128, 1010 E2 E1 E0 R/W) E0..E2 are connected to Gnd.
		0								//! SMBUS mode (set 1 to use SMBUS quick command, otherwise don't).
	};
	status_code_t			tRetVal;

	printf("Setup I2C master on I2C bus 1\n");
	
	u32RetVal = pmc_enable_periph_clk(ID_TWI0);
	if(u32RetVal != SUCCESS)
	{
		while(1);
	}

	u32RetVal = pio_configure(PIOA, PIO_PERIPH_A, (PIO_PA4A_TWCK0 | PIO_PA3A_TWD0), PIO_OPENDRAIN);
	if(u32RetVal != 1) // This will return one in case of success!
	{
		while(1);
	}

	tRetVal = twi_master_setup(BOARD_DSP1_I2C_BUS, &sTwiMasterOptions); 
	if (tRetVal != TWI_SUCCESS)
	{
		while(1);
	}
	twi_master_enable(BOARD_DSP1_I2C_BUS);
}
honzek68
Posts: 5
Joined: Wed Nov 26, 2014 7:01 pm

Re: Starting a simple TWI on SAM4S

Wed Jan 13, 2016 7:44 pm

I have the same problem, sometimes everything works, but after some time the program stuck int the same pleace...

Return to “SAM4 Cortex-M4 MCU”

Who is online

Users browsing this forum: Baidu [Spider] and 1 guest