Пример #1
0
void StartSketch(void)
{
	cli();
	
	/* Undo TIMER1 setup and clear the count before running the sketch */
	TIMSK1 = 0;
	TCCR1B = 0;
	// MAH 8/15/12 this clear is removed to save memory. Okay, it
	//   introduces some inaccuracy in the timer in the sketch, but
	//   not enough that it really matters.
	//TCNT1H = 0;		// 16-bit write to TCNT1 requires high byte be written first
	//TCNT1L = 0;
	
	/* Relocate the interrupt vector table to the application section */
	MCUCR = (1 << IVCE);
	MCUCR = 0;

	L_LED_OFF();
	TX_LED_OFF();
	RX_LED_OFF();

	/* jump to beginning of application space */
	__asm__ volatile("jmp 0x0000");
	
}
Пример #2
0
/** Configures all hardware required for the bootloader. */
void SetupHardware(void)
{
	/* Disable watchdog if enabled by bootloader/fuses */
	MCUSR &= ~(1 << WDRF);
	wdt_disable();

	/* Disable clock division */
	clock_prescale_set(clock_div_1);

	/* Relocate the interrupt vector table to the bootloader section */
	MCUCR = (1 << IVCE);
	MCUCR = (1 << IVSEL);
	
	LED_SETUP();
	CPU_PRESCALE(0); 
	L_LED_OFF();
	TX_LED_OFF();
	RX_LED_OFF();
	
	/* Initialize TIMER1 to handle bootloader timeout and LED tasks.  
	 * With 16 MHz clock and 1/64 prescaler, timer 1 is clocked at 250 kHz
	 * Our chosen compare match generates an interrupt every 1 ms.
	 * This interrupt is disabled selectively when doing memory reading, erasing,
	 * or writing since SPM has tight timing requirements.
	 */ 
	OCR1AH = 0;
	OCR1AL = 250;
	TIMSK1 = (1 << OCIE1A);					// enable timer 1 output compare A match interrupt
	TCCR1B = ((1 << CS11) | (1 << CS10));	// 1/64 prescaler on timer 1 input

	/* Initialize USB Subsystem */
	USB_Init();
}
Пример #3
0
//uint16_t ctr = 0;
ISR(TIMER1_COMPA_vect, ISR_BLOCK)
{
	/* Reset counter */
	TCNT1H = 0;
	TCNT1L = 0;

	/* Check whether the TX or RX LED one-shot period has elapsed.  if so, turn off the LED */
	if (TxLEDPulse && !(--TxLEDPulse))
		TX_LED_OFF();
	if (RxLEDPulse && !(--RxLEDPulse))
		RX_LED_OFF();
	
	if (pgm_read_word(0) != 0xFFFF)
		Timeout++;
}
Пример #4
0
ISR(TIMER1_COMPA_vect, ISR_BLOCK)
{
	/* Reset counter */
	TCNT1H = 0;
	TCNT1L = 0;

	/* Check whether the TX or RX LED one-shot period has elapsed.  if so, turn off the LED */
	if (TxLEDPulse && !(--TxLEDPulse))
		TX_LED_OFF();
	if (RxLEDPulse && !(--RxLEDPulse))
		RX_LED_OFF();
	resetTimeout++;  // Needed for the "short reset delay" mode- governs the time the board waits
					 //  for a second reset before loading the sketch.
	if (pgm_read_word(0) != 0xFFFF)
		Timeout++;
}
Пример #5
0
// StartSketch() is called to clean up our mess before passing execution to the sketch.
void StartSketch(void)
{
	cli();

	/* Undo TIMER1 setup and clear the count before running the sketch */
	TIMSK1 = 0;
	TCCR1B = 0;

	/* Relocate the interrupt vector table to the application section */
	MCUCR = (1 << IVCE);
	MCUCR = 0;

	L_LED_OFF();
	TX_LED_OFF();
	RX_LED_OFF();

	/* jump to beginning of application space */
	__asm__ volatile("jmp 0x0000");

}
Пример #6
0
void StartSketch(void)
{
	CPU_PRESCALE(1);

	cli();
	
	/* Undo TIMER1 setup and clear the count before running the sketch */
	TIMSK1 = 0;
	TCCR1B = 0;
	TCNT1H = 0;		// 16-bit write to TCNT1 requires high byte be written first
	TCNT1L = 0;
	
	/* Relocate the interrupt vector table to the application section */
	MCUCR = (1 << IVCE);
	MCUCR = 0;

	L_LED_OFF();
	TX_LED_OFF();
	RX_LED_OFF();

	/* jump to beginning of application space */
	__asm__ volatile("jmp 0x0000");
}
Пример #7
0
/** Main program entry point. This routine configures the hardware required by the bootloader, then continuously
 *  runs the bootloader processing routine until it times out or is instructed to exit.
 */
int main(void)
{
	/* Save the value of the boot key memory before it is overwritten */
	uint8_t bootKeyPtrVal = *bootKeyPtr;
	*bootKeyPtr = 0;

	/* Check the reason for the reset so we can act accordingly */
	uint8_t  mcusr_state = MCUSR;		// store the initial state of the Status register
	MCUSR = 0;							// clear all reset flags	

	/* Watchdog may be configured with a 15 ms period so must disable it before going any further */
	// MAH 8/15/12- I removed this because wdt_disable() is the first thing SetupHardware() does- why
	//  do it twice right in a row?
	//wdt_disable();
	
	/* Setup hardware required for the bootloader */
	// MAH 8/15/12- Moved this up to before the bootloader go/no-go decision tree so I could use the
	//  timer in that decision tree. Removed the USBInit() call from it; if I'm not going to stay in
	//  the bootloader, there's no point spending the time initializing the USB.
	// SetupHardware();
	wdt_disable();

	// Disable clock division 
	clock_prescale_set(clock_div_1);

	// Relocate the interrupt vector table to the bootloader section
	MCUCR = (1 << IVCE);
	MCUCR = (1 << IVSEL);
	
	LED_SETUP();
	CPU_PRESCALE(0); 
	L_LED_OFF();
	TX_LED_OFF();
	RX_LED_OFF();
	
	// Initialize TIMER1 to handle bootloader timeout and LED tasks.  
	// With 16 MHz clock and 1/64 prescaler, timer 1 is clocked at 250 kHz
	// Our chosen compare match generates an interrupt every 1 ms.
	// This interrupt is disabled selectively when doing memory reading, erasing,
	// or writing since SPM has tight timing requirements. 

	OCR1AH = 0;
	OCR1AL = 250;
	TIMSK1 = (1 << OCIE1A);					// enable timer 1 output compare A match interrupt
	TCCR1B = ((1 << CS11) | (1 << CS10));	// 1/64 prescaler on timer 1 input
	
	
	// MAH 8/15/12- this replaces bulky pgm_read_word(0) calls later on, to save memory.
	if (pgm_read_word(0) != 0xFFFF) sketchPresent = true;
	
	// MAH 8/15/12- quite a bit changed in this section- let's just pretend nothing has been reserved
	//  and all comments throughout are from me.
	// First case: external reset, bootKey NOT in memory. We'll put the bootKey in memory, then spin
	//  our wheels for about 750ms, then proceed to the sketch, if there is one. If, during that 750ms,
	//  another external reset occurs, on the next pass through this decision tree, execution will fall
	//  through to the bootloader.
	if ( (mcusr_state & (1<<EXTRF)) && (bootKeyPtrVal != bootKey) ) {
		*bootKeyPtr = bootKey;
		sei();
		while (RunBootloader) 
		{
			if (resetTimeout > EXT_RESET_TIMEOUT_PERIOD)
				RunBootloader = false;
		}
		cli();
		*bootKeyPtr = 0;
		RunBootloader = true;
		if (sketchPresent) StartSketch();
	} 
	// On a power-on reset, we ALWAYS want to go to the sketch. If there is one.
	else if ( (mcusr_state & (1<<PORF)) && sketchPresent) {	
		StartSketch();
	} 
	// On a watchdog reset, if the bootKey isn't set, and there's a sketch, we should just
	//  go straight to the sketch.
	else if ( (mcusr_state & (1<<WDRF) ) && (bootKeyPtrVal != bootKey) && sketchPresent) {	
		// If it looks like an "accidental" watchdog reset then start the sketch.
		StartSketch();
	}
	
	// END ALL COMMENTS ON THIS SECTION FROM MAH.
	
	/* Initialize USB Subsystem */
	USB_Init();

	/* Enable global interrupts so that the USB stack can function */
	sei();
	
	Timeout = 0;
	
	while (RunBootloader)
	{
		CDC_Task();
		USB_USBTask();
		/* Time out and start the sketch if one is present */
		if (Timeout > TIMEOUT_PERIOD)
			RunBootloader = false;
			
		// MAH 8/15/12- This used to be a function call- inlining it saves a few bytes.
		LLEDPulse++;
		uint8_t p = LLEDPulse >> 8;
		if (p > 127)
			p = 254-p;
		p += p;
		if (((uint8_t)LLEDPulse) > p)
			L_LED_OFF();
		else
			L_LED_ON();
	}

	/* Disconnect from the host - USB interface will be reset later along with the AVR */
	USB_Detach();

	/* Jump to beginning of application space to run the sketch - do not reset */	
	StartSketch();
}
Пример #8
0
/** Main program entry point. This routine configures the hardware required by the bootloader, then continuously
 *  runs the bootloader processing routine until it times out or is instructed to exit.
 */
int main(void)
{
	/* Save the value of the boot key memory before it is overwritten */
	uint8_t bootKeyPtrVal = *bootKeyPtr;
	*bootKeyPtr = 0;

	/* Check the reason for the reset so we can act accordingly */
	uint8_t  mcusr_state = MCUSR;		// store the initial state of the Status register
	MCUSR = 0;							// clear all reset flags

	/* Watchdog may be configured with a 15 ms period so must disable it before going any further */
	// MAH 8/15/12- I removed this because wdt_disable() is the first thing SetupHardware() does- why
	//  do it twice right in a row?
	//wdt_disable();

	/* Setup hardware required for the bootloader */
	// MAH 8/15/12- Moved this up to before the bootloader go/no-go decision tree so I could use the
	//  timer in that decision tree. Removed the USBInit() call from it; if I'm not going to stay in
	//  the bootloader, there's no point spending the time initializing the USB.
	// SetupHardware();
	wdt_disable();

	// Disable clock division
	clock_prescale_set(clock_div_1);

	// Relocate the interrupt vector table to the bootloader section
	MCUCR = (1 << IVCE);
	MCUCR = (1 << IVSEL);

	LED_SETUP();
	CPU_PRESCALE(0);
	L_LED_OFF();
	TX_LED_OFF();
	RX_LED_OFF();

	// Initialize TIMER1 to handle bootloader timeout and LED tasks.
	// With 16 MHz clock and 1/64 prescaler, timer 1 is clocked at 250 kHz
	// Our chosen compare match generates an interrupt every 1 ms.
	// This interrupt is disabled selectively when doing memory reading, erasing,
	// or writing since SPM has tight timing requirements.

	OCR1AH = 0;
	OCR1AL = 250;
	TIMSK1 = (1 << OCIE1A);					// enable timer 1 output compare A match interrupt
	TCCR1B = ((1 << CS11) | (1 << CS10));	// 1/64 prescaler on timer 1 input


	// MAH 8/15/12- this replaces bulky pgm_read_word(0) calls later on, to save memory.
	if (pgm_read_word(0) != 0xFFFF) sketchPresent = true;

// MAH 26 Oct 2012- The "bootload or not?" section has been modified since the code released
//  with Arduino 1.0.1. The simplest modification is the replacement of equivalence checks on
//  the reset bits with masked checks, so if more than one reset occurs before the register is
//  checked, the check doesn't fail and fall through to the bootloader unnecessarily.

// The second, more in depth modification addresses behavior after an external reset (i.e.,
//  user pushes the reset button). The Leonardo treats all external resets as requests to
//  re-enter the bootloader and wait for code to be loaded. It remains in bootloader mode for
//  8 seconds before continuing on to the sketch (if one is present). By defining RESET_DELAY
//  equal to 1, this behavior will persist.

// However, if RESET_DELAY is defined to 0, the reset timeout before loading the sketch drops
//  to 750ms. If, during that 750ms, another external reset occurs, THEN an 8-second delay
//  in the bootloader will occur.

	// This is the "no-8-second-delay" code. If this is the first time through the loop, we
	//  don't expect to see the bootKey in memory.
	if ( (mcusr_state & (1<<EXTRF)) && (bootKeyPtrVal != bootKey) ) {
		*bootKeyPtr = bootKey;   // Put the bootKey in memory so if we get back to this
		                         //  point again, we know to jump into the bootloader
		sei();  // Enable interrupts, so we can use timer1 to track our time in the bootloader
		while (RunBootloader)
		{
			if (resetTimeout > EXT_RESET_TIMEOUT_PERIOD) // resetTimeout is getting incremeted
				RunBootloader = false;                   //  in the timer1 ISR.
		}
		// If we make it past that while loop, it's sketch loading time!
		*bootKeyPtr = 0;   // clear out the bootKey; from now on, we want to treat a reset like
						   //  a normal reset.
		cli();             // Disable interrupts, in case no sketch is present.
		RunBootloader = true;  // We want to hang out in the bootloader if no sketch is present.
		if (sketchPresent) StartSketch(); // If a sketch is present, go! Otherwise, wait around
										  //  in the bootloader until one is uploaded.
	}
	// On a power-on reset, we ALWAYS want to go to the sketch. If there is one.
	//  This is a place where the old code had an equivalence and now there is a mask.
	else if ( (mcusr_state & (1<<PORF)) && sketchPresent) {
		StartSketch();
	}
	// On a watchdog reset, if the bootKey isn't set, and there's a sketch, we should just
	//  go straight to the sketch.
	//  This is a place where the old code had an equivalence and now there is a mask.
	else if ( (mcusr_state & (1<<WDRF) ) && (bootKeyPtrVal != bootKey) && sketchPresent) {
		// If it looks like an "accidental" watchdog reset then start the sketch.
		StartSketch();
	}

	/* Initialize USB Subsystem */
	USB_Init();

	/* Enable global interrupts so that the USB stack can function */
	sei();

	Timeout = 0;

	while (RunBootloader)
	{
		CDC_Task();
		USB_USBTask();
		/* Time out and start the sketch if one is present */
		if (Timeout > TIMEOUT_PERIOD)
			RunBootloader = false;

		// MAH 8/15/12- This used to be a function call- inlining it saves a few bytes.
		LLEDPulse++;
		uint8_t p = LLEDPulse >> 8;
		if (p > 127)
			p = 254-p;
		p += p;
		if (((uint8_t)LLEDPulse) > p)
			L_LED_OFF();
		else
			L_LED_ON();
	}

	/* Disconnect from the host - USB interface will be reset later along with the AVR */
	USB_Detach();

	/* Jump to beginning of application space to run the sketch - do not reset */
	StartSketch();
}
Пример #9
0
static int USB_ISR(int irq, void* data)
{
	DWORD isr;
	USB_Device *usb;
	
	usb = (USB_Device *)data;

	if ((isr = io_inpdw(usb->ISR)) != 0x00L)
	{
		// Bus reset interrupt
		if (isr & IBRST)
		{
			io_outpdw(usb->ISR, IALL);
			usb_Reset(usb);
		}
		
		// SOF interrupt
		if (isr & ISOF)
		{
			io_outpdw(usb->ISR, ISOF);
			if (usb->ReadySetAddr == true)
			{
				io_outpb(usb->DAR, usb->DevAddr | 0x80);
				usb->ReadySetAddr = false;
			}
#ifdef DMP_86DUINO_MODE
			if(tx_led_count && !(--tx_led_count)) TX_LED_OFF();
			if(rx_led_count && !(--rx_led_count)) RX_LED_OFF();
#endif
		}
		
		// Suspend interrupt
		if (isr & ISUSP)
		{
			io_outpdw(usb->ISR, ISUSP);
			usb->IsSet = 0;
			usb->state = USB_DEV_POWERED;
#ifdef DMP_86DUINO_MODE
			TX_LED_OFF();
			RX_LED_OFF();
#endif
		}
		
		// Resume interrupt
		if (isr & IRESM)
		{
			io_outpdw(usb->ISR, IRESM);
		}
		
		// System error interrupt
		if (isr & SYSERR)
		{
			io_outpdw(usb->ISR, SYSERR);
		}
		
		// EP0 Setup interrupt
		if (isr & IEP0SETUP)
		{
			io_outpdw(usb->ISR, IEP0SETUP);
			EP0_SetupHandler(usb);
		}
		
		// EP0 RX interrupt
		if (isr & IEP0RX)
		{
			io_outpdw(usb->ISR, IEP0RX);
			EP0_OutHandler(usb);
		}
		
		// EP0 TX interrupt
		if (isr & IEP0TX)
		{
			io_outpdw(usb->ISR, IEP0TX);
			EP0_InHandler(usb);
		}
		
		// EP1 RX interrupt
		if (isr & IEP1RX)
		{
			io_outpdw(usb->ISR, IEP1RX);
		}
		
		// EP1 TX interrupt
		if (isr & IEP1TX)
		{
			io_outpdw(usb->ISR, IEP1TX);
			EP1_InHandler(usb);
		}
		
		// EP2 RX interrupt
		if (isr & IEP2RX)
		{
			io_outpdw(usb->ISR, IEP2RX);
			EP2_OutHandler(usb);
		}
		
		// EP2 TX interrupt
		if (isr & IEP2TX)
		{
			io_outpdw(usb->ISR, IEP2TX);
			usb->bulk_in_transmitting = false;
			EP2_InHandler(usb);
		}
		
		// EP3 RX interrupt
		if (isr & IEP3RX)
		{
			io_outpdw(usb->ISR, IEP3RX);
		}
		
		// EP3 TX interrupt
		if (isr & IEP3TX)
		{
			io_outpdw(usb->ISR, IEP3TX);
		}
		
#ifdef DMP_86DUINO_MODE	
		// the below behavier is only for compatible of Arduino Leonado (windows)
		if(usb->ling_coding.dwDTERate == 1200 && (usb->control_line_state & 0x01) == 0)
		{   
			io_outpb(usb_on_off_data, io_inpb(usb_on_off_data) | (1 << usb_on_off_pin));
			io_outpb(0xf21A, 0x5a); // write soft reset key
			io_outpb(0x64, 0xfe); // reboot
		}
#endif
	}
	else
		return ISR_NONE;


	return ISR_HANDLED;
}
Пример #10
0
DMPAPI(void *) CreateUSBDevice(void)
{
	USB_Device *usb = NULL;
	
	if ((usb = (USB_Device *)ker_Malloc(sizeof(USB_Device))) == NULL) return NULL;
	
	if (io_Init() == false) {
		err_print((char*)"%s: Init IO lib error!!\n", __FUNCTION__);
		ker_Mfree((void *)usb);
		return NULL;
	}

	usb->addr = vx86_GetUSBDevAddr();
	usb->nIRQ = vx86_GetUSBDevIRQ();
	if (usb->addr == 0x0000 || usb->nIRQ == 0)
	{ 
		io_Close();
		ker_Mfree((void *)usb);
		return NULL;
	}
	
	usb->DevAddr                 = 0x00;
	usb->ReadySetAddr            = false;
	
	usb->state					 = USB_DEV_NOT_ATTACHED;
	usb->stall					 = false;
	
	usb->InUse                   = 0;
	usb->IsSet                   = 0;
	usb->setup_in_handled        = false;
	usb->setup_out_handled       = false;
	usb->bulk_in_transmitting 	 = false;
	
	usb->TimeOut		         = USB_NO_TIMEOUT;
	
	usb->InDataPtr               = NULL;
	usb->OutDataPtr              = NULL;
	usb->InDataSize              = 0;
	usb->OutDataSize             = 0;

	if ((usb->rcvd = CreateQueue(RX_QUEUE_SIZE)) == NULL) goto CREATE_RX_QUEUE_FAIL;
	if ((usb->xmit = CreateQueue(TX_QUEUE_SIZE)) == NULL) goto CREATE_TX_QUEUE_FAIL;
	
	usb->Setup.bmRequestType     = 0;
	usb->Setup.bRequest          = 0;
	usb->Setup.wValue.Value      = 0;
	usb->Setup.wIndex.Value      = 0;
	usb->Setup.wLength           = 0;
	
	usb->ling_coding.dwDTERate   = 0;
	usb->ling_coding.bCharFormat = 0;
	usb->ling_coding.bParityType = 0;
	usb->ling_coding.bDataBits   = 0;
	
	usb->control_line_state      = 0;
	usb->serial_state            = 0;
	
	usb->DAR = usb->addr + 0x00;
	usb->CFR = usb->addr + 0x02;
	usb->FNR = usb->addr + 0x06;
	usb->IER = usb->addr + 0x08;
	usb->ISR = usb->addr + 0x0C;
	usb->TMR = usb->addr + 0x68;
	
	memset((Endpoint *)usb->EP, 0, sizeof(usb->EP));
	usb->EP[0].CtrlTR   = usb->addr + 0x10;
	usb->EP[1].OutTR    = usb->addr + 0x12;
	usb->EP[1].InTR     = usb->addr + 0x14;
	usb->EP[2].OutTR    = usb->addr + 0x16;
	usb->EP[2].InTR     = usb->addr + 0x18;
	usb->EP[3].OutTR    = usb->addr + 0x1A;
	usb->EP[3].InTR     = usb->addr + 0x1C;
	usb->EP[0].SetupDLR = usb->addr + 0x20;
	usb->EP[0].OutDLR   = usb->addr + 0x24;
	usb->EP[0].InDLR    = usb->addr + 0x28;
	usb->EP[1].OutDLR   = usb->addr + 0x2C;
	usb->EP[1].InDLR    = usb->addr + 0x30;
	usb->EP[2].OutDLR   = usb->addr + 0x34;
	usb->EP[2].InDLR    = usb->addr + 0x38;
	usb->EP[3].OutDLR   = usb->addr + 0x3C;
	usb->EP[3].InDLR    = usb->addr + 0x40;
	usb->EP[0].SetupDSR = usb->addr + 0x44;
	usb->EP[0].OutDSR   = usb->addr + 0x48;
	usb->EP[0].InDSR    = usb->addr + 0x4C;
	usb->EP[1].OutDSR   = usb->addr + 0x50;
	usb->EP[1].InDSR    = usb->addr + 0x54;
	usb->EP[2].OutDSR   = usb->addr + 0x58;
	usb->EP[2].InDSR    = usb->addr + 0x5C;
	usb->EP[3].OutDSR   = usb->addr + 0x60;
	usb->EP[3].InDSR    = usb->addr + 0x64;	

#ifdef DMP_86DUINO_MODE
	set_gpio_config_addr(GPIO_CONFIG_ADDR); // for 86duino
	set_tx_led(7, 2);
	set_rx_led(7, 3);
	TX_LED_OFF();
	RX_LED_OFF();
#endif
	return (void *)usb;
	
CREATE_TX_QUEUE_FAIL:
	DestoryQueue(usb->rcvd);
CREATE_RX_QUEUE_FAIL:
	io_Close();
	ker_Mfree((void *)usb);
	return NULL;
}