Chciałbym zaprezentować rozwinięcie eksperymentalnego odbiornika SDR, jaki opisałem ostatnio: Link. Wówczas zastosowałem głowicę z tunera DVB-T z układem R820T. Tym razem jednak zdecydowałem się uruchomić inny układ tj. MxL5007T. Układ ten występuje w tunerze DVB-T02 firmy Manta, który szerzej opisałem pod koniec zeszłego roku: Link. Płyta tunera jest przedstawiona na poniższych zdjęciach:
Najbardziej w tym momencie interesującym fragmentem płyty jest głowica:
Znaleźć tu można układ MxL5007T:
Teraz pojawia się podstawowy problem. Brak jest datasheet tego układu. To, co jest dostępne stanowi tylko skrótowy opis funkcjonalności MxL5007T. Nie ma nawet opisu wyprowadzeń czy rejestrów programowanych przez I2C. Można jednak znaleźć bardzo uproszczony schemat blokowy:
Wynika z tego, że jest to układ o podwójnej przemianie częstotliwości. Można zaprogramować różne częstotliwości pośrednie i szerokości pasma dla toru p.cz. Wzmocnienie ma być zadawane zewnętrznym napięciem Vagc. Zgodnie z opisem ma być też wewnętrzne ARW (AGC). Zatem mamy tu wielopoziomowe ARW, z tą różnicą, że w R820T są trzy poziomy ARW, tu zaś tylko dwa. Jest też wspomniany opis:
Początkowo poszukiwałem w Google chociaż jakiegoś kodu drivera do MxL5007T. Łatwo coś znaleźć na Githubie: Link. Byłoby sporo pracy, by przeprotować ten kod (Linux) pod STM32. Widać też, że ktoś uruchomił ten układ pod Arduino - jest nawet dostępna biblioteka: Link. Przeportowanie tego kodu jest bardzo łatwe. Ciekawe materiały w Google o takich układach można znaleźć po zmianie języka wyszukiwania na chiński. W ten sposób znalazłem wręcz "Święty Graal": Link. Jest to oryginalny driver dla MxL5007, jaki przygotował producent układu! Zatem jest już niezła baza odnośnie kodu. Wciąż jednak brak opisu wyprowadzeń. Na tej samej chińskiej stronie znalazłem schemat tunera na MSD7818 (na tym chipsecie jest oparty DVB-T02). Założyłem, że może tam być MxL5007T. Tak jest faktycznie:
Widzimy tu fragment schematu z głowicą. Powinno to wystarczyć do uruchomienia MxL5007T. Wstępnie jednak trzeba rozpracować płytę, czyli znaleźć punkty do jakich można dołączyć STM32. Potrzeba więc zlokalizować I2C (SDA i SCL), VAGC (zmiana wzmocnienia), +3,3V (zasilanie) oraz wyjście p.cz. IF_OUT_P i IF_OUT_N. Należy to zrobić omomierzem wg powyższego schematu. Poniżej to, co udało się ustalić:
Większość łatwo można znaleźć. Najtrudniej było z ARW i zasilaniem. To ostatnie stanowi ścieżkę idącą pod trzema kondensatorami (prowizorycznie trzeba je było wylutować):
Najprościej byłoby oczywiście wyciąć głowicę z całej płyty, ale szkoda mi było tego tunera. Wciąż można coś zrobić z MSD7818. Na chińskich stronach można sporo znaleźć o platformie MSTAR. Postanowiłem więc przerobić tuner tak, by dało się odciąć MxL5007T od reszty układu za pomocą zworek i zasilić go z zewnątrz. Dodałem też dodatkowe kołki, by ułatwić dołączanie oscyloskopu i analizatora stanów logicznych. Powstało coś takiego:
Dodałem dodatkowe płytki uniwersalne lutowane do złącza HDMI, pól masy na płycie i ekranu głowicy. Okazało się to być całkiem wygodne. Część elementów trzeba było oczywiście odlutować z płyty tunera. Obecnie można wstawić zworki i wszystko działa tak samo jak przedtem. Sprawdzenie tunera:
Wykorzystałem przedstawiony z prawej strony USB Grabber. Można tym przechwytywać analogowy sygnał composite video. Od strony komputera PC USB Grabber jest zainstalowany jako zwykła kamera "internetowa". Tuner działał poprawnie. Jak widać na zdjęciu taki tuner łatwo jest zasilić z zewnętrznego zasilacza. Wystarczy podać +5 V na katodę diody w prostowniku zasilacza flyback. Udało się nawet coś odebrać na MUX-8 (prawie brak możliwości odbioru - słaby sygnał w Grudziądzu):
Są to obrazy uzyskane z USB Grabbera, który to był dołączony do wyjścia composite viedo w tunerze. W dalszej kolejności można sprawdzić konsolę UART. Podczas startu i bootowania jest coś takiego z dołączonym MxL5007T:
Spoiler:
UART_115200
BIST0-OK
_snPDMDrv_PM_RtcGetCounter(CurrentCounter=0)
Hello U-Boot
U-Boot 1.1.6 (Jul 19 2012 - 03:28:39)
Board: MSTAR KRNOUS (CPU Speed 552 MHz)
DRAM: 64 X 0 MBytes
U-Boot is running at DRAM 0x87600000
###############BOARD CONFIGURATION#####################
DEFAULT ENBALE L2-Cache
FPU(ENABLE)
DDR_FREQUENCY(1066MHz)
###############BOARD CONFIGURATION#####################
Module: USB FAT FLASH SPI LOGO OSD ENV=SERIAL
Flash is detected (0x0703, 0xEF, 0x40, 0x16)
MDrv_SERFLASH_GetInfo()
u32AccessWidth = 1
u32TotalSize = 4194304
u32SecNum = 64
u32SecSize = 65536
In: serial
Out: serial
Err: serial
MSVC00B000100100208768TH0000000T
[do_set_paneltype][768] is invoked!!
MDrv_PNL_Init u32PnlRiuBaseAddr = BF200000
MDrv_PNL_Init u32PMRiuBaseAddr = BF000000
MDrv_HDMITx_Init
Get IOMAP ID:300 Base:BF000000!
MDrv_HDMITx_SetHDMITxMode: HDMI mode
DAC eTiming =6
MDrv_HDMITx_SetHDMITxMode: HDMI mode
HDMITx eTiming =7
MDrv_HDMITx_Exhibit: Create Check Rx timer success!
HDMITx eTiming =7
boot_logo=>cmd: spi_rdc 0x80B2C000 0x70000 0x8930
offset 0x70000, size 0x8930
WARNING: it is better to set dram start addr aligned to 65536 !!!
WARNING: it is better to set total length aligned to 65536 !!!
Flash is detected (0x0703, 0xEF, 0x40, 0x16)
initialization done!
u32ReadBuffVirAddr = A0000000, u32IntBuffVirAddr = A0100000, u32OutBuffVirAddr = A0730000
verJPD_SetStatus >>>>>>>>>>> w:720, h:576, p:720
spi_rdc 0x80B00000 0x20000 0x1000
offset 0x20000, size 0x1000
WARNING: it is better to set total length aligned to 65536 !!!
cmd spi_rdc 0x80B00000 0x20000 0x1000 success
u32UbootInfoAddr: 0x7892F
K1_INFO_ADDR: 0x80000
spi_rdc 0x80B00000 0x80000 0x1000
offset 0x80000, size 0x1000
WARNING: it is better to set total length aligned to 65536 !!!
cmd spi_rdc 0x80B00000 0x80000 0x1000 success
u32LogoMagicFlag ERROR !! return GOP_BUFFER_ADDR
GE_SetOnePixelMode
Hit any key to stop autoboot: 0
Kronus 128-pin package
Check USB port[0]:
??? Waiting for Peripheral Connecting Fail...
usb init failed
Error, couldn't init Lowlevel part
Kronus 128-pin package
Check USB port[1]:
??? Waiting for Peripheral Connecting Fail...
usb init failed
Error, couldn't init Lowlevel part
Kronus 128-pin package
Check USB port[2]:
??? Waiting for Peripheral Connecting Fail...
usb init failed
Error, couldn't init Lowlevel part
WDT Initialize ...
Start 75F2000 End 769E000
UnProtect MIU block 0 : 0x75F2000 0x769E000
offset 0x8001C, size 0x2839B3
WARNING: it is better to set flash start addr aligned to 65536 !!!
WARNING: it is better to set total length aligned to 65536 !!!
in=0x80B00000, in_size=0x2839B3, out= 0x80000180, alloc_buf = 0x81000000
in=0x80B00000, in_size=0x2839B3, out= 0x80000180, alloc_buf = 0x81000000
in_size=2636211 out_size=7234292 unpack_size=0
LZMA Decompression...CRC_result F1E891C2 CRC_value F1E891C2
CRC check success !!
ok
## Starting application at 0x80000224 ...
[cyg_net_init] Init: mbinit(0x00000000)
[cyg_net_init] Init: cyg_net_init_devs(0x00000000)
Init device 'pcnet_eth0'
[cyg_net_init] Init: loopattach(0x00000000)
[cyg_net_init] Init: ifinit(0x00000000)
[cyg_net_init] Init: domaininit(0x00000000)
[cyg_net_init] Init: cyg_net_add_domain(0x8068f568)
New domain internet at 0x00000000
[cyg_net_init] Init: cyg_net_add_domain(0x8068f130)
New domain route at 0x00000000
[cyg_net_init] Init: call_route_init(0x00000000)
[cyg_net_init] Done
[SysInit][1972]
[SysInit][1974]
****** Customer_info:Before ******
0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,
0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,
0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,
0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,
0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,
0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,
abcdef => 0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,
ABCDEF => 0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,
****** Customer_info ******
0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,
0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,
0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,
0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,
0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,
0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,[SysInit][1976]
Customer info: 00660630002f000000000000000000000000000408f81800
Hash: 57896ceada56f7bbb0af9151e38029b1
Auth OK
[SysInit][1978]
Hardware Initialize...
MDrv_MIOMap_Init
[HAL_MIU_SetPMIOMapBase][1107] Non implement for MIU _gPM_MapBase= bf000000
MsOS_Init
_MApi_SystemInit_CreateMemoryPool
upoolSize = 320000 and u32Addr = 90F958
mdrv_gpio_init
[SysInit][1987]
MIU Initialize...
Get IOMap u32NonPmBase = 0xbf200000
Get IOMap u32PmBase = 0xbf000000
Disable MIU1
[SysInit][1995]
WDT_Init
[SysInit][2002]
[SysInit][2005]
MDrv_WDT_IsReset = 0
[SysInit][2011]
[MAPI_MEMINFO] DVBC System Memory Usage
[MAPI_MEMINFO] ============================ START END SIZE
[MAPI_MEMINFO] POOL_START 0x00000000 0x016ce800 0x016ce800
[MAPI_MEMINFO] Cached Pool Start 0x0090f958 0x00c2f958 0x00320000
[MAPI_MEMINFO] NONCACHED_POOL_START 0x00c2f958 0x016ce800 0x00a9eea8
[MAPI_MEMINFO]
[MAPI_MEMINFO] Memory Layout:
[MAPI_MEMINFO] ============================ START END SIZE
[MAPI_MEMINFO] XC_MEM_START 0x03d00000 0x04000000 0x00300000
[MAPI_MEMINFO] MAD_MEM_START 0x03a00000 0x03d00000 0x00300000
[MAPI_MEMINFO] MVD_MEM_START 0x01d00000 0x03a00000 0x01d00000
[MAPI_MEMINFO] VE_MEM_START 0x01b60000 0x01d00000 0x001a0000
[MAPI_MEMINFO] GOP_DMAMEM_START 0x01b5f000 0x01b60000 0x00001000
[MAPI_MEMINFO] TSP_VQ_START 0x01b5e000 0x01b5f000 0x00001000
[MAPI_MEMINFO] PM51_MEM_ADR 0x01b5dc00 0x01b5e000 0x00000400
[MAPI_MEMINFO] PM51_VAR_MEM_ADR 0x01b5d800 0x01b5dc00 0x00000400
[MAPI_MEMINFO] GOP_GWINMEM_START 0x016ce800 0x01b59800 0x0048b000
[MAPI_MEMINFO] pFirstAvailableMemory 0x8090f958
[SysInit][2015]
[SysInit][2024]
Hello Hummingbird!!
_appDemo_Task.iId = 1985216513
----------Hello World----------
-------Welcome to Demo AP------
>> [_SysInit_InitAPI][1691]SPI Flash Driver Init !!
Flash is detected (0x0703, 0xEF, 0x40, 0x16)
[HAL_AUDIO_AllocateVars], init Shared
>>
HAL_MAD_SetMemInfo[DSP_DEC] = 0x03b00000
HAL_MAD2_SetMemInfo[DSP_SE] = 0x03a00000
[HAL_AUDSP_DspLoadCode], pau_info->cm_len == 0
ADEC Done and do default setting 4
===== Check Audio Decoder Protection from hash-key IP =====
Hash-key Support DD.
Hash-key Support DD+.
This is Demo Mode!!
Hash-key Support Generic HE-AAC !!
===== Check Protection IP End =====
MDrv_SERFLASH_GetInfo()
u32AccessWidth = 1
u32TotalSize = 4194304
u32SecNum = 64
u32SecSize = 65536
Check Boot Logo OK!! logo_cmd [boot_logo 0 0 1 1]
Get Boot Panel Type!!
pEnvStr = set_paneltype 12
ptr = set_paneltype 12
ptr+PANEL_CMD_LENGTH = 12
result = 1
result = 12
g_PNL_TypeSel = 12
eTiming =6
[MSAPI_XC,Version] [0;32m 01.74 00486343
[mMDrv_PNL_Init u32PnlRiuBaseAddr = bf200000
MDrv_PNL_Init u32PMRiuBaseAddr = bf000000
[XC,Version] [0;36m 00489048
[mMDrv_HDMITx_Init
Get IOMAP ID:300 Base:bf000000!
MDrv_HDMITx_SetHDMITxMode: HDMI mode
DAC eTiming =6
MDrv_HDMITx_SetHDMITxMode: HDMI mode
HDMITx eTiming =7
MDrv_HDMITx_Exhibit: Create Check Rx timer success!
Wait V Sync!!
GE_SetOnePixelMode
driver GE init ok
[_SysInit_GEGOP][1263]
[_SysInit_GEGOP][1272]
[_SysInit_GEGOP][1298]driver GOP0 init ok
[_SysInit_GEGOP][1298]driver GOP1 init ok
[_SysInit_GEGOP][1298]driver GOP2 init ok
Path2
Set to Mixer
GE_Init and VE setting done
BASEADDRESS_STRING_DATABASE_IN_FLASH = 00370000
BASEADDRESS_BITMAP_DATABASE_IN_FLASH = 00370000
BASEADDRESS_GENSETTING_IN_FLASH = 00370000
BASEADDRESS_CURRENT_DTV_ORDER_IN_FLASH = 00380000
BASEADDRESS_CH_DATABASE_IN_FLASH = 00390000
BASEADDRESS_MOSAIC_IN_FLASH = 003D0000
BASEADDRESS_TFCA_MAIL_IN_FLASH = 003E0000
NUMBER_OF_CURRENT_DTV_PROGRAM = 00001000
USB init
MDrv_Usb_Init..
Usb init
The base address is 0xA16AE000
Base addr is 0xA16AE000
Top addr is 0xA16BDFFF
Pages per pool is 16
Bit map base addr is 0xa16ad7d0
usb_init start
usb_hcd_cpe_ehci_probe
ehci: 80c2c7c0
hcd: 80c2c7f4
The allocated addr is 0xa16ae000, bit_map[0] is 0xFFFFFFFE
qh: a16ae000, qh->qh_dma: 16ae000
The allocated addr is 0xa16af000, bit_map[0] is 0xFFFFFFFC
The allocated addr is 0xa16b0000, bit_map[0] is 0xFFFFFFF8
qh: 16ae000
usb_new_device
usb_set_address before
usb_set_address after
The allocated addr is 0xa16b1000, bit_map[0] is 0xFFFFFFF0
InitUSBIntr enter
Usb start..
MDrv_Usb_Done ...........UsbTask..
......................................
>>> Allocate Addr = A16AA6C0 , FwPhyAddr = 016AA700
************************ Start TSP_Init ************************
<FWTSP> : >> FwVersion:001B210E , Date:20100918
************************* End TSP_Init *************************
[MApi_SI_System_Startup] OK !!
[AP_NC_Alloc] Size = 1010
[AP_C_Alloc] Size = 6be00
[AP_NC_Alloc] Size = c8cf
MApi_DigiTuner_Init mutex id 1985216537
MDrv_IIC_Init PORT 1
MDrv_IIC_InitPort0: FAIL
MApi_VectorFont_Init total size=3276800, free size=2815824, large size=2815780
alloc mem 0x330c
alloc mem 0x1f14
SysInit done .................................................
into _appMain_Task
[MApp_CheckFlash][1178] s8SN0 = 1
MApi_DB_CM_LoadDTVProgramDatabaseFromFlash -- u16Index[1] [4096]
MApi_DB_CM_InitDTVDataManager: m_eCurrentServiceType = 1
MApi_DB_CM_InitDTVDataManager: m_wCurrentOrderOfTV = 0
MApi_DB_CM_InitDTVDataManager: m_wCurrentOrderOfRadio = 0
MApi_DB_CM_InitDTVDataManager: m_wCurrentOrderOfMosaic = 0
MApi_DB_CM_InitDTVDataManager: m_wCurrentOrderOfNvod_Ref = 0
MApi_DB_CM_InitDTVDataManager: m_wCurrentOrderOfNvod_TimeShifted = 0
MXL5007T SetTuner
MXL5007 SetTuner dwFreq = -1000, ucBw = 8
MxL_RFSynth_Lock_Status = 0xc
RFSynth bLock = 1
REFSynth bLock = 1
Tuner Success
into appMain_AddApp
[ZUI] init: sz_msg_q=6216
fix appTV_GetInfo before using
SCART ON, CVBS ON, RGB ON
[msCHIP_DAC_SetOutputSource][79] input bitmap: 0x00000011
CVBS on
SVIDEO off, YPBPR off, RGB on
SCART on
problem happen
App_GetTVFormat:[0]
tvvideo_SetDCOutputTiming : 0, 1
Check the Source type 6
MDrv_HDMITx_SetAVMUTE
[tvvideo_SetDCOutputTiming][473]: ## Change Resolution ##, eCompType = 6
[msAPI_XC_ReMapComponentType][246]: msAPI_XC eTiming = 6
DAC eTiming =6
MDrv_HDMITx_SetHDMITxMode: HDMI mode
HDMITx eTiming =7
##########$$$$$$$$$$$2into appMain_AddApp
into appMain_AddApp
into appMain_AddApp
[+]MApi_EpgDB_Init
[AP_NC_Alloc] Size = 50
[AP_NC_Alloc] Size = 5
[AP_NC_Alloc] Size = 190
[AP_NC_Alloc] Size = 3e8
[AP_NC_Alloc] Size = b40
[AP_NC_Alloc] Size = 9d80
[AP_NC_Alloc] Size = 14000
[AP_NC_Alloc] Size = 1d4c0
[AP_NC_Alloc] Size = 1f5f40
[AP_NC_Alloc] Size = c8
[AP_NC_Alloc] Size = 2000
[AP_NC_Alloc] Size = 2000
[AP_NC_Alloc] Size = 4e0000
[EPGDB][000692] =========================================================================
[EPGDB][000693] _pu16SrvMappingTable: (Start, End, Length)= (0xa14e2940, 0xa14e2990, 0x00000050)
[EPGDB][000694] _pu8EitBufMask: (Start, End, Length)= (0xa14e2920, 0xa14e2925, 0x00000005)
[EPGDB][000695] _pMapBufIdxTable: (Start, End, Length)= (0xa14e2780, 0xa14e2910, 0x00000190)
[EPGDB][000696] _pu8EpgDbEvtMask (Start, End, Length)= (0xa14e2380, 0xa14e2768, 0x000003e8)
[EPGDB][000697] _pu8EpgDbScheHdrList (Start, End, Length)= (0xa14e1830, 0xa14e2370, 0x00000b40)
[EPGDB][000698] _pu8EpgDbSrvEvtList (Start, End, Length)= (0xa14d7aa0, 0xa14e1820, 0x00009d80)
[EPGDB][000699] _pu8EpgDbSrvSecList (Start, End, Length)= (0xa14c3a90, 0xa14d7a90, 0x00014000)
[EPGDB][000700] _pu8EpgDbEvtHdrList (Start, End, Length)= (0xa14a65c0, 0xa14c3a80, 0x0001d4c0)
[EPGDB][000701] _pu8EpgDbEvtNameList (Start, End, Length)= (0xa12b0670, 0xa14a65b0, 0x001f5f40)
[EPGDB][000702] _pu8EpgDbPfHdrList (Start, End, Length)= (0xa12b0590, 0xa12b0658, 0x000000c8)
[EPGDB][000703] _pu8EpgDbPfPresent (Start, End, Length)= (0xa12ae580, 0xa12b0580, 0x00002000)
[EPGDB][000704] _pu8EpgDbPfFollow (Start, End, Length)= (0xa12ac570, 0xa12ae570, 0x00002000)
[EPGDB][000708] _pu8EpgDbScheExtStrBuf (Start, End, Length)= (0xa0dcc560, 0xa12ac560, 0x004e0000)
[EPGDB][000710] EPG database allocate 0x00716355 bytes
[EPGDB][000716] =========================================================================
[-]MApi_EpgDB_Init
MDrv_SERFLASH_GetInfo()
u32AccessWidth = 1
u32TotalSize = 4194304
u32SecNum = 64
u32SecSize = 65536
MApp_ZUI_ACT_StartupOSD TV_PROG
[MApp_ZUI_ACT_PrepareOSDPage][438]MS_COMPONENT_OUTPUT_TYPE : 6
fix _MApp_ZUI_SetupDisplayList before using
SD: 720 x 576, HD: 960 x 1080
leave MApp_ZUI_API_InitCanvasGDI -> MApp_ZUI_API_GetFontMVF in 131
Set PAL
MDrv_SERFLASH_GetInfo()
u32AccessWidth = 1
u32TotalSize = 4194304
u32SecNum = 64
u32SecSize = 65536
SD Gwin = 4
disp[1]'s FBID = 2
HD Gwin = 0
[MApp_ZUI_ACT_PrepareOSDPage][438]_Zapper_Disable_AV: Enter at 4350.
alloc mem 0x40000
alloc mem 0x2400
alloc mem 0x2000
alloc mem 0x1000
BIST0-OK
_snPDMDrv_PM_RtcGetCounter(CurrentCounter=0)
Hello U-Boot
U-Boot 1.1.6 (Jul 19 2012 - 03:28:39)
Board: MSTAR KRNOUS (CPU Speed 552 MHz)
DRAM: 64 X 0 MBytes
U-Boot is running at DRAM 0x87600000
###############BOARD CONFIGURATION#####################
DEFAULT ENBALE L2-Cache
FPU(ENABLE)
DDR_FREQUENCY(1066MHz)
###############BOARD CONFIGURATION#####################
Module: USB FAT FLASH SPI LOGO OSD ENV=SERIAL
Flash is detected (0x0703, 0xEF, 0x40, 0x16)
MDrv_SERFLASH_GetInfo()
u32AccessWidth = 1
u32TotalSize = 4194304
u32SecNum = 64
u32SecSize = 65536
In: serial
Out: serial
Err: serial
MSVC00B000100100208768TH0000000T
[do_set_paneltype][768] is invoked!!
MDrv_PNL_Init u32PnlRiuBaseAddr = BF200000
MDrv_PNL_Init u32PMRiuBaseAddr = BF000000
MDrv_HDMITx_Init
Get IOMAP ID:300 Base:BF000000!
MDrv_HDMITx_SetHDMITxMode: HDMI mode
DAC eTiming =6
MDrv_HDMITx_SetHDMITxMode: HDMI mode
HDMITx eTiming =7
MDrv_HDMITx_Exhibit: Create Check Rx timer success!
HDMITx eTiming =7
boot_logo=>cmd: spi_rdc 0x80B2C000 0x70000 0x8930
offset 0x70000, size 0x8930
WARNING: it is better to set dram start addr aligned to 65536 !!!
WARNING: it is better to set total length aligned to 65536 !!!
Flash is detected (0x0703, 0xEF, 0x40, 0x16)
initialization done!
u32ReadBuffVirAddr = A0000000, u32IntBuffVirAddr = A0100000, u32OutBuffVirAddr = A0730000
verJPD_SetStatus >>>>>>>>>>> w:720, h:576, p:720
spi_rdc 0x80B00000 0x20000 0x1000
offset 0x20000, size 0x1000
WARNING: it is better to set total length aligned to 65536 !!!
cmd spi_rdc 0x80B00000 0x20000 0x1000 success
u32UbootInfoAddr: 0x7892F
K1_INFO_ADDR: 0x80000
spi_rdc 0x80B00000 0x80000 0x1000
offset 0x80000, size 0x1000
WARNING: it is better to set total length aligned to 65536 !!!
cmd spi_rdc 0x80B00000 0x80000 0x1000 success
u32LogoMagicFlag ERROR !! return GOP_BUFFER_ADDR
GE_SetOnePixelMode
Hit any key to stop autoboot: 0
Kronus 128-pin package
Check USB port[0]:
??? Waiting for Peripheral Connecting Fail...
usb init failed
Error, couldn't init Lowlevel part
Kronus 128-pin package
Check USB port[1]:
??? Waiting for Peripheral Connecting Fail...
usb init failed
Error, couldn't init Lowlevel part
Kronus 128-pin package
Check USB port[2]:
??? Waiting for Peripheral Connecting Fail...
usb init failed
Error, couldn't init Lowlevel part
WDT Initialize ...
Start 75F2000 End 769E000
UnProtect MIU block 0 : 0x75F2000 0x769E000
offset 0x8001C, size 0x2839B3
WARNING: it is better to set flash start addr aligned to 65536 !!!
WARNING: it is better to set total length aligned to 65536 !!!
in=0x80B00000, in_size=0x2839B3, out= 0x80000180, alloc_buf = 0x81000000
in=0x80B00000, in_size=0x2839B3, out= 0x80000180, alloc_buf = 0x81000000
in_size=2636211 out_size=7234292 unpack_size=0
LZMA Decompression...CRC_result F1E891C2 CRC_value F1E891C2
CRC check success !!
ok
## Starting application at 0x80000224 ...
[cyg_net_init] Init: mbinit(0x00000000)
[cyg_net_init] Init: cyg_net_init_devs(0x00000000)
Init device 'pcnet_eth0'
[cyg_net_init] Init: loopattach(0x00000000)
[cyg_net_init] Init: ifinit(0x00000000)
[cyg_net_init] Init: domaininit(0x00000000)
[cyg_net_init] Init: cyg_net_add_domain(0x8068f568)
New domain internet at 0x00000000
[cyg_net_init] Init: cyg_net_add_domain(0x8068f130)
New domain route at 0x00000000
[cyg_net_init] Init: call_route_init(0x00000000)
[cyg_net_init] Done
[SysInit][1972]
[SysInit][1974]
****** Customer_info:Before ******
0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,
0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,
0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,
0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,
0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,
0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,
abcdef => 0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,
ABCDEF => 0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,
****** Customer_info ******
0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,
0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,
0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,
0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,
0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,
0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,0xbx,[SysInit][1976]
Customer info: 00660630002f000000000000000000000000000408f81800
Hash: 57896ceada56f7bbb0af9151e38029b1
Auth OK
[SysInit][1978]
Hardware Initialize...
MDrv_MIOMap_Init
[HAL_MIU_SetPMIOMapBase][1107] Non implement for MIU _gPM_MapBase= bf000000
MsOS_Init
_MApi_SystemInit_CreateMemoryPool
upoolSize = 320000 and u32Addr = 90F958
mdrv_gpio_init
[SysInit][1987]
MIU Initialize...
Get IOMap u32NonPmBase = 0xbf200000
Get IOMap u32PmBase = 0xbf000000
Disable MIU1
[SysInit][1995]
WDT_Init
[SysInit][2002]
[SysInit][2005]
MDrv_WDT_IsReset = 0
[SysInit][2011]
[MAPI_MEMINFO] DVBC System Memory Usage
[MAPI_MEMINFO] ============================ START END SIZE
[MAPI_MEMINFO] POOL_START 0x00000000 0x016ce800 0x016ce800
[MAPI_MEMINFO] Cached Pool Start 0x0090f958 0x00c2f958 0x00320000
[MAPI_MEMINFO] NONCACHED_POOL_START 0x00c2f958 0x016ce800 0x00a9eea8
[MAPI_MEMINFO]
[MAPI_MEMINFO] Memory Layout:
[MAPI_MEMINFO] ============================ START END SIZE
[MAPI_MEMINFO] XC_MEM_START 0x03d00000 0x04000000 0x00300000
[MAPI_MEMINFO] MAD_MEM_START 0x03a00000 0x03d00000 0x00300000
[MAPI_MEMINFO] MVD_MEM_START 0x01d00000 0x03a00000 0x01d00000
[MAPI_MEMINFO] VE_MEM_START 0x01b60000 0x01d00000 0x001a0000
[MAPI_MEMINFO] GOP_DMAMEM_START 0x01b5f000 0x01b60000 0x00001000
[MAPI_MEMINFO] TSP_VQ_START 0x01b5e000 0x01b5f000 0x00001000
[MAPI_MEMINFO] PM51_MEM_ADR 0x01b5dc00 0x01b5e000 0x00000400
[MAPI_MEMINFO] PM51_VAR_MEM_ADR 0x01b5d800 0x01b5dc00 0x00000400
[MAPI_MEMINFO] GOP_GWINMEM_START 0x016ce800 0x01b59800 0x0048b000
[MAPI_MEMINFO] pFirstAvailableMemory 0x8090f958
[SysInit][2015]
[SysInit][2024]
Hello Hummingbird!!
_appDemo_Task.iId = 1985216513
----------Hello World----------
-------Welcome to Demo AP------
>> [_SysInit_InitAPI][1691]SPI Flash Driver Init !!
Flash is detected (0x0703, 0xEF, 0x40, 0x16)
[HAL_AUDIO_AllocateVars], init Shared
>>
HAL_MAD_SetMemInfo[DSP_DEC] = 0x03b00000
HAL_MAD2_SetMemInfo[DSP_SE] = 0x03a00000
[HAL_AUDSP_DspLoadCode], pau_info->cm_len == 0
ADEC Done and do default setting 4
===== Check Audio Decoder Protection from hash-key IP =====
Hash-key Support DD.
Hash-key Support DD+.
This is Demo Mode!!
Hash-key Support Generic HE-AAC !!
===== Check Protection IP End =====
MDrv_SERFLASH_GetInfo()
u32AccessWidth = 1
u32TotalSize = 4194304
u32SecNum = 64
u32SecSize = 65536
Check Boot Logo OK!! logo_cmd [boot_logo 0 0 1 1]
Get Boot Panel Type!!
pEnvStr = set_paneltype 12
ptr = set_paneltype 12
ptr+PANEL_CMD_LENGTH = 12
result = 1
result = 12
g_PNL_TypeSel = 12
eTiming =6
[MSAPI_XC,Version] [0;32m 01.74 00486343
[mMDrv_PNL_Init u32PnlRiuBaseAddr = bf200000
MDrv_PNL_Init u32PMRiuBaseAddr = bf000000
[XC,Version] [0;36m 00489048
[mMDrv_HDMITx_Init
Get IOMAP ID:300 Base:bf000000!
MDrv_HDMITx_SetHDMITxMode: HDMI mode
DAC eTiming =6
MDrv_HDMITx_SetHDMITxMode: HDMI mode
HDMITx eTiming =7
MDrv_HDMITx_Exhibit: Create Check Rx timer success!
Wait V Sync!!
GE_SetOnePixelMode
driver GE init ok
[_SysInit_GEGOP][1263]
[_SysInit_GEGOP][1272]
[_SysInit_GEGOP][1298]driver GOP0 init ok
[_SysInit_GEGOP][1298]driver GOP1 init ok
[_SysInit_GEGOP][1298]driver GOP2 init ok
Path2
Set to Mixer
GE_Init and VE setting done
BASEADDRESS_STRING_DATABASE_IN_FLASH = 00370000
BASEADDRESS_BITMAP_DATABASE_IN_FLASH = 00370000
BASEADDRESS_GENSETTING_IN_FLASH = 00370000
BASEADDRESS_CURRENT_DTV_ORDER_IN_FLASH = 00380000
BASEADDRESS_CH_DATABASE_IN_FLASH = 00390000
BASEADDRESS_MOSAIC_IN_FLASH = 003D0000
BASEADDRESS_TFCA_MAIL_IN_FLASH = 003E0000
NUMBER_OF_CURRENT_DTV_PROGRAM = 00001000
USB init
MDrv_Usb_Init..
Usb init
The base address is 0xA16AE000
Base addr is 0xA16AE000
Top addr is 0xA16BDFFF
Pages per pool is 16
Bit map base addr is 0xa16ad7d0
usb_init start
usb_hcd_cpe_ehci_probe
ehci: 80c2c7c0
hcd: 80c2c7f4
The allocated addr is 0xa16ae000, bit_map[0] is 0xFFFFFFFE
qh: a16ae000, qh->qh_dma: 16ae000
The allocated addr is 0xa16af000, bit_map[0] is 0xFFFFFFFC
The allocated addr is 0xa16b0000, bit_map[0] is 0xFFFFFFF8
qh: 16ae000
usb_new_device
usb_set_address before
usb_set_address after
The allocated addr is 0xa16b1000, bit_map[0] is 0xFFFFFFF0
InitUSBIntr enter
Usb start..
MDrv_Usb_Done ...........UsbTask..
......................................
>>> Allocate Addr = A16AA6C0 , FwPhyAddr = 016AA700
************************ Start TSP_Init ************************
<FWTSP> : >> FwVersion:001B210E , Date:20100918
************************* End TSP_Init *************************
[MApi_SI_System_Startup] OK !!
[AP_NC_Alloc] Size = 1010
[AP_C_Alloc] Size = 6be00
[AP_NC_Alloc] Size = c8cf
MApi_DigiTuner_Init mutex id 1985216537
MDrv_IIC_Init PORT 1
MDrv_IIC_InitPort0: FAIL
MApi_VectorFont_Init total size=3276800, free size=2815824, large size=2815780
alloc mem 0x330c
alloc mem 0x1f14
SysInit done .................................................
into _appMain_Task
[MApp_CheckFlash][1178] s8SN0 = 1
MApi_DB_CM_LoadDTVProgramDatabaseFromFlash -- u16Index[1] [4096]
MApi_DB_CM_InitDTVDataManager: m_eCurrentServiceType = 1
MApi_DB_CM_InitDTVDataManager: m_wCurrentOrderOfTV = 0
MApi_DB_CM_InitDTVDataManager: m_wCurrentOrderOfRadio = 0
MApi_DB_CM_InitDTVDataManager: m_wCurrentOrderOfMosaic = 0
MApi_DB_CM_InitDTVDataManager: m_wCurrentOrderOfNvod_Ref = 0
MApi_DB_CM_InitDTVDataManager: m_wCurrentOrderOfNvod_TimeShifted = 0
MXL5007T SetTuner
MXL5007 SetTuner dwFreq = -1000, ucBw = 8
MxL_RFSynth_Lock_Status = 0xc
RFSynth bLock = 1
REFSynth bLock = 1
Tuner Success
into appMain_AddApp
[ZUI] init: sz_msg_q=6216
fix appTV_GetInfo before using
SCART ON, CVBS ON, RGB ON
[msCHIP_DAC_SetOutputSource][79] input bitmap: 0x00000011
CVBS on
SVIDEO off, YPBPR off, RGB on
SCART on
problem happen
App_GetTVFormat:[0]
tvvideo_SetDCOutputTiming : 0, 1
Check the Source type 6
MDrv_HDMITx_SetAVMUTE
[tvvideo_SetDCOutputTiming][473]: ## Change Resolution ##, eCompType = 6
[msAPI_XC_ReMapComponentType][246]: msAPI_XC eTiming = 6
DAC eTiming =6
MDrv_HDMITx_SetHDMITxMode: HDMI mode
HDMITx eTiming =7
##########$$$$$$$$$$$2into appMain_AddApp
into appMain_AddApp
into appMain_AddApp
[+]MApi_EpgDB_Init
[AP_NC_Alloc] Size = 50
[AP_NC_Alloc] Size = 5
[AP_NC_Alloc] Size = 190
[AP_NC_Alloc] Size = 3e8
[AP_NC_Alloc] Size = b40
[AP_NC_Alloc] Size = 9d80
[AP_NC_Alloc] Size = 14000
[AP_NC_Alloc] Size = 1d4c0
[AP_NC_Alloc] Size = 1f5f40
[AP_NC_Alloc] Size = c8
[AP_NC_Alloc] Size = 2000
[AP_NC_Alloc] Size = 2000
[AP_NC_Alloc] Size = 4e0000
[EPGDB][000692] =========================================================================
[EPGDB][000693] _pu16SrvMappingTable: (Start, End, Length)= (0xa14e2940, 0xa14e2990, 0x00000050)
[EPGDB][000694] _pu8EitBufMask: (Start, End, Length)= (0xa14e2920, 0xa14e2925, 0x00000005)
[EPGDB][000695] _pMapBufIdxTable: (Start, End, Length)= (0xa14e2780, 0xa14e2910, 0x00000190)
[EPGDB][000696] _pu8EpgDbEvtMask (Start, End, Length)= (0xa14e2380, 0xa14e2768, 0x000003e8)
[EPGDB][000697] _pu8EpgDbScheHdrList (Start, End, Length)= (0xa14e1830, 0xa14e2370, 0x00000b40)
[EPGDB][000698] _pu8EpgDbSrvEvtList (Start, End, Length)= (0xa14d7aa0, 0xa14e1820, 0x00009d80)
[EPGDB][000699] _pu8EpgDbSrvSecList (Start, End, Length)= (0xa14c3a90, 0xa14d7a90, 0x00014000)
[EPGDB][000700] _pu8EpgDbEvtHdrList (Start, End, Length)= (0xa14a65c0, 0xa14c3a80, 0x0001d4c0)
[EPGDB][000701] _pu8EpgDbEvtNameList (Start, End, Length)= (0xa12b0670, 0xa14a65b0, 0x001f5f40)
[EPGDB][000702] _pu8EpgDbPfHdrList (Start, End, Length)= (0xa12b0590, 0xa12b0658, 0x000000c8)
[EPGDB][000703] _pu8EpgDbPfPresent (Start, End, Length)= (0xa12ae580, 0xa12b0580, 0x00002000)
[EPGDB][000704] _pu8EpgDbPfFollow (Start, End, Length)= (0xa12ac570, 0xa12ae570, 0x00002000)
[EPGDB][000708] _pu8EpgDbScheExtStrBuf (Start, End, Length)= (0xa0dcc560, 0xa12ac560, 0x004e0000)
[EPGDB][000710] EPG database allocate 0x00716355 bytes
[EPGDB][000716] =========================================================================
[-]MApi_EpgDB_Init
MDrv_SERFLASH_GetInfo()
u32AccessWidth = 1
u32TotalSize = 4194304
u32SecNum = 64
u32SecSize = 65536
MApp_ZUI_ACT_StartupOSD TV_PROG
[MApp_ZUI_ACT_PrepareOSDPage][438]MS_COMPONENT_OUTPUT_TYPE : 6
fix _MApp_ZUI_SetupDisplayList before using
SD: 720 x 576, HD: 960 x 1080
leave MApp_ZUI_API_InitCanvasGDI -> MApp_ZUI_API_GetFontMVF in 131
Set PAL
MDrv_SERFLASH_GetInfo()
u32AccessWidth = 1
u32TotalSize = 4194304
u32SecNum = 64
u32SecSize = 65536
SD Gwin = 4
disp[1]'s FBID = 2
HD Gwin = 0
[MApp_ZUI_ACT_PrepareOSDPage][438]_Zapper_Disable_AV: Enter at 4350.
alloc mem 0x40000
alloc mem 0x2400
alloc mem 0x2000
alloc mem 0x1000
W trakcie próby inicjalizacji MxL5007T pojawia się coś takiego:
MXL5007T SetTuner
MXL5007 SetTuner dwFreq = -1000, ucBw = 8
MxL_RFSynth_Lock_Status = 0xc
RFSynth bLock = 1
REFSynth bLock = 1
Tuner Success Bez MxL5007T pojawia się oczywiście to:
InitTuner fail Myślałem, że tuner się nie uruchomi przy braku MxL5007T, ale jednak startuje. Można się domyślać, że "ucBw = 8" to pasmo 8 MHz. Potem okazało się, że tajemnicze "RFSynth bLock = 1" i "REFSynth bLock = 1" to flagi tego, że obie pętle PLL (pierwsza i druga przemiana częstotliwości) weszły w zakres chwytania. Przytrzymując CR podczas bootowania można wejść do samego bootladera U-Boot. Można więc pobawić się MxL5007T i zobaczyć co jest na szynie I2C za pomocą analizatora stanów logicznych. Początkowo można wykorzystać komendę "tuner_init<CR>":
Jak widać MxL5007T jest inicjalizowany. Jego adres na I2C to 192(dec)=0xC0. Dalej wynik z analizatora stanów logicznych:
Trochę to trwa. Są jakieś opóźnienia i dziwna sprawa na początku. Dochodzi do zapisu pod adres 0x00. Nie wiem po co. Częstotliwość SCL na szynie I2C to ok. 150 kHz. Za pomocą generatora w.cz. i oscyloskopu udało się ustalić, że częstotliwość pośrednia to ok. 5 MHz. Generalnie dla inicjalizacji jest coś takiego:
Spoiler:
Time,Packet ID,Address,Read/Write,Data
0.0000084320,1,0x00,W
0.0020556640,1,0x00,W
0.0069490960,2,0xC0,W,0xFF
0.0135358800,3,0xC0,W,0x02 0x03 0x03 0x40 0x05 0x04 0x06 0x11 0x2E 0x15 0x30 0x10 0x45 0x58 0x48 0x19 0x52 0x03 0x53 0x44 0x6A 0x4B 0x76 0x00 0x78 0x18 0x7A 0x17 0x85 0x06 0x01 0x01
0.0000084320,1,0x00,W
0.0020556640,1,0x00,W
0.0069490960,2,0xC0,W,0xFF
0.0135358800,3,0xC0,W,0x02 0x03 0x03 0x40 0x05 0x04 0x06 0x11 0x2E 0x15 0x30 0x10 0x45 0x58 0x48 0x19 0x52 0x03 0x53 0x44 0x6A 0x4B 0x76 0x00 0x78 0x18 0x7A 0x17 0x85 0x06 0x01 0x01
Kolejna komenda to "tuner_demodtype [param]<CR>":
Tutaj nie dochodzi do żadnej aktywności na I2C. Widać, że ustawiana jest jednak zmienna środowiskowa. Ostatecznie można użyć "tuner_tune". Da się dzięki temu ustawić częstotliwość i pasmo. Wybrałem 100 MHz i pasmo 6 MHz:
Spoiler:
do_tuner_setfreq u32Freq = 100000KHz, eRfBandwidth = 0x1
FE 100000 BW 0
MXL5007T SetTuner
MXL5007 SetTuner dwFreq = 100000000, ucBw = 6
MxL_RFSynth_Lock_Status = 0xC
RFSynth bLock = 1
REFSynth bLock = 1
[cmd_tuner.c][53] (Freq, bandth) = (100000 1) Try Lock
MApi_FE_GetSignalQuality Lock Failed
[cmd_tuner.c][64] Signal quality 0 0
MApi_FE_GetSignalQuality Lock Failed
[cmd_tuner.c][64] Signal quality 0 0
MApi_FE_GetSignalQuality Lock Failed
[cmd_tuner.c][64] Signal quality 0 0
MApi_FE_GetSignalQuality Lock Failed
[cmd_tuner.c][64] Signal quality 0 0
MApi_FE_GetSignalQuality Lock Failed
[cmd_tuner.c][64] Signal quality 0 0
MApi_FE_GetSignalQuality Lock Failed
[cmd_tuner.c][64] Signal quality 0 0
MApi_FE_GetSignalQuality Lock Failed
[cmd_tuner.c][64] Signal quality 0 0
MApi_FE_GetSignalQuality Lock Failed
[cmd_tuner.c][64] Signal quality 0 0
MApi_FE_GetSignalQuality Lock Failed
[cmd_tuner.c][64] Signal quality 0 0
MApi_FE_GetSignalQuality Lock Failed
[cmd_tuner.c][64] Signal quality 0 0
MApi_FE_GetSignalQuality Lock Failed
[cmd_tuner.c][64] Signal quality 0 0
MApi_FE_GetSignalQuality Lock Failed
[cmd_tuner.c][64] Signal quality 0 0
MApi_FE_GetSignalQuality Lock Failed
[cmd_tuner.c][64] Signal quality 0 0
MApi_FE_GetSignalQuality Lock Failed
[cmd_tuner.c][64] Signal quality 0 0
MApi_FE_GetSignalQuality Lock Failed
[cmd_tuner.c][64] Signal quality 0 0
MApi_FE_GetSignalQuality Lock Failed
[cmd_tuner.c][64] Signal quality 0 0
MApi_FE_GetSignalQuality Lock Failed
[cmd_tuner.c][64] Signal quality 0 0
MApi_FE_GetSignalQuality Lock Failed
[cmd_tuner.c][64] Signal quality 0 0
MApi_FE_GetSignalQuality Lock Failed
[cmd_tuner.c][64] Signal quality 0 0
MApi_FE_GetSignalQuality Lock Failed
[cmd_tuner.c][64] Signal quality 0 0
MApi_FE_GetSignalQuality Lock Failed
[cmd_tuner.c][64] Signal quality 0 0
FE un-lock
<< MStar >>#
do_tuner_setfreq u32Freq = 100000KHz, eRfBandwidth = 0x1
FE 100000 BW 0
MXL5007T SetTuner
MXL5007 SetTuner dwFreq = 100000000, ucBw = 6
MxL_RFSynth_Lock_Status = 0xC
RFSynth bLock = 1
REFSynth bLock = 1
[cmd_tuner.c][53] (Freq, bandth) = (100000 1) Try Lock
MApi_FE_GetSignalQuality Lock Failed
[cmd_tuner.c][64] Signal quality 0 0
MApi_FE_GetSignalQuality Lock Failed
[cmd_tuner.c][64] Signal quality 0 0
MApi_FE_GetSignalQuality Lock Failed
[cmd_tuner.c][64] Signal quality 0 0
MApi_FE_GetSignalQuality Lock Failed
[cmd_tuner.c][64] Signal quality 0 0
MApi_FE_GetSignalQuality Lock Failed
[cmd_tuner.c][64] Signal quality 0 0
MApi_FE_GetSignalQuality Lock Failed
[cmd_tuner.c][64] Signal quality 0 0
MApi_FE_GetSignalQuality Lock Failed
[cmd_tuner.c][64] Signal quality 0 0
MApi_FE_GetSignalQuality Lock Failed
[cmd_tuner.c][64] Signal quality 0 0
MApi_FE_GetSignalQuality Lock Failed
[cmd_tuner.c][64] Signal quality 0 0
MApi_FE_GetSignalQuality Lock Failed
[cmd_tuner.c][64] Signal quality 0 0
MApi_FE_GetSignalQuality Lock Failed
[cmd_tuner.c][64] Signal quality 0 0
MApi_FE_GetSignalQuality Lock Failed
[cmd_tuner.c][64] Signal quality 0 0
MApi_FE_GetSignalQuality Lock Failed
[cmd_tuner.c][64] Signal quality 0 0
MApi_FE_GetSignalQuality Lock Failed
[cmd_tuner.c][64] Signal quality 0 0
MApi_FE_GetSignalQuality Lock Failed
[cmd_tuner.c][64] Signal quality 0 0
MApi_FE_GetSignalQuality Lock Failed
[cmd_tuner.c][64] Signal quality 0 0
MApi_FE_GetSignalQuality Lock Failed
[cmd_tuner.c][64] Signal quality 0 0
MApi_FE_GetSignalQuality Lock Failed
[cmd_tuner.c][64] Signal quality 0 0
MApi_FE_GetSignalQuality Lock Failed
[cmd_tuner.c][64] Signal quality 0 0
MApi_FE_GetSignalQuality Lock Failed
[cmd_tuner.c][64] Signal quality 0 0
MApi_FE_GetSignalQuality Lock Failed
[cmd_tuner.c][64] Signal quality 0 0
FE un-lock
<< MStar >>#
Oczywiście sygnał z generatora nie zostanie rozpoznany jako DVB-T. Stąd wynika otrzymany komunikat w konsoli UART. Jednak zmiany poziomu sygnału z generatora mają oczywiście wpływ na wartość napięcia ARW. Na szynie I2C jest znowu programowanie jakichś rejestrów:
Spoiler:
Time,Packet ID,Address,Read/Write,Data
0.0000198720,1,0xC0,W,0x0F 0x00 0x0C 0x15 0x0D 0x00 0x0E 0x19 0x1F 0x87 0x20 0x1F 0x21 0x87 0x22 0x1F 0x80 0x01 0x0F 0x01
0.0096766960,2,0xC0,W,0xF8 0xD8
0.0098780720,2,0xC1,R,0x0F
0.0143467200,3,0xC0,W,0xF8 0xD8
0.0145480160,3,0xC1,R,0x0F
0.0000198720,1,0xC0,W,0x0F 0x00 0x0C 0x15 0x0D 0x00 0x0E 0x19 0x1F 0x87 0x20 0x1F 0x21 0x87 0x22 0x1F 0x80 0x01 0x0F 0x01
0.0096766960,2,0xC0,W,0xF8 0xD8
0.0098780720,2,0xC1,R,0x0F
0.0143467200,3,0xC0,W,0xF8 0xD8
0.0145480160,3,0xC1,R,0x0F
Jak widać najpierw coś jest programowane, potem odczytywane. Jak się potem okazało w rejestrze 0xD8 jest status obu pętli PLL. Byłoby trudno to rozpracować bez opisu rejestrów. Jednak układ ten wydaje się trochę prostszy w programowaniu od R820T. Jest to więc bardzo wstępna zabawa z MxL5007T. Można by to pominąć, ale zakładałem, że ze znalezionym kodem będą problemy. Stąd musiałem mieć zapis tego, co jest na I2C dla porównania. Co ciekawe znalazłem też kod dla MxL5007, ale pod platformę MSTAR: Link. Kod ten pasuje do zachowania tunera i tego, co jest w konsoli UART. Przykładowo taka funkcja:
Kod: C / C++
Odpowiada czemuś takiemu w konsoli po wywołaniu "tuner_tune":
MXL5007T SetTuner
MXL5007 SetTuner dwFreq = 100000000, ucBw = 6
MxL_RFSynth_Lock_Status = 0xC
RFSynth bLock = 1
REFSynth bLock = 1 Widać, że jest to nieco inaczej wg kodu, bo nie powinno być "MxL_RFSynth_Lock_Status = 0xC", ale reszta się zgadza. Na tym etapie można zakończyć wstępną inżynierię wsteczną płyty tunera.
W dalszej kolejności można dołączyć STM32. Schemat blokowy odbiornika ma odpowiadać koncepcji podanej wcześniej. Chodzi więc o próbkowanie sygnału pasmowego z wyjścia p.cz. i w dalszej kolejności mieszanie cyfrowe dla otrzymania i(n) i q(n). Zatem schemat blokowy jest prawie identyczny:
Wykorzystałem tu wzmacniacz p.cz., jaki opracowałem dla R820T. Powstał więc uproszczony schemat dołączenia STM32 i wzmacniacz p.cz. do płyty tunera:
Dzięki wspomnianym zworkom (widoczne na fotografiach i schemacie) można po odłączeniu płytki p.cz. i STM32F4DISCOVERY przywrócić tuner do stanu pierwotnego.
Odnośnie samego programowania MxL5007T początkowo przeportowałem kod Arduino. Wyniki tych prac zamieściłem na chińskiej stronie: Link. Działało to poprawnie, ale uznałem, że ciekawiej będzie jak uruchomię oryginalny kod producenta. Jak się okazuje kody, które można znaleźć w Internecie są oparte właśnie na tym źródle. Warto na początek poczytać dokumentację wspomnianego drivera:
Ma to być niby tak zrobione (nie do końca tak ostatecznie jest):
Widzimy warstwowość tego kodu i osobny plik na implementację kodu zależnego od danej platformy. Adres I2C ustawia się przez wyprowadzenie AS (6):
Linia ta jest zwarta do masy, więc adres to 96(dec). Po przesunięciu w lewo o jeden bit jest właśnie widoczne wcześniej 0xC0. Przykładowo dla komendy RESET trzeba wysłać 0xFF. Stąd na początku inicjalizacji było "0xC0,W,0xFF". Jest to więc właśnie RESET. Zapis czegoś do MxL5007T jest ciekawy:
Generalnie najpierw wysyłany jest adres 0xC0. Potem zaś pary: adres rejestru i jego wartość. W większości układów wysyła się tylko adres pierwszego rejestru. Potem wszystko idzie już po kolei z autoinkrementacją wewnętrznego licznika. Tu jest inne rozwiązanie. Nigdy się z czymś takim nie spotkałem. Odczyt rejestru jest bardziej skomplikowany:
Najpierw trzeba wysłać adres 0xC0, 0xFB (komenda) i adres rejestru do odczytu. Potem wysyłamy adres do odczytu 0xC1 i odczytujemy rejestr. W dokumentacji drivera jest też opis funkcji API, tego jak zrobić własne funkcje zależne od platformy i przykładowy kod (nie do końca poprawny). Uruchomienie drivera było proste, ale są tam błędy. Poprawiłem funkcję od sprawdzania ID układu na bazie podanego wcześniej kodu: Link. Konsola UART w STM32 została z poprzedniego projektu. Dodałem tylko odpowiednie polecenia, inne zaś usunąłem i zamieniłem kod od R820T na MxL5007T.
MxL5007T zaprogramowałem tak, by pasował do projektu. Zatem częstotliwość pośrednia to 4,5 MHz i pasmo 6 MHz. Generalnie pasmo toru p.cz. i tak musi być wąskie, więc lepiej ustawić jaknajwęższe pasmo dla filtra p.cz. w MxL5007T.
Mając już uruchomiony MxL5007T trzeba go przetestować za pomocą oscyloskopu i generatora w.cz. Należy też podać jakieś napięcie na wyprowadzenie VAGC. Wykorzystałem więc generator G4-116 i oscyloskop PM3233:
Sygnały na wyjściach p.cz. dla sygnału w.cz. 100 MHz:
Jak widać wyjście jest różnicowe. Widoczna niesymetryczność wynika częściowo z nieco rozstrojonego kanału B oscyloskopu. Faktycznie jest dużo mniejsza. W tym momencie można już było wstępnie dołączyć MxL5007T do toru p.cz. i uruchomić odbiornik. Dało się odebrać już jakieś stacje. Jednak o tym napiszę w dalszej części.
Mając wstępnie uruchomiony MxL5007T można było przystąpić do jego badań, ponieważ nic o tym układzie nie wiadomo. Wg cytowanego wcześniej szczątkowego datasheet miało być bardzo dobre ARW (pierwszy poziom ARW). Można to łatwo sprawdzić ustawiając stałą wartość napięcia na VAGC i zmieniając poziom sygnału z generatora po dostrojeniu odbiornika do jego częstotliwości. Wzrost poziomu powinien powodować ograniczanie wzmocnienia. Poniżej wyniki:
Ma tam być niby ARW o dynamice 100 dB. W moim wypadku zmiany poziomu sygnału są rzędu 25...28 dB. Oczywiście mogłem zwiększać poziom jeszcze znacznie bardziej, ale MxL5007T przestawał pracować liniowo. Wzmocnienie jest prawie stałe. Z uwagi na szumy w skrajnych przypadkach był problem by to dokładnie pomierzyć. Zatem wniosek jest taki, że ARW nie jest włączone przez jakieś rejestry. W tym kodzie jest coś o ARW, ale zmiany w rejestrze 0x12 nic nie dają, zaś ustawianie rejestrów w podany tam sposób prowadzi do tego, że MxL5007T przestaje działać. Skoro jesteśmy przy ARW, to należy wyznaczyć zależność wzmocnienia od napięcia na VAGC tj. ku=f(Uvagc) przy f=const. Uzyskałem taki wynik dla f=100 MHz:
Wzmocnienie jest podane w V/V. Napięcie VAGC było mierzone bezpośrednio na wyprowadzeniu 27 (VAGC). Wyjścia IF MxL5007T nie były obciążone. W celu wyznaczenia wzmocnienia w tak szerokim zakresie zmian na VAGC konieczna była zmiana poziomu na generatorze i jej stopniowe redukowanie w trakcie badania, tak by uzyskać sensowny sygnał na wyjściu i liniową pracę. Skoro nie ma wewnętrznego ARW to taki eksperyment ma sens. Jest to nieliniowa zależność i w dodatku o bardzo dużym nachyleniu. Co to za funkcja? Z pewnością jakaś wykładnicza. Będzie to więc coś w stylu:
gdzie: a, b - stałe. Można zrobić aproksymację, by wyznaczyć te współczynniki (metoda najmniejszych kwadratów - minimalizacja błędu średniokwadratowego), ale nie widzę potrzeby. Znacznie korzystniej przedstawić to w skali log-lin:
Jest to ta sama zależność. Jednak tym razem jest ku[dB]=20*log10(ku[V/V). Skoro poprzednia funkcja jest wykładnicza i podstawę ma 10, to logarytm o podstawie 10 jest funkcją odwrotną. Stąd powstaje zależność liniowa. W Excelu można wyznaczyć linię trendu (też metoda najmniejszych kwadratów). Jest to bardzo praktyczny wzór. Można wyznaczyć funkcję odwrotną:
//Gain [dB] = 65.441*V_if_agc [V] - 36.681 -> V_if_agc [V] = 1.5281E-2*Gain [dB] + 5.6052E-1Wstawiając te stałe do programu poprzez #define można już obliczyć potrzebne napięcie dla VAGC przy zadanym wzmocnieniu MxL5007T. Należy jednak uwzględnić jeszcze korektę z uwagi na obciążenie filtra dolnoprzepustowego dla PWM (R17-C11). Ustaliłem ze spadków napięć w obwodzie i znajomości rezystancji, że rezystancja wejściowa dla VAGC wynosi 54,5 kΩ. Ostatecznie w programie wychodzi to bardzo ładnie:
Kod: C / C++
Z uwagi na silne obciążenie filtra R17-C11 musiałem znacznie zmniejszyć wartość R17 i zwiększyć pojemność C11. Było to projektowane dla innych warunków pracy tj. przy R820T. Skoro już zajmujemy się wzmocnieniem, to można powiedzieć, że wzmocnienie wzmacniacza p.cz. dla częstotliwości środkowej wynosi 16,95 dB. Z kolei po dołączeniu toru p.cz. do wyjść IF MxL5007T napięcie spada, bo dochodzi do obciążenia. Warto więc wiedzieć ile wynosi rezystancja wyjściowa (różnicowa). Można to wyznaczyć różnie. Ja zmierzyłem napięcie wyjściowe wyjść obciążonych rezystorem o znanej rezystancji i przy braku obciążenia (włączenie obciążenia pomiędzy wyprowadzenia IF).
Potem można obliczyć rezystancję wyjściową wykorzystując model Thevenina. Obciążałem wyjście rezystorem 2,64 kΩ (wartość zmierzona). Uzyskałem wynik pomiaru rezystancji wyjściowej 600 Ω. Tor p.cz. ma dość małą rezystancję wejściową. Wynika to z wartości R1 i R2. Tutaj Rwe zależy głównie od nich. Rezystancja wejściowa samego tranzystora z uwagi na brak zwarcia emitera do masy dla składowej zmiennej jest duża i wyniesie r1=rbb'+rb'e+(β+1)*R4||R5. Ostatecznie Rw=R1||R2||r1, ale R1||R2<<r1. Trzeba to teraz sprowadzić na stronę pierwotną transformatora, czyli dzielimy przez kwadrat przekładni. Stąd z punktu widzenia uzwojenia pierwotnego mamy mniejszą Rwe', bo przekładnia to 1:2. Wynikające z tego tłumienie wynosi -5,46 dB. Można to wszystko wziąć pod uwagę i zadawać przez konsolę wzmocnienie całego toru. Stąd zadaję Total_Gain i obliczam potrzebne wzmocnienie dla MxL5007T.
float MxL_gain = Total_Gain - (IF_Gain + Attenuation);Pokazuje to jak praktyczna i wygodna jest miara wzmocnienia w dB. Tak to wygląda w konsoli:
Pytanie na ile dobrze to działa? Zbadałem wzmocnienie przy kilku częstotliwościach. Obawiałem się, że dla częstotliwości innej, niż 100 MHz (przy takiej częstotliwości robiłem pomiary) już to się nie będzie zgadzać, ale jest nieźle:
Tutaj Gset to wzmocnienie zadane z konsoli UART, zaś Gmeas zmierzone. Można uzyskać wzmocnienie całego toru ponad 100 dB. Inna sprawa czy ma to jakiś sens w związku z SNR.
Pytanie też na ile zgadza się częstotliwość zaprogramowana w MxL5007T z faktycznie odbieraną? Zrobiłem kilka eksperymentów. Poniżej fotografie wyniku pomiaru na mierniku częstotliwości:
Idąc od lewej zaprogramowana częstotliwość wynosiła: 50,00000 MHz; 100,00000 MHz; 160,00000 MHz i 200,00000 MHz. Jest zatem bardzo dobrze. W tym przypadku oczywiście dostrajałem generator do uzyskania maksymalnej wartości sygnału na wyjściu wzmacniacza p.cz.
Bawiąc się dalej chciałem zrobić RSSI (Received Signal Strength Indication). W tym kodzie jest jakaś funkcja, ale nie działa. Zacząłem więc przeglądać rejestry. Wstępnie zrobiłem komendę dump. Poniżej efekt:
Spoiler:
0x00=0x3F
0x01=0x01
0x02=0x02
0x03=0x40
0x04=0x01
0x05=0x04
0x06=0x11
0x07=0x0A
0x08=0x80
0x09=0x3F
0x0A=0x3F
0x0B=0x3F
0x0C=0x15
0x0D=0x00
0x0E=0x19
0x0F=0x01
0x10=0x00
0x11=0x00
0x12=0x05
0x13=0x01
0x14=0x3C
0x15=0x0A
0x16=0x10
0x17=0x66
0x18=0x1D
0x19=0x01
0x1A=0x08
0x1B=0x05
0x1C=0x06
0x1D=0x00
0x1E=0x00
0x1F=0x87
0x20=0x1F
0x21=0x87
0x22=0x1F
0x23=0x00
0x24=0x83
0x25=0x03
0x26=0xC8
0x27=0x0C
0x28=0x00
0x29=0x00
0x2A=0x0F
0x2B=0x02
0x2C=0x00
0x2D=0x36
0x2E=0x15
0x2F=0x17
0x30=0x10
0x31=0x00
0x32=0x00
0x33=0x00
0x34=0x07
0x35=0x00
0x36=0x00
0x37=0x27
0x38=0x00
0x39=0x80
0x3A=0xE4
0x3B=0x08
0x3C=0x00
0x3D=0x00
0x3E=0x00
0x3F=0x00
0x40=0x00
0x41=0x00
0x42=0x02
0x43=0x00
0x44=0x12
0x45=0x58
0x46=0x14
0x47=0x1D
0x48=0x19
0x49=0x00
0x4A=0x00
0x4B=0x00
0x4C=0x08
0x4D=0x24
0x4E=0x04
0x4F=0x13
0x50=0x45
0x51=0x01
0x52=0x03
0x53=0x44
0x54=0x08
0x55=0x00
0x56=0x00
0x57=0x00
0x58=0x00
0x59=0x08
0x5A=0x00
0x5B=0x00
0x5C=0x80
0x5D=0x00
0x5E=0x00
0x5F=0x00
0x60=0x00
0x61=0x00
0x62=0x03
0x63=0x00
0x64=0x0C
0x65=0x02
0x66=0x8F
0x67=0x28
0x68=0x4C
0x69=0x26
0x6A=0x4B
0x6B=0x0F
0x6C=0x00
0x6D=0x00
0x6E=0x30
0x6F=0x00
0x70=0x08
0x71=0x17
0x72=0x04
0x73=0x27
0x74=0x1E
0x75=0x06
0x76=0x00
0x77=0x17
0x78=0x18
0x79=0x27
0x7A=0x17
0x7B=0x57
0x7C=0x00
0x7D=0x64
0x7E=0xD7
0x7F=0x1A
0x80=0x01
0x81=0x02
0x82=0x00
0x83=0x00
0x84=0x00
0x85=0x06
0x86=0x00
0x87=0x09
0x88=0x00
0x89=0x06
0x8A=0xAA
0x8B=0x00
0x8C=0x00
0x8D=0x00
0x8E=0x00
0x8F=0x21
0x90=0xF0
0x91=0x70
0x92=0x00
0x93=0x18
0x94=0x74
0x95=0x8A
0x96=0xA2
0x97=0x00
0x98=0x41
0x99=0x7C
0x9A=0x30
0x9B=0x00
0x9C=0x60
0x9D=0x20
0x9E=0x28
0x9F=0x10
0xA0=0x52
0xA1=0x00
0xA2=0x00
0xA3=0x00
0xA4=0x00
0xA5=0x00
0xA6=0x90
0xA7=0x2C
0xA8=0x0B
0xA9=0x0B
0xAA=0x00
0xAB=0x1F
0xAC=0x1F
0xAD=0x00
0xAE=0x39
0xAF=0x03
0xB0=0x17
0xB1=0x00
0xB2=0x27
0xB3=0x12
0xB4=0x00
0xB5=0x00
0xB6=0x6A
0xB7=0x00
0xB8=0x24
0xB9=0x00
0xBA=0x00
0xBB=0x00
0xBC=0x00
0xBD=0x00
0xBE=0x08
0xBF=0x00
0xC0=0x00
0xC1=0x00
0xC2=0x00
0xC3=0x00
0xC4=0x48
0xC5=0x00
0xC6=0x17
0xC7=0xB0
0xC8=0xAA
0xC9=0x2A
0xCA=0x27
0xCB=0x85
0xCC=0x55
0xCD=0xF0
0xCE=0x00
0xCF=0x15
0xD0=0x17
0xD1=0x10
0xD2=0x04
0xD3=0x31
0xD4=0x1E
0xD5=0x4C
0xD6=0x3A
0xD7=0x11
0xD8=0x0F
0xD9=0x14
0xDA=0x00
0xDB=0x00
0xDC=0x00
0xDD=0x00
0xDE=0x00
0xDF=0x00
0xE0=0x00
0xE1=0x00
0xE2=0x00
0xE3=0x00
0xE4=0x00
0xE5=0x00
0xE6=0x00
0xE7=0x00
0xE8=0x00
0xE9=0x00
0xEA=0x00
0xEB=0x00
0xEC=0x00
0xED=0x00
0xEE=0x00
0xEF=0x00
0xF0=0x00
0xF1=0x00
0xF2=0x00
0xF3=0x00
0xF4=0x00
0xF5=0x00
0xF6=0x00
0xF7=0x00
0xF8=0x00
0xF9=0x00
0xFA=0x00
0xFB=0x00
0xFC=0x00
0xFD=0x00
0xFE=0x00
0xFF=0x00
Command>
0x00=0x3F
0x01=0x01
0x02=0x02
0x03=0x40
0x04=0x01
0x05=0x04
0x06=0x11
0x07=0x0A
0x08=0x80
0x09=0x3F
0x0A=0x3F
0x0B=0x3F
0x0C=0x15
0x0D=0x00
0x0E=0x19
0x0F=0x01
0x10=0x00
0x11=0x00
0x12=0x05
0x13=0x01
0x14=0x3C
0x15=0x0A
0x16=0x10
0x17=0x66
0x18=0x1D
0x19=0x01
0x1A=0x08
0x1B=0x05
0x1C=0x06
0x1D=0x00
0x1E=0x00
0x1F=0x87
0x20=0x1F
0x21=0x87
0x22=0x1F
0x23=0x00
0x24=0x83
0x25=0x03
0x26=0xC8
0x27=0x0C
0x28=0x00
0x29=0x00
0x2A=0x0F
0x2B=0x02
0x2C=0x00
0x2D=0x36
0x2E=0x15
0x2F=0x17
0x30=0x10
0x31=0x00
0x32=0x00
0x33=0x00
0x34=0x07
0x35=0x00
0x36=0x00
0x37=0x27
0x38=0x00
0x39=0x80
0x3A=0xE4
0x3B=0x08
0x3C=0x00
0x3D=0x00
0x3E=0x00
0x3F=0x00
0x40=0x00
0x41=0x00
0x42=0x02
0x43=0x00
0x44=0x12
0x45=0x58
0x46=0x14
0x47=0x1D
0x48=0x19
0x49=0x00
0x4A=0x00
0x4B=0x00
0x4C=0x08
0x4D=0x24
0x4E=0x04
0x4F=0x13
0x50=0x45
0x51=0x01
0x52=0x03
0x53=0x44
0x54=0x08
0x55=0x00
0x56=0x00
0x57=0x00
0x58=0x00
0x59=0x08
0x5A=0x00
0x5B=0x00
0x5C=0x80
0x5D=0x00
0x5E=0x00
0x5F=0x00
0x60=0x00
0x61=0x00
0x62=0x03
0x63=0x00
0x64=0x0C
0x65=0x02
0x66=0x8F
0x67=0x28
0x68=0x4C
0x69=0x26
0x6A=0x4B
0x6B=0x0F
0x6C=0x00
0x6D=0x00
0x6E=0x30
0x6F=0x00
0x70=0x08
0x71=0x17
0x72=0x04
0x73=0x27
0x74=0x1E
0x75=0x06
0x76=0x00
0x77=0x17
0x78=0x18
0x79=0x27
0x7A=0x17
0x7B=0x57
0x7C=0x00
0x7D=0x64
0x7E=0xD7
0x7F=0x1A
0x80=0x01
0x81=0x02
0x82=0x00
0x83=0x00
0x84=0x00
0x85=0x06
0x86=0x00
0x87=0x09
0x88=0x00
0x89=0x06
0x8A=0xAA
0x8B=0x00
0x8C=0x00
0x8D=0x00
0x8E=0x00
0x8F=0x21
0x90=0xF0
0x91=0x70
0x92=0x00
0x93=0x18
0x94=0x74
0x95=0x8A
0x96=0xA2
0x97=0x00
0x98=0x41
0x99=0x7C
0x9A=0x30
0x9B=0x00
0x9C=0x60
0x9D=0x20
0x9E=0x28
0x9F=0x10
0xA0=0x52
0xA1=0x00
0xA2=0x00
0xA3=0x00
0xA4=0x00
0xA5=0x00
0xA6=0x90
0xA7=0x2C
0xA8=0x0B
0xA9=0x0B
0xAA=0x00
0xAB=0x1F
0xAC=0x1F
0xAD=0x00
0xAE=0x39
0xAF=0x03
0xB0=0x17
0xB1=0x00
0xB2=0x27
0xB3=0x12
0xB4=0x00
0xB5=0x00
0xB6=0x6A
0xB7=0x00
0xB8=0x24
0xB9=0x00
0xBA=0x00
0xBB=0x00
0xBC=0x00
0xBD=0x00
0xBE=0x08
0xBF=0x00
0xC0=0x00
0xC1=0x00
0xC2=0x00
0xC3=0x00
0xC4=0x48
0xC5=0x00
0xC6=0x17
0xC7=0xB0
0xC8=0xAA
0xC9=0x2A
0xCA=0x27
0xCB=0x85
0xCC=0x55
0xCD=0xF0
0xCE=0x00
0xCF=0x15
0xD0=0x17
0xD1=0x10
0xD2=0x04
0xD3=0x31
0xD4=0x1E
0xD5=0x4C
0xD6=0x3A
0xD7=0x11
0xD8=0x0F
0xD9=0x14
0xDA=0x00
0xDB=0x00
0xDC=0x00
0xDD=0x00
0xDE=0x00
0xDF=0x00
0xE0=0x00
0xE1=0x00
0xE2=0x00
0xE3=0x00
0xE4=0x00
0xE5=0x00
0xE6=0x00
0xE7=0x00
0xE8=0x00
0xE9=0x00
0xEA=0x00
0xEB=0x00
0xEC=0x00
0xED=0x00
0xEE=0x00
0xEF=0x00
0xF0=0x00
0xF1=0x00
0xF2=0x00
0xF3=0x00
0xF4=0x00
0xF5=0x00
0xF6=0x00
0xF7=0x00
0xF8=0x00
0xF9=0x00
0xFA=0x00
0xFB=0x00
0xFC=0x00
0xFD=0x00
0xFE=0x00
0xFF=0x00
Command>
Jak widać od rejestru 0xDA są już same zera (zawsze tak jest). Stąd potem ograniczyłem to tylko do 0xD9, czyli wszystkich rejestrów jest chyba 218. Potem zrobiłem komendę reg_diff do sprawdzania co się zmieniło w jakich rejestrach pomiędzy wywołaniami tej komendy:
Wielokrotne wywołanie reg_diff:
Właśnie te rejestry często się zmieniają. RSSI z uwagi na szumy nie jest stabilne, więc jest to jakiś trop. Potem mogłem zrobić komendę test do sprawdzania zmian tylko w tych specyficznych rejestrach:
Obserwując co tu się dzieje próbowałem analizować bliżej różne pary tych rejestrów. Najbardziej obiecujące moim zdaniem były 0xAE i 0xAD. W 0xAD są prawdopodobnie jeszcze jakieś flagi. Musiałem też zrobić wielokrotny odczyt słowa w 0xAE i 0xAD, by wyznaczać wartość maksymalną (tylko tak jakoś to działa). Ogólnie słowo to zależy od napięcia na VAGC i od poziomu na wejściu. Wyszła po wielu eksperymentach dosyć dziwna funkcja:
Kod: C / C++
Co to daje? Jest to zapisane w komentarzu. Zrobiłem poprzez wysyłanie danych do LabVIEW wykres zmian RSSI przy stałym wzmocnieniu i zmianach poziomu:
Problem w tym, by to uzyskać trzeba zmieniać poziom o ±20 dB. Inaczej brak jest reakcji. Wywołanie komendy RSSI w konsoli:
dla Urf=60,0 µV
i dla Urf=240,0 µV:
Zmieniałem tu wzmocnienie. Z uwagi na czułość tak uzyskanego RSSI odpuściłem sobie jego skalowanie, chociaż zależność od napięcia wejściowego wygląda na logarytmiczną. Z analizy kodu dla MSTAR nie wynika, by tuner odczytywał jakieś RSSI. Zresztą z analizy analizatorem stanów logicznych wynika, że tuner nawet nie odczytuje ID. Jedyne, co jest odczytywane to status PLL.
Dalej chcąc się jak najwięcej dowiedzieć o MxL5007T postanowiłem dla zabawy ustalić częstotliwość pośrednią pierwszej przemiany częstotliwości.
Jak to zrobić? Generalnie jeśli nie ma tu jakichś specyficznych rozwiązań, to można wykorzystać częstotliwości lustrzane. Chodzi o coś takiego:
[Boksa J. Analogowe układy elektroniczne, BTC, Warszawa 2007]
Pamiętajmy zatem, że w prostym mieszaczu produkt f_p.cz. powstaje dla fs=|fh±f_p.cz.|. Stąd ustawiłem:
-duże Urf=180 µV i gain=70,00 dB
-zaprogramowałem częstotliwość w MxL5007: 140 MHz.
Potem po dostrojeniu generatora do 140 MHz odstrajałem go w górę, by znaleźć częstotliwość lustrzaną. Nic jednak nie było aż do 300 MHz (koniec zakresu generatora). Wątpiłem, by była tak wielka częstotliwość pośrednia. Zatem przestawiłem dla wygody MxL5007 na 220 MHz i odstrajałem w dół. Układ zareagował przy 145,2 MHz. Oczywiście wzmocnienie było dużo mniejsze. Z uzyskanego wyniku można wnioskować, że heterodyna ma mniejszą częstotliwość od sygnału fs, czyli tutaj fs2=220 MHz i fs1=145,2 MHz. Ile jest f_p.cz.? Otóż częstotliwość lustrzana jest odległa od tej "podstawowej" o 2*f_p.cz., więc f_p.cz.=(220-145,2)/2=37,4 MHz. Blisko typowej wartości 38 MHz z telewizorów analogowych.
Jaki jest krok przestrajania w MxL5007T? Z kodu drivera wynika, że jest to 7,8124 kHz.
Robiłem też porównanie do R820T. Okazuje się, że wzmocnienie jest znacznie większe w MxL5007T. Wychodzi na to, że R820T to jakaś słabsza wersja tak popularnego R820T2. Z R820T jest też znacznie więcej szumu. Największe wzmocnienie jakie uzyskałem dla całego toru z R820T wynosi raptem 61,43 dB. Jest znacząca różnica do 100 dB dla całego toru z MxL5007T.
W programie dla STM32 poprawiłem też filtr audio dla demodulacji AM. Okazał się być on trochę niestabilny, co wynikało z błędów obliczeń zmiennoprzecinkowych pojedynczej precyzji. Niby w Matlabie to uwzględniałem, ale widocznie znaczenie ma też konkretna implementacja i to co zrobi z tym kompilator. Musiałem to przerobić na filtr dwu sekcyjny, bo inaczej nie dało się tego zrobić. Chodzi o coś takiego:
[R. G. Lyons: Wprowadzenie do cyfrowego przetwarzania sygnałów, WKŁ, Warszawa1999]
Tutaj jest rozwiązanie a. Generalnie takie coś może prowadzić do zmniejszenia błędów zaokrągleń. Obecnie jest 100 razy lepszy odbiór. Słyszalny w poprzednim artykule szum dla AM wynikał właśnie w dużej mierze z tego problemu. Ponadto znacznie większe wzmocnienie pozwala słuchać całej masy aktywności jaka jest na falach krótkich. Zatem również i do MxL5007T można dołączyć opracowany wcześnie up-converter:
Ponieważ znam wzmocnienie całego toru, to mogłem wyznaczyć tłumienie up-convertera. Ustawiłem gain na 70 dB i zaprogramowałem częstotliwość na MxL5007T na 60 MHz. Na wejście up-convertera podałem 10 MHz i napięcie Urf=150 µV. Wzmocnienie całego toru wynosiło teraz 64,10 dB. Czyli up-converter tłumi 64,10 dB-70 dB=-5,90 dB. Jest to zgodne z datasheet, bo dla tego mieszacza szerokopasmowego ma to być rzędu -5 dB.
Poniżej nagrania dla odbioru kilku stacji komercyjnych na falach krótkich, zresztą teraz jest w czym wybierać:
11,65 MHz
11,98 MHz
13,81 MHz
15,23 MHz
Spory problem stanowi brak jakiegokolwiek ARW. W R820T miałem przynajmniej dwa poziomy wewnętrznego ARW. Tu nie ma niczego. Stąd bywa z tym kłopot przy zmianach poziomu sygnału:
Na oscyloskopie widać sygnał p.cz. Widoczne są znaczne wahania poziomu sygnału, co mocno utrudnia odbiór. Jest to oczywiście dla AM. Niestety nie ma szans na dorobienie ARW z uwagi na brak możliwości obliczeniowych w STM32.
Inny kłopot to słaba selektywność tego odbiornika. To jest jednak w dużym stopniu poprawiane przez DSP, ale to nie zawsze wystarcza.
Bardzo aktywne okazują się być pasma amatorskie z okolic 7 MHz i 14 MHz. Udało się odebrać CW i również SSB, ale tego na tym odbiorniku się nie odbierze poprawnie. Do odbioru CW zwyczajnie wystawiałem na C/A sygnały i(n) i q(n). W ten sposób powstawał odbiornik homodynowy tj. o bezpośredniej przemianie częstotliwości. Tak też można zrobić podejście do SSB, ale nie dało się tego zrozumieć. Duży problem to krok strojenia w takim przypadku i stała wartość częstotliwości heterodyny w mieszaniu cyfrowym (można to traktować jak BFO). Udało się np. odebrać w ten sposób coś na 14,01 MHz może RTTY?
Robiłem też podejście do odbioru CW (również w improwizowany sposób homodynowy). Tutaj przeprowadzałem też jakieś próby dekodowania. W nagraniach pominąłem obraz, bo tym razem nagrywałem tylko dźwięk rejestratorem dźwięku w Windows. Potem skonwertowałem pliki WMA na MP4, by wygodnie je tu zamieścić:
7,03 MHz
Ledwo to słychać. Nie udało mi się tego zdekodować.
14,025 MHz
To już jakoś udało się zdekodować. Skorzystałem tu ze strony: Link. Po ustawieniu "Volume threshold" na 240 i dwukrotnym odtworzeniu tego pliku (dobór parametrów) uzyskuje się coś takiego:
TEST N AA AA3T HRT TNT WN TU TE RTIEE CME E ST UET5 E IR UA3RBS TEST URBR TEST UA3RBR UTJest w tym pewnie sporo błędów, ale np. UA3RBR i UA3RBS to faktycznie znaki rosyjskich krótkofalowców. Dla odmiany AA3T, to ktoś z USA.
Ponownie 14,01 MHz:
Tym razem udało się zdekodować tylko tyle:
GS R5BS A5DA TU TEST RK5K/PTylko R5BS faktycznie istnieje. Reszta odebrana jest błędnie.
Odbiór stacji z zakresu 88-108 MHz też jest dobry.
95,60 MHz
106,60 MHz
Na zakończenie dodam jeszcze jakieś wyniki z konsoli UART. Tak w tej chwili wygląda start odbiornika:
Jak widać mam tu wersję MxL5007T_V4. W takim wypadku w rejstrze 0xD9 będzie 0x14. Kilka komend po kolei:
Również i tym razem projekt zamieściłem w repozytorium na Githubie: MxL5007-and-STM32F407-SDR-receiver. Mam nadzieję, że tym razem nie przesadziłem ze szczegółowością opisu. Chciałem jednak przedstawić cały tok rozumowania. Mam nadzieję, że ktoś dotarł do tego miejsca. W razie pojawienia się zainteresowania chętnie odpowiem na wszelkie pytania.
Fajne? Ranking DIY