C preprocessor

Posted by: 邱小新 at 下午4:07

標準指令

  • #include
  • #define
  • #if
  • #ifdef
  • #ifndef
  • #else
  • #elif
  • #endif

特殊指令

  • #pragma
  • #error
  • #warning

巨集指令

  • __STDC__
  • __STDC_VERSION__
  • __cplusplus(C++)
  • __DATE__
  • __TIME__
  • __func__(C99)

Paradigm debug

Posted by: 邱小新 at 下午3:51 in

每次拿到別人或是原廠的 code,總是包含一堆 #ifdef,有的還是巢狀 #if #else,看到最後都快暈倒了。最後為了看是否此段原始碼到底有沒有被 compile,總是要耗費不少時間,有時還會看錯咧。

#pragma message "test"

今天讓我發現一個好用的巨集指令,也就是 #pragma message。只要在程式碼的上一行加入 #pragma message "test",然後再經過編譯,看一下編譯結果有沒有一個 warning 叫 "test" 就知道此段程式碼有被編譯,而不用幸苦的對程式碼。

Paradigm Locator (*.CFG) part 3

Posted by: 邱小新 at 下午3:50 in

※ INITCODE

INICODE 用來自動產生 reset vector,堆疊初始化,週邊初始化。

Syntax: INITCODE [BOOT386] [RESET|NORESET] [NOTHING] [STACK|NOSTACK] [ioport=data]
[OUTBYTE addr16=value8] [OUTWORD addr16=value16] [OUTDWORD addr16=value32]
[INBYTE addr16] [INWORD addr16] [INDWORD addr16]
[WRITEBYTE addr32=value8] [WRITEWORD addr32=value16] [WRITEDWORD addr32=value32]
[READBYTE addr32] [READWORD addr32] [READDWROD addr32]
[filename=file.ext CLASS=class_name]

  • BOOT386: 產生與 386 以後 cpu 的相容開機引導程式。
  • RESET: 在 FFFF0H 產生一段 far jump 到程式開始的位址。
  • NOTHING: 強制產生 class ??LOCATE。
  • STACK: 產生 SS:SP 初始化程式碼,會放在 class ??LOCATE 的 segment ??STACKINIT。
  • ioport: 允許週邊暫存器透過檔案初始化,會放在 class ??LOCATE 的 segment ??CPUINIT。
  • OUTBYTE/INBYTE: GPIO 的讀寫操作。
  • WRITEBYTE/READBYTE: 記憶體的讀寫操作。
  • INITCODE NOTHING: 建立一個 segment 包含一個 far jump 到程式進入點,沒有包含任何初始碼。
  • INITCODE filename=file.ext CLASS=class_name
    把 file.ext(binary) 放到 class_name,並把 code 放到 startup code execution list。

Examples 範例

  • cputype i80186
    initcode reset umcs=0xf038 lmcs=0x0ff8
  • initcode outbyte 0xfffe=0x11

※ LISTFILE

LISTFILE 用來設定 listing file 要包含那些資料。

