|
View:
New views
6 Messages
—
Rating Filter:
Alert me
|
|
|
Mega644 bit test problemHallo,
I am writing code for an ATMega 644P and have come across some very strange behaviour. A small part of the code is required to read an asynchronous serial signal (data & clock - low speed) over PORTB pins. The relevant code snippet is: snip #define CLOCK_TIMEOUT 2000 #define ASYNCPIN PORTB #define ASYNCCLK 0 #define ASYNCDATA 3 for (i = 0 ; i < 16 ; ++i) { while ((ASYNCPIN & _BV(ASYNCCLK)) != 0) // Wait for clock low { if (mSecdowncnt == 0) { noclock = 1; break; // Timeout } } result = result >> 1; if ((ASYNCPIN & _BV(ASYNCDATA)) != 0) { result |= 0x8000; } while ((ASYNCPIN & _BV(ASYNCCLK)) != 1) // Wait for clock high { if (mSecdowncnt == 0) { noclock = 1; break; // Timeout } } if (noclock == 1) { break; } } /snip This works fine. I want, however to use portb bits 1 & 3 for clock & data. I simply change to #define ASYNCCLK 1 and re-compile Now, nothing works and the code generated is much smaller (0xe5 bytes instead of 0x193 bytes for the working variant). I am using OPTIMIZE = -O1 -fno-inline in my Makefile Does anyone know why simply changing a bit-mask should have such a serious effect ? Best regards, Robert von Knobloch _______________________________________________ AVR-chat mailing list AVR-chat@... http://lists.nongnu.org/mailman/listinfo/avr-chat |
|
|
Re: Mega644 bit test problemOn May 8, 2009, at 11:41 AM, Robert von Knobloch wrote: > Hallo, > > I am writing code for an ATMega 644P and have come across some very > strange behaviour. > A small part of the code is required to read an asynchronous serial > signal (data & clock - low speed) over PORTB pins. > The relevant code snippet is: > > snip > #define CLOCK_TIMEOUT 2000 > #define ASYNCPIN PORTB > #define ASYNCCLK 0 > #define ASYNCDATA 3 > > for (i = 0 ; i < 16 ; ++i) > { > while ((ASYNCPIN & _BV(ASYNCCLK)) != 0) // Wait for > clock low > Sorry for out of topic, but shouldn't you use PINB instead of PORTB when reading pin state? Regards, PN _______________________________________________ AVR-chat mailing list AVR-chat@... http://lists.nongnu.org/mailman/listinfo/avr-chat |
|
|
Re: Mega644 bit test problemI don't see where you set the appropriate DDR pin.
-- There is no computer problem which cannot be solved by proper application of a sufficiently large hammer. _______________________________________________ AVR-chat mailing list AVR-chat@... http://lists.nongnu.org/mailman/listinfo/avr-chat |
|
|
Re: Mega644 bit test problem(Reading through some very old email, it looks like this one might not
have been resolved...) On Fri, May 8, 2009 at 2:41 AM, Robert von Knobloch<bob@...> wrote: > Hallo, > > I am writing code for an ATMega 644P and have come across some very > strange behaviour. > A small part of the code is required to read an asynchronous serial > signal (data & clock - low speed) over PORTB pins. > The relevant code snippet is: > > snip > #define CLOCK_TIMEOUT 2000 > #define ASYNCPIN PORTB > #define ASYNCCLK 0 > #define ASYNCDATA 3 > > for (i = 0 ; i < 16 ; ++i) > { > while ((ASYNCPIN & _BV(ASYNCCLK)) != 0) // Wait for clock low > { > if (mSecdowncnt == 0) > { > noclock = 1; > break; // Timeout > } > } > > result = result >> 1; > if ((ASYNCPIN & _BV(ASYNCDATA)) != 0) > { > result |= 0x8000; > } > > while ((ASYNCPIN & _BV(ASYNCCLK)) != 1) // Wait for clock This line is probably the problem. > This works fine. I want, however to use portb bits 1 & 3 for clock & > data. I simply change to #define ASYNCCLK 1 > and re-compile > Now, nothing works and the code generated is much smaller (0xe5 bytes > instead of 0x193 bytes for the working variant). _BV(0)==1 but _BV(1)==2, so when you do ((value & _BV(1)) != 1), it's never false because the possible values of (ASYNCPIN & _BV(1)) are 0 or 2, never 1. I would try to write these kinds of statements as while( !(ASYNCPIN & _BV(ASYNCCLK)) ) { blah, blah; } -Tarmigan _______________________________________________ AVR-chat mailing list AVR-chat@... http://lists.nongnu.org/mailman/listinfo/avr-chat |
|
|
Re: Mega644 bit test problemtarmigan a écrit :
>> snip >> #define CLOCK_TIMEOUT 2000 >> #define ASYNCPIN PORTB >> #define ASYNCCLK 0 >> #define ASYNCDATA 3 >> >> for (i = 0 ; i < 16 ; ++i) >> { >> while ((ASYNCPIN & _BV(ASYNCCLK)) != 0) // Wait for clock low >> { >> if (mSecdowncnt == 0) >> { >> noclock = 1; >> break; // Timeout >> } >> } >> >> result = result >> 1; >> if ((ASYNCPIN & _BV(ASYNCDATA)) != 0) >> { >> result |= 0x8000; >> } >> >> while ((ASYNCPIN & _BV(ASYNCCLK)) != 1) // Wait for clock >> > > This line is probably the problem. > > >> This works fine. I want, however to use portb bits 1 & 3 for clock & >> data. I simply change to #define ASYNCCLK 1 >> and re-compile >> Now, nothing works and the code generated is much smaller (0xe5 bytes >> instead of 0x193 bytes for the working variant). >> > > _BV(0)==1 but _BV(1)==2, so when you do ((value & _BV(1)) != 1), it's > never false because the possible values of (ASYNCPIN & _BV(1)) are 0 > or 2, never 1. > > I would try to write these kinds of statements as > while( !(ASYNCPIN & _BV(ASYNCCLK)) ) { > blah, blah; > } > > -Tarmigan > > > question in any situation if MASK is modified and doesn't assume the fact that for C language "!=0" stands for TRUE. _______________________________________________ AVR-chat mailing list AVR-chat@... http://lists.nongnu.org/mailman/listinfo/avr-chat |
|
|
|
| Free embeddable forum powered by Nabble | Forum Help |