📄 fmcapp.c
字号:
// 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.
//------------------------------------------------------------------------------
uint8 fmcapp_cpex(t_message *msgp) reentrant
{
uint8 pktsz;
uint8 pnr_loc;
t_usb_rqst *rqstp;
rqstp = (t_usb_rqst *)(message_rd_arg(msgp));
switch(message_rd_id(msgp))
{
// standard requests
//--------------------------------------------------------------------------
// Note - the 97C2xx has an SIE that is smart enough to handle most standard
// control requests. therefore, many of these messages won't appear in this cpex
// as they would if this were built for the 100 or 102 mcu's
// class specific requests
//--------------------------------------------------------------------------
case k_cls_mass_storage_reset:
trace0(0, atapi, 0, "got k_hci_msc_reset");
// command block reset
// $$$ cds to do - we MUST find a way to NAK the host until
// the reset has occured by order of the Mass Storage Class Spec
// fmc_soft_reset()...
// for now, just send a usbreset and return success... it'll work, but it's technically
// non compliant for devices that actually send this message
thread_set_sync(g_ix_ata_thread, kbm_sync_usbrst) ;
return k_success;
case k_cls_mass_storage_get_max_lun:
trace0(0, atapi, 0, "got k_dci_msc_get_max_lun");
g_tmp = 0;
// tell the data pump where to find it and how much there is
_payload_source(&g_tmp, k_lun_max);
return k_success;
// os messages
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_loc = *(uint8 *)(message_rd_arg(msgp));
pktsz = _min(g_data_len, k_maxpktsz);
g_data_len -= pktsz;
mmu_wr_pkt(0, pnr_loc, g_source_addr, pktsz);
g_source_addr += pktsz;
#ifdef k_mcu_97200
x_ep0tx_bc = pktsz;
#endif
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_loc = *(uint8 *)(message_rd_arg(msgp));
#ifdef k_mcu_97200
pktsz = x_ep0rx_bc;
#else
pktsz = _min(g_data_len, k_maxpktsz);
#endif
g_data_len -= pktsz;
mmu_rd_pkt(pnr_loc, pktsz, g_sink_addr);
g_sink_addr += pktsz;
return g_data_len ? k_in_progress : k_finished;
default:
return k_error;
}
return k_error;
}
//------------------------------------------------------------------------------
// <<< ATA INTERFACE - POLLER >>>
// Target MCU:
// 200
// Declaration:
// void ctl_poll(void);
// Purpose:
// Poll for non-interrupt events related to this interface and synchronize
// the associated thread(s).
// Arguments:
// None.
// Return:
// None.
// 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 flounder, panic, flail, and eventually expire.
//------------------------------------------------------------------------------
// i think we may need this...
// implement ata_poll_whatever() here if you end up needing it...
//------------------------------------------------------------------------------
// <<< ATA INTERFACEE - THREAD >>>
// Target MCU:
// 200
// Purpose:
// Handles the application specific peripheral control state machine for this
// interface.
//------------------------------------------------------------------------------
/*****************************************************************************/
/* ATAPI_CreateThread aka wait_until_atapi_thread_gets_created() */
/*****************************************************************************/
void fmcapp_init_2() reentrant ;
void fmcapp_init_3() reentrant ;
void fmcapp_init_4() reentrant ;
void fmcapp_create_thread() reentrant
{
TRACE0(332, fmcapp, 0, "+fmcapp_create_thread()") ;
// initialize fmcapp state variables
g_available_pkt_length = 0x0000;
#if defined(k_mcu_97200) || defined(k_mcu_97201)
// frob the fmc registers to prepare the fmc hardware.
// clr muxen to select ATA interface.
x_ata_ctl |= kbm_ata_ctl_out_control ;
x_ata_ctl &= ~kbm_ata_ctl_muxen ;
#endif
#if defined(k_mcu_97210)
// initialize the compact flash controller & device
thread_run_dfa(fmc_init, NULL, fmcapp_init_2) ;
#endif
}
//------------------------------------------------------------------------------
void fmcapp_trace_compiled_opts() reentrant
{
TRACE0(335, fmcapp, 0, "** SMSC Flash Media Controller Configuration **") ;
TRACE4(336, fmcapp, 0, " -firmware version: %d.%d.%d.%d", kbcd_dev_version_major, kbcd_dev_version_minor, kbcd_dev_version_external_change, kbcd_dev_version_internal_change) ;
TRACE1(337, fmcapp, 0, " -dma support: %c", k_dma_mode > 0 ? 'Y' : 'N' ) ;
if(k_dma_mode > 0)
{
switch(k_dma_mode)
{
case k_dma_mode_multiword_0 :
trace0(0, atapi, 0, "DMA Mode: Multiword Mode 0") ;
break;
case k_dma_mode_multiword_1 :
trace0(0, atapi, 0, "DMA Mode: Multiword Mode 1") ;
break;
case k_dma_mode_multiword_2 :
trace0(0, atapi, 0, "DMA Mode: Multiword Mode 2") ;
break;
case k_dma_mode_ultra_dma_0 :
trace0(0, atapi, 0, "DMA Mode: Ultra DMA Mode 0") ;
break;
case k_dma_mode_ultra_dma_1 :
trace0(0, atapi, 0, "DMA Mode: Ultra DMA Mode 1") ;
break;
case k_dma_mode_ultra_dma_2 :
trace0(0, atapi, 0, "DMA Mode: Ultra DMA Mode 2") ;
break;
case k_dma_mode_ultra_dma_3 :
trace0(0, atapi, 0, "DMA Mode: Ultra DMA Mode 3") ;
break;
case k_dma_mode_ultra_dma_4 :
trace0(0, atapi, 0, "DMA Mode: Ultra DMA Mode 4") ;
break;
case k_dma_mode_ultra_dma_5 :
trace0(0, atapi, 0, "DMA Mode: Ultra DMA Mode 5") ;
break;
default:
trace1(0, atapi, 0, "DMA Mode: Unknown Mode Specifed (%d)", k_dma_mode) ;
break;
}
trace1(0, atapi, 0, "DMA Used for Data In (ATA to SIE): %c", (k_dma_data_in ? 'Y' : 'N') ) ;
trace1(0, atapi, 0, "DMA Used for Data Out (SIE to ATA): %c", (k_dma_data_out ? 'Y' : 'N') ) ;
}
#ifdef SHADOW_PIO_COMPLETE
TRACE0(338, fmcdev, 0, "Shadow PIO_COMPLETE: Y") ;
#else
TRACE0(339, fmcdev, 0, "Shadow PIO_COMPLETE: N") ;
#endif
#ifdef k_support_ata
TRACE0(340, fmcdev, 0, "ATA Device Support:Y") ;
#else
TRACE0(341, fmcdev, 0, "ATA Device Support:N") ;
#endif
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -