Show Posts
Pages: 1 [2] 3 4 ... 7
16  Using Arduino / Programming Questions / Re: how can I add a second function to the same switch? on: September 20, 2011, 08:44:13 pm
You could attach an interrupt to your function.  That way the function gets called automatically when the button is pushed / let go.

http://arduino.cc/en/Reference/AttachInterrupt

Simply use millis() to record when the button state changes (is pushed / let go).  Subtract the two times.  Then do a specific action based on the elapsed time.  Reset the timers whenever the button is let go... after an action is done.
17  Using Arduino / Programming Questions / Re: Stack size and sub-methods on: September 20, 2011, 08:34:12 pm
Thanks Nick and westfw.  I was happy to see some helpful conversation.  That totally makes sense now that we're dealing with a pure software stack which would have to be managed by an OS for large processors.  I guess I imagined some sort of hardware stack implemented in the chip architechture, or that they kept pointers to the high used heap address.  Now I understand why it's not managed for embedded devices.

So, just for my education, how are variables allocated in the heap space?  What I mean, is how is the memory managed?  How do we keep track of which memory addresses are currently allocated to variables, and which addresses are free?  Is that done by the compiler?  If I were to attempt to write my own code to detect a heap / stack collision, is there a way to get the byte address of the highest used heap space memory?

Thanks.
18  Using Arduino / Programming Questions / Re: Stack size and sub-methods on: September 10, 2011, 12:34:38 am
Currently I have two Arduinos.  One is a Duemilenova DIP the other is an Uno SMD.  Both are using the ATMega328p.  2kB SRAM, 32kB Program Mem.  The Program Mem doesn't seem to be a problem, it's more the SRAM...  It looks like the stack is getting pretty large.


End of SRAM = 0x08FF
End of Regs = 0x00FF
SRAM Size = 0x08FF-0x00FF = 0x0800 = 2048 Bytes (2kB)

Stack Pointer = 0x0606
Stack Size = 0x08FF- 0x0606 = 0x0259 = 761 Bytes
Heap Space = 0x0800-0x0259 =  0x05A7 = 1447 Bytes

Why isn't there some sort of protection to prevent the heap and stack from overlapping?  Don't they protect against this on other processors?  You'd get some sort of error like a stack-overflow or something on a PC.  Is that too much work on a uC?
19  Using Arduino / Programming Questions / Re: ? How to graph data and curves? on: September 10, 2011, 12:03:40 am
You can get the QT libraries for C, if that's your desired language.  Granted, C is probably the toughest language to do graphics easily in.

You can easily write some java code with the standard packages in eclipse to draw your own graphs.  You probably could google for a graphing java class, and come up with some source that's ready to go.

I've used Visual Basic to draw graphs before, super easy.

Excel can do it, if you don't mind VBA, and don't need it real-time.
20  Using Arduino / Programming Questions / Stack size and sub-methods on: September 09, 2011, 11:25:23 pm
Hi Folks,
   I've been writing a fairly large sketch which has functions that call other functions several times deep.  They're not recursive, but say about 7-subroutines deep.  From what I understand about the stack, is that all the register values are pushed onto the stack each time a new method is called.  Are all the local variables from the calling method also pushed onto the stack as well?  They must-- I don't see how we'd keep track of local variables otherwise.

I understand that the stack starts at the highest SRAM address and grows downward, whereas the regular Data Memory starts just after all the External IO Registers and grows upward.  Eventually, as SRAM usage grows, the heap space and the stack space collide.

The reason I ask is because once I reached a certain method-depth, the program ceases to function correctly... if at all.  I assume that the heap data has over-written part of the stack, and thus a return value is no longer valid.  From my previous programming experience, it was good practice to use local variables wherever possible... but with such limited stack space, and no warning that stack corruption is taking place, I'm unsure if there's a better way to handle this.

Is there a way to set a maximum stack size?  Or to limit the area of SRAM which can be used for the heap?  How do the advanced users out there deal with these issues?





21  Using Arduino / Programming Questions / Re: How to extract server/domain from a URL in char[] on: July 01, 2011, 04:30:27 pm
The problem here is that people are used to software fixing their URLs for them.  Check out wikipedia's article on URLs:  http://en.wikipedia.org/wiki/Uniform_Resource_Locator#Syntax

Depending on the context of the URL, programs attempt to fix the "scheme" parameter if it is missing.  This works well in contexts that you know what the usual method of retriving that data type is, and which port that usually happens on.  ie:  web-browsers usually look on the http port 80 for web page data.  Browsers will automatically pre-pend the http:// to the domain name, and see if it gets a response.  This doesn't always work though, if you're really looking for a FTP site, for example.  So really, unless you know the context, not having the "scheme" parameter indicates a malformed URL.

Check out http://en.wikipedia.org/wiki/URL_normalization.  It's a good list of things you should do too, if you want it to work at least good (poorly?) as web-browsers do.

That being said, your spagetti code is probably on the right track.


You'd probably have best luck using the String library.  Otherwise, checking individual array location gets to be a pain.  The string library will let you use a substring function too, so you'll easily be able to search for the "http://" and the "www." strings and remove them from the beginning of your complete URL.  There are quite a few protocols that you'd need to check and remove from the beginning, but getting all the standard ones might be good enough to do the job. 

Here's a list of the scheme parameters you may need to parse out:  http://en.wikipedia.org/wiki/URI_scheme

Once those are removed from the front, simply search for the first "/" you find.  Everything before that will be the domain.  Everything else (including the "/") will be the rest of the URL, obviously.

Good Luck, parsing sucks.
22  Using Arduino / Networking, Protocols, and Devices / Re: Checksum for RF transmission on: June 07, 2011, 01:58:16 pm
Bitwise negation.  http://arduino.cc/en/Reference/BitwiseXorNot

~0x00 = 0xFF

You can think of a byte as signed or not.  It doesn't really matter, it's just your interpretation of the bits.  In this case, I treat it as unsigned because it's declared as a byte type.
23  Using Arduino / Networking, Protocols, and Devices / Checksum for RF transmission on: June 07, 2011, 01:28:03 pm
Hi guys.  I have two RF radios I am using to send data between Arduinos.

I am sending data using a structure of 3 bytes.

Byte1 = Packet Type
Byte2 = Data
Byte3 = Checksum

My checksum is simply the Packet Type and Data bytes added together and then negated.  

When all of the expected bytes are received, this simple checksum can detect single-order errors in the data.  However, if one of the bytes is lost, sometimes this still passes the checksum, because it doesn't handle cyclic redundancy.  (It is possible that double or 2^n-order errors could occur and pass this checksum too, if they occured just right)

ie:

Packet 1:

0x00
0x00
0xFF

Packet 2:
0x00
0x00
0xFF


If I happen to lose the first byte of the Packet1, then it reads the packet as:
0x00  <--Packet1
0xFF  <--Packet1
0x00  <--Packet2

This passes the checksum test still.  Is there a simple checksum algorithm I could use that would be easy to implement on the Arduino that guarantees the paket is received exactly as it was sent?  Are there any Arduino libraries that implement checksums for arbitrary data?

24  Using Arduino / Networking, Protocols, and Devices / Re: RF Transcievers, Async Communication? on: May 04, 2011, 01:41:35 pm
cpixip,
    Thank you for your response.  Unfortunately, I already have the nRF2401a, and won't be buyying the upgraded nRF24L01+ anytime soon.


I did manage to code up an Async TCP type communication protocol.  This code uses the "Request to Send" / "Clear to Send" method.  Both clients may designate themself the host by initiating a RTS and receiving a CTS.  But, only one of them will be granted the ability to send data.  The negotiation occurs on a first-to-request basis.  In the chance that both radios attempt to transmit at the same time, the client waits a random amount of time (100-1100 milliseconds) and tries again.  This ensures that the two won't be stuck in an infinate pattern of rx / tx mode blocking.

It currently allows a data payload of 128 bytes per packet, but forces acknowledgement (ACK) of packet receipt before more data can be sent.  Although it uses sequence numbers, it will not accept out-of-order packets.

You're right, this method is certainly a *LOT* slower, but guarantees packet delivery end to end.

Still un-implemented is the FIN packet.  This would allow the sender to end termination as "host" and allow the other radio the ability to become host.

I will try to finish up my implementation and produce a more robust library for the nRF2401a.

25  Using Arduino / Networking, Protocols, and Devices / RF Transcievers, Async Communication? on: April 30, 2011, 08:16:45 pm
Hi All!

I've got 2 Arduinos, each with it's own Nrf2401a (Nordic RF Transciever).  There's a nifty (but a bit too simple) library for them out on the Arduino Playground.

I've gotten them working with the very simple blocking communication style. 
ie:  A sends to B, changes to RX mode and waits for B to respond.  When B receive's A's message, it changes to TX mode and esponds, and then changes to RX mode and waits for A again.  etc, etc...

That works fairly well, until A or B misses a packet.  Then they both end up in RX mode and quit talking to eachother.

However, I'd love to implement something a bit more complex.  Something more like TCP that guarantees packet delivery (ie: that detects lost packets and re-sends).  I'm trying to expand upon the library, using it for sending and receiving, and then implementing the TCP protocol on top of that.

Has anyone done something similar that would like to share their experience, tips, or code?

My first attempt didn't work quite right  The receiver doesn't detect the SYN-ACK for some reason.

Here's the code:

Code:
#include <ByteBuffer.h>
#include "Nrf2401.h"

Nrf2401 Radio;
byte PacketData[256];
ByteBuffer CircularBuffer;

// 0  = CLOSED
// 1  = LISTEN
// 2  = SYN SENT
// 3  = SYN RECEIVED
// 4  = ESTABLISHED
// 5  = FIN WAIT 1
// 6  = FIN WAIT 2
// 7  = CLOSE WAIT
// 8  = CLOSING
// 9  = LAST ACK
// 10 = TIME WAIT

int ConnectionState=0;

int TCPHeaderSize=6;

typedef struct {
  byte SequenceNumber;
  byte AcknowledgementNumber;
  byte Flags;
  byte WindowSize;
  byte Checksum;
  byte DataLength;
}
TCPHeader;

TCPHeader TCPSendHeader;
TCPHeader TCPReceiveHeader;




void setup(void)
{

  TCPSendHeader.SequenceNumber=0x00;
  TCPSendHeader.AcknowledgementNumber=0x00;
  TCPSendHeader.Flags=0x00;
  TCPSendHeader.WindowSize=0x00;
  TCPSendHeader.Checksum=0x00;
  TCPSendHeader.DataLength=0x00;

  TCPReceiveHeader.SequenceNumber=0x00;
  TCPReceiveHeader.AcknowledgementNumber=0x00;
  TCPReceiveHeader.Flags=0x00;
  TCPReceiveHeader.WindowSize=0x00;
  TCPReceiveHeader.Checksum=0x00;
  TCPReceiveHeader.DataLength=0x00;


  CircularBuffer.init(512);
  Serial.begin(9600);
  pinMode(13, OUTPUT);
  randomSeed(analogRead(7));                    // start the random number generator
  attachInterrupt(0, messageReceived, RISING);  // look for rising edges on digital pin 2
  ConnectionState=0;
  Radio.rxMode(1);
}



void loop(void)
{
  digitalWrite(13, !digitalRead(13));
  //Wait 1-2 seconds
  delay(random(2000)+1000);
if (ConnectionState )


  if (ConnectionState<3)
  {
    Connect();
  }
  else if (ConnectionState==8)
  {
    Disconnect();
  }
  else
  {
    Serial.print("Connection State = ");
    Serial.println(ConnectionState,DEC);
  }

}//End RequestData


void Connect()

  Serial.println("Sending Connect...");
  TCPSendHeader.SequenceNumber = (byte)random(0,256);
  TCPSendHeader.AcknowledgementNumber=0x00;
  TCPSendHeader.Flags=0x02;  // 00000010 = SYN
  TCPSendHeader.WindowSize=0x00;
  TCPSendHeader.Checksum=0x00;
  TCPSendHeader.DataLength=0x00;
  SendPacket();
  ConnectionState=2;  //SYN SENT
}

void Disconnect()
{
  Serial.println("Sending Disconnect...");
  TCPSendHeader.SequenceNumber=TCPSendHeader.SequenceNumber+1;
  TCPSendHeader.AcknowledgementNumber=0x00;
  TCPSendHeader.Flags=0x01;  // 0000 0001 = FIN
  TCPSendHeader.WindowSize=0x00;
  TCPSendHeader.Checksum=0x00;
  TCPSendHeader.DataLength=0x00;
  SendPacket();
  ConnectionState=0;  //CLOSED
}


void SendPacket()
{
  Serial.println("Sending Packet...");
  Radio.txMode(1);

  Radio.write(TCPSendHeader.SequenceNumber);
  delay(50);
  Radio.write(TCPSendHeader.AcknowledgementNumber);
  delay(50);
  Radio.write(TCPSendHeader.Flags);
  delay(50);
  Radio.write(TCPSendHeader.WindowSize);
  delay(50);
  Radio.write(TCPSendHeader.Checksum);
  delay(50);
  Radio.write(TCPSendHeader.DataLength);
  delay(50);
  Radio.rxMode(1);
}







void messageReceived(void)
{


  Serial.println("Received:");
  while(Radio.available())
  {
    Radio.read();

    CircularBuffer.put(Radio.data[0]);
    Serial.print("CircularBuffer[");
    Serial.print(CircularBuffer.getSize()-1,DEC);
    Serial.print("] = ");
    Serial.println(CircularBuffer.peek(CircularBuffer.getSize()-1),DEC);
  }//End Copy Bytes from Receive Buffer.


  if (CircularBuffer.getSize()>=TCPHeaderSize)
  {
    Serial.println("Buffer has enough data to be TCP Header.");

    TCPReceiveHeader.SequenceNumber=CircularBuffer.get();
    TCPReceiveHeader.AcknowledgementNumber=CircularBuffer.get();
    TCPReceiveHeader.Flags=CircularBuffer.get();
    TCPReceiveHeader.WindowSize=CircularBuffer.get();
    TCPReceiveHeader.Checksum=CircularBuffer.get();
    TCPReceiveHeader.DataLength=CircularBuffer.get();


    Serial.print("TCPReceiveHeader.SequenceNumber=");
    Serial.println(TCPReceiveHeader.SequenceNumber,DEC);
    Serial.print("TCPReceiveHeader.AcknowledgementNumber=");
    Serial.println(TCPReceiveHeader.AcknowledgementNumber,DEC);
    Serial.print("TCPReceiveHeader.Flags=");
    Serial.println(TCPReceiveHeader.Flags,DEC);
    Serial.print("TCPReceiveHeader.WindowSize=");
    Serial.println(TCPReceiveHeader.WindowSize,DEC);
    Serial.print("TCPReceiveHeader.Checksum=");
    Serial.println(TCPReceiveHeader.Checksum,DEC);
    Serial.print("TCPReceiveHeader.DataLength=");
    Serial.println(TCPReceiveHeader.DataLength,DEC);


    if (ConnectionState==0)
    {
      //Received a SYN Packet
      if ((TCPReceiveHeader.Flags & 0x02)==0x02)
      {
        Serial.println("Received a SYN Packet.");
        ConnectionState=3;  //SYN RECEIVED

        //Reply with SYN-ACK
        TCPSendHeader.SequenceNumber=(byte)random(0,255);
        TCPSendHeader.AcknowledgementNumber=TCPReceiveHeader.SequenceNumber+1;
        TCPSendHeader.Flags=0x12;  // 00010010 = ACK,SYN
        TCPSendHeader.WindowSize=0x00;
        TCPSendHeader.Checksum=0x00;
        TCPSendHeader.DataLength=0x00;

        Serial.println("Sending SYN ACK...");
        SendPacket();
        ConnectionState=4;  //CONNECTED
      }
    }

    if (ConnectionState==2)
    {
      //Received SYN ACK Packet
      if ((TCPReceiveHeader.Flags & 0x12)==0x12)
      {
        Serial.println("Received SYN ACK Packet.");
        ConnectionState=4;  //CONNECTED
      }
    }

if (ConnectionState==4)
{
    //Received an ACK Packet
    if ((TCPReceiveHeader.Flags & 0x10)==0x10)
    {
      Serial.println("Received an ACK Packet.");
      TCPSendHeader.SequenceNumber=TCPReceiveHeader.AcknowledgementNumber;
      TCPSendHeader.AcknowledgementNumber=TCPReceiveHeader.SequenceNumber+1;
    }
}

    //Received a FIN Packet
    if ((TCPReceiveHeader.Flags & 0x01)==0x01)
    {
      Serial.println("Received FIN Packet.");
      ConnectionState=0;  //CLOSED
    }

  }//End Has whole header


}//End messageReceived











