usbtmc.c 100 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993
  1. #define _USBTMC_C_
  2. #include <string.h>
  3. #include "lpc176x.h"
  4. #include "stdio.h"
  5. #include "usb_hardware.h"
  6. #include "queue.h"
  7. #include "mem.h"
  8. #ifndef USBTMC // #endif â êîíöå ôàéëà
  9. #pragma message(" _____________________________________________________________ " )
  10. #pragma message(" ############################################################# " )
  11. #pragma message(" # USBTMC Project, Alpha Version # " )
  12. #pragma message(" # v 2.1 - Âåðñèÿ ïðîåêòà # " )
  13. #pragma message(" # Ïðîåêò ïîääåðæèâàåò ñòàðûé ïðîòîêîë USB-CONTROL # " )
  14. #pragma message(" # ×òîáû âêëþ÷òü TMC íóæíî îáúÿâèòü ìàêðîñ 'USBTMC' â ôàéëå # " )
  15. #pragma message(" # project.h # " )
  16. #pragma message(" # 21-ñåí-2011 15:00 # " )
  17. #pragma message(" ############################################################# " )
  18. #pragma message(" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ " )
  19. #else
  20. #include "gpib_parser.h"
  21. #include "usb_enumeration.h"
  22. //#include "spi.h"
  23. #include "hal.h"
  24. #include "usbtmc.h"
  25. #include "utils.h"
  26. #include "i2_c.h"
  27. #include "options.h"
  28. #include "usb_options.h"
  29. #include "endpoints.h"
  30. #include "usb_application.h"
  31. #include "usb_proto.h"
  32. //
  33. // Âñå ñâÿçàííîå ñ USBTMC ïðîòîêîëîì íàõîäèòñÿ â ýòîì ôàéëå, à
  34. // òàêæå â ôàéëå GPIB_parser.c
  35. //
  36. #include "../usbtmc/gpib.h"
  37. BYTE SerialNumber[9];
  38. unsigned short int DeviceID = 0;
  39. BYTE gEP2BufOutExpand[USB_MAX_BULKOUT_BUFFERSIZE]; // ïåðåä gEP2BufInExpand
  40. BYTE gEP2BufInExpand[USB_MAX_BULKIN_BUFFERSIZE]; // ñëåäîì çà gEP2BufOutExpand ( íà ñëó÷àé ïåðåïîëíåíèÿ )
  41. BYTE gGPIBErrorQueue[USB_MAX_ERROR_QUEUE];
  42. BYTE gGPIBFunctionContext[USB_MAX_FUNCCONTEXT];
  43. extern const BYTE abDescriptors_USBTMC[];
  44. extern const BYTE abDescriptors_Proprietary[];
  45. extern BYTE SerialNumberDescriptor[];
  46. const char *DeviceIDs[] =
  47. {
  48. "SC6000T",
  49. "SC8000T"
  50. };
  51. BOOL bUSBTMCEnable =FALSE;
  52. BOOL usbtmc_RaiseError_CatDescription( USB_DEVICE_INFO * udi, const char * description, unsigned int desc_len );
  53. BOOL usbtmc_RaiseError( USB_DEVICE_INFO * udi, GPIB_ErrorClass_t errClass, int dwCode, const char * description, unsigned int desc_len );
  54. // =========================================================================================================================================
  55. void ReadDeviceInfo( void )
  56. {
  57. {
  58. s_memset( SerialNumber, '0', 8 );
  59. DeviceID = 0;
  60. }
  61. SerialNumber[8] = '\0';
  62. }
  63. // =========================================================================================================================================
  64. void usbtmc_HOOK_control_out( USB_DEVICE_INFO * udi );
  65. // =========================================================================================================================================
  66. // volatile size_t debug_call_ep2irq_1 = 0;
  67. // volatile size_t debug_call_ep2irq_2 = 0;
  68. // volatile size_t debug_call_ep2irq_3 = 0;
  69. // volatile size_t debug_call_ep2irq_4 = 0;
  70. // volatile size_t debug_call_ep2irq_5 = 0;
  71. // Îáðàáîò÷èê ïðåðûâàíèé EP2 (IN/OUT)
  72. // âûçûâàåòñÿ ïî àäðåñó èç ïåðåìåííîé, èíèöèàëèçàöèÿ â UsbtmcInit()
  73. void USB_Interrupt( unsigned int EndpointStatus )
  74. {
  75. // debug_call_ep2irq_5++;
  76. if( USB_EVENT_ENDPOINT( EndpointStatus,USB_EP_PHY_ADDRESS_BULK_OUT ) )
  77. { //debug_call_ep2irq_1++;
  78. usb_EP2_rx_int_func(&gUSBInfo); //-- Bulk-OUT
  79. }
  80. if( USB_EVENT_ENDPOINT( EndpointStatus,USB_EP_PHY_ADDRESS_BULK_IN ) )
  81. { //debug_call_ep2irq_2++;
  82. usb_EP2_tx_int_func(&gUSBInfo); //-- Bulk-IN
  83. }
  84. if( USB_EVENT_ENDPOINT( EndpointStatus,USB_EP_PHY_ADDRESS_INT_IN ) )
  85. { // debug_call_ep2irq_3++;
  86. usb_EP1_tx_int_func(&gUSBInfo); //-- Int-IN
  87. }
  88. if(USB_EVENT_ENDPOINT(EndpointStatus,USB_EP_PADDRESS_OUT )) // Control OUT
  89. { //debug_call_ep2irq_4++;
  90. usbtmc_HOOK_control_out(&gUSBInfo); //-- IN
  91. }
  92. }
  93. // =========================================================================================================================================
  94. IRQ_FUNCTION_ADDRESS UsbtmcInit(void)
  95. {
  96. USB_DEVICE_INFO * udi = &gUSBInfo;
  97. bUSBTMCEnable = FALSE;
  98. #ifdef USBTMC_SUPPORT_OLD
  99. if(USB_INTERFACE_CONT==GetInterface(udi))
  100. {
  101. //ReadDeviceInfo(); --- replaced with VariableInit_Post()
  102. // DevDepInit(); --- replaced with VariableInit_Post()
  103. return 0; // åñëè áûëî ïðîèçâåäåíî ïåðåêëþ÷åíèå èíòåðôåéñà -> âûõîäèì
  104. }
  105. #endif
  106. bUSBTMCEnable = TRUE;
  107. udi->Descriptors = (BYTE*)&abDescriptors_USBTMC[0]; //-- Descriptors
  108. udi->EPBulkStatus.OutPipe.pDefaultBuffer = gEP2BufOutExpand;//-- EP2 buffer
  109. udi->EPBulkStatus.InPipe.pDefaultBuffer = gEP2BufInExpand;//-- EP2 buffer
  110. udi->EPBulkStatus.InPipe.pfTransferEndHandler = usbtmc_EndOfTransfer;
  111. udi->EPBulkStatus.OutPipe.pfTransferEndHandler = NULL;
  112. memset( (BYTE*)&udi->GPIBFunctionContext, 0, sizeof(udi->GPIBFunctionContext) );
  113. usb_reset_endpoint_status( &udi->EPBulkStatus );
  114. //-- configure logical-EP2 [In-EP5, Out-EP4, Bulk]
  115. // ÄÎÑÒÀÒÎ×ÍÎ ÏÎÄÌÅÍÈÒÜ udi->Descriptors
  116. // -- usb_config_endpoints( udi->Descriptors ) --
  117. // âûçûâàòü usb_config_endpoints íå íàäî, âûçîâ â InitUSB()
  118. udi->usbtmcGpib.gpib_root = GPIB_InitializeAllCommands(); // init SCPI command tree
  119. usbtmc_state_machine_init( &udi->usbtmcGpib.StateMachine );
  120. /* ---------- îáÿçàòåëüíàÿ çàùèòà áàíêà ïàìÿòè 0 (çàâîäñêèå êàëèáðîâêè) ------------- */
  121. /* WARNING: êîìàíäà çàùèòà ïàìÿòè ïåðåíåñåíà, òåïåðü îíà âûïîëíÿåòñÿ ïðè èíèöèàëèçàöèè
  122. êëàññà ACMBase() âíå çàâèñèìîñòè îò èñïîëüçóåìîãî ïðîòîêîëà (USBTMC/PLANAR) */
  123. // SPI äîëæåí áûòü èíèöèàëèçèðîâàí
  124. // USB_SETUP_PACKET dummy_setup_packet;
  125. // s_memset( &dummy_setup_packet, 0, sizeof(USB_SETUP_PACKET));
  126. // usbapp_SET_PROTECT_FLASH( &dummy_setup_packet ); // çàùèòà áàíêà ïàìÿòè 0
  127. /* ---------------------------------------------------------------------------------- */
  128. UsbtmcDevDepInit( udi );
  129. return (IRQ_FUNCTION_ADDRESS)USB_Interrupt;
  130. }
  131. // ====================================================================================================================
  132. // ïåðåõâàò ñîáûòèé EP0
  133. //
  134. void usbtmc_HOOK_control_out( USB_DEVICE_INFO * udi ) // ïåðåõâàò ñîîáùåíèé êîíòðîëüíîãî ïðîòîêîëà (OUT)
  135. { // ïîñëå åãî îáðàáîòêè â usb_enumeration
  136. USB_SETUP_PACKET * usb_setup_packet = &udi->EP0SetupPacket;
  137. switch( usb_setup_packet->bmRequestType & USB_CMD_MASK_COMMON )
  138. {
  139. case USB_CMD_STD_DEV_OUT: //-- STANDARD OUT device requests
  140. {
  141. switch(usb_setup_packet->bRequest)
  142. {
  143. case CLEAR_FEATURE:
  144. {
  145. if( usb_setup_packet->wValue == 0 ) // for EP
  146. {
  147. switch(usb_setup_packet->wIndex)
  148. {
  149. case USB_EP_LOG_ADDRESS_BULK_IN:
  150. {
  151. usbtmc_reset_bulkrespond_status (&udi->BulkRespondStatus);
  152. usb_reset_pipe_status (&udi->EPBulkStatus.InPipe);
  153. s_memset( (BYTE*)usb_setup_packet, 0x00, sizeof(USB_SETUP_PACKET) ); // ïàêåò óæå îòðàáîòàí, ñòðèàåì ïàêåò ÷òîáû íå ïîïàñòü ñþäà ñíîâà ïðè ëþáîì äðóãîì ïðåðûâàíèè
  154. }
  155. break;
  156. case USB_EP_LOG_ADDRESS_BULK_OUT:
  157. {
  158. usbtmc_reset_bulkmessage_status (&udi->BulkMessageStatus);
  159. usb_reset_pipe_status (&udi->EPBulkStatus.OutPipe);
  160. s_memset( (BYTE*)usb_setup_packet, 0x00, sizeof(USB_SETUP_PACKET) ); // ïàêåò óæå îòðàáîòàí, ñòðèàåì ïàêåò ÷òîáû íå ïîïàñòü ñþäà ñíîâà ïðè ëþáîì äðóãîì ïðåðûâàíèè
  161. }
  162. break;
  163. }
  164. }
  165. }
  166. break;
  167. } // switch(usb_setup_packet->bRequest)
  168. } // case USB_CMD_STD_DEV_OUT
  169. break;
  170. }
  171. }
  172. // =========================================================================================================================================
  173. void UsbtmcDevDepInit( USB_DEVICE_INFO * udi )
  174. {
  175. /* ReadDeviceInfo(); --- replaced, VariableInit_Post */
  176. GPIBInit( udi );
  177. GPIB_DevDepInit( udi );
  178. }
  179. // =========================================================================================================================================
  180. void usbtmc_state_machine_init( USB_USBTMC_GPIBEMULATION_STATEMACHINE * pStateMachine )
  181. {
  182. s_memset( (BYTE*)pStateMachine, 0x00, sizeof(USB_USBTMC_GPIBEMULATION_STATEMACHINE) );
  183. pStateMachine->ESR |= (1<<ESR_PWN);
  184. queue_create( gGPIBErrorQueue, USB_MAX_ERROR_QUEUE, &pStateMachine->qErrorQueue);
  185. }
  186. // =========================================================================================================================================
  187. // @ @ @@@@@ @@@@@ @@@@@@ @ @ @@@@ @@@@ @@@@@ @@@@@ @@@@ @@@@@
  188. // @ @ @ @ @ @ @@ @@ @ @ @ @ @ @ @ @ @ @ @ @
  189. // @ @ @@@@@@ @@@@@ @ @ @@ @ @ @@@@@@ @@@@@ @@@@@ @ @ @@@@@
  190. // @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @
  191. // @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @
  192. // @@@@ @@@@ @@@@@ @@@ @ @ @@@@ @@@@ @ @@ @ @@ @@@@ @ @@
  193. void usbtmc_GenRecieveError( USB_DEVICE_INFO * udi )
  194. {
  195. //usbtmc_RaiseError( udi, GPIB_ERROR_ID_EXE, ERROR_USBTMC_BUFFER_OVERFLOW_OUT, "", 0);
  196. /* 27/08/18 usbtmc_RaiseError( udi, GPIB_ERROR_ID_EXE, ERROR_USBTMC_INTERNAL, "", 0); */
  197. if( ! usbtmc_RaiseError( udi, errClass_Device, ERROR_USBTMC_INTERNAL, "", 0) )
  198. {
  199. usbtmc_ErrorQueue_RestoreCheckpoint( udi );
  200. }
  201. }
  202. BOOL usbtmc_RaiseError_CatDescription( USB_DEVICE_INFO * udi, const char * description, unsigned int desc_len )
  203. {
  204. // äîïîëíÿåò usbtmc_RaiseError(). íóæíà äëÿ äîáàâëåíèÿ description ïðåäûäóùåé äîáàâëåííîé îøèáêè â î÷åðåäü
  205. // Ïîçâîëÿåò íå ñîçäàâàòü íîâûé ýëåìåíò â î÷åðåäè (ñ êîäîì îøèáêè) à äîáàâèòü òåêñò ê ïðåäûäóùåé
  206. QUEUE * pQueue = &udi->usbtmcGpib.StateMachine.qErrorQueue;
  207. return queue_cat( pQueue, description, desc_len );
  208. }
  209. // =========================================================================================================================================
  210. BOOL usbtmc_ErrorQueue_CreateCheckpoint( USB_DEVICE_INFO * udi )
  211. {
  212. QUEUE * pQueueSrc = &udi->usbtmcGpib.StateMachine.qErrorQueue;
  213. QUEUE * pQueueDst = &udi->usbtmcGpib.StateMachine.qErrorQueue_backup;
  214. *pQueueDst = *pQueueSrc;
  215. return TRUE;
  216. }
  217. BOOL usbtmc_ErrorQueue_RestoreCheckpoint( USB_DEVICE_INFO * udi )
  218. {
  219. QUEUE * pQueueDst = &udi->usbtmcGpib.StateMachine.qErrorQueue;
  220. QUEUE * pQueueSrc = &udi->usbtmcGpib.StateMachine.qErrorQueue_backup;
  221. *pQueueDst = *pQueueSrc;
  222. return TRUE;
  223. }
  224. // =========================================================================================================================================
  225. BOOL usbtmc_RaiseError( USB_DEVICE_INFO * udi, GPIB_ErrorClass_t errClass,
  226. int dwCode,
  227. const char * pDesc,
  228. size_t nDescLen )
  229. {
  230. QUEUE * pQueue = &udi->usbtmcGpib.StateMachine.qErrorQueue;
  231. BOOL rc = FALSE;
  232. uint8_t aMemBuf[64];
  233. // ---------------------------------------------------------
  234. usbtmc_ErrorQueue_CreateCheckpoint( udi );
  235. // ---------------------------------------------------------
  236. if( pDesc == NULL ) nDescLen = 0;
  237. if( nDescLen > sizeof(aMemBuf) - 2*sizeof(uint32_t) )
  238. {
  239. nDescLen = sizeof(aMemBuf) - 2*sizeof(uint32_t);
  240. }
  241. // ---------------------------------------------------------
  242. {
  243. size_t nCount = 0;
  244. if( !queue_getcount( pQueue, &nCount ) ) return FALSE;
  245. if( nCount > 16 ) return FALSE;
  246. }
  247. // ---------------------------------------------------------
  248. uint32_t * pCode = (unsigned int*)((ptrdiff_t)aMemBuf + 0); // error code
  249. uint32_t * pClass = (unsigned int*)((ptrdiff_t)aMemBuf + sizeof(uint32_t)); // error class
  250. // ---------------------------------------------------------
  251. *pCode = dwCode;
  252. *pClass = errClass; // 27/08/18, *pCode = ErrorID
  253. // ---------------------------------------------------------
  254. if( NULL != pDesc && 0 != nDescLen )
  255. {
  256. char * pText = (char*)((ptrdiff_t)aMemBuf + 2* sizeof(uint32_t)); // error description
  257. memcpy( pText, pDesc, nDescLen );
  258. }
  259. // ---------------------------------------------------------
  260. switch( errClass )
  261. {
  262. case errClass_Command: GPIB_SET_CME(); break;
  263. case errClass_Execution: GPIB_SET_EXE(); break;
  264. case errClass_Query: GPIB_SET_QRE(); break;
  265. case errClass_Device: GPIB_SET_DDE(); break;
  266. default: GPIB_SET_DDE(); break;
  267. }
  268. // ---------------------------------------------------------
  269. if( TRUE == queue_add( pQueue, aMemBuf, 2* sizeof(uint32_t) + nDescLen ) )
  270. {
  271. GPIB_SET_EAV();
  272. rc = TRUE;
  273. }
  274. return rc;
  275. }
  276. // =========================================================================================================================================
  277. BOOL usbtmc_ClearLastError( USB_DEVICE_INFO * udi )
  278. {
  279. char dummy[64];
  280. usbtmc_GetErrorText( udi, dummy, 64 );
  281. return (GPIB_GET_EAV());
  282. }
  283. // =========================================================================================================================================
  284. int usbtmc_GetRegisteredErrorDescription( int dwErrCode, char * pOutput, unsigned int cbMaxLength )
  285. {
  286. switch(dwErrCode)
  287. { case ERROR_USBTMC_PARAMETER:
  288. return snprintf(pOutput, cbMaxLength, "%s", "Parameter error ");
  289. case ERROR_USBTMC_EXECUTION:
  290. return snprintf(pOutput, cbMaxLength, "%s", "Execution error ");
  291. case ERROR_USBTMC_DATANOTFOUND:
  292. return snprintf(pOutput, cbMaxLength, "%s", "No data found ");
  293. case ERROR_USBTMC_NOTHERMCOMPDATA:
  294. return snprintf(pOutput, cbMaxLength, "%s", "No data found ");
  295. case ERROR_USBTMC_ARRAY_CORRUPTED:
  296. return snprintf(pOutput, cbMaxLength, "%s", "Data array corrupted ");
  297. //case ERROR_USBTMC_HEADER_CORRUPTED:
  298. //return snprintf(pOutput, cbMaxLength, "%s", "Header corrupted ");
  299. case ERROR_USBTMC_INTERNAL:
  300. return snprintf(pOutput, cbMaxLength, "%s", "Internal execution error");
  301. case ERROR_USBTMC_TOOMANY_REQUESTS:
  302. return snprintf(pOutput, cbMaxLength, "%s", "Too many requests in line (");
  303. case ERROR_USBTMC_INVALID_HEADER:
  304. //case ERROR_USBTMC_COMMANDONLY:
  305. //case ERROR_USBTMC_REQUESTONLY:
  306. //
  307. return snprintf(pOutput, cbMaxLength, "%s", "Invalid header ");
  308. //case ERROR_USBTMC_BUFFER_OVERFLOW_OUT:
  309. //return snprintf(pOutput, cbMaxLength, "%s", "IN-Buffer overflow"); // IN-Buffer: Host->Dev
  310. //case ERROR_USBTMC_BUFFER_OVERFLOW_IN:
  311. //return snprintf(pOutput, cbMaxLength, "%s", "OUT-Buffer overflow"); // OUT-Buffer: Dev->Host
  312. }
  313. return 0;
  314. }
  315. // =========================================================================================================================================
  316. int usbtmc_GetErrorText( USB_DEVICE_INFO * udi, char * pText, unsigned int dwMaxSize)
  317. {
  318. QUEUE * pQueue = &udi->usbtmcGpib.StateMachine.qErrorQueue;
  319. int rc = 0;
  320. size_t nCount = 0;
  321. if( queue_getcount( pQueue, &nCount ) )
  322. {
  323. if( nCount == 0 )
  324. {
  325. GPIB_CLR_EAV();
  326. strcpy( pText, "0, \"No error\"" );
  327. rc = strlen( pText );
  328. }
  329. else
  330. {
  331. if( queue_get_topitemsize(pQueue, (unsigned int*)&rc) )
  332. {
  333. if( queue_get( pQueue, pText, dwMaxSize, (unsigned int*)&rc) )
  334. {
  335. // ---------------------------------------------------------------
  336. // 80 00 00 00 B L A B L A B L A
  337. // _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ... _ _ _
  338. // \ / \ /
  339. // code error description
  340. //
  341. //
  342. // 1 2 8 , " BLA BLA BLA "
  343. // _ _ _ ... _ _ _ _ _ _ _ _ _ _ _ ... _ _ _
  344. // \ / \ /
  345. // code error description
  346. //
  347. // ---------------------------------------------------------------
  348. // the description is the rest bytes after two integer codes (8bytes)
  349. size_t nDescLen = ( rc - sizeof(int) * 2 );
  350. if( rc > 0 )
  351. {
  352. if( pText[ rc - 1 ] == '\0' )
  353. {
  354. nDescLen--; // cut off the null-term
  355. }
  356. }
  357. // retrieve the error number
  358. int dwCode = *((int*)pText);
  359. //unsigned int ID = *((unsigned int*)pText + 1);
  360. char tmpBuf[64];
  361. size_t nTmpBufSize = sizeof(tmpBuf);
  362. nCount = snprintf( tmpBuf, nTmpBufSize,"%d, \"", dwCode);
  363. if( nCount >= nTmpBufSize )
  364. nCount = 0;
  365. else
  366. nTmpBufSize -= nCount;
  367. // retrieve the common description length
  368. // note: cbMaxLength is 0
  369. size_t nCommonDescLength = usbtmc_GetRegisteredErrorDescription( dwCode, &tmpBuf[nCount], 0 );
  370. if( dwMaxSize < nCount + nCommonDescLength + nDescLen )
  371. {
  372. // not enougth free space in the buffer
  373. rc = 0;
  374. }
  375. else
  376. {
  377. // The description begins with the (sizeof(int) * 2) character
  378. // and has a nDescLen character length
  379. // We have @nCount bytes in @tmpBuf to print
  380. // It is required to move the description in the @pText
  381. // to the (nCount + nCommonDescLength), due to it is
  382. // required to print firstly the data from @pText, then
  383. // the @nCommonDescLength bytes of data returned by @usbtmc_GetRegisteredErrorDescription(),
  384. // and then the data that actually is in @pText (@nDescLen length)
  385. // [nCount] [nCommonDescLength] [nDescLen]
  386. // So, we know, that is required to allocate the space for:
  387. // - @nCount bytes of @tmpBuf
  388. // - @nCommonDescLength bytes of common description (usbtmc_GetRegisteredErrorDescription)
  389. // Let's move the description:
  390. memmove( &pText[nCount + nCommonDescLength], &pText[sizeof(int) * 2], nDescLen );
  391. // copy @tmpBuf to the begin of @pText
  392. memcpy( &pText[0], tmpBuf, nCount );
  393. // and actually print the common description to the @pText after the @tmpBuf contents
  394. char x = pText[nCount+nCommonDescLength]; // this character will be filled with null-term by usbtmc_GetRegisteredErrorDescription()
  395. usbtmc_GetRegisteredErrorDescription( dwCode, &pText[nCount], (nCommonDescLength + 1) );
  396. pText[nCount+nCommonDescLength] = x;
  397. rc = nCount + nCommonDescLength + nDescLen;
  398. if( rc < dwMaxSize )
  399. {
  400. pText[rc] = '\"';
  401. rc++;
  402. }
  403. }
  404. }
  405. else
  406. {
  407. rc = 0;
  408. }
  409. }
  410. if( queue_getcount(pQueue, &nCount)==TRUE && nCount==0) GPIB_CLR_EAV();
  411. }
  412. }
  413. return rc;
  414. }
  415. // =========================================================================================================================================
  416. unsigned int usbtmc_EndOfTransfer( void * vudi )
  417. {
  418. USB_DEVICE_INFO * udi = (USB_DEVICE_INFO *) vudi;
  419. USB_EP_STATUS * pbulk_status = (USB_EP_STATUS *) &udi->EPBulkStatus;
  420. USB_PIPE_ENTRY_IN * pInPipe = (USB_PIPE_ENTRY_IN *) &pbulk_status->InPipe;
  421. USB_BULKRESPOND_STATUS * pBulkRespond = (USB_BULKRESPOND_STATUS*) &udi->BulkRespondStatus;
  422. // âûçûâàåòñÿ êîãäà â Pipe êîí÷àþòñÿ äàííûå:
  423. // InPipe èìååò äâà ïîëÿ: dwAllLength è dwLength
  424. // Ïåðâîå çàäàåò êîè÷åñòâî äàííûõ, êîòîðûå íóæíî ïåðåäàòü
  425. // Âòîðîå - òîëüêî òî ÷òî âìåùàåòñÿ â âûõîäíîé áóôåð (èëè ñêîëüêî çàïðîñèë Host, ñìîòðÿ, ÷òî ìåíüøå)
  426. // -----------------------------------
  427. if( pInPipe->dwLength != 0 ) return 0;
  428. // -----------------------------------
  429. if ( pBulkRespond->dwDeviceOut > 0 && pInPipe->dwLength == 0 )
  430. {
  431. unsigned int dwBytesRemaining = pBulkRespond->dwDeviceOut;
  432. s_memcpy( pInPipe->pDefaultBuffer + sizeof(BULKIN_HEADER), // ñäâèãàåì áóôåð ê íà÷àëó. Îñòàâëÿåì ìåñòî ïîä çàãîëîâîê
  433. pInPipe->pData, // òåêóùèé óêàçàòåëü íà äàííûå
  434. dwBytesRemaining); // îñòàâøååñÿ êîëè÷åñòâî íåïåðåäàííûõ äàííûõ
  435. // ---------------------------
  436. usbtmc_init_intransfer( udi ); // ñáðîñ
  437. // ---------------------------
  438. pBulkRespond->dwDeviceOut = dwBytesRemaining;
  439. pBulkRespond->bIsLastTransfer = FALSE;
  440. pBulkRespond->bEndOfMessage = FALSE;
  441. if( (udi->GPIBFunctionContext.LastFunction != NULL && udi->GPIBFunctionContext.bEnable == TRUE) )
  442. {
  443. TCmdParser_f LastFunction = (TCmdParser_f)udi->GPIBFunctionContext.LastFunction;
  444. // ------------------------------------------
  445. udi->GPIBFunctionContext.bEnable = TRUE;
  446. udi->GPIBFunctionContext.LastFunction = NULL;
  447. // ------------------------------------------
  448. udi->usbtmcGpib.pData = pInPipe->pDefaultBuffer + sizeof(BULKIN_HEADER) + dwBytesRemaining;
  449. udi->BulkRespondStatus.RespondBufferSize-= dwBytesRemaining;
  450. udi->BulkRespondStatus.dwDeviceOut += LastFunction( udi, NULL, FALSE );
  451. }
  452. // íå óõîäèì íà REQUEST_DEV_DEP_MSG_IN. òàê êàê ñþäà ïîïàäåì ðàíüøå ÷åì ïðèäåò ðåàëüíûé REQ_MSG_IN => bTag åùå ñòàðûé
  453. // îñòàâëÿåì pInPipe.dwLength = 0 ÷òîáû êîðìèòü NAKàìè äî ïðèõîäà ñëåäóþùåãî REQ_MSG_IN
  454. }
  455. else
  456. {
  457. // ---------------------------------------------------------------------------------
  458. // ïîêà ôóíêöèÿ íå óñòàíîâèò ôëàã bIsLastTransfer, EndOfTransfer() áóäåò âûçûâàòü åå
  459. if( pBulkRespond->bIsLastTransfer == FALSE )
  460. {
  461. if( ! (udi->GPIBFunctionContext.LastFunction != NULL && udi->GPIBFunctionContext.bEnable == TRUE) )
  462. {
  463. pInPipe->dwAllLength = 0;
  464. pBulkRespond->bIsLastTransfer = TRUE;
  465. pBulkRespond->bEndOfMessage = TRUE;
  466. }
  467. else
  468. {
  469. TCmdParser_f LastFunction = (TCmdParser_f)udi->GPIBFunctionContext.LastFunction;
  470. // ---------------------------------------------------------------------------------
  471. // ------------------------------------------
  472. udi->GPIBFunctionContext.bEnable = TRUE;
  473. udi->GPIBFunctionContext.LastFunction = NULL;
  474. // ------------------------------------------
  475. // ---------------------------
  476. usbtmc_init_intransfer( udi );
  477. // ---------------------------
  478. udi->BulkRespondStatus.dwDeviceOut += LastFunction( udi, NULL, FALSE );
  479. // usbtmc_REQUEST_DEV_DEP_MSG_IN( udi ); // òàì èäåò ìîäèôèêàöèÿ çàãîëîâêà äàííûõ
  480. }
  481. }
  482. }
  483. return pBulkRespond->bIsLastTransfer;
  484. }
  485. // =========================================================================================================================================
  486. void usbtmc_create_function_context( USB_DEVICE_INFO * udi, void * pFunction )
  487. {
  488. udi->GPIBFunctionContext.LastFunction = pFunction;
  489. udi->GPIBFunctionContext.bEnable =TRUE;
  490. queue_create( gGPIBFunctionContext, USB_MAX_FUNCCONTEXT, &udi->GPIBFunctionContext.Context);
  491. }
  492. // =========================================================================================================================================
  493. void usbtmc_delete_function_context( USB_DEVICE_INFO * udi )
  494. {
  495. udi->GPIBFunctionContext.bEnable = FALSE;
  496. udi->GPIBFunctionContext.LastFunction = NULL;
  497. queue_clear( &udi->GPIBFunctionContext.Context);
  498. }
  499. // =========================================================================================================================================
  500. int USBTMC_StateMachine_Modified( USB_USBTMC_GPIBEMULATION_STATEMACHINE * pStateMachine)
  501. {
  502. // Check event status register and the mask
  503. if( (pStateMachine->ESE) & (pStateMachine->ESR) )
  504. {
  505. // set Event Status Bit
  506. pStateMachine->STB |= (1<<STB_ESB);
  507. }
  508. else
  509. {
  510. // clear Event Status Bit
  511. pStateMachine->STB &= (~(1<<STB_ESB));
  512. }
  513. // Check the Status Byte Register and the mask (SRE)
  514. if( (pStateMachine->STB & 0xBF) & pStateMachine->SRE )
  515. {
  516. pStateMachine->STB |= (1<<STB_RQS_MSS);
  517. }
  518. else
  519. {
  520. pStateMachine->STB &= (~(1<<STB_RQS_MSS));
  521. }
  522. // pStateMachine->ESR |= (1<<ESR_PWN);
  523. // pStateMachine->ESR |= (1<<ESR_OPC);
  524. return TRUE; // only true!, see usbtmc.h, #defines
  525. }
  526. // ====================================================================================================================
  527. void usbtmc_service( USB_DEVICE_INFO * udi, BOOL Tick )
  528. {
  529. /* 30/08/18 Ðåôàêòîðèíã.
  530. Ìåòîä âûçîâà ôóíêöèé èç îñíîâîãî ïîòîêà, êîòîðûé áûë ðåàëèçîâàí çäåñü,
  531. áûë îñíîâàí íà ïðåäïîëîæåíèè, ÷òî íåëüçÿ îáîðâàòü ïåðåäà÷ó bulk â ïðîöåññå
  532. åå âûïîëíåíèÿ â îñíîâíîì ïîòîêå... Íî ïîñëå îñìîòðà êîäà, òàêèõ âûçîâîâ
  533. èç îñíîâíîãî ïîòîêà ÿ íå íàøåë. Âîçìîæíî ýòî legacy-êîä, êîìåíòàðèè áîëåå
  534. íå àêòóàëüíû. Ò.ê. âñå âûçîâû ðàáîòàþò èñêëþ÷èòåëüíî â ïðåðûâàíèÿõ,
  535. ÿ çàìåíèë âñå âûçîâû ÷åðåç ôëàãè íà ïðÿìûå âûçîâû ôóíêöèé.
  536. À äàííàÿ ôóíêöèÿ áîëåå íåàêòóàëüíà.
  537. if(bUSBTMCEnable==FALSE) return; // ñì UsbtmcInit()
  538. // ---------- ÔËÀà INITIATE_CLEAR ïîëó÷åí -----------
  539. USB_INTERRUPT_DISABLE();
  540. if(MACRO_FLAGGET_INITIATE_CLEAR())
  541. { MACRO_FLAGCLR_INITIATE_CLEAR();
  542. USB_INTERRUPT_ENABLE();
  543. // íåëüçÿ âûïîëíèòü usbtmc_initiate_clear ñðàçó â ïðåðûâàíèè, ýòî ÷ðåâàòî
  544. // òåì, ÷òî çàïðîñ íà usbtmc_initiate_clear ìîæåò ïðèéòè âî âðåìÿ îáàáîòêè
  545. // ñêàæåì usb_EP2_tx_func__() êîãäà îíà âûïîëíÿåòñÿ â îñíîâíîì ïîòîêå.
  546. // Ôóíêöèÿ usbtmc_initiate_clear âûïîëíèò
  547. // usbtmc_abort_bulkin_transfer() â êîíòåêñòå ïðåðûâàíèÿ, îñòàíîâèâ usb_EP2_tx_func__
  548. // â ñàìîì íåïðèëè÷íîì ìåñòå (:-D) usbtmc_initiate_clear îòðàáîòàâ, âåðíåò óïðàâëåíèå ê
  549. // usb_EP2_tx_func__() è òàê êàê íè â ÷åì íå áûâàëî ïðîäîëæèò ÍÅÈÇÂÅÑÒÍÎ îòêóäà
  550. // è íåèçâåñòíî ÷òî ïðè ýòîì ñäåëàåò ( ïåðåäà÷à òî óæå çàâåðøåíà ïîèäåå, à îíà
  551. // òàì ïåðåìåííûå íà÷íåò ìåíÿòü )
  552. usbtmc_initiate_clear( udi, 0 );
  553. }
  554. USB_INTERRUPT_ENABLE();
  555. // -------------------------------------------
  556. // ---------- ÔËÀà INITIATE_ABORT_BULK_IN ïîëó÷åí ----------
  557. USB_INTERRUPT_DISABLE();
  558. if(MACRO_FLAGGET_INITIATE_BULKIN_ABORT())
  559. { MACRO_FLAGCLR_INITIATE_BULKIN_ABORT();
  560. USB_INTERRUPT_ENABLE();
  561. // ïðè÷èíó ñì âûøå äëÿ usbtmc_initiate_clear, àíàëîãè÷íî
  562. usbtmc_abort_bulkin_transfer ( udi, 0 );
  563. }
  564. USB_INTERRUPT_ENABLE();
  565. // -------------------------------------------
  566. // -------------------------------------------
  567. // ---------- ÔËÀà INITIATE_ABORT_BULK_OUT ïîëó÷åí ----------
  568. USB_INTERRUPT_DISABLE();
  569. if(MACRO_FLAGGET_INITIATE_BULKOUT_ABORT())
  570. { MACRO_FLAGCLR_INITIATE_BULKOUT_ABORT();
  571. USB_INTERRUPT_ENABLE();
  572. // ïðè÷èíó ñì âûøå äëÿ usbtmc_initiate_clear, àíàëîãè÷íî
  573. usbtmc_abort_bulkout_transfer ( udi, 0 );
  574. }
  575. USB_INTERRUPT_ENABLE();
  576. // -------------------------------------------
  577. */
  578. }
  579. //=========================================================================================================================
  580. // @@@@ @@@@ @ @ @ @ @@@@ @ @ @@@@@@ @ @ @ @ @@@@
  581. // @ @ @ @ @@ @@ @@ @@ @ @ @@ @ @ @ @ @@ @ @ @
  582. // @ @ @ @ @@ @ @ @@ @ @ @ @ @ @ @@@@ @ @ @ @ @ @
  583. // @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @
  584. // @ @ @ @ @ @ @ @ @ @ @ @@ @ @ @ @ @@ @ @
  585. // @@@@ @@@@ @ @ @ @ @@@@ @ @ @ @@@@ @ @ @@@@
  586. void usbtmc_bulkout_stall_and_abort( USB_DEVICE_INFO * udi )
  587. {
  588. usb_stall_ep( USB_EP_LOG_ADDRESS_BULK_OUT, 0x01 );
  589. usbtmc_abort_bulkout_transfer( udi, FLAG_USBTMC_FORCE_BULKOUT_ABORT ); // ôëàã FLAG_USBTMC_FORCE_BULKIN_ABORT - çàãëóøêà, ôëàã FLAG_USBTMC_FORCE_BULKOUT_ABORT ïðèíóæäàåò çàâåðøèòü ïåðåäà÷ó ìãíîâåííî
  590. }
  591. // ----------------------------------------------------------------------------------------------------
  592. void usbtmc_bulkin_stall_and_abort( USB_DEVICE_INFO * udi )
  593. {
  594. usb_stall_ep( USB_EP_LOG_ADDRESS_BULK_IN, 0x01 );
  595. usbtmc_abort_bulkin_transfer( udi, FLAG_USBTMC_FORCE_BULKIN_ABORT ); // ôëàã FLAG_USBTMC_FORCE_BULKIN_ABORT ïðèíóæäàåò çàâåðøèòü ïåðåäà÷ó ìíãîâåííî, áåç îæèäàíèÿ îòïðàâêè Short ïàêåòà
  596. }
  597. //=========================================================================================================================
  598. // see USBTMC spec., rev 1.0., 2003, page 22, 4.2.1.3
  599. // @@@@ @ @ @@@@ @@@@ @ @ @@@@ @@@@@ @@@ @@@@@ @@@@@@@ @@@@@ @ @ @ @ @ @@@ @ @ @@@@@@@
  600. // @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @
  601. // @ @ @ @@@@@@ @ @@@@ @ @ @@@@@ @ @ @ @ @ @@@@@ @ @ @ @@@@ @@@@@ @ @ @ @ @
  602. // @ @@@@@ @ @ @ @ @@@@@@ @ @ @ @ @@@@@ @ @ @ @ @ @ @ @ @ @ @ @ @
  603. // @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @
  604. // @@@@ @ @ @@@@ @@@@ @ @ @ @ @@@@@ @@@ @ @ @ @@@@@ @@@@ @ @@@@@@ @ @ @@@ @@@@ @ @
  605. int usbtmc_checkstatus_abort_bulkout( USB_DEVICE_INFO * udi )
  606. {
  607. USB_USBTMC_CLASS_STATUS * pusbtmcStatus = (USB_USBTMC_CLASS_STATUS *) &udi->usbtmcStatus;
  608. USB_BULKMESSAGE_STATUS * pBulkMessage = (USB_BULKMESSAGE_STATUS*) &udi->BulkMessageStatus;
  609. USB_SETUP_PACKET * usp = &udi->EP0SetupPacket;
  610. USB_EP_STATUS * eps = &udi->EP0Status;
  611. BYTE * pbRespondBytes = ( BYTE * ) eps->InPipe.pData;
  612. // ïðîâåðÿþò, ñáðîñèëè ëè ìû ïåðåäà÷ó ïî Bulk-OUT.
  613. if( pusbtmcStatus->USBTMC_InitiateRecieved == TRUE ) // åñëè âîîáùå áûë ïðèíÿò çàïðîñ íà ñáðîñ ïåðåäà÷è
  614. {
  615. pusbtmcStatus->USBTMC_InitiateRecieved = FALSE;
  616. pbRespondBytes[0] = pusbtmcStatus->USBTMC_status;
  617. pbRespondBytes[1] = 0; // reserved
  618. pbRespondBytes[2] = 0; // reserved
  619. pbRespondBytes[3] = 0; // reserved
  620. *((unsigned int *)(&pbRespondBytes[4])) = pBulkMessage->nBytesRecieved;
  621. pBulkMessage->nBytesRecieved = 0;
  622. }
  623. else
  624. {
  625. pbRespondBytes[0] = STATUS_SPLIT_NOT_IN_PROGRESS;
  626. pbRespondBytes[1] = 0; // reserved
  627. pbRespondBytes[2] = 0; // reserved
  628. pbRespondBytes[3] = 0; // reserved
  629. *((unsigned int *)(&pbRespondBytes[4])) = 0;
  630. }
  631. eps->InPipe.dwLength = ( 8 <= usp->wLength)? 8: usp->wLength;
  632. return 0x00;
  633. }
  634. //=========================================================================================================================
  635. //=========================================================================================================================
  636. // usbtmc_abort_bulkout_transfer - ïðåðûâàåò òåêóùóþ ïåðåäà÷ó Bulk-OUT,
  637. // èíèöèàëèçèðóÿ âñå íåîáõîäèìûå ïåðåìåííûå è ïàðàìåòðû òàê, ÷òîáû ïðèíÿòü
  638. // êîððåêòíî íîâóþ Bulk-OUT ïåðåäà÷ó íà÷èíàÿ ñ BULK-OUT Header îò õîñòà
  639. // @@@@ @@@@@ @@@ @@@@@ @@@@@@@ @@@@@ @ @ @ @ @ @@@ @ @ @@@@@@@
  640. // @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @
  641. // @ @ @@@@@ @ @ @ @ @ @@@@@ @ @ @ @@@@ @@@@@ @ @ @ @ @
  642. // @@@@@@ @ @ @ @ @@@@@ @ @ @ @ @ @ @ @ @ @ @ @ @
  643. // @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @
  644. // @ @ @@@@@ @@@ @ @ @ @@@@@ @@@@ @ @@@@@@ @ @ @@@ @@@@ @ @
  645. int usbtmc_abort_bulkout_transfer ( USB_DEVICE_INFO * udi, int dwFlags ){
  646. // abort HOST->DEVICE
  647. int ep_state;
  648. USB_USBTMC_CLASS_STATUS * pusbtmcStatus = (USB_USBTMC_CLASS_STATUS *) &udi->usbtmcStatus;
  649. USB_BULKMESSAGE_STATUS * pBulkMessage = (USB_BULKMESSAGE_STATUS*) &udi->BulkMessageStatus;
  650. USB_SETUP_PACKET * usp = &udi->EP0SetupPacket;
  651. USB_EP_STATUS * eps = &udi->EP0Status;
  652. BYTE * pbRespondBytes = ( BYTE * ) eps->InPipe.pData;
  653. // MACRO_PROGRAMSECURITY_BOACXT_TRYENTER(); // ïðîâåðÿåì, âûçâàíà ëè usbtmc_abort_bulkin_transfer() ðåêóðñèâíî, åñëè äà, âûõîäèì
  654. //-----------------------------------------------------------------------------------------------------------------
  655. if( dwFlags & FLAG_USB_SETUPPACKET_RECIEVED )
  656. {
  657. /* åñëè ôóíêöèÿ âûçâàíà ñ ýòèì ôëàãîì, ýòî îçíà÷àåò, ÷òî áûë ïðèíÿò çàïðîñ íà óíè÷òîæåíèå ïåðåäà÷è Bulk-Out
  658. Ïåðåäà÷à íå áóäåò óíè÷òîæåíà ñðàçó.  ïðåðûâàíèè äåëàòü ýòîãî íå ñòîèò, òàê êàê âïîëíå âîçìîæíî, ÷òî ôóíêöèÿ
  659. áóäåò âûçâàíà â ìîìåíò, êîãäà âåäåòñÿ ïåðåäà÷à è âûïîëíÿåòñÿ ôóíêöèÿ usb_EP2_tx_func__(), êîòîðàÿ ðàáîòàåò
  660. ñ ïåðåìåííûìè è óêàçàòåëÿìè, êîòîðûå íóæíî îáíóëèòü çäåñü. Íóæíî äîæäàòüñÿ, îñíîâíîé ïîòîê âûäéäåò èç òàêèõ
  661. ôóíêöèé. Ñëåäóåò ïîñòàâèòü çàïïðîñ â î÷åðåäü, óñòàíîâèâ ôëàæîê.
  662. Ðåôàêòîðèíã. 30/08/18. Ïðî÷èòàë. Íå ïîíÿë.
  663. Íè îäíà èç ôóíêöèé ïðîòîêîëà USBTMC íå âûçûâàåòñÿ èç îñíîâãîãî ïîòîêà.
  664. Âîçìîæíî, êîìåíòàðèé óæå óñòàðåë. Âñå ïåðåäà÷è âåäóòñÿ èç ïðåðûâàíèÿ,
  665. à çíà÷èò "çàñòàòü" íèêàêóþ ôóíêöèþ â íèêàêîì ìåñòå íåëüçÿ, ïîñêîëüêó
  666. îíà âûçûâàåòñÿ èç êîíòåêñòà òîãî æå âåêòîðà ïðåðûâàíèÿ.
  667. */
  668. // çàïðîñ ïîñòàâëåí â î÷åðåäü íà îáðàáîòêó èç êîíòåêñòà ïðåðûâàíèÿ
  669. // see "USBTMC spec., rev 1.0, 2003": "page 18-19..."
  670. if(pusbtmcStatus->USBTMC_InitiateRecieved == FALSE)
  671. {
  672. // -- çàïðîñ INITIATE_ABORT_BULK_OUT ïðèíÿò íå áûë
  673. // -- õîñò íå äîëæåí ïðèñûëàòü äâà òàêèõ çàïðîñà ïîäðÿä
  674. // -- åñëè õîñò ïðèñëàë class request íå CHECK_STATUS, åãî îáðàáîòàåò usbtmc_class_request_fault
  675. pbRespondBytes[1] = pBulkMessage->bTag; // -- çàïîëíÿåì îñòàâøååñÿ ïîëå îòâåòíîãî ñîîáùåíèÿ
  676. eps->InPipe.dwLength = ( 2 <= usp->wLength)? 2: usp->wLength; // -- îòâåòíîå ñîîáùåíèå ñîäåðæèò 2 áàéòà
  677. if((pBulkMessage->OUTTransferInProgress == TRUE) && (pBulkMessage->bTag == (0xFF & usp->wValue)))
  678. {
  679. // - Ïåðåäà÷à â ïðîöåññå ---> Ïåðåäà÷à áóäåò çàâåðøåíà,
  680. // - bTag ñîâïàë ---> çàïðîñ ïîñòàâëåí â î÷åðåäü, ñòàòóñ: STATUS_PENDING
  681. pusbtmcStatus->USBTMC_InitiateRecieved = TRUE; // -- ïðèíÿò çàïðîñ INITIATE
  682. pusbtmcStatus->USBTMC_status = STATUS_PENDING; // -- ïåðåäà÷à îæèæàåò çàâåðøåíèÿ
  683. pbRespondBytes[0] = STATUS_SUCCESS; // -- ñòàòóñ îïåðàöèè (òåêóùåãî çàïðîñà) : STATUS_SUCCESS, îïåðàöèÿ âûïîëíåíà, çàïðîñ ïîñòàâëåí â î÷åðåäü
  684. /* 30/08/18, ðåôàêòîðèíã.
  685. ïîñêîëüêó â ïðîãðàììå íå íàéäåíû âûçîâû îáðàáîò÷èêîâ usbtmc
  686. â îñíîâíîì ïîòîêå main(), ìåðà ïðåäîñòîðîæíîñòè îáðàáîòêè
  687. âûçîâà usbtmc_abort_bulkout_transfer ( udi, 0 ) ÷åðåç usbtmc_service èçëèøíÿÿ.
  688. Çàìåíèë âûçîâ -MACRO_FLAGSET_INITIATE_BULKOUT_ABORT()- íà ïðÿìîé
  689. âûçîâ usbtmc_abort_bulkout_transfer ( udi, 0 )
  690. -- MACRO_FLAGSET_INITIATE_BULKOUT_ABORT(); // -- ñèãíàëèçèðóåì
  691. */
  692. usbtmc_abort_bulkout_transfer ( udi, 0 );
  693. }
  694. else
  695. {
  696. // - èëè bTag íå ñîâïàë --->
  697. // - èëè bTag ñîâïàë, íî ïåðåäà÷à óæå çàâåðøåíà. ---> ñòàòóñ îïåðàöèè: íå STATUS_SUCCESS
  698. pusbtmcStatus->USBTMC_InitiateRecieved = FALSE; // -- çàïðîñ INITIATE íå ïðèíÿò
  699. // -- see USBTMC spec, rev 1.0, 2003, page 22, table 20
  700. // -- ïîëó÷àåì ñîñîòîÿíèå EP. ñìîòðèì, çàíÿòû ëè åå áóôåðû
  701. ep_state = usb_lpc_cmd_read(CMD_EP_SELECT | USB_EP_PHY_ADDRESS_BULK_OUT);
  702. if( ep_state & ((1<<5)|(1<<6)))
  703. pusbtmcStatus->USBTMC_status = STATUS_TRANSFER_NOT_IN_PROGRESS;
  704. else
  705. pusbtmcStatus->USBTMC_status = STATUS_FAILED;
  706. pbRespondBytes[0] = pusbtmcStatus->USBTMC_status;
  707. }
  708. }
  709. }
  710. else
  711. {
  712. // âûçîâ ôóíêöèè èç main
  713. // -- ñþäà ìû ïîïàäåì, åñëè âûçîâåì ô-þ áåç ôëàãà FLAG_USB_SETUPPACKET_RECIEVED
  714. // -- ýòî ìîæåò îçíà÷àòü, ÷òî áûë ïðèíÿò çàïðîñ íà îáðûâ ïåðåäà÷è è óñòàíîâëåí ôëàã FLAG_USBTMC_INITIATE_BULKOUT_ABORT
  715. // -- òàê êàê âûçîâ îñóùåñòâëåí èç îñíîâíîãî ïîòîêà, à íå èç ïðåðûâàíèÿ, îáðàáîòàåì çàïðîñ
  716. // ===============================================================================================
  717. // >>> Âàæíî! Î âûçîâå usbtmc_abort_bulkin, usbtmc_abort_bulkout <<<
  718. // -----------------------------------------------------------------------------------------------
  719. // / \ > Íåëüçÿ âûçûâàòü usbtmc_abort_bulkout è usbtmc_abort_bulkin èç ïðåðûâàíèÿ! < //
  720. // / | \ > Òàê êàê ôóíêöèè usb_EP2_t(/r)x âûçûâàþòñÿ èç îñíîâíîãî ïîòîêà, òî è < //
  721. // /__*__\ > ïðåðûâàòü ïåðåäà÷è íóæíî ÓÁÅÄÈÂØÈÑÜ, ÷òî îñíîâíîé ïîòîê íå íàõîäèòñÿ â < //
  722. // > usb_EP2_t(/r)x è íå èçìåíèò êàêóþ ëèáî èç ïåðåìåííûõ ñðàçó ïîñëå âûõîäà < //
  723. // > èç ïðåðûâàíèÿ, ãäå ýòà ïåðåìåííàÿ áûëà ñáðîøåíà. Ýòî ÷ðåâàòî íåïðîãíîçèðóåìûì ïîâåäåíèåì < //
  724. // > óñòðîéñòâà è, ñîîòâåòñòâåííî, íåïðàâèëüíîé ðàáîòîé ïðîòîêîëà USBTMC < //
  725. // > < //
  726. // ===============================================================================================
  727. // Abort Bulk trnasfer (Host->Device)
  728. //usp->wValue; // -- D0...D7 - the bTag value associated with the transfer to abort
  729. //usp->wIndex; // -- must specify direction (D7) and endpoint number (D0...D3)
  730. //usp->wLength; // -- Number of bytes to transfer: length of response to this request
  731. // -- èìååì òîëüêî îäíó Bulk-Out ïîýòîìó èãíîðèðóåì ïîëå usp->wIndex
  732. // -- îáðàáàòûâàåì bTag
  733. // -- see "USBTMC spec., rev 1.0, 2003": "page 18-19..."
  734. if(pBulkMessage->OUTTransferInProgress == TRUE )
  735. {
  736. // -- bTag ñîâïàë ïðè ïðîâåðêå çàïðîñà èç ïðåðûâàíèÿ, ïåðåäà÷à â ïðîãðåññå è áóäåò çàâåðøåíà
  737. usb_stall_ep( USB_EP_LOG_ADDRESS_BULK_OUT, 0x01 ); // -- see USBTMC spec, rev 1.0, 2003, page 22, table 20, desc. of "STATUS_SUCCESS"
  738. pusbtmcStatus->USBTMC_status = STATUS_SUCCESS;
  739. }
  740. else
  741. {
  742. // bTag õîòü è ñîâïàë ïðè ïðîâåðêå çàïðîñà èç ïðåðûâàíèÿ, íî ïåðåäà÷à âèäèìî óùå çàêîí÷åíà
  743. usb_stall_ep( USB_EP_LOG_ADDRESS_BULK_OUT, 0x01 ); // -- see USBTMC spec, rev 1.0, 2003, page 22, table 20, desc. of "STATUS_SUCCESS"
  744. pusbtmcStatus->USBTMC_status = STATUS_SUCCESS; // -- âñå ðàâíî STATUS_SUCCESS
  745. // -- see USBTMC spec, rev 1.0, 2003, page 19, table 16, page 23, table 23
  746. // -- STATUS_TRANSFER_NOT_IN_PROGRESS ìîæíî óñòàíîâèòü ÒÎËÜÊÎ ïðè ïðèåìå çàïðîñà, òîåñòü â ïðåðâààíèè
  747. // -- à çäåñü ìû óæå îáðàáàòûâàåì óæå ïðèíÿòûé çàïðîñ. Çäåñü ìû ñîãëàñíû, ÷òî ïåðåäà÷à â ïðîãðåññå
  748. // -- òàê êàê îíà áûëà â ïðîãðåññå íà ìîìåíò ïðèåìà çàïðîñà. òîëüêî STATUS_SUCCESS
  749. }
  750. pBulkMessage->MsgID = 0x00;
  751. pBulkMessage->bTag = 0x00;
  752. pBulkMessage->bTagLast = 0x00;
  753. pBulkMessage->bBulkHeaderRecieved = FALSE;
  754. //(void)pBulkMessage->nBytesRemaining; // = 0x00;
  755. pBulkMessage->nBytesRecieved = 0x00;
  756. (void)pBulkMessage->nBytesRecieved; // = 0x00; // òðåáóåòñÿ íå îáíóëÿòü ÷òîáû âåðíóòü â çàïðîñå CHECK_ABORT_BULK_OUT_STATUS
  757. pBulkMessage->OUTTransferInProgress = FALSE;
  758. }
  759. // MACRO_PROGRAMSECURITY_BOACXT_LEAVE(); // -- ïîêèäàåì
  760. return 0x00;
  761. }
  762. //=========================================================================================================================
  763. void usbtmc_reset_bulkmessage_status ( USB_BULKMESSAGE_STATUS * pBulkMessage )
  764. {
  765. s_memset( (BYTE*)pBulkMessage, 0x00, sizeof(USB_BULKMESSAGE_STATUS) );
  766. }
  767. void usbtmc_reset_bulkrespond_status ( USB_BULKRESPOND_STATUS * pBulkRespond )
  768. {
  769. s_memset( (BYTE*)pBulkRespond, 0x00, sizeof(USB_BULKRESPOND_STATUS) );
  770. }
  771. //=========================================================================================================================
  772. // usbtmc_abort_bulkin_transfer - ïðåðûâàåò òåêóùóþ ïåðåäà÷ó Bulk-IN,
  773. // èíèöèàëèçèðóÿ âñå íåîáõîäèìûå ïåðåìåííûå è ïàðàìåòðû òàê, ÷òîáû íà÷àòü
  774. // êîððåêòíî íîâóþ Bulk-IN ïåðåäà÷ó íà÷èíàÿ ñ BULK-IN Header ê õîñòó
  775. // @@@@ @@@@@ @@@ @@@@@ @@@@@@@ @@@@@ @ @ @ @ @ @@@ @ @
  776. // @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @@ @
  777. // @ @ @@@@@ @ @ @ @ @ @@@@@ @ @ @ @@@@ @@@@@ @ @ @ @
  778. // @@@@@@ @ @ @ @ @@@@@ @ @ @ @ @ @ @ @ @ @ @ @
  779. // @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @
  780. // @ @ @@@@@ @@@ @ @ @ @@@@@ @@@@ @ @@@@@@ @ @ @@@ @ @@
  781. int usbtmc_abort_bulkin_transfer ( USB_DEVICE_INFO * udi, int dwFlags )
  782. {
  783. // abort DEVICE->HOST
  784. USB_USBTMC_CLASS_STATUS * pusbtmcStatus = (USB_USBTMC_CLASS_STATUS *) &udi->usbtmcStatus;
  785. USB_BULKRESPOND_STATUS * pBulkRespond = (USB_BULKRESPOND_STATUS*) &udi->BulkRespondStatus;
  786. USB_SETUP_PACKET * usp = &udi->EP0SetupPacket;
  787. USB_EP_STATUS * eps = &udi->EP0Status;
  788. BYTE * pbRespondBytes = ( BYTE * ) eps->InPipe.pData;
  789. int ep_state;
  790. // MACRO_PROGRAMSECURITY_BIACXT_TRYENTER(); // ïðîâåðÿåì, âûçâàíà ëè usbtmc_abort_bulkin_transfer() ðåêóðñèâíî, åñëè äà, âûõîäèì
  791. //-------------------------------------------------------------------------------------------
  792. // ======================================================= //
  793. // >>> Î ñòàòóñàõ STATUS_SUCCESS è STATUS_PENDING <<< //
  794. // ------------------------------------------------------- //
  795. // Îïåðàöèÿ INITIATE_ABORT_BULK_IN ïðîèñõîäèò â //
  796. // / \ äâà ýòàïà: ïðèíèìàåòñÿ çàïðîñ îò õîñòà, ÷òî //
  797. // / | \ òðåáóåòñÿ çàâåðøèòü ïåðåäà÷ó, çàòåì õîñò ïî- //
  798. // /__*__\ ñûëàåò çàïðîñ, ñïðàâëÿÿñü î ðåçóëüòàòàõ. //
  799. // //
  800. // INITIATE_ABORT_BULK_IN - èíèöèðóåò çàâåðøåíèå ïåðåäà÷è. //
  801. // Åñëè â îòâåò íà ýòîò çàïðîñ óñòðîéñòâî îòïðàâèò STATUS_ //
  802. // SUCCESS, äëÿ õîñòà ýòî çíà÷èò, ÷òî óñòðîéñòâî ïðèíÿëî //
  803. // çàïðîñ â îáðàáîòêó, íî íå îçíà÷àåò, ÷òî ïåðåäà÷à ÓÆÅ //
  804. // ïðåðâàíà! Îá ðåçóëüòàòå îí óçíàåò ïîçæå, ïîýòîìó, ñðàçó //
  805. // ïîñëå îòïðàâêè îòâåòà STATUS_SUCCESS, óñòðîéñòâî ìåíÿåò //
  806. // ñòàòóñ íà STATUS_PENDING è ñòàðàåòñÿ çàâåðøèòü ïåðåäà÷ó //
  807. // Òåïåðü, åñëè õîñò ïðèøëåò çàïðîñ CHECK_ABORT_BULK_OUT_ //
  808. // STATUS ÄÎ òîãî, êàê ïðèøëåò î÷åðåäíîé Bulk-IN çàïðîñ, //
  809. // ëèøàÿ óñòðîéñòâî âîçìîæíîñòè îòîñëàâ SHORT ïàêåò êîððå- //
  810. // êòíî çàâåðøèòü ïåðåäà÷ó, óñòðîéñòâî îòâåòèò åìó ñòà - //
  811. // òóñîì STATUS_PENDING! À åñëè õîñò ñíà÷àëà çàïðîñèò //
  812. // Short ïàêåò, è îïðåäåëèâ, ÷òî îí Short, çàïðîñèò //
  813. // CHECK_ABORT_BULK_OUT_STATUS, óñòðîéñòâî âåðíåò õîñòó //
  814. // STATUS_SUCCESS, òàê êàê îíî êîððåêòíî çàâåðøèëî ïåðåäà÷ó//
  815. // =======================================================
  816. if( dwFlags & FLAG_USB_SETUPPACKET_RECIEVED )
  817. {
  818. /* åñëè ôóíêöèÿ âûçâàíà ñ ýòèì ôëàãîì, ýòî îçíà÷àåò, ÷òî áûë ïðèíÿò çàïðîñ íà óíè÷òîæåíèå ïåðåäà÷è Bulk-In
  819. Ïåðåäà÷à íå áóäåò óíè÷òîæåíà ñðàçó.  ïðåðûâàíèè äåëàòü ýòîãî íå ñòîèò, òàê êàê âïîëíå âîçìîæíî, ÷òî ôóíêöèÿ
  820. áóäåò âûçâàíà â ìîìåíò, êîãäà âåäåòñÿ ïåðåäà÷à è âûïîëíÿåòñÿ ôóíêöèÿ usb_EP2_rx_func(), êîòîðàÿ ðàáîòàåò
  821. ñ ïåðåìåííûìè è óêàçàòåëÿìè, êîòîðûå íóæíî îáíóëèòü çäåñü. Íóæíî äîæäàòüñÿ, îñíîâíîé ïîòîê âûäéäåò èç òàêèõ
  822. ôóíêöèé. Ñëåäóåò ïîñòàâèòü çàïïðîñ â î÷åðåäü, óñòàíîâèâ ôëàæîê. */
  823. // çàïðîñ ïîñòàâëåí â î÷åðåäü íà îáðàáîòêó èç êîíòåêñòà ïðåðûâàíèÿ
  824. // see "USBTMC spec., rev 1.0, 2003": "page 18-19..."
  825. if(pusbtmcStatus->USBTMC_InitiateRecieved == FALSE)
  826. {
  827. // -- çàïðîñ INITIATE_ABORT_BULK_OUT ïðèíÿò íå áûë
  828. // -- õîñò íå äîëæåí ïðèñûëàòü äâà òàêèõ çàïðîñà ïîäðÿä
  829. // -- åñëè õîñò ïðèñëàë class request íå CHECK_STATUS, åãî îáðàáîòàåò usbtmc_class_request_fault
  830. pbRespondBytes[1] = udi->BulkRespondStatus.bTag;
  831. eps->InPipe.dwLength = (2 <= usp->wLength)? 2: usp->wLength;
  832. if((pBulkRespond->INTransferInProgress == TRUE) && (udi->BulkRespondStatus.bTag == (0xFF & usp->wValue)))
  833. {
  834. // - Ïåðåäà÷à â ïðîöåññå ---> Ïåðåäà÷à áóäåò çàâåðøåíà,
  835. // - bTag ñîâïàë ---> çàïðîñ ïîñòàâëåí â î÷åðåäü, ñòàòóñ: STATUS_PENDING
  836. pusbtmcStatus->USBTMC_InitiateRecieved = TRUE; // -- ïðèíÿò çàïðîñ INITIATE
  837. pusbtmcStatus->USBTMC_status = STATUS_PENDING; // -- ïåðåäà÷à îæèæàåò çàâåðøåíèÿ
  838. pbRespondBytes[0] = STATUS_SUCCESS; // -- ñòàòóñ îïåðàöèè (òåêóùåãî çàïðîñà) : STATUS_SUCCESS, îïåðàöèÿ âûïîëíåíà, çàïðîñ ïîñòàâëåí â î÷åðåäü
  839. /* 30/08/18, ðåôàêòîðèíã.
  840. ïîñêîëüêó â ïðîãðàììå íå íàéäåíû âûçîâû îáðàáîò÷èêîâ usbtmc
  841. â îñíîâíîì ïîòîêå main(), ìåðà ïðåäîñòîðîæíîñòè îáðàáîòêè
  842. âûçîâà usbtmc_abort_bulkin_transfer ( udi, 0 ) ÷åðåç usbtmc_service èçëèøíÿÿ.
  843. Çàìåíèë âûçîâ -MACRO_FLAGSET_INITIATE_BULKIN_ABORT()- íà ïðÿìîé
  844. âûçîâ usbtmc_abort_bulkout_transfer ( udi, 0 )
  845. -- MACRO_FLAGSET_INITIATE_BULKIN_ABORT();
  846. */
  847. usbtmc_abort_bulkin_transfer ( udi, 0 );
  848. }
  849. else
  850. {
  851. // - èëè bTag íå ñîâïàë --->
  852. // - èëè bTag ñîâïàë, íî ïåðåäà÷à óæå çàâåðøåíà. ---> ñòàòóñ îïåðàöèè: íå STATUS_SUCCESS
  853. pusbtmcStatus->USBTMC_InitiateRecieved = FALSE; // -- çàïðîñ INITIATE íå ïðèíÿò
  854. // -- see USBTMC spec, rev 1.0, 2003, page 22, table 24
  855. // -- ïîëó÷àåì ñîñîòîÿíèå EP. ñìîòðèì, çàíÿòû ëè åå áóôåðû
  856. ep_state = usb_lpc_cmd_read(CMD_EP_SELECT | USB_EP_PHY_ADDRESS_BULK_IN);
  857. if( ep_state & ((1<<5)|(1<<6)))
  858. pusbtmcStatus->USBTMC_status = STATUS_TRANSFER_NOT_IN_PROGRESS;
  859. else
  860. pusbtmcStatus->USBTMC_status = STATUS_FAILED;
  861. pbRespondBytes[0] = pusbtmcStatus->USBTMC_status;
  862. }
  863. }
  864. }
  865. else
  866. {
  867. // ================================================================================== //
  868. // >>> Î INTransferInProgress = TRUE, ÷òî íàïèñàíî ÷óòü íèæå <<< //
  869. // -------------------------------------------------------------------------------- //
  870. // / \ Âíèìàíèå! Âîçìîæåí òàêîé âàðèàíò. Õîñò çàïðîñèë äàííûå. Êîëè÷åñòâî //
  871. // / | \ äàííûõ êðàòíî ðàçìåðó áóôåðà òî÷êè, è, ïîèäåå, ñëåäóåò îòïðàâèòü Short //
  872. // /__*__\ ïàêåò. Êîãäà Short ïàêåò ñòàâèòñÿ â î÷åðåäü íà îòïðàâêó ïî ïðåðûâàíèþ, //
  873. // ïåðåìåííàÿ INTransferInProgress óñòàíàâëèâàåòñÿ â FALSE. Åñëè õîñò íå //
  874. // ñòàíåò çàïðàøèâàòü ýòîò Short ïàêåò, òî ïåðåäà÷à ïîèäåå åùå íå çàâåðøåíà. Íî: //
  875. // INTransferInProgress óæå ðàâíà FALSE. Åñëè ïðèñëàòü çàïðîñ INITIATE_ABORT_BULK_IN //
  876. // òî âåðíåòñÿ ñòàòóñ STATUS_TRANSFER_NOT_IN_PROGRESS, õîòÿ ýòî íå òàê, ò.ê. íå //
  877. // çàïðîøåí Short ïàêåò! Ïîýòîìó, INTransferInProgress ðàâíà TRUE âîïðåêè ëîãèêå //
  878. /*--------------------------------------------------------*/ //
  879. /* see USBTMC spec, page 12, point 10, and also */ //
  880. /* see USBTMC spec, page 26, example in 4.2.1.5 */ //
  881. /* "Device MUST always terminate bulk-in trnasfer by sen- */ //
  882. /* ding short packet!!!" ïîýòîìó íåëüçÿ ñðàçó âçÿòü è */ //
  883. /* pBulkMessage->INTransferInProgress = false, òàê êàê */ //
  884. /* òîãäà short ïàêåò íå îòïðàâèòñÿ. */ //
  885. /* Îäíàêî åñëè ôëàã FLAG_USBTMC_FORCE_BULKIN_ABORT óñòà - */ //
  886. /* íîâëåí, çíà÷èò EP îñòàíîâëåíà (HALT (STALLED)), è íåò */ //
  887. /* íåîáõîäèìîñòè è ñìûñëà æäàòü îòñûëêè Short ïàêåòà, */ //
  888. /* êîòîðûé, ñîáñòâåííî, íèêîäà íå áóäåò îòïðàâëåí ïî îäíîé*/ //
  889. /* ïðîñòîé ïðè÷èíå: òî÷êà îñòàíîâëåíà (HALT) è íàù short */ //
  890. /* ïàêåò õîñòó íå íóæåí, îí ïðèøëåò CLEAR_FEATURE, ïîýòîìó*/ //
  891. /* íóæíî INTransferInProgress óñòàíîâèòü â FALSE */ //
  892. /*--- ---*/ //
  893. /* Åñëè âûçâàòü ôóíêöèþ èç Initiate_clear ñ ïàðàìåòðîì */
  894. /* FLAG_USBTMC_FORCE_BULKIN_ABORT òî âñå îãðàíè÷åíèÿ îò- */
  895. /* ìåíÿþòñÿ è INTransferInProgress è INTransferTerminating*/
  896. /* ïðèðàâíèâàþòñÿ â FALSE */
  897. /* !!! âîîáùå, â ñïåöèôèêàöèè ñêàçàíî, ÷òî ìîæíî âåðíóòü */
  898. /* ñòàòóñ PENDING â îòâåò íà çàïðîñ CHECK_CLEAR_STATUS */
  899. /* åñëè õîñò íå ïðî÷åë short ïàêåò. (USBTMC, rev 1.0,2003 */
  900. /* page 28, table 34 Îäíàêî ýòî ñïðàâåäëèâî*/
  901. /* åñëè óñòðîéñòâî ÍÅ ìîæåò óäàëèòü ïàêåò èç FIFO è òðå- */
  902. /* áóåòñÿ, ÷òîáû õîñò åãî ïðî÷åë. Ìîæíî ïðîñòî óäàëèòü âñå*/
  903. /* äàííûå èç áóôåðîâ è âñåãäà âîçâðàùàòü STATUS_SUCCESS */
  904. /*--- ---*/
  905. /* BOOLVAR ðàâíÿåòñÿ TRUE åñëè íå ïåðåäàí íóëåâîé ïàêåò */ //
  906. /* èëè åùå îñòàëèñü äàííûå íà îòïðàâêó */ //
  907. /**/BOOL BOOLVAR = (udi->EPBulkStatus.InPipe.dwLength>0 || eps->shortpacketsending || eps->shortpacket) ? TRUE:FALSE; //
  908. /**/ BOOLVAR&= pBulkRespond->INTransferInProgress; // -- åñëè ìû ïîïàëè ñþäà ïîñëå ïîñëåäíåãî ïàêåòà ïåðåäà÷è è ïåðåäà÷à óæå çàâåðøåíà!
  909. /**/pBulkRespond->INTransferInProgress = ( dwFlags & //
  910. /**/ FLAG_USBTMC_FORCE_BULKIN_ABORT )?FALSE:(BOOLVAR); //
  911. /**/pBulkRespond->INTransferTerminating =( dwFlags & //
  912. /**/ FLAG_USBTMC_FORCE_BULKIN_ABORT )?FALSE:(BOOLVAR); //
  913. /**/ /* pBulkMessage->nBytesSent = 0; */ /* Îáíóëèòñÿ ïî íà÷àëó íî- *///
  914. /**/ /* âîé ïåðåäà÷è. Íóæíà äëÿ çàïðîñà ñòàòóñà *///
  915. /**/ /* çàâåðøåíèÿ ïåðåäà÷è (CHECK_ABORT_BULK_IN_STATUS) *///
  916. /*--------------------------------------------------------*/ //
  917. // ---------------------------------------------------------------------------------- //
  918. //============================================================================================================
  919. // ïåðåäà÷à äîëæíà çàâåðøèòüñÿ Short ïàêåòîì. äëÿ ýòîãî åãî íàäî ïîëîæèòü â î÷åðåäü íà îòïðàâêó â áóôåð EP
  920. // åñëè áóôåðû â äàííûé ìîìåíò çàíÿòû, òî ïî çàâåðøåíèþ ïåðåäà÷è â ôóíêöèè ïî ïðåðûâàíèþ îò çàâåðøåíèÿ ïåðåäà÷è
  921. // (usb_EP2_tx_func__) short ïàêåò ñàì âñòàíåò â î÷åðåäü, åñëè íóæíî (åñëè êîëè÷åñòâî äàííûõ êðàòíî ðàçìåðó
  922. // áóôåðà. Åñëè õîòÿ áû îäèí áóôåð ïóñò, ìîæíî ïîëîæèòü Short ïàêåò ïðÿìî çäåñü. Îäíàêî îí íå íóæåí, åñëè îñòàâ-
  923. // øååñÿ êîëè÷åñòâî äàííûõ ìåíüøå ðàçìåðà áóôåðà EP.
  924. //-----------------------------------------------------------------------------------------------------------
  925. ep_state = usb_lpc_cmd_read(CMD_EP_SELECT | USB_EP_PHY_ADDRESS_BULK_IN);
  926. if( udi->EPBulkStatus.InPipe.dwLength!=0 && (!(dwFlags & FLAG_USBTMC_FORCE_BULKIN_ABORT))) // åñëè îñòàëèñü íå ïåðåäàííûå äàííûå
  927. {
  928. if(udi->EPBulkStatus.InPipe.dwLength >= USB_MAX_PACKET2) // íåîáõîäèì short ïàêåò, òàê êàê ïîñëåäíÿÿ ïîðöèÿ äàííûõ ðàâíà èëè áîëüøå ðàçìåð áóôåðà
  929. {
  930. if( !((ep_state&(1<<5))) && ((ep_state&(1<<6))) ) // åñëè áóôåðû òî÷êè ñâîáîäíû (õîòÿáû îäèí)
  931. {
  932. udi->EPBulkStatus.shortpacket = FALSE; // áóäåì èñïîëüçîâàòü äâîéíóþ áóôôåðèçàöèþ
  933. usb_ep_write(USB_EP_LOG_ADDRESS_BULK_IN,(BYTE*)0, 0); // ñòàâèì â î÷åðåäü short ïàêåò
  934. }
  935. else
  936. {
  937. udi->EPBulkStatus.shortpacket = FALSE; // ïàêåò ïåðåäàòñÿ â ñëåäóùåé òðàíçàêöèè
  938. }
  939. }
  940. }
  941. else
  942. {
  943. // ÷òî ìû èìååì: udi->EPBulkStatus.InPipe.dwLength == 0
  944. // ìû â ôóíêöèè, çíà÷èò INTransferInProgress áûëà ðàâíà true, êîãäà áûë ïðèíÿò çàïðîñ
  945. // çíà÷èò ïîëó÷èëîñü òàê, ÷òî çàïðîñ îáðàáîòàí ñ îïîçäàíèåì è ïîñëåäíÿÿ ïîðöèÿ äàííûõ óæå îòïðàâëåíà
  946. // âîçìîæíî åùå íå ïåðåäàí short ïàêåò íóëåâîé äëèííû
  947. // òàêæå ñþäà ïîïàäåì åñëè âûçâàëè ôóíêöèþ èç initiate_clear ñ ôëàãîì FLAG_USBTMC_FORCE_BULKIN_ABORT
  948. if(dwFlags & FLAG_USBTMC_FORCE_BULKIN_ABORT)
  949. {
  950. udi->EPBulkStatus.shortpacket=FALSE;
  951. udi->EPBulkStatus.shortpacketsending=FALSE;
  952. }
  953. }
  954. //===========================================================================================================
  955. usb_reset_pipe_status( &udi->EPBulkStatus.InPipe );
  956. pBulkRespond->MsgID = 0x00; // äëÿ ÷åñòíîñòè
  957. pBulkRespond->bTag = 0x00; // äëÿ ÷åñòíîñòè
  958. udi->GPIBFunctionContext.bEnable = FALSE;
  959. udi->GPIBFunctionContext.LastFunction = NULL;
  960. }
  961. // MACRO_PROGRAMSECURITY_BIACXT_LEAVE();
  962. return 0x00;
  963. }
  964. //=========================================================================================================================
  965. //=========================================================================================================================
  966. // @@@@ @ @ @@@@ @@@@ @ @ @@@@ @@@@@ @@@ @@@@@ @@@@@@@ @@@@@ @ @ @ @ @ @@@ @@ @
  967. // @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @@ @
  968. // @ @ @ @@@@@@ @ @@@@ @ @ @@@@@ @ @ @ @ @ @@@@@ @ @ @ @@@@ @@@@@ @ @ @ @
  969. // @ @@@@@ @ @ @ @ @@@@@@ @ @ @ @ @@@@@ @ @ @ @ @ @ @ @ @ @ @ @
  970. // @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @@
  971. // @@@@ @ @ @@@@ @@@@ @ @ @ @ @@@@@ @@@ @ @ @ @@@@@ @@@@ @ @@@@@@ @ @ @@@ @ @@
  972. int usbtmc_checkstatus_abort_bulkin (USB_DEVICE_INFO * udi )
  973. {
  974. USB_USBTMC_CLASS_STATUS * pusbtmcStatus = (USB_USBTMC_CLASS_STATUS *) &udi->usbtmcStatus;
  975. USB_BULKRESPOND_STATUS * pBulkRespond = (USB_BULKRESPOND_STATUS*) &udi->BulkRespondStatus;
  976. USB_SETUP_PACKET * usp = &udi->EP0SetupPacket;
  977. USB_EP_STATUS * eps = &udi->EP0Status;
  978. BYTE * pbRespondBytes = ( BYTE * ) eps->InPipe.pData;
  979. // ïðîâåðÿþò, ñáðîñèëè ëè ìû ïåðåäà÷ó ïî Bulk-IN.
  980. if( pusbtmcStatus->USBTMC_InitiateRecieved == TRUE ) // åñëè âîîáùå áûë ïðèíÿò çàïðîñ íà ñáðîñ ïåðåäà÷è
  981. {
  982. pusbtmcStatus->USBTMC_InitiateRecieved = FALSE;
  983. pbRespondBytes[0] = pusbtmcStatus->USBTMC_status;
  984. //----------------------------------------------------------------------
  985. // see USBTMC spec, rev 1.0, 2003, page 25, table 29, description of "STATUS_PENDING"
  986. // and also see USBTMC spec, rev 1.0, 2003, page 25, table 28, desc. of byte with offset 1
  987. pbRespondBytes[1] = ( /* bmAbortBulkIn */
  988. (pusbtmcStatus->USBTMC_status==STATUS_PENDING)
  989. &&
  990. (pBulkRespond->INTransferInProgress == TRUE)
  991. &&
  992. (pBulkRespond->INTransferTerminating == TRUE)
  993. )?(1<<0):0x00;
  994. // Åñëè ñòàòóñ STATUS_PENDING (îæèäàåòñÿ), INTransferInProgress=TRUE, è INTransferTerminating = TRUE
  995. // çíà÷èò ïåðåäà÷à â ïðîöåññå çàâåðøåíèÿ, è ñóäÿ ïî äîêóìåíòàöèè äëÿ ñ÷àñòüÿ òîëüêî è íåõâàòàåò îòïðàâèòü
  996. // Short ïàêåò õîñòó. ( ñì ññûëêè íà äîê-þ âûøå )
  997. pbRespondBytes[1] &= 0x01; // bytes Reserved
  998. //-----------------------------------------------------------------------
  999. pbRespondBytes[2] = 0; // reserved
  1000. pbRespondBytes[3] = 0; // reserved
  1001. *((unsigned int *)(&pbRespondBytes[4])) = pBulkRespond->nBytesSent;
  1002. pBulkRespond->nBytesSent = 0;
  1003. }
  1004. else
  1005. {
  1006. pbRespondBytes[0] = STATUS_SPLIT_NOT_IN_PROGRESS;
  1007. pbRespondBytes[1] = 0; // reserved
  1008. pbRespondBytes[2] = 0; // reserved
  1009. pbRespondBytes[3] = 0; // reserved
  1010. *((unsigned int *)(&pbRespondBytes[4])) = 0;
  1011. }
  1012. eps->InPipe.dwLength = ( 8 <= usp->wLength)? 8: usp->wLength;
  1013. return 0x00;
  1014. }
  1015. //=========================================================================================================================
  1016. //=========================================================================================================================
  1017. // @@@ @ @ @@@ @@@@@ @@@ @@@@ @@@@@ @@@@ @@@@ @ @@@@ @@@@ @@@@@
  1018. // @ @@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @
  1019. // @ @ @ @ @ @ @ @@@@@@ @ @@@@@ @ @ @@@@@@ @@@@@@ @@@@@
  1020. // @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @
  1021. // @ @ @@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @
  1022. // @@@ @ @ @@@ @ @@@ @ @ @ @@@@ @@@@ @@@@@@ @@@@ @ @ @ @@
  1023. int usbtmc_initiate_clear( USB_DEVICE_INFO * udi, int dwFlags)
  1024. {
  1025. USB_USBTMC_CLASS_STATUS * pusbtmcStatus = (USB_USBTMC_CLASS_STATUS *) &udi->usbtmcStatus;
  1026. USB_BULKRESPOND_STATUS * pBulkRespond = (USB_BULKRESPOND_STATUS*) &udi->BulkRespondStatus;
  1027. USB_EP_STATUS * eps = &udi->EP0Status;
  1028. BYTE * pbRespondBytes = ( BYTE * ) eps->InPipe.pData;
  1029. if( FLAG_USB_SETUPPACKET_RECIEVED & dwFlags )
  1030. {
  1031. if(pusbtmcStatus->USBTMC_InitiateRecieved == FALSE)
  1032. {
  1033. //pbRespondBytes[0] = STATUS_SPLIT_NOT_IN_PROGRESS;
  1034. //pusbtmcStatus->USBTMC_status = STATUS_SPLIT_NOT_IN_PROGRESS;
  1035. // -- çàïðîñ òîëüêî ïðèøåë, ñòàâèì åãî â îæèäàíèå
  1036. pusbtmcStatus->USBTMC_InitiateRecieved = TRUE;
  1037. pusbtmcStatus->USBTMC_status = STATUS_PENDING;
  1038. pbRespondBytes[0] = STATUS_SUCCESS;
  1039. /* 30/08/18, ðåôàêòîðèíã.
  1040. ïîñêîëüêó â ïðîãðàììå íå íàéäåíû âûçîâû îáðàáîò÷èêîâ usbtmc
  1041. â îñíîâíîì ïîòîêå main(), ìåðà ïðåäîñòîðîæíîñòè îáðàáîòêè
  1042. âûçîâà usbtmc_initiate_clear() ÷åðåç usbtmc_service èçëèøíÿÿ.
  1043. Çàìåíèë âûçîâ -MACRO_FLAGSET_INITIATE_CLEAR()- íà ïðÿìîé
  1044. âûçîâ usbtmc_initiate_clear(udi, 0)
  1045. -- MACRO_FLAGSET_INITIATE_CLEAR(); --
  1046. */
  1047. eps->InPipe.dwLength = 1;
  1048. usbtmc_initiate_clear(udi, 0);
  1049. }
  1050. else ; // -- îòðàáîòàåò usbtmc_class_request_fault()
  1051. }
  1052. else
  1053. {
  1054. usbtmc_bulkout_stall_and_abort ( udi ); // see USBTMC spec, rev 1.0, 2003, page 26, "4.2.1.6 INITIATE_CLEAR", last paragraph
  1055. // =====================================================================
  1056. // >>> Ïî÷åìó áóôåðû ÷èñòÿòñÿ äî âûçîâà usbtmc_abort_bulkin_transfer <<<
  1057. // ---------------------------------------------------------------------
  1058. // / \ > Ïî ñïåöèôèêàöèè êàæäàÿ ïåðåäà÷à Bulk-In Äîëæíà çàêàí÷è-
  1059. // / | \ > âàòüñÿ short ïàêåòîì. Â ñîîòâåñòâèè ñ íåé, ñòð 28, òàáë. 34
  1060. // /__*__\ > îïèñàíèå áàéòà bmClear, â î÷åðåäè äîëæåí íàõîäèòüñÿ short
  1061. // > ïàêåò, ïîêà õîñò åãî íå ïðî÷òåò. Âûçîâ ôóíöèè
  1062. // > usbtmc_abort_bulkin_transfer ìîæåò ïîñòàâèòü â î÷åðåäü íóëåâîé ïàêåò,
  1063. // > êîòîðûé íåîáõîäèì äëÿ çàâåðøåíèÿ ïåðåäà÷è, à ÷èñòêà áóôåðîâ åãî
  1064. // > åãî óíè÷òîæèò. Ïîýòîìó, íóæíî ñíà÷àëà ïî÷èñèòü, à ïîòîì âûçâàòü
  1065. // > ôóíêöèþ, êîòîðàÿ !ìîæåò áûòü! ïîñòàâèò â î÷åðåäü short ïàêåò.
  1066. // ---------------------------------------------------------------------
  1067. // íåîáõîäèìî Î×ÈÑÒÈÒÜ ÂÑÅ áóôåðû
  1068. // ---------- Discard Last queued respond -----------------------------/
  1069. /*----- Clear Buffer 1*/
  1070. usb_lpc_cmd(CMD_EP_SELECT | USB_EP_PHY_ADDRESS_BULK_IN);
  1071. usb_lpc_cmd(CMD_EP_CLEAR_BUFFER );
  1072. /*----- Clear Buffer 2*/
  1073. usb_lpc_cmd(CMD_EP_SELECT | USB_EP_PHY_ADDRESS_BULK_IN);
  1074. usb_lpc_cmd(CMD_EP_CLEAR_BUFFER );
  1075. /*----- Clear Buffer 1*/
  1076. usb_lpc_cmd(CMD_EP_SELECT | USB_EP_PHY_ADDRESS_BULK_OUT);
  1077. usb_lpc_cmd(CMD_EP_CLEAR_BUFFER );
  1078. /*----- Clear Buffer 2*/
  1079. usb_lpc_cmd(CMD_EP_SELECT | USB_EP_PHY_ADDRESS_BULK_OUT);
  1080. usb_lpc_cmd(CMD_EP_CLEAR_BUFFER );
  1081. // clear Bulk-IN transfer
  1082. usbtmc_abort_bulkin_transfer( udi, FLAG_USBTMC_FORCE_BULKIN_ABORT );
  1083. // clear Bulk-Out transfer for restore Bulk-Out syncronization
  1084. // it is invoked in usbtmc_bulkout_stall() above
  1085. // -- usbtmc_abort_bulkout_transfer ( udi, 0);
  1086. eps->InPipe.dwLength = 1;
  1087. if( pBulkRespond->INTransferInProgress == TRUE)
  1088. {
  1089. // see USBTMC spec, rev 1.0, 2003, page 27, table 32
  1090. // íóæíî óíè÷òîæèòü âñå ïåðåäà÷è, âíå çàâèñèìîñòè îò òîãî, ïåðåäàí ëè short ïàêåò èëè íåò
  1091. pusbtmcStatus->USBTMC_status = STATUS_SUCCESS;
  1092. pbRespondBytes[0] = STATUS_SUCCESS; // -- çàïðîñ îáðàáîòàí
  1093. }
  1094. else
  1095. {
  1096. pusbtmcStatus->USBTMC_status = STATUS_SUCCESS;
  1097. pbRespondBytes[0] = STATUS_SUCCESS; // -- çàïðîñ îáðàáîòàí
  1098. }
  1099. }
  1100. return 0x00;
  1101. }
  1102. //=========================================================================================================================
  1103. //=========================================================================================================================
  1104. // @@@@ @ @ @@@@ @@@@ @ @ @@@@ @ @@@@ @@@@ @@@@@
  1105. // @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @
  1106. // @ @@@@@@ @@@@@@ @ @@@@ @ @ @@@@@@ @@@@@@ @@@@@
  1107. // @ @ @ @ @ @ @ @ @ @ @ @ @ @
  1108. // @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @
  1109. // @@@@ @ @ @@@@ @@@@ @ @ @@@@ @@@@@@ @@@@ @ @ @ @@
  1110. int usbtmc_checkstatus_clear( USB_DEVICE_INFO * udi )
  1111. {
  1112. USB_USBTMC_CLASS_STATUS * pusbtmcStatus = (USB_USBTMC_CLASS_STATUS *) &udi->usbtmcStatus;
  1113. USB_BULKRESPOND_STATUS * pBulkRespond = (USB_BULKRESPOND_STATUS*) &udi->BulkRespondStatus;
  1114. USB_EP_STATUS * eps = &udi->EP0Status;
  1115. BYTE * pbRespondBytes = ( BYTE * ) eps->InPipe.pData;
  1116. if( pusbtmcStatus->USBTMC_InitiateRecieved == TRUE )
  1117. {
  1118. eps->InPipe.dwLength = 2;
  1119. if( pBulkRespond->INTransferInProgress == TRUE )
  1120. {
  1121. pbRespondBytes[0] = pusbtmcStatus->USBTMC_status;
  1122. pbRespondBytes[1] = (0x01 & (1<<0)); // -- bmClear.D0 = 0, see USBTMC spec, rev 1.0, 2003, page 29, table 34.
  1123. }
  1124. else
  1125. {
  1126. pbRespondBytes[0] = pusbtmcStatus->USBTMC_status;
  1127. pbRespondBytes[1] = (0x01 & (0<<0)); // -- bmClear.D0 = 0, see USBTMC spec, rev 1.0, 2003, page 29, table 34.
  1128. }
  1129. pusbtmcStatus->USBTMC_InitiateRecieved = FALSE;
  1130. }
  1131. else
  1132. {
  1133. pbRespondBytes[0] = STATUS_SPLIT_NOT_IN_PROGRESS;
  1134. pbRespondBytes[1] = 0x00;
  1135. }
  1136. eps->InPipe.dwLength = 2;
  1137. return 0x00;
  1138. }
  1139. //=========================================================================================================================
  1140. //=========================================================================================================================
  1141. // ##### #### #### #### ##### ###### #### ###### # # ##### ##### # # ###### ####
  1142. // # # # # # # # # # # # # # # # # # # # # # # #
  1143. // ##### ###### ###### # # ###### # ###### # # # ###### ##### # # # ######
  1144. // # # # # # # # # # # # # # # # # # ## # #
  1145. // # # # # # # # # # # # # # # # # # # # # ## # # #
  1146. // # ## #### # # #### #### ### # # ### #### #### ##### ## ### ####
  1147. #ifdef __SERIAL_POLL_SUPPORT__
  1148. int usbtmc_READ_STATUS_BYTE( USB_DEVICE_INFO * udi ){
  1149. int rc = FALSE;
  1150. struct _INTERRUPT_IN {
  1151. BYTE bNotify1;
  1152. BYTE bNotify2;
  1153. } InterruptIn;
  1154. USB_INTERRUPT_DISABLE_INTIN_NAK();
  1155. InterruptIn.bNotify1 = 0x80; //D7 must be 1, see USB488 spec, rev 1.0, 2003, page 9, 3.4 Interrupt_IN, Table 6,7
  1156. InterruptIn.bNotify2 = _STB;
  1157. #ifdef __USBTMC_SERVICE_REQUEST_SUPPORT__
  1158. // see USB488 spec, rev 1.0, 2003, page 9, 3.4 Interrupt_IN, Table
  1159. if( GPIB_GET_RQS() ) // GPIB_GET_RQS() gets RQS Bit from STB registers and DO not clears it!
  1160. {
  1161. InterruptIn.bNotify1 = 0x81; // see USB488 spec, rev 1.0, 2003, page 9, 3.4 Interrupt_IN, Table 6
  1162. // see USB488 spec, rev 1.0, 2003, page 9, 3.4 Interrupt_IN, text below Table 6
  1163. GPIB_CLR_RQS__(); // no state-machine state modify, clear ServiceRequestBit
  1164. }
  1165. else
  1166. #endif
  1167. InterruptIn.bNotify1 |=udi->usbtmcGpib.StateMachine.bTag_Interrupt;
  1168. // --------------- ïðîâåðÿåì ìîæåì ëè ïîëîæèòü â Interrupt Òî÷êó äàííûå --------------
  1169. rc = usb_lpc_cmd_read( CMD_EP_SELECT | USB_EP_PHY_ADDRESS_INT_IN );
  1170. rc = ( (rc & (1<<5))?FALSE:TRUE ); // return whether it is possible to queue bytes
  1171. if( rc )
  1172. {
  1173. usb_ep_write( USB_EP_LOG_ADDRESS_INT_IN, (BYTE*)&InterruptIn, 2);
  1174. rc = usb_lpc_cmd_read( CMD_EP_SELECT | USB_EP_PHY_ADDRESS_INT_IN );
  1175. rc = ( (rc & (1<<5))?TRUE:FALSE ); // return result of queuing bytes
  1176. }
  1177. return rc;
  1178. }
  1179. #endif
  1180. int usbtmc_read_status_byte( USB_DEVICE_INFO * udi ) {
  1181. USB_USBTMC_CLASS_STATUS * pusbtmcStatus = (USB_USBTMC_CLASS_STATUS *) &udi->usbtmcStatus;
  1182. USB_EP_STATUS * eps = &udi->EP0Status;
  1183. BYTE * pbRespondBytes = ( BYTE * ) eps->InPipe.pData;
  1184. USB_SETUP_PACKET * usp = &udi->EP0SetupPacket;
  1185. USB_USBTMC_GPIBEMULATION_STATEMACHINE * pStateMachine = (USB_USBTMC_GPIBEMULATION_STATEMACHINE*) &(udi->usbtmcGpib.StateMachine);
  1186. // -------------------------------------------------------------------------------------------
  1187. pStateMachine->bTag_Interrupt = (0x7F & (usp->wValue)); // Prior to call usbtmc_READ_STATUS_BYTE_Interrupt()
  1188. // -----------------------------------------------------------
  1189. #ifdef __SERIAL_POLL_SUPPORT__
  1190. // see USB488 spec, rev 1.0, 2003, page 13, 4.3.1.2
  1191. if( usbtmc_READ_STATUS_BYTE(udi) == FALSE )
  1192. pusbtmcStatus->USBTMC_status = STATUS_INTERRUPT_IN_BUSY;
  1193. else
  1194. pusbtmcStatus->USBTMC_status = STATUS_SUCCESS;
  1195. pbRespondBytes[2] = 0x00; // STB will be returned in INTERRUPT IN
  1196. #else
  1197. pbRespondBytes[2] = _STB; // STB will be returned here, in Control Response Packet
  1198. pusbtmcStatus->USBTMC_status = STATUS_SUCCESS;
  1199. #endif
  1200. // see USB488 spec, rev 1.0, 2003, page 13, table 12
  1201. pbRespondBytes[0] = pusbtmcStatus->USBTMC_status;
  1202. pbRespondBytes[1] = pStateMachine->bTag_Interrupt;
  1203. // -----------------------------------------------------------
  1204. eps->InPipe.dwLength = 3;
  1205. return 0x00;
  1206. }
  1207. //=========================================================================================================================
  1208. //=========================================================================================================================
  1209. // @@@@ @@@@ @@@@@@ @@@@ @@@@ @@@@@ @@@@ @@@@@ @@@ @ @@@ @@@@@@ @@@@ @@@@@
  1210. // @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @
  1211. // @ @@@@@@ @ @ @@@@@@ @ @ @@@@@@ @@@@@ @ @ @ @ @@@@@@ @@@@@@
  1212. // @ @@@ @ @ @ @ @ @@@@@ @ @ @ @ @ @ @ @ @ @
  1213. // @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @
  1214. // @@@@ @@@@ @@@ @@@@ @ @ @ @ @ @@@@@ @@@ @@@@@@ @@@ @@@ @@@@ @@@@
  1215. // see USBTMC spec, rev 1,0, 2003, page 28-29
  1216. int usbtmc_getcapabilites ( USB_DEVICE_INFO * udi ) {
  1217. USB_USBTMC_CLASS_STATUS * pusbtmcStatus = (USB_USBTMC_CLASS_STATUS *) &udi->usbtmcStatus;
  1218. USB_EP_STATUS * eps = &udi->EP0Status;
  1219. BYTE * pbRespondBytes = ( BYTE * ) eps->InPipe.pData;
  1220. /*pbRespondBytes[0] = pusbtmcStatus->USBTMC_status;*/
  1221. pbRespondBytes[0] = STATUS_SUCCESS; // fixed: 05/09/18, NiVisa warned VI_WARN_UNKNOWN_STATUS if this value is 0x00
  1222. pbRespondBytes[1] = 0; // reserved
  1223. pbRespondBytes[2] = 0x01; // BCD version number of the relevant USBTMC spec
  1224. pbRespondBytes[3] = 0x00; // ver 1.0
  1225. // interface in not Listen-only and is not Talk-Only
  1226. // interface not support INDICATOR_PULSE
  1227. pbRespondBytes[4] = (0x07 & ((0<<USBTMC_SUPPORT__INDICATOR_PULSE) | (0<<USBTMC_SUPPORT__TALK_ONLY) | (0<<USBTMC_SUPPORT__LISTEN_ONLY)));
  1228. // device not support TermChar
  1229. pbRespondBytes[5] = (0x01 & (0<<USBTMC_SUPPORT__TERMCHAR));
  1230. pbRespondBytes[6] = 0x00; // reserved
  1231. pbRespondBytes[7] = 0x00; // reserved
  1232. pbRespondBytes[8] = 0x00; // reserved
  1233. pbRespondBytes[9] = 0x00; // reserved
  1234. pbRespondBytes[10] = 0x00; // reserved
  1235. pbRespondBytes[11] = 0x00; // reserved
  1236. // ---- USB488 ---------------------
  1237. // -- see USB488 spec, rev 1.0, 2003, page 10, table 8
  1238. *( (unsigned short int *) &(pbRespondBytes[12]) ) = 0x0001; // -- bcdUSB488 1.00
  1239. #ifdef __USBTMC_SERVICE_REQUEST_SUPPORT__
  1240. #ifndef __SERIAL_POLL_SUPPORT__
  1241. #error Íåâîçìîæíà ïîääåðæêà Service Request áåç ïîääåðæêè Serial Poll.
  1242. #error Îáúÿâèòå __SERIAL_POLL_SUPPORT__ â options.h
  1243. #else
  1244. // byte with offset 15:
  1245. // D0 - DT0 Device Trigger
  1246. // D1 - RL0 Remote Local
  1247. // D2 - SR1 Service Request
  1248. // D3 - Support SCPI
  1249. pbRespondBytes[15] = 0x0F & ((1<<3) | (1<<2) | (0<<1) | (0<<0));
  1250. // byte with offset 14:
  1251. // D0 - Not support TRIGGER message
  1252. // D1 - Not support GO_TO_LOCAL, REN_CONTROL, LOCAL_LOCKOUT
  1253. // D2 - It is USB488 interface.
  1254. pbRespondBytes[14] = 0x07 & ((1<<2) | (0<<1) | (0<<0));
  1255. #pragma message(">>> USB488 compatibilites: IEEE 488.2 Interface <<<")
  1256. #pragma message(">>> USB488 compatibilites: SCPI Commands are supported <<<")
  1257. #pragma message(">>> USB488 compatibilites: Service Request are supported <<<")
  1258. #endif
  1259. #else
  1260. // byte with offset 15:
  1261. // D0 - DT0 Device Trigger
  1262. // D1 - RL0 Remote Local
  1263. // D2 - SR0 Service Request
  1264. // D3 - Not Support SCPI
  1265. pbRespondBytes[15] = 0x0F & ((0<<3) | (0<<2) | (0<<1) | (0<<0));
  1266. // byte with offset 14:
  1267. // D0 - Not support TRIGGER message
  1268. // D1 - Not support GO_TO_LOCAL, REN_CONTROL, LOCAL_LOCKOUT
  1269. // D2 - It is USB488 interface, but SR1 not supported, SCPI not supported
  1270. pbRespondBytes[14] = 0x07 & ((1<<2) | (0<<1) | (0<<0));
  1271. #pragma message(">>> USB488 compatibilites: IEEE 488.2 Interface <<<")
  1272. #pragma message(">>> USB488 compatibilites: NOT Support SCPI <<<")
  1273. #pragma message(">>> USB488 compatibilites: NOT Support Service Request <<<")
  1274. #endif
  1275. pbRespondBytes[16] = 0x00; // USB488 Reserved
  1276. pbRespondBytes[17] = 0x00; // USB488 Reserved
  1277. pbRespondBytes[18] = 0x00; // USB488 Reserved
  1278. pbRespondBytes[19] = 0x00; // USB488 Reserved
  1279. pbRespondBytes[20] = 0x00; // USB488 Reserved
  1280. pbRespondBytes[21] = 0x00; // USB488 Reserved
  1281. pbRespondBytes[22] = 0x00; // USB488 Reserved
  1282. pbRespondBytes[23] = 0x00; // USB488 Reserved
  1283. eps->InPipe.dwLength = 24;
  1284. return 0x00;
  1285. }
  1286. //=========================================================================================================================
  1287. // @@@ @ @ @@@@ @@@ @@@@ @@@@ @@@@@@ @@@@ @@@@@ @@@@@ @ @ @ @@@@@ @@@@
  1288. // @ @@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @
  1289. // @ @ @ @ @ @ @ @ @@@@@@ @ @ @ @@@@@ @ @ @ @ @ @@@@@@ @@@@@@
  1290. // @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @@@@@ @ @ @ @ @
  1291. // @ @ @@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @
  1292. // @@@ @ @ @@@@ @@@ @@@@ @ @ @@@ @@@@ @ @@ @ @@@@ @@@@@@ @@@@ @@@@
  1293. //=========================================================================================================================
  1294. int usbtmc_indicator_pulse ( USB_DEVICE_INFO * udi )
  1295. {
  1296. // -- Request "INDICATOR_PULSE" is not supported.
  1297. // see USBTMC spec, rev 1.0, 2003, page 29, table 37, decription of byte with offset 4, bit D2.
  1298. // Control-IN -> STALL
  1299. usb_stall_ep( 0x01, TRUE );
  1300. return 0x00;
  1301. }
  1302. //=========================================================================================================================
  1303. //=========================================================================================================================
  1304. // @@@@@ @@@@ @@@@@ @@@@@ @@@@ @@@@@ @ @ @ @ @ @ @ @@@@ @@@@@ @@@@@ @@@@ @@@@ @@@@
  1305. // @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @@ @@ @ @ @ @ @ @ @ @ @ @
  1306. // @ @ @@@@@@ @@@@@ @@@@@@ @@@@@@ @@@@@ @ @ @ @@@@ @ @@ @ @@@@@@ @@@@@@ @@@@@@ @@@@@@ @ @@@@@@
  1307. // @@@@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @@@ @
  1308. // @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @
  1309. // @ @ @ @ @@ @@@@ @@@@ @@@@@ @@@@ @@@@@@ @ @ @ @ @@@@ @@@@ @@@@ @ @ @@@@ @@@@
  1310. //
  1311. // Ïàðàìåòð bCheckDataStage:
  1312. // Ïðîòîêîë USBTMC ñîäåðæèò 4 îñíîâíûõ êîììàíäû: DEV_DEP_MSG_OUT, VENDOR_SPECIFIC_OUT, REQUEST_DEV_DEP_MSG_IN, REQUEST_VENDOR_SPECIFIC_IN
  1313. // DEV_DEP_MSG_OUT, VENDOR_SPECIFIC_OUT ïðåäïîëàãàþò ñòàäèþ äàííûõ â Bulk-Out, òîåñòü óñòðîéñòâî ïðèíèìàåò TransferSize áàéò
  1314. // REQUEST_DEV_DEP_MSG_IN, REQUEST_VENDOR_SPECIFIC_IN æå ïðåäïîëàãàþò ñòàäèþ äàííûõ â Bulk-IN, òîåñòü óñòðîéñòâî íå ïðèíèìàåò, à ïåðåäàåò TransferSize áàéò
  1315. // Ïðè ïðèåìå êîììàíäû Bulk-Out òðåáóåòñÿ òî÷íî îïðåäåëèòü, ñêîëüêî äàííûõ áóäåò ïåðåäàíî, òîåñòü êîãäà çàâåðøàòü ïåðåäà÷ó è ðàññìàòðèâàòü ñëåäóþùóþ ïîðöèþ
  1316. // äàííûõ êàê íîâóþ ïåðåäà÷ó. Äëÿ ýòîãî è ñëóæèò ïîëå TransferSize. Îäíàêî â äâóõ çàïðîñàõ REQUEST_DEV_DEP_MSG_IN, REQUEST_VENDOR_SPECIFIC_IN ýòî
  1317. // ïîëå ó÷èòûâàòü íå íóæíî, òàê êàê îíî èìååò ïðîòèâîïîëîæíûé ñìûñë. Äëÿ îïðåäåëåíèÿ, ó÷èòûâàòü èëè íå ó÷èòûâàòü TransferSize ââåäåí ïàðàìåòð bCheckDataStage
  1318. // Ïðèíèìàÿ çàïðîñ è îïðåäåëèâ, ÷òî ýòî çàãîëîâîê, íóæíî âûçâàòü ôóíêöèþ usbtmc_parse( ..., TRUE ), ôóíêöèÿ âåðíåò TRUE, åñëè ýòî ïîòîê
  1319. // Host->Device ( DEV_DEP_MSG_OUT, VENDOR_SPECIFIC_OUT ) èëè FALSE, åñëè TransferSize îïðåäåëÿåò, ñêîëüêî äàííûõ òðåáóåòñÿ ïðî÷èòàòü èç óñòðîéñòâà Device->Host (REQUEST_DEV_DEP_MSG_IN, REQUEST_VENDOR_SPECIFIC_IN)
  1320. // Ôóíêöèÿ, ïðèíÿâ TRUE â bCheckDataStage çàâåðøèòñÿ íåìåäëåííî, íå îáðàáàòûâàÿ çàïðîñ
  1321. int usbtmc_parse( USB_DEVICE_INFO * udi, BOOL bCheckDataStage )
  1322. {
  1323. USB_BULKMESSAGE_STATUS * pBulkMessage = (USB_BULKMESSAGE_STATUS*) &udi->BulkMessageStatus;
  1324. int rc = FALSE;
  1325. //----------------------------------------------------------------------------------------
  1326. switch( pBulkMessage->MsgID )
  1327. {
  1328. // DEV_DEP_MSG_OUT
  1329. // Host sent a message to the device
  1330. // The message length: TransferSize ( size of Bulk-Out transaction )
  1331. case DEV_DEP_MSG_OUT:
  1332. {
  1333. // Process the flag: @bCheckDataStage
  1334. // It is dummy call to identify the direction
  1335. if( bCheckDataStage ) return (TRUE);
  1336. // identify a transfer that sends a USBTMC device dependent
  1337. // command message from the Host to a device
  1338. rc = usbtmc_DEV_DEP_MSG_OUT( udi );
  1339. }
  1340. break;
  1341. // REQUEST_DEV_DEP_MSG_IN
  1342. // Device responds to the host
  1343. // Maximum Bulk-IN transaction size is @TransferSize
  1344. case REQUEST_DEV_DEP_MSG_IN:
  1345. {
  1346. // Process the flag: @bCheckDataStage
  1347. // It is dummy call to identify the direction
  1348. if( bCheckDataStage == TRUE ) return (FALSE);
  1349. // identify the transfer as a USBTMC command message to the device,
  1350. // allowing the device to send a USBTMC response message containing
  1351. // device dependent message data bytes
  1352. rc = usbtmc_REQUEST_DEV_DEP_MSG_IN( udi );
  1353. }
  1354. break;
  1355. //
  1356. // VENDOR_SPECIFIC_OUT
  1357. // Host sent a vendor specific message to the device
  1358. case VENDOR_SPECIFIC_OUT:
  1359. {
  1360. // Process the flag: @bCheckDataStage
  1361. // It is dummy call to identify the direction
  1362. if( bCheckDataStage == TRUE ) return (TRUE);
  1363. rc = FALSE; // not supported
  1364. }
  1365. break;
  1366. //
  1367. // VENDOR_SPECIFIC_OUT
  1368. // Host requests answer on vendor specific message from device
  1369. case REQUEST_VENDOR_SPECIFIC_IN:
  1370. {
  1371. // Process the flag: @bCheckDataStage
  1372. // It is dummy call to identify the direction
  1373. if( bCheckDataStage == TRUE ) return (FALSE);
  1374. rc = FALSE; // not supported
  1375. }
  1376. break;
  1377. case TRIGGER:
  1378. rc = FALSE; // not supported
  1379. break;
  1380. default:;
  1381. rc = FALSE; // not supported
  1382. }
  1383. return rc;
  1384. }
  1385. //=========================================================================================================================
  1386. //=========================================================================================================================
  1387. // @@@@@ @@@@ @@@@@ @@@@@ @@@@ @@@@ @@@@@@ @@@@@ @ @@@@@ @@@@ @@@@
  1388. // @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @
  1389. // @ @ @@@@@@ @@@@@ @@@@@@ @@@@@@ @ @ @@@@@ @ @@@@@ @@@@@@ @ @
  1390. // @@@@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @
  1391. // @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @
  1392. // @ @ @ @ @@ @@@@ @@@@ @@@@ @@@ @ @@ @@@@@@ @ @@ @@@@ @@@ @
  1393. BOOL usbtmc_class_request(USB_DEVICE_INFO * udi)
  1394. {
  1395. BOOL rc = FALSE;
  1396. USB_USBTMC_CLASS_STATUS * pusbtmcStatus = (USB_USBTMC_CLASS_STATUS *) &udi->usbtmcStatus;
  1397. USB_SETUP_PACKET * usp = &udi->EP0SetupPacket;
  1398. // -- ïðîâåðÿåì, íóæíî ëè îáðàáàòûâàòü çàïðîñ.
  1399. // -- åñëè èíèöèðîâàí çàïðîñ INITIATE, çàïðîñ ðàññìàòðèâàåòñÿ êàê non operate, ñîãëàñíî äîêóìåíòàöèè
  1400. // -- see USBTMC spec, rev 1.0, 2003, page 20-21 "a","b","c"
  1401. // See USBTMC spec, rev 1.0, 2003, 4.2.1.1, "USBTMC split transactions"
  1402. if( (TRUE == pusbtmcStatus->USBTMC_InitiateRecieved)
  1403. && (CHECK_ABORT_BULK_IN_STATUS != usp->bRequest)
  1404. && (CHECK_ABORT_BULK_OUT_STATUS != usp->bRequest)
  1405. && (CHECK_CLEAR_STATUS != usp->bRequest)
  1406. )
  1407. {
  1408. rc = usbtmc_class_request_fault( udi );
  1409. }
  1410. else
  1411. {
  1412. // Processing USBTMC Class requests, see "USBTMC spec., rev. 1.0, 2003", 4.2.1, "USBTMC requests"
  1413. switch(usp->bRequest)
  1414. {
  1415. case INITIATE_ABORT_BULK_OUT:
  1416. usbtmc_abort_bulkout_transfer ( udi, FLAG_USB_SETUPPACKET_RECIEVED );
  1417. rc = TRUE;
  1418. break;
  1419. case CHECK_ABORT_BULK_OUT_STATUS:
  1420. usbtmc_checkstatus_abort_bulkout( udi );
  1421. rc = TRUE;
  1422. break;
  1423. case INITIATE_ABORT_BULK_IN:
  1424. usbtmc_abort_bulkin_transfer ( udi, FLAG_USB_SETUPPACKET_RECIEVED );
  1425. rc = TRUE;
  1426. break;
  1427. case CHECK_ABORT_BULK_IN_STATUS:
  1428. usbtmc_checkstatus_abort_bulkin( udi );
  1429. rc = TRUE;
  1430. break;
  1431. case INITIATE_CLEAR:
  1432. usbtmc_initiate_clear( udi, FLAG_USB_SETUPPACKET_RECIEVED );
  1433. rc = TRUE;
  1434. break;
  1435. case CHECK_CLEAR_STATUS:
  1436. usbtmc_checkstatus_clear( udi );
  1437. rc = TRUE;
  1438. break;
  1439. case GET_CAPABILITES:
  1440. usbtmc_getcapabilites( udi );
  1441. rc = TRUE;
  1442. break;
  1443. case READ_STATUS_BYTE:
  1444. usbtmc_read_status_byte( udi );
  1445. rc = TRUE;
  1446. break;
  1447. case INDICATOR_PULSE:
  1448. rc = usbtmc_indicator_pulse( udi ); // see USBTMC spec, rev 1.0, 2003, page29, table 37, desc. of byte with offset 4, bit D2
  1449. break;
  1450. case GO_TO_LOCAL:
  1451. case LOCAL_LOCKOUT:
  1452. case REN_CONTROL:
  1453. usb_stall_ep( 0x01, TRUE ); // not support, -> stall
  1454. rc = FALSE;
  1455. break;
  1456. default:
  1457. // see USB 2.0 spec, page 256, 9.4.5, last paragaph, "device need not return STALL for class-specific and vendor-specific requests."
  1458. // see USB 2.0 spec, 9.2.7: It is preferred that the STALL PID be returned at the next Data stage transaction, as this avoids unnecessary bus activity
  1459. // "preferred" - ïðåäïî÷òèòåëüíî, íî íå îáÿçàòåëüíî
  1460. //
  1461. // rc = FALSE; // STALL, see USB 2.0 spec, page 252, "9.4 Standard Device Requests"
  1462. rc = TRUE; // No STALL
  1463. }
  1464. }
  1465. return rc;
  1466. }
  1467. //- ---------------------------------------------------------------------------------------------------------------------------------
  1468. int usbtmc_class_request_fault ( USB_DEVICE_INFO * udi )
  1469. {
  1470. // -- usbtmc_request_fault - îáðàáîò÷èê çàïðîñà êàê non-operation çàïðîñà.
  1471. USB_USBTMC_CLASS_STATUS * pusbtmcStatus = (USB_USBTMC_CLASS_STATUS *) &udi->usbtmcStatus;
  1472. USB_EP_STATUS * eps = &udi->EP0Status;
  1473. BYTE * pbRespondBytes = ( BYTE * ) eps->InPipe.pData;
  1474. if( pusbtmcStatus->USBTMC_InitiateRecieved==TRUE )
  1475. {
  1476. pbRespondBytes[0] = STATUS_SPLIT_IN_PROGRESS;
  1477. pbRespondBytes[1] = 0x00; // -- íå âàæíî, see USBTMC spec, rev 1.0, 2003, page 19, after table 16, "A response with ...", "Host MUST ignore " ... "all response bytes"
  1478. eps->InPipe.dwLength = 2;
  1479. }
  1480. return TRUE;
  1481. }
  1482. //=========================================================================================================================
  1483. int usbtmc_DEV_DEP_MSG_OUT ( USB_DEVICE_INFO * udi )
  1484. {
  1485. int rc = FALSE;
  1486. USB_BULKRESPOND_STATUS * pBulkRespond = (USB_BULKRESPOND_STATUS*) &udi->BulkRespondStatus;
  1487. BYTE * pBulkData_DeviceIn = (BYTE*) udi->BulkMessageStatus.pData; // óêàçàòåëü íà ïðèíÿòûå äàííûå. äàííûå ìîãóò ëåæàòü êàê â áóôåðå EP òàê è â îáùåì áóôåðå
  1488. // -----------------------------------------------------------------------------------------------------------------------------------------------------------------
  1489. // Õîñò èíèöèðóåò DEV_DEP_MSG_OUT. Ðàçìåð ïåðåäà÷è ýòîãî çàïðîñà ìîæåò áûòü áîëüøå
  1490. // áóôåðà êîíå÷íîé òî÷êè, è òîãäà äàííûå íóæíî êåøèðîâàòü. Êåøèðîâàíèå ïðîèñõîäèò
  1491. // â åäèíñòâåííûé áóôôåð, â 1,5Êá, àäðåñ get_addr_in_buffer(). Äåëàåòñÿ äîïóùåíèå,
  1492. // ÷òî êîãäà õîñò èíèöèðóåò REQUEST_DEV_DEP_MSG_IN, ýòîò áóôåð íå ïîíàäîáèòñÿ, ïîñêîëüêó
  1493. // â íåì óæå ëåæàò ïîäãîòîâëåííûå äàííûå äëÿ îòâåòà íà çàïðîñ DEV_DEP_MSG_OUT.
  1494. // Îäíàêî åñëè ïðèäåò íåñêîëüêî êîììàíä â îäíîé ñòðîêå, âûçîâû íàçíà÷åííûõ íà êîììàíäó
  1495. // ôóíêöèé èçìåíÿò ñîäåðæèìîå áóôåðà pBulkData_DeviceIn îáðàùàÿñü ê íåìó êàê
  1496. // ê óêàçàòåëþ íà çàãîëîâîê BULKIN, áóäóò êåøèðîâàòü îòïðàâëÿåìûå äàííûå â íåãî
  1497. // Âîáùåì, ñòðîêà êîììàíä áóäåò ïîâðåæäåíà. ×òîáû ýòîãî èçáåæàòü, GPIB_CommandExecute
  1498. // êåøèðóåò ñòðîêó êîììàíä íà âðåìÿ ðàçáîðà.
  1499. // ---------------------------------------------
  1500. // èíèöèàëèçàöèÿ ïåðåäà÷è
  1501. usbtmc_init_intransfer_newcmd( udi );
  1502. // ---------------------------------------------
  1503. // ïåðåä âûïîëíåíèåì GPIB ôóíêöèè íåëüçÿ óäàëÿòü êîíòåêñò,
  1504. // âåäü ñëåä êîììàíäà ( cmd1;cmd2 ) ìîæåò åãî è íå èñïîëüçóåò, à òåêóùàÿ (cmd1) íå óñïååò ïåðåäàòü äàííûå
  1505. usbtmc_delete_function_context( udi );
  1506. // ----------------------------------------------------------------------------------------------------------------------------
  1507. // âûçûâàåì îáðàáîò÷èê êîììàíä SCPI
  1508. if( 0 <= GPIB_CommandExecute( udi, pBulkData_DeviceIn ) )
  1509. {
  1510. // òóò ïðîèçîøëî ïðåîáðàçîâàíèå â ÂÅÐÕÍÈÉ ÐÅÃÈÑÒÐ!!!
  1511. rc = TRUE;
  1512. // -------------------------------------------------------------------
  1513. // See USB488, rev 1.0, 2003, page 13, 4.3.1.3 Status byte MAV bit
  1514. if( pBulkRespond->dwDeviceOut > 0 ) GPIB_SET_MAV();
  1515. // -- óñòàíàâëèâàåì Message Available áèò åñëè åñòü ÷òî îòâåòèòü
  1516. // -------------------------------------------------------------------
  1517. }
  1518. else
  1519. {
  1520. rc = FALSE; // êàêàÿ-òî îøèáêà
  1521. }
  1522. return rc;
  1523. }
  1524. // =========================================================================================================================================
  1525. int usbtmc_REQUEST_DEV_DEP_MSG_IN ( USB_DEVICE_INFO * udi ) {
  1526. int rc = FALSE;
  1527. // USB_USBTMC_CLASS_STATUS * pusbtmcStatus = (USB_USBTMC_CLASS_STATUS *) &udi->usbtmcStatus;
  1528. USB_EP_STATUS * bulk_endpoint = (USB_EP_STATUS*) &udi->EPBulkStatus;
  1529. USB_PIPE_ENTRY_IN * pInPipe = (USB_PIPE_ENTRY_IN*) &bulk_endpoint->InPipe;
  1530. USB_BULKMESSAGE_STATUS * pBulkMessage = (USB_BULKMESSAGE_STATUS*) &udi->BulkMessageStatus;
  1531. USB_BULKRESPOND_STATUS * pBulkRespond = (USB_BULKRESPOND_STATUS*) &udi->BulkRespondStatus;
  1532. BULKIN_HEADER * pBulkInHeader = (BULKIN_HEADER*) pInPipe->pData;
  1533. BYTE * pData = (BYTE*) pInPipe->pData + sizeof(BULKIN_HEADER); // pdata !!!
  1534. // -------------------------------------------------------------------------------------------------------------------------------------
  1535. // ============== INITIALIZE RESPOND ===============
  1536. pInPipe->dwLength = 0;
  1537. pBulkRespond->nBytesSent = 0; // îáíóëÿåì ñòàòèñòèêó îòïðàâëåííûõ áàéò
  1538. pBulkRespond->bTag = pBulkMessage->bTag;
  1539. pBulkRespond->MsgID = DEV_DEP_MSG_IN;
  1540. pBulkRespond->INTransferInProgress = TRUE; // see USBTMC spec, rev 1.0, 2003, page 12, point 5
  1541. // íóæíî: ïðèìåð: õîñò ïîñëàë DEV_DEP_MSG_OUT à ïîòîì ïåðåäóìàë è ðåøèë ïðåðâàòü çàïðîñ BulkIN, äàæå íå íà÷àâ ÷èòàòü!
  1542. //-----------------------------------------------------
  1543. // WARNING! 29/08/18
  1544. // Ïðè âêëþ÷åíèè îïòèìèçàöèè êîìïèëÿòîð ìîæåò çàìåíèòü âûçîâ
  1545. // memset() íà ïîñëåäîâàòåëüíîñòü èíñòðóêöèé áûñòðîé î÷èñòêè
  1546. // ïàìÿòè íà îñíîâå èíñòðóêöèè STM, êîòîðàÿ òðåáóåò, ÷òîáû
  1547. // àäðåñ áûë âûðîâíåí íà 4. Ò.ê. óêàçàòåëü pBulkInHeader
  1548. // áûë ïîëó÷åí ïðåîáðàçîâàíèåì òèïà èç pData òèïà uint8_t,
  1549. // òî è ïîëó÷åííûé óêàçàòåëü ìîæåò îêàçàòüñÿ íåâûðîâíåí íà 4.
  1550. // Îäíàêî ïîñëå êàñòèíãà ê òèïó BULKIN_HEADER* êîìïèëÿòîð ïðî
  1551. // ýòî "çàáûâàåò" è ñ÷èòàåò àäðåñ @pBulkInHeader âûðîâíåííûì.
  1552. // Íà íåêîòîðîì óðîâíå îïòèìèçàöèè ïðèâåäåò ê HardFault,
  1553. // ò.ê. êîìïèëÿòîð ïî ïðàâó ñ÷èòàåò @pBulkInHeader ÷åñòíûì
  1554. // àäðåñîì íà âûðîâíåííóþ ñòðóêòóðó è âñòàâëÿåò èíñòðóêöèþ STM
  1555. // (STM R6!, {R0-R2}, ãäå R0..R2 = 0x00000000 )
  1556. // ×ÒÎÁÛ èçáåæàòü òàêîãî ïîâåäåíèÿ, òðåáóåòñÿ ÎÁÐÀÒÍÎ ñêàñòèòü
  1557. // óêàçàòåëü @pBulkInHeader ê òèïó uint8_t, ÷òîáû ó êîìïèëÿòîðà
  1558. // íå âîçíèêàëà ñîáëàçíà ïðîâåðíóòü âûøåîïèñàííûé òðþê.
  1559. // Ïðè áàíàëüíîì (BYTE*)pBulkInHeader ïîëó÷åííûé óêàçàòåëü óæå
  1560. // íå ñ÷èòàåòñÿ âûðîâíåííûì íà 4, è âûçîâ memset() áóäåò íåëüçÿ
  1561. // çàìåíèòü íà STM-èíñòðóêöèþ, è êîìïèëÿòîðó ïðèäåòñÿ ñäåëàòü
  1562. // âûçîâ memclr(), ÷òî óæå íå ïðèâåäåò ê îøèáêå.
  1563. // Òàêèå äåëà.
  1564. memset( (BYTE*) /* ïðîáëåìû ñ îïòèìèçàöèåé: ÍÓÆÍÎ ÎÁßÇÀÒÅËÜÍÎ ÊÀÑÒÈÒÜ Ê ÒÈÏÓ uint8_t !!!! */
  1565. pBulkInHeader, 0x00, sizeof(BULKIN_HEADER) );
  1566. // =============== DEFAULT ====================
  1567. pBulkInHeader->MsgID = pBulkRespond->MsgID;
  1568. pBulkInHeader->bTag = pBulkRespond->bTag; // -- must match with bTag in last message
  1569. pBulkInHeader->bTagInverse = ~pBulkInHeader->bTag;
  1570. // TransferSize èíèöèàëèçèðîâàíà â DEV_DEP_MSG_OUT
  1571. // ------------------------------------------------------
  1572. rc = TRUE;
  1573. // ------------------------------------------------------
  1574. // Êîãäà ïðèõîäèò DEV_DEP_MSG_OUT äàííûå, êîòîðûå íóæíî îòïðàâèòü â îòâåò
  1575. // ñêëàäûâàþòñÿ â âûõîäíîé áóôåð ñî ñìåùåíèåì â sizeof(BULKIN_HEADER)
  1576. // â REQUEST_DEV_DEP_MSG_OUT ìîäèôèöèðóåòñÿ ëèøü HEADER, è îòïðàâëÿåòñÿ îòâåò
  1577. // Ýòî äîñòèãàåòñÿ çà ñ÷åò ðàçíåñåíèÿ áóôåðîâ ïðèåìà êîììàíä DEV_DEP_MSG_OUT
  1578. // è REQUEST_DEV_DEP_MSG_OUT.
  1579. //-----------------------------------------------------
  1580. {
  1581. // õîñò ïðèñëûàåò â Bulk-Out çàãîëîâêå ðàçìåð ïåðåäà÷è TransferSize
  1582. // äëÿ çàïðîñà REQUEST_DEV_DEP_MSG_IN ýòî ÷èñëî îïðåäåëÿåò êîëè÷åñòâî äàííûõ
  1583. // êîòîðûå òðåáóåòñÿ ïðî÷èòàòü èç óñòðîéñòâà. Ñâûøå ýòîãî ÷èñëà îòïðàâëÿòü íåëüçÿ
  1584. USB_INTERRUPT_ENABLE_BULKIN_NAK();
  1585. if(pBulkRespond->bIsLastTransfer == TRUE && pBulkRespond->dwDeviceOut > pBulkRespond->InTransferSize)
  1586. pBulkRespond->bIsLastTransfer = FALSE;
  1587. // ------------------------------------------------------------------------------------------------------
  1588. // Is it the last transfer?
  1589. if( pBulkRespond->bIsLastTransfer == TRUE )
  1590. {
  1591. // Yes, it is the last transfer
  1592. // Is anything to send?
  1593. if( 0 == pBulkRespond->dwDeviceOut )
  1594. {
  1595. // No.
  1596. // IEEE 488.2, 11.5.1.1.7 Bit 2 — Query ERROR (QYE)
  1597. // An attempt is being made to read data from the Output Queue when no output is either present or pending
  1598. if( pBulkRespond->bEndOfMessage )
  1599. {
  1600. // this is the last read event of long transfer
  1601. // ignore this read
  1602. (void)pBulkRespond->bEndOfMessage;
  1603. }
  1604. else
  1605. GPIB_SET_QRE();
  1606. }
  1607. pData[pBulkRespond->dwDeviceOut++] = '\n';
  1608. }
  1609. // ------------------------------------------------------------------------------------------------------
  1610. // ---------------------------------------------------------------------------------------------------------
  1611. pBulkInHeader->stRespondMessage.TransferSize = MIN(pBulkRespond->dwDeviceOut, pBulkRespond->InTransferSize);
  1612. // ---------------------------------------------------------------------------------------------------------
  1613. // ----------------------------------------------------------------------------
  1614. pBulkRespond->dwDeviceOut+=sizeof(BULKIN_HEADER); // äëÿ óïðîùåíèÿ ó÷åòà äàííûõ
  1615. // ----------------------------------------------------------------------------
  1616. // -----------------------------------------------------------------------------------------
  1617. pInPipe->dwLength = sizeof(BULKIN_HEADER) + pBulkInHeader->stRespondMessage.TransferSize;
  1618. // -----------------------------------------------------------------------------------------
  1619. // -----------------------------------------------------------------
  1620. // Óñòàíîâêà àòòðèáóòà End Of Message (EOM) â BULKIN çàãîëîâêå
  1621. if( pBulkRespond->bIsLastTransfer == TRUE)
  1622. pBulkInHeader->stRespondMessage.bmTransferAttributes |= (1<<0);
  1623. // Åñëè ôóíêöèÿ íå ñáðîñèëà bIsLastTransfer, òî ïåðåäà÷à ñ÷èòàåòñÿ ïîñëåäíåé
  1624. else
  1625. pBulkInHeader->stRespondMessage.bmTransferAttributes &= ~(1<<0);
  1626. // -----------------------------------------------------------------
  1627. }
  1628. return rc;
  1629. }
  1630. // ==========================================================================================================================================
  1631. // ==========================================================================================================================================
  1632. void usbtmc_flush_buffer( TENDPOINT_LOG_ADDRESS apropriate_endpoint, USB_PIPE_ENTRY * pipe_entry )
  1633. {
  1634. switch( apropriate_endpoint )
  1635. {
  1636. case USB_EP_LOG_ADDRESS_BULK_OUT:
  1637. {
  1638. if( pipe_entry->pDefaultBuffer == gEP2BufOutExpand )
  1639. s_memset( (BYTE*)gEP2BufOutExpand, 0x00, USB_MAX_BULKOUT_BUFFERSIZE );
  1640. }
  1641. break;
  1642. case USB_EP_LOG_ADDRESS_BULK_IN:
  1643. {
  1644. if( pipe_entry->pDefaultBuffer == gEP2BufInExpand )
  1645. s_memset( (BYTE*)gEP2BufInExpand, 0x00, USB_MAX_BULKIN_BUFFERSIZE );
  1646. }
  1647. break;
  1648. }
  1649. }
  1650. // ==========================================================================================================================================
  1651. void usbtmc_init_intransfer( USB_DEVICE_INFO * udi )
  1652. {
  1653. USB_EP_STATUS * bulk_endpoint = (USB_EP_STATUS*) &udi->EPBulkStatus;
  1654. USB_PIPE_ENTRY_IN * pPipeIn = (USB_PIPE_ENTRY_IN*) &bulk_endpoint->InPipe;
  1655. USB_BULKRESPOND_STATUS * pBulkRespond = (USB_BULKRESPOND_STATUS*) &udi->BulkRespondStatus;
  1656. BULKIN_HEADER * pBulkInHeader = (BULKIN_HEADER*) pPipeIn->pDefaultBuffer;
  1657. GPIB_COMMAND_TREE * pGpib = (GPIB_COMMAND_TREE*) &udi->usbtmcGpib;
  1658. // -------------------------------------------------------------------------------------------------------------------------
  1659. // -------------------------------------------------------------------------------------------------------------------------
  1660. pPipeIn->pData = pPipeIn->pDefaultBuffer; // óêàçûâàåì áóôåð äëÿ ïåðåäà÷è
  1661. pBulkInHeader->stRespondMessage.TransferSize = 0; // îáíóëÿåì ðàçìåð ïåðåäà÷è
  1662. pGpib->pData = pPipeIn->pData + sizeof(BULKIN_HEADER); // óêàçûâàåì íà÷àëî áóôåðà äëÿ ñêëàäûâàíèÿ îòâåòîâ íà êîììàíäû
  1663. pBulkRespond->bIsLastTransfer = TRUE; // ñ÷èòàåì ñîîáøåíèå êîðîòêèì (â îäíó Transfer )
  1664. // óñòàíàâëèâàåì ìàêñèìàëüíîå êîëè÷åñòâî äàííûõ, êîòîðîå ìîæíî çàïèñàòü â âûõîäíîé áóôåð
  1665. pBulkRespond->RespondBufferSize = USB_MAX_BULKIN_BUFFERSIZE - sizeof(BULKIN_HEADER);
  1666. pBulkRespond->dwDeviceOut = 0;
  1667. }
  1668. void usbtmc_init_intransfer_newcmd( USB_DEVICE_INFO * udi )
  1669. {
  1670. USB_EP_STATUS * bulk_endpoint = (USB_EP_STATUS*) &udi->EPBulkStatus;
  1671. USB_BULKRESPOND_STATUS * pBulkRespond = (USB_BULKRESPOND_STATUS*) &udi->BulkRespondStatus;
  1672. if( pBulkRespond->dwDeviceOut > 0 )
  1673. {
  1674. /* IEEE 488.2, 11.5.1.1.7 Bit 2 — Query ERROR (QYE)
  1675. Query Errors are detected by the Output Queue Control, see 6.1.10. This event bit indicates that either
  1676. 1) An attempt is being made to read data from the Output Queue when no output is either present or pending, or
  1677. > 2) Data in the Output Queue has been lost.
  1678. See 6.5.7 for a complete description.
  1679. The Query Error bit shall not be set to report any other condition. Events that generate Query Errors shall not also
  1680. generate Execution Errors, Command Errors, or Device-Specific Errors.
  1681. */
  1682. // The device already has some bytes of respond.
  1683. // This call will make the device to lost the respond.
  1684. // In this case the Query Error bit should be set in Event Status Register
  1685. GPIB_SET_QRE();
  1686. }
  1687. // -------------------------------------------------------------------------------------------------------------------------
  1688. usbtmc_init_intransfer( udi );
  1689. }
  1690. #endif