⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 syncregio.cpp

📁 完整的基于Conxant平台的USB电视棒的WIN驱动程序。
💻 CPP
📖 第 1 页 / 共 2 页
字号:
            writeDword(DL_CTL, dl_control);

            //Note: Evidently the firmware upload succeeds only if I read the values back
            // after every write.
            DWORD value;
            readDword(DL_CTL, &value);

            DWORD retries = 0;
            const DWORD MAX_RETRIES = 5;
            //The upper bits of the address byte are ignored, so we don't care
            // what is in them.
            while((value & 0xFFFF3FFF) != (dl_control & 0xFFFF3FFF))
            {
                if(retries >= MAX_RETRIES)
                {
                    DbgLogError((
                        "Failed to write Merlin firmware byte. written = %x, read = %x",
                        dl_control, value));
                    status = STATUS_UNSUCCESSFUL;
                }


                //Check if we can correct the byte by changing the address.  We can
                // only write the lower byte of the address.

                if((value & 0x3F00) == (dl_control & 0x3F00))
                {

                    //Write again
                    writeDword(DL_CTL, dl_control);

                    //Read back to see if it is accurate.
                    readDword(DL_CTL, &value);
                    retries++;

                }
                else
                {
                    status = STATUS_UNSUCCESSFUL;
                }

                if(!NT_SUCCESS(status))
                {
                    //Break if we failed.
                    break;
                }
            }
        }
    }

    //We were successful if we dropped out of the loop at the end of the file.
    if(status == STATUS_END_OF_FILE) status = STATUS_SUCCESS;

    if(status == STATUS_SUCCESS)
    {
        if(!_firmware_stop_reasons)
        {
            //Take the 8051 out of reset and enable firmware execution
            writeDword(DL_CTL, 0x13000000 | address);

            _firmware_state = FIRMWARE_STATE_ENABLED;
        }
        else
        {
            _firmware_state = FIRMWARE_STATE_STOPPED;
        }
    }

    unlock();

    return status;
}
*/

NTSTATUS SyncRegIo::writeAudioFirmware(HANDLE file_handle,DWORD rev_id)
{
    lock();
    LARGE_INTEGER start;
    LARGE_INTEGER end;
    RtlZeroMemory((PVOID)&start, sizeof(start));
    RtlZeroMemory((PVOID)&end, sizeof(end));
    KeQuerySystemTime(&start);
    
    //Put the 8051 in reset and enable firmware upload
    writeByte(DL_CTL_CONTROL, 0xB);
    
    //Turn off Mako's auto increment feature so we can write to the same register 
    // multiple times.
    BYTE value;
    readByte(HOST_REG1, &value);
    writeByte(HOST_REG1, value | 0x20);
	
    //Write the address of zero to the firmware upload register
    writeByte(DL_CTL_ADDRESS_HIGH, 0);
    writeByte(DL_CTL_ADDRESS_LOW, 0);
	
    NTSTATUS status = STATUS_SUCCESS;
    NTSTATUS i2cstatus = STATUS_SUCCESS;
	
    IO_STATUS_BLOCK status_block;

    ULONG write_size =0;
    if(rev_id >=POLARIS_REVID_A0)
    {
        write_size = TRANSFER_SIZE_A0; 
        
    }
    else if(rev_id == POLARIS_REVID_T0)
    {
        write_size = TRANSFER_SIZE_T0; 
    }
    else
    {
        status = STATUS_UNSUCCESSFUL;
        unlock(); 
        return status;        
    }

    DWORD address = 0;
    DWORD data=0;
    //ALLOCATED_BUFFER_SIZE should be multiples of 4B.
    const DWORD ALLOCATED_BUFFER_SIZE = 256;
    BYTE* p_buffer=NULL;
    BYTE* p_data=NULL;
    p_buffer = new BYTE[ALLOCATED_BUFFER_SIZE]; 
    
    if(p_buffer==NULL)
    {
        unlock();
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    BOOLEAN first_write=TRUE;
    ULONG last_data=0;
    ULONG write_byte =0;

    while(status == STATUS_SUCCESS)
    {
        RtlZeroMemory((PVOID)p_buffer,ALLOCATED_BUFFER_SIZE);
        status = ZwReadFile(
            file_handle,       //file handle
            NULL,               //event
            NULL,               //apc routine
            NULL,               //apc context
            &status_block,      // io status block
            p_buffer,              //buffer
            ALLOCATED_BUFFER_SIZE,              //Size of buffer
            NULL,               //Offset in the file to read
            NULL);              //key 

        if(NT_SUCCESS(status))  
        {  
            ULONG_PTR buffer_size = status_block.Information;             
            p_data = p_buffer;
            ULONG buffer_byte = (ULONG)buffer_size;
            while(buffer_size >= write_size)
            {
                if(rev_id >=POLARIS_REVID_A0)
                {            
                    if(first_write==TRUE)
                    {
                        first_write=FALSE;
                        i2cstatus = setCommandFormat(TRUE,FALSE);//first time write to the address
                    }
                    else
                    {
                        last_data = (ULONG)buffer_size-write_size;
                        if(last_data==0&&buffer_byte<ALLOCATED_BUFFER_SIZE) 
                        {	                   
                            i2cstatus = setCommandFormat(FALSE,TRUE);//the last time write to the address                   
                        }
                        else
                        {                  
                            i2cstatus = setCommandFormat(FALSE,FALSE);//middle time write to the address                    
                        }
                    }
                }

                if(!NT_SUCCESS(i2cstatus))
                {
                    status = STATUS_UNSUCCESSFUL;
                }
                else
                {                					
                    if (!NT_SUCCESS(writeMultiByte(DL_CTL_DATA, p_data,write_size)))
                    {
                        if(rev_id >=POLARIS_REVID_A0)//change to common format
                        {
                            setCommandFormat(TRUE,TRUE);
                        }
                        DbgLogError(("I2C transcation failed. Bailing out !!!\n"));
                        //we failed I2C transaction - no point in writing any further. Bail out
                        status = STATUS_UNSUCCESSFUL;
                    }  
                }
                write_byte+=write_size;    
                buffer_size-=write_size;
                p_data+=write_size;
            }
            while((buffer_size<write_size) && (buffer_size>0))
            {  
                if(rev_id >=POLARIS_REVID_A0)
                {
                    if(buffer_size==1)
                    {
                        i2cstatus = setCommandFormat(FALSE,TRUE);// the last time write to the address                 
                    }
                    else
                    {            
                        i2cstatus = setCommandFormat(FALSE,FALSE); //middle time               
                    }
                }
                if(!NT_SUCCESS(i2cstatus))
                {
                    status = STATUS_UNSUCCESSFUL;
                }
                else
                {     
                    if (!NT_SUCCESS(writeByte(DL_CTL_DATA, *p_data))) 
                    {
                        if(rev_id >=POLARIS_REVID_A0)
                        {
                            setCommandFormat(TRUE,TRUE);
                        }
                        DbgLogError(("I2C transcation failed. Bailing out !!!\n"));
                        //we failed I2C transaction - no point in writing any further. Bail out
                        status = STATUS_UNSUCCESSFUL;
                    } 
                }
                write_byte+=1;
                buffer_size--;
                p_data++;      
            }             
        }		
    }

    delete [] p_buffer;

    //We were successful if we dropped out of the loop at the end of the file.
    if(status == STATUS_END_OF_FILE)
    {
        status = STATUS_SUCCESS;
    }
    else
    {
        DbgLogError(("writeAudioFirmware failed, status = %lx\n",status));
    }
    DbgLog(("merlin firmware have load %0x\n",write_byte));
    if(rev_id >=POLARIS_REVID_A0)
    {
        i2cstatus = setCommandFormat(TRUE,TRUE);//change to common format
    }

    if(!NT_SUCCESS(i2cstatus))
    {
        status = STATUS_UNSUCCESSFUL;
        unlock(); 
        return status;        
    }
    
    //Turn on Mako's auto increment feature
    readByte(HOST_REG1, &value);
    writeByte(HOST_REG1, value & 0xDF);

    DWORD dl_ctrl = 0xFF;
    readDword(DL_CTL, &dl_ctrl);
    dl_ctrl &= 0x00FFFFFF;
    dl_ctrl |= 0x3000000;

    //do not enable 8051 but disable auto increment on read and disable download
    writeDword(DL_CTL, dl_ctrl);
	
    // Default to firmware stopped, Only enable firmware based on crossbar switching to tuner
    _firmware_state = FIRMWARE_STATE_STOPPED;
    
    KeQuerySystemTime(&end);
    DbgLog(("writeAudioFirmware time cost:%d\n", end.QuadPart-start.QuadPart));


	
    unlock(); 
    return status;
}

/////////////////////////////////////////////////////////////////////////////////////////

VOID SyncRegIo::verifyAudioFirmware(HANDLE file_handle)
{
    DbgLog(("****Verifying every byte of audio firmware **** \n"));

    lock();

    DWORD dl_ctrl = 0xFF;
    readDword(DL_CTL, &dl_ctrl);

    dl_ctrl &= 0x00FFFFFF;
    dl_ctrl |= 0x0F000000;

    //Put the 8051 in reset and enable firmware upload
    writeDword(DL_CTL, dl_ctrl);

    //Read DL_CTL until the address gets to 0
    while(dl_ctrl & 0x3FFF)
    {

        //we failed I2C transaction - no point in writing any further. Bail out
        if (!NT_SUCCESS(readDword(DL_CTL, &dl_ctrl)))
        {
            DbgLogError(("Firmware verify failed - I2C transcation failed. Bailing out !!!\n"));
            return;
        }
    }


    //Now get the data bytes from the file one at a time
    NTSTATUS status = STATUS_SUCCESS;
    IO_STATUS_BLOCK status_block;
    DWORD address = 0;

    while(status == STATUS_SUCCESS)
    {
        BYTE data;

        status = ZwReadFile(
            file_handle,       //file handle
            NULL,               //event
            NULL,               //apc routine
            NULL,               //apc context
            &status_block,      // io status block
            &data,              //buffer
            1,                  //Size of buffer
            NULL,               //Offset in the file to read
            NULL);              //key

        if(NT_SUCCESS(status))
        {
            DWORD address2 = dl_ctrl & 0x3FFF;

            if(address != address2)
            {
                DbgLog(("Address is incorrect.  Address in DL_CTL = %x, Should be %x\n",
                    address2, address));
                break;
            }

            DWORD data2 = ((dl_ctrl & 0x00FF0000) >> 16);

            if(data != data2)
            {
                DbgLog(("Data is incorrect.  Address = %x, data = %x, should be %x\n",
                    address, data2, data));
                break;
            }

            readDword(DL_CTL, &dl_ctrl);
            address++;
        }
        else
        {
            if (status != STATUS_END_OF_FILE)
                DbgLogError(("Firmware verify ZwReadFile error status %lx\n",status));
        }
    }

    //We were successful if we dropped out of the loop at the end of the file.
    if(status == STATUS_END_OF_FILE)
    {
        DbgLog(("Firmware verify successful\n"));
        status = STATUS_SUCCESS;
    }
    else
    {
        DbgLogError(("Firmware verify failed\n"));
        status = STATUS_SUCCESS;
    }

    dl_ctrl &= 0x00FFFFFF;
    dl_ctrl |= 0x3000000;

    //do not enable 8051 but disable auto increment on read and disable download
    writeDword(DL_CTL, dl_ctrl);


#if 0 // Only enable firmware based on crossbar switching to tuner
    if(status == STATUS_SUCCESS)
    {
        if(!_firmware_stop_reasons)
        {
            //Take the 8051 out of reset and enable firmware execution
            writeDword(DL_CTL, FLD_START_8051 | FLD_DL_MAP | address);

            _firmware_state = FIRMWARE_STATE_ENABLED;
        }
        else
        {
            _firmware_state = FIRMWARE_STATE_STOPPED;
        }
    }
#endif

    unlock();
}

NTSTATUS SyncRegIo::RegMaskWrite(BYTE size, WORD register_address,BYTE bit_start,BYTE bit_end, DWORD value)
{

    if (bit_start>(size-1) || bit_end>(size-1))
    {
        return STATUS_UNSUCCESSFUL;
    }

    CHAR tmp[4] = {0,};
    NTSTATUS status = STATUS_SUCCESS;
    if (size==8)
    {
        status = readByte(register_address, (PBYTE)tmp);
    }
    else
    {
        status = readDword(register_address, (PDWORD)tmp);
    }

    if (!NT_SUCCESS(status))
    {
        return status;
    }

    DWORD mask = 1<<bit_end;
    for (int i=bit_end; i>bit_start&&i>0; i--)
    {
        mask = mask + (1<<(i-1));
    }

    value <<= bit_start;

    if (size==8)
    {
        (*(PBYTE)tmp) = (*(PBYTE)tmp) & ((BYTE)~mask);
        (*(PBYTE)tmp) = (*(PBYTE)tmp) | ((BYTE)value);
        status = writeByte(register_address, (*(PBYTE)tmp));
    }
    else
    {
        (*(PDWORD)tmp) = (*(PDWORD)tmp) & ((DWORD)~mask);
        (*(PDWORD)tmp) = (*(PDWORD)tmp) | ((DWORD)value);
        status = writeDword(register_address, (*(PDWORD)tmp));
    }

    return status;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -