6 #include <Raym/Log.h>
\r
7 #include "ry0/device/PT1/PT1Core.h"
\r
8 #include "ry0/device/PT1/PT1Tuner.h"
\r
17 unsigned __stdcall PT1Core_transfer(void *arg)
\r
19 ((PT1Core *)arg)->transfer();
\r
23 PT1Core::PT1Core(EARTH::PT::Bus *bus, const EARTH::PT::Bus::DeviceInfo *deviceInfo, Tuner *tuners[MAX_TUNERS], HMODULE multi2_dll)
\r
25 DebugLog2("PT1Core::PT1Core()");
\r
27 InitializeCriticalSection(&_cs);
\r
29 // initialize: variables
\r
31 for (EARTH::uint i = 0; i < 4; ++i)
\r
37 _transfer = ST_IDLE;
\r
40 EARTH::status status;
\r
41 status = bus->NewDevice(deviceInfo, &_device, NULL);
\r
42 if (status != EARTH::PT::STATUS_OK)
\r
44 DebugLog3("error: Bus::NewDevice() (0x%08x)\n", status);
\r
45 throw EXCEPTION_NEW_DEVICE;
\r
48 status = _device->Open();
\r
49 if (status != EARTH::PT::STATUS_OK)
\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
56 DebugLog3("error: Device::Delete() (0x%08x)\n", status);
\r
57 except |= EXCEPTION_DELETE;
\r
62 status = _device->SetTunerPowerReset(EARTH::PT::Device::TUNER_POWER_ON_RESET_ENABLE);
\r
63 if (status != EARTH::PT::STATUS_OK)
\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
70 DebugLog3("error: Device::Close() (0x%08x)\n", status);
\r
71 except |= EXCEPTION_CLOSE;
\r
73 status = _device->Delete();
\r
74 if (status != EARTH::PT::STATUS_OK)
\r
76 DebugLog3("error: Device::Delete() (0x%08x)\n", status);
\r
77 except |= EXCEPTION_DELETE;
\r
83 EARTH::OS::Thread::Sleep((20)*1000*1000); // 20 ms
\r
87 status = _device->SetTunerPowerReset(EARTH::PT::Device::TUNER_POWER_ON_RESET_DISABLE);
\r
88 if (status != EARTH::PT::STATUS_OK)
\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
95 DebugLog3("error: Device::Close() (0x%08x)\n", status);
\r
96 except |= EXCEPTION_CLOSE;
\r
98 status = _device->Delete();
\r
99 if (status != EARTH::PT::STATUS_OK)
\r
101 DebugLog3("error: Device::Delete() (0x%08x)\n", status);
\r
102 except |= EXCEPTION_DELETE;
\r
108 EARTH::OS::Thread::Sleep((1)*1000*1000); // 1 ms
\r
112 for (EARTH::uint i = 0; i < 2; ++i)
\r
114 status = _device->InitTuner(i);
\r
115 if (status != EARTH::PT::STATUS_OK)
\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
122 DebugLog3("error: Device::Close() (0x%08x)\n", status);
\r
123 except |= EXCEPTION_CLOSE;
\r
125 status = _device->Delete();
\r
126 if (status != EARTH::PT::STATUS_OK)
\r
128 DebugLog3("error: Device::Delete() (0x%08x)\n", status);
\r
129 except |= EXCEPTION_DELETE;
\r
135 for (EARTH::uint i = 0; i < 2; ++i)
\r
137 for (EARTH::uint j = 0; j < 2; ++j)
\r
139 status = _device->SetTunerSleep(i, static_cast<EARTH::PT::Device::ISDB>(j), false);
\r
140 if (status != EARTH::PT::STATUS_OK)
\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
147 DebugLog3("error: Device::Close() (0x%08x)\n", status);
\r
148 except |= EXCEPTION_CLOSE;
\r
150 status = _device->Delete();
\r
151 if (status != EARTH::PT::STATUS_OK)
\r
153 DebugLog3("error: Device::Delete() (0x%08x)\n", status);
\r
154 except |= EXCEPTION_DELETE;
\r
161 for (EARTH::uint i = 0; i < 2; ++i)
\r
163 for (EARTH::uint j = 0; j < 2; ++j)
\r
165 status = _device->SetStreamEnable(i, static_cast<EARTH::PT::Device::ISDB>(j), true);
\r
166 if (status != EARTH::PT::STATUS_OK)
\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
173 DebugLog3("error: Device::Close() (0x%08x)\n", status);
\r
174 except |= EXCEPTION_CLOSE;
\r
176 status = _device->Delete();
\r
177 if (status != EARTH::PT::STATUS_OK)
\r
179 DebugLog3("error: Device::Delete() (0x%08x)\n", status);
\r
180 except |= EXCEPTION_DELETE;
\r
187 for (EARTH::uint i = 0; i < 2; ++i)
\r
189 for (EARTH::uint j = 0; j < 2; ++j)
\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
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
199 DebugLog3("error: Device::Close() (0x%08x)\n", status);
\r
200 except |= EXCEPTION_CLOSE;
\r
202 status = _device->Delete();
\r
203 if (status != EARTH::PT::STATUS_OK)
\r
205 DebugLog3("error: Device::Delete() (0x%08x)\n", status);
\r
206 except |= EXCEPTION_DELETE;
\r
213 for (EARTH::uint i = 0; i < 4; ++i)
\r
215 _tuners[i] = new PT1Tuner(this, i, multi2_dll);
\r
216 tuners[i] = _tuners[i];
\r
219 int ret = sprintf_s(_name, sizeof(_name), "PT%d@%02d%02d%02d",
\r
223 deviceInfo->Function);
\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
231 DebugLog3("error: Device::Close() (0x%08x)\n", status);
\r
232 except |= EXCEPTION_CLOSE;
\r
234 status = _device->Delete();
\r
235 if (status != EARTH::PT::STATUS_OK)
\r
237 DebugLog3("error: Device::Delete() (0x%08x)\n", status);
\r
238 except |= EXCEPTION_DELETE;
\r
244 EnterCriticalSection(&_cs);
\r
247 unsigned int uiThreadId;
\r
248 h = (HANDLE)_beginthreadex(NULL,
\r
256 _transfer = ST_READY;
\r
258 LeaveCriticalSection(&_cs);
\r
263 bool needSleep = false;
\r
264 EnterCriticalSection(&_cs);
\r
266 if (_transfer == ST_IDLE)
\r
270 else if (_transfer == ST_RUN)
\r
274 else if (_transfer == ST_READY)
\r
278 LeaveCriticalSection(&_cs);
\r
282 ::Sleep(100); // 100 ms
\r
286 EnterCriticalSection(&_cs);
\r
290 throw EXCEPTION_OTHER;
\r
293 LeaveCriticalSection(&_cs);
\r
297 PT1Core::~PT1Core()
\r
299 EARTH::status status = _device->Close();
\r
300 if (status != EARTH::PT::STATUS_OK)
\r
302 DebugLog3("error: Device::Close() (0x%08x)\n", status);
\r
304 status = _device->Delete();
\r
305 if (status != EARTH::PT::STATUS_OK)
\r
307 DebugLog3("error: Device::Delete() (0x%08x)\n", status);
\r
310 DeleteCriticalSection(&_cs);
\r
312 DebugLog2("PT1Core::~PT1Core()\n");
\r
315 void PT1Core::release(Tuner *tuner)
\r
317 DebugLog2("PT1Core::release()\n");
\r
320 bool needStop = true;
\r
321 for (EARTH::uint i = 0; i < MAX_TUNERS; ++i)
\r
323 if (_tuners[i] == NULL)
\r
331 // stop transfer thread
\r
332 EnterCriticalSection(&_cs);
\r
333 if (_transfer == ST_RUN)
\r
335 DebugLog3("_transfer == ST_RUN\n");
\r
336 _transfer = ST_STOP;
\r
338 LeaveCriticalSection(&_cs);
\r
342 EnterCriticalSection(&_cs);
\r
343 done = (_transfer == ST_IDLE);
\r
344 LeaveCriticalSection(&_cs);
\r
346 EnterCriticalSection(&_cs);
\r
350 DebugLog3("koko\n");
\r
352 LeaveCriticalSection(&_cs);
\r
355 bool exist = false;
\r
356 for (EARTH::uint i = 0; i < 4; ++i)
\r
358 if (_tuners[i] == tuner)
\r
362 else if (_tuners[i] != NULL)
\r
369 DebugLog3("delete.\n");
\r
374 const char *PT1Core::name()
\r
376 DebugLog2("PT1Core::name()\n");
\r
380 bool PT1Core::getCnAgc(EARTH::uint tuner, EARTH::uint *cn100, EARTH::uint *agc, EARTH::uint *maxAgc)
\r
382 DebugLog2("PT1Core::getCnAgc()\n");
\r
383 bool result = false;
\r
384 if ((tuner < MAX_TUNERS) && (cn100 != NULL) && (agc != NULL) && (maxAgc != NULL))
\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
395 LeaveCriticalSection(&_cs);
\r
400 bool PT1Core::setChannel(EARTH::uint tuner, int channel)
\r
402 DebugLog2("TunerCore::setChannel(%d, %d)\n", channel, tuner);
\r
404 EARTH::status status;
\r
405 bool result = false;
\r
407 EnterCriticalSection(&_cs);
\r
409 if (tuner >= 0 && tuner < 4)
\r
411 if ((tuner % 2) == 0)
\r
414 while ((0 <= channel) && (channel <= Tuner::MAX_CHANNELS_ISDB_S))
\r
416 EARTH::PT::Device::TmccS tmcc;
\r
417 bool tmccIsValid = false;
\r
419 status = _device->SetFrequency((tuner / 2), EARTH::PT::Device::ISDB_S, channel, 0);
\r
420 if (status != EARTH::PT::STATUS_OK)
\r
422 DebugLog3("error: Device::SetFrequency() (0x%08x)\n", status);
\r
426 for (int i = 0; i < 6; ++i)
\r
428 status = _device->GetTmccS((tuner / 2), &tmcc);
\r
429 if (status == EARTH::PT::STATUS_OK)
\r
431 tmccIsValid = true;
\r
436 DebugLog3("error: Device::GetTmccS() (0x%08x)\n", status);
\r
438 ::Sleep(50); // 50 ms
\r
441 result = tmccIsValid;
\r
448 while ((0 <= channel) && (channel <= Tuner::MAX_CHANNELS_ISDB_T))
\r
450 EARTH::PT::Device::TmccT tmcc;
\r
451 bool tmccIsValid = false;
\r
453 status = _device->SetFrequency((tuner / 2), EARTH::PT::Device::ISDB_T, channel, 0);
\r
454 if (status != EARTH::PT::STATUS_OK)
\r
456 DebugLog3("error: Device::SetFrequency() (0x%08x)\n", status);
\r
460 for (int i = 0; i < 2; ++i)
\r
462 status = _device->GetTmccT((tuner / 2), &tmcc);
\r
463 if (status == EARTH::PT::STATUS_OK)
\r
465 tmccIsValid = true;
\r
470 DebugLog3("error: Device::GetTmccT() (0x%08x)\n", status);
\r
474 result = tmccIsValid;
\r
478 _locked[tuner] = result;
\r
481 LeaveCriticalSection(&_cs);
\r
486 void PT1Core::transfer()
\r
488 DebugLog2("PT1Core::transfer() called.\n");
\r
492 EARTH::status status;
\r
494 EARTH::PT::Device::BufferInfo bufferInfo;
\r
495 status = _device->GetBufferInfo(&bufferInfo);
\r
496 if (status != EARTH::PT::STATUS_OK)
\r
498 DebugLog3("error: Device::GetBufferInfo() (0x%08x)\n", status);
\r
502 if (bufferInfo.VirtualSize == 0)
\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
510 DebugLog3("error: Device::SetBufferInfo() (0x%08x)\n", status);
\r
515 EnterCriticalSection(&_cs);
\r
516 _transfer = ST_RUN;
\r
517 LeaveCriticalSection(&_cs);
\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
525 for (int j = 0; j < VIRTUAL_SIZE; ++j)
\r
527 for (int k = 0; k < BLOCK_COUNT; ++k)
\r
529 clearBlock(i, j, k);
\r
534 // reset transfer counter
\r
535 status = _device->ResetTransferCounter();
\r
536 if (status != EARTH::PT::STATUS_OK)
\r
538 DebugLog3("error: Device::ResetTransferCounter() (0x%08x)\n", status);
\r
542 // increment transfer counter
\r
544 for (int i = 0; i < VIRTUAL_SIZE * VIRTUAL_COUNT; ++i)
\r
546 status = _device->IncrementTransferCounter();
\r
547 if (status != EARTH::PT::STATUS_OK)
\r
549 DebugLog3("error: Device::IncrementTransferCounter() (0x%08x)\n", status);
\r
559 // enable DMA transfer
\r
560 status = _device->SetTransferEnable(true);
\r
561 if (status != EARTH::PT::STATUS_OK)
\r
563 DebugLog3("error: Device::SetTransferEnable(true) (0x%08x)\n", status);
\r
571 DebugLog2("transfer start.\n");
\r
581 if (!dispatchBlock())
\r
586 DebugLog2("transfer stop.\n");
\r
588 status = _device->SetTransferEnable(false);
\r
589 if (status != EARTH::PT::STATUS_OK)
\r
591 DebugLog3("error: Device::SetTransferEnable(false) (0x%08x)\n", status);
\r
595 EnterCriticalSection(&_cs);
\r
596 done = (_transfer != ST_RUN);
\r
597 LeaveCriticalSection(&_cs);
\r
602 EnterCriticalSection(&_cs);
\r
603 _transfer = ST_IDLE;
\r
604 LeaveCriticalSection(&_cs);
\r
606 DebugLog2("PT1Core::transfer() end.\n");
\r
609 uint32_t PT1Core::offset(uint32_t imageIndex, uint32_t blockIndex, uint32_t additionalOffset)
\r
611 blockIndex += BLOCK_COUNT * imageIndex;
\r
612 uint32_t offset = (BLOCK_SIZE * blockIndex + additionalOffset) / sizeof(uint32_t);
\r
616 uint32_t PT1Core::offset(uint32_t imageIndex, uint32_t blockIndex)
\r
618 return offset(imageIndex, blockIndex, (BLOCK_SIZE - sizeof(uint32_t)));
\r
621 uint32_t PT1Core::read(uint32_t virtualIndex, uint32_t imageIndex, uint32_t blockIndex)
\r
624 if (_device->GetBufferPtr(virtualIndex, &voidPtr) != EARTH::PT::STATUS_OK)
\r
626 DebugLog3("error: Device::GetBufferPtr() :read\n");
\r
630 volatile const uint32_t *ptr = (volatile const uint32_t *)voidPtr;
\r
633 return ptr[offset(imageIndex, blockIndex)];
\r
637 DebugLog3("ptr is NULL (read)\n");
\r
642 void PT1Core::clearBlock(uint32_t virtualIndex, uint32_t imageIndex, uint32_t blockIndex)
\r
644 void *voidPtr = NULL;
\r
645 if (_device->GetBufferPtr(virtualIndex, &voidPtr) != EARTH::PT::STATUS_OK)
\r
647 DebugLog3("error: Device::GetBufferPtr() :clearBlock\n");
\r
651 uint32_t *ptr = (uint32_t *)voidPtr;
\r
654 ptr[offset(imageIndex, blockIndex)] = 0;
\r
658 DebugLog3("ptr is NULL (clearBlock)");
\r
662 bool PT1Core::waitBlock()
\r
664 bool result = true;
\r
668 EARTH::OS::Thread::Sleep((10)*1000*1000); // 10 ms
\r
673 if (read(_virtualIndex, _imageIndex, _blockIndex) != 0)
\r
678 EnterCriticalSection(&_cs);
\r
679 result = (_transfer == ST_RUN);
\r
680 LeaveCriticalSection(&_cs);
\r
685 void PT1Core::copyBlock()
\r
688 if (_device->GetBufferPtr(_virtualIndex, &voidPtr) != EARTH::PT::STATUS_OK)
\r
690 DebugLog3("error: Device::GetBufferPtr(): copyBlock\n");
\r
694 uint32_t *srcPtr = (uint32_t *)voidPtr;
\r
696 srcPtr += offset(_imageIndex, _blockIndex, 0);
\r
698 memcpy(_buffer, srcPtr, BLOCK_SIZE);
\r
701 srcPtr[BLOCK_SIZE / sizeof(*srcPtr) - 1] = 0;
\r
703 if (BLOCK_COUNT <= ++_blockIndex)
\r
708 if (_device->IncrementTransferCounter() != EARTH::PT::STATUS_OK)
\r
710 DebugLog3("error: Device::IncrementTransferCounter()\n");
\r
714 if (VIRTUAL_SIZE <= ++_imageIndex)
\r
717 if (VIRTUAL_COUNT <= ++_virtualIndex)
\r
725 bool PT1Core::dispatchBlock()
\r
727 const uint32_t *ptr = (uint32_t *)_buffer;
\r
730 for (i = 0; i < BLOCK_SIZE / sizeof(*ptr); ++i)
\r
732 uint32_t packet = ptr[i];
\r
734 uint32_t packetId = BIT_SHIFT_MASK(packet, 29, 3);
\r
735 uint32_t packetError = BIT_SHIFT_MASK(packet, 24, 1);
\r
740 EARTH::PT::Device::TransferInfo info;
\r
741 if (_device->GetTransferInfo(&info) != EARTH::PT::STATUS_OK)
\r
743 DebugLog3("error: Device::GetTransferInfo()\n");
\r
747 if (info.TransferCounter1)
\r
749 DebugLog3("Transfer counter is now less than 1\n");
\r
751 else if (info.BufferOverflow)
\r
753 DebugLog3("Buffer Overflow\n");
\r
757 DebugLog3("Transfer error\n");
\r
762 if ((1 <= packetId) && (packetId <= 4))
\r
764 if (_locked[packetId - 1] && (_tuners[packetId - 1] != NULL))
\r
766 _tuners[packetId - 1]->addPacket(packet);
\r