📄 upgrade.c
字号:
/*============================================================================
____________________________________________________________________________
______________________________________________
SSSS M M CCCC Standard Microsystems Corporation
S MM MM SSSS C Austin Design Center
SSS M M M S C 11000 N. Mopac Expressway
S M M SSS C Stonelake Bldg. 6, Suite 500
SSSS M M S CCCC Austin, Texas 78759
SSSS ______________________________________________
____________________________________________________________________________
Copyright(C) 1999, Standard Microsystems Corporation
All Rights Reserved.
This program code listing is proprietary to SMSC and may not be copied,
distributed, or used without a license to do so. Such license may have
Limited or Restricted Rights. Please refer to the license for further
clarification.
____________________________________________________________________________
Notice: The program contained in this listing is a proprietary trade
secret of SMSC, Hauppauge, New York, and is copyrighted
under the United States Copyright Act of 1976 as an unpublished work,
pursuant to Section 104 and Section 408 of Title XVII of the United
States code. Unauthorized copying, adaption, distribution, use, or
display is prohibited by this law.
____________________________________________________________________________
Use, duplication, or disclosure by the Government is subject to
restrictions as set forth in subparagraph(c)(1)(ii) of the Rights
in Technical Data and Computer Software clause at DFARS 52.227-7013.
Contractor/Manufacturer is Standard Microsystems Corporation,
80 Arkay Drive, Hauppauge, New York, 1178-8847.
____________________________________________________________________________
____________________________________________________________________________
<module name> - <module description>
____________________________________________________________________________
comments tbd
____________________________________________________________________________
Revision History
Date Who Comment
________ ___ _____________________________________________________________
05/31/00 tbh initial version
11/05/01 tbh eliminate dfu jumper, replaced with PCON.GF0
07/09/02 tbh changed (g_cdm0 <= _dfu_timer.u16) to
(g_cdm0 < _dfu_timer.u16) in dfu_mnger(k_msg_usbrst)
and in dfu_cpex(k_msg_transaction_done) to compensate
for faster enuumeration where the initial reset comes
while g_cdm0 is still zero.
============================================================================*/
#define __manager__
#include "..\inc\minimos.h"
#include "upgrade.h"
//------------------------------------------------------------------------------
t_uw16 _dfu_timer;
//+-----------------------------------------------------------------------------
// Name:
// _flash_select_lower_bank
//
// Declaration:
// void _flash_select_lower_bank(void);
//
// Purpose:
// Select the lower 64K bank of the 128K flash chip (the DFU loader).
//
// Arguments:
// None
//
// Return:
// None
//
// Notes:
// Only call while executing from RAM.
//
// Since:
// dfu-1.0
//------------------------------------------------------------------------------
#define _flash_select_lower_bank(); \
{ \
_mcu_register_clr_bits(x_gpioa_dir, kbm_gpio6); \
_mcu_register_clr_bits(x_gpioa_out, kbm_gpio6); \
}
//+-----------------------------------------------------------------------------
// Name:
// _flash_execute_from_ram
//
// Declaration:
// void _flash_execute_from_ram(void);
//
// Purpose:
// Begin execution from RAM, at the current program counter.
//
// Arguments:
// None
//
// Return:
// None
//
// Notes:
// Be sure to copy the code into RAM before calling.
//
// Since:
// dfu-1.0
//------------------------------------------------------------------------------
#define _flash_execute_from_ram() \
_mcu_register_set_bits(x_util_config, kbm_util_config_sram_sw)
//+-----------------------------------------------------------------------------
// Name:
// _flash_execute_from_flash
//
// Declaration:
// void _flash_execute_from_flash(void);
//
// Purpose:
// Begin execution from flash, at the current program counter.
//
// Arguments:
// None
//
// Return:
// None
//
// Notes:
// Only call while executing from RAM.
//
// Since:
// dfu-1.0
//------------------------------------------------------------------------------
#define _flash_execute_from_flash() \
_mcu_register_clr_bits(x_util_config, kbm_util_config_sram_sw)
//------------------------------------------------------------------------------
// Declaration:
// static void flash_coerce_dfu();
//
// Purpose:
// Forces the DFU loader to execute.
//
// Arguments:
// None.
//
// Return:
// None.
//
// Note:
// This function must be copied to sram at 0x400 and executed from sram because
// it changes code banks to the lower 64k. It is linked elsewhere at some
// address not overlapping 0x0400..0x06FF. It is relocated to 0x0400 on the fly.
// Therefore it cannot call any functions, do any jumps (other that the reset),
// or depend on the contents of the flash space outside 0x0400..0x06FF.
//
// Since:
// dfu-1.0
//------------------------------------------------------------------------------
static void flash_coerce_dfu(void) reentrant;
static void flash_coerce_dfu() reentrant
{
trace0(0, dfu, 0, "flash_coerce_dfu()");
_flash_select_lower_bank();
_mcu_reboot();
}
//------------------------------------------------------------------------------
// Declaration:
// static void dfu_copy_flash_to_sram();
//
// Purpose:
// Copies the flash range flash_coerce_dfu() to flash_coerce_dfu()+100
// from code space to xdata space at 0x0400 (into the executable sram)
// This relocates the code into the sram (required because the dfu loader
// cannot write code from 0x0400..0x06FF, forcing the function to exist
// outside the range) so it can be executed there.
//
// Arguments:
// None.
//
// Return:
// None.
//
// Note:
// If an error occurrs then mcu is halted and a diagnostic dumped on the trace fifo.
//
// Since:
// dfu-1.0
//------------------------------------------------------------------------------
static void dfu_copy_flash_to_sram(void) reentrant;
static void dfu_copy_flash_to_sram() reentrant
{
trace0(0, dfu, 0, "dfu_copy_flash_to_sram()");
mcu_begin_critical_section();
// turn the sram back into xdata space
_flash_execute_from_flash();
// copy flash_coerce_dfu() into sram
memcpy((uint8 xdata *)(0x0400), (uint8 code *)(flash_coerce_dfu), 100);
if (memcmp((uint8 xdata *)(0x0400), (uint8 code *)(flash_coerce_dfu), 100))
{
trace0(0, dfu, 0, "ERROR: copy failed.");
mcu_halt();
}
mcu_end_critical_section();
}
//------------------------------------------------------------------------------
// Declaration:
// uint8 dfu_mngr(t_message *msgp);
//
// Purpose:
// This is the manager for all things related to the dfu interface.
//
// Arguments:
// None.
//
// Return:
// k_success
// K-error
//
// Note:
// Do NOT yield from this routine. It is NOT part of any thread. It does
// not execute in an any thread's context. Yielding from within this function
// will cause your firmware to crash.
//
// $$$ the initial version of the sie is made with a maximum of 1
// interface. so, dfu must be broken to accept class commands off the
// runtime interface. at least until the VCI hooks are implemented in the sie.
//------------------------------------------------------------------------------
t_result dfu_mngr(t_message_ref msgp) reentrant
{
trace0(0, dfu, 0, "dfu_mngr()");
switch (message_rd_id(msgp))
{
case k_msg_usbrst:
trace0(0, dfu, 0, "k_msg_usbrst");
// if we are timing the DFU_DETACH request then check to see if time to enter dfu mode...
if (g_cdm0 < _dfu_timer.u16)
{
_dfu_timer.u16 = 0;
// load the "relocatable" flash_coerce_dfu() into sram
dfu_copy_flash_to_sram();
mcu_begin_critical_section();
// communicate between app and loader via GF0 of PCON register
_cpu_register_setbit(PCON, 2);
// make sram executable so flash_coerce_dfu() can run from sram
_flash_execute_from_ram();
trace0(0, dfu, 0, "dfu_mngr: coerce dfu");
// jump to flash_coerce_dfu() at its new address in sram
((t_code_fragment)0x0400)();
}
return k_success;
default:
trace0(0, dfu, 0, "error");
// unexpected message
return k_error;
}
// unexpected message
return k_error;
}
//------------------------------------------------------------------------------
// Declaration:
// uint8 dfu_cpex(t_message *msgp);
//
// Purpose:
// Watches for the DFU_DETACH message.
//
// Arguments:
// None.
//
// Return:
// k_success - Causes the protocol engine to complete the status stage successfully.
// k_error - Causes the protocol engine to stall the control pipe.
// k_in_progress - For k_msg_source_payload, causes the protocol engine to deliver
// another empty packet buffer to the cpex to be loaded for transmission.
// For k_msg_sink_payload, informs the protocol engine that the cpex expects at
// least one more payload buffer to be delivered to it by the protocol engine.
// k_finished - For k_msg_source_payload and k_msg_sink_payload, informs the
// protocol engine that the data phase is complete and no more data is expected
// in either direction.
//
// Note:
// Do NOT yield from this routine. It is part of the protocol engine's thread.
// It executes in the context of g_ix_ctl_thread. Yielding from within this
// function will cause the protocol engine's state machine to float belly up.
// And that will cause your firmware to shuffle off this mortal coil, post haste.
//------------------------------------------------------------------------------
t_result dfu_cpex(t_message_ref msgp) reentrant
{
t_usb_rqst *rqstp;
rqstp = (t_usb_rqst *)message_rd_arg(msgp);
switch (message_rd_id(msgp))
{
case k_hci_dfu_detach:
case k_hvd_dfu_detach:
mcu_begin_critical_section();
trace0(0, dfu, 0, "dfu_cpex: k_hci_dfu_detach / k_hvd_detach");
// communicate between app and loader via GF0 of PCON register
_cpu_register_setbit(PCON, 2);
// start up the detach timeout
_dfu_timer.u8.hi = rqstp->wValueHi;
_dfu_timer.u8.lo = rqstp->wValueLo;
g_cdm0 = 0;
mcu_end_critical_section();
// now wait for the usb reset
return k_success;
case k_msg_transaction_done:
trace0(0, dfu, 0, "dfu_cpex: k_msg_transaction_done");
// if we are timing the DFU_DETACH request then check to see if time to enter dfu mode...
if (g_cdm0 < _dfu_timer.u16)
{
_dfu_timer.u16 = 0;
// load the "relocatable" flash_coerce_dfu() into sram
dfu_copy_flash_to_sram();
mcu_begin_critical_section();
// communicate between app and loader via GF0 of PCON register
_cpu_register_setbit(PCON, 2);
// make sram executable so flash_coerce_dfu() can run from sram
_flash_execute_from_ram();
trace0(0, dfu, 0, "dfu_cpex: coerce dfu");
// jump to flash_coerce_dfu() at its new address in sram
((t_code_fragment)0x0400)();
}
return k_success;
default:
return k_error;
}
return k_error;
}
//---eof------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -