EmbeddedRelated.com
Forums

twi interface / frequency problem

Started by Bernd July 26, 2008
Hi,

I`m working with the AT91SAM9260 controller and I want to install the
TWI interface. Taking a look at the examples from the atmel homepage,
I get a very strange error. When I choose a frequency higher than 8k
Hz for the twi interface, the controller will only send the first
startbyte. When the frequency is smaller than 8k Hz than the
controller send the startbyte and the addr for the slave.

I checked the calculation for the frequency - but there`s no error.
Here`s my initialization code - maybe someone of you could tell me
where the error is. The twi traces are only 5cm long and I use 10k as
pullup for both traces.

The frequency from the controller is correct (approximately 100 MHz).
#define AT91B_MAIN_OSC (18432000) //main oscillator
#define AT91B_PROCESSOR_CLOCK ((AT91B_MAIN_OSC/14)*74)
#define AT91B_MASTER_CLOCK (AT91B_PROCESSOR_CLOCK)

#define TWI_BUS_CLOCK (100000) //100k Hz twi clock
/*
configurate twi interface clock registers
*/

void AT91F_SetTwiClock(void){
int sclock;
/* Here, CKDIV = 1 and CHDIV=CLDIV ==> CLDIV = CHDIV = 1/4*
((Fmclk/FTWI) -6)*/

sclock = (10*MCK /TWI_BUS_CLOCK);
if (sclock % 10 >= 5)
sclock = (sclock /10) - 5;
else
sclock = (sclock /10)- 6;
sclock = (sclock + (4 - sclock %4)) >> 2; // div 4
AT91C_BASE_TWI->TWI_CWGR = ( 1<<16 ) | (sclock << 8) | sclock;
}

/*
scan the bus for twi slaves
*/

unsigned char twi_scan(unsigned char *data)
{
unsigned int timeout = 0;
unsigned char mem_adr = 0x01;
unsigned char i, counter;
for(i = 0; i <= 0xFE; i++){
timeout = 0;
*AT91C_TWI_CR = AT91C_TWI_MSEN;
*AT91C_TWI_IADR = mem_adr;
*AT91C_TWI_MMR = ((i<<16) //Slave address
| AT91C_TWI_MREAD //Master read mode
| AT91C_TWI_IADRSZ_1_BYTE);

*AT91C_TWI_CR = AT91C_TWI_START; //Send the start condition
while(!(*AT91C_AIC_IPR & (1< { //TX Complete TWI irq polling
timeout++;
if(timeout >= 10000000){
// twi_stop();
return TWI_TXTIMEOUT; //Exit on TXCOMP timeout
}
}
twi_nack_wait();
if(*AT91C_TWI_SR & AT91C_TWI_NACK)
{ //Slave exist and send ACK?
counter++;
*(data+counter) = i;
}
// twi_stop();
}
return 0;
}
/*
dummy irq
*/

void dummy_irq(void) __irq
{

}
/*
main routine
*/

int main(void)
{
unsigned char buffer[256];
unsigned int i=0;

/* init buffer */
for(i=0; i<256; i++)
buffer[i] = 0x00;

/* Configure TWI PIOs */
AT91F_TWI_CfgPIO ();

/* Configure PMC by enabling TWI clock */
AT91F_TWI_CfgPMC ();

/* Reset the TWI */
AT91C_BASE_TWI->TWI_CR = AT91C_TWI_SWRST;

/* Configure TWI in master mode */
AT91F_TWI_Configure (AT91C_BASE_TWI);

/* Set TWI Clock Waveform Generator Register */
AT91F_SetTwiClock();

//TWI NACK Bug workaround
AT91F_AIC_ConfigureIt ( AT91C_BASE_AIC,
AT91C_ID_TWI,
7,
AT91C_AIC_SRCTYPE_EXT_POSITIVE_EDGE,
(void (*) (void))dummy_irq);

*AT91C_TWI_IER = (1<<0);
*AT91C_TWI_CR = AT91C_TWI_MSEN;

//init is ready

//scan for twi interfaces / slaves
if(twi_scan(buffer) != 0) ;

while(1);
}

I hope someone of you have a helpful hint for me to solve this
problem.

best regards
Bernd

Maybe someone of you have a working examle for the twi (from the
AT91SAM9260) controller and could send me this small example (with his or
her prefernces - PLL, clock (MHz) and the twi clock settings). It would be
very nice to have a working example to find my error faster.

best regards
Bernd

2008/7/26 Bernd

> Hi,
>
> I`m working with the AT91SAM9260 controller and I want to install the
> TWI interface. Taking a look at the examples from the atmel homepage,
> I get a very strange error. When I choose a frequency higher than 8k
> Hz for the twi interface, the controller will only send the first
> startbyte. When the frequency is smaller than 8k Hz than the
> controller send the startbyte and the addr for the slave.
>
> I checked the calculation for the frequency - but there`s no error.
> Here`s my initialization code - maybe someone of you could tell me
> where the error is. The twi traces are only 5cm long and I use 10k as
> pullup for both traces.
>
> The frequency from the controller is correct (approximately 100 MHz).
>
> #define AT91B_MAIN_OSC (18432000) //main oscillator
> #define AT91B_PROCESSOR_CLOCK ((AT91B_MAIN_OSC/14)*74)
> #define AT91B_MASTER_CLOCK (AT91B_PROCESSOR_CLOCK)
>
> #define TWI_BUS_CLOCK (100000) //100k Hz twi clock
>
> /*
> configurate twi interface clock registers
> */
>
> void AT91F_SetTwiClock(void){
> int sclock;
> /* Here, CKDIV = 1 and CHDIV=CLDIV ==> CLDIV = CHDIV = 1/4*
> ((Fmclk/FTWI) -6)*/
>
> sclock = (10*MCK /TWI_BUS_CLOCK);
> if (sclock % 10 >= 5)
> sclock = (sclock /10) - 5;
> else
> sclock = (sclock /10)- 6;
> sclock = (sclock + (4 - sclock %4)) >> 2; // div 4
> AT91C_BASE_TWI->TWI_CWGR = ( 1<<16 ) | (sclock << 8) | sclock;
> }
>
> /*
> scan the bus for twi slaves
> */
>
> unsigned char twi_scan(unsigned char *data)
> {
> unsigned int timeout = 0;
> unsigned char mem_adr = 0x01;
> unsigned char i, counter;
> for(i = 0; i <= 0xFE; i++){
> timeout = 0;
> *AT91C_TWI_CR = AT91C_TWI_MSEN;
> *AT91C_TWI_IADR = mem_adr;
> *AT91C_TWI_MMR = ((i<<16) //Slave address
> | AT91C_TWI_MREAD //Master read mode
> | AT91C_TWI_IADRSZ_1_BYTE);
>
> *AT91C_TWI_CR = AT91C_TWI_START; //Send the start condition
>
> while(!(*AT91C_AIC_IPR & (1< > { //TX Complete TWI irq polling
> timeout++;
> if(timeout >= 10000000){
> // twi_stop();
> return TWI_TXTIMEOUT; //Exit on TXCOMP timeout
> }
> }
> twi_nack_wait();
> if(*AT91C_TWI_SR & AT91C_TWI_NACK)
> { //Slave exist and send ACK?
> counter++;
> *(data+counter) = i;
> }
> // twi_stop();
> }
> return 0;
> }
>
> /*
> dummy irq
> */
>
> void dummy_irq(void) __irq
> {
>
> }
>
> /*
> main routine
> */
>
> int main(void)
> {
> unsigned char buffer[256];
> unsigned int i=0;
>
> /* init buffer */
> for(i=0; i<256; i++)
> buffer[i] = 0x00;
>
> /* Configure TWI PIOs */
> AT91F_TWI_CfgPIO ();
>
> /* Configure PMC by enabling TWI clock */
> AT91F_TWI_CfgPMC ();
>
> /* Reset the TWI */
> AT91C_BASE_TWI->TWI_CR = AT91C_TWI_SWRST;
>
> /* Configure TWI in master mode */
> AT91F_TWI_Configure (AT91C_BASE_TWI);
>
> /* Set TWI Clock Waveform Generator Register */
> AT91F_SetTwiClock();
>
> //TWI NACK Bug workaround
> AT91F_AIC_ConfigureIt ( AT91C_BASE_AIC,
> AT91C_ID_TWI,
> 7,
> AT91C_AIC_SRCTYPE_EXT_POSITIVE_EDGE,
> (void (*) (void))dummy_irq);
>
> *AT91C_TWI_IER = (1<<0);
> *AT91C_TWI_CR = AT91C_TWI_MSEN;
>
> //init is ready
>
> //scan for twi interfaces / slaves
> if(twi_scan(buffer) != 0) ;
> while(1);
> }
>
> I hope someone of you have a helpful hint for me to solve this
> problem.
>
> best regards
> Bernd
>