📄 device_new.c
字号:
TRACE1(38, dev, 0, "dev_cpex(msg:%04X)", message_rd_id(msgp));
rqstp = (t_usb_rqst *)message_rd_arg(msgp);
g_wtmp = rqstp->wLengthHi;
g_wtmp *= 256;
g_wtmp += (uint16)rqstp->wLengthLo;
switch (message_rd_id(msgp))
{
case k_dsd_usb_get_descriptor:
_nvram_insert_vidpid = k_false;
_nvram_ix = 0;
_nvram_sz = 0;
TRACE3(39, dev, 0, "wLengthHi:%02X wLengthLo:%02X wtmp:%d", rqstp->wLengthHi, rqstp->wLengthLo, g_wtmp);
switch (rqstp->wValueHi)
{
case k_usb_dscr_typ_device:
TRACE0(40, dev, 0, "RQ_GET_DESCRIPTOR: device");
// tell the data pump where to find it and how much there is
if (sie_is_high_speed())
{
// eeprom vid/pid => if eeprom is valid, insert vidpid
_nvram_insert_vidpid = _nvram_data_valid;
_payload_source((_serial_number_valid?(&g_hs_dev_dscr_w_ser):(&g_hs_dev_dscr)), _min(g_hs_dev_dscr[0], g_wtmp));
}
else
{
// eeprom vid/pid => if eeprom is valid, insert vidpid
_nvram_insert_vidpid = _nvram_data_valid;
_payload_source((_serial_number_valid?(&g_fs_dev_dscr_w_ser):(&g_fs_dev_dscr)), _min(g_fs_dev_dscr[0], g_wtmp));
}
break;
case k_usb_dscr_typ_devqual:
TRACE0(41, dev, 0, "RQ_GET_DESCRIPTOR: devqual");
// tell the data pump where to find it and how much there is
if (sie_is_high_speed())
{
_payload_source(&g_fs_devqual_dscr, _min(g_fs_devqual_dscr[0], g_wtmp));
}
else
{
_payload_source(&g_hs_devqual_dscr, _min(g_hs_devqual_dscr[0], g_wtmp));
}
break;
case k_usb_dscr_typ_config:
TRACE0(42, dev, 0, "RQ_GET_DESCRIPTOR: configuration");
// make sure it is in the supported range
if (rqstp->wValueLo > k_dev_max_configuration)
return k_error;
// tell the data pump where to find it and how much there is
if (sie_is_high_speed())
{
_payload_source(&g_hs_cfg_dscr, _min(g_hs_cfg_dscr[2], g_wtmp));
}
else
{
_payload_source(&g_fs_cfg_dscr, _min(g_fs_cfg_dscr[2], g_wtmp));
}
break;
case k_usb_dscr_typ_osconfig:
TRACE0(43, dev, 0, "RQ_GET_DESCRIPTOR: other speed configuration");
// make sure it is in the supported range
if (rqstp->wValueLo > k_dev_max_configuration)
return k_error;
// tell the data pump where to find it and how much there is
if (sie_is_high_speed())
{
_payload_source( &g_fs_oscfg_dscr, _min(g_fs_oscfg_dscr[2], g_wtmp));
}
else
{
_payload_source(&g_hs_oscfg_dscr, _min(g_hs_oscfg_dscr[2], g_wtmp));
}
break;
case k_usb_dscr_typ_string:
TRACE0(44, dev, 0, "RQ_GET_DESCRIPTOR: string");
// make sure it is in the supported range
if (rqstp->wValueLo >= k_dev_max_string)
return k_error;
#ifdef k_support_nvram
// tell the data pump where to find it and how much there is
// grab string from rom, unless its asking for the serial number...
if (_nvram_data_valid)
{
switch (rqstp->wValueLo)
{
case k_dev_idx_str_dscr_lng:
TRACE0(45, dev, 0, "source: eeprom Language ID String descriptor");
_nvram_ix = k_ix_lng; // data only (same semantics as _source_eeprom_raw=k_false)
_nvram_sz = nvram_read(k_ix_lng);
break;
case k_dev_idx_str_dscr_mfg:
TRACE0(46, dev, 0, "source: eeprom Manufacturer ID String descriptor");
_nvram_ix = k_ix_mfr; // data only (same semantics as _source_eeprom_raw=k_false)
_nvram_sz = nvram_read(k_ix_mfr);
break;
case k_dev_idx_str_dscr_prd:
TRACE0(47, dev, 0, "source: eeprom Product ID String descriptor");
_nvram_ix = k_ix_prd; // data only (same semantics as _source_eeprom_raw=k_false)
_nvram_sz = nvram_read(k_ix_prd);
break;
case k_dev_idx_str_dscr_ser:
// ... in which case, extract it from the eeprom
if (_serial_number_valid)
{
TRACE0(48, dev, 0, "source: eeprom Serial Number String descriptor");
_nvram_ix = k_ix_ser; // data only (same semantics as _source_eeprom_raw=k_false)
_nvram_sz = nvram_read(k_ix_ser);
}
else
{
TRACE0(49, dev, 0, "warning: source, eeprom Serial Number String, not valid. no serial # reported");
return k_error;
}
break;
default:
TRACE1(50, dev, 0, "warning: no string descriptor at index %d", rqstp->wValueLo);
return k_error;
}
// send it along
// _payload_source(NULL, _min(eeprom_read(_nvram_ix), g_wtmp));
_payload_source(NULL, _min(_nvram_sz, g_wtmp));
}
else
{
if (rqstp->wValueLo != k_dev_idx_str_dscr_ser)
{
TRACE0(51, dev, 0, "source: default string descriptor");
_payload_source(g_str_dscr[rqstp->wValueLo], _min(*((uint8 *)g_str_dscr[rqstp->wValueLo]), g_wtmp));
}
else
{
// cannot happen
TRACE1(52, dev, 0, "warning: no string descriptor at index %d", rqstp->wValueLo);
return k_error;
}
}
#else
TRACE0(53, dev, 0, "source: default string descriptor (eeprom support disabled)");
_payload_source(g_str_dscr[rqstp->wValueLo], _min(*((uint8 *)g_str_dscr[rqstp->wValueLo]), g_wtmp));
#endif
break;
default:
return k_error;
}
return k_success;
case k_hsd_usb_set_configuration:
TRACE0(54, dev, 0, "RQ_SET_CONFIGURATION");
if ((uint8)message_rd_arg(msgp)) // unconfigured -> configured
dev_power_up();
else
dev_power_dn();
dev_wr_most_recent_config(sie_rd_configuration());
return k_success;
// vendor specific requests
case k_hci_dfu_detach:
trace0(0, dfu, 0, "k_hci_dfu_detach");
return dfu_cpex(msgp);
case k_hvd_wr_eerom:
TRACE1(55, dev, 0, "k_hvd_wr_eerom - length:%d", g_wtmp);
_nvram_ix = 0;
_nvram_sz = 256;
_payload_sink(NULL, _min(256, g_wtmp));
return k_success;
case k_dvd_rd_eerom:
TRACE1(56, dev, 0, "k_hvd_rd_eerom - length:%d", g_wtmp);
_nvram_ix = 0;
_nvram_sz = 256;
_payload_source(NULL, _min(256, g_wtmp));
return k_success;
case k_dvd_inq_devid:
TRACE0(57, dev, 0, "k_dvd_inq_devid");
_payload_source(_devid, sizeof(_devid));
return k_success;
// requests from the usb protocol engine
case k_msg_source_payload:
// load some application specific data into a packet buffer
// return k_in_progress if app expects to be supply at least one more packet's worth of data
// return k_finished otherwise
pnr = *(uint8 *)message_rd_arg(msgp);
pktsz = _min(g_data_len, k_maxpktsz);
g_data_len -= pktsz;
TRACE2(58, dev, 0, "k_msg_source_payload - pnr:%d pktsz:%d", pnr, pktsz);
// NULL addr means read non-volitile memory location like eeprom, flashed config info or hard-coded bytes
#ifdef k_support_nvram
if (NULL == g_source_addr)
{
nvram_source_payload(pnr, pktsz) ;
}
else
#endif
{
// write the default data
mmu_wr_pkt(0, pnr, g_source_addr, pktsz);
#ifdef k_support_nvram
if ( _nvram_insert_vidpid )
{
// overwrite the default data with eeprom vid-pid
mcu_begin_critical_section();
_mcu_register_wr(x_sram_addr_lo, (k_pkt_addrlo[pnr]+k_ix_dev_vid_lo) );
_mcu_register_wr(x_sram_addr_hi, k_pkt_addrhi[pnr]);
_mcu_register_wr(x_sram_data, nvram_read(k_ix_vid_lo));
_mcu_register_wr(x_sram_data, nvram_read(k_ix_vid_hi));
_mcu_register_wr(x_sram_data, nvram_read(k_ix_pid_lo));
_mcu_register_wr(x_sram_data, nvram_read(k_ix_pid_hi));
_nvram_insert_vidpid = k_false;
mcu_end_critical_section();
}
#endif
g_source_addr += pktsz;
}
return g_data_len ? k_in_progress : k_finished;
case k_msg_sink_payload:
// unload data from a packet buffer and do something application specific with it
// return k_in_progress if app can process this request
// return k_finished otherwise
pnr = *(uint8 *)message_rd_arg(msgp);
TRACE1(59, dev, 0, "and the packet number is:%d", pnr);
pktsz = _min(g_data_len, k_maxpktsz);
g_data_len -= pktsz;
#ifdef k_support_nvram
// NULL means write the eeprom
if (NULL == g_sink_addr)
{
nvram_sink_payload(pnr, pktsz) ;
}
else
#endif
{
mmu_rd_pkt(pnr, pktsz, g_sink_addr);
g_sink_addr += pktsz;
}
return g_data_len ? k_in_progress : k_finished;
default:
return k_error;
}
return k_error;
}
//------------------------------------------------------------------------------
// Declaration:
// t_result dev_intr(uint8 intr);
//
// Purpose:
// Handle interrupts.
//
// Arguments:
// intr - the interrupt that occurred. It is a number, not a bitmask.
//
// Return:
// k_ignored - causes default processing within the kernel isr
// k_success - prevents default processing within the kernel isr
//
// Note:
// This function is called from the kernel isrs. Therefore it executes at
// interrupt level, not foreground level.
//
// This function uses register bank 1 (as do the kernel's isrs) so you cannot
// call any function that is not wrapped by the #pragma NOAREGS.
// Only functions wrapped by this #pragma are callable from the isrs
// (except this one, of course, because it explicitly uses register bank 1...)
//
// 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 flounder, panic, flail, and eventually expire.
//
// Since:
// fmc-1.0
//------------------------------------------------------------------------------
extern t_isr_fragment _hpbot_thread_entry;
t_result dev_intr(uint8 intr) reentrant using 1
{
t_result rslt;
TRACE1(60, dev, 1, "-(dev_intr(%d))", intr);
_stack_check();
// give first crack at it to the high priority interrupt chain
rslt = k_ignored;
if (_hpbot_thread_entry)
rslt = (*_hpbot_thread_entry)(intr);
if (rslt != k_ignored)
return rslt;
// high priority interupt chain didn't process it, so synchronize the foreground
switch (intr)
{
case k_irq_ramwr_a: // external0
// current xfer TO sram buffer A has completed
TRACE0(61, dev, 1, "--(k_irq_ramwr_a)");
thread_set_sync(g_ix_dev_thread, kbm_sync_usbrx);
return k_ignored;
case k_irq_ramwr_b: // external0
// current xfer TO sram buffer B has completed
TRACE0(62, dev, 1, "--(k_irq_ramwr_b)");
thread_set_sync(g_ix_dev_thread, kbm_sync_usbrx);
return k_ignored;
case k_irq_ramrd_a: // external0
// current xfer FROM sram buffer A has completed
TRACE0(63, dev, 1, "--(k_irq_ramrd_a)");
thread_set_sync(g_ix_dev_thread, kbm_sync_usbtx);
return k_ignored;
case k_irq_ramrd_b: // external0
// current xfer FROM sram buffer B has completed
TRACE0(64, dev, 1, "--(k_irq_ramrd_b)");
thread_set_sync(g_ix_dev_thread, kbm_sync_usbtx);
return k_ignored;
case k_irq_nak2rx: // external5
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -