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

📄 main.c

📁 可用来自做的AVR-USB-ISP的源码,内符电路图,用AVR M8来模拟USB接口
💻 C
字号:
/************************************************************************************************ * Project: USB AVR-ISP * Author: Christian Ulrich
 * Contact: christian at ullihome dot de
 * * Creation Date: 2007-03-22 * Copyright: (c) 2007 by Christian Ulrich * License: GPLv2
 *
 * Changes:
 *  2007-07-12
 *      AVR910 protocol by Jens Aehle
 *	2007-05-25
 *	    Atmega88 compatibility
 *		CDC Rewrite
 *	    fix of RDY/BSY polling
 *  2007-05-03
 *		RS232 Hardwareinit corrected
 *	2007-04-28
 *		New USB Driver Version
 *		RS232 Logging
 *		Removed Menue for Bootloader Support  ***********************************************************************************************/
#include "config.h"

#include <avr/io.h>
#include <stdio.h>#include <string.h>#include <stdlib.h>#include <avr/pgmspace.h>
#include <avr/eeprom.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#include "usbdrv.h"
#include "usbconfig.h"
#include "usb_uart.h"
#ifdef HASMENUE
  #include "vt100.h"
  #include "menue.h"
#endif
#include "isp.h"
#include "led.h"
#include "timer.h"
#include "stk500protocol.h"
#include "avr910protocol.h"
#include "main.h"

#define PROTOCOL_STK500 0
#define PROTOCOL_AN910  1

#if defined(HAS_STK500_PROTOCOL) && defined(HAS_AVR910_PROTOCOL)
uint8_t eeProtocolType EEMEM = PROTOCOL_STK500;
uint8_t ProtocolType;
#endif
uint8_t eeispSpeed EEMEM = 1;

#ifdef HASMENUE
void ShowInfo(void);
#ifdef HAS_ISP_SPEEDSETTING
  void opSetSpeed(void) {ISP_Speed = MENUE_entry-4;eeprom_write_byte(&eeispSpeed,ISP_Speed);MENUE_prevlevel();}
  void opAutodetectSpeed(void);
#endif
#ifdef HAS_STK500_PROTOCOL
void SetSTK500Ver(void);
#endif

const struct menueentry_t menue[] PROGMEM = 
	{
	  {0,"Menu"},
#ifdef HAS_INFO
		{1,"Show Info",ShowInfo},
#endif
#ifdef HAS_ISP_SPEEDSETTING
        {1,"ISP Speed"},
  	      {2,"Autodetect",opAutodetectSpeed},
	      {2,"1 khz",opSetSpeed},
	      {2,"93,75 khz",opSetSpeed},
	      {2,"187,5 khz",opSetSpeed},
	      {2,"375 khz",opSetSpeed},
	      {2,"750 khz",opSetSpeed},
	      {2,"1,5 Mhz",opSetSpeed},
	      {2,"3 Mhz",opSetSpeed},
#endif
#ifdef HAS_STK500_PROTOCOL
		  {1,"STK500 SW Ver",SetSTK500Ver},
#endif
	};

const int MENUE_size = sizeof(menue);

#endif

#ifndef USBASP_COMPATIBLE
  #ifndef CCCB_COMPATIBLE
led_t leds[] =  {{4,LED_OFF,LED_OFF},
                 {3,LED_OFF,LED_OFF},
                 {5,LED_OFF,LED_OFF}}; 
  #else //CCCB_COMPATIBLE
led_t leds[] =  {{2,LED_OFF,LED_OFF},
                 {3,LED_OFF,LED_OFF}, //not there
                 {5,LED_OFF,LED_OFF}};//not there 
  #endif
#else 
led_t leds[] =  {{0,LED_OFF,LED_OFF},
                 {1,LED_OFF,LED_OFF},
                 {3,LED_OFF,LED_OFF}}; 
#endif
const uint8_t led_count = sizeof(leds)/sizeof(led_t);

#if defined(HASMENUE)
uint8_t inmenue = 0;
#endif

void Oncharrecived(uint8_t c)
{
  leds[LED_BLUE].counter = 10; 
  leds[LED_BLUE].frequency = LED_FLASH_NEG;
#if defined(HASMENUE)
 #if defined(HAS_STK500_PROTOCOL)
   if (STK500_Status == PGM_STATUS_IDLE)
 #endif
 #if defined(HAS_AVR910_PROTOCOL)
   if (AVR910_Status == PGM_STATUS_IDLE)
 #endif
     {
       if      ((inmenue == 0) && (c == 'm')) inmenue++;
       else if ((inmenue == 1) && (c == 'e')) inmenue++;
       else if ((inmenue == 2) && (c == 'n')) inmenue++;
       else if ((inmenue == 3) && (c == 'u')) inmenue++;
       else if ((inmenue == 4) && (c == 'e')) inmenue++;
       else if ((inmenue == 5) && (c == 0xD))
         {
           inmenue++;
           MENUE_init();
           MENUE_update();
           CDC_charrecived = NULL;
           leds[LED_BLUE].frequency = 100;
         }
       else
         inmenue = 0;
     }  
#endif
#ifdef HAS_STK500_PROTOCOL
   STK500_byterecived(c);
#endif
 #if defined(HAS_STK500_PROTOCOL)
   if (STK500_Status == PGM_STATUS_IDLE)
 #endif
 #if defined(HAS_AVR910_PROTOCOL)
   if (AVR910_Status == PGM_STATUS_IDLE)
 #endif
 #ifdef HAS_MENUE
   if (inmenue<6)
 #endif 
     {
#if defined(__AVR_ATmega88__) || defined(__AVR_ATmega168__)
       while (!(UCSR0A & (1<<UDRE0)));
       UDR0 = c;
#else
       while (!(UCSRA & (1<<UDRE)));
       UDR = c;
#endif
     }
}

void Onispstatuschanged(uint8_t status)
{
  leds[LED_GREEN].frequency = LED_OFF;
  leds[LED_RED].frequency = LED_OFF;
  switch(status)
    {
	  case ISP_STATUS_CONNECTED_OK:
        leds[LED_GREEN].frequency = LED_ON;
		break;
	  case ISP_STATUS_CONNECTED_NOT_OK:
        leds[LED_RED].frequency = 50;
		break;
	}
}

void OnPGMstatuschanged(uint8_t status)
{
  if (status == PGM_STATUS_PROGRAMMING)
    {
	  eeprom_write_byte(&eeispSpeed,ISP_Speed);
	  leds[LED_RED].frequency = 30;
	  leds[LED_GREEN].frequency = LED_OFF;
    }
  else
    Onispstatuschanged(ISP_Status);	  
}

void uartDisconnect(void)
{
  #ifdef HAS_MENUE
  inmenue = 0;
  #endif
  CDC_charrecived = Oncharrecived;
  leds[LED_BLUE].frequency = LED_OFF;
}

void uartReset(void)
{
  leds[LED_BLUE].frequency = LED_ON;
  uint16_t baudrate = (CDC_mode[1]<<8)+CDC_mode[0];
  baudrate = ((F_CPU)/(( baudrate )*16l)-1);
#if defined(__AVR_ATmega88__) || defined(__AVR_ATmega168__)
  UCSR0B  = 0;  UBRR0H = (uint8_t)(baudrate>>8);
  UBRR0L = (uint8_t) baudrate;
  UCSR0B = (1<<RXEN0) | (1<<TXEN0) | (1<<RXCIE0);
#else
  UCSRB  = 0;  UBRRH = (uint8_t)(baudrate>>8);
  UBRRL = (uint8_t) baudrate;
  UCSRB = (1<<RXEN) | (1<<TXEN) | (1<<RXCIE);
#endif
}

#if defined(__AVR_ATmega88__) || defined(__AVR_ATmega168__)
ISR(USART_RX_vect)
#else
ISR(USART_RXC_vect)
#endif
{
 #if defined(HAS_STK500_PROTOCOL)
   if (STK500_Status == PGM_STATUS_IDLE)
 #endif
 #if defined(HAS_AVR910_PROTOCOL)
   if (AVR910_Status == PGM_STATUS_IDLE)
 #endif
 #ifdef HAS_MENUE  
   if (inmenue<6)
 #endif
#if defined(__AVR_ATmega88__) || defined(__AVR_ATmega168__)
     UART_putc(UDR0);
#else
     UART_putc(UDR);
#endif
}

int main(void)
{
  uint8_t i;
#if defined(HAS_STK500_PROTOCOL) && defined(HAS_AVR910_PROTOCOL)
  ProtocolType = eeprom_read_byte(&eeProtocolType);
#endif
  ISP_Speed = eeprom_read_byte(&eeispSpeed);
  if ((ISP_Speed < 1) | (ISP_Speed > 7))
    ISP_Speed = 5;
#if defined(HAS_AVR910_PROTOCOL) && defined(HAS_STK500_PROTOCOL)
  if (ProtocolType == PROTOCOL_AN910)
#endif
#if defined(HAS_AVR910_PROTOCOL)
    AVR910_init();
#endif
#if defined(HAS_AVR910_PROTOCOL) && defined(HAS_STK500_PROTOCOL)
  else
#endif
#if defined(HAS_STK500_PROTOCOL)
    STK500_init();
#endif
  leds[LED_RED].frequency = LED_ON;
  LED_init();
  for (i=0;i<3;i++)
    TIMER_delay(250);
  CDC_charrecived = Oncharrecived;
  CDC_init();
  ISP_statuschanged = Onispstatuschanged;
  PGM_statuschanged = OnPGMstatuschanged;
  leds[LED_RED].frequency = LED_OFF;
  CDC_ondisconnect = uartDisconnect;
  CDC_uartreset = uartReset;  

  while(1)
    {
	  MAIN_tasks();
	}
}

void MAIN_tasks(void)
{
#ifdef HASMENUE
  uint16_t c;
#endif
  MAIN_critical_tasks();
  ISP_checkstatus();
  LED_poll();
#ifdef HASMENUE
  if (inmenue == 6)
    {
      c = UART_getc();
      if (c >> 8 == 0)
        MENUE_task(c);
    }
#endif
}

void MAIN_critical_tasks(void)
{
  CDC_poll();
}

#ifdef HASMENUE

#ifdef HAS_STK500_PROTOCOL
void PrintSTK500Ver(void)
{
  char version[3];
  Term_Set_Cursor_Position(13,39);
  itoa(STK500_Param.s.softwareVersionMajor,version,16);
  if (strlen(version) == 1)
    UART_putc(0x20);
  UART_puts(version);
  UART_puts_P(PSTR ("."));
  itoa(STK500_Param.s.softwareVersionMinor,version,16);
  if (strlen(version) == 1)
    UART_putc('0');
  UART_puts(version);
}

void SetSTK500Ver(void)
{
  uint16_t c;
  Term_Set_Display_Colour(COL_BACKGROUND,COL_BLUE);
#ifdef HAS_ISP_SPEEDSETTING
  Term_Draw_Window(menue[12].name,29,10,14,3);
#else
  Term_Draw_Window(menue[3].name,29,10,14,3);
#endif
  Term_Set_Cursor_Position(13,30);
  UART_puts_P(PSTR ("Version:"));
  PrintSTK500Ver();
  while (inmenue == 6)
    {
	  c = UART_getc();
      if ((c & 0xFF00) >> 8 == 0)
	    {
		  c = MENUE_is_key(c);
		  if (c == KEY_next)
		    {
			  if (STK500_Param.s.softwareVersionMinor < 0xff)
			    STK500_Param.s.softwareVersionMinor++;
              else 
			    {
  			      STK500_Param.s.softwareVersionMajor++;
   			      STK500_Param.s.softwareVersionMinor = 0;
				}
              PrintSTK500Ver();
			}
		  else if (c == KEY_back)
		    {
			  if (STK500_Param.s.softwareVersionMinor > 0)
			    STK500_Param.s.softwareVersionMinor--;
              else 
			    {
  			      STK500_Param.s.softwareVersionMajor--;
   			      STK500_Param.s.softwareVersionMinor = 0xff;
				}
              PrintSTK500Ver();
			}
		  else if (c == KEY_ok)
		  	{
			  STK500_save();
              return;
			} 	 
		}
      CDC_poll();
	}
}
#endif

#ifdef HAS_INFO

void ShowInfo(void)
{
  uint8_t signature[3];
  uint8_t i;
  char out[3];
  Term_Set_Display_Colour(COL_BACKGROUND,COL_BLUE);
  Term_Draw_Window(PSTR ("Target Information:"),20,7,40,5);
  Term_Set_Cursor_Position(10,21);
  signature[1] = 0x79;
  UART_puts_P(PSTR ("Device bits:"));
  ISP_connect();
  if (ISP_enterprogrammingmode() == 1)
    {
	  UART_puts_P(PSTR ("no device !"));
	}
  else
    {
	  for (i=0;i<3;i++)
	    {
		  signature[i] = ISP_readsignaturebyte(i);          itoa(signature[i],out,16);
          UART_puts(out);
		  if (i!=2)            UART_puts_P(PSTR (","));        }
      Term_Set_Cursor_Position(11,21);
      UART_puts_P(PSTR ("Manufacturer:"));
      if (signature[0] ==0x1e)
	    UART_puts_P(PSTR ("Atmel"));
      else
        UART_puts_P(PSTR ("Unknown"));
      Term_Set_Cursor_Position(12,21);
      UART_puts_P(PSTR ("Flash Memory:"));
      itoa(1<<(signature[1]-0x90),out,10);
      UART_puts(out);
      UART_puts_P(PSTR ("k"));
    }  ISP_disconnect();  
#ifdef HAS_ISP_SPEEDSETTING
  Term_Draw_Window(PSTR ("Programmer Information"),20,17,40,3);
  Term_Set_Cursor_Position(20,21);
  UART_puts_P(PSTR ("ISP Frequency:"));
  UART_puts_P(menue[4+ISP_Speed].name);
#endif
  while (((UART_getc() & 0xFF) != 0xD) && (inmenue == 6))
    CDC_poll();
}

#endif

#ifdef HAS_ISP_SPEEDSETTING

uint8_t TryISPSpeed(uint8_t speed)
{
  ISP_Speed = speed;
  ISP_connect();
  if (ISP_enterprogrammingmode() == 1)
    {
	  UART_puts_P(PSTR ("failed !"));
      ISP_disconnect();  
	  return 1;
	}
  else
    {
	  UART_puts_P(PSTR ("ok !"));
	  eeprom_write_byte(&eeispSpeed,ISP_Speed);
      ISP_disconnect();  
	  return 0;
    }}

char strtrying[] PROGMEM = "Trying "; 

void opAutodetectSpeed(void)
{
  uint8_t i;
  Term_Set_Display_Colour(COL_BACKGROUND,COL_BLUE);
  Term_Draw_Window(menue[3].name,20,8,40,10);
  Term_Set_Cursor_Position(8,21);
  for (i=7;i>0;i--)
    {
      Term_Set_Cursor_Position(11+(7-i),21);
      UART_puts_P(strtrying);
      UART_puts_P(menue[4+i].name);
      UART_putc(0x20);
      if (TryISPSpeed(i) == 0) break; 
    } 
  CDC_charrecived = NULL;
  while (((UART_getc() & 0xFF) != 0xD) && (inmenue == 6))
    CDC_poll();
} 

#endif

#endif

uint8_t usbFunctionSetup(uint8_t data[8]){
  return CDC_usbFunctionSetup(data);
}
uint8_t usbFunctionRead( uint8_t *data, uint8_t len ){
  return CDC_usbFunctionRead(data,len);}uint8_t usbFunctionWrite( uint8_t *data, uint8_t len ){  return CDC_usbFunctionWrite(data,len);
}void usbFunctionWriteOut( uint8_t *data, uint8_t len ){  return CDC_usbFunctionWriteOut(data,len);}
uint8_t usbFunctionDescriptor(usbRequest_t *rq)
{
  return CDC_usbFunctionDescriptor(rq);
}

⌨️ 快捷键说明

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