Syntax: LISTFILE [SEGMENTS] [PUBLICS[BY ADDRESS|BY NAME] [COLUMNS=(1|2)] [WIDTH=(80|132)] [SYMBOLS] [LINES] [REGIONS] [CHECKSUMS] [FILENAME=file]

  • SEGMENTS: 建立一個 absolute segment map,包含 segment 的開始位置,結束位置,長度。
  • REGIONS: 包含一份由 MAP 所建立的記憶體空間配置
  • CHECKSUMS: 包含在程序中使用的 checksum 或 CRC。
  • PUBLICS: 輸出 public symbol,利用 BY ADDRESS/BY NAME 排序。
  • COLUMNS: 輸出 public symbol 的列數 1 or 2。
  • WIDTH: 輸出 public symbol 的寬度 80 or 132。
  • SYMBOLS: 輸出額外的除錯訊息,比如 local symbol。
  • LINES: 輸出行數。
  • FILENAME: 設定輸出的檔名,預設值為原始輸入檔案,副檔案改成 .LOC。

Examples 範例

  • listfile segments file=test.loc
  • listfile publics lines symbols segments

※ MAP

MAP 用來指定某塊記憶體的存取型態。

Syntax: MAP [name] addr TO addr AS memtype

  • name: 別名。
  • addr: 定義起始位址及終止位址。
  • memtype:
    • RDONLY: 唯讀。
    • RDWR: 可讀可寫。
    • RESERVED: 不可存取。
    • MMIO: Memory-mapped I/O。
    • IRAM: Internal RAM。
    • SFR: Special function registers。

Examples 範例

  • map my_data 0x00000 to 0x0ffff as rdwr
  • map 0x10000 to 0xEFFFF as reserved

※ ORDER

ORDER 用來連結 anchor

Syntax: ORDER anchor_class class_list

Examples 範例

  • order DATA BSS STACK
  • order DATA BSS
    order BSS STACK

Syntax:

Examples 範例

Paradigm Locator (*.CFG) part 2

Posted by: 邱小新 at 下午3:45 in

※ DEBUG

DEBUG 用來指定那些除錯訊息資料結構要包含在 Intel OMF86 檔案。

Syntax: DEBUG option [option ...]

  • IC86:
  • NOIC86:
  • TYPES:
  • NOTYPES:
  • PUBLICS
  • NOPUBLICS
  • SYMBOLS
  • NOSYMBOLS
  • LINES
  • NOLINES
  • ALL

Examples 範例

Paradigm Locator (*.CFG) part 1

Posted by: 邱小新 at 下午3:45 in

參考文件:C:\Program Files\Paradigm\Docs\locate.pdf。

※ 注意事項

  • file 路徑中的反斜線(\)都要用斜線(/)來代替。
  • addr 可以是一個 class name 或是 20-bit 的物理位址。

※ ABSFILE

ABSFILE 主要是用來決定是用 integrated debugger 或是採用 Intel OMF86 格式的開發工具。

Syntax: ABSFILE [AXE86|OMF86|NONE] [FORMAT=type] [FILENAME=file]

  • AXE86: 選用 integrated debugger 格式,預設輸出副檔名為 .AXE。
  • OMF86: 選用 Intel OMF86 格式,預設輸出副檔名為 .ABS。
  • NONE: 取消 absolute output file 輸出。
  • FORMAT: 用來設定 AXE86 的格式,PD60(Paradigm DEBUG 6.0),PD50(Paradigm DEBUG 5.0),PD40(Paradigm DEBUG 4.0)。
  • FILENAME: 用來設定輸出檔案的位置及名稱。

Examples 範例

  • absfile omf86 filename=c:\myprog.abs
  • absfile axe86 format=pd40

※ CHECKSUM

CHECKSUM 用來計算記憶體區塊的 CRC 值。

Syntax: CHECKSUM addr TO addr [ADDRESS=addr] [FILL=fill] [ROMBIOS|CRC16|CRC32]

  • ADDRESS: 用來指定存放 checksum 的物理位置,預設值為記憶體區塊的下一個位址。
  • FILL: 用來填滿記憶體區塊未使用到的地方,預設值為 0xFF。
  • ROMBIOS: 使用 IBM PC ROM BIOS 計算方法,checksum 1 byte。
  • CRC16: 使用 CRC-16 計算方法,checksum 2 bytes。
  • CRC32: 使用 CRC-32 計算方法,checksum 4 bytes。

Examples 範例

  • checksum 0xc0000 to 0xc07fe fill=0x00 rombios
  • checksum 0xf8000 to 0xffffd address=0xffffe crc16
  • checksum CODE to ROMDATA crc32

※ CLASS

CLASS 用來指定物理位置到 class 的每一個 segment。

Syntax: CLASS classname = addr16

  • addr16: 用來指定 class 的第一個 segment,剩下的 segment 則根據前一個 segment 依序指定物理位置。

Examples 範例

  • class CODE = 0xfc00
  • class DATA = 0x0040

※ COMPRESS

COMPRESS 用來壓縮重覆的 class,藉此節省空間。

Syntax: COMPRESS classname

  • classname: 要被壓縮的 class 名稱,這個 class 必須出現在 DUP 指令中。

Examples 範例

  • dup FARDATA ROMFARDATA
    compress ROMFARDATA

※ CPUTYPE

CPUTYPE 用來指定微處器的型號。

Syntax: CPUTYPE cpu_id

  • cpu_id: Turbo186 - genesis 專用的。

Examples 範例

  • cputype turbo186

※ DISPLAY

Syntax: DISPLAY option [option ...]

  • NONE: 取消所有診斷顯示。
  • FILES: 顯示輸出檔案。
  • MODULES: 顯示在輸入檔案找到的模組名稱。
  • COMPRESSION: 顯示在壓縮 class 的壓縮統計。
  • ALL: 顯示所有的訊息。

Examples 範例

  • display files modules
  • display none
  • display all

※ DUPLICATE

DUPLICATE 用來複製一個 class。一般都是 startup code 用來複製 FLASH 到 RAM。

Syntax: DUPLICATE src_class dest_class

Examples 範例

  • dup DATA ROMDATA // copy class DATA
    class DATA = 0x0040 // DATA at 00400H
    class CODE = 0xfc00 // CODE at FC000H
    order CODE ROMDATA // ROMDATA after CODE

※ HEXFILE

HEXFILE

Syntax: HEXFILE [INTEL80|INTEL86|INTEL386|BINARY|TEKHEX] [OFFSET=addr] [SIZE=size] [SPLIT=split] [FILL=fill] [LENGTH=len] [TRUNCATE] [EOFRECORD|NOEOFRECORD] [ENTRYPOINT|NOENTRYPOINT] [FILENAME=file]

  • INTEL80: Intel hex (64KB).
  • INTEL86: Intel extended hex (1MB), 預設值.
  • INTEL386: Intel 386 extended hex (1MB or 16MB).
  • BINARY: Binary (1MB).
  • TEKHEX: Tektronix hex (64KB).
  • OFFSET: 用來指定開始位址。
  • SIZE: 設定 image 的大小,預設值則根據 image type 的最大值來設定,除了 binary 是 32KB。
  • SPLIT: 用來分割 image,可分為 1~4 個,預設值是一個,也就是不分割。
  • FILL: 在 binary 格式時,用來做未使用的區域填充值,預設值為 0FFH。
  • LENGTH: 設定每行記錄有多少 bytes,範圍為 8~64,預設值為 16。
  • TRUNCATE: 用來把 binary image 多餘的空白去除,減少 image 的大小。
  • EOFRECORD: 設定 end of record 寫入與否,預設是寫入。
  • ENTRYPOINT: 設定 entry point record 寫入與否,預設是寫入。
  • FILENAME: 用來設定輸出檔案的位置及名稱。

Examples 範例

  • hexfile intel80 offset=0xf0000 size=32 file=no1
    hexfile intel80 offset=0xf8000 size=32 file=no2

Paradigm Source Pools

Posted by: 邱小新 at 下午3:44 in

Source Pools 是 node 的集合,用來整理成堆的 source/header files。由於在 .rom 只能新增 node,如果 source file 很多的時候,就變成一團,很難搜尋要修改的檔案。但是 Paradigm 又不援目錄格式,此時就只能靠 SourcePools 來收集 nodes 再丟進 .rom 內,也就是相當於變相的目錄格式。

  • Project → New target...
  • 輸入 Name,type 選 SourcePool。
  • 接著把 test.c 拉到 test[SourcePool](滑鼠移到 test.c,按左鍵不放,移動滑鼠到 test[SourcePool],放開左鍵)。
  • 再來先按住 Alt 鍵不放,再把 test[SourcePool] 拉到 test.rom,此時會看到 test.rom 出現粗體字的 test[SourcePool],表示它只是 reference 而已。
  • 在原始的 test[SourcePool] add note 會同步出現在 test.rom 的 test[SourcePool],如同 aaa.c,在原始 SourcePool 為原始字體,在 test.rom 的 SourcePool 為粗體字。但是在 test.rom 的 test[SourcePool] add note 是不會同步原始的 test[SourcePool] 喔,如同 bbb.c,新增後為正常字體,表示非 reference 檔案,也沒有在原始 SourcePool 出現。
  • 接著 build all,大功告成,三個檔案都有 build 成功。
  • 請注意不要把 test[SourcePool] 直接拉到 test.rom 而不做 reference 喔,這樣會造成在 build all 時找不到任何檔案,原因不詳。

Paradigm 初體驗

Posted by: 邱小新 at 下午3:41 in
  • File → New → Project...
  • Project Path and Name 輸入你指定的位置,其它的就不用改了。
  • 輸入完成按 OK,就會出現下列專案管理視窗。
  • 接下來在 test.rom 按右鍵叫出選單,選擇 Add node,就可以新增已存在的檔案。如果要新增一個 c source,則必須先 File → New → Text Edit,然後再 File → Save as... 另存成一個新檔案,再利用 Add node 加進 Project 內。
  • 接著 Project → Build all,或是在 test.axe 按右鍵選 Build note 就可以開始編譯,Message 視窗出現 Build process completed,就表示大功告成了。
  • 如果要修改一開始專案所指定的 Target,可以在 test.axe 按右鍵叫出選單,再按 TargetExpert...,就會呼叫出 TargetExpert 選單。

PLIB -- library tool

Posted by: 邱小新 at 下午3:36 in

pcppug.pdf 寫的
>> plib [@respfile] [option] libname [operations] [, listfile]

執行 PLIB 寫的
>> PLIB libname [/C] [/E] [/P] [/0] commands, listfile

operations/commands
  • "+": 新增 OBJ。
  • "-": 刪除已存在的 OBJ。
  • "*": 還原已存在的 OBJ。
  • "+-" or "-+": 替換已存在的 OBJ。
  • "*-" or "-*": 還原已存在的 OBJ 並刪除。

examples
  • plib mylib +x +y +z
    新增 x.obj, y.obj, z.obj 到 mylib.lib。
  • plib mylib, mylib.lst
    把 mylib.lib 內的所有模組的符號列表輸出到 mylib.lst。
  • plib mylib -+x +a -z
    替換 x.obj, 新增 a.obj, 刪除 z.obj。
  • plib mylib *y, mylib.lst
    還原 y.obj 成檔案,並把 mylib.lib 內的所有模組的符號列表輸出到 mylib.lst。

WT61P9 讀 code 心得

Posted by: 邱小新 at 上午9:21 in
  • Timer0 做為 poller 使用,每 10ms 中斷一次,再根據每個 flag 在 main loop 執行。
  • 所有的變數設定初始值是先把 address 放在 SubAddr_Table,data 放在 SubAddr_Default_Table,要注意二個位置要一致,以免出現問題。原來是要給 slave IIC 用的,讓其它週邊可以透過 slave IIC 來讀取資料。
  • 在 idata 開了一個 PMCTL_DATA 大陣列,index 定義在 os.h 的 enum 裏。不知為什麼要如此麻煩,想不懂。
  • 讀取風扇轉速透過 HV2Sync_Detect_Routine 及 HVSync_Detect_Routine,搞不懂其計算原理。會把值存在 FANx_RPM,但似乎都沒有用到。假如有一個轉速為 0,則會把 LED9_Fan Fail 點亮。
  • 在 main 的 while loop 內會呼叫 Check_PWM_Output,會去檢查 PWM 值是否被外部 MCU 透過 IIC 變更,然後再變更風扇的 PWM 值,藉此改變風扇轉速。
  • 溫度感應器有二組,一組透過 I2C,一組透過 ADC,I2C 讀取溫度透過 Thermal_routine,ADC 讀取溫度透過 Read_ADC_Routine,當溫度大於 Thermal_Thres1(0x2F,47C) 會把 LED7_High temperature 點亮。

CD4052

Posted by: 邱小新 at 上午9:06 in

CD4052/CC4052是一個差分4通道數位控制類比開關,有A、B兩個二進位控制輸入端和INH輸入,具有低導通阻抗和很低的截止漏電流。幅值為4.5~20V的數位信號可控制峰峰值至20V的類比信號。例如,若 VDD=+5V,VSS=0,VEE=-13.5V,則 0~5V 的數位信號可控制 -13.5~4.5V 的類比信號,這些開關電路在整個 VDD-VSS 和 VDD-VEE 電源範圍內具有極低的靜態功耗,與控制信號的邏輯狀態無關,當 INH 輸入端="1"時,所有通道截止。二位元二進位輸入信號選通 4 對通道中的一通道,可連接該輸入至輸出。

Truth Table

INHIBITBA"ON" CHANNELS
0000X,0Y
0011X,1Y
0102X,2Y
0113X,3Y
1--none

Pin Define

PINSymbolFunction
1,2,4,5IN/OUTY 通道輸入/輸出端
11,12,14,15IN/OUTX 通道輸入/輸出端
9,10IN/OUT地址端
3OUT/INY 公共輸出/輸入端
13OUT/INX 公共輸出/輸入端
6INH禁止端
7VEE類比訊號接地端
8Vss數位訊號接地端
16VDD電源+

參考資料

Weltren MCU ISP Tool 設定

Posted by: 邱小新 at 上午11:27 in

我使用是 WT61P9,板子是公司的,不知道跟公板有沒有差別,反正什麼資料都沒有,只好把自己試的結果記錄下來。

  • 首先從 Config → Interface 進入,把下面選項設定好。
  • Control Port Selection → USB Port
  • SCL Pin 不用管
  • COM Port 不用管
  • Auto Reset → Enable
  • ISP Target Selection → WT61P9
  • 24M Crystal 不用管
  • S_ISP Board Selection 不用管

不管有沒有做好設定,都要按 Exit&Save 才能離開,右上角的 X 鈕根本沒用。按下 Exit&Save 後,會自動偵測 USB 是否有作用,如果 USB 沒接會出現 "NO USB Device Connect";如果有接上,則沒有任何訊息。雖然會偵測 USB 功能,但卻不會偵測 MCU type 有沒有選對喔。