Higher-Level I2C/TWI Library, Non-GPL?

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

I'm strongly considering into dropping the few remains of the Arduino framework I use and moving to "bare" Atmel avr-g++ development.

 

While working with "raw" TWI commands doesn't scare me for "happy path", there are enough wonky chips out there and enough strange things that happen with I2C in the real world where a library that has some robustness to them would be appreciated.

 

I've seen several positive references to the work of Fleury in this area, but a GPL license is a non-starter for me. There are some LGPL alternatives out there, but that license still has "lesser" challenges.

 

I only need bus-master functionality in a single-master environment. Some of the devices I interface with require "repeated start", so that is an essential. "Nine-clock" bus reset would be nice, but I suspect it's easy enough to code up at the TWI level. 

 

Any recommendations of what to look into other than Fleury's work?

Last Edited: Tue. Nov 6, 2018 - 10:42 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well, I wrote my own as a learning experience, but My guess is that almost everybody will point you back in the direction of the Fleurylibs.

 

I do know that there is an atmel appnote  on how to use the TWI interface as a master complete with example code, cannot recall its number and even if I would might well be the Microchip has changed it. Best is to have a look.

 

do not think I have read other real alternatives.

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

Not suggesting you plagiarize Fleury's work but I would spend some time reading it to understand the exact sequence in which you need to do stuff (also armed with datasheet alongside) then go and sit in a "clean room" and see if you can implement something similar.

 

Another option is to do the same with Arduino's Wire.h/Wire.cpp (it is LGPL in fact)

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

Hi @jeffsf,

 

I'm apologizing in advance for shamelessly promoting my own stuff. Here is my version (with a MIT license):

https://piconomix.com/fwlib/grou...

 

Do you like the API? You can try it out risk-free on an Arduino Uno:

https://piconomix.com/fwlib/_a_r...

 

The whole library is hosted here:

https://github.com/piconomix/pic...

 

I've ported it to AVR and STM32L0 (work in progress).

 

Regards,

Pieter

https://piconomix.com/contact

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

I2C is not very difficult. Just some commands such as start, restart, read, write, stop and ack/nack. That's all. Everything else depends on the chip that you are talking to.

extronic.pl

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

I2C is very easy.  Just read Fleury code and compare with datasheet.

 

Then go to a darkened room and write "your own" code.    It is then technically "your own work".

 

As a silly question,   if you use printf() from the C library,  you don't have to publish the source code to a compiled binary.

Likewise there are many things that are not patentable or copyrightable e.g. me typing on this keyboard or me making a cup of tea.

 

David.

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

I'm slightly confused about what the OP wants. In the topic title he says 'higher-level'. That to me says they are looking for Arduino style libraries which are dedicated to one specific chip rather than raw drivers like Fleury.

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

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

I am likewise confused.    Fleury does not seem to have any copyright or GPL conditions.

 

He simply acknowledges that his ASM code was derived / inspired from AVR300 application note.

 

It is only polite to say that you have used Fleury's code.    I don't think that there is any obligation.

 

David.

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

david.prentice wrote:
if you use printf() from the C library,  you don't have to publish the source code to a compiled binary.
Don't know about other libraries but when you contribute to AVR-LibC there is a stipulation that you must agree to assign a liberal FreeBSD licence to it that allows re-use. I presume that applied equally to the man who wrote vfprintf()?

 

EDIT: actually it's interesting what line 12 says in this:

 

http://svn.savannah.gnu.org/view...

 

12	   * Redistributions in binary form must reproduce the above copyright
13	     notice, this list of conditions and the following disclaimer in
14	     the documentation and/or other materials provided with the
15	     distribution.

Wonder how many people building AVR programs that include use of printf() actually know about this requirement?

Last Edited: Wed. Nov 7, 2018 - 04:06 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for the suggestions around looking at Fleury's work. No doubt it is well though out and robust based on the respect that it receives here. Unfortunately, as soon as you look at GPL code deeply enough to understand the flow, you are more than likely going to end up creating a Derivative Work, which is then covered by GPL. Looking at LGPL source code similarly has the same implications. 

 

I agree that the I2C protocol is very straightforward and, from what I've seen from the TWI app note and example code, is well implemented at the primitive-operation level by Atmel.

 

I'm not looking for specific device "drivers", as I write those myself for the client devices that I use.
 

It is that handling the "unhappy paths" when a device doesn't respond as expected requires running into them at least once. Timeouts are reasonably straightforward to imagine, but as outlined in the top paragraph, keeping code unencumbered by GPL/LGPL makes reading another's so-licensed work to determine the cases covered unwise.

 

Yes, as @clawson points out, distribution of a work that includes or is a derivative work of copyrighted code has obligations associated with it, depending on the all the licenses involved; GPL, LGPL, MIT, BSD, Eclipse, Apache, .... It's not just printf(), but anyone using the LGPL-licensed Arduino framework in a static-linked binary has obligations to, as I understand it, make at least re-linkable object code available for the entire project

Last Edited: Wed. Nov 7, 2018 - 08:50 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Fleury says his code is based upon AVR300 so shouldn't his work inherit whatever license that is issued under?

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

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

Or, in other words, does it really matter?

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

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

Here is some simple non-interrupt TWI code, enjoy!

 Header

// **************************************************************
// ***  I2C_ROUTINES HEADER FILE ******** 		
// **************************************************************

#define	 START				0x08
#define  REPEAT_START		0x10
#define  MT_SLA_ACK			0x18
#define  MT_SLA_NACK		0x20
#define  MT_DATA_ACK		0x28
#define  MT_DATA_NACK		0x30
#define  MR_SLA_ACK			0x40
#define  MR_SLA_NACK		0x48
#define  MR_DATA_ACK		0x50
#define  MR_DATA_NACK		0x58
#define  ARB_LOST			0x38

#define  ERROR_CODE			0x7e
	
#define  DS1307_W			0xd0
#define  DS1307_R			0xd1
#define  EEPROM_W			0xa0
#define  EEPROM_R			0xa1


unsigned char i2c_start(void);
unsigned char i2c_repeatStart(void);
unsigned char i2c_sendAddress(unsigned char);
unsigned char i2c_sendData(unsigned char);
unsigned char i2c_receiveData_ACK(void);
unsigned char i2c_receiveData_NACK(void);
void i2c_stop(void);

functions



#include <avr/io.h>
#include "i2c_routines.h"
#include "UART_routines.h"

//*************************************************
//Function to start i2c communication
//*************************************************
unsigned char i2c_start(void)
{
 
	TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); 	//Send START condition
	
    while (!(TWCR & (1<<TWINT)));   		//Wait for TWINT flag set. This indicates that the
		  								//START condition has been transmitted
    if ((TWSR & 0xF8) == START)			//Check value of TWI Status Register
 	   return(0);
	else
	   return(1);
}

//*************************************************
//Function for repeat start condition
//*************************************************
unsigned char i2c_repeatStart(void)
{
 
    TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); 		//Send START condition
    while (!(TWCR & (1<<TWINT)));   		//Wait for TWINT flag set. This indicates that the
		  								//START condition has been transmitted
    if ((TWSR & 0xF8) == REPEAT_START)			//Check value of TWI Status Register
 	   return(0);
	else
	   return(1);
}
//**************************************************
//Function to transmit address of the slave
//*************************************************
unsigned char i2c_sendAddress(unsigned char address)
{
   unsigned char STATUS;
   
   if((address & 0x01) == 0) 
     STATUS = MT_SLA_ACK;
   else
     STATUS = MR_SLA_ACK; 
   
   TWDR = address; 
   TWCR = (1<<TWINT)|(1<<TWEN);	   //Load SLA_W into TWDR Register. Clear TWINT bit
   		  			 				   //in TWCR to start transmission of address
   while (!(TWCR & (1<<TWINT)));	   //Wait for TWINT flag set. This indicates that the
   		 		   					   //SLA+W has been transmitted, and
									   //ACK/NACK has been received.
   if ((TWSR & 0xF8) == STATUS)	   //Check value of TWI Status Register
   	  return(0);
   else 
      return(1);
}

Enjoy!  No guarantees for suitability!

 

Jim 

 

 

Click Link: Get Free Stock: Retire early!

share.robinhood.com/jamesc3274

 

 

 

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

Brian Fairchild wrote:
Fleury says his code is based upon AVR300 so shouldn't his work inherit whatever license that is issued under?

 

http://homepage.hispeed.ch/peter...

Copyright

(C) 2015 Peter Fleury, GNU General Public License Version 3

 

Thanks @ki0bk, I'll look through what you've got Jim -- Congrats on 20 WPM, not many can claim that these days!