OSDN Git Service

initial files
[iptd/iPTd_R3.git] / src / ry0 / device / PT1 / PT1Core.cpp
1 //\r
2 // PT1Core.cpp\r
3 //\r
4 \r
5 #define DBG_LEVEL 0\r
6 #include <Raym/Log.h>\r
7 #include "ry0/device/PT1/PT1Core.h"\r
8 #include "ry0/device/PT1/PT1Tuner.h"\r
9 \r
10 namespace ry0\r
11 {\r
12 namespace device\r
13 {\r
14 namespace PT1\r
15 {\r
16 \r
17 unsigned __stdcall PT1Core_transfer(void *arg)\r
18 {\r
19     ((PT1Core *)arg)->transfer();\r
20     return 0;\r
21 }\r
22 \r
23 PT1Core::PT1Core(EARTH::PT::Bus *bus, const EARTH::PT::Bus::DeviceInfo *deviceInfo, Tuner *tuners[MAX_TUNERS], HMODULE multi2_dll)\r
24 {\r
25     DebugLog2("PT1Core::PT1Core()");\r
26 \r
27     InitializeCriticalSection(&_cs);\r
28 \r
29     // initialize: variables\r
30     _device = NULL;\r
31     for (EARTH::uint i = 0; i < 4; ++i)\r
32     {\r
33         _tuners[i] = NULL;\r
34         _locked[i] = false;\r
35     }\r
36     _name[0] = '\0';\r
37     _transfer = ST_IDLE;\r
38 \r
39     // initialize: PT1\r
40     EARTH::status status;\r
41     status = bus->NewDevice(deviceInfo, &_device, NULL);\r
42     if (status != EARTH::PT::STATUS_OK)\r
43     {\r
44         DebugLog3("error: Bus::NewDevice() (0x%08x)\n", status);\r
45         throw EXCEPTION_NEW_DEVICE;\r
46     }\r
47 \r
48     status = _device->Open();\r
49     if (status != EARTH::PT::STATUS_OK)\r
50     {\r
51         DebugLog3("error: Device::Open() (0x%08x)\n", status);\r
52         int except = EXCEPTION_OPEN;\r
53         status = _device->Delete();\r
54         if (status != EARTH::PT::STATUS_OK)\r
55         {\r
56             DebugLog3("error: Device::Delete() (0x%08x)\n", status);\r
57             except |= EXCEPTION_DELETE;\r
58         }\r
59         throw except;\r
60     }\r
61 \r
62     status = _device->SetTunerPowerReset(EARTH::PT::Device::TUNER_POWER_ON_RESET_ENABLE);\r
63     if (status != EARTH::PT::STATUS_OK)\r
64     {\r
65         DebugLog3("error: Device::SetTunerPowerReset(TUNER_POWER_ON_RESET_ENABLE) (0x%08x)\n", status);\r
66         int except = EXCEPTION_SET_TUNER_POWER_RESET;\r
67         status = _device->Close();\r
68         if (status != EARTH::PT::STATUS_OK)\r
69         {\r
70             DebugLog3("error: Device::Close() (0x%08x)\n", status);\r
71             except |= EXCEPTION_CLOSE;\r
72         }\r
73         status = _device->Delete();\r
74         if (status != EARTH::PT::STATUS_OK)\r
75         {\r
76             DebugLog3("error: Device::Delete() (0x%08x)\n", status);\r
77             except |= EXCEPTION_DELETE;\r
78         }\r
79         throw except;\r
80     }\r
81 \r
82     /*\r
83     EARTH::OS::Thread::Sleep((20)*1000*1000); // 20 ms\r
84     */\r
85     ::Sleep(20);\r
86     \r
87     status = _device->SetTunerPowerReset(EARTH::PT::Device::TUNER_POWER_ON_RESET_DISABLE);\r
88     if (status != EARTH::PT::STATUS_OK)\r
89     {\r
90         DebugLog3("error: Device::SetTunerPowerReset(TUNER_POWER_ON_RESET_DISABLE) (0x%08x)\n", status);\r
91         int except = EXCEPTION_SET_TUNER_POWER_RESET;\r
92         status = _device->Close();\r
93         if (status != EARTH::PT::STATUS_OK)\r
94         {\r
95             DebugLog3("error: Device::Close() (0x%08x)\n", status);\r
96             except |= EXCEPTION_CLOSE;\r
97         }\r
98         status = _device->Delete();\r
99         if (status != EARTH::PT::STATUS_OK)\r
100         {\r
101             DebugLog3("error: Device::Delete() (0x%08x)\n", status);\r
102             except |= EXCEPTION_DELETE;\r
103         }\r
104         throw except;\r
105     }\r
106 \r
107     /*\r
108     EARTH::OS::Thread::Sleep((1)*1000*1000); // 1 ms\r
109     */\r
110     ::Sleep(1);\r
111 \r
112     for (EARTH::uint i = 0; i < 2; ++i)\r
113     {\r
114         status = _device->InitTuner(i);\r
115         if (status != EARTH::PT::STATUS_OK)\r
116         {\r
117             DebugLog3("error: Device::InitTuner() (0x%08x)\n", status);\r
118             int except = EXCEPTION_INIT_TUNER;\r
119             status = _device->Close();\r
120             if (status != EARTH::PT::STATUS_OK)\r
121             {\r
122                 DebugLog3("error: Device::Close() (0x%08x)\n", status);\r
123                 except |= EXCEPTION_CLOSE;\r
124             }\r
125             status = _device->Delete();\r
126             if (status != EARTH::PT::STATUS_OK)\r
127             {\r
128                 DebugLog3("error: Device::Delete() (0x%08x)\n", status);\r
129                 except |= EXCEPTION_DELETE;\r
130             }\r
131             throw except;\r
132         }\r
133     }\r
134 \r
135     for (EARTH::uint i = 0; i < 2; ++i)\r
136     {\r
137         for (EARTH::uint j = 0; j < 2; ++j)\r
138         {\r
139             status = _device->SetTunerSleep(i, static_cast<EARTH::PT::Device::ISDB>(j), false);\r
140             if (status != EARTH::PT::STATUS_OK)\r
141             {\r
142                 DebugLog3("error: Device::SetTunerSleep() (0x%08x)\n", status);\r
143                 int except = EXCEPTION_SET_TUNER_SLEEP;\r
144                 status = _device->Close();\r
145                 if (status != EARTH::PT::STATUS_OK)\r
146                 {\r
147                     DebugLog3("error: Device::Close() (0x%08x)\n", status);\r
148                     except |= EXCEPTION_CLOSE;\r
149                 }\r
150                 status = _device->Delete();\r
151                 if (status != EARTH::PT::STATUS_OK)\r
152                 {\r
153                     DebugLog3("error: Device::Delete() (0x%08x)\n", status);\r
154                     except |= EXCEPTION_DELETE;\r
155                 }\r
156                 throw except;\r
157             }\r
158         }\r
159     }\r
160 \r
161     for (EARTH::uint i = 0; i < 2; ++i)\r
162     {\r
163         for (EARTH::uint j = 0; j < 2; ++j)\r
164         {\r
165             status = _device->SetStreamEnable(i, static_cast<EARTH::PT::Device::ISDB>(j), true);\r
166             if (status != EARTH::PT::STATUS_OK)\r
167             {\r
168                 DebugLog3("error: Device::SetStreamEnable() (0x%08x)\n", status);\r
169                 int except = EXCEPTION_SET_STREAM_ENABLE;\r
170                 status = _device->Close();\r
171                 if (status != EARTH::PT::STATUS_OK)\r
172                 {\r
173                     DebugLog3("error: Device::Close() (0x%08x)\n", status);\r
174                     except |= EXCEPTION_CLOSE;\r
175                 }\r
176                 status = _device->Delete();\r
177                 if (status != EARTH::PT::STATUS_OK)\r
178                 {\r
179                     DebugLog3("error: Device::Delete() (0x%08x)\n", status);\r
180                     except |= EXCEPTION_DELETE;\r
181                 }\r
182                 throw except;\r
183             }\r
184         }\r
185     }\r
186     \r
187     for (EARTH::uint i = 0; i < 2; ++i)\r
188     {\r
189         for (EARTH::uint j = 0; j < 2; ++j)\r
190         {\r
191             status = _device->SetStreamGray(i, static_cast<EARTH::PT::Device::ISDB>(j), 4 + i*2 + j);\r
192             if (status != EARTH::PT::STATUS_OK)\r
193             {\r
194                 DebugLog3("error: Device::SetStreamGray() (0x%08x)\n", status);\r
195                 int except = EXCEPTION_SET_STREAM_GRAY;\r
196                 status = _device->Close();\r
197                 if (status != EARTH::PT::STATUS_OK)\r
198                 {\r
199                     DebugLog3("error: Device::Close() (0x%08x)\n", status);\r
200                     except |= EXCEPTION_CLOSE;\r
201                 }\r
202                 status = _device->Delete();\r
203                 if (status != EARTH::PT::STATUS_OK)\r
204                 {\r
205                     DebugLog3("error: Device::Delete() (0x%08x)\n", status);\r
206                     except |= EXCEPTION_DELETE;\r
207                 }\r
208                 throw except;\r
209             }\r
210         }\r
211     }\r
212 \r
213     for (EARTH::uint i = 0; i < 4; ++i)\r
214     {\r
215         _tuners[i] = new PT1Tuner(this, i, multi2_dll);\r
216         tuners[i] = _tuners[i];\r
217     }\r
218 \r
219     int ret = sprintf_s(_name, sizeof(_name), "PT%d@%02d%02d%02d",\r
220                         deviceInfo->PTn,\r
221                         deviceInfo->Bus,\r
222                         deviceInfo->Slot,\r
223                         deviceInfo->Function);\r
224     if (ret < 0)\r
225     {\r
226         DebugLog3("error: snprintf() (0x%08x)\n", ret);\r
227         int except = EXCEPTION_OTHER;\r
228         status = _device->Close();\r
229         if (status != EARTH::PT::STATUS_OK)\r
230         {\r
231             DebugLog3("error: Device::Close() (0x%08x)\n", status);\r
232             except |= EXCEPTION_CLOSE;\r
233         }\r
234         status = _device->Delete();\r
235         if (status != EARTH::PT::STATUS_OK)\r
236         {\r
237             DebugLog3("error: Device::Delete() (0x%08x)\n", status);\r
238             except |= EXCEPTION_DELETE;\r
239         }\r
240         throw except;\r
241     }\r
242 \r
243     // start thread\r
244     EnterCriticalSection(&_cs);\r
245 \r
246     HANDLE h;\r
247     unsigned int uiThreadId;\r
248     h = (HANDLE)_beginthreadex(NULL,\r
249                                0,\r
250                                PT1Core_transfer,\r
251                                this,\r
252                                0,\r
253                                &uiThreadId);\r
254     if (h != NULL)\r
255     {\r
256         _transfer = ST_READY;\r
257 \r
258         LeaveCriticalSection(&_cs);\r
259 \r
260         bool done = false;\r
261         while (!done)\r
262         {\r
263             bool needSleep = false;\r
264             EnterCriticalSection(&_cs);\r
265 \r
266             if (_transfer == ST_IDLE)\r
267             {\r
268                 done = true;\r
269             }\r
270             else if (_transfer == ST_RUN)\r
271             {\r
272                 done = true;\r
273             }\r
274             else if (_transfer == ST_READY)\r
275             {\r
276                 needSleep = true;\r
277             }\r
278             LeaveCriticalSection(&_cs);\r
279 \r
280             if (needSleep)\r
281             {\r
282                 ::Sleep(100); // 100 ms\r
283             }\r
284         }\r
285 \r
286         EnterCriticalSection(&_cs);\r
287     }\r
288     else\r
289     {\r
290         throw EXCEPTION_OTHER;\r
291     }\r
292 \r
293     LeaveCriticalSection(&_cs);\r
294 \r
295 }\r
296 \r
297 PT1Core::~PT1Core()\r
298 {\r
299     EARTH::status status = _device->Close();\r
300     if (status != EARTH::PT::STATUS_OK)\r
301     {\r
302         DebugLog3("error: Device::Close() (0x%08x)\n", status);\r
303     }\r
304     status = _device->Delete();\r
305     if (status != EARTH::PT::STATUS_OK)\r
306     {\r
307         DebugLog3("error: Device::Delete() (0x%08x)\n", status);\r
308     }\r
309 \r
310     DeleteCriticalSection(&_cs);\r
311 \r
312     DebugLog2("PT1Core::~PT1Core()\n");\r
313 }\r
314 \r
315 void PT1Core::release(Tuner *tuner)\r
316 {\r
317     DebugLog2("PT1Core::release()\n");\r
318 \r
319     // check tuners\r
320     bool needStop = true;\r
321     for (EARTH::uint i = 0; i < MAX_TUNERS; ++i)\r
322     {\r
323         if (_tuners[i] == NULL)\r
324         {\r
325             needStop = false;\r
326             break;\r
327         }\r
328     }\r
329     if (needStop)\r
330     {\r
331         // stop transfer thread\r
332         EnterCriticalSection(&_cs);\r
333         if (_transfer == ST_RUN)\r
334         {\r
335             DebugLog3("_transfer == ST_RUN\n");\r
336             _transfer = ST_STOP;\r
337 \r
338             LeaveCriticalSection(&_cs);\r
339             bool done = false;\r
340             while (!done)\r
341             {\r
342                 EnterCriticalSection(&_cs);\r
343                 done = (_transfer == ST_IDLE);\r
344                 LeaveCriticalSection(&_cs);\r
345             }\r
346             EnterCriticalSection(&_cs);\r
347         }\r
348         else\r
349         {\r
350             DebugLog3("koko\n");\r
351         }\r
352         LeaveCriticalSection(&_cs);\r
353     }\r
354 \r
355     bool exist = false;\r
356     for (EARTH::uint i = 0; i < 4; ++i)\r
357     {\r
358         if (_tuners[i] == tuner)\r
359         {\r
360             _tuners[i] = NULL;\r
361         }\r
362         else if (_tuners[i] != NULL)\r
363         {\r
364             exist = true;\r
365         }\r
366     }\r
367     if (!exist)\r
368     {\r
369         DebugLog3("delete.\n");\r
370         delete this;\r
371     }\r
372 }\r
373 \r
374 const char *PT1Core::name()\r
375 {\r
376     DebugLog2("PT1Core::name()\n");\r
377     return _name;\r
378 }\r
379 \r
380 bool PT1Core::getCnAgc(EARTH::uint tuner, EARTH::uint *cn100, EARTH::uint *agc, EARTH::uint *maxAgc)\r
381 {\r
382     DebugLog2("PT1Core::getCnAgc()\n");\r
383     bool result = false;\r
384     if ((tuner < MAX_TUNERS) && (cn100 != NULL) && (agc != NULL) && (maxAgc != NULL))\r
385     {\r
386         EnterCriticalSection(&_cs);\r
387         EARTH::status status;\r
388         status = _device->GetCnAgc(tuner / 2,\r
389                                    tuner % 2 == 0 ? EARTH::PT::Device::ISDB_S : EARTH::PT::Device::ISDB_T,\r
390                                    cn100, agc, maxAgc);\r
391         if (status == EARTH::PT::STATUS_OK)\r
392         {\r
393             result = true;\r
394         }\r
395         LeaveCriticalSection(&_cs);\r
396     }\r
397     return result;\r
398 }\r
399 \r
400 bool PT1Core::setChannel(EARTH::uint tuner, int channel)\r
401 {\r
402     DebugLog2("TunerCore::setChannel(%d, %d)\n", channel, tuner);\r
403 \r
404     EARTH::status status;\r
405     bool result = false;\r
406 \r
407     EnterCriticalSection(&_cs);\r
408 \r
409     if (tuner >= 0 && tuner < 4)\r
410     {\r
411         if ((tuner % 2) == 0)\r
412         {\r
413             // ISDB-S\r
414             while ((0 <= channel) && (channel <= Tuner::MAX_CHANNELS_ISDB_S))\r
415             {\r
416                 EARTH::PT::Device::TmccS tmcc;\r
417                 bool tmccIsValid = false;\r
418 \r
419                 status = _device->SetFrequency((tuner / 2), EARTH::PT::Device::ISDB_S, channel, 0);\r
420                 if (status != EARTH::PT::STATUS_OK)\r
421                 {\r
422                     DebugLog3("error: Device::SetFrequency() (0x%08x)\n", status);\r
423                     break;\r
424                 }\r
425 \r
426                 for (int i = 0; i < 6; ++i)\r
427                 {\r
428                     status = _device->GetTmccS((tuner / 2), &tmcc);\r
429                     if (status == EARTH::PT::STATUS_OK)\r
430                     {\r
431                         tmccIsValid = true;\r
432                         break;\r
433                     }\r
434                     else\r
435                     {\r
436                         DebugLog3("error: Device::GetTmccS() (0x%08x)\n", status);\r
437                     }\r
438                     ::Sleep(50);    // 50 ms\r
439                 }\r
440 \r
441                 result = tmccIsValid;\r
442                 break;\r
443             }\r
444         }\r
445         else\r
446         {\r
447             // ISDB-T\r
448             while ((0 <= channel) && (channel <= Tuner::MAX_CHANNELS_ISDB_T))\r
449             {\r
450                 EARTH::PT::Device::TmccT tmcc;\r
451                 bool tmccIsValid = false;\r
452 \r
453                 status = _device->SetFrequency((tuner / 2), EARTH::PT::Device::ISDB_T, channel, 0);\r
454                 if (status != EARTH::PT::STATUS_OK)\r
455                 {\r
456                     DebugLog3("error: Device::SetFrequency() (0x%08x)\n", status);\r
457                     break;\r
458                 }\r
459 \r
460                 for (int i = 0; i < 2; ++i)\r
461                 {\r
462                     status = _device->GetTmccT((tuner / 2), &tmcc);\r
463                     if (status == EARTH::PT::STATUS_OK)\r
464                     {\r
465                         tmccIsValid = true;\r
466                         break;\r
467                     }\r
468                     else\r
469                     {\r
470                         DebugLog3("error: Device::GetTmccT() (0x%08x)\n", status);\r
471                     }\r
472                 }\r
473 \r
474                 result = tmccIsValid;\r
475                 break;\r
476             }\r
477         }\r
478         _locked[tuner] = result;\r
479     }\r
480 \r
481     LeaveCriticalSection(&_cs);\r
482 \r
483     return result;\r
484 }\r
485 \r
486 void PT1Core::transfer()\r
487 {\r
488     DebugLog2("PT1Core::transfer() called.\n");\r
489 \r
490     while (true)\r
491     {\r
492         EARTH::status status;\r
493 \r
494         EARTH::PT::Device::BufferInfo bufferInfo;\r
495         status = _device->GetBufferInfo(&bufferInfo);\r
496         if (status != EARTH::PT::STATUS_OK)\r
497         {\r
498             DebugLog3("error: Device::GetBufferInfo() (0x%08x)\n", status);\r
499             break;\r
500         }\r
501 \r
502         if (bufferInfo.VirtualSize == 0)\r
503         {\r
504             bufferInfo.VirtualSize  = VIRTUAL_SIZE;\r
505             bufferInfo.VirtualCount = VIRTUAL_COUNT;\r
506             bufferInfo.LockSize     = LOCK_SIZE;\r
507             status = _device->SetBufferInfo(&bufferInfo);\r
508             if (status != EARTH::PT::STATUS_OK)\r
509             {\r
510                 DebugLog3("error: Device::SetBufferInfo() (0x%08x)\n", status);\r
511                 break;\r
512             }\r
513         }\r
514 \r
515         EnterCriticalSection(&_cs);\r
516         _transfer = ST_RUN;\r
517         LeaveCriticalSection(&_cs);\r
518 \r
519         bool done = false;\r
520         while (!done)\r
521         {\r
522             // In order to examine to what extent DMA transfer or advanced, is cleared to 0 the end of each block\r
523             for (int i = 0; i < VIRTUAL_COUNT; ++i)\r
524             {\r
525                 for (int j = 0; j < VIRTUAL_SIZE; ++j)\r
526                 {\r
527                     for (int k = 0; k < BLOCK_COUNT; ++k)\r
528                     {\r
529                         clearBlock(i, j, k);\r
530                     }\r
531                 }\r
532             }\r
533             \r
534             // reset transfer counter\r
535             status = _device->ResetTransferCounter();\r
536             if (status != EARTH::PT::STATUS_OK)\r
537             {\r
538                 DebugLog3("error: Device::ResetTransferCounter() (0x%08x)\n", status);\r
539                 break;\r
540             }\r
541             \r
542             // increment transfer counter\r
543             bool flag = false;\r
544             for (int i = 0; i < VIRTUAL_SIZE * VIRTUAL_COUNT; ++i)\r
545             {\r
546                 status = _device->IncrementTransferCounter();\r
547                 if (status != EARTH::PT::STATUS_OK)\r
548                 {\r
549                     DebugLog3("error: Device::IncrementTransferCounter() (0x%08x)\n", status);\r
550                     flag = true;\r
551                     break;\r
552                 }\r
553             }\r
554             if (flag)\r
555             {\r
556                 break;\r
557             }\r
558             \r
559             // enable DMA transfer\r
560             status = _device->SetTransferEnable(true);\r
561             if (status != EARTH::PT::STATUS_OK)\r
562             {\r
563                 DebugLog3("error: Device::SetTransferEnable(true) (0x%08x)\n", status);\r
564                 break;\r
565             }\r
566             \r
567             _virtualIndex = 0;\r
568             _imageIndex = 0;\r
569             _blockIndex = 0;\r
570             \r
571             DebugLog2("transfer start.\n");\r
572             while (true)\r
573             {\r
574                 if (!waitBlock())\r
575                 {\r
576                     break;\r
577                 }\r
578                 \r
579                 copyBlock();\r
580                 \r
581                 if (!dispatchBlock())\r
582                 {\r
583                     break;\r
584                 }\r
585             }\r
586             DebugLog2("transfer stop.\n");\r
587 \r
588             status = _device->SetTransferEnable(false);\r
589             if (status != EARTH::PT::STATUS_OK)\r
590             {\r
591                 DebugLog3("error: Device::SetTransferEnable(false) (0x%08x)\n", status);\r
592                 break;\r
593             }\r
594 \r
595             EnterCriticalSection(&_cs);\r
596             done = (_transfer != ST_RUN);\r
597             LeaveCriticalSection(&_cs);\r
598         }\r
599         break;\r
600     }\r
601 \r
602     EnterCriticalSection(&_cs);\r
603     _transfer = ST_IDLE;\r
604     LeaveCriticalSection(&_cs);\r
605 \r
606     DebugLog2("PT1Core::transfer() end.\n");\r
607 }\r
608 \r
609 uint32_t PT1Core::offset(uint32_t imageIndex, uint32_t blockIndex, uint32_t additionalOffset)\r
610 {\r
611     blockIndex += BLOCK_COUNT * imageIndex;\r
612     uint32_t offset = (BLOCK_SIZE * blockIndex + additionalOffset) / sizeof(uint32_t);\r
613     return offset;\r
614 }\r
615 \r
616 uint32_t PT1Core::offset(uint32_t imageIndex, uint32_t blockIndex)\r
617 {\r
618     return offset(imageIndex, blockIndex, (BLOCK_SIZE - sizeof(uint32_t)));\r
619 }\r
620 \r
621 uint32_t PT1Core::read(uint32_t virtualIndex, uint32_t imageIndex, uint32_t blockIndex)\r
622 {\r
623     void *voidPtr;\r
624     if (_device->GetBufferPtr(virtualIndex, &voidPtr) != EARTH::PT::STATUS_OK)\r
625     {\r
626         DebugLog3("error: Device::GetBufferPtr() :read\n");\r
627         return 0;\r
628     }\r
629 \r
630     volatile const uint32_t *ptr = (volatile const uint32_t *)voidPtr;\r
631     if (ptr != NULL)\r
632     {\r
633         return ptr[offset(imageIndex, blockIndex)];\r
634     }\r
635     else\r
636     {\r
637         DebugLog3("ptr is NULL (read)\n");\r
638     }\r
639     return 0;\r
640 }\r
641 \r
642 void PT1Core::clearBlock(uint32_t virtualIndex, uint32_t imageIndex, uint32_t blockIndex)\r
643 {\r
644     void *voidPtr = NULL;\r
645     if (_device->GetBufferPtr(virtualIndex, &voidPtr) != EARTH::PT::STATUS_OK)\r
646     {\r
647         DebugLog3("error: Device::GetBufferPtr() :clearBlock\n");\r
648         return;\r
649     }\r
650 \r
651     uint32_t *ptr = (uint32_t *)voidPtr;\r
652     if (ptr != NULL)\r
653     {\r
654         ptr[offset(imageIndex, blockIndex)] = 0;\r
655     }\r
656     else\r
657     {\r
658         DebugLog3("ptr is NULL (clearBlock)");\r
659     }\r
660 }\r
661 \r
662 bool PT1Core::waitBlock()\r
663 {\r
664     bool result = true;\r
665     while (result)\r
666     {\r
667         /*\r
668         EARTH::OS::Thread::Sleep((10)*1000*1000); // 10 ms\r
669         */\r
670         ::Sleep(10);\r
671 \r
672         //\r
673         if (read(_virtualIndex, _imageIndex, _blockIndex) != 0)\r
674         {\r
675             break;\r
676         }\r
677 \r
678         EnterCriticalSection(&_cs);\r
679         result = (_transfer == ST_RUN);\r
680         LeaveCriticalSection(&_cs);\r
681     }\r
682     return result;\r
683 }\r
684 \r
685 void PT1Core::copyBlock()\r
686 {\r
687     void *voidPtr;\r
688     if (_device->GetBufferPtr(_virtualIndex, &voidPtr) != EARTH::PT::STATUS_OK)\r
689     {\r
690         DebugLog3("error: Device::GetBufferPtr(): copyBlock\n");\r
691         return;\r
692     }\r
693 \r
694     uint32_t *srcPtr = (uint32_t *)voidPtr;\r
695 \r
696     srcPtr += offset(_imageIndex, _blockIndex, 0);\r
697 \r
698     memcpy(_buffer, srcPtr, BLOCK_SIZE);\r
699 \r
700     //\r
701     srcPtr[BLOCK_SIZE / sizeof(*srcPtr) - 1] = 0;\r
702 \r
703     if (BLOCK_COUNT <= ++_blockIndex)\r
704     {\r
705         _blockIndex = 0;\r
706 \r
707         //\r
708         if (_device->IncrementTransferCounter() != EARTH::PT::STATUS_OK)\r
709         {\r
710             DebugLog3("error: Device::IncrementTransferCounter()\n");\r
711             return;\r
712         }\r
713 \r
714         if (VIRTUAL_SIZE <= ++_imageIndex)\r
715         {\r
716             _imageIndex = 0;\r
717             if (VIRTUAL_COUNT <= ++_virtualIndex)\r
718             {\r
719                 _virtualIndex = 0;\r
720             }\r
721         }\r
722     }\r
723 }\r
724 \r
725 bool PT1Core::dispatchBlock()\r
726 {\r
727     const uint32_t *ptr = (uint32_t *)_buffer;\r
728 \r
729     uint32_t i;\r
730     for (i = 0; i < BLOCK_SIZE / sizeof(*ptr); ++i)\r
731     {\r
732         uint32_t packet = ptr[i];\r
733 \r
734         uint32_t packetId    = BIT_SHIFT_MASK(packet, 29, 3);\r
735         uint32_t packetError = BIT_SHIFT_MASK(packet, 24, 1);\r
736 \r
737         if (packetError)\r
738         {\r
739             // check error\r
740             EARTH::PT::Device::TransferInfo info;\r
741             if (_device->GetTransferInfo(&info) != EARTH::PT::STATUS_OK)\r
742             {\r
743                 DebugLog3("error: Device::GetTransferInfo()\n");\r
744                 return false;\r
745             }\r
746 \r
747             if (info.TransferCounter1)\r
748             {\r
749                 DebugLog3("Transfer counter is now less than 1\n");\r
750             }\r
751             else if (info.BufferOverflow)\r
752             {\r
753                 DebugLog3("Buffer Overflow\n");\r
754             }\r
755             else\r
756             {\r
757                 DebugLog3("Transfer error\n");\r
758             }\r
759             return false;\r
760         }\r
761 \r
762         if ((1 <= packetId) && (packetId <= 4))\r
763         {\r
764             if (_locked[packetId - 1] && (_tuners[packetId - 1] != NULL))\r
765             {\r
766                 _tuners[packetId - 1]->addPacket(packet);\r
767             }\r
768         }\r
769     }\r
770 \r
771     return true;\r
772 }\r
773 \r
774 } // PT1\r
775 } // device\r
776 } // ry0\r
777 \r