⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmodem.c

📁 Henriks AVR Boot Loader for AVR ATMEGA88 with xmodem and autoboot
💻 C
字号:
/*
xmodem.c

For specification see:
http://www.atmel.com/dyn/resources/prod_documents/doc1472.pdf
http://www.avrfreaks.net/index.php?module=Freaks%20Academy&func=viewItem&item_id=200&item_type=project


Change history:


2007-03-15
Adapted for ATMEGA88.
/Henrik Bjorkman

*/


#include <stdio.h>
#include <inttypes.h>
#include <avr/io.h>
#include <avr/boot.h>
#include <setjmp.h>
#include "avr_cfg.h"
#include "avr_uart.h"


#define XMODEM_BUFFER_SIZE 128+SPM_PAGESIZE

#define XMODEM_SOH 0x01 // Start of header
#define XMODEM_EOT 0x04 // End of transmission
#define XMODEM_ACK 0x06 // Acknowledge
#define XMODEM_NACK 0x15 // Not acknowledge
#define XMODEM_RRC 'C' // Ready to receive with CRC

#define XMODEM_TIMERCOUNT_RESTART_VALUE 3000L*(AVR_FOSC/1000000L)



inline int xmodem_crc(unsigned char *ptr, int count)
{
  int crc=0;
  while (--count >= 0)
  {
    crc = crc ^ (int) *ptr++ << 8;
    char i = 8;
    do
    {
      if (crc & 0x8000)
      {
        crc = crc << 1 ^ 0x1021;
      }
      else
      {
        crc = crc << 1;
      }
    } while(--i);
  }
  return (crc);
}



int xmodem(void)
{
  int timercount=0;
  unsigned char packetNumber=1;
  unsigned int programMemoryPtr=0;
  unsigned char data[XMODEM_BUFFER_SIZE];
  unsigned int dataPtr=0;

  while(uart_getchar()!=XMODEM_SOH)
  {
    if (timercount==0)
    {
      uart_putchar(XMODEM_RRC);
      timercount=XMODEM_TIMERCOUNT_RESTART_VALUE;
    }
    else
    {
      timercount--;
    }
  }


  do
  {

    if(packetNumber==(char)uart_waitchar())
    {
      if(packetNumber==(unsigned char)(~uart_waitchar()))
      {
        unsigned int crc;
        int i;
        int j;
        for(i=0;i<128;i++)
        {
          data[dataPtr]=(unsigned char)uart_waitchar();  
          dataPtr++;  
        }
        crc=(uart_waitchar()<<8);
        crc+=uart_waitchar();
        if(xmodem_crc(&data[dataPtr-128],128)==crc)
        {
          while(dataPtr>=SPM_PAGESIZE)
          {
          #if 1
            boot_page_erase(programMemoryPtr);
            while(boot_rww_busy())
            {
              boot_rww_enable();
            }
            for(i=0;i<SPM_PAGESIZE;i+=2)
            {
              boot_page_fill(programMemoryPtr%SPM_PAGESIZE,data[i]+(data[i+1]<<8));
              programMemoryPtr+=2;
            }  
            boot_page_write(programMemoryPtr-1);
            while(boot_rww_busy())
            {
              boot_rww_enable();
            }
          #else
            i=SPM_PAGESIZE;
          #endif
            for(j=0;i<dataPtr;i++,j++)
            {
              data[j]=data[i];
            }
            dataPtr=j;
          }  
          uart_putchar(XMODEM_ACK);
          packetNumber++;
        }
        else
        {
          uart_putchar(XMODEM_NACK);
        }
      }
    }
    else
    {
      uart_putchar(XMODEM_NACK);
    }
  }while(uart_waitchar()!=XMODEM_EOT);
  uart_putchar(XMODEM_ACK);
  
  return 0;
}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -