mirror of
https://github.com/pConst/basic_verilog.git
synced 2025-01-28 07:02:55 +08:00
1619 lines
66 KiB
Plaintext
1619 lines
66 KiB
Plaintext
/* Symbol Table */
|
|
// ADC0_lsb = CONSTANT: 0
|
|
// ADC0_msb = CONSTANT: 1
|
|
// ADC1_lsb = CONSTANT: 2
|
|
// ADC1_msb = CONSTANT: 3
|
|
// AD_sign = LABEL: 59
|
|
// BTN_east = CONSTANT: 2
|
|
// BTN_north = CONSTANT: 1
|
|
// BTN_south = CONSTANT: 4
|
|
// BTN_west = CONSTANT: 8
|
|
// ISR = LABEL: 539
|
|
// LCD_DB4 = CONSTANT: 16
|
|
// LCD_DB5 = CONSTANT: 32
|
|
// LCD_DB6 = CONSTANT: 64
|
|
// LCD_DB7 = CONSTANT: 128
|
|
// LCD_E = CONSTANT: 1
|
|
// LCD_RS = CONSTANT: 4
|
|
// LCD_RW = CONSTANT: 2
|
|
// LCD_clear = LABEL: 524
|
|
// LCD_cursor = LABEL: 529
|
|
// LCD_drive = CONSTANT: 8
|
|
// LCD_input_port = CONSTANT: 2
|
|
// LCD_output_port = CONSTANT: 64
|
|
// LCD_pulse_E = LABEL: 440
|
|
// LCD_read_DB4 = CONSTANT: 16
|
|
// LCD_read_DB5 = CONSTANT: 32
|
|
// LCD_read_DB6 = CONSTANT: 64
|
|
// LCD_read_DB7 = CONSTANT: 128
|
|
// LCD_read_data8 = LABEL: 482
|
|
// LCD_read_spare0 = CONSTANT: 1
|
|
// LCD_read_spare1 = CONSTANT: 2
|
|
// LCD_read_spare2 = CONSTANT: 4
|
|
// LCD_read_spare3 = CONSTANT: 8
|
|
// LCD_reset = LABEL: 507
|
|
// LCD_write_data = LABEL: 465
|
|
// LCD_write_inst4 = LABEL: 446
|
|
// LCD_write_inst8 = LABEL: 450
|
|
// LED0 = CONSTANT: 1
|
|
// LED1 = CONSTANT: 2
|
|
// LED2 = CONSTANT: 4
|
|
// LED3 = CONSTANT: 8
|
|
// LED4 = CONSTANT: 16
|
|
// LED5 = CONSTANT: 32
|
|
// LED6 = CONSTANT: 64
|
|
// LED7 = CONSTANT: 128
|
|
// LED_port = CONSTANT: 128
|
|
// SPI_adc_conv = CONSTANT: 16
|
|
// SPI_amp_cs = CONSTANT: 8
|
|
// SPI_amp_sdi = CONSTANT: 64
|
|
// SPI_amp_shdn = CONSTANT: 64
|
|
// SPI_control_port = CONSTANT: 8
|
|
// SPI_dac_clr = CONSTANT: 128
|
|
// SPI_dac_cs = CONSTANT: 32
|
|
// SPI_init = LABEL: 287
|
|
// SPI_input_port = CONSTANT: 1
|
|
// SPI_output_port = CONSTANT: 4
|
|
// SPI_rom_cs = CONSTANT: 2
|
|
// SPI_sck = CONSTANT: 1
|
|
// SPI_sdi = CONSTANT: 128
|
|
// SPI_sdo = CONSTANT: 128
|
|
// SPI_spare_control = CONSTANT: 4
|
|
// VREF_lsb = CONSTANT: 114
|
|
// VREF_msb = CONSTANT: 6
|
|
// adc_read = LABEL: 307
|
|
// amp_A_gain = CONSTANT: 4
|
|
// amp_B_gain = CONSTANT: 5
|
|
// character_0 = CONSTANT: 48
|
|
// character_1 = CONSTANT: 49
|
|
// character_2 = CONSTANT: 50
|
|
// character_3 = CONSTANT: 51
|
|
// character_4 = CONSTANT: 52
|
|
// character_5 = CONSTANT: 53
|
|
// character_6 = CONSTANT: 54
|
|
// character_7 = CONSTANT: 55
|
|
// character_8 = CONSTANT: 56
|
|
// character_9 = CONSTANT: 57
|
|
// character_A = CONSTANT: 65
|
|
// character_B = CONSTANT: 66
|
|
// character_BS = CONSTANT: 8
|
|
// character_C = CONSTANT: 67
|
|
// character_CR = CONSTANT: 13
|
|
// character_D = CONSTANT: 68
|
|
// character_E = CONSTANT: 69
|
|
// character_F = CONSTANT: 70
|
|
// character_G = CONSTANT: 71
|
|
// character_H = CONSTANT: 72
|
|
// character_I = CONSTANT: 73
|
|
// character_J = CONSTANT: 74
|
|
// character_K = CONSTANT: 75
|
|
// character_L = CONSTANT: 76
|
|
// character_M = CONSTANT: 77
|
|
// character_N = CONSTANT: 78
|
|
// character_O = CONSTANT: 79
|
|
// character_P = CONSTANT: 80
|
|
// character_Q = CONSTANT: 81
|
|
// character_R = CONSTANT: 82
|
|
// character_S = CONSTANT: 83
|
|
// character_T = CONSTANT: 84
|
|
// character_U = CONSTANT: 85
|
|
// character_V = CONSTANT: 86
|
|
// character_W = CONSTANT: 87
|
|
// character_X = CONSTANT: 88
|
|
// character_Y = CONSTANT: 89
|
|
// character_Z = CONSTANT: 90
|
|
// character_a = CONSTANT: 97
|
|
// character_b = CONSTANT: 98
|
|
// character_c = CONSTANT: 99
|
|
// character_colon = CONSTANT: 58
|
|
// character_comma = CONSTANT: 44
|
|
// character_d = CONSTANT: 100
|
|
// character_divide = CONSTANT: 47
|
|
// character_dollar = CONSTANT: 36
|
|
// character_e = CONSTANT: 101
|
|
// character_equals = CONSTANT: 61
|
|
// character_exclaim = CONSTANT: 33
|
|
// character_f = CONSTANT: 102
|
|
// character_g = CONSTANT: 103
|
|
// character_greater_than = CONSTANT: 62
|
|
// character_h = CONSTANT: 104
|
|
// character_i = CONSTANT: 105
|
|
// character_j = CONSTANT: 106
|
|
// character_k = CONSTANT: 107
|
|
// character_l = CONSTANT: 108
|
|
// character_less_than = CONSTANT: 60
|
|
// character_m = CONSTANT: 109
|
|
// character_minus = CONSTANT: 45
|
|
// character_n = CONSTANT: 110
|
|
// character_o = CONSTANT: 111
|
|
// character_p = CONSTANT: 112
|
|
// character_plus = CONSTANT: 43
|
|
// character_q = CONSTANT: 113
|
|
// character_question = CONSTANT: 63
|
|
// character_r = CONSTANT: 114
|
|
// character_s = CONSTANT: 115
|
|
// character_semi_colon = CONSTANT: 59
|
|
// character_space = CONSTANT: 32
|
|
// character_stop = CONSTANT: 46
|
|
// character_t = CONSTANT: 116
|
|
// character_u = CONSTANT: 117
|
|
// character_v = CONSTANT: 118
|
|
// character_w = CONSTANT: 119
|
|
// character_x = CONSTANT: 120
|
|
// character_y = CONSTANT: 121
|
|
// character_z = CONSTANT: 122
|
|
// cold_start = LABEL: 0
|
|
// decimal0 = CONSTANT: 7
|
|
// decimal1 = CONSTANT: 8
|
|
// decimal2 = CONSTANT: 9
|
|
// decimal3 = CONSTANT: 10
|
|
// decimal4 = CONSTANT: 11
|
|
// delay_1ms = LABEL: 425
|
|
// delay_1s = LABEL: 435
|
|
// delay_1us = LABEL: 416
|
|
// delay_1us_constant = CONSTANT: 11
|
|
// delay_20ms = LABEL: 430
|
|
// delay_40us = LABEL: 420
|
|
// disp_AD = LABEL: 383
|
|
// disp_ADC_Control = LABEL: 353
|
|
// disp_PicoBlaze = LABEL: 334
|
|
// disp_VA = LABEL: 376
|
|
// disp_VINA_volts = LABEL: 114
|
|
// disp_hex_byte = LABEL: 409
|
|
// disp_volts = LABEL: 116
|
|
// div10_loop = LABEL: 273
|
|
// div10_restore = LABEL: 278
|
|
// div10_shifts = LABEL: 281
|
|
// divide_16bit_by_10 = LABEL: 266
|
|
// gain_A7 = LABEL: 217
|
|
// gain_decrease = LABEL: 141
|
|
// gain_increase = LABEL: 134
|
|
// hex_byte_to_ASCII = LABEL: 392
|
|
// hex_to_ASCII = LABEL: 404
|
|
// int_to_BCD_loop = LABEL: 260
|
|
// integer16_to_BCD = LABEL: 258
|
|
// m16s_loop = LABEL: 238
|
|
// m16s_noadd = LABEL: 245
|
|
// m16s_nosub = LABEL: 257
|
|
// m16s_pos = LABEL: 236
|
|
// mult_16x16s = LABEL: 228
|
|
// mult_VINA = LABEL: 90
|
|
// neg_AD = LABEL: 54
|
|
// new_gain_set = LABEL: 146
|
|
// next_adc_bit = LABEL: 313
|
|
// next_amp_SPI_bit = LABEL: 294
|
|
// number_char = LABEL: 407
|
|
// s0 = REGISTER: 0
|
|
// s1 = REGISTER: 1
|
|
// s2 = REGISTER: 2
|
|
// s3 = REGISTER: 3
|
|
// s4 = REGISTER: 4
|
|
// s5 = REGISTER: 5
|
|
// s6 = REGISTER: 6
|
|
// s7 = REGISTER: 7
|
|
// s8 = REGISTER: 8
|
|
// s9 = REGISTER: 9
|
|
// sA = REGISTER: 10
|
|
// sB = REGISTER: 11
|
|
// sC = REGISTER: 12
|
|
// sD = REGISTER: 13
|
|
// sE = REGISTER: 14
|
|
// sF = REGISTER: 15
|
|
// sample_count = CONSTANT: 6
|
|
// set_amp = LABEL: 290
|
|
// set_line2 = LABEL: 535
|
|
// switch0 = CONSTANT: 16
|
|
// switch1 = CONSTANT: 32
|
|
// switch2 = CONSTANT: 64
|
|
// switch3 = CONSTANT: 128
|
|
// switch_port = CONSTANT: 0
|
|
// test_A2 = LABEL: 172
|
|
// test_A3 = LABEL: 181
|
|
// test_A4 = LABEL: 190
|
|
// test_A5 = LABEL: 199
|
|
// test_A6 = LABEL: 208
|
|
// test_max_pos = LABEL: 108
|
|
// wait_1ms = LABEL: 426
|
|
// wait_1s = LABEL: 436
|
|
// wait_1us = LABEL: 417
|
|
// wait_20ms = LABEL: 431
|
|
// wait_40us = LABEL: 421
|
|
// wait_int = LABEL: 22
|
|
// wait_no_press = LABEL: 223
|
|
// warm_start = LABEL: 20
|
|
|
|
/* Program Code */
|
|
// #1: ;KCPSM3 Program - SPI Control of Amplifier and A/D converter on Spartan-3E Starter Kit.
|
|
// #2: ;
|
|
// #3: ;
|
|
// #4: ;Ken Chapman - Xilinx Ltd
|
|
// #5: ;
|
|
// #6: ;Version v1.00 - 21th December 2005
|
|
// #7: ;
|
|
// #8: ;This program uses an 8KHz interrupt to generate test waveforms on the
|
|
// #9: ;4 analogue outputs provided by the Linear Technology LTC2624 device.
|
|
// #10: ;
|
|
// #11: ;As well as the port connections vital to communication with the UART and the SPI
|
|
// #12: ;FLASH memory, there are additional port connections used to disable the other
|
|
// #13: ;devices sharing the SPI bus on the Starter Kit board. Although these could have been
|
|
// #14: ;controlled at the hardware level, they are included in this code to aid
|
|
// #15: ;future investigations of communication with the other SPI devices using PicoBlaze.
|
|
// #16: ;
|
|
// #17: ;Connections to the LEDs, switches and press buttons are provided to aid
|
|
// #18: ;development and enable further experiments. Otherwise know as having fun!
|
|
// #19: ;
|
|
// #20: ;Port definitions
|
|
// #21: ;
|
|
// #22: ;
|
|
// #23: CONSTANT(SPI_control_port,8) ;SPI clock and chip selects
|
|
// #24: CONSTANT(SPI_sck,1) ; SCK - bit0
|
|
// #25: CONSTANT(SPI_rom_cs,2) ; serial rom select - bit1
|
|
// #26: CONSTANT(SPI_spare_control,4) ; spare - bit2
|
|
// #27: CONSTANT(SPI_amp_cs,8) ; amplifier select - bit3
|
|
// #28: CONSTANT(SPI_adc_conv,16) ; A/D convert - bit4
|
|
// #29: CONSTANT(SPI_dac_cs,32) ; D/A select - bit5
|
|
// #30: CONSTANT(SPI_amp_shdn,64) ; amplifier SHDN - bit6
|
|
// #31: CONSTANT(SPI_dac_clr,128) ; D/A clear - bit7
|
|
// #32: ;
|
|
// #33: CONSTANT(SPI_output_port,4) ;SPI data output
|
|
// #34: CONSTANT(SPI_sdo,128) ; SDO - bit7
|
|
// #35: ;
|
|
// #36: CONSTANT(SPI_input_port,1) ;SPI data input
|
|
// #37: CONSTANT(SPI_sdi,128) ; SDI - bit7
|
|
// #38: CONSTANT(SPI_amp_sdi,64) ; amplifier SDI - bit6
|
|
// #39: ;
|
|
// #40: ;
|
|
// #41: CONSTANT(LED_port,128) ;8 simple LEDs
|
|
// #42: CONSTANT(LED0,1) ; LED 0 - bit0
|
|
// #43: CONSTANT(LED1,2) ; 1 - bit1
|
|
// #44: CONSTANT(LED2,4) ; 2 - bit2
|
|
// #45: CONSTANT(LED3,8) ; 3 - bit3
|
|
// #46: CONSTANT(LED4,16) ; 4 - bit4
|
|
// #47: CONSTANT(LED5,32) ; 5 - bit5
|
|
// #48: CONSTANT(LED6,64) ; 6 - bit6
|
|
// #49: CONSTANT(LED7,128) ; 7 - bit7
|
|
// #50: ;
|
|
// #51: ;
|
|
// #52: CONSTANT(switch_port,0) ;Read switches and press buttons
|
|
// #53: CONSTANT(BTN_north,1) ; Buttons North - bit0
|
|
// #54: CONSTANT(BTN_east,2) ; East - bit1
|
|
// #55: CONSTANT(BTN_south,4) ; South - bit2
|
|
// #56: CONSTANT(BTN_west,8) ; West - bit3
|
|
// #57: CONSTANT(switch0,16) ; Switches 0 - bit4
|
|
// #58: CONSTANT(switch1,32) ; 1 - bit5
|
|
// #59: CONSTANT(switch2,64) ; 2 - bit6
|
|
// #60: CONSTANT(switch3,128) ; 3 - bit7
|
|
// #61: ;
|
|
// #62: ;LCD interface ports
|
|
// #63: ;
|
|
// #64: ;The master enable signal is not used by the LCD display itself
|
|
// #65: ;but may be required to confirm that LCD communication is active.
|
|
// #66: ;This is required on the Spartan-3E Starter Kit if the StrataFLASH
|
|
// #67: ;is used because it shares the same data pins and conflicts must be avoided.
|
|
// #68: ;
|
|
// #69: CONSTANT(LCD_output_port,64) ;LCD character module output data and control
|
|
// #70: CONSTANT(LCD_E,1) ; active High Enable E - bit0
|
|
// #71: CONSTANT(LCD_RW,2) ; Read=1 Write=0 RW - bit1
|
|
// #72: CONSTANT(LCD_RS,4) ; Instruction=0 Data=1 RS - bit2
|
|
// #73: CONSTANT(LCD_drive,8) ; Master enable (active High) - bit3
|
|
// #74: CONSTANT(LCD_DB4,16) ; 4-bit Data DB4 - bit4
|
|
// #75: CONSTANT(LCD_DB5,32) ; interface Data DB5 - bit5
|
|
// #76: CONSTANT(LCD_DB6,64) ; Data DB6 - bit6
|
|
// #77: CONSTANT(LCD_DB7,128) ; Data DB7 - bit7
|
|
// #78: ;
|
|
// #79: ;
|
|
// #80: CONSTANT(LCD_input_port,2) ;LCD character module input data
|
|
// #81: CONSTANT(LCD_read_spare0,1) ; Spare bits - bit0
|
|
// #82: CONSTANT(LCD_read_spare1,2) ; are zero - bit1
|
|
// #83: CONSTANT(LCD_read_spare2,4) ; - bit2
|
|
// #84: CONSTANT(LCD_read_spare3,8) ; - bit3
|
|
// #85: CONSTANT(LCD_read_DB4,16) ; 4-bit Data DB4 - bit4
|
|
// #86: CONSTANT(LCD_read_DB5,32) ; interface Data DB5 - bit5
|
|
// #87: CONSTANT(LCD_read_DB6,64) ; Data DB6 - bit6
|
|
// #88: CONSTANT(LCD_read_DB7,128) ; Data DB7 - bit7
|
|
// #89: ;
|
|
// #90: ;
|
|
// #91: ;
|
|
// #92: ;
|
|
// #93: ;Special Register usage
|
|
// #94: ;
|
|
// #95: ;
|
|
// #96: ;
|
|
// #97: ;Scratch Pad Memory Locations
|
|
// #98: ;
|
|
// #99: ;Values read from the A/D converter
|
|
// #100: ;
|
|
// #101: CONSTANT(ADC0_lsb,0) ;ADC Channel 0 value LS-Byte
|
|
// #102: CONSTANT(ADC0_msb,1) ; MS-Byte
|
|
// #103: ;
|
|
// #104: CONSTANT(ADC1_lsb,2) ;ADC Channel 1 value LS-Byte
|
|
// #105: CONSTANT(ADC1_msb,3) ; MS-Byte
|
|
// #106: ;
|
|
// #107: ;Amplifier gain settings.
|
|
// #108: ;
|
|
// #109: ;Stored value is the 4-bit code for gain setting
|
|
// #110: ; Code 1 2 3 4 5 6 7
|
|
// #111: ; Gain -1 -2 -5 -10 -20 -50 -100
|
|
// #112: CONSTANT(amp_A_gain,4) ;Amplifier A gain value
|
|
// #113: CONSTANT(amp_B_gain,5) ;Amplifier B gain value
|
|
// #114: ;
|
|
// #115: ;Sample counter used to give activity indication on LEDs
|
|
// #116: ;
|
|
// #117: CONSTANT(sample_count,6) ;8-bit counter LS-Byte
|
|
// #118: ;
|
|
// #119: CONSTANT(decimal0,7) ;5 digit decimal value
|
|
// #120: CONSTANT(decimal1,8)
|
|
// #121: CONSTANT(decimal2,9)
|
|
// #122: CONSTANT(decimal3,10)
|
|
// #123: CONSTANT(decimal4,11)
|
|
// #124: ;
|
|
// #125: ;
|
|
// #126: ;
|
|
// #127: ;
|
|
// #128: ;Useful data constants
|
|
// #129: ;
|
|
// #130: CONSTANT(VREF_lsb,114) ;Reference voltage in milli-volts
|
|
// #131: CONSTANT(VREF_msb,6) ;Nominal value 1.65v so value is 1650 (0672 hex)
|
|
// #132: ;
|
|
// #133: ;Constant to define a software delay of 1us. This must be adjusted to reflect the
|
|
// #134: ;clock applied to KCPSM3. Every instruction executes in 2 clock cycles making the
|
|
// #135: ;calculation highly predictable. The '6' in the following equation even allows for
|
|
// #136: ;'CALL delay_1us' instruction in the initiating code.
|
|
// #137: ;
|
|
// #138: ; delay_1us_constant = (clock_rate - 6)/4 Where 'clock_rate' is in MHz
|
|
// #139: ;
|
|
// #140: ;Example: For a 50MHz clock the constant value is (10-6)/4 = 11 (0B Hex).
|
|
// #141: ;For clock rates below 10MHz the value of 1 must be used and the operation will
|
|
// #142: ;become lower than intended.
|
|
// #143: ;
|
|
// #144: CONSTANT(delay_1us_constant,11)
|
|
// #145: ;
|
|
// #146: ;
|
|
// #147: ;
|
|
// #148: ;ASCII table
|
|
// #149: ;
|
|
// #150: CONSTANT(character_a,97)
|
|
// #151: CONSTANT(character_b,98)
|
|
// #152: CONSTANT(character_c,99)
|
|
// #153: CONSTANT(character_d,100)
|
|
// #154: CONSTANT(character_e,101)
|
|
// #155: CONSTANT(character_f,102)
|
|
// #156: CONSTANT(character_g,103)
|
|
// #157: CONSTANT(character_h,104)
|
|
// #158: CONSTANT(character_i,105)
|
|
// #159: CONSTANT(character_j,106)
|
|
// #160: CONSTANT(character_k,107)
|
|
// #161: CONSTANT(character_l,108)
|
|
// #162: CONSTANT(character_m,109)
|
|
// #163: CONSTANT(character_n,110)
|
|
// #164: CONSTANT(character_o,111)
|
|
// #165: CONSTANT(character_p,112)
|
|
// #166: CONSTANT(character_q,113)
|
|
// #167: CONSTANT(character_r,114)
|
|
// #168: CONSTANT(character_s,115)
|
|
// #169: CONSTANT(character_t,116)
|
|
// #170: CONSTANT(character_u,117)
|
|
// #171: CONSTANT(character_v,118)
|
|
// #172: CONSTANT(character_w,119)
|
|
// #173: CONSTANT(character_x,120)
|
|
// #174: CONSTANT(character_y,121)
|
|
// #175: CONSTANT(character_z,122)
|
|
// #176: CONSTANT(character_A,65)
|
|
// #177: CONSTANT(character_B,66)
|
|
// #178: CONSTANT(character_C,67)
|
|
// #179: CONSTANT(character_D,68)
|
|
// #180: CONSTANT(character_E,69)
|
|
// #181: CONSTANT(character_F,70)
|
|
// #182: CONSTANT(character_G,71)
|
|
// #183: CONSTANT(character_H,72)
|
|
// #184: CONSTANT(character_I,73)
|
|
// #185: CONSTANT(character_J,74)
|
|
// #186: CONSTANT(character_K,75)
|
|
// #187: CONSTANT(character_L,76)
|
|
// #188: CONSTANT(character_M,77)
|
|
// #189: CONSTANT(character_N,78)
|
|
// #190: CONSTANT(character_O,79)
|
|
// #191: CONSTANT(character_P,80)
|
|
// #192: CONSTANT(character_Q,81)
|
|
// #193: CONSTANT(character_R,82)
|
|
// #194: CONSTANT(character_S,83)
|
|
// #195: CONSTANT(character_T,84)
|
|
// #196: CONSTANT(character_U,85)
|
|
// #197: CONSTANT(character_V,86)
|
|
// #198: CONSTANT(character_W,87)
|
|
// #199: CONSTANT(character_X,88)
|
|
// #200: CONSTANT(character_Y,89)
|
|
// #201: CONSTANT(character_Z,90)
|
|
// #202: CONSTANT(character_0,48)
|
|
// #203: CONSTANT(character_1,49)
|
|
// #204: CONSTANT(character_2,50)
|
|
// #205: CONSTANT(character_3,51)
|
|
// #206: CONSTANT(character_4,52)
|
|
// #207: CONSTANT(character_5,53)
|
|
// #208: CONSTANT(character_6,54)
|
|
// #209: CONSTANT(character_7,55)
|
|
// #210: CONSTANT(character_8,56)
|
|
// #211: CONSTANT(character_9,57)
|
|
// #212: CONSTANT(character_colon,58)
|
|
// #213: CONSTANT(character_stop,46)
|
|
// #214: CONSTANT(character_semi_colon,59)
|
|
// #215: CONSTANT(character_minus,45)
|
|
// #216: CONSTANT(character_divide,47) ;'/'
|
|
// #217: CONSTANT(character_plus,43)
|
|
// #218: CONSTANT(character_comma,44)
|
|
// #219: CONSTANT(character_less_than,60)
|
|
// #220: CONSTANT(character_greater_than,62)
|
|
// #221: CONSTANT(character_equals,61)
|
|
// #222: CONSTANT(character_space,32)
|
|
// #223: CONSTANT(character_CR,13) ;carriage return
|
|
// #224: CONSTANT(character_question,63) ;'?'
|
|
// #225: CONSTANT(character_dollar,36)
|
|
// #226: CONSTANT(character_exclaim,33) ;'!'
|
|
// #227: CONSTANT(character_BS,8) ;Back Space command character
|
|
// #228: ;
|
|
// #229: ;
|
|
// #230: ;
|
|
// #231: ;
|
|
// #232: ;
|
|
// #233: ;
|
|
// #234: ;Initialise the system
|
|
// #235: ;
|
|
// #236: ;
|
|
// @000 #237: [cold_start]
|
|
3011f // @000 #237: CALL(SPI_init) ;initialise SPI bus ports
|
|
301fb // @001 #238: CALL(LCD_reset) ;initialise LCD display
|
|
// #239: ;
|
|
// #240: ;Write welcome message to LCD display
|
|
// #241: ;
|
|
00510 // @002 #242: LOAD(s5,16) ;Line 1 position 0
|
|
30211 // @003 #243: CALL(LCD_cursor)
|
|
3014e // @004 #244: CALL(disp_PicoBlaze) ;Display 'PicoBlaze Inside'
|
|
00523 // @005 #245: LOAD(s5,35) ;Line 2 position 3
|
|
30211 // @006 #246: CALL(LCD_cursor)
|
|
30161 // @007 #247: CALL(disp_ADC_Control)
|
|
301b3 // @008 #248: CALL(delay_1s) ;wait 5 seconds
|
|
301b3 // @009 #249: CALL(delay_1s)
|
|
301b3 // @00a #250: CALL(delay_1s)
|
|
301b3 // @00b #251: CALL(delay_1s)
|
|
301b3 // @00c #252: CALL(delay_1s)
|
|
3020c // @00d #253: CALL(LCD_clear) ;Clear display
|
|
// #254: ;
|
|
00000 // @00e #255: LOAD(s0,0) ;clear event counter
|
|
2e006 // @00f #256: STORE(s0,sample_count)
|
|
// #257: ;
|
|
// #258: ;
|
|
// #259: ;
|
|
// #260: ;
|
|
00001 // @010 #261: LOAD(s0,1) ;set initial amplifier gain to 1 on both channels
|
|
2e004 // @011 #262: STORE(s0,amp_A_gain)
|
|
2e005 // @012 #263: STORE(s0,amp_B_gain)
|
|
34092 // @013 #264: JUMP(new_gain_set) ;set, display the initial gain and enable interrupts
|
|
// #265: ;
|
|
// #266: ;
|
|
// #267: ;The program is interrupt driven to maintain an 8KHz sample rate. The main body
|
|
// #268: ;of the program waits for an interrupt to occur. The interrupt updates all four
|
|
// #269: ;analogue outputs with values stored in scratch pad memory. This takes approximately
|
|
// #270: ;58us of the 125us available between interrupts. The main program then prepares
|
|
// #271: ;new values for the analogue outputs (in less than 67us) before waiting for the
|
|
// #272: ;next interrupt.
|
|
// #273: ;
|
|
// #274: ;
|
|
// @014 #275: [warm_start]
|
|
00fff // @014 #275: LOAD(sF,FF) ;flag set and wait for interrupt to be serviced
|
|
3c001 // @015 #276: ENABLE(INTERRUPT) ;normal operation
|
|
// @016 #277: [wait_int]
|
|
04e00 // @016 #277: INPUT(sE,switch_port) ;test for button press changes to amplifier gain
|
|
12e01 // @017 #278: TEST(sE,BTN_north) ;sE used as this in not effected by ISR
|
|
35486 // @018 #279: JUMP(NZ,gain_increase)
|
|
12e04 // @019 #280: TEST(sE,BTN_south)
|
|
3548d // @01a #281: JUMP(NZ,gain_decrease)
|
|
14fff // @01b #282: COMPARE(sF,FF) ;wait for interrupt
|
|
35016 // @01c #283: JUMP(Z,wait_int) ;interrupt clears the flag
|
|
// #284: ;
|
|
// #285: ;
|
|
// #286: ;
|
|
// #287: ;Drive LEDs with simple binary count of the samples to indicate
|
|
// #288: ;that the design is active.
|
|
// #289: ;
|
|
06006 // @01d #290: FETCH(s0,sample_count) ;increment counter
|
|
18001 // @01e #291: ADD(s0,1)
|
|
2e006 // @01f #292: STORE(s0,sample_count)
|
|
2c080 // @020 #293: OUTPUT(s0,LED_port) ;count increments at 1Hz
|
|
// #294: ;
|
|
// #295: ;
|
|
// #296: ;Display the A/D Channel 0 value as hex on LCD
|
|
// #297: ;
|
|
0052c // @021 #298: LOAD(s5,44) ;Line 2 position 12
|
|
30211 // @022 #299: CALL(LCD_cursor)
|
|
06001 // @023 #300: FETCH(s0,ADC0_msb)
|
|
30199 // @024 #301: CALL(disp_hex_byte)
|
|
06000 // @025 #302: FETCH(s0,ADC0_lsb)
|
|
30199 // @026 #303: CALL(disp_hex_byte)
|
|
// #304: ;
|
|
// #305: ;
|
|
// #306: ;
|
|
// #307: ;Convert A/D channel 0 value to decimal voltage
|
|
// #308: ;
|
|
// #309: ;The 14-bit signed value from the A/D (sign extended to 16-bits)
|
|
// #310: ;relates to a voltage in the range -1.25v to +1.25v at the input
|
|
// #311: ;to the A/D converter relative to the 1.65v mid-rail reference point.
|
|
// #312: ;
|
|
// #313: ;The 14-bit value can be translated into the -1.25v to +1.25v using the
|
|
// #314: ;simple equation...
|
|
// #315: ;
|
|
// #316: ; ADin = AD_value x 1.25/8192
|
|
// #317: ;
|
|
// #318: ;It is possible to scale the AD_value by 1.25/8192 using a fixed point
|
|
// #319: ;representation.
|
|
// #320: ;
|
|
// #321: ;However, it is also possible to scale it by another factor at the
|
|
// #322: ;same time which nicely converts to a binary value which is readily
|
|
// #323: ;converted to decimal. This can be achieved by example...
|
|
// #324: ;
|
|
// #325: ;For an input to the A/D converter of +1.25v relative to the reference,
|
|
// #326: ;the A/D will output the maximum conversion of 1FFF (+8191).
|
|
// #327: ;
|
|
// #328: ;In this case we would like to have the result value +1.250v which can be represented
|
|
// #329: ;by the integer value +1250 with appropiate positioning of the decimal point.
|
|
// #330: ;The constant to achieve this conversion is +1250/8191=+0.152606...
|
|
// #331: ;Also a number requiring fixed point representation but how many bits to use?
|
|
// #332: ;
|
|
// #333: ;The way to resolve this is to realise that a multiplication will be
|
|
// #334: ;performed and it would be nice if the +1250 result ended up in a register pair.
|
|
// #335: ;So if we perform a 16x16-bit multiplication such that the upper 16-bits of
|
|
// #336: ;the 32-bit result is the required value, then everything will resolve itself.
|
|
// #337: ;
|
|
// #338: ;Hence the constant required is actually (1250x(2^16))/8191=+10001 (2711 hex).
|
|
// #339: ;
|
|
// #340: ;Using the example 1FFF x 2711 = 04E1F8EF
|
|
// #341: ; of which the upper 16-bits = 04E1 (+1249 decimal)
|
|
// #342: ;
|
|
// #343: ;Likewise the other limit case is E000 x 2711 = FB1DE000
|
|
// #344: ; of which the upper 16-bits = FB1D (-1251 decimal)
|
|
// #345: ;
|
|
// #346: ;The values can be made perfect by rounding before truncation
|
|
// #347: ;
|
|
06200 // @027 #348: FETCH(s2,ADC0_lsb) ;Read A/D channel 0 value
|
|
06301 // @028 #349: FETCH(s3,ADC0_msb)
|
|
00011 // @029 #350: LOAD(s0,17) ;scaling value for input to A/D converter
|
|
00127 // @02a #351: LOAD(s1,39)
|
|
300e4 // @02b #352: CALL(mult_16x16s) ;[s7,s6,s5,s4]=[s3,s2]x[s1,s0]
|
|
20506 // @02c #353: SL0(s5) ;round value before truncation
|
|
1a600 // @02d #354: ADDCY(s6,0)
|
|
1a700 // @02e #355: ADDCY(s7,0)
|
|
// #356: ;
|
|
// #357: ;The register pair [s7,s6] now holds the binary value
|
|
// #358: ;representing the input level to the A/D converter in milli-volts.
|
|
// #359: ;This is now displayed on the LCD. Negative values need to be converted to
|
|
// #360: ;signed magnitude for display.
|
|
// #361: ;
|
|
00520 // @02f #362: LOAD(s5,32) ;Line 2 position 0
|
|
30211 // @030 #363: CALL(LCD_cursor)
|
|
3017f // @031 #364: CALL(disp_AD) ;display A/D=
|
|
12780 // @032 #365: TEST(s7,128) ;test sign bit of value
|
|
35436 // @033 #366: JUMP(NZ,neg_AD)
|
|
0052b // @034 #367: LOAD(s5,character_plus)
|
|
3403b // @035 #368: JUMP(AD_sign)
|
|
// @036 #369: [neg_AD]
|
|
0e6ff // @036 #369: XOR(s6,FF) ;complement [s7,s6] to make positive
|
|
0e7ff // @037 #370: XOR(s7,FF)
|
|
18601 // @038 #371: ADD(s6,1)
|
|
1a700 // @039 #372: ADDCY(s7,0)
|
|
0052d // @03a #373: LOAD(s5,character_minus)
|
|
// @03b #374: [AD_sign]
|
|
301d1 // @03b #374: CALL(LCD_write_data) ;display sign of value
|
|
30074 // @03c #375: CALL(disp_volts) ;display 4 digit value as X.XXXv
|
|
// #376: ;
|
|
// #377: ;Convert A/D channel 0 value to display the VINA decimal voltage
|
|
// #378: ;
|
|
// #379: ;The same fundamental technique can be used to convert the 14-bit
|
|
// #380: ;A/D value into the level at the VINA input except that two more factors
|
|
// #381: ;must be considered.
|
|
// #382: ;
|
|
// #383: ;The first is that the amplifier inverts and has gain. Therefore the
|
|
// #384: ;VINA input level is opposite polarity and could be a smaller deviation
|
|
// #385: ;from the mid rail 1.65v reference.
|
|
// #386: ;
|
|
// #387: ;Secondly, to display the actual voltage level at the VINA terminal
|
|
// #388: ;the 1.65v offset must be added.
|
|
// #389: ;
|
|
// #390: ;The voltage at the VINA input is therefore...
|
|
// #391: ;
|
|
// #392: ; VINA = [AD_value x (1.25/(8192 x G))]+1.65
|
|
// #393: ;
|
|
// #394: ;Following the same methodology as for the A/D value, it means that there
|
|
// #395: ;is a set of scaling factors to deal with the negative gain values.
|
|
// #396: ;
|
|
// #397: ; K = (+1250 x (2^16)) / (8191 x G)
|
|
// #398: ;
|
|
// #399: ; G K (K Hex)
|
|
// #400: ; -1 -10001 (D8EF)
|
|
// #401: ; -2 -5001 (EC77)
|
|
// #402: ; -5 -2000 (F830)
|
|
// #403: ; -10 -1000 (FC18)
|
|
// #404: ; -20 -500 (FE0C)
|
|
// #405: ; -50 -200 (FF38)
|
|
// #406: ; -100 -100 (FF9C)
|
|
// #407: ;
|
|
06200 // @03d #408: FETCH(s2,ADC0_lsb) ;Read A/D channel 0 value
|
|
06301 // @03e #409: FETCH(s3,ADC0_msb)
|
|
06404 // @03f #410: FETCH(s4,amp_A_gain) ;read A gain and select appropiate gain setting
|
|
000ef // @040 #411: LOAD(s0,EF) ;scaling value for amplifier gain of -1
|
|
001d8 // @041 #412: LOAD(s1,D8)
|
|
14401 // @042 #413: COMPARE(s4,1)
|
|
3505a // @043 #414: JUMP(Z,mult_VINA)
|
|
00077 // @044 #415: LOAD(s0,119) ;scaling value for amplifier gain of -2
|
|
001ec // @045 #416: LOAD(s1,EC)
|
|
14402 // @046 #417: COMPARE(s4,2)
|
|
3505a // @047 #418: JUMP(Z,mult_VINA)
|
|
00030 // @048 #419: LOAD(s0,48) ;scaling value for amplifier gain of -5
|
|
001f8 // @049 #420: LOAD(s1,F8)
|
|
14403 // @04a #421: COMPARE(s4,3)
|
|
3505a // @04b #422: JUMP(Z,mult_VINA)
|
|
00018 // @04c #423: LOAD(s0,24) ;scaling value for amplifier gain of -10
|
|
001fc // @04d #424: LOAD(s1,FC)
|
|
14405 // @04e #425: COMPARE(s4,5)
|
|
3505a // @04f #426: JUMP(Z,mult_VINA)
|
|
0000c // @050 #427: LOAD(s0,12) ;scaling value for amplifier gain of -20
|
|
001fe // @051 #428: LOAD(s1,FE)
|
|
14406 // @052 #429: COMPARE(s4,6)
|
|
3505a // @053 #430: JUMP(Z,mult_VINA)
|
|
00038 // @054 #431: LOAD(s0,56) ;scaling value for amplifier gain of -50
|
|
001ff // @055 #432: LOAD(s1,FF)
|
|
14401 // @056 #433: COMPARE(s4,1)
|
|
3505a // @057 #434: JUMP(Z,mult_VINA)
|
|
0009c // @058 #435: LOAD(s0,156) ;scaling value for amplifier gain of -100
|
|
001ff // @059 #436: LOAD(s1,FF)
|
|
// @05a #437: [mult_VINA]
|
|
300e4 // @05a #437: CALL(mult_16x16s) ;[s7,s6,s5,s4]=[s3,s2]x[s1,s0]
|
|
20506 // @05b #438: SL0(s5) ;round value before truncation
|
|
1a600 // @05c #439: ADDCY(s6,0)
|
|
1a700 // @05d #440: ADDCY(s7,0)
|
|
18672 // @05e #441: ADD(s6,VREF_lsb) ;add 1.65v offset represented at 1650 (0672 hex)
|
|
1a706 // @05f #442: ADDCY(s7,VREF_msb)
|
|
// #443: ;
|
|
// #444: ;The register pair [s7,s6] now holds the binary value
|
|
// #445: ;representing the VINA input level in milli-volts.
|
|
// #446: ;This must be a positive value due to the offset of 1.65v
|
|
// #447: ;being greater than the maximum relative range of -1.25v to +1.25v.
|
|
// #448: ;This binary value can now be converted to a decimal digits
|
|
// #449: ;and displayed on the LCD.
|
|
// #450: ;
|
|
// #451: ;If the A/D value is maximum negative (E000) or maximum positive (1FFF)
|
|
// #452: ;then an indication of the actual value being applied being greater or
|
|
// #453: ;less than that computed will be made.
|
|
// #454: ;
|
|
00517 // @060 #455: LOAD(s5,23) ;Line 1 position 7
|
|
30211 // @061 #456: CALL(LCD_cursor)
|
|
30178 // @062 #457: CALL(disp_VA) ;display VA=
|
|
06200 // @063 #458: FETCH(s2,ADC0_lsb) ;Read A/D channel 0 value
|
|
06301 // @064 #459: FETCH(s3,ADC0_msb)
|
|
143e0 // @065 #460: COMPARE(s3,E0) ;test for maximum negative
|
|
3546c // @066 #461: JUMP(NZ,test_max_pos)
|
|
14200 // @067 #462: COMPARE(s2,0)
|
|
3546c // @068 #463: JUMP(NZ,test_max_pos)
|
|
0053e // @069 #464: LOAD(s5,character_greater_than) ;display >
|
|
301d1 // @06a #465: CALL(LCD_write_data)
|
|
34072 // @06b #466: JUMP(disp_VINA_volts)
|
|
// @06c #467: [test_max_pos]
|
|
1431f // @06c #467: COMPARE(s3,31) ;test for maximum positive
|
|
35472 // @06d #468: JUMP(NZ,disp_VINA_volts)
|
|
142ff // @06e #469: COMPARE(s2,FF)
|
|
35472 // @06f #470: JUMP(NZ,disp_VINA_volts)
|
|
0053c // @070 #471: LOAD(s5,character_less_than) ;display <
|
|
301d1 // @071 #472: CALL(LCD_write_data)
|
|
// @072 #473: [disp_VINA_volts]
|
|
30074 // @072 #473: CALL(disp_volts) ;display 4 digit value as X.XXXv
|
|
34014 // @073 #474: JUMP(warm_start)
|
|
// #475: ;
|
|
// #476: ;
|
|
// #477: ;**************************************************************************************
|
|
// #478: ;Display voltage level at in the form X.XXX on the LCD at current cursor position
|
|
// #479: ;**************************************************************************************
|
|
// #480: ;
|
|
// #481: ;Value to be displayed must be unsigned (positive) in the
|
|
// #482: ;[s7,s6] register pair. Only the lower 4 digits are displayed.
|
|
// #483: ;
|
|
// @074 #484: [disp_volts]
|
|
30102 // @074 #484: CALL(integer16_to_BCD) ;convert [s7,s6] to BCD in scratch pad memory
|
|
0650a // @075 #485: FETCH(s5,decimal3)
|
|
18530 // @076 #486: ADD(s5,48) ;convert to ASCII
|
|
301d1 // @077 #487: CALL(LCD_write_data)
|
|
0052e // @078 #488: LOAD(s5,character_stop)
|
|
301d1 // @079 #489: CALL(LCD_write_data)
|
|
06509 // @07a #490: FETCH(s5,decimal2)
|
|
18530 // @07b #491: ADD(s5,48) ;convert to ASCII
|
|
301d1 // @07c #492: CALL(LCD_write_data)
|
|
06508 // @07d #493: FETCH(s5,decimal1)
|
|
18530 // @07e #494: ADD(s5,48) ;convert to ASCII
|
|
301d1 // @07f #495: CALL(LCD_write_data)
|
|
06507 // @080 #496: FETCH(s5,decimal0)
|
|
18530 // @081 #497: ADD(s5,48) ;convert to ASCII
|
|
301d1 // @082 #498: CALL(LCD_write_data)
|
|
00520 // @083 #499: LOAD(s5,character_space) ;ensure next position is cleared
|
|
301d1 // @084 #500: CALL(LCD_write_data)
|
|
2a000 // @085 #501: RETURN
|
|
// #502: ;
|
|
// #503: ;**************************************************************************************
|
|
// #504: ;Changing amplifier gain using press buttons
|
|
// #505: ;**************************************************************************************
|
|
// #506: ;
|
|
// #507: ;Possible gain values are
|
|
// #508: ; Gain Amplifier
|
|
// #509: ; code
|
|
// #510: ; -1 1
|
|
// #511: ; -2 2
|
|
// #512: ; -5 3
|
|
// #513: ; -10 4
|
|
// #514: ; -20 5
|
|
// #515: ; -50 6
|
|
// #516: ; -100 7
|
|
// #517: ;
|
|
// @086 #518: [gain_increase]
|
|
3c000 // @086 #518: DISABLE(INTERRUPT) ;stop normal operation
|
|
06004 // @087 #519: FETCH(s0,amp_A_gain) ;read current gain
|
|
18001 // @088 #520: ADD(s0,1)
|
|
14008 // @089 #521: COMPARE(s0,8) ;test for too big
|
|
35492 // @08a #522: JUMP(NZ,new_gain_set)
|
|
00007 // @08b #523: LOAD(s0,7) ;maximum gain
|
|
34092 // @08c #524: JUMP(new_gain_set)
|
|
// @08d #525: [gain_decrease]
|
|
3c000 // @08d #525: DISABLE(INTERRUPT) ;stop normal operation
|
|
06004 // @08e #526: FETCH(s0,amp_A_gain) ;read current gain
|
|
1c001 // @08f #527: SUB(s0,1)
|
|
35492 // @090 #528: JUMP(NZ,new_gain_set)
|
|
00001 // @091 #529: LOAD(s0,1) ;minimum gain
|
|
// @092 #530: [new_gain_set]
|
|
2e004 // @092 #530: STORE(s0,amp_A_gain) ;store new value
|
|
06205 // @093 #531: FETCH(s2,amp_B_gain) ;form the amplifier control byte
|
|
20206 // @094 #532: SL0(s2) ;B amplifier set by upper 4 bits
|
|
20206 // @095 #533: SL0(s2)
|
|
20206 // @096 #534: SL0(s2)
|
|
20206 // @097 #535: SL0(s2)
|
|
0d200 // @098 #536: OR(s2,s0) ;A amplifier set by lower
|
|
30122 // @099 #537: CALL(set_amp) ;set SPI amplifier
|
|
// #538: ;display gain setting on LCD
|
|
00510 // @09a #539: LOAD(s5,16) ;Line 1 position 0
|
|
30211 // @09b #540: CALL(LCD_cursor)
|
|
00547 // @09c #541: LOAD(s5,character_G)
|
|
301d1 // @09d #542: CALL(LCD_write_data)
|
|
0053d // @09e #543: LOAD(s5,character_equals)
|
|
301d1 // @09f #544: CALL(LCD_write_data)
|
|
0052d // @0a0 #545: LOAD(s5,character_minus)
|
|
301d1 // @0a1 #546: CALL(LCD_write_data)
|
|
06004 // @0a2 #547: FETCH(s0,amp_A_gain) ;read A gain setting
|
|
14001 // @0a3 #548: COMPARE(s0,1) ;determine actual gain value
|
|
354ac // @0a4 #549: JUMP(NZ,test_A2)
|
|
00531 // @0a5 #550: LOAD(s5,character_1) ;gain is -1
|
|
301d1 // @0a6 #551: CALL(LCD_write_data)
|
|
00520 // @0a7 #552: LOAD(s5,character_space)
|
|
301d1 // @0a8 #553: CALL(LCD_write_data)
|
|
00520 // @0a9 #554: LOAD(s5,character_space)
|
|
301d1 // @0aa #555: CALL(LCD_write_data)
|
|
340df // @0ab #556: JUMP(wait_no_press)
|
|
// @0ac #557: [test_A2]
|
|
14002 // @0ac #557: COMPARE(s0,2)
|
|
354b5 // @0ad #558: JUMP(NZ,test_A3)
|
|
00532 // @0ae #559: LOAD(s5,character_2) ;gain is -2
|
|
301d1 // @0af #560: CALL(LCD_write_data)
|
|
00520 // @0b0 #561: LOAD(s5,character_space)
|
|
301d1 // @0b1 #562: CALL(LCD_write_data)
|
|
00520 // @0b2 #563: LOAD(s5,character_space)
|
|
301d1 // @0b3 #564: CALL(LCD_write_data)
|
|
340df // @0b4 #565: JUMP(wait_no_press)
|
|
// @0b5 #566: [test_A3]
|
|
14003 // @0b5 #566: COMPARE(s0,3)
|
|
354be // @0b6 #567: JUMP(NZ,test_A4)
|
|
00535 // @0b7 #568: LOAD(s5,character_5) ;gain is -5
|
|
301d1 // @0b8 #569: CALL(LCD_write_data)
|
|
00520 // @0b9 #570: LOAD(s5,character_space)
|
|
301d1 // @0ba #571: CALL(LCD_write_data)
|
|
00520 // @0bb #572: LOAD(s5,character_space)
|
|
301d1 // @0bc #573: CALL(LCD_write_data)
|
|
340df // @0bd #574: JUMP(wait_no_press)
|
|
// @0be #575: [test_A4]
|
|
14004 // @0be #575: COMPARE(s0,4)
|
|
354c7 // @0bf #576: JUMP(NZ,test_A5)
|
|
00531 // @0c0 #577: LOAD(s5,character_1) ;gain is -10
|
|
301d1 // @0c1 #578: CALL(LCD_write_data)
|
|
00530 // @0c2 #579: LOAD(s5,character_0)
|
|
301d1 // @0c3 #580: CALL(LCD_write_data)
|
|
00520 // @0c4 #581: LOAD(s5,character_space)
|
|
301d1 // @0c5 #582: CALL(LCD_write_data)
|
|
340df // @0c6 #583: JUMP(wait_no_press)
|
|
// @0c7 #584: [test_A5]
|
|
14005 // @0c7 #584: COMPARE(s0,5)
|
|
354d0 // @0c8 #585: JUMP(NZ,test_A6)
|
|
00532 // @0c9 #586: LOAD(s5,character_2) ;gain is -20
|
|
301d1 // @0ca #587: CALL(LCD_write_data)
|
|
00530 // @0cb #588: LOAD(s5,character_0)
|
|
301d1 // @0cc #589: CALL(LCD_write_data)
|
|
00520 // @0cd #590: LOAD(s5,character_space)
|
|
301d1 // @0ce #591: CALL(LCD_write_data)
|
|
340df // @0cf #592: JUMP(wait_no_press)
|
|
// @0d0 #593: [test_A6]
|
|
14006 // @0d0 #593: COMPARE(s0,6)
|
|
354d9 // @0d1 #594: JUMP(NZ,gain_A7)
|
|
00535 // @0d2 #595: LOAD(s5,character_5) ;gain is -50
|
|
301d1 // @0d3 #596: CALL(LCD_write_data)
|
|
00530 // @0d4 #597: LOAD(s5,character_0)
|
|
301d1 // @0d5 #598: CALL(LCD_write_data)
|
|
00520 // @0d6 #599: LOAD(s5,character_space)
|
|
301d1 // @0d7 #600: CALL(LCD_write_data)
|
|
340df // @0d8 #601: JUMP(wait_no_press)
|
|
// @0d9 #602: [gain_A7]
|
|
00531 // @0d9 #602: LOAD(s5,character_1) ;gain is -100
|
|
301d1 // @0da #603: CALL(LCD_write_data)
|
|
00530 // @0db #604: LOAD(s5,character_0)
|
|
301d1 // @0dc #605: CALL(LCD_write_data)
|
|
00530 // @0dd #606: LOAD(s5,character_0)
|
|
301d1 // @0de #607: CALL(LCD_write_data)
|
|
// @0df #608: [wait_no_press]
|
|
301ae // @0df #608: CALL(delay_20ms) ;delay to help avoid switch bounce
|
|
04000 // @0e0 #609: INPUT(s0,switch_port) ;check for release of press buttons
|
|
12005 // @0e1 #610: TEST(s0,5) ;north and south buttons
|
|
354df // @0e2 #611: JUMP(NZ,wait_no_press)
|
|
34014 // @0e3 #612: JUMP(warm_start)
|
|
// #613: ;
|
|
// #614: ;**************************************************************************************
|
|
// #615: ;16-bit by 16-bit Signed multiplier
|
|
// #616: ;**************************************************************************************
|
|
// #617: ;
|
|
// #618: ;16 bit signed multiplication using shift and add technique.
|
|
// #619: ;The full precision 32-bit product is returned.
|
|
// #620: ;
|
|
// #621: ;The key to signed multiplication is to think of all bits of the second operand
|
|
// #622: ;[s1,s0] as being positive except for the most significant bit. This means that
|
|
// #623: ;the first operand is added to the result in all cases when there is a '1' in the
|
|
// #624: ;second operand except for the MSB case when the first operand is subtracted if there
|
|
// #625: ;is a '1'.
|
|
// #626: ;
|
|
// #627: ;[s7,s6,s5,s4]=[s3,s2]x[s1,s0]
|
|
// #628: ;
|
|
// #629: ;Registers used s0,s1,s2,s3,s4,s5,s6,s7,s8,s9,sA
|
|
// #630: ;
|
|
// @0e4 #631: [mult_16x16s]
|
|
00700 // @0e4 #631: LOAD(s7,0) ;clear accumulator
|
|
00600 // @0e5 #632: LOAD(s6,0)
|
|
00500 // @0e6 #633: LOAD(s5,0) ;Set bit 14 to act as a bit shift counter
|
|
00400 // @0e7 #634: LOAD(s4,0)
|
|
00800 // @0e8 #635: LOAD(s8,0) ;sign extend [s3,s2] to form [s9,s8,s3,s2]
|
|
12380 // @0e9 #636: TEST(s3,128) ;test sign of first operand
|
|
350ec // @0ea #637: JUMP(Z,m16s_pos)
|
|
008ff // @0eb #638: LOAD(s8,FF)
|
|
// @0ec #639: [m16s_pos]
|
|
01980 // @0ec #639: LOAD(s9,s8) ;[s9,s8,s3,s2]=0000xxxx or FFFFxxxx as required
|
|
00a0f // @0ed #640: LOAD(sA,15) ;15 positive shift and add operations to perform
|
|
// @0ee #641: [m16s_loop]
|
|
2010e // @0ee #641: SR0(s1) ;shift right operand [s1,s0]
|
|
20008 // @0ef #642: SRA(s0)
|
|
35cf5 // @0f0 #643: JUMP(NC,m16s_noadd) ;test for a '1'
|
|
19420 // @0f1 #644: ADD(s4,s2) ;32-bit addition [s7,s6,s5,s4]=[s7,s6,s5,s4]+[s9,s8,s3,s2]
|
|
1b530 // @0f2 #645: ADDCY(s5,s3)
|
|
1b680 // @0f3 #646: ADDCY(s6,s8)
|
|
1b790 // @0f4 #647: ADDCY(s7,s9)
|
|
// @0f5 #648: [m16s_noadd]
|
|
20206 // @0f5 #648: SL0(s2) ;multiply first operand by 2
|
|
20300 // @0f6 #649: SLA(s3)
|
|
20800 // @0f7 #650: SLA(s8)
|
|
20900 // @0f8 #651: SLA(s9)
|
|
1ca01 // @0f9 #652: SUB(sA,1)
|
|
354ee // @0fa #653: JUMP(NZ,m16s_loop) ;move to next unsigned bit
|
|
12001 // @0fb #654: TEST(s0,1) ;test sign bit of operand [s1,s0]
|
|
35d01 // @0fc #655: JUMP(NC,m16s_nosub)
|
|
1d420 // @0fd #656: SUB(s4,s2) ;32-bit subtraction [s7,s6,s5,s4]=[s7,s6,s5,s4]-[s9,s8,s3,s2]
|
|
1f530 // @0fe #657: SUBCY(s5,s3)
|
|
1f680 // @0ff #658: SUBCY(s6,s8)
|
|
1f790 // @100 #659: SUBCY(s7,s9)
|
|
// @101 #660: [m16s_nosub]
|
|
2a000 // @101 #660: RETURN
|
|
// #661: ;
|
|
// #662: ;
|
|
// #663: ;
|
|
// #664: ;**************************************************************************************
|
|
// #665: ;16-bit positive integer to 5 digit decimal conversion
|
|
// #666: ;**************************************************************************************
|
|
// #667: ;
|
|
// #668: ;Convert the 16 bit value in register set [s7,s6]
|
|
// #669: ;into the BCD decimal equivalent located in the scratch pad memory
|
|
// #670: ;locations 'decimal0' to 'decimal4' which must be in ascending locations.
|
|
// #671: ;
|
|
// #672: ;Register set [s9,s8,s7,s6] are preserved.
|
|
// #673: ;
|
|
// #674: ;
|
|
// #675: ;Each digit is formed in turn starting with the least significant.
|
|
// #676: ;
|
|
// #677: ;Registers used s0,s1,s2,s3,s4,s5,s6,s7,s8
|
|
// #678: ;
|
|
// @102 #679: [integer16_to_BCD]
|
|
00005 // @102 #679: LOAD(s0,5) ;5 digits to be formed from value up to 65535
|
|
00807 // @103 #680: LOAD(s8,decimal0) ;pointer for LS-Digit
|
|
// @104 #681: [int_to_BCD_loop]
|
|
3010a // @104 #681: CALL(divide_16bit_by_10) ;[s7,s6]=[s7,s6]/10 with remainder in s4
|
|
2f480 // @105 #682: STORE(s4,s8) ;remainder becomes digit value
|
|
18801 // @106 #683: ADD(s8,1) ;move to next most significant digit
|
|
1c001 // @107 #684: SUB(s0,1) ;one less digit to compute
|
|
35504 // @108 #685: JUMP(NZ,int_to_BCD_loop)
|
|
2a000 // @109 #686: RETURN
|
|
// #687: ;
|
|
// #688: ;Divide 16-bit binary integer by 10
|
|
// #689: ;
|
|
// #690: ;The value to be divided is held in register set [s7,s6]
|
|
// #691: ;and this is where the result is returned to.
|
|
// #692: ;
|
|
// #693: ;At then end of the integer division the remainder in the range 0 to 9
|
|
// #694: ;will be in register s4.
|
|
// #695: ;
|
|
// #696: ;Registers used s1,s2,s3,s4,s5,s6,s7
|
|
// #697: ;Other registers are used but are preserved
|
|
// #698: ;
|
|
// @10a #699: [divide_16bit_by_10]
|
|
01460 // @10a #699: LOAD(s4,s6) ;copy input value to [s5,s4]
|
|
01570 // @10b #700: LOAD(s5,s7)
|
|
00600 // @10c #701: LOAD(s6,0) ;clear result
|
|
00700 // @10d #702: LOAD(s7,0)
|
|
00200 // @10e #703: LOAD(s2,0) ;initialise '10' value into msb's of set [s3,s2]
|
|
003a0 // @10f #704: LOAD(s3,A0)
|
|
0010d // @110 #705: LOAD(s1,13) ;13 subtract and shift iterations to be performed
|
|
// @111 #706: [div10_loop]
|
|
1d420 // @111 #706: SUB(s4,s2) ;perform 16-bit subtract [s5,s4]-[s3,s2]
|
|
1f530 // @112 #707: SUBCY(s5,s3)
|
|
35916 // @113 #708: JUMP(C,div10_restore)
|
|
20607 // @114 #709: SL1(s6) ;shift '1' into result because subtract was possible
|
|
34119 // @115 #710: JUMP(div10_shifts)
|
|
// @116 #711: [div10_restore]
|
|
19420 // @116 #711: ADD(s4,s2) ;perform 32-bit addition [s5,s4]+[s3,s2]
|
|
1b530 // @117 #712: ADDCY(s5,s3) ;to restore value
|
|
20606 // @118 #713: SL0(s6) ;shift '0' into result because subtract was not possible
|
|
// @119 #714: [div10_shifts]
|
|
20700 // @119 #714: SLA(s7) ;complete 16-bit shift left
|
|
2030e // @11a #715: SR0(s3) ;divide '10' value by 2 (shift right 1 place)
|
|
20208 // @11b #716: SRA(s2)
|
|
1c101 // @11c #717: SUB(s1,1) ;count iterations
|
|
35511 // @11d #718: JUMP(NZ,div10_loop)
|
|
2a000 // @11e #719: RETURN
|
|
// #720: ;
|
|
// #721: ;
|
|
// #722: ;**************************************************************************************
|
|
// #723: ;SPI communication routines for Spartan-3E Starter Kit
|
|
// #724: ;**************************************************************************************
|
|
// #725: ;
|
|
// #726: ;These routines will work with two output ports and one input port which should be
|
|
// #727: ;defined as follows using CONSTANT directives.
|
|
// #728: ; (replace 'pp' with appropriate port address in each case)
|
|
// #729: ;In the list of CONSTANT directives, there are ports associated with all the SPI devices
|
|
// #730: ;provided on the board. Even if some devices are not used, it is vital that the remaining
|
|
// #731: ;devices are disabled. Leaving all signals connected and use of these routines will ensure
|
|
// #732: ;that all other devices are disabled when communicating with a particular device.
|
|
// #733: ;
|
|
// #734: ;
|
|
// #735: ;
|
|
// #736: ;CONSTANT SPI_control_port, pp ;SPI clock and chip selects
|
|
// #737: ;CONSTANT SPI_sck, 01 ; SCK - bit0
|
|
// #738: ;CONSTANT SPI_rom_cs, 02 ; serial rom select - bit1
|
|
// #739: ;CONSTANT SPI_spare_control, 04 ; spare - bit2
|
|
// #740: ;CONSTANT SPI_amp_cs, 08 ; amplifier select - bit3
|
|
// #741: ;CONSTANT SPI_adc_conv, 10 ; A/D convert - bit4
|
|
// #742: ;CONSTANT SPI_dac_cs, 20 ; D/A select - bit5
|
|
// #743: ;CONSTANT SPI_amp_shdn, 40 ; amplifier SHDN - bit6
|
|
// #744: ;CONSTANT SPI_dac_clr, 80 ; D/A clear - bit7
|
|
// #745: ;
|
|
// #746: ;CONSTANT SPI_output_port, pp ;SPI data output
|
|
// #747: ;CONSTANT SPI_sdo, 80 ; SDO - bit7
|
|
// #748: ;
|
|
// #749: ;CONSTANT SPI_input_port, pp ;SPI data input
|
|
// #750: ;CONSTANT SPI_sdi, 80 ; SDI - bit7
|
|
// #751: ;CONSTANT SPI_amp_sdi, 40 ; amplifier SDI - bit6
|
|
// #752: ;
|
|
// #753: ;
|
|
// #754: ;
|
|
// #755: ;
|
|
// #756: ;Initialise SPI bus
|
|
// #757: ;
|
|
// #758: ;This routine should be used to initialise the SPI bus.
|
|
// #759: ;The SCK clock is made low.
|
|
// #760: ;Device selections are made inactive as follows
|
|
// #761: ; SPI_sck = 0 Clock is Low (required)
|
|
// #762: ; SPI_rom_cs = 1 Deselect ROM
|
|
// #763: ; spare = 1 spare control bit
|
|
// #764: ; SPI_amp_cs = 1 Deselect amplifier
|
|
// #765: ; SPI_adc_conv = 0 A/D convert ready to apply positive pulse
|
|
// #766: ; SPI_dac_cs = 1 Deselect D/A
|
|
// #767: ; SPI_amp_shdn = 0 Amplifier active and available
|
|
// #768: ; SPI_dac_clr = 1 D/A clear off
|
|
// #769: ;
|
|
// @11f #770: [SPI_init]
|
|
000ae // @11f #770: LOAD(s0,AE) ;normally AE
|
|
2c008 // @120 #771: OUTPUT(s0,SPI_control_port)
|
|
2a000 // @121 #772: RETURN
|
|
// #773: ;
|
|
// #774: ;
|
|
// #775: ;
|
|
// #776: ;
|
|
// #777: ;**************************************************************************************
|
|
// #778: ;SPI communication routines for Programmable Amplifier
|
|
// #779: ;**************************************************************************************
|
|
// #780: ;
|
|
// #781: ;
|
|
// #782: ;Set the A and B channel gain of the Dual Amplifier (LTC6912-1).
|
|
// #783: ;
|
|
// #784: ;The gain value should be provided in the s2 register with the upper nibble
|
|
// #785: ;defining the gain for the B channel and lower nibble the gain for the A channel.
|
|
// #786: ; 0000 = 0 hex = Gain 0 with input hi-Z and output driving
|
|
// #787: ; 0001 = 1 hex = Gain -1
|
|
// #788: ; 0010 = 2 hex = Gain -2
|
|
// #789: ; 0011 = 3 hex = Gain -5
|
|
// #790: ; 0100 = 4 hex = Gain -10
|
|
// #791: ; 0101 = 5 hex = Gain -20
|
|
// #792: ; 0110 = 6 hex = Gain -50
|
|
// #793: ; 0111 = 7 hex = Gain -100
|
|
// #794: ; 1000 = 8 hex = software shutdown (power on default). Hi-Z output.
|
|
// #795: ;
|
|
// #796: ;On return, the s2, register will contain the response from the LTC6912-1 amplifier.
|
|
// #797: ;This will be the same format and indicate the previous setting of the amplifier.
|
|
// #798: ;The response is obtained from the dedicated AMP_SDI signal since the LTC6912 output
|
|
// #799: ;is always active and can not be on a shared SPI bus.
|
|
// #800: ;
|
|
// @122 #801: [set_amp]
|
|
3011f // @122 #801: CALL(SPI_init) ;ensure known state of bus and s0 register
|
|
0e008 // @123 #802: XOR(s0,SPI_amp_cs) ;select low on Amplifier chip select
|
|
2c008 // @124 #803: OUTPUT(s0,SPI_control_port)
|
|
00108 // @125 #804: LOAD(s1,8) ;8-bits to transmit and receive
|
|
// @126 #805: [next_amp_SPI_bit]
|
|
2c204 // @126 #805: OUTPUT(s2,SPI_output_port) ;output data bit
|
|
0e001 // @127 #806: XOR(s0,SPI_sck) ;clock High (bit0)
|
|
2c008 // @128 #807: OUTPUT(s0,SPI_control_port) ;drive clock High
|
|
04301 // @129 #808: INPUT(s3,SPI_input_port) ;read input bit
|
|
12340 // @12a #809: TEST(s3,SPI_amp_sdi) ;detect state of received bit
|
|
20200 // @12b #810: SLA(s2) ;shift new data into result and move to next transmit bit
|
|
0e001 // @12c #811: XOR(s0,SPI_sck) ;clock Low (bit0)
|
|
2c008 // @12d #812: OUTPUT(s0,SPI_control_port) ;drive clock Low
|
|
1c101 // @12e #813: SUB(s1,1) ;count bits
|
|
35526 // @12f #814: JUMP(NZ,next_amp_SPI_bit) ;repeat until finished
|
|
0e008 // @130 #815: XOR(s0,SPI_amp_cs) ;deselect the amplifier
|
|
2c008 // @131 #816: OUTPUT(s0,SPI_control_port)
|
|
2a000 // @132 #817: RETURN
|
|
// #818: ;
|
|
// #819: ;
|
|
// #820: ;
|
|
// #821: ;**************************************************************************************
|
|
// #822: ;SPI communication routines for A/D Converter
|
|
// #823: ;**************************************************************************************
|
|
// #824: ;
|
|
// #825: ;
|
|
// #826: ;
|
|
// #827: ;Sample A/D converter (LTC1407A-1) and return results.
|
|
// #828: ;
|
|
// #829: ;Note there is a latency of one read to obtain the value. Each read results in the
|
|
// #830: ;the analogue inputs being sampled and converted but this value will only be transmitted
|
|
// #831: ;during the next read and conversion cycle.
|
|
// #832: ;
|
|
// #833: ;The results are returned as follows.
|
|
// #834: ; Channel 0 in registers [s9,s8]
|
|
// #835: ; Channel 1 in registers [s7,s6]
|
|
// #836: ;Where each is a 14-bit twos complement value sign extended to 16-bits.
|
|
// #837: ;
|
|
// #838: ;Each 14-bit value represents the analogue voltage in the range -1.25v to +1.25v
|
|
// #839: ;relative to the reference voltage of 1.65v (3.3v/2). Hence the actual input voltage
|
|
// #840: ;range is 0.4v to 2.9v. Since the input to the A/D is supplied via the programmable
|
|
// #841: ;amplifier, the VINA and VINB inputs are inverted and may cover a smaller range if ;
|
|
// #842: ;desired.
|
|
// #843: ;
|
|
// #844: ;Examples
|
|
// #845: ; VINA = 0.65v with gain=-1 means input to A/D = 2.65v
|
|
// #846: ; This is equivalent to +1.00v which is value (8192/1.25)*1 = 6553 (1999 hex)
|
|
// #847: ;
|
|
// #848: ; VINA = 2.65v with gain=-1 means input to A/D = 0.65v
|
|
// #849: ; This is equivalent to -1.00v which is value (2048/1.25)*-1 = -6553 (E667 hex)
|
|
// #850: ;
|
|
// #851: ;
|
|
// #852: ;Although the A/D converter claims to be an SPI device, it really
|
|
// #853: ;does not conform to the normal specification of the 4-wire interface.
|
|
// #854: ;
|
|
// #855: ;Firstly the CONV signal is only pulsed High and does not behave like
|
|
// #856: ;a normal active low select signal. Secondly, the communication is
|
|
// #857: ;34 bits which does not fit a byte boundary, and thirdly, the data output
|
|
// #858: ;to its SDO pin changes as a result of rising edges of SCK clock which
|
|
// #859: ;is not the same as the falling edge used by other devices.
|
|
// #860: ;
|
|
// @133 #861: [adc_read]
|
|
3011f // @133 #861: CALL(SPI_init) ;ensure known state of bus and s0 register
|
|
0e010 // @134 #862: XOR(s0,SPI_adc_conv) ;Pulse AD-CONV High to take sample and start
|
|
2c008 // @135 #863: OUTPUT(s0,SPI_control_port) ; conversion and transmission of data.
|
|
0e010 // @136 #864: XOR(s0,SPI_adc_conv) ;AD-CONV Low
|
|
2c008 // @137 #865: OUTPUT(s0,SPI_control_port)
|
|
00122 // @138 #866: LOAD(s1,34) ;34 clocks to read all data
|
|
// @139 #867: [next_adc_bit]
|
|
0e001 // @139 #867: XOR(s0,SPI_sck) ;clock High (bit0)
|
|
2c008 // @13a #868: OUTPUT(s0,SPI_control_port) ;drive clock High
|
|
0e001 // @13b #869: XOR(s0,SPI_sck) ;clock Low (bit0)
|
|
2c008 // @13c #870: OUTPUT(s0,SPI_control_port) ;drive clock Low
|
|
04301 // @13d #871: INPUT(s3,SPI_input_port) ;read input bit
|
|
12380 // @13e #872: TEST(s3,SPI_sdi) ;detect state of received bit
|
|
20600 // @13f #873: SLA(s6) ;shift new data into result registers
|
|
20700 // @140 #874: SLA(s7)
|
|
20800 // @141 #875: SLA(s8)
|
|
20900 // @142 #876: SLA(s9)
|
|
1c101 // @143 #877: SUB(s1,1) ;count bits
|
|
35539 // @144 #878: JUMP(NZ,next_adc_bit) ;repeat until finished
|
|
2090a // @145 #879: SRX(s9) ;sign extend 14-bit result in [s9,s8]
|
|
20808 // @146 #880: SRA(s8)
|
|
2090a // @147 #881: SRX(s9)
|
|
20808 // @148 #882: SRA(s8)
|
|
2070a // @149 #883: SRX(s7) ;sign extend 14-bit result in [s7,s6]
|
|
20608 // @14a #884: SRA(s6)
|
|
2070a // @14b #885: SRX(s7)
|
|
20608 // @14c #886: SRA(s6)
|
|
2a000 // @14d #887: RETURN
|
|
// #888: ;
|
|
// #889: ;
|
|
// #890: ;**************************************************************************************
|
|
// #891: ;LCD text messages
|
|
// #892: ;**************************************************************************************
|
|
// #893: ;
|
|
// #894: ;
|
|
// #895: ;Display 'PicoBlaze' on LCD at current cursor position
|
|
// #896: ;
|
|
// #897: ;
|
|
// @14e #898: [disp_PicoBlaze]
|
|
00550 // @14e #898: LOAD(s5,character_P)
|
|
301d1 // @14f #899: CALL(LCD_write_data)
|
|
00569 // @150 #900: LOAD(s5,character_i)
|
|
301d1 // @151 #901: CALL(LCD_write_data)
|
|
00563 // @152 #902: LOAD(s5,character_c)
|
|
301d1 // @153 #903: CALL(LCD_write_data)
|
|
0056f // @154 #904: LOAD(s5,character_o)
|
|
301d1 // @155 #905: CALL(LCD_write_data)
|
|
00542 // @156 #906: LOAD(s5,character_B)
|
|
301d1 // @157 #907: CALL(LCD_write_data)
|
|
0056c // @158 #908: LOAD(s5,character_l)
|
|
301d1 // @159 #909: CALL(LCD_write_data)
|
|
00561 // @15a #910: LOAD(s5,character_a)
|
|
301d1 // @15b #911: CALL(LCD_write_data)
|
|
0057a // @15c #912: LOAD(s5,character_z)
|
|
301d1 // @15d #913: CALL(LCD_write_data)
|
|
00565 // @15e #914: LOAD(s5,character_e)
|
|
301d1 // @15f #915: CALL(LCD_write_data)
|
|
2a000 // @160 #916: RETURN
|
|
// #917: ;
|
|
// #918: ;
|
|
// #919: ;Display 'ADC Control' on LCD at current cursor position
|
|
// #920: ;
|
|
// #921: ;
|
|
// @161 #922: [disp_ADC_Control]
|
|
00541 // @161 #922: LOAD(s5,character_A)
|
|
301d1 // @162 #923: CALL(LCD_write_data)
|
|
00544 // @163 #924: LOAD(s5,character_D)
|
|
301d1 // @164 #925: CALL(LCD_write_data)
|
|
00543 // @165 #926: LOAD(s5,character_C)
|
|
301d1 // @166 #927: CALL(LCD_write_data)
|
|
00520 // @167 #928: LOAD(s5,character_space)
|
|
301d1 // @168 #929: CALL(LCD_write_data)
|
|
00543 // @169 #930: LOAD(s5,character_C)
|
|
301d1 // @16a #931: CALL(LCD_write_data)
|
|
0056f // @16b #932: LOAD(s5,character_o)
|
|
301d1 // @16c #933: CALL(LCD_write_data)
|
|
0056e // @16d #934: LOAD(s5,character_n)
|
|
301d1 // @16e #935: CALL(LCD_write_data)
|
|
00574 // @16f #936: LOAD(s5,character_t)
|
|
301d1 // @170 #937: CALL(LCD_write_data)
|
|
00572 // @171 #938: LOAD(s5,character_r)
|
|
301d1 // @172 #939: CALL(LCD_write_data)
|
|
0056f // @173 #940: LOAD(s5,character_o)
|
|
301d1 // @174 #941: CALL(LCD_write_data)
|
|
0056c // @175 #942: LOAD(s5,character_l)
|
|
301d1 // @176 #943: CALL(LCD_write_data)
|
|
2a000 // @177 #944: RETURN
|
|
// #945: ;
|
|
// #946: ;
|
|
// #947: ;Display 'VA=' on LCD at current cursor position
|
|
// #948: ;
|
|
// #949: ;
|
|
// @178 #950: [disp_VA]
|
|
00556 // @178 #950: LOAD(s5,character_V)
|
|
301d1 // @179 #951: CALL(LCD_write_data)
|
|
00541 // @17a #952: LOAD(s5,character_A)
|
|
301d1 // @17b #953: CALL(LCD_write_data)
|
|
0053d // @17c #954: LOAD(s5,character_equals)
|
|
301d1 // @17d #955: CALL(LCD_write_data)
|
|
2a000 // @17e #956: RETURN
|
|
// #957: ;
|
|
// #958: ;
|
|
// #959: ;Display 'A/D' on LCD at current cursor position
|
|
// #960: ;
|
|
// #961: ;
|
|
// @17f #962: [disp_AD]
|
|
00541 // @17f #962: LOAD(s5,character_A)
|
|
301d1 // @180 #963: CALL(LCD_write_data)
|
|
0052f // @181 #964: LOAD(s5,character_divide)
|
|
301d1 // @182 #965: CALL(LCD_write_data)
|
|
00544 // @183 #966: LOAD(s5,character_D)
|
|
301d1 // @184 #967: CALL(LCD_write_data)
|
|
0053d // @185 #968: LOAD(s5,character_equals)
|
|
301d1 // @186 #969: CALL(LCD_write_data)
|
|
2a000 // @187 #970: RETURN
|
|
// #971: ;
|
|
// #972: ;
|
|
// #973: ;
|
|
// #974: ;**************************************************************************************
|
|
// #975: ;Value to ASCII Conversions and LCD display
|
|
// #976: ;**************************************************************************************
|
|
// #977: ;
|
|
// #978: ;Convert hexadecimal value provided in register s0 into ASCII characters
|
|
// #979: ;
|
|
// #980: ;The value provided must can be any value in the range 00 to FF and will be converted into
|
|
// #981: ;two ASCII characters.
|
|
// #982: ; The upper nibble will be represented by an ASCII character returned in register s2.
|
|
// #983: ; The lower nibble will be represented by an ASCII character returned in register s1.
|
|
// #984: ;
|
|
// #985: ;The ASCII representations of '0' to '9' are 30 to 39 hexadecimal which is simply 30 hex
|
|
// #986: ;added to the actual decimal value. The ASCII representations of 'A' to 'F' are 41 to 46
|
|
// #987: ;hexadecimal requiring a further addition of 07 to the 30 already added.
|
|
// #988: ;
|
|
// #989: ;Registers used s0, s1 and s2.
|
|
// #990: ;
|
|
// @188 #991: [hex_byte_to_ASCII]
|
|
01100 // @188 #991: LOAD(s1,s0) ;remember value supplied
|
|
2000e // @189 #992: SR0(s0) ;isolate upper nibble
|
|
2000e // @18a #993: SR0(s0)
|
|
2000e // @18b #994: SR0(s0)
|
|
2000e // @18c #995: SR0(s0)
|
|
30194 // @18d #996: CALL(hex_to_ASCII) ;convert
|
|
01200 // @18e #997: LOAD(s2,s0) ;upper nibble value in s2
|
|
01010 // @18f #998: LOAD(s0,s1) ;restore complete value
|
|
0a00f // @190 #999: AND(s0,15) ;isolate lower nibble
|
|
30194 // @191 #1000: CALL(hex_to_ASCII) ;convert
|
|
01100 // @192 #1001: LOAD(s1,s0) ;lower nibble value in s1
|
|
2a000 // @193 #1002: RETURN
|
|
// #1003: ;
|
|
// #1004: ;Convert hexadecimal value provided in register s0 into ASCII character
|
|
// #1005: ;
|
|
// #1006: ;Register used s0
|
|
// #1007: ;
|
|
// @194 #1008: [hex_to_ASCII]
|
|
1c00a // @194 #1008: SUB(s0,10) ;test if value is in range 0 to 9
|
|
35997 // @195 #1009: JUMP(C,number_char)
|
|
18007 // @196 #1010: ADD(s0,7) ;ASCII char A to F in range 41 to 46
|
|
// @197 #1011: [number_char]
|
|
1803a // @197 #1011: ADD(s0,58) ;ASCII char 0 to 9 in range 30 to 40
|
|
2a000 // @198 #1012: RETURN
|
|
// #1013: ;
|
|
// #1014: ;
|
|
// #1015: ;Display the two character HEX value of the register contents 's0' on
|
|
// #1016: ;the LCD display at the current cursor position.
|
|
// #1017: ;
|
|
// #1018: ;Registers used s0, s1, s2, s4, s5, s6
|
|
// #1019: ;
|
|
// @199 #1020: [disp_hex_byte]
|
|
30188 // @199 #1020: CALL(hex_byte_to_ASCII)
|
|
01610 // @19a #1021: LOAD(s6,s1) ;remember lower hex character
|
|
01520 // @19b #1022: LOAD(s5,s2) ;display upper hex character
|
|
301d1 // @19c #1023: CALL(LCD_write_data)
|
|
01560 // @19d #1024: LOAD(s5,s6) ;display lower hex character
|
|
301d1 // @19e #1025: CALL(LCD_write_data)
|
|
2a000 // @19f #1026: RETURN
|
|
// #1027: ;
|
|
// #1028: ;
|
|
// #1029: ;**************************************************************************************
|
|
// #1030: ;Software delay routines
|
|
// #1031: ;**************************************************************************************
|
|
// #1032: ;
|
|
// #1033: ;
|
|
// #1034: ;
|
|
// #1035: ;Delay of 1us.
|
|
// #1036: ;
|
|
// #1037: ;Constant value defines reflects the clock applied to KCPSM3. Every instruction
|
|
// #1038: ;executes in 2 clock cycles making the calculation highly predictable. The '6' in
|
|
// #1039: ;the following equation even allows for 'CALL delay_1us' instruction in the initiating code.
|
|
// #1040: ;
|
|
// #1041: ; delay_1us_constant = (clock_rate - 6)/4 Where 'clock_rate' is in MHz
|
|
// #1042: ;
|
|
// #1043: ;Registers used s0
|
|
// #1044: ;
|
|
// @1a0 #1045: [delay_1us]
|
|
0000b // @1a0 #1045: LOAD(s0,delay_1us_constant)
|
|
// @1a1 #1046: [wait_1us]
|
|
1c001 // @1a1 #1046: SUB(s0,1)
|
|
355a1 // @1a2 #1047: JUMP(NZ,wait_1us)
|
|
2a000 // @1a3 #1048: RETURN
|
|
// #1049: ;
|
|
// #1050: ;Delay of 40us.
|
|
// #1051: ;
|
|
// #1052: ;Registers used s0, s1
|
|
// #1053: ;
|
|
// @1a4 #1054: [delay_40us]
|
|
00128 // @1a4 #1054: LOAD(s1,40) ;40 x 1us = 40us
|
|
// @1a5 #1055: [wait_40us]
|
|
301a0 // @1a5 #1055: CALL(delay_1us)
|
|
1c101 // @1a6 #1056: SUB(s1,1)
|
|
355a5 // @1a7 #1057: JUMP(NZ,wait_40us)
|
|
2a000 // @1a8 #1058: RETURN
|
|
// #1059: ;
|
|
// #1060: ;
|
|
// #1061: ;Delay of 1ms.
|
|
// #1062: ;
|
|
// #1063: ;Registers used s0, s1, s2
|
|
// #1064: ;
|
|
// @1a9 #1065: [delay_1ms]
|
|
00219 // @1a9 #1065: LOAD(s2,25) ;25 x 40us = 1ms
|
|
// @1aa #1066: [wait_1ms]
|
|
301a4 // @1aa #1066: CALL(delay_40us)
|
|
1c201 // @1ab #1067: SUB(s2,1)
|
|
355aa // @1ac #1068: JUMP(NZ,wait_1ms)
|
|
2a000 // @1ad #1069: RETURN
|
|
// #1070: ;
|
|
// #1071: ;Delay of 20ms.
|
|
// #1072: ;
|
|
// #1073: ;Delay of 20ms used during initialisation.
|
|
// #1074: ;
|
|
// #1075: ;Registers used s0, s1, s2, s3
|
|
// #1076: ;
|
|
// @1ae #1077: [delay_20ms]
|
|
00314 // @1ae #1077: LOAD(s3,20) ;20 x 1ms = 20ms
|
|
// @1af #1078: [wait_20ms]
|
|
301a9 // @1af #1078: CALL(delay_1ms)
|
|
1c301 // @1b0 #1079: SUB(s3,1)
|
|
355af // @1b1 #1080: JUMP(NZ,wait_20ms)
|
|
2a000 // @1b2 #1081: RETURN
|
|
// #1082: ;
|
|
// #1083: ;Delay of approximately 1 second.
|
|
// #1084: ;
|
|
// #1085: ;Registers used s0, s1, s2, s3, s4
|
|
// #1086: ;
|
|
// @1b3 #1087: [delay_1s]
|
|
00432 // @1b3 #1087: LOAD(s4,50) ;50 x 20ms = 1000ms
|
|
// @1b4 #1088: [wait_1s]
|
|
301ae // @1b4 #1088: CALL(delay_20ms)
|
|
1c401 // @1b5 #1089: SUB(s4,1)
|
|
355b4 // @1b6 #1090: JUMP(NZ,wait_1s)
|
|
2a000 // @1b7 #1091: RETURN
|
|
// #1092: ;
|
|
// #1093: ;
|
|
// #1094: ;
|
|
// #1095: ;**************************************************************************************
|
|
// #1096: ;LCD Character Module Routines
|
|
// #1097: ;**************************************************************************************
|
|
// #1098: ;
|
|
// #1099: ;LCD module is a 16 character by 2 line display but all displays are very similar
|
|
// #1100: ;The 4-wire data interface will be used (DB4 to DB7).
|
|
// #1101: ;
|
|
// #1102: ;The LCD modules are relatively slow and software delay loops are used to slow down
|
|
// #1103: ;KCPSM3 adequately for the LCD to communicate. The delay routines are provided in
|
|
// #1104: ;a different section (see above in this case).
|
|
// #1105: ;
|
|
// #1106: ;
|
|
// #1107: ;Pulse LCD enable signal 'E' high for greater than 230ns (1us is used).
|
|
// #1108: ;
|
|
// #1109: ;Register s4 should define the current state of the LCD output port.
|
|
// #1110: ;
|
|
// #1111: ;Registers used s0, s4
|
|
// #1112: ;
|
|
// @1b8 #1113: [LCD_pulse_E]
|
|
0e401 // @1b8 #1113: XOR(s4,LCD_E) ;E=1
|
|
2c440 // @1b9 #1114: OUTPUT(s4,LCD_output_port)
|
|
301a0 // @1ba #1115: CALL(delay_1us)
|
|
0e401 // @1bb #1116: XOR(s4,LCD_E) ;E=0
|
|
2c440 // @1bc #1117: OUTPUT(s4,LCD_output_port)
|
|
2a000 // @1bd #1118: RETURN
|
|
// #1119: ;
|
|
// #1120: ;Write 4-bit instruction to LCD display.
|
|
// #1121: ;
|
|
// #1122: ;The 4-bit instruction should be provided in the upper 4-bits of register s4.
|
|
// #1123: ;Note that this routine does not release the master enable but as it is only
|
|
// #1124: ;used during initialisation and as part of the 8-bit instruction write it
|
|
// #1125: ;should be acceptable.
|
|
// #1126: ;
|
|
// #1127: ;Registers used s4
|
|
// #1128: ;
|
|
// @1be #1129: [LCD_write_inst4]
|
|
0a4f8 // @1be #1129: AND(s4,F8) ;Enable=1 RS=0 Instruction, RW=0 Write, E=0
|
|
2c440 // @1bf #1130: OUTPUT(s4,LCD_output_port) ;set up RS and RW >40ns before enable pulse
|
|
301b8 // @1c0 #1131: CALL(LCD_pulse_E)
|
|
2a000 // @1c1 #1132: RETURN
|
|
// #1133: ;
|
|
// #1134: ;
|
|
// #1135: ;Write 8-bit instruction to LCD display.
|
|
// #1136: ;
|
|
// #1137: ;The 8-bit instruction should be provided in register s5.
|
|
// #1138: ;Instructions are written using the following sequence
|
|
// #1139: ; Upper nibble
|
|
// #1140: ; wait >1us
|
|
// #1141: ; Lower nibble
|
|
// #1142: ; wait >40us
|
|
// #1143: ;
|
|
// #1144: ;Registers used s0, s1, s4, s5
|
|
// #1145: ;
|
|
// @1c2 #1146: [LCD_write_inst8]
|
|
01450 // @1c2 #1146: LOAD(s4,s5)
|
|
0a4f0 // @1c3 #1147: AND(s4,F0) ;Enable=0 RS=0 Instruction, RW=0 Write, E=0
|
|
0c408 // @1c4 #1148: OR(s4,LCD_drive) ;Enable=1
|
|
301be // @1c5 #1149: CALL(LCD_write_inst4) ;write upper nibble
|
|
301a0 // @1c6 #1150: CALL(delay_1us) ;wait >1us
|
|
01450 // @1c7 #1151: LOAD(s4,s5) ;select lower nibble with
|
|
20407 // @1c8 #1152: SL1(s4) ;Enable=1
|
|
20406 // @1c9 #1153: SL0(s4) ;RS=0 Instruction
|
|
20406 // @1ca #1154: SL0(s4) ;RW=0 Write
|
|
20406 // @1cb #1155: SL0(s4) ;E=0
|
|
301be // @1cc #1156: CALL(LCD_write_inst4) ;write lower nibble
|
|
301a4 // @1cd #1157: CALL(delay_40us) ;wait >40us
|
|
004f0 // @1ce #1158: LOAD(s4,F0) ;Enable=0 RS=0 Instruction, RW=0 Write, E=0
|
|
2c440 // @1cf #1159: OUTPUT(s4,LCD_output_port) ;Release master enable
|
|
2a000 // @1d0 #1160: RETURN
|
|
// #1161: ;
|
|
// #1162: ;
|
|
// #1163: ;
|
|
// #1164: ;Write 8-bit data to LCD display.
|
|
// #1165: ;
|
|
// #1166: ;The 8-bit data should be provided in register s5.
|
|
// #1167: ;Data bytes are written using the following sequence
|
|
// #1168: ; Upper nibble
|
|
// #1169: ; wait >1us
|
|
// #1170: ; Lower nibble
|
|
// #1171: ; wait >40us
|
|
// #1172: ;
|
|
// #1173: ;Registers used s0, s1, s4, s5
|
|
// #1174: ;
|
|
// @1d1 #1175: [LCD_write_data]
|
|
01450 // @1d1 #1175: LOAD(s4,s5)
|
|
0a4f0 // @1d2 #1176: AND(s4,F0) ;Enable=0 RS=0 Instruction, RW=0 Write, E=0
|
|
0c40c // @1d3 #1177: OR(s4,12) ;Enable=1 RS=1 Data, RW=0 Write, E=0
|
|
2c440 // @1d4 #1178: OUTPUT(s4,LCD_output_port) ;set up RS and RW >40ns before enable pulse
|
|
301b8 // @1d5 #1179: CALL(LCD_pulse_E) ;write upper nibble
|
|
301a0 // @1d6 #1180: CALL(delay_1us) ;wait >1us
|
|
01450 // @1d7 #1181: LOAD(s4,s5) ;select lower nibble with
|
|
20407 // @1d8 #1182: SL1(s4) ;Enable=1
|
|
20407 // @1d9 #1183: SL1(s4) ;RS=1 Data
|
|
20406 // @1da #1184: SL0(s4) ;RW=0 Write
|
|
20406 // @1db #1185: SL0(s4) ;E=0
|
|
2c440 // @1dc #1186: OUTPUT(s4,LCD_output_port) ;set up RS and RW >40ns before enable pulse
|
|
301b8 // @1dd #1187: CALL(LCD_pulse_E) ;write lower nibble
|
|
301a4 // @1de #1188: CALL(delay_40us) ;wait >40us
|
|
004f0 // @1df #1189: LOAD(s4,F0) ;Enable=0 RS=0 Instruction, RW=0 Write, E=0
|
|
2c440 // @1e0 #1190: OUTPUT(s4,LCD_output_port) ;Release master enable
|
|
2a000 // @1e1 #1191: RETURN
|
|
// #1192: ;
|
|
// #1193: ;
|
|
// #1194: ;
|
|
// #1195: ;
|
|
// #1196: ;Read 8-bit data from LCD display.
|
|
// #1197: ;
|
|
// #1198: ;The 8-bit data will be read from the current LCD memory address
|
|
// #1199: ;and will be returned in register s5.
|
|
// #1200: ;It is advisable to set the LCD address (cursor position) before
|
|
// #1201: ;using the data read for the first time otherwise the display may
|
|
// #1202: ;generate invalid data on the first read.
|
|
// #1203: ;
|
|
// #1204: ;Data bytes are read using the following sequence
|
|
// #1205: ; Upper nibble
|
|
// #1206: ; wait >1us
|
|
// #1207: ; Lower nibble
|
|
// #1208: ; wait >40us
|
|
// #1209: ;
|
|
// #1210: ;Registers used s0, s1, s4, s5
|
|
// #1211: ;
|
|
// @1e2 #1212: [LCD_read_data8]
|
|
0040e // @1e2 #1212: LOAD(s4,14) ;Enable=1 RS=1 Data, RW=1 Read, E=0
|
|
2c440 // @1e3 #1213: OUTPUT(s4,LCD_output_port) ;set up RS and RW >40ns before enable pulse
|
|
0e401 // @1e4 #1214: XOR(s4,LCD_E) ;E=1
|
|
2c440 // @1e5 #1215: OUTPUT(s4,LCD_output_port)
|
|
301a0 // @1e6 #1216: CALL(delay_1us) ;wait >260ns to access data
|
|
04502 // @1e7 #1217: INPUT(s5,LCD_input_port) ;read upper nibble
|
|
0e401 // @1e8 #1218: XOR(s4,LCD_E) ;E=0
|
|
2c440 // @1e9 #1219: OUTPUT(s4,LCD_output_port)
|
|
301a0 // @1ea #1220: CALL(delay_1us) ;wait >1us
|
|
0e401 // @1eb #1221: XOR(s4,LCD_E) ;E=1
|
|
2c440 // @1ec #1222: OUTPUT(s4,LCD_output_port)
|
|
301a0 // @1ed #1223: CALL(delay_1us) ;wait >260ns to access data
|
|
04002 // @1ee #1224: INPUT(s0,LCD_input_port) ;read lower nibble
|
|
0e401 // @1ef #1225: XOR(s4,LCD_E) ;E=0
|
|
2c440 // @1f0 #1226: OUTPUT(s4,LCD_output_port)
|
|
0a5f0 // @1f1 #1227: AND(s5,F0) ;merge upper and lower nibbles
|
|
2000e // @1f2 #1228: SR0(s0)
|
|
2000e // @1f3 #1229: SR0(s0)
|
|
2000e // @1f4 #1230: SR0(s0)
|
|
2000e // @1f5 #1231: SR0(s0)
|
|
0d500 // @1f6 #1232: OR(s5,s0)
|
|
00404 // @1f7 #1233: LOAD(s4,4) ;Enable=0 RS=1 Data, RW=0 Write, E=0
|
|
2c440 // @1f8 #1234: OUTPUT(s4,LCD_output_port) ;Stop reading 5V device and release master enable
|
|
301a4 // @1f9 #1235: CALL(delay_40us) ;wait >40us
|
|
2a000 // @1fa #1236: RETURN
|
|
// #1237: ;
|
|
// #1238: ;
|
|
// #1239: ;Reset and initialise display to communicate using 4-bit data mode
|
|
// #1240: ;Includes routine to clear the display.
|
|
// #1241: ;
|
|
// #1242: ;Requires the 4-bit instructions 3,3,3,2 to be sent with suitable delays
|
|
// #1243: ;following by the 8-bit instructions to set up the display.
|
|
// #1244: ;
|
|
// #1245: ; 28 = '001' Function set, '0' 4-bit mode, '1' 2-line, '0' 5x7 dot matrix, 'xx'
|
|
// #1246: ; 06 = '000001' Entry mode, '1' increment, '0' no display shift
|
|
// #1247: ; 0C = '00001' Display control, '1' display on, '0' cursor off, '0' cursor blink off
|
|
// #1248: ; 01 = '00000001' Display clear
|
|
// #1249: ;
|
|
// #1250: ;Registers used s0, s1, s2, s3, s4
|
|
// #1251: ;
|
|
// @1fb #1252: [LCD_reset]
|
|
301ae // @1fb #1252: CALL(delay_20ms) ;wait more that 15ms for display to be ready
|
|
00430 // @1fc #1253: LOAD(s4,48)
|
|
301be // @1fd #1254: CALL(LCD_write_inst4) ;send '3'
|
|
301ae // @1fe #1255: CALL(delay_20ms) ;wait >4.1ms
|
|
301be // @1ff #1256: CALL(LCD_write_inst4) ;send '3'
|
|
301a9 // @200 #1257: CALL(delay_1ms) ;wait >100us
|
|
301be // @201 #1258: CALL(LCD_write_inst4) ;send '3'
|
|
301a4 // @202 #1259: CALL(delay_40us) ;wait >40us
|
|
00420 // @203 #1260: LOAD(s4,32)
|
|
301be // @204 #1261: CALL(LCD_write_inst4) ;send '2'
|
|
301a4 // @205 #1262: CALL(delay_40us) ;wait >40us
|
|
00528 // @206 #1263: LOAD(s5,40) ;Function set
|
|
301c2 // @207 #1264: CALL(LCD_write_inst8)
|
|
00506 // @208 #1265: LOAD(s5,6) ;Entry mode
|
|
301c2 // @209 #1266: CALL(LCD_write_inst8)
|
|
0050c // @20a #1267: LOAD(s5,12) ;Display control
|
|
301c2 // @20b #1268: CALL(LCD_write_inst8)
|
|
// @20c #1269: [LCD_clear]
|
|
00501 // @20c #1269: LOAD(s5,1) ;Display clear
|
|
301c2 // @20d #1270: CALL(LCD_write_inst8)
|
|
301a9 // @20e #1271: CALL(delay_1ms) ;wait >1.64ms for display to clear
|
|
301a9 // @20f #1272: CALL(delay_1ms)
|
|
2a000 // @210 #1273: RETURN
|
|
// #1274: ;
|
|
// #1275: ;Position the cursor ready for characters to be written.
|
|
// #1276: ;The display is formed of 2 lines of 16 characters and each
|
|
// #1277: ;position has a corresponding address as indicated below.
|
|
// #1278: ;
|
|
// #1279: ; Character position
|
|
// #1280: ; 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
|
// #1281: ;
|
|
// #1282: ; Line 1 - 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F
|
|
// #1283: ; Line 2 - C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF
|
|
// #1284: ;
|
|
// #1285: ;This routine will set the cursor position using the value provided
|
|
// #1286: ;in register s5. The upper nibble will define the line and the lower
|
|
// #1287: ;nibble the character position on the line.
|
|
// #1288: ; Example s5 = 2B will position the cursor on line 2 position 11
|
|
// #1289: ;
|
|
// #1290: ;Registers used s0, s1, s2, s3, s4
|
|
// #1291: ;
|
|
// @211 #1292: [LCD_cursor]
|
|
12510 // @211 #1292: TEST(s5,16) ;test for line 1
|
|
35217 // @212 #1293: JUMP(Z,set_line2)
|
|
0a50f // @213 #1294: AND(s5,15) ;make address in range 80 to 8F for line 1
|
|
0c580 // @214 #1295: OR(s5,128)
|
|
301c2 // @215 #1296: CALL(LCD_write_inst8) ;instruction write to set cursor
|
|
2a000 // @216 #1297: RETURN
|
|
// @217 #1298: [set_line2]
|
|
0a50f // @217 #1298: AND(s5,15) ;make address in range C0 to CF for line 2
|
|
0c5c0 // @218 #1299: OR(s5,C0)
|
|
301c2 // @219 #1300: CALL(LCD_write_inst8) ;instruction write to set cursor
|
|
2a000 // @21a #1301: RETURN
|
|
// #1302: ;
|
|
// #1303: ;
|
|
// #1304: ;**************************************************************************************
|
|
// #1305: ;Interrupt Service Routine (ISR)
|
|
// #1306: ;**************************************************************************************
|
|
// #1307: ;
|
|
// #1308: ;Interrupts occur at 1 second intervals.
|
|
// #1309: ;
|
|
// #1310: ;Each interrupt is used to take analogue samples and store them in scratch pad memory.
|
|
// #1311: ;The interrupt clears a 'flag' in register sF so that the main program can advance.
|
|
// #1312: ;
|
|
// @21b #1313: [ISR]
|
|
30133 // @21b #1313: CALL(adc_read) ;read A/D Converter
|
|
2e800 // @21c #1314: STORE(s8,ADC0_lsb) ;store ADC Channel 0
|
|
2e901 // @21d #1315: STORE(s9,ADC0_msb)
|
|
2e602 // @21e #1316: STORE(s6,ADC1_lsb) ;store ADC Channel 1
|
|
2e703 // @21f #1317: STORE(s7,ADC1_msb)
|
|
// #1318: ;
|
|
00f00 // @220 #1319: LOAD(sF,0) ;clear flag
|
|
38001 // @221 #1320: RETURNI(ENABLE)
|
|
// #1321: ;
|
|
// #1322: ;
|
|
// #1323: ;**************************************************************************************
|
|
// #1324: ;Interrupt Vector
|
|
// #1325: ;**************************************************************************************
|
|
// #1326: ;
|
|
@3ff // #1327: ADDRESS(1023)
|
|
3421b // @3ff #1328: JUMP(ISR)
|
|
// #1329: ;
|
|
// #1330: ;
|