EmbeddedRelated.com
Forums
Memfault Beyond the Launch

Procyon Library for Atmel AVR MCU - I²C problems

Started by Unknown July 30, 2008
Hello!

I am new to programming and am struck with the Manual for the Procyon
Library for Atmel's ATMega MCUs. It basically provides functions for all
the interfaces and functions available on the Atmel MCUs.

Problem is as follows:
I have a Thermopile array sensor - TPA81 ( 
http://www.robot-electronics.co.uk/htm/tpa81tech.htm ) - which should be
connected to a Mega32 MCU (
http://www.atmel.com/dyn/Products/Product_card.asp?part_id=2014 ) by it's
I�C interface, using the Procyon Library (
http://hubbard.engr.scu.edu/embedded/ )

The incoming data should be written out, amongst other things, over the
serial port of the ATMEGA32. 
Writing to the UART and receiving on the PC works flawless.

But there is no data in the receiving array.

Here is my code collecting the I�C data:
// BEGIN read TPA81
volatile uint8_t tpa81data[9] = {0,0,0,0,0,0,0,0,0}; // globally readable
variable
#define WRITE_TPA81_ADDRESS  0xD0
#define READ_TPA81_ADDRESS  0xD1
void tpa81_read(void)
{
  int8_t looper = 8;
  while (looper >= 0)
  {
    //i2cSendStop; // Terminate pending transmissions
    i2cSendStart(); // Initiate I�C transmission
    i2cSendByte(WRITE_TPA81_ADDRESS); //Send Target Address
    //i2cSendStart(); // Initiate next I�C transmission
    i2cSendByte(looper); // Send Target Register
    //i2cSendStart(); // Initiate next I�C transmission
    i2cReceiveByte(FALSE); // Receive answer from Target
    tpa81data[looper] = i2cGetReceivedByte(); // Write answer from Target
into Array
    i2cSendStop(); // finish transmission
    looper--; // decrease counter and array-index
  }
}
// END read TPA81

I guess I have a conceptual error in understanding the I�C Protocol and / or
utilizing the Procyon Library.
The program compiles without problems under avr-gcc.

Any sggestions and hints welcome!

R=FCdiger Leibrandt wrote:

> Hello! >=20 > I am new to programming and am struck with the Manual for the Procyon > Library for Atmel's ATMega MCUs. It basically provides functions for al=
l
> the interfaces and functions available on the Atmel MCUs.
[...]
> I guess I have a conceptual error in understanding the I=B2C Protocol a=
nd / or
> utilizing the Procyon Library.
The conceptual error is in multiplying the entities beyond the necessity. For something as simple as AVR (tm), you don't need any=20 libraries, and the only manual required is the AVR datasheet. All it=20 takes to run I2C is to program a couple of registers.
> The program compiles without problems under avr-gcc. > Any sggestions and hints welcome!
As simple as that: static void I2C_WaitDone(void) { while(!(TWCR&0x80)); } static void I2C_Stop(void) { TWCR =3D 0x94; while(TWCR&0x10); } static void I2C_Start(void) { TWCR =3D 0xA4; I2C_WaitDone(); } static void I2C_Transmit_Byte(u8 byte) { TWDR =3D byte; TWCR =3D 0x84; I2C_WaitDone(); } //=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D void I2C_Action(u8 address, u8 *data, u8 length) { u8 ci; I2C_Start(); I2C_Transmit_Byte(address); if(address & 0x01) // I2C read { for(ci =3D 0; ci < length; ci++) { if(ci < (length - 1)) TWCR =3D 0xC4; // Confirm byte with ACK else TWCR =3D 0x84; // Last byte - send NAK I2C_WaitDone(); data[ci] =3D TWDR; } } else // I2C write { for(ci =3D 0; ci < length; ci++) I2C_Transmit_Byte(data[ci]); } I2C_Stop(); } //---------------------------------- Vladimir Vassilevsky DSP and Mixed Signal Design Consultant http://www.abvolt.com
First of all: Thank you for the code!

The reason why I use the Procyon-Library is because I shall use it - for
following projects will use more and more of it's functions - and it's
deemend unnecessary that I - literally - re-invent the wheel with all the
functions that will be needed with future projects.

On my own feet I got as far as being able to sample analog values and check
input-pins, write those values out over the serial port, recieve them on
another MCU, and reproduce the digital states on GPIO-pins, the analog
states on generic Servos - and I got to admit I still don't understand the
Interrupt-Routine for real, it just works.

I'll first of all will use your code to check that the sensor is working -
and then I'll dig into the I2C libraries of the procyon-libraries and try
to compare and understand what is happening.

One thing I don't understand for example is why, when I want to transmit a
single databyte, I have to use a pointer instead of the actual variable, or
even if I want to read data fro man array I have to use a pointer instead
of simply incrementing through the arrays field.

I learned programming on TI Basic, but the modern Basic dialects are stuffed
with functions doing honors to assembly language and C, so it was decided
that the time to learn using C to be "future-proof" would be more worthy
than trying to learn either Assembly or one of the other more recent Basic
Languages and Dialects.

*sighs*

Anyway.
I'll try your code tomorrow to see if the sensor is talking with me, and
then I'll hook up the osscilloscope and the analyzer and compare what the
two programs are doing differently.

Thank you very much so far.


Vladimir Vassilevsky wrote:

> > > R&#4294967295;diger Leibrandt wrote: > >> Hello! >> >> I am new to programming and am struck with the Manual for the Procyon >> Library for Atmel's ATMega MCUs. It basically provides functions for all >> the interfaces and functions available on the Atmel MCUs. > > [...] > > >> I guess I have a conceptual error in understanding the I&#4294967295;C Protocol and / >> or utilizing the Procyon Library. > > The conceptual error is in multiplying the entities beyond the > necessity. For something as simple as AVR (tm), you don't need any > libraries, and the only manual required is the AVR datasheet. All it > takes to run I2C is to program a couple of registers. > >> The program compiles without problems under avr-gcc. >> Any sggestions and hints welcome! > > As simple as that: > > static void I2C_WaitDone(void) > { > while(!(TWCR&0x80)); > } > > static void I2C_Stop(void) > { > TWCR = 0x94; > while(TWCR&0x10); > } > > static void I2C_Start(void) > { > TWCR = 0xA4; > I2C_WaitDone(); > } > > static void I2C_Transmit_Byte(u8 byte) > { > TWDR = byte; > TWCR = 0x84; > I2C_WaitDone(); > } > > > //======================= > > void I2C_Action(u8 address, u8 *data, u8 length) > { > u8 ci; > > I2C_Start(); > I2C_Transmit_Byte(address); > > if(address & 0x01) // I2C read > { > for(ci = 0; ci < length; ci++) > { > if(ci < (length - 1)) TWCR = 0xC4; // Confirm byte with ACK > else TWCR = 0x84; // Last byte - send NAK > I2C_WaitDone(); > data[ci] = TWDR; > } > } > else // I2C write > { > for(ci = 0; ci < length; ci++) I2C_Transmit_Byte(data[ci]); > } > > I2C_Stop(); > } > > //---------------------------------- > > Vladimir Vassilevsky > DSP and Mixed Signal Design Consultant > http://www.abvolt.com
-- Sincerely Ruediger

R=FCdiger wrote:

> First of all: Thank you for the code!
Your "thank you" is very valuable. You don't have to thank; the check=20 for $100 will be just all right for many cases.
> The reason why I use the Procyon-Library is because I shall use it - fo=
r
> following projects will use more and more of it's functions - and it's > deemend unnecessary that I - literally - re-invent the wheel with all t=
he
> functions that will be needed with future projects.
A very naive idea. Nothing will work properly unless you understand the=20 hardware in the every detail. Othewise you will be fighting with the=20 strange problems at all time. AVR is the simplest CPU; it doesn't take=20 much effort do to whatever can be done with it.
> I'll first of all will use your code to check that the sensor is workin=
g -
> and then I'll dig into the I2C libraries of the procyon-libraries and t=
ry
> to compare and understand what is happening.
First of all you should open the AVR datasheet and read the chapter=20 about the I2C interface.
> One thing I don't understand for example is why, when I want to transmi=
t a
> single databyte, I have to use a pointer instead of the actual variable=
, or
> even if I want to read data fro man array I have to use a pointer inste=
ad
> of simply incrementing through the arrays field.
Read the manual.
> I learned programming on TI Basic,
Basic is worseless. It is a dead end. Learn C/C++.
> I'll try your code tomorrow
Why waiting till tomorrow?
> to see if the sensor is talking with me,
If the sensor talks to you, you'd better check with a doctor.
> and > then I'll hook up the osscilloscope and the analyzer and compare what t=
he
> two programs are doing differently.
Read the manual. Vladimir Vassilevsky DSP and Mixed Signal Design Consultant http://www.abvolt.com

Memfault Beyond the Launch