[En-Nut-Discussion] TWI interrupts on AT91SAM7x256 and Ethernut 4.6.5/4.8.0
Ulrich Prinz
uprinz2 at netscape.net
Fri Apr 10 22:26:20 CEST 2009
Ok, here it goes...
The actual at91_spi.c does not switch from sending to receiving. As far
as I understood, it only switches from sending bytes immediately to
reception, what is not supported by the hardware.
The correct way of doing it is:
1) If there is data to be send...
prepare for sending, setup needed interrupts, write first byte to the
bus and enable the interrupts and timeout.
2) If then therer is data to be received...
prepare again for reception, setup needed interrupts, wait for data
coming in via interrupt.
This works in my version now for single / multiple bytes sending, single
byte send and single byte receive.
Now I'll add my eeprom driver fpr I2C eeproms of the AT24C series to the
at91 code and test multiple tx/rx transfers.
But I have one extra:
The at91sam devices support internal register addressing. So one could
setup up to 3 bytes that are written to the slave and select an internal
register or memory address of it. Then a restart condition is put
automatically by the at91 to the bus and sending or receiving of data is
initiated. This works a bit faster as the I2C has not to go through a
complete stop start condition and the internal address bytes are sent
without interrupt and other cpu interaction. So I stronlgy admit to
implement this functionality.
As far as now I have the TwMasterRegRead in the code and it works pretty
fine. But I need to add TwMasterRegWrite.
Hopefully the complete code including the partly redone TwMasterTransact
will go online this weekend.
Best regards and happy easter
Ulrich
Ulrich Prinz wrote:
> I have to correct myself, sorry.
>
> TwMasterTransact is sending data without a problem. If one needs to send
> and receive data, the sending fails under any condition, regardless of
> the timeout value. If the timout is 0 (infinite) the system hangs.
>
> Measurements of the interrupt routine ( gpios put on a scope) show, that
> after the sending part of one transaction is done, no further interrupt
> is called. So the receiver part does not happen.
>
> I continue to track that issue down.
>
> Best regards and some happy easter
> Ulrich
>
> Ulrich Prinz wrote:
>> Hi Ajit!
>>
>> I implemented your patches in my local checkout of latest 4.9.x version. I
>> investigate on TwMasterTransact problems too.
>> As far as I can see, this function works well as long as you don't give a
>> timout value. If you do so, TwMasterTransact will send given data out but
>> does not continue to receive data if there is a number given for rxlen.
>>
>> Example:
>>
>> uint8_t PCA_Register = 0; // Register inside I2C chip for its port 0
>> uint8_t PCA_Keys; // There are pushubuttons at port 0
>>
>> TwMasterTransact( PCA9555_ADDR, &PCA_Register, 1, %PCA_Keys, 1, 50);
>>
>> On the I2C bus I can see:
>> <ST>0x23, 0x00<SP>
>>
>> Now I call it like this:
>> TwMasterTransact( PCA9555_ADDR, &PCA_Register, 1, %PCA_Keys, 1,
>> NUT_WAIT_INFINITE);
>> And I see:
>> <ST>0x23, 0x00<SP><ST>0x27, 0xkk<SP>
>>
>> where kk depends on the pressed buttons.
>>
>> So there is a problem inside the timeout handling of the I2C.
>>
>> I am not convinced about not keeping up TxMasterRegRead(). This funktion
>> might speed up I2C as it handles registers inside target chips itself
>> wihtout multiple transfers. But I have to read through the atmel bug lists
>> carefully before making a decision in that.
>>
>> Best regards, Ulrich
>>
>> On Fri, 3 Apr 2009 21:06:19 +0530 (IST), "Ajit Narayanan"
>> <ajitn at inventionlabs.in> wrote:
>>> Hi Harald/Ole,
>>>
>>> I made some progress on this bug. It looks like there are a few issues in
>>> at91_twi.c related to the TWI errata of AT91SAM7x256 (41.4.9.1) which
>> says
>>> The value of CLDIV x 2^CKDIV must be less than or equal to 8191, the
>> value
>>> of CHDIV x 2^CKDIV must be less than or equal to 8191.
>>>
>>> For a client bitrate of 2400, this is not possible; we need a faster
>>> bitrate. This can be changed in TwInit(). I changed it to 4800.
>>>
>>> The return value of the SETSPEED IOCtl is not being checked; this would
>>> have caught the bug earlier:
>>>
>>> - TwIOCtl(TWI_SETSPEED, &speed)
>>> + if( TwIOCtl(TWI_SETSPEED, &speed) ) {
>>> + return -1;
>>> + }
>>>
>>> Also, the check in the IOCtl (line 344) is incorrect:
>>> - if (cldiv * (2 << ckdiv) > 8191) {
>>> + if (cldiv * (1 << ckdiv) > 8191) {
>>>
>>> The bad news is, with all of the above, my application still doesn't work
>>> :-(. But when I check with a scope, I see that at least master
>>> transactions are initiated now. If someone with a Calypso board could
>> give
>>> it a shot and let me know, that would be great.
>>>
>>> It is still a mystery to me why this works with older Nut/OS versions.
>>>
>>>
>>> -Ajit
>>>
>>>
>>>> Ole Reinhardt wrote:
>>>>
>>>>> Ok, I had it just running with a client, but the above bug is realy a
>>>>> bug :)
>>>> On a SAM7X? May be there's a difference among MCUs.
>>>>
>>>>
>>>>> I'll test it here any further if I get a I2C device connected to my
>>>>> olimex board. Until then you might add a hint to the configurator
>> option
>>>>> not to use this code right now...
>>>> No hurry.
>>>>
>>>> Unfortunately here is a second problem. Both, the hardware TWI as well
>>>> as the bit banging version are added to the libs. It seems they are
>>>> added by random, depending on the sequence of the referrers.
>>>>
>>>> As a temporary workaround one might copy twbbif.c to the application
>>>> directory and add it to the Makefile.
>>>>
>>>> Harald
>>>>
>>>>
>>>> _______________________________________________
>>>> http://lists.egnite.de/mailman/listinfo/en-nut-discussion
>>>>
>>>
>>>
>>>
>>> _______________________________________________
>>> http://lists.egnite.de/mailman/listinfo/en-nut-discussion
>> _______________________________________________
>> http://lists.egnite.de/mailman/listinfo/en-nut-discussion
> _______________________________________________
> http://lists.egnite.de/mailman/listinfo/en-nut-discussion
More information about the En-Nut-Discussion
mailing list