| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412 |
- #include "usbapp/usb_application_flash.h"
- #include "usb/usb_bridge.h"
- #include "usb/usb_config.h"
- #include "usbd_vendor.h"
- #include "drivers/flash/base/extmem_flash.h"
- #include "core/csect.h"
- #include "core/config.h"
- #include "app/nfm/nfm_base.h"
- #define PROTO_REQ_READ_DATA_FLASH 0x02 // ïðî÷èòàòü äàííûå èç ôëåø (ðåæèì ýìóëÿöèè áàíêîâ)
- #define PROTO_REQ_WRITE_DATA_FLASH 0x03 // çàïèñàòü äàííûå âî ôëåø (ðåæèì ýìóëÿöèè áàíêîâ)
- #define PROTO_REQ_GET_FLAG_FLASH_STATUS 0x06 // ñ÷èòàòü ñîñòîÿíèå ñòàòóñà çàïèñè ôëåøà
- #define PROTO_REQ_SET_PROTECT_FLASH 0x07 // óñòàíîâèòü çàùèòó ôëåøà
- #define PROTO_REQ_READ_DATA_FLASH_EX 0xA3 // ïðî÷èòàòü äàííûå èç ôëåøè (ëèíåéíûé ýêñïåðòíûé ðåæèì)
- #define PROTO_REQ_READ_INFO 0xA4 // ÷òåíèå ñëóæåáíîé èíôîðìàöèè
- #define PROTO_REQ_WRITE_DATA_FLASH_LIN 0xA5 // çàïèñàòü äàííûå âî ôëåø (ëèíåéíûé ðåæèì)
- #define PROTO_REQ_READ_DATA_FLASH_LIN 0xA6 // ïðî÷èòàòü äàííûå èç ôëåø (ëèíåéíûé ðåæèì)
- static int8_t fFlashAppInit();
- static int8_t fFlashAppDeInit();
- static void fFlashAppReset();
- static bool fFlashAppSetup( const tUSBSetupPacket_t * pSetup, bool bFirstStage, bool success );
- static size_t fFlashAppControlRx( const tUSBSetupPacket_t * pSetup, sUSBTransfer_t * tx, size_t idx, size_t bytesRemaining );
- static size_t fFlashAppControlTx( const tUSBSetupPacket_t * pSetup, sUSBTransfer_t * rx, size_t idx, size_t bytesRemaining );
- const sUSBAppEntry_Control_t usbapplication_ACM_planarproto_flash = {
- .fUsbInit = fFlashAppInit,
- .fUsbDeInit = fFlashAppDeInit,
- .fUsbSetup = fFlashAppSetup,
- .fUsbCtlEpRx = fFlashAppControlRx,
- .fUsbCtlEpTx = fFlashAppControlTx,
- .fResetEvent = fFlashAppReset,
- };
- //-----------------------------------------------------
- static sUSBTransfer_t transf_write_flash;
- static flash_address_t WritingAddress = 0;
- static volatile bool bFlagWritingInProgress = false;
- static inline bool fGetWritingFlag()
- {
- bool flag;
- __DI__ flag = bFlagWritingInProgress; __EI__
- return flag;
- }
- bool usb_application_flash_fGetWritingFlag()
- {
- return fGetWritingFlag();
- }
- /*
- static inline void fSetWritingFlag()
- {
- __DI__ bFlagWritingInProgress = true; __EI__
- }
- */
- static inline void fClrWritingFlag()
- {
- __DI__ bFlagWritingInProgress = false; __EI__
- }
- static inline bool fTrySetWritingFlag()
- {
- bool flag = false;
- __DI__
- if( ! bFlagWritingInProgress )
- {
- bFlagWritingInProgress = flag = true;
- }
- __EI__
- return flag;
- }
- //-----------------------------------------------------
- static size_t fFlashApp_ReadDataFlash( const tUSBSetupPacket_t * pSetup, sUSBTransfer_t * rx, size_t idx, size_t bytesRemaining );
- static size_t fFlashApp_WriteDataFlash( const tUSBSetupPacket_t * pSetup, sUSBTransfer_t * tx, size_t idx, size_t bytesRemaining );
- static size_t fFlashApp_ReadReadyFlash( const tUSBSetupPacket_t * pSetup, sUSBTransfer_t * tx, size_t idx, size_t bytesRemaining );
- static bool fFlashApp_SetProtectionFlash( const tUSBSetupPacket_t * pSetup );
- // &&&& &&&& &&&& &&&& &&&& &&&& &&&& &&&& &&&& &&&& &&&& &&&& &&&& &&&& &&&& &&&& &&&& &&&& &&&& &&&& &&&& &&&& &&&& &&&&
- static int8_t fFlashAppInit()
- {
- return 0;
- }
- // &&&& ---- &&&& ---- &&&& ---- &&&& ---- &&&& ---- &&&& ---- &&&& ---- &&&& ---- &&&& ---- &&&& ---- &&&& ---- &&&& ----
- static int8_t fFlashAppDeInit()
- {
- return 0;
- }
- // &&&& ---- &&&& ---- &&&& ---- &&&& ---- &&&& ---- &&&& ---- &&&& ---- &&&& ---- &&&& ---- &&&& ---- &&&& ---- &&&& ----
- static void fFlashAppReset()
- {
- }
- // &&&& ---- &&&& ---- &&&& ---- &&&& ---- &&&& ---- &&&& ---- &&&& ---- &&&& ---- &&&& ---- &&&& ---- &&&& ---- &&&& ----
- static bool fFlashAppSetup( const tUSBSetupPacket_t * pSetup, bool bFirstStage, bool success )
- {
- switch ( pSetup->bRequest )
- {
- case PROTO_REQ_READ_DATA_FLASH:
- {
- // check device ready
- if( fGetWritingFlag() )
- {
- return false; // device busy
- }
- else
- {
- return (bool)fFlashApp_ReadDataFlash( pSetup, NULL, 0, 0 );
- }
- }
- break;
- case PROTO_REQ_WRITE_DATA_FLASH:
- {
- // check device ready
- if( fGetWritingFlag() )
- {
- return false; // device busy
- }
- else
- {
- return (bool)fFlashApp_WriteDataFlash( pSetup, NULL, 0, 0 );;
- }
- }
- break;
- case PROTO_REQ_GET_FLAG_FLASH_STATUS:
- {
- return true; // accept
- }
- break;
- case PROTO_REQ_SET_PROTECT_FLASH:
- {
- // perform factory-memory bank protection: inside this IRQ routine
- switch( pSetup->wValue )
- {
- case 0x0000:
- case 0x0001:
- {
- // 0x0000, 0x0001
- return fFlashApp_SetProtectionFlash( pSetup );
- }
- }
- }
- break;
- }
- return false;
- }
- // &&&& ---- &&&& ---- &&&& ---- &&&& ---- &&&& ---- &&&& ---- &&&& ---- &&&& ---- &&&& ---- &&&& ---- &&&& ---- &&&& ----
- static size_t fFlashAppControlRx( const tUSBSetupPacket_t * pSetup, sUSBTransfer_t * rx, size_t idx, size_t bytesRemaining )
- {
- switch ( pSetup->bRequest )
- {
- case PROTO_REQ_WRITE_DATA_FLASH:
- {
- return fFlashApp_WriteDataFlash( pSetup, rx, idx, bytesRemaining );
- }
- break;
- }
- return 0;
- }
- // &&&& ---- &&&& ---- &&&& ---- &&&& ---- &&&& ---- &&&& ---- &&&& ---- &&&& ---- &&&& ---- &&&& ---- &&&& ---- &&&& ----
- static size_t fFlashAppControlTx( const tUSBSetupPacket_t * pSetup, sUSBTransfer_t * tx, size_t idx, size_t bytesRemaining )
- {
- switch ( pSetup->bRequest )
- {
- case PROTO_REQ_READ_DATA_FLASH:
- {
- return fFlashApp_ReadDataFlash( pSetup, tx, idx, bytesRemaining );
- }
- break;
- case PROTO_REQ_GET_FLAG_FLASH_STATUS:
- {
- return fFlashApp_ReadReadyFlash( pSetup, tx, idx, bytesRemaining );
- }
- break;
- }
- return 0;
- }
- // &--& ---- &--& ---- &--& ---- &--& ---- &--& ---- &--& ---- &--& ---- &--& ---- &--& ---- &--& ---- &--& ---- &--& ----
- static size_t fFlashApp_ReadDataFlash( const tUSBSetupPacket_t * pSetup, sUSBTransfer_t * tx, size_t idx, size_t bytesRemaining )
- {
- flash_address_t chunk_address = idx + (flash_address_t)pSetup->wIndex + (((flash_address_t)pSetup->wValue)<<16);
- if( NULL == tx )
- {
- return ((ExtMemHandle.RangeCheck_Read( chunk_address, bytesRemaining ))?1:0);
- }
- flash_size_t chunk_bytes = MIN( bytesRemaining, usb_space_transfer( tx ) );
- if( ExtMemHandle.Read( chunk_address, usb_transfer_raw_write(tx), chunk_bytes ) )
- {
- return usb_transfer_virtual_write( tx, chunk_bytes );
- }
- return 0;
- }
- // &--& ---- &--& ---- &--& ---- &--& ---- &--& ---- &--& ---- &--& ---- &--& ---- &--& ---- &--& ---- &--& ---- &--& ----
- static size_t fFlashApp_WriteDataFlash( const tUSBSetupPacket_t * pSetup, sUSBTransfer_t * rx, size_t idx, size_t bytesRemaining )
- {
- flash_address_t chunk_address = idx + (flash_address_t)pSetup->wIndex + (((flash_address_t)pSetup->wValue)<<16);
- if( NULL == rx )
- {
- // For normal operation it is required that whole the packet
- // fits to the Low-Level RX-buffer (aka RX-transfer), and this
- // event fires only when all the data already received.
- // This fact guaranees that the application CAN USE MOVE SEMANTIC
- // on the RX-transfer because it is a last RX-event in the sequence.
- if( pSetup->wLength > USBD_VENDOR_get_control_rx_transfer_size() )
- {
- // No, the whole transfer length is greater than RX-transfer size.
- // Partial writing is not supported
- // Whole packet must fit into the transfer size.
- return false;
- }
- return ((ExtMemHandle.RangeCheck_Write( chunk_address, bytesRemaining ))?1:0);
- }
- // Check device ready and set busy flag
- if( fTrySetWritingFlag() )
- {
- flash_size_t chunk_bytes = MIN( bytesRemaining, usb_count_transfer( rx ) );
- // For normal operation it is required that whole the packet
- // fits to the Low-Level RX-buffer (aka RX-transfer), and this
- // event fires only when all the data already received.
- // This fact guaranees that the application CAN USE MOVE SEMANTIC
- // on the RX-transfer because it is a last RX-event in the sequence.
- // Check if all the data already is in the transfer:
- if( (0 == idx) && (usb_count_transfer( rx ) == bytesRemaining) )
- {
- // Ok, all conditions are true
- // use MOVE SEMANTIC on the passed transfer @rx
- // Make the source @rx transfer invalid
- // Move all resources from @rx to the new object @transf_write_flash
- // After the operation the source @rx transfer will be invalid.
- // The core will not be able use internal RX-transfer (specified by @rx).
- // Need to move the transfer back
- usb_move_transfer( &transf_write_flash, rx, false );
- // Remember region parameters
- WritingAddress = chunk_address;
- // It is required to remember the transfer object the move semantic implemented on.
- // Use user context value of the transfer objects: store the @rx pointer into the @transf_write_flash
- usb_transfer_set_context( &transf_write_flash, rx );
- // NOW USB-CORE UNABLE TO RECEIVE DATA!!!
- // Internal USB-CORE RX-buffer is moved to the @transf_write_flash object!
- // report the core that all
- return usb_count_transfer( &transf_write_flash );
- }
- // on error case: reset the flag
- fClrWritingFlag();
- }
- return 0;
- }
- // &--& ---- &--& ---- &--& ---- &--& ---- &--& ---- &--& ---- &--& ---- &--& ---- &--& ---- &--& ---- &--& ---- &--& ----
- static size_t fFlashApp_ReadReadyFlash( const tUSBSetupPacket_t * pSetup, sUSBTransfer_t * tx, size_t idx, size_t bytesRemaining )
- {
- flash_size_t chunk_bytes = MIN( bytesRemaining, usb_space_transfer( tx ) );
- uint8_t value[2] = { 0x00 };
- if( fGetWritingFlag() )
- value[0] = 0x00A5;
- else
- value[0] = 0x0000;
- if( (idx < sizeof( value )) && (bytesRemaining <= sizeof( value )) )
- {
- usb_push_transfer( tx, &value[idx], bytesRemaining );
- }
- return usb_count_transfer( tx );
- }
- // &--& ---- &--& ---- &--& ---- &--& ---- &--& ---- &--& ---- &--& ---- &--& ---- &--& ---- &--& ---- &--& ---- &--& ----
- static bool fFlashApp_SetProtectionFlash( const tUSBSetupPacket_t * pSetup )
- {
- bool ret = false;
- switch( pSetup->wValue )
- {
- case 0x0000:
- {
- #if CONFIG_NFMBASECLASS
- ret = NFMClass->methods.xMemoryProtection.enable();
- #else
- ret = ExtMemHandle.BankProtect( extmem_bank_factory, true ) // Set BANK0 protection
- &&
- ExtMemHandle.BankProtect( extmem_bank_user, false ); // Clear BANK1 protection (always unprotected)
- #endif
- }
- break;
- case 0x0001:
- {
- #if CONFIG_NFMBASECLASS
- ret = NFMClass->methods.xMemoryProtection.disable();
- #else
- ret = ExtMemHandle.BankProtect( extmem_bank_factory, false ) // Clear BANK0 protection
- &&
- ExtMemHandle.BankProtect( extmem_bank_user, false ); // Clear BANK1 protection (always unprotected)
- #endif
- }
- break;
- }
- /* 30/05/19, Testing
- asm("bkpt #0");
- bool bank0 = false;
- bool bank1 = false;
- ExtMemHandle.CheckBankProtect( extmem_bank_factory, &bank0 );
- ExtMemHandle.CheckBankProtect( extmem_bank_user, &bank1 );
- asm("bkpt #0");
- ExtMemHandle.BankProtect( extmem_bank_factory, false );
- ExtMemHandle.BankProtect( extmem_bank_user, false );
- asm("bkpt #0");
- ExtMemHandle.BankProtect( extmem_bank_factory, true );
- ExtMemHandle.BankProtect( extmem_bank_user, false );
- asm("bkpt #0");
- ExtMemHandle.BankProtect( extmem_bank_factory, false );
- ExtMemHandle.BankProtect( extmem_bank_user, true );
- asm("bkpt #0");
- ExtMemHandle.BankProtect( extmem_bank_factory, true );
- ExtMemHandle.BankProtect( extmem_bank_user, true );
- asm("bkpt #0");
- (void)bank0; (void)bank1;
- */
- return ret;
- }
- // &--& ---- &--& ---- &--& ---- &--& ---- &--& ---- &--& ---- &--& ---- &--& ---- &--& ---- &--& ---- &--& ---- &--& ----
-
- void usb_application_flash_serve()
- {
- // Serve the flash u-application
- // Check if the writing flag is set
- if( fGetWritingFlag() )
- {
- #if CONFIG_NFMCLASS_AUTOPROTECT_MEMORY
- // protect factory data: set memory protection
- NFMClass->methods.xMemoryProtection.disable();
- #endif
-
- // retireve the data pointer
- void * pWriteData = usb_transfer_raw_read( &transf_write_flash );
- flash_address_t WritingSize = usb_count_transfer( &transf_write_flash );
- // perform the writing
- ExtMemHandle.Write( WritingAddress, pWriteData, WritingSize );
- // It is required to return the USB-CORE buffer back.
- sUSBTransfer_t * usb_core_rx_transfer = NULL;
- // Retrieve the core-transfer object pointer from the @transf_write_flash context value:
- if( usb_transfer_get_context( &transf_write_flash, (void**)&usb_core_rx_transfer ) )
- {
- // Move the memory buffer back to the CORE:
- usb_move_transfer( usb_core_rx_transfer, &transf_write_flash, false );
- // Reset transfer (optional)
- usb_reset_transfer( usb_core_rx_transfer );
- }
- // Reset the writing flag
- fClrWritingFlag();
- #if CONFIG_NFMCLASS_AUTOPROTECT_MEMORY
- // protect factory data: set memory protection
- NFMClass->methods.xMemoryProtection.enable();
- #endif
- }
- }
|