;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Output ports CONSTANT port_TX_UART, 00 CONSTANT port_SPI_CLK, 01 CONSTANT port_SPI_MOSI, 02 CONSTANT port_SPI_CS, 03 CONSTANT port_IIC_OUT, 04 ;[0]=clk, [1]=data CONSTANT port_LEDS, 05 CONSTANT port_CTRL, 06 ;Bit definitions for port_SPI_CS CONSTANT SPI_CS_SampClkBuf, 01 CONSTANT SPI_CS_RFRefClkBuf, 02 CONSTANT SPI_CS_ClkModPLL, 04 ;Bit definitions for port_CTRL CONSTANT CONFIG_DONE, 01 CONSTANT PLL_REFCLK_MON_EN, 02 CONSTANT TX_UART_RESET, 04 ;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Input ports CONSTANT port_TX_UART_STATUS, 00 CONSTANT port_SPI_MISO, 01 CONSTANT port_CM_STATUS, 02 CONSTANT port_IIC_IN, 03 ;[0]=clk, [1]=data ;Bit definitions for port_TX_UART_STATUS CONSTANT TX_UART_STATUS_FULL, 04 ;Bit definitions for port_CM_STATUS CONSTANT CM_STATUS_SW0, 01 CONSTANT CM_STATUS_SW1, 02 CONSTANT CM_STATUS_SW01, 03 CONSTANT CM_STATUS_SW2, 04 CONSTANT CM_STATUS_SW_ALL, 07 CONSTANT CM_STATUS_PLL_LOCK, 08 CONSTANT CM_STATUS_REFCLK_VLD, 10 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;IIC EEPROM Contents ; 15000:15001 Delimeter bytes == 0xA5CD ; ; 15002 RF Ref Configs (16 bytes each) ; 15002:15017 RF Ref Config No-CM ; 15018:15033 RF Ref Config A CM-MMCX ; 15034:15049 RF Ref Config B CM-MMCX ; 15050:15065 RF Ref Config C CM-MMCX ; 15066:15081 RF Ref Config A CM-PLL ; 15082:15097 RF Ref Config B CM-PLL ; 15098:15113 RF Ref Config C CM-PLL ; ; 15130 Samp Configs (16 bytes each) ; 15130:15145 Samp Config No-CM ; 15146:15161 Samp Config A CM-MMCX ; 15162:15177 Samp Config B CM-MMCX ; 15178:15193 Samp Config C CM-MMCX ; 15194:15209 Samp Config A CM-PLL ; 15210:15225 Samp Config B CM-PLL ; 15226:15241 Samp Config C CM-PLL ; ; 15258 PLL Configs (80 bytes each) ; 15258:15337 PLL Config No-CM ; 15338:15417 PLL Config A CM-PLL ; 15418:15497 PLL Config B CM-PLL ; 15498:15577 PLL Config C CM-PLL CONSTANT EEPROM_IIC_ADDR, 50 ; 24AA128 EEPROM dev addr = 0b1010000 = 0x50 CONSTANT EEPROM_CFG_DELIM_B0, A5 CONSTANT EEPROM_CFG_DELIM_B1, CD CONSTANT EEPROM_ADDR_CFG_BASE_U, 3A ;1500 = 0x3A98 CONSTANT EEPROM_ADDR_CFG_BASE_L, 98 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; RF Ref Clk Buffer Config Offsets CONSTANT EEPROM_ADDR_CFG_RFREF_NOCM_U, 3A ;15002 = 0x3A9A CONSTANT EEPROM_ADDR_CFG_RFREF_NOCM_L, 9A CONSTANT EEPROM_ADDR_CFG_RFREF_CMMMCX_A_U, 3A ;15018 = 0x3AAA CONSTANT EEPROM_ADDR_CFG_RFREF_CMMMCX_A_L, AA CONSTANT EEPROM_ADDR_CFG_RFREF_CMMMCX_B_U, 3A ;15034 = 0x3ABA CONSTANT EEPROM_ADDR_CFG_RFREF_CMMMCX_B_L, BA CONSTANT EEPROM_ADDR_CFG_RFREF_CMMMCX_C_U, 3A ;15050 = 0x3ACA CONSTANT EEPROM_ADDR_CFG_RFREF_CMMMCX_C_L, CA CONSTANT EEPROM_ADDR_CFG_RFREF_CMPLL_A_U, 3A ;15066 = 0x3ADA CONSTANT EEPROM_ADDR_CFG_RFREF_CMPLL_A_L, DA CONSTANT EEPROM_ADDR_CFG_RFREF_CMPLL_B_U, 3A ;15082 = 0x3AEA CONSTANT EEPROM_ADDR_CFG_RFREF_CMPLL_B_L, EA CONSTANT EEPROM_ADDR_CFG_RFREF_CMPLL_C_U, 3A ;15098 = 0x3AFA CONSTANT EEPROM_ADDR_CFG_RFREF_CMPLL_C_L, FA ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Samp Clk Buffer Config Offsets CONSTANT EEPROM_ADDR_CFG_SAMP_NOCM_U, 3B ;15130 = 0x3B1A CONSTANT EEPROM_ADDR_CFG_SAMP_NOCM_L, 1A CONSTANT EEPROM_ADDR_CFG_SAMP_CMMMCX_A_U, 3B ;15146 = 0x3B2A CONSTANT EEPROM_ADDR_CFG_SAMP_CMMMCX_A_L, 2A CONSTANT EEPROM_ADDR_CFG_SAMP_CMMMCX_B_U, 3B ;15162 = 0x3B3A CONSTANT EEPROM_ADDR_CFG_SAMP_CMMMCX_B_L, 3A CONSTANT EEPROM_ADDR_CFG_SAMP_CMMMCX_C_U, 3B ;15178 = 0x3B4A CONSTANT EEPROM_ADDR_CFG_SAMP_CMMMCX_C_L, 4A CONSTANT EEPROM_ADDR_CFG_SAMP_CMPLL_A_U, 3B ;15194 = 0x3B5A CONSTANT EEPROM_ADDR_CFG_SAMP_CMPLL_A_L, 5A CONSTANT EEPROM_ADDR_CFG_SAMP_CMPLL_B_U, 3B ;15210 = 0x3B6A CONSTANT EEPROM_ADDR_CFG_SAMP_CMPLL_B_L, 6A CONSTANT EEPROM_ADDR_CFG_SAMP_CMPLL_C_U, 3B ;15226 = 0x3B7A CONSTANT EEPROM_ADDR_CFG_SAMP_CMPLL_C_L, 7A ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; PLL Config Offsets CONSTANT EEPROM_ADDR_CFG_PLL_NOCM_A_U, 3B ;15258 = 0x3B9A CONSTANT EEPROM_ADDR_CFG_PLL_NOCM_A_L, 9A CONSTANT EEPROM_ADDR_CFG_PLL_CMPLL_A_U, 3B ;15338 = 0x3BEA CONSTANT EEPROM_ADDR_CFG_PLL_CMPLL_A_L, EA CONSTANT EEPROM_ADDR_CFG_PLL_CMPLL_B_U, 3C ;15418 = 0x3C3A CONSTANT EEPROM_ADDR_CFG_PLL_CMPLL_B_L, 3A CONSTANT EEPROM_ADDR_CFG_PLL_CMPLL_C_U, 3C ;15338 = 0x3C8A CONSTANT EEPROM_ADDR_CFG_PLL_CMPLL_C_L, 8A CONSTANT SPAD_ADDR_CFG_RFREF, 00 CONSTANT SPAD_ADDR_CFG_SAMP, 16'd CONSTANT SPAD_ADDR_CFG_PLL, 32'd ;;;;;;;;;;;;;;;;;;;;;;;;;;; ; COMPARE sX, sY: ; Z C Cond ; 0 0 sX > sY ; x 1 sX < sY ; 1 x sX == sY ; TEST sX, sY: ; Z C Cond ; 1 0 (sX bitand sY) == 8'b0 ; 0 1 (sX bitand sY) has odd number of 1 start: CALL delay_10ms CALL init_scratchpad OUTPUTK 00, port_CTRL LOAD sB, msg_init'upper LOAD sA, msg_init'lower CALL send_message OUTPUTK 01, port_LEDS ;Check for valid config delimeter in EEPROM LOAD s7, EEPROM_ADDR_CFG_BASE_L LOAD s8, EEPROM_ADDR_CFG_BASE_U CALL EEPROM_read_byte COMPARE sD, EEPROM_CFG_DELIM_B0 JUMP NZ, config_no_eeprom ;first byte wrong - ignore EEPROM ADD s7, 01 ADDCY s8, 00 CALL EEPROM_read_byte COMPARE sD, EEPROM_CFG_DELIM_B1 JUMP NZ, config_no_eeprom ;second byte wrong - ignore EEPROM ;Valid delimeter found in EEPROM - use EEPROM contents for clock config config_from_eeprom: LOAD sB, msg_eeprom_det'upper LOAD sA, msg_eeprom_det'lower CALL send_message ; INPUT s0, port_CM_STATUS ;read CM switch AND s0, CM_STATUS_SW_ALL ;mask off switch bits LOAD s1, s0 ;make copy AND s1, CM_STATUS_SW01 ;check for sw[1:0]==0x3 COMPARE s1, CM_STATUS_SW01 ; 0x3 indicates no clock module is mounted JUMP Z, read_eeprom_cfgs_nocm ; sw[1:0]==0x3 -> no clk module ;Clock module found! TEST s0, CM_STATUS_SW2 ;check if CM-PLL (sw[2]==0) JUMP Z, read_eeprom_cfgs_cmpll ;sw[2]==0 -> CM-PLL is mounted JUMP read_eeprom_cfgs_cmmmcx ;otherwise CM-MMCX is mounted ; s1 still has sw[1:0] values ; sw[1:0] == 3 already handled above (indicates no clock module) read_eeprom_cfgs_cmpll: LOAD sB, msg_cmpll_det'upper LOAD sA, msg_cmpll_det'lower CALL send_message ; COMPARE s1, 00 ; sw[1:0] == [2,1,0] -> configs [A,B,C] JUMP Z, read_eeprom_cfgs_cmpll_C COMPARE s1, CM_STATUS_SW0 JUMP Z, read_eeprom_cfgs_cmpll_B JUMP read_eeprom_cfgs_cmpll_A read_eeprom_cfgs_cmpll_A: LOAD sB, msg_cfg_A'upper LOAD sA, msg_cfg_A'lower CALL send_message ; LOAD s7, EEPROM_ADDR_CFG_RFREF_CMPLL_A_L LOAD s8, EEPROM_ADDR_CFG_RFREF_CMPLL_A_U LOAD s9, SPAD_ADDR_CFG_RFREF LOAD s2, 16'd CALL copy_eeprom_to_scratchpad LOAD s7, EEPROM_ADDR_CFG_SAMP_CMPLL_A_L LOAD s8, EEPROM_ADDR_CFG_SAMP_CMPLL_A_U LOAD s9, SPAD_ADDR_CFG_SAMP LOAD s2, 16'd CALL copy_eeprom_to_scratchpad LOAD s7, EEPROM_ADDR_CFG_PLL_CMPLL_A_L LOAD s8, EEPROM_ADDR_CFG_PLL_CMPLL_A_U LOAD s9, SPAD_ADDR_CFG_PLL LOAD s2, 40'd CALL copy_eeprom_to_scratchpad LOAD sF, 01 ;do wait on PLL lock JUMP write_cfg_from_scratchpad read_eeprom_cfgs_cmpll_B: LOAD sB, msg_cfg_B'upper LOAD sA, msg_cfg_B'lower CALL send_message ; LOAD s7, EEPROM_ADDR_CFG_RFREF_CMPLL_B_L LOAD s8, EEPROM_ADDR_CFG_RFREF_CMPLL_B_U LOAD s9, SPAD_ADDR_CFG_RFREF LOAD s2, 16'd CALL copy_eeprom_to_scratchpad LOAD s7, EEPROM_ADDR_CFG_SAMP_CMPLL_B_L LOAD s8, EEPROM_ADDR_CFG_SAMP_CMPLL_B_U LOAD s9, SPAD_ADDR_CFG_SAMP LOAD s2, 16'd CALL copy_eeprom_to_scratchpad LOAD s7, EEPROM_ADDR_CFG_PLL_CMPLL_B_L LOAD s8, EEPROM_ADDR_CFG_PLL_CMPLL_B_U LOAD s9, SPAD_ADDR_CFG_PLL LOAD s2, 40'd CALL copy_eeprom_to_scratchpad LOAD sF, 01 ;do wait on PLL lock JUMP write_cfg_from_scratchpad read_eeprom_cfgs_cmpll_C: LOAD sB, msg_cfg_C'upper LOAD sA, msg_cfg_C'lower CALL send_message ; LOAD s7, EEPROM_ADDR_CFG_RFREF_CMPLL_C_L LOAD s8, EEPROM_ADDR_CFG_RFREF_CMPLL_C_U LOAD s9, SPAD_ADDR_CFG_RFREF LOAD s2, 16'd CALL copy_eeprom_to_scratchpad LOAD s7, EEPROM_ADDR_CFG_SAMP_CMPLL_C_L LOAD s8, EEPROM_ADDR_CFG_SAMP_CMPLL_C_U LOAD s9, SPAD_ADDR_CFG_SAMP LOAD s2, 16'd CALL copy_eeprom_to_scratchpad LOAD s7, EEPROM_ADDR_CFG_PLL_CMPLL_C_L LOAD s8, EEPROM_ADDR_CFG_PLL_CMPLL_C_U LOAD s9, SPAD_ADDR_CFG_PLL LOAD s2, 40'd CALL copy_eeprom_to_scratchpad LOAD sF, 01 ;do wait on PLL lock JUMP write_cfg_from_scratchpad ; s1 still has sw[1:0] values ; sw[1:0] == 3 already handled above (indicates no clock module) read_eeprom_cfgs_cmmmcx: LOAD sB, msg_cmmmcx_det'upper LOAD sA, msg_cmmmcx_det'lower CALL send_message ; COMPARE s1, 00 ; sw[1:0] == [2,1,0] -> configs [A,B,C] JUMP Z, read_eeprom_cfgs_cmmmcx_C COMPARE s1, CM_STATUS_SW0 JUMP Z, read_eeprom_cfgs_cmmmcx_B JUMP read_eeprom_cfgs_cmmmcx_A read_eeprom_cfgs_cmmmcx_A: LOAD sB, msg_cfg_A'upper LOAD sA, msg_cfg_A'lower CALL send_message ; LOAD s7, EEPROM_ADDR_CFG_RFREF_CMMMCX_A_L LOAD s8, EEPROM_ADDR_CFG_RFREF_CMMMCX_A_U LOAD s9, SPAD_ADDR_CFG_RFREF LOAD s2, 16'd CALL copy_eeprom_to_scratchpad LOAD s7, EEPROM_ADDR_CFG_SAMP_CMMMCX_A_L LOAD s8, EEPROM_ADDR_CFG_SAMP_CMMMCX_A_U LOAD s9, SPAD_ADDR_CFG_SAMP LOAD s2, 16'd CALL copy_eeprom_to_scratchpad LOAD sF, 00 ;don't wait on PLL lock JUMP write_cfg_from_scratchpad read_eeprom_cfgs_cmmmcx_B: LOAD sB, msg_cfg_B'upper LOAD sA, msg_cfg_B'lower CALL send_message ; LOAD s7, EEPROM_ADDR_CFG_RFREF_CMMMCX_B_L LOAD s8, EEPROM_ADDR_CFG_RFREF_CMMMCX_B_U LOAD s9, SPAD_ADDR_CFG_RFREF LOAD s2, 16'd CALL copy_eeprom_to_scratchpad LOAD s7, EEPROM_ADDR_CFG_SAMP_CMMMCX_B_L LOAD s8, EEPROM_ADDR_CFG_SAMP_CMMMCX_B_U LOAD s9, SPAD_ADDR_CFG_SAMP LOAD s2, 16'd CALL copy_eeprom_to_scratchpad LOAD sF, 00 ;don't wait on PLL lock JUMP write_cfg_from_scratchpad read_eeprom_cfgs_cmmmcx_C: LOAD sB, msg_cfg_C'upper LOAD sA, msg_cfg_C'lower CALL send_message ; LOAD s7, EEPROM_ADDR_CFG_RFREF_CMMMCX_C_L LOAD s8, EEPROM_ADDR_CFG_RFREF_CMMMCX_C_U LOAD s9, SPAD_ADDR_CFG_RFREF LOAD s2, 16'd CALL copy_eeprom_to_scratchpad LOAD s7, EEPROM_ADDR_CFG_SAMP_CMMMCX_C_L LOAD s8, EEPROM_ADDR_CFG_SAMP_CMMMCX_C_U LOAD s9, SPAD_ADDR_CFG_SAMP LOAD s2, 16'd CALL copy_eeprom_to_scratchpad LOAD sF, 00 ;don't wait on PLL lock JUMP write_cfg_from_scratchpad ; No clock module mounted ; Still write SPI config to PLL pins, just in case the user ; left sw[1:0] de-asserted, to avoid unecessary noise/power by PLL ; circuit whose outputs are ignored read_eeprom_cfgs_nocm: LOAD sB, msg_nocm_det'upper LOAD sA, msg_nocm_det'lower CALL send_message ; LOAD s7, EEPROM_ADDR_CFG_RFREF_NOCM_L LOAD s8, EEPROM_ADDR_CFG_RFREF_NOCM_U LOAD s9, SPAD_ADDR_CFG_RFREF LOAD s2, 16'd CALL copy_eeprom_to_scratchpad LOAD s7, EEPROM_ADDR_CFG_SAMP_NOCM_L LOAD s8, EEPROM_ADDR_CFG_SAMP_NOCM_U LOAD s9, SPAD_ADDR_CFG_SAMP LOAD s2, 16'd CALL copy_eeprom_to_scratchpad LOAD s7, EEPROM_ADDR_CFG_PLL_NOCM_A_L LOAD s8, EEPROM_ADDR_CFG_PLL_NOCM_A_U LOAD s9, SPAD_ADDR_CFG_PLL LOAD s2, 40'd CALL copy_eeprom_to_scratchpad ; LOAD sF, 00 ;don't wait on PLL lock JUMP write_cfg_from_scratchpad config_no_eeprom: LOAD sB, msg_noeeprom_det'upper LOAD sA, msg_noeeprom_det'lower CALL send_message INPUT s0, port_CM_STATUS ;read CM switch AND s0, CM_STATUS_SW_ALL ;mask off switch bits LOAD s1, s0 ;make copy AND s1, CM_STATUS_SW01 ;check for sw[1:0]==0x3 COMPARE s1, CM_STATUS_SW01 ; 0x3 indicates no clock module is mounted JUMP Z, read_noeeprom_cfgs_nocm ; sw[1:0]==0x3 -> no clk module ;Clock module found! TEST s0, CM_STATUS_SW2 ;check if CM-PLL (sw[2]==0) JUMP Z, read_noeeprom_cfgs_cmpll ;sw[2]==0 -> CM-PLL is mounted JUMP read_noeeprom_cfgs_cmmmcx ;otherwise CM-MMCX is mounted ; No clock module mounted ; Still write SPI config to PLL pins, just in case the user ; left sw[1:0] de-asserted, to avoid unecessary noise/power by PLL ; circuit whose outputs are ignored read_noeeprom_cfgs_nocm: LOAD sB, msg_nocm_det'upper LOAD sA, msg_nocm_det'lower CALL send_message ;Copy RF ref configs LOAD s7, cfg_nocm_rfref_addr'lower LOAD s8, cfg_nocm_rfref_addr'upper LOAD s9, cfg_nocm_rfref_data'lower LOAD sA, cfg_nocm_rfref_data'upper LOAD s6, SPAD_ADDR_CFG_RFREF LOAD s5, 16'd CALL copy_tables_to_scratchpad ;Copy samp configs LOAD s7, cfg_nocm_samp_addr'lower LOAD s8, cfg_nocm_samp_addr'upper LOAD s9, cfg_nocm_samp_data'lower LOAD sA, cfg_nocm_samp_data'upper LOAD s6, SPAD_ADDR_CFG_SAMP LOAD s5, 16'd CALL copy_tables_to_scratchpad ;Copy PLL configs LOAD s7, cfg_nocm_pll_addr'lower LOAD s8, cfg_nocm_pll_addr'upper LOAD s9, cfg_nocm_pll_data'lower LOAD sA, cfg_nocm_pll_data'upper LOAD s6, SPAD_ADDR_CFG_PLL LOAD s5, 40'd CALL copy_tables_to_scratchpad ; LOAD sF, 00 ;don't wait on PLL lock JUMP write_cfg_from_scratchpad ; s1 still has sw[1:0] values ; sw[1:0] == 3 already handled above (indicates no clock module) read_noeeprom_cfgs_cmmmcx: LOAD sB, msg_cmmmcx_det'upper LOAD sA, msg_cmmmcx_det'lower CALL send_message ; COMPARE s1, 00 ; sw[1:0] == [2,1,0] -> configs [A,B,C] JUMP Z, read_noeeprom_cfgs_cmmmcx_C COMPARE s1, CM_STATUS_SW0 JUMP Z, read_noeeprom_cfgs_cmmmcx_B JUMP read_noeeprom_cfgs_cmmmcx_A read_noeeprom_cfgs_cmmmcx_A: LOAD sB, msg_cfg_A'upper LOAD sA, msg_cfg_A'lower CALL send_message ;Copy RF ref configs LOAD s7, cfg_cmmmcx_A_rfref_addr'lower LOAD s8, cfg_cmmmcx_A_rfref_addr'upper LOAD s9, cfg_cmmmcx_A_rfref_data'lower LOAD sA, cfg_cmmmcx_A_rfref_data'upper LOAD s6, SPAD_ADDR_CFG_RFREF LOAD s5, 16'd CALL copy_tables_to_scratchpad ;Copy samp configs LOAD s7, cfg_cmmmcx_A_samp_addr'lower LOAD s8, cfg_cmmmcx_A_samp_addr'upper LOAD s9, cfg_cmmmcx_A_samp_data'lower LOAD sA, cfg_cmmmcx_A_samp_data'upper LOAD s6, SPAD_ADDR_CFG_SAMP LOAD s5, 16'd CALL copy_tables_to_scratchpad ; LOAD sF, 00 ;don't wait on PLL lock JUMP write_cfg_from_scratchpad read_noeeprom_cfgs_cmmmcx_B: LOAD sB, msg_cfg_B'upper LOAD sA, msg_cfg_B'lower CALL send_message ;Copy RF ref configs LOAD s7, cfg_cmmmcx_B_rfref_addr'lower LOAD s8, cfg_cmmmcx_B_rfref_addr'upper LOAD s9, cfg_cmmmcx_B_rfref_data'lower LOAD sA, cfg_cmmmcx_B_rfref_data'upper LOAD s6, SPAD_ADDR_CFG_RFREF LOAD s5, 16'd CALL copy_tables_to_scratchpad ;Copy samp configs LOAD s7, cfg_cmmmcx_B_samp_addr'lower LOAD s8, cfg_cmmmcx_B_samp_addr'upper LOAD s9, cfg_cmmmcx_B_samp_data'lower LOAD sA, cfg_cmmmcx_B_samp_data'upper LOAD s6, SPAD_ADDR_CFG_SAMP LOAD s5, 16'd CALL copy_tables_to_scratchpad ; LOAD sF, 00 ;don't wait on PLL lock JUMP write_cfg_from_scratchpad read_noeeprom_cfgs_cmmmcx_C: LOAD sB, msg_cfg_C'upper LOAD sA, msg_cfg_C'lower CALL send_message ;Copy RF ref configs LOAD s7, cfg_cmmmcx_C_rfref_addr'lower LOAD s8, cfg_cmmmcx_C_rfref_addr'upper LOAD s9, cfg_cmmmcx_C_rfref_data'lower LOAD sA, cfg_cmmmcx_C_rfref_data'upper LOAD s6, SPAD_ADDR_CFG_RFREF LOAD s5, 16'd CALL copy_tables_to_scratchpad ;Copy samp configs LOAD s7, cfg_cmmmcx_C_samp_addr'lower LOAD s8, cfg_cmmmcx_C_samp_addr'upper LOAD s9, cfg_cmmmcx_C_samp_data'lower LOAD sA, cfg_cmmmcx_C_samp_data'upper LOAD s6, SPAD_ADDR_CFG_SAMP LOAD s5, 16'd CALL copy_tables_to_scratchpad ; LOAD sF, 00 ;don't wait on PLL lock JUMP write_cfg_from_scratchpad ; s1 still has sw[1:0] values ; sw[1:0] == 3 already handled above (indicates no clock module) read_noeeprom_cfgs_cmpll: LOAD sB, msg_cmpll_det'upper LOAD sA, msg_cmpll_det'lower CALL send_message ; COMPARE s1, 00 ; sw[1:0] == [2,1,0] -> configs [A,B,C] JUMP Z, read_noeeprom_cfgs_cmpll_C COMPARE s1, CM_STATUS_SW0 JUMP Z, read_noeeprom_cfgs_cmpll_B JUMP read_noeeprom_cfgs_cmpll_A read_noeeprom_cfgs_cmpll_A: LOAD sB, msg_cfg_A'upper LOAD sA, msg_cfg_A'lower CALL send_message ;Copy RF ref configs LOAD s7, cfg_cmpll_A_rfref_addr'lower LOAD s8, cfg_cmpll_A_rfref_addr'upper LOAD s9, cfg_cmpll_A_rfref_data'lower LOAD sA, cfg_cmpll_A_rfref_data'upper LOAD s6, SPAD_ADDR_CFG_RFREF LOAD s5, 16'd CALL copy_tables_to_scratchpad ;Copy samp configs LOAD s7, cfg_cmpll_A_samp_addr'lower LOAD s8, cfg_cmpll_A_samp_addr'upper LOAD s9, cfg_cmpll_A_samp_data'lower LOAD sA, cfg_cmpll_A_samp_data'upper LOAD s6, SPAD_ADDR_CFG_SAMP LOAD s5, 16'd CALL copy_tables_to_scratchpad ;Copy PLL configs LOAD s7, cfg_cmpll_A_pll_addr'lower LOAD s8, cfg_cmpll_A_pll_addr'upper LOAD s9, cfg_cmpll_A_pll_data'lower LOAD sA, cfg_cmpll_A_pll_data'upper LOAD s6, SPAD_ADDR_CFG_PLL LOAD s5, 40'd CALL copy_tables_to_scratchpad ; LOAD sF, 01 ;do wait on PLL lock JUMP write_cfg_from_scratchpad read_noeeprom_cfgs_cmpll_B: LOAD sB, msg_cfg_B'upper LOAD sA, msg_cfg_B'lower CALL send_message ;Copy RF ref configs LOAD s7, cfg_cmpll_B_rfref_addr'lower LOAD s8, cfg_cmpll_B_rfref_addr'upper LOAD s9, cfg_cmpll_B_rfref_data'lower LOAD sA, cfg_cmpll_B_rfref_data'upper LOAD s6, SPAD_ADDR_CFG_RFREF LOAD s5, 16'd CALL copy_tables_to_scratchpad ;Copy samp configs LOAD s7, cfg_cmpll_B_samp_addr'lower LOAD s8, cfg_cmpll_B_samp_addr'upper LOAD s9, cfg_cmpll_B_samp_data'lower LOAD sA, cfg_cmpll_B_samp_data'upper LOAD s6, SPAD_ADDR_CFG_SAMP LOAD s5, 16'd CALL copy_tables_to_scratchpad ;Copy PLL configs LOAD s7, cfg_cmpll_B_pll_addr'lower LOAD s8, cfg_cmpll_B_pll_addr'upper LOAD s9, cfg_cmpll_B_pll_data'lower LOAD sA, cfg_cmpll_B_pll_data'upper LOAD s6, SPAD_ADDR_CFG_PLL LOAD s5, 40'd CALL copy_tables_to_scratchpad ; LOAD sF, 01 ;do wait on PLL lock JUMP write_cfg_from_scratchpad read_noeeprom_cfgs_cmpll_C: LOAD sB, msg_cfg_C'upper LOAD sA, msg_cfg_C'lower CALL send_message ;Copy RF ref configs LOAD s7, cfg_cmpll_C_rfref_addr'lower LOAD s8, cfg_cmpll_C_rfref_addr'upper LOAD s9, cfg_cmpll_C_rfref_data'lower LOAD sA, cfg_cmpll_C_rfref_data'upper LOAD s6, SPAD_ADDR_CFG_RFREF LOAD s5, 16'd CALL copy_tables_to_scratchpad ;Copy samp configs LOAD s7, cfg_cmpll_C_samp_addr'lower LOAD s8, cfg_cmpll_C_samp_addr'upper LOAD s9, cfg_cmpll_C_samp_data'lower LOAD sA, cfg_cmpll_C_samp_data'upper LOAD s6, SPAD_ADDR_CFG_SAMP LOAD s5, 16'd CALL copy_tables_to_scratchpad ;Copy PLL configs LOAD s7, cfg_cmpll_C_pll_addr'lower LOAD s8, cfg_cmpll_C_pll_addr'upper LOAD s9, cfg_cmpll_C_pll_data'lower LOAD sA, cfg_cmpll_C_pll_data'upper LOAD s6, SPAD_ADDR_CFG_PLL LOAD s5, 40'd CALL copy_tables_to_scratchpad ; LOAD sF, 01 ;do wait on PLL lock JUMP write_cfg_from_scratchpad ; write_cfg_from_scratchpad: write cfg values from scratchpad to all devices ; ; Scratchpad contains SPI address/data values to write ; RF Ref (16 addr/data values at SPAD_ADDR_CFG_RFREF) ; Samp (16 addr/data values at SPAD_ADDR_CFG_SAMP) ; PLL (40 addr/data values at SPAD_ADDR_CFG_PLL) ; ; Addr=0xFF terminates each device's config write_cfg_from_scratchpad: LOAD s0, SPI_CS_RFRefClkBuf LOAD sA, SPAD_ADDR_CFG_RFREF LOAD sB, 16'd CALL write_device_regs LOAD s0, SPI_CS_SampClkBuf LOAD sA, SPAD_ADDR_CFG_SAMP LOAD sB, 16'd CALL write_device_regs COMPARE sF, 00 CALL NZ, wait_for_pll_refclk LOAD s0, SPI_CS_ClkModPLL LOAD sA, SPAD_ADDR_CFG_PLL LOAD sB, 40'd CALL write_device_regs COMPARE sF, 00 JUMP Z, config_complete LOAD sB, msg_cm_pll_lock_wait'upper LOAD sA, msg_cm_pll_lock_wait'lower CALL send_message CALL wait_for_pll_lock config_complete: LOAD sB, msg_config_done'upper LOAD sA, msg_config_done'lower CALL send_message ; OUTPUTK 00, port_TX_UART ;Ensure all outputs stay at 0 post-sleep OUTPUTK 00, port_SPI_CLK OUTPUTK 00, port_SPI_MOSI OUTPUTK 00, port_SPI_CS ;PB output is active-high; wrapper inverts OUTPUTK 00, port_IIC_OUT ;00 tri-states both IIC IOBUFTs OUTPUTK 00, port_LEDS OUTPUTK CONFIG_DONE, port_CTRL ;asserts PicoBlaze sleep, halting execution JUMP end_loop end_loop: JUMP end_loop ;wait forever (wrapper will assert PicoBlaze.sleep) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Subroutines ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;wait_for_pll_refclk: loops until refclk monitor indicates stable refclk input ; Regs: modifies s1 ; wait_for_pll_refclk: LOAD sB, msg_refclk_wait'upper LOAD sA, msg_refclk_wait'lower CALL send_message OUTPUTK PLL_REFCLK_MON_EN, port_CTRL wait_for_pll_refclk_next: INPUT s1, port_CM_STATUS TEST s1, CM_STATUS_REFCLK_VLD JUMP Z, wait_for_pll_refclk_next wait_for_pll_refclk_done: LOAD sB, msg_refclk_valid'upper LOAD sA, msg_refclk_valid'lower CALL send_message RETURN ;write_device_regs: write addr/data values from scratchpad to SPI ; Args: ; sA: First addr value in scrathpad (values must be addr/data/addr/data...) ; sB: Number of addr/data values to write ; ; sA,sB not preserved ; write_device_regs: FETCH s2, (sA) ;retrieve the address byte from the scratcpad COMPARE s2, FF ;check for magic value - addr=0xFF means stop RETURN Z ;return if finished, otherwise continue with byte Tx ADD sA, 01 ;incremenet scratchpad pointer (to corresponding data value) FETCH s1, (sA) ;retrieve the data byte from the scratcpad CALL write_spi_reg ;send byte in s2 to address in s1 via SPI SUB sB, 01 RETURN Z ;return if all bytes have been sent ADD sA, 01 ;incremenet scratchpad pointer (to next addr value) JUMP write_device_regs ;wait_for_pll_lock: loops until PLL STATUS indicates lock ; Hardware design must pull STATUS pin high so no-CM and CM-MMCX ; configurations complete successfully ; Args: None ; Reg s0 not preserved ; wait_for_pll_lock: INPUT s0, port_CM_STATUS AND s0, CM_STATUS_PLL_LOCK JUMP Z, wait_for_pll_lock LOAD sB, msg_cm_pll_lock_done'upper LOAD sA, msg_cm_pll_lock_done'lower CALL send_message RETURN ; Copies bytes from IIC EEPROM to scratchpad memory ; Args: s7: LSB of starting EEPROM address ; s8: MSB of starting EEPROM address ; s9: Starting scratchpad address ; s2: Number of bytes to copy ; Regs: Modifies s0, s1, s2, s5, s7, s8, s9, sD, sF copy_eeprom_to_scratchpad: CALL EEPROM_read_byte ;read eeprom([s8,s7]) into sD STORE sD, (s9) ;save byte to scratchpad SUB s2, 01 ;decrement byte counter RETURN Z ;return when all bytes have been copied ADD s9, 01 ;increment scratchpad address ADD s7, 01 ;incremenet EEPROM address ADDCY s8, 00 JUMP copy_eeprom_to_scratchpad ; copy_tables_to_scratchpad - copies bytes from addr/data tables to scratchpad memory ; Iterates for s5 bytes or until an address byte == 0xFF ; ; Args: s5: Number of addr/data pairs to copy ; s6: Starting addresss in scratchpad ; s7: LSB of address of table containing SPI address bytes ; s8: MSB of address of table containing SPI address bytes ; s9: LSB of address of table containing SPI data bytes ; sA: MSB of address of table containing SPI data bytes ; Regs: modifies s2, s3, s5, s6, s7, s8, s9, sA ; ; Requires tables use LOAD&RETURN syntax with returned value stored in s2 copy_tables_to_scratchpad: CALL@ (s8, s7) ;load next addr byte into s2 STORE s2, (s6) ;write addr byte to scratchpad LOAD s3, s2 ;make a copy for comparison below ADD s6, 01 ;incremenet scratchpad pointer CALL@ (sA, s9) ;load next data byte into s2 STORE s2, (s6) ;write data byte to scratchpad COMPARE s3, FF ;check for magic value indicating last byte RETURN Z ;return if finished, otherwise continue with byte Tx SUB s5, 01 RETURN Z ;Return if all requested bytes have been copied ADD s6, 01 ;incremenet scratchpad pointer ADD s7, 01 ;increment addr table pointer ADDCY s8, 00 ADD s9, 01 ;increment data table pointer ADDCY sA, 00 JUMP copy_tables_to_scratchpad ; Initialize scratchpad memory with 0xFF at addresses 0:127 ; Regs: Modifies s0, s1 init_scratchpad: LOAD s0, 127'd LOAD s1, FF init_scratchpad_next: STORE s1, (s0) ;Write value of s1 (0xFF) to offset in s0 SUB s0, 01 JUMP NZ, init_scratchpad_next RETURN ; EEPROM_read_byte - reads 1 byte from the EEPROM ; This routine will read the byte from the 24AA128 EEPROM at the address specified by the [s8,s7] ; registers and return it in register 'sD'. [s8,s7] must be an address in the range 000 to 3FFF hex. ; Args: ; [s8,s7]: Byte address in 0x000 to 0x3FFF ; Regs: Modifies s0, s1, s2, s5, s7, s8, s9, sD, sF EEPROM_read_byte: CALL I2C_initialise ;ensure bus state and initialise 'sF' CALL I2C_start ;bus start (S) ; LOAD s5, EEPROM_IIC_ADDR ;device base address (7-bits) SL0 s5 ;Write operation (LSB = 0) CALL I2C_Tx_byte ;Transmit address with write CALL I2C_Rx_ACK ;Receive ACK RETURN C ;Return on failure (Carry flag set) ; LOAD s5, s8 ;{x, x, byte_addr[13:8]} CALL I2C_Tx_byte CALL I2C_Rx_ACK ;Receive ACK RETURN C ;Return on failure (Carry flag set) ; LOAD s5, s7 ;byte_addr[7:0] CALL I2C_Tx_byte CALL I2C_Rx_ACK ;Receive ACK RETURN C ;Return on failure (Carry flag set) ; CALL I2C_start ;bus restart (Sr) ; LOAD s5, EEPROM_IIC_ADDR ;device base address (7-bits) SL1 s5 ;Read operation (LSB = 1) CALL I2C_Tx_byte ;Transmit address with write CALL I2C_Rx_ACK ;Receive ACK RETURN C ;Return on failure (Carry flag set) ; CALL I2C_Rx_byte ;Read data from M24C08 LOAD sD, s5 ; CALL I2C_Tx_NACK ;Transmit NACK to end read operation CALL I2C_stop ;transmit stop (P) RETURN ;with Carry flag reset ;write_spi_reg: Writes 1 byte to SPI ; Implements SPI protocol for many ADI devices. Every SPI transaction is 24 bits: ; Bits 0- 7: SPI command - all zeros for 1-byte write ; Bits 8-15: SPI register address (MSB first) ; Bits 16-23: Data byte to write ; ; This method only implements SPI write and ignores the slave device's MISO signal ; ; Register usage: ; Arg: Chip select value in s0 ; Arg: Data byte in s1 ; Arg: Address byte in s2 ; Internal: s3, s4, s5 ; ; Registers s1, s2 are preserved ; Registers s3, s4, s5 are not preserved ; ; Internal regs: ; s3: Data byte currently being transmitted; byte left-shifted in place ; s4: Bit counter ; write_spi_reg: OUTPUT s0, port_SPI_CS ;Assert the selected chip select LOAD s3, 00 ;Send SPI instruction byte (00 == write 1 byte) CALL write_spi_byte LOAD s3, s2 ;Send SPI register address CALL write_spi_byte LOAD s3, s1 ;Send data byte CALL write_spi_byte OUTPUTK 00, port_SPI_CS ;de-assert all chip selects RETURN ;write_spi_byte: helper method for write_spi_reg ; writes single byte to SPI output ; Byte must be passed in s3, s3 will be shifted in-place as bits are sent ; ; The instruction order here determines the setup/hold times betweek the CLK and MOSI signals ; With a 200MHz clk the instruction order below results in: ; SPI clk @ 12.5MHz, (3/8) duty cycle (~30ns high, ~50ns low) ; MOSI-SCLK setup time = 16ns (approx) ; SCLK-MOSI hold time = 60ns (approx) ; ; These timings provide a large margin from AD9511/AD9512 requirements ; write_spi_byte: LOAD s4, 08 ;Load bit counter write_spi_bit: LOAD s5, s3 ;prepare next bit to transmit OUTPUT s5, port_SPI_MOSI ;output data bit to MOSI port (hardware must ignore bits [6:0]!) SLA s3 ;shift data byte, moving next bit to MSB OUTPUTK FF, port_SPI_CLK ;set clk outputs to 1 SUB s4, 01 ;decrement bit counter LOAD s0, s0 ;noop OUTPUTK 00, port_SPI_CLK ;set clk outputs to 0 (doesn't touch flags) JUMP NZ, write_spi_bit ;repeat until last bit RETURN ; 10ms is 200,000 x 50ns (200,000 = 030D40 hex) delay_10ms: LOAD s2, 03 LOAD s1, 0D LOAD s0, 40 JUMP software_delay ; 10 cycles per iteration (50ns @ 200MHz) software_delay: LOAD s0, s0 ;pad loop to make it 10 clock cycles (5 instructions) SUB s0, 1'd SUBCY s1, 0'd SUBCY s2, 0'd JUMP NZ, software_delay RETURN ; send_message - writes string to UART ; Message must be stored at address [sB,sA] using standard LOAD&RETURN scheme ; String must include trailing NUL character for send_message to terminate send_message: CALL@ (sB, sA) COMPARE s9, 00 ;terminate on NUL character RETURN Z CALL UART_TX ADD sA, 1'd ADDCY sB, 0'd JUMP send_message reset_UART_Tx: OUTPUTK TX_UART_RESET, port_CTRL OUTPUTK 00, port_CTRL RETURN UART_TX: INPUT s0, port_TX_UART_STATUS ;Check if buffer is full TEST s0, TX_UART_STATUS_FULL JUMP NZ, UART_TX ;wait if full OUTPUT s9, port_TX_UART RETURN ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Define code sections with SPI data and address values ; LOAD&RETURN instructions are auto-expanded by the assembler ; ;;;;;;;;;;;;;;;;;;;;;;; ; RF ref clock buffer cfg_nocm_rfref_addr: LOAD&RETURN s2, TBL_CFG_NOCM_RFREF_ADDR# cfg_nocm_rfref_data: LOAD&RETURN s2, TBL_CFG_NOCM_RFREF_DATA# cfg_cmmmcx_A_rfref_addr: LOAD&RETURN s2, TBL_CFG_CMMMCX_A_RFREF_ADDR# cfg_cmmmcx_A_rfref_data: LOAD&RETURN s2, TBL_CFG_CMMMCX_A_RFREF_DATA# cfg_cmmmcx_B_rfref_addr: LOAD&RETURN s2, TBL_CFG_CMMMCX_B_RFREF_ADDR# cfg_cmmmcx_B_rfref_data: LOAD&RETURN s2, TBL_CFG_CMMMCX_B_RFREF_DATA# cfg_cmmmcx_C_rfref_addr: LOAD&RETURN s2, TBL_CFG_CMMMCX_C_RFREF_ADDR# cfg_cmmmcx_C_rfref_data: LOAD&RETURN s2, TBL_CFG_CMMMCX_C_RFREF_DATA# cfg_cmpll_A_rfref_addr: LOAD&RETURN s2, TBL_CFG_CMPLL_A_RFREF_ADDR# cfg_cmpll_A_rfref_data: LOAD&RETURN s2, TBL_CFG_CMPLL_A_RFREF_DATA# cfg_cmpll_B_rfref_addr: LOAD&RETURN s2, TBL_CFG_CMPLL_B_RFREF_ADDR# cfg_cmpll_B_rfref_data: LOAD&RETURN s2, TBL_CFG_CMPLL_B_RFREF_DATA# cfg_cmpll_C_rfref_addr: LOAD&RETURN s2, TBL_CFG_CMPLL_C_RFREF_ADDR# cfg_cmpll_C_rfref_data: LOAD&RETURN s2, TBL_CFG_CMPLL_C_RFREF_DATA# ;;;;;;;;;;;;;;;;;;;;;;; ; Sampling clock buffer cfg_nocm_samp_addr: LOAD&RETURN s2, TBL_CFG_NOCM_SAMP_ADDR# cfg_nocm_samp_data: LOAD&RETURN s2, TBL_CFG_NOCM_SAMP_DATA# cfg_cmmmcx_A_samp_addr: LOAD&RETURN s2, TBL_CFG_CMMMCX_A_SAMP_ADDR# cfg_cmmmcx_A_samp_data: LOAD&RETURN s2, TBL_CFG_CMMMCX_A_SAMP_DATA# cfg_cmmmcx_B_samp_addr: LOAD&RETURN s2, TBL_CFG_CMMMCX_B_SAMP_ADDR# cfg_cmmmcx_B_samp_data: LOAD&RETURN s2, TBL_CFG_CMMMCX_B_SAMP_DATA# cfg_cmmmcx_C_samp_addr: LOAD&RETURN s2, TBL_CFG_CMMMCX_C_SAMP_ADDR# cfg_cmmmcx_C_samp_data: LOAD&RETURN s2, TBL_CFG_CMMMCX_C_SAMP_DATA# cfg_cmpll_A_samp_addr: LOAD&RETURN s2, TBL_CFG_CMPLL_A_SAMP_ADDR# cfg_cmpll_A_samp_data: LOAD&RETURN s2, TBL_CFG_CMPLL_A_SAMP_DATA# cfg_cmpll_B_samp_addr: LOAD&RETURN s2, TBL_CFG_CMPLL_B_SAMP_ADDR# cfg_cmpll_B_samp_data: LOAD&RETURN s2, TBL_CFG_CMPLL_B_SAMP_DATA# cfg_cmpll_C_samp_addr: LOAD&RETURN s2, TBL_CFG_CMPLL_C_SAMP_ADDR# cfg_cmpll_C_samp_data: LOAD&RETURN s2, TBL_CFG_CMPLL_C_SAMP_DATA# ;;;;;;;;;;;;;;;;;;;;;;; ; PLL cfg_nocm_pll_addr: LOAD&RETURN s2, TBL_CFG_NOCM_PLL_ADDR# cfg_nocm_pll_data: LOAD&RETURN s2, TBL_CFG_NOCM_PLL_DATA# cfg_cmpll_A_pll_addr: LOAD&RETURN s2, TBL_CFG_CMPLL_A_PLL_ADDR# cfg_cmpll_A_pll_data: LOAD&RETURN s2, TBL_CFG_CMPLL_A_PLL_DATA# cfg_cmpll_B_pll_addr: LOAD&RETURN s2, TBL_CFG_CMPLL_B_PLL_ADDR# cfg_cmpll_B_pll_data: LOAD&RETURN s2, TBL_CFG_CMPLL_B_PLL_DATA# cfg_cmpll_C_pll_addr: LOAD&RETURN s2, TBL_CFG_CMPLL_C_PLL_ADDR# cfg_cmpll_C_pll_data: LOAD&RETURN s2, TBL_CFG_CMPLL_C_PLL_DATA# ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Define strings for UART output STRING str_init1$, " ***** WARP v3 Clock Config Core *****" STRING str_init2$, " Program Assembly Date: " STRING str_eeprom_det$, "Found config data in EEPROM" STRING str_noeeprom_det$, "No config data in EEPROM - Using Defaults" STRING str_nocm_det$, "No Clock Module Detected" STRING str_cmmmcx_det$, "Detected CM-MMCX Module" STRING str_cmpll_det$, "Detected CM-PLL Module" STRING str_cfg_A$, "Loading configuration A" STRING str_cfg_B$, "Loading configuration B" STRING str_cfg_C$, "Loading configuration C" STRING str_pll_lock_wait$, "Waiting for AD9511 PLL lock..." STRING str_pll_lock_done$, "PLL locked!" STRING str_refclk_wait$, "Waiting for valid PLL ref clk......" STRING str_refclk_valid$, "ref clk valid!" STRING str_config_done$, "Clock Config Complete - Continuing Boot Process" STRING str_div_line$, "***********************************************" msg_init: LOAD&RETURN s9, CR LOAD&RETURN s9, str_div_line$ LOAD&RETURN s9, CR LOAD&RETURN s9, str_init1$ LOAD&RETURN s9, CR LOAD&RETURN s9, str_init2$ LOAD&RETURN s9, datestamp$ LOAD&RETURN s9, CR LOAD&RETURN s9, CR LOAD&RETURN s9, NUL msg_eeprom_det: LOAD&RETURN s9, str_eeprom_det$ LOAD&RETURN s9, CR LOAD&RETURN s9, NUL msg_noeeprom_det: LOAD&RETURN s9, str_noeeprom_det$ LOAD&RETURN s9, CR LOAD&RETURN s9, NUL msg_nocm_det: LOAD&RETURN s9, str_nocm_det$ LOAD&RETURN s9, CR LOAD&RETURN s9, NUL msg_cfg_A: LOAD&RETURN s9, str_cfg_A$ LOAD&RETURN s9, CR LOAD&RETURN s9, NUL msg_cfg_B: LOAD&RETURN s9, str_cfg_B$ LOAD&RETURN s9, CR LOAD&RETURN s9, NUL msg_cfg_C: LOAD&RETURN s9, str_cfg_C$ LOAD&RETURN s9, CR LOAD&RETURN s9, NUL msg_cmmmcx_det: LOAD&RETURN s9, str_cmmmcx_det$ LOAD&RETURN s9, CR LOAD&RETURN s9, NUL msg_cmpll_det: LOAD&RETURN s9, str_cmpll_det$ LOAD&RETURN s9, CR LOAD&RETURN s9, NUL msg_refclk_wait: LOAD&RETURN s9, str_refclk_wait$ LOAD&RETURN s9, NUL msg_refclk_valid: LOAD&RETURN s9, str_refclk_valid$ LOAD&RETURN s9, CR LOAD&RETURN s9, NUL msg_cm_pll_lock_wait: LOAD&RETURN s9, str_pll_lock_wait$ LOAD&RETURN s9, NUL msg_cm_pll_lock_done: LOAD&RETURN s9, str_pll_lock_done$ LOAD&RETURN s9, CR LOAD&RETURN s9, CR LOAD&RETURN s9, NUL msg_config_done: LOAD&RETURN s9, str_config_done$ LOAD&RETURN s9, CR LOAD&RETURN s9, str_div_line$ LOAD&RETURN s9, CR LOAD&RETURN s9, CR LOAD&RETURN s9, NUL INCLUDE "i2c_routines.psm" INCLUDE "clk_config_defaults.psm"