Author Topic: ATmega644 USART software/programming error  (Read 7109 times)

0 Members and 1 Guest are viewing this topic.

Offline MrAureliusR

  • Supporter
  • ****
  • Posts: 366
  • Country: ca
  • frozenelectronics.ca
    • Frozen Electronics
ATmega644 USART software/programming error
« on: October 08, 2013, 06:41:09 am »
I was supposed to go to bed by midnight, but when I went out for a smoke I noticed that my package from SparkFun had (FINALLY) gotten here... how I didn't notice it the rest of the day is a question in itself  :palm:

My new Olimex 40-pin AVR dev board was in there, which I'm excited about because it's got RS-232 built in, level-shifter and all, and it should make serial communication between MCU and any peripheral easy... or so I thought. The other cool thing is it has two headers, one for ICSP and one for JTAG. I'm using the JTAG header, just for reference.

I popped an ATmega644 into the socket, fired up Atmel Studio, wrote a quick LED blink/button press program to test everything out and it worked without a hitch. Excellent, I thought, let's get something cooking here. I soldered the RX/TX pins to the inputs of the MAX232, hooked a serial cable up to my computer, and wrote this program: http://aurelius.pastebay.net/1319247

(Note: the PRR line that is commented out is part of my debugging... wanted to see if the power reduction feature had anything to do with it)

The strange thing is, it will program the MCU, but then I get a strange error I've never seen before: "Timed out waiting for device to reset". I've been trying to figure out why the MCU wouldn't reset... it was able to hold it in reset before, when programming the LED blink program before. I'm fairly sure my code is all accurate, as I spent quite a while reading about the USART registers and how to set them up... (spent much time reading when I should be sleeping!) Then I check my serial terminal, and nothing is happening. It's almost like the MCU is freezing up? Or getting stuck in a loop? I don't know how that's possible though. Perhaps I set up a register wrong?? I'm really stumped. It should be so simple. I was reading a tutorial regarding the ATmega32 but I double-checked all the register names as most of them were different. And I of course adjusted all the values for my crystal (14.7456, which is also supposed to make USART easy as it cleanly divides by most baud rates -- I'm using 19200, which when you go through the formula, yields 47 as the UBRR0).

Anyway, if someone spots a glaring error, please let me know! I'm stuck already, and I've only had the board a couple hours. Now I need to go sleep! Thanks in advance for any help offered  8)
« Last Edit: October 08, 2013, 06:44:10 am by MrAureliusR »
--------------------------------------
Amateur Radio operator VA3XMR
-.-. --.-  -.. .  ...- .- ...-- -..- -- .-.
 

Offline Psi

  • Super Contributor
  • ***
  • Posts: 7597
  • Country: nz
Re: ATmega644 USART software/programming error
« Reply #1 on: October 08, 2013, 06:55:57 am »
I'm just about to go out, but here's two things that occurred to me while reading your post.

1) You say the dev board has "RS-232 built in"  and you   "soldered the RX/TX pins to the inputs of the MAX232, hooked a serial cable up to my computer"
If it has RS-232 built in then all it needs is a direct connection from the board TX/RX to a PC com port, it almost sounds like your using a max232 when it already has one itself? Which of cause wont work because you'd be feeding +/-12 into the 5v max232 inputs.
Also check the directions of your connections. ie TX -> RX and not TX -> TX  etc..

2) Check the MCU is getting proper 5V power on VCC. I know its a simple thing but MCUs are notorious for powering up and running purely from the power coming in on their i/o (like the programming pins).
Also, an unpowered MAX232 will leak power from its inputs onto its VCC which then gets onto the VCC of everything else.

It can easy fool you. The chip will sometimes program fine and even flash an led and other times it will fail to flash correctly and throw timeout errors.
« Last Edit: October 08, 2013, 07:03:13 am by Psi »
Greek letter 'Psi' (not Pounds per Square Inch)
 

Offline RMS95

  • Contributor
  • Posts: 12
  • Country: nl
    • RMS95
