I2C Library Problems with ATtiny817

Go To Last Post
57 posts / 0 new

Pages

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

Regular international mail is fine. I was surprised to hear you say DHL when El Tangas's photos show regular mail.
.
It will be interesting to see how you get on with the UPDI and mEDBG chip.
And of course the new features of the Tiny817.
.
David.

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

I was surprised to hear you say DHL

I'm getting something else trough DHL so I ASS_U_MEd that the board was in the same package.

 

So the UPDI clock defaults to 100KHz and the main clock at 20MHz. I'm not messing around with those until I understand a lot more.

 

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

Hello, 

 

I try to implement I2C routine on Attiny 817 Xplained mini for reading T° on LM75A device and I would like to share it once it will be fully functional!

First I looked at I2C blocks available on atmel start, but they are so complex and twisted!

So here is my code.

The problem is that the read with Ack or Nack doesn't seem to work. I receive twice the same value (never the second byte from LM75A).

Perhaps it misses a test to check that the previous operation is done?

Any idea and suggestion is welcome!

 

 

#define F_CPU 20000000UL

#include <util/delay.h>

#include <stdlib.h>

 

/* -------------------------------------------------------*/

 

#define TWI0_BAUD(F_SCL)      ((((float)F_CPU / (float)F_SCL)) - 10 )

#define LM75A_ADDRESS_W 0b10010000

#define LM75A_ADDRESS_R 0b10010001

#define LM75A_TEMP_REGISTER 0x00

 

void TWI_init()

{

TWI0.MBAUD = (uint8_t)TWI0_BAUD(100000);                          // set MBAUD register for 100kHz

TWI0.MSTATUS |= (0x1);                                                         //Force TWI state machine into IDLE state

TWI0.MCTRLA = 1 << TWI_ENABLE_bp                                    /* Enable TWI Master: enabled */

| 1 << TWI_QCEN_bp                                                             /* Quick Command Enable: enabled */

| 0 << TWI_RIEN_bp                                                              /* Read Interrupt Enable: disabled */

| 0 << TWI_SMEN_bp                                                             /* Smart Mode Enable: disabled */

| TWI_TIMEOUT_DISABLED_gc                                                /* Bus Timeout Disabled */

| 0 << TWI_WIEN_bp;                                                            /* Write Interrupt Enable: disabled */

}

 

void TWI_start(uint8_t slaveAddr)

{

TWI0.MADDR = slaveAddr;                                                    //Create TWI start condition by loading slave address into MADDR register

}

 

uint8_t TWI_read(uint8_t ACK)                                             // ACK=1 send ACK ; ACK=0 send NACK 

{

if (ACK) TWI0.MCTRLB &= ~(1<<TWI_ACKACT_bp);              //  si ACK=1 mise à 0 ACKACT => send ACK

else  TWI0.MCTRLB |= (1<<TWI_ACKACT_bp);                     //  sinon (ACK=0) => mise à 1 ACKACT => send NACK 

return TWI0.MDATA ;                                                          // lecture du registre MDATA et envoi de l'action définie par ACKACT

}

 

void TWI_WRITE(uint8_t write_data)

{

TWI0.MDATA = write_data;                                                 //Transfer write_data into MDATA register

}

 

void TWI_STOP(void)

{

TWI0.MCTRLB |= (1<<TWI_ACKACT_bp);                           // Set acknowledge action to NACK

TWI0.MCTRLB |= (TWI_MCMD_gm);                                   //Triggers Master to execute acknowledge action (NACK), succeeded by issuing STOP condition

}

 

TWI_init();

uint8_t tempHigh;

uint8_t tempLow;

 

while (1)

{

_delay_ms(200);

PORTC_OUTTGL = (1<<PIN0_bp);

TWI_start(LM75A_ADDRESS_R);

tempHigh = TWI_read(1);                    // read avec ack

tempLow = TWI_read(0);                    // read avec nack

TWI_STOP();

 

utoa (tempHigh, buffer, 10);

printString(buffer);

printString("/");

utoa (tempLow, buffer, 10);

printString(buffer);

printString(" ");

}

Attachment(s): 

 main.c

 terminal out.jpg

 IMG_0543.JPG

Attachment(s): 

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

The nice thing about I2C protocol is, it will tell you when something goes wrong, but you wrote all of your I2C functions with void return values!!!  So it throws away any chance to do that!

Re-write your I2C functions to return the twi status register value and test it for correctness (expected value) and you will do much better.

Take some time to study what others have successfully done, ask questions if you need help understanding why they did it the way they did.

 

Jim

 

Edit: Please use the "<>" button to post code to preserve correct spacing!

Last Edited: Thu. Oct 12, 2017 - 07:10 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks Jim,

 

here is the list of functions :

 

void TWI_init();
void TWI_start(uint8_t slaveAddr);
uint8_t TWI_read(uint8_t ACK);
void TWI_WRITE(uint8_t write_data);
void TWI_STOP(void);

 

the read function returns an uint8_t value read from MDATA

I don't need values back from other function (init, start; write, stop).

 

So I don't think it's the problem.

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

Really, how do you know you got an ACK to your start(address)?  A very common failure seen here by Freaks!

 

Jim

 

Pages