Windows Embedded Compact 7 wave 3 update (2017/06)
en_windows_embedded_compact_7_december_2014_x86_x64_dvd_6315546.iso
自己找....
不要再來找我要啥 CE 的 service, 我只會回給你十個字, 去死吧去死吧去死吧幹
2017年8月28日 星期一
2017年3月31日 星期五
[Win32] 阻止 winsock.h
compile 多加一個定義 _WINSOCKAPI_
可以有效阻止 include windows.h 時順路把 winsock.h (不是 winsock2.h) include 進來 -_-
王八蛋......
2016年4月9日 星期六
[Windows CE] x86 default debug UART
很懶的在 loadcepc.exe 這裡下參數的可以改在這裡.
COM1, 38400.
C:\WINCE700\platform\CEPC\src\bootloader\dos\loadcepc\main.c
約 201 行
BootArgs.ucComPort = 1;
BootArgs.ucBaudDivisor = 3; // Default 38400
ubBaudDivisor 的設定在 BaudTable, 設定為 1 時就是 115200.
BaudTable[] =
{
{ 9600, 12},
{ 19200, 6},
{ 38400, 3},
{ 57600, 2},
{ 115200, 1}
};
COM1, 38400.
C:\WINCE700\platform\CEPC\src\bootloader\dos\loadcepc\main.c
約 201 行
BootArgs.ucComPort = 1;
BootArgs.ucBaudDivisor = 3; // Default 38400
BaudTable[] =
{
{ 9600, 12},
{ 19200, 6},
{ 38400, 3},
{ 57600, 2},
{ 115200, 1}
};
怎麼 compile 就是個大工程了, 不寫在這.
2015年10月16日 星期五
CE hive registry (續)
其實後來發現. windows CE hive registry 從 5.0 以來就沒什麼改變, 本文講的是 CE 7.0, hive registry 儲存界面為 SDmemory. 因為 SDbus 在一開機時並不會載入, 所以需要另外加進 boot.hv 中. 但因為這些內容是擺在 Microsoft Windows core registry 中, 基本上個人並不建議去更動 (事實上隨著 Microsoft 的 update 這個檔內容也會一直修一直改, 改動它, 難保哪天做 update 時又再被改回來, 也就是說改它等於做白工), 所以另外做一個 sd_hive.reg 檔, 內容就從 common.reg 裡抄出來. common.reg 檔案在 C:\WINCE700\public\common\oak\files 裡.
再說一次因為很重要, 請從自己的 common.reg 裡 copy/paste, 因為每一版 common.reg 並不會完全一樣, 硬貼上我的版本是有機會開不了機的...
sd_hive.reg 內容, 紅色為必加內容.
; @CESYSGEN IF CE_MODULES_SDBUS
; HIVE BOOT SECTION
[HKEY_LOCAL_MACHINE\Drivers\Builtin\SDBusDriver]
"Order"=dword:15
"Dll"="SDBus.dll"
"Prefix"="SDC"
"ThreadPriority"=dword:64 ; default thread priority for dispatch thread
"RequestListDepth"=dword:30 ; pre-allocated requests
"IClass"=multi_sz:"{20FA98A8-B298-4b32-8D72-C716AEE2FA84}=%b","{6F40791D-300E-44E4-BC38-E0E63CA8375C}=%b"
"Flags"=dword:1000
"BootPhase"=dword:0
; END HIVE BOOT SECTION
; @CESYSGEN ENDIF CE_MODULES_SDBUS
; @CESYSGEN IF CE_MODULES_SDMEMORY
; HIVE BOOT SECTION
[HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\SDMemory]
....中略....
[HKEY_LOCAL_MACHINE\Drivers\SDCARD\ClientDrivers\Class\MMC_Class\High_Capacity]
....中略....
; END HIVE BOOT SECTION
; @CESYSGEN ENDIF CE_MODULES_SDMEMORY
以上 HIVE BOOT SECTION 與 END HIVE BOOT SECTION 為必加, 很重要.
再來的是 platform build 有一個環境設定的 .bat 檔裡加上
set PRJ_ENABLE_FSREGHIVE=1
set PRJ_ENABLE_REGFLUSH_THREAD=1
set PRJ_ENABLE_FSMOUNTASROOT=1
這幾個敘述, 但是 PRJ_ENABLE_FSREGHIVE 這個設定其實跟 PRJ_BOOTDEVICE_MSFLASH 和 PRJ_BOOTDEVICE_ATAPI 有關, 而這兩者都不設定時, 會被默認為 PRJ_BOOTDEVICE_ATAPI, 於是要再做一個 sd_plat.reg 註消在這裡面設定的內容.
sd_plat.reg 內容:
; HIVE BOOT SECTION
[HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\HDProfile]
"MountAsBootable"=-
"MountAsRoot"=-
[HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\MSFlash]
"MountAsBootable"=-
[HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\MSFlash\FATFS]
"MountAsRoot"=-
[HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\MMC]
"MountAsBootable"=dword:1
[HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\SDMemory]
"MountAsBootable"=dword:1
[HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\SDHCMemory]
"MountAsBootable"=dword:1
;enable compress, unnecessary
[HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\MMC\FATFS\Filters\CEFilt]
"Dll"="cefilt.dll"
[HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\SDMemory\FATFS\Filters\CEFilt]
"Dll"="cefilt.dll"
[HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\SDHCMemory\FATFS\Filters\CEFilt]
"Dll"="cefilt.dll"
IF PRJ_ENABLE_FSREGHIVE
[HKEY_LOCAL_MACHINE\init\BootVars]
"Flags"=dword:1
[HKEY_LOCAL_MACHINE\System\StorageManager\AutoLoad\ObjectStore]
"MountAsRoot"=dword:1
ENDIF
; END HIVE BOOT SECTION
一般來講 mountasbootable=dword:1 如果有多處, 你就要確定這些東西開機時只會有其中一樣有作用. mountasroot=dword:1 這個就要小心, 如果設定在 storage/FS 上就會看到所有的根目錄都變成那個 storage 圖示. 在這裡是走預設掛到 RAMdisk 去. 如果看到範例裡設定一大票地方都 mountasroot=dword:1, 那表示這個是亂槍打鳥打中的, 哪天也會出包, 要小心.
以上都是系統的, 再來才是 BSP 外加的 SD host driver 加在 boot.hv 中, 例如:
; HIVE BOOT SECTION
IF BSP_SDHC
[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\SDHC]
"Prefix"="SHC"
"Dll"="omap_sdhc.dll"
"Flags"=dword:1000
ENDIF BSP_SDHC
; END HIVE BOOT SECTION
在這裡 "Flags"=dword:1000 這句很重要, 再來是前面講的 HIVE BOOT SECTION 一定要加上.
然後在 platform.reg 裡加上剛剛寫的 registry file:
#include "$(_TARGETPLATROOT)\sd_hive.reg"
#include "$(_TARGETPLATROOT)\sd_plat.reg"
build platform 蓋好後可以用 show built image 這個功能打開 nk.bin 看 boot.hv
看boot.hv是否如預期要求加上需要的 registry.
如果不如預期, 可以改剛剛做的那兩個 sd_plat.reg 與 sd_hive.reg 後做 mage run-time image, 就可以一直驗證到滿意為止.
相關筆記可以參考這裡的文章:
http://processors.wiki.ti.com/index.php/Persistent_Registry_in_ARM-A8_BSP
ps. 如果開不了機, 需要注意是不是其它的 driver 擋到開機流程....
下次有時間我再來驗證走 USB storage 的...
再說一次因為很重要, 請從自己的 common.reg 裡 copy/paste, 因為每一版 common.reg 並不會完全一樣, 硬貼上我的版本是有機會開不了機的...
sd_hive.reg 內容, 紅色為必加內容.
; @CESYSGEN IF CE_MODULES_SDBUS
; HIVE BOOT SECTION
[HKEY_LOCAL_MACHINE\Drivers\Builtin\SDBusDriver]
"Order"=dword:15
"Dll"="SDBus.dll"
"Prefix"="SDC"
"ThreadPriority"=dword:64 ; default thread priority for dispatch thread
"RequestListDepth"=dword:30 ; pre-allocated requests
"IClass"=multi_sz:"{20FA98A8-B298-4b32-8D72-C716AEE2FA84}=%b","{6F40791D-300E-44E4-BC38-E0E63CA8375C}=%b"
"Flags"=dword:1000
"BootPhase"=dword:0
; END HIVE BOOT SECTION
; @CESYSGEN ENDIF CE_MODULES_SDBUS
; @CESYSGEN IF CE_MODULES_SDMEMORY
; HIVE BOOT SECTION
[HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\SDMemory]
....中略....
[HKEY_LOCAL_MACHINE\Drivers\SDCARD\ClientDrivers\Class\MMC_Class\High_Capacity]
....中略....
; END HIVE BOOT SECTION
; @CESYSGEN ENDIF CE_MODULES_SDMEMORY
以上 HIVE BOOT SECTION 與 END HIVE BOOT SECTION 為必加, 很重要.
再來的是 platform build 有一個環境設定的 .bat 檔裡加上
set PRJ_ENABLE_FSREGHIVE=1
set PRJ_ENABLE_REGFLUSH_THREAD=1
set PRJ_ENABLE_FSMOUNTASROOT=1
這幾個敘述, 但是 PRJ_ENABLE_FSREGHIVE 這個設定其實跟 PRJ_BOOTDEVICE_MSFLASH 和 PRJ_BOOTDEVICE_ATAPI 有關, 而這兩者都不設定時, 會被默認為 PRJ_BOOTDEVICE_ATAPI, 於是要再做一個 sd_plat.reg 註消在這裡面設定的內容.
sd_plat.reg 內容:
; HIVE BOOT SECTION
[HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\HDProfile]
"MountAsBootable"=-
"MountAsRoot"=-
[HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\MSFlash]
"MountAsBootable"=-
[HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\MSFlash\FATFS]
"MountAsRoot"=-
[HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\MMC]
"MountAsBootable"=dword:1
[HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\SDMemory]
"MountAsBootable"=dword:1
[HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\SDHCMemory]
"MountAsBootable"=dword:1
;enable compress, unnecessary
[HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\MMC\FATFS\Filters\CEFilt]
"Dll"="cefilt.dll"
[HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\SDMemory\FATFS\Filters\CEFilt]
"Dll"="cefilt.dll"
[HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\SDHCMemory\FATFS\Filters\CEFilt]
"Dll"="cefilt.dll"
IF PRJ_ENABLE_FSREGHIVE
[HKEY_LOCAL_MACHINE\init\BootVars]
"Flags"=dword:1
[HKEY_LOCAL_MACHINE\System\StorageManager\AutoLoad\ObjectStore]
"MountAsRoot"=dword:1
ENDIF
; END HIVE BOOT SECTION
一般來講 mountasbootable=dword:1 如果有多處, 你就要確定這些東西開機時只會有其中一樣有作用. mountasroot=dword:1 這個就要小心, 如果設定在 storage/FS 上就會看到所有的根目錄都變成那個 storage 圖示. 在這裡是走預設掛到 RAMdisk 去. 如果看到範例裡設定一大票地方都 mountasroot=dword:1, 那表示這個是亂槍打鳥打中的, 哪天也會出包, 要小心.
以上都是系統的, 再來才是 BSP 外加的 SD host driver 加在 boot.hv 中, 例如:
; HIVE BOOT SECTION
IF BSP_SDHC
[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\SDHC]
"Prefix"="SHC"
"Dll"="omap_sdhc.dll"
"Flags"=dword:1000
ENDIF BSP_SDHC
; END HIVE BOOT SECTION
在這裡 "Flags"=dword:1000 這句很重要, 再來是前面講的 HIVE BOOT SECTION 一定要加上.
然後在 platform.reg 裡加上剛剛寫的 registry file:
#include "$(_TARGETPLATROOT)\sd_hive.reg"
#include "$(_TARGETPLATROOT)\sd_plat.reg"
這樣, 再 build platform.
build platform 蓋好後可以用 show built image 這個功能打開 nk.bin 看 boot.hv
看boot.hv是否如預期要求加上需要的 registry.
如果不如預期, 可以改剛剛做的那兩個 sd_plat.reg 與 sd_hive.reg 後做 mage run-time image, 就可以一直驗證到滿意為止.
相關筆記可以參考這裡的文章:
http://processors.wiki.ti.com/index.php/Persistent_Registry_in_ARM-A8_BSP
ps. 如果開不了機, 需要注意是不是其它的 driver 擋到開機流程....
下次有時間我再來驗證走 USB storage 的...
2013年6月21日 星期五
Windows CE, GPRS.
實驗的筆記, 沒有在 ublox G350 以外的 GPRS modules 確認過.
首先的, ublox G350 它可以對 UART 的波型做相位修正的工作, 也就是 baud auto-detect, 所以這裡並沒有 UART 的通訊與控制等.
首先的要在 control-panel 裡設定網路 (Network and Dial-up Connections), 設定撥號 (Make new Connection),
2003/06/23 update:
如果覺的沒有撥號圖示感覺好像少了什麼似的, 的話, 來試試第二個方法. 第二個方法比較簡單:
rnapp.exe -m -n -p -eDIALUPNAME
DIALUPNAME 就是在電話簿裡取的名字.
以下就是可有可無的東西了, 但是很多...
這樣做通常還要再搭配另一個東西, windows-message receiver, 專門去接收 WM_NETCONNECT 這個訊息, 在 MFC 底下可以設定一個很簡單的訊息接收器, 像這樣:
.h
------------
#ifndef WM_NETCONNECT
#define WM_NETCONNECT 0x3feL
#endif
#ifndef RAS_MaxEntryName
#define RAS_MaxEntryName 20
#endif
typedef struct tagRNAAppInfo {
DWORD dwSize;
DWORD hWndRNAApp;
DWORD Context;
DWORD ErrorCode;
TCHAR RasEntryName[RAS_MaxEntryName+1];
} RNAAPP_INFO, *PRNAAPP_INFO;
class Ctheapp : public CWnd
{
afx_msg LRESULT msg_NetConnect(WPARAM, LPARAM);
}
------------
.cpp
------------
BEGIN_MESSAGE_MAP(Ctheapp, CWnd)
ON_MESSAGE(MSG_UI_INIT, msg_NetConnect)
END_MESSAGE_MAP()
LRESULT Ctheapp::msg_NetConnect(WPARAM wParam, LPARAM lParam)
{
BOOL bConnect = (BOOL)wParam;
PRNAAPP_INFO pInfo = (PRNAAPP_INFO)lParam;
if(bConnect)
wprintf(L"connect to %s\n", pInfo->RasEntryName);
else
wprintf(L"%s Disconnect\n", pInfo->RasEntryName);
return 0;
}
------------
要斷線更麻煩, 要用 findwindow 去找到 rnaapp.exe 後對它發 message. 所以一開始就不使用 rnaapp 當撥接器..
首先的, ublox G350 它可以對 UART 的波型做相位修正的工作, 也就是 baud auto-detect, 所以這裡並沒有 UART 的通訊與控制等.
首先的要在 control-panel 裡設定網路 (Network and Dial-up Connections), 設定撥號 (Make new Connection),
- 設定電話簿名稱 (註: 這個名字十分重要, 請盡可能用英文名), Dial-up connection, next.
- 選擇好 COM (device properites 有些該注意的設定像 baud, data bits, parity, stop bits, flow-control 要注意, 還有第二頁的 "Extra settings" 請一定要在這裡設定好 APN 名稱指令, 如 +cgdcont=1,"IP","internet" ), next.
- 設定 phone number, 一般用 *99#, 但並不是所有的電信業者都一模一樣, 請注意.
因為在 code 裡面是呼叫電話簿來使用, 所以電話簿本身的設定正不正確, 直接影響 GPRS 能不能正常連線.
再來是 code.
//pwEntryName 就是電話簿名稱, 所以前面提這個名字非常重要.
//pRasConn 是之後連線狀況取得與斷線會用上的 handle, 必需保留.
int RAS_Dial(TCHAR pwEntryName[20], HRASCONN *pRasConn)
{
RASDIALPARAMS tRasDialParams = { 0 };
int nERR = 0;
tRasDialParams.dwSize = sizeof(RASDIALPARAMS);
_tcscpy_s(tRasDialParams.szEntryName, 20, pwEntryName);
RasGetEntryDialParams(pwEntryName, 0, 0);
nERR = (int)RasDial(0, 0, &tRasDialParams, (DWORD)-1, 0, pRasConn);
return nERR;
}
int RAS_HangUp(HRASCONN tRasConn)
{
return (int)RasHangUp(tRasConn);
}
int RAS_GetConnectState(HRASCONN tRasConn)
{
RASCONNSTATUS tStatus = { 0 };
RasGetConnectStatus(tRasConn, &tStatus);
if(tStatus.rasconnstate == RASCS_Connected)
{
return 1;
}
return 0;
}
其中比較奇怪的在 RasDial 這裡的 hwnd 要直接給它 null 不能傳入 cWnd 裡的 hwnd 參數, 否則無法工作, 這個不知道是為什麼.
純筆記.
2003/06/23 update:
如果覺的沒有撥號圖示感覺好像少了什麼似的, 的話, 來試試第二個方法. 第二個方法比較簡單:
rnapp.exe -m -n -p -eDIALUPNAME
DIALUPNAME 就是在電話簿裡取的名字.
以下就是可有可無的東西了, 但是很多...
這樣做通常還要再搭配另一個東西, windows-message receiver, 專門去接收 WM_NETCONNECT 這個訊息, 在 MFC 底下可以設定一個很簡單的訊息接收器, 像這樣:
.h
------------
#ifndef WM_NETCONNECT
#define WM_NETCONNECT 0x3feL
#endif
#ifndef RAS_MaxEntryName
#define RAS_MaxEntryName 20
#endif
typedef struct tagRNAAppInfo {
DWORD dwSize;
DWORD hWndRNAApp;
DWORD Context;
DWORD ErrorCode;
TCHAR RasEntryName[RAS_MaxEntryName+1];
} RNAAPP_INFO, *PRNAAPP_INFO;
class Ctheapp : public CWnd
{
afx_msg LRESULT msg_NetConnect(WPARAM, LPARAM);
}
------------
.cpp
------------
BEGIN_MESSAGE_MAP(Ctheapp, CWnd)
ON_MESSAGE(MSG_UI_INIT, msg_NetConnect)
END_MESSAGE_MAP()
LRESULT Ctheapp::msg_NetConnect(WPARAM wParam, LPARAM lParam)
{
BOOL bConnect = (BOOL)wParam;
PRNAAPP_INFO pInfo = (PRNAAPP_INFO)lParam;
if(bConnect)
wprintf(L"connect to %s\n", pInfo->RasEntryName);
else
wprintf(L"%s Disconnect\n", pInfo->RasEntryName);
return 0;
}
------------
2013年6月7日 星期五
Windows CE 下 flash memory raw data 操作
這個部份的操作, 其實在有 BSP code 時就有注意到了, 但是微軟有關 "IOCTL_FLASH_PDD" 方面的資料並不算很多, 網路上更是少的可以..
這是 FLASH_PDD 整個 driver 的架構一覽:
http://msdn.microsoft.com/en-us/library/bb821532.aspx
從這裡可以知道, FLASH PDD driver 其實是比一般 disk IO 更底層的 driver, 一般皆使用 DeviceIoControl 去操作, 在這裡有 CE 提供的既有功能:
http://msdn.microsoft.com/en-us/library/ee484253(v=winembedded.60).aspx
好的, 從這裡可以知道有哪些工具可以用. 至於這些 DeviceIoControl 用的 header, 其實要用 OpenStore() 去開, 而非 CreateFile 開 DSK?:
http://msdn.microsoft.com/en-US/library/ee489981(v=winembedded.60).aspx
到這裡, 才算是真正可以拿到 flash memory (可能是 NAND, 可能是 NOR, 不一定) 的 RAW data.
example code: (read only)
int GetNandAssignData(void *pvDstData, int nSectorAddr, int nSectorCount)
{ //for XP35C6, iVC1 only.
HANDLE hndDSK = 0;
int nERR = -1;
FLASH_PDD_TRANSFER
tPDDtrans;
FLASH_READ_STATUS
tPDDstate;
hndDSK = OpenStore(L"MSFlash");
if(!hndDSK || hndDSK == INVALID_HANDLE_VALUE) return -1;
tPDDtrans.pData = (unsigned char*)pvDstData;
tPDDtrans.pSpare = 0;
tPDDtrans.RegionIndex = 0;
tPDDtrans.SectorRun.StartSector = nSectorAddr;
tPDDtrans.SectorRun.SectorCount = nSectorCount;
nERR = (int)DeviceIoControl(
hndDSK,
IOCTL_FLASH_PDD_READ_PHYSICAL_SECTORS,
&tPDDtrans,
sizeof(FLASH_PDD_TRANSFER),
&tPDDstate,
sizeof(ULONG),
0,
0);
CloseHandle(hndDSK);
if(nERR) return 0;
else return -2;
}
版權沒有, 僅管拿去用.
到這裡還需要的, 尚有:
1. BSP 設定的 flash memory map. 有這個地圖, 才會知道哪區擺的是哪個.
2. Flash 的 page size,spare size, block size.
3. NAND 需要 ECC 產生器, 而且必需要跟原本用的格式一樣.
目前試過 physical read 跟 block erase 沒有問題, 寫入因為欠 ECC 產生器作罷.
ps. 20130610後記: 在 FreeScale 官方 Windows CE BSP 上 page read/write 皆無 spare, spare 的部份設定只能借 block get/set (FLASH_BLOCK_STATUS_BAD, FLASH_BLOCK_STATUS_RESERVED) 得到或設定這個 flag.
別家的 SoC 的 BSP 有沒有把這部份 implement 的夠完整? 我不知道, 我也沒辦法做任何保證. 畢竟 BSP code 裡有多少地雷, 老闆跟 PM 不會知道也不會關心.
這是 FLASH_PDD 整個 driver 的架構一覽:
http://msdn.microsoft.com/en-us/library/bb821532.aspx
從這裡可以知道, FLASH PDD driver 其實是比一般 disk IO 更底層的 driver, 一般皆使用 DeviceIoControl 去操作, 在這裡有 CE 提供的既有功能:
http://msdn.microsoft.com/en-us/library/ee484253(v=winembedded.60).aspx
好的, 從這裡可以知道有哪些工具可以用. 至於這些 DeviceIoControl 用的 header, 其實要用 OpenStore() 去開, 而非 CreateFile 開 DSK?:
http://msdn.microsoft.com/en-US/library/ee489981(v=winembedded.60).aspx
到這裡, 才算是真正可以拿到 flash memory (可能是 NAND, 可能是 NOR, 不一定) 的 RAW data.
example code: (read only)
int GetNandAssignData(void *pvDstData, int nSectorAddr, int nSectorCount)
{ //for XP35C6, iVC1 only.
HANDLE hndDSK = 0;
int nERR = -1;
FLASH_PDD_TRANSFER
tPDDtrans;
FLASH_READ_STATUS
tPDDstate;
hndDSK = OpenStore(L"MSFlash");
if(!hndDSK || hndDSK == INVALID_HANDLE_VALUE) return -1;
tPDDtrans.pData = (unsigned char*)pvDstData;
tPDDtrans.pSpare = 0;
tPDDtrans.RegionIndex = 0;
tPDDtrans.SectorRun.StartSector = nSectorAddr;
tPDDtrans.SectorRun.SectorCount = nSectorCount;
nERR = (int)DeviceIoControl(
hndDSK,
IOCTL_FLASH_PDD_READ_PHYSICAL_SECTORS,
&tPDDtrans,
sizeof(FLASH_PDD_TRANSFER),
&tPDDstate,
sizeof(ULONG),
0,
0);
CloseHandle(hndDSK);
if(nERR) return 0;
else return -2;
}
到這裡還需要的, 尚有:
1. BSP 設定的 flash memory map. 有這個地圖, 才會知道哪區擺的是哪個.
2. Flash 的 page size,
3. NAND 需要 ECC 產生器, 而且必需要跟原本用的格式一樣.
目前試過 physical read 跟 block erase 沒有問題, 寫入因為欠 ECC 產生器作罷.
ps. 20130610後記: 在 FreeScale 官方 Windows CE BSP 上 page read/write 皆無 spare, spare 的部份設定只能借 block get/set (FLASH_BLOCK_STATUS_BAD, FLASH_BLOCK_STATUS_RESERVED) 得到或設定這個 flag.
別家的 SoC 的 BSP 有沒有把這部份 implement 的夠完整? 我不知道, 我也沒辦法做任何保證. 畢竟 BSP code 裡有多少地雷, 老闆跟 PM 不會知道也不會關心.
2012年10月2日 星期二
i.MX35 256M DDR2 at XLDR (Windows CE)
這個 code 是抄自 u-boot 的 patch:
http://lists.infradead.org/pipermail/barebox/2011-April/003461.html
要修改的檔案有 xldr.s 跟 startup.s, 但 startup.s 是 OALLIB 裡的檔案, 修改好後, 建議 XLDR / eboot / OS 三樣都一起換掉.
ldr r0, =0x304 ; bit 9 is DDR2_EN
str r0, [r1, #ESDCTL_ESDMISC_OFFSET]
+ ldr r0, =0x30C ; Reset mDDR
+ str r0, [r1, #ESDCTL_ESDMISC_OFFSET]
...
IF :DEF: BSP_CPU_TO1 ; 有兩處
ldr r0, =0x007FFC2F ; Conservative
ELSE
- ldr r0, =0x0079542A ; Moderate
+ ldr r0, =0x007FFC3F ;
ENDIF
...
ldr r0, =0x00002000
str r0, [r1, #ESDCTL_ESDCTL1_OFFSET]
ENDIF
+ ldr r0, =0x007FFC3F
+ str r0, [r1, #ESDCTL_ESDCFG0_OFFSET]
...
IF :DEF: BSP_CPU_TO1 ; 這是第二處
ldr r0, =0x007FFC2F ; Conservative
ELSE
- ldr r0, =0x0079542A ; Moderate
+ ldr r0, =0x007FFC3F ;
ENDIF
...
ldr r0, =0x82226080
str r0, [r1, #ESDCTL_ESDCTL1_OFFSET]
+ ldr r0, =0x007FFC3F
+ str r0, [r1, #ESDCTL_ESDCFG1_OFFSET]
ENDIF
+ ldr r0, =0x00000304
+ str r0, [r1, #ESDCTL_ESDMISC_OFFSET]
這裡只貼出要修改的部份, 要完整的 code 請來我 google+ 或 facebook 找我要...
2013/01/09 update:
以下是開 9MiB frame buffer 的值, 如果有把 frame buffer size 再自行縮小設定值, RAM_SIZE 的值就再自行修正...
config.bib 中修改 RAM_SIZE 從 03500000 到 04600000
IF IMGFLASH !
#define NK_START 80200000
.....
#define RAM_START 83100000
; #define RAM_SIZE 03500000
#define RAM_SIZE 04600000
ENDIF
image_cfg.h 中做一點修正:
#define IMAGE_BOOT_RAMDEV_RAM_SIZE (128*1024*1024) ;這是單一bank的DRAM size.
#define IMAGE_WINCE_IPU_RAM_SIZE (8064*1024)
#define IMAGE_WINCE_IPU_REV_RAM_SIZE (9216*1024)
#define IMAGE_WINCE_IPU_RAM_OFFSET (IMAGE_BOOT_RAMDEV_RAM_SIZE - IMAGE_WINCE_IPU_REV_RAM_SIZE) //(0x7700000)
#define IMAGE_WINCE_IPU_RAM_PA_START (CSP_BASE_MEM_PA_CSD0 + IMAGE_WINCE_IPU_RAM_OFFSET)
http://lists.infradead.org/pipermail/barebox/2011-April/003461.html
要修改的檔案有 xldr.s 跟 startup.s, 但 startup.s 是 OALLIB 裡的檔案, 修改好後, 建議 XLDR / eboot / OS 三樣都一起換掉.
ldr r0, =0x304 ; bit 9 is DDR2_EN
str r0, [r1, #ESDCTL_ESDMISC_OFFSET]
+ ldr r0, =0x30C ; Reset mDDR
+ str r0, [r1, #ESDCTL_ESDMISC_OFFSET]
...
IF :DEF: BSP_CPU_TO1 ; 有兩處
ldr r0, =0x007FFC2F ; Conservative
ELSE
- ldr r0, =0x0079542A ; Moderate
+ ldr r0, =0x007FFC3F ;
ENDIF
...
ldr r0, =0x00002000
str r0, [r1, #ESDCTL_ESDCTL1_OFFSET]
ENDIF
+ ldr r0, =0x007FFC3F
+ str r0, [r1, #ESDCTL_ESDCFG0_OFFSET]
...
IF :DEF: BSP_CPU_TO1 ; 這是第二處
ldr r0, =0x007FFC2F ; Conservative
ELSE
- ldr r0, =0x0079542A ; Moderate
+ ldr r0, =0x007FFC3F ;
ENDIF
...
ldr r0, =0x82226080
str r0, [r1, #ESDCTL_ESDCTL1_OFFSET]
+ ldr r0, =0x007FFC3F
+ str r0, [r1, #ESDCTL_ESDCFG1_OFFSET]
ENDIF
+ ldr r0, =0x00000304
+ str r0, [r1, #ESDCTL_ESDMISC_OFFSET]
這裡只貼出要修改的部份, 要完整的 code 請來我 google+ 或 facebook 找我要...
2013/01/09 update:
以下是開 9MiB frame buffer 的值, 如果有把 frame buffer size 再自行縮小設定值, RAM_SIZE 的值就再自行修正...
config.bib 中修改 RAM_SIZE 從 03500000 到 04600000
IF IMGFLASH !
#define NK_START 80200000
.....
#define RAM_START 83100000
; #define RAM_SIZE 03500000
#define RAM_SIZE 04600000
ENDIF
image_cfg.h 中做一點修正:
#define IMAGE_BOOT_RAMDEV_RAM_SIZE (128*1024*1024) ;這是單一bank的DRAM size.
#define IMAGE_WINCE_IPU_RAM_SIZE (8064*1024)
#define IMAGE_WINCE_IPU_REV_RAM_SIZE (9216*1024)
#define IMAGE_WINCE_IPU_RAM_OFFSET (IMAGE_BOOT_RAMDEV_RAM_SIZE - IMAGE_WINCE_IPU_REV_RAM_SIZE) //(0x7700000)
#define IMAGE_WINCE_IPU_RAM_PA_START (CSP_BASE_MEM_PA_CSD0 + IMAGE_WINCE_IPU_RAM_OFFSET)
最後段要保留一點記憶體... 我不知道 FreeScale 在這裡動了什麼手腳.
最後記得環境變數 IMGRAM256 = 1 要設定, 其它的 source code 不用改.
2012年6月23日 星期六
另一種 system();
就是用 CreateProcess 取代.
不過一般 CreateProcess 是開一個 task 以多工的方式跑另一個執行檔, 和 system() 不一樣, system() 會等待那個執行檔執行結束.
CreateProcess 也可以在該執行檔結束時發一個 event 通知, 像這樣:
PROCESS_INFORMATION tPI = { 0 };
CreateProcess(TEXT("exe.exe"), 0, 0, 0, 0, 0, 0, 0, 0, &tPI);
WaitForSingleObject(tPI.hProcess, INFINITE);
exe.exe 就是要執行的, 這樣就會無限時等待 exe.exe 執行完畢.
會寫這篇是因為 1.太久沒更新 2.CE 上沒有 system() 可用.
不過一般 CreateProcess 是開一個 task 以多工的方式跑另一個執行檔, 和 system() 不一樣, system() 會等待那個執行檔執行結束.
CreateProcess 也可以在該執行檔結束時發一個 event 通知, 像這樣:
PROCESS_INFORMATION tPI = { 0 };
CreateProcess(TEXT("exe.exe"), 0, 0, 0, 0, 0, 0, 0, 0, &tPI);
WaitForSingleObject(tPI.hProcess, INFINITE);
exe.exe 就是要執行的, 這樣就會無限時等待 exe.exe 執行完畢.
會寫這篇是因為 1.太久沒更新 2.CE 上沒有 system() 可用.
2011年11月14日 星期一
CE 6.0 HIVE
很久以前解掉的, 留一下筆記.
除了網路上找的到的設定以外, environment 裡加上兩個很重要的參數:
PRJ_ENABLE_FSREGHIVE=1
PRJ_BOOTDEVICE_MSFLASH=1
這兩個的相關設定被擺在
C:\WINCE600\PUBLIC\COMMON\OAK\FILES\common.reg
裡, 而 PRJ_BOOTDEVICE_MSFLASH 這個跟用什麼 storage 存 HIVE 有關係.
2011年11月11日 星期五
i.MX35 e-boot splash
這個 driver 是別人從 i.MX31 IPU driver 中的 SDC.C 裡改出來的, 我再給它改成 i.MX35 使用, main function 是 OALDisplaySplashScreen().
改到 i.MX35要更動的東西, 我現在只剩下記得:
1.DISP3 pin (DISP0~2 是 ADC 用的非 SDC 用的).
2.CCM 中 IPU clock 對應的啟動 bits 要打開, i.MX35 上是 CCM[1] bit 18,19.
3.DMA address, i.MX35 我把它指到 image_cfg.h 中 IPU_PA_START, i.MX31 跟 i.MX35 的 frame buffer 地點似乎都不一樣, 寫圖片載入器時記得加載到 OALPAtoUA(IMAGE_BOOT_DISPLAY_RAM_START) 去.
這裡預設的圖片格式是 RGB565 而非 windows 的 ARGB1555, 寫轉換程式時要梢加注意.
兩個要自行 implement.
1.LCD power GPIO pin, 這個要記得給它 enable 而且打開.
2.圖片載入. 這個可能從外面讀進來, 可能從 image 裡解壓縮出來, 不一定, 看使用者高興.
檔案下載:
https://skydrive.live.com/?cid=ea95177ed13eeda8&sc=documents&uc=1&id=EA95177ED13EEDA8%21342#
source code:
#pragma warning(disable: 4100 4115 4201 4204 4214 4702)
#include
#include
#include "loader.h"
// Defines
#define FLOW_ARM 0
#define SDC_DMA_CHANNEL IPU_DMA_CHA_DMASDC_0_LSH // background
//#define SDC_DMA_CHANNEL IPU_DMA_CHA_DMASDC_1_LSH // background
// #define IMAGE_BOOT_DISPLAY_RAM_START IMAGE_WINCE_IPU_RAM_PA_START
// #define IMAGE_BOOT_DISPLAY_RAM_SIZE IMAGE_WINCE_IPU_RAM_SIZE
BOOL OALDisplaySplashScreen(void);
void DumpIMA(PCSP_IPU_REGS pIPU, int ch);
// i.MX35 Registers
static PCSP_CCM_REGS g_pCCM = 0;
static PCSP_IOMUX_REGS g_pIOMUX = 0;
static PCSP_IPU_REGS g_pIPU = 0;
extern BOOL NANDLoadLogoPicture(VOID);
// Init the IPU DMA module
static void SetupIDMAC(int width, int height, int bpp, int nFlip, const int channel)
{ //setup IDMAC Channel Parameter Memory.
UINT32 bpp_code, npb_code, sat_code, bam_code, ofs[4], wid[4];
//=================================
// Configure First 132 bit word
//=================================
// Default access type to 32-bit
sat_code = 2;
bam_code = nFlip ? 1 : 0;
npb_code = 0;
switch (bpp)
{
case 32:
bpp_code = 0;
npb_code = 8 - 1;
ofs[0] = 0;
ofs[1] = 8;
ofs[2] = 16;
ofs[3] = 24;
wid[0] = 8 - 1;
wid[1] = 8 - 1;
wid[2] = 8 - 1;
wid[3] = 8 - 1;
break;
case 24:
bpp_code = 1;
npb_code = 10 - 1;
sat_code = 0;
ofs[0] = 0;
ofs[1] = 8;
ofs[2] = 16;
ofs[3] = 0;
wid[0] = 8 - 1;
wid[1] = 8 - 1;
wid[2] = 8 - 1;
wid[3] = 0;
break;
case 16:
bpp_code = 2;
npb_code = 16 - 1;
ofs[0] = 0;
ofs[1] = 5;
ofs[2] = 11;
ofs[3] = 0;
wid[0] = 5 - 1;
wid[1] = 6 - 1;
wid[2] = 5 - 1;
wid[3] = 0;
break;
case 8:
bpp_code = 3;
npb_code = 32 - 1;
ofs[0] = 0;
ofs[1] = 0;
ofs[2] = 0;
ofs[3] = 0;
wid[0] = 8 - 1;
wid[1] = 0;
wid[2] = 0;
wid[3] = 0;
break;
case 4:
bpp_code = 4;
npb_code = 32 - 1;
ofs[0] = 0;
ofs[1] = 0;
ofs[2] = 0;
ofs[3] = 0;
wid[0] = 4 - 1;
wid[1] = 0;
wid[2] = 0;
wid[3] = 0;
break;
case 1:
bpp_code = 5;
npb_code = 64 - 1;
ofs[0] = 0;
ofs[1] = 0;
ofs[2] = 0;
ofs[3] = 0;
wid[0] = 1 - 1;
wid[1] = 0;
wid[2] = 0;
wid[3] = 0;
break;
default:
bpp_code = 7;
// TODO: Should report error here. bpp_code is reserved.
break;
}
// Set IPU_IMA_ADDR (IPU Internal Memory Access Address)
OUTREG32(&g_pIPU->IPU_IMA_ADDR,
CSP_BITFVAL( IPU_IPU_IMA_ADDR_MEM_NU, IPU_IMA_ADDR_MEM_NU_CPM) |
CSP_BITFVAL( IPU_IPU_IMA_ADDR_ROW_NU, (2 * channel )) | // channel is 14
CSP_BITFVAL( IPU_IPU_IMA_ADDR_WORD_NU, 0));
//...0th 32 bit word
// XV [9:0], YV [19:10], XB [31:20]
OUTREG32(&g_pIPU->IPU_IMA_DATA,
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_XV, 0) | // 0
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_YV, 0) | // 10
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_XB, 0)); // 20
//...1st 32 bit word
// YB [11:0], SCE [12], RESERVED [13], NSB [14], LNPB [20:15], SX [30:21],
// SY~ [31]
// - Set NSB
OUTREG32(&g_pIPU->IPU_IMA_DATA,
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_YB, 0) | // 32-32
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_SCE, 0) | // 44-32
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_NSB, 1) | // 46-32
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_LNPB, 0) | // 47-32
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_SX, 0) | // 53-32
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_LOW_SY, 0)); // 63-32
//...2nd 32 bit word
// ~SY [8:0], NS [18:9], SM [28:10] SDX~ [31:29]
OUTREG32(&g_pIPU->IPU_IMA_DATA,
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_HIGH_SY, 0) |
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_NS, 0) |
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_SM, 0) |
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_LOW_SDX, 0));
//...3rd 32 bit word
// ~SDX [1:0], SDY [6:2], SDRX [7], SDRY [8], SCRQ [9], RESERVED [11:10]
// - FW [23:12], FH~ [31:24]
// - Set FW & FH
OUTREG32(&g_pIPU->IPU_IMA_DATA,
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_HIGH_SDX, 0) |
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_SDY, 0) |
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_SDRX, 0) |
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_SDRY, 0) |
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_SCRQ, 0) |
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_FW, (width - 1)) |
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_LOW_FH, (height - 1)));
//...4th 32 bit word
// ~FH [3:0]
// NOTE: this takes care of the upper four bits in the FH field
OUTREG32(&g_pIPU->IPU_IMA_DATA, ((height - 1) >> 8));
//=================================
// Configure Second 132 bit word
//=================================
if(channel == IPU_DMA_CHA_DMASDC_0_LSH || channel == IPU_DMA_CHA_DMASDC_1_LSH)
{
// Set IPU IPU_IMA_ADDR (IPU Internal Memory Access Address)
// MEM_NU = 0x0001 (CPM)
// ROW_NU = 2*N + 1 (N is channel number)
// WORD_NU = 0
OALMSG(1, (TEXT("SDC DMA addr 0x%08x\r\n"), IMAGE_BOOT_DISPLAY_RAM_START));
OUTREG32(&g_pIPU->IPU_IMA_ADDR,
CSP_BITFVAL( IPU_IPU_IMA_ADDR_MEM_NU, IPU_IMA_ADDR_MEM_NU_CPM) |
CSP_BITFVAL( IPU_IPU_IMA_ADDR_ROW_NU, (2 * channel + 1)) |
CSP_BITFVAL( IPU_IPU_IMA_ADDR_WORD_NU, 0));
//...parameters for YUV/RGB interleaved - 2nd 132 bit word
//...0th 32 bit word
// EBA0 [31:0], double buffer page 0
// Set buffer #1 to physical frame buffer address
// 在這裡設定 double buffer page 0 起始位置, 必需是絕對位址.
OUTREG32(&g_pIPU->IPU_IMA_DATA, IMAGE_BOOT_DISPLAY_RAM_START);
//...1st 32 bit word
// EBA1 [31:0], double buffer page 1
OUTREG32(&g_pIPU->IPU_IMA_DATA, 0);
}
else
{
//..skip over EBA0 and EBA1 for the viewfinder mode
//.. Set IPU_IMA_ADDR (IPU Internal Memory Access Address)
//EBA0 與 EBA1 不設定, ADDR_WORD_NU = 2 表從第二個 dword 開始設定.
OUTREG32(&g_pIPU->IPU_IMA_ADDR,
CSP_BITFVAL( IPU_IPU_IMA_ADDR_MEM_NU, IPU_IMA_ADDR_MEM_NU_CPM) |
CSP_BITFVAL( IPU_IPU_IMA_ADDR_ROW_NU, (2 * channel + 1)) |
CSP_BITFVAL( IPU_IPU_IMA_ADDR_WORD_NU, 2));
}
//...2nd 32 bit word
// - BPP [2:0], SL [16:3], PFS [19:17], BAM [24:20], NPB [30:25],
// - RESERVED [31]
// - Set BPP to 24bpp (1)
// - Set SL (Scaling Factor) to bytes_pp * width
// - Set PFS (Packing) to RGB (%100)
OUTREG32(&g_pIPU->IPU_IMA_DATA,
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_BPP, bpp_code) |
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_SL, ((width * bpp / 8) - 1)) |
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_PFS, 0x4) | //0x4 是 RGB
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_BAM, bam_code) |
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_NPB, npb_code));
//...3rd 32 bit word
// SAT [1:0], SCC [2], OFS0 [7:3], 0FS1 [12:8], OFS2 [17:13], OFS3 [22:18]
// - WID0 [25:23], WID1 [28:26], WID2 [31:29]
OUTREG32(&g_pIPU->IPU_IMA_DATA,
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_SAT, sat_code) |
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_SCC, 0) |
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_OFS0, ofs[0]) |
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_OFS1, ofs[1]) |
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_OFS2, ofs[2]) |
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_OFS3, ofs[3]) |
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_WID0, wid[0]) |
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_WID1, wid[1]) |
CSP_BITFVAL( IPU_IPU_IMA_DATA_PARAM_WID2, wid[2]));
//...4th 32 bit word
// WID3 [2:0], DEC_SEL [3],
// Set WID3 (7 - 8 bit size), Color component 3 width (Alpha)
OUTREG32(&g_pIPU->IPU_IMA_DATA,
CSP_BITFVAL(IPU_IPU_IMA_DATA_PARAM_WID3, wid[3]));
}
static void EnableSDC2(void)
{
g_pIOMUX = (PCSP_IOMUX_REGS)OALPAtoUA(CSP_BASE_REG_PA_IOMUXC);
g_pIPU = (PCSP_IPU_REGS)OALPAtoUA(CSP_BASE_REG_PA_IPU);
g_pCCM = (PCSP_CCM_REGS)OALPAtoUA(CSP_BASE_REG_PA_CCM);
// Configure IOMUX to request IPU SDC pins
OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_LD0, DDK_IOMUX_PIN_MUXMODE_ALT0, DDK_IOMUX_PIN_SION_REGULAR);
OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_LD1, DDK_IOMUX_PIN_MUXMODE_ALT0, DDK_IOMUX_PIN_SION_REGULAR);
OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_LD2, DDK_IOMUX_PIN_MUXMODE_ALT0, DDK_IOMUX_PIN_SION_REGULAR);
OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_LD3, DDK_IOMUX_PIN_MUXMODE_ALT0, DDK_IOMUX_PIN_SION_REGULAR);
OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_LD4, DDK_IOMUX_PIN_MUXMODE_ALT0, DDK_IOMUX_PIN_SION_REGULAR);
OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_LD5, DDK_IOMUX_PIN_MUXMODE_ALT0, DDK_IOMUX_PIN_SION_REGULAR);
OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_LD6, DDK_IOMUX_PIN_MUXMODE_ALT0, DDK_IOMUX_PIN_SION_REGULAR);
OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_LD7, DDK_IOMUX_PIN_MUXMODE_ALT0, DDK_IOMUX_PIN_SION_REGULAR);
OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_LD8, DDK_IOMUX_PIN_MUXMODE_ALT0, DDK_IOMUX_PIN_SION_REGULAR);
OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_LD9, DDK_IOMUX_PIN_MUXMODE_ALT0, DDK_IOMUX_PIN_SION_REGULAR);
OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_LD10, DDK_IOMUX_PIN_MUXMODE_ALT0, DDK_IOMUX_PIN_SION_REGULAR);
OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_LD11, DDK_IOMUX_PIN_MUXMODE_ALT0, DDK_IOMUX_PIN_SION_REGULAR);
OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_LD12, DDK_IOMUX_PIN_MUXMODE_ALT0, DDK_IOMUX_PIN_SION_REGULAR);
OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_LD13, DDK_IOMUX_PIN_MUXMODE_ALT0, DDK_IOMUX_PIN_SION_REGULAR);
OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_LD14, DDK_IOMUX_PIN_MUXMODE_ALT0, DDK_IOMUX_PIN_SION_REGULAR);
OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_LD15, DDK_IOMUX_PIN_MUXMODE_ALT0, DDK_IOMUX_PIN_SION_REGULAR);
OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_LD16, DDK_IOMUX_PIN_MUXMODE_ALT0, DDK_IOMUX_PIN_SION_REGULAR);
OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_LD17, DDK_IOMUX_PIN_MUXMODE_ALT0, DDK_IOMUX_PIN_SION_REGULAR);
OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_LD18, DDK_IOMUX_PIN_MUXMODE_ALT0, DDK_IOMUX_PIN_SION_REGULAR);
OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_LD19, DDK_IOMUX_PIN_MUXMODE_ALT0, DDK_IOMUX_PIN_SION_REGULAR);
OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_LD20, DDK_IOMUX_PIN_MUXMODE_ALT0, DDK_IOMUX_PIN_SION_REGULAR);
OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_LD21, DDK_IOMUX_PIN_MUXMODE_ALT0, DDK_IOMUX_PIN_SION_REGULAR);
OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_LD22, DDK_IOMUX_PIN_MUXMODE_ALT0, DDK_IOMUX_PIN_SION_REGULAR);
OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_LD23, DDK_IOMUX_PIN_MUXMODE_ALT0, DDK_IOMUX_PIN_SION_REGULAR);
OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_D3_VSYNC, DDK_IOMUX_PIN_MUXMODE_ALT0, DDK_IOMUX_PIN_SION_REGULAR);
OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_D3_HSYNC, DDK_IOMUX_PIN_MUXMODE_ALT0, DDK_IOMUX_PIN_SION_REGULAR);
OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_D3_FPSHIFT, DDK_IOMUX_PIN_MUXMODE_ALT0, DDK_IOMUX_PIN_SION_REGULAR);
OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_D3_DRDY, DDK_IOMUX_PIN_MUXMODE_ALT0, DDK_IOMUX_PIN_SION_REGULAR);
OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_D3_REV, DDK_IOMUX_PIN_MUXMODE_ALT0, DDK_IOMUX_PIN_SION_REGULAR);//
OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_D3_CLS, DDK_IOMUX_PIN_MUXMODE_ALT0, DDK_IOMUX_PIN_SION_REGULAR);//
OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_D3_SPL, DDK_IOMUX_PIN_MUXMODE_ALT0, DDK_IOMUX_PIN_SION_REGULAR);//
OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_CONTRAST, DDK_IOMUX_PIN_MUXMODE_ALT0, DDK_IOMUX_PIN_SION_REGULAR);
// Enable DI and SDC
SETREG32(&g_pIPU->IPU_CONF,
CSP_BITFVAL( IPU_IPU_CONF_DI_EN, IPU_IPU_CONF_DI_EN_ENABLE) |
CSP_BITFVAL( IPU_IPU_CONF_SDC_EN, IPU_IPU_CONF_SDC_EN_ENABLE));
// Enable DMA SDC Channel 0
INSREG32BF(&g_pIPU->IDMAC_CHA_EN,
IPU_DMA_CHA_DMASDC_0, IPU_ENABLE);
// Enable SDC background
// Set BG_EN = 1 (Background is enabled)
INSREG32BF(&g_pIPU->SDC_COM_CONF,
IPU_SDC_COM_CONF_BG_EN, IPU_ENABLE);
// Set DMA SDC Channel 0 as ready
INSREG32BF(&g_pIPU->IPU_CHA_BUF0_RDY,
IPU_DMA_CHA_DMASDC_0, IPU_DMA_CHA_READY);
}
static void InitializeSDC2(void)
{
UINT32 g_IPUCLK = 0x7ed6b40;
UINT32 m_PixelClock = 0, m_PixelDivider;
INT WIDTH = 320; //以下參數比照 driver 中 sdc.c 的修改值.
INT HEIGHT = 240;
INT VSYNCWIDTH = 1;
INT VSTARTWIDTH = 17;
INT VENDWIDTH = 4;
INT HSYNCWIDTH = 1;
INT HSTARTWIDTH = 67;
INT HENDWIDTH = 20;
// map registers
g_pIOMUX = (PCSP_IOMUX_REGS)OALPAtoUA(CSP_BASE_REG_PA_IOMUXC);
g_pIPU = (PCSP_IPU_REGS)OALPAtoUA(CSP_BASE_REG_PA_IPU);
g_pCCM = (PCSP_CCM_REGS)OALPAtoUA(CSP_BASE_REG_PA_CCM);
// Enable clock to IPU -- bits 18-19 of CGR1
// Read in current value, "or" it with bits 22-23, write the value back to the register
OUTREG32( &g_pCCM->CGR[1], INREG32(&g_pCCM->CGR[1]) | 0xc0000 );
//----- General configuration
//step 1
// Set little endian
INSREG32BF(&g_pIPU->IPU_CONF, IPU_IPU_CONF_PXL_ENDIAN, IPU_LITTLE_ENDIAN);
//----- Display interface configuration
//step 2
//... SDC_COM_CONF
OUTREG32( &g_pIPU->SDC_COM_CONF,
//.. SDC mode, TFT color
CSP_BITFVAL(IPU_SDC_COM_CONF_SDC_MODE, IPU_SDC_MODE_TFT_COLOR) |
//.. sharp pannel enable
CSP_BITFVAL(IPU_SDC_COM_CONF_SHARP, 0x0) |
//.. dual mode disable, only smart lcd supports dual mode
CSP_BITFVAL(IPU_SDC_COM_CONF_DUAL_MODE, 0));
//step 3, setup panel
//... SDC_HOR_CONF
OUTREG32( &g_pIPU->SDC_HOR_CONF,
//.. display width for tearing and Vsync calculation
// Screen width minus 1. Specifies the number of pixel clock periods between
// the last HSYNC and the new HSYNC.
CSP_BITFVAL(IPU_SDC_HOR_CONF_SCREEN_WIDTH, (WIDTH + HSTARTWIDTH + HENDWIDTH )) | //nathan
//.. horizontal synchronization pulse, actually hsync pulse width is 1
CSP_BITFVAL(IPU_SDC_HOR_CONF_H_SYNC_WIDTH, HSYNCWIDTH - 1));
//... SDC_VER_CONF
OUTREG32( &g_pIPU->SDC_VER_CONF,
//..line/pixel resolution
CSP_BITFVAL(IPU_SDC_VER_CONF_V_SYNC_WIDTH_L, 0x1) |
//..display height for tearing and Vsync calculation
CSP_BITFVAL(IPU_SDC_VER_CONF_SCREEN_HEIGHT, (HEIGHT + VSTARTWIDTH + VENDWIDTH)) | //nathan
//..vsync size, vsync width is 1
CSP_BITFVAL(IPU_SDC_VER_CONF_V_SYNC_WIDTH, VSYNCWIDTH));
//step 4
OUTREG32(&g_pIPU->DI_DISP_IF_CONF,
//..data mask for display 3
CSP_BITFVAL( IPU_DI_DISP_IF_CONF_DISP3_DATAMSK, 0x0) | //0
// select interface display clock for display 3
CSP_BITFVAL( IPU_DI_DISP_IF_CONF_DISP3_CLK_SEL, 0) |
// display clock idle enable
CSP_BITFVAL( IPU_DI_DISP_IF_CONF_DISP3_CLK_IDLE, 0)); // 0x1
OUTREG32(&g_pIPU->DI_DISP_SIG_POL,
//..1: inverse data polarity
CSP_BITFVAL( IPU_DI_DISP_SIG_POL_D3_DATA_POL, 0) |
//..display interface clock polarity
CSP_BITFVAL( IPU_DI_DISP_SIG_POL_D3_CLK_POL, 0) |
//..1: active high horizontal signal polarity
CSP_BITFVAL( IPU_DI_DISP_SIG_POL_D3_HSYNC_POL, 1) |
//..1: active high vertical signal polarity
CSP_BITFVAL( IPU_DI_DISP_SIG_POL_D3_VSYNC_POL, 1) |
// output enable polarity
CSP_BITFVAL( IPU_DI_DISP_SIG_POL_D3_DRDY_SHARP_POL, 1));
//step 5
// HSP_CLK = 133 MHz
//
// DI_CLK = HSP_CLK * HSP_CLOCK_PER = 133 MHz
// ==> HSP_CLOCK_PER = 1
// these are 7 bit fields iiiffff
// where i = integer part and f = fractional part of the value
OUTREG32(&g_pIPU->DI_HSP_CLK_PER,
CSP_BITFVAL( IPU_DI_HSP_CLK_PER_HSP_CLK_PERIOD_1, 1 << 4) |
CSP_BITFVAL( IPU_DI_HSP_CLK_PER_HSP_CLK_PERIOD_2, 1 << 4));
m_PixelClock = ( WIDTH + HSTARTWIDTH + HSYNCWIDTH + HENDWIDTH) * ( HEIGHT + VSTARTWIDTH + VSYNCWIDTH + VENDWIDTH) * 60;
g_IPUCLK = 0x7ed6b40;
m_PixelDivider = (g_IPUCLK << 4) / m_PixelClock; // g_IPUClk is 0x3F6B5A0
if (m_PixelDivider < 0x40) // Divider less than 4
{
DEBUGMSG(SDC_ERROR,
(TEXT("InitPanel() - Pixel clock divider less than 1\r\n")));
m_PixelDivider = 0x40;
}
OUTREG32(&g_pIPU->DI_DISP3_TIME_CONF,
//..write strobe end
CSP_BITFVAL( IPU_DI_DISP3_TIME_CONF_DISP3_IF_CLK_DOWN_WR, (m_PixelDivider / 8) - 1) |
//.. period
CSP_BITFVAL( IPU_DI_DISP3_TIME_CONF_DISP3_IF_CLK_PER_WR, m_PixelDivider));
//step 6
//... DI_DISP_ACC_CC
INSREG32BF(&g_pIPU->DI_DISP_ACC_CC,
// Display clock cycles number minus 1 for output/input one data word. This
// bit describe in which clock displayed bit is masked.
IPU_DI_DISP_ACC_CC_DISP3_IF_CLK_CNT_D, 0);
//step 7
//... DI_DISP3_B0_MAP
OUTREG32(&g_pIPU->DI_DISP3_B0_MAP,
// set0; data offset
CSP_BITFVAL( IPU_DI_DISP3_B0_MAP_M30_OFFS0, 0x5) |
CSP_BITFVAL( IPU_DI_DISP3_B0_MAP_M30_OFFS1, 0) |
CSP_BITFVAL( IPU_DI_DISP3_B0_MAP_M30_OFFS2, 0) |
// set0; data maping
// mask LSB
CSP_BITFVAL( IPU_DI_DISP3_B0_MAP_M30_M0, 3) |
// mask LSB
CSP_BITFVAL( IPU_DI_DISP3_B0_MAP_M30_M1, 3) |
// Enable LSB in the first clock cycle
CSP_BITFVAL( IPU_DI_DISP3_B0_MAP_M30_M2, 0) |
// enable LSB in the first clock cycle
CSP_BITFVAL( IPU_DI_DISP3_B0_MAP_M30_M3, 0) |
// enable LSB in the first clock cycle
CSP_BITFVAL( IPU_DI_DISP3_B0_MAP_M30_M4, 0) |
// enable LSB in the first clock cycle
CSP_BITFVAL( IPU_DI_DISP3_B0_MAP_M30_M5, 0) |
// enable LSB in the first clock cycle
CSP_BITFVAL( IPU_DI_DISP3_B0_MAP_M30_M6, 0) |
// enable LSB in the first clock cycle
CSP_BITFVAL( IPU_DI_DISP3_B0_MAP_M30_M7, 0));
//... DI_DISP3_B1_MAP
OUTREG32(&g_pIPU->DI_DISP3_B1_MAP,
// set1; data offset
CSP_BITFVAL( IPU_DI_DISP3_B1_MAP_M31_OFFS0, 0xb) |
CSP_BITFVAL( IPU_DI_DISP3_B1_MAP_M31_OFFS1, 0) |
CSP_BITFVAL( IPU_DI_DISP3_B1_MAP_M31_OFFS2, 0) |
// set1; data maping
CSP_BITFVAL( IPU_DI_DISP3_B1_MAP_M31_M0, 3) |
CSP_BITFVAL( IPU_DI_DISP3_B1_MAP_M31_M1, 3) |
CSP_BITFVAL( IPU_DI_DISP3_B1_MAP_M31_M2, 0) |
CSP_BITFVAL( IPU_DI_DISP3_B1_MAP_M31_M3, 0) |
CSP_BITFVAL( IPU_DI_DISP3_B1_MAP_M31_M4, 0) |
CSP_BITFVAL( IPU_DI_DISP3_B1_MAP_M31_M5, 0) |
CSP_BITFVAL( IPU_DI_DISP3_B1_MAP_M31_M6, 0) |
CSP_BITFVAL( IPU_DI_DISP3_B1_MAP_M31_M7, 0));
//... DI_DISP3_B2_MAP
OUTREG32(&g_pIPU->DI_DISP3_B2_MAP,
// set2; data offset
CSP_BITFVAL( IPU_DI_DISP3_B2_MAP_M32_OFFS0, 0x11) |
CSP_BITFVAL( IPU_DI_DISP3_B2_MAP_M32_OFFS1, 0) |
CSP_BITFVAL( IPU_DI_DISP3_B2_MAP_M32_OFFS2, 0) |
// set2; data maping
CSP_BITFVAL( IPU_DI_DISP3_B2_MAP_M32_M0, 3) |
CSP_BITFVAL( IPU_DI_DISP3_B2_MAP_M32_M1, 3) |
CSP_BITFVAL( IPU_DI_DISP3_B2_MAP_M32_M2, 0) |
CSP_BITFVAL( IPU_DI_DISP3_B2_MAP_M32_M3, 0) |
CSP_BITFVAL( IPU_DI_DISP3_B2_MAP_M32_M4, 0) |
CSP_BITFVAL( IPU_DI_DISP3_B2_MAP_M32_M5, 0) |
CSP_BITFVAL( IPU_DI_DISP3_B2_MAP_M32_M6, 0) |
CSP_BITFVAL( IPU_DI_DISP3_B2_MAP_M32_M7, 0));
//step 8
//----- SDC Configuration
//Select graphic window to be on foreground or background.
// background selected
INSREG32BF(&g_pIPU->SDC_COM_CONF,
IPU_SDC_COM_CONF_GWSEL, IPU_SDC_COM_CONF_GWSEL_BG);
// Graphic window alpha mode. Select the use of alpha to be global or local.
// global alpha selcted
// INSREG32BF(&g_pIPU->SDC_COM_CONF,
// IPU_SDC_COM_CONF_SDC_GLB_LOC_A, 1);
//disable alpha channel, 這部份是參考 u-boot 2011.09 的版本.
OUTREG32(&g_pIPU->SDC_GRAPH_WIND_CTRL, INREG32(&g_pIPU->SDC_GRAPH_WIND_CTRL) & 0x00ffffffL);
{
UINT32 reg;
reg = INREG32(&g_pIPU->SDC_COM_CONF);
//Graphic window alpha mode is global (1).
reg |= 0x40L;
//Graphic window select. Graphic window is background (0).
reg &= ~0x20L;
//Graphic window color keying enable, Disable color keying of graphic window (0)
reg &= ~0x80L;
OUTREG32(&g_pIPU->SDC_COM_CONF, reg);
}
OUTREG32(&g_pIPU->SDC_BG_POS,
CSP_BITFVAL( IPU_SDC_BG_POS_BGXP, HSTARTWIDTH) | //nathan
CSP_BITFVAL( IPU_SDC_BG_POS_BGYP, VSTARTWIDTH)); //nathan
OUTREG32(&g_pIPU->SDC_FG_POS,
CSP_BITFVAL( IPU_SDC_FG_POS_FGXP, HSTARTWIDTH+1) | //nathan
CSP_BITFVAL( IPU_SDC_FG_POS_FGYP, VSTARTWIDTH)); //nathan
//step 9
//----- IDMAC Configuration
// Set no double-buffer, use single buffer
INSREG32BF(&g_pIPU->IPU_CHA_DB_MODE_SEL, IPU_DMA_CHA_DMASDC_0, IPU_SIG_BUF); //14
INSREG32BF(&g_pIPU->IPU_CHA_DB_MODE_SEL, IPU_DMA_CHA_DMASDC_1, IPU_SIG_BUF); //15
// Set buffer 0 as current buffer (non double buffered)
// for chanel DMASDC_0, current buffer is buffer 0
INSREG32BF(&g_pIPU->IPU_CHA_CUR_BUF, IPU_DMA_CHA_DMASDC_0, IPU_SIG_BUF);
// for chanel DMASDC_1, current buffer is buffer 0 too.
INSREG32BF(&g_pIPU->IPU_CHA_CUR_BUF, IPU_DMA_CHA_DMASDC_1, IPU_SIG_BUF);
// Set high priority for DMA SDC Channel 0
INSREG32BF(&g_pIPU->IDMAC_CHA_PRI,
IPU_DMA_CHA_DMASDC_0, 1);
// Set high priority for DMA SDC Channel 1
INSREG32BF(&g_pIPU->IDMAC_CHA_PRI,
IPU_DMA_CHA_DMASDC_1, 1); //original is 1.
// Set high priority for DMA SDC Channel 1
// INSREG32BF(&g_pIPU->IDMAC_CHA_PRI,
// IPU_DMA_CHA_DMASDC_3, 1);
// Set max for consecutive bursts for each channel
INSREG32BF(&g_pIPU->IDMAC_CONF,
IPU_IDMAC_CONF_SRCNT, 7);
// Select source of SDC channel as ARM
// SDC background channel 0 source select as MCU(arm).
// SDC foreground channel 1 source select as MCU(arm).
OUTREG32(&g_pIPU->IPU_FS_DISP_FLOW,
CSP_BITFVAL( IPU_IPU_FS_DISP_FLOW_SDC0_SRC_SEL, FLOW_ARM) |
CSP_BITFVAL( IPU_IPU_FS_DISP_FLOW_SDC1_SRC_SEL, FLOW_ARM));
// Turn contrast fully on
OUTREG32(&g_pIPU->SDC_CUR_BLINK_PWM_CTRL,
// Source select. Selects the input clock source for the PWM counter. The
// PWM output frequency is equal to the frequency of the input clock divided by 256.
// source select as pixel clock
CSP_BITFVAL( IPU_SDC_CUR_BLINK_PWM_CTRL_SCR, 1) |
// Contrast control is on.
CSP_BITFVAL( IPU_SDC_CUR_BLINK_PWM_CTRL_CC_EN, 1) |
//
CSP_BITFVAL( IPU_SDC_CUR_BLINK_PWM_CTRL_PWM, 0xffL));
SetupIDMAC(320, 240, 16, FALSE, IPU_DMA_CHA_DMASDC_0_LSH); // SDC_DMA_CHANNEL is 14
}
BOOL OALDisplaySplashScreen(void)
{
InitializeSDC2();
//NANDLoadLogoPicture();
EnableSDC2();
OALMSG(1, (TEXT("-DisplaySplashScreen(%d)\r\n"), success));
return TRUE;
}
訂閱:
文章 (Atom)