Re: ATmega644 USART software/programming error
« Reply #2 on: October 08, 2013, 06:59:59 am »
2 things:

  • Check if the reset pin is actually pulled down, best way is to check all the programming pins with a logic analyzer
  • Set everything (hardware and software) back to the state you received it.

Quote
"Timed out waiting for device to reset"
Means, it has pulled the reset pin, nothing seems to happen. (But I guess you already knew that.)
 

Offline MrAureliusR

  • Supporter
  • ****
  • Posts: 366
  • Country: ca
  • frozenelectronics.ca
    • Frozen Electronics
Re: ATmega644 USART software/programming error
« Reply #3 on: October 08, 2013, 07:02:00 am »
1) the olimex 40-pin dev board has a MAX232 connected to a DB9. All you have to do is solder wires from the RX/TX of the micro to the RX/TX 5V input of the MAX232. It seems strange that they don't have these connections already made on the board but I triple checked and they aren't by default. Which explains why they have holes waiting for you to solder to beside the MAX labelled rx, tx etc.

2) I'm %1000 sure its getting VCC. This board has a separate DC power barrel for 6-9VAC or 9-12VDC. I'm using 12VDC and its regulating it down to 5V no problem.

@RMS95 yeah I figured it was pulling the line low and nothing was happening. But it programs it successfully if I use the separate programming window - which is strange because I thought it had to be held in reset while programming. It's when I try to hit the "play" button (start debugging) that it fails.. However even when it successfully programs it still sits there doing nothing. Ill fire up my digital channels tomorrow and check that to be sure but when I push the included reset button on board it resets the other programs fine...
« Last Edit: October 08, 2013, 07:06:29 am by MrAureliusR »
--------------------------------------
Amateur Radio operator VA3XMR
-.-. --.-  -.. .  ...- .- ...-- -..- -- .-.
 

Offline MrAureliusR

  • Supporter
  • ****
  • Posts: 366
  • Country: ca
  • frozenelectronics.ca
    • Frozen Electronics
Re: ATmega644 USART software/programming error
« Reply #4 on: October 09, 2013, 02:51:44 am »
Strange computers...

When I got home today, I restarted my computer, compiled the EXACT SAME code, loaded it, and it worked. First time. Bizarre...  |O |O |O
--------------------------------------
Amateur Radio operator VA3XMR
-.-. --.-  -.. .  ...- .- ...-- -..- -- .-.
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8229
  • Country: 00
Re: ATmega644 USART software/programming error
« Reply #5 on: October 09, 2013, 10:33:39 am »
Quote
Bizarre...

"Bugs are rarely where you think they are."

A smart programmer told me that.
================================
https://dannyelectronics.wordpress.com/
 

Offline MrAureliusR

  • Supporter
  • ****
  • Posts: 366
  • Country: ca
  • frozenelectronics.ca
    • Frozen Electronics
Re: ATmega644 USART software/programming error
« Reply #6 on: October 10, 2013, 09:55:07 pm »
Okay, so after getting the USART working, my next step is to interface the ATmega644 to both my serial terminal on the PC, and also to a real-time clock I2C chip I have. It seems simple enough, and luckily I've discovered more and more about how awesome it is to have a JTAG debugger (AVR Dragon) which is helping. I'll post a link to a paste of my whole code, but the problem I'm having is in the following section.

The main() function calls the init functions for both USART and I2C (to set up the baud rates, and prescalers, etc etc) which works fine. I checked the registers while it was running just to be sure that's not the problem, and it isn't. Then (because I'm also learning interrupts for the first time) I call sei() to enable global interrupts, and then it just sits there until something is received on the USART (ISR(USART0_RX_vect) as seen below. This is where there's problems. The interrupt works fine -- if I send a character over the serial port, it immediately calls the interrupt. But then it only seems to do part of the code. It will read the data out of the USART data buffer, then I call a routine to check and see what instruction was sent, and depending on that instruction it either reads the date or debug info from the RTC. It gets to the if statement (and because the received data from the USART is always 0 (another bug I'm trying to solve)) it jumps to the else{}, which is then proceeds to do. It calls IIC_read, but once it's done that, it doesn't do any of the instructions after that! I know that obviously there's more problems than just this, but I've been debugging for a while now and I really can't get my head wrapped around what's happening. But I'm trying -- I really am!!!

Any and all help is, as usual, greatly appreciated! Please point out any glaring errors. I'm pretty confident my UART code is correct, fairly confident the IIC code is correct, but I'm still learning about interrupts and how they're handled so I'm probably missing something. The volatile tags are just for debugging, so the variable doesn't get optimized away and then I can't watch what's happening.

Psate: http://aurelius.pastebay.net/1320021

Code: [Select]
ISR(USART0_RX_vect)
{
volatile int input = 0;
int action;
volatile int output[5] = {0, 0, 0, 0, 0};

input = USART_read();

action = decode(input);

if (action == 50) // if time is requested then get register 0x02
{
output[0] = IIC_read(0x02); // hours
output[1] = IIC_read(0x01); // minutes
output[2] = IIC_read(0x00); // seconds
}
else
{
output[0] = IIC_read(0x07);
output[1] = IIC_read(0x06);
output[2] = IIC_read(0x05);
}

USART_write(output[0]); // send whatever we got to USART (still debugging this at this point)
USART_write(output[1]);
USART_write(output[2]);
UCSR0B |= (1<<RXCIE0); // re-enable UART receive interrupt
sei();
}

Datasheet for the Timekeeper RAM: https://my.st.com/st-extranet-web-active/static/active/en/resource/technical/document/datasheet/CD00189496.pdf
« Last Edit: October 10, 2013, 09:58:06 pm by MrAureliusR »
--------------------------------------
Amateur Radio operator VA3XMR
-.-. --.-  -.. .  ...- .- ...-- -..- -- .-.
 

Offline Jope

  • Regular Contributor
  • *
  • Posts: 75
  • Country: de
Re: ATmega644 USART software/programming error
« Reply #7 on: October 10, 2013, 10:32:12 pm »
In your main(), put the sei() call after the IIC_init().

After you enable the UART RX interrupt in USART_init(), it is possible that an interrupt occurs before your IIC_init() is called, so your two-wire interface is never enabled and your IIC_read() never returns because it hangs while waiting in one of the while loops.

You can also delete the sei() and UCSR0B |= (1<<RXCIE0) from your USART ISR. The global interrupt bit is set again automatically when returning from the ISR (as part of the C library code) and the RXCIE0 bit is not cleared upon entering the ISR, so you don't need to reenable it.
« Last Edit: October 10, 2013, 10:36:45 pm by Jope »
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8229
  • Country: 00
Re: ATmega644 USART software/programming error
« Reply #8 on: October 10, 2013, 10:40:28 pm »
Quote
The interrupt works fine

The interrupt doesn't work. It is supposed to be quick / fast, and typically without calling other functions. Typical usage is to set a flag and process the flag in the main loop.
================================
https://dannyelectronics.wordpress.com/
 

Offline Psi

  • Super Contributor
  • ***
  • Posts: 7597
  • Country: nz
Re: ATmega644 USART software/programming error
« Reply #9 on: October 10, 2013, 10:48:37 pm »
Quote
The interrupt works fine

The interrupt doesn't work. It is supposed to be quick / fast, and typically without calling other functions. Typical usage is to set a flag and process the flag in the main loop.

If all you do is set a flag on RX char you might as well check it from the main loop and forget the interrupt.

You want some code to store the value, perhaps append it to an array if its a multi-byte message etc..
Then flag when the message is complete and ready for processing.
Greek letter 'Psi' (not Pounds per Square Inch)
 

Offline elgonzo

  • Supporter
  • ****
  • Posts: 690
  • Country: 00
Re: ATmega644 USART software/programming error
« Reply #10 on: October 10, 2013, 11:30:46 pm »
In your IIC_read(...) function, after loading the byte to send into TWDR, you seemed to forget to load the appropriate control signals into TWCR, clearing the TWINT flag (and TWSTA, if necessary).

The TWINT flag is cleared by writing a "1" to the respective bit in TWCR.

See details in the Atmega644 data sheet, chapter "19.6.  Using the TWI".
I quote from this chapter:

However, it is important that the TWINT bit is set in the value written. Writing a one to
TWINT clears the flag. The TWI will not start any operation as long as the TWINT bit in
TWCR is set. Immediately after the application has cleared TWINT, the TWI will initiate
transmission of the address packet.
« Last Edit: October 10, 2013, 11:42:56 pm by elgonzo »
 

Offline MrAureliusR

  • Supporter
  • ****
  • Posts: 366
  • Country: ca
  • frozenelectronics.ca
    • Frozen Electronics
Re: ATmega644 USART software/programming error
« Reply #11 on: October 11, 2013, 01:44:35 am »
In your main(), put the sei() call after the IIC_init().

After you enable the UART RX interrupt in USART_init(), it is possible that an interrupt occurs before your IIC_init() is called, so your two-wire interface is never enabled and your IIC_read() never returns because it hangs while waiting in one of the while loops.

You can also delete the sei() and UCSR0B |= (1<<RXCIE0) from your USART ISR. The global interrupt bit is set again automatically when returning from the ISR (as part of the C library code) and the RXCIE0 bit is not cleared upon entering the ISR, so you don't need to reenable it.

Thanks, I made both of these changes. I wasn't sure whether or not global interrupts were re-enabled, because it seems like they weren't being re-enabled. After the ISR is called once, and then it exits, the I bit in the MCU status register never seems to get set again. However that's more likely due to whatever the major problem is that's causing the ISR to exit prematurely.

Quote
The interrupt works fine

The interrupt doesn't work. It is supposed to be quick / fast, and typically without calling other functions. Typical usage is to set a flag and process the flag in the main loop.

If all you do is set a flag on RX char you might as well check it from the main loop and forget the interrupt.

You want some code to store the value, perhaps append it to an array if its a multi-byte message etc..
Then flag when the message is complete and ready for processing.

Again, I wasn't sure about any of this. As I mentioned before, this is the first time I've programmed using interrupts. I suppose most of what I have in the ISR could get moved to main(). Should I simply declare a global variable and have main() check to see if it's set? And then have the ISR set it whenever it's done copying the input from UDR0? Or is there a better way (I'm sure there probably is)?

All I'm trying to do right now is get this simple program running. Then I'll optimize it and add more usefulness. I will have a Bus Pirate soon so that will help in learning more about I2C. I need to add a function to program the current date and time to the RTC on reset. I used to be very good at writing code to manipulate/concatenate/edit strings, but that was in C++. I'm not really sure what the macros/functions are in C. For example, string doesn't seem to be a valid variable type. What should I use for multiple characters? A char array? That seems a bit clunky.

I'm going to do some more debugging and I'll keep an eye on this thread. Thanks a bunch everyone -- I truly appreciate the help! I'm always trying to learn, and most of the websites I've found have either bad, contradictory or incomplete info... so I'm trying to do the best I can with what I have.

EDIT: I just remembered what you said about IIC_read(). Do you mean that I should add TWCR |= (1<<TWINT); before every byte is sent? I re-read that part of the datasheet (believe me, I've been reading that datasheet a lot!!) but it's confusing because at the beginning of the function I DO have a 1 written to TWINT. Does it get cleared after every send? Not to mention, that paragraph seems contradictory. "Writing a one to TWINT clears the flag." "The TWI will not start any operation as long as the TWINT bit in TWCR is set." Doesn't "is set" usually mean true/written to 1?? And then it says after the application has cleared TWINT it will initiate transmission. A little clarification would help a lot here...
« Last Edit: October 11, 2013, 01:50:49 am by MrAureliusR »
--------------------------------------
Amateur Radio operator VA3XMR
-.-. --.-  -.. .  ...- .- ...-- -..- -- .-.
 

Offline elgonzo

  • Supporter
  • ****
  • Posts: 690
  • Country: 00
Re: ATmega644 USART software/programming error
« Reply #12 on: October 11, 2013, 02:12:27 am »
EDIT: I just remembered what you said about IIC_read(). Do you mean that I should add TWCR |= (1<<TWINT); before every byte is sent? I re-read that part of the datasheet (believe me, I've been reading that datasheet a lot!!) but it's confusing because at the beginning of the function I DO have a 1 written to TWINT. Does it get cleared after every send? Not to mention, that paragraph seems contradictory. "Writing a one to TWINT clears the flag." "The TWI will not start any operation as long as the TWINT bit in TWCR is set." Doesn't "is set" usually mean true/written to 1?? And then it says after the application has cleared TWINT it will initiate transmission. A little clarification would help a lot here...

You should reset the TWINT flag after TWDR is set, otherwise the TWI will not start with the transmission. Just setting TWDR doesn't start the data transfer, if the datasheet is correct.
You should try doing something in the order like this in your IIC_Read function:

TWCR |= (1<<TWINT) | (1<<TWSTA) | (1<<TWEN)
while (!(TWCR & (1<<TWINT)));
TWDR = slave address + write bit
TWCR = (1<<TWINT) | (1<<TWEN)
while (!(TWCR & (1<<TWINT)));
TWDR = address to read from
TWCR = (1<<TWINT) | (1<<TWEN)
while (!(TWCR & (1<<TWINT)));
... and so on and so forth...

I guess, you would need to adapt IIC_Write similarily.

(The Atmega644 datasheet i used is the curren revision 2593O-AVR-02/12)
« Last Edit: October 11, 2013, 02:14:30 am by elgonzo »
 

Offline elgonzo

  • Supporter
  • ****
  • Posts: 690
  • Country: 00
Re: ATmega644 USART software/programming error
« Reply #13 on: October 11, 2013, 02:18:25 am »
"Writing a one to TWINT clears the flag." "The TWI will not start any operation as long as the TWINT bit in TWCR is set." Doesn't "is set" usually mean true/written to 1?? And then it says after the application has cleared TWINT it will initiate transmission. A little clarification would help a lot here...

Yes it is counter-intuitive and confusing for beginners to reset a bit by writing an "1" into it.
But actually i am quite used to it from the IRQ programming of the old home computers of yore...  ;D
 

Offline MrAureliusR

  • Supporter
  • ****
  • Posts: 366
  • Country: ca
  • frozenelectronics.ca
    • Frozen Electronics
Re: ATmega644 USART software/programming error
« Reply #14 on: October 11, 2013, 02:25:26 am »
EDIT: OH MY GOD I'M A FLAMING IDIOT... when I started debugging an hour ago I forgot to turn the power supply on!!! So the ATmega has power, the AVR dragon has power, but the Timekeeper doesn't ... DOH  |O |O |O |O |O ... even after turning the power on, it's still getting stuck at the same spot as mentioned below... lol that's strange. I guess it doesn't even need the RTC there to screw up...  :-DD

so here's the revised IIC_read):
int IIC_read(int addr)
{
   TWCR |= (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); // enable TWINT and generate a start condition
   TWDR = 0b11010000; // send slave address plus write bit
   TWCR = (1<<TWINT)|(1<<TWEN);
   while (!(TWCR & (1<<TWINT))); // wait for byte to send
   TWDR = addr; // send address that we are reading from
   TWCR = (1<<TWINT)|(1<<TWEN);
   while (!(TWCR & (1<<TWINT))); // wait for byte to send
   TWCR |= (1<<TWSTA); //repeated start
   TWCR = (1<<TWINT)|(1<<TWEN);
   while (!(TWCR & (1<<TWINT))); // wait for byte to send
   TWDR = 0b11010001; // slave address plus READ bit
   TWCR = (1<<TWINT)|(1<<TWEN);
   while (!(TWCR & (1<<TWINT))); // wait for byte to send
   TWDR = 0xFF; // shift junk data out to shift in the data byte requested
   TWCR = (1<<TWINT)|(1<<TWEN);
   while (!(TWCR & (1<<TWINT))); // wait for byte to send
   TWCR |= (1<<TWSTO); // generate a STOP condition to bring bus back to rest
   TWCR = (1<<TWINT)|(1<<TWEN);
   while (!(TWCR & (1<<TWINT))); // wait for byte to send
   return TWDR;
}

Now, it's getting stuck on the first "while (!(TWCR & (1<<TWINT)))", the one right after the slave address and write bit. It just sits there forever. I'm trying to understand what this while loop actually does. Obviously part of it is waiting for TWINT to be cleared, but why is TWCR in there? Why is it evaluating the entire register ANDed with TWINT?!? I know the whole statement is ! but still... confusing.

EDIT #2: So I busted out the oscilloscope. I am probing SDA, and when I send a character across the UART, the SDA line goes low... and just stays low. No action whatsoever. So even though the code has gotten to the while loop, the hardware hasn't even sent the first byte. I think it's sent the start condition but that's it. Strange. I guess I'll bust out the logic analyzer and watch everything a bit more closely.
« Last Edit: October 11, 2013, 02:43:58 am by MrAureliusR »
--------------------------------------
Amateur Radio operator VA3XMR
-.-. --.-  -.. .  ...- .- ...-- -..- -- .-.
 

Offline elgonzo

  • Supporter
  • ****
  • Posts: 690
  • Country: 00
Re: ATmega644 USART software/programming error
« Reply #15 on: October 11, 2013, 02:42:13 am »
Now, it's getting stuck on the first "while (!(TWCR & (1<<TWINT)))", the one right after the slave address and write bit. It just sits there forever. I'm trying to understand what this while loop actually does. Obviously part of it is waiting for TWINT to be cleared, but why is TWCR in there? Why is it evaluating the entire register ANDed with TWINT?!? I know the whole statement is ! but still... confusing.

It seems, the I2C slave device doesn't send a ACK signal.
The reason why there is no ACK signal can be manifold: wrong slave address, wiring mistake, defective part, electrical issues, violation of the I2C protocol from either of the involved parts, etc...etc...

Do you have a logic analyzer to see what is happening on the wires?
Without some test gear to watch the action on the wires, troubleshooting will become random poking in the dark.


Regarding the syntax of the source code, you have to understand that TWCR is a register, whereas TWINT is just a number (the number 7, which is the bit position of the TWINT bit in TWCR).

Code: [Select]
while (!(TWCR & (1<<TWINT))) would actually be equivalent to:

Code: [Select]
while (!(TWCR & (1<<7)))
TWCR & (1<<7) obviously yields the value of bit 7 in TWCR (which is the TWINT bit). Since the bit position is 7, possible values for this expression are 128 when the bit is set, and 0 when the bit is not set.
« Last Edit: October 11, 2013, 02:48:33 am by elgonzo »
 

Offline elgonzo

  • Supporter
  • ****
  • Posts: 690
  • Country: 00
Re: ATmega644 USART software/programming error
« Reply #16 on: October 11, 2013, 03:08:04 am »
Perhaps it's not working because you missed a while loop after the START condition has been set...

int IIC_read(int addr)
{
   TWCR |= (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); // enable TWINT and generate a start condition
   while (!(TWCR & (1<<TWINT))); // wait for START condition transmitted
   TWDR = 0b11010000; // send slave address plus write bit
   TWCR = (1<<TWINT)|(1<<TWEN);
        [...snip...]
 

Offline MrAureliusR

  • Supporter
  • ****
  • Posts: 366
  • Country: ca
  • frozenelectronics.ca
    • Frozen Electronics
Re: ATmega644 USART software/programming error
« Reply #17 on: October 11, 2013, 03:23:32 am »
I added that while loop to the start condition, by the way. Which is probably why it's getting as far as described below...

So I thought that when I send a character over UART, that the lines were just going low and staying low (and they are staying low) BUT now that I'm using the digital channels (logic analyzer feature) on my scope, I can see that in the time I thought it was just going low, the ATmega sends the start condition, then the slave address and read bit, it receives the ACK from the slave, then it starts clocking for the slave. The slave sends what looks like a full byte (0b00000111) but then there seems to be an extra clock cycle, and then a couple weird pulses on the data line (they're not interference though, because they're there every time). I'm not entirely sure what an ACK should look like, but from what I've read (I have a copy of free_electron's Mastering the I2C Bus) the master should let the data line go high, and the slave should pull it low and then let it go high again, almost like a little nod of the head. If that's what's happening at the end (which I think it is) then it seems that the ATmega is the one screwing up, because it's either not recognizing the ACK, or something else is happening. After that ACK, the ATmega stops clocking, and nothing else happens. The lines go low and stay low.

By the way,  I thought I did my math correctly to set the I2C speed at ~150kHz, but I'm getting a clock speed of almost 400kHz, which is the maximum speed that the RTC chip can handle. I'm not sure what I did wrong, I followed the formula correctly (or so I thought)... perhaps I implemented it wrong? I was thinking maybe if I bring the I2C clock speed down it's likely to be more reliable. I'll try fiddling with that now.

See attached a picture of what I'm seeing on the bus.

--------------------------------------
Amateur Radio operator VA3XMR
-.-. --.-  -.. .  ...- .- ...-- -..- -- .-.
 

Offline elgonzo

  • Supporter
  • ****
  • Posts: 690
  • Country: 00
Re: ATmega644 USART software/programming error
« Reply #18 on: October 11, 2013, 04:06:18 am »
An ACK (or NACK) will appear on the Logic Analyzer as 9th bit. ACK is a "0" bit, NACK is a "1" bit.
However for the ACK (or NACK) master and slave swap the roles (which you cannot see on the LA). So far so good.

The problem with the TWI "dying" when trying to do a repeated START, is that the restart code is faulty. Replace

Code: [Select]
TWCR |= (1<<TWSTA); //repeated start
TWCR = (1<<TWINT)|(1<<TWEN);

with

Code: [Select]
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); // START repeat
and that should work.

Regarding the bit rate. I see in your source (IIC_init function) that you enable the TWI first, and then try to set the bit rate.
Perhaps, the clock generation is locked when the TWI is enabled, and changes of TWBR don't have effect; but i am not sure about that.
Anyway, you can safely comment out the line "TWCR |= (1<<TWEN);", because TWEN is and should be handled in the transmission routine(s).
« Last Edit: October 11, 2013, 04:09:12 am by elgonzo »
 

Offline elgonzo

  • Supporter
  • ****
  • Posts: 690
  • Country: 00
Re: ATmega644 USART software/programming error
« Reply #19 on: October 11, 2013, 04:23:14 am »
Looking at the read function, is it correct, that you throw away the 1st byte sent from the RTC?
« Last Edit: October 11, 2013, 04:27:20 am by elgonzo »
 

Offline MrAureliusR

  • Supporter
  • ****
  • Posts: 366
  • Country: ca
  • frozenelectronics.ca
    • Frozen Electronics
Re: ATmega644 USART software/programming error
« Reply #20 on: October 11, 2013, 04:31:02 am »
The problem with the TWI "dying" when trying to do a repeated START, is that the restart code is faulty. Replace

Code: [Select]
TWCR |= (1<<TWSTA); //repeated start
TWCR = (1<<TWINT)|(1<<TWEN);

with

Code: [Select]
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); // START repeat
and that should work.
....
Anyway, you can safely comment out the line "TWCR |= (1<<TWEN);", because TWEN is and should be handled in the transmission routine(s).

Thanks for all the tips! Those couple of changes seem to have made a difference. The logic analyzer is now seeing 4 full bytes sent/received, and decoding them it's slowly starting to work. There's still a few problems (UART doesn't seem to be sending) but I should be able to iron them out.

Looking at the read function, is it correct, that you throw away the 1st byte sent from the RTC?
No, why would I throw away the first byte sent from the RTC? I'm confused
--------------------------------------
Amateur Radio operator VA3XMR
-.-. --.-  -.. .  ...- .- ...-- -..- -- .-.
 

Offline elgonzo

  • Supporter
  • ****
  • Posts: 690
  • Country: 00
Re: ATmega644 USART software/programming error
« Reply #21 on: October 11, 2013, 04:44:33 am »
No, why would I throw away the first byte sent from the RTC? I'm confused

Ah, okay, never mind. I got confused over the TWDR = 0xff line. Brain fart on my side...  :-//
Anyway, i am glad that i could help.  :)
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf