diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index bc16f03..af4ea64 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -71,7 +71,7 @@ jobs:
- version: linux
os: ubuntu-latest
- linux-packages: libudev-dev
+ apt-packages: libudev-dev
executable: target/release/sc64deployer
package-name: sc64-deployer-linux
package-params: -czf
@@ -98,11 +98,11 @@ jobs:
string: '${{ github.ref_name }}'
replace-with: '-'
- - name: Install linux packages
- if: matrix.linux-packages
+ - name: Install apt packages
+ if: matrix.apt-packages
run: |
sudo apt-get update
- sudo apt-get -y install ${{ matrix.linux-packages }}
+ sudo apt-get -y install ${{ matrix.apt-packages }}
- name: Build deployer
run: cargo b -r ${{ matrix.build-params }}
diff --git a/fw/project/lcmxo2/sc64.ldf b/fw/project/lcmxo2/sc64.ldf
index f3198e8..5d2cc62 100644
--- a/fw/project/lcmxo2/sc64.ldf
+++ b/fw/project/lcmxo2/sc64.ldf
@@ -3,6 +3,9 @@
+
@@ -12,6 +15,9 @@
+
diff --git a/fw/project/lcmxo2/sc64.lpf b/fw/project/lcmxo2/sc64.lpf
index 6feb8ab..3fd38a2 100644
--- a/fw/project/lcmxo2/sc64.lpf
+++ b/fw/project/lcmxo2/sc64.lpf
@@ -214,7 +214,7 @@ LOCATE COMP "usb_miso" SITE "10" ;
LOCATE COMP "usb_pwrsav" SITE "2" ;
SYSCONFIG SDM_PORT=DISABLE I2C_PORT=ENABLE ;
VOLTAGE 3.300 V;
-FREQUENCY NET "clk" 100.000000 MHz PAR_ADJ 10.000000 ;
+FREQUENCY NET "clk" 100.000000 MHz ;
BLOCK PATH TO PORT "mcu_int" ;
BLOCK PATH TO PORT "n64_irq" ;
BLOCK PATH FROM PORT "usb_pwrsav" ;
diff --git a/fw/rtl/fifo/fifo_bus.sv b/fw/rtl/fifo/fifo_bus.sv
index 80ca607..9d3c17f 100644
--- a/fw/rtl/fifo/fifo_bus.sv
+++ b/fw/rtl/fifo/fifo_bus.sv
@@ -1,35 +1,29 @@
interface fifo_bus ();
logic rx_empty;
- logic rx_almost_empty;
logic rx_read;
logic [7:0] rx_rdata;
logic tx_full;
- logic tx_almost_full;
logic tx_write;
logic [7:0] tx_wdata;
modport controller (
input rx_empty,
- input rx_almost_empty,
output rx_read,
input rx_rdata,
input tx_full,
- input tx_almost_full,
output tx_write,
output tx_wdata
);
modport fifo (
output rx_empty,
- output rx_almost_empty,
input rx_read,
output rx_rdata,
output tx_full,
- output tx_almost_full,
input tx_write,
input tx_wdata
);
diff --git a/fw/rtl/fifo/fifo_junction.sv b/fw/rtl/fifo/fifo_junction.sv
index cd3ffdc..459c218 100644
--- a/fw/rtl/fifo/fifo_junction.sv
+++ b/fw/rtl/fifo/fifo_junction.sv
@@ -11,16 +11,12 @@ module fifo_junction (
dev_bus.tx_wdata = cfg_bus.tx_write ? cfg_bus.tx_wdata : dma_bus.tx_wdata;
cfg_bus.rx_empty = dev_bus.rx_empty;
- cfg_bus.rx_almost_empty = dev_bus.rx_almost_empty;
cfg_bus.rx_rdata = dev_bus.rx_rdata;
cfg_bus.tx_full = dev_bus.tx_full;
- cfg_bus.tx_almost_full = dev_bus.tx_almost_full;
dma_bus.rx_empty = dev_bus.rx_empty;
- dma_bus.rx_almost_empty = dev_bus.rx_almost_empty;
dma_bus.rx_rdata = dev_bus.rx_rdata;
dma_bus.tx_full = dev_bus.tx_full;
- dma_bus.tx_almost_full = dev_bus.tx_almost_full;
end
endmodule
diff --git a/fw/rtl/mcu/mcu_top.sv b/fw/rtl/mcu/mcu_top.sv
index a0540d5..41b9627 100644
--- a/fw/rtl/mcu/mcu_top.sv
+++ b/fw/rtl/mcu/mcu_top.sv
@@ -394,13 +394,13 @@ module mcu_top (
REG_USB_SCR: begin
reg_rdata <= {
- 2'd0,
+ 1'd0,
+ usb_scb.fifo_flush_busy,
usb_scb.pwrsav,
usb_scb.reset_state,
usb_scb.tx_count,
usb_scb.rx_count,
- 2'b00,
- usb_scb.reset_pending,
+ 3'b000,
~fifo_bus.tx_full,
~fifo_bus.rx_empty,
1'b0
@@ -681,9 +681,10 @@ module mcu_top (
mem_start <= 1'b0;
mem_stop <= 1'b0;
- usb_scb.write_buffer_flush <= 1'b0;
- usb_scb.reset_ack <= 1'b0;
usb_scb.fifo_flush <= 1'b0;
+ usb_scb.write_buffer_flush <= 1'b0;
+ usb_scb.reset_on_ack <= 1'b0;
+ usb_scb.reset_off_ack <= 1'b0;
usb_dma_scb.start <= 1'b0;
usb_dma_scb.stop <= 1'b0;
@@ -770,11 +771,10 @@ module mcu_top (
end
REG_USB_SCR: begin
- {
- usb_scb.write_buffer_flush,
- usb_scb.reset_ack,
- usb_scb.fifo_flush
- } <= {reg_wdata[5:4], reg_wdata[0]};
+ usb_scb.write_buffer_flush <= reg_wdata[5];
+ usb_scb.reset_off_ack <= reg_wdata[4];
+ usb_scb.reset_on_ack <= reg_wdata[3];
+ usb_scb.fifo_flush <= reg_wdata[0];
end
REG_USB_DMA_ADDRESS: begin
diff --git a/fw/rtl/memory/dma_scb.sv b/fw/rtl/memory/dma_scb.sv
new file mode 100644
index 0000000..da8d709
--- /dev/null
+++ b/fw/rtl/memory/dma_scb.sv
@@ -0,0 +1,31 @@
+interface dma_scb ();
+
+ logic start;
+ logic stop;
+ logic busy;
+ logic direction;
+ logic byte_swap;
+ logic [26:0] starting_address;
+ logic [26:0] transfer_length;
+
+ modport controller (
+ output start,
+ output stop,
+ input busy,
+ output direction,
+ output byte_swap,
+ output starting_address,
+ output transfer_length
+ );
+
+ modport dma (
+ input start,
+ input stop,
+ output busy,
+ input direction,
+ input byte_swap,
+ input starting_address,
+ input transfer_length
+ );
+
+endinterface
diff --git a/fw/rtl/memory/memory_dma.sv b/fw/rtl/memory/memory_dma.sv
index b401ddf..7bd529f 100644
--- a/fw/rtl/memory/memory_dma.sv
+++ b/fw/rtl/memory/memory_dma.sv
@@ -1,36 +1,3 @@
-interface dma_scb ();
-
- logic start;
- logic stop;
- logic busy;
- logic direction;
- logic byte_swap;
- logic [26:0] starting_address;
- logic [26:0] transfer_length;
-
- modport controller (
- output start,
- output stop,
- input busy,
- output direction,
- output byte_swap,
- output starting_address,
- output transfer_length
- );
-
- modport dma (
- input start,
- input stop,
- output busy,
- input direction,
- input byte_swap,
- input starting_address,
- input transfer_length
- );
-
-endinterface
-
-
module memory_dma (
input clk,
input reset,
@@ -41,213 +8,403 @@ module memory_dma (
mem_bus.controller mem_bus
);
- // DMA start/stop control
+ // Start/stop logic
logic dma_start;
logic dma_stop;
- always_comb begin
- dma_start = dma_scb.start && !dma_scb.stop && !dma_scb.busy;
- dma_stop = dma_scb.stop;
+ always_ff @(posedge clk) begin
+ dma_start <= 1'b0;
+ if (dma_scb.stop) begin
+ dma_stop <= 1'b1;
+ end else if (dma_scb.start) begin
+ dma_start <= 1'b1;
+ dma_stop <= 1'b0;
+ end
end
- // Remaining counter and FIFO enable
+ // Memory bus controller
- logic [26:0] remaining;
- logic trx_enabled;
+ typedef enum bit [1:0] {
+ MEM_BUS_STATE_IDLE,
+ MEM_BUS_STATE_WAIT,
+ MEM_BUS_STATE_TRANSFER
+ } e_mem_bus_state;
+
+ e_mem_bus_state mem_bus_state;
+ e_mem_bus_state next_mem_bus_state;
+
+ logic mem_bus_wdata_ready;
+ logic mem_bus_wdata_empty;
+ logic mem_bus_wdata_end;
+ logic [1:0] mem_bus_wdata_valid;
+ logic [15:0] mem_bus_wdata_buffer;
+
+ logic mem_bus_rdata_ready;
+ logic mem_bus_rdata_ack;
+ logic mem_bus_rdata_end;
+ logic [1:0] mem_bus_rdata_valid;
+ logic [15:0] mem_bus_rdata_buffer;
+
+ logic [26:0] mem_bus_remaining_bytes;
+ logic mem_bus_last_transfer;
+ logic mem_bus_almost_last_transfer;
+ logic mem_bus_unaligned_start;
+ logic mem_bus_unaligned_end;
+
+ always_ff @(posedge clk) begin
+ if (reset) begin
+ mem_bus_state <= MEM_BUS_STATE_IDLE;
+ end else begin
+ mem_bus_state <= next_mem_bus_state;
+ end
+ end
always_comb begin
- trx_enabled = remaining > 27'd0;
+ next_mem_bus_state = mem_bus_state;
+
+ mem_bus_last_transfer = (mem_bus_remaining_bytes == 27'd0);
+ mem_bus_almost_last_transfer = (mem_bus_remaining_bytes <= 27'd2);
+
+ mem_bus_wdata_end = mem_bus_last_transfer;
+ mem_bus_wdata_valid = (mem_bus_unaligned_end && mem_bus_almost_last_transfer) ? 2'b10 :
+ mem_bus_unaligned_start ? 2'b01 :
+ 2'b11;
+
+ case (mem_bus_state)
+ MEM_BUS_STATE_IDLE: begin
+ if (dma_start) begin
+ next_mem_bus_state = MEM_BUS_STATE_WAIT;
+ end
+ end
+
+ MEM_BUS_STATE_WAIT: begin
+ if (dma_stop || mem_bus_last_transfer) begin
+ next_mem_bus_state = MEM_BUS_STATE_IDLE;
+ end else if (mem_bus_wdata_ready || !mem_bus_wdata_empty || mem_bus_rdata_ready) begin
+ next_mem_bus_state = MEM_BUS_STATE_TRANSFER;
+ end
+ end
+
+ MEM_BUS_STATE_TRANSFER: begin
+ if (mem_bus.ack) begin
+ if (dma_stop || mem_bus_last_transfer) begin
+ next_mem_bus_state = MEM_BUS_STATE_IDLE;
+ end else if (!(mem_bus_wdata_ready || !mem_bus_wdata_empty || mem_bus_rdata_ready)) begin
+ next_mem_bus_state = MEM_BUS_STATE_WAIT;
+ end
+ end
+ end
+
+ default: begin
+ next_mem_bus_state = MEM_BUS_STATE_IDLE;
+ end
+ endcase
+ end
+
+ always_ff @(posedge clk) begin
+ mem_bus_rdata_ack <= 1'b0;
+
+ if (mem_bus.ack) begin
+ mem_bus.request <= 1'b0;
+ mem_bus.address <= (mem_bus.address + 26'd2);
+ mem_bus_rdata_ack <= 1'b1;
+ mem_bus_rdata_end <= mem_bus_last_transfer;
+ mem_bus_rdata_valid <= mem_bus.wmask;
+ mem_bus_rdata_buffer <= mem_bus.rdata;
+ end
+
+ if (mem_bus_wdata_ready) begin
+ mem_bus_wdata_empty <= 1'b0;
+ end
+
+ case (mem_bus_state)
+ MEM_BUS_STATE_IDLE: begin
+ mem_bus.request <= 1'b0;
+ mem_bus_rdata_end <= 1'b1;
+ if (dma_start) begin
+ mem_bus.write <= dma_scb.direction;
+ mem_bus.address <= {dma_scb.starting_address[26:1], 1'b0};
+ mem_bus_remaining_bytes <= dma_scb.transfer_length;
+ mem_bus_unaligned_start <= dma_scb.starting_address[0];
+ mem_bus_unaligned_end <= (dma_scb.starting_address[0] ^ dma_scb.transfer_length[0]);
+ mem_bus_rdata_end <= 1'b0;
+ mem_bus_wdata_empty <= 1'b1;
+ end
+ end
+
+ MEM_BUS_STATE_WAIT: begin
+ if (!dma_stop && !mem_bus_last_transfer) begin
+ if (mem_bus_wdata_ready || !mem_bus_wdata_empty || mem_bus_rdata_ready) begin
+ mem_bus.request <= 1'b1;
+ mem_bus_unaligned_start <= 1'b0;
+ mem_bus.wdata <= (dma_scb.byte_swap ? {mem_bus_wdata_buffer[7:0], mem_bus_wdata_buffer[15:8]} : mem_bus_wdata_buffer);
+ mem_bus.wmask <= 2'b11;
+ mem_bus_remaining_bytes <= (mem_bus_remaining_bytes - 27'd2);
+ if (mem_bus_unaligned_end && mem_bus_almost_last_transfer) begin
+ mem_bus.wmask <= 2'b10;
+ mem_bus_remaining_bytes <= (mem_bus_remaining_bytes - 27'd1);
+ end
+ if (mem_bus_unaligned_start) begin
+ mem_bus.wmask <= 2'b01;
+ mem_bus_remaining_bytes <= (mem_bus_remaining_bytes - 27'd1);
+ end
+ mem_bus_wdata_empty <= 1'b1;
+ end
+ end
+ end
+
+ MEM_BUS_STATE_TRANSFER: begin
+ if (!dma_stop && !mem_bus_last_transfer) begin
+ if (mem_bus.ack && (mem_bus_wdata_ready || !mem_bus_wdata_empty || mem_bus_rdata_ready)) begin
+ mem_bus.request <= 1'b1;
+ mem_bus.wdata <= (dma_scb.byte_swap ? {mem_bus_wdata_buffer[7:0], mem_bus_wdata_buffer[15:8]} : mem_bus_wdata_buffer);
+ mem_bus.wmask <= 2'b11;
+ mem_bus_remaining_bytes <= (mem_bus_remaining_bytes - 27'd2);
+ if (mem_bus_unaligned_end && mem_bus_almost_last_transfer) begin
+ mem_bus.wmask <= 2'b10;
+ mem_bus_remaining_bytes <= (mem_bus_remaining_bytes - 27'd1);
+ end
+ mem_bus_wdata_empty <= 1'b1;
+ end
+ end
+ end
+
+ default: begin end
+ endcase
end
// RX FIFO controller
- logic [1:0] rx_wmask;
- logic rx_rdata_pop;
- logic rx_rdata_shift;
- logic rx_rdata_valid;
- logic [15:0] rx_buffer;
- logic rx_buffer_valid;
- logic [1:0] rx_buffer_counter;
- logic [1:0] rx_buffer_valid_counter;
+ typedef enum bit [2:0] {
+ RX_FIFO_BUS_STATE_IDLE,
+ RX_FIFO_BUS_STATE_WAIT,
+ RX_FIFO_BUS_STATE_TRANSFER_1,
+ RX_FIFO_BUS_STATE_TRANSFER_2,
+ RX_FIFO_BUS_STATE_ACK
+ } e_rx_fifo_bus_state;
+
+ e_rx_fifo_bus_state rx_fifo_bus_state;
+ e_rx_fifo_bus_state next_rx_fifo_bus_state;
+
+ logic rx_fifo_shift;
+ logic rx_fifo_shift_delayed;
+ logic [1:0] rx_fifo_valid;
+
+ always_ff @(posedge clk) begin
+ if (reset || dma_stop) begin
+ rx_fifo_bus_state <= RX_FIFO_BUS_STATE_IDLE;
+ end else begin
+ rx_fifo_bus_state <= next_rx_fifo_bus_state;
+ end
+ end
always_comb begin
- rx_buffer_valid = rx_buffer_valid_counter == 2'd2;
+ next_rx_fifo_bus_state = rx_fifo_bus_state;
+
+ rx_fifo_shift = 1'b0;
+
+ fifo_bus.rx_read = 1'b0;
+
+ case (rx_fifo_bus_state)
+ RX_FIFO_BUS_STATE_IDLE: begin
+ if (dma_start && dma_scb.direction) begin
+ next_rx_fifo_bus_state = RX_FIFO_BUS_STATE_WAIT;
+ end
+ end
+
+ RX_FIFO_BUS_STATE_WAIT: begin
+ if (mem_bus_wdata_end) begin
+ next_rx_fifo_bus_state = RX_FIFO_BUS_STATE_IDLE;
+ end else if (mem_bus_wdata_empty) begin
+ next_rx_fifo_bus_state = RX_FIFO_BUS_STATE_TRANSFER_1;
+ end
+ end
+
+ RX_FIFO_BUS_STATE_TRANSFER_1: begin
+ fifo_bus.rx_read = (!fifo_bus.rx_empty && rx_fifo_valid[1]);
+ if (!fifo_bus.rx_empty || !rx_fifo_valid[1]) begin
+ next_rx_fifo_bus_state = RX_FIFO_BUS_STATE_TRANSFER_2;
+ rx_fifo_shift = 1'b1;
+ end
+ end
+
+ RX_FIFO_BUS_STATE_TRANSFER_2: begin
+ fifo_bus.rx_read = (!fifo_bus.rx_empty && rx_fifo_valid[1]);
+ if (!fifo_bus.rx_empty || !rx_fifo_valid[1]) begin
+ next_rx_fifo_bus_state = RX_FIFO_BUS_STATE_ACK;
+ rx_fifo_shift = 1'b1;
+ end
+ end
+
+ RX_FIFO_BUS_STATE_ACK: begin
+ if (mem_bus_wdata_ready) begin
+ next_rx_fifo_bus_state = RX_FIFO_BUS_STATE_WAIT;
+ end
+ end
+
+ default: begin
+ next_rx_fifo_bus_state = RX_FIFO_BUS_STATE_IDLE;
+ end
+ endcase
end
always_ff @(posedge clk) begin
- rx_rdata_pop <= (
- !rx_rdata_pop &&
- !fifo_bus.rx_read &&
- trx_enabled &&
- rx_buffer_counter < 2'd2 &&
- !fifo_bus.rx_empty &&
- mem_bus.write
- );
- rx_rdata_shift <= 1'b0;
- fifo_bus.rx_read <= rx_rdata_pop;
- rx_rdata_valid <= fifo_bus.rx_read;
+ mem_bus_wdata_ready <= 1'b0;
+ rx_fifo_shift_delayed <= rx_fifo_shift;
- if (dma_start) begin
- if (dma_scb.starting_address[0]) begin
- rx_wmask <= 2'b01;
- rx_buffer_counter <= 2'd1;
- rx_buffer_valid_counter <= 2'd1;
- end else begin
- rx_wmask <= 2'b11;
- rx_buffer_counter <= 2'd0;
- rx_buffer_valid_counter <= 2'd0;
+ if (rx_fifo_shift) begin
+ rx_fifo_valid <= {rx_fifo_valid[0], 1'bX};
+ end
+
+ if (rx_fifo_shift_delayed) begin
+ if (rx_fifo_bus_state == RX_FIFO_BUS_STATE_ACK) begin
+ mem_bus_wdata_ready <= 1'b1;
end
+ mem_bus_wdata_buffer <= {mem_bus_wdata_buffer[7:0], fifo_bus.rx_rdata};
end
- if (rx_rdata_pop) begin
- rx_buffer_counter <= rx_buffer_counter + 1'd1;
- end
-
- if (rx_rdata_shift || rx_rdata_valid) begin
- if (dma_scb.byte_swap) begin
- rx_buffer <= {fifo_bus.rx_rdata, rx_buffer[15:8]};
- end else begin
- rx_buffer <= {rx_buffer[7:0], fifo_bus.rx_rdata};
+ case (rx_fifo_bus_state)
+ RX_FIFO_BUS_STATE_WAIT: begin
+ if (mem_bus_wdata_empty) begin
+ rx_fifo_valid <= mem_bus_wdata_valid;
+ end
end
- rx_buffer_valid_counter <= rx_buffer_valid_counter + 1'd1;
- if (remaining == 27'd0 && rx_buffer_counter == 2'd1) begin
- rx_wmask <= 2'b10;
- rx_rdata_shift <= 1'b1;
- rx_buffer_counter <= rx_buffer_counter + 1'd1;
- end
- end
- if (rx_buffer_valid && !mem_bus.request) begin
- rx_wmask <= 2'b11;
- rx_buffer_counter <= 2'd0;
- rx_buffer_valid_counter <= 2'd0;
- end
+ default: begin end
+ endcase
end
// TX FIFO controller
- logic tx_wdata_push;
- logic tx_wdata_first_push;
- logic [7:0] tx_buffer;
- logic tx_buffer_counter;
- logic tx_buffer_ready;
- logic tx_buffer_valid;
+ typedef enum bit [1:0] {
+ TX_FIFO_BUS_STATE_IDLE,
+ TX_FIFO_BUS_STATE_WAIT,
+ TX_FIFO_BUS_STATE_TRANSFER_1,
+ TX_FIFO_BUS_STATE_TRANSFER_2
+ } e_tx_fifo_bus_state;
+
+ e_tx_fifo_bus_state tx_fifo_bus_state;
+ e_tx_fifo_bus_state next_tx_fifo_bus_state;
+
+ logic tx_fifo_shift;
+ logic tx_fifo_waiting;
+ logic [1:0] tx_fifo_valid;
+ logic [15:0] tx_fifo_buffer;
+
+ always_ff @(posedge clk) begin
+ if (reset || dma_stop) begin
+ tx_fifo_bus_state <= TX_FIFO_BUS_STATE_IDLE;
+ end else begin
+ tx_fifo_bus_state <= next_tx_fifo_bus_state;
+ end
+ end
always_comb begin
- fifo_bus.tx_write = tx_wdata_push;
- end
+ next_tx_fifo_bus_state = tx_fifo_bus_state;
- always_ff @(posedge clk) begin
- tx_wdata_push <= (
- !tx_wdata_push &&
- trx_enabled &&
- tx_buffer_valid &&
- !fifo_bus.tx_full &&
- !mem_bus.write
- );
+ tx_fifo_shift = 1'b0;
- if (reset || dma_stop) begin
- tx_buffer_ready <= 1'b0;
- tx_buffer_valid <= 1'b0;
- end
+ fifo_bus.tx_write = 1'b0;
+ fifo_bus.tx_wdata = tx_fifo_buffer[15:8];
- if (dma_start) begin
- tx_wdata_first_push <= 1'b1;
- tx_buffer_ready <= 1'b1;
- tx_buffer_valid <= 1'b0;
- end
-
- if (tx_buffer_ready && mem_bus.request) begin
- tx_buffer_ready <= 1'b0;
- end
-
- if (mem_bus.ack) begin
- tx_wdata_first_push <= 1'b0;
- tx_buffer_counter <= 1'd1;
- tx_buffer_valid <= 1'b1;
- {fifo_bus.tx_wdata, tx_buffer} <= mem_bus.rdata;
- if (tx_wdata_first_push && dma_scb.starting_address[0]) begin
- fifo_bus.tx_wdata <= mem_bus.rdata[7:0];
- tx_buffer_counter <= 1'd0;
- end
- end
-
- if (tx_wdata_push) begin
- tx_buffer_counter <= tx_buffer_counter - 1'd1;
- fifo_bus.tx_wdata <= tx_buffer;
- if (tx_buffer_counter == 1'd0) begin
- tx_buffer_ready <= 1'b1;
- tx_buffer_valid <= 1'b0;
- end
- end
- end
-
-
- // Remaining counter controller
-
- always_ff @(posedge clk) begin
- if (reset || dma_stop) begin
- remaining <= 27'd0;
- end else begin
- if (dma_start) begin
- remaining <= dma_scb.transfer_length;
+ case (tx_fifo_bus_state)
+ TX_FIFO_BUS_STATE_IDLE: begin
+ if (dma_start && !dma_scb.direction) begin
+ next_tx_fifo_bus_state = TX_FIFO_BUS_STATE_WAIT;
+ end
end
- if ((mem_bus.write && rx_rdata_pop) || (!mem_bus.write && tx_wdata_push)) begin
- remaining <= remaining - 1'd1;
+ TX_FIFO_BUS_STATE_WAIT: begin
+ if (mem_bus_rdata_ack || tx_fifo_waiting) begin
+ next_tx_fifo_bus_state = TX_FIFO_BUS_STATE_TRANSFER_1;
+ end else if (mem_bus_rdata_end) begin
+ next_tx_fifo_bus_state = TX_FIFO_BUS_STATE_IDLE;
+ end
end
- end
- end
+ TX_FIFO_BUS_STATE_TRANSFER_1: begin
+ fifo_bus.tx_write = (!fifo_bus.tx_full && tx_fifo_valid[1]);
+ if (!fifo_bus.tx_full || !tx_fifo_valid[1]) begin
+ next_tx_fifo_bus_state = TX_FIFO_BUS_STATE_TRANSFER_2;
+ tx_fifo_shift = 1'b1;
+ end
+ end
- // Mem bus controller
-
- always_ff @(posedge clk) begin
- dma_scb.busy <= mem_bus.request || trx_enabled;
- end
-
- always_ff @(posedge clk) begin
- if (reset) begin
- mem_bus.request <= 1'b0;
- end else begin
- if (!mem_bus.request) begin
- if (mem_bus.write) begin
- if (rx_buffer_valid) begin
- mem_bus.request <= 1'b1;
- mem_bus.wmask <= rx_wmask;
- mem_bus.wdata <= rx_buffer;
- end
- end else begin
- if (tx_buffer_ready) begin
- mem_bus.request <= 1'b1;
+ TX_FIFO_BUS_STATE_TRANSFER_2: begin
+ fifo_bus.tx_write = (!fifo_bus.tx_full && tx_fifo_valid[1]);
+ if (!fifo_bus.tx_full || !tx_fifo_valid[1]) begin
+ next_tx_fifo_bus_state = TX_FIFO_BUS_STATE_WAIT;
+ tx_fifo_shift = 1'b1;
+ if (!mem_bus_rdata_ack && !tx_fifo_waiting && mem_bus_rdata_end) begin
+ next_tx_fifo_bus_state = TX_FIFO_BUS_STATE_IDLE;
end
end
end
- end
- if (mem_bus.ack) begin
- mem_bus.request <= 1'b0;
- end
+ default: begin
+ next_tx_fifo_bus_state = TX_FIFO_BUS_STATE_IDLE;
+ end
+ endcase
end
always_ff @(posedge clk) begin
- if (dma_start) begin
- mem_bus.write <= dma_scb.direction;
+ if (tx_fifo_shift) begin
+ tx_fifo_valid <= {tx_fifo_valid[0], 1'bX};
+ tx_fifo_buffer <= {tx_fifo_buffer[7:0], 8'hXX};
end
+
+ case (tx_fifo_bus_state)
+ TX_FIFO_BUS_STATE_IDLE: begin
+ mem_bus_rdata_ready <= 1'b0;
+ tx_fifo_waiting <= 1'b0;
+ if (dma_start) begin
+ mem_bus_rdata_ready <= !dma_scb.direction;
+ end
+ end
+
+ TX_FIFO_BUS_STATE_WAIT: begin
+ if (mem_bus_rdata_ack || tx_fifo_waiting) begin
+ mem_bus_rdata_ready <= 1'b0;
+ tx_fifo_waiting <= 1'b0;
+ tx_fifo_valid <= mem_bus_rdata_valid;
+ tx_fifo_buffer <= mem_bus_rdata_buffer;
+ end
+ end
+
+ TX_FIFO_BUS_STATE_TRANSFER_1: begin
+ if (mem_bus_rdata_ack) begin
+ tx_fifo_waiting <= 1'b1;
+ end
+ end
+
+ TX_FIFO_BUS_STATE_TRANSFER_2: begin
+ if (mem_bus_rdata_ack) begin
+ tx_fifo_waiting <= 1'b1;
+ end
+ if (fifo_bus.tx_write || !tx_fifo_valid[1]) begin
+ mem_bus_rdata_ready <= !mem_bus_rdata_end;
+ end
+ end
+
+ default: begin end
+ endcase
end
- always_ff @(posedge clk) begin
- if (dma_start) begin
- mem_bus.address <= {dma_scb.starting_address[26:1], 1'b0};
- end
- if (mem_bus.ack) begin
- mem_bus.address <= mem_bus.address + 2'd2;
- end
+ // DMA busy indicator
+
+ always_ff @(posedge clk) begin
+ dma_scb.busy <= (
+ (dma_scb.start && !dma_scb.stop) ||
+ dma_start ||
+ (mem_bus_state != MEM_BUS_STATE_IDLE) ||
+ (rx_fifo_bus_state != RX_FIFO_BUS_STATE_IDLE) ||
+ (tx_fifo_bus_state != TX_FIFO_BUS_STATE_IDLE)
+ );
end
endmodule
diff --git a/fw/rtl/memory/memory_sdram.sv b/fw/rtl/memory/memory_sdram.sv
index fce983a..0d4179b 100644
--- a/fw/rtl/memory/memory_sdram.sv
+++ b/fw/rtl/memory/memory_sdram.sv
@@ -14,29 +14,38 @@ module memory_sdram (
inout [15:0] sdram_dq
);
- localparam [2:0] CAS_LATENCY = 3'd2;
+ // in Hz
+ localparam real FREQUENCY = 100_000_000.0;
- localparam real T_INIT = 100_000.0;
- localparam real T_RC = 60.0;
- localparam real T_RP = 15.0;
- localparam real T_RCD = 15.0;
- localparam real T_MRD = 14.0;
- localparam real T_REF = 7_800.0;
+ // in clocks
+ localparam bit [2:0] CAS_LATENCY = 3'd2;
- localparam real T_CLK = (1.0 / 100_000_000) * 1_000_000_000.0;
- localparam int C_INIT = int'((T_INIT + T_CLK - 1) / T_CLK);
- localparam int C_RC = int'((T_RC + T_CLK - 1) / T_CLK);
- localparam int C_RP = int'((T_RP + T_CLK - 1) / T_CLK);
- localparam int C_RCD = int'((T_RCD + T_CLK - 1) / T_CLK);
- localparam int C_MRD = int'((T_MRD + T_CLK - 1) / T_CLK);
- localparam int C_REF = int'((T_REF + T_CLK - 1) / T_CLK);
+ // in nanoseconds
+ localparam real T_INIT = 100_000.0;
+ localparam real T_MRD = 14.0;
+ localparam real T_RAS = 37.0;
+ localparam real T_RC = 60.0;
+ localparam real T_RCD = 15.0;
+ localparam real T_REF = 7_812.5;
+ localparam real T_RP = 15.0;
- localparam INIT_PRECHARGE = 4'd0;
- localparam INIT_REFRESH_1 = C_RP;
- localparam INIT_REFRESH_2 = C_RP + C_RC;
- localparam INIT_MODE_REG = C_RP + (2 * C_RC);
- localparam INIT_DONE = C_RP + (2 * C_RC) + C_MRD;
+ localparam real T_CLK = (1.0 / FREQUENCY) * 1_000_000_000.0;
+ const bit [13:0] C_INIT = 14'(int'($ceil(T_INIT / T_CLK)));
+ const bit [4:0] C_MRD = 5'(int'($ceil(T_MRD / T_CLK)));
+ const bit [2:0] C_RAS = 3'(int'($ceil(T_RAS / T_CLK)));
+ const bit [4:0] C_RC = 5'(int'($ceil(T_RC / T_CLK)));
+ const bit [4:0] C_RCD = 5'(int'($ceil(T_RCD / T_CLK)));
+ const bit [13:0] C_REF = 14'(int'($ceil(T_REF / T_CLK)));
+ const bit [4:0] C_RP = 5'(int'($ceil(T_RP / T_CLK)));
+
+ const bit [4:0] INIT_PRECHARGE = 5'd0;
+ const bit [4:0] INIT_REFRESH_1 = INIT_PRECHARGE + C_RP;
+ const bit [4:0] INIT_REFRESH_2 = INIT_REFRESH_1 + C_RC;
+ const bit [4:0] INIT_MODE_REG = INIT_REFRESH_2 + C_RC;
+ const bit [4:0] INIT_DONE = INIT_MODE_REG + C_MRD;
+
+ // /CS, /RAS, /CAS, /WE
typedef enum bit [3:0] {
CMD_DESL = 4'b1111,
CMD_NOP = 4'b0111,
@@ -58,13 +67,10 @@ module memory_sdram (
always_ff @(posedge clk) begin
{sdram_cs, sdram_ras, sdram_cas, sdram_we} <= 4'(sdram_next_cmd);
-
{sdram_ba, sdram_a} <= 15'd0;
sdram_dqm <= 2'b00;
-
sdram_dq_input <= sdram_dq;
sdram_dq_output <= mem_bus.wdata;
-
sdram_dq_output_enable <= 1'b0;
case (sdram_next_cmd)
@@ -76,19 +82,31 @@ module memory_sdram (
CMD_ACT: begin
{sdram_ba, sdram_a} <= mem_bus.address[25:11];
- sdram_dqm <= 2'b00;
current_active_bank_row <= mem_bus.address[25:11];
end
CMD_PRE: begin
- {sdram_ba, sdram_a} <= {2'b00, 2'b00, 1'b1, 10'd0};
- sdram_dqm <= 2'b00;
+ {sdram_ba, sdram_a} <= {
+ 2'b00, // [BA1:BA0] Don't care
+ 2'b00, // [A12:A11] Don't care
+ 1'b1, // [A10] Precharge all banks
+ 10'd0 // [A9:A0] Don't care
+ };
end
CMD_MRS: begin
- {sdram_ba, sdram_a} <= {2'b00, 1'b0, 1'b0, 2'b00, CAS_LATENCY, 1'b0, 3'b000};
- sdram_dqm <= 2'b00;
+ {sdram_ba, sdram_a} <= {
+ 2'b00, // [BA1:BA0] Reserved = 0
+ 3'b000, // [A12:A10] Reserved = 0
+ 1'b0, // [A9] Write Burst Mode = Programmed Burst Length
+ 2'b00, // [A8:A7] Operating Mode = Standard Operation
+ CAS_LATENCY, // [A6:A4] Latency Mode = 2
+ 1'b0, // [A3] Burst Type = Sequential
+ 3'b000 // [A2:A0] Burst Length = 1
+ };
end
+
+ default: begin end
endcase
end
@@ -121,35 +139,51 @@ module memory_sdram (
end
end
- logic [13:0] powerup_coutner;
- logic powerup_done;
+ logic [13:0] refresh_counter;
logic [4:0] wait_counter;
- logic [9:0] refresh_counter;
+ logic [2:0] precharge_counter;
+ logic powerup_done;
logic pending_refresh;
+ logic precharge_valid;
always_ff @(posedge clk) begin
- if (reset) begin
- powerup_coutner <= 14'd0;
- powerup_done <= 1'b0;
- end else if (powerup_coutner < C_INIT) begin
- powerup_coutner <= powerup_coutner + 1'd1;
- end else begin
+ refresh_counter <= refresh_counter + 1'd1;
+
+ if (refresh_counter == C_INIT) begin
+ refresh_counter <= 14'd0;
powerup_done <= 1'b1;
end
- if (reset || state != next_state) begin
- wait_counter <= 5'd0;
- end else begin
- wait_counter <= wait_counter + 1'd1;
+ if (powerup_done && refresh_counter == C_REF - 14'd1) begin
+ refresh_counter <= 14'd0;
+ pending_refresh <= 1'b1;
end
if (sdram_next_cmd == CMD_REF) begin
- refresh_counter <= 10'd0;
pending_refresh <= 1'b0;
- end else if (refresh_counter < C_REF) begin
- refresh_counter <= refresh_counter + 1'd1;
- end else begin
- pending_refresh <= 1'b1;
+ end
+
+ if (reset) begin
+ refresh_counter <= 14'd0;
+ powerup_done <= 1'b0;
+ pending_refresh <= 1'b0;
+ end
+
+ wait_counter <= wait_counter + 1'd1;
+
+ if (state != next_state) begin
+ wait_counter <= 5'd0;
+ end
+
+ precharge_counter <= precharge_counter + 1'd1;
+
+ if (precharge_counter >= C_RAS - 2'd2) begin
+ precharge_valid <= 1'b1;
+ end
+
+ if (sdram_next_cmd == CMD_ACT) begin
+ precharge_counter <= 3'd0;
+ precharge_valid <= 1'b0;
end
end
@@ -157,6 +191,7 @@ module memory_sdram (
always_ff @(posedge clk) begin
mem_bus.ack <= 1'b0;
+
read_cmd_ack_delay <= {sdram_next_cmd == CMD_READ, read_cmd_ack_delay[(CAS_LATENCY):1]};
if (sdram_next_cmd == CMD_WRITE || read_cmd_ack_delay[0]) begin
@@ -202,20 +237,20 @@ module memory_sdram (
end
S_ACTIVATING: begin
- if (wait_counter == C_RCD) begin
+ if (wait_counter == C_RCD - 5'd2) begin
next_state = S_ACTIVE;
end
end
S_ACTIVE: begin
- if (pending_refresh) begin
+ if (pending_refresh && precharge_valid) begin
next_state = S_PRECHARGE;
sdram_next_cmd = CMD_PRE;
end else if (mem_bus.request) begin
if (request_in_current_active_bank_row) begin
next_state = S_BUSY;
sdram_next_cmd = mem_bus.write ? CMD_WRITE : CMD_READ;
- end else begin
+ end else if (precharge_valid) begin
next_state = S_PRECHARGE;
sdram_next_cmd = CMD_PRE;
end
@@ -229,18 +264,13 @@ module memory_sdram (
end
S_PRECHARGE: begin
- if (wait_counter == C_RP) begin
- if (pending_refresh) begin
- next_state = S_REFRESH;
- sdram_next_cmd = CMD_REF;
- end else begin
- next_state = S_IDLE;
- end
+ if (wait_counter == C_RP - 5'd2) begin
+ next_state = S_IDLE;
end
end
S_REFRESH: begin
- if (wait_counter == C_RC) begin
+ if (wait_counter == C_RC - 5'd2) begin
next_state = S_IDLE;
end
end
diff --git a/fw/rtl/sd/sd_dat.sv b/fw/rtl/sd/sd_dat.sv
index 419efa8..00c88c4 100644
--- a/fw/rtl/sd/sd_dat.sv
+++ b/fw/rtl/sd/sd_dat.sv
@@ -36,12 +36,10 @@ module sd_dat (
// FIFO
logic rx_full;
- logic rx_almost_full;
logic rx_write;
logic [7:0] rx_wdata;
logic tx_empty;
- logic tx_almost_empty;
logic tx_read;
logic [7:0] tx_rdata;
@@ -50,12 +48,10 @@ module sd_dat (
.reset(reset || sd_scb.dat_fifo_flush),
.empty(fifo_bus.rx_empty),
- .almost_empty(fifo_bus.rx_almost_empty),
.read(fifo_bus.rx_read),
.rdata(fifo_bus.rx_rdata),
.full(rx_full),
- .almost_full(rx_almost_full),
.write(rx_write),
.wdata(rx_wdata),
@@ -67,12 +63,10 @@ module sd_dat (
.reset(reset || sd_scb.dat_fifo_flush),
.empty(tx_empty),
- .almost_empty(tx_almost_empty),
.read(tx_read),
.rdata(tx_rdata),
.full(fifo_bus.tx_full),
- .almost_full(fifo_bus.tx_almost_full),
.write(fifo_bus.tx_write),
.wdata(fifo_bus.tx_wdata),
diff --git a/fw/rtl/usb/usb_ft1248.sv b/fw/rtl/usb/usb_ft1248.sv
index 9b2153b..fd3f3af 100644
--- a/fw/rtl/usb/usb_ft1248.sv
+++ b/fw/rtl/usb/usb_ft1248.sv
@@ -1,39 +1,3 @@
-interface usb_scb ();
-
- logic fifo_flush;
- logic reset_pending;
- logic reset_ack;
- logic write_buffer_flush;
- logic [10:0] rx_count;
- logic [10:0] tx_count;
- logic pwrsav;
- logic reset_state;
-
- modport controller (
- output fifo_flush,
- input reset_pending,
- output reset_ack,
- output write_buffer_flush,
- input rx_count,
- input tx_count,
- input pwrsav,
- input reset_state
- );
-
- modport usb (
- input fifo_flush,
- output reset_pending,
- input reset_ack,
- input write_buffer_flush,
- output rx_count,
- output tx_count,
- output pwrsav,
- output reset_state
- );
-
-endinterface
-
-
module usb_ft1248 (
input clk,
input reset,
@@ -50,27 +14,25 @@ module usb_ft1248 (
);
logic rx_full;
- logic rx_almost_full;
- logic rx_write;
+ logic rx_write_delayed;
logic [7:0] rx_wdata;
logic tx_empty;
- logic tx_almost_empty;
logic tx_read;
logic [7:0] tx_rdata;
+ logic fifo_flush;
+
fifo_8kb fifo_8kb_rx_inst (
.clk(clk),
- .reset(reset || usb_scb.fifo_flush),
+ .reset(fifo_flush),
.empty(fifo_bus.rx_empty),
- .almost_empty(fifo_bus.rx_almost_empty),
.read(fifo_bus.rx_read),
.rdata(fifo_bus.rx_rdata),
.full(rx_full),
- .almost_full(rx_almost_full),
- .write(rx_write),
+ .write(rx_write_delayed),
.wdata(rx_wdata),
.count(usb_scb.rx_count)
@@ -78,15 +40,13 @@ module usb_ft1248 (
fifo_8kb fifo_8kb_tx_inst (
.clk(clk),
- .reset(reset || usb_scb.fifo_flush),
+ .reset(fifo_flush),
.empty(tx_empty),
- .almost_empty(tx_almost_empty),
.read(tx_read),
.rdata(tx_rdata),
.full(fifo_bus.tx_full),
- .almost_full(fifo_bus.tx_almost_full),
.write(fifo_bus.tx_write),
.wdata(fifo_bus.tx_wdata),
@@ -140,9 +100,10 @@ module usb_ft1248 (
e_cmd cmd;
e_cmd next_cmd;
logic [3:0] phase;
+ logic rx_write;
+ logic last_rx_failed;
logic last_tx_failed;
logic reset_reply;
- logic last_reset_status;
logic [4:0] modem_status_counter;
logic write_modem_status_pending;
logic write_buffer_flush_pending;
@@ -152,7 +113,9 @@ module usb_ft1248 (
cmd <= next_cmd;
usb_scb.pwrsav <= !ft_pwrsav;
- usb_scb.reset_state <= last_reset_status;
+ fifo_flush <= 1'b0;
+
+ rx_write_delayed <= rx_write;
phase <= {phase[2:0], phase[3]};
if (state == STATE_IDLE) begin
@@ -160,25 +123,49 @@ module usb_ft1248 (
end
if (reset) begin
+ usb_scb.fifo_flush_busy <= 1'b0;
+ usb_scb.reset_state <= 1'b0;
+ last_rx_failed <= 1'b0;
last_tx_failed <= 1'b0;
- usb_scb.reset_pending <= 1'b0;
- last_reset_status <= 1'b0;
+ reset_reply <= 1'b0;
modem_status_counter <= 5'd0;
- write_modem_status_pending <= 1'b0;
+ write_modem_status_pending <= 1'b1;
write_buffer_flush_pending <= 1'b0;
end else begin
- if (usb_scb.reset_ack) begin
- usb_scb.reset_pending <= 1'b0;
+ if (usb_scb.fifo_flush) begin
+ usb_scb.fifo_flush_busy <= 1'b1;
+ end
+
+ if (usb_scb.reset_on_ack) begin
reset_reply <= 1'b1;
write_modem_status_pending <= 1'b1;
end
+ if (usb_scb.reset_off_ack) begin
+ reset_reply <= 1'b0;
+ write_modem_status_pending <= 1'b1;
+ end
+
if (usb_scb.write_buffer_flush) begin
write_buffer_flush_pending <= 1'b1;
end
if (state == STATE_IDLE) begin
modem_status_counter <= modem_status_counter + 1'd1;
+ if (usb_scb.fifo_flush_busy) begin
+ usb_scb.fifo_flush_busy <= 1'b0;
+ fifo_flush <= 1'b1;
+ last_rx_failed <= 1'b0;
+ last_tx_failed <= 1'b0;
+ end else if (last_rx_failed && !rx_full) begin
+ last_rx_failed <= 1'b0;
+ rx_write_delayed <= 1'b1;
+ end
+ end
+
+ if ((state == STATE_DATA) && (cmd == CMD_READ) && phase[3]) begin
+ rx_wdata <= ft_miosi_in;
+ last_rx_failed <= !ft_miso && rx_full;
end
if ((state == STATE_DATA) && (cmd == CMD_WRITE) && phase[3]) begin
@@ -187,14 +174,7 @@ module usb_ft1248 (
if (!ft_miso && (state == STATE_DATA) && phase[3]) begin
if (cmd == CMD_READ_MODEM_STATUS) begin
- last_reset_status <= ft_miosi_in[0];
- if (!last_reset_status && ft_miosi_in[0]) begin
- usb_scb.reset_pending <= 1'b1;
- end
- if (last_reset_status && !ft_miosi_in[0]) begin
- reset_reply <= 1'b0;
- write_modem_status_pending <= 1'b1;
- end
+ usb_scb.reset_state <= ft_miosi_in[0];
end
if (cmd == CMD_WRITE_MODEM_STATUS) begin
write_modem_status_pending <= 1'b0;
@@ -252,8 +232,6 @@ module usb_ft1248 (
rx_write = 1'b0;
tx_read = 1'b0;
- rx_wdata = ft_miosi_in;
-
if (!ft_miso && phase[3]) begin
case (state)
STATE_STATUS: begin
@@ -263,13 +241,15 @@ module usb_ft1248 (
end
STATE_DATA: begin
- if (cmd == CMD_READ) begin
+ if (cmd == CMD_READ && !rx_full) begin
rx_write = 1'b1;
end
if (cmd == CMD_WRITE && !tx_empty) begin
tx_read = 1'b1;
end
end
+
+ default: begin end
endcase
end
end
@@ -283,7 +263,7 @@ module usb_ft1248 (
end else begin
case (state)
STATE_IDLE: begin
- if (ft_pwrsav) begin
+ if (ft_pwrsav && !(usb_scb.fifo_flush || usb_scb.fifo_flush_busy || fifo_flush)) begin
if (write_modem_status_pending) begin
next_state = STATE_SELECT;
next_cmd = CMD_WRITE_MODEM_STATUS;
@@ -330,7 +310,7 @@ module usb_ft1248 (
if (ft_miso) begin
next_state = STATE_DESELECT;
end else if (cmd == CMD_READ) begin
- if (rx_almost_full) begin
+ if (rx_full) begin
next_state = STATE_DESELECT;
end
end else if (cmd == CMD_WRITE) begin
diff --git a/fw/rtl/usb/usb_scb.sv b/fw/rtl/usb/usb_scb.sv
new file mode 100644
index 0000000..b2a322d
--- /dev/null
+++ b/fw/rtl/usb/usb_scb.sv
@@ -0,0 +1,37 @@
+interface usb_scb ();
+
+ logic fifo_flush;
+ logic fifo_flush_busy;
+ logic write_buffer_flush;
+ logic [10:0] rx_count;
+ logic [10:0] tx_count;
+ logic pwrsav;
+ logic reset_state;
+ logic reset_on_ack;
+ logic reset_off_ack;
+
+ modport controller (
+ output fifo_flush,
+ input fifo_flush_busy,
+ output write_buffer_flush,
+ input rx_count,
+ input tx_count,
+ input pwrsav,
+ input reset_state,
+ output reset_on_ack,
+ output reset_off_ack
+ );
+
+ modport usb (
+ input fifo_flush,
+ output fifo_flush_busy,
+ input write_buffer_flush,
+ output rx_count,
+ output tx_count,
+ output pwrsav,
+ output reset_state,
+ input reset_on_ack,
+ input reset_off_ack
+ );
+
+endinterface
diff --git a/fw/rtl/vendor/lcmxo2/fifo_8kb.sv b/fw/rtl/vendor/lcmxo2/fifo_8kb.sv
index db02ad2..05fb8b3 100644
--- a/fw/rtl/vendor/lcmxo2/fifo_8kb.sv
+++ b/fw/rtl/vendor/lcmxo2/fifo_8kb.sv
@@ -3,18 +3,19 @@ module fifo_8kb (
input reset,
output empty,
- output almost_empty,
input read,
output [7:0] rdata,
output full,
- output almost_full,
input write,
input [7:0] wdata,
-
+
output logic [10:0] count
);
+ logic almost_empty;
+ logic almost_full;
+
fifo_8kb_lattice_generated fifo_8kb_lattice_generated_inst (
.Data(wdata),
.WrClock(clk),
@@ -25,7 +26,7 @@ module fifo_8kb (
.RPReset(reset),
.Q(rdata),
.Empty(empty),
- .Full(full),
+ .Full(full),
.AlmostEmpty(almost_empty),
.AlmostFull(almost_full)
);
diff --git a/fw/tests/.gitignore b/fw/tests/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/fw/tests/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/fw/tests/Makefile b/fw/tests/Makefile
new file mode 100644
index 0000000..42e11a1
--- /dev/null
+++ b/fw/tests/Makefile
@@ -0,0 +1,35 @@
+RTL_DIR = ../rtl
+BENCHES_DIR = benches
+MOCKS_DIR = mocks
+BUILD_DIR = build
+SRC_DIRS = \
+ $(RTL_DIR)/fifo \
+ $(RTL_DIR)/mcu \
+ $(RTL_DIR)/memory \
+ $(RTL_DIR)/n64 \
+ $(RTL_DIR)/sd \
+ $(RTL_DIR)/serv \
+ $(RTL_DIR)/usb \
+ $(RTL_DIR)/vendor \
+ $(RTL_DIR) \
+ $(MOCKS_DIR)/vendor \
+ $(MOCKS_DIR)
+
+INC_DIRS = $(addprefix -I, $(SRC_DIRS))
+TEST_FILES = $(shell find "./$(BENCHES_DIR)" -not -path "$(BUILD_DIR)/*" -type f -name "*_tb.sv")
+TESTS = $(addprefix $(BUILD_DIR)/, $(basename $(TEST_FILES)))
+
+VERILATOR_FLAGS = --binary --trace --timescale 10ns/1ns -j --quiet $(INC_DIRS)
+
+$(BUILD_DIR)/%: %.sv
+ @echo "[VERILATOR] $<"
+ @mkdir -p $@.obj
+ @verilator $(VERILATOR_FLAGS) -Mdir $@.obj $< > /dev/null
+ @$@.obj/V$(notdir $@)
+
+tests: $(TESTS)
+
+clean:
+ @rm -rf ./$(BUILD_DIR)
+
+.PHONY: tests
diff --git a/fw/tests/benches/memory_dma_tb.sv b/fw/tests/benches/memory_dma_tb.sv
new file mode 100644
index 0000000..f07efc0
--- /dev/null
+++ b/fw/tests/benches/memory_dma_tb.sv
@@ -0,0 +1,126 @@
+module memory_dma_tb;
+
+ logic clk;
+ logic reset;
+
+ dma_scb dma_scb ();
+ fifo_bus fifo_bus ();
+ mem_bus mem_bus ();
+
+ logic start;
+ logic stop;
+ logic direction;
+ logic byte_swap;
+ logic [26:0] starting_address;
+ logic [26:0] transfer_length;
+
+ logic flush;
+ logic rx_fill_enabled;
+ logic tx_drain_enabled;
+
+ memory_dma memory_dma (
+ .clk(clk),
+ .reset(reset),
+
+ .dma_scb(dma_scb),
+ .fifo_bus(fifo_bus),
+ .mem_bus(mem_bus)
+ );
+
+ dma_controller_mock dma_controller_mock (
+ .clk(clk),
+ .reset(reset),
+
+ .dma_scb(dma_scb),
+
+ .start(start),
+ .stop(stop),
+ .direction(direction),
+ .byte_swap(byte_swap),
+ .starting_address(starting_address),
+ .transfer_length(transfer_length)
+ );
+
+ fifo_bus_fifo_mock #(
+ .DEPTH(8),
+ .FILL_RATE(3),
+ .DRAIN_RATE(3)
+ ) fifo_bus_fifo_mock (
+ .clk(clk),
+ .reset(reset),
+
+ .fifo_bus(fifo_bus),
+
+ .flush(flush),
+
+ .rx_fill_enabled(rx_fill_enabled),
+ .tx_drain_enabled(tx_drain_enabled)
+ );
+
+ memory_sdram_mock memory_sdram_mock (
+ .clk(clk),
+ .reset(reset),
+
+ .mem_bus(mem_bus)
+ );
+
+ initial begin
+ clk = 1'b0;
+ forever begin
+ clk = ~clk; #0.5;
+ end
+ end
+
+ initial begin
+ reset = 1'b0;
+ #10;
+ reset = 1'b1;
+ #10;
+ reset = 1'b0;
+ end
+
+ initial begin
+ $dumpfile("traces/memory_dma_tb.vcd");
+
+ #10000;
+
+ $dumpvars();
+
+ #100;
+ start = 1'b1;
+ direction = 1'b0;
+ byte_swap = 1'b0;
+ starting_address = 27'hFFF1;
+ transfer_length = 27'd64;
+ #1;
+ start = 1'b0;
+
+ #9;
+ tx_drain_enabled = 1'b1;
+
+ #490;
+ stop = 1'b1;
+ #1;
+ stop = 1'b0;
+
+ #165;
+
+ start = 1'b1;
+ direction = 1'b1;
+ #1;
+ start = 1'b0;
+
+ #9;
+ rx_fill_enabled = 1'b1;
+
+ #490;
+ stop = 1'b1;
+ #1;
+ stop = 1'b0;
+
+ #99;
+
+ $finish;
+ end
+
+endmodule
diff --git a/fw/tests/benches/usb_ft1248_tb.sv b/fw/tests/benches/usb_ft1248_tb.sv
new file mode 100644
index 0000000..8c62dd5
--- /dev/null
+++ b/fw/tests/benches/usb_ft1248_tb.sv
@@ -0,0 +1,119 @@
+module usb_ft1248_tb;
+
+ logic clk;
+ logic reset;
+
+ usb_scb usb_scb ();
+ fifo_bus fifo_bus ();
+
+ logic usb_pwrsav;
+ logic usb_clk;
+ logic usb_cs;
+ logic usb_miso;
+ logic [7:0] usb_miosi;
+
+ usb_ft1248 usb_ft1248 (
+ .clk(clk),
+ .reset(reset),
+ .usb_scb(usb_scb),
+ .fifo_bus(fifo_bus),
+ .usb_pwrsav(usb_pwrsav),
+ .usb_clk(usb_clk),
+ .usb_cs(usb_cs),
+ .usb_miso(usb_miso),
+ .usb_miosi(usb_miosi)
+ );
+
+ initial begin
+ clk = 1'b0;
+ forever begin
+ clk = ~clk; #0.5;
+ end
+ end
+
+ initial begin
+ reset = 1'b1;
+ #10;
+ reset = 1'b0;
+ end
+
+ initial begin
+ $dumpfile("traces/usb_ft1248_tb.vcd");
+
+ $dumpvars();
+
+ usb_pwrsav = 1'b1;
+ usb_miso = 1'b1;
+
+ #100;
+
+ fifo_bus.tx_write = 1'b1;
+ #100;
+ fifo_bus.tx_write = 1'b0;
+
+ #103;
+
+ usb_miso = 1'b0;
+ #80;
+ usb_scb.write_buffer_flush = 1'b1;
+ #1;
+ usb_scb.write_buffer_flush = 1'b0;
+ #20;
+ usb_miso = 1'b1;
+ #26;
+ usb_miso = 1'b0;
+
+ #4430;
+
+ usb_miso = 1'b1;
+ #13;
+ usb_miso = 1'b0;
+
+ #79;
+
+ fifo_bus.rx_read = 1'b1;
+ #1;
+ fifo_bus.rx_read = 1'b0;
+
+ #10;
+
+ fifo_bus.rx_read = 1'b1;
+ #1;
+ fifo_bus.rx_read = 1'b0;
+
+ #80;
+
+ fifo_bus.rx_read = 1'b1;
+ #1;
+ fifo_bus.rx_read = 1'b0;
+
+ #200;
+
+ usb_scb.reset_on_ack = 1'b1;
+ #1;
+ usb_scb.reset_on_ack = 1'b0;
+
+ #200;
+
+ usb_scb.reset_off_ack = 1'b1;
+ #1;
+ usb_scb.reset_off_ack = 1'b0;
+
+ #200;
+
+ usb_scb.fifo_flush = 1'b1;
+ #1;
+ usb_scb.fifo_flush = 1'b0;
+
+ #3000;
+
+ usb_scb.fifo_flush = 1'b1;
+ #1;
+ usb_scb.fifo_flush = 1'b0;
+
+ #6000;
+
+ $finish;
+ end
+
+endmodule
diff --git a/fw/tests/docker_run.sh b/fw/tests/docker_run.sh
new file mode 100755
index 0000000..908d27e
--- /dev/null
+++ b/fw/tests/docker_run.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+
+pushd $(dirname $0) > /dev/null
+
+docker run \
+ -it \
+ --rm \
+ --user $(id -u):$(id -g) \
+ -v "$(pwd)":/work \
+ -v "$(pwd)/../rtl":/rtl \
+ -e CCACHE_DIR=/tmp/ccache \
+ --entrypoint /bin/bash \
+ verilator/verilator:latest \
+ -c "make -j"
+
+BUILD_ERROR=$?
+
+popd > /dev/null
+
+if [ $BUILD_ERROR -ne 0 ]; then
+ exit -1
+fi
diff --git a/fw/tests/mocks/dma_controller_mock.sv b/fw/tests/mocks/dma_controller_mock.sv
new file mode 100644
index 0000000..d1d3b54
--- /dev/null
+++ b/fw/tests/mocks/dma_controller_mock.sv
@@ -0,0 +1,39 @@
+module dma_controller_mock (
+ input clk,
+ input reset,
+
+ dma_scb.controller dma_scb,
+
+ input start,
+ input stop,
+ input direction,
+ input byte_swap,
+ input [26:0] starting_address,
+ input [26:0] transfer_length
+);
+
+ always_ff @(posedge clk) begin
+ dma_scb.start <= 1'b0;
+ dma_scb.stop <= 1'b0;
+
+ if (reset) begin
+ dma_scb.direction <= 1'b0;
+ dma_scb.byte_swap <= 1'b0;
+ dma_scb.starting_address <= 27'd0;
+ dma_scb.transfer_length <= 27'd0;
+ end else begin
+ if (start) begin
+ dma_scb.start <= 1'b1;
+ dma_scb.direction <= direction;
+ dma_scb.byte_swap <= byte_swap;
+ dma_scb.starting_address <= starting_address;
+ dma_scb.transfer_length <= transfer_length;
+ end
+
+ if (stop) begin
+ dma_scb.stop <= 1'b1;
+ end
+ end
+ end
+
+endmodule
diff --git a/fw/tests/mocks/fifo_bus_fifo_mock.sv b/fw/tests/mocks/fifo_bus_fifo_mock.sv
new file mode 100644
index 0000000..2fc57de
--- /dev/null
+++ b/fw/tests/mocks/fifo_bus_fifo_mock.sv
@@ -0,0 +1,145 @@
+module fifo_bus_fifo_mock #(
+ parameter int DEPTH = 1024,
+ parameter int FILL_RATE = 3,
+ parameter int DRAIN_RATE = 3
+) (
+ input clk,
+ input reset,
+
+ fifo_bus.fifo fifo_bus,
+
+ input flush,
+
+ input rx_fill_enabled,
+ input tx_drain_enabled
+);
+
+ localparam int PTR_BITS = $clog2(DEPTH);
+
+
+ // RX FIFO mock
+
+ logic rx_full;
+ logic rx_write;
+ logic [7:0] rx_wdata;
+
+ logic [PTR_BITS:0] rx_count;
+
+ fifo_mock #(
+ .DEPTH(DEPTH)
+ ) fifo_rx (
+ .clk(clk),
+ .reset(reset),
+
+ .empty(fifo_bus.rx_empty),
+ .read(fifo_bus.rx_read),
+ .rdata(fifo_bus.rx_rdata),
+
+ .full(rx_full),
+ .write(rx_write),
+ .wdata(rx_wdata),
+
+ .count(rx_count)
+ );
+
+ localparam int FILL_BITS = $clog2(FILL_RATE);
+ logic [FILL_BITS:0] fill_counter;
+ logic rx_fill;
+
+ always_ff @(posedge clk) begin
+ rx_fill <= rx_fill_enabled;
+ end
+
+ generate;
+ if (FILL_RATE == 0) begin
+ always_comb begin
+ rx_write = rx_fill && !rx_full;
+ end
+ end else begin
+ always_comb begin
+ rx_write = rx_fill && !rx_full && (fill_counter == (FILL_BITS + 1)'(FILL_RATE));
+ end
+ always_ff @(posedge clk) begin
+ if (fill_counter < (FILL_BITS + 1)'(FILL_RATE)) begin
+ fill_counter <= fill_counter + (FILL_BITS + 1)'('d1);
+ end
+ if (reset) begin
+ fill_counter <= (FILL_BITS + 1)'('d0);
+ end else begin
+ if (rx_write) begin
+ fill_counter <= (FILL_BITS + 1)'('d0);
+ end
+ end
+ end
+ end
+ endgenerate
+
+ always_ff @(posedge clk) begin
+ if (reset) begin
+ rx_wdata <= 8'h01;
+ end else begin
+ if (rx_write) begin
+ rx_wdata <= rx_wdata + 8'h01;
+ end
+ end
+ end
+
+
+ // TX FIFO mock
+
+ logic tx_empty;
+ logic tx_read;
+ logic [7:0] tx_rdata;
+
+ logic [PTR_BITS:0] tx_count;
+
+ fifo_mock #(
+ .DEPTH(DEPTH)
+ ) fifo_tx (
+ .clk(clk),
+ .reset(reset),
+
+ .empty(tx_empty),
+ .read(tx_read),
+ .rdata(tx_rdata),
+
+ .full(fifo_bus.tx_full),
+ .write(fifo_bus.tx_write),
+ .wdata(fifo_bus.tx_wdata),
+
+ .count(tx_count)
+ );
+
+ localparam int DRAIN_BITS = $clog2(DRAIN_RATE);
+ logic [DRAIN_BITS:0] drain_counter;
+ logic tx_drain;
+
+ always_ff @(posedge clk) begin
+ tx_drain <= tx_drain_enabled;
+ end
+
+ generate;
+ if (DRAIN_RATE == 0) begin
+ always_comb begin
+ tx_read = tx_drain && !tx_empty;
+ end
+ end else begin
+ always_comb begin
+ tx_read = tx_drain && !tx_empty && (drain_counter == (DRAIN_BITS + 1)'(DRAIN_RATE));
+ end
+ always_ff @(posedge clk) begin
+ if (drain_counter < (DRAIN_BITS + 1)'(DRAIN_RATE)) begin
+ drain_counter <= drain_counter + (DRAIN_BITS + 1)'('d1);
+ end
+ if (reset) begin
+ drain_counter <= (DRAIN_BITS + 1)'('d0);
+ end else begin
+ if (tx_read) begin
+ drain_counter <= (DRAIN_BITS + 1)'('d0);
+ end
+ end
+ end
+ end
+ endgenerate
+
+endmodule
diff --git a/fw/tests/mocks/fifo_mock.sv b/fw/tests/mocks/fifo_mock.sv
new file mode 100644
index 0000000..acf9065
--- /dev/null
+++ b/fw/tests/mocks/fifo_mock.sv
@@ -0,0 +1,49 @@
+module fifo_mock #(
+ parameter int DEPTH = 1024,
+ localparam int PTR_BITS = $clog2(DEPTH)
+) (
+ input clk,
+ input reset,
+
+ output logic empty,
+ input read,
+ output [7:0] rdata,
+
+ output logic full,
+ input write,
+ input [7:0] wdata,
+
+ output logic [PTR_BITS:0] count
+);
+
+ logic [7:0] fifo_mem [0:(DEPTH - 1)];
+ logic [(PTR_BITS - 1):0] fifo_rptr;
+ logic [(PTR_BITS - 1):0] fifo_wptr;
+
+ always_comb begin
+ full = count >= (PTR_BITS + 1)'(DEPTH);
+ empty = count == (PTR_BITS + 1)'('d0);
+ end
+
+ always_ff @(posedge clk) begin
+ if (read) begin
+ rdata <= fifo_mem[fifo_rptr];
+ fifo_rptr <= fifo_rptr + PTR_BITS'('d1);
+ count <= count - (PTR_BITS + 1)'('d1);
+ end
+ if (write) begin
+ fifo_mem[fifo_wptr] <= wdata;
+ fifo_wptr <= fifo_wptr + PTR_BITS'('d1);
+ count <= count + (PTR_BITS + 1)'('d1);
+ end
+ if (read && write) begin
+ count <= count;
+ end
+ if (reset) begin
+ count <= (PTR_BITS + 1)'('d0);
+ fifo_rptr <= PTR_BITS'('d0);
+ fifo_wptr <= PTR_BITS'('d0);
+ end
+ end
+
+endmodule
diff --git a/fw/tests/mocks/memory_sdram_mock.sv b/fw/tests/mocks/memory_sdram_mock.sv
new file mode 100644
index 0000000..9f5d34a
--- /dev/null
+++ b/fw/tests/mocks/memory_sdram_mock.sv
@@ -0,0 +1,70 @@
+module memory_sdram_mock (
+ input clk,
+ input reset,
+
+ mem_bus.memory mem_bus
+);
+
+ logic sdram_cs;
+ logic sdram_ras;
+ logic sdram_cas;
+ logic sdram_we;
+ logic [1:0] sdram_ba;
+ logic [12:0] sdram_a;
+ logic [1:0] sdram_dqm;
+ logic [15:0] sdram_dq;
+
+ memory_sdram memory_sdram_inst (
+ .clk(clk),
+ .reset(reset),
+
+ .mem_bus(mem_bus),
+
+ .sdram_cs(sdram_cs),
+ .sdram_ras(sdram_ras),
+ .sdram_cas(sdram_cas),
+ .sdram_we(sdram_we),
+ .sdram_ba(sdram_ba),
+ .sdram_a(sdram_a),
+ .sdram_dqm(sdram_dqm),
+ .sdram_dq(sdram_dq)
+ );
+
+ logic [1:0] cas_delay;
+ logic [15:0] data_from_sdram;
+ logic [15:0] data_to_sdram;
+ logic [15:0] sdram_dq_driven;
+
+ assign sdram_dq = sdram_dq_driven;
+
+ always_ff @(posedge clk) begin
+ if (reset) begin
+ cas_delay <= 2'b00;
+ data_from_sdram <= 16'h0102;
+ data_to_sdram <= 16'hFFFF;
+ end else begin
+ cas_delay <= {cas_delay[0], 1'b0};
+
+ if ({sdram_cs, sdram_ras, sdram_cas, sdram_we} == 4'b0101) begin
+ cas_delay[0] <= 1'b1;
+ end
+
+ if (cas_delay[1]) begin
+ data_from_sdram <= data_from_sdram + 16'h0202;
+ end
+
+ if ({sdram_cs, sdram_ras, sdram_cas, sdram_we} == 4'b0100) begin
+ if (!sdram_dqm[0]) data_to_sdram[7:0] <= sdram_dq[7:0];
+ if (!sdram_dqm[1]) data_to_sdram[15:8] <= sdram_dq[15:8];
+ end
+ end
+ end
+
+ always_comb begin
+ sdram_dq_driven = 16'hXXXX;
+ if (cas_delay[1]) begin
+ sdram_dq_driven = data_from_sdram;
+ end
+ end
+
+endmodule
diff --git a/fw/tests/mocks/vendor/fifo_8kb.sv b/fw/tests/mocks/vendor/fifo_8kb.sv
new file mode 100644
index 0000000..f20105b
--- /dev/null
+++ b/fw/tests/mocks/vendor/fifo_8kb.sv
@@ -0,0 +1,33 @@
+module fifo_8kb (
+ input clk,
+ input reset,
+
+ output empty,
+ input read,
+ output [7:0] rdata,
+
+ output full,
+ input write,
+ input [7:0] wdata,
+
+ output logic [10:0] count
+);
+
+ fifo_mock #(
+ .DEPTH(1024)
+ ) fifo_8kb (
+ .clk(clk),
+ .reset(reset),
+
+ .empty(empty),
+ .read(read),
+ .rdata(rdata),
+
+ .full(full),
+ .write(write),
+ .wdata(wdata),
+
+ .count(count)
+ );
+
+endmodule
diff --git a/fw/tests/traces/.gitignore b/fw/tests/traces/.gitignore
new file mode 100644
index 0000000..6167be1
--- /dev/null
+++ b/fw/tests/traces/.gitignore
@@ -0,0 +1,2 @@
+*.vcd
+*.gtkw
diff --git a/hw/shell/button/sc64_shell_button_b3fs-105x_with_end_stop.step b/hw/shell/button/sc64_shell_button_b3fs-105x_with_end_stop.step
index 6c2f52b..02e00b6 100644
--- a/hw/shell/button/sc64_shell_button_b3fs-105x_with_end_stop.step
+++ b/hw/shell/button/sc64_shell_button_b3fs-105x_with_end_stop.step
@@ -9,12 +9,12 @@ FILE_DESCRIPTION(
/* implementation_level */ '2;1');
FILE_NAME(
-/* name */ 'sc64_button with end stop.step',
-/* time_stamp */ '2024-02-29T20:34:23-06:00',
+/* name */ 'button v1.step',
+/* time_stamp */ '2024-07-07T13:11:13-04:00',
/* author */ (''),
/* organization */ (''),
/* preprocessor_version */ 'ST-DEVELOPER v20',
-/* originating_system */ 'Autodesk Translation Framework v12.14.0.127',
+/* originating_system */ 'Autodesk Translation Framework v13.14.0.145',
/* authorisation */ '');
@@ -22,1052 +22,1346 @@ FILE_SCHEMA (('AUTOMOTIVE_DESIGN { 1 0 10303 214 3 1 1 }'));
ENDSEC;
DATA;
-#10=MECHANICAL_DESIGN_GEOMETRIC_PRESENTATION_REPRESENTATION('',(#13),#932);
-#11=SHAPE_REPRESENTATION_RELATIONSHIP('SRR','None',#938,#12);
-#12=ADVANCED_BREP_SHAPE_REPRESENTATION('',(#14),#931);
-#13=STYLED_ITEM('',(#950),#14);
-#14=MANIFOLD_SOLID_BREP('ButtonCap',#527);
-#15=ELLIPSE('',#564,57.3219678278922,3.);
-#16=ELLIPSE('',#566,57.3219678278922,3.);
-#17=ELLIPSE('',#567,57.3219678278922,3.);
-#18=ELLIPSE('',#569,57.3219678278922,3.);
-#19=CYLINDRICAL_SURFACE('',#563,3.);
-#20=B_SPLINE_CURVE_WITH_KNOTS('',3,(#822,#823,#824,#825,#826,#827,#828,
-#829,#830,#831),.UNSPECIFIED.,.F.,.F.,(4,2,2,2,4),(0.152690815970772,0.170769832092777,
-0.189403419448823,0.208859780179844,0.228997077857732),.UNSPECIFIED.);
-#21=B_SPLINE_CURVE_WITH_KNOTS('',3,(#834,#835,#836,#837,#838,#839,#840,
-#841,#842,#843),.UNSPECIFIED.,.F.,.F.,(4,2,2,2,4),(0.0765657026251719,0.0967030003030594,
-0.11615936103408,0.134792948390126,0.152871964512132),.UNSPECIFIED.);
-#22=B_SPLINE_CURVE_WITH_KNOTS('',3,(#850,#851,#852,#853,#854,#855,#856,
-#857,#858,#859),.UNSPECIFIED.,.F.,.F.,(4,2,2,2,4),(0.152690815970771,0.170769832092777,
-0.189403419448823,0.208859780179844,0.228997077857731),.UNSPECIFIED.);
-#23=B_SPLINE_CURVE_WITH_KNOTS('',3,(#861,#862,#863,#864,#865,#866,#867,
-#868,#869,#870),.UNSPECIFIED.,.F.,.F.,(4,2,2,2,4),(0.0765657026251716,0.0967030003030594,
-0.11615936103408,0.134792948390127,0.152871964512132),.UNSPECIFIED.);
-#24=TOROIDAL_SURFACE('',#550,3.5,0.5);
-#25=TOROIDAL_SURFACE('',#555,3.5,0.5);
-#26=TOROIDAL_SURFACE('',#558,2.5,0.5);
-#27=CONICAL_SURFACE('',#534,4.,0.0872664625997165);
-#28=CONICAL_SURFACE('',#547,4.,0.0872664625997165);
-#29=CIRCLE('',#531,3.5);
-#30=CIRCLE('',#533,3.5);
-#31=CIRCLE('',#535,4.);
-#32=CIRCLE('',#536,4.06561649764444);
-#33=CIRCLE('',#539,3.5);
-#34=CIRCLE('',#542,3.5);
-#35=CIRCLE('',#544,3.5);
-#36=CIRCLE('',#546,4.06561649764444);
-#37=CIRCLE('',#548,4.);
-#38=CIRCLE('',#551,3.5);
-#39=CIRCLE('',#552,3.);
-#40=CIRCLE('',#553,3.);
-#41=CIRCLE('',#556,3.);
-#42=CIRCLE('',#559,2.5);
-#43=CIRCLE('',#560,0.5);
-#44=CIRCLE('',#561,3.);
-#45=CIRCLE('',#565,3.);
-#46=CIRCLE('',#568,3.);
-#47=FACE_OUTER_BOUND('',#77,.T.);
-#48=FACE_OUTER_BOUND('',#78,.T.);
-#49=FACE_OUTER_BOUND('',#79,.T.);
-#50=FACE_OUTER_BOUND('',#80,.T.);
-#51=FACE_OUTER_BOUND('',#81,.T.);
-#52=FACE_OUTER_BOUND('',#82,.T.);
-#53=FACE_OUTER_BOUND('',#83,.T.);
-#54=FACE_OUTER_BOUND('',#84,.T.);
-#55=FACE_OUTER_BOUND('',#85,.T.);
-#56=FACE_OUTER_BOUND('',#86,.T.);
-#57=FACE_OUTER_BOUND('',#87,.T.);
-#58=FACE_OUTER_BOUND('',#88,.T.);
-#59=FACE_OUTER_BOUND('',#89,.T.);
-#60=FACE_OUTER_BOUND('',#90,.T.);
-#61=FACE_OUTER_BOUND('',#91,.T.);
-#62=FACE_OUTER_BOUND('',#92,.T.);
-#63=FACE_OUTER_BOUND('',#93,.T.);
-#64=FACE_OUTER_BOUND('',#94,.T.);
-#65=FACE_OUTER_BOUND('',#95,.T.);
-#66=FACE_OUTER_BOUND('',#96,.T.);
-#67=FACE_OUTER_BOUND('',#97,.T.);
-#68=FACE_OUTER_BOUND('',#98,.T.);
-#69=FACE_OUTER_BOUND('',#99,.T.);
-#70=FACE_OUTER_BOUND('',#100,.T.);
-#71=FACE_OUTER_BOUND('',#101,.T.);
-#72=FACE_OUTER_BOUND('',#102,.T.);
-#73=FACE_OUTER_BOUND('',#103,.T.);
-#74=FACE_OUTER_BOUND('',#104,.T.);
-#75=FACE_OUTER_BOUND('',#105,.T.);
-#76=FACE_OUTER_BOUND('',#106,.T.);
-#77=EDGE_LOOP('',(#323,#324,#325,#326,#327,#328,#329,#330));
-#78=EDGE_LOOP('',(#331,#332,#333,#334));
-#79=EDGE_LOOP('',(#335,#336,#337,#338));
-#80=EDGE_LOOP('',(#339,#340,#341,#342));
-#81=EDGE_LOOP('',(#343,#344,#345,#346));
-#82=EDGE_LOOP('',(#347,#348,#349,#350));
-#83=EDGE_LOOP('',(#351,#352,#353,#354,#355,#356,#357,#358));
-#84=EDGE_LOOP('',(#359,#360,#361,#362));
-#85=EDGE_LOOP('',(#363,#364,#365,#366));
-#86=EDGE_LOOP('',(#367,#368));
-#87=EDGE_LOOP('',(#369,#370,#371,#372));
-#88=EDGE_LOOP('',(#373,#374,#375,#376));
-#89=EDGE_LOOP('',(#377,#378,#379,#380,#381,#382,#383));
-#90=EDGE_LOOP('',(#384,#385,#386,#387));
-#91=EDGE_LOOP('',(#388,#389,#390,#391,#392,#393));
-#92=EDGE_LOOP('',(#394,#395));
-#93=EDGE_LOOP('',(#396,#397,#398,#399));
-#94=EDGE_LOOP('',(#400));
-#95=EDGE_LOOP('',(#401,#402,#403,#404,#405,#406,#407,#408,#409,#410,#411,
-#412));
-#96=EDGE_LOOP('',(#413,#414,#415,#416));
-#97=EDGE_LOOP('',(#417,#418,#419,#420,#421,#422,#423,#424,#425,#426));
-#98=EDGE_LOOP('',(#427,#428,#429,#430));
-#99=EDGE_LOOP('',(#431,#432,#433,#434,#435,#436,#437,#438,#439,#440));
-#100=EDGE_LOOP('',(#441,#442,#443,#444));
-#101=EDGE_LOOP('',(#445,#446,#447,#448,#449));
-#102=EDGE_LOOP('',(#450,#451,#452,#453,#454));
-#103=EDGE_LOOP('',(#455,#456,#457,#458));
-#104=EDGE_LOOP('',(#459,#460,#461,#462,#463));
-#105=EDGE_LOOP('',(#464,#465,#466,#467,#468));
-#106=EDGE_LOOP('',(#469,#470,#471,#472));
-#107=LINE('',#740,#152);
-#108=LINE('',#746,#153);
-#109=LINE('',#748,#154);
-#110=LINE('',#750,#155);
-#111=LINE('',#752,#156);
-#112=LINE('',#753,#157);
-#113=LINE('',#758,#158);
-#114=LINE('',#759,#159);
-#115=LINE('',#764,#160);
-#116=LINE('',#765,#161);
-#117=LINE('',#771,#162);
-#118=LINE('',#773,#163);
-#119=LINE('',#774,#164);
-#120=LINE('',#784,#165);
-#121=LINE('',#786,#166);
-#122=LINE('',#788,#167);
-#123=LINE('',#790,#168);
-#124=LINE('',#792,#169);
-#125=LINE('',#797,#170);
-#126=LINE('',#802,#171);
-#127=LINE('',#803,#172);
-#128=LINE('',#808,#173);
-#129=LINE('',#809,#174);
-#130=LINE('',#816,#175);
-#131=LINE('',#818,#176);
-#132=LINE('',#819,#177);
-#133=LINE('',#881,#178);
-#134=LINE('',#895,#179);
-#135=LINE('',#897,#180);
-#136=LINE('',#899,#181);
-#137=LINE('',#900,#182);
-#138=LINE('',#903,#183);
-#139=LINE('',#904,#184);
-#140=LINE('',#905,#185);
-#141=LINE('',#907,#186);
-#142=LINE('',#908,#187);
-#143=LINE('',#910,#188);
-#144=LINE('',#913,#189);
-#145=LINE('',#915,#190);
-#146=LINE('',#916,#191);
-#147=LINE('',#917,#192);
-#148=LINE('',#920,#193);
-#149=LINE('',#922,#194);
-#150=LINE('',#924,#195);
-#151=LINE('',#927,#196);
-#152=VECTOR('',#585,10.);
-#153=VECTOR('',#586,10.);
-#154=VECTOR('',#587,10.);
-#155=VECTOR('',#588,10.);
-#156=VECTOR('',#589,10.);
-#157=VECTOR('',#590,10.);
-#158=VECTOR('',#595,10.);
-#159=VECTOR('',#596,10.);
-#160=VECTOR('',#601,10.);
-#161=VECTOR('',#602,10.);
-#162=VECTOR('',#611,10.);
-#163=VECTOR('',#612,10.);
-#164=VECTOR('',#613,10.);
-#165=VECTOR('',#620,10.);
-#166=VECTOR('',#621,10.);
-#167=VECTOR('',#622,10.);
-#168=VECTOR('',#623,10.);
-#169=VECTOR('',#624,10.);
-#170=VECTOR('',#625,10.);
-#171=VECTOR('',#630,10.);
-#172=VECTOR('',#631,10.);
-#173=VECTOR('',#636,10.);
-#174=VECTOR('',#637,10.);
-#175=VECTOR('',#648,10.);
-#176=VECTOR('',#649,10.);
-#177=VECTOR('',#650,10.);
-#178=VECTOR('',#679,3.);
-#179=VECTOR('',#694,10.);
-#180=VECTOR('',#695,10.);
-#181=VECTOR('',#696,10.);
-#182=VECTOR('',#697,10.);
-#183=VECTOR('',#700,10.);
-#184=VECTOR('',#701,10.);
-#185=VECTOR('',#702,10.);
-#186=VECTOR('',#703,10.);
-#187=VECTOR('',#704,10.);
-#188=VECTOR('',#707,10.);
-#189=VECTOR('',#710,10.);
-#190=VECTOR('',#711,10.);
-#191=VECTOR('',#712,10.);
-#192=VECTOR('',#713,10.);
-#193=VECTOR('',#718,10.);
-#194=VECTOR('',#721,10.);
-#195=VECTOR('',#724,10.);
-#196=VECTOR('',#729,10.);
-#197=(
-BOUNDED_CURVE()
-B_SPLINE_CURVE(2,(#736,#737,#738),.UNSPECIFIED.,.F.,.F.)
-B_SPLINE_CURVE_WITH_KNOTS((3,3),(178.46477889567,178.853392228292),
- .UNSPECIFIED.)
-CURVE()
-GEOMETRIC_REPRESENTATION_ITEM()
-RATIONAL_B_SPLINE_CURVE((13.687831583365,13.6241212154299,13.5600732229849))
-REPRESENTATION_ITEM('')
+#10=MECHANICAL_DESIGN_GEOMETRIC_PRESENTATION_REPRESENTATION('',(#17),#1253);
+#11=ITEM_DEFINED_TRANSFORMATION($,$,#760,#822);
+#12=(
+REPRESENTATION_RELATIONSHIP($,$,#1264,#1263)
+REPRESENTATION_RELATIONSHIP_WITH_TRANSFORMATION(#11)
+SHAPE_REPRESENTATION_RELATIONSHIP()
);
-#198=(
-BOUNDED_CURVE()
-B_SPLINE_CURVE(2,(#742,#743,#744),.UNSPECIFIED.,.F.,.F.)
-B_SPLINE_CURVE_WITH_KNOTS((3,3),(31.4120598130892,31.8006731457097),
- .UNSPECIFIED.)
-CURVE()
-GEOMETRIC_REPRESENTATION_ITEM()
-RATIONAL_B_SPLINE_CURVE((13.5600732229849,13.6241212154297,13.6878315833646))
-REPRESENTATION_ITEM('')
+#13=CONTEXT_DEPENDENT_SHAPE_REPRESENTATION(#12,#1262);
+#14=NEXT_ASSEMBLY_USAGE_OCCURRENCE('SC64_SHELL_BUTTON-20240702:1',
+'SC64_SHELL_BUTTON-20240702:1','SC64_SHELL_BUTTON-20240702:1',#1266,#1267,
+'SC64_SHELL_BUTTON-20240702:1');
+#15=SHAPE_REPRESENTATION_RELATIONSHIP('SRR','None',#1264,#16);
+#16=ADVANCED_BREP_SHAPE_REPRESENTATION('',(#18),#1252);
+#17=STYLED_ITEM('',(#1278),#18);
+#18=MANIFOLD_SOLID_BREP('Body1',#746);
+#19=TOROIDAL_SURFACE('',#818,2.8,0.2);
+#20=FACE_BOUND('',#91,.T.);
+#21=FACE_BOUND('',#94,.T.);
+#22=PLANE('',#764);
+#23=PLANE('',#768);
+#24=PLANE('',#773);
+#25=PLANE('',#777);
+#26=PLANE('',#779);
+#27=PLANE('',#781);
+#28=PLANE('',#782);
+#29=PLANE('',#783);
+#30=PLANE('',#786);
+#31=PLANE('',#790);
+#32=PLANE('',#791);
+#33=PLANE('',#792);
+#34=PLANE('',#793);
+#35=PLANE('',#796);
+#36=PLANE('',#800);
+#37=PLANE('',#801);
+#38=PLANE('',#802);
+#39=PLANE('',#803);
+#40=PLANE('',#806);
+#41=PLANE('',#810);
+#42=PLANE('',#811);
+#43=PLANE('',#812);
+#44=PLANE('',#813);
+#45=PLANE('',#814);
+#46=PLANE('',#815);
+#47=PLANE('',#816);
+#48=PLANE('',#817);
+#49=PLANE('',#821);
+#50=FACE_OUTER_BOUND('',#89,.T.);
+#51=FACE_OUTER_BOUND('',#90,.T.);
+#52=FACE_OUTER_BOUND('',#92,.T.);
+#53=FACE_OUTER_BOUND('',#93,.T.);
+#54=FACE_OUTER_BOUND('',#95,.T.);
+#55=FACE_OUTER_BOUND('',#96,.T.);
+#56=FACE_OUTER_BOUND('',#97,.T.);
+#57=FACE_OUTER_BOUND('',#98,.T.);
+#58=FACE_OUTER_BOUND('',#99,.T.);
+#59=FACE_OUTER_BOUND('',#100,.T.);
+#60=FACE_OUTER_BOUND('',#101,.T.);
+#61=FACE_OUTER_BOUND('',#102,.T.);
+#62=FACE_OUTER_BOUND('',#103,.T.);
+#63=FACE_OUTER_BOUND('',#104,.T.);
+#64=FACE_OUTER_BOUND('',#105,.T.);
+#65=FACE_OUTER_BOUND('',#106,.T.);
+#66=FACE_OUTER_BOUND('',#107,.T.);
+#67=FACE_OUTER_BOUND('',#108,.T.);
+#68=FACE_OUTER_BOUND('',#109,.T.);
+#69=FACE_OUTER_BOUND('',#110,.T.);
+#70=FACE_OUTER_BOUND('',#111,.T.);
+#71=FACE_OUTER_BOUND('',#112,.T.);
+#72=FACE_OUTER_BOUND('',#113,.T.);
+#73=FACE_OUTER_BOUND('',#114,.T.);
+#74=FACE_OUTER_BOUND('',#115,.T.);
+#75=FACE_OUTER_BOUND('',#116,.T.);
+#76=FACE_OUTER_BOUND('',#117,.T.);
+#77=FACE_OUTER_BOUND('',#118,.T.);
+#78=FACE_OUTER_BOUND('',#119,.T.);
+#79=FACE_OUTER_BOUND('',#120,.T.);
+#80=FACE_OUTER_BOUND('',#121,.T.);
+#81=FACE_OUTER_BOUND('',#122,.T.);
+#82=FACE_OUTER_BOUND('',#123,.T.);
+#83=FACE_OUTER_BOUND('',#124,.T.);
+#84=FACE_OUTER_BOUND('',#125,.T.);
+#85=FACE_OUTER_BOUND('',#126,.T.);
+#86=FACE_OUTER_BOUND('',#127,.T.);
+#87=FACE_OUTER_BOUND('',#128,.T.);
+#88=FACE_OUTER_BOUND('',#129,.T.);
+#89=EDGE_LOOP('',(#489,#490,#491,#492));
+#90=EDGE_LOOP('',(#493));
+#91=EDGE_LOOP('',(#494));
+#92=EDGE_LOOP('',(#495,#496,#497,#498));
+#93=EDGE_LOOP('',(#499));
+#94=EDGE_LOOP('',(#500,#501,#502,#503,#504,#505,#506,#507,#508,#509,#510,
+#511,#512,#513,#514,#515));
+#95=EDGE_LOOP('',(#516,#517,#518,#519,#520,#521,#522,#523,#524));
+#96=EDGE_LOOP('',(#525,#526,#527,#528));
+#97=EDGE_LOOP('',(#529,#530,#531,#532));
+#98=EDGE_LOOP('',(#533,#534,#535,#536,#537,#538,#539,#540,#541));
+#99=EDGE_LOOP('',(#542,#543,#544,#545));
+#100=EDGE_LOOP('',(#546,#547,#548));
+#101=EDGE_LOOP('',(#549,#550,#551,#552,#553,#554,#555,#556,#557,#558,#559,
+#560));
+#102=EDGE_LOOP('',(#561,#562,#563,#564,#565,#566,#567,#568,#569));
+#103=EDGE_LOOP('',(#570,#571,#572,#573));
+#104=EDGE_LOOP('',(#574,#575,#576,#577,#578,#579,#580,#581,#582));
+#105=EDGE_LOOP('',(#583,#584,#585,#586));
+#106=EDGE_LOOP('',(#587,#588,#589,#590));
+#107=EDGE_LOOP('',(#591,#592,#593));
+#108=EDGE_LOOP('',(#594,#595,#596,#597));
+#109=EDGE_LOOP('',(#598,#599,#600,#601,#602,#603,#604,#605,#606));
+#110=EDGE_LOOP('',(#607,#608,#609,#610));
+#111=EDGE_LOOP('',(#611,#612,#613,#614,#615,#616,#617,#618,#619));
+#112=EDGE_LOOP('',(#620,#621,#622,#623));
+#113=EDGE_LOOP('',(#624,#625,#626,#627));
+#114=EDGE_LOOP('',(#628,#629,#630));
+#115=EDGE_LOOP('',(#631,#632,#633,#634));
+#116=EDGE_LOOP('',(#635,#636,#637,#638,#639,#640,#641,#642,#643));
+#117=EDGE_LOOP('',(#644,#645,#646,#647));
+#118=EDGE_LOOP('',(#648,#649,#650,#651,#652,#653,#654,#655,#656));
+#119=EDGE_LOOP('',(#657,#658,#659,#660));
+#120=EDGE_LOOP('',(#661,#662,#663,#664));
+#121=EDGE_LOOP('',(#665,#666,#667));
+#122=EDGE_LOOP('',(#668,#669,#670,#671));
+#123=EDGE_LOOP('',(#672,#673,#674,#675));
+#124=EDGE_LOOP('',(#676,#677,#678,#679));
+#125=EDGE_LOOP('',(#680,#681,#682,#683));
+#126=EDGE_LOOP('',(#684,#685,#686,#687));
+#127=EDGE_LOOP('',(#688,#689,#690,#691));
+#128=EDGE_LOOP('',(#692,#693,#694,#695));
+#129=EDGE_LOOP('',(#696));
+#130=LINE('',#1039,#212);
+#131=LINE('',#1047,#213);
+#132=LINE('',#1051,#214);
+#133=LINE('',#1053,#215);
+#134=LINE('',#1055,#216);
+#135=LINE('',#1059,#217);
+#136=LINE('',#1061,#218);
+#137=LINE('',#1063,#219);
+#138=LINE('',#1067,#220);
+#139=LINE('',#1069,#221);
+#140=LINE('',#1071,#222);
+#141=LINE('',#1075,#223);
+#142=LINE('',#1077,#224);
+#143=LINE('',#1079,#225);
+#144=LINE('',#1084,#226);
+#145=LINE('',#1086,#227);
+#146=LINE('',#1088,#228);
+#147=LINE('',#1090,#229);
+#148=LINE('',#1092,#230);
+#149=LINE('',#1093,#231);
+#150=LINE('',#1095,#232);
+#151=LINE('',#1096,#233);
+#152=LINE('',#1101,#234);
+#153=LINE('',#1106,#235);
+#154=LINE('',#1109,#236);
+#155=LINE('',#1111,#237);
+#156=LINE('',#1112,#238);
+#157=LINE('',#1113,#239);
+#158=LINE('',#1114,#240);
+#159=LINE('',#1120,#241);
+#160=LINE('',#1121,#242);
+#161=LINE('',#1123,#243);
+#162=LINE('',#1125,#244);
+#163=LINE('',#1127,#245);
+#164=LINE('',#1129,#246);
+#165=LINE('',#1131,#247);
+#166=LINE('',#1133,#248);
+#167=LINE('',#1135,#249);
+#168=LINE('',#1136,#250);
+#169=LINE('',#1139,#251);
+#170=LINE('',#1140,#252);
+#171=LINE('',#1142,#253);
+#172=LINE('',#1144,#254);
+#173=LINE('',#1146,#255);
+#174=LINE('',#1148,#256);
+#175=LINE('',#1149,#257);
+#176=LINE('',#1153,#258);
+#177=LINE('',#1157,#259);
+#178=LINE('',#1158,#260);
+#179=LINE('',#1160,#261);
+#180=LINE('',#1161,#262);
+#181=LINE('',#1162,#263);
+#182=LINE('',#1170,#264);
+#183=LINE('',#1171,#265);
+#184=LINE('',#1173,#266);
+#185=LINE('',#1175,#267);
+#186=LINE('',#1177,#268);
+#187=LINE('',#1179,#269);
+#188=LINE('',#1181,#270);
+#189=LINE('',#1182,#271);
+#190=LINE('',#1186,#272);
+#191=LINE('',#1190,#273);
+#192=LINE('',#1191,#274);
+#193=LINE('',#1193,#275);
+#194=LINE('',#1194,#276);
+#195=LINE('',#1195,#277);
+#196=LINE('',#1203,#278);
+#197=LINE('',#1204,#279);
+#198=LINE('',#1206,#280);
+#199=LINE('',#1208,#281);
+#200=LINE('',#1210,#282);
+#201=LINE('',#1212,#283);
+#202=LINE('',#1214,#284);
+#203=LINE('',#1215,#285);
+#204=LINE('',#1219,#286);
+#205=LINE('',#1223,#287);
+#206=LINE('',#1224,#288);
+#207=LINE('',#1226,#289);
+#208=LINE('',#1227,#290);
+#209=LINE('',#1228,#291);
+#210=LINE('',#1235,#292);
+#211=LINE('',#1240,#293);
+#212=VECTOR('',#831,3.);
+#213=VECTOR('',#842,4.);
+#214=VECTOR('',#845,1.073213749462);
+#215=VECTOR('',#846,0.8);
+#216=VECTOR('',#847,1.073213749462);
+#217=VECTOR('',#850,1.073213749462);
+#218=VECTOR('',#851,0.8);
+#219=VECTOR('',#852,1.073213749462);
+#220=VECTOR('',#855,1.073213749462);
+#221=VECTOR('',#856,0.8);
+#222=VECTOR('',#857,1.073213749462);
+#223=VECTOR('',#860,1.073213749462);
+#224=VECTOR('',#861,0.8);
+#225=VECTOR('',#862,1.073213749462);
+#226=VECTOR('',#867,3.2);
+#227=VECTOR('',#868,1.559591794228);
+#228=VECTOR('',#869,2.);
+#229=VECTOR('',#870,0.9);
+#230=VECTOR('',#871,1.9);
+#231=VECTOR('',#872,0.848528137423803);
+#232=VECTOR('',#873,1.3);
+#233=VECTOR('',#874,1.013621955235);
+#234=VECTOR('',#879,3.2);
+#235=VECTOR('',#886,1.013621955235);
+#236=VECTOR('',#889,0.848528137423843);
+#237=VECTOR('',#890,1.9);
+#238=VECTOR('',#891,0.9);
+#239=VECTOR('',#892,1.559591794228);
+#240=VECTOR('',#893,1.3);
+#241=VECTOR('',#900,0.9);
+#242=VECTOR('',#901,0.8);
+#243=VECTOR('',#902,0.8);
+#244=VECTOR('',#903,0.9);
+#245=VECTOR('',#904,0.9);
+#246=VECTOR('',#905,0.8);
+#247=VECTOR('',#906,0.9);
+#248=VECTOR('',#907,0.9);
+#249=VECTOR('',#908,0.8);
+#250=VECTOR('',#909,0.9);
+#251=VECTOR('',#912,0.848528137423903);
+#252=VECTOR('',#913,1.9);
+#253=VECTOR('',#914,2.);
+#254=VECTOR('',#915,1.559591794228);
+#255=VECTOR('',#916,3.2);
+#256=VECTOR('',#917,1.013621955235);
+#257=VECTOR('',#918,1.3);
+#258=VECTOR('',#923,1.3);
+#259=VECTOR('',#926,3.2);
+#260=VECTOR('',#927,1.559591794228);
+#261=VECTOR('',#928,1.9);
+#262=VECTOR('',#929,0.848528137423843);
+#263=VECTOR('',#930,1.013621955235);
+#264=VECTOR('',#943,0.848528137423843);
+#265=VECTOR('',#944,0.8);
+#266=VECTOR('',#947,1.9);
+#267=VECTOR('',#948,2.);
+#268=VECTOR('',#949,1.559591794228);
+#269=VECTOR('',#950,3.2);
+#270=VECTOR('',#951,1.013621955235);
+#271=VECTOR('',#952,1.3);
+#272=VECTOR('',#957,1.3);
+#273=VECTOR('',#960,3.2);
+#274=VECTOR('',#961,1.559591794228);
+#275=VECTOR('',#962,1.9);
+#276=VECTOR('',#963,0.848528137423843);
+#277=VECTOR('',#964,1.013621955235);
+#278=VECTOR('',#977,0.848528137423843);
+#279=VECTOR('',#978,0.8);
+#280=VECTOR('',#981,1.9);
+#281=VECTOR('',#982,2.);
+#282=VECTOR('',#983,1.559591794228);
+#283=VECTOR('',#984,3.2);
+#284=VECTOR('',#985,1.013621955235);
+#285=VECTOR('',#986,1.3);
+#286=VECTOR('',#991,1.3);
+#287=VECTOR('',#994,3.2);
+#288=VECTOR('',#995,1.559591794228);
+#289=VECTOR('',#996,1.9);
+#290=VECTOR('',#997,0.848528137423843);
+#291=VECTOR('',#998,1.013621955235);
+#292=VECTOR('',#1011,0.8);
+#293=VECTOR('',#1020,0.8);
+#294=CIRCLE('',#762,3.);
+#295=CIRCLE('',#763,3.);
+#296=CIRCLE('',#765,4.);
+#297=CIRCLE('',#767,4.);
+#298=CIRCLE('',#769,3.);
+#299=CIRCLE('',#770,3.);
+#300=CIRCLE('',#771,3.);
+#301=CIRCLE('',#772,3.);
+#302=CIRCLE('',#775,2.);
+#303=CIRCLE('',#776,2.);
+#304=CIRCLE('',#778,3.);
+#305=CIRCLE('',#785,3.);
+#306=CIRCLE('',#788,2.);
+#307=CIRCLE('',#789,2.);
+#308=CIRCLE('',#795,3.);
+#309=CIRCLE('',#798,2.);
+#310=CIRCLE('',#799,2.);
+#311=CIRCLE('',#805,3.);
+#312=CIRCLE('',#808,2.);
+#313=CIRCLE('',#809,2.);
+#314=CIRCLE('',#819,2.8);
+#315=CIRCLE('',#820,0.2);
+#316=VERTEX_POINT('',#1036);
+#317=VERTEX_POINT('',#1038);
+#318=VERTEX_POINT('',#1042);
+#319=VERTEX_POINT('',#1045);
+#320=VERTEX_POINT('',#1049);
+#321=VERTEX_POINT('',#1050);
+#322=VERTEX_POINT('',#1052);
+#323=VERTEX_POINT('',#1054);
+#324=VERTEX_POINT('',#1056);
+#325=VERTEX_POINT('',#1058);
+#326=VERTEX_POINT('',#1060);
+#327=VERTEX_POINT('',#1062);
+#328=VERTEX_POINT('',#1064);
+#329=VERTEX_POINT('',#1066);
+#330=VERTEX_POINT('',#1068);
+#331=VERTEX_POINT('',#1070);
+#332=VERTEX_POINT('',#1072);
+#333=VERTEX_POINT('',#1074);
+#334=VERTEX_POINT('',#1076);
+#335=VERTEX_POINT('',#1078);
+#336=VERTEX_POINT('',#1082);
+#337=VERTEX_POINT('',#1083);
+#338=VERTEX_POINT('',#1085);
+#339=VERTEX_POINT('',#1087);
+#340=VERTEX_POINT('',#1089);
+#341=VERTEX_POINT('',#1091);
+#342=VERTEX_POINT('',#1094);
+#343=VERTEX_POINT('',#1098);
+#344=VERTEX_POINT('',#1100);
+#345=VERTEX_POINT('',#1104);
+#346=VERTEX_POINT('',#1108);
+#347=VERTEX_POINT('',#1110);
+#348=VERTEX_POINT('',#1118);
+#349=VERTEX_POINT('',#1119);
+#350=VERTEX_POINT('',#1122);
+#351=VERTEX_POINT('',#1124);
+#352=VERTEX_POINT('',#1126);
+#353=VERTEX_POINT('',#1128);
+#354=VERTEX_POINT('',#1130);
+#355=VERTEX_POINT('',#1132);
+#356=VERTEX_POINT('',#1134);
+#357=VERTEX_POINT('',#1138);
+#358=VERTEX_POINT('',#1141);
+#359=VERTEX_POINT('',#1143);
+#360=VERTEX_POINT('',#1145);
+#361=VERTEX_POINT('',#1147);
+#362=VERTEX_POINT('',#1151);
+#363=VERTEX_POINT('',#1155);
+#364=VERTEX_POINT('',#1156);
+#365=VERTEX_POINT('',#1159);
+#366=VERTEX_POINT('',#1169);
+#367=VERTEX_POINT('',#1174);
+#368=VERTEX_POINT('',#1176);
+#369=VERTEX_POINT('',#1178);
+#370=VERTEX_POINT('',#1180);
+#371=VERTEX_POINT('',#1184);
+#372=VERTEX_POINT('',#1188);
+#373=VERTEX_POINT('',#1189);
+#374=VERTEX_POINT('',#1192);
+#375=VERTEX_POINT('',#1202);
+#376=VERTEX_POINT('',#1207);
+#377=VERTEX_POINT('',#1209);
+#378=VERTEX_POINT('',#1211);
+#379=VERTEX_POINT('',#1213);
+#380=VERTEX_POINT('',#1217);
+#381=VERTEX_POINT('',#1221);
+#382=VERTEX_POINT('',#1222);
+#383=VERTEX_POINT('',#1225);
+#384=VERTEX_POINT('',#1243);
+#385=EDGE_CURVE('',#316,#316,#294,.T.);
+#386=EDGE_CURVE('',#316,#317,#130,.T.);
+#387=EDGE_CURVE('',#317,#317,#295,.T.);
+#388=EDGE_CURVE('',#318,#318,#296,.T.);
+#389=EDGE_CURVE('',#319,#319,#297,.T.);
+#390=EDGE_CURVE('',#319,#318,#131,.T.);
+#391=EDGE_CURVE('',#320,#321,#132,.T.);
+#392=EDGE_CURVE('',#322,#320,#133,.T.);
+#393=EDGE_CURVE('',#323,#322,#134,.T.);
+#394=EDGE_CURVE('',#324,#323,#298,.T.);
+#395=EDGE_CURVE('',#325,#324,#135,.T.);
+#396=EDGE_CURVE('',#326,#325,#136,.T.);
+#397=EDGE_CURVE('',#327,#326,#137,.T.);
+#398=EDGE_CURVE('',#328,#327,#299,.T.);
+#399=EDGE_CURVE('',#329,#328,#138,.T.);
+#400=EDGE_CURVE('',#330,#329,#139,.T.);
+#401=EDGE_CURVE('',#331,#330,#140,.T.);
+#402=EDGE_CURVE('',#332,#331,#300,.T.);
+#403=EDGE_CURVE('',#333,#332,#141,.T.);
+#404=EDGE_CURVE('',#334,#333,#142,.T.);
+#405=EDGE_CURVE('',#335,#334,#143,.T.);
+#406=EDGE_CURVE('',#321,#335,#301,.T.);
+#407=EDGE_CURVE('',#336,#337,#144,.T.);
+#408=EDGE_CURVE('',#337,#338,#145,.T.);
+#409=EDGE_CURVE('',#338,#339,#146,.T.);
+#410=EDGE_CURVE('',#339,#340,#147,.T.);
+#411=EDGE_CURVE('',#341,#340,#148,.T.);
+#412=EDGE_CURVE('',#320,#341,#149,.T.);
+#413=EDGE_CURVE('',#321,#342,#150,.T.);
+#414=EDGE_CURVE('',#342,#336,#151,.T.);
+#415=EDGE_CURVE('',#336,#343,#302,.T.);
+#416=EDGE_CURVE('',#344,#343,#152,.T.);
+#417=EDGE_CURVE('',#344,#337,#303,.T.);
+#418=EDGE_CURVE('',#345,#342,#304,.T.);
+#419=EDGE_CURVE('',#343,#345,#153,.T.);
+#420=EDGE_CURVE('',#346,#334,#154,.T.);
+#421=EDGE_CURVE('',#346,#347,#155,.T.);
+#422=EDGE_CURVE('',#339,#347,#156,.T.);
+#423=EDGE_CURVE('',#338,#344,#157,.T.);
+#424=EDGE_CURVE('',#345,#335,#158,.T.);
+#425=EDGE_CURVE('',#348,#349,#159,.T.);
+#426=EDGE_CURVE('',#340,#349,#160,.T.);
+#427=EDGE_CURVE('',#350,#347,#161,.T.);
+#428=EDGE_CURVE('',#351,#350,#162,.T.);
+#429=EDGE_CURVE('',#351,#352,#163,.T.);
+#430=EDGE_CURVE('',#353,#352,#164,.T.);
+#431=EDGE_CURVE('',#354,#353,#165,.T.);
+#432=EDGE_CURVE('',#354,#355,#166,.T.);
+#433=EDGE_CURVE('',#356,#355,#167,.T.);
+#434=EDGE_CURVE('',#348,#356,#168,.T.);
+#435=EDGE_CURVE('',#357,#322,#169,.T.);
+#436=EDGE_CURVE('',#357,#349,#170,.T.);
+#437=EDGE_CURVE('',#358,#348,#171,.T.);
+#438=EDGE_CURVE('',#359,#358,#172,.T.);
+#439=EDGE_CURVE('',#359,#360,#173,.T.);
+#440=EDGE_CURVE('',#360,#361,#174,.T.);
+#441=EDGE_CURVE('',#361,#323,#175,.T.);
+#442=EDGE_CURVE('',#361,#362,#305,.T.);
+#443=EDGE_CURVE('',#324,#362,#176,.T.);
+#444=EDGE_CURVE('',#363,#364,#177,.T.);
+#445=EDGE_CURVE('',#358,#364,#178,.T.);
+#446=EDGE_CURVE('',#365,#356,#179,.T.);
+#447=EDGE_CURVE('',#325,#365,#180,.T.);
+#448=EDGE_CURVE('',#362,#363,#181,.T.);
+#449=EDGE_CURVE('',#363,#360,#306,.T.);
+#450=EDGE_CURVE('',#359,#364,#307,.T.);
+#451=EDGE_CURVE('',#366,#326,#182,.T.);
+#452=EDGE_CURVE('',#366,#365,#183,.T.);
+#453=EDGE_CURVE('',#366,#355,#184,.T.);
+#454=EDGE_CURVE('',#367,#354,#185,.T.);
+#455=EDGE_CURVE('',#368,#367,#186,.T.);
+#456=EDGE_CURVE('',#368,#369,#187,.T.);
+#457=EDGE_CURVE('',#369,#370,#188,.T.);
+#458=EDGE_CURVE('',#370,#327,#189,.T.);
+#459=EDGE_CURVE('',#370,#371,#308,.T.);
+#460=EDGE_CURVE('',#328,#371,#190,.T.);
+#461=EDGE_CURVE('',#372,#373,#191,.T.);
+#462=EDGE_CURVE('',#367,#373,#192,.T.);
+#463=EDGE_CURVE('',#374,#353,#193,.T.);
+#464=EDGE_CURVE('',#329,#374,#194,.T.);
+#465=EDGE_CURVE('',#371,#372,#195,.T.);
+#466=EDGE_CURVE('',#372,#369,#309,.T.);
+#467=EDGE_CURVE('',#368,#373,#310,.T.);
+#468=EDGE_CURVE('',#375,#330,#196,.T.);
+#469=EDGE_CURVE('',#375,#374,#197,.T.);
+#470=EDGE_CURVE('',#375,#352,#198,.T.);
+#471=EDGE_CURVE('',#376,#351,#199,.T.);
+#472=EDGE_CURVE('',#376,#377,#200,.T.);
+#473=EDGE_CURVE('',#377,#378,#201,.T.);
+#474=EDGE_CURVE('',#378,#379,#202,.T.);
+#475=EDGE_CURVE('',#379,#331,#203,.T.);
+#476=EDGE_CURVE('',#379,#380,#311,.T.);
+#477=EDGE_CURVE('',#332,#380,#204,.T.);
+#478=EDGE_CURVE('',#381,#382,#205,.T.);
+#479=EDGE_CURVE('',#382,#376,#206,.T.);
+#480=EDGE_CURVE('',#383,#350,#207,.T.);
+#481=EDGE_CURVE('',#333,#383,#208,.T.);
+#482=EDGE_CURVE('',#380,#381,#209,.T.);
+#483=EDGE_CURVE('',#381,#378,#312,.T.);
+#484=EDGE_CURVE('',#377,#382,#313,.T.);
+#485=EDGE_CURVE('',#346,#383,#210,.T.);
+#486=EDGE_CURVE('',#357,#341,#211,.T.);
+#487=EDGE_CURVE('',#384,#384,#314,.T.);
+#488=EDGE_CURVE('',#384,#316,#315,.T.);
+#489=ORIENTED_EDGE('',*,*,#385,.T.);
+#490=ORIENTED_EDGE('',*,*,#386,.T.);
+#491=ORIENTED_EDGE('',*,*,#387,.T.);
+#492=ORIENTED_EDGE('',*,*,#386,.F.);
+#493=ORIENTED_EDGE('',*,*,#388,.F.);
+#494=ORIENTED_EDGE('',*,*,#387,.F.);
+#495=ORIENTED_EDGE('',*,*,#389,.T.);
+#496=ORIENTED_EDGE('',*,*,#390,.T.);
+#497=ORIENTED_EDGE('',*,*,#388,.T.);
+#498=ORIENTED_EDGE('',*,*,#390,.F.);
+#499=ORIENTED_EDGE('',*,*,#389,.F.);
+#500=ORIENTED_EDGE('',*,*,#391,.F.);
+#501=ORIENTED_EDGE('',*,*,#392,.F.);
+#502=ORIENTED_EDGE('',*,*,#393,.F.);
+#503=ORIENTED_EDGE('',*,*,#394,.F.);
+#504=ORIENTED_EDGE('',*,*,#395,.F.);
+#505=ORIENTED_EDGE('',*,*,#396,.F.);
+#506=ORIENTED_EDGE('',*,*,#397,.F.);
+#507=ORIENTED_EDGE('',*,*,#398,.F.);
+#508=ORIENTED_EDGE('',*,*,#399,.F.);
+#509=ORIENTED_EDGE('',*,*,#400,.F.);
+#510=ORIENTED_EDGE('',*,*,#401,.F.);
+#511=ORIENTED_EDGE('',*,*,#402,.F.);
+#512=ORIENTED_EDGE('',*,*,#403,.F.);
+#513=ORIENTED_EDGE('',*,*,#404,.F.);
+#514=ORIENTED_EDGE('',*,*,#405,.F.);
+#515=ORIENTED_EDGE('',*,*,#406,.F.);
+#516=ORIENTED_EDGE('',*,*,#407,.T.);
+#517=ORIENTED_EDGE('',*,*,#408,.T.);
+#518=ORIENTED_EDGE('',*,*,#409,.T.);
+#519=ORIENTED_EDGE('',*,*,#410,.T.);
+#520=ORIENTED_EDGE('',*,*,#411,.F.);
+#521=ORIENTED_EDGE('',*,*,#412,.F.);
+#522=ORIENTED_EDGE('',*,*,#391,.T.);
+#523=ORIENTED_EDGE('',*,*,#413,.T.);
+#524=ORIENTED_EDGE('',*,*,#414,.T.);
+#525=ORIENTED_EDGE('',*,*,#415,.T.);
+#526=ORIENTED_EDGE('',*,*,#416,.F.);
+#527=ORIENTED_EDGE('',*,*,#417,.T.);
+#528=ORIENTED_EDGE('',*,*,#407,.F.);
+#529=ORIENTED_EDGE('',*,*,#415,.F.);
+#530=ORIENTED_EDGE('',*,*,#414,.F.);
+#531=ORIENTED_EDGE('',*,*,#418,.F.);
+#532=ORIENTED_EDGE('',*,*,#419,.F.);
+#533=ORIENTED_EDGE('',*,*,#405,.T.);
+#534=ORIENTED_EDGE('',*,*,#420,.F.);
+#535=ORIENTED_EDGE('',*,*,#421,.T.);
+#536=ORIENTED_EDGE('',*,*,#422,.F.);
+#537=ORIENTED_EDGE('',*,*,#409,.F.);
+#538=ORIENTED_EDGE('',*,*,#423,.T.);
+#539=ORIENTED_EDGE('',*,*,#416,.T.);
+#540=ORIENTED_EDGE('',*,*,#419,.T.);
+#541=ORIENTED_EDGE('',*,*,#424,.T.);
+#542=ORIENTED_EDGE('',*,*,#406,.T.);
+#543=ORIENTED_EDGE('',*,*,#424,.F.);
+#544=ORIENTED_EDGE('',*,*,#418,.T.);
+#545=ORIENTED_EDGE('',*,*,#413,.F.);
+#546=ORIENTED_EDGE('',*,*,#408,.F.);
+#547=ORIENTED_EDGE('',*,*,#417,.F.);
+#548=ORIENTED_EDGE('',*,*,#423,.F.);
+#549=ORIENTED_EDGE('',*,*,#425,.T.);
+#550=ORIENTED_EDGE('',*,*,#426,.F.);
+#551=ORIENTED_EDGE('',*,*,#410,.F.);
+#552=ORIENTED_EDGE('',*,*,#422,.T.);
+#553=ORIENTED_EDGE('',*,*,#427,.F.);
+#554=ORIENTED_EDGE('',*,*,#428,.F.);
+#555=ORIENTED_EDGE('',*,*,#429,.T.);
+#556=ORIENTED_EDGE('',*,*,#430,.F.);
+#557=ORIENTED_EDGE('',*,*,#431,.F.);
+#558=ORIENTED_EDGE('',*,*,#432,.T.);
+#559=ORIENTED_EDGE('',*,*,#433,.F.);
+#560=ORIENTED_EDGE('',*,*,#434,.F.);
+#561=ORIENTED_EDGE('',*,*,#393,.T.);
+#562=ORIENTED_EDGE('',*,*,#435,.F.);
+#563=ORIENTED_EDGE('',*,*,#436,.T.);
+#564=ORIENTED_EDGE('',*,*,#425,.F.);
+#565=ORIENTED_EDGE('',*,*,#437,.F.);
+#566=ORIENTED_EDGE('',*,*,#438,.F.);
+#567=ORIENTED_EDGE('',*,*,#439,.T.);
+#568=ORIENTED_EDGE('',*,*,#440,.T.);
+#569=ORIENTED_EDGE('',*,*,#441,.T.);
+#570=ORIENTED_EDGE('',*,*,#394,.T.);
+#571=ORIENTED_EDGE('',*,*,#441,.F.);
+#572=ORIENTED_EDGE('',*,*,#442,.T.);
+#573=ORIENTED_EDGE('',*,*,#443,.F.);
+#574=ORIENTED_EDGE('',*,*,#444,.T.);
+#575=ORIENTED_EDGE('',*,*,#445,.F.);
+#576=ORIENTED_EDGE('',*,*,#437,.T.);
+#577=ORIENTED_EDGE('',*,*,#434,.T.);
+#578=ORIENTED_EDGE('',*,*,#446,.F.);
+#579=ORIENTED_EDGE('',*,*,#447,.F.);
+#580=ORIENTED_EDGE('',*,*,#395,.T.);
+#581=ORIENTED_EDGE('',*,*,#443,.T.);
+#582=ORIENTED_EDGE('',*,*,#448,.T.);
+#583=ORIENTED_EDGE('',*,*,#449,.T.);
+#584=ORIENTED_EDGE('',*,*,#439,.F.);
+#585=ORIENTED_EDGE('',*,*,#450,.T.);
+#586=ORIENTED_EDGE('',*,*,#444,.F.);
+#587=ORIENTED_EDGE('',*,*,#449,.F.);
+#588=ORIENTED_EDGE('',*,*,#448,.F.);
+#589=ORIENTED_EDGE('',*,*,#442,.F.);
+#590=ORIENTED_EDGE('',*,*,#440,.F.);
+#591=ORIENTED_EDGE('',*,*,#438,.T.);
+#592=ORIENTED_EDGE('',*,*,#445,.T.);
+#593=ORIENTED_EDGE('',*,*,#450,.F.);
+#594=ORIENTED_EDGE('',*,*,#451,.T.);
+#595=ORIENTED_EDGE('',*,*,#396,.T.);
+#596=ORIENTED_EDGE('',*,*,#447,.T.);
+#597=ORIENTED_EDGE('',*,*,#452,.F.);
+#598=ORIENTED_EDGE('',*,*,#397,.T.);
+#599=ORIENTED_EDGE('',*,*,#451,.F.);
+#600=ORIENTED_EDGE('',*,*,#453,.T.);
+#601=ORIENTED_EDGE('',*,*,#432,.F.);
+#602=ORIENTED_EDGE('',*,*,#454,.F.);
+#603=ORIENTED_EDGE('',*,*,#455,.F.);
+#604=ORIENTED_EDGE('',*,*,#456,.T.);
+#605=ORIENTED_EDGE('',*,*,#457,.T.);
+#606=ORIENTED_EDGE('',*,*,#458,.T.);
+#607=ORIENTED_EDGE('',*,*,#398,.T.);
+#608=ORIENTED_EDGE('',*,*,#458,.F.);
+#609=ORIENTED_EDGE('',*,*,#459,.T.);
+#610=ORIENTED_EDGE('',*,*,#460,.F.);
+#611=ORIENTED_EDGE('',*,*,#461,.T.);
+#612=ORIENTED_EDGE('',*,*,#462,.F.);
+#613=ORIENTED_EDGE('',*,*,#454,.T.);
+#614=ORIENTED_EDGE('',*,*,#431,.T.);
+#615=ORIENTED_EDGE('',*,*,#463,.F.);
+#616=ORIENTED_EDGE('',*,*,#464,.F.);
+#617=ORIENTED_EDGE('',*,*,#399,.T.);
+#618=ORIENTED_EDGE('',*,*,#460,.T.);
+#619=ORIENTED_EDGE('',*,*,#465,.T.);
+#620=ORIENTED_EDGE('',*,*,#466,.T.);
+#621=ORIENTED_EDGE('',*,*,#456,.F.);
+#622=ORIENTED_EDGE('',*,*,#467,.T.);
+#623=ORIENTED_EDGE('',*,*,#461,.F.);
+#624=ORIENTED_EDGE('',*,*,#466,.F.);
+#625=ORIENTED_EDGE('',*,*,#465,.F.);
+#626=ORIENTED_EDGE('',*,*,#459,.F.);
+#627=ORIENTED_EDGE('',*,*,#457,.F.);
+#628=ORIENTED_EDGE('',*,*,#467,.F.);
+#629=ORIENTED_EDGE('',*,*,#455,.T.);
+#630=ORIENTED_EDGE('',*,*,#462,.T.);
+#631=ORIENTED_EDGE('',*,*,#468,.T.);
+#632=ORIENTED_EDGE('',*,*,#400,.T.);
+#633=ORIENTED_EDGE('',*,*,#464,.T.);
+#634=ORIENTED_EDGE('',*,*,#469,.F.);
+#635=ORIENTED_EDGE('',*,*,#401,.T.);
+#636=ORIENTED_EDGE('',*,*,#468,.F.);
+#637=ORIENTED_EDGE('',*,*,#470,.T.);
+#638=ORIENTED_EDGE('',*,*,#429,.F.);
+#639=ORIENTED_EDGE('',*,*,#471,.F.);
+#640=ORIENTED_EDGE('',*,*,#472,.T.);
+#641=ORIENTED_EDGE('',*,*,#473,.T.);
+#642=ORIENTED_EDGE('',*,*,#474,.T.);
+#643=ORIENTED_EDGE('',*,*,#475,.T.);
+#644=ORIENTED_EDGE('',*,*,#402,.T.);
+#645=ORIENTED_EDGE('',*,*,#475,.F.);
+#646=ORIENTED_EDGE('',*,*,#476,.T.);
+#647=ORIENTED_EDGE('',*,*,#477,.F.);
+#648=ORIENTED_EDGE('',*,*,#478,.T.);
+#649=ORIENTED_EDGE('',*,*,#479,.T.);
+#650=ORIENTED_EDGE('',*,*,#471,.T.);
+#651=ORIENTED_EDGE('',*,*,#428,.T.);
+#652=ORIENTED_EDGE('',*,*,#480,.F.);
+#653=ORIENTED_EDGE('',*,*,#481,.F.);
+#654=ORIENTED_EDGE('',*,*,#403,.T.);
+#655=ORIENTED_EDGE('',*,*,#477,.T.);
+#656=ORIENTED_EDGE('',*,*,#482,.T.);
+#657=ORIENTED_EDGE('',*,*,#483,.T.);
+#658=ORIENTED_EDGE('',*,*,#473,.F.);
+#659=ORIENTED_EDGE('',*,*,#484,.T.);
+#660=ORIENTED_EDGE('',*,*,#478,.F.);
+#661=ORIENTED_EDGE('',*,*,#483,.F.);
+#662=ORIENTED_EDGE('',*,*,#482,.F.);
+#663=ORIENTED_EDGE('',*,*,#476,.F.);
+#664=ORIENTED_EDGE('',*,*,#474,.F.);
+#665=ORIENTED_EDGE('',*,*,#484,.F.);
+#666=ORIENTED_EDGE('',*,*,#472,.F.);
+#667=ORIENTED_EDGE('',*,*,#479,.F.);
+#668=ORIENTED_EDGE('',*,*,#420,.T.);
+#669=ORIENTED_EDGE('',*,*,#404,.T.);
+#670=ORIENTED_EDGE('',*,*,#481,.T.);
+#671=ORIENTED_EDGE('',*,*,#485,.F.);
+#672=ORIENTED_EDGE('',*,*,#485,.T.);
+#673=ORIENTED_EDGE('',*,*,#480,.T.);
+#674=ORIENTED_EDGE('',*,*,#427,.T.);
+#675=ORIENTED_EDGE('',*,*,#421,.F.);
+#676=ORIENTED_EDGE('',*,*,#469,.T.);
+#677=ORIENTED_EDGE('',*,*,#463,.T.);
+#678=ORIENTED_EDGE('',*,*,#430,.T.);
+#679=ORIENTED_EDGE('',*,*,#470,.F.);
+#680=ORIENTED_EDGE('',*,*,#452,.T.);
+#681=ORIENTED_EDGE('',*,*,#446,.T.);
+#682=ORIENTED_EDGE('',*,*,#433,.T.);
+#683=ORIENTED_EDGE('',*,*,#453,.F.);
+#684=ORIENTED_EDGE('',*,*,#486,.T.);
+#685=ORIENTED_EDGE('',*,*,#411,.T.);
+#686=ORIENTED_EDGE('',*,*,#426,.T.);
+#687=ORIENTED_EDGE('',*,*,#436,.F.);
+#688=ORIENTED_EDGE('',*,*,#435,.T.);
+#689=ORIENTED_EDGE('',*,*,#392,.T.);
+#690=ORIENTED_EDGE('',*,*,#412,.T.);
+#691=ORIENTED_EDGE('',*,*,#486,.F.);
+#692=ORIENTED_EDGE('',*,*,#487,.T.);
+#693=ORIENTED_EDGE('',*,*,#488,.T.);
+#694=ORIENTED_EDGE('',*,*,#385,.F.);
+#695=ORIENTED_EDGE('',*,*,#488,.F.);
+#696=ORIENTED_EDGE('',*,*,#487,.F.);
+#697=CYLINDRICAL_SURFACE('',#761,3.);
+#698=CYLINDRICAL_SURFACE('',#766,4.);
+#699=CYLINDRICAL_SURFACE('',#774,2.);
+#700=CYLINDRICAL_SURFACE('',#780,3.);
+#701=CYLINDRICAL_SURFACE('',#784,3.);
+#702=CYLINDRICAL_SURFACE('',#787,2.);
+#703=CYLINDRICAL_SURFACE('',#794,3.);
+#704=CYLINDRICAL_SURFACE('',#797,2.);
+#705=CYLINDRICAL_SURFACE('',#804,3.);
+#706=CYLINDRICAL_SURFACE('',#807,2.);
+#707=ADVANCED_FACE('',(#50),#697,.T.);
+#708=ADVANCED_FACE('',(#51,#20),#22,.F.);
+#709=ADVANCED_FACE('',(#52),#698,.T.);
+#710=ADVANCED_FACE('',(#53,#21),#23,.F.);
+#711=ADVANCED_FACE('',(#54),#24,.F.);
+#712=ADVANCED_FACE('',(#55),#699,.F.);
+#713=ADVANCED_FACE('',(#56),#25,.T.);
+#714=ADVANCED_FACE('',(#57),#26,.F.);
+#715=ADVANCED_FACE('',(#58),#700,.F.);
+#716=ADVANCED_FACE('',(#59),#27,.T.);
+#717=ADVANCED_FACE('',(#60),#28,.F.);
+#718=ADVANCED_FACE('',(#61),#29,.T.);
+#719=ADVANCED_FACE('',(#62),#701,.F.);
+#720=ADVANCED_FACE('',(#63),#30,.T.);
+#721=ADVANCED_FACE('',(#64),#702,.F.);
+#722=ADVANCED_FACE('',(#65),#31,.T.);
+#723=ADVANCED_FACE('',(#66),#32,.F.);
+#724=ADVANCED_FACE('',(#67),#33,.T.);
+#725=ADVANCED_FACE('',(#68),#34,.T.);
+#726=ADVANCED_FACE('',(#69),#703,.F.);
+#727=ADVANCED_FACE('',(#70),#35,.T.);
+#728=ADVANCED_FACE('',(#71),#704,.F.);
+#729=ADVANCED_FACE('',(#72),#36,.T.);
+#730=ADVANCED_FACE('',(#73),#37,.F.);
+#731=ADVANCED_FACE('',(#74),#38,.T.);
+#732=ADVANCED_FACE('',(#75),#39,.F.);
+#733=ADVANCED_FACE('',(#76),#705,.F.);
+#734=ADVANCED_FACE('',(#77),#40,.F.);
+#735=ADVANCED_FACE('',(#78),#706,.F.);
+#736=ADVANCED_FACE('',(#79),#41,.T.);
+#737=ADVANCED_FACE('',(#80),#42,.T.);
+#738=ADVANCED_FACE('',(#81),#43,.T.);
+#739=ADVANCED_FACE('',(#82),#44,.F.);
+#740=ADVANCED_FACE('',(#83),#45,.F.);
+#741=ADVANCED_FACE('',(#84),#46,.F.);
+#742=ADVANCED_FACE('',(#85),#47,.F.);
+#743=ADVANCED_FACE('',(#86),#48,.T.);
+#744=ADVANCED_FACE('',(#87),#19,.T.);
+#745=ADVANCED_FACE('',(#88),#49,.T.);
+#746=CLOSED_SHELL('',(#707,#708,#709,#710,#711,#712,#713,#714,#715,#716,
+#717,#718,#719,#720,#721,#722,#723,#724,#725,#726,#727,#728,#729,#730,#731,
+#732,#733,#734,#735,#736,#737,#738,#739,#740,#741,#742,#743,#744,#745));
+#747=DERIVED_UNIT_ELEMENT(#749,1.);
+#748=DERIVED_UNIT_ELEMENT(#1255,-3.);
+#749=(
+MASS_UNIT()
+NAMED_UNIT(*)
+SI_UNIT(.KILO.,.GRAM.)
);
-#199=(
-BOUNDED_CURVE()
-B_SPLINE_CURVE(2,(#780,#781,#782),.UNSPECIFIED.,.F.,.F.)
-B_SPLINE_CURVE_WITH_KNOTS((3,3),(31.4120598130698,31.8006731456901),
- .UNSPECIFIED.)
-CURVE()
-GEOMETRIC_REPRESENTATION_ITEM()
-RATIONAL_B_SPLINE_CURVE((13.5600732229924,13.6241212154372,13.6878315833722))
-REPRESENTATION_ITEM('')
-);
-#200=(
-BOUNDED_CURVE()
-B_SPLINE_CURVE(2,(#794,#795,#796),.UNSPECIFIED.,.F.,.F.)
-B_SPLINE_CURVE_WITH_KNOTS((3,3),(178.464778895689,178.853392228311),
- .UNSPECIFIED.)
-CURVE()
-GEOMETRIC_REPRESENTATION_ITEM()
-RATIONAL_B_SPLINE_CURVE((13.6878315833726,13.6241212154374,13.5600732229924))
-REPRESENTATION_ITEM('')
-);
-#201=VERTEX_POINT('',#734);
-#202=VERTEX_POINT('',#735);
-#203=VERTEX_POINT('',#739);
-#204=VERTEX_POINT('',#741);
-#205=VERTEX_POINT('',#745);
-#206=VERTEX_POINT('',#747);
-#207=VERTEX_POINT('',#749);
-#208=VERTEX_POINT('',#751);
-#209=VERTEX_POINT('',#755);
-#210=VERTEX_POINT('',#757);
-#211=VERTEX_POINT('',#761);
-#212=VERTEX_POINT('',#763);
-#213=VERTEX_POINT('',#770);
-#214=VERTEX_POINT('',#772);
-#215=VERTEX_POINT('',#778);
-#216=VERTEX_POINT('',#779);
-#217=VERTEX_POINT('',#783);
-#218=VERTEX_POINT('',#785);
-#219=VERTEX_POINT('',#787);
-#220=VERTEX_POINT('',#789);
-#221=VERTEX_POINT('',#791);
-#222=VERTEX_POINT('',#793);
-#223=VERTEX_POINT('',#799);
-#224=VERTEX_POINT('',#801);
-#225=VERTEX_POINT('',#805);
-#226=VERTEX_POINT('',#807);
-#227=VERTEX_POINT('',#815);
-#228=VERTEX_POINT('',#817);
-#229=VERTEX_POINT('',#821);
-#230=VERTEX_POINT('',#833);
-#231=VERTEX_POINT('',#844);
-#232=VERTEX_POINT('',#849);
-#233=VERTEX_POINT('',#860);
-#234=VERTEX_POINT('',#874);
-#235=VERTEX_POINT('',#876);
-#236=VERTEX_POINT('',#882);
-#237=VERTEX_POINT('',#884);
-#238=VERTEX_POINT('',#887);
-#239=VERTEX_POINT('',#889);
-#240=VERTEX_POINT('',#893);
-#241=VERTEX_POINT('',#894);
-#242=VERTEX_POINT('',#896);
-#243=VERTEX_POINT('',#898);
-#244=VERTEX_POINT('',#902);
-#245=VERTEX_POINT('',#906);
-#246=VERTEX_POINT('',#912);
-#247=VERTEX_POINT('',#914);
-#248=EDGE_CURVE('',#201,#202,#197,.F.);
-#249=EDGE_CURVE('',#203,#201,#107,.T.);
-#250=EDGE_CURVE('',#204,#203,#198,.F.);
-#251=EDGE_CURVE('',#205,#204,#108,.T.);
-#252=EDGE_CURVE('',#206,#205,#109,.T.);
-#253=EDGE_CURVE('',#207,#206,#110,.T.);
-#254=EDGE_CURVE('',#208,#207,#111,.T.);
-#255=EDGE_CURVE('',#202,#208,#112,.T.);
-#256=EDGE_CURVE('',#208,#209,#29,.T.);
-#257=EDGE_CURVE('',#207,#210,#113,.T.);
-#258=EDGE_CURVE('',#210,#209,#114,.F.);
-#259=EDGE_CURVE('',#211,#205,#30,.T.);
-#260=EDGE_CURVE('',#211,#212,#115,.T.);
-#261=EDGE_CURVE('',#212,#206,#116,.T.);
-#262=EDGE_CURVE('',#202,#204,#31,.T.);
-#263=EDGE_CURVE('',#201,#203,#32,.F.);
-#264=EDGE_CURVE('',#206,#213,#117,.T.);
-#265=EDGE_CURVE('',#213,#214,#118,.T.);
-#266=EDGE_CURVE('',#214,#207,#119,.T.);
-#267=EDGE_CURVE('',#205,#208,#33,.T.);
-#268=EDGE_CURVE('',#215,#216,#199,.F.);
-#269=EDGE_CURVE('',#217,#215,#120,.T.);
-#270=EDGE_CURVE('',#218,#217,#121,.T.);
-#271=EDGE_CURVE('',#219,#218,#122,.T.);
-#272=EDGE_CURVE('',#220,#219,#123,.T.);
-#273=EDGE_CURVE('',#221,#220,#124,.T.);
-#274=EDGE_CURVE('',#222,#221,#200,.F.);
-#275=EDGE_CURVE('',#216,#222,#125,.T.);
-#276=EDGE_CURVE('',#220,#223,#34,.T.);
-#277=EDGE_CURVE('',#219,#224,#126,.T.);
-#278=EDGE_CURVE('',#224,#223,#127,.F.);
-#279=EDGE_CURVE('',#225,#217,#35,.T.);
-#280=EDGE_CURVE('',#225,#226,#128,.T.);
-#281=EDGE_CURVE('',#226,#218,#129,.T.);
-#282=EDGE_CURVE('',#222,#216,#36,.F.);
-#283=EDGE_CURVE('',#221,#215,#37,.T.);
-#284=EDGE_CURVE('',#218,#227,#130,.T.);
-#285=EDGE_CURVE('',#227,#228,#131,.T.);
-#286=EDGE_CURVE('',#228,#219,#132,.T.);
-#287=EDGE_CURVE('',#229,#225,#20,.T.);
-#288=EDGE_CURVE('',#217,#220,#38,.T.);
-#289=EDGE_CURVE('',#223,#230,#21,.T.);
-#290=EDGE_CURVE('',#230,#231,#39,.T.);
-#291=EDGE_CURVE('',#231,#229,#40,.T.);
-#292=EDGE_CURVE('',#232,#211,#22,.T.);
-#293=EDGE_CURVE('',#209,#233,#23,.T.);
-#294=EDGE_CURVE('',#233,#232,#41,.T.);
-#295=EDGE_CURVE('',#234,#234,#42,.T.);
-#296=EDGE_CURVE('',#234,#235,#43,.T.);
-#297=EDGE_CURVE('',#235,#235,#44,.T.);
-#298=EDGE_CURVE('',#235,#231,#133,.T.);
-#299=EDGE_CURVE('',#230,#236,#15,.T.);
-#300=EDGE_CURVE('',#236,#237,#45,.T.);
-#301=EDGE_CURVE('',#237,#232,#16,.T.);
-#302=EDGE_CURVE('',#233,#238,#17,.T.);
-#303=EDGE_CURVE('',#238,#239,#46,.T.);
-#304=EDGE_CURVE('',#239,#229,#18,.T.);
-#305=EDGE_CURVE('',#240,#241,#134,.T.);
-#306=EDGE_CURVE('',#242,#240,#135,.T.);
-#307=EDGE_CURVE('',#243,#242,#136,.T.);
-#308=EDGE_CURVE('',#241,#243,#137,.T.);
-#309=EDGE_CURVE('',#210,#244,#138,.T.);
-#310=EDGE_CURVE('',#214,#240,#139,.T.);
-#311=EDGE_CURVE('',#227,#241,#140,.T.);
-#312=EDGE_CURVE('',#245,#226,#141,.T.);
-#313=EDGE_CURVE('',#244,#245,#142,.T.);
-#314=EDGE_CURVE('',#213,#242,#143,.T.);
-#315=EDGE_CURVE('',#246,#212,#144,.T.);
-#316=EDGE_CURVE('',#247,#246,#145,.T.);
-#317=EDGE_CURVE('',#224,#247,#146,.T.);
-#318=EDGE_CURVE('',#228,#243,#147,.T.);
-#319=EDGE_CURVE('',#244,#238,#148,.F.);
-#320=EDGE_CURVE('',#237,#246,#149,.F.);
-#321=EDGE_CURVE('',#239,#245,#150,.F.);
-#322=EDGE_CURVE('',#247,#236,#151,.F.);
-#323=ORIENTED_EDGE('',*,*,#248,.F.);
-#324=ORIENTED_EDGE('',*,*,#249,.F.);
-#325=ORIENTED_EDGE('',*,*,#250,.F.);
-#326=ORIENTED_EDGE('',*,*,#251,.F.);
-#327=ORIENTED_EDGE('',*,*,#252,.F.);
-#328=ORIENTED_EDGE('',*,*,#253,.F.);
-#329=ORIENTED_EDGE('',*,*,#254,.F.);
-#330=ORIENTED_EDGE('',*,*,#255,.F.);
-#331=ORIENTED_EDGE('',*,*,#256,.F.);
-#332=ORIENTED_EDGE('',*,*,#254,.T.);
-#333=ORIENTED_EDGE('',*,*,#257,.T.);
-#334=ORIENTED_EDGE('',*,*,#258,.T.);
-#335=ORIENTED_EDGE('',*,*,#259,.F.);
-#336=ORIENTED_EDGE('',*,*,#260,.T.);
-#337=ORIENTED_EDGE('',*,*,#261,.T.);
-#338=ORIENTED_EDGE('',*,*,#252,.T.);
-#339=ORIENTED_EDGE('',*,*,#248,.T.);
-#340=ORIENTED_EDGE('',*,*,#262,.T.);
-#341=ORIENTED_EDGE('',*,*,#250,.T.);
-#342=ORIENTED_EDGE('',*,*,#263,.F.);
-#343=ORIENTED_EDGE('',*,*,#253,.T.);
-#344=ORIENTED_EDGE('',*,*,#264,.T.);
-#345=ORIENTED_EDGE('',*,*,#265,.T.);
-#346=ORIENTED_EDGE('',*,*,#266,.T.);
-#347=ORIENTED_EDGE('',*,*,#255,.T.);
-#348=ORIENTED_EDGE('',*,*,#267,.F.);
-#349=ORIENTED_EDGE('',*,*,#251,.T.);
-#350=ORIENTED_EDGE('',*,*,#262,.F.);
-#351=ORIENTED_EDGE('',*,*,#268,.F.);
-#352=ORIENTED_EDGE('',*,*,#269,.F.);
-#353=ORIENTED_EDGE('',*,*,#270,.F.);
-#354=ORIENTED_EDGE('',*,*,#271,.F.);
-#355=ORIENTED_EDGE('',*,*,#272,.F.);
-#356=ORIENTED_EDGE('',*,*,#273,.F.);
-#357=ORIENTED_EDGE('',*,*,#274,.F.);
-#358=ORIENTED_EDGE('',*,*,#275,.F.);
-#359=ORIENTED_EDGE('',*,*,#276,.F.);
-#360=ORIENTED_EDGE('',*,*,#272,.T.);
-#361=ORIENTED_EDGE('',*,*,#277,.T.);
-#362=ORIENTED_EDGE('',*,*,#278,.T.);
-#363=ORIENTED_EDGE('',*,*,#279,.F.);
-#364=ORIENTED_EDGE('',*,*,#280,.T.);
-#365=ORIENTED_EDGE('',*,*,#281,.T.);
-#366=ORIENTED_EDGE('',*,*,#270,.T.);
-#367=ORIENTED_EDGE('',*,*,#275,.T.);
-#368=ORIENTED_EDGE('',*,*,#282,.T.);
-#369=ORIENTED_EDGE('',*,*,#268,.T.);
-#370=ORIENTED_EDGE('',*,*,#282,.F.);
-#371=ORIENTED_EDGE('',*,*,#274,.T.);
-#372=ORIENTED_EDGE('',*,*,#283,.T.);
-#373=ORIENTED_EDGE('',*,*,#271,.T.);
-#374=ORIENTED_EDGE('',*,*,#284,.T.);
-#375=ORIENTED_EDGE('',*,*,#285,.T.);
-#376=ORIENTED_EDGE('',*,*,#286,.T.);
-#377=ORIENTED_EDGE('',*,*,#287,.T.);
-#378=ORIENTED_EDGE('',*,*,#279,.T.);
-#379=ORIENTED_EDGE('',*,*,#288,.T.);
-#380=ORIENTED_EDGE('',*,*,#276,.T.);
-#381=ORIENTED_EDGE('',*,*,#289,.T.);
-#382=ORIENTED_EDGE('',*,*,#290,.T.);
-#383=ORIENTED_EDGE('',*,*,#291,.T.);
-#384=ORIENTED_EDGE('',*,*,#269,.T.);
-#385=ORIENTED_EDGE('',*,*,#283,.F.);
-#386=ORIENTED_EDGE('',*,*,#273,.T.);
-#387=ORIENTED_EDGE('',*,*,#288,.F.);
-#388=ORIENTED_EDGE('',*,*,#292,.T.);
-#389=ORIENTED_EDGE('',*,*,#259,.T.);
-#390=ORIENTED_EDGE('',*,*,#267,.T.);
-#391=ORIENTED_EDGE('',*,*,#256,.T.);
-#392=ORIENTED_EDGE('',*,*,#293,.T.);
-#393=ORIENTED_EDGE('',*,*,#294,.T.);
-#394=ORIENTED_EDGE('',*,*,#249,.T.);
-#395=ORIENTED_EDGE('',*,*,#263,.T.);
-#396=ORIENTED_EDGE('',*,*,#295,.T.);
-#397=ORIENTED_EDGE('',*,*,#296,.T.);
-#398=ORIENTED_EDGE('',*,*,#297,.T.);
-#399=ORIENTED_EDGE('',*,*,#296,.F.);
-#400=ORIENTED_EDGE('',*,*,#295,.F.);
-#401=ORIENTED_EDGE('',*,*,#297,.F.);
-#402=ORIENTED_EDGE('',*,*,#298,.T.);
-#403=ORIENTED_EDGE('',*,*,#290,.F.);
-#404=ORIENTED_EDGE('',*,*,#299,.T.);
-#405=ORIENTED_EDGE('',*,*,#300,.T.);
-#406=ORIENTED_EDGE('',*,*,#301,.T.);
-#407=ORIENTED_EDGE('',*,*,#294,.F.);
-#408=ORIENTED_EDGE('',*,*,#302,.T.);
-#409=ORIENTED_EDGE('',*,*,#303,.T.);
-#410=ORIENTED_EDGE('',*,*,#304,.T.);
-#411=ORIENTED_EDGE('',*,*,#291,.F.);
-#412=ORIENTED_EDGE('',*,*,#298,.F.);
-#413=ORIENTED_EDGE('',*,*,#305,.F.);
-#414=ORIENTED_EDGE('',*,*,#306,.F.);
-#415=ORIENTED_EDGE('',*,*,#307,.F.);
-#416=ORIENTED_EDGE('',*,*,#308,.F.);
-#417=ORIENTED_EDGE('',*,*,#309,.F.);
-#418=ORIENTED_EDGE('',*,*,#257,.F.);
-#419=ORIENTED_EDGE('',*,*,#266,.F.);
-#420=ORIENTED_EDGE('',*,*,#310,.T.);
-#421=ORIENTED_EDGE('',*,*,#305,.T.);
-#422=ORIENTED_EDGE('',*,*,#311,.F.);
-#423=ORIENTED_EDGE('',*,*,#284,.F.);
-#424=ORIENTED_EDGE('',*,*,#281,.F.);
-#425=ORIENTED_EDGE('',*,*,#312,.F.);
-#426=ORIENTED_EDGE('',*,*,#313,.F.);
-#427=ORIENTED_EDGE('',*,*,#265,.F.);
-#428=ORIENTED_EDGE('',*,*,#314,.T.);
-#429=ORIENTED_EDGE('',*,*,#306,.T.);
-#430=ORIENTED_EDGE('',*,*,#310,.F.);
-#431=ORIENTED_EDGE('',*,*,#315,.F.);
-#432=ORIENTED_EDGE('',*,*,#316,.F.);
-#433=ORIENTED_EDGE('',*,*,#317,.F.);
-#434=ORIENTED_EDGE('',*,*,#277,.F.);
-#435=ORIENTED_EDGE('',*,*,#286,.F.);
-#436=ORIENTED_EDGE('',*,*,#318,.T.);
-#437=ORIENTED_EDGE('',*,*,#307,.T.);
-#438=ORIENTED_EDGE('',*,*,#314,.F.);
-#439=ORIENTED_EDGE('',*,*,#264,.F.);
-#440=ORIENTED_EDGE('',*,*,#261,.F.);
-#441=ORIENTED_EDGE('',*,*,#285,.F.);
-#442=ORIENTED_EDGE('',*,*,#311,.T.);
-#443=ORIENTED_EDGE('',*,*,#308,.T.);
-#444=ORIENTED_EDGE('',*,*,#318,.F.);
-#445=ORIENTED_EDGE('',*,*,#309,.T.);
-#446=ORIENTED_EDGE('',*,*,#319,.T.);
-#447=ORIENTED_EDGE('',*,*,#302,.F.);
-#448=ORIENTED_EDGE('',*,*,#293,.F.);
-#449=ORIENTED_EDGE('',*,*,#258,.F.);
-#450=ORIENTED_EDGE('',*,*,#315,.T.);
-#451=ORIENTED_EDGE('',*,*,#260,.F.);
-#452=ORIENTED_EDGE('',*,*,#292,.F.);
-#453=ORIENTED_EDGE('',*,*,#301,.F.);
-#454=ORIENTED_EDGE('',*,*,#320,.T.);
-#455=ORIENTED_EDGE('',*,*,#313,.T.);
-#456=ORIENTED_EDGE('',*,*,#321,.F.);
-#457=ORIENTED_EDGE('',*,*,#303,.F.);
-#458=ORIENTED_EDGE('',*,*,#319,.F.);
-#459=ORIENTED_EDGE('',*,*,#312,.T.);
-#460=ORIENTED_EDGE('',*,*,#280,.F.);
-#461=ORIENTED_EDGE('',*,*,#287,.F.);
-#462=ORIENTED_EDGE('',*,*,#304,.F.);
-#463=ORIENTED_EDGE('',*,*,#321,.T.);
-#464=ORIENTED_EDGE('',*,*,#317,.T.);
-#465=ORIENTED_EDGE('',*,*,#322,.T.);
-#466=ORIENTED_EDGE('',*,*,#299,.F.);
-#467=ORIENTED_EDGE('',*,*,#289,.F.);
-#468=ORIENTED_EDGE('',*,*,#278,.F.);
-#469=ORIENTED_EDGE('',*,*,#316,.T.);
-#470=ORIENTED_EDGE('',*,*,#320,.F.);
-#471=ORIENTED_EDGE('',*,*,#300,.F.);
-#472=ORIENTED_EDGE('',*,*,#322,.F.);
-#473=PLANE('',#529);
-#474=PLANE('',#530);
-#475=PLANE('',#532);
-#476=PLANE('',#537);
-#477=PLANE('',#538);
-#478=PLANE('',#540);
-#479=PLANE('',#541);
-#480=PLANE('',#543);
-#481=PLANE('',#545);
-#482=PLANE('',#549);
-#483=PLANE('',#554);
-#484=PLANE('',#557);
-#485=PLANE('',#562);
-#486=PLANE('',#570);
-#487=PLANE('',#571);
-#488=PLANE('',#572);
-#489=PLANE('',#573);
-#490=PLANE('',#574);
-#491=PLANE('',#575);
-#492=PLANE('',#576);
-#493=PLANE('',#577);
-#494=PLANE('',#578);
-#495=PLANE('',#579);
-#496=PLANE('',#580);
-#497=ADVANCED_FACE('',(#47),#473,.F.);
-#498=ADVANCED_FACE('',(#48),#474,.F.);
-#499=ADVANCED_FACE('',(#49),#475,.F.);
-#500=ADVANCED_FACE('',(#50),#27,.T.);
-#501=ADVANCED_FACE('',(#51),#476,.F.);
-#502=ADVANCED_FACE('',(#52),#477,.F.);
-#503=ADVANCED_FACE('',(#53),#478,.F.);
-#504=ADVANCED_FACE('',(#54),#479,.F.);
-#505=ADVANCED_FACE('',(#55),#480,.F.);
-#506=ADVANCED_FACE('',(#56),#481,.T.);
-#507=ADVANCED_FACE('',(#57),#28,.T.);
-#508=ADVANCED_FACE('',(#58),#482,.F.);
-#509=ADVANCED_FACE('',(#59),#24,.F.);
-#510=ADVANCED_FACE('',(#60),#483,.F.);
-#511=ADVANCED_FACE('',(#61),#25,.F.);
-#512=ADVANCED_FACE('',(#62),#484,.T.);
-#513=ADVANCED_FACE('',(#63),#26,.T.);
-#514=ADVANCED_FACE('',(#64),#485,.T.);
-#515=ADVANCED_FACE('',(#65),#19,.T.);
-#516=ADVANCED_FACE('',(#66),#486,.F.);
-#517=ADVANCED_FACE('',(#67),#487,.F.);
-#518=ADVANCED_FACE('',(#68),#488,.F.);
-#519=ADVANCED_FACE('',(#69),#489,.F.);
-#520=ADVANCED_FACE('',(#70),#490,.F.);
-#521=ADVANCED_FACE('',(#71),#491,.F.);
-#522=ADVANCED_FACE('',(#72),#492,.F.);
-#523=ADVANCED_FACE('',(#73),#493,.F.);
-#524=ADVANCED_FACE('',(#74),#494,.F.);
-#525=ADVANCED_FACE('',(#75),#495,.F.);
-#526=ADVANCED_FACE('',(#76),#496,.F.);
-#527=CLOSED_SHELL('',(#497,#498,#499,#500,#501,#502,#503,#504,#505,#506,
-#507,#508,#509,#510,#511,#512,#513,#514,#515,#516,#517,#518,#519,#520,#521,
-#522,#523,#524,#525,#526));
-#528=AXIS2_PLACEMENT_3D('',#732,#581,#582);
-#529=AXIS2_PLACEMENT_3D('',#733,#583,#584);
-#530=AXIS2_PLACEMENT_3D('',#754,#591,#592);
-#531=AXIS2_PLACEMENT_3D('',#756,#593,#594);
-#532=AXIS2_PLACEMENT_3D('',#760,#597,#598);
-#533=AXIS2_PLACEMENT_3D('',#762,#599,#600);
-#534=AXIS2_PLACEMENT_3D('',#766,#603,#604);
-#535=AXIS2_PLACEMENT_3D('',#767,#605,#606);
-#536=AXIS2_PLACEMENT_3D('',#768,#607,#608);
-#537=AXIS2_PLACEMENT_3D('',#769,#609,#610);
-#538=AXIS2_PLACEMENT_3D('',#775,#614,#615);
-#539=AXIS2_PLACEMENT_3D('',#776,#616,#617);
-#540=AXIS2_PLACEMENT_3D('',#777,#618,#619);
-#541=AXIS2_PLACEMENT_3D('',#798,#626,#627);
-#542=AXIS2_PLACEMENT_3D('',#800,#628,#629);
-#543=AXIS2_PLACEMENT_3D('',#804,#632,#633);
-#544=AXIS2_PLACEMENT_3D('',#806,#634,#635);
-#545=AXIS2_PLACEMENT_3D('',#810,#638,#639);
-#546=AXIS2_PLACEMENT_3D('',#811,#640,#641);
-#547=AXIS2_PLACEMENT_3D('',#812,#642,#643);
-#548=AXIS2_PLACEMENT_3D('',#813,#644,#645);
-#549=AXIS2_PLACEMENT_3D('',#814,#646,#647);
-#550=AXIS2_PLACEMENT_3D('',#820,#651,#652);
-#551=AXIS2_PLACEMENT_3D('',#832,#653,#654);
-#552=AXIS2_PLACEMENT_3D('',#845,#655,#656);
-#553=AXIS2_PLACEMENT_3D('',#846,#657,#658);
-#554=AXIS2_PLACEMENT_3D('',#847,#659,#660);
-#555=AXIS2_PLACEMENT_3D('',#848,#661,#662);
-#556=AXIS2_PLACEMENT_3D('',#871,#663,#664);
-#557=AXIS2_PLACEMENT_3D('',#872,#665,#666);
-#558=AXIS2_PLACEMENT_3D('',#873,#667,#668);
-#559=AXIS2_PLACEMENT_3D('',#875,#669,#670);
-#560=AXIS2_PLACEMENT_3D('',#877,#671,#672);
-#561=AXIS2_PLACEMENT_3D('',#878,#673,#674);
-#562=AXIS2_PLACEMENT_3D('',#879,#675,#676);
-#563=AXIS2_PLACEMENT_3D('',#880,#677,#678);
-#564=AXIS2_PLACEMENT_3D('',#883,#680,#681);
-#565=AXIS2_PLACEMENT_3D('',#885,#682,#683);
-#566=AXIS2_PLACEMENT_3D('',#886,#684,#685);
-#567=AXIS2_PLACEMENT_3D('',#888,#686,#687);
-#568=AXIS2_PLACEMENT_3D('',#890,#688,#689);
-#569=AXIS2_PLACEMENT_3D('',#891,#690,#691);
-#570=AXIS2_PLACEMENT_3D('',#892,#692,#693);
-#571=AXIS2_PLACEMENT_3D('',#901,#698,#699);
-#572=AXIS2_PLACEMENT_3D('',#909,#705,#706);
-#573=AXIS2_PLACEMENT_3D('',#911,#708,#709);
-#574=AXIS2_PLACEMENT_3D('',#918,#714,#715);
-#575=AXIS2_PLACEMENT_3D('',#919,#716,#717);
-#576=AXIS2_PLACEMENT_3D('',#921,#719,#720);
-#577=AXIS2_PLACEMENT_3D('',#923,#722,#723);
-#578=AXIS2_PLACEMENT_3D('',#925,#725,#726);
-#579=AXIS2_PLACEMENT_3D('',#926,#727,#728);
-#580=AXIS2_PLACEMENT_3D('',#928,#730,#731);
-#581=DIRECTION('axis',(0.,0.,1.));
-#582=DIRECTION('refdir',(1.,0.,0.));
-#583=DIRECTION('center_axis',(0.998629534754574,0.,0.0523359562429438));
-#584=DIRECTION('ref_axis',(0.0523359562429438,0.,-0.998629534754574));
-#585=DIRECTION('',(0.,1.,0.));
-#586=DIRECTION('',(0.,-1.,0.));
-#587=DIRECTION('',(0.,-1.,0.));
-#588=DIRECTION('',(0.,-1.,0.));
-#589=DIRECTION('',(0.,-1.,0.));
-#590=DIRECTION('',(0.,-1.,0.));
-#591=DIRECTION('center_axis',(0.,0.,1.));
-#592=DIRECTION('ref_axis',(0.,-1.,0.));
-#593=DIRECTION('center_axis',(0.,0.,1.));
-#594=DIRECTION('ref_axis',(1.,0.,0.));
-#595=DIRECTION('',(-1.,0.,0.));
-#596=DIRECTION('',(0.,-1.,0.));
-#597=DIRECTION('center_axis',(0.,0.,1.));
-#598=DIRECTION('ref_axis',(0.,-1.,0.));
-#599=DIRECTION('center_axis',(0.,0.,1.));
-#600=DIRECTION('ref_axis',(1.,0.,0.));
-#601=DIRECTION('',(0.,1.,0.));
-#602=DIRECTION('',(1.,0.,0.));
-#603=DIRECTION('center_axis',(0.,0.,-1.));
-#604=DIRECTION('ref_axis',(1.,0.,0.));
-#605=DIRECTION('center_axis',(0.,0.,-1.));
-#606=DIRECTION('ref_axis',(1.,0.,0.));
-#607=DIRECTION('center_axis',(0.,0.,1.));
-#608=DIRECTION('ref_axis',(1.,0.,0.));
-#609=DIRECTION('center_axis',(0.,0.,-1.));
-#610=DIRECTION('ref_axis',(1.,0.,0.));
-#611=DIRECTION('',(1.,0.,0.));
-#612=DIRECTION('',(0.,1.,0.));
-#613=DIRECTION('',(-1.,0.,0.));
-#614=DIRECTION('center_axis',(0.,0.,-1.));
-#615=DIRECTION('ref_axis',(1.,0.,0.));
-#616=DIRECTION('center_axis',(0.,0.,1.));
-#617=DIRECTION('ref_axis',(1.,0.,0.));
-#618=DIRECTION('center_axis',(-0.998629534754574,0.,0.0523359562429438));
-#619=DIRECTION('ref_axis',(0.0523359562429438,0.,0.998629534754574));
-#620=DIRECTION('',(0.,1.,0.));
-#621=DIRECTION('',(0.,1.,0.));
-#622=DIRECTION('',(0.,1.,0.));
-#623=DIRECTION('',(0.,1.,0.));
-#624=DIRECTION('',(0.,1.,0.));
-#625=DIRECTION('',(0.,-1.,0.));
-#626=DIRECTION('center_axis',(0.,0.,1.));
-#627=DIRECTION('ref_axis',(0.,1.,0.));
-#628=DIRECTION('center_axis',(0.,0.,1.));
-#629=DIRECTION('ref_axis',(-1.,0.,0.));
-#630=DIRECTION('',(1.,0.,0.));
-#631=DIRECTION('',(0.,1.,0.));
-#632=DIRECTION('center_axis',(0.,0.,1.));
-#633=DIRECTION('ref_axis',(0.,1.,0.));
-#634=DIRECTION('center_axis',(0.,0.,1.));
-#635=DIRECTION('ref_axis',(-1.,0.,0.));
-#636=DIRECTION('',(0.,-1.,0.));
-#637=DIRECTION('',(-1.,0.,0.));
-#638=DIRECTION('center_axis',(0.,0.,-1.));
-#639=DIRECTION('ref_axis',(1.,0.,0.));
-#640=DIRECTION('center_axis',(0.,0.,1.));
-#641=DIRECTION('ref_axis',(1.,0.,0.));
-#642=DIRECTION('center_axis',(0.,0.,-1.));
-#643=DIRECTION('ref_axis',(-1.,-8.75931951708652E-15,0.));
-#644=DIRECTION('center_axis',(0.,0.,-1.));
-#645=DIRECTION('ref_axis',(1.,0.,0.));
-#646=DIRECTION('center_axis',(0.,0.,-1.));
-#647=DIRECTION('ref_axis',(1.,0.,0.));
-#648=DIRECTION('',(-1.,0.,0.));
-#649=DIRECTION('',(0.,-1.,0.));
-#650=DIRECTION('',(1.,0.,0.));
-#651=DIRECTION('center_axis',(0.,0.,1.));
-#652=DIRECTION('ref_axis',(-1.,0.,0.));
-#653=DIRECTION('center_axis',(0.,0.,1.));
-#654=DIRECTION('ref_axis',(-1.,0.,0.));
-#655=DIRECTION('center_axis',(0.,0.,-1.));
-#656=DIRECTION('ref_axis',(-1.,0.,0.));
-#657=DIRECTION('center_axis',(0.,0.,-1.));
-#658=DIRECTION('ref_axis',(-1.,0.,0.));
-#659=DIRECTION('center_axis',(0.,0.,-1.));
-#660=DIRECTION('ref_axis',(1.,0.,0.));
-#661=DIRECTION('center_axis',(0.,0.,1.));
-#662=DIRECTION('ref_axis',(1.,0.,0.));
-#663=DIRECTION('center_axis',(0.,0.,-1.));
-#664=DIRECTION('ref_axis',(1.,0.,0.));
-#665=DIRECTION('center_axis',(0.,0.,-1.));
-#666=DIRECTION('ref_axis',(1.,0.,0.));
-#667=DIRECTION('center_axis',(0.,0.,1.));
-#668=DIRECTION('ref_axis',(1.,0.,0.));
-#669=DIRECTION('center_axis',(0.,0.,-1.));
-#670=DIRECTION('ref_axis',(1.,0.,0.));
-#671=DIRECTION('center_axis',(0.,-1.,0.));
-#672=DIRECTION('ref_axis',(-1.,0.,0.));
-#673=DIRECTION('center_axis',(0.,0.,1.));
-#674=DIRECTION('ref_axis',(1.,0.,0.));
-#675=DIRECTION('center_axis',(0.,0.,1.));
-#676=DIRECTION('ref_axis',(1.,0.,0.));
-#677=DIRECTION('center_axis',(0.,0.,1.));
-#678=DIRECTION('ref_axis',(1.,0.,0.));
-#679=DIRECTION('',(0.,0.,-1.));
-#680=DIRECTION('center_axis',(-0.998629534754574,0.,0.0523359562429438));
-#681=DIRECTION('ref_axis',(0.0523359562429438,0.,0.998629534754574));
-#682=DIRECTION('center_axis',(0.,0.,1.));
-#683=DIRECTION('ref_axis',(1.,0.,0.));
-#684=DIRECTION('center_axis',(0.998629534754574,0.,0.0523359562429438));
-#685=DIRECTION('ref_axis',(0.0523359562429438,0.,-0.998629534754574));
-#686=DIRECTION('center_axis',(0.998629534754574,0.,0.0523359562429438));
-#687=DIRECTION('ref_axis',(0.0523359562429438,0.,-0.998629534754574));
-#688=DIRECTION('center_axis',(0.,0.,1.));
-#689=DIRECTION('ref_axis',(1.,0.,0.));
-#690=DIRECTION('center_axis',(-0.998629534754574,0.,0.0523359562429438));
-#691=DIRECTION('ref_axis',(0.0523359562429438,0.,0.998629534754574));
-#692=DIRECTION('center_axis',(0.,0.,1.));
-#693=DIRECTION('ref_axis',(1.,0.,0.));
-#694=DIRECTION('',(-1.,0.,0.));
-#695=DIRECTION('',(0.,1.,0.));
-#696=DIRECTION('',(1.,0.,0.));
-#697=DIRECTION('',(0.,-1.,0.));
-#698=DIRECTION('center_axis',(0.,1.,0.));
-#699=DIRECTION('ref_axis',(-1.,0.,0.));
-#700=DIRECTION('',(-0.0523359562429438,0.,0.998629534754574));
-#701=DIRECTION('',(0.,0.,1.));
-#702=DIRECTION('',(0.,0.,1.));
-#703=DIRECTION('',(-0.0523359562429438,0.,-0.998629534754574));
-#704=DIRECTION('',(-1.,0.,0.));
-#705=DIRECTION('center_axis',(1.,0.,0.));
-#706=DIRECTION('ref_axis',(0.,1.,0.));
-#707=DIRECTION('',(0.,0.,1.));
-#708=DIRECTION('center_axis',(0.,-1.,0.));
-#709=DIRECTION('ref_axis',(1.,0.,0.));
-#710=DIRECTION('',(0.0523359562429438,0.,-0.998629534754574));
-#711=DIRECTION('',(1.,0.,0.));
-#712=DIRECTION('',(0.0523359562429438,0.,0.998629534754574));
-#713=DIRECTION('',(0.,0.,1.));
-#714=DIRECTION('center_axis',(-1.,0.,0.));
-#715=DIRECTION('ref_axis',(0.,-1.,0.));
-#716=DIRECTION('center_axis',(0.998629534754574,0.,0.0523359562429438));
-#717=DIRECTION('ref_axis',(0.,1.,0.));
-#718=DIRECTION('',(0.,-1.,0.));
-#719=DIRECTION('center_axis',(0.998629534754574,0.,0.0523359562429438));
-#720=DIRECTION('ref_axis',(0.,1.,0.));
-#721=DIRECTION('',(0.,-1.,0.));
-#722=DIRECTION('center_axis',(0.,0.,1.));
-#723=DIRECTION('ref_axis',(1.,0.,0.));
-#724=DIRECTION('',(0.,1.,0.));
-#725=DIRECTION('center_axis',(-0.998629534754574,0.,0.0523359562429438));
-#726=DIRECTION('ref_axis',(0.,-1.,0.));
-#727=DIRECTION('center_axis',(-0.998629534754574,0.,0.0523359562429438));
-#728=DIRECTION('ref_axis',(0.,-1.,0.));
-#729=DIRECTION('',(0.,1.,0.));
-#730=DIRECTION('center_axis',(0.,0.,1.));
-#731=DIRECTION('ref_axis',(1.,0.,0.));
-#732=CARTESIAN_POINT('',(0.,0.,0.));
-#733=CARTESIAN_POINT('Origin',(-31.3972446899932,39.,6.59725906950915));
-#734=CARTESIAN_POINT('',(-31.2532669430451,44.1197408428233,3.85));
-#735=CARTESIAN_POINT('',(-31.2925727775074,44.0634131040819,4.6));
-#736=CARTESIAN_POINT('Ctrl Pts',(-31.2925727775077,44.0634131040822,4.6000000000019));
-#737=CARTESIAN_POINT('Ctrl Pts',(-31.2730639423025,44.0913973222213,4.22774924883471));
-#738=CARTESIAN_POINT('Ctrl Pts',(-31.2532669430453,44.1197408428237,3.85000000000001));
-#739=CARTESIAN_POINT('',(-31.2532669430451,36.3802591571767,3.85));
-#740=CARTESIAN_POINT('',(-31.2532669430451,39.625,3.85));
-#741=CARTESIAN_POINT('',(-31.2925727775074,36.4365868959181,4.6));
-#742=CARTESIAN_POINT('Ctrl Pts',(-31.2532669430453,36.3802591571764,3.85000000000001));
-#743=CARTESIAN_POINT('Ctrl Pts',(-31.2730639423025,36.4086026777788,4.22774924883371));
-#744=CARTESIAN_POINT('Ctrl Pts',(-31.2925727775076,36.4365868959177,4.59999999999993));
-#745=CARTESIAN_POINT('',(-31.2925727775074,36.9648638532956,4.6));
-#746=CARTESIAN_POINT('',(-31.2925727775074,39.625,4.6));
-#747=CARTESIAN_POINT('',(-31.2925727775074,39.,4.6));
-#748=CARTESIAN_POINT('',(-31.2925727775074,40.875,4.6));
-#749=CARTESIAN_POINT('',(-31.2925727775074,41.5,4.6));
-#750=CARTESIAN_POINT('',(-31.2925727775074,39.625,4.6));
-#751=CARTESIAN_POINT('',(-31.2925727775074,43.5351361467044,4.6));
-#752=CARTESIAN_POINT('',(-31.2925727775074,40.875,4.6));
-#753=CARTESIAN_POINT('',(-31.2925727775074,39.625,4.6));
-#754=CARTESIAN_POINT('Origin',(-31.4165727775074,44.1004786005849,4.6));
-#755=CARTESIAN_POINT('',(-31.3117572189413,43.5421237967704,4.6));
-#756=CARTESIAN_POINT('Origin',(-32.5,40.25,4.6));
-#757=CARTESIAN_POINT('',(-31.3117572189413,41.5,4.6));
-#758=CARTESIAN_POINT('',(-31.875,41.5,4.6));
-#759=CARTESIAN_POINT('',(-31.3117572189413,38.8190911978746,4.6));
-#760=CARTESIAN_POINT('Origin',(-31.4165727775074,44.1004786005849,4.6));
-#761=CARTESIAN_POINT('',(-31.3117572189413,36.9578762032296,4.6));
-#762=CARTESIAN_POINT('Origin',(-32.5,40.25,4.6));
-#763=CARTESIAN_POINT('',(-31.3117572189413,39.,4.6));
-#764=CARTESIAN_POINT('',(-31.3117572189413,38.8190911978746,4.6));
-#765=CARTESIAN_POINT('',(-33.125,39.,4.6));
-#766=CARTESIAN_POINT('Origin',(-32.5,40.25,4.6));
-#767=CARTESIAN_POINT('Origin',(-32.5,40.25,4.6));
-#768=CARTESIAN_POINT('Origin',(-32.5,40.25,3.85));
-#769=CARTESIAN_POINT('Origin',(-32.5,40.25,4.6));
-#770=CARTESIAN_POINT('',(-31.25,39.,4.6));
-#771=CARTESIAN_POINT('',(-33.125,39.,4.6));
-#772=CARTESIAN_POINT('',(-31.25,41.5,4.6));
-#773=CARTESIAN_POINT('',(-31.25,39.625,4.6));
-#774=CARTESIAN_POINT('',(-31.875,41.5,4.6));
-#775=CARTESIAN_POINT('Origin',(-32.5,40.25,4.6));
-#776=CARTESIAN_POINT('Origin',(-32.5,40.25,4.6));
-#777=CARTESIAN_POINT('Origin',(-33.6027553100068,37.4524679709498,6.59725906950915));
-#778=CARTESIAN_POINT('',(-33.7074272224926,44.0634131040819,4.6));
-#779=CARTESIAN_POINT('',(-33.7467330569549,44.1197408428233,3.85));
-#780=CARTESIAN_POINT('Ctrl Pts',(-33.7467330569546,44.1197408428226,3.85000000000001));
-#781=CARTESIAN_POINT('Ctrl Pts',(-33.7269360576974,44.0913973222202,4.22774924883367));
-#782=CARTESIAN_POINT('Ctrl Pts',(-33.7074272224924,44.0634131040812,4.59999999999986));
-#783=CARTESIAN_POINT('',(-33.7074272224926,43.5351361467044,4.6));
-#784=CARTESIAN_POINT('',(-33.7074272224926,38.8512339854749,4.6));
-#785=CARTESIAN_POINT('',(-33.7074272224926,41.5,4.6));
-#786=CARTESIAN_POINT('',(-33.7074272224926,38.8512339854749,4.6));
-#787=CARTESIAN_POINT('',(-33.7074272224926,39.,4.6));
-#788=CARTESIAN_POINT('',(-33.7074272224926,38.8512339854749,4.6));
-#789=CARTESIAN_POINT('',(-33.7074272224926,36.9648638532956,4.6));
-#790=CARTESIAN_POINT('',(-33.7074272224926,38.8512339854749,4.6));
-#791=CARTESIAN_POINT('',(-33.7074272224926,36.4365868959181,4.6));
-#792=CARTESIAN_POINT('',(-33.7074272224926,38.8512339854749,4.6));
-#793=CARTESIAN_POINT('',(-33.7467330569549,36.3802591571767,3.85));
-#794=CARTESIAN_POINT('Ctrl Pts',(-33.7074272224923,36.4365868959189,4.60000000000185));
-#795=CARTESIAN_POINT('Ctrl Pts',(-33.7269360576974,36.4086026777799,4.22774924883469));
-#796=CARTESIAN_POINT('Ctrl Pts',(-33.7467330569546,36.3802591571774,3.85000000000002));
-#797=CARTESIAN_POINT('',(-33.7467330569549,38.8512339854749,3.85));
-#798=CARTESIAN_POINT('Origin',(-33.5834272224926,36.3995213994151,4.6));
-#799=CARTESIAN_POINT('',(-33.6882427810587,36.9578762032296,4.6));
-#800=CARTESIAN_POINT('Origin',(-32.5,40.25,4.6));
-#801=CARTESIAN_POINT('',(-33.6882427810587,39.,4.6));
-#802=CARTESIAN_POINT('',(-33.125,39.,4.6));
-#803=CARTESIAN_POINT('',(-33.6882427810587,41.6809088021254,4.6));
-#804=CARTESIAN_POINT('Origin',(-33.5834272224926,36.3995213994151,4.6));
-#805=CARTESIAN_POINT('',(-33.6882427810587,43.5421237967704,4.6));
-#806=CARTESIAN_POINT('Origin',(-32.5,40.25,4.6));
-#807=CARTESIAN_POINT('',(-33.6882427810587,41.5,4.6));
-#808=CARTESIAN_POINT('',(-33.6882427810587,41.6809088021254,4.6));
-#809=CARTESIAN_POINT('',(-31.875,41.5,4.6));
-#810=CARTESIAN_POINT('Origin',(-32.5,40.25,3.85));
-#811=CARTESIAN_POINT('Origin',(-32.5,40.25,3.85));
-#812=CARTESIAN_POINT('Origin',(-32.5,40.25,4.6));
-#813=CARTESIAN_POINT('Origin',(-32.5,40.25,4.6));
-#814=CARTESIAN_POINT('Origin',(-32.5,40.25,4.6));
-#815=CARTESIAN_POINT('',(-33.75,41.5,4.6));
-#816=CARTESIAN_POINT('',(-31.875,41.5,4.6));
-#817=CARTESIAN_POINT('',(-33.75,39.,4.6));
-#818=CARTESIAN_POINT('',(-33.75,40.875,4.6));
-#819=CARTESIAN_POINT('',(-33.125,39.,4.6));
-#820=CARTESIAN_POINT('Origin',(-32.5,40.25,5.1));
-#821=CARTESIAN_POINT('',(-33.6620388914172,43.0158028879213,5.10000000000001));
-#822=CARTESIAN_POINT('Ctrl Pts',(-33.6620388914172,43.0158028879213,5.1));
-#823=CARTESIAN_POINT('Ctrl Pts',(-33.6651920712123,43.01447809447,5.03983374532976));
-#824=CARTESIAN_POINT('Ctrl Pts',(-33.6689112159236,43.0278824868506,4.96886823673186));
-#825=CARTESIAN_POINT('Ctrl Pts',(-33.6748289210536,43.0746859130229,4.85595169626728));
-#826=CARTESIAN_POINT('Ctrl Pts',(-33.6780423060377,43.1169412026611,4.79463665815568));
-#827=CARTESIAN_POINT('Ctrl Pts',(-33.6826780062787,43.2079072106537,4.70618222821446));
-#828=CARTESIAN_POINT('Ctrl Pts',(-33.6848769587568,43.2734163503024,4.66422371540944));
-#829=CARTESIAN_POINT('Ctrl Pts',(-33.6874521920649,43.3958794376124,4.61508533665515));
-#830=CARTESIAN_POINT('Ctrl Pts',(-33.6882427810587,43.4749994711774,4.6));
-#831=CARTESIAN_POINT('Ctrl Pts',(-33.6882427810587,43.5421237967704,4.6));
-#832=CARTESIAN_POINT('Origin',(-32.5,40.25,4.6));
-#833=CARTESIAN_POINT('',(-33.6620388914172,37.4841971120787,5.10000000000001));
-#834=CARTESIAN_POINT('Ctrl Pts',(-33.6882427810587,36.9578762032296,4.6));
-#835=CARTESIAN_POINT('Ctrl Pts',(-33.6882427810587,37.0250005288226,4.6));
-#836=CARTESIAN_POINT('Ctrl Pts',(-33.6874521920649,37.1041205623876,4.61508533665515));
-#837=CARTESIAN_POINT('Ctrl Pts',(-33.6848769587568,37.2265836496976,4.66422371540945));
-#838=CARTESIAN_POINT('Ctrl Pts',(-33.6826780062787,37.2920927893463,4.70618222821446));
-#839=CARTESIAN_POINT('Ctrl Pts',(-33.6780423060377,37.3830587973389,4.79463665815568));
-#840=CARTESIAN_POINT('Ctrl Pts',(-33.6748289210536,37.4253140869771,4.85595169626728));
-#841=CARTESIAN_POINT('Ctrl Pts',(-33.6689112159236,37.4721175131494,4.96886823673186));
-#842=CARTESIAN_POINT('Ctrl Pts',(-33.6651920712123,37.48552190553,5.03983374532976));
-#843=CARTESIAN_POINT('Ctrl Pts',(-33.6620388914172,37.4841971120787,5.1));
-#844=CARTESIAN_POINT('',(-35.5,40.25,5.09999999999999));
-#845=CARTESIAN_POINT('Origin',(-32.5,40.25,5.1));
-#846=CARTESIAN_POINT('Origin',(-32.5,40.25,5.1));
-#847=CARTESIAN_POINT('Origin',(-32.5,40.25,4.6));
-#848=CARTESIAN_POINT('Origin',(-32.5,40.25,5.1));
-#849=CARTESIAN_POINT('',(-31.3379611085828,37.4841971120787,5.10000000000001));
-#850=CARTESIAN_POINT('Ctrl Pts',(-31.3379611085828,37.4841971120787,5.1));
-#851=CARTESIAN_POINT('Ctrl Pts',(-31.3348079287877,37.48552190553,5.03983374532976));
-#852=CARTESIAN_POINT('Ctrl Pts',(-31.3310887840764,37.4721175131494,4.96886823673186));
-#853=CARTESIAN_POINT('Ctrl Pts',(-31.3251710789464,37.4253140869771,4.85595169626728));
-#854=CARTESIAN_POINT('Ctrl Pts',(-31.3219576939623,37.3830587973389,4.79463665815568));
-#855=CARTESIAN_POINT('Ctrl Pts',(-31.3173219937213,37.2920927893463,4.70618222821446));
-#856=CARTESIAN_POINT('Ctrl Pts',(-31.3151230412432,37.2265836496976,4.66422371540944));
-#857=CARTESIAN_POINT('Ctrl Pts',(-31.3125478079351,37.1041205623876,4.61508533665515));
-#858=CARTESIAN_POINT('Ctrl Pts',(-31.3117572189413,37.0250005288226,4.6));
-#859=CARTESIAN_POINT('Ctrl Pts',(-31.3117572189413,36.9578762032296,4.6));
-#860=CARTESIAN_POINT('',(-31.3379611085828,43.0158028879213,5.10000000000001));
-#861=CARTESIAN_POINT('Ctrl Pts',(-31.3117572189413,43.5421237967704,4.6));
-#862=CARTESIAN_POINT('Ctrl Pts',(-31.3117572189413,43.4749994711774,4.6));
-#863=CARTESIAN_POINT('Ctrl Pts',(-31.3125478079351,43.3958794376124,4.61508533665515));
-#864=CARTESIAN_POINT('Ctrl Pts',(-31.3151230412432,43.2734163503024,4.66422371540944));
-#865=CARTESIAN_POINT('Ctrl Pts',(-31.3173219937213,43.2079072106537,4.70618222821446));
-#866=CARTESIAN_POINT('Ctrl Pts',(-31.3219576939623,43.1169412026611,4.79463665815568));
-#867=CARTESIAN_POINT('Ctrl Pts',(-31.3251710789464,43.0746859130229,4.85595169626728));
-#868=CARTESIAN_POINT('Ctrl Pts',(-31.3310887840764,43.0278824868506,4.96886823673186));
-#869=CARTESIAN_POINT('Ctrl Pts',(-31.3348079287877,43.01447809447,5.03983374532976));
-#870=CARTESIAN_POINT('Ctrl Pts',(-31.3379611085828,43.0158028879213,5.1));
-#871=CARTESIAN_POINT('Origin',(-32.5,40.25,5.1));
-#872=CARTESIAN_POINT('Origin',(-32.5,40.25,3.85));
-#873=CARTESIAN_POINT('Origin',(-32.5,40.25,12.6));
-#874=CARTESIAN_POINT('',(-35.,40.25,13.1));
-#875=CARTESIAN_POINT('Origin',(-32.5,40.25,13.1));
-#876=CARTESIAN_POINT('',(-35.5,40.25,12.6));
-#877=CARTESIAN_POINT('Origin',(-35.,40.25,12.6));
-#878=CARTESIAN_POINT('Origin',(-32.5,40.25,12.6));
-#879=CARTESIAN_POINT('Origin',(-32.5,40.25,13.1));
-#880=CARTESIAN_POINT('Origin',(-32.5,40.25,4.6));
-#881=CARTESIAN_POINT('',(-35.5,40.25,4.6));
-#882=CARTESIAN_POINT('',(-33.5834272224926,37.4524679709498,6.6));
-#883=CARTESIAN_POINT('Origin',(-32.5,40.25,27.2730229235879));
-#884=CARTESIAN_POINT('',(-31.4165727775074,37.4524679709498,6.6));
-#885=CARTESIAN_POINT('Origin',(-32.5,40.25,6.6));
-#886=CARTESIAN_POINT('Origin',(-32.5,40.25,27.2730229235879));
-#887=CARTESIAN_POINT('',(-31.4165727775074,43.0475320290502,6.6));
-#888=CARTESIAN_POINT('Origin',(-32.5,40.25,27.2730229235879));
-#889=CARTESIAN_POINT('',(-33.5834272224926,43.0475320290502,6.6));
-#890=CARTESIAN_POINT('Origin',(-32.5,40.25,6.6));
-#891=CARTESIAN_POINT('Origin',(-32.5,40.25,27.2730229235879));
-#892=CARTESIAN_POINT('Origin',(-32.5,40.25,8.6));
-#893=CARTESIAN_POINT('',(-31.25,41.5,8.6));
-#894=CARTESIAN_POINT('',(-33.75,41.5,8.6));
-#895=CARTESIAN_POINT('',(-33.75,41.5,8.6));
-#896=CARTESIAN_POINT('',(-31.25,39.,8.6));
-#897=CARTESIAN_POINT('',(-31.25,41.5,8.6));
-#898=CARTESIAN_POINT('',(-33.75,39.,8.6));
-#899=CARTESIAN_POINT('',(-31.25,39.,8.6));
-#900=CARTESIAN_POINT('',(-33.75,39.,8.6));
-#901=CARTESIAN_POINT('Origin',(-31.25,41.5,4.6));
-#902=CARTESIAN_POINT('',(-31.4165727775074,41.5,6.6));
-#903=CARTESIAN_POINT('',(-31.3118701541713,41.5,4.60215493256167));
-#904=CARTESIAN_POINT('',(-31.25,41.5,4.6));
-#905=CARTESIAN_POINT('',(-33.75,41.5,4.6));
-#906=CARTESIAN_POINT('',(-33.5834272224926,41.5,6.6));
-#907=CARTESIAN_POINT('',(-33.6847060304338,41.5,4.66748522210396));
-#908=CARTESIAN_POINT('',(-31.875,41.5,6.6));
-#909=CARTESIAN_POINT('Origin',(-31.25,39.,4.6));
-#910=CARTESIAN_POINT('',(-31.25,39.,4.6));
-#911=CARTESIAN_POINT('Origin',(-33.75,39.,4.6));
-#912=CARTESIAN_POINT('',(-31.4165727775074,39.,6.6));
-#913=CARTESIAN_POINT('',(-31.3152939695662,39.,4.66748522210396));
-#914=CARTESIAN_POINT('',(-33.5834272224926,39.,6.6));
-#915=CARTESIAN_POINT('',(-33.125,39.,6.6));
-#916=CARTESIAN_POINT('',(-33.6881298458287,39.,4.60215493256167));
-#917=CARTESIAN_POINT('',(-33.75,39.,4.6));
-#918=CARTESIAN_POINT('Origin',(-33.75,41.5,4.6));
-#919=CARTESIAN_POINT('Origin',(-31.312152245655,37.3881823957492,4.60753755871915));
-#920=CARTESIAN_POINT('',(-31.4165727775074,38.8190911978746,6.6));
-#921=CARTESIAN_POINT('Origin',(-31.312152245655,37.3881823957492,4.60753755871915));
-#922=CARTESIAN_POINT('',(-31.4165727775074,38.8190911978746,6.6));
-#923=CARTESIAN_POINT('Origin',(-32.5,40.25,6.6));
-#924=CARTESIAN_POINT('',(-33.5834272224926,41.6809088021254,6.6));
-#925=CARTESIAN_POINT('Origin',(-33.687847754345,43.1118176042508,4.60753755871915));
-#926=CARTESIAN_POINT('Origin',(-33.687847754345,43.1118176042508,4.60753755871915));
-#927=CARTESIAN_POINT('',(-33.5834272224926,41.6809088021254,6.6));
-#928=CARTESIAN_POINT('Origin',(-32.5,40.25,6.6));
-#929=UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(0.01),#933,
+#750=DERIVED_UNIT((#747,#748));
+#751=MEASURE_REPRESENTATION_ITEM('density measure',
+POSITIVE_RATIO_MEASURE(7850.),#750);
+#752=PROPERTY_DEFINITION_REPRESENTATION(#757,#754);
+#753=PROPERTY_DEFINITION_REPRESENTATION(#758,#755);
+#754=REPRESENTATION('material name',(#756),#1252);
+#755=REPRESENTATION('density',(#751),#1252);
+#756=DESCRIPTIVE_REPRESENTATION_ITEM('Steel','Steel');
+#757=PROPERTY_DEFINITION('material property','material name',#1267);
+#758=PROPERTY_DEFINITION('material property','density of part',#1267);
+#759=AXIS2_PLACEMENT_3D('',#1033,#823,#824);
+#760=AXIS2_PLACEMENT_3D('',#1034,#825,#826);
+#761=AXIS2_PLACEMENT_3D('',#1035,#827,#828);
+#762=AXIS2_PLACEMENT_3D('',#1037,#829,#830);
+#763=AXIS2_PLACEMENT_3D('',#1040,#832,#833);
+#764=AXIS2_PLACEMENT_3D('',#1041,#834,#835);
+#765=AXIS2_PLACEMENT_3D('',#1043,#836,#837);
+#766=AXIS2_PLACEMENT_3D('',#1044,#838,#839);
+#767=AXIS2_PLACEMENT_3D('',#1046,#840,#841);
+#768=AXIS2_PLACEMENT_3D('',#1048,#843,#844);
+#769=AXIS2_PLACEMENT_3D('',#1057,#848,#849);
+#770=AXIS2_PLACEMENT_3D('',#1065,#853,#854);
+#771=AXIS2_PLACEMENT_3D('',#1073,#858,#859);
+#772=AXIS2_PLACEMENT_3D('',#1080,#863,#864);
+#773=AXIS2_PLACEMENT_3D('',#1081,#865,#866);
+#774=AXIS2_PLACEMENT_3D('',#1097,#875,#876);
+#775=AXIS2_PLACEMENT_3D('',#1099,#877,#878);
+#776=AXIS2_PLACEMENT_3D('',#1102,#880,#881);
+#777=AXIS2_PLACEMENT_3D('',#1103,#882,#883);
+#778=AXIS2_PLACEMENT_3D('',#1105,#884,#885);
+#779=AXIS2_PLACEMENT_3D('',#1107,#887,#888);
+#780=AXIS2_PLACEMENT_3D('',#1115,#894,#895);
+#781=AXIS2_PLACEMENT_3D('',#1116,#896,#897);
+#782=AXIS2_PLACEMENT_3D('',#1117,#898,#899);
+#783=AXIS2_PLACEMENT_3D('',#1137,#910,#911);
+#784=AXIS2_PLACEMENT_3D('',#1150,#919,#920);
+#785=AXIS2_PLACEMENT_3D('',#1152,#921,#922);
+#786=AXIS2_PLACEMENT_3D('',#1154,#924,#925);
+#787=AXIS2_PLACEMENT_3D('',#1163,#931,#932);
+#788=AXIS2_PLACEMENT_3D('',#1164,#933,#934);
+#789=AXIS2_PLACEMENT_3D('',#1165,#935,#936);
+#790=AXIS2_PLACEMENT_3D('',#1166,#937,#938);
+#791=AXIS2_PLACEMENT_3D('',#1167,#939,#940);
+#792=AXIS2_PLACEMENT_3D('',#1168,#941,#942);
+#793=AXIS2_PLACEMENT_3D('',#1172,#945,#946);
+#794=AXIS2_PLACEMENT_3D('',#1183,#953,#954);
+#795=AXIS2_PLACEMENT_3D('',#1185,#955,#956);
+#796=AXIS2_PLACEMENT_3D('',#1187,#958,#959);
+#797=AXIS2_PLACEMENT_3D('',#1196,#965,#966);
+#798=AXIS2_PLACEMENT_3D('',#1197,#967,#968);
+#799=AXIS2_PLACEMENT_3D('',#1198,#969,#970);
+#800=AXIS2_PLACEMENT_3D('',#1199,#971,#972);
+#801=AXIS2_PLACEMENT_3D('',#1200,#973,#974);
+#802=AXIS2_PLACEMENT_3D('',#1201,#975,#976);
+#803=AXIS2_PLACEMENT_3D('',#1205,#979,#980);
+#804=AXIS2_PLACEMENT_3D('',#1216,#987,#988);
+#805=AXIS2_PLACEMENT_3D('',#1218,#989,#990);
+#806=AXIS2_PLACEMENT_3D('',#1220,#992,#993);
+#807=AXIS2_PLACEMENT_3D('',#1229,#999,#1000);
+#808=AXIS2_PLACEMENT_3D('',#1230,#1001,#1002);
+#809=AXIS2_PLACEMENT_3D('',#1231,#1003,#1004);
+#810=AXIS2_PLACEMENT_3D('',#1232,#1005,#1006);
+#811=AXIS2_PLACEMENT_3D('',#1233,#1007,#1008);
+#812=AXIS2_PLACEMENT_3D('',#1234,#1009,#1010);
+#813=AXIS2_PLACEMENT_3D('',#1236,#1012,#1013);
+#814=AXIS2_PLACEMENT_3D('',#1237,#1014,#1015);
+#815=AXIS2_PLACEMENT_3D('',#1238,#1016,#1017);
+#816=AXIS2_PLACEMENT_3D('',#1239,#1018,#1019);
+#817=AXIS2_PLACEMENT_3D('',#1241,#1021,#1022);
+#818=AXIS2_PLACEMENT_3D('',#1242,#1023,#1024);
+#819=AXIS2_PLACEMENT_3D('',#1244,#1025,#1026);
+#820=AXIS2_PLACEMENT_3D('',#1245,#1027,#1028);
+#821=AXIS2_PLACEMENT_3D('',#1246,#1029,#1030);
+#822=AXIS2_PLACEMENT_3D('',#1247,#1031,#1032);
+#823=DIRECTION('axis',(0.,0.,1.));
+#824=DIRECTION('refdir',(1.,0.,0.));
+#825=DIRECTION('axis',(0.,0.,1.));
+#826=DIRECTION('refdir',(1.,0.,0.));
+#827=DIRECTION('center_axis',(0.,0.,1.));
+#828=DIRECTION('ref_axis',(1.,0.,0.));
+#829=DIRECTION('center_axis',(0.,0.,-1.));
+#830=DIRECTION('ref_axis',(1.,0.,0.));
+#831=DIRECTION('',(0.,0.,-1.));
+#832=DIRECTION('center_axis',(0.,0.,1.));
+#833=DIRECTION('ref_axis',(-1.,0.,0.));
+#834=DIRECTION('center_axis',(0.,0.,-1.));
+#835=DIRECTION('ref_axis',(-1.,0.,0.));
+#836=DIRECTION('center_axis',(0.,0.,-1.));
+#837=DIRECTION('ref_axis',(-1.,0.,0.));
+#838=DIRECTION('center_axis',(0.,0.,-1.));
+#839=DIRECTION('ref_axis',(-1.,0.,0.));
+#840=DIRECTION('center_axis',(0.,0.,1.));
+#841=DIRECTION('ref_axis',(1.,0.,0.));
+#842=DIRECTION('',(0.,0.,1.));
+#843=DIRECTION('center_axis',(0.,0.,1.));
+#844=DIRECTION('ref_axis',(1.,0.,0.));
+#845=DIRECTION('',(1.456554222731E-13,1.,0.));
+#846=DIRECTION('',(1.,-3.5527136788E-14,0.));
+#847=DIRECTION('',(1.522761232855E-13,-1.,0.));
+#848=DIRECTION('center_axis',(0.,0.,-1.));
+#849=DIRECTION('ref_axis',(-0.991071249821237,0.133333333333305,0.));
+#850=DIRECTION('',(-1.,1.522761232855E-13,0.));
+#851=DIRECTION('',(0.,1.,0.));
+#852=DIRECTION('',(1.,1.456554222731E-13,0.));
+#853=DIRECTION('center_axis',(0.,0.,-1.));
+#854=DIRECTION('ref_axis',(-0.133333333333305,-0.991071249821237,0.));
+#855=DIRECTION('',(-1.522761232855E-13,-1.,0.));
+#856=DIRECTION('',(-1.,0.,0.));
+#857=DIRECTION('',(-1.456554222731E-13,1.,0.));
+#858=DIRECTION('center_axis',(0.,0.,-1.));
+#859=DIRECTION('ref_axis',(0.991071249821237,-0.133333333333305,0.));
+#860=DIRECTION('',(1.,-1.456554222731E-13,0.));
+#861=DIRECTION('',(0.,-1.,0.));
+#862=DIRECTION('',(-1.,-1.522761232855E-13,0.));
+#863=DIRECTION('center_axis',(0.,0.,-1.));
+#864=DIRECTION('ref_axis',(0.133333333333305,0.991071249821237,0.));
+#865=DIRECTION('center_axis',(-1.,0.,0.));
+#866=DIRECTION('ref_axis',(0.,1.,0.));
+#867=DIRECTION('',(0.,0.,1.));
+#868=DIRECTION('',(1.457905051083E-13,-1.,0.));
+#869=DIRECTION('',(0.,0.,-1.));
+#870=DIRECTION('',(0.,1.,0.));
+#871=DIRECTION('',(0.,0.,1.));
+#872=DIRECTION('',(0.,-0.707106781186498,0.707106781186598));
+#873=DIRECTION('',(0.,0.,1.));
+#874=DIRECTION('',(-3.785366677674E-13,-1.,0.));
+#875=DIRECTION('center_axis',(0.,0.,-1.));
+#876=DIRECTION('ref_axis',(-1.,0.,0.));
+#877=DIRECTION('center_axis',(0.,0.,-1.));
+#878=DIRECTION('ref_axis',(0.199999999999994,0.979795897113273,0.));
+#879=DIRECTION('',(0.,0.,-1.));
+#880=DIRECTION('center_axis',(0.,0.,1.));
+#881=DIRECTION('ref_axis',(0.979795897113273,0.199999999999994,0.));
+#882=DIRECTION('center_axis',(0.,0.,-1.));
+#883=DIRECTION('ref_axis',(-1.,0.,0.));
+#884=DIRECTION('center_axis',(0.,0.,1.));
+#885=DIRECTION('ref_axis',(0.991071249821237,0.133333333333305,0.));
+#886=DIRECTION('',(1.,3.855466060594E-13,0.));
+#887=DIRECTION('center_axis',(0.,-1.,0.));
+#888=DIRECTION('ref_axis',(-1.,0.,0.));
+#889=DIRECTION('',(0.707106781186547,0.,-0.707106781186547));
+#890=DIRECTION('',(0.,0.,1.));
+#891=DIRECTION('',(1.,0.,0.));
+#892=DIRECTION('',(1.,-1.457905051083E-13,0.));
+#893=DIRECTION('',(0.,0.,-1.));
+#894=DIRECTION('center_axis',(0.,0.,-1.));
+#895=DIRECTION('ref_axis',(-1.,0.,0.));
+#896=DIRECTION('center_axis',(0.,0.,-1.));
+#897=DIRECTION('ref_axis',(-1.,0.,0.));
+#898=DIRECTION('center_axis',(0.,0.,1.));
+#899=DIRECTION('ref_axis',(1.,0.,0.));
+#900=DIRECTION('',(0.,1.,0.));
+#901=DIRECTION('',(-1.,0.,0.));
+#902=DIRECTION('',(0.,1.,0.));
+#903=DIRECTION('',(1.,0.,0.));
+#904=DIRECTION('',(0.,-1.,0.));
+#905=DIRECTION('',(1.,0.,0.));
+#906=DIRECTION('',(0.,-1.,0.));
+#907=DIRECTION('',(-1.,0.,0.));
+#908=DIRECTION('',(0.,-1.,0.));
+#909=DIRECTION('',(-1.,0.,0.));
+#910=DIRECTION('center_axis',(-1.,0.,0.));
+#911=DIRECTION('ref_axis',(0.,1.,0.));
+#912=DIRECTION('',(0.,0.707106781186498,-0.707106781186597));
+#913=DIRECTION('',(0.,0.,1.));
+#914=DIRECTION('',(0.,0.,-1.));
+#915=DIRECTION('',(-1.457905051083E-13,-1.,0.));
+#916=DIRECTION('',(0.,0.,-1.));
+#917=DIRECTION('',(-3.855466060594E-13,1.,0.));
+#918=DIRECTION('',(0.,0.,-1.));
+#919=DIRECTION('center_axis',(0.,0.,-1.));
+#920=DIRECTION('ref_axis',(-1.,0.,0.));
+#921=DIRECTION('center_axis',(0.,0.,1.));
+#922=DIRECTION('ref_axis',(-0.133333333333305,0.991071249821237,0.));
+#923=DIRECTION('',(0.,0.,1.));
+#924=DIRECTION('center_axis',(0.,1.,0.));
+#925=DIRECTION('ref_axis',(1.,0.,0.));
+#926=DIRECTION('',(0.,0.,1.));
+#927=DIRECTION('',(-1.,-1.457905051083E-13,0.));
+#928=DIRECTION('',(0.,0.,1.));
+#929=DIRECTION('',(0.707106781186547,0.,0.707106781186547));
+#930=DIRECTION('',(1.,-3.855466060594E-13,0.));
+#931=DIRECTION('center_axis',(0.,0.,1.));
+#932=DIRECTION('ref_axis',(1.,0.,0.));
+#933=DIRECTION('center_axis',(0.,0.,-1.));
+#934=DIRECTION('ref_axis',(-0.979795897113273,0.199999999999994,0.));
+#935=DIRECTION('center_axis',(0.,0.,1.));
+#936=DIRECTION('ref_axis',(-0.199999999999994,0.979795897113273,0.));
+#937=DIRECTION('center_axis',(0.,0.,-1.));
+#938=DIRECTION('ref_axis',(-1.,0.,0.));
+#939=DIRECTION('center_axis',(0.,0.,1.));
+#940=DIRECTION('ref_axis',(1.,0.,0.));
+#941=DIRECTION('center_axis',(0.707106781186548,0.,-0.707106781186548));
+#942=DIRECTION('ref_axis',(0.707106781186548,0.,0.707106781186548));
+#943=DIRECTION('',(-0.707106781186547,0.,-0.707106781186547));
+#944=DIRECTION('',(0.,1.,0.));
+#945=DIRECTION('center_axis',(0.,-1.,0.));
+#946=DIRECTION('ref_axis',(-1.,0.,0.));
+#947=DIRECTION('',(0.,0.,1.));
+#948=DIRECTION('',(0.,0.,-1.));
+#949=DIRECTION('',(1.,-1.457905051083E-13,0.));
+#950=DIRECTION('',(0.,0.,-1.));
+#951=DIRECTION('',(-1.,-3.785366677674E-13,0.));
+#952=DIRECTION('',(0.,0.,-1.));
+#953=DIRECTION('center_axis',(0.,0.,-1.));
+#954=DIRECTION('ref_axis',(-1.,0.,0.));
+#955=DIRECTION('center_axis',(0.,0.,1.));
+#956=DIRECTION('ref_axis',(-0.991071249821237,-0.133333333333305,0.));
+#957=DIRECTION('',(0.,0.,1.));
+#958=DIRECTION('center_axis',(-1.,0.,0.));
+#959=DIRECTION('ref_axis',(0.,1.,0.));
+#960=DIRECTION('',(0.,0.,1.));
+#961=DIRECTION('',(1.457905051083E-13,-1.,0.));
+#962=DIRECTION('',(0.,0.,1.));
+#963=DIRECTION('',(0.,0.707106781186547,0.707106781186547));
+#964=DIRECTION('',(3.855466060594E-13,1.,0.));
+#965=DIRECTION('center_axis',(0.,0.,1.));
+#966=DIRECTION('ref_axis',(1.,0.,0.));
+#967=DIRECTION('center_axis',(0.,0.,-1.));
+#968=DIRECTION('ref_axis',(-0.199999999999994,-0.979795897113273,0.));
+#969=DIRECTION('center_axis',(0.,0.,1.));
+#970=DIRECTION('ref_axis',(-0.979795897113273,-0.199999999999994,0.));
+#971=DIRECTION('center_axis',(0.,0.,-1.));
+#972=DIRECTION('ref_axis',(-1.,0.,0.));
+#973=DIRECTION('center_axis',(0.,0.,1.));
+#974=DIRECTION('ref_axis',(1.,0.,0.));
+#975=DIRECTION('center_axis',(0.,0.707106781186548,-0.707106781186548));
+#976=DIRECTION('ref_axis',(0.,0.707106781186548,0.707106781186548));
+#977=DIRECTION('',(0.,-0.707106781186547,-0.707106781186547));
+#978=DIRECTION('',(-1.,0.,0.));
+#979=DIRECTION('center_axis',(-1.,0.,0.));
+#980=DIRECTION('ref_axis',(0.,1.,0.));
+#981=DIRECTION('',(0.,0.,1.));
+#982=DIRECTION('',(0.,0.,-1.));
+#983=DIRECTION('',(-1.457905051083E-13,-1.,0.));
+#984=DIRECTION('',(0.,0.,-1.));
+#985=DIRECTION('',(3.785366677674E-13,-1.,0.));
+#986=DIRECTION('',(0.,0.,-1.));
+#987=DIRECTION('center_axis',(0.,0.,-1.));
+#988=DIRECTION('ref_axis',(-1.,0.,0.));
+#989=DIRECTION('center_axis',(0.,0.,1.));
+#990=DIRECTION('ref_axis',(0.133333333333305,-0.991071249821237,0.));
+#991=DIRECTION('',(0.,0.,1.));
+#992=DIRECTION('center_axis',(0.,1.,0.));
+#993=DIRECTION('ref_axis',(1.,0.,0.));
+#994=DIRECTION('',(0.,0.,1.));
+#995=DIRECTION('',(-1.,-1.457905051083E-13,0.));
+#996=DIRECTION('',(0.,0.,1.));
+#997=DIRECTION('',(-0.707106781186547,0.,0.707106781186547));
+#998=DIRECTION('',(-1.,3.785366677674E-13,0.));
+#999=DIRECTION('center_axis',(0.,0.,-1.));
+#1000=DIRECTION('ref_axis',(-1.,0.,0.));
+#1001=DIRECTION('center_axis',(0.,0.,-1.));
+#1002=DIRECTION('ref_axis',(0.979795897113273,-0.199999999999994,0.));
+#1003=DIRECTION('center_axis',(0.,0.,1.));
+#1004=DIRECTION('ref_axis',(0.199999999999994,-0.979795897113273,0.));
+#1005=DIRECTION('center_axis',(0.,0.,-1.));
+#1006=DIRECTION('ref_axis',(-1.,0.,0.));
+#1007=DIRECTION('center_axis',(0.,0.,-1.));
+#1008=DIRECTION('ref_axis',(-1.,0.,0.));
+#1009=DIRECTION('center_axis',(-0.707106781186548,0.,-0.707106781186548));
+#1010=DIRECTION('ref_axis',(-0.707106781186548,0.,0.707106781186548));
+#1011=DIRECTION('',(0.,-1.,0.));
+#1012=DIRECTION('center_axis',(1.,0.,0.));
+#1013=DIRECTION('ref_axis',(0.,-1.,0.));
+#1014=DIRECTION('center_axis',(0.,-1.,0.));
+#1015=DIRECTION('ref_axis',(-1.,0.,0.));
+#1016=DIRECTION('center_axis',(-1.,0.,0.));
+#1017=DIRECTION('ref_axis',(0.,1.,0.));
+#1018=DIRECTION('center_axis',(0.,1.,0.));
+#1019=DIRECTION('ref_axis',(1.,0.,0.));
+#1020=DIRECTION('',(1.,1.7763568394E-14,-3.663735981263E-14));
+#1021=DIRECTION('center_axis',(0.,-0.707106781186598,-0.707106781186498));
+#1022=DIRECTION('ref_axis',(0.,-0.707106781186498,0.707106781186598));
+#1023=DIRECTION('center_axis',(0.,0.,1.));
+#1024=DIRECTION('ref_axis',(1.,0.,0.));
+#1025=DIRECTION('center_axis',(0.,0.,-1.));
+#1026=DIRECTION('ref_axis',(-1.,0.,0.));
+#1027=DIRECTION('center_axis',(0.,-1.,0.));
+#1028=DIRECTION('ref_axis',(-1.,0.,0.));
+#1029=DIRECTION('center_axis',(0.,0.,1.));
+#1030=DIRECTION('ref_axis',(1.,0.,0.));
+#1031=DIRECTION('',(0.,0.,1.));
+#1032=DIRECTION('',(1.,0.,0.));
+#1033=CARTESIAN_POINT('',(0.,0.,0.));
+#1034=CARTESIAN_POINT('',(0.,0.,0.));
+#1035=CARTESIAN_POINT('Origin',(-32.5,40.25,4.6));
+#1036=CARTESIAN_POINT('',(-35.5,40.25,9.9));
+#1037=CARTESIAN_POINT('Origin',(-32.5,40.25,9.9));
+#1038=CARTESIAN_POINT('',(-35.5,40.25,6.9));
+#1039=CARTESIAN_POINT('',(-35.5,40.25,4.6));
+#1040=CARTESIAN_POINT('Origin',(-32.5,40.25,6.9));
+#1041=CARTESIAN_POINT('Origin',(0.,0.,6.9));
+#1042=CARTESIAN_POINT('',(-28.5,40.25,6.9));
+#1043=CARTESIAN_POINT('Origin',(-32.5,40.25,6.9));
+#1044=CARTESIAN_POINT('Origin',(-32.5,40.25,4.6));
+#1045=CARTESIAN_POINT('',(-28.5,40.25,4.6));
+#1046=CARTESIAN_POINT('Origin',(-32.5,40.25,4.6));
+#1047=CARTESIAN_POINT('',(-28.5,40.25,4.6));
+#1048=CARTESIAN_POINT('Origin',(-32.5,40.25,4.6));
+#1049=CARTESIAN_POINT('',(-32.1,42.15,4.6));
+#1050=CARTESIAN_POINT('',(-32.1,43.22321374946,4.6));
+#1051=CARTESIAN_POINT('',(-32.1,42.15,4.6));
+#1052=CARTESIAN_POINT('',(-32.9,42.15,4.6));
+#1053=CARTESIAN_POINT('',(-32.9,42.15,4.6));
+#1054=CARTESIAN_POINT('',(-32.9,43.22321374946,4.6));
+#1055=CARTESIAN_POINT('',(-32.9,43.22321374946,4.6));
+#1056=CARTESIAN_POINT('',(-35.47321374946,40.65,4.6));
+#1057=CARTESIAN_POINT('Origin',(-32.5,40.25,4.6));
+#1058=CARTESIAN_POINT('',(-34.4,40.65,4.6));
+#1059=CARTESIAN_POINT('',(-34.4,40.65,4.6));
+#1060=CARTESIAN_POINT('',(-34.4,39.85,4.6));
+#1061=CARTESIAN_POINT('',(-34.4,39.85,4.6));
+#1062=CARTESIAN_POINT('',(-35.47321374946,39.85,4.6));
+#1063=CARTESIAN_POINT('',(-35.47321374946,39.85,4.6));
+#1064=CARTESIAN_POINT('',(-32.9,37.27678625054,4.6));
+#1065=CARTESIAN_POINT('Origin',(-32.5,40.25,4.6));
+#1066=CARTESIAN_POINT('',(-32.9,38.35,4.6));
+#1067=CARTESIAN_POINT('',(-32.9,38.35,4.6));
+#1068=CARTESIAN_POINT('',(-32.1,38.35,4.6));
+#1069=CARTESIAN_POINT('',(-32.1,38.35,4.6));
+#1070=CARTESIAN_POINT('',(-32.1,37.27678625054,4.6));
+#1071=CARTESIAN_POINT('',(-32.1,37.27678625054,4.6));
+#1072=CARTESIAN_POINT('',(-29.52678625054,39.85,4.6));
+#1073=CARTESIAN_POINT('Origin',(-32.5,40.25,4.6));
+#1074=CARTESIAN_POINT('',(-30.6,39.85,4.6));
+#1075=CARTESIAN_POINT('',(-30.6,39.85,4.6));
+#1076=CARTESIAN_POINT('',(-30.6,40.65,4.6));
+#1077=CARTESIAN_POINT('',(-30.6,40.65,4.6));
+#1078=CARTESIAN_POINT('',(-29.52678625054,40.65,4.6));
+#1079=CARTESIAN_POINT('',(-29.52678625054,40.65,4.6));
+#1080=CARTESIAN_POINT('Origin',(-32.5,40.25,4.6));
+#1081=CARTESIAN_POINT('Origin',(-32.1,40.65,4.6));
+#1082=CARTESIAN_POINT('',(-32.1,42.20959179423,5.9));
+#1083=CARTESIAN_POINT('',(-32.1,42.20959179423,9.1));
+#1084=CARTESIAN_POINT('',(-32.1,42.20959179423,5.9));
+#1085=CARTESIAN_POINT('',(-32.1,40.65,9.1));
+#1086=CARTESIAN_POINT('',(-32.1,42.20959179423,9.1));
+#1087=CARTESIAN_POINT('',(-32.1,40.65,7.1));
+#1088=CARTESIAN_POINT('',(-32.1,40.65,9.1));
+#1089=CARTESIAN_POINT('',(-32.1,41.55,7.1));
+#1090=CARTESIAN_POINT('',(-32.1,40.65,7.1));
+#1091=CARTESIAN_POINT('',(-32.1,41.55,5.2));
+#1092=CARTESIAN_POINT('',(-32.1,41.55,5.2));
+#1093=CARTESIAN_POINT('',(-32.1,42.15,4.6));
+#1094=CARTESIAN_POINT('',(-32.1,43.22321374946,5.9));
+#1095=CARTESIAN_POINT('',(-32.1,43.22321374946,4.6));
+#1096=CARTESIAN_POINT('',(-32.1,43.22321374946,5.9));
+#1097=CARTESIAN_POINT('Origin',(-32.5,40.25,4.6));
+#1098=CARTESIAN_POINT('',(-30.54040820577,40.65,5.9));
+#1099=CARTESIAN_POINT('Origin',(-32.5,40.25,5.9));
+#1100=CARTESIAN_POINT('',(-30.54040820577,40.65,9.1));
+#1101=CARTESIAN_POINT('',(-30.54040820577,40.65,9.1));
+#1102=CARTESIAN_POINT('Origin',(-32.5,40.25,9.1));
+#1103=CARTESIAN_POINT('Origin',(0.,0.,5.9));
+#1104=CARTESIAN_POINT('',(-29.52678625054,40.65,5.9));
+#1105=CARTESIAN_POINT('Origin',(-32.5,40.25,5.9));
+#1106=CARTESIAN_POINT('',(-30.54040820577,40.65,5.9));
+#1107=CARTESIAN_POINT('Origin',(-30.54040820577,40.65,4.6));
+#1108=CARTESIAN_POINT('',(-31.2,40.65,5.2));
+#1109=CARTESIAN_POINT('',(-31.2,40.65,5.2));
+#1110=CARTESIAN_POINT('',(-31.2,40.65,7.1));
+#1111=CARTESIAN_POINT('',(-31.2,40.65,5.2));
+#1112=CARTESIAN_POINT('',(-32.1,40.65,7.1));
+#1113=CARTESIAN_POINT('',(-32.1,40.65,9.1));
+#1114=CARTESIAN_POINT('',(-29.52678625054,40.65,5.9));
+#1115=CARTESIAN_POINT('Origin',(-32.5,40.25,4.6));
+#1116=CARTESIAN_POINT('Origin',(0.,0.,9.1));
+#1117=CARTESIAN_POINT('Origin',(0.,0.,7.1));
+#1118=CARTESIAN_POINT('',(-32.9,40.65,7.1));
+#1119=CARTESIAN_POINT('',(-32.9,41.55,7.1));
+#1120=CARTESIAN_POINT('',(-32.9,40.65,7.1));
+#1121=CARTESIAN_POINT('',(-32.1,41.55,7.1));
+#1122=CARTESIAN_POINT('',(-31.2,39.85,7.1));
+#1123=CARTESIAN_POINT('',(-31.2,39.85,7.1));
+#1124=CARTESIAN_POINT('',(-32.1,39.85,7.1));
+#1125=CARTESIAN_POINT('',(-32.1,39.85,7.1));
+#1126=CARTESIAN_POINT('',(-32.1,38.95,7.1));
+#1127=CARTESIAN_POINT('',(-32.1,39.85,7.1));
+#1128=CARTESIAN_POINT('',(-32.9,38.95,7.1));
+#1129=CARTESIAN_POINT('',(-32.9,38.95,7.1));
+#1130=CARTESIAN_POINT('',(-32.9,39.85,7.1));
+#1131=CARTESIAN_POINT('',(-32.9,39.85,7.1));
+#1132=CARTESIAN_POINT('',(-33.8,39.85,7.1));
+#1133=CARTESIAN_POINT('',(-32.9,39.85,7.1));
+#1134=CARTESIAN_POINT('',(-33.8,40.65,7.1));
+#1135=CARTESIAN_POINT('',(-33.8,40.65,7.1));
+#1136=CARTESIAN_POINT('',(-32.9,40.65,7.1));
+#1137=CARTESIAN_POINT('Origin',(-32.9,40.65,4.6));
+#1138=CARTESIAN_POINT('',(-32.9,41.55,5.2));
+#1139=CARTESIAN_POINT('',(-32.9,41.55,5.2));
+#1140=CARTESIAN_POINT('',(-32.9,41.55,5.2));
+#1141=CARTESIAN_POINT('',(-32.9,40.65,9.1));
+#1142=CARTESIAN_POINT('',(-32.9,40.65,9.1));
+#1143=CARTESIAN_POINT('',(-32.9,42.20959179423,9.1));
+#1144=CARTESIAN_POINT('',(-32.9,42.20959179423,9.1));
+#1145=CARTESIAN_POINT('',(-32.9,42.20959179423,5.9));
+#1146=CARTESIAN_POINT('',(-32.9,42.20959179423,9.1));
+#1147=CARTESIAN_POINT('',(-32.9,43.22321374946,5.9));
+#1148=CARTESIAN_POINT('',(-32.9,42.20959179423,5.9));
+#1149=CARTESIAN_POINT('',(-32.9,43.22321374946,5.9));
+#1150=CARTESIAN_POINT('Origin',(-32.5,40.25,4.6));
+#1151=CARTESIAN_POINT('',(-35.47321374946,40.65,5.9));
+#1152=CARTESIAN_POINT('Origin',(-32.5,40.25,5.9));
+#1153=CARTESIAN_POINT('',(-35.47321374946,40.65,4.6));
+#1154=CARTESIAN_POINT('Origin',(-34.45959179423,40.65,4.6));
+#1155=CARTESIAN_POINT('',(-34.45959179423,40.65,5.9));
+#1156=CARTESIAN_POINT('',(-34.45959179423,40.65,9.1));
+#1157=CARTESIAN_POINT('',(-34.45959179423,40.65,5.9));
+#1158=CARTESIAN_POINT('',(-32.9,40.65,9.1));
+#1159=CARTESIAN_POINT('',(-33.8,40.65,5.2));
+#1160=CARTESIAN_POINT('',(-33.8,40.65,5.2));
+#1161=CARTESIAN_POINT('',(-34.4,40.65,4.6));
+#1162=CARTESIAN_POINT('',(-35.47321374946,40.65,5.9));
+#1163=CARTESIAN_POINT('Origin',(-32.5,40.25,4.6));
+#1164=CARTESIAN_POINT('Origin',(-32.5,40.25,5.9));
+#1165=CARTESIAN_POINT('Origin',(-32.5,40.25,9.1));
+#1166=CARTESIAN_POINT('Origin',(0.,0.,5.9));
+#1167=CARTESIAN_POINT('Origin',(-65.,0.,9.1));
+#1168=CARTESIAN_POINT('Origin',(-34.1,40.25,4.9));
+#1169=CARTESIAN_POINT('',(-33.8,39.85,5.2));
+#1170=CARTESIAN_POINT('',(-33.8,39.85,5.2));
+#1171=CARTESIAN_POINT('',(-33.8,39.85,5.2));
+#1172=CARTESIAN_POINT('Origin',(-32.9,39.85,4.6));
+#1173=CARTESIAN_POINT('',(-33.8,39.85,5.2));
+#1174=CARTESIAN_POINT('',(-32.9,39.85,9.1));
+#1175=CARTESIAN_POINT('',(-32.9,39.85,9.1));
+#1176=CARTESIAN_POINT('',(-34.45959179423,39.85,9.1));
+#1177=CARTESIAN_POINT('',(-34.45959179423,39.85,9.1));
+#1178=CARTESIAN_POINT('',(-34.45959179423,39.85,5.9));
+#1179=CARTESIAN_POINT('',(-34.45959179423,39.85,9.1));
+#1180=CARTESIAN_POINT('',(-35.47321374946,39.85,5.9));
+#1181=CARTESIAN_POINT('',(-34.45959179423,39.85,5.9));
+#1182=CARTESIAN_POINT('',(-35.47321374946,39.85,5.9));
+#1183=CARTESIAN_POINT('Origin',(-32.5,40.25,4.6));
+#1184=CARTESIAN_POINT('',(-32.9,37.27678625054,5.9));
+#1185=CARTESIAN_POINT('Origin',(-32.5,40.25,5.9));
+#1186=CARTESIAN_POINT('',(-32.9,37.27678625054,4.6));
+#1187=CARTESIAN_POINT('Origin',(-32.9,38.29040820577,4.6));
+#1188=CARTESIAN_POINT('',(-32.9,38.29040820577,5.9));
+#1189=CARTESIAN_POINT('',(-32.9,38.29040820577,9.1));
+#1190=CARTESIAN_POINT('',(-32.9,38.29040820577,5.9));
+#1191=CARTESIAN_POINT('',(-32.9,39.85,9.1));
+#1192=CARTESIAN_POINT('',(-32.9,38.95,5.2));
+#1193=CARTESIAN_POINT('',(-32.9,38.95,5.2));
+#1194=CARTESIAN_POINT('',(-32.9,38.35,4.6));
+#1195=CARTESIAN_POINT('',(-32.9,37.27678625054,5.9));
+#1196=CARTESIAN_POINT('Origin',(-32.5,40.25,4.6));
+#1197=CARTESIAN_POINT('Origin',(-32.5,40.25,5.9));
+#1198=CARTESIAN_POINT('Origin',(-32.5,40.25,9.1));
+#1199=CARTESIAN_POINT('Origin',(0.,0.,5.9));
+#1200=CARTESIAN_POINT('Origin',(-65.,0.,9.1));
+#1201=CARTESIAN_POINT('Origin',(-32.5,38.65,4.9));
+#1202=CARTESIAN_POINT('',(-32.1,38.95,5.2));
+#1203=CARTESIAN_POINT('',(-32.1,38.95,5.2));
+#1204=CARTESIAN_POINT('',(-32.1,38.95,5.2));
+#1205=CARTESIAN_POINT('Origin',(-32.1,38.29040820577,4.6));
+#1206=CARTESIAN_POINT('',(-32.1,38.95,5.2));
+#1207=CARTESIAN_POINT('',(-32.1,39.85,9.1));
+#1208=CARTESIAN_POINT('',(-32.1,39.85,9.1));
+#1209=CARTESIAN_POINT('',(-32.1,38.29040820577,9.1));
+#1210=CARTESIAN_POINT('',(-32.1,39.85,9.1));
+#1211=CARTESIAN_POINT('',(-32.1,38.29040820577,5.9));
+#1212=CARTESIAN_POINT('',(-32.1,38.29040820577,9.1));
+#1213=CARTESIAN_POINT('',(-32.1,37.27678625054,5.9));
+#1214=CARTESIAN_POINT('',(-32.1,38.29040820577,5.9));
+#1215=CARTESIAN_POINT('',(-32.1,37.27678625054,5.9));
+#1216=CARTESIAN_POINT('Origin',(-32.5,40.25,4.6));
+#1217=CARTESIAN_POINT('',(-29.52678625054,39.85,5.9));
+#1218=CARTESIAN_POINT('Origin',(-32.5,40.25,5.9));
+#1219=CARTESIAN_POINT('',(-29.52678625054,39.85,4.6));
+#1220=CARTESIAN_POINT('Origin',(-32.1,39.85,4.6));
+#1221=CARTESIAN_POINT('',(-30.54040820577,39.85,5.9));
+#1222=CARTESIAN_POINT('',(-30.54040820577,39.85,9.1));
+#1223=CARTESIAN_POINT('',(-30.54040820577,39.85,5.9));
+#1224=CARTESIAN_POINT('',(-30.54040820577,39.85,9.1));
+#1225=CARTESIAN_POINT('',(-31.2,39.85,5.2));
+#1226=CARTESIAN_POINT('',(-31.2,39.85,5.2));
+#1227=CARTESIAN_POINT('',(-30.6,39.85,4.6));
+#1228=CARTESIAN_POINT('',(-29.52678625054,39.85,5.9));
+#1229=CARTESIAN_POINT('Origin',(-32.5,40.25,4.6));
+#1230=CARTESIAN_POINT('Origin',(-32.5,40.25,5.9));
+#1231=CARTESIAN_POINT('Origin',(-32.5,40.25,9.1));
+#1232=CARTESIAN_POINT('Origin',(0.,0.,5.9));
+#1233=CARTESIAN_POINT('Origin',(0.,0.,9.1));
+#1234=CARTESIAN_POINT('Origin',(-30.9,40.25,4.9));
+#1235=CARTESIAN_POINT('',(-31.2,40.65,5.2));
+#1236=CARTESIAN_POINT('Origin',(-31.2,41.55,4.6));
+#1237=CARTESIAN_POINT('Origin',(-31.2,38.95,4.6));
+#1238=CARTESIAN_POINT('Origin',(-33.8,38.95,4.6));
+#1239=CARTESIAN_POINT('Origin',(-33.8,41.55,4.6));
+#1240=CARTESIAN_POINT('',(-32.9,41.55,5.2));
+#1241=CARTESIAN_POINT('Origin',(-32.5,41.85,4.9));
+#1242=CARTESIAN_POINT('Origin',(-32.5,40.25,9.9));
+#1243=CARTESIAN_POINT('',(-35.3,40.25,10.1));
+#1244=CARTESIAN_POINT('Origin',(-32.5,40.25,10.1));
+#1245=CARTESIAN_POINT('Origin',(-35.3,40.25,9.9));
+#1246=CARTESIAN_POINT('Origin',(-32.5,40.25,10.1));
+#1247=CARTESIAN_POINT('',(58.1672236319,12.16722114154,-9.067222041201));
+#1248=UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(0.01),#1254,
'DISTANCE_ACCURACY_VALUE',
'Maximum model space distance between geometric entities at asserted c
onnectivities');
-#930=UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(0.01),#933,
+#1249=UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(0.01),#1254,
'DISTANCE_ACCURACY_VALUE',
'Maximum model space distance between geometric entities at asserted c
onnectivities');
-#931=(
+#1250=UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(0.01),#1254,
+'DISTANCE_ACCURACY_VALUE',
+'Maximum model space distance between geometric entities at asserted c
+onnectivities');
+#1251=(
GEOMETRIC_REPRESENTATION_CONTEXT(3)
-GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#929))
-GLOBAL_UNIT_ASSIGNED_CONTEXT((#933,#934,#935))
+GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#1248))
+GLOBAL_UNIT_ASSIGNED_CONTEXT((#1254,#1256,#1257))
REPRESENTATION_CONTEXT('','3D')
);
-#932=(
+#1252=(
GEOMETRIC_REPRESENTATION_CONTEXT(3)
-GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#930))
-GLOBAL_UNIT_ASSIGNED_CONTEXT((#933,#934,#935))
+GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#1249))
+GLOBAL_UNIT_ASSIGNED_CONTEXT((#1254,#1256,#1257))
REPRESENTATION_CONTEXT('','3D')
);
-#933=(
+#1253=(
+GEOMETRIC_REPRESENTATION_CONTEXT(3)
+GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#1250))
+GLOBAL_UNIT_ASSIGNED_CONTEXT((#1254,#1256,#1257))
+REPRESENTATION_CONTEXT('','3D')
+);
+#1254=(
LENGTH_UNIT()
NAMED_UNIT(*)
SI_UNIT(.MILLI.,.METRE.)
);
-#934=(
+#1255=(
+LENGTH_UNIT()
+NAMED_UNIT(*)
+SI_UNIT($,.METRE.)
+);
+#1256=(
NAMED_UNIT(*)
PLANE_ANGLE_UNIT()
SI_UNIT($,.RADIAN.)
);
-#935=(
+#1257=(
NAMED_UNIT(*)
SI_UNIT($,.STERADIAN.)
SOLID_ANGLE_UNIT()
);
-#936=SHAPE_DEFINITION_REPRESENTATION(#937,#938);
-#937=PRODUCT_DEFINITION_SHAPE('',$,#940);
-#938=SHAPE_REPRESENTATION('',(#528),#931);
-#939=PRODUCT_DEFINITION_CONTEXT('part definition',#944,'design');
-#940=PRODUCT_DEFINITION('sc64_shell reworked','sc64_shell reworked v13',
-#941,#939);
-#941=PRODUCT_DEFINITION_FORMATION('',$,#946);
-#942=PRODUCT_RELATED_PRODUCT_CATEGORY('sc64_shell reworked v13',
-'sc64_shell reworked v13',(#946));
-#943=APPLICATION_PROTOCOL_DEFINITION('international standard',
-'automotive_design',2009,#944);
-#944=APPLICATION_CONTEXT(
+#1258=SHAPE_DEFINITION_REPRESENTATION(#1260,#1263);
+#1259=SHAPE_DEFINITION_REPRESENTATION(#1261,#1264);
+#1260=PRODUCT_DEFINITION_SHAPE('',$,#1266);
+#1261=PRODUCT_DEFINITION_SHAPE('',$,#1267);
+#1262=PRODUCT_DEFINITION_SHAPE($,$,#14);
+#1263=SHAPE_REPRESENTATION('',(#759,#822),#1251);
+#1264=SHAPE_REPRESENTATION('',(#760),#1252);
+#1265=PRODUCT_DEFINITION_CONTEXT('part definition',#1273,'design');
+#1266=PRODUCT_DEFINITION('button','button v1',#1268,#1265);
+#1267=PRODUCT_DEFINITION('SC64_SHELL_BUTTON-20240702',
+'SC64_SHELL_BUTTON-20240702',#1269,#1265);
+#1268=PRODUCT_DEFINITION_FORMATION('',$,#1275);
+#1269=PRODUCT_DEFINITION_FORMATION('',$,#1276);
+#1270=PRODUCT_RELATED_PRODUCT_CATEGORY('button v1','button v1',(#1275));
+#1271=PRODUCT_RELATED_PRODUCT_CATEGORY('SC64_SHELL_BUTTON-20240702',
+'SC64_SHELL_BUTTON-20240702',(#1276));
+#1272=APPLICATION_PROTOCOL_DEFINITION('international standard',
+'automotive_design',2009,#1273);
+#1273=APPLICATION_CONTEXT(
'Core Data for Automotive Mechanical Design Process');
-#945=PRODUCT_CONTEXT('part definition',#944,'mechanical');
-#946=PRODUCT('sc64_shell reworked','sc64_shell reworked v13',$,(#945));
-#947=PRESENTATION_STYLE_ASSIGNMENT((#951));
-#948=PRESENTATION_STYLE_ASSIGNMENT((#952));
-#949=PRESENTATION_STYLE_ASSIGNMENT((#953));
-#950=PRESENTATION_STYLE_ASSIGNMENT((#954));
-#951=SURFACE_STYLE_USAGE(.BOTH.,#955);
-#952=SURFACE_STYLE_USAGE(.BOTH.,#956);
-#953=SURFACE_STYLE_USAGE(.BOTH.,#957);
-#954=SURFACE_STYLE_USAGE(.BOTH.,#958);
-#955=SURFACE_SIDE_STYLE('',(#959));
-#956=SURFACE_SIDE_STYLE('',(#960));
-#957=SURFACE_SIDE_STYLE('',(#961));
-#958=SURFACE_SIDE_STYLE('',(#962));
-#959=SURFACE_STYLE_FILL_AREA(#963);
-#960=SURFACE_STYLE_FILL_AREA(#964);
-#961=SURFACE_STYLE_FILL_AREA(#965);
-#962=SURFACE_STYLE_FILL_AREA(#966);
-#963=FILL_AREA_STYLE('Steel - Satin',(#967));
-#964=FILL_AREA_STYLE('Plastic - Translucent Matte (Blue)',(#968));
-#965=FILL_AREA_STYLE('Powder Coat - Rough (White)',(#969));
-#966=FILL_AREA_STYLE('Plastic - Glossy (Black)',(#970));
-#967=FILL_AREA_STYLE_COLOUR('Steel - Satin',#971);
-#968=FILL_AREA_STYLE_COLOUR('Plastic - Translucent Matte (Blue)',#972);
-#969=FILL_AREA_STYLE_COLOUR('Powder Coat - Rough (White)',#973);
-#970=FILL_AREA_STYLE_COLOUR('Plastic - Glossy (Black)',#974);
-#971=COLOUR_RGB('Steel - Satin',0.627450980392157,0.627450980392157,0.627450980392157);
-#972=COLOUR_RGB('Plastic - Translucent Matte (Blue)',0.188235294117647,
-0.231372549019608,0.588235294117647);
-#973=COLOUR_RGB('Powder Coat - Rough (White)',0.964705882352941,0.964705882352941,
-0.952941176470588);
-#974=COLOUR_RGB('Plastic - Glossy (Black)',0.0980392156862745,0.0980392156862745,
-0.0980392156862745);
+#1274=PRODUCT_CONTEXT('part definition',#1273,'mechanical');
+#1275=PRODUCT('button','button v1',$,(#1274));
+#1276=PRODUCT('SC64_SHELL_BUTTON-20240702','SC64_SHELL_BUTTON-20240702',
+$,(#1274));
+#1277=PRESENTATION_STYLE_ASSIGNMENT((#1279));
+#1278=PRESENTATION_STYLE_ASSIGNMENT((#1280));
+#1279=SURFACE_STYLE_USAGE(.BOTH.,#1281);
+#1280=SURFACE_STYLE_USAGE(.BOTH.,#1282);
+#1281=SURFACE_SIDE_STYLE('',(#1283));
+#1282=SURFACE_SIDE_STYLE('',(#1284));
+#1283=SURFACE_STYLE_FILL_AREA(#1285);
+#1284=SURFACE_STYLE_FILL_AREA(#1286);
+#1285=FILL_AREA_STYLE('Steel - Satin',(#1287));
+#1286=FILL_AREA_STYLE('Opaque(211,255,71)',(#1288));
+#1287=FILL_AREA_STYLE_COLOUR('Steel - Satin',#1289);
+#1288=FILL_AREA_STYLE_COLOUR('Opaque(211,255,71)',#1290);
+#1289=COLOUR_RGB('Steel - Satin',0.627450980392157,0.627450980392157,0.627450980392157);
+#1290=COLOUR_RGB('Opaque(211,255,71)',0.827450980392157,1.,0.27843137254902);
ENDSEC;
END-ISO-10303-21;
diff --git a/sw/controller/src/fpga.h b/sw/controller/src/fpga.h
index 7c3f0d5..652cf54 100644
--- a/sw/controller/src/fpga.h
+++ b/sw/controller/src/fpga.h
@@ -79,8 +79,8 @@ typedef enum {
#define USB_SCR_FIFO_FLUSH (1 << 0)
#define USB_SCR_RXNE (1 << 1)
#define USB_SCR_TXE (1 << 2)
-#define USB_SCR_RESET_PENDING (1 << 3)
-#define USB_SCR_RESET_ACK (1 << 4)
+#define USB_SCR_RESET_ON_ACK (1 << 3)
+#define USB_SCR_RESET_OFF_ACK (1 << 4)
#define USB_SCR_WRITE_FLUSH (1 << 5)
#define USB_SCR_RX_COUNT_BIT (6)
#define USB_SCR_RX_COUNT_MASK (0x7FF << USB_SCR_RX_COUNT_BIT)
@@ -88,6 +88,7 @@ typedef enum {
#define USB_SCR_TX_COUNT_MASK (0x7FF << USB_SCR_TX_COUNT_BIT)
#define USB_SCR_RESET_STATE (1 << 28)
#define USB_SCR_PWRSAV (1 << 29)
+#define USB_SCR_FIFO_FLUSH_BUSY (1 << 30)
#define DMA_SCR_START (1 << 0)
#define DMA_SCR_STOP (1 << 1)
diff --git a/sw/controller/src/usb.c b/sw/controller/src/usb.c
index 760f68d..212c0d2 100644
--- a/sw/controller/src/usb.c
+++ b/sw/controller/src/usb.c
@@ -43,6 +43,8 @@ enum tx_state {
struct process {
+ bool last_reset_state;
+
enum rx_state rx_state;
uint8_t rx_counter;
uint8_t rx_cmd;
@@ -80,10 +82,6 @@ static const uint32_t ERR_TOKEN = (0x45525200UL);
static const uint32_t PKT_TOKEN = (0x504B5400UL);
-static bool usb_dma_ready (void) {
- return !((fpga_reg_get(REG_USB_DMA_SCR) & DMA_SCR_BUSY));
-}
-
static bool usb_rx_byte (uint8_t *data) {
if (fpga_usb_status_get() & USB_STATUS_RXNE) {
*data = fpga_usb_pop();
@@ -149,7 +147,63 @@ static bool usb_rx_cmd (uint8_t *cmd) {
return false;
}
+static void usb_reset (void) {
+ fpga_reg_set(REG_USB_DMA_SCR, DMA_SCR_STOP);
+ while (fpga_reg_get(REG_USB_DMA_SCR) & DMA_SCR_BUSY);
+ fpga_reg_set(REG_USB_SCR, USB_SCR_FIFO_FLUSH);
+ while (fpga_reg_get(REG_USB_SCR) & USB_SCR_FIFO_FLUSH_BUSY);
+
+ p.rx_state = RX_STATE_IDLE;
+ p.tx_state = TX_STATE_IDLE;
+
+ p.response_pending = false;
+ p.packet_pending = false;
+
+ p.read_ready = true;
+ p.read_length = 0;
+ p.read_address = 0;
+
+ usb_rx_word_counter = 0;
+ usb_rx_word_buffer = 0;
+ usb_tx_word_counter = 0;
+ usb_rx_cmd_counter = 0;
+}
+
+static void usb_flush_packet (void) {
+ if (p.packet_pending && p.packet_info.done_callback) {
+ p.packet_pending = false;
+ p.packet_info.done_callback();
+ }
+ if (p.tx_state != TX_STATE_IDLE && p.tx_info.done_callback) {
+ p.tx_info.done_callback();
+ p.tx_info.done_callback = NULL;
+ }
+}
+
+static bool usb_is_active (void) {
+ uint32_t scr = fpga_reg_get(REG_USB_SCR);
+ bool reset_state = (scr & USB_SCR_RESET_STATE);
+ if (p.last_reset_state != reset_state) {
+ p.last_reset_state = reset_state;
+ if (reset_state) {
+ usb_flush_packet();
+ usb_reset();
+ fpga_reg_set(REG_USB_SCR, USB_SCR_WRITE_FLUSH);
+ }
+ fpga_reg_set(REG_USB_SCR, reset_state ? USB_SCR_RESET_ON_ACK : USB_SCR_RESET_OFF_ACK);
+ return false;
+ }
+ return !(reset_state || (scr & USB_SCR_PWRSAV));
+}
+
+static bool usb_dma_ready (void) {
+ return !((fpga_reg_get(REG_USB_DMA_SCR) & DMA_SCR_BUSY));
+}
+
static bool usb_validate_address_length (uint32_t address, uint32_t length, bool exclude_bootloader) {
+ if (length == 0) {
+ return true;
+ }
if ((address >= MEMORY_LENGTH) || (length > MEMORY_LENGTH)) {
return true;
}
@@ -410,27 +464,34 @@ static void usb_rx_process (void) {
}
if (p.rx_state == RX_STATE_FLUSH) {
- if (usb_dma_ready()) {
- if (p.rx_args[1] != 0) {
+ if (p.rx_args[1] > 0) {
+ if (usb_dma_ready()) {
uint32_t length = (p.rx_args[1] > RX_FLUSH_LENGTH) ? RX_FLUSH_LENGTH : p.rx_args[1];
- fpga_reg_set(REG_USB_DMA_ADDRESS, RX_FLUSH_ADDRESS);
- fpga_reg_set(REG_USB_DMA_LENGTH, length);
- fpga_reg_set(REG_USB_DMA_SCR, DMA_SCR_DIRECTION | DMA_SCR_START);
- p.rx_args[1] -= length;
- } else {
- if (p.flush_response) {
- p.rx_state = RX_STATE_IDLE;
- p.response_pending = true;
- p.response_error = true;
- } else if (p.flush_packet) {
- usb_tx_info_t packet_info;
- usb_create_packet(&packet_info, PACKET_CMD_DATA_FLUSHED);
- if (usb_enqueue_packet(&packet_info)) {
- p.rx_state = RX_STATE_IDLE;
- }
+ if (!p.rx_dma_running) {
+ fpga_reg_set(REG_USB_DMA_ADDRESS, RX_FLUSH_ADDRESS);
+ fpga_reg_set(REG_USB_DMA_LENGTH, length);
+ fpga_reg_set(REG_USB_DMA_SCR, DMA_SCR_DIRECTION | DMA_SCR_START);
+ p.rx_dma_running = true;
} else {
+ p.rx_args[1] -= length;
+ p.rx_dma_running = false;
+ }
+ }
+ }
+
+ if (p.rx_args[1] == 0) {
+ if (p.flush_response) {
+ p.rx_state = RX_STATE_IDLE;
+ p.response_pending = true;
+ p.response_error = true;
+ } else if (p.flush_packet) {
+ usb_tx_info_t packet_info;
+ usb_create_packet(&packet_info, PACKET_CMD_DATA_FLUSHED);
+ if (usb_enqueue_packet(&packet_info)) {
p.rx_state = RX_STATE_IDLE;
}
+ } else {
+ p.rx_state = RX_STATE_IDLE;
}
}
}
@@ -556,42 +617,16 @@ void usb_get_read_info (uint32_t *args) {
void usb_init (void) {
- fpga_reg_set(REG_USB_DMA_SCR, DMA_SCR_STOP);
- fpga_reg_set(REG_USB_SCR, USB_SCR_FIFO_FLUSH);
-
- p.rx_state = RX_STATE_IDLE;
- p.tx_state = TX_STATE_IDLE;
-
- p.response_pending = false;
- p.packet_pending = false;
-
- p.read_ready = true;
- p.read_length = 0;
- p.read_address = 0;
-
- usb_rx_word_counter = 0;
- usb_rx_word_buffer = 0;
- usb_tx_word_counter = 0;
- usb_rx_cmd_counter = 0;
+ p.last_reset_state = false;
+ usb_reset();
}
void usb_process (void) {
- uint32_t scr = fpga_reg_get(REG_USB_SCR);
- if (scr & (USB_SCR_PWRSAV | USB_SCR_RESET_STATE | USB_SCR_RESET_PENDING)) {
- if (p.packet_pending && p.packet_info.done_callback) {
- p.packet_pending = false;
- p.packet_info.done_callback();
- }
- if (scr & USB_SCR_RESET_PENDING) {
- if (p.tx_state != TX_STATE_IDLE && p.tx_info.done_callback) {
- p.tx_info.done_callback();
- }
- usb_init();
- fpga_reg_set(REG_USB_SCR, USB_SCR_RESET_ACK);
- }
- } else {
+ if (usb_is_active()) {
usb_rx_process();
usb_tx_process();
+ } else {
+ usb_flush_packet();
}
}
diff --git a/sw/deployer/Cargo.lock b/sw/deployer/Cargo.lock
index 29aa09d..6712a7e 100644
--- a/sw/deployer/Cargo.lock
+++ b/sw/deployer/Cargo.lock
@@ -27,13 +27,19 @@ dependencies = [
[[package]]
name = "aho-corasick"
-version = "1.1.2"
+version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0"
+checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
dependencies = [
"memchr",
]
+[[package]]
+name = "aligned-vec"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4aa90d7ce82d4be67b64039a3d588d38dbcc6736577de4a847025ce5b0c468d1"
+
[[package]]
name = "android-tzdata"
version = "0.1.1"
@@ -51,57 +57,110 @@ dependencies = [
[[package]]
name = "anstream"
-version = "0.6.13"
+version = "0.6.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb"
+checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
+ "is_terminal_polyfill",
"utf8parse",
]
[[package]]
name = "anstyle"
-version = "1.0.6"
+version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc"
+checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b"
[[package]]
name = "anstyle-parse"
-version = "0.2.3"
+version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c"
+checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
-version = "1.0.2"
+version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648"
+checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391"
dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "anstyle-wincon"
-version = "3.0.2"
+version = "3.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7"
+checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19"
dependencies = [
"anstyle",
"windows-sys 0.52.0",
]
[[package]]
-name = "autocfg"
-version = "1.1.0"
+name = "anyhow"
+version = "1.0.86"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
+checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da"
+
+[[package]]
+name = "arbitrary"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110"
+
+[[package]]
+name = "arg_enum_proc_macro"
+version = "0.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.68",
+]
+
+[[package]]
+name = "arrayvec"
+version = "0.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711"
+
+[[package]]
+name = "autocfg"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
+
+[[package]]
+name = "av1-grain"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6678909d8c5d46a42abcf571271e15fdbc0a225e3646cf23762cd415046c78bf"
+dependencies = [
+ "anyhow",
+ "arrayvec",
+ "log",
+ "nom",
+ "num-rational",
+ "v_frame",
+]
+
+[[package]]
+name = "avif-serialize"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "876c75a42f6364451a033496a14c44bffe41f5f4a8236f697391f11024e596d2"
+dependencies = [
+ "arrayvec",
+]
[[package]]
name = "bit_field"
@@ -117,21 +176,33 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
+version = "2.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
+
+[[package]]
+name = "bitstream-io"
version = "2.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf"
+checksum = "415f8399438eb5e4b2f73ed3152a3448b98149dda642a957ee704e1daa5cf1d8"
+
+[[package]]
+name = "built"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c6a6c0b39c38fd754ac338b00a88066436389c0f029da5d37d1e01091d9b7c17"
[[package]]
name = "bumpalo"
-version = "3.15.4"
+version = "3.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa"
+checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
[[package]]
name = "bytemuck"
-version = "1.15.0"
+version = "1.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5d6d68c57235a3a081186990eca2867354726650f42f7516ca50c28d6281fd15"
+checksum = "b236fc92302c97ed75b38da1f4917b5cdda4984745740f153a5d3059e48d725e"
[[package]]
name = "byteorder"
@@ -140,10 +211,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
-name = "cc"
-version = "1.0.90"
+name = "byteorder-lite"
+version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5"
+checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495"
+
+[[package]]
+name = "cc"
+version = "1.0.103"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2755ff20a1d93490d26ba33a6f092a38a508398a5320df5d4b3014fcccce9410"
+dependencies = [
+ "jobserver",
+ "libc",
+ "once_cell",
+]
+
+[[package]]
+name = "cfg-expr"
+version = "0.15.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02"
+dependencies = [
+ "smallvec",
+ "target-lexicon",
+]
[[package]]
name = "cfg-if"
@@ -159,23 +251,23 @@ checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e"
[[package]]
name = "chrono"
-version = "0.4.35"
+version = "0.4.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8eaf5903dcbc0a39312feb77df2ff4c76387d591b9fc7b04a238dcf8bb62639a"
+checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401"
dependencies = [
"android-tzdata",
"iana-time-zone",
"js-sys",
"num-traits",
"wasm-bindgen",
- "windows-targets 0.52.4",
+ "windows-targets 0.52.5",
]
[[package]]
name = "clap"
-version = "4.5.2"
+version = "4.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b230ab84b0ffdf890d5a10abdbc8b83ae1c4918275daea1ab8801f71536b2651"
+checksum = "84b3edb18336f4df585bc9aa31dd99c036dfa5dc5e9a2939a722a188f3a8970d"
dependencies = [
"clap_builder",
"clap_derive",
@@ -192,9 +284,9 @@ dependencies = [
[[package]]
name = "clap_builder"
-version = "4.5.2"
+version = "4.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4"
+checksum = "c1c09dd5ada6c6c78075d6fd0da3f90d8080651e2d6cc8eb2f1aaa4034ced708"
dependencies = [
"anstream",
"anstyle",
@@ -204,21 +296,21 @@ dependencies = [
[[package]]
name = "clap_derive"
-version = "4.5.0"
+version = "4.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "307bc0538d5f0f83b8248db3087aa92fe504e4691294d0c96c0eabc33f47ba47"
+checksum = "2bac35c6dafb060fd4d275d9a4ffae97917c13a6327903a8be2153cd964f7085"
dependencies = [
"heck",
"proc-macro2",
"quote",
- "syn 2.0.52",
+ "syn 2.0.68",
]
[[package]]
name = "clap_lex"
-version = "0.7.0"
+version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce"
+checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70"
[[package]]
name = "color_quant"
@@ -228,9 +320,9 @@ checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
[[package]]
name = "colorchoice"
-version = "1.0.0"
+version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
+checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422"
[[package]]
name = "colored"
@@ -250,9 +342,9 @@ checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
[[package]]
name = "crc32fast"
-version = "1.4.0"
+version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa"
+checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3"
dependencies = [
"cfg-if",
]
@@ -278,9 +370,9 @@ dependencies = [
[[package]]
name = "crossbeam-utils"
-version = "0.8.19"
+version = "0.8.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345"
+checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
[[package]]
name = "crunchy"
@@ -306,19 +398,25 @@ checksum = "0688c2a7f92e427f44895cd63841bff7b29f8d7a1648b9e7e07a4a365b2e1257"
[[package]]
name = "either"
-version = "1.10.0"
+version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a"
+checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
[[package]]
name = "encoding_rs"
-version = "0.8.33"
+version = "0.8.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1"
+checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59"
dependencies = [
"cfg-if",
]
+[[package]]
+name = "equivalent"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
+
[[package]]
name = "exr"
version = "1.72.0"
@@ -346,9 +444,9 @@ dependencies = [
[[package]]
name = "flate2"
-version = "1.0.28"
+version = "1.0.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e"
+checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae"
dependencies = [
"crc32fast",
"miniz_oxide",
@@ -365,9 +463,9 @@ dependencies = [
[[package]]
name = "getrandom"
-version = "0.2.12"
+version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5"
+checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
dependencies = [
"cfg-if",
"libc",
@@ -386,9 +484,9 @@ dependencies = [
[[package]]
name = "half"
-version = "2.4.0"
+version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b5eceaaeec696539ddaf7b333340f1af35a5aa87ae3e4f3ead0532f72affab2e"
+checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888"
dependencies = [
"cfg-if",
"crunchy",
@@ -404,10 +502,16 @@ dependencies = [
]
[[package]]
-name = "heck"
-version = "0.4.1"
+name = "hashbrown"
+version = "0.14.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
+checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
+
+[[package]]
+name = "heck"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "hex"
@@ -440,22 +544,43 @@ dependencies = [
[[package]]
name = "image"
-version = "0.24.9"
+version = "0.25.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d"
+checksum = "fd54d660e773627692c524beaad361aca785a4f9f5730ce91f42aabe5bce3d11"
dependencies = [
"bytemuck",
"byteorder",
"color_quant",
"exr",
"gif",
- "jpeg-decoder",
+ "image-webp",
"num-traits",
"png",
"qoi",
+ "ravif",
+ "rayon",
+ "rgb",
"tiff",
+ "zune-core",
+ "zune-jpeg",
]
+[[package]]
+name = "image-webp"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d730b085583c4d789dfd07fdcf185be59501666a90c97c40162b37e4fdad272d"
+dependencies = [
+ "byteorder-lite",
+ "thiserror",
+]
+
+[[package]]
+name = "imgref"
+version = "1.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "44feda355f4159a7c757171a77de25daf6411e217b4cabd03bd6650690468126"
+
[[package]]
name = "include-flate"
version = "0.2.0"
@@ -491,23 +616,65 @@ dependencies = [
]
[[package]]
-name = "io-kit-sys"
-version = "0.4.0"
+name = "indexmap"
+version = "2.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4769cb30e5dcf1710fc6730d3e94f78c47723a014a567de385e113c737394640"
+checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26"
+dependencies = [
+ "equivalent",
+ "hashbrown 0.14.5",
+]
+
+[[package]]
+name = "interpolate_name"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.68",
+]
+
+[[package]]
+name = "io-kit-sys"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "617ee6cf8e3f66f3b4ea67a4058564628cde41901316e19f559e14c7c72c5e7b"
dependencies = [
"core-foundation-sys",
"mach2",
]
+[[package]]
+name = "is_terminal_polyfill"
+version = "1.70.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800"
+
+[[package]]
+name = "itertools"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"
+dependencies = [
+ "either",
+]
+
+[[package]]
+name = "jobserver"
+version = "0.1.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e"
+dependencies = [
+ "libc",
+]
+
[[package]]
name = "jpeg-decoder"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0"
-dependencies = [
- "rayon",
-]
[[package]]
name = "js-sys"
@@ -520,9 +687,9 @@ dependencies = [
[[package]]
name = "lazy_static"
-version = "1.4.0"
+version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "lebe"
@@ -532,9 +699,9 @@ checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8"
[[package]]
name = "libc"
-version = "0.2.153"
+version = "0.2.155"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
+checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
[[package]]
name = "libflate"
@@ -556,6 +723,38 @@ dependencies = [
"rle-decode-fast",
]
+[[package]]
+name = "libftdi1-source-lgpl"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4412918d38c7b78f59c5b0cefec46e2099876dfd95f07f9bb2269d1d7b09fdb1"
+
+[[package]]
+name = "libftdi1-sys"
+version = "1.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "575286f9af093f56c7805f4f94874871b84216d1545f499d2cbad9e370000fe7"
+dependencies = [
+ "cc",
+ "cfg-if",
+ "libc",
+ "libftdi1-source-lgpl",
+ "libusb1-sys",
+ "pkg-config",
+ "vcpkg",
+]
+
+[[package]]
+name = "libfuzzer-sys"
+version = "0.4.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a96cfd5557eb82f2b83fed4955246c988d331975a002961b07c81584d107e7f7"
+dependencies = [
+ "arbitrary",
+ "cc",
+ "once_cell",
+]
+
[[package]]
name = "libudev"
version = "0.3.0"
@@ -577,10 +776,22 @@ dependencies = [
]
[[package]]
-name = "lock_api"
-version = "0.4.11"
+name = "libusb1-sys"
+version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45"
+checksum = "17f6bace2f39082e9787c851afce469e7b2fe0f1cc64bbc68ca96653b63d8f17"
+dependencies = [
+ "cc",
+ "libc",
+ "pkg-config",
+ "vcpkg",
+]
+
+[[package]]
+name = "lock_api"
+version = "0.4.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
dependencies = [
"autocfg",
"scopeguard",
@@ -588,9 +799,18 @@ dependencies = [
[[package]]
name = "log"
-version = "0.4.21"
+version = "0.4.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
+checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
+
+[[package]]
+name = "loop9"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0fae87c125b03c1d2c0150c90365d7d6bcc53fb73a9acaef207d2d065860f062"
+dependencies = [
+ "imgref",
+]
[[package]]
name = "mach2"
@@ -601,6 +821,16 @@ dependencies = [
"libc",
]
+[[package]]
+name = "maybe-rayon"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ea1f30cedd69f0a2954655f7188c6a834246d2bcf1e315e2ac40c4b24dc9519"
+dependencies = [
+ "cfg-if",
+ "rayon",
+]
+
[[package]]
name = "md5"
version = "0.7.0"
@@ -609,20 +839,32 @@ checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771"
[[package]]
name = "memchr"
-version = "2.7.1"
+version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
+checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
+
+[[package]]
+name = "minimal-lexical"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]]
name = "miniz_oxide"
-version = "0.7.2"
+version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7"
+checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08"
dependencies = [
"adler",
"simd-adler32",
]
+[[package]]
+name = "new_debug_unreachable"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086"
+
[[package]]
name = "nix"
version = "0.26.4"
@@ -640,17 +882,74 @@ version = "0.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4"
dependencies = [
- "bitflags 2.4.2",
+ "bitflags 2.6.0",
"cfg-if",
"cfg_aliases",
"libc",
]
[[package]]
-name = "num-traits"
-version = "0.2.18"
+name = "nom"
+version = "7.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a"
+checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
+dependencies = [
+ "memchr",
+ "minimal-lexical",
+]
+
+[[package]]
+name = "noop_proc_macro"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8"
+
+[[package]]
+name = "num-bigint"
+version = "0.4.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9"
+dependencies = [
+ "num-integer",
+ "num-traits",
+]
+
+[[package]]
+name = "num-derive"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.68",
+]
+
+[[package]]
+name = "num-integer"
+version = "0.1.46"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f"
+dependencies = [
+ "num-traits",
+]
+
+[[package]]
+name = "num-rational"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824"
+dependencies = [
+ "num-bigint",
+ "num-integer",
+ "num-traits",
+]
+
+[[package]]
+name = "num-traits"
+version = "0.2.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
]
@@ -668,7 +967,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ccd746e37177e1711c20dd619a1620f34f5c8b569c53590a72dedd5344d8924a"
dependencies = [
"dlv-list",
- "hashbrown",
+ "hashbrown 0.12.3",
]
[[package]]
@@ -677,6 +976,12 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "384e52fd8fbd4cbe3c317e8216260c21a0f9134de108cea8a4dd4e7e152c472d"
+[[package]]
+name = "paste"
+version = "1.0.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
+
[[package]]
name = "pkg-config"
version = "0.3.30"
@@ -710,13 +1015,32 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068"
[[package]]
name = "proc-macro2"
-version = "1.0.79"
+version = "1.0.86"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e"
+checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
dependencies = [
"unicode-ident",
]
+[[package]]
+name = "profiling"
+version = "1.0.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "43d84d1d7a6ac92673717f9f6d1518374ef257669c24ebc5ac25d5033828be58"
+dependencies = [
+ "profiling-procmacros",
+]
+
+[[package]]
+name = "profiling-procmacros"
+version = "1.0.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8021cf59c8ec9c432cfc2526ac6b8aa508ecaf29cd415f271b8406c1b851c3fd"
+dependencies = [
+ "quote",
+ "syn 2.0.68",
+]
+
[[package]]
name = "qoi"
version = "0.4.1"
@@ -727,10 +1051,16 @@ dependencies = [
]
[[package]]
-name = "quote"
-version = "1.0.35"
+name = "quick-error"
+version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
+checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3"
+
+[[package]]
+name = "quote"
+version = "1.0.36"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
dependencies = [
"proc-macro2",
]
@@ -766,10 +1096,60 @@ dependencies = [
]
[[package]]
-name = "rayon"
-version = "1.9.0"
+name = "rav1e"
+version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e4963ed1bc86e4f3ee217022bd855b297cef07fb9eac5dfa1f788b220b49b3bd"
+checksum = "cd87ce80a7665b1cce111f8a16c1f3929f6547ce91ade6addf4ec86a8dda5ce9"
+dependencies = [
+ "arbitrary",
+ "arg_enum_proc_macro",
+ "arrayvec",
+ "av1-grain",
+ "bitstream-io",
+ "built",
+ "cfg-if",
+ "interpolate_name",
+ "itertools",
+ "libc",
+ "libfuzzer-sys",
+ "log",
+ "maybe-rayon",
+ "new_debug_unreachable",
+ "noop_proc_macro",
+ "num-derive",
+ "num-traits",
+ "once_cell",
+ "paste",
+ "profiling",
+ "rand",
+ "rand_chacha",
+ "simd_helpers",
+ "system-deps",
+ "thiserror",
+ "v_frame",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "ravif"
+version = "0.11.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "67376f469e7e7840d0040bbf4b9b3334005bb167f814621326e4c7ab8cd6e944"
+dependencies = [
+ "avif-serialize",
+ "imgref",
+ "loop9",
+ "quick-error",
+ "rav1e",
+ "rayon",
+ "rgb",
+]
+
+[[package]]
+name = "rayon"
+version = "1.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa"
dependencies = [
"either",
"rayon-core",
@@ -787,9 +1167,9 @@ dependencies = [
[[package]]
name = "regex"
-version = "1.10.3"
+version = "1.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15"
+checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f"
dependencies = [
"aho-corasick",
"memchr",
@@ -799,9 +1179,9 @@ dependencies = [
[[package]]
name = "regex-automata"
-version = "0.4.6"
+version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea"
+checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df"
dependencies = [
"aho-corasick",
"memchr",
@@ -810,9 +1190,18 @@ dependencies = [
[[package]]
name = "regex-syntax"
-version = "0.8.2"
+version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
+checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
+
+[[package]]
+name = "rgb"
+version = "0.8.40"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a7439be6844e40133eda024efd85bf07f59d0dd2f59b10c00dd6cfb92cc5c741"
+dependencies = [
+ "bytemuck",
+]
[[package]]
name = "rle-decode-fast"
@@ -844,6 +1233,8 @@ dependencies = [
"hex",
"image",
"include-flate",
+ "libftdi1-sys",
+ "libusb1-sys",
"md5",
"panic-message",
"rand",
@@ -859,10 +1250,39 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
-name = "serial2"
-version = "0.2.20"
+name = "serde"
+version = "1.0.203"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "532d7a51dc8416e952987dbd39dd5e24fb9d1cbe86f1263521ec5032cb7ff0fb"
+checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.203"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.68",
+]
+
+[[package]]
+name = "serde_spanned"
+version = "0.6.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "serial2"
+version = "0.2.26"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f39915da34f43a64c66d53c228b8ba9a4e21fed4894af24304e47f96996acafd"
dependencies = [
"cfg-if",
"libc",
@@ -871,11 +1291,11 @@ dependencies = [
[[package]]
name = "serialport"
-version = "4.3.0"
+version = "4.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f5a15d0be940df84846264b09b51b10b931fb2f275becb80934e3568a016828"
+checksum = "de7c4f0cce25b9b3518eea99618112f9ee4549f974480c8f43d3c06f03c131a0"
dependencies = [
- "bitflags 2.4.2",
+ "bitflags 2.6.0",
"cfg-if",
"core-foundation-sys",
"io-kit-sys",
@@ -895,10 +1315,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
[[package]]
-name = "smallvec"
-version = "1.13.1"
+name = "simd_helpers"
+version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7"
+checksum = "95890f873bec569a0362c235787f3aca6e1e887302ba4840839bcc6459c42da6"
+dependencies = [
+ "quote",
+]
+
+[[package]]
+name = "smallvec"
+version = "1.13.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
[[package]]
name = "spin"
@@ -911,9 +1340,9 @@ dependencies = [
[[package]]
name = "strsim"
-version = "0.11.0"
+version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01"
+checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "syn"
@@ -928,9 +1357,9 @@ dependencies = [
[[package]]
name = "syn"
-version = "2.0.52"
+version = "2.0.68"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07"
+checksum = "901fa70d88b9d6c98022e23b4136f9f3e54e4662c3bc1bd1d84a42a9a0f0c1e9"
dependencies = [
"proc-macro2",
"quote",
@@ -938,23 +1367,42 @@ dependencies = [
]
[[package]]
-name = "thiserror"
-version = "1.0.58"
+name = "system-deps"
+version = "6.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297"
+checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349"
+dependencies = [
+ "cfg-expr",
+ "heck",
+ "pkg-config",
+ "toml",
+ "version-compare",
+]
+
+[[package]]
+name = "target-lexicon"
+version = "0.12.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e1fc403891a21bcfb7c37834ba66a547a8f402146eba7265b5a6d88059c9ff2f"
+
+[[package]]
+name = "thiserror"
+version = "1.0.61"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
-version = "1.0.58"
+version = "1.0.61"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7"
+checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.52",
+ "syn 2.0.68",
]
[[package]]
@@ -969,10 +1417,44 @@ dependencies = [
]
[[package]]
-name = "unescaper"
-version = "0.1.4"
+name = "toml"
+version = "0.8.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0adf6ad32eb5b3cadff915f7b770faaac8f7ff0476633aa29eb0d9584d889d34"
+checksum = "6f49eb2ab21d2f26bd6db7bf383edc527a7ebaee412d17af4d40fdccd442f335"
+dependencies = [
+ "serde",
+ "serde_spanned",
+ "toml_datetime",
+ "toml_edit",
+]
+
+[[package]]
+name = "toml_datetime"
+version = "0.6.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "toml_edit"
+version = "0.22.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f21c7aaf97f1bd9ca9d4f9e73b0a6c74bd5afef56f2bc931943a6e1c37e04e38"
+dependencies = [
+ "indexmap",
+ "serde",
+ "serde_spanned",
+ "toml_datetime",
+ "winnow",
+]
+
+[[package]]
+name = "unescaper"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c878a167baa8afd137494101a688ef8c67125089ff2249284bd2b5f9bfedb815"
dependencies = [
"thiserror",
]
@@ -985,9 +1467,32 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "utf8parse"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
+checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
+
+[[package]]
+name = "v_frame"
+version = "0.3.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d6f32aaa24bacd11e488aa9ba66369c7cd514885742c9fe08cfe85884db3e92b"
+dependencies = [
+ "aligned-vec",
+ "num-traits",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "vcpkg"
+version = "0.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
+
+[[package]]
+name = "version-compare"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b"
[[package]]
name = "version_check"
@@ -1022,7 +1527,7 @@ dependencies = [
"once_cell",
"proc-macro2",
"quote",
- "syn 2.0.52",
+ "syn 2.0.68",
"wasm-bindgen-shared",
]
@@ -1044,7 +1549,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.52",
+ "syn 2.0.68",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
@@ -1089,7 +1594,7 @@ version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
dependencies = [
- "windows-targets 0.52.4",
+ "windows-targets 0.52.5",
]
[[package]]
@@ -1107,7 +1612,7 @@ version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
- "windows-targets 0.52.4",
+ "windows-targets 0.52.5",
]
[[package]]
@@ -1127,17 +1632,18 @@ dependencies = [
[[package]]
name = "windows-targets"
-version = "0.52.4"
+version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b"
+checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb"
dependencies = [
- "windows_aarch64_gnullvm 0.52.4",
- "windows_aarch64_msvc 0.52.4",
- "windows_i686_gnu 0.52.4",
- "windows_i686_msvc 0.52.4",
- "windows_x86_64_gnu 0.52.4",
- "windows_x86_64_gnullvm 0.52.4",
- "windows_x86_64_msvc 0.52.4",
+ "windows_aarch64_gnullvm 0.52.5",
+ "windows_aarch64_msvc 0.52.5",
+ "windows_i686_gnu 0.52.5",
+ "windows_i686_gnullvm",
+ "windows_i686_msvc 0.52.5",
+ "windows_x86_64_gnu 0.52.5",
+ "windows_x86_64_gnullvm 0.52.5",
+ "windows_x86_64_msvc 0.52.5",
]
[[package]]
@@ -1148,9 +1654,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]]
name = "windows_aarch64_gnullvm"
-version = "0.52.4"
+version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9"
+checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263"
[[package]]
name = "windows_aarch64_msvc"
@@ -1160,9 +1666,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]]
name = "windows_aarch64_msvc"
-version = "0.52.4"
+version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675"
+checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6"
[[package]]
name = "windows_i686_gnu"
@@ -1172,9 +1678,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]]
name = "windows_i686_gnu"
-version = "0.52.4"
+version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3"
+checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670"
+
+[[package]]
+name = "windows_i686_gnullvm"
+version = "0.52.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9"
[[package]]
name = "windows_i686_msvc"
@@ -1184,9 +1696,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]]
name = "windows_i686_msvc"
-version = "0.52.4"
+version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02"
+checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf"
[[package]]
name = "windows_x86_64_gnu"
@@ -1196,9 +1708,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
[[package]]
name = "windows_x86_64_gnu"
-version = "0.52.4"
+version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03"
+checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9"
[[package]]
name = "windows_x86_64_gnullvm"
@@ -1208,9 +1720,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[package]]
name = "windows_x86_64_gnullvm"
-version = "0.52.4"
+version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177"
+checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596"
[[package]]
name = "windows_x86_64_msvc"
@@ -1220,9 +1732,24 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
[[package]]
name = "windows_x86_64_msvc"
-version = "0.52.4"
+version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8"
+checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0"
+
+[[package]]
+name = "winnow"
+version = "0.6.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "59b5e5f6c299a3c7890b876a2a587f3115162487e704907d9b6cd29473052ba1"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "zune-core"
+version = "0.4.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a"
[[package]]
name = "zune-inflate"
@@ -1232,3 +1759,12 @@ checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02"
dependencies = [
"simd-adler32",
]
+
+[[package]]
+name = "zune-jpeg"
+version = "0.4.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec866b44a2a1fd6133d363f073ca1b179f438f99e7e5bfb1e33f7181facfe448"
+dependencies = [
+ "zune-core",
+]
diff --git a/sw/deployer/Cargo.toml b/sw/deployer/Cargo.toml
index 7eac40d..b6f5ff0 100644
--- a/sw/deployer/Cargo.toml
+++ b/sw/deployer/Cargo.toml
@@ -7,22 +7,24 @@ description = "SummerCart64 loader and control software"
documentation = "https://github.com/Polprzewodnikowy/SummerCart64"
[dependencies]
-chrono = "0.4.23"
-clap = { version = "4.1.6", features = ["derive"] }
-clap-num = "1.0.2"
-colored = "2.0.0"
-crc32fast = "1.3.2"
-ctrlc = "3.2.5"
-encoding_rs = "0.8.32"
+chrono = "0.4.38"
+clap = { version = "4.5.8", features = ["derive"] }
+clap-num = "1.1.1"
+colored = "2.1.0"
+crc32fast = "1.4.2"
+ctrlc = "3.4.4"
+encoding_rs = "0.8.34"
hex = "0.4.3"
-image = "0.24.5"
+image = "0.25.1"
include-flate = { version = "0.2.0", features = ["stable"] }
+libftdi1-sys = { version = "1.1.3", features = ["libusb1-sys", "vendored"] }
+libusb1-sys = { version = "0.6.5", features = ["vendored"] }
md5 = "0.7.0"
panic-message = "0.3.0"
rand = "0.8.5"
rust-ini = "0.18.0"
-serial2 = "0.2.20"
-serialport = "4.3.0"
+serial2 = "0.2.26"
+serialport = "4.4.0"
[profile.release]
lto = true
diff --git a/sw/deployer/src/debug.rs b/sw/deployer/src/debug.rs
index d78244b..35f29af 100644
--- a/sw/deployer/src/debug.rs
+++ b/sw/deployer/src/debug.rs
@@ -291,17 +291,7 @@ impl Handler {
let filename = &if let Some(path) = path {
path.to_string_lossy().to_string()
} else {
- generate_filename(
- "save",
- match save_writeback.save {
- sc64::SaveType::Eeprom4k | sc64::SaveType::Eeprom16k => "eep",
- sc64::SaveType::Sram | sc64::SaveType::SramBanked | sc64::SaveType::Sram1m => {
- "srm"
- }
- sc64::SaveType::Flashram => "fla",
- _ => "sav",
- },
- )
+ generate_filename("save", "sav")
};
match File::create(filename) {
Ok(mut file) => {
diff --git a/sw/deployer/src/main.rs b/sw/deployer/src/main.rs
index a346caa..f538822 100644
--- a/sw/deployer/src/main.rs
+++ b/sw/deployer/src/main.rs
@@ -25,7 +25,7 @@ struct Cli {
#[command(subcommand)]
command: Commands,
- /// Connect to SC64 device on provided serial port
+ /// Connect to SC64 device on provided local port
#[arg(short, long)]
port: Option,
@@ -350,7 +350,13 @@ fn handle_list_command() -> Result<(), sc64::Error> {
println!("{}", "Found devices:".bold());
for (i, d) in devices.iter().enumerate() {
- println!(" {i}: [{}] at port [{}]", d.serial_number, d.port);
+ let index = i + 1;
+ println!(
+ " {index}: [{}] at port [{}] (using \"{}\" backend)",
+ d.serial.bold(),
+ d.port.bold(),
+ d.backend.to_string().bold()
+ );
}
Ok(())
@@ -733,35 +739,35 @@ fn handle_info_command(connection: Connection) -> Result<(), sc64::Error> {
let datetime = state.datetime.format("%Y-%m-%d %H:%M:%S");
println!("{}", "SummerCart64 state information:".bold());
- println!(" Firmware version: v{}.{}.{}", major, minor, revision);
- println!(" RTC datetime: {}", datetime);
- println!(" Boot mode: {}", state.boot_mode);
- println!(" Save type: {}", state.save_type);
- println!(" CIC seed: {}", state.cic_seed);
- println!(" TV type: {}", state.tv_type);
- println!(" Bootloader switch: {}", state.bootloader_switch);
- println!(" ROM write: {}", state.rom_write_enable);
- println!(" ROM shadow: {}", state.rom_shadow_enable);
- println!(" ROM extended: {}", state.rom_extended_enable);
- println!(" 64DD mode: {}", state.dd_mode);
- println!(" 64DD SD card mode: {}", state.dd_sd_enable);
- println!(" 64DD drive type: {}", state.dd_drive_type);
- println!(" 64DD disk state: {}", state.dd_disk_state);
- println!(" Button mode: {}", state.button_mode);
- println!(" Button state: {}", state.button_state);
- println!(" LED blink: {}", state.led_enable);
- println!(" IS-Viewer 64 offset: 0x{:08X}", state.isv_address);
+ println!(" Firmware version: v{}.{}.{}", major, minor, revision);
+ println!(" RTC datetime: {}", datetime);
+ println!(" Boot mode: {}", state.boot_mode);
+ println!(" Save type: {}", state.save_type);
+ println!(" CIC seed: {}", state.cic_seed);
+ println!(" TV type: {}", state.tv_type);
+ println!(" Bootloader switch: {}", state.bootloader_switch);
+ println!(" ROM write: {}", state.rom_write_enable);
+ println!(" ROM shadow: {}", state.rom_shadow_enable);
+ println!(" ROM extended: {}", state.rom_extended_enable);
+ println!(" 64DD mode: {}", state.dd_mode);
+ println!(" 64DD SD card mode: {}", state.dd_sd_enable);
+ println!(" 64DD drive type: {}", state.dd_drive_type);
+ println!(" 64DD disk state: {}", state.dd_disk_state);
+ println!(" Button mode: {}", state.button_mode);
+ println!(" Button state: {}", state.button_state);
+ println!(" LED blink: {}", state.led_enable);
+ println!(" IS-Viewer 64: {}", state.isviewer);
println!("{}", "SummerCart64 diagnostic information:".bold());
println!(
- " Last PI address: 0x{:08X}",
+ " Last PI address: 0x{:08X}",
state.fpga_debug_data.last_pi_address
);
println!(
- " PI FIFO flags: {}",
+ " PI FIFO flags: {}",
state.fpga_debug_data.pi_fifo_flags
);
- println!(" Current CIC step: {}", state.fpga_debug_data.cic_step);
- println!(" Diagnostic data: {}", state.diagnostic_data);
+ println!(" Current CIC step: {}", state.fpga_debug_data.cic_step);
+ println!(" Diagnostic data: {}", state.diagnostic_data);
Ok(())
}
diff --git a/sw/deployer/src/sc64/error.rs b/sw/deployer/src/sc64/error.rs
index 416bebb..0702fd5 100644
--- a/sw/deployer/src/sc64/error.rs
+++ b/sw/deployer/src/sc64/error.rs
@@ -26,9 +26,3 @@ impl From for Error {
Error::new(format!("IO error: {}", value).as_str())
}
}
-
-impl From for Error {
- fn from(value: serialport::Error) -> Self {
- Error::new(format!("SerialPort error: {}", value.description).as_str())
- }
-}
diff --git a/sw/deployer/src/sc64/ftdi.rs b/sw/deployer/src/sc64/ftdi.rs
new file mode 100644
index 0000000..38574de
--- /dev/null
+++ b/sw/deployer/src/sc64/ftdi.rs
@@ -0,0 +1,540 @@
+pub struct DeviceInfo {
+ pub description: String,
+ pub serial: String,
+ pub port: String,
+}
+
+#[allow(dead_code)]
+enum InterfaceIndex {
+ Any,
+ A,
+ B,
+ C,
+ D,
+}
+
+#[allow(dead_code)]
+enum ModuleDetachMode {
+ AutoDetach,
+ DontDetach,
+ AutoDetachReattach,
+}
+
+struct ModemStatus {
+ dsr: bool,
+}
+
+struct Wrapper {
+ context: *mut libftdi1_sys::ftdi_context,
+ unclog_buffer: std::collections::VecDeque,
+ write_buffer: Vec,
+ read_timeout: std::time::Duration,
+ write_timeout: std::time::Duration,
+ read_chunksize: usize,
+ write_chunksize: usize,
+}
+
+impl Wrapper {
+ const DEFAULT_POLL_TIMEOUT: std::time::Duration = std::time::Duration::from_millis(16);
+ const DEFAULT_RW_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(5);
+ const WRITE_CHUNK_TIMEOUT: std::time::Duration = std::time::Duration::from_millis(100);
+
+ fn new(
+ read_timeout: Option,
+ write_timeout: Option,
+ ) -> std::io::Result {
+ let context = unsafe { libftdi1_sys::ftdi_new() };
+ if context.is_null() {
+ return Err(std::io::ErrorKind::OutOfMemory.into());
+ }
+ let mut wrapper = Self {
+ context,
+ unclog_buffer: std::collections::VecDeque::new(),
+ write_buffer: vec![],
+ read_timeout: Self::DEFAULT_RW_TIMEOUT,
+ write_timeout: Self::DEFAULT_RW_TIMEOUT,
+ read_chunksize: 4096,
+ write_chunksize: 4096,
+ };
+ wrapper.set_timeouts(read_timeout, write_timeout)?;
+ wrapper.read_data_set_chunksize(wrapper.read_chunksize)?;
+ wrapper.write_data_set_chunksize(wrapper.write_chunksize)?;
+ Ok(wrapper)
+ }
+
+ fn list_devices(vendor: u16, product: u16) -> std::io::Result> {
+ let wrapper = Self::new(None, None)?;
+
+ let mut device_list: *mut libftdi1_sys::ftdi_device_list = std::ptr::null_mut();
+ let devices = unsafe {
+ libftdi1_sys::ftdi_usb_find_all(
+ wrapper.context,
+ &mut device_list,
+ vendor as i32,
+ product as i32,
+ )
+ };
+
+ let result = if devices > 0 {
+ let mut list: Vec = vec![];
+
+ let mut description = [0i8; 128];
+ let mut serial = [0i8; 128];
+
+ let mut device = device_list;
+ let mut index = 0;
+ while !device.is_null() {
+ let result = unsafe {
+ libftdi1_sys::ftdi_usb_get_strings(
+ wrapper.context,
+ (*device).dev,
+ std::ptr::null_mut(),
+ 0,
+ description.as_mut_ptr(),
+ description.len() as i32,
+ serial.as_mut_ptr(),
+ serial.len() as i32,
+ )
+ };
+
+ let description = unsafe { std::ffi::CStr::from_ptr(description.as_ptr()) }
+ .to_string_lossy()
+ .into_owned();
+ let serial = unsafe { std::ffi::CStr::from_ptr(serial.as_ptr()) }
+ .to_string_lossy()
+ .into_owned();
+ let port = if list.binary_search_by(|d| d.serial.cmp(&serial)).is_ok() {
+ format!("i:0x{vendor:04X}:0x{product:04X}:{index}")
+ } else {
+ format!("s:0x{vendor:04X}:0x{product:04X}:{serial}")
+ };
+
+ if result == 0 {
+ list.push(DeviceInfo {
+ description,
+ serial,
+ port,
+ });
+ }
+
+ device = unsafe { (*device).next };
+ index += 1;
+ }
+
+ list.sort_by(|a, b| a.serial.cmp(&b.serial));
+
+ Ok(list)
+ } else {
+ match devices {
+ 0 => Ok(vec![]),
+ -3 => Err(std::io::ErrorKind::OutOfMemory.into()),
+ -5 => Err(std::io::ErrorKind::BrokenPipe.into()),
+ -6 => Err(std::io::ErrorKind::BrokenPipe.into()),
+ result => Err(std::io::Error::other(format!(
+ "Unexpected response from ftdi_usb_find_all: {result}"
+ ))),
+ }
+ };
+
+ unsafe { libftdi1_sys::ftdi_list_free(&mut device_list) }
+
+ result
+ }
+
+ fn libusb_convert_result(&self, result: i32) -> std::io::Error {
+ if result == libusb1_sys::constants::LIBUSB_ERROR_OVERFLOW {
+ return std::io::Error::other("libusb overflow");
+ }
+ match result {
+ libusb1_sys::constants::LIBUSB_ERROR_IO => std::io::ErrorKind::UnexpectedEof,
+ libusb1_sys::constants::LIBUSB_ERROR_INVALID_PARAM => std::io::ErrorKind::InvalidInput,
+ libusb1_sys::constants::LIBUSB_ERROR_ACCESS => std::io::ErrorKind::PermissionDenied,
+ libusb1_sys::constants::LIBUSB_ERROR_NO_DEVICE => std::io::ErrorKind::NotConnected,
+ libusb1_sys::constants::LIBUSB_ERROR_NOT_FOUND => std::io::ErrorKind::NotFound,
+ libusb1_sys::constants::LIBUSB_ERROR_BUSY => std::io::ErrorKind::WouldBlock,
+ libusb1_sys::constants::LIBUSB_ERROR_TIMEOUT => std::io::ErrorKind::TimedOut,
+ libusb1_sys::constants::LIBUSB_ERROR_PIPE => std::io::ErrorKind::BrokenPipe,
+ libusb1_sys::constants::LIBUSB_ERROR_INTERRUPTED => std::io::ErrorKind::Interrupted,
+ libusb1_sys::constants::LIBUSB_ERROR_NO_MEM => std::io::ErrorKind::OutOfMemory,
+ libusb1_sys::constants::LIBUSB_ERROR_NOT_SUPPORTED => std::io::ErrorKind::Unsupported,
+ _ => std::io::ErrorKind::Other,
+ }
+ .into()
+ }
+
+ fn set_timeouts(
+ &mut self,
+ read_timeout: Option,
+ write_timeout: Option,
+ ) -> std::io::Result<()> {
+ let read_timeout = read_timeout.unwrap_or(Self::DEFAULT_RW_TIMEOUT);
+ let write_timeout = write_timeout.unwrap_or(Self::DEFAULT_RW_TIMEOUT);
+ unsafe {
+ (*self.context).usb_read_timeout = i32::try_from(read_timeout.as_millis())
+ .map_err(|_| std::io::ErrorKind::InvalidInput)?;
+ (*self.context).usb_write_timeout = i32::try_from(write_timeout.as_millis())
+ .map_err(|_| std::io::ErrorKind::InvalidInput)?;
+ }
+ self.read_timeout = read_timeout;
+ self.write_timeout = write_timeout;
+ Ok(())
+ }
+
+ fn set_module_detach_mode(&mut self, mode: ModuleDetachMode) {
+ let mode = match mode {
+ ModuleDetachMode::AutoDetach => {
+ libftdi1_sys::ftdi_module_detach_mode::AUTO_DETACH_SIO_MODULE
+ }
+ ModuleDetachMode::DontDetach => {
+ libftdi1_sys::ftdi_module_detach_mode::DONT_DETACH_SIO_MODULE
+ }
+ ModuleDetachMode::AutoDetachReattach => {
+ libftdi1_sys::ftdi_module_detach_mode::AUTO_DETACH_REATACH_SIO_MODULE
+ }
+ };
+ unsafe {
+ (*self.context).module_detach_mode = mode;
+ };
+ }
+
+ fn set_interface(&mut self, interface: InterfaceIndex) -> std::io::Result<()> {
+ let interface = match interface {
+ InterfaceIndex::Any => libftdi1_sys::ftdi_interface::INTERFACE_ANY,
+ InterfaceIndex::A => libftdi1_sys::ftdi_interface::INTERFACE_A,
+ InterfaceIndex::B => libftdi1_sys::ftdi_interface::INTERFACE_B,
+ InterfaceIndex::C => libftdi1_sys::ftdi_interface::INTERFACE_C,
+ InterfaceIndex::D => libftdi1_sys::ftdi_interface::INTERFACE_D,
+ };
+ match unsafe { libftdi1_sys::ftdi_set_interface(self.context, interface) } {
+ 0 => Ok(()),
+ -1 => Err(std::io::ErrorKind::InvalidInput.into()),
+ -2 => Err(std::io::ErrorKind::NotConnected.into()),
+ -3 => Err(std::io::ErrorKind::InvalidData.into()),
+ result => Err(std::io::Error::other(format!(
+ "Unexpected response from ftdi_set_interface: {result}"
+ ))),
+ }
+ }
+
+ fn usb_open_string(&mut self, description: &str) -> std::io::Result<()> {
+ let description = std::ffi::CString::new(description)
+ .unwrap_or_default()
+ .into_raw();
+ match unsafe { libftdi1_sys::ftdi_usb_open_string(self.context, description) } {
+ 0 => Ok(()),
+ -2 => Err(std::io::ErrorKind::ConnectionRefused.into()),
+ -3 => Err(std::io::ErrorKind::NotFound.into()),
+ -4 => Err(std::io::ErrorKind::PermissionDenied.into()),
+ -5 => Err(std::io::ErrorKind::PermissionDenied.into()),
+ -6 => Err(std::io::ErrorKind::ConnectionRefused.into()),
+ -7 => Err(std::io::ErrorKind::ConnectionRefused.into()),
+ -8 => Err(std::io::ErrorKind::ConnectionRefused.into()),
+ -9 => Err(std::io::ErrorKind::ConnectionRefused.into()),
+ -10 => Err(std::io::ErrorKind::BrokenPipe.into()),
+ -11 => Err(std::io::ErrorKind::InvalidInput.into()),
+ -12 => Err(std::io::ErrorKind::InvalidData.into()),
+ result => Err(std::io::Error::other(format!(
+ "Unexpected response from ftdi_usb_open_string: {result}"
+ ))),
+ }
+ }
+
+ fn usb_reset(&mut self) -> std::io::Result<()> {
+ match unsafe { libftdi1_sys::ftdi_usb_reset(self.context) } {
+ 0 => Ok(()),
+ -1 => Err(std::io::ErrorKind::BrokenPipe.into()),
+ -2 => Err(std::io::ErrorKind::NotConnected.into()),
+ result => Err(std::io::Error::other(format!(
+ "Unexpected response from ftdi_usb_reset: {result}"
+ ))),
+ }
+ }
+
+ fn set_latency_timer(&mut self, latency: Option) -> std::io::Result<()> {
+ let latency = u8::try_from(latency.unwrap_or(Self::DEFAULT_POLL_TIMEOUT).as_millis())
+ .map_err(|_| std::io::ErrorKind::InvalidInput)?;
+ match unsafe { libftdi1_sys::ftdi_set_latency_timer(self.context, latency) } {
+ 0 => Ok(()),
+ -1 => Err(std::io::ErrorKind::InvalidInput.into()),
+ -2 => Err(std::io::ErrorKind::BrokenPipe.into()),
+ -3 => Err(std::io::ErrorKind::NotConnected.into()),
+ result => Err(std::io::Error::other(format!(
+ "Unexpected response from ftdi_set_latency_timer: {result}"
+ ))),
+ }
+ }
+
+ fn read_data_set_chunksize(&mut self, chunksize: usize) -> std::io::Result<()> {
+ match unsafe {
+ libftdi1_sys::ftdi_read_data_set_chunksize(
+ self.context,
+ u32::try_from(chunksize).map_err(|_| std::io::ErrorKind::InvalidInput)?,
+ )
+ } {
+ 0 => {
+ self.read_chunksize = chunksize;
+ Ok(())
+ }
+ -1 => Err(std::io::ErrorKind::NotConnected.into()),
+ result => Err(std::io::Error::other(format!(
+ "Unexpected response from ftdi_read_data_set_chunksize: {result}"
+ ))),
+ }
+ }
+
+ fn write_data_set_chunksize(&mut self, chunksize: usize) -> std::io::Result<()> {
+ match unsafe {
+ libftdi1_sys::ftdi_write_data_set_chunksize(
+ self.context,
+ u32::try_from(chunksize).map_err(|_| std::io::ErrorKind::InvalidInput)?,
+ )
+ } {
+ 0 => {
+ self.write_chunksize = chunksize;
+ self.commit_write()
+ }
+ -1 => Err(std::io::ErrorKind::NotConnected.into()),
+ result => Err(std::io::Error::other(format!(
+ "Unexpected response from ftdi_write_data_set_chunksize: {result}"
+ ))),
+ }
+ }
+
+ pub fn set_dtr(&mut self, value: bool) -> std::io::Result<()> {
+ let state = if value { 1 } else { 0 };
+ match unsafe { libftdi1_sys::ftdi_setdtr(self.context, state) } {
+ 0 => Ok(()),
+ -1 => Err(std::io::ErrorKind::BrokenPipe.into()),
+ -2 => Err(std::io::ErrorKind::NotConnected.into()),
+ result => Err(std::io::Error::other(format!(
+ "Unexpected response from ftdi_setdtr: {result}"
+ ))),
+ }
+ }
+
+ fn poll_modem_status(&mut self) -> std::io::Result {
+ const DSR_BIT: u16 = 1 << 5;
+
+ let mut status = 0;
+
+ match unsafe { libftdi1_sys::ftdi_poll_modem_status(self.context, &mut status) } {
+ 0 => Ok(ModemStatus {
+ dsr: (status & DSR_BIT) != 0,
+ }),
+ -1 => Err(std::io::ErrorKind::BrokenPipe.into()),
+ -2 => Err(std::io::ErrorKind::NotConnected.into()),
+ result => Err(std::io::Error::other(format!(
+ "Unexpected response from ftdi_poll_modem_status: {result}"
+ ))),
+ }
+ }
+
+ fn tciflush(&mut self) -> std::io::Result<()> {
+ let timeout = std::time::Instant::now();
+ loop {
+ match self.read(&mut vec![0u8; self.read_chunksize]) {
+ Ok(_) => {}
+ Err(error) => match error.kind() {
+ std::io::ErrorKind::Interrupted
+ | std::io::ErrorKind::TimedOut
+ | std::io::ErrorKind::WouldBlock => {
+ return Ok(());
+ }
+ _ => return Err(error),
+ },
+ };
+ if timeout.elapsed() > self.read_timeout {
+ return Err(std::io::ErrorKind::TimedOut.into());
+ }
+ }
+ }
+
+ fn tcoflush(&mut self) -> std::io::Result<()> {
+ self.write_buffer.clear();
+ match unsafe { libftdi1_sys::ftdi_tcoflush(self.context) } {
+ 0 => Ok(()),
+ -1 => Err(std::io::ErrorKind::BrokenPipe.into()),
+ -2 => Err(std::io::ErrorKind::BrokenPipe.into()),
+ -3 => Err(std::io::ErrorKind::NotConnected.into()),
+ result => Err(std::io::Error::other(format!(
+ "Unexpected response from ftdi_tcoflush: {result}"
+ ))),
+ }
+ }
+
+ pub fn read_data(&mut self, buffer: &mut [u8]) -> std::io::Result {
+ let length = i32::try_from(buffer.len()).map_err(|_| std::io::ErrorKind::InvalidInput)?;
+ let result =
+ unsafe { libftdi1_sys::ftdi_read_data(self.context, buffer.as_mut_ptr(), length) };
+ match result {
+ 1.. => Ok(result as usize),
+ 0 => Err(std::io::ErrorKind::WouldBlock.into()),
+ -666 => Err(std::io::ErrorKind::NotConnected.into()),
+ result => Err(self.libusb_convert_result(result)),
+ }
+ }
+
+ fn write_data(&mut self, buffer: &[u8], written: &mut usize) -> std::io::Result<()> {
+ let mut transferred = 0;
+ let result = unsafe {
+ // NOTE: Nasty hack to overcome libftdi1 API limitation.
+ // Write can partially succeed, but the default ftdi_write_data
+ // function doesn't report number of transferred bytes in that case.
+ libusb1_sys::libusb_bulk_transfer(
+ (*self.context).usb_dev,
+ (*self.context).in_ep as u8,
+ Vec::from(buffer).as_mut_ptr(),
+ buffer.len() as i32,
+ &mut transferred,
+ Self::WRITE_CHUNK_TIMEOUT.as_millis() as u32,
+ )
+ };
+ *written = transferred as usize;
+ if result < 0 {
+ return Err(self.libusb_convert_result(result));
+ }
+ Ok(())
+ }
+
+ fn unclog_pipe(&mut self) -> std::io::Result<()> {
+ let mut buffer = vec![0u8; self.read_chunksize];
+ let read = match self.read_data(&mut buffer) {
+ Ok(read) => read,
+ Err(error) => match error.kind() {
+ std::io::ErrorKind::Interrupted | std::io::ErrorKind::WouldBlock => 0,
+ _ => return Err(error),
+ },
+ };
+ self.unclog_buffer.extend(buffer[0..read].iter());
+ Ok(())
+ }
+
+ fn commit_write(&mut self) -> std::io::Result<()> {
+ let timeout = std::time::Instant::now();
+ while !self.write_buffer.is_empty() {
+ let mut written = 0;
+ let result = self.write_data(&self.write_buffer.clone(), &mut written);
+ self.write_buffer.drain(..written);
+ if let Err(error) = result {
+ match error.kind() {
+ std::io::ErrorKind::TimedOut => self.unclog_pipe()?,
+ _ => return Err(error),
+ }
+ }
+ if timeout.elapsed() > self.write_timeout {
+ return Err(std::io::ErrorKind::TimedOut.into());
+ }
+ }
+ Ok(())
+ }
+
+ fn read(&mut self, buffer: &mut [u8]) -> std::io::Result {
+ if buffer.is_empty() {
+ Err(std::io::ErrorKind::InvalidInput.into())
+ } else if self.unclog_buffer.is_empty() {
+ self.read_data(buffer)
+ } else {
+ for (index, item) in buffer.iter_mut().enumerate() {
+ if let Some(byte) = self.unclog_buffer.pop_front() {
+ *item = byte;
+ } else {
+ return Ok(index);
+ }
+ }
+ Ok(buffer.len())
+ }
+ }
+
+ fn write(&mut self, buffer: &[u8]) -> std::io::Result {
+ let remaining_space = self.write_chunksize - self.write_buffer.len();
+ let length = buffer.len().min(remaining_space);
+ self.write_buffer.extend(&buffer[..length]);
+ if self.write_buffer.len() >= self.write_chunksize {
+ self.commit_write()?
+ }
+ Ok(length)
+ }
+
+ fn flush(&mut self) -> std::io::Result<()> {
+ self.commit_write()
+ }
+}
+
+impl Drop for Wrapper {
+ fn drop(&mut self) {
+ unsafe { libftdi1_sys::ftdi_free(self.context) }
+ }
+}
+
+pub struct FtdiDevice {
+ wrapper: Wrapper,
+}
+
+impl FtdiDevice {
+ pub fn list(vendor: u16, product: u16) -> std::io::Result> {
+ Wrapper::list_devices(vendor, product)
+ }
+
+ pub fn open(
+ description: &str,
+ poll_timeout: Option,
+ read_timeout: Option,
+ write_timeout: Option,
+ ) -> std::io::Result {
+ let mut wrapper = Wrapper::new(read_timeout, write_timeout)?;
+
+ wrapper.set_module_detach_mode(ModuleDetachMode::AutoDetachReattach);
+ wrapper.set_interface(InterfaceIndex::A)?;
+
+ const CHUNK_SIZE: usize = 2 * 1024 * 1024;
+
+ wrapper.read_data_set_chunksize(CHUNK_SIZE)?;
+ wrapper.write_data_set_chunksize(CHUNK_SIZE)?;
+
+ wrapper.usb_open_string(description)?;
+
+ wrapper.usb_reset()?;
+
+ wrapper.set_latency_timer(poll_timeout)?;
+
+ Ok(FtdiDevice { wrapper })
+ }
+
+ pub fn set_dtr(&mut self, value: bool) -> std::io::Result<()> {
+ self.wrapper.set_dtr(value)
+ }
+
+ pub fn read_dsr(&mut self) -> std::io::Result {
+ Ok(self.wrapper.poll_modem_status()?.dsr)
+ }
+
+ pub fn discard_input(&mut self) -> std::io::Result<()> {
+ self.wrapper.tciflush()
+ }
+
+ pub fn discard_output(&mut self) -> std::io::Result<()> {
+ self.wrapper.tcoflush()
+ }
+}
+
+impl std::io::Read for FtdiDevice {
+ fn read(&mut self, buffer: &mut [u8]) -> std::io::Result {
+ self.wrapper.read(buffer)
+ }
+}
+
+impl std::io::Write for FtdiDevice {
+ fn write(&mut self, buffer: &[u8]) -> std::io::Result {
+ self.wrapper.write(buffer)
+ }
+
+ fn flush(&mut self) -> std::io::Result<()> {
+ self.wrapper.flush()
+ }
+}
+
+impl Drop for FtdiDevice {
+ fn drop(&mut self) {
+ unsafe { libftdi1_sys::ftdi_usb_close(self.wrapper.context) };
+ }
+}
diff --git a/sw/deployer/src/sc64/link.rs b/sw/deployer/src/sc64/link.rs
index 88fe748..029870e 100644
--- a/sw/deployer/src/sc64/link.rs
+++ b/sw/deployer/src/sc64/link.rs
@@ -1,10 +1,9 @@
-use super::error::Error;
-use serial2::SerialPort;
+use super::{error::Error, ftdi::FtdiDevice, serial::SerialDevice};
use std::{
collections::VecDeque,
- io::{BufReader, BufWriter, ErrorKind, Read, Write},
+ fmt::Display,
+ io::{BufReader, BufWriter, Read, Write},
net::TcpStream,
- thread,
time::{Duration, Instant},
};
@@ -51,82 +50,97 @@ pub struct Response {
pub error: bool,
}
-pub struct Packet {
+pub struct AsynchronousPacket {
pub id: u8,
pub data: Vec,
}
-pub struct Serial {
- serial: SerialPort,
+pub enum UsbPacket {
+ Response(Response),
+ AsynchronousPacket(AsynchronousPacket),
}
-impl Serial {
- fn reset(&self) -> Result<(), Error> {
- const RESET_WAIT_DURATION: Duration = Duration::from_millis(10);
- const RESET_RETRY_COUNT: i32 = 100;
- const FLUSH_TIMEOUT: Duration = Duration::from_secs(1);
+const SERIAL_PREFIX: &str = "serial://";
+const FTDI_PREFIX: &str = "ftdi://";
- self.serial.set_dtr(true)?;
- for n in 0..=RESET_RETRY_COUNT {
- self.serial.discard_buffers()?;
- thread::sleep(RESET_WAIT_DURATION);
- if self.serial.read_dsr()? {
- break;
- }
- if n == RESET_RETRY_COUNT {
- return Err(Error::new("Couldn't reset SC64 device (on)"));
- }
- }
+const RESET_TIMEOUT: Duration = Duration::from_secs(1);
+const POLL_TIMEOUT: Duration = Duration::from_millis(5);
+const READ_TIMEOUT: Duration = Duration::from_secs(5);
+const WRITE_TIMEOUT: Duration = Duration::from_secs(5);
- let flush_timeout = Instant::now();
+pub trait Backend {
+ fn read(&mut self, buffer: &mut [u8]) -> std::io::Result;
+ fn write_all(&mut self, buffer: &[u8]) -> std::io::Result<()>;
+
+ fn flush(&mut self) -> std::io::Result<()>;
+
+ fn discard_input(&mut self) -> std::io::Result<()> {
+ Ok(())
+ }
+
+ fn discard_output(&mut self) -> std::io::Result<()> {
+ Ok(())
+ }
+
+ fn set_dtr(&mut self, _value: bool) -> std::io::Result<()> {
+ Ok(())
+ }
+
+ fn read_dsr(&mut self) -> std::io::Result {
+ Ok(false)
+ }
+
+ fn close(&mut self) {}
+
+ fn reset(&mut self) -> std::io::Result<()> {
+ self.discard_output()?;
+
+ let timeout = Instant::now();
+ self.set_dtr(true)?;
loop {
- match self.serial.read(&mut vec![0; 1]) {
- Ok(length) => match length {
- 0 => break,
- _ => {}
- },
- Err(error) => match error.kind() {
- ErrorKind::TimedOut => break,
- _ => {
- return Err(Error::new(
- format!("Couldn't flush SC64 serial buffer: {error}").as_str(),
- ))
- }
- },
+ if self.read_dsr()? {
+ break;
}
- if flush_timeout.elapsed() >= FLUSH_TIMEOUT {
- return Err(Error::new("SC64 serial buffer flush took too long"));
+ if timeout.elapsed() > RESET_TIMEOUT {
+ return Err(std::io::Error::new(
+ std::io::ErrorKind::TimedOut,
+ "Couldn't reset SC64 device (on)",
+ ));
}
}
- self.serial.set_dtr(false)?;
- for n in 0..=RESET_RETRY_COUNT {
- thread::sleep(RESET_WAIT_DURATION);
- if !self.serial.read_dsr()? {
+ self.discard_input()?;
+
+ let timeout = Instant::now();
+ self.set_dtr(false)?;
+ loop {
+ if !self.read_dsr()? {
break;
}
- if n == RESET_RETRY_COUNT {
- return Err(Error::new("Couldn't reset SC64 device (off)"));
+ if timeout.elapsed() > RESET_TIMEOUT {
+ return Err(std::io::Error::new(
+ std::io::ErrorKind::TimedOut,
+ "Couldn't reset SC64 device (off)",
+ ));
}
}
Ok(())
}
- fn read_data(&self, buffer: &mut [u8], block: bool) -> Result