[En-Nut-Discussion] SAM7X256-EK with TWI (24C65 or active Slaves) / polling "NutTcpAccept" / timer interrupt

Szemző András saam at kometa.hu
Tue May 27 13:39:25 CEST 2008


hi,

or until that, you can use this simple polling "userspace" code:

at91_twi.h :

#ifndef _AT91_TWI_H_
#define _AT91_TWI_H_

#define AT91C_EEPROM_I2C_ADDRESS  	(0x50<<16)

// -------- TWI_CR : (TWI Offset: 0x0) TWI Control Register -------- 
#define AT91C_TWI_START       ((unsigned int) 0x1 <<  0) // (TWI) Send a
START Condition
#define AT91C_TWI_STOP        ((unsigned int) 0x1 <<  1) // (TWI) Send a
STOP Condition
#define AT91C_TWI_MSEN        ((unsigned int) 0x1 <<  2) // (TWI) TWI Master
Transfer Enabled
#define AT91C_TWI_MSDIS       ((unsigned int) 0x1 <<  3) // (TWI) TWI Master
Transfer Disabled
#define AT91C_TWI_SWRST       ((unsigned int) 0x1 <<  7) // (TWI) Software
Reset
// -------- TWI_MMR : (TWI Offset: 0x4) TWI Master Mode Register -------- 
#define AT91C_TWI_IADRSZ      ((unsigned int) 0x3 <<  8) // (TWI) Internal
Device Address Size
#define 	AT91C_TWI_IADRSZ_NO                   ((unsigned int) 0x0 <<
8) // (TWI) No internal device address
#define 	AT91C_TWI_IADRSZ_1_BYTE               ((unsigned int) 0x1 <<
8) // (TWI) One-byte internal device address
#define 	AT91C_TWI_IADRSZ_2_BYTE               ((unsigned int) 0x2 <<
8) // (TWI) Two-byte internal device address
#define 	AT91C_TWI_IADRSZ_3_BYTE               ((unsigned int) 0x3 <<
8) // (TWI) Three-byte internal device address
#define AT91C_TWI_MREAD       ((unsigned int) 0x1 << 12) // (TWI) Master
Read Direction
#define AT91C_TWI_DADR        ((unsigned int) 0x7F << 16) // (TWI) Device
Address
// -------- TWI_CWGR : (TWI Offset: 0x10) TWI Clock Waveform Generator
Register -------- 
#define AT91C_TWI_CLDIV       ((unsigned int) 0xFF <<  0) // (TWI) Clock Low
Divider
#define AT91C_TWI_CHDIV       ((unsigned int) 0xFF <<  8) // (TWI) Clock
High Divider
#define AT91C_TWI_CKDIV       ((unsigned int) 0x7 << 16) // (TWI) Clock
Divider
// -------- TWI_SR : (TWI Offset: 0x20) TWI Status Register -------- 
#define AT91C_TWI_TXCOMP      ((unsigned int) 0x1 <<  0) // (TWI)
Transmission Completed
#define AT91C_TWI_RXRDY       ((unsigned int) 0x1 <<  1) // (TWI) Receive
holding register ReaDY
#define AT91C_TWI_TXRDY       ((unsigned int) 0x1 <<  2) // (TWI) Transmit
holding register ReaDY
#define AT91C_TWI_OVRE        ((unsigned int) 0x1 <<  6) // (TWI) Overrun
Error
#define AT91C_TWI_UNRE        ((unsigned int) 0x1 <<  7) // (TWI) Underrun
Error
#define AT91C_TWI_NACK        ((unsigned int) 0x1 <<  8) // (TWI) Not
Acknowledged
// -------- TWI_IER : (TWI Offset: 0x24) TWI Interrupt Enable Register
-------- 
// -------- TWI_IDR : (TWI Offset: 0x28) TWI Interrupt Disable Register
-------- 
// -------- TWI_IMR : (TWI Offset: 0x2c) TWI Interrupt Mask Register
-------- 

#define ERROR (AT91C_TWI_NACK) 
#define LOCKED	0x01
#define UNLOCKED	0x00

int at91_i2c_init(void);

#endif 



24xx128.c :

#define TWI_PIO_ASR PIOA_ASR
#define TWI_PIO_PDR PIOA_PDR
#define TWI_PIO_MDER PIOA_MDER

#define TWI_TWD  PA10_TWD_A
#define TWI_TWCK PA11_TWCK_A

static HANDLE twi_semaphore;

static void twi_lock (void) {
  NutEventWait(&twi_semaphore, 0);
} 

static void twi_free (void) {
  NutEventPost(&twi_semaphore);
} 

static void twi_semaphore_init (void) {
  NutEventPost(&twi_semaphore);
} 


/*!
 * \brief Initialize TWI interface.
 */
int at91_i2c_init(void)
{
    u_long speed = 400000;
	int sclock;


    outr(TWI_PIO_ASR, _BV(TWI_TWD) | _BV(TWI_TWCK));  // Set TWD and TWCK as
peripheral line
    outr(TWI_PIO_PDR, _BV(TWI_TWD) | _BV(TWI_TWCK));  // Let periperal
control the PIO lines
    
    outr(TWI_PIO_MDER, _BV(TWI_TWD) | _BV(TWI_TWCK)); // Enabled OpenDrain
output on both lines
    
    outr(PMC_PCER, _BV(TWI_ID));              // Enable TWI clock in PMC
    
    outr(TWI_IDR, 0xFFFFFFFF);                // Disable all interrupts 
    outr(TWI_CR, TWI_SWRST);                  // Reset bus
    outr(TWI_CR, TWI_MSEN | TWI_SVDIS);       // Enable master mode
    
	/* Here, CKDIV = 1 and CHDIV=CLDIV  ==> CLDIV = CHDIV =
1/4*((Fmclk/FTWI) -6)*/
	sclock = (10*NutGetCpuClock() / speed);
	if (sclock % 10 >= 5)
		sclock = (sclock /10) - 5;
	else
		sclock = (sclock /10)- 6;
	sclock = (sclock + (4 - sclock %4)) >> 2;	// div 4

    outr(TWI_CWGR,  ( 1<<16 ) | (sclock << 8) | sclock ) ;

	// Init the semaphore for locking twi device
	twi_semaphore_init();

    return 0;
}



//*-------------------------------------------------------------------------
---
//* \fn    AT91F_TWI_WriteByte
//* \brief Send a byte to a slave device
//*-------------------------------------------------------------------------
---
static int AT91F_TWI_WriteByte(int mode, int int_address, char *data2send,
int nb)
{
	unsigned int status,counter=0,error=0;

	// Set TWI Internal Address Register
	if ((mode & AT91C_TWI_IADRSZ) != 0) outr(TWI_IADRR, int_address);

	// Set the TWI Master Mode Register
    outr(TWI_MMR, mode & ~AT91C_TWI_MREAD);
    
	if( nb < 2 ) {

		outr(TWI_CR, AT91C_TWI_START | AT91C_TWI_MSEN |
AT91C_TWI_STOP);
		outb(TWI_THR, *data2send);

	} 	else {
	// Set the TWI Master Mode Register
	  for(counter=0;counter<nb;counter++){
          outr(TWI_CR, AT91C_TWI_START | AT91C_TWI_MSEN);
          if (counter == (nb - 1)) outr(TWI_CR, AT91C_TWI_STOP);
          status = inr(TWI_SR);
          if ((status & ERROR) == ERROR) error++;
          while (!(status & AT91C_TWI_TXRDY)){
               status =inr(TWI_SR);
               if ((status & ERROR) == ERROR) error++;
          }
          outb(TWI_THR, *(data2send+counter));
	   }
	}
	status = inr(TWI_SR);
	if ((status & ERROR) == ERROR) error++;
	
	while (!(status & AT91C_TWI_TXCOMP)){
    		status = inr(TWI_SR);
    		if ((status & ERROR) == ERROR) error++;
    }
	return error;
}



//*-------------------------------------------------------------------------
---
//* \fn    AT91F_TWI_ReadByte
//* \brief Read a byte from a slave device
//*-------------------------------------------------------------------------
---
static int AT91F_TWI_ReadByte( int mode, int int_address, char *data, int
nb)
{
	unsigned int status,counter=0,error=0;

	// Set TWI Internal Address Register
	if ((mode & AT91C_TWI_IADRSZ) != 0) outr(TWI_IADRR, int_address);

	// Set the TWI Master Mode Register
	outr(TWI_MMR, mode | AT91C_TWI_MREAD);

	// Start transfer
	if (nb == 1){
	   outr(TWI_CR, AT91C_TWI_START | AT91C_TWI_STOP );
	   status = inr(TWI_SR);
    	   if ((status & ERROR) == ERROR) error++;
	   while (!(status & AT91C_TWI_TXCOMP)){
    	      status = inr(TWI_SR);
              if ((status & ERROR) == ERROR) error++;
    	   }
	   *(data) = inb(TWI_RHR);
	}
 	else{
 	   outr(TWI_CR, AT91C_TWI_START | AT91C_TWI_MSEN);
	   status =  inr(TWI_SR);
	   if ((status & ERROR) == ERROR) error++;

	// Wait transfer is finished
           while (!(status & AT91C_TWI_TXCOMP)){
   		status =  inr(TWI_SR);
   		if ((status & ERROR )== ERROR) error++;
    		if(status & AT91C_TWI_RXRDY){
			*(data+counter++) = inb(TWI_RHR);
			if (counter == (nb - 1)) outr(TWI_CR,
AT91C_TWI_STOP);
		}
	   }
	}
	return error;
}


example read:
	for ( i=0; i< 8; i++ ) {
		AT91F_TWI_ReadByte(AT91C_EEPROM_I2C_ADDRESS |
AT91C_TWI_IADRSZ_2_BYTE, i, &data, 1);
	}


example write:
	for ( i=0; i< 8; i++ ) {
		data =  0xAA;
		AT91F_TWI_WriteByte(AT91C_EEPROM_I2C_ADDRESS |
AT91C_TWI_IADRSZ_2_BYTE, i, &data, 1);
		NutSleep(5);
	}


remember to use 	twi_lock() and twi_unlock() !

Andras

> -----Original Message-----
> From: en-nut-discussion-bounces at egnite.de 
> [mailto:en-nut-discussion-bounces at egnite.de] On Behalf Of Ole 
> Reinhardt
> Sent: Tuesday, May 27, 2008 1:25 PM
> To: Ethernut User Chat (English)
> Subject: Re: [En-Nut-Discussion]SAM7X256-EK with TWI (24C65 
> or active Slaves) / polling "NutTcpAccept" / timer interrupt
> 
> Hi!
> 
> > As I am no specialist I am looking for any samples (TWI and 
> others) .
> 
> TWI is currently expected to be broken for SAM7x. I'll track 
> down this problem the next days. The driver is not working 
> correctly at the moment.
> 
> So far please consider to use the bitbanging twi driver.
> 
> Regards,
> 
> Ole Reinhardt
> 
> 
> --
>  _____________________________________________________________
> |                                                             |
> | Embedded-IT          Hard- und Softwarelösungen             |
> |                                                             |
> | Ole Reinhardt        Tel. / Fax:        +49 (0)271  7420433 |
> | Luisenstraße 29      Mobil:             +49 (0)177  7420433 |
> | 57076 Siegen         eMail:    ole.reinhardt at embedded-it.de |
> | Germany              Web:         http://www.embedded-it.de |
> |                      UstID / VAT:       DE198944716         |
> |_____________________________________________________________|
> 
> _______________________________________________
> http://lists.egnite.de/mailman/listinfo/en-nut-discussion
> 


----
Kometa 99 Élelmiszeripari ZRt.
Székhely: 7400 Kaposvár, Pécsi u. 67-69., Levelezési cím: 7401 Kaposvár, Pf. 58
Cégszám: Somogy Megyei Bíróság mint Cégbíróság 14-10-300239
Adószám: 13749619-2-44
Telefon: 82/502-400, Fax: 82/502-415
http://www.kometa.hu
http://www.kemencessult.hu




More information about the En-Nut-Discussion mailing list