ioport.c
来自「CNC 的开放码,EMC2 V2.2.8版」· C语言 代码 · 共 605 行 · 第 1/2 页
C
605 行
// it's a full GPIO // if (hm2->pin[i].gtag == HM2_GTAG_IOPORT) { r = hal_pin_bit_newf( HAL_IN, &(hm2->pin[i].instance->hal.pin.out), hm2->llio->comp_id, "%s.gpio.%s.%03d.out", hm2->llio->name, hm2->llio->ioport_connector_name[port], i ); if (r != HAL_SUCCESS) { ERR("error %d adding gpio pin, aborting\n", r); return -EINVAL; } *(hm2->pin[i].instance->hal.pin.out) = 0; // parameters r = hal_param_bit_newf( HAL_RW, &(hm2->pin[i].instance->hal.param.is_output), hm2->llio->comp_id, "%s.gpio.%s.%03d.is_output", hm2->llio->name, hm2->llio->ioport_connector_name[port], i ); if (r != HAL_SUCCESS) { ERR("error %d adding gpio param, aborting\n", r); return -EINVAL; } hm2->pin[i].instance->hal.param.is_output = 0; } } return 0;}void hm2_ioport_print_module(hostmot2_t *hm2) { int i; PRINT("IO Ports: %d\n", hm2->ioport.num_instances); if (hm2->ioport.num_instances <= 0) return; PRINT(" clock_frequency: %d Hz (%s MHz)\n", hm2->ioport.clock_frequency, hm2_hz_to_mhz(hm2->ioport.clock_frequency)); PRINT(" version: %d\n", hm2->ioport.version); PRINT(" data_addr: 0x%04X\n", hm2->ioport.data_addr); PRINT(" ddr_addr: 0x%04X\n", hm2->ioport.ddr_addr); PRINT(" alt_source_addr: 0x%04X\n", hm2->ioport.alt_source_addr); PRINT(" open_drain_addr: 0x%04X\n", hm2->ioport.open_drain_addr); PRINT(" output_invert_addr: 0x%04X\n", hm2->ioport.output_invert_addr); for (i = 0; i < hm2->ioport.num_instances; i ++) { PRINT(" instance %d:\n", i); PRINT(" data_read = 0x%06X\n", hm2->ioport.data_read_reg[i]); PRINT(" data_write = 0x%06X\n", hm2->ioport.data_write_reg[i]); PRINT(" ddr = 0x%06X\n", hm2->ioport.ddr_reg[i]); PRINT(" alt_source = 0x%06X\n", hm2->ioport.alt_source_reg[i]); PRINT(" open_drain = 0x%06X\n", hm2->ioport.open_drain_reg[i]); PRINT(" output_invert = 0x%06X\n", hm2->ioport.output_invert_reg[i]); }}static void hm2_ioport_force_write_ddr(hostmot2_t *hm2) { int size = hm2->ioport.num_instances * sizeof(u32); hm2->llio->write(hm2->llio, hm2->ioport.ddr_addr, hm2->ioport.ddr_reg, size); memcpy(hm2->ioport.written_ddr, hm2->ioport.ddr_reg, size);}static void hm2_ioport_force_write_output_invert(hostmot2_t *hm2) { int size = hm2->ioport.num_instances * sizeof(u32); hm2->llio->write(hm2->llio, hm2->ioport.output_invert_addr, hm2->ioport.output_invert_reg, size); memcpy(hm2->ioport.written_output_invert, hm2->ioport.output_invert_reg, size);}static void hm2_ioport_force_write_open_drain(hostmot2_t *hm2) { int size = hm2->ioport.num_instances * sizeof(u32); hm2->llio->write(hm2->llio, hm2->ioport.open_drain_addr, hm2->ioport.open_drain_reg, size); memcpy(hm2->ioport.written_open_drain, hm2->ioport.open_drain_reg, size);}void hm2_ioport_update(hostmot2_t *hm2) { int port; int port_pin; for (port = 0; port < hm2->ioport.num_instances; port ++) { for (port_pin = 0; port_pin < hm2->idrom.port_width; port_pin ++) { int io_pin = (port * hm2->idrom.port_width) + port_pin; if (hm2->pin[io_pin].gtag == HM2_GTAG_IOPORT) { if (hm2->pin[io_pin].instance->hal.param.is_output) { hm2->pin[io_pin].direction = HM2_PIN_DIR_IS_OUTPUT; } else { hm2->pin[io_pin].direction = HM2_PIN_DIR_IS_INPUT; } } if (hm2->pin[io_pin].direction == HM2_PIN_DIR_IS_OUTPUT) { hm2->ioport.ddr_reg[port] |= (1 << port_pin); // set the bit in the ddr register // Open Drain Register if (hm2->pin[io_pin].instance->hal.param.is_opendrain) { hm2->ioport.open_drain_reg[port] |= (1 << port_pin); // set the bit in the open drain register } else { hm2->ioport.open_drain_reg[port] &= ~(1 << port_pin); // clear the bit in the open drain register } // Invert Output Register if (hm2->pin[io_pin].instance->hal.param.invert_output) { hm2->ioport.output_invert_reg[port] |= (1 << port_pin); // set the bit in the output invert register } else { hm2->ioport.output_invert_reg[port] &= ~(1 << port_pin); // clear the bit in the output invert register } } else { hm2->ioport.open_drain_reg[port] &= ~(1 << port_pin); // clear the bit in the open drain register hm2->ioport.ddr_reg[port] &= ~(1 << port_pin); // clear the bit in the ddr register // it doesnt matter what the Invert Output register says } } }}void hm2_ioport_force_write(hostmot2_t *hm2) { int size = hm2->ioport.num_instances * sizeof(u32); hm2_ioport_update(hm2); hm2_ioport_force_write_ddr(hm2); hm2_ioport_force_write_output_invert(hm2); hm2_ioport_force_write_open_drain(hm2); hm2->llio->write(hm2->llio, hm2->ioport.alt_source_addr, hm2->ioport.alt_source_reg, size);}void hm2_ioport_write(hostmot2_t *hm2) { int port; hm2_ioport_update(hm2); for (port = 0; port < hm2->ioport.num_instances; port ++) { if (hm2->ioport.written_ddr[port] != hm2->ioport.ddr_reg[port]) { hm2_ioport_force_write_ddr(hm2); break; } } for (port = 0; port < hm2->ioport.num_instances; port ++) { if (hm2->ioport.written_open_drain[port] != hm2->ioport.open_drain_reg[port]) { hm2_ioport_force_write_open_drain(hm2); break; } } for (port = 0; port < hm2->ioport.num_instances; port ++) { if (hm2->ioport.written_output_invert[port] != hm2->ioport.output_invert_reg[port]) { hm2_ioport_force_write_output_invert(hm2); break; } }}//// initialize the tram write registers//void hm2_ioport_gpio_tram_write_init(hostmot2_t *hm2) { int port; for (port = 0; port < hm2->ioport.num_instances; port ++) { hm2->ioport.data_write_reg[port] = 0; }}//// the ioport.data_read buffer has been updated by a TRAM read from the values in the ioport data register// this function sets the HAL pins based on the values in the data_read register buffer//void hm2_ioport_gpio_process_tram_read(hostmot2_t *hm2) { int port; int port_pin; // // parse it out to the HAL pins // for (port = 0; port < hm2->ioport.num_instances; port ++) { for (port_pin = 0; port_pin < hm2->idrom.port_width; port_pin ++) { int io_pin = (port * hm2->idrom.port_width) + port_pin; hal_bit_t bit; if (hm2->pin[io_pin].direction != HM2_PIN_DIR_IS_INPUT) continue; bit = (hm2->ioport.data_read_reg[port] >> port_pin) & 0x1; *hm2->pin[io_pin].instance->hal.pin.in = bit; *hm2->pin[io_pin].instance->hal.pin.in_not = !bit; } }}//// this function sets the data_write register TRAM buffer from the values of the HAL pins// the data_write buffer will get written to the TRAM and thus to the ioport data register by the caller// void hm2_ioport_gpio_prepare_tram_write(hostmot2_t *hm2) { int port; int port_pin; // // copy HAL pins to HM2 pins // for (port = 0; port < hm2->ioport.num_instances; port ++) { for (port_pin = 0; port_pin < hm2->idrom.port_width; port_pin ++) { int io_pin = (port * hm2->idrom.port_width) + port_pin; if (hm2->pin[io_pin].gtag != HM2_GTAG_IOPORT) continue; hm2->ioport.data_write_reg[port] &= ~(1 << port_pin); // zero the bit hm2->ioport.data_write_reg[port] |= (*(hm2->pin[io_pin].instance->hal.pin.out) << port_pin); // and set it as appropriate } }}void hm2_ioport_gpio_read(hostmot2_t *hm2) { int port; int port_pin; hm2->llio->read( hm2->llio, hm2->ioport.data_addr, hm2->ioport.data_read_reg, hm2->ioport.num_instances * sizeof(u32) ); // FIXME: this block duplicates code in hm2_ioport_gpio_process_tram_read() for (port = 0; port < hm2->ioport.num_instances; port ++) { for (port_pin = 0; port_pin < hm2->idrom.port_width; port_pin ++) { int io_pin = (port * hm2->idrom.port_width) + port_pin; hal_bit_t bit; if (hm2->pin[io_pin].direction != HM2_PIN_DIR_IS_INPUT) continue; bit = (hm2->ioport.data_read_reg[port] >> port_pin) & 0x1; *hm2->pin[io_pin].instance->hal.pin.in = bit; *hm2->pin[io_pin].instance->hal.pin.in_not = !bit; } }}void hm2_ioport_gpio_write(hostmot2_t *hm2) { int port; int port_pin; hm2_ioport_write(hm2); // this updates any config registers that need it // FIXME: this block duplicates code in hm2_ioport_gpio_prepare_tram_write() for (port = 0; port < hm2->ioport.num_instances; port ++) { for (port_pin = 0; port_pin < hm2->idrom.port_width; port_pin ++) { int io_pin = (port * hm2->idrom.port_width) + port_pin; if (hm2->pin[io_pin].gtag != HM2_GTAG_IOPORT) continue; hm2->ioport.data_write_reg[port] &= ~(1 << port_pin); // zero the bit hm2->ioport.data_write_reg[port] |= (*(hm2->pin[io_pin].instance->hal.pin.out) << port_pin); // and set it as appropriate } } hm2->llio->write( hm2->llio, hm2->ioport.data_addr, hm2->ioport.data_write_reg, hm2->ioport.num_instances * sizeof(u32) );}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?