#include "core/config.h" #include "usbapp/usb_application_switch.h" #include "usb/usb_bridge.h" #include "usb/usb_config.h" #include "usbd_vendor.h" #if CONFIG_NFMBASECLASS #include "app/nfm/nfm_base.h" #elif CONFIG_KEYSW #include "drivers/keycontrol/keycontrol.h" #endif #define PROTO_REQ_GET_KEY_STAT 0x04 // считать состояние ключей #define PROTO_REQ_SET_KEY_STAT 0x05 // записать состояние ключей #define PROTO_REQ_GET_KEY_STAT2 0xF0 // прочесть управляющий код выданный на ключи #define PROTO_REQ_AMP_KEY_STAT 0x05 // Записать состояние усилителей #define PROTO_REQ_FILT_KEY_STAT 0x0C // Записать состояние фильтров #define PROTO_REQ_AMP_KEY_READ 0x0D // Считать состояние усилителей #define PROTO_REQ_FILT_KEY_READ 0x0E // Считать состояние фильтров static int8_t fSwitchAppInit(); static int8_t fSwitchAppDeInit(); static void fSwitchAppReset(); static bool fSwitchAppSetup( const tUSBSetupPacket_t * pSetup, bool bFirstStage, bool success ); static size_t fSwitchAppControlRx( const tUSBSetupPacket_t * pSetup, sUSBTransfer_t * rx, size_t idx, size_t bytesRemaining ); static size_t fSwitchAppControlTx( const tUSBSetupPacket_t * pSetup, sUSBTransfer_t * tx, size_t idx, size_t bytesRemaining ); const sUSBAppEntry_Control_t usbapplication_ACM_planarproto_switch = { .fUsbInit = fSwitchAppInit, .fUsbDeInit = fSwitchAppDeInit, .fUsbSetup = fSwitchAppSetup, .fUsbCtlEpRx = fSwitchAppControlRx, .fUsbCtlEpTx = fSwitchAppControlTx, .fResetEvent = fSwitchAppReset, }; static int8_t fSwitchAppInit() { return 0; } static int8_t fSwitchAppDeInit() { return 0; } static void fSwitchAppReset() { } static bool fSwitchAppSetup( const tUSBSetupPacket_t * pSetup, bool bFirstStage, bool success ) { switch( pSetup->bRequest ) { case PROTO_REQ_GET_KEY_STAT2: case PROTO_REQ_GET_KEY_STAT: { return true; } break; case PROTO_REQ_AMP_KEY_STAT: { eNFMAmpState_t state = (eNFMAmpState_t)pSetup->wValue; if( ! NFMClass->methods.checkAmpStateAvailable( state )) { return false; // Key State unavailable in this device } else if( ! NFMClass->methods.keyStatesMethods.setAmpStateCommon( state )) { return false; // Key Switch Error } return true; }break; case PROTO_REQ_FILT_KEY_STAT: { eNFMFiltState_t state = (eNFMFiltState_t)pSetup->wValue; if( ! NFMClass->methods.checkFiltStateAvailable( state )) { return false; // Key State unavailable in this device } else if( ! NFMClass->methods.keyStatesMethods.setFiltStateCommon( state )) { return false; // Key Switch Error } return true; }break; case PROTO_REQ_AMP_KEY_READ: { return true; }break; case PROTO_REQ_FILT_KEY_READ: { return true; }break; // #if CONFIG_NFMBASECLASS // uint32_t dwCode = (((uint32_t)pSetup->wIndex)<<16ul) | (uint32_t)pSetup->wValue; // return NFMClass->methods.keyStatesMethods.setKeyStateLegacy( dwCode ); // #elif CONFIG_KEYSW // #error Программа отправляет код в виде wIndex wValue // tKeySwitchState_t state = KEYSWITCH_LEGACYSTATE_2_STATE( pSetup->wValue ); // return KeySwitchHandle.SetKeyState( state ); // #else // return false; // #endif } return false; } static size_t fSwitchAppControlRx( const tUSBSetupPacket_t * pSetup, sUSBTransfer_t * rx, size_t idx, size_t bytesRemaining ) { return 0; } static size_t fSwitchAppControlTx( const tUSBSetupPacket_t * pSetup, sUSBTransfer_t * tx, size_t idx, size_t bytesRemaining ) { switch( pSetup->bRequest ) { #if CONFIG_NFMBASECLASS case PROTO_REQ_GET_KEY_STAT2: // read the raw lowlevel control code { if( 0 == idx && sizeof(uint32_t) == bytesRemaining ) { uint32_t code = NFMClass->methods.keyStatesMethods.getRawKeyControlCode(); usb_push_transfer( tx, &code, sizeof( code ) ); } } break; case PROTO_REQ_GET_KEY_STAT: { if( 0 == idx && sizeof(uint16_t) == bytesRemaining ) { uint16_t lstate = 0; uint32_t state = 0; if( NFMClass->methods.keyStatesMethods.getKeyStateLegacy( &state ) ) { lstate = (uint16_t)state; // in 2-port ACM only lower 16-bit are used usb_push_transfer( tx, &lstate, sizeof( lstate ) ); } } } break; case PROTO_REQ_AMP_KEY_READ: { if( 0 == idx && sizeof(uint16_t) == bytesRemaining ) { uint16_t currentState = (uint16_t)NFMClass->methods.keyStatesMethods.getAmpStateCommon(); usb_push_transfer( tx, ¤tState, sizeof( currentState ) ); } } break; case PROTO_REQ_FILT_KEY_READ: { if( 0 == idx && sizeof(uint16_t) == bytesRemaining ) { uint16_t currentState = (uint16_t)NFMClass->methods.keyStatesMethods.getFiltStateCommon(); usb_push_transfer( tx, ¤tState, sizeof( currentState ) ); } } break; #elif CONFIG_KEYSW case PROTO_REQ_GET_KEY_STAT2: { if( 0 == idx && sizeof(tKeySwitchCode_t) == bytesRemaining ) { tKeySwitchCode_t code; if( KeySwitchHandle.GetKeyCode( &code ) ) { usb_push_transfer( tx, &code, sizeof( code ) ); } } } break; case PROTO_REQ_GET_KEY_STAT: { if( 0 == idx && sizeof(tKeySwitchStateLegacy_t) == bytesRemaining ) { tKeySwitchStateLegacy_t lstate; tKeySwitchState_t state; if( KeySwitchHandle.GetKeyState( &state ) ) { lstate = KEYSWITCH_STATE_2_LEGACYSTATE( state ); usb_push_transfer( tx, &lstate, sizeof( lstate ) ); } } } break; #endif } return usb_count_transfer( tx ); }