📄 m7i43_hm2.comp
字号:
static inline void m7i43_epp_write(int w) { outb(w, ioaddr + M7I43_EPP_DATA_OFFSET); DEBUG(debug_epp, "wrote data 0x%02X\n", w);}static inline int m7i43_epp_read(void) { int val; val = inb(ioaddr + M7I43_EPP_DATA_OFFSET); DEBUG(debug_epp, "read data 0x%02X\n", val); return val;}static inline __u32 m7i43_epp_read32(void) { uint32_t data; if (epp_wide) { data = inl(ioaddr + M7I43_EPP_DATA_OFFSET); DEBUG(debug_epp, "read data 0x%08X\n", data); } else { uint8_t a, b, c, d; a = m7i43_epp_read(); b = m7i43_epp_read(); c = m7i43_epp_read(); d = m7i43_epp_read(); data = a + (b<<8) + (c<<16) + (d<<24); } return data;}static inline void m7i43_epp_write32(uint32_t w) { if (epp_wide) { outl(w, ioaddr + M7I43_EPP_DATA_OFFSET); DEBUG(debug_epp, "wrote data 0x%08X\n", w); } else { m7i43_epp_write((w) & 0xFF); m7i43_epp_write((w >> 8) & 0xFF); m7i43_epp_write((w >> 16) & 0xFF); m7i43_epp_write((w >> 24) & 0xFF); }}static inline uint8_t m7i43_epp_read_status(void) { uint8_t val; val = inb(ioaddr + M7I43_EPP_STATUS_OFFSET); DEBUG(debug_epp, "read status 0x%02X\n", val); return val;}static inline void m7i43_epp_write_status(uint8_t status_byte) { outb(status_byte, ioaddr + M7I43_EPP_STATUS_OFFSET); DEBUG(debug_epp, "wrote status 0x%02X\n", status_byte);}static inline void m7i43_epp_write_control(uint8_t control_byte) { outb(control_byte, ioaddr + M7I43_EPP_CONTROL_OFFSET); DEBUG(debug_epp, "wrote control 0x%02X\n", control_byte);}static inline int m7i43_epp_check_for_timeout(void) { return (m7i43_epp_read_status() & 0x01);}static int m7i43_epp_clear_timeout(void) { uint8_t status; if (!m7i43_epp_check_for_timeout()) { return 1; } /* To clear timeout some chips require double read */ (void)m7i43_epp_read_status(); // read in the actual status register status = m7i43_epp_read_status(); m7i43_epp_write_status(status | 0x01); // Some reset by writing 1 m7i43_epp_write_status(status & 0xFE); // Others by writing 0 return !m7i43_epp_check_for_timeout();}// // misc generic helper functions// static void m7i43_nanosleep(unsigned long int nanoseconds) { long int max_ns_delay; max_ns_delay = rtapi_delay_max(); while (nanoseconds > max_ns_delay) { rtapi_delay(max_ns_delay); nanoseconds -= max_ns_delay; } rtapi_delay(nanoseconds);}// // helper functions for dealing with the 7i43 board// static const char *hm2_hz_to_mhz(__u32 freq_hz) { static char mhz_str[20]; int freq_mhz, freq_mhz_fractional; freq_mhz = freq_hz / (1000*1000); freq_mhz_fractional = (freq_hz / 1000) % 1000; sprintf(mhz_str, "%d.%03d", freq_mhz, freq_mhz_fractional); return mhz_str;}// this function resets the FPGA *only* if it's currently configured with the HostMot2 firmwarestatic void m7i43_hm2_reset(void) { m7i43_epp_addr16(0x7F7F); m7i43_epp_write(0x5A);}static void m7i43_hm2_print_idrom(int level, m7i43_t *board) { PRINT(level, "IDRom:\n"); if (board->idrom.idrom_type == 2) { PRINT(level, " IDRom Type: 0x%08X\n", board->idrom.idrom_type); } else { PRINT(level, " IDRom Type: 0x%08X ***** Expected 2! Continuing anyway! *****\n", board->idrom.idrom_type); } if (board->idrom.offset_to_modules == 0x40) { PRINT(level, " Offset to Modules: 0x%08X\n", board->idrom.offset_to_modules); } else { PRINT(level, " Offset to Modules: 0x%08X ***** Expected 0x40! Continuing anyway *****\n", board->idrom.offset_to_modules); } if (board->idrom.offset_to_pin_desc == 0x200) { PRINT(level, " Offset to Pin Description: 0x%08X\n", board->idrom.offset_to_pin_desc); } else { PRINT(level, " Offset to Pin Description: 0x%08X ***** Expected 0x200! Continuing anyway! *****\n", board->idrom.offset_to_pin_desc); } PRINT(level, " Board Name: %s\n", board->idrom.board_name); if (board->idrom.fpga_size == board->cpld.fpga_size) { PRINT(level, " FPGA Size: %u\n", board->idrom.fpga_size); } else { PRINT(level, " FPGA Size: %u ***** CPLD reported FPGA Size %d! Continuing anyway! *****\n", board->idrom.fpga_size, board->cpld.fpga_size); } PRINT(level, " FPGA Pins: %u\n", board->idrom.fpga_pins); PRINT(level, " IO Ports: %u\n", board->idrom.io_ports); PRINT(level, " IO Width: %u\n", board->idrom.io_width); if (board->idrom.port_width == 24) { PRINT(level, " Port Width: %u\n", board->idrom.port_width); } else { PRINT(level, " Port Width: %u ***** Expected 24! Continuing anyway! *****\n", board->idrom.port_width); } PRINT( level, " Clock Low: %d Hz (%d KHz, %d MHz)\n", board->idrom.clock_low, (board->idrom.clock_low / 1000), (board->idrom.clock_low / (1000 * 1000)) ); PRINT( level, " Clock High: %d Hz (%d KHz, %d MHz)\n", board->idrom.clock_high, (board->idrom.clock_high / 1000), (board->idrom.clock_high / (1000 * 1000)) ); PRINT(level, " Instance Stride 0: 0x%08X\n", board->idrom.instance_stride_0); PRINT(level, " Instance Stride 1: 0x%08X\n", board->idrom.instance_stride_1); PRINT(level, " Register Stride 0: 0x%08X\n", board->idrom.register_stride_0); PRINT(level, " Register Stride 1: 0x%08X\n", board->idrom.register_stride_1); }//// Update the PWM Mode Registers of all pwmgen instances that need it//static void hm2_pwmgen_update_mode_registers(m7i43_t *board) { int need_update = 0; int i; for (i = 0; i < board->pwmgen.num_instances; i ++) { if (board->pwmgen.instance[i].hal.param.output_type == board->pwmgen.instance[i].hal.param.written_output_type) continue; need_update = 1; board->pwmgen.instance[i].hal.param.written_output_type = board->pwmgen.instance[i].hal.param.output_type; board->pwmgen.instance[i].hw.pwm_mode = board->pwmgen.instance[i].pwm_width_select; board->pwmgen.instance[i].hw.pwm_mode |= board->pwmgen.instance[i].pwm_mode_select << 2; switch (board->pwmgen.instance[i].hal.param.output_type) { case 1: { // PWM & Dir board->pwmgen.instance[i].hw.pwm_mode |= 0x0 << 3; PRINT( RTAPI_MSG_INFO, "pwmgen.%02d.output-mode is %d (PWM & Dir), Out0 is PWM, Out1 is Dir\n", i, board->pwmgen.instance[i].hal.param.output_type ); break; } case 2: { // Up & Down board->pwmgen.instance[i].hw.pwm_mode |= 0x2 << 3; PRINT( RTAPI_MSG_INFO, "pwmgen.%02d.output-mode is %d (Up & Down), Out0 is Up, Out1 is Down\n", i, board->pwmgen.instance[i].hal.param.output_type ); break; } default: { // unknown pwm mode! complain and switch to pwm/dir PRINT( RTAPI_MSG_WARN, "invalid pwmgen output_type %d, 1 and 2 are supported, switching to 1\n", board->pwmgen.instance[i].hal.param.output_type ); board->pwmgen.instance[i].hal.param.output_type = 1; board->pwmgen.instance[i].hal.param.written_output_type = board->pwmgen.instance[i].hal.param.output_type; board->pwmgen.instance[i].hw.pwm_mode |= 0x0 << 3; PRINT( RTAPI_MSG_INFO, "pwmgen.%02d.output-mode is %d (PWM & Dir), Out0 is PWM, Out1 is Dir\n", i, board->pwmgen.instance[i].hal.param.output_type ); break; } } board->pwmgen.instance[i].hw.pwm_mode |= board->pwmgen.instance[i].pwm_double_buffered << 5; } if (need_update) { m7i43_epp_addr16(board->pwmgen.pwm_mode_addr + M7I43_HM2_ADDR_AUTOINCREMENT); for (i = 0; i < board->pwmgen.num_instances; i ++) { m7i43_epp_write32(board->pwmgen.instance[i].hw.pwm_mode); } }}// // read the idrom// use address autoincrement, and just read everything in the correct order// static int m7i43_hm2_read_idrom(m7i43_t *board) { int i; int ret_val = 0; int show_idrom = 0; m7i43_epp_addr16(board->idrom_offset + M7I43_HM2_ADDR_AUTOINCREMENT); board->idrom.idrom_type = m7i43_epp_read32(); if (board->idrom.idrom_type != 2) { PRINT(RTAPI_MSG_WARN, "invalid IDROM type %d, expected 2, aborting load\n", board->idrom.idrom_type); return -EINVAL; } board->idrom.offset_to_modules = m7i43_epp_read32(); board->idrom.offset_to_pin_desc = m7i43_epp_read32(); for (i = 0; i < 8; i ++) { board->idrom.board_name[i] = m7i43_epp_read(); } board->idrom.board_name[8] = '\0'; board->idrom.fpga_size = m7i43_epp_read32(); if (board->idrom.fpga_size != board->cpld.fpga_size) { show_idrom = 1; PRINT( RTAPI_MSG_WARN, "IDRom FPGA Size %d disagrees with CPLD FPGA Size %d, oh well\n", board->idrom.fpga_size, board->cpld.fpga_size ); } board->idrom.fpga_pins = m7i43_epp_read32(); board->idrom.io_ports = m7i43_epp_read32(); board->idrom.io_width = m7i43_epp_read32(); board->idrom.port_width = m7i43_epp_read32(); if (board->idrom.port_width != 24) { PRINT(RTAPI_MSG_WARN, "invalid IDROM PortWidth %d, expected 24, aborting load\n", board->idrom.port_width); ret_val = -EINVAL; show_idrom = 1; } board->idrom.clock_low = m7i43_epp_read32(); board->idrom.clock_high = m7i43_epp_read32(); board->idrom.instance_stride_0 = m7i43_epp_read32(); board->idrom.instance_stride_1 = m7i43_epp_read32(); board->idrom.register_stride_0 = m7i43_epp_read32(); board->idrom.register_stride_1 = m7i43_epp_read32(); if (show_idrom) { m7i43_hm2_print_idrom(RTAPI_MSG_WARN, board); } else if (debug_idrom) { m7i43_hm2_print_idrom(RTAPI_MSG_INFO, board); } return ret_val;}// // helper functions for dealing with the Module Descriptions//static const char *hm2_get_general_function_name(int gtag) { switch (gtag) { case HM2_GTAG_WATCHDOG: return "Watchdog"; case HM2_GTAG_IOPORT: return "IOPort"; case HM2_GTAG_ENCODER: return "Encoder"; case HM2_GTAG_STEPGEN: return "StepGen"; case HM2_GTAG_PWMGEN: return "PWMGen"; case HM2_GTAG_TRANSLATIONRAM: return "TranslationRAM"; default: { static char unknown[100]; rtapi_snprintf(unknown, 100, "(unknown-gtag-%d)", gtag); return unknown; } }}// // read the modules// static int hm2_md_is_consistent( hm2_module_descriptor_t *m, __u8 version, __u8 num_registers, __u32 instance_stride, __u32 multiple_registers) { if ( (m->num_registers == num_registers) && (m->version == version) && (m->instance_stride == instance_stride) && (m->multiple_registers == multiple_registers) ) { return 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -