1. Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.
    Dismiss Notice

xmodem in hyperterminal

Discussion in 'Microcontrollers' started by AtomSoft, Sep 21, 2008.

  1. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    Im trying to add this function to my pic to download a file into memory. In hyper terminal it acts like the file was send and all is well but in pic there seems to be no data. Here is what i got so far:
    Code (text):

    void GetFile(char *buff){
        char i;    // Length counter
        unsigned char dat;

        while(!DataRdyUSART()){
            if(Btn01 == 1) //I press button to send first NAK to initiate transfer
                putcUSART(21);//sends NAK aka NCGByte
            Delayms(50); //debounce
        }
        i = 0;
    again:
            while(!DataRdyUSART());// Wait for data to be received

            dat = getcUSART();    // Get a character from the USART
                               // and save in the string

            if(dat == 4){  //The End of transmision byte
                putcUSART(21);  //NAK
                while(!DataRdyUSART());
                dat = getcUSART();

                if(dat == 4) //EOT
                    putcUSART(21);//NAK

            } else {
                *buff = dat;
                buff++;  
                i++;
                if(i==132){ //After the 132 Bytes come in 0-131
                    putcUSART(6); //ACK
                    i = 0; //set back to 0
                }
                goto again;
            }


    }
     
    Ill attach the info i have on xmodem also.
     

    Attached Files:

    Last edited: Sep 21, 2008
  2. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,022
    Likes:
    317
    Location:
    Brisbane Australia
    You need to add more comments to your code but my first question would be how is buff declared? And my second is why you have the termination code twice?

    Mike.
     
  3. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    Ok i commented better i hope:
    Code (text):
    void GetFile(char *buff){
      /*
      With each packet sent...

        The uploader sends:

        1. an SOH byte                             {1 byte}
        2. the packet number                       {1 byte}
        3. the 1's complement of the packet number {1 byte}
        4. the packet                            {128 bytes}
        5. the checksum                            {1 byte}
        The above five things are called the block.
        132 Bytes (0-131)
      */
        char i;    // Length counter
        unsigned char dat;

        while(!DataRdyUSART()){
            if(Btn01 == 1) //I press button to send first NAK to initiate transfer
                putcUSART(21);//sends NAK aka NCGByte and starts transfer
            Delayms(50); //debounce
        }
        i = 0;
    again:
            while(!DataRdyUSART());// Wait for data to be received

            dat = getcUSART();    // Get a character from the USART
                               // and save in the string

            if(dat == 4){  //The End of transmision byte
                putcUSART(21);  //Send a NAK and wait for another EOT

                while(!DataRdyUSART()); //Wait for data to come in
                dat = getcUSART();  //wait to receive a EOT

                if(dat == 4) // IF ITS A EOT
                    putcUSART(21);//SEND NAK

            } else {
                *buff = dat; // The buff is a char data[512];
                buff++;      // Increment Buff Pointer Position

                i++;         // increment i untill 132 which is the first byte of next packet
                if(i==132){ //After the 132 Bytes come in 0-131
                    putcUSART(6); //ACK
                    i = 0; //set back to 0
                }
                goto again;
            }


    }
    The answer to question 2 is:

    "When the uploader sends an EOT byte instead of an SOH byte, the downloader
    sends a NAK byte. If the uploader sends another EOT immediately after that,
    the downloader sends an ACK byte and the transfer is complete."
     
    Last edited: Sep 21, 2008
  4. dave

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    -
    Likes:
    0


     
  5. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,022
    Likes:
    317
    Location:
    Brisbane Australia

    The normal way to debug something like this would be to have a simple receive char routine that stores bytes at *buff++ and send a "hello world\n" string from your PC. Put a break point on when it receives a newline and see what you have. You will then know if your pic is receiving the data and if it is putting it in your buffer. If it is, then you move on to the next part.

    I just noticed the 50mS delay - this could be a very long time (byte transfered time) if you have a transfer rate greater than 300 baud.

    Mike.
    P.S. are you calling the routine with a ram char pointer as the parameter?
     
  6. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    Yes its in Ram. Also the delay is only in use when the transfer isnt. Its there to wait and debounce the button press. When i press the button it continues. Maybe i should remove it anyway. Thanks. I know i can get data because... well let me show you some more of the code

    Code (text):

    void ReadCmds (void){
        char inputstr[100] = {0};
        char badCmd = 1;
        char cmd_01[4] = {"cLed"};
        char cmd_02[4] = {"Menu"};
        char cmd_03[4] = {"File"};

        getUSARTString( inputstr, 4 );

        if(!memcmp(inputstr,cmd_03,4)){
            GetFile(data);
        }
        if(!memcmp(inputstr,cmd_01,4)){
            if (SigPassPort == 1){
                SigPass = 0;
                putrsUSART("\r\nGreen LED OFF!\r\n");
            } else {
                putrsUSART("\r\nGreen LED ON!\r\n");
                SigPass = 1;
            }
            badCmd = 0;
        }
        if(!memcmp(inputstr,cmd_02,5)){
            putrsUSART("\r\n");
            showMenu();
            badCmd = 0;        
        }

        if(badCmd == 1)
            putrsUSART("\r\nUnknown Command! Try Again.\r\n");
           
       
    }
     
    This is what i use to get commands.
     
  7. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,022
    Likes:
    317
    Location:
    Brisbane Australia
    If the delay is only for debounce, could I suggest you do,

    Code (text):

            if(Btn01 == 1) //I press button to send first NAK to initiate transfer
                putcUSART(21);//sends NAK aka NCGByte and starts transfer
            else
                Delayms(50); //debounce
     
    However, I know realise I don't understand why you wait for a byte to be available before you check for the button.

    Mike.
     
  8. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    its there to loop only lol so it will stay in the loop until data is comming in. But i guess i should change it also 1 minute ill change
     
  9. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    Wow thanks i got it working now.

    Code (text):

    void GetFile(char *buff){
      /*
      With each packet sent...

        The uploader sends:

        1. an SOH byte                             {1 byte}
        2. the packet number                       {1 byte}
        3. the 1's complement of the packet number {1 byte}
        4. the packet                            {128 bytes}
        5. the checksum                            {1 byte}
        The above five things are called the block.
        132 Bytes (0-131)
      */
        char i;    // Length counter
        unsigned char dat;
    sendit:
        while(1){
            if(Btn01 == 1){ //I press button to send first NAK to initiate transfer
                Delayms(10);
                putcUSART(21);//sends NAK aka NCGByte and starts transfer

                break;
            }
        }
        i = 0;
    again:
            putcUSART(6);
            while(!DataRdyUSART());// Wait for data to be received

            dat = getcUSART();    // Get a character from the USART
                               // and save in the string

            if(dat == 0x72){  //The End of transmision byte
                putcUSART(21);  //Send a NAK and wait for another EOT

                while(!DataRdyUSART()); //Wait for data to come in
                dat = getcUSART();  //wait to receive a EOT

                if(dat == 0x72) // IF ITS A EOT
                    putcUSART(21);//SEND NAK

            } else {
                *buff = dat; // The buff is a char data[512];
                buff++;      // Increment Buff Pointer Position

                i++;         // increment i untill 132 which is the first byte of next packet
                if(i==132){ //After the 132 Bytes come in 0-131
                    putcUSART(6); //ACK
                    i = 0; //set back to 0
                }
                goto again;
            }
    }
     
     
  10. Nigel Goodwin

    Nigel Goodwin Super Moderator Most Helpful Member

    Joined:
    Nov 17, 2003
    Messages:
    39,234
    Likes:
    641
    Location:
    Derbyshire, UK
    What are you actually trying to do?, HyperTerminal and Xmodem seems a completely bizarre method of doing it?. Are you wanting to upload new programming to the PIC, if so a bootloader would be a better idea (and freely available).

    Xmodem is intended for modem use (hence the name), with a piece of wire from the PC to the PIC you don't really need to use it.

    I wrote Xmodem code years and years ago, in Turbo Pascal under DOS (pre-Windows), for a Packet Radio program I wrote.
     
  11. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,022
    Likes:
    317
    Location:
    Brisbane Australia
    So, it was that innocent looking delay.

    Mike.
     
  12. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    Thanks Pommie ... Nigel i want to use this to send my pic some small binary / text files and have it store it on a SD card. I have it so far. Thanks for your interest. I always wanted to know what a bootloader was for. Can you give me a link to more info on that too thanks!
     
  13. Nigel Goodwin

    Nigel Goodwin Super Moderator Most Helpful Member

    Joined:
    Nov 17, 2003
    Messages:
    39,234
    Likes:
    641
    Location:
    Derbyshire, UK
    There are loads of bootloaders out there, and even examples in the MicroChip application notes, but here's the one I've always used.

    http://www.microchipc.com/
     

Share This Page