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

📄 main.c

📁 基于MEGA8单片机的AVR单片机STK500编程器源代码(GCC编译器),改软件完全实现ATMEL STK500协议
💻 C
📖 第 1 页 / 共 2 页
字号:
                  spi_transfer_8(msg_buffer[5]|(1<<3));
                }
              else
                {
                  spi_transfer_8(msg_buffer[5]);
                }

              spi_transfer_16(address&0xFFFF);
              spi_transfer_8(msg_buffer[i+10]);

              //Check if we can do polling
              if (msg_buffer[8]!=msg_buffer[i+10])
                {
                  //We have to check if we have an uneven byte.
                  //Set the polling address to a byte address
                  //so that we can poll the right location
                  polling_address = (address&0xFFFF)*2;
                  if (i&1) polling_address++;
                }

              //increment (word) address only when we have an uneven (byte) address
              if (i&1) address++;
            }

          //If this page is complete the bit 7 of mode will be set and we programm the page
          if (mode&0x80)
            {
              spi_transfer_8(msg_buffer[6]);
              spi_transfer_16(start_address&0xFFFF);
              spi_transfer_8(0);

              //If we have no valid polling address switch to simple wait mode
              if (polling_address==0)
                {
                  mode = (mode&(~0x70)) | 0x10;
                }

              //Different polling methods
              //Hard waiting
              if ((mode&0x70) == 0x10)
                {
                  wait_ms(msg_buffer[4]);
                }
              //Data polling
              else if ((mode&0x70) == 0x20)
                {
                  do
                    {
                      //If we have an uneven byte read the
                      //high byte
                      if (polling_address%2)
                        {
                          spi_transfer_8(msg_buffer[7]|(1<<3));
                        }
                      else
                        {
                          spi_transfer_8(msg_buffer[7]);
                        }
                      spi_transfer_16(polling_address/2);
                      tmp=spi_transfer_8(0x00);
                    }
                  while (tmp==msg_buffer[8]);
                }
              //RDY/BSY polling
              else if ((mode&0x70) == 0x40)
                {
                  while (spi_transfer_32(0xF0000000)&1);
                }
              //If something was not correct with the given mode do
              //hard waiting. Should never reach this point
              else
                {
                  wait_ms(msg_buffer[4]);
                }
            }
        }

      num_bytes = 2;
      msg_buffer[0] = CMD_PROGRAM_FLASH_ISP;
      msg_buffer[1] = STATUS_CMD_OK;
    }
  //////////////////////////////////////
  //CMD_READ_FLASH_ISP
  //////////////////////////////////////
  else if (cmd==CMD_READ_FLASH_ISP)
    {
      block_size = ((unsigned int)msg_buffer[1])<<8;
      block_size |= msg_buffer[2];
      tmp = msg_buffer[3];

      for (i=0;i<block_size;i++)
        {
          //Select Low or High-Byte
          if (i&1)
            {
              spi_transfer_8(tmp|(1<<3));
            }
          else
            {
              spi_transfer_8(tmp);
            }

          spi_transfer_16(address&0xFFFF);
          msg_buffer[i+2] = spi_transfer_8(0);

          //increment (word) address only when we have an uneven (byte) address
          if (i&1) address++;
        }

      num_bytes = block_size+3;
      msg_buffer[0] = CMD_READ_FLASH_ISP;
      msg_buffer[1] = STATUS_CMD_OK;
      msg_buffer[block_size+2] = STATUS_CMD_OK;
    }
  //////////////////////////////////////
  //CMD_PROGRAM_EEPROM_ISP
  //////////////////////////////////////
  else if (cmd==CMD_PROGRAM_EEPROM_ISP)
    {
      block_size = ((unsigned int)msg_buffer[1])<<8;
      block_size |= msg_buffer[2];
      mode = msg_buffer[3];

      //Byte Mode
      if ((mode&1) == 0)
        {
          for (i=0;i<block_size;i++)
            {
              spi_transfer_8(msg_buffer[5]);
              spi_transfer_16(address&0xFFFF);
              spi_transfer_8(msg_buffer[i+10]);

              //Check if we can do polling
              if ((msg_buffer[i+10]!=msg_buffer[8])&&(msg_buffer[i+10]!=msg_buffer[9]))
                {
                  polling_address = address&0xFFFF;
                }
              //If not switch the mode hard waiting
              else
                {
                  mode = (mode&(~0x0E)) | 0x02;
                }

              //Different polling methods
              //Hard waiting
              if ((mode&0x0E) == 0x02)
                {
                  wait_ms(msg_buffer[4]);
                }
              //Data polling
              else if ((mode&0x0E) == 0x04)
                {
                  do
                    {
                      spi_transfer_8(msg_buffer[7]);
                      spi_transfer_16(polling_address);
                      tmp=spi_transfer_8(0x00);
                    }
                  while ((tmp==msg_buffer[8])||(tmp==msg_buffer[9]));
                }
              //RDY/BSY polling
              else if ((mode&0x0E) == 0x08)
                {
                  while (spi_transfer_32(0xF0000000)&1);
                }
              //If something was not correct with the given mode do
              //hard waiting. Should never reach this point
              else
                {
                  wait_ms(msg_buffer[4]);
                }

              //increment address
              address++;
            }
        }
      //Page Mode
      else
        {
          for (i=0;i<block_size;i++)
            {
              spi_transfer_8(msg_buffer[5]);
              spi_transfer_16(address&0xFFFF);
              spi_transfer_8(msg_buffer[i+10]);

              //Check if we can do polling
              if ((msg_buffer[i+10]!=msg_buffer[8])&&(msg_buffer[i+10]!=msg_buffer[9]))
                {
                  polling_address = address&0xFFFF;
                }

              //increment (word) address only when we have an uneven (byte) address
              address++;
            }

          //If this page is complete the bit 7 of mode will be set and we programm the page
          if (mode&0x80)
            {
              spi_transfer_8(msg_buffer[6]);
              spi_transfer_16(start_address&0xFFFF);
              spi_transfer_8(0);

              //If we have no valid polling address switch to simple wait mode
              if (polling_address==0)
                {
                  mode = (mode&(~0x70)) | 0x10;
                }

              //Different polling methods
              //Hard waiting
              if ((mode&0x70) == 0x10)
                {
                  wait_ms(msg_buffer[4]);
                }
              //Data polling
              else if ((mode&0x70) == 0x20)
                {
                  do
                    {
                      //If we have an uneven byte read the
                      //high byte
                      if (i&1)
                        {
                          spi_transfer_8(msg_buffer[7]|(1<<3));
                        }
                      else
                        {
                          spi_transfer_8(msg_buffer[7]);
                        }
                      spi_transfer_16(polling_address);
                      tmp=spi_transfer_8(0x00);
                    }
                  while (tmp==msg_buffer[8]);
                }
              //RDY/BSY polling
              else if ((mode&0x70) == 0x40)
                {
                  while (spi_transfer_32(0xF0000000)&1);
                }
              //If something was not correct with the given mode do
              //hard waiting. Should never reach this point
              else
                {
                  wait_ms(msg_buffer[4]);
                }
            }
        }

      num_bytes = 2;
      msg_buffer[0] = CMD_PROGRAM_EEPROM_ISP;
      msg_buffer[1] = STATUS_CMD_OK;
    }

  //////////////////////////////////////
  //CMD_READ_EEPROM_ISP
  //////////////////////////////////////
  else if (cmd==CMD_READ_EEPROM_ISP)
    {
      block_size = ((unsigned int)msg_buffer[1])<<8;
      block_size |= msg_buffer[2];
      tmp = msg_buffer[3];

      for (i=0;i<block_size;i++)
        {
          //Select Low or High-Byte
          spi_transfer_8(tmp);
          spi_transfer_16(address&0xFFFF);
          msg_buffer[i+2] = spi_transfer_8(0);

          //increment address
          address++;
        }

      num_bytes = block_size+3;
      msg_buffer[0] = CMD_READ_EEPROM_ISP;
      msg_buffer[1] = STATUS_CMD_OK;
      msg_buffer[block_size+2] = STATUS_CMD_OK;
    }


  //////////////////////////////////////
  //CMD_PROGRAM_FUSE_ISP
  //////////////////////////////////////
  else if (cmd==CMD_PROGRAM_FUSE_ISP)
    {
      tmp = spi_transfer_8(msg_buffer[1]);
      tmp = spi_transfer_8(msg_buffer[2]);
      tmp = spi_transfer_8(msg_buffer[3]);
      tmp = spi_transfer_8(msg_buffer[4]);

      num_bytes = 3;
      msg_buffer[0] = CMD_PROGRAM_FUSE_ISP;
      msg_buffer[1] = STATUS_CMD_OK;
      msg_buffer[2] = STATUS_CMD_OK;
    }
  //////////////////////////////////////
  //CMD_READ_FUSE_ISP
  //////////////////////////////////////
  else if (cmd==CMD_READ_FUSE_ISP)
    {
      tmp = spi_transfer_8(msg_buffer[2]);
      if (msg_buffer[1] == 1) msg_buffer[2] = tmp;
      tmp = spi_transfer_8(msg_buffer[3]);
      if (msg_buffer[1] == 2) msg_buffer[2] = tmp;
      tmp = spi_transfer_8(msg_buffer[4]);
      if (msg_buffer[1] == 3) msg_buffer[2] = tmp;
      tmp = spi_transfer_8(msg_buffer[5]);
      if (msg_buffer[1] == 4) msg_buffer[2] = tmp;

      num_bytes = 4;
      msg_buffer[0] = CMD_READ_FUSE_ISP;
      msg_buffer[1] = STATUS_CMD_OK;
      msg_buffer[3] = STATUS_CMD_OK;
    }
  //////////////////////////////////////
  //CMD_PROGRAM_LOCK_ISP
  //////////////////////////////////////
  else if (cmd==CMD_PROGRAM_LOCK_ISP)
    {
      tmp = spi_transfer_8(msg_buffer[1]);
      tmp = spi_transfer_8(msg_buffer[2]);
      tmp = spi_transfer_8(msg_buffer[3]);
      tmp = spi_transfer_8(msg_buffer[4]);

      num_bytes = 3;
      msg_buffer[0] = CMD_PROGRAM_LOCK_ISP;
      msg_buffer[1] = STATUS_CMD_OK;
      msg_buffer[2] = STATUS_CMD_OK;
    }
  //////////////////////////////////////
  //CMD_READ_LOCK_ISP
  //////////////////////////////////////
  else if (cmd==CMD_READ_LOCK_ISP)
    {
      tmp = spi_transfer_8(msg_buffer[2]);
      if (msg_buffer[1] == 1) msg_buffer[2] = tmp;
      tmp = spi_transfer_8(msg_buffer[3]);
      if (msg_buffer[1] == 2) msg_buffer[2] = tmp;
      tmp = spi_transfer_8(msg_buffer[4]);
      if (msg_buffer[1] == 3) msg_buffer[2] = tmp;
      tmp = spi_transfer_8(msg_buffer[5]);
      if (msg_buffer[1] == 4) msg_buffer[2] = tmp;

      num_bytes = 4;
      msg_buffer[0] = CMD_READ_LOCK_ISP;
      msg_buffer[1] = STATUS_CMD_OK;
      msg_buffer[3] = STATUS_CMD_OK;
    }
  //////////////////////////////////////
  //CMD_READ_SIGNATURE_ISP
  //////////////////////////////////////
  else if (cmd==CMD_READ_SIGNATURE_ISP)
    {
      tmp = spi_transfer_8(msg_buffer[2]);
      if (msg_buffer[1] == 1) msg_buffer[2] = tmp;
      tmp = spi_transfer_8(msg_buffer[3]);
      if (msg_buffer[1] == 2) msg_buffer[2] = tmp;
      tmp = spi_transfer_8(msg_buffer[4]);
      if (msg_buffer[1] == 3) msg_buffer[2] = tmp;
      tmp = spi_transfer_8(msg_buffer[5]);
      if (msg_buffer[1] == 4) msg_buffer[2] = tmp;

      num_bytes = 4;
      msg_buffer[0] = CMD_READ_SIGNATURE_ISP;
      msg_buffer[1] = STATUS_CMD_OK;
      msg_buffer[3] = STATUS_CMD_OK;
    }
  //////////////////////////////////////
  //CMD_READ_OSCCAL_ISP
  //////////////////////////////////////
  else if (cmd==CMD_READ_OSCCAL_ISP)
    {
      tmp = spi_transfer_8(msg_buffer[2]);
      if (msg_buffer[1] == 1) msg_buffer[2] = tmp;
      tmp = spi_transfer_8(msg_buffer[3]);
      if (msg_buffer[1] == 2) msg_buffer[2] = tmp;
      tmp = spi_transfer_8(msg_buffer[4]);
      if (msg_buffer[1] == 3) msg_buffer[2] = tmp;
      tmp = spi_transfer_8(msg_buffer[5]);
      if (msg_buffer[1] == 4) msg_buffer[2] = tmp;

      num_bytes = 4;
      msg_buffer[0] = CMD_READ_OSCCAL_ISP;
      msg_buffer[1] = STATUS_CMD_OK;
      msg_buffer[3] = STATUS_CMD_OK;
    }
  //////////////////////////////////////
  //CMD_SPI_MULTI
  //////////////////////////////////////
  else if (cmd==CMD_SPI_MULTI)
    {
      unsigned char bytes_to_transmit;
      unsigned char tx_bytes = msg_buffer[1];
      unsigned char rx_bytes = msg_buffer[2];
      unsigned char rx_from = msg_buffer[3];

      //When there are more bytes to receive than to transmit
      if (tx_bytes < rx_bytes)
        {
          bytes_to_transmit = rx_bytes;
        }
      else
        {
          bytes_to_transmit = tx_bytes;
        }

      i = 0;
      num_bytes = 0;
      do
        {
          if (tx_bytes > 0)
            {
              tmp = spi_transfer_8(msg_buffer[i+4]);
            }
          else
            {
              tmp = spi_transfer_8(0);
            }

          if (rx_from == 0)
            {
              msg_buffer[2 + num_bytes] = tmp;
              num_bytes++;
            }
          else
            {
              rx_from--;
            }

          i++;
          tx_bytes--;
        }
      while (--bytes_to_transmit);

      num_bytes += 3;
      msg_buffer[0] = CMD_SPI_MULTI;
      msg_buffer[1] = STATUS_CMD_OK;
      msg_buffer[num_bytes-1] = STATUS_CMD_OK;
    }

  //////////////////////////////////////
  //Transmission of the result
  //////////////////////////////////////
  if (num_bytes>0)
    {
      interface_putc(MESSAGE_START);
      interface_putc(seq_num);
      interface_put16(num_bytes);
      interface_putc(TOKEN);
      for (i=0;i<num_bytes;i++)
        {
          interface_putc(msg_buffer[i]);
        }
      interface_send_check();
    }
}


/**
	Hardware initialization
	Timer
	ADC
*/
void chip_init(void)
{
  DDRB = 0;
  DDRC = 0;
  DDRD = 0;

  PORTB = 0;
  PORTC = 0;
  PORTD = 0;

  DDRB=(1<<0)|(1<<1)|(1<<2);	
  DDRC=(1<<0)|(1<<1)|(1<<2);	//LED_RT, LED_GN

  //ADC
  ADMUX=0x60;					//Avcc=Aref, Left Adjusted (8Bit-Aufl鰏ung aus ADCH)
  ADCSRA = 0xC6;				//ADC Enable, Init, 125kHz (bei 8MHz Clock)

  //Timer 1 (Systemint 1ms)
  TCCR1B=0x09;				//CTC-Mode /1
  OCR1A=(F_CPU/1000);					//8MHz / 8000 = 1kHz
  TIMSK|=(1<<OCIE1A);			//enable OC-INT
}

⌨️ 快捷键说明

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