26  Using Arduino / Microcontrollers / Re: Understanding the .hex file on: April 27, 2011, 11:21:13 am
westfw,

Thank you for your reply.  You are exactly right.  The AVR GCC creates "Little-Endian" (low-byte at the lower address) hex files.  I made a quick change to my program and everything started working as expected. 

Is the data in the program memory on the ATMega328 also stored Little-Endian, or does the programmer swap the bytes as it uploads the sketch?  I assume the latter, as the ATMega328 datasheet shows the instructions in "Big-Endian" format.
27  Using Arduino / Microcontrollers / Re: Understanding the .hex file on: April 26, 2011, 02:15:23 pm
I posted this question over on AVRFreaks.net and found the answer I was looking for, so I thought it would be prudent to post the answer here as well for people who are seeing the same issue:

http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=821010#821010

Turns out the bytes of the instruction are being reversed.

Code:
0x0C94  -->  0x940C

It appears that the second word for the double-word instruction is also reversed.
Code:
0x3400  -->  0x0034

Then 0x0034 is being shifted to the left one bit which results in 0x68.  This is done because the JMP address needs to end up on an even byte boundry, so the last binary digit in the jump address will always be zero.  They can save a bit (and thus address a space one power of two larger) if they store the bit-shifted number instead.

That's how the compiler is generating the JMP 0x68 assembler instruction.

I'm still not quite sure how to tell if the bytes have been reversed or not.  Is that just for double-word instructions?  Is there some documentation I missed that indicates this is how it works?
28  Using Arduino / Microcontrollers / Re: Understanding the .hex file on: April 25, 2011, 04:53:48 pm
ok, I found how to disassemble the .cpp.elf file using avr-objdump -S command from /hardware/tools/avr/bin/

That worked and now I have the following assembler:

Code:
C:\blink_1MHz.cpp.elf:     file format elf32-avr


Disassembly of section .text:

00000000 <__vectors>:
    }
  
    return(0);
}

void ioinit (void)
   0: 0c 94 34 00 jmp 0x68 ; 0x68 <__ctors_end>
   4: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt>
   8: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt>
   c: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt>
  10: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt>
  14: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt>
  18: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt>
  1c: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt>
  20: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt>
  24: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt>
  28: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt>
  2c: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt>
  30: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt>
  34: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt>
  38: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt>
  3c: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt>
  40: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt>
  44: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt>
  48: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt>
  4c: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt>
  50: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt>
  54: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt>
  58: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt>
  5c: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt>
  60: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt>
  64: 0c 94 51 00 jmp 0xa2 ; 0xa2 <__bad_interrupt>

00000068 <__ctors_end>:
  68: 11 24       eor r1, r1
  6a: 1f be       out 0x3f, r1 ; 63
  6c: cf ef       ldi r28, 0xFF ; 255
  6e: d8 e0       ldi r29, 0x08 ; 8
  70: de bf       out 0x3e, r29 ; 62
  72: cd bf       out 0x3d, r28 ; 61

00000074 <__do_copy_data>:
  74: 11 e0       ldi r17, 0x01 ; 1
  76: a0 e0       ldi r26, 0x00 ; 0
  78: b1 e0       ldi r27, 0x01 ; 1
  7a: e2 e0       ldi r30, 0x02 ; 2
  7c: f1 e0       ldi r31, 0x01 ; 1
  7e: 02 c0       rjmp .+4       ; 0x84 <.do_copy_data_start>

00000080 <.do_copy_data_loop>:
  80: 05 90       lpm r0, Z+
  82: 0d 92       st X+, r0

00000084 <.do_copy_data_start>:
  84: a0 30       cpi r26, 0x00 ; 0
  86: b1 07       cpc r27, r17
  88: d9 f7       brne .-10     ; 0x80 <.do_copy_data_loop>

0000008a <__do_clear_bss>:
  8a: 11 e0       ldi r17, 0x01 ; 1
  8c: a0 e0       ldi r26, 0x00 ; 0
  8e: b1 e0       ldi r27, 0x01 ; 1
  90: 01 c0       rjmp .+2       ; 0x94 <.do_clear_bss_start>

00000092 <.do_clear_bss_loop>:
  92: 1d 92       st X+, r1

00000094 <.do_clear_bss_start>:
  94: a0 30       cpi r26, 0x00 ; 0
  96: b1 07       cpc r27, r17
  98: e1 f7       brne .-8       ; 0x92 <.do_clear_bss_loop>
  9a: 0e 94 53 00 call 0xa6 ; 0xa6 <main>
  9e: 0c 94 7f 00 jmp 0xfe ; 0xfe <_exit>

000000a2 <__bad_interrupt>:
  a2: 0c 94 00 00 jmp 0 ; 0x0 <__vectors>

000000a6 <main>:
{
    //1 = output, 0 = input
    DDRB = 0b11111111; //All outputs
  a6: 8f ef       ldi r24, 0xFF ; 255
  a8: 84 b9       out 0x04, r24 ; 4
    DDRC = 0b11111111; //All outputs
  aa: 87 b9       out 0x07, r24 ; 7
    DDRD = 0b11111110; //PORTD (RX on PD0)
  ac: 8e ef       ldi r24, 0xFE ; 254
  ae: 8a b9       out 0x0a, r24 ; 10
{
    ioinit(); //Setup IO pins and defaults

    while(1)
    {
PORTC = 0xFF;
  b0: 3f ef       ldi r19, 0xFF ; 255
  b2: 38 b9       out 0x08, r19 ; 8
PORTB = 0xFF;
  b4: 35 b9       out 0x05, r19 ; 5
PORTD = 0xFF;
  b6: 3b b9       out 0x0b, r19 ; 11
  b8: 84 ef       ldi r24, 0xF4 ; 244
  ba: 91 e0       ldi r25, 0x01 ; 1
  bc: 0b c0       rjmp .+22     ; 0xd4 <main+0x2e>
...
//General short delays
void delay_ms(uint16_t x)
{
  uint8_t y, z;
  for ( ; x > 0 ; x--){
    for ( y = 0 ; y < 90 ; y++){
  ca: 2f 5f       subi r18, 0xFF ; 255
  cc: 2a 35       cpi r18, 0x5A ; 90
  ce: b9 f7       brne .-18     ; 0xbe <main+0x18>

//General short delays
void delay_ms(uint16_t x)
{
  uint8_t y, z;
  for ( ; x > 0 ; x--){
  d0: 01 97       sbiw r24, 0x01 ; 1
  d2: 11 f0       breq .+4       ; 0xd8 <main+0x32>
  d4: 20 e0       ldi r18, 0x00 ; 0
  d6: f3 cf       rjmp .-26     ; 0xbe <main+0x18>
PORTC = 0xFF;
PORTB = 0xFF;
PORTD = 0xFF;
delay_ms(500);

PORTC = 0x00;
  d8: 18 b8       out 0x08, r1 ; 8
PORTB = 0x00;
  da: 15 b8       out 0x05, r1 ; 5
PORTD = 0x00;
  dc: 1b b8       out 0x0b, r1 ; 11
  de: 84 ef       ldi r24, 0xF4 ; 244
  e0: 91 e0       ldi r25, 0x01 ; 1
  e2: 0b c0       rjmp .+22     ; 0xfa <main+0x54>
...
//General short delays
void delay_ms(uint16_t x)
{
  uint8_t y, z;
  for ( ; x > 0 ; x--){
    for ( y = 0 ; y < 90 ; y++){
  f0: 2f 5f       subi r18, 0xFF ; 255
  f2: 2a 35       cpi r18, 0x5A ; 90
  f4: b9 f7       brne .-18     ; 0xe4 <main+0x3e>

//General short delays
void delay_ms(uint16_t x)
{
  uint8_t y, z;
  for ( ; x > 0 ; x--){
  f6: 01 97       sbiw r24, 0x01 ; 1
  f8: e1 f2       breq .-72     ; 0xb2 <main+0xc>
  fa: 20 e0       ldi r18, 0x00 ; 0
  fc: f3 cf       rjmp .-26     ; 0xe4 <main+0x3e>

000000fe <_exit>:
  fe: f8 94       cli

00000100 <__stop_program>:
 100: ff cf       rjmp .-2       ; 0x100 <__stop_program>

From my somewhat crude understanding of this assembly,
We start out at 0x00, which has the JMP 0x68 instruction.
Immediately we jump to 0x68.  It looks like most of this is overhead associated with setting up the timer.
Eventually we make it down to 0x9A where we do a jump to 0xA6 <main>.
This is where our actual program starts.

I can follow it through from there.

So what happened to the CFEF instruction that was in the .hex file?  Am I using the wrong instruction set?

In the assembler, I see it listed as:

Code:
 6c: cf ef       ldi r28, 0xFF ; 255

Why is this coming up as a load immediate instead of an RJMP?!

LDI's opcode is
Code:
1110 KKKK dddd KKKK

0b'1110 = 0xE

Shouldn't this instruction start with E, not C?

29  Using Arduino / Microcontrollers / Re: Understanding the .hex file on: April 25, 2011, 04:09:08 pm
You're right, no need to disassemble if the original assembly listing still exists somewhere.  Any idea what it's named?

I've found the /Temp/build.../ directory where the code is compiled, but don't have anything that looks like assembly.

I have:

blink_1MHz.cpp         <--- the original source code.
blink_1MHz.cpp.eep   <--- just a single EOF record for the .hex file. 
blink_1MHz.cpp.elf     <--- Bunch of garbled text (Looks like it could be a raw hex file)
blink_1MHz.cpp.hex   <--- .hex file as shown earlier.
blink_1MHz.cpp.o      <--- object file
 
There's a few more .o files listed there, but I assume the object files aren't what I'm looking for.  I was expecting to find a .s or a .lss file, but didn't see one.
30  Using Arduino / Microcontrollers / Re: Understanding the .hex file on: April 25, 2011, 03:16:07 pm
Frank, thank you for your reply. 

Is there a program that will dis-assemble these .hex files?  Could you point me to one?

I will gladly run the disassembly and check what actual assembler instructions are being used.  Perhaps that will provide some clarity.
Pages: 1 [2] 3 4 ... 7