ASF Configuring wrong port pins Mega32 for an I2C project

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

Help!

 

My very simple ASF program for Mega32 is configuring the wrong registers when using ioport_set_pin  /set_dir

  
#define I2C_SDA		IOPORT_CREATE_PIN(PORTC, 1)
#define I2C_CLK		IOPORT_CREATE_PIN(PORTC, 0)
  
        a= I2C_CLK;  // to check value
        b= IOPORT_DIR_OUTPUT; // to check value 
         ioport_set_pin_dir(I2C_CLK, IOPORT_DIR_OUTPUT);
         ioport_set_pin_dir(I2C_SDA, IOPORT_DIR_OUTPUT);

 

Instead of PORTC, direction register at 0x34, it's hitting the ADMUX at Register address 0x27

i.e. the disassembled code shows the instruction sbi 0x07,0  which I assume gets the register offset added automatically.

I think it should be sbi 0x14,0

I've added local variables a and b to see the definitions before it gets to do anything. I2C_CLK is fixed at 0x10.

I'm a bit stumped because it was a Studio generated ASF program ( on a user defined board ).

I've attached the whole project in case anyone feels inclined .. it's got I2C drivers for TSL2561 in it.. but of course I can't get that far because the port pins dont even get set up correctly.

 

 

		a= I2C_CLK;
0000018C  LDI R24,0x10		Load immediate 
0000018D  STS 0x006D,R24		Store direct to data space 
		b= IOPORT_DIR_OUTPUT;
0000018F  LDI R24,0x01		Load immediate 
00000190  STS 0x006C,R24		Store direct to data space 
--- C:\Users\Rob\Dropbox\AVR\Studio 7\../../src/ASF/common/services/ioport/mega/ioport.h 
		base->DIR |= arch_ioport_pin_to_mask(pin);
00000192  SBI 0x07,0		Set bit in I/O register 
00000193  SBI 0x07,1		Set bit in I/O register 
			= (base_add->PORTDATA  | arch_ioport_pin_to_mask
00000194  SBI 0x08,0		Set bit in I/O register 
00000195  SBI 0x08,1		Set bit in I/O register 

 

 

 

Attachment(s): 

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

I am utterly gobsmacked.   I have never seen anything quite so convoluted as your ASF code.

 

I built your project.   Ran the Simulator to a breakpoint at i2c_master_init().

 

It clears bits 0, 1 of the Analog Comparator ACSR !!!

 

I have no idea what a TSL2561 is.   But I bet that I could write readable code for it.

Incidentally,  you do not need to set up I2C pins at all.   The TWI peripheral looks after them.

 

Ok,  some of the old Atmel App Notes were not perfect.   But at least you could follow what was going on.   e.g. simple file stucture.

 

David.

Last Edited: Tue. Jan 3, 2017 - 04:46 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ahh.. you need to ignore the TSL driver -- that's certainly a hogs wash of imported code and various trials simply because accessing the chip was totally unreliable. The issue for me is that the initialisiation of the IO pins doesn't work correctly, and that's only executing the basic startup.

 

The PORTC direction doesnt get set - instead it sets the bis in ADMUX...

The project was created entirely automatically from Studio 7  and I added just the I2C and TSL drivers.... 

 

Personally I hate ASF, but felt it might be a way to try to resolve my original chip access problem ..  however, it's gone from bad to worse.

 

Last Edited: Tue. Jan 3, 2017 - 04:56 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What do you want to do?

 

A polled I2C Master works just fine in many apps.   e.g. Fleury.

An interrupt driven I2C Master from AVR315 App Note works fine too.

 

Likewise,  CodeVision,  Arduino, ... all provide interrupt driven I2C.   Both Master and Slave.

I am sure that you would find any of these libraries easier to use.

 

Mind you,   I had always assumed that ASF might be convoluted but at least it should work.

Are you sure that you have not told it something silly?

 

I have built and run 3 or 4 Start example projects as provided for Atmel Evaluation kits.

I have never tried to create a "custom board".    It is bad enough trying to follow what the examples do.

 

David.

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

The story so far is typical of those... must be doing something stupid projects. The chip is a light sensor, tried fleury, tried bit banging, tried importing arduino libraries. None reliable, so resorted to a fresh project rather than adding the task to an existing job. Thinking ASF might have a driver... nope. Update Avr7 .. plagued with the dreaded registry unintelligible issues. Days spent getting this far only to find this new ASF project didn't even set the DDR register. 9 (Original post issue). I'm now back to a flat structure..... using yet someone else's 'proven' driver.... well, you know how it is sometimes. I've moved on from worrying about the ASF DDR register problem although knowing why it wasn't correct would be educational. Time to stop for today..

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

Go on.   You have no need to write to any DDR registers.

 

The TSL2561 has only got 16 registers.   One IRQ pin.

I bet that your biggest problem is using the correct Slave Address pair.   e.g 0x52/0x53 (W/R)

 

You don't have massive amounts of data.   So speed or efficiency is not important.

 

David.

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

It's not that David. It has been working, the Lux level changing and the correct values read back from the registers. The problem is that it seemed only to work when the I2C clock was ridiculously slow. The hardware sensor is on a separate board and worked fine when connected to an example Arduino project which I had to do for sanity. So reverting back to my oem hardware simply gives me inconsistent results. Logic analyser and scope confirm data levels are ok, just reading from the chip is eratic. Hence suspecting all the third party drivers, led me to bring in the Arduino library.. modified from c++ which also worked at the slow speed.
But then not reliably. It's all pointing to a hardware problem, but as you say it's only a few pins. These days these modules get used by Arduino users, but of course the project that it's destined for is native c, avr.
Every different i2c library requires different calls, from the TSL driver which is why I have so many alternate functions created over the last days of experimenting.

Tomorrow is another day... of course a known working TSL2561 project would graciously be put to the test on my hardware.

Last Edited: Tue. Jan 3, 2017 - 10:53 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you need a bus speed below the standard 100kHz, it is because you have not got suitable external pullup resistors.
4k7 is fine for 5V. 2k7 for 3.3V. Your comms should be 100% reliable.
.
David.

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

This is the module

https://www.adafruit.com/product...

THis is the schematic

https://cdn-learn.adafruit.com/a...

It does voltage translation

Pull ups are 10K on either side of the translator. 

I've scoped the signals, they look ok, the logic analyser reads them ok...

This mornings test seem to show it working at around 275KHz which should be ok for the chip. 

I'm using an interrupt driven I2C driver from another source which is in use on other projects.

 

However, there is one issue existing which is still a cause for concern and I've seen it before, that is, the data sheet states that writing 0x03 to the control reg and reading it back should also give 0x03.

I get 0x33 returned frm this register, yet a check of the timing register reads back ok.  **  Attached the actual decoded logic waveforms for reference **

I'm going to reduce the resistors, and see if it makes a difference.

There may be a case for getting this thread moved to a new thread about the TSL2561 to assist any other users looking for help with this chip.

I'll post the final code when it's all working.

 

*UPDATE*  

Changed resistors to 4k7 on  5V side and 2k2 on 3V side. Considering they are effectively in parallel the load is even smaller.

Exactly the same .. it appears to work, but the readback of the control register is still 0x33 and not 0x03.  I have sent a ticket to AMS for their opinion.

 

*FURTHER UPDATE*

Found this on the Electric Imp website about TSL2561.

 

"Just to check this has worked, we read the control register: the return value, logged in the IDE, should be 3 if the TSL2561 has just started up, or 51 if the device has already been switched on."

 

 That 51 equates to 0x33..  so now, according to that little useful snippet - everything is working. I cannot see mention of this on the datasheet, I may have missed it.. but if not, then I've spent days trying in part to fix a non existent problem.

 

 

 

 

Attachment(s): 

Last Edited: Wed. Jan 4, 2017 - 10:08 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The TSL2561 is specified for 0-400kHz with I2C bus.   Or 10-100kHz with an SMBUS.

 

Yes,  it is an excellent strategy:   Write a value to a register and read it back.

Write a whole Test Suite if you are feeling keen.

 

Are you saying that everything has always worked at 100kHz?  Except for one register returning 0x33?

 

If you are using the bus for several devices,  you must "start" at the lowest common bus speed.    Once acknowledged,   you can communicate at 400kHz if the Slave supports it.

 

In practice,   you might just as well stick to 100kHz.   Your bus traffic is not significant.

 

David.

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

It looks working, and the 0x33 seems to be an ambiguity with the datasheet. Which if so, had me foxed for a long time.

Its running at 240kHz now. Earlier attempts with different drivers seemed to be erratic but I was spending time trying to fix the 0x33 / 0x03 issue thinking it was a comms problem, which perhaps blinded me to other issues.

The sensor responds to light level changes as expected .

Only this device on the I2C bus - although the main project has SPI driving CAN. I'll try other bus speeds, but the comms looks ok right now.

 

So it seems to function now when integrated with existing code, but I'm not convinced the conversion to Lux values are correct. However the values are stable-ish.

The actual Lux is calculated from two AtoDs in the chip, one for infra red, and another for visible light. I use two different conversion functions both imported from the web and the outputs agree exactly.

I've just ordered a lux meter... 

Watch this space.

Rob

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

If you only have one device on the bus,   the bus capacitance will be pretty negligible.    Only you know your pcb trace geometry and any external bus wiring.    Your 10k pullups would have been fine.   I would stick to 100kHz.

 

I know nothing about Lux.    Except that "low energy" light bulbs were an amazing confidence trick.    They quote Lumens but compare against the "poorest" standard wattage incandescent bulbs.

 

You certainly get more light from an old 100W than the "equivalent" low energy replacement.

I am all in favour of electrical efficiency.   But if I want to see something,   I need sufficient Lumens.

 

David.

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

Finally!!!! Solved.

And the underlying problem was of course me. Mistaking a defined value for the timing register address, as the value. So when I changed the define... the register address went wrong.

Although it appeared to work, the lux values were way off. In the end I had to do a 12c packet by packet comparison with a working Arduino example to spot it.

 

I now have a working set of code for the TSL2561 on a Mega 32.  Attached for anyone who may be stuck. Still could do with tidying up a little but it should work out of the box.

 

If anyone needs help...  and thanks for listening.

Rob

 

Attachment(s): 

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

Ah-ha.    It looks like you have a manageable number of files.

 

That seems a lot easier than the ASF minefield.

 

Note that the datasheets for the legacy ATmega32 advise against low values in TWBR.

I always managed to get reliable I2C with high bus speeds.

 

I would strongly advise against your DDRC and PORTC statements.   You must NOT drive the I2C bus high.   Nor should you enable internal pullups.     (this is only done for Arduino users who can not afford resistors)

 

David.

Last Edited: Fri. Jan 6, 2017 - 01:58 PM