TWI ATxmega192A3

Go To Last Post
4 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hallo!

I have a problem with TWI. I poll PCF8535 (watch) over TWI. First poll of chip clock is ok. But next polls unsuccessful. The TWIE.MASTER.STATUS register tells that the bus is BUSY. What is wrong? Please, tell me what i do wrong. Thanks. Here is my code:


char TWI_recieve(unsigned char add_sl, unsigned char add_byte )
{
char temp_data;

if (!RESET) asm("wdr");
TWIE.MASTER.STATUS = TWI_MASTER_BUSSTATE_IDLE_gc;
Delay(15);
if (!RESET) asm("wdr"); putchar_s(TWIE.MASTER.STATUS);
TWIE.MASTER.ADDR=add_sl;
while (!(TWIE.MASTER.STATUS & TWI_MASTER_WIF_bm)) if (!RESET) asm("wdr");
if (!RESET) asm("wdr"); putchar_s(TWIE.MASTER.STATUS);
TWIE.MASTER.DATA=add_byte;
while (!(TWIE.MASTER.STATUS & TWI_MASTER_WIF_bm)) if (!RESET) asm("wdr");

if (!RESET) asm("wdr"); putchar_s(TWIE.MASTER.STATUS);
TWIE.MASTER.ADDR=add_sl|1;
Delay(3);
putchar_s(TWIE.MASTER.STATUS);
while ((!(TWIE.MASTER.STATUS & TWI_MASTER_RIF_bm))
&&(!(TWIE.MASTER.STATUS & TWI_MASTER_ARBLOST_bm))
&&(!(TWIE.MASTER.STATUS & TWI_MASTER_BUSERR_bm)))
if (!RESET) asm("wdr");

if (!RESET) asm("wdr");
putchar_s(TWIE.MASTER.STATUS);
temp_data=TWIE.MASTER.DATA; putchar_s(TWIE.MASTER.STATUS);
TWIC.MASTER.CTRLC = TWI_MASTER_ACKACT_bm | TWI_MASTER_CMD_STOP_gc;
Delay(15);
putchar_s(TWIE.MASTER.STATUS);
return temp_data;
} 

The value of external resistors 7800 Om. he frequency that is determined by the TWIE.MASTER.BAUD register is equal to 92160 Hz.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Has anybody the same problem?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
//First You read data from data register

temp_data=TWIE.MASTER.DATA; putchar_s(TWIE.MASTER.STATUS);

//and _THEN_ you set action that must be performed on
//such read (_after_ actual reading).

TWIC.MASTER.CTRLC = TWI_MASTER_ACKACT_bm | TWI_MASTER_CMD_STOP_gc; 

It seems to me that there is something wrong with command order.
(Btw, MASTER_ACKACT works only if Smart Mode is enabled. It's not mentioned in your code sample.)
Try to paid attention to command order shown above. I.e. try to set action before actual reading, or don't use smart mode at all (and ACKACT too), but send MASTER_CMD_STOP manually at finish. It's strobe, and is applied immediately.
Hope this will help.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Also note that setting desired status has sense only from unknown bus state at the first TWI enabling.

TWIE.MASTER.STATUS = TWI_MASTER_BUSSTATE_IDLE_gc;

It's better to wait for Idle status before any TWI operation instead, and move the shown command to the first TWI init code to run it once after enabling TWI. Also it's handy to setup Timeout (CTRLB) to automatically set Idle state if bus is not busy.

Getting busy bus after transaction shows no stop marker sent, generally.