#include "usbapp/usb_application_benchmark.h" #include "usb/usb_bridge.h" #include "usb/usb_config.h" #include "usbd_usbtmc.h" #include "crc32.h" static uint8_t selectedTest = 0; static unsigned long crc = 0; static int8_t fBenchmarkInit(); static int8_t fBenchmarkDeInit(); static void fBenchmarkReset(); static bool fBenchmarkSetup( const tUSBSetupPacket_t * pSetup, bool bFirstStage, bool success ); static size_t fBenchmarkControlRx( const tUSBSetupPacket_t * pSetup, sUSBTransfer_t * rx, size_t idx, size_t bytesRemaining ); static size_t fBenchmarkControlTx( const tUSBSetupPacket_t * pSetup, sUSBTransfer_t * tx, size_t idx, size_t bytesRemaining ); uint8_t BENCHMARK_datain_beginsend( uint8_t epnum ); uint8_t BENCHMARK_datain_sendprepared( uint8_t epnum ); const sUSBAppEntry_Control_t usbapplication_BENCHMARK_control = { .fUsbInit = fBenchmarkInit, .fUsbDeInit = fBenchmarkDeInit, .fUsbSetup = fBenchmarkSetup, .fUsbCtlEpRx = fBenchmarkControlRx, .fUsbCtlEpTx = fBenchmarkControlTx, .fResetEvent = fBenchmarkReset, }; static bool fBenchmark_DataInitHandler( uint8_t bEpLogAddress ); static bool fBenchmark_DataRxHandler( uint8_t bEpLogAddress, sUSBTransfer_t * rx ); static bool fBenchmark_DataTxHandler( uint8_t bEpLogAddress, sUSBTransfer_t * tx ); static bool fBenchmark_DataErrHandler( uint8_t bEpLogAddress, uint32_t error ); static void fBenchmark_DataDeInitHandler( uint8_t bEpLogAddress ); const sUSBAppEntry_Data_t usbapplication_BENCHMARK_dataapp = { .fDataInitHandler = fBenchmark_DataInitHandler, .fDataRxHandler = fBenchmark_DataRxHandler, .fDataTxHandler = fBenchmark_DataTxHandler, .fDataErrHandler = fBenchmark_DataErrHandler, .fDataDeInitHandler = fBenchmark_DataDeInitHandler, }; static size_t g_TxByte = 0; static size_t g_RxByte = 0; static size_t g_RxBytesReceived = 0; static uint8_t g_BenchmarkBuffer[ 64 ]; static int8_t fBenchmarkInit() { // if( !usb_bridge_register_dataapp( USBTMC_BENCHMARK_EP, &usbapplication_BENCHMARK_dataapp ) ) // return 1; return 0; } static int8_t fBenchmarkDeInit() { // usb_bridge_unregister_dataapp( USBTMC_BENCHMARK_EP ); return 0; } static void fBenchmarkReset() { } static bool fBenchmarkSetup( const tUSBSetupPacket_t * pSetup, bool bFirstStage, bool success ) { switch( pSetup->bRequest ) { // Benchmark select test: // bRequest = 0x0E // wValue = 0(None), 1(Read), 2(Write), 3(Loop) case 0x0E: { switch( pSetup->wValue ) { case 0: // None case 1: // Read case 2: // Write case 3: // Loop selectedTest = pSetup->wValue; g_TxByte = 0; g_RxByte = 0; memset( g_BenchmarkBuffer, 0, sizeof(g_BenchmarkBuffer) ); g_RxBytesReceived = 0; crc = ICRC32; sUSBTransfer_t * tx = USBD_USBTMC_GetDataTxTransferHandle(); sUSBTransfer_t * rx = USBD_USBTMC_GetDataRxTransferHandle(); usb_reset_transfer( tx ); usb_reset_transfer( rx ); return true; //bibb } } break; // Benchmark get selected test: // bRequest = 0x0F case 0x0F: { return true; //bibb } } return false; } static size_t fBenchmarkControlRx( const tUSBSetupPacket_t * pSetup, sUSBTransfer_t * rx, size_t idx, size_t bytesRemaining ) { return 0; } static size_t fBenchmarkControlTx( const tUSBSetupPacket_t * pSetup, sUSBTransfer_t * tx, size_t idx, size_t bytesRemaining ) { return usb_write_transfer( tx, &selectedTest, 1 ); // Select test accept or return selected test } static bool fBenchmark_DataInitHandler( uint8_t bEpLogAddress ) { return true; } static bool fBenchmark_DataRxHandler( uint8_t bEpLogAddress, sUSBTransfer_t * rx ) { size_t n = usb_count_transfer(rx); g_RxBytesReceived += n; crc = CRC32( crc, usb_transfer_raw_read(rx), n ); sUSBTransfer_t * tx = USBD_USBTMC_GetDataTxTransferHandle(); bool first = ( usb_count_transfer(tx) == 0 ); if( n < usb_copy_transfer( tx, rx, n, false ) ) { // tx buffer full asm("bkpt #0"); } usb_reset_transfer( rx ); if( first ) BENCHMARK_datain_sendprepared( bEpLogAddress ); return true; while( n > 0 ) { size_t pos = g_RxByte % sizeof(g_BenchmarkBuffer); size_t free = sizeof(g_BenchmarkBuffer) - pos; size_t bytes = usb_read_transfer( rx, &g_BenchmarkBuffer[ pos ], free, false ); g_RxByte += bytes; n -= bytes; } usb_bridge_datain_beginsend( bEpLogAddress ); return true; } static bool fBenchmark_DataTxHandler( uint8_t bEpLogAddress, sUSBTransfer_t * tx ) { // for( ;; ) // { // size_t TxByte = g_TxByte++; // if( 0 == usb_write_transfer( tx, &g_BenchmarkBuffer[TxByte % sizeof(g_BenchmarkBuffer)], 1 ) ) // { // break; // } // } return true; } static bool fBenchmark_DataErrHandler( uint8_t bEpLogAddress, uint32_t error ) { return true; } static void fBenchmark_DataDeInitHandler( uint8_t bEpLogAddress ) { } // BENCHMARK_datain_beginsend() // Begin the transmission using already prepared TX-transfer. // Due to the hardware does not support NAK-sent-interrupt, it is // required to initiate the first packet sending to start TX-flow (DataIN). // This function issues the first packet sending using virtual DataIN event. // uint8_t BENCHMARK_datain_beginsend( uint8_t epnum ) { // issue virtual DataIN event: return USBD_USBTMC_DataIn_BeginSend( epnum, false ); } // BENCHMARK_datain_sendprepared() // Begin the transmission using DataIN handler virtual call. // Due to the hardware does not support NAK-sent-interrupt, it is // required to initiate the first packet sending to start TX-flow (DataIN). // This function issues the first packet sending using virtual DataIN event. // uint8_t BENCHMARK_datain_sendprepared( uint8_t epnum ) { // issue virtual DataIN event: return USBD_USBTMC_DataIn_BeginSend( epnum, true ); }