Esempio n. 1
0
//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtuEventsGetCancel -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
//
// This functions cancels the DtuEventGetWait function if that function was waiting
// for an event to happen
//
DtStatus  DtuEventsGetCancel(DtuDeviceData* pDvcData, DtFileObject* pFile)
{
    DtuEvents*  pDtuEvents;

    if (pFile == NULL)
        return DT_STATUS_INVALID_PARAMETER;

    DtDbgOut(MAX, EVENTS, "Start");

    // We force the Pending event to be signaled.
    pDtuEvents = DtuEventsGetEventsObject(pDvcData, pFile);
    if (pDtuEvents == NULL)
    {
        DtDbgOut(MAX, EVENTS, "Exit");
        return DT_STATUS_NOT_FOUND;
    }

    pDtuEvents->m_CancelInProgress = TRUE;

#ifdef WINBUILD
    // Dequeue pending events
    DtuEventsDequeue(pDvcData, pFile);
#endif

    // Trigger event
    DtEventSet(&pDtuEvents->m_PendingEvent);

    // Decrement refcount
    DtuEventsUnrefEventsObject(pDvcData, pDtuEvents);

    DtDbgOut(MAX, EVENTS, "Exit");

    return DT_STATUS_OK;
}
Esempio n. 2
0
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtaPPBufferReadDataFinished -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
//
void  DtaPPBufferReadDataFinished(PPBuffer* pPPBuffer)
{
    DtDbgOut(MAX, PP, "Start");
    DT_ASSERT(pPPBuffer->m_pDmaChannel->m_DmaDirection == DT_DMA_DIRECTION_FROM_DEVICE);
    DtaPPBufferRWFinished(pPPBuffer);
    DtDbgOut(MAX, PP, "Exit");
}
Esempio n. 3
0
//-.-.-.-.-.-.-.-.-.-.-.-.-.- DtaPPBufferTransferDataStartDma -.-.-.-.-.-.-.-.-.-.-.-.-.-.
//
static DtStatus  DtaPPBufferTransferDataStartDma(PPBuffer* pPPBuffer, 
                                                                    UInt BufferToTransfer)
{
    DtStatus  Status = DT_STATUS_OK;
    UInt  TransferSize;
    UInt  BufStart;
    UInt  BufStop;
    UInt  TransferSizeNew;
    UInt8*  pLocalAddress;

    DtDbgOut(MAX, PP, "Start");

    if (pPPBuffer->m_pDmaChannel->m_DmaDirection == DT_DMA_DIRECTION_TO_DEVICE)
        TransferSize = pPPBuffer->m_BufTransferSize[BufferToTransfer];
    else
        TransferSize = pPPBuffer->m_BufSize[BufferToTransfer];

    // Transfer buffer
    pPPBuffer->m_pGetLocAddrFunc(pPPBuffer->m_pGetLocAddrContext, 
                                   &pLocalAddress, &BufStart, &BufStop, &TransferSizeNew);
    if (TransferSizeNew != 0)
        TransferSize = TransferSizeNew;

    Status = DtaDmaStartKernelBufTransfer(pPPBuffer->m_pDmaChannel, 
                                                 pPPBuffer->m_pBufStart,TransferSize,
                                                 pPPBuffer->m_BufOffset[BufferToTransfer],
                                                 pLocalAddress, BufStart, BufStop);
    DtDbgOut(MAX, PP, "Exit");
    return Status;
}
Esempio n. 4
0
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtuDvcReset -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
//
// Handler for reset device command
//
DtStatus  DtuDvcReset(DtuDeviceData* pDvcData)
{
    DtStatus  Status = DT_STATUS_OK;
    Int  Dummy;
    Int  i=0;

    if (pDvcData->m_DevInfo.m_TypeNumber>=300 && pDvcData->m_DevInfo.m_TypeNumber<400)
    {
        DtDbgOut(ERR, DTU, "Attempt to reset USB3 device with USB2 command");
        return DT_STATUS_NOT_SUPPORTED;
    }

    // Reset temporariy for all channels
    for (i=0; i<pDvcData->m_NumNonIpPorts; i++)
    {
        DtuNonIpPort*  pNonIpPort = &(pDvcData->m_pNonIpPorts[i]);

        // Clear temporariy buffer
        pNonIpPort->m_TempBufWrIndex = 0;
        pNonIpPort->m_TempBufRdIndex = 0;
    }

    // Simply send the vendor command to the device
    Status = DtUsbVendorRequest(&pDvcData->m_Device, NULL, DTU_USB_RESET_DEVICE, 
                                                     0, 0, DT_USB_HOST_TO_DEVICE, NULL, 0,
                                                     &Dummy, MAX_USB_REQ_TIMEOUT);

    DtDbgOut(AVG, DTU, "DTU-%d reset", pDvcData->m_DevInfo.m_TypeNumber);

    return Status;
}
Esempio n. 5
0
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtaEventsSet -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
//
// This function adds new events to the pending events.
//
DtStatus  DtaEventsSet(
    DtaDeviceData*  pDvcData,
    DtFileObject*  pFile,
    UInt  EventType,
    UInt  Value1,
    UInt  Value2)
{
    DtStatus  Result = DT_STATUS_OK;
    DtaEvents*  pDtaEvents = NULL;
    
    DtDbgOut(MAX, EVENTS, "Start");
    DtDbgOut(AVG, EVENTS, "EventType: %i, Value1: %i, Value2: %i", EventType, Value1, 
                                                                                  Value2);
    if (pFile != NULL)
    {
        // Get corresponding events object
        pDtaEvents = DtaEventsGetEventsObject(pDvcData, pFile);
        if (pDtaEvents == NULL)
            Result = DT_STATUS_NOT_FOUND;
        else {
            Result = DtaEventsSetEvent(pDtaEvents, EventType, Value1, Value2);
#ifdef WINBUILD
            if (pDtaEvents->m_NumPendingEvents != 0)
            {
                // Dequeue pending events
                pFile = &pDtaEvents->m_File;
                DtaEventsDequeue(pDvcData, pFile, pDtaEvents);
            }
#endif
            DtaEventsUnrefEventsObject(pDvcData, pDtaEvents);
        }
    } else {
        // Set event for all file handles
        DtSpinLockAcquire(&pDvcData->m_EventsSpinlock);

        pDtaEvents = pDvcData->m_pEvents;
        while (pDtaEvents != NULL)
        {
            // Set event
            Result = DtaEventsSetEvent(pDtaEvents, EventType, Value1, Value2);
#ifdef WINBUILD
            if (pDtaEvents->m_NumPendingEvents != 0)
            {
                // Dequeue pending events
                pFile = &pDtaEvents->m_File;
                DtaEventsDequeue(pDvcData, pFile, pDtaEvents);
            }
#endif
            pDtaEvents = pDtaEvents->m_pNext;
        }
        DtSpinLockRelease(&pDvcData->m_EventsSpinlock);
    }
    
    DtDbgOut(MAX, EVENTS, "Exit");

    return Result;
}
Esempio n. 6
0
//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtuEventsSetEvent -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
//
static DtStatus  DtuEventsSetEvent(
    DtuEvents*  pDtuEvents,
    UInt  EventType,
    UInt  Value1,
    UInt  Value2)
{
    DtuEvent*  pDtuEvent;

    // Skip unregistered events
    if ((EventType & pDtuEvents->m_EventTypeMask) != 0)
    {
        DtSpinLockAcquire(&pDtuEvents->m_Lock);

        if (EventType == DTU_EVENT_TYPE_IOCONFIG)
        {
            UInt i;
            for (i=0; i<pDtuEvents->m_NumPendingEvents; i++)
            {
                if (pDtuEvents->m_PendingEvents[i].m_EventType==DTU_EVENT_TYPE_IOCONFIG
                                  && pDtuEvents->m_PendingEvents[i].m_EventValue1==Value1)
                {
                    // Event is already pending, don't create a duplicate
                    DtSpinLockRelease(&pDtuEvents->m_Lock);
                    return DT_STATUS_OK;
                }
            }
        }

        // Add new events
        if (pDtuEvents->m_NumPendingEvents == MAX_PENDING_EVENTS)
        {
            // Remove oldest event
            DtDbgOut(AVG, EVENTS, "Max. number of events. Remove old event");
            DtMemMove(&pDtuEvents->m_PendingEvents[0],
                                         &pDtuEvents->m_PendingEvents[1],
                                         sizeof(DtuEvent) * (MAX_PENDING_EVENTS - 1));
            pDtuEvent = &pDtuEvents->m_PendingEvents[MAX_PENDING_EVENTS - 1];
        } else {
            pDtuEvent = &pDtuEvents->m_PendingEvents[pDtuEvents->m_NumPendingEvents];
            pDtuEvents->m_NumPendingEvents++;
        }

        DtDbgOut(MAX, EVENTS, "New event #%d. Type: %d, Value1: %d, Value2: %d", 
                           pDtuEvents->m_NumPendingEvents, EventType, Value1, Value2);
        
        pDtuEvent->m_EventType = EventType;
        pDtuEvent->m_EventValue1 = Value1;
        pDtuEvent->m_EventValue2 = Value2;

        // Trigger wait function if it was waiting
        DtEventSet(&pDtuEvents->m_PendingEvent);
        DtSpinLockRelease(&pDtuEvents->m_Lock);
    }
    return DT_STATUS_OK;
}
Esempio n. 7
0
//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- EzUsbLoadFirmware -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
//
DtStatus  EzUsbLoadFirmware(
    DtuDeviceData*  pDvcData,
    const DtuIntelHexRecord*  pMicroCode)
{
    DtStatus  Status;
    Int  Dummy = 0;
    DtuIntelHexRecord*  pPtr = NULL;

    if (pMicroCode == NULL)
        return DT_STATUS_INVALID_PARAMETER;

    //.-.-.-.-.-.-.-.-.-.-.-.- Download firmware to internal RAM -.-.-.-.-.-.-.-.-.-.-.-.-
    //
    // Before starting the upload, stop the 8051

    Status = EzUsbResetProcessor(pDvcData, TRUE);
    if (!DT_SUCCESS(Status))
    {
        DtDbgOut(ERR, DTU, "Failed to stop the processor (Status=0x%08X)", Status);
        return Status;
    }

    pPtr = (DtuIntelHexRecord*)pMicroCode;
    while (pPtr->Type == 0)
    {
        // Send load command
        Status = DtUsbVendorRequest(&pDvcData->m_Device, NULL, EZUSB_FX2_LOAD_INTERNAL, 
                                   pPtr->Address, 0, DT_USB_HOST_TO_DEVICE, 
                                   pPtr->Data, pPtr->Length, &Dummy, MAX_USB_REQ_TIMEOUT);
        if (!DT_SUCCESS(Status))
        {
            DtDbgOut(ERR, DTU, "Failed to send load command (Status=0x%08X)", Status);
            return Status;
        }
        pPtr++;
    }
    // Restart the 8051
    if (Status == DT_STATUS_OK)
    {
        Status = EzUsbResetProcessor(pDvcData, FALSE);
        if (!DT_SUCCESS(Status))
        {
            DtDbgOut(ERR, DTU, "Failed to start the processor (Status=0x%08X)", Status);
            return Status;
        }
    }
  
    return DT_STATUS_OK;
}
Esempio n. 8
0
//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtaGs296xWriteRegister -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
//
DtStatus  DtaM235x4WriteRegister(DtaNonIpPort* pNonIpPort, Int Addr, UInt32 Value)
{
    UInt  Timeout=100, SpiCmd=0;

    // Port must has a matrix-API register interface
    if (!pNonIpPort->m_CapMatrix)
        return DT_STATUS_NOT_SUPPORTED;

    // Step 1: write write-command to card
    SpiCmd = (Value << DT_HD_SPICTRL_DATA_SH) & DT_HD_SPICTRL_DATA_MSK;
    SpiCmd |= (Addr << DT_HD_SPICTRL_ADDR_SH) & DT_HD_SPICTRL_ADDR_MSK;
    SpiCmd |= (0<<DT_HD_SPICTRL_AUTOINC_SH) & DT_HD_SPICTRL_AUTOINC_MSK;
    SpiCmd |= (0<<DT_HD_SPICTRL_READ_SH) & DT_HD_SPICTRL_READ_MSK;
    SpiCmd |= (1<<DT_HD_SPICTRL_START_SH) & DT_HD_SPICTRL_START_MSK;

    DtDbgOut(MAX, DTA, "Addr=0x%04X, Value=0x%04X, SpiCmd=0x%08X", Addr, Value, SpiCmd);
    
    WRITE_UINT(SpiCmd, pNonIpPort->m_pRxRegs, DT_HD_REG_SPICTRL);

    // Step 2: wait for done bit
    SpiCmd = READ_UINT(pNonIpPort->m_pRxRegs, DT_HD_REG_SPICTRL);
    while ((SpiCmd & DT_HD_SPICTRL_DONE_MSK) == 0)
    {
        DtSleep(1);
        SpiCmd = READ_UINT(pNonIpPort->m_pRxRegs, DT_HD_REG_SPICTRL);
        Timeout--;
        if (Timeout <= 0)
            return DT_STATUS_TIMEOUT;
    }
    return DT_STATUS_OK;
}
Esempio n. 9
0
//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtaGenlockGetRefState -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
//
// Return lock status
//
DtStatus  DtaGenlockGetRefState(DtaDeviceData* pDvcData, 
  Int  PortIndex, 
  Int  *pEnabled,
  Int  *pInLock)
{ 
    DtStatus  Status = DT_STATUS_OK;

#ifdef _DEBUG
    Int  GenRefPortIndex = pDvcData->m_Genlock.m_RefPortIndex;
#endif
    Bool  InLock = FALSE;
    Bool  Enabled = FALSE;
    if(pDvcData->m_Genlock.m_GenlArch == GENLOCK_ARCH_2144 ||
                                   pDvcData->m_Genlock.m_GenlArch == GENLOCK_ARCH_145)
    {
        Status = DtaFpgaGenlockGetRefState(pDvcData, PortIndex, &Enabled, &InLock);
        *pEnabled = Enabled == TRUE ? 1 : 0;
        *pInLock = InLock == TRUE ? 1 : 0;
        return Status;
    }

    // TODO: Should we also implement this for HDSDI?
    //if(pDvcData->m_Genlock.m_GenlArch != GENLOCK_ARCH_2152)
    //  return DtaLmh1982GenlockGetRefState(pDvcData, pInLock);

    DtDbgOut(ERR, GENL, "[%d] GENREF NOT SUPPORTED", GenRefPortIndex);
    return DT_STATUS_NOT_SUPPORTED;
}
Esempio n. 10
0
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtPropertiesInit -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
//
DtStatus  DtPropertiesInit(DtPropertyData* pPropData)
{
    Int  Index;

    // Default no property store found for our device
    pPropData->m_pPropertyStore = NULL;

    // Find the property store for our device
    for (Index=0; Index<DtPropertyStoreCount; Index++)
    {
        if (DtPropertyStores[Index].m_TypeNumber==pPropData->m_TypeNumber &&
                                  DtPropertyStores[Index].m_SubDvc == pPropData->m_SubDvc)
        {
            pPropData->m_pPropertyStore = (void*)&DtPropertyStores[Index];
            break;
        }
    }

    // Check if we found a property store for our device
    if (pPropData->m_pPropertyStore == NULL)
    {
          DtDbgOut(ERR, PROP, "PropertyStore not found DTA %d, SubDvc %d", pPropData->m_TypeNumber, 
                                                                    pPropData->m_SubDvc);
          return DT_STATUS_NOT_FOUND;
    }

    pPropData->m_PropertyNotFoundCounter = 0;
    return DtStringAlloc(&pPropData->m_PropertyNotFoundString, 50);
}
Esempio n. 11
0
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtTablesInit -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
//
DtStatus  DtTablesInit(DtPropertyData* pPropData)
{
    Int  Index;

    // Default no table store found for our device
    pPropData->m_pTableStore = NULL;

    // Find the table store for our device
    for (Index=0; Index<DtTableStoreCount; Index++)
    {
        if (DtTableStores[Index].m_TypeNumber==pPropData->m_TypeNumber && 
                                       DtTableStores[Index].m_SubDvc==pPropData->m_SubDvc)
        {
            pPropData->m_pTableStore = (void*)&DtTableStores[Index];
            break;
        }
    }

    // It's not a fault if no table store is found. Not all cards have tables
    if (pPropData->m_pTableStore == NULL)
        DtDbgOut(MIN, TABLE, "Tablestore not found for %s-%d:%d", pPropData->m_TypeName,
                                                                  pPropData->m_TypeNumber,
                                                                     pPropData->m_SubDvc);
    return DT_STATUS_OK;
}
Esempio n. 12
0
//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DriverParametersKeyDelete -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
//
NTSTATUS  DriverParametersKeyDelete(
    WDFDRIVER  Driver,
    DtString*  pKeyName)
{
    NTSTATUS  NtStatus;
    WDFKEY  ParametersKey;
    WDFKEY  Key = NULL;
    
    DT_ASSERT(KeGetCurrentIrql()<=PASSIVE_LEVEL);

    // Open the drivers parameters key (under services)
    NtStatus = WdfDriverOpenParametersRegistryKey(Driver, KEY_WRITE,
                                                WDF_NO_OBJECT_ATTRIBUTES, &ParametersKey);
    if (!NT_SUCCESS(NtStatus))
    {
        DtDbgOut(ERR, SAL, "WdfDriverOpenParametersRegistryKey failed. Error: 0x%x", 
                                                                                NtStatus);
        return NtStatus;
    }

    // Open subkey
    NtStatus = WdfRegistryOpenKey(ParametersKey, pKeyName, KEY_WRITE, 
                                                          WDF_NO_OBJECT_ATTRIBUTES, &Key);
    if (!NT_SUCCESS(NtStatus))
    {
        if (NtStatus == STATUS_OBJECT_NAME_NOT_FOUND)
            DtDbgOut(MAX, SAL, "WdfRegistryOpenKey error:'STATUS_OBJECT_NAME_NOT_FOUND'");
        else
            DtDbgOut(ERR, SAL, "WdfRegistryOpenKey failed. Error: 0x%x", NtStatus);
    }

    if (NT_SUCCESS(NtStatus))
    {
        // Delete the key
        NtStatus = WdfRegistryRemoveKey(Key);
        if (!NT_SUCCESS(NtStatus))
            DtDbgOut(ERR, SAL, "WdfRegistryRemoveKey failed. Error: 0x%x", NtStatus);
        else 
            Key = NULL;
    }
    if (Key != NULL)
        WdfRegistryClose(Key);
    WdfRegistryClose(ParametersKey);
    return NtStatus;
}
Esempio n. 13
0
//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- EzUsbLoadFirmware -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
//
DtStatus  EzUsbLoadFirmwareFx3(
    DtuDeviceData*  pDvcData,
    const DtuFx3HexRecord*  pMicroCode)
{
    DtStatus  Status;
    Int  Dummy = 0;
    const DtuFx3HexRecord*  pPtr = pMicroCode;
    Bool  Cont = TRUE;

    if (pMicroCode == NULL)
        return DT_STATUS_INVALID_PARAMETER;

    DtDbgOut(MAX, DTU, "Loading firmware");
    
    while (Cont)
    {
        UInt32  Len = pPtr->Length;
        UInt32  Addr = pPtr->Address;
        UInt8*  Data = (UInt8*)(pPtr->Data);
        UInt32  NumToWrite;
        Cont = (pPtr->Length != 0);
        do
        {
            NumToWrite = Len < FX3_MAX_CHUNK_SIZE ? Len : FX3_MAX_CHUNK_SIZE;
            
            // Send load command
            Status = DtUsbVendorRequest(&pDvcData->m_Device, NULL, EZUSB_FX2_LOAD_INTERNAL, 
                                       Addr&0xFFFF, Addr>>16, DT_USB_HOST_TO_DEVICE, 
                                       Data, NumToWrite, &Dummy, MAX_USB_REQ_TIMEOUT);
            if (!DT_SUCCESS(Status))
            {
                DtDbgOut(ERR, DTU, "Failed to send load command (Status=0x%08X)", Status);
                return Status;
            }
            Len -= NumToWrite;
            Addr += NumToWrite;
            Data += NumToWrite;
        } while (Len > 0);
        pPtr++;
    }
  
    return DT_STATUS_OK;
}
Esempio n. 14
0
//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtaEventsSetEvent -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
//
static DtStatus  DtaEventsSetEvent(
    DtaEvents*  pDtaEvents,
    UInt  EventType,
    UInt  Value1,
    UInt  Value2)
{
    DtStatus  Result = DT_STATUS_OK;
    DtaEvent*  pDtaEvent;

    // Skip unregistered events
    if ((EventType & pDtaEvents->m_EventTypeMask) != 0)
    {
        DtSpinLockAcquire(&pDtaEvents->m_Lock);

        // Add new events
        if (pDtaEvents->m_NumPendingEvents == MAX_PENDING_EVENTS)
        {
            // Remove oldest event
            DtDbgOut(AVG, EVENTS, "Max. number of events. Remove old event");
            DtMemMove(&pDtaEvents->m_PendingEvents[0],
                                         &pDtaEvents->m_PendingEvents[1],
                                         sizeof(DtaEvent) * (MAX_PENDING_EVENTS - 1));
            pDtaEvent = &pDtaEvents->m_PendingEvents[MAX_PENDING_EVENTS - 1];
        } else {
            pDtaEvent = &pDtaEvents->m_PendingEvents[pDtaEvents->m_NumPendingEvents];
            pDtaEvents->m_NumPendingEvents++;
        }

        DtDbgOut(MAX, EVENTS, "New event #%d. Type: %d, Value1: %d, Value2: %d", 
                           pDtaEvents->m_NumPendingEvents, EventType, Value1, Value2);
        
        pDtaEvent->m_EventType = EventType;
        pDtaEvent->m_EventValue1 = Value1;
        pDtaEvent->m_EventValue2 = Value2;

        // Trigger wait function if it was waiting
        DtEventSet(&pDtaEvents->m_PendingEvent);
        DtSpinLockRelease(&pDtaEvents->m_Lock);
    }
    return Result;
}
Esempio n. 15
0
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtuDemodInit -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
//
DtStatus  DtuDemodInit(DtuDeviceData* pDvcData)
{
    DtStatus  Status = DT_STATUS_OK;
    const DtuDemodFirmwareStore*  pDemodFirmware = NULL;
    
    pDemodFirmware = DtuGetDemodFirmware(pDvcData->m_DevInfo.m_ProductId,
                                                  pDvcData->m_DevInfo.m_HardwareRevision);
    if (pDemodFirmware == NULL)
        return DT_STATUS_OK;
    
    Status =  DtuLoadDemodFirmware(pDvcData, pDemodFirmware);
    if (!DT_SUCCESS(Status))
    {
        DtDbgOut(ERR, DTU, "Failed to upload demodulator firmware (Status=0x%08X)", 
                                                                                  Status);
        return Status;
    }
    DtDbgOut(AVG, DTU, "Demodulator firmware uploaded successfully");
                                                                                  
    return Status;
}
Esempio n. 16
0
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtuEventsNumPending -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
//
Int  DtuEventsNumPending(DtuDeviceData* pDvcData, DtFileObject* pFile)
{
    DtuEvents*  pDtuEvents;
    Int  NumPending = 0;

    DtDbgOut(MAX, EVENTS, "Start");

    // We force the Pending event to be signaled.
    pDtuEvents = DtuEventsGetEventsObject(pDvcData, pFile);
    if (pDtuEvents != NULL)
    {
        NumPending = pDtuEvents->m_NumPendingEvents;
        
        // Decrement refcount
        DtuEventsUnrefEventsObject(pDvcData, pDtuEvents);
    }

    DtDbgOut(MAX, EVENTS, "Exit (%d pending events)", NumPending);

    return NumPending;
}
Esempio n. 17
0
//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtuDvcPowerSupplyInit -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
//
// Initializes the Altera power supply
// 
DtStatus  DtuDvcPowerSupplyInit(DtuDeviceData* pDvcData)
{
    DtStatus  Status = DT_STATUS_OK;
    UInt8  I2cBuf[8];
    Int  TypeNumber = pDvcData->m_DevInfo.m_TypeNumber;

    if (TypeNumber==215)
    {
        // Start 1V2 power supply (ALTERA core voltage)
        // NOTE: we only start the 1V2 power supply here. Other power supplies are started
        // later when we init the device hardware.
        I2cBuf[0] = DTU215_IIC_ADDR_PWR_1V2;
        I2cBuf[1] = DTU215_IIC_PWR_1V2_CTRL;
        Status = DtuI2cWrite(pDvcData, NULL, DTU215_IIC_ADDR_PWR_SUPPLY, 2, I2cBuf);
        // Sleep shortly to allow power-supply to settle
        DtSleep(200);
        if (DT_SUCCESS(Status))
            DtDbgOut(AVG, DTU, "DTU-%d power supply started", TypeNumber);
        else
            DtDbgOut(ERR, DTU, "DTU-%d power supply start ERROR. Error: %xh", TypeNumber, 
                                                                                  Status);
    }
    else if ((TypeNumber==350 || TypeNumber==351) && pDvcData->m_DevInfo.m_UsbSpeed==2)
    {
        Status = DtUsbVendorRequest(&pDvcData->m_Device, NULL, DTU_USB3_PNP_CMD,
                           DTU_PNP_CMD_DVC_POWER, DTU_DVC_POWER_ON, DT_USB_HOST_TO_DEVICE,
                           NULL, 0, NULL, MAX_USB_REQ_TIMEOUT);
        if (DT_SUCCESS(Status))
            DtSleep(100);
    }
    else if (TypeNumber==315 && pDvcData->m_DevInfo.m_UsbSpeed==2)
    {
        // DTU-315 specific: Enable LED (fade PWM mode)
        Dtu3RegWrite(pDvcData, DTU3_FX3_BLOCK_OFFSET, &FwbFx3.LedCtrl, 1);
    }
    
    return Status;
}
Esempio n. 18
0
//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtaEventsRegister -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
//
DtStatus DtaEventsRegister(
    DtaDeviceData*  pDvcData,
    DtFileObject*  pFile,
    UInt  EventTypeMask)
{
    DtaEvents*  pDtaEvents;

    if (pFile == NULL)
        return DT_STATUS_INVALID_PARAMETER;
        
    DtDbgOut(MAX, EVENTS, "Register event mask 0x%x", EventTypeMask);

    pDtaEvents = DtaEventsAllocEventsObject(pDvcData, pFile, EventTypeMask);
    if (pDtaEvents == NULL)
        return DT_STATUS_OUT_OF_RESOURCES;

    return DT_STATUS_OK;
}
Esempio n. 19
0
//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtaPPBufferRWFinished -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
//
static void  DtaPPBufferRWFinished(PPBuffer* pPPBuffer)
{
    UInt  OldState = pPPBuffer->m_BufState;
    UInt  AddState;

    if (pPPBuffer->m_CurRwBufferId == DTA_PPBUF_PING_ID)
        AddState = DTA_PPBUF_STAT_PING;
    else 
        AddState = DTA_PPBUF_STAT_PONG;
    
    DT_ASSERT((OldState & AddState) == 0);
    while (OldState != DtAtomicCompareExchange(&pPPBuffer->m_BufState, OldState, 
                                                                      OldState | AddState))
    {
        OldState = pPPBuffer->m_BufState;
        DT_ASSERT((OldState & AddState) == 0);
    }
    DtDbgOut(MAX, PP, "OldState: %xh NewState: %xh", OldState, OldState | AddState);

    DtaPPBufferSwap(&pPPBuffer->m_CurRwBufferId);
}
Esempio n. 20
0
//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtaEventsAllocEventsObject -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
//
static DtaEvents*  DtaEventsAllocEventsObject(
    DtaDeviceData*  pDvcData,
    DtFileObject*  pFileHandle,
    UInt  EventTypeMask)
{
    DtaEvents*  pDtaEvents;

    pDtaEvents = (DtaEvents*)DtMemAllocPool(DtPoolNonPaged, sizeof(DtaEvents), DTA_TAG);
    if (pDtaEvents == NULL)
    {
        DtDbgOut(ERR, EVENTS, "Out of memory allocating DtaEvents struct");
        return NULL;
    }

    DtAtomicSet(&pDtaEvents->m_RefCount, 1);
    pDtaEvents->m_File = *pFileHandle;
    pDtaEvents->m_EventTypeMask = EventTypeMask;
    pDtaEvents->m_CancelInProgress = FALSE;
    pDtaEvents->m_NumPendingEvents = 0;
    DtEventInit(&pDtaEvents->m_PendingEvent, FALSE);
    DtSpinLockInit(&pDtaEvents->m_Lock);
    memset(&pDtaEvents->m_PendingEvents, 0, sizeof(pDtaEvents->m_PendingEvents));

    // Insert at start of list
    DtSpinLockAcquire(&pDvcData->m_EventsSpinlock);
    pDtaEvents->m_pPrev = NULL;
    pDtaEvents->m_pNext = NULL;
    if (pDvcData->m_pEvents != NULL)
    {
        pDtaEvents->m_pNext = pDvcData->m_pEvents;
        pDtaEvents->m_pNext->m_pPrev = pDtaEvents;
    }
    pDvcData->m_pEvents = pDtaEvents;
    DtSpinLockRelease(&pDvcData->m_EventsSpinlock);

    return pDtaEvents;
}
Esempio n. 21
0
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtuEventsSet -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
//
// This function adds new events to the pending events. If the Events argument is 0, 
// this function does nothing.
//
DtStatus  DtuEventsSet(
    DtuDeviceData*  pDvcData,
    DtFileObject*  pFile,
    UInt  EventType,
    UInt  Value1,
    UInt  Value2)
{
    DtStatus  Result = DT_STATUS_OK;
    Int  i;
    DtuEvents*  pDtuEvents = NULL;
    Bool  InUse;
    
    DtDbgOut(MAX, EVENTS, "Start");
    DtDbgOut(AVG, EVENTS, "EventType: %i, Value1: %i, Value2: %i", EventType, Value1, 
                                                                                  Value2);
    if (pFile != NULL)
    {
        // Get corresponding events object
        pDtuEvents = DtuEventsGetEventsObject(pDvcData, pFile);
        if (pDtuEvents == NULL)
            Result = DT_STATUS_NOT_FOUND;
        else {
            Result = DtuEventsSetEvent(pDtuEvents, EventType, Value1, Value2);
#ifdef WINBUILD
            if (pDtuEvents->m_NumPendingEvents != 0)
            {
                // Dequeue pending events
                DtuEventsDequeue(pDvcData, pFile);
            }
#endif
            DtuEventsUnrefEventsObject(pDvcData, pDtuEvents);
        }
    } else {
        // Set event for all file handles
        for (i=0; i<MAX_NUM_FILE_HANDLES; i++)
        {
            pDtuEvents = &pDvcData->m_Events[i];

            // Increment refcount
            InUse = FALSE;
            DtSpinLockAcquire(&pDtuEvents->m_Lock);
            if (pDtuEvents->m_RefCount > 0)
            {
                pDtuEvents->m_RefCount++;
                InUse = TRUE;
            }
            DtSpinLockRelease(&pDtuEvents->m_Lock);
            
            if (InUse)
            {
                // Set event
                Result = DtuEventsSetEvent(pDtuEvents, EventType, Value1, Value2);
#ifdef WINBUILD
                if (pDtuEvents->m_NumPendingEvents != 0)
                {
                    // Dequeue pending events
                    pFile = &pDtuEvents->m_File;
                    DtuEventsDequeue(pDvcData, pFile);
                }
#endif
                // Decrement refcount
                DtuEventsUnrefEventsObject(pDvcData, pDtuEvents);
            }
        }
    }
    
    DtDbgOut(MAX, EVENTS, "Exit");

    return Result;
}
Esempio n. 22
0
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtPropertiesFind -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
//
DtStatus  DtPropertiesFind(DtPropertyData* pPropData, const char* pName, Int PortIndex,
               const DtProperty** ppProperty, Int DtapiMaj, Int DtapiMin, Int DtapiBugfix)
{
    DtStatus  Status = DT_STATUS_OK;
    const DtPropertyStore*  pStore = (DtPropertyStore*)pPropData->m_pPropertyStore;
    const DtPropertyHashSet*  pHashSets = (DtPropertyHashSet*)pStore->m_pPropertyHashSets;
    UInt  HashSetCount = pStore->m_PropertyHashSetCount;
    Int  FwVersion = pPropData->m_FirmwareVersion;
    Int  HwRevision = pPropData->m_HardwareRevision;
    Int  FwVariant = pPropData->m_FirmwareVariant;


    UInt  Hash = 0;
    Int  Index;
    Int  FindCount = 0;
    Bool  PropertyNameFound = FALSE;
    const DtPropertyHashSet*  pHashSet = NULL;
    Int  PropertyCount = 0;
    *ppProperty = NULL;

    // For devices with no 'EC' VPD resource and no registry key which forces the
    // hardware revision, treat the hardware revision as 0
    if (HwRevision < 0)
        HwRevision = 0;

    // Determine the name hash
    Hash = DtDjb2(pName) % HashSetCount;

    // Get correct hash set (if it exists)
    if (DT_SUCCESS(Status))
    {
        pHashSet = &pHashSets[Hash];
        PropertyCount = pHashSets[Hash].m_PropertyCount;

        // Check if a hash set was available for this hash value
        if (pHashSet == NULL)
            Status = DT_STATUS_NOT_FOUND;
    }

    if (DT_SUCCESS(Status))
    {

        // If the property is not found for a specific fw-variant try a second time
        // without specifying a specific fw-variant
        for (FindCount=0; FindCount<2 && *ppProperty==NULL; FindCount++)
        {
            if (FindCount == 1)
                FwVariant = -1;
            
            // Get correct property entry within hash set
            PropertyNameFound = FALSE;
            
            // Search all properties
            for (Index=0; Index<PropertyCount; Index++)
            {
                const DtProperty*  pProp = &pHashSet->m_pProperties[Index];

                // Check the property name was already found
                if (PropertyNameFound)
                {
                    // When the property name was found earlier, only accept entries 
                    // without a name. We just stop when (another) named entry is found.
                    if (pProp->m_pName != NULL)
                          break;
                } else {
                    // Compare name to check if we found the first occurrence
                    if (DtAnsiCharArrayIsEqual(pName, pProp->m_pName))
                        PropertyNameFound = TRUE;
                }

                if (PropertyNameFound)
                {
                    // Check port number and firmware variant
                    if (PortIndex==pProp->m_PortIndex && FwVariant==pProp->m_FwVariant)
                    {
                        // Check minimal firmware version and hardware version
                        if (FwVersion>=pProp->m_MinFw && HwRevision>=pProp->m_MinHw &&
                                        (pProp->m_MaxHw==-1 || HwRevision<pProp->m_MaxHw))
                        {
                            Bool  DtapiVerOk = FALSE;
                            // -1 means the request came from the driver
                            if (DtapiMaj==-1 && DtapiMin==-1 && DtapiBugfix==-1)
                                DtapiVerOk = TRUE;
                            else if (DtapiMaj > pProp->m_MinDtapiMaj)
                                DtapiVerOk = TRUE;
                            else if (DtapiMaj==pProp->m_MinDtapiMaj)
                            {
                                if (DtapiMin > pProp->m_MinDtapiMin)
                                    DtapiVerOk = TRUE;
                                else if (DtapiMin==pProp->m_MinDtapiMin
                                                  && DtapiBugfix>= pProp->m_MinDtapiBugfix)
                                    DtapiVerOk = TRUE;
                            }
                            // Check minimal DTAPI version
                            if (DtapiVerOk)
                            {
                                *ppProperty = pProp;
                                // We can stop here since the parser has ordered each
                                // property by minimal firmware version/hardware version.
                                // This means the first hit is the best one...
                                break;
                            }
                        }
                    }
                }
            }
        }

        if (!PropertyNameFound)
        {   
            if (DtAnsiCharArrayStartsWith(pName, "CAP_"))
                DtDbgOut(AVG, PROP, "PropertyName(Capability) %s is not found at all for"
                         " %s-%d", pName, pPropData->m_TypeName, pPropData->m_TypeNumber);
            else
                DtDbgOut(MIN, PROP, "PropertyName %s is not found at all for %s-%d",
                                   pName, pPropData->m_TypeName, pPropData->m_TypeNumber);
        }
            
        // Check if the property was found
        if (*ppProperty == NULL)
        {
            Status = DT_STATUS_NOT_FOUND;
            DtDbgOut(AVG, PROP, "Failed to find property %s for %s-%d, FW %d, HW %d"
                     "VAR %d", pName, pPropData->m_TypeName, pPropData->m_TypeNumber,
                             pPropData->m_FirmwareVersion, pPropData->m_HardwareRevision,
                             pPropData->m_FirmwareVariant);
        }
    }

    return Status;
}
Esempio n. 23
0
//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtTableGet -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
//
DtStatus  DtTableGet(
    DtPropertyData*  pPropData,
    const char*  pTableName,
    Int  PortIndex,
    UInt  MaxNumEntries,
    UInt*  pNumEntries,
    DtTableEntry*  pTableEntry2,
    UInt OutBufSize)
{
    DtStatus  Status = DT_STATUS_OK;
    const DtTableStore*  pStore = (DtTableStore*)pPropData->m_pTableStore;
    Int  HwRevision = pPropData->m_HardwareRevision;
    Int  FwVariant = pPropData->m_FirmwareVariant;

    Bool  TableNameFound = FALSE;
    Int  FindCount = 0;
    UInt  Index;
    DtTableLink*  pTableLinkFound = NULL;

    // For devices with no 'EC' VPD resource and no registry key which forces the
    // hardware revision, treat the hardware revision as 0
    if (HwRevision < 0)
        HwRevision = 0;
    
    *pNumEntries = 0;
    if (pPropData->m_pTableStore == NULL)
    {
        DtDbgOut(ERR, TABLE, "There are no tables defined at all for DTX-%d", 
                                                                 pPropData->m_TypeNumber);
        return DT_STATUS_NOT_FOUND;
    }

    // If the property is not found for a specific fw-variant try a second time
    // without specifying a specific fw-variant
    for (FindCount=0; FindCount<2 && pTableLinkFound==NULL; FindCount++)
    {
        if (FindCount == 1)
            FwVariant = -1;

        TableNameFound = FALSE;

        // Search all tables
        for (Index=0; Index<pStore->m_TableLinkCount; Index++)
        {
            const DtTableLink*  pTableLink = &pStore->m_pTableLink[Index];

            // Check if the table name was already found. If so, we stop if
            // name <> NULL.
            if (TableNameFound)
            {
                // When the table name was found earlier, only accept entries without
                // a name. We just stop when (another) named entry is found.
                if (pTableLink->m_pName != NULL)
                    break;
            } else {
                // Compare name to check if we found the first occurrence
                if (DtAnsiCharArrayIsEqual(pTableName, pTableLink->m_pName))
                    TableNameFound = TRUE;
            }

            if (TableNameFound)
            {
                // Check port number and firmware variant
                if (PortIndex==pTableLink->m_PortIndex
                                                    && FwVariant==pTableLink->m_FwVariant)
                {
                    // Check minimal firmware version
                    if (pPropData->m_FirmwareVersion >= pTableLink->m_MinFw)
                    {
                        // Check minimal hardware version
                        if (HwRevision >= pTableLink->m_MinHw)
                        {
                            pTableLinkFound = (DtTableLink*)pTableLink;

                            // We can stop here since the parser has ordened each
                            // property by minimal firmware version/hardware version.
                            // This means the first hit is the best one
                            break;
                        }
                    }
                }
            }
        }
    }

    if (!TableNameFound)
    {   
        DtDbgOut(ERR, TABLE, "Table %s is not found at all for DTX-%d",
                                                        pTableName, pStore->m_TypeNumber);
        Status = DT_STATUS_NOT_FOUND;
    }
        
    // Check if the table was found
    if (pTableLinkFound == NULL)
    {
        Status = DT_STATUS_NOT_FOUND;
        DtDbgOut(ERR, TABLE, "Failed to get table %s for DTX-%d:%d, FW %d, HW %d port %i", 
                                                  pTableName,
                                                  pPropData->m_TypeNumber,
                                                  pPropData->m_SubDvc,
                                                  pPropData->m_FirmwareVersion,
                                                  pPropData->m_HardwareRevision,
                                                  PortIndex);
    }
    
    if (DT_SUCCESS(Status) && pTableLinkFound!=NULL)
    {
        DtDbgOut(MAX, TABLE, "Found table %s for DTX-%d:%d, FW %d, HW %d. #EL:%i #MAX:%i" ,
                                                  pTableName,
                                                  pPropData->m_TypeNumber,
                                                  pPropData->m_SubDvc,
                                                  pPropData->m_FirmwareVersion,
                                                  pPropData->m_HardwareRevision,
                                                  pTableLinkFound->m_TableEntryCount,
                                                  MaxNumEntries);
        *pNumEntries =  pTableLinkFound->m_TableEntryCount;
        
        // Check if enough space for the table
        if (MaxNumEntries < pTableLinkFound->m_TableEntryCount)
        {
            if (MaxNumEntries != 0)
                DtDbgOut(ERR, TABLE, "Max. number of entries to small. Needed:%i, "
                       "Space for:%i", pTableLinkFound->m_TableEntryCount, MaxNumEntries);
        }
        else if (OutBufSize < pTableLinkFound->m_TableEntryCount * sizeof(DtTableEntry)) {
            DtDbgOut(ERR, TABLE, "Buffer smaller than indicated by MaxNumEntries");
            Status = DT_STATUS_INVALID_PARAMETER;
        } else {
            // Copy table
            DtMemCopy(pTableEntry2, (void*)pTableLinkFound->m_pTableEntries, 
                             pTableLinkFound->m_TableEntryCount * sizeof(DtTableEntry));
        }
    } 
    return Status;
}
Esempio n. 24
0
//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtAvGetFrameProps -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
//
// Returns the AV frame properties for the given video standard
//
DtStatus  DtAvGetFrameProps(Int VidStd, DtAvFrameProps*  pProps)
{
    DT_ASSERT(pProps != NULL);

    switch (VidStd)
    {
    case DT_VIDSTD_525I59_94:
        pProps->m_NumLines = 525;
        pProps->m_Fps = 30;
        pProps->m_IsFractional = TRUE;
        pProps->m_IsInterlaced = TRUE;
        pProps->m_IsHd = FALSE;

        pProps->m_Field1Start = 1;
        pProps->m_Field1End = 262;
        pProps->m_Field1ActVidStart = 17;
        pProps->m_Field1ActVidEnd = 260;
        pProps->m_SwitchingLines[0] = 7;

        pProps->m_Field2Start = 263;
        pProps->m_Field2End = 525;
        pProps->m_Field2ActVidStart = 280;
        pProps->m_Field2ActVidEnd = 522;
        pProps->m_SwitchingLines[1] = 270;

        pProps->m_VancNumS = pProps->m_ActVidNumS = 720*2;
        pProps->m_HancNumS = 268;
        pProps->m_SavNumS = 4;
        pProps->m_EavNumS = 4;

        pProps->m_SyncPointPixelOff = 16;   // Sync point @pixel 16
        
        break;

    case DT_VIDSTD_525P59_94:
    case DT_VIDSTD_480P59_94:
        pProps->m_NumLines = 525;
        pProps->m_Fps = 60;
        pProps->m_IsFractional = TRUE;
        pProps->m_IsInterlaced = FALSE;
        pProps->m_IsHd = FALSE;

        pProps->m_Field1Start = 1;
        pProps->m_Field1End = 525;
        pProps->m_Field1ActVidStart = 17;
        pProps->m_Field1ActVidEnd = 496;

        pProps->m_SwitchingLines[0] = 7;
        pProps->m_SwitchingLines[1] = -1;

        pProps->m_Field2Start = 0;
        pProps->m_Field2End = 0;
        pProps->m_Field2ActVidStart = 0;
        pProps->m_Field2ActVidEnd  = 0;

        if (VidStd == DT_VIDSTD_480P59_94)
            pProps->m_VancNumS = pProps->m_ActVidNumS = 640*2;
        else
            pProps->m_VancNumS = pProps->m_ActVidNumS = 720*2;
        pProps->m_HancNumS = 268;
        pProps->m_SavNumS = 4;
        pProps->m_EavNumS = 4;

        pProps->m_SyncPointPixelOff = 0;
        break;

    case DT_VIDSTD_625I50:
        pProps->m_NumLines = 625;
        pProps->m_Fps = 25;
        pProps->m_IsFractional = FALSE;
        pProps->m_IsInterlaced = TRUE;
        pProps->m_IsHd = FALSE;

        pProps->m_Field1Start = 1;    
        pProps->m_Field1End = 312;
        pProps->m_Field1ActVidStart = 23;   
        pProps->m_Field1ActVidEnd = 310;
        pProps->m_SwitchingLines[0] = 6;

        pProps->m_Field2Start = 313;  
        pProps->m_Field2End = 625;
        pProps->m_Field2ActVidStart = 336;  
        pProps->m_Field2ActVidEnd  = 623;
        pProps->m_SwitchingLines[1] = 319;

        pProps->m_VancNumS = pProps->m_ActVidNumS = 720*2;
        pProps->m_HancNumS = 280;
        pProps->m_SavNumS = 4;
        pProps->m_EavNumS = 4;

        pProps->m_SyncPointPixelOff = 12;   // Sync point @pixel 12
        break;

    case DT_VIDSTD_625P50:
        pProps->m_NumLines = 625;
        pProps->m_Fps = 50;
        pProps->m_IsFractional = FALSE;
        pProps->m_IsInterlaced = FALSE;
        pProps->m_IsHd = FALSE;

        pProps->m_Field1Start = 1;
        pProps->m_Field1End = 625;
        pProps->m_Field1ActVidStart = 23;
        pProps->m_Field1ActVidEnd = 598;

        pProps->m_SwitchingLines[0] = 6;
        pProps->m_SwitchingLines[1] = -1;

        pProps->m_Field2Start = 0;
        pProps->m_Field2End = 0;
        pProps->m_Field2ActVidStart = 0;
        pProps->m_Field2ActVidEnd  = 0;

        pProps->m_VancNumS = pProps->m_ActVidNumS = 720*2;
        pProps->m_HancNumS = 280;
        pProps->m_SavNumS = 4;
        pProps->m_EavNumS = 4;

        pProps->m_SyncPointPixelOff = 0;
        break;

    case DT_VIDSTD_2160P60:
    case DT_VIDSTD_2160P60B:
    case DT_VIDSTD_2160P59_94:
    case DT_VIDSTD_2160P59_94B:
    case DT_VIDSTD_2160P50:
    case DT_VIDSTD_2160P50B:
    case DT_VIDSTD_1080P60:
    case DT_VIDSTD_1080P60B:
    case DT_VIDSTD_1080P59_94:
    case DT_VIDSTD_1080P59_94B:
    case DT_VIDSTD_1080P50:
    case DT_VIDSTD_1080P50B:

        pProps->m_NumLines = 1125;

        if (VidStd==DT_VIDSTD_1080P50 || VidStd==DT_VIDSTD_1080P50B
                               || VidStd==DT_VIDSTD_2160P50 || VidStd==DT_VIDSTD_2160P50B)

            pProps->m_Fps = 50;
        else
            pProps->m_Fps = 60;

        pProps->m_IsFractional = (VidStd==DT_VIDSTD_1080P59_94
                                                        || VidStd==DT_VIDSTD_1080P59_94B
                                                        || VidStd==DT_VIDSTD_2160P59_94
                                                        || VidStd==DT_VIDSTD_2160P59_94B);
        pProps->m_IsInterlaced = FALSE;
        pProps->m_IsHd = TRUE;

        pProps->m_Field1Start = 1;
        pProps->m_Field1End = 1125;

        pProps->m_Field1ActVidStart = 42;
        pProps->m_Field1ActVidEnd = 1121;

        pProps->m_SwitchingLines[0] = 7;
        pProps->m_SwitchingLines[1] = -1;

        pProps->m_Field2Start = 0;
        pProps->m_Field2End = 0;
        
        pProps->m_Field2ActVidStart = 0;
        pProps->m_Field2ActVidEnd  = 0;
        
        pProps->m_VancNumS = pProps->m_ActVidNumS = 1920*2;
        if (VidStd==DT_VIDSTD_1080P60 || VidStd==DT_VIDSTD_1080P60B
                         || VidStd==DT_VIDSTD_1080P59_94 || VidStd==DT_VIDSTD_1080P59_94B
                         || VidStd==DT_VIDSTD_2160P60 || VidStd==DT_VIDSTD_2160P60B
                         || VidStd==DT_VIDSTD_2160P59_94 || VidStd==DT_VIDSTD_2160P59_94B)

        {
            pProps->m_HancNumS = 268*2;
            // Set Sync point
            pProps->m_SyncPointPixelOff = 88;   // Sync point @pixel 88
        }
        else if (VidStd==DT_VIDSTD_1080P50 || VidStd==DT_VIDSTD_1080P50B 
                               || VidStd==DT_VIDSTD_2160P50 || VidStd==DT_VIDSTD_2160P50B)

        {
            pProps->m_HancNumS = 708*2;
            pProps->m_SyncPointPixelOff = 528;   // Sync point @pixel 528
        }
        else
            DT_ASSERT(1==0);

        pProps->m_EavNumS = 8*2;
        pProps->m_SavNumS = 4*2;
        break;

    case DT_VIDSTD_2160P30:
    case DT_VIDSTD_2160P29_97:
    case DT_VIDSTD_2160P25:
    case DT_VIDSTD_2160P24:
    case DT_VIDSTD_2160P23_98:
    case DT_VIDSTD_1080P30:
    case DT_VIDSTD_1080P29_97:
    case DT_VIDSTD_1080P25:
    case DT_VIDSTD_1080P24:
    case DT_VIDSTD_1080P23_98:

        pProps->m_NumLines = 1125;

        if (VidStd==DT_VIDSTD_1080P30 || VidStd==DT_VIDSTD_1080P29_97
                             || VidStd==DT_VIDSTD_2160P30 || VidStd==DT_VIDSTD_2160P29_97)
            pProps->m_Fps = 30;
        else if (VidStd==DT_VIDSTD_1080P25 || VidStd==DT_VIDSTD_2160P25)
            pProps->m_Fps = 25;
        else if (VidStd==DT_VIDSTD_1080P24 || VidStd==DT_VIDSTD_1080P23_98
                             || VidStd==DT_VIDSTD_2160P24 || VidStd==DT_VIDSTD_2160P23_98)
            pProps->m_Fps = 24;
        else
            DT_ASSERT(1==0);

        pProps->m_IsFractional = (VidStd==DT_VIDSTD_1080P29_97 
                                                         || VidStd==DT_VIDSTD_1080P23_98
                                                         || VidStd==DT_VIDSTD_2160P29_97
                                                         || VidStd==DT_VIDSTD_2160P23_98);
        pProps->m_IsInterlaced = FALSE;
        pProps->m_IsHd = TRUE;

        pProps->m_Field1Start = 1;
        pProps->m_Field1End = 1125;

        pProps->m_Field1ActVidStart = 42;
        pProps->m_Field1ActVidEnd = 1121;
        pProps->m_SwitchingLines[0] = 7;

        pProps->m_Field2Start = 0;
        pProps->m_Field2End = 0;
        pProps->m_Field2ActVidStart = 0;
        pProps->m_Field2ActVidEnd = 0;
        pProps->m_SwitchingLines[1] = -1;

        pProps->m_VancNumS = pProps->m_ActVidNumS = 1920*2;
        if (VidStd==DT_VIDSTD_1080P30 || VidStd==DT_VIDSTD_1080P29_97
                             || VidStd==DT_VIDSTD_2160P30 || VidStd==DT_VIDSTD_2160P29_97)
        {
            pProps->m_HancNumS = 268*2;
            pProps->m_SyncPointPixelOff = 88;   // Sync point @pixel 88
        }
        else if (VidStd==DT_VIDSTD_1080P25 || VidStd==DT_VIDSTD_2160P25)
        {
            pProps->m_HancNumS = 708*2;
            pProps->m_SyncPointPixelOff = 528;   // Sync point @pixel 528
        }
        else if (VidStd==DT_VIDSTD_1080P24 || VidStd==DT_VIDSTD_1080P23_98
                             || VidStd==DT_VIDSTD_2160P24 || VidStd==DT_VIDSTD_2160P23_98)
        {
            pProps->m_HancNumS = 818*2;
            pProps->m_SyncPointPixelOff = 638;   // Sync point @pixel 638
        }
        else
            DT_ASSERT(1==0);

        pProps->m_EavNumS = 8*2;
        pProps->m_SavNumS = 4*2;

        break;

    case DT_VIDSTD_1080I60:
    case DT_VIDSTD_1080I59_94:
    case DT_VIDSTD_1080I50:
    case DT_VIDSTD_1080PSF30:
    case DT_VIDSTD_1080PSF29_97:
    case DT_VIDSTD_1080PSF25:
    case DT_VIDSTD_1080PSF24:
    case DT_VIDSTD_1080PSF23_98:
        pProps->m_NumLines = 1125;

        if (VidStd==DT_VIDSTD_1080I60 || VidStd==DT_VIDSTD_1080I59_94 
                         || VidStd==DT_VIDSTD_1080PSF30 || VidStd==DT_VIDSTD_1080PSF29_97)
            pProps->m_Fps = 30;
        else if (VidStd==DT_VIDSTD_1080I50 || VidStd==DT_VIDSTD_1080PSF25)
            pProps->m_Fps = 25;
        else if (VidStd==DT_VIDSTD_1080PSF24 || VidStd==DT_VIDSTD_1080PSF23_98)
            pProps->m_Fps = 24;
        else
            DT_ASSERT(1==0);

        pProps->m_IsFractional = (VidStd==DT_VIDSTD_1080I59_94 ||
                                  VidStd==DT_VIDSTD_1080PSF29_97 ||
                                  VidStd==DT_VIDSTD_1080PSF23_98);
        pProps->m_IsInterlaced = TRUE;
        pProps->m_IsHd = TRUE;

        pProps->m_Field1Start = 1; 
        pProps->m_Field1End = 563;
        pProps->m_Field1ActVidStart = 21; 
        pProps->m_Field1ActVidEnd = 560;
        pProps->m_SwitchingLines[0] = 7;

        pProps->m_Field2Start = 564;
        pProps->m_Field2End = 1125;
        pProps->m_Field2ActVidStart = 584;
        pProps->m_Field2ActVidEnd = 1123;
        pProps->m_SwitchingLines[1] = 569;

        pProps->m_VancNumS = pProps->m_ActVidNumS = 1920*2;
        if (VidStd==DT_VIDSTD_1080I60 || VidStd==DT_VIDSTD_1080I59_94 ||
            VidStd==DT_VIDSTD_1080PSF30 || VidStd==DT_VIDSTD_1080PSF29_97)
        {
            pProps->m_HancNumS = 268*2;
            pProps->m_SyncPointPixelOff = 88;   // Sync point @pixel 88
        }
        else if (VidStd==DT_VIDSTD_1080I50 || VidStd==DT_VIDSTD_1080PSF25)
        {
            pProps->m_HancNumS = 708*2;
            pProps->m_SyncPointPixelOff = 528;   // Sync point @pixel 528
        }
        else if (VidStd==DT_VIDSTD_1080PSF24 || VidStd==DT_VIDSTD_1080PSF23_98)
        {
            pProps->m_HancNumS = 818*2;
            pProps->m_SyncPointPixelOff = 638;   // Sync point @pixel 638
        }
        else
            DT_ASSERT(1==0);
        
        pProps->m_EavNumS = 8*2;
        pProps->m_SavNumS = 4*2;
        break;

    case DT_VIDSTD_720P60:
    case DT_VIDSTD_720P59_94:
    case DT_VIDSTD_720P50:
    case DT_VIDSTD_720P30:
    case DT_VIDSTD_720P29_97:
    case DT_VIDSTD_720P25:
    case DT_VIDSTD_720P24:
    case DT_VIDSTD_720P23_98:
        pProps->m_NumLines = 750;

        if (VidStd==DT_VIDSTD_720P60 || VidStd==DT_VIDSTD_720P59_94)
            pProps->m_Fps = 60;
        else if (VidStd==DT_VIDSTD_720P50)
            pProps->m_Fps = 50;
        else if (VidStd==DT_VIDSTD_720P30 || VidStd==DT_VIDSTD_720P29_97)
            pProps->m_Fps = 30;
        else if (VidStd==DT_VIDSTD_720P25)
            pProps->m_Fps = 25;
        else if (VidStd==DT_VIDSTD_720P24 || VidStd==DT_VIDSTD_720P23_98)
            pProps->m_Fps = 24;
        else
            DT_ASSERT(1==0);

        pProps->m_IsFractional = (VidStd==DT_VIDSTD_720P59_94 
                                                          || VidStd==DT_VIDSTD_720P29_97 
                                                          || VidStd==DT_VIDSTD_720P23_98);
        pProps->m_IsInterlaced = FALSE;
        pProps->m_IsHd = TRUE;

        pProps->m_Field1Start = 1;
        pProps->m_Field1End = 750;
        pProps->m_Field1ActVidStart = 26; 
        pProps->m_Field1ActVidEnd = 745;
        pProps->m_SwitchingLines[0] = 7;

        pProps->m_Field2Start = 0;
        pProps->m_Field2End = 0;
        pProps->m_Field2ActVidStart = 0; 
        pProps->m_Field2ActVidEnd = 0;
        pProps->m_SwitchingLines[1] = -1;

        pProps->m_VancNumS = pProps->m_ActVidNumS = 1280*2;
        if (VidStd==DT_VIDSTD_720P60 || VidStd==DT_VIDSTD_720P59_94)
        {
            pProps->m_HancNumS = 358*2;
            pProps->m_SyncPointPixelOff = 110;   // Sync point @pixel 110
        }
        else if (VidStd==DT_VIDSTD_720P50)
        {
            pProps->m_HancNumS = 688*2;
            pProps->m_SyncPointPixelOff = 440;   // Sync point @pixel 440
        }
        else if (VidStd==DT_VIDSTD_720P30 || VidStd==DT_VIDSTD_720P29_97)
        {
            pProps->m_HancNumS = 2008*2;
            pProps->m_SyncPointPixelOff = 1760;   // Sync point @pixel 88
        }
        else if (VidStd==DT_VIDSTD_720P25)
        {
            pProps->m_HancNumS = 2668*2;
            pProps->m_SyncPointPixelOff = 2420;   // Sync point @pixel 88
        }
        else if (VidStd==DT_VIDSTD_720P24 || VidStd==DT_VIDSTD_720P23_98)
        {
            pProps->m_HancNumS = 2833*2;
            pProps->m_SyncPointPixelOff = 2585;   // Sync point @pixel 88
        }
        else
            DT_ASSERT(1==0);

        pProps->m_EavNumS = 8*2;
        pProps->m_SavNumS = 4*2;
        break;

    default:
        DtDbgOut(ERR, AV, "Unknown IO-standard");
        return DT_STATUS_INVALID_PARAMETER;
    }
    // Store the video video standard
    pProps->m_VidStd = VidStd;
    return DT_STATUS_OK;
}
Esempio n. 25
0
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtuEventsGet -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
//
// Return a pending event. This functions blocks if no events are pending.
//
DtStatus  DtuEventsGet(
    DtuDeviceData*  pDvcData,
    DtFileObject*  pFile, 
    UInt*  pEventType, 
    UInt*  pValue1,
    UInt*  pValue2,
    Bool  Wait)
{
    DtStatus  Result = DT_STATUS_OK;
    DtuEvents*  pDtuEvents;

    if (pFile==NULL || pEventType==NULL || pValue1==NULL || pValue2==NULL)
        return DT_STATUS_INVALID_PARAMETER;

    // Get corresponding events object
    pDtuEvents = DtuEventsGetEventsObject(pDvcData, pFile);
    if (pDtuEvents == NULL)
        Result = DT_STATUS_NOT_FOUND;

    if (DT_SUCCESS(Result))
    {
        DtEventReset(&pDtuEvents->m_PendingEvent);

        if (Wait && pDtuEvents->m_NumPendingEvents==0 && !pDtuEvents->m_CancelInProgress) 
        {
            DtDbgOut(MAX, EVENTS, "Waiting for event");
        
            // Wait for event to be triggered
            DtEventWait(&pDtuEvents->m_PendingEvent, -1);
        }

        // The next request will be rejected by the IoCtl function, so we can reset
        // the Cancel state here.
        if (pDtuEvents->m_CancelInProgress)
            Result = DT_STATUS_CANCELLED;
        pDtuEvents->m_CancelInProgress = FALSE;

        DtSpinLockAcquire(&pDtuEvents->m_Lock);
        
        // Return pending events
        if (pDtuEvents->m_NumPendingEvents != 0)
        {  
            *pEventType = pDtuEvents->m_PendingEvents[0].m_EventType;
            *pValue1 = pDtuEvents->m_PendingEvents[0].m_EventValue1;
            *pValue2 =  pDtuEvents->m_PendingEvents[0].m_EventValue2;
            DtDbgOut(MAX, EVENTS, "Event #%d. Type: %d, Value1: %d, Value2: %d", 
                         pDtuEvents->m_NumPendingEvents, *pEventType, *pValue1, *pValue2);
            pDtuEvents->m_NumPendingEvents--;

            if (pDtuEvents->m_NumPendingEvents != 0)
            {   
                // Remove the old event
                DtMemMove(&pDtuEvents->m_PendingEvents[0],
                                       &pDtuEvents->m_PendingEvents[1],
                                       sizeof(DtuEvent) * pDtuEvents->m_NumPendingEvents);
            }
        } else {
            *pEventType = 0;
            *pValue1 = 0;
            *pValue2 = 0;
            if (Result == DT_STATUS_OK)
                Result = DT_STATUS_REQUEUE; // No pending events
            DtDbgOut(MAX, EVENTS, "Event #%d. No event", pDtuEvents->m_NumPendingEvents);
        }
    
        DtSpinLockRelease(&pDtuEvents->m_Lock);

        // Decrement refcount
        DtuEventsUnrefEventsObject(pDvcData, pDtuEvents);
    }
    
    return Result;
}
Esempio n. 26
0
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- IoConfigCodesCodeGet -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
//
DtStatus  IoConfigCodeGet( const char*  pName, Int  *pConfigCode)
{
    DtStatus  Status = DT_STATUS_OK;
    const IoConfigCodeHashSet*  pHashSets = IoConfigCodeHashSets;
    UInt  HashSetCount = IoConfigCodesHashCount;
    
    UInt  Hash = 0;
    Int  Index;
    Bool  ConfigNameFound = FALSE;
    const IoConfigCodeHashSet*  pHashSet = NULL;
    Int  ConfigCount = 0;
    const IoConfigCode*  pConfig = NULL;

    // Special case empty string
    if (pName[0] == '\0')
    {
        *pConfigCode = -1;
        return Status;
    }

    // Determine the name hash
    Hash = DtDjb2(pName) % HashSetCount;

    // Get correct hash set (if exists)
    if (DT_SUCCESS(Status))
    {
        pHashSet = &pHashSets[Hash];
        ConfigCount = pHashSets[Hash].m_ConfigCodeCount;

        // Check if a hash set was available for this hash value
        if (pHashSet == NULL)
            Status = DT_STATUS_NOT_FOUND;
    }

    // Get correct config entry within hash set
    if (DT_SUCCESS(Status))
    {
        // Search all configs
        for (Index=0; Index<ConfigCount; Index++)
        {
            pConfig = &pHashSet->m_pConfigCodes[Index];

            // Compare name to check if we found the first occurrence
            if (DtAnsiCharArrayIsEqual(pName, pConfig->m_pName))
            {
                *pConfigCode = pConfig->m_Value;
                ConfigNameFound = TRUE;
                break;
            }
        }
        if (!ConfigNameFound)
            Status = DT_STATUS_NOT_FOUND;

    }

    if (!ConfigNameFound)
        DtDbgOut(ERR, PROP, "ConfigName %s is not found", pName);
    else
        DtDbgOut(MAX, PROP, "Found config code %d for %s", *pConfigCode, pName);

    return Status;
}
Esempio n. 27
0
File: Hdmi.c Progetto: levic/dektec
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtaHdmiControllerThread -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
//
void  DtaHdmiControllerThread(DtThread* pThread, void* pContext)
{
    DtStatus  Status = DT_STATUS_OK;
    DtaNonIpPort* pNonIpPort = (DtaNonIpPort*)pContext;
    DtaHdmi*  pHdmi = &pNonIpPort->m_HdmiRx;
    Bool  ConfigForHd = TRUE;

    DtDbgOut(MAX, HDMI, "Thread begin");
    
    DtaFwbRegWrite(pNonIpPort->m_pFwbRegs, &pHdmi->m_pFwbHdmiAdv7610Ctrl->Control_Reset, 1);
    DtSleep(5);
    DtaFwbRegWrite(pNonIpPort->m_pFwbRegs, &pHdmi->m_pFwbHdmiAdv7610Ctrl->Control_Reset, 0);
    DtSleep(10);
    
    // Disable VGA framing
    DtaFwbRegWrite(pNonIpPort->m_pFwbRegs,
                &pHdmi->m_pFwbHdmiAdv7610Ctrl->Control_VgaFraming, DTFWB_HDMI_NO_FRAMING);

    //  Disable powerdown bit
    if (Status == DT_STATUS_OK)
        Status = ADV7610_WRITE_REG(GENERAL, IO_REG_0C, 0x42);
    
    DtSleep(10);

    if (Status != DT_STATUS_OK)
    {
        DtDbgOut(ERR, HDMI, "Failed to disable powerdown bit: 0x%X", Status);
        DtaFwbRegWrite(pNonIpPort->m_pFwbRegs,
                                         &pHdmi->m_pFwbHdmiAdv7610Ctrl->Control_Reset, 1);
        DtThreadWaitForStop(pThread);
        return;
    }

    // Initialize I2C addresses of other register pages
    
    if (Status == DT_STATUS_OK)
        Status = ADV7610_WRITE_REG(GENERAL, CEC_SLAVE_ADDRESS, ADV7610_I2CADDR_CEC);
    if (Status == DT_STATUS_OK)
        Status = ADV7610_WRITE_REG(GENERAL, INFOFRAME_SLAVE_ADDRESS, ADV7610_I2CADDR_INFOFRAME);
    if (Status == DT_STATUS_OK)
        Status = ADV7610_WRITE_REG(GENERAL, KSV_SLAVE_ADDRESS, ADV7610_I2CADDR_KSV);
    if (Status == DT_STATUS_OK)
        Status = ADV7610_WRITE_REG(GENERAL, EDID_SLAVE_ADDRESS, ADV7610_I2CADDR_EDID);
    if (Status == DT_STATUS_OK)
        Status = ADV7610_WRITE_REG(GENERAL, HDMI_SLAVE_ADDRESS, ADV7610_I2CADDR_HDMI);
    if (Status == DT_STATUS_OK)
        Status = ADV7610_WRITE_REG(GENERAL, CP_SLAVE_ADDRESS, ADV7610_I2CADDR_CP);

    if (Status != DT_STATUS_OK)
        DtDbgOut(ERR, HDMI, "Failed to set slave I2C addresses: 0x%X", Status);

    // Setting clock frequency to 27Mhz and pixel bus to mode 2
    if (Status == DT_STATUS_OK)
        Status = ADV7610_WRITE_REG(GENERAL, IO_REG_04, 0x60);
    // color space settings
    if (Status == DT_STATUS_OK)
        Status = ADV7610_WRITE_REG(GENERAL, IO_REG_02, 0xF4);
    // set IO_REG_05
    if (Status == DT_STATUS_OK)
        Status = ADV7610_WRITE_REG(GENERAL, IO_REG_05, 0x2C);
    // enabling output
    if (Status == DT_STATUS_OK)
        Status = ADV7610_WRITE_REG(GENERAL, IO_REG_15, 0xA8);
    // disable free run mode
    if (Status == DT_STATUS_OK)
        Status = ADV7610_WRITE_REG(CP, HDMI_CP_CNTRL_1, 0x00);
    // disable cable detect reset
    if (Status == DT_STATUS_OK)
        Status = ADV7610_WRITE_REG(HDMI, REGISTER_48, 0x40);
    // enable termination automatic control
    if (Status == DT_STATUS_OK)
        Status = ADV7610_WRITE_REG(HDMI, REGISTER_01, 0x01);
    // enable clock termination on port a
    if (Status == DT_STATUS_OK)
        Status = ADV7610_WRITE_REG(HDMI, REGISTER_02, 0xFE);
    // enable dynamic eq control
    if (Status == DT_STATUS_OK)
        Status = ADV7610_WRITE_REG(HDMI, EQ_DYNAMIC_ENABLE, 0x01);
    // Set bit width for right justified mode on I2S interface
    //if (Status == DT_STATUS_OK)
    //    Status = ADV7610_WRITE_REG(HDMI, REGISTER_03, 0x10);
    // Disable "mute if compressed audio is detected" bit
    if (Status == DT_STATUS_OK)
        Status = ADV7610_WRITE_REG(HDMI, MUTE_MASK21_16, 0x1F);
    
    if (Status != DT_STATUS_OK)
        DtDbgOut(ERR, HDMI, "Failed to initialize general registers");

    // Write EDID data
    if (Status == DT_STATUS_OK)
    {
        Int  i;
        UInt8  Sum = 0;
        UInt8  Edid[257];
        UInt32  Serial;
        Edid[0] = 0; // Address byte
        DtMemCopy(Edid+1, EDID_Block, sizeof(EDID_Block));
        Serial = (UInt32)pNonIpPort->m_pDvcData->m_DevInfo.m_Serial;
        DtMemCopy(Edid+1+0x0C, &Serial, sizeof(Serial));
        for (i=0; i<127; i++)
            Sum += Edid[i+1];
        Edid[0x80] = (255 - Sum + 1);
        Status = DtaI2cmWrite(&pHdmi->m_I2c, ADV7610_I2CADDR_EDID, sizeof(Edid), Edid);
    }

    if (Status != DT_STATUS_OK)
        DtDbgOut(ERR, HDMI, "Write EDID failure");

    // enable EDID for port a
    if (Status == DT_STATUS_OK)
        Status = ADV7610_WRITE_REG(KSV, HDCP_EDID_CONTROLS, 0x01);

    if (Status == DT_STATUS_OK)
        Status = DtaHdmiConfigForHd(pHdmi);
    ConfigForHd = TRUE;
    
    // Set interrupt signal duration to '11': Active until cleared
    // Set signal configuration '10': drives high when active
    if (Status == DT_STATUS_OK)
        Status = ADV7610_WRITE_REG(GENERAL, INT1_CONFIGURATION, 0xE2);
    
    // Enable cable detect / encrypted signal interrupts
    if (Status == DT_STATUS_OK)
        Status = ADV7610_WRITE_REG(GENERAL, HDMI_LVL_INT_MASKB4, 0x05);
    // Enable Video clock changed, Audio mode changed, new sample rate,
    // TMDS freq changed interrupts
    if (Status == DT_STATUS_OK)
        Status = ADV7610_WRITE_REG(GENERAL, HDMI_EDG_INT_MASKB3, 0x6A);
    // Enable TMDS-PLL locked, TMDS clock detect, Vertical sync lock, DE regeneration
    // lock interrupts
    if (Status == DT_STATUS_OK)
        Status = ADV7610_WRITE_REG(GENERAL, HDMI_LVL_INT_MASKB3, 0x53);
    // Enable NEW_AVI_INFO and NEW_AUDIO_INFO interrupts
    if (Status == DT_STATUS_OK)
        Status = ADV7610_WRITE_REG(GENERAL, HDMI_LVL_INT_MASKB1, 0x03);

    if (Status != DT_STATUS_OK)
    {
        DtDbgOut(ERR, HDMI, "HDMI initialization failed.");
        DtaFwbRegWrite(pNonIpPort->m_pFwbRegs,
                                         &pHdmi->m_pFwbHdmiAdv7610Ctrl->Control_Reset, 1);
        DtThreadWaitForStop(pThread);
        return;
    }

    DtDbgOut(AVG, HDMI, "HDMI initialization complete");

    while (!pThread->m_StopThread)
    {
        UInt8  Value;
        DtaHdmiStatus  NewStatus;
        Int  NewVidStd = DT_VIDSTD_UNKNOWN;

        DtaHdmiClearStatus(&NewStatus);

        // Read/clear cable detect / encrypted signal interrupts
        Status = ADV7610_READ_REG(GENERAL, HDMI_LVL_INT_STATUS4, &Value);
        if (Status==DT_STATUS_OK && Value!=0)
            ADV7610_WRITE_REG(GENERAL, HDMI_LVL_INT_CLR4, Value&0x05);
        
        Status = ADV7610_READ_REG(GENERAL, HDMI_LVL_RAW_STATUS4, &Value);
        if (Status == DT_STATUS_OK)
        {
            NewStatus.m_CableDet = (Value&0x01)!=0;
            NewStatus.m_Encrypted = (Value&0x04)!=0;
        }
        
        // Read/clear TMDS-PLL locked, TMDS clock detect, Vertical sync lock, 
        // DE regeneration lock interrupts
        Status = ADV7610_READ_REG(GENERAL, HDMI_LVL_INT_STATUS3, &Value);
        if (Status==DT_STATUS_OK && Value!=0)
            ADV7610_WRITE_REG(GENERAL, HDMI_LVL_INT_CLR3, Value);

        // Read/clear TMDS freq changed interrupt
        Status = ADV7610_READ_REG(GENERAL, HDMI_EDG_STATUS3, &Value);
        if (Status==DT_STATUS_OK && Value!=0)
            ADV7610_WRITE_REG(GENERAL, HDMI_EDG_INT_CLR3, Value);
        if (NewStatus.m_CableDet)
        {
            Status = ADV7610_READ_REG(HDMI, REGISTER_04, &Value);
            NewStatus.m_TmdsPllLocked = (Value&0x02)!=0;
            NewStatus.m_AudioLocked = (Value&0x01)!=0;
        }

        // Read/clear new audio info interrupt
        Status = ADV7610_READ_REG(GENERAL, HDMI_LVL_INT_STATUS1, &Value);
        if (Status==DT_STATUS_OK && Value!=0)
            ADV7610_WRITE_REG(GENERAL, HDMI_LVL_INT_CLR1, Value);

        if (NewStatus.m_TmdsPllLocked)
        {
            Status = ADV7610_READ_REG(HDMI, HDMI_COLORSPACE, &Value);
            NewStatus.m_InpColorspace = Value&0x0F;
            
            Status = ADV7610_READ_REG(HDMI, REGISTER_05, &Value);
            NewStatus.m_PixelRepetition = Value&0x0F;
            
            Status = ADV7610_READ_REG(HDMI, LINE_WIDTH1, &Value);
            NewStatus.m_VertFilterLocked = (Value&0x80)!=0;
            NewStatus.m_DeRegenFilterLocked = (Value&0x20)!=0;
            NewStatus.m_VidWidth = (Value&0x01F)<<8;
            Status = ADV7610_READ_REG(HDMI, LINE_WIDTH2, &Value);
            NewStatus.m_VidWidth |= Value;
            
            Status = ADV7610_READ_REG(HDMI, FIELD0_HEIGHT1, &Value);
            NewStatus.m_VidHeight1 = (Value&0x01F)<<8;
            Status = ADV7610_READ_REG(HDMI, FIELD0_HEIGHT2, &Value);
            NewStatus.m_VidHeight1 |= Value;
            
            Status = ADV7610_READ_REG(HDMI, REGISTER_51, &Value);
            NewStatus.m_TmdsFreq = Value<<8;
            Status = ADV7610_READ_REG(HDMI, REGISTER_52, &Value);
            NewStatus.m_TmdsFreq |= Value;
            
            Status = ADV7610_READ_REG(HDMI, FIELD1_HEIGHT1, &Value);
            switch (Value>>6)
            {
            case 0: NewStatus.m_BitsPerChannel = 8; break;
            case 1: NewStatus.m_BitsPerChannel = 10; break;
            case 2: NewStatus.m_BitsPerChannel = 12; break;
            case 3: NewStatus.m_BitsPerChannel = 16; break;
            }
            NewStatus.m_Interlaced = (Value&0x20)!=0;
            NewStatus.m_VidHeight2 = (Value&0x01F)<<8;
            Status = ADV7610_READ_REG(HDMI, FIELD1_HEIGHT2, &Value);
            NewStatus.m_VidHeight2 |= Value;
            
            Status = ADV7610_READ_REG(GENERAL, HDMI_LVL_RAW_STATUS2, &Value);
            NewStatus.m_AudioChanStatusValid = (Value&0x80)!=0;
            if (NewStatus.m_AudioChanStatusValid)
            {
                UInt8  RegAddr = ADV7610_HDMI_CHANNEL_STATUS_DATA_1;
                DtaI2cmWriteRead(&pHdmi->m_I2c, ADV7610_I2CADDR_HDMI, 1, &RegAddr,
                                                   sizeof(NewStatus.m_AudioChannelStatus),
                                                   NewStatus.m_AudioChannelStatus);
            }
        }

        if (NewStatus.m_AudioLocked)
        {
            Status = ADV7610_READ_REG(HDMI, LINE_WIDTH1, &Value);
            NewStatus.m_AudioChannelMode = (Value>>6)&1;
            Status = ADV7610_READ_REG(HDMI, PACKETS_DETECTED_2, &Value);
            if ((Value&0x01) != 0)
                NewStatus.m_AudioType = 0;
            else if ((Value&0x02) != 0)
                NewStatus.m_AudioType = 1;
            else if ((Value&0x04) != 0)
                NewStatus.m_AudioType = 2;
            else if ((Value&0x08) != 0)
                NewStatus.m_AudioType = 3;
        }
Esempio n. 28
0
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtaNonIpTxIoctl -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
//
DtStatus  DtaNonIpTxIoctl(
    DtaDeviceData*  pDvcData,
    DtFileObject*  pFile,
    DtIoctlObject*  pIoctl)
{
    DtStatus  Status = DT_STATUS_OK;
    char*  pCmdStr;             // Mnemonic string for Command
    UInt  InReqSize = 0;        // Required length of input buffer
    UInt  OutReqSize = 0;       // Required length of output buffer
    Int  NonIpPortIndex;        // Index in the nonip port struct
    DtaIoctlNonIpTxCmdInput* pNonIpTxCmdInput = 
                                         (DtaIoctlNonIpTxCmdInput*)pIoctl->m_pInputBuffer;
    DtaIoctlNonIpTxCmdOutput* pNonIpTxCmdOutput =
                                       (DtaIoctlNonIpTxCmdOutput*)pIoctl->m_pOutputBuffer;
    
    // Default require at least the size of the header preceding the data
    InReqSize = OFFSETOF(DtaIoctlNonIpTxCmdInput, m_Data);
    OutReqSize = OFFSETOF(DtaIoctlNonIpTxCmdOutput, m_Data);

    // Check if we can read m_Cmd / m_PortIndex
    if (pIoctl->m_InputBufferSize < InReqSize)
        return DT_STATUS_INVALID_PARAMETER;

    // Validate port index
    if (!DT_SUCCESS(DtaGetNonIpPortIndex(pDvcData, pNonIpTxCmdInput->m_PortIndex,
                                                                        &NonIpPortIndex)))
        return DT_STATUS_INVALID_PARAMETER;
    
    // Determine final required output/input sizes
    switch (pNonIpTxCmdInput->m_Cmd)
    {
    case DTA_NONIP_TX_CMD_GET_FLAGS:
        pCmdStr = "DTA_NONIP_TX_CMD_GET_FLAGS";
        OutReqSize += sizeof(DtaIoctlNonIpTxCmdGetFlagsOutput);
        // We expect no additional data in the input buffer
        InReqSize += 0;
        break;

    case DTA_NONIP_TX_CMD_CLEAR_FLAGS:
        pCmdStr = "DTA_NONIP_TX_CMD_CLEAR_FLAGS";
        InReqSize += sizeof(DtaIoctlNonIpTxCmdClearFlagsInput);
        // We expect no output buffer at all
        OutReqSize = 0;
        break;

    case DTA_NONIP_TX_CMD_SET_FAILSAFE_CFG:
        pCmdStr = "DTA_NONIP_TX_CMD_SET_FAILSAFE_CFG";
        InReqSize += sizeof(DtaIoctlNonIpTxCmdSetFailsafeCfgInput);
        // We expect no output buffer at all
        OutReqSize = 0;
        break;

    case DTA_NONIP_TX_CMD_SET_FAILSAFE_ALIVE:
        pCmdStr = "DTA_NONIP_TX_CMD_SET_FAILSAFE_ALIVE";
        // We expect no additional data in the input buffer
        InReqSize += 0;
        // We expect no output buffer at all
        OutReqSize = 0;
        break;
    
    case DTA_NONIP_TX_CMD_GET_FAILSAFE_INFO:
        pCmdStr = "DTA_NONIP_TX_CMD_GET_FAILSAFE_INFO";
        OutReqSize += sizeof(DtaIoctlNonIpTxCmdGetFailsafeInfoOutput);
        // We expect no additional data in the input buffer
        InReqSize += 0;
        break;

    default:
        pCmdStr = "??UNKNOWN VPDCMD CODE??";
        Status = DT_STATUS_NOT_SUPPORTED;
    }

    if (DT_SUCCESS(Status))
    {
        // Check buffer sizes
        if (pIoctl->m_InputBufferSize < InReqSize)
        {
            DtDbgOut(ERR, NONIP, "%s: INPUT BUFFER TOO SMALL Size=%d Req=%d", pCmdStr, 
                                                    pIoctl->m_InputBufferSize, InReqSize);
            return DT_STATUS_INVALID_PARAMETER;
        }
        if (pIoctl->m_OutputBufferSize < OutReqSize)
        {
            DtDbgOut(ERR, NONIP, "%s: OUTPUT BUFFER TOO SMALL Size=%d Req=%d", pCmdStr, 
                                                  pIoctl->m_OutputBufferSize, OutReqSize);
            return DT_STATUS_INVALID_PARAMETER;
        }

        DtDbgOut(MAX, NONIP, "%s: In=%d (Rq=%d), Out=%d (Rq=%d)", pCmdStr,
                pIoctl->m_InputBufferSize, InReqSize, pIoctl->m_OutputBufferSize, OutReqSize);
    }
    
    // The bytes written will be updated if needed. Set the default value here.
    pIoctl->m_OutputBufferBytesWritten = OutReqSize;

    if (DT_SUCCESS(Status))
    {
        // Execute cmd
        switch (pNonIpTxCmdInput->m_Cmd)
        {
        case DTA_NONIP_TX_CMD_GET_FLAGS:
            Status = DtaNonIpTxGetFlags(&pDvcData->m_pNonIpPorts[NonIpPortIndex],
                                         &pNonIpTxCmdOutput->m_Data.m_GetFlags.m_Status,
                                         &pNonIpTxCmdOutput->m_Data.m_GetFlags.m_Latched);
            break;

        case DTA_NONIP_TX_CMD_CLEAR_FLAGS:
            Status = DtaNonIpTxClearFlags(&pDvcData->m_pNonIpPorts[NonIpPortIndex],
                                    pNonIpTxCmdInput->m_Data.m_ClearFlags.m_FlagsToClear);
            break;

        case DTA_NONIP_TX_CMD_SET_FAILSAFE_CFG:
            Status = DtaNonIpTxSetFailsafeCfg(&pDvcData->m_pNonIpPorts[NonIpPortIndex],
                                     pNonIpTxCmdInput->m_Data.m_SetFailsafeCfg.m_Enable,
                                     pNonIpTxCmdInput->m_Data.m_SetFailsafeCfg.m_Timeout);
            break;

        case DTA_NONIP_TX_CMD_SET_FAILSAFE_ALIVE:
            Status = DtaNonIpTxSetFailsafeAlive(&pDvcData->m_pNonIpPorts[NonIpPortIndex]);
            break;
        
        case DTA_NONIP_TX_CMD_GET_FAILSAFE_INFO:
            Status = DtaNonIpTxGetFailsafeInfo(&pDvcData->m_pNonIpPorts[NonIpPortIndex],
                                   &pNonIpTxCmdOutput->m_Data.m_GetFailsafeInfo.m_Enable,
                                   &pNonIpTxCmdOutput->m_Data.m_GetFailsafeInfo.m_Timeout,
                                   &pNonIpTxCmdOutput->m_Data.m_GetFailsafeInfo.m_Alive);
            break;

        default:
            Status = DT_STATUS_NOT_SUPPORTED;
        }
    }

    // If we failed, no data has te be copied to user space
    if (!DT_SUCCESS(Status))
    {
        pIoctl->m_OutputBufferBytesWritten = 0;
        if (Status == DT_STATUS_NOT_SUPPORTED)
            DtDbgOut(MIN, NONIP, "NonIpTxCmd=0x%x: NOT SUPPORTED", 
                                                                 pNonIpTxCmdInput->m_Cmd);
        else 
            DtDbgOut(MIN, NONIP, "%s: ERROR %xh", pCmdStr, Status);
    }

    return Status;
}
Esempio n. 29
0
//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- EzUsbInit -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
//
DtStatus  EzUsbInit(DtuDeviceData* pDvcData, Bool* pReEnumerate)
{
    DtStatus  Status = DT_STATUS_OK;
    const DtuIntelHexRecord*  pEzUsbFirmware = NULL;
    DtPropertyData*  pPropData = &pDvcData->m_PropData;
    Bool  IsEzUsbFwLoaded=FALSE, IsPldFwLoaded=FALSE;
    Int  FirmwareEndpoint;
    Int  ReadEndpoint;
    Int  WriteEndpoint;
    
    

    // Initialize properties
    FirmwareEndpoint = DtPropertiesGetInt(pPropData, "USB_END_POINT_FIRMWARE", -1);
    ReadEndpoint = DtPropertiesGetInt(pPropData, "USB_END_POINT_READ", -1);
    WriteEndpoint = DtPropertiesGetInt(pPropData, "USB_END_POINT_WRITE", -1);
        
    // Check if no property error occurred
    Status = DtuPropertiesReportDriverErrors(pDvcData);
    if (!DT_SUCCESS(Status))
        return Status;

    // Check if we need to load firmware. NOTE: there are two conditions to load the 
    // firmware namely:
    //   1. EzUsb firmware is not loaded yet
    //   2. PLD firmware is loaded already, which suggest a warm-reboot which we want to
    //      treat as a cold roboot => upload EzUsb firmware, but no re-enumeration
    *pReEnumerate = FALSE;

    IsEzUsbFwLoaded = EzUsbIsFirmwareLoaded(pDvcData);
    IsPldFwLoaded = FALSE;
    if (IsEzUsbFwLoaded && !(pDvcData->m_DevInfo.m_TypeNumber>=300
                                                 && pDvcData->m_DevInfo.m_TypeNumber<400))
        IsPldFwLoaded = DtuPldIsFirmwareLoaded(pDvcData);
    if (!IsEzUsbFwLoaded || IsPldFwLoaded)
    {
        if (IsPldFwLoaded)
            DtDbgOut(MIN, DTU, "PLD FW is already loaded => warm reboot");
        else
            DtDbgOut(MIN, DTU, "No EzUsb firmware loaded => cold reboot");

        if (pDvcData->m_DevInfo.m_TypeNumber>=300 && pDvcData->m_DevInfo.m_TypeNumber<400)
        {
            // Lookup firmware
            const DtuFx3HexRecord*  pFx3Firmware = Dtu3GetFx3Firmware(
                                                pDvcData->m_DevInfo.m_TypeNumber,
                                                -1,
                                                pDvcData->m_DevInfo.m_HardwareRevision);
            if (pFx3Firmware == NULL)
                DtDbgOut(ERR, DTU, "FX3 firmware not found for Typenumber: %d,"
                                                                     " HardwareRev: 0x%X",
                                                  pDvcData->m_DevInfo.m_TypeNumber,
                                                  pDvcData->m_DevInfo.m_HardwareRevision);

            if (!DtUsbManufNameEq(&pDvcData->m_Device, "Cypress"))
            {
                DtDbgOut(ERR, DTU, "DTU-3XX vid/pid found but wrong manufacturer string");
                return DT_STATUS_FAIL;
            }
            if (pDvcData->m_DevInfo.m_ProductId == DTU3_PID_UNIT_EEPROM)
                pDvcData->m_BootState = DTU_BOOTSTATE_FACTORY_COLD;
            else
                pDvcData->m_BootState = DTU_BOOTSTATE_COLD;

            //TODOTM: verify product string is "DTU-351"

            // Upload firmware for EzUsb chip
            Status = EzUsbLoadFirmwareFx3(pDvcData, pFx3Firmware);
            if (!DT_SUCCESS(Status))
            {
                DtDbgOut(ERR, DTU, "Failed to upload FX3 firmware (Status=0x%08X)", Status);
                return Status;
            }
            DtDbgOut(ERR, DTU, "FX3 firmware uploaded");
        } else {
            // Lookup firmware
            pEzUsbFirmware = DtuGetEzUsbFirmware(pDvcData->m_DevInfo.m_ProductId,
                                                  -1,
                                                  pDvcData->m_DevInfo.m_HardwareRevision);
            if (pEzUsbFirmware == NULL)
            {
                DtDbgOut(ERR, DTU, "No EzUsb firmware available for DTU-%d", 
                                                            pDvcData->m_DevInfo.m_TypeNumber);
                return DT_STATUS_FAIL;
            }

            // Upload firmware for EzUsb chip
            Status = EzUsbLoadFirmware(pDvcData, pEzUsbFirmware);
            if (!DT_SUCCESS(Status))
            {
                DtDbgOut(ERR, DTU, "Failed to upload FX2 firmware (Status=0x%08X)", Status);
                return Status;
            }
        }

        *pReEnumerate = !IsPldFwLoaded;   // Device will reenumerate, if cold reboot
        if (!IsPldFwLoaded)
            return DT_STATUS_OK;  // In case of cold reboot we are done (will reenumerate)
    }

    // Convert endpoint to pipe numbers
    if (FirmwareEndpoint != -1)
    {
        // Convert endpoint to pipe number
        pDvcData->m_EzUsb.m_FirmwarePipe = DtUsbGetBulkPipeNumber(&pDvcData->m_Device,
                                                 DT_USB_HOST_TO_DEVICE, FirmwareEndpoint);
        DT_ASSERT(pDvcData->m_EzUsb.m_FirmwarePipe != -1);
    }
    
    if (ReadEndpoint != -1)
    {
        // Convert endpoint to pipe number
        pDvcData->m_EzUsb.m_ReadPipe = DtUsbGetBulkPipeNumber(&pDvcData->m_Device,
                                 DT_USB_DEVICE_TO_HOST, ReadEndpoint);
        DT_ASSERT(pDvcData->m_EzUsb.m_ReadPipe != -1);
    }
    
    if (WriteEndpoint != -1)
    {
        // Convert endpoint to pipe number
        pDvcData->m_EzUsb.m_WritePipe = DtUsbGetBulkPipeNumber(&pDvcData->m_Device,
                                DT_USB_HOST_TO_DEVICE, WriteEndpoint);
        DT_ASSERT(pDvcData->m_EzUsb.m_WritePipe != -1);
    }

    return Status;
}
Esempio n. 30
0
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DtuLoadDemodFirmware -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
//
DtStatus  DtuLoadDemodFirmware(
    DtuDeviceData*  pDvcData, 
    const DtuDemodFirmwareStore*  pDemodFirmware)
{
    DtStatus  Status = DT_STATUS_OK;
    UInt8  Buffer[2];
    Int  i, j;
    UInt DvcAddr = pDemodFirmware->m_DemodI2cAddress;
    
    DT_ASSERT(pDemodFirmware != NULL);
    
    // First do the PRE-upload register writes
    if (pDemodFirmware->m_pPreUpload != NULL)
    {
        const DtuInitRegisterStruct*  pInitRegisterData = pDemodFirmware->m_pPreUpload;

        for (i=0; i<pInitRegisterData->m_RegisterDataCount; i++)
        {
            Buffer[0] = pInitRegisterData->m_RegData[i].m_Data[0];
            Buffer[1] = pInitRegisterData->m_RegData[i].m_Data[1];
            Status = DtuI2cWrite(pDvcData, NULL, DvcAddr, 2, Buffer);
            if (!DT_SUCCESS(Status))
            {
                DtDbgOut(ERR, DTU, "Error writing I2C pre-upload data. (Status=0x%08X)",
                                                                                  Status);
                return Status;
            }
        }
    }

    // Upload demodulator firmware
    if (pDemodFirmware->m_pFirmware != NULL)
    {
        const Int  MAX_BYTES_TO_TRY = 60;
        UInt8  AddrHigh;
        UInt8  AddrLow;
        Int  DataCount;
        Int  BytesToTry;
        const DtuHexStruct* pFirmware = pDemodFirmware->m_pFirmware;
        UInt8* pHexData=NULL;

        // First allocate memory for temporary helper buffer
        pHexData = DtMemAllocPool(DtPoolNonPaged, 4096, DTU_TAG);
        if (pHexData == NULL)
            return DT_STATUS_OUT_OF_MEMORY;
    
        for (i=0; i<pFirmware->m_HexBlockCount; i++)
        {
            const DtuHexBlockStruct*  pHexBlock = &(pFirmware->m_HexBlock[i]);
            DataCount = pHexBlock->m_DataCount;

            BytesToTry = 0;

            while (DataCount > 0)
            {
                AddrHigh = (UInt8)((pHexBlock->m_Address +
                                                  pHexBlock->m_DataCount-DataCount) >> 8);
                AddrLow = (UInt8)(pHexBlock->m_Address +
                                                        pHexBlock->m_DataCount-DataCount);
                // Write high address
                Buffer[0] = (UInt8)pDemodFirmware->m_AddrRegH;
                Buffer[1] = AddrHigh;
                Status = DtuI2cWrite(pDvcData, NULL, DvcAddr, 2, Buffer);
                if (!DT_SUCCESS(Status))
                {
                    DtDbgOut(ERR, DTU, "Error writing I2C high address. (Status=0x%08X)",
                                                                                  Status);
                    DtMemFreePool(pHexData, DTU_TAG);
                    return Status;
                }

                // Write low address
                Buffer[0] = (UInt8)pDemodFirmware->m_AddrRegL;
                Buffer[1] = AddrLow;
                Status = DtuI2cWrite(pDvcData, NULL, DvcAddr, 2, Buffer);
                if (!DT_SUCCESS(Status))
                {
                    DtDbgOut(ERR, DTU, "Error writing I2C low address. (Status=0x%08X)",
                                                                                  Status);
                    DtMemFreePool(pHexData, DTU_TAG);
                    return Status;
                }

                // Write data
                pHexData[0] = (UInt8)pDemodFirmware->m_DataReg;
                BytesToTry = (DataCount<=MAX_BYTES_TO_TRY ? DataCount : MAX_BYTES_TO_TRY);
                for (j=0; j<BytesToTry; j++) 
                    pHexData[j + 1] = pHexBlock->m_Data[j + pHexBlock->m_DataCount - 
                                                                               DataCount];
                Status = DtuI2cWrite(pDvcData, NULL, DvcAddr, BytesToTry+1, pHexData);
                if (!DT_SUCCESS(Status))
                {
                    DtDbgOut(ERR, DTU, "Error writing I2C data. (Status=0x%08X)", Status);
                    DtMemFreePool(pHexData, DTU_TAG);
                    return Status;
                }
                DataCount -= BytesToTry;
            }

        }
        DtMemFreePool(pHexData, DTU_TAG);
    }

    // Do the STOP-upload register writes
    if (pDemodFirmware->m_pStopUpload != NULL)
    {
        const DtuInitRegisterStruct*  pInitRegisterData = pDemodFirmware->m_pStopUpload;

        for (i=0; i<pInitRegisterData->m_RegisterDataCount; i++)
        {
            Buffer[0] = pInitRegisterData->m_RegData[i].m_Data[0];
            Buffer[1] = pInitRegisterData->m_RegData[i].m_Data[1];
            Status = DtuI2cWrite(pDvcData, NULL, DvcAddr, 2, Buffer);
            if (!DT_SUCCESS(Status))
            {
                DtDbgOut(ERR, DTU, "Error writing I2C stop-upload data. (Status=0x%08X)",
                                                                                  Status);
                return Status;
            }
        }
    }

    // Wait until AP is running
    if (pDemodFirmware->m_pFirmware != NULL)
    {   
        Int  TimeOut;
        Buffer[0] = (UInt8)pDemodFirmware->m_ApStatReg;
        Status = DtuI2cWrite(pDvcData, NULL, DvcAddr, 1, Buffer);
        if (!DT_SUCCESS(Status))
        {
            DtDbgOut(ERR, DTU, "Error writing I2C apstat data. (Status=0x%08X)", Status);
            return Status;
        }

        // Wait until ready
        Buffer[0] = 1;
        TimeOut = 0;
        while (Buffer[0]==1 && TimeOut<250) // Wait max. 250ms
        {
            DtSleep(10);
            TimeOut += 10;
            // Read the app status
            Status = DtuI2cRead(pDvcData, NULL, DvcAddr, 1, Buffer);
            if (!DT_SUCCESS(Status))
            {
                DtDbgOut(ERR, DTU, "Error reading I2C apstat data. (Status=0x%08X)",
                                                                                  Status);
                return Status;
            }
        }
        if (Buffer[0] == 1)
        {
            DtDbgOut(ERR, DTU, "TIMEOUT! APSTAT = %x.", (Int)(Buffer[0]));
        }
    }

    //Do the post-upload register writes
    if (pDemodFirmware->m_pPostUpload != NULL)
    {
        const DtuInitRegisterStruct*  pInitRegisterData = pDemodFirmware->m_pPostUpload;

        for (i=0; i<pInitRegisterData->m_RegisterDataCount; i++)
        {
            Buffer[0] = pInitRegisterData->m_RegData[i].m_Data[0];
            Buffer[1] = pInitRegisterData->m_RegData[i].m_Data[1];
            Status = DtuI2cWrite(pDvcData, NULL, DvcAddr, 2, Buffer);
            if (!DT_SUCCESS(Status))
            {
                DtDbgOut(ERR, DTU, "Error writing I2C post-upload data. (Status=0x%08X)",
                                                                                  Status);
                return Status;
            }
        }
    }
    return Status;
}