#include "usbapp/usb_application_service.h" #include "usbapp/usb_application_service_def.h" #include "usbapp/usb_application_flash.h" // usb_application_flash_fGetWritingFlag #include "usb/usb_bridge.h" #include "usb/usb_config.h" #include "usbd_vendor.h" #include "app/thermo/tsensor.h" #include "drivers/flash/base/extmem_flash.h" #include "app/version/version.h" #include "app/nfm/nfm_base.h" #define READ_INFO 0xA4 // чтение служебной информации static int8_t fServiceAppInit(); static int8_t fServiceAppDeInit(); static void fServiceAppReset(); static bool fServiceAppSetup( const tUSBSetupPacket_t * pSetup, bool bFirstStage, bool success ); static size_t fServiceAppControlRx( const tUSBSetupPacket_t * pSetup, sUSBTransfer_t * rx, size_t idx, size_t bytesRemaining ); static size_t fServiceAppControlTx( const tUSBSetupPacket_t * pSetup, sUSBTransfer_t * tx, size_t idx, size_t bytesRemaining ); static TServiceRequestBuffer_t sRequestBuffer; const sUSBAppEntry_Control_t usbapplication_ACM_planarproto_service = { .fUsbInit = fServiceAppInit, .fUsbDeInit = fServiceAppDeInit, .fUsbSetup = fServiceAppSetup, .fUsbCtlEpRx = fServiceAppControlRx, .fUsbCtlEpTx = fServiceAppControlTx, .fResetEvent = fServiceAppReset, }; static int8_t fServiceAppInit() { return 0; } static int8_t fServiceAppDeInit() { return 0; } static void fServiceAppReset() { } static bool fServiceAppSetup( const tUSBSetupPacket_t * pSetup, bool bFirstStage, bool success ) { switch ( pSetup->bRequest ) { case READ_INFO: { if( 0x8000 == pSetup->wValue ) { switch( pSetup->wIndex ) { #if CONFIG_EXTMEM case 0x001: // get flash info { // check the request data stage size if( sizeof(sRequestBuffer.svcReq_Flash) >= pSetup->wLength ) { memset( &sRequestBuffer, 0, sizeof(sRequestBuffer) ); sRequestBuffer.svcReq_Flash.dwProtocolVersion = 1; sRequestBuffer.svcReq_Flash.cReserved0 = 0; sRequestBuffer.svcReq_Flash.cReserved1 = 0; sRequestBuffer.svcReq_Flash.wDriverVersion = pProgramVersion->firmware_version; // Maximum Chip size sRequestBuffer.svcReq_Flash.dwFlashSize = ExtMemHandle.pFlashProperties->maxSectors * ExtMemHandle.pFlashProperties->sectorSize; // Available capacity sRequestBuffer.svcReq_Flash.dwCapacity = ExtMemHandle.pBanksProperties->factoryBankSize + ExtMemHandle.pBanksProperties->userBankSize; bool protectStatus = false; if( ExtMemHandle.CheckBankProtect( extmem_bank_factory, &protectStatus ) ) sRequestBuffer.svcReq_Flash.bBank0Protection = (protectStatus)?1:0; else sRequestBuffer.svcReq_Flash.bBank0Protection = 0; // Write-Erase-count Resource descriptor: useless, supported only for protocol compatibility sRequestBuffer.svcReq_Flash.WERInfo.wReserved2 = 0; sRequestBuffer.svcReq_Flash.WERInfo.wRBSCount = 0; sRequestBuffer.svcReq_Flash.WERInfo.dwMaxWER = 0; sRequestBuffer.svcReq_Flash.ChipDescription.cDesc[0] = '\0'; strncpy( sRequestBuffer.svcReq_Flash.ChipDescription.cDesc, ExtMemHandle.pFlashProperties->pChipDescription, sizeof(sRequestBuffer.svcReq_Flash.ChipDescription.cDesc) ); sRequestBuffer.svcReq_Flash.ChipDescription.cDescLength = strlen( sRequestBuffer.svcReq_Flash.ChipDescription.cDesc ); return true; } } break; case 0x002: // get flash busy flag (char) { // check the request data stage size if( sizeof(sRequestBuffer.svcReq_FlashReady) >= pSetup->wLength ) { memset( &sRequestBuffer, 0, sizeof(sRequestBuffer) ); sRequestBuffer.svcReq_FlashReady = (usb_application_flash_fGetWritingFlag()?0x01:0x00); return true; } } break; #endif case 0x003: // get model info { // check the request data stage size if( sizeof(sRequestBuffer.svcReq_Model) >= pSetup->wLength ) { memset( &sRequestBuffer, 0, sizeof(sRequestBuffer) ); sRequestBuffer.svcReq_Model.requestVersion = 0x0001; sRequestBuffer.svcReq_Model.deviceId = NFMClass->properties.deviceId; sRequestBuffer.svcReq_Model.firmwareId = pProgramVersion->firmware_version; NFMClass->methods.getModelName( (char*)sRequestBuffer.svcReq_Model.modelName, sizeof(sRequestBuffer.svcReq_Model.modelName) ); sRequestBuffer.svcReq_Model.ampStatesCount = 0; //NFMClass->properties.allowedAmpStatesCount; sRequestBuffer.svcReq_Model.filtStatesCount = 0; //NFMClass->properties.allowedFiltStatesCount; return true; } } break; } } } break; } return false; } static size_t fServiceAppControlRx( const tUSBSetupPacket_t * pSetup, sUSBTransfer_t * rx, size_t idx, size_t bytesRemaining ) { return 0; } static size_t fServiceAppControlTx( const tUSBSetupPacket_t * pSetup, sUSBTransfer_t * tx, size_t idx, size_t bytesRemaining ) { switch ( pSetup->bRequest ) { case READ_INFO: { if( 0x8000 == pSetup->wValue ) { switch( pSetup->wIndex ) { case 0x001: // get flash info { // try to write the 'svcReq_Flash' structure to the output buffer. // If the buffer size has insufficient space to store whole structure, // only part of target structure is written to the buffer, the rest part // will be transmitted in the next transaction ( @idx pointer is used ) usb_write_transfer( tx, &sRequestBuffer.raw_bytes[ idx ], sizeof( sRequestBuffer.svcReq_Flash ) ); } break; case 0x002: // get flash busy flag (char) { usb_write_transfer( tx, &sRequestBuffer.raw_bytes[ idx ], sizeof( sRequestBuffer.svcReq_FlashReady ) ); } break; case 0x003: // get model info { // try to write the 'svcReq_Model' structure to the output buffer. // If the buffer size has insufficient space to store whole structure, // only part of target structure is written to the buffer, the rest part // will be transmitted in the next transaction ( @idx pointer is used ) usb_write_transfer( tx, &sRequestBuffer.raw_bytes[ idx ], sizeof( sRequestBuffer.svcReq_Model ) ); } break; } } } break; } return usb_count_transfer( tx ); }