[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