mirror of
https://github.com/Polprzewodnikowy/SummerCart64.git
synced 2024-12-24 03:51:57 +01:00
nice
This commit is contained in:
parent
676bf07d91
commit
87fddd912e
@ -56,6 +56,7 @@ set_global_assignment -name SIGNALTAP_FILE stp.stp
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE btldr/btldr.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE picorv32/picorv32.v
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_bus.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_cfg.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_dma.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_gpio.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_i2c.sv
|
||||
@ -68,6 +69,7 @@ set_global_assignment -name SYSTEMVERILOG_FILE rtl/memory/memory_flash.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/memory/memory_sdram.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_bootloader.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_bus.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_cfg.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_pi.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_sdram.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/n64/n64_soc.sv
|
||||
@ -302,254 +304,6 @@ set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
|
||||
# ------------------------
|
||||
set_global_assignment -name QIP_FILE rtl/intel/gpio/intel_gpio_ddro.qip
|
||||
|
||||
set_global_assignment -name SLD_NODE_CREATOR_ID 110 -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_NODE_ENTITY_NAME sld_signaltap -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_clk -to "system:system_inst|intel_pll:intel_pll_inst|altpll:altpll_component|clk[0]" -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_RAM_BLOCK_TYPE=AUTO" -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_NODE_INFO=805334528" -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_POWER_UP_TRIGGER=0" -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_ATTRIBUTE_MEM_MODE=OFF" -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_STATE_FLOW_USE_GENERATED=0" -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_STATE_BITS=11" -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_BUFFER_FULL_STOP=1" -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_CURRENT_RESOURCE_WIDTH=1" -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_INCREMENTAL_ROUTING=1" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[0] -to auto_signaltap_0|vcc -section_id auto_signaltap_0
|
||||
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[1] -to auto_signaltap_0|vcc -section_id auto_signaltap_0
|
||||
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[2] -to auto_signaltap_0|vcc -section_id auto_signaltap_0
|
||||
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[3] -to auto_signaltap_0|vcc -section_id auto_signaltap_0
|
||||
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[6] -to auto_signaltap_0|gnd -section_id auto_signaltap_0
|
||||
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[7] -to auto_signaltap_0|vcc -section_id auto_signaltap_0
|
||||
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[10] -to auto_signaltap_0|gnd -section_id auto_signaltap_0
|
||||
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[13] -to auto_signaltap_0|gnd -section_id auto_signaltap_0
|
||||
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[14] -to auto_signaltap_0|vcc -section_id auto_signaltap_0
|
||||
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[15] -to auto_signaltap_0|gnd -section_id auto_signaltap_0
|
||||
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[16] -to auto_signaltap_0|gnd -section_id auto_signaltap_0
|
||||
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[17] -to auto_signaltap_0|gnd -section_id auto_signaltap_0
|
||||
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[19] -to auto_signaltap_0|gnd -section_id auto_signaltap_0
|
||||
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[25] -to auto_signaltap_0|vcc -section_id auto_signaltap_0
|
||||
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[26] -to auto_signaltap_0|gnd -section_id auto_signaltap_0
|
||||
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[27] -to auto_signaltap_0|gnd -section_id auto_signaltap_0
|
||||
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[28] -to auto_signaltap_0|vcc -section_id auto_signaltap_0
|
||||
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[30] -to auto_signaltap_0|gnd -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_TRIGGER_LEVEL=1" -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_TRIGGER_IN_ENABLED=0" -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_TRIGGER_PIPELINE=0" -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_RAM_PIPELINE=0" -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_COUNTER_PIPELINE=0" -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_ADVANCED_TRIGGER_ENTITY=basic,1," -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_TRIGGER_LEVEL_PIPELINE=1" -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_ENABLE_ADVANCED_TRIGGER=0" -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_STORAGE_QUALIFIER_INVERSION_MASK_LENGTH=0" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[4] -to auto_signaltap_0|gnd -section_id auto_signaltap_0
|
||||
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[8] -to auto_signaltap_0|gnd -section_id auto_signaltap_0
|
||||
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[9] -to auto_signaltap_0|gnd -section_id auto_signaltap_0
|
||||
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[12] -to auto_signaltap_0|vcc -section_id auto_signaltap_0
|
||||
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[18] -to auto_signaltap_0|vcc -section_id auto_signaltap_0
|
||||
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[20] -to auto_signaltap_0|vcc -section_id auto_signaltap_0
|
||||
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[22] -to auto_signaltap_0|vcc -section_id auto_signaltap_0
|
||||
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[24] -to auto_signaltap_0|gnd -section_id auto_signaltap_0
|
||||
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[29] -to auto_signaltap_0|gnd -section_id auto_signaltap_0
|
||||
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[31] -to auto_signaltap_0|vcc -section_id auto_signaltap_0
|
||||
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[5] -to auto_signaltap_0|vcc -section_id auto_signaltap_0
|
||||
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[11] -to auto_signaltap_0|vcc -section_id auto_signaltap_0
|
||||
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[21] -to auto_signaltap_0|vcc -section_id auto_signaltap_0
|
||||
set_instance_assignment -name POST_FIT_CONNECT_TO_SLD_NODE_ENTITY_PORT crc[23] -to auto_signaltap_0|gnd -section_id auto_signaltap_0
|
||||
set_global_assignment -name SOURCE_FILE sfp.spf
|
||||
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_SEGMENT_SIZE=1024" -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_SAMPLE_DEPTH=1024" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[0] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.ack" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[1] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[0]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[2] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[10]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[3] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[11]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[4] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[12]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[5] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[13]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[6] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[14]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[7] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[15]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[8] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[16]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[9] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[17]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[10] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[18]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[11] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[19]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[12] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[1]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[13] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[20]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[14] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[21]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[15] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[22]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[16] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[23]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[17] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[24]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[18] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[25]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[19] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[26]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[20] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[27]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[21] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[28]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[22] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[29]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[23] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[2]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[24] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[30]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[25] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[31]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[26] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[3]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[27] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[4]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[28] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[5]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[29] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[6]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[30] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[7]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[31] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[8]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[32] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[9]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[33] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.id[0]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[34] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.id[1]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[35] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.request" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[36] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.rx_empty" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[37] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.rx_rdata[0]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[38] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.rx_rdata[1]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[39] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.rx_rdata[2]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[40] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.rx_rdata[3]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[41] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.rx_rdata[4]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[42] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.rx_rdata[5]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[43] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.rx_rdata[6]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[44] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.rx_rdata[7]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[45] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.rx_read" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[46] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.wdata[0]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[47] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.wdata[10]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[48] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.wdata[11]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[49] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.wdata[12]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[50] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.wdata[13]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[51] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.wdata[14]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[52] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.wdata[15]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[53] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.wdata[1]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[54] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.wdata[2]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[55] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.wdata[3]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[56] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.wdata[4]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[57] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.wdata[5]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[58] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.wdata[6]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[59] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.wdata[7]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[60] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.wdata[8]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[61] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.wdata[9]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[62] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.write" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[63] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[0]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[64] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[10]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[65] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[11]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[66] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[12]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[67] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[13]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[68] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[14]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[69] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[15]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[70] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[16]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[71] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[17]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[72] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[18]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[73] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[19]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[74] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[1]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[75] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[20]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[76] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[21]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[77] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[22]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[78] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[23]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[79] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[24]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[80] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[25]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[81] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[26]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[82] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[27]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[83] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[2]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[84] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[3]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[85] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[4]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[86] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[5]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[87] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[6]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[88] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[7]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[89] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[8]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[90] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[9]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[91] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|state.S_FETCH" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[92] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|state.S_IDLE" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_trigger_in[93] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|state.S_TRANSFER" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[0] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.ack" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[1] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[0]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[2] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[10]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[3] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[11]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[4] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[12]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[5] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[13]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[6] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[14]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[7] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[15]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[8] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[16]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[9] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[17]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[10] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[18]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[11] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[19]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[12] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[1]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[13] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[20]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[14] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[21]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[15] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[22]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[16] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[23]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[17] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[24]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[18] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[25]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[19] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[26]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[20] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[27]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[21] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[28]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[22] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[29]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[23] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[2]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[24] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[30]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[25] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[31]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[26] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[3]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[27] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[4]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[28] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[5]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[29] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[6]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[30] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[7]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[31] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[8]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[32] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.address[9]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[33] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.id[0]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[34] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.id[1]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[35] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.request" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[36] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.rx_empty" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[37] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.rx_rdata[0]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[38] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.rx_rdata[1]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[39] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.rx_rdata[2]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[40] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.rx_rdata[3]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[41] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.rx_rdata[4]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[42] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.rx_rdata[5]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[43] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.rx_rdata[6]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[44] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.rx_rdata[7]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[45] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.rx_read" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[46] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.wdata[0]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[47] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.wdata[10]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[48] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.wdata[11]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[49] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.wdata[12]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[50] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.wdata[13]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[51] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.wdata[14]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[52] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.wdata[15]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[53] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.wdata[1]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[54] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.wdata[2]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[55] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.wdata[3]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[56] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.wdata[4]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[57] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.wdata[5]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[58] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.wdata[6]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[59] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.wdata[7]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[60] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.wdata[8]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[61] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.wdata[9]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[62] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|dma.write" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[63] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[0]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[64] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[10]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[65] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[11]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[66] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[12]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[67] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[13]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[68] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[14]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[69] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[15]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[70] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[16]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[71] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[17]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[72] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[18]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[73] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[19]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[74] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[1]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[75] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[20]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[76] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[21]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[77] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[22]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[78] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[23]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[79] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[24]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[80] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[25]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[81] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[26]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[82] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[27]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[83] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[2]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[84] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[3]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[85] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[4]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[86] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[5]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[87] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[6]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[88] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[7]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[89] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[8]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[90] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|length[9]" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[91] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|state.S_FETCH" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[92] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|state.S_IDLE" -section_id auto_signaltap_0
|
||||
set_instance_assignment -name CONNECT_TO_SLD_NODE_ENTITY_PORT acq_data_in[93] -to "cpu_soc:cpu_soc_inst|cpu_dma:cpu_dma_inst|state.S_TRANSFER" -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_DATA_BITS=94" -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_TRIGGER_BITS=94" -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_STORAGE_QUALIFIER_BITS=128" -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_INVERSION_MASK=000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_NODE_PARAMETER_ASSIGNMENT "SLD_INVERSION_MASK_LENGTH=306" -section_id auto_signaltap_0
|
||||
set_global_assignment -name SLD_FILE db/stp_auto_stripped.stp
|
||||
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
|
@ -1,21 +1,39 @@
|
||||
#include "btldr.h"
|
||||
|
||||
int reset_handler (void) {
|
||||
#ifdef BOOT_UART
|
||||
io8_t pointer = &RAM;
|
||||
#else
|
||||
#ifdef BOOT_N64
|
||||
io32_t pointer = &RAM;
|
||||
#endif
|
||||
#endif
|
||||
uint32_t length = 0;
|
||||
|
||||
while (!(USB_SR & USB_SR_TXE));
|
||||
USB_DR = '>';
|
||||
|
||||
#ifdef BOOT_UART
|
||||
for (int i = 0; i < 4; i++) {
|
||||
while (!(USB_SR & USB_SR_RXNE));
|
||||
length |= (USB_DR << (i * 8));
|
||||
while (!(UART_SR & UART_SR_RXNE));
|
||||
length |= (UART_DR << (i * 8));
|
||||
}
|
||||
#else
|
||||
#ifdef BOOT_N64
|
||||
while (!(CFG_SCR & CFG_SCR_BOOTSTRAP_PENDING));
|
||||
length = CFG_BOOTSTRAP;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
while (1) {
|
||||
while (!(USB_SR & USB_SR_RXNE));
|
||||
*pointer++ = USB_DR;
|
||||
if ((uint32_t)pointer == length) {
|
||||
#ifdef BOOT_UART
|
||||
while (!(UART_SR & UART_SR_RXNE));
|
||||
*pointer++ = UART_DR;
|
||||
#else
|
||||
#ifdef BOOT_N64
|
||||
while (!(CFG_SCR & CFG_SCR_BOOTSTRAP_PENDING));
|
||||
*pointer++ = CFG_BOOTSTRAP;
|
||||
#endif
|
||||
#endif
|
||||
if (((uint32_t) pointer) == length) {
|
||||
CFG_SCR |= CFG_SCR_CPU_BOOTSTRAPPED;
|
||||
__asm__("call 0");
|
||||
}
|
||||
}
|
||||
|
@ -5,15 +5,31 @@
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
typedef volatile uint8_t * io8_t;
|
||||
typedef volatile uint32_t * io32_t;
|
||||
#define BOOT_UART
|
||||
// #define BOOT_N64
|
||||
|
||||
#define RAM (*((io8_t) 0x00000000))
|
||||
#define USB_SR (*((io8_t) 0x50000000))
|
||||
#define USB_DR (*((io8_t) 0x50000004))
|
||||
typedef volatile uint8_t * io8_t;
|
||||
typedef volatile uint32_t * io32_t;
|
||||
|
||||
#define USB_SR_RXNE (1 << 0)
|
||||
#define USB_SR_TXE (1 << 1)
|
||||
#ifdef BOOT_UART
|
||||
#define RAM (*((io8_t) 0x00000000))
|
||||
#else
|
||||
#ifdef BOOT_N64
|
||||
#define RAM (*((io32_t) 0x00000000))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define UART_SR (*((io8_t) 0x50000000))
|
||||
#define UART_DR (*((io8_t) 0x50000004))
|
||||
|
||||
#define UART_SR_RXNE (1 << 0)
|
||||
#define UART_SR_TXE (1 << 1)
|
||||
|
||||
#define CFG_SCR (*((io32_t) 0x70000000))
|
||||
#define CFG_BOOTSTRAP (*((io32_t) 0x7000001C))
|
||||
|
||||
#define CFG_SCR_CPU_BOOTSTRAPPED (1 << 31)
|
||||
#define CFG_SCR_BOOTSTRAP_PENDING (1 << 29)
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -14,38 +14,37 @@ module cpu_bootloader (
|
||||
bus.rdata = 32'd0;
|
||||
if (bus.ack) begin
|
||||
case (bus.address[6:2])
|
||||
0: bus.rdata = 32'h50000737;
|
||||
1: bus.rdata = 32'h00074783;
|
||||
2: bus.rdata = 32'h0027f793;
|
||||
3: bus.rdata = 32'hfe078ce3;
|
||||
4: bus.rdata = 32'h03e00793;
|
||||
5: bus.rdata = 32'h00f70223;
|
||||
6: bus.rdata = 32'h50000637;
|
||||
7: bus.rdata = 32'h00000793;
|
||||
8: bus.rdata = 32'h00000713;
|
||||
9: bus.rdata = 32'h02000593;
|
||||
10: bus.rdata = 32'h00064683;
|
||||
11: bus.rdata = 32'h0016f693;
|
||||
12: bus.rdata = 32'hfe068ce3;
|
||||
13: bus.rdata = 32'h00464683;
|
||||
14: bus.rdata = 32'h00f696b3;
|
||||
15: bus.rdata = 32'h00878793;
|
||||
16: bus.rdata = 32'h00d76733;
|
||||
17: bus.rdata = 32'hfeb792e3;
|
||||
18: bus.rdata = 32'h00000793;
|
||||
19: bus.rdata = 32'h500005b7;
|
||||
20: bus.rdata = 32'h0005c683;
|
||||
21: bus.rdata = 32'h0016f693;
|
||||
22: bus.rdata = 32'hfe068ce3;
|
||||
23: bus.rdata = 32'h0045c683;
|
||||
24: bus.rdata = 32'h00178613;
|
||||
25: bus.rdata = 32'h0ff6f693;
|
||||
26: bus.rdata = 32'h00d78023;
|
||||
27: bus.rdata = 32'h00e61663;
|
||||
28: bus.rdata = 32'hf0000097;
|
||||
29: bus.rdata = 32'hf90080e7;
|
||||
30: bus.rdata = 32'h00060793;
|
||||
31: bus.rdata = 32'hfd5ff06f;
|
||||
0: bus.rdata = 32'h00000793;
|
||||
1: bus.rdata = 32'h00000713;
|
||||
2: bus.rdata = 32'h50000637;
|
||||
3: bus.rdata = 32'h02000593;
|
||||
4: bus.rdata = 32'h00064683;
|
||||
5: bus.rdata = 32'h0016f693;
|
||||
6: bus.rdata = 32'hfe068ce3;
|
||||
7: bus.rdata = 32'h00464683;
|
||||
8: bus.rdata = 32'h00f696b3;
|
||||
9: bus.rdata = 32'h00878793;
|
||||
10: bus.rdata = 32'h00d76733;
|
||||
11: bus.rdata = 32'hfeb792e3;
|
||||
12: bus.rdata = 32'h00000793;
|
||||
13: bus.rdata = 32'h50000537;
|
||||
14: bus.rdata = 32'h70000637;
|
||||
15: bus.rdata = 32'h80000837;
|
||||
16: bus.rdata = 32'h00054683;
|
||||
17: bus.rdata = 32'h0016f693;
|
||||
18: bus.rdata = 32'hfe068ce3;
|
||||
19: bus.rdata = 32'h00454683;
|
||||
20: bus.rdata = 32'h00178593;
|
||||
21: bus.rdata = 32'h0ff6f693;
|
||||
22: bus.rdata = 32'h00d78023;
|
||||
23: bus.rdata = 32'h00e59c63;
|
||||
24: bus.rdata = 32'h00062783;
|
||||
25: bus.rdata = 32'h0107e7b3;
|
||||
26: bus.rdata = 32'h00f62023;
|
||||
27: bus.rdata = 32'hf0000097;
|
||||
28: bus.rdata = 32'hf94080e7;
|
||||
29: bus.rdata = 32'h00058793;
|
||||
30: bus.rdata = 32'hfc9ff06f;
|
||||
default: bus.rdata = 32'd0;
|
||||
endcase
|
||||
end
|
||||
|
@ -20,12 +20,12 @@ cntrllr.elf: cntrllr.ld main.c rtc.c startup.S
|
||||
@$(CROSS)gcc $(FLAGS) -Tcntrllr.ld main.c rtc.c startup.S -o cntrllr.elf
|
||||
|
||||
cntrllr.bin: cntrllr.elf
|
||||
@$(CROSS)objcopy -O binary --gap-fill 0xFF --pad-to 0x4004 cntrllr.elf cntrllr.bin
|
||||
@$(CROSS)objcopy -O binary cntrllr.elf cntrllr.bin
|
||||
|
||||
print_size:
|
||||
@echo 'Size of target .elf file:'
|
||||
@$(CROSS)size -B cntrllr.elf
|
||||
@echo $(shell $(CROSS)size -B cntrllr.elf | awk 'NR==2 { printf "\nTotal memory used: %.2f%%\n",(100/(16*1024))*($$4-4) }')
|
||||
@echo $(shell $(CROSS)size -B cntrllr.elf | awk 'NR==2 { printf "\nTotal memory used: %.2f%%\n",(100/(16*1024))*($$4) }')
|
||||
|
||||
clean:
|
||||
@rm -f cntrllr.bin cntrllr.elf
|
||||
|
BIN
fw/cntrllr/cntrllr.bin.bak
Normal file
BIN
fw/cntrllr/cntrllr.bin.bak
Normal file
Binary file not shown.
@ -10,12 +10,7 @@ ENTRY(reset_handler)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.metadata :
|
||||
{
|
||||
KEEP(*(.rodata.metadata));
|
||||
}
|
||||
|
||||
.ram ORIGIN(ram) :
|
||||
.ram :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.text.startup);
|
||||
@ -25,5 +20,6 @@ SECTIONS
|
||||
*(.bss .bss.* .sbss .sbss.*);
|
||||
. = ALIGN(4);
|
||||
*(.data .data.* .sdata .stada.*);
|
||||
. = ALIGN(4);
|
||||
} > ram AT > ram
|
||||
}
|
||||
|
@ -70,75 +70,94 @@ __NAKED__ int main (void) {
|
||||
DMA_SCR = DMA_SCR_STOP;
|
||||
USB_SCR = USB_SCR_FLUSH_TX | USB_SCR_FLUSH_TX;
|
||||
|
||||
print("CPU START\r\n");
|
||||
|
||||
while (1) {
|
||||
arg1 = 0;
|
||||
arg2 = 0;
|
||||
|
||||
print("Loop start\r\n");
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
while (!(USB_SCR & USB_SCR_RXNE));
|
||||
data = USB_DR;
|
||||
if (i < 3 && data != CMD[i]) {
|
||||
i = 0;
|
||||
print("Wrong data ");
|
||||
print_02hex(data);
|
||||
print("\r\n");
|
||||
} else {
|
||||
cmd = data;
|
||||
if (USB_SCR & USB_SCR_RXNE) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
while (!(USB_SCR & USB_SCR_RXNE));
|
||||
data = USB_DR;
|
||||
if (i < 3 && data != CMD[i]) {
|
||||
i = 0;
|
||||
print("Wrong data ");
|
||||
print_02hex(data);
|
||||
print("\r\n");
|
||||
} else {
|
||||
cmd = data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
print("Received CMD");
|
||||
tmp[0] = cmd;
|
||||
print(tmp);
|
||||
print("\r\n");
|
||||
print("Received CMD");
|
||||
tmp[0] = cmd;
|
||||
print(tmp);
|
||||
print("\r\n");
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
while (!(USB_SCR & USB_SCR_RXNE));
|
||||
arg1 = (arg1 << 8) | USB_DR;
|
||||
}
|
||||
|
||||
print("Received ARG_1 0x");
|
||||
for (int i = 0; i < 4; i++) {
|
||||
print_02hex((uint8_t) (arg1 >> ((3 - i) * 8)));
|
||||
}
|
||||
print("\r\n");
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
while (!(USB_SCR & USB_SCR_RXNE));
|
||||
arg2 = (arg2 << 8) | USB_DR;
|
||||
}
|
||||
|
||||
print("Received ARG_2 0x");
|
||||
for (int i = 0; i < 4; i++) {
|
||||
print_02hex((uint8_t) (arg2 >> ((3 - i) * 8)));
|
||||
}
|
||||
print("\r\n");
|
||||
|
||||
DMA_MADDR = arg1;
|
||||
DMA_ID_LEN = arg2;
|
||||
DMA_SCR = (cmd == CMD_W ? DMA_SCR_DIR : 0) | DMA_SCR_START;
|
||||
|
||||
print("Started DMA\r\n");
|
||||
|
||||
while (DMA_SCR & DMA_SCR_BUSY);
|
||||
|
||||
print("Finished DMA\r\n");
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
while (!(USB_SCR & USB_SCR_TXE));
|
||||
if (i < 3) {
|
||||
USB_DR = CMP[i];
|
||||
} else {
|
||||
USB_DR = cmd;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
while (!(USB_SCR & USB_SCR_RXNE));
|
||||
arg1 = (arg1 << 8) | USB_DR;
|
||||
}
|
||||
}
|
||||
|
||||
print("Sent response CMP");
|
||||
tmp[0] = cmd;
|
||||
print(tmp);
|
||||
print("\r\n\r\n");
|
||||
print("Received ARG_1 0x");
|
||||
for (int i = 0; i < 4; i++) {
|
||||
print_02hex((uint8_t) (arg1 >> ((3 - i) * 8)));
|
||||
}
|
||||
print("\r\n");
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
while (!(USB_SCR & USB_SCR_RXNE));
|
||||
arg2 = (arg2 << 8) | USB_DR;
|
||||
}
|
||||
|
||||
print("Received ARG_2 0x");
|
||||
for (int i = 0; i < 4; i++) {
|
||||
print_02hex((uint8_t) (arg2 >> ((3 - i) * 8)));
|
||||
}
|
||||
print("\r\n");
|
||||
|
||||
DMA_MADDR = arg1;
|
||||
DMA_ID_LEN = arg2;
|
||||
DMA_SCR = (cmd == CMD_W ? DMA_SCR_DIR : 0) | DMA_SCR_START;
|
||||
|
||||
print("Started DMA\r\n");
|
||||
|
||||
while (DMA_SCR & DMA_SCR_BUSY);
|
||||
|
||||
print("Finished DMA\r\n");
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
while (!(USB_SCR & USB_SCR_TXE));
|
||||
if (i < 3) {
|
||||
USB_DR = CMP[i];
|
||||
} else {
|
||||
USB_DR = cmd;
|
||||
}
|
||||
}
|
||||
|
||||
print("Sent response CMP");
|
||||
tmp[0] = cmd;
|
||||
print(tmp);
|
||||
print("\r\n\r\n");
|
||||
} else if (CFG_SCR & CFG_SCR_CPU_BUSY) {
|
||||
uint8_t cmd = CFG_COMMAND;
|
||||
arg1 = CFG_ARG_1;
|
||||
arg2 = CFG_ARG_2;
|
||||
print("Received N64 CMD");
|
||||
tmp[0] = cmd;
|
||||
print(tmp);
|
||||
print("\r\n");
|
||||
if (cmd == 'S') {
|
||||
if (arg1) {
|
||||
CFG_SCR |= CFG_SCR_SDRAM_SWITCH;
|
||||
} else {
|
||||
CFG_SCR &= ~CFG_SCR_SDRAM_SWITCH;
|
||||
}
|
||||
}
|
||||
CFG_RESPONSE = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,3 @@
|
||||
.section .rodata.metadata
|
||||
metadata:
|
||||
.word __ram_size
|
||||
|
||||
.section .text.startup
|
||||
.global reset_handler
|
||||
reset_handler:
|
||||
|
@ -27,6 +27,13 @@ typedef volatile uint32_t * io32_t;
|
||||
#define DMA_MADDR (*((io32_t) 0x60000004))
|
||||
#define DMA_ID_LEN (*((io32_t) 0x60000008))
|
||||
#define SDRAM (*((io32_t) 0x68000000))
|
||||
#define CFG_SCR (*((io32_t) 0x70000000))
|
||||
#define CFG_DD_OFFSET (*((io32_t) 0x70000004))
|
||||
#define CFG_SAVE_OFFSET (*((io32_t) 0x70000008))
|
||||
#define CFG_COMMAND (*((io8_t) 0x7000000C))
|
||||
#define CFG_ARG_1 (*((io32_t) 0x70000010))
|
||||
#define CFG_ARG_2 (*((io32_t) 0x70000014))
|
||||
#define CFG_RESPONSE (*((io32_t) 0x70000018))
|
||||
|
||||
#define I2C_SR_START (1 << 0)
|
||||
#define I2C_SR_STOP (1 << 1)
|
||||
@ -51,5 +58,8 @@ typedef volatile uint32_t * io32_t;
|
||||
#define DMA_ID_USB (0)
|
||||
#define DMA_ID_SD (1)
|
||||
|
||||
#define CFG_SCR_CPU_BUSY (1 << 30)
|
||||
#define CFG_SCR_SDRAM_SWITCH (1 << 0)
|
||||
|
||||
|
||||
#endif
|
||||
|
121
fw/rtl/cpu/cpu_cfg.sv
Normal file
121
fw/rtl/cpu/cpu_cfg.sv
Normal file
@ -0,0 +1,121 @@
|
||||
module cpu_cfg (
|
||||
if_system.sys sys,
|
||||
if_cpu_bus bus,
|
||||
if_config.cpu cfg
|
||||
);
|
||||
|
||||
typedef enum bit [2:0] {
|
||||
R_SCR,
|
||||
R_DD_OFFSET,
|
||||
R_SAVE_OFFSET,
|
||||
R_COMMAND,
|
||||
R_ARG_1,
|
||||
R_ARG_2,
|
||||
R_RESPONSE,
|
||||
R_BOOTSTRAP
|
||||
} e_reg_id;
|
||||
|
||||
logic bootstrap_pending;
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
bus.ack <= 1'b0;
|
||||
if (bus.request) begin
|
||||
bus.ack <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
bus.rdata = 32'd0;
|
||||
if (bus.ack) begin
|
||||
case (bus.address[4:2])
|
||||
R_SCR: bus.rdata = {
|
||||
cfg.cpu_bootstrapped,
|
||||
cfg.cpu_busy,
|
||||
bootstrap_pending,
|
||||
24'd0,
|
||||
cfg.flashram_enabled,
|
||||
cfg.sram_enabled,
|
||||
cfg.dd_enabled,
|
||||
cfg.sdram_writable,
|
||||
cfg.sdram_switch
|
||||
};
|
||||
R_DD_OFFSET: bus.rdata = {6'd0, cfg.dd_offset};
|
||||
R_SAVE_OFFSET: bus.rdata = {6'd0, cfg.save_offset};
|
||||
R_COMMAND: bus.rdata = {24'd0, cfg.command};
|
||||
R_ARG_1: bus.rdata = cfg.arg[0];
|
||||
R_ARG_2: bus.rdata = cfg.arg[1];
|
||||
R_RESPONSE: bus.rdata = cfg.response;
|
||||
R_BOOTSTRAP: bus.rdata = cfg.arg[0];
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
if (sys.reset) begin
|
||||
cfg.cpu_bootstrapped <= 1'b0;
|
||||
cfg.cpu_busy <= 1'b0;
|
||||
cfg.sdram_switch <= 1'b0;
|
||||
cfg.sdram_writable <= 1'b0;
|
||||
cfg.dd_enabled <= 1'b0;
|
||||
cfg.sram_enabled <= 1'b0;
|
||||
cfg.flashram_enabled <= 1'b0;
|
||||
cfg.dd_offset <= 26'h3BE_0000;
|
||||
cfg.save_offset <= 26'h3FE_0000;
|
||||
bootstrap_pending <= 1'b0;
|
||||
end else begin
|
||||
if (sys.n64_soft_reset) begin
|
||||
cfg.sdram_switch <= 1'b0;
|
||||
end
|
||||
if (cfg.request) begin
|
||||
cfg.cpu_busy <= 1'b1;
|
||||
end
|
||||
if (cfg.boot_write) begin
|
||||
bootstrap_pending <= 1'b1;
|
||||
end
|
||||
if (bus.request) begin
|
||||
case (bus.address[4:2])
|
||||
R_SCR: begin
|
||||
if (bus.wmask[3]) begin
|
||||
cfg.cpu_bootstrapped <= bus.wdata[31];
|
||||
end
|
||||
if (bus.wmask[0]) begin
|
||||
{
|
||||
cfg.flashram_enabled,
|
||||
cfg.sram_enabled,
|
||||
cfg.dd_enabled,
|
||||
cfg.sdram_writable,
|
||||
cfg.sdram_switch
|
||||
} <= bus.wdata[4:0];
|
||||
end
|
||||
end
|
||||
|
||||
R_DD_OFFSET: begin
|
||||
if (&bus.wmask) begin
|
||||
cfg.dd_offset <= bus.wdata[25:0];
|
||||
end
|
||||
end
|
||||
|
||||
R_SAVE_OFFSET: begin
|
||||
if (&bus.wmask) begin
|
||||
cfg.save_offset <= bus.wdata[25:0];
|
||||
end
|
||||
end
|
||||
|
||||
R_RESPONSE: begin
|
||||
if (&bus.wmask) begin
|
||||
cfg.cpu_busy <= 1'b0;
|
||||
cfg.response <= bus.wdata;
|
||||
end
|
||||
end
|
||||
|
||||
R_BOOTSTRAP: begin
|
||||
if (!(|bus.wmask)) begin
|
||||
bootstrap_pending <= 1'b0;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
@ -55,7 +55,7 @@ interface if_dma ();
|
||||
tx_full = 1'b0;
|
||||
|
||||
for (integer i = 0; i < NUM_DEVICES; i++) begin
|
||||
rx_rdata = rx_rdata | device_rx_rdata[i];//(device_rx_rdata[i] & {8{id == i[1:0]});
|
||||
rx_rdata = rx_rdata | (id == i[1:0] ? device_rx_rdata[i] : 8'd0);
|
||||
rx_empty = rx_empty | (device_rx_empty[i] && id == i[1:0]);
|
||||
tx_full = tx_full | (device_tx_full[i] && id == i[1:0]);
|
||||
end
|
||||
@ -104,6 +104,7 @@ module cpu_dma (
|
||||
logic direction;
|
||||
logic [27:0] length;
|
||||
logic [15:0] rdata_buffer;
|
||||
logic byte_counter;
|
||||
|
||||
always_comb begin
|
||||
bus.rdata = 32'd0;
|
||||
@ -116,8 +117,6 @@ module cpu_dma (
|
||||
end
|
||||
end
|
||||
|
||||
logic byte_counter;
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
bus.ack <= 1'b0;
|
||||
if (bus.request) begin
|
||||
|
@ -1,6 +1,6 @@
|
||||
module cpu_soc (
|
||||
if_system.sys sys,
|
||||
if_config cfg,
|
||||
if_config.cpu cfg,
|
||||
if_dma dma,
|
||||
|
||||
input [7:0] gpio_i,
|
||||
@ -84,4 +84,10 @@ module cpu_soc (
|
||||
.dma(dma)
|
||||
);
|
||||
|
||||
cpu_cfg cpu_cfg_inst (
|
||||
.sys(sys),
|
||||
.bus(bus.at[sc64::ID_CPU_CFG].device),
|
||||
.cfg(cfg)
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
@ -71,8 +71,8 @@
|
||||
<parameter name="SECTOR_ACCESS_MODE">Read only,Read only,Hidden,Read only,Read only</parameter>
|
||||
<parameter name="autoInitializationFileName">$${FILENAME}_onchip_flash_0</parameter>
|
||||
<parameter name="initFlashContent" value="true" />
|
||||
<parameter name="initializationFileName">C:/Dev/SummerCollection/sw/bootloader/what/build/SummerLoader64.hex</parameter>
|
||||
<parameter name="initializationFileNameForSim">C:/Dev/SummerCollection/sw/bootloader/what/build/SummerLoader64.hex</parameter>
|
||||
<parameter name="initializationFileName">C:/Dev/SummerCollection/sw/bootloader/build/SummerLoader64.hex</parameter>
|
||||
<parameter name="initializationFileNameForSim">C:/Dev/SummerCollection/sw/bootloader/build/SummerLoader64.hex</parameter>
|
||||
<parameter name="useNonDefaultInitFile" value="true" />
|
||||
</module>
|
||||
<interconnectRequirement for="$system" name="qsys_mm.clockCrossingAdapter" value="HANDSHAKE" />
|
||||
|
111
fw/rtl/intel/flash/intel_flash/intel_flash.bsf
Normal file
111
fw/rtl/intel/flash/intel_flash/intel_flash.bsf
Normal file
@ -0,0 +1,111 @@
|
||||
/*
|
||||
WARNING: Do NOT edit the input and output ports in this file in a text
|
||||
editor if you plan to continue editing the block that represents it in
|
||||
the Block Editor! File corruption is VERY likely to occur.
|
||||
*/
|
||||
/*
|
||||
Copyright (C) 2020 Intel Corporation. All rights reserved.
|
||||
Your use of Intel Corporation's design tools, logic functions
|
||||
and other software and tools, and any partner logic
|
||||
functions, and any output files from any of the foregoing
|
||||
(including device programming or simulation files), and any
|
||||
associated documentation or information are expressly subject
|
||||
to the terms and conditions of the Intel Program License
|
||||
Subscription Agreement, the Intel Quartus Prime License Agreement,
|
||||
the Intel FPGA IP License Agreement, or other applicable license
|
||||
agreement, including, without limitation, that your use is for
|
||||
the sole purpose of programming logic devices manufactured by
|
||||
Intel and sold by Intel or its authorized distributors. Please
|
||||
refer to the applicable agreement for further details, at
|
||||
https://fpgasoftware.intel.com/eula.
|
||||
*/
|
||||
(header "symbol" (version "1.1"))
|
||||
(symbol
|
||||
(rect 0 0 368 264)
|
||||
(text "intel_flash" (rect 154 -1 192 11)(font "Arial" (font_size 10)))
|
||||
(text "inst" (rect 8 248 20 260)(font "Arial" ))
|
||||
(port
|
||||
(pt 0 72)
|
||||
(input)
|
||||
(text "clock" (rect 0 0 20 12)(font "Arial" (font_size 8)))
|
||||
(text "clock" (rect 4 61 34 72)(font "Arial" (font_size 8)))
|
||||
(line (pt 0 72)(pt 144 72)(line_width 1))
|
||||
)
|
||||
(port
|
||||
(pt 0 112)
|
||||
(input)
|
||||
(text "avmm_data_addr[15..0]" (rect 0 0 96 12)(font "Arial" (font_size 8)))
|
||||
(text "avmm_data_addr[15..0]" (rect 4 101 130 112)(font "Arial" (font_size 8)))
|
||||
(line (pt 0 112)(pt 144 112)(line_width 3))
|
||||
)
|
||||
(port
|
||||
(pt 0 128)
|
||||
(input)
|
||||
(text "avmm_data_read" (rect 0 0 73 12)(font "Arial" (font_size 8)))
|
||||
(text "avmm_data_read" (rect 4 117 88 128)(font "Arial" (font_size 8)))
|
||||
(line (pt 0 128)(pt 144 128)(line_width 1))
|
||||
)
|
||||
(port
|
||||
(pt 0 192)
|
||||
(input)
|
||||
(text "avmm_data_burstcount[1..0]" (rect 0 0 115 12)(font "Arial" (font_size 8)))
|
||||
(text "avmm_data_burstcount[1..0]" (rect 4 181 160 192)(font "Arial" (font_size 8)))
|
||||
(line (pt 0 192)(pt 144 192)(line_width 3))
|
||||
)
|
||||
(port
|
||||
(pt 0 232)
|
||||
(input)
|
||||
(text "reset_n" (rect 0 0 30 12)(font "Arial" (font_size 8)))
|
||||
(text "reset_n" (rect 4 221 46 232)(font "Arial" (font_size 8)))
|
||||
(line (pt 0 232)(pt 144 232)(line_width 1))
|
||||
)
|
||||
(port
|
||||
(pt 0 144)
|
||||
(output)
|
||||
(text "avmm_data_readdata[31..0]" (rect 0 0 113 12)(font "Arial" (font_size 8)))
|
||||
(text "avmm_data_readdata[31..0]" (rect 4 133 154 144)(font "Arial" (font_size 8)))
|
||||
(line (pt 0 144)(pt 144 144)(line_width 3))
|
||||
)
|
||||
(port
|
||||
(pt 0 160)
|
||||
(output)
|
||||
(text "avmm_data_waitrequest" (rect 0 0 99 12)(font "Arial" (font_size 8)))
|
||||
(text "avmm_data_waitrequest" (rect 4 149 130 160)(font "Arial" (font_size 8)))
|
||||
(line (pt 0 160)(pt 144 160)(line_width 1))
|
||||
)
|
||||
(port
|
||||
(pt 0 176)
|
||||
(output)
|
||||
(text "avmm_data_readdatavalid" (rect 0 0 107 12)(font "Arial" (font_size 8)))
|
||||
(text "avmm_data_readdatavalid" (rect 4 165 142 176)(font "Arial" (font_size 8)))
|
||||
(line (pt 0 176)(pt 144 176)(line_width 1))
|
||||
)
|
||||
(drawing
|
||||
(text "clk" (rect 129 43 276 99)(font "Arial" (color 128 0 0)(font_size 9)))
|
||||
(text "clk" (rect 149 67 316 144)(font "Arial" (color 0 0 0)))
|
||||
(text "data" (rect 120 83 264 179)(font "Arial" (color 128 0 0)(font_size 9)))
|
||||
(text "address" (rect 149 107 340 224)(font "Arial" (color 0 0 0)))
|
||||
(text "read" (rect 149 123 322 256)(font "Arial" (color 0 0 0)))
|
||||
(text "readdata" (rect 149 139 346 288)(font "Arial" (color 0 0 0)))
|
||||
(text "waitrequest" (rect 149 155 364 320)(font "Arial" (color 0 0 0)))
|
||||
(text "readdatavalid" (rect 149 171 376 352)(font "Arial" (color 0 0 0)))
|
||||
(text "burstcount" (rect 149 187 358 384)(font "Arial" (color 0 0 0)))
|
||||
(text "nreset" (rect 108 203 252 419)(font "Arial" (color 128 0 0)(font_size 9)))
|
||||
(text "reset_n" (rect 149 227 340 464)(font "Arial" (color 0 0 0)))
|
||||
(text " system " (rect 333 248 714 506)(font "Arial" ))
|
||||
(line (pt 144 32)(pt 224 32)(line_width 1))
|
||||
(line (pt 224 32)(pt 224 248)(line_width 1))
|
||||
(line (pt 144 248)(pt 224 248)(line_width 1))
|
||||
(line (pt 144 32)(pt 144 248)(line_width 1))
|
||||
(line (pt 145 52)(pt 145 76)(line_width 1))
|
||||
(line (pt 146 52)(pt 146 76)(line_width 1))
|
||||
(line (pt 145 92)(pt 145 196)(line_width 1))
|
||||
(line (pt 146 92)(pt 146 196)(line_width 1))
|
||||
(line (pt 145 212)(pt 145 236)(line_width 1))
|
||||
(line (pt 146 212)(pt 146 236)(line_width 1))
|
||||
(line (pt 0 0)(pt 368 0)(line_width 1))
|
||||
(line (pt 368 0)(pt 368 264)(line_width 1))
|
||||
(line (pt 0 264)(pt 368 264)(line_width 1))
|
||||
(line (pt 0 0)(pt 0 264)(line_width 1))
|
||||
)
|
||||
)
|
13
fw/rtl/intel/flash/intel_flash/intel_flash.cmp
Normal file
13
fw/rtl/intel/flash/intel_flash/intel_flash.cmp
Normal file
@ -0,0 +1,13 @@
|
||||
component intel_flash is
|
||||
port (
|
||||
clock : in std_logic := 'X'; -- clk
|
||||
avmm_data_addr : in std_logic_vector(15 downto 0) := (others => 'X'); -- address
|
||||
avmm_data_read : in std_logic := 'X'; -- read
|
||||
avmm_data_readdata : out std_logic_vector(31 downto 0); -- readdata
|
||||
avmm_data_waitrequest : out std_logic; -- waitrequest
|
||||
avmm_data_readdatavalid : out std_logic; -- readdatavalid
|
||||
avmm_data_burstcount : in std_logic_vector(1 downto 0) := (others => 'X'); -- burstcount
|
||||
reset_n : in std_logic := 'X' -- reset_n
|
||||
);
|
||||
end component intel_flash;
|
||||
|
17
fw/rtl/intel/flash/intel_flash/intel_flash.ppf
Normal file
17
fw/rtl/intel/flash/intel_flash/intel_flash.ppf
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<pinplan
|
||||
variation_name="onchip_flash_0"
|
||||
megafunction_name="ALTERA_ONCHIP_FLASH"
|
||||
intended_family="MAX 10"
|
||||
specifies="all_ports">
|
||||
<global>
|
||||
<pin name="clock" direction="input" scope="external" />
|
||||
<pin name="reset_n" direction="input" scope="external" />
|
||||
<pin name="avmm_data_addr[15..0]" direction="input" scope="external" />
|
||||
<pin name="avmm_data_read" direction="input" scope="external" />
|
||||
<pin name="avmm_data_readdata[31..0]" direction="output" scope="external" />
|
||||
<pin name="avmm_data_waitrequest" direction="output" scope="external" />
|
||||
<pin name="avmm_data_readdatavalid" direction="output" scope="external" />
|
||||
<pin name="avmm_data_burstcount[1..0]" direction="input" scope="external" />
|
||||
</global>
|
||||
</pinplan>
|
20
fw/rtl/intel/flash/intel_flash/intel_flash_bb.v
Normal file
20
fw/rtl/intel/flash/intel_flash/intel_flash_bb.v
Normal file
@ -0,0 +1,20 @@
|
||||
|
||||
module intel_flash (
|
||||
clock,
|
||||
avmm_data_addr,
|
||||
avmm_data_read,
|
||||
avmm_data_readdata,
|
||||
avmm_data_waitrequest,
|
||||
avmm_data_readdatavalid,
|
||||
avmm_data_burstcount,
|
||||
reset_n);
|
||||
|
||||
input clock;
|
||||
input [15:0] avmm_data_addr;
|
||||
input avmm_data_read;
|
||||
output [31:0] avmm_data_readdata;
|
||||
output avmm_data_waitrequest;
|
||||
output avmm_data_readdatavalid;
|
||||
input [1:0] avmm_data_burstcount;
|
||||
input reset_n;
|
||||
endmodule
|
11
fw/rtl/intel/flash/intel_flash/intel_flash_inst.v
Normal file
11
fw/rtl/intel/flash/intel_flash/intel_flash_inst.v
Normal file
@ -0,0 +1,11 @@
|
||||
intel_flash u0 (
|
||||
.clock (<connected-to-clock>), // clk.clk
|
||||
.avmm_data_addr (<connected-to-avmm_data_addr>), // data.address
|
||||
.avmm_data_read (<connected-to-avmm_data_read>), // .read
|
||||
.avmm_data_readdata (<connected-to-avmm_data_readdata>), // .readdata
|
||||
.avmm_data_waitrequest (<connected-to-avmm_data_waitrequest>), // .waitrequest
|
||||
.avmm_data_readdatavalid (<connected-to-avmm_data_readdatavalid>), // .readdatavalid
|
||||
.avmm_data_burstcount (<connected-to-avmm_data_burstcount>), // .burstcount
|
||||
.reset_n (<connected-to-reset_n>) // nreset.reset_n
|
||||
);
|
||||
|
25
fw/rtl/intel/flash/intel_flash/intel_flash_inst.vhd
Normal file
25
fw/rtl/intel/flash/intel_flash/intel_flash_inst.vhd
Normal file
@ -0,0 +1,25 @@
|
||||
component intel_flash is
|
||||
port (
|
||||
clock : in std_logic := 'X'; -- clk
|
||||
avmm_data_addr : in std_logic_vector(15 downto 0) := (others => 'X'); -- address
|
||||
avmm_data_read : in std_logic := 'X'; -- read
|
||||
avmm_data_readdata : out std_logic_vector(31 downto 0); -- readdata
|
||||
avmm_data_waitrequest : out std_logic; -- waitrequest
|
||||
avmm_data_readdatavalid : out std_logic; -- readdatavalid
|
||||
avmm_data_burstcount : in std_logic_vector(1 downto 0) := (others => 'X'); -- burstcount
|
||||
reset_n : in std_logic := 'X' -- reset_n
|
||||
);
|
||||
end component intel_flash;
|
||||
|
||||
u0 : component intel_flash
|
||||
port map (
|
||||
clock => CONNECTED_TO_clock, -- clk.clk
|
||||
avmm_data_addr => CONNECTED_TO_avmm_data_addr, -- data.address
|
||||
avmm_data_read => CONNECTED_TO_avmm_data_read, -- .read
|
||||
avmm_data_readdata => CONNECTED_TO_avmm_data_readdata, -- .readdata
|
||||
avmm_data_waitrequest => CONNECTED_TO_avmm_data_waitrequest, -- .waitrequest
|
||||
avmm_data_readdatavalid => CONNECTED_TO_avmm_data_readdatavalid, -- .readdatavalid
|
||||
avmm_data_burstcount => CONNECTED_TO_avmm_data_burstcount, -- .burstcount
|
||||
reset_n => CONNECTED_TO_reset_n -- nreset.reset_n
|
||||
);
|
||||
|
75
fw/rtl/n64/n64_cfg.sv
Normal file
75
fw/rtl/n64/n64_cfg.sv
Normal file
@ -0,0 +1,75 @@
|
||||
module n64_cfg (
|
||||
if_system sys,
|
||||
if_n64_bus bus,
|
||||
if_config.n64 cfg
|
||||
);
|
||||
|
||||
typedef enum bit [0:0] {
|
||||
S_IDLE,
|
||||
S_WAIT
|
||||
} e_state;
|
||||
|
||||
e_state state;
|
||||
|
||||
always_comb begin
|
||||
bus.rdata = 16'd0;
|
||||
if (bus.ack) begin
|
||||
case (bus.address[4:1])
|
||||
0: bus.rdata = {cfg.cpu_bootstrapped, cfg.cpu_busy, 14'd0};
|
||||
// ...
|
||||
3: bus.rdata = {8'd0, cfg.command};
|
||||
4: bus.rdata = cfg.arg[0][31:16];
|
||||
5: bus.rdata = cfg.arg[0][15:0];
|
||||
6: bus.rdata = cfg.arg[1][31:16];
|
||||
7: bus.rdata = cfg.arg[1][15:0];
|
||||
8: bus.rdata = cfg.response[31:16];
|
||||
9: bus.rdata = cfg.response[15:0];
|
||||
10: bus.rdata = cfg.arg[0][31:16];
|
||||
11: bus.rdata = cfg.arg[0][15:0];
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge sys.clk) begin
|
||||
bus.ack <= 1'b0;
|
||||
cfg.request <= 1'b0;
|
||||
cfg.boot_write <= 1'b0;
|
||||
|
||||
if (sys.reset) begin
|
||||
state <= S_IDLE;
|
||||
end else begin
|
||||
case (state)
|
||||
S_IDLE: begin
|
||||
if (bus.request) begin
|
||||
state <= S_WAIT;
|
||||
if (bus.write) begin
|
||||
case (bus.address[4:1])
|
||||
// ...
|
||||
3: begin
|
||||
cfg.command <= bus.wdata[7:0];
|
||||
cfg.request <= 1'b1;
|
||||
end
|
||||
4: cfg.arg[0][31:16] <= bus.wdata;
|
||||
5: cfg.arg[0][15:0] <= bus.wdata;
|
||||
6: cfg.arg[1][31:16] <= bus.wdata;
|
||||
7: cfg.arg[1][15:0] <= bus.wdata;
|
||||
// ...
|
||||
10: cfg.arg[0][31:16] <= bus.wdata;
|
||||
11: begin
|
||||
cfg.arg[0][15:0] <= bus.wdata;
|
||||
cfg.boot_write <= 1'b1;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
S_WAIT: begin
|
||||
bus.ack <= 1'b1;
|
||||
state <= S_IDLE;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
@ -154,7 +154,7 @@ module n64_pi (
|
||||
end
|
||||
if (n64_pi_ad_input == 16'h1FFF) begin
|
||||
n64_pi_address_valid <= 1'b1;
|
||||
next_id <= sc64::ID_N64_CPU;
|
||||
next_id <= sc64::ID_N64_CFG;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -61,7 +61,7 @@ module n64_sdram (
|
||||
|
||||
always_comb begin
|
||||
bus.ack = bus_or_dma == T_BUS && mem_ack;
|
||||
bus.rdata = mem_rdata;
|
||||
bus.rdata = bus.ack ? mem_rdata : 16'd0;
|
||||
|
||||
dma.ack = bus_or_dma == T_DMA && mem_ack;
|
||||
dma.rdata = mem_rdata;
|
||||
|
@ -54,4 +54,10 @@ module n64_soc (
|
||||
.bus(bus.at[sc64::ID_N64_BOOTLOADER].device)
|
||||
);
|
||||
|
||||
n64_cfg n64_cfg_inst (
|
||||
.sys(sys),
|
||||
.bus(bus.at[sc64::ID_N64_CFG].device),
|
||||
.cfg(cfg)
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
@ -1,5 +1,12 @@
|
||||
interface if_config ();
|
||||
|
||||
logic cpu_bootstrapped;
|
||||
logic cpu_busy;
|
||||
logic request;
|
||||
logic [7:0] command;
|
||||
logic [31:0] arg [0:1];
|
||||
logic [31:0] response;
|
||||
logic boot_write;
|
||||
logic sdram_switch;
|
||||
logic sdram_writable;
|
||||
logic dd_enabled;
|
||||
@ -9,17 +16,6 @@ interface if_config ();
|
||||
logic [25:0] dd_offset;
|
||||
logic [25:0] save_offset;
|
||||
|
||||
always_comb begin
|
||||
sdram_switch = 1'b1;
|
||||
sdram_writable = 1'b0;
|
||||
dd_enabled = 1'b1;
|
||||
sram_enabled = 1'b1;
|
||||
flashram_enabled = 1'b1;
|
||||
flashram_read_mode = 1'b1;
|
||||
dd_offset = 26'h3BE_0000;
|
||||
save_offset = 26'h3FE_0000;
|
||||
end
|
||||
|
||||
modport pi (
|
||||
input sdram_switch,
|
||||
input sdram_writable,
|
||||
@ -31,4 +27,35 @@ interface if_config ();
|
||||
input save_offset
|
||||
);
|
||||
|
||||
modport flashram (
|
||||
output flashram_read_mode
|
||||
);
|
||||
|
||||
modport n64 (
|
||||
input cpu_bootstrapped,
|
||||
input cpu_busy,
|
||||
output request,
|
||||
output command,
|
||||
output arg,
|
||||
input response,
|
||||
output boot_write
|
||||
);
|
||||
|
||||
modport cpu (
|
||||
output cpu_bootstrapped,
|
||||
output cpu_busy,
|
||||
input request,
|
||||
input command,
|
||||
input arg,
|
||||
output response,
|
||||
input boot_write,
|
||||
output sdram_switch,
|
||||
output sdram_writable,
|
||||
output dd_enabled,
|
||||
output sram_enabled,
|
||||
output flashram_enabled,
|
||||
output dd_offset,
|
||||
output save_offset
|
||||
);
|
||||
|
||||
endinterface
|
||||
|
@ -5,7 +5,7 @@ package sc64;
|
||||
ID_N64_BOOTLOADER,
|
||||
ID_N64_FLASHRAM,
|
||||
ID_N64_DDREGS,
|
||||
ID_N64_CPU,
|
||||
ID_N64_CFG,
|
||||
__ID_N64_END
|
||||
} e_n64_id;
|
||||
|
||||
@ -17,6 +17,7 @@ package sc64;
|
||||
ID_CPU_USB,
|
||||
ID_CPU_UART,
|
||||
ID_CPU_DMA,
|
||||
ID_CPU_CFG,
|
||||
__ID_CPU_END
|
||||
} e_cpu_id;
|
||||
|
||||
@ -30,6 +31,6 @@ package sc64;
|
||||
|
||||
parameter int UART_BAUD_RATE = 32'd1_000_000;
|
||||
|
||||
parameter bit DEBUG_ENABLED = 1'b1;
|
||||
parameter bit DEBUG_ENABLED = 1'b0;
|
||||
|
||||
endpackage
|
||||
|
10
fw/stp.stp
10
fw/stp.stp
File diff suppressed because one or more lines are too long
@ -24,7 +24,7 @@ BUILD_DIR = build
|
||||
SRC_DIRS = $(SOURCE_DIR) $(sort $(dir $(wildcard $(SOURCE_DIR)/*/.)))
|
||||
INC_DIRS = $(addprefix -I, . $(SRC_DIRS)) -I./libsc64/inc
|
||||
SRC_FILES = $(wildcard $(patsubst %, %/*.c, . $(SRC_DIRS)))
|
||||
IMG_FILES = $(wildcard $(patsubst %, %/*.png, . $(SRC_DIRS)))
|
||||
# IMG_FILES = $(wildcard $(patsubst %, %/*.png, . $(SRC_DIRS)))
|
||||
OBJ_FILES = $(addprefix $(BUILD_DIR)/, $(notdir $(IMG_FILES:.png=.o) $(SRC_FILES:.c=.o)))
|
||||
|
||||
VPATH = $(SRC_DIRS)
|
||||
@ -32,7 +32,8 @@ VPATH = $(SRC_DIRS)
|
||||
COMMONFLAGS = -march=vr4300 -mtune=vr4300
|
||||
ASFLAGS = $(COMMONFLAGS)
|
||||
CFLAGS = $(COMMONFLAGS) -std=gnu11 -Os -Wall -I$(ROOTDIR)/mips64-elf/include $(INC_DIRS) -ffunction-sections -fdata-sections -Wl,--gc-sections
|
||||
LINK_FLAGS = -L$(ROOTDIR)/mips64-elf/lib -ldragon -lc -lm -ldragonsys -Tn64.ld -L./libsc64/lib -lsc64_libdragon
|
||||
LINK_FLAGS = -L$(ROOTDIR)/mips64-elf/lib -ldragon -lc -lm -ldragonsys -Tn64.ld
|
||||
#-L./libsc64/lib -lsc64_libdragon
|
||||
N64_FLAGS = -l $(ROM_SIZE) -h $(HEADER_PATH)/$(HEADER_NAME) -o $(BUILD_DIR)/$(PROG_NAME).z64
|
||||
N64_FLAGS_PADDED = -l 1028k -h $(HEADER_PATH)/$(HEADER_NAME) -o $(BUILD_DIR)/$(PROG_NAME)_padded.z64
|
||||
|
||||
@ -55,11 +56,11 @@ $(BUILD_DIR)/$(PROG_NAME).elf: $(OBJ_FILES)
|
||||
$(BUILD_DIR)/%.o: %.c
|
||||
$(COMPILE.c) $(OUTPUT_OPTION) $<
|
||||
|
||||
$(BUILD_DIR)/%.sprite: $(IMG_FILES)
|
||||
$(MKSPRITE) 32 $< $@
|
||||
# $(BUILD_DIR)/%.sprite: $(IMG_FILES)
|
||||
# $(MKSPRITE) 32 $< $@
|
||||
|
||||
$(BUILD_DIR)/%.o: $(BUILD_DIR)/%.sprite
|
||||
$(OBJCOPY) -I binary -O elf32-bigmips -B mips:4000 --rename-section .data=.rodata $< $@
|
||||
# $(BUILD_DIR)/%.o: $(BUILD_DIR)/%.sprite
|
||||
# $(OBJCOPY) -I binary -O elf32-bigmips -B mips:4000 --rename-section .data=.rodata $< $@
|
||||
|
||||
make_output_dir:
|
||||
$(shell mkdir ./$(BUILD_DIR) 2> /dev/null)
|
||||
|
@ -1,3 +0,0 @@
|
||||
# SummerLoader64
|
||||
|
||||
A N64 bootloader for SummerCart64. This project is mainly based on work by **`jago85`** contained in [Brutzelkarte_Bootloader repository](https://github.com/jago85/Brutzelkarte_Bootloader) with some modifications that made code a little bit more readable.
|
@ -1,9 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
#--mount type=bind,src=`realpath "$(pwd)/../libsc64"`,target="/src/libsc64" \
|
||||
build_in_docker() {
|
||||
docker run -t \
|
||||
--mount type=bind,src=`realpath $(pwd)`,target="/src" \
|
||||
--mount type=bind,src=`realpath "$(pwd)/../libsc64"`,target="/src/libsc64" \
|
||||
$1 /bin/bash -c "cd /src && make clean && make -f $2 all"
|
||||
}
|
||||
|
||||
|
@ -1,12 +0,0 @@
|
||||
#ifndef ASSETS_H__
|
||||
#define ASSETS_H__
|
||||
|
||||
|
||||
#include <libdragon.h>
|
||||
|
||||
|
||||
extern sprite_t _binary_build_sc64_logo_sprite_start[];
|
||||
extern sprite_t _binary_build_sc64_logo_sprite_end[];
|
||||
|
||||
|
||||
#endif
|
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 5.9 KiB |
@ -23,7 +23,7 @@ static const struct crc32_to_cic_seed {
|
||||
static cart_header_t global_cart_header __attribute__((aligned(16)));
|
||||
|
||||
|
||||
cart_header_t *boot_load_cart_header(bool ddipl) {
|
||||
cart_header_t *boot_load_cart_header(void) {
|
||||
cart_header_t *cart_header_pointer = &global_cart_header;
|
||||
|
||||
platform_pi_dma_read(cart_header_pointer, CART_BASE, sizeof(cart_header_t));
|
||||
@ -73,10 +73,9 @@ tv_type_t boot_get_tv_type(cart_header_t *cart_header) {
|
||||
}
|
||||
}
|
||||
|
||||
void boot(cart_header_t *cart_header, uint16_t cic_seed, tv_type_t tv_type, uint32_t ddipl_override) {
|
||||
void boot(cart_header_t *cart_header, uint16_t cic_seed, tv_type_t tv_type) {
|
||||
uint32_t is_x105_boot = (cic_seed == crc32_to_cic_seed[5].cic_seed);
|
||||
uint32_t is_ddipl_boot = (
|
||||
ddipl_override ||
|
||||
(cic_seed == crc32_to_cic_seed[7].cic_seed) ||
|
||||
(cic_seed == crc32_to_cic_seed[8].cic_seed) ||
|
||||
(cic_seed == crc32_to_cic_seed[9].cic_seed)
|
||||
|
@ -54,10 +54,10 @@ typedef struct os_boot_config_s os_boot_config_t;
|
||||
#define BOOT_SEED_OS_VERSION(x) (((x) & 0x00000100) >> 8)
|
||||
|
||||
|
||||
cart_header_t *boot_load_cart_header(bool ddipl);
|
||||
cart_header_t *boot_load_cart_header(void);
|
||||
uint16_t boot_get_cic_seed(cart_header_t *cart_header);
|
||||
tv_type_t boot_get_tv_type(cart_header_t *cart_header);
|
||||
void boot(cart_header_t *cart_header, uint16_t cic_seed, tv_type_t tv_type, uint32_t ddipl_override);
|
||||
void boot(cart_header_t *cart_header, uint16_t cic_seed, tv_type_t tv_type);
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -1,346 +0,0 @@
|
||||
----------------------------------------------------------------------------
|
||||
Revision history of FatFs module
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
R0.00 (February 26, 2006)
|
||||
|
||||
Prototype.
|
||||
|
||||
|
||||
|
||||
R0.01 (April 29, 2006)
|
||||
|
||||
The first release.
|
||||
|
||||
|
||||
|
||||
R0.02 (June 01, 2006)
|
||||
|
||||
Added FAT12 support.
|
||||
Removed unbuffered mode.
|
||||
Fixed a problem on small (<32M) partition.
|
||||
|
||||
|
||||
|
||||
R0.02a (June 10, 2006)
|
||||
|
||||
Added a configuration option (_FS_MINIMUM).
|
||||
|
||||
|
||||
|
||||
R0.03 (September 22, 2006)
|
||||
|
||||
Added f_rename().
|
||||
Changed option _FS_MINIMUM to _FS_MINIMIZE.
|
||||
|
||||
|
||||
|
||||
R0.03a (December 11, 2006)
|
||||
|
||||
Improved cluster scan algorithm to write files fast.
|
||||
Fixed f_mkdir() creates incorrect directory on FAT32.
|
||||
|
||||
|
||||
|
||||
R0.04 (February 04, 2007)
|
||||
|
||||
Added f_mkfs().
|
||||
Supported multiple drive system.
|
||||
Changed some interfaces for multiple drive system.
|
||||
Changed f_mountdrv() to f_mount().
|
||||
|
||||
|
||||
|
||||
R0.04a (April 01, 2007)
|
||||
|
||||
Supported multiple partitions on a physical drive.
|
||||
Added a capability of extending file size to f_lseek().
|
||||
Added minimization level 3.
|
||||
Fixed an endian sensitive code in f_mkfs().
|
||||
|
||||
|
||||
|
||||
R0.04b (May 05, 2007)
|
||||
|
||||
Added a configuration option _USE_NTFLAG.
|
||||
Added FSINFO support.
|
||||
Fixed DBCS name can result FR_INVALID_NAME.
|
||||
Fixed short seek (<= csize) collapses the file object.
|
||||
|
||||
|
||||
|
||||
R0.05 (August 25, 2007)
|
||||
|
||||
Changed arguments of f_read(), f_write() and f_mkfs().
|
||||
Fixed f_mkfs() on FAT32 creates incorrect FSINFO.
|
||||
Fixed f_mkdir() on FAT32 creates incorrect directory.
|
||||
|
||||
|
||||
|
||||
R0.05a (February 03, 2008)
|
||||
|
||||
Added f_truncate() and f_utime().
|
||||
Fixed off by one error at FAT sub-type determination.
|
||||
Fixed btr in f_read() can be mistruncated.
|
||||
Fixed cached sector is not flushed when create and close without write.
|
||||
|
||||
|
||||
|
||||
R0.06 (April 01, 2008)
|
||||
|
||||
Added fputc(), fputs(), fprintf() and fgets().
|
||||
Improved performance of f_lseek() on moving to the same or following cluster.
|
||||
|
||||
|
||||
|
||||
R0.07 (April 01, 2009)
|
||||
|
||||
Merged Tiny-FatFs as a configuration option. (_FS_TINY)
|
||||
Added long file name feature. (_USE_LFN)
|
||||
Added multiple code page feature. (_CODE_PAGE)
|
||||
Added re-entrancy for multitask operation. (_FS_REENTRANT)
|
||||
Added auto cluster size selection to f_mkfs().
|
||||
Added rewind option to f_readdir().
|
||||
Changed result code of critical errors.
|
||||
Renamed string functions to avoid name collision.
|
||||
|
||||
|
||||
|
||||
R0.07a (April 14, 2009)
|
||||
|
||||
Septemberarated out OS dependent code on reentrant cfg.
|
||||
Added multiple sector size feature.
|
||||
|
||||
|
||||
|
||||
R0.07c (June 21, 2009)
|
||||
|
||||
Fixed f_unlink() can return FR_OK on error.
|
||||
Fixed wrong cache control in f_lseek().
|
||||
Added relative path feature.
|
||||
Added f_chdir() and f_chdrive().
|
||||
Added proper case conversion to extended character.
|
||||
|
||||
|
||||
|
||||
R0.07e (November 03, 2009)
|
||||
|
||||
Septemberarated out configuration options from ff.h to ffconf.h.
|
||||
Fixed f_unlink() fails to remove a sub-directory on _FS_RPATH.
|
||||
Fixed name matching error on the 13 character boundary.
|
||||
Added a configuration option, _LFN_UNICODE.
|
||||
Changed f_readdir() to return the SFN with always upper case on non-LFN cfg.
|
||||
|
||||
|
||||
|
||||
R0.08 (May 15, 2010)
|
||||
|
||||
Added a memory configuration option. (_USE_LFN = 3)
|
||||
Added file lock feature. (_FS_SHARE)
|
||||
Added fast seek feature. (_USE_FASTSEEK)
|
||||
Changed some types on the API, XCHAR->TCHAR.
|
||||
Changed .fname in the FILINFO structure on Unicode cfg.
|
||||
String functions support UTF-8 encoding files on Unicode cfg.
|
||||
|
||||
|
||||
|
||||
R0.08a (August 16, 2010)
|
||||
|
||||
Added f_getcwd(). (_FS_RPATH = 2)
|
||||
Added sector erase feature. (_USE_ERASE)
|
||||
Moved file lock semaphore table from fs object to the bss.
|
||||
Fixed f_mkfs() creates wrong FAT32 volume.
|
||||
|
||||
|
||||
|
||||
R0.08b (January 15, 2011)
|
||||
|
||||
Fast seek feature is also applied to f_read() and f_write().
|
||||
f_lseek() reports required table size on creating CLMP.
|
||||
Extended format syntax of f_printf().
|
||||
Ignores duplicated directory separators in given path name.
|
||||
|
||||
|
||||
|
||||
R0.09 (September 06, 2011)
|
||||
|
||||
f_mkfs() supports multiple partition to complete the multiple partition feature.
|
||||
Added f_fdisk().
|
||||
|
||||
|
||||
|
||||
R0.09a (August 27, 2012)
|
||||
|
||||
Changed f_open() and f_opendir() reject null object pointer to avoid crash.
|
||||
Changed option name _FS_SHARE to _FS_LOCK.
|
||||
Fixed assertion failure due to OS/2 EA on FAT12/16 volume.
|
||||
|
||||
|
||||
|
||||
R0.09b (January 24, 2013)
|
||||
|
||||
Added f_setlabel() and f_getlabel().
|
||||
|
||||
|
||||
|
||||
R0.10 (October 02, 2013)
|
||||
|
||||
Added selection of character encoding on the file. (_STRF_ENCODE)
|
||||
Added f_closedir().
|
||||
Added forced full FAT scan for f_getfree(). (_FS_NOFSINFO)
|
||||
Added forced mount feature with changes of f_mount().
|
||||
Improved behavior of volume auto detection.
|
||||
Improved write throughput of f_puts() and f_printf().
|
||||
Changed argument of f_chdrive(), f_mkfs(), disk_read() and disk_write().
|
||||
Fixed f_write() can be truncated when the file size is close to 4GB.
|
||||
Fixed f_open(), f_mkdir() and f_setlabel() can return incorrect value on error.
|
||||
|
||||
|
||||
|
||||
R0.10a (January 15, 2014)
|
||||
|
||||
Added arbitrary strings as drive number in the path name. (_STR_VOLUME_ID)
|
||||
Added a configuration option of minimum sector size. (_MIN_SS)
|
||||
2nd argument of f_rename() can have a drive number and it will be ignored.
|
||||
Fixed f_mount() with forced mount fails when drive number is >= 1. (appeared at R0.10)
|
||||
Fixed f_close() invalidates the file object without volume lock.
|
||||
Fixed f_closedir() returns but the volume lock is left acquired. (appeared at R0.10)
|
||||
Fixed creation of an entry with LFN fails on too many SFN collisions. (appeared at R0.07)
|
||||
|
||||
|
||||
|
||||
R0.10b (May 19, 2014)
|
||||
|
||||
Fixed a hard error in the disk I/O layer can collapse the directory entry.
|
||||
Fixed LFN entry is not deleted when delete/rename an object with lossy converted SFN. (appeared at R0.07)
|
||||
|
||||
|
||||
|
||||
R0.10c (November 09, 2014)
|
||||
|
||||
Added a configuration option for the platforms without RTC. (_FS_NORTC)
|
||||
Changed option name _USE_ERASE to _USE_TRIM.
|
||||
Fixed volume label created by Mac OS X cannot be retrieved with f_getlabel(). (appeared at R0.09b)
|
||||
Fixed a potential problem of FAT access that can appear on disk error.
|
||||
Fixed null pointer dereference on attempting to delete the root direcotry. (appeared at R0.08)
|
||||
|
||||
|
||||
|
||||
R0.11 (February 09, 2015)
|
||||
|
||||
Added f_findfirst(), f_findnext() and f_findclose(). (_USE_FIND)
|
||||
Fixed f_unlink() does not remove cluster chain of the file. (appeared at R0.10c)
|
||||
Fixed _FS_NORTC option does not work properly. (appeared at R0.10c)
|
||||
|
||||
|
||||
|
||||
R0.11a (September 05, 2015)
|
||||
|
||||
Fixed wrong media change can lead a deadlock at thread-safe configuration.
|
||||
Added code page 771, 860, 861, 863, 864, 865 and 869. (_CODE_PAGE)
|
||||
Removed some code pages actually not exist on the standard systems. (_CODE_PAGE)
|
||||
Fixed errors in the case conversion teble of code page 437 and 850 (ff.c).
|
||||
Fixed errors in the case conversion teble of Unicode (cc*.c).
|
||||
|
||||
|
||||
|
||||
R0.12 (April 12, 2016)
|
||||
|
||||
Added support for exFAT file system. (_FS_EXFAT)
|
||||
Added f_expand(). (_USE_EXPAND)
|
||||
Changed some members in FINFO structure and behavior of f_readdir().
|
||||
Added an option _USE_CHMOD.
|
||||
Removed an option _WORD_ACCESS.
|
||||
Fixed errors in the case conversion table of Unicode (cc*.c).
|
||||
|
||||
|
||||
|
||||
R0.12a (July 10, 2016)
|
||||
|
||||
Added support for creating exFAT volume with some changes of f_mkfs().
|
||||
Added a file open method FA_OPEN_APPEND. An f_lseek() following f_open() is no longer needed.
|
||||
f_forward() is available regardless of _FS_TINY.
|
||||
Fixed f_mkfs() creates wrong volume. (appeared at R0.12)
|
||||
Fixed wrong memory read in create_name(). (appeared at R0.12)
|
||||
Fixed compilation fails at some configurations, _USE_FASTSEEK and _USE_FORWARD.
|
||||
|
||||
|
||||
|
||||
R0.12b (September 04, 2016)
|
||||
|
||||
Made f_rename() be able to rename objects with the same name but case.
|
||||
Fixed an error in the case conversion teble of code page 866. (ff.c)
|
||||
Fixed writing data is truncated at the file offset 4GiB on the exFAT volume. (appeared at R0.12)
|
||||
Fixed creating a file in the root directory of exFAT volume can fail. (appeared at R0.12)
|
||||
Fixed f_mkfs() creating exFAT volume with too small cluster size can collapse unallocated memory. (appeared at R0.12)
|
||||
Fixed wrong object name can be returned when read directory at Unicode cfg. (appeared at R0.12)
|
||||
Fixed large file allocation/removing on the exFAT volume collapses allocation bitmap. (appeared at R0.12)
|
||||
Fixed some internal errors in f_expand() and f_lseek(). (appeared at R0.12)
|
||||
|
||||
|
||||
|
||||
R0.12c (March 04, 2017)
|
||||
|
||||
Improved write throughput at the fragmented file on the exFAT volume.
|
||||
Made memory usage for exFAT be able to be reduced as decreasing _MAX_LFN.
|
||||
Fixed successive f_getfree() can return wrong count on the FAT12/16 volume. (appeared at R0.12)
|
||||
Fixed configuration option _VOLUMES cannot be set 10. (appeared at R0.10c)
|
||||
|
||||
|
||||
|
||||
R0.13 (May 21, 2017)
|
||||
|
||||
Changed heading character of configuration keywords "_" to "FF_".
|
||||
Removed ASCII-only configuration, FF_CODE_PAGE = 1. Use FF_CODE_PAGE = 437 instead.
|
||||
Added f_setcp(), run-time code page configuration. (FF_CODE_PAGE = 0)
|
||||
Improved cluster allocation time on stretch a deep buried cluster chain.
|
||||
Improved processing time of f_mkdir() with large cluster size by using FF_USE_LFN = 3.
|
||||
Improved NoFatChain flag of the fragmented file to be set after it is truncated and got contiguous.
|
||||
Fixed archive attribute is left not set when a file on the exFAT volume is renamed. (appeared at R0.12)
|
||||
Fixed exFAT FAT entry can be collapsed when write or lseek operation to the existing file is done. (appeared at R0.12c)
|
||||
Fixed creating a file can fail when a new cluster allocation to the exFAT directory occures. (appeared at R0.12c)
|
||||
|
||||
|
||||
|
||||
R0.13a (October 14, 2017)
|
||||
|
||||
Added support for UTF-8 encoding on the API. (FF_LFN_UNICODE = 2)
|
||||
Added options for file name output buffer. (FF_LFN_BUF, FF_SFN_BUF).
|
||||
Added dynamic memory allocation option for working buffer of f_mkfs() and f_fdisk().
|
||||
Fixed f_fdisk() and f_mkfs() create the partition table with wrong CHS parameters. (appeared at R0.09)
|
||||
Fixed f_unlink() can cause lost clusters at fragmented file on the exFAT volume. (appeared at R0.12c)
|
||||
Fixed f_setlabel() rejects some valid characters for exFAT volume. (appeared at R0.12)
|
||||
|
||||
|
||||
|
||||
R0.13b (April 07, 2018)
|
||||
|
||||
Added support for UTF-32 encoding on the API. (FF_LFN_UNICODE = 3)
|
||||
Added support for Unix style volume ID. (FF_STR_VOLUME_ID = 2)
|
||||
Fixed accesing any object on the exFAT root directory beyond the cluster boundary can fail. (appeared at R0.12c)
|
||||
Fixed f_setlabel() does not reject some invalid characters. (appeared at R0.09b)
|
||||
|
||||
|
||||
|
||||
R0.13c (October 14, 2018)
|
||||
Supported stdint.h for C99 and later. (integer.h was included in ff.h)
|
||||
Fixed reading a directory gets infinite loop when the last directory entry is not empty. (appeared at R0.12)
|
||||
Fixed creating a sub-directory in the fragmented sub-directory on the exFAT volume collapses FAT chain of the parent directory. (appeared at R0.12)
|
||||
Fixed f_getcwd() cause output buffer overrun when the buffer has a valid drive number. (appeared at R0.13b)
|
||||
|
||||
|
||||
|
||||
R0.14 (October 14, 2019)
|
||||
Added support for 64-bit LBA and GUID partition table (FF_LBA64 = 1)
|
||||
Changed some API functions, f_mkfs() and f_fdisk().
|
||||
Fixed f_open() function cannot find the file with file name in length of FF_MAX_LFN characters.
|
||||
Fixed f_readdir() function cannot retrieve long file names in length of FF_MAX_LFN - 1 characters.
|
||||
Fixed f_readdir() function returns file names with wrong case conversion. (appeared at R0.12)
|
||||
Fixed f_mkfs() function can fail to create exFAT volume in the second partition. (appeared at R0.12)
|
||||
|
||||
|
||||
R0.14a (December 5, 2020)
|
||||
Limited number of recursive calls in f_findnext().
|
||||
Fixed old floppy disks formatted with MS-DOS 2.x and 3.x cannot be mounted.
|
||||
Fixed some compiler warnings.
|
||||
|
@ -1,21 +0,0 @@
|
||||
FatFs Module Source Files R0.14a
|
||||
|
||||
|
||||
FILES
|
||||
|
||||
00readme.txt This file.
|
||||
00history.txt Revision history.
|
||||
ff.c FatFs module.
|
||||
ffconf.h Configuration file of FatFs module.
|
||||
ff.h Common include file for FatFs and application module.
|
||||
diskio.h Common include file for FatFs and disk I/O module.
|
||||
diskio.c An example of glue function to attach existing disk I/O module to FatFs.
|
||||
ffunicode.c Optional Unicode utility functions.
|
||||
ffsystem.c An example of optional O/S related functions.
|
||||
|
||||
|
||||
Low level disk I/O module is not included in this archive because the FatFs
|
||||
module is only a generic file system layer and it does not depend on any specific
|
||||
storage device. You need to provide a low level disk I/O module written to
|
||||
control the storage device that attached to the target system.
|
||||
|
@ -1,93 +0,0 @@
|
||||
#include "ff.h"
|
||||
#include "diskio.h"
|
||||
|
||||
#include "sc64_sd.h"
|
||||
|
||||
|
||||
DSTATUS disk_status(BYTE pdrv) {
|
||||
if (pdrv > 0) {
|
||||
return STA_NOINIT;
|
||||
}
|
||||
|
||||
return sc64_sd_status_get() ? 0 : STA_NOINIT;
|
||||
}
|
||||
|
||||
DSTATUS disk_initialize(BYTE pdrv) {
|
||||
if (pdrv > 0) {
|
||||
return STA_NOINIT;
|
||||
}
|
||||
|
||||
if (!sc64_sd_status_get()) {
|
||||
if (sc64_sd_init()) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return STA_NOINIT;
|
||||
}
|
||||
|
||||
DRESULT disk_read(BYTE pdrv, BYTE *buff, LBA_t sector, UINT count) {
|
||||
sc64_sd_err_t error;
|
||||
|
||||
if (pdrv > 0) {
|
||||
return RES_PARERR;
|
||||
}
|
||||
|
||||
error = sc64_sd_sectors_read(sector, count, buff);
|
||||
|
||||
if (error != E_OK) {
|
||||
switch (error) {
|
||||
case E_NO_INIT:
|
||||
return RES_NOTRDY;
|
||||
case E_PAR_ERROR:
|
||||
return RES_PARERR;
|
||||
default:
|
||||
return RES_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return RES_OK;
|
||||
}
|
||||
|
||||
#if !FF_FS_READONLY
|
||||
|
||||
DRESULT disk_write(BYTE pdrv, const BYTE* buff, LBA_t sector, UINT count) {
|
||||
sc64_sd_err_t error;
|
||||
|
||||
if (pdrv > 0) {
|
||||
return RES_PARERR;
|
||||
}
|
||||
|
||||
error = sc64_sd_sectors_write(sector, count, (uint8_t *) buff);
|
||||
|
||||
if (error != E_OK) {
|
||||
switch (error) {
|
||||
case E_NO_INIT:
|
||||
return RES_NOTRDY;
|
||||
case E_PAR_ERROR:
|
||||
return RES_PARERR;
|
||||
default:
|
||||
return RES_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return RES_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void *buff) {
|
||||
switch (cmd) {
|
||||
case CTRL_SYNC: {
|
||||
sc64_sd_err_t error = sc64_sd_dat_busy_wait();
|
||||
if (error != E_OK) {
|
||||
return RES_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return RES_OK;
|
||||
}
|
@ -1,77 +0,0 @@
|
||||
/*-----------------------------------------------------------------------/
|
||||
/ Low level disk interface modlue include file (C)ChaN, 2019 /
|
||||
/-----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _DISKIO_DEFINED
|
||||
#define _DISKIO_DEFINED
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Status of Disk Functions */
|
||||
typedef BYTE DSTATUS;
|
||||
|
||||
/* Results of Disk Functions */
|
||||
typedef enum {
|
||||
RES_OK = 0, /* 0: Successful */
|
||||
RES_ERROR, /* 1: R/W Error */
|
||||
RES_WRPRT, /* 2: Write Protected */
|
||||
RES_NOTRDY, /* 3: Not Ready */
|
||||
RES_PARERR /* 4: Invalid Parameter */
|
||||
} DRESULT;
|
||||
|
||||
|
||||
/*---------------------------------------*/
|
||||
/* Prototypes for disk control functions */
|
||||
|
||||
|
||||
DSTATUS disk_initialize (BYTE pdrv);
|
||||
DSTATUS disk_status (BYTE pdrv);
|
||||
DRESULT disk_read (BYTE pdrv, BYTE* buff, LBA_t sector, UINT count);
|
||||
DRESULT disk_write (BYTE pdrv, const BYTE* buff, LBA_t sector, UINT count);
|
||||
DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);
|
||||
|
||||
|
||||
/* Disk Status Bits (DSTATUS) */
|
||||
|
||||
#define STA_NOINIT 0x01 /* Drive not initialized */
|
||||
#define STA_NODISK 0x02 /* No medium in the drive */
|
||||
#define STA_PROTECT 0x04 /* Write protected */
|
||||
|
||||
|
||||
/* Command code for disk_ioctrl fucntion */
|
||||
|
||||
/* Generic command (Used by FatFs) */
|
||||
#define CTRL_SYNC 0 /* Complete pending write process (needed at FF_FS_READONLY == 0) */
|
||||
#define GET_SECTOR_COUNT 1 /* Get media size (needed at FF_USE_MKFS == 1) */
|
||||
#define GET_SECTOR_SIZE 2 /* Get sector size (needed at FF_MAX_SS != FF_MIN_SS) */
|
||||
#define GET_BLOCK_SIZE 3 /* Get erase block size (needed at FF_USE_MKFS == 1) */
|
||||
#define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at FF_USE_TRIM == 1) */
|
||||
|
||||
/* Generic command (Not used by FatFs) */
|
||||
#define CTRL_POWER 5 /* Get/Set power status */
|
||||
#define CTRL_LOCK 6 /* Lock/Unlock media removal */
|
||||
#define CTRL_EJECT 7 /* Eject media */
|
||||
#define CTRL_FORMAT 8 /* Create physical format on the media */
|
||||
|
||||
/* MMC/SDC specific ioctl command */
|
||||
#define MMC_GET_TYPE 10 /* Get card type */
|
||||
#define MMC_GET_CSD 11 /* Get CSD */
|
||||
#define MMC_GET_CID 12 /* Get CID */
|
||||
#define MMC_GET_OCR 13 /* Get OCR */
|
||||
#define MMC_GET_SDSTAT 14 /* Get SD status */
|
||||
#define ISDIO_READ 55 /* Read data form SD iSDIO register */
|
||||
#define ISDIO_WRITE 56 /* Write data to SD iSDIO register */
|
||||
#define ISDIO_MRITE 57 /* Masked write data to SD iSDIO register */
|
||||
|
||||
/* ATA/CF specific ioctl command */
|
||||
#define ATA_GET_REV 20 /* Get F/W revision */
|
||||
#define ATA_GET_MODEL 21 /* Get model name */
|
||||
#define ATA_GET_SN 22 /* Get serial number */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
@ -1,424 +0,0 @@
|
||||
/*----------------------------------------------------------------------------/
|
||||
/ FatFs - Generic FAT Filesystem module R0.14a /
|
||||
/-----------------------------------------------------------------------------/
|
||||
/
|
||||
/ Copyright (C) 2020, ChaN, all right reserved.
|
||||
/
|
||||
/ FatFs module is an open source software. Redistribution and use of FatFs in
|
||||
/ source and binary forms, with or without modification, are permitted provided
|
||||
/ that the following condition is met:
|
||||
|
||||
/ 1. Redistributions of source code must retain the above copyright notice,
|
||||
/ this condition and the following disclaimer.
|
||||
/
|
||||
/ This software is provided by the copyright holder and contributors "AS IS"
|
||||
/ and any warranties related to this software are DISCLAIMED.
|
||||
/ The copyright owner or contributors be NOT LIABLE for any damages caused
|
||||
/ by use of this software.
|
||||
/
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#ifndef FF_DEFINED
|
||||
#define FF_DEFINED 80196 /* Revision ID */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "ffconf.h" /* FatFs configuration options */
|
||||
|
||||
#if FF_DEFINED != FFCONF_DEF
|
||||
#error Wrong configuration file (ffconf.h).
|
||||
#endif
|
||||
|
||||
|
||||
/* Integer types used for FatFs API */
|
||||
|
||||
#if defined(_WIN32) /* Main development platform */
|
||||
#define FF_INTDEF 2
|
||||
#include <windows.h>
|
||||
typedef unsigned __int64 QWORD;
|
||||
#elif (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__cplusplus) /* C99 or later */
|
||||
#define FF_INTDEF 2
|
||||
#include <stdint.h>
|
||||
typedef unsigned int UINT; /* int must be 16-bit or 32-bit */
|
||||
typedef unsigned char BYTE; /* char must be 8-bit */
|
||||
typedef uint16_t WORD; /* 16-bit unsigned integer */
|
||||
typedef uint32_t DWORD; /* 32-bit unsigned integer */
|
||||
typedef uint64_t QWORD; /* 64-bit unsigned integer */
|
||||
typedef WORD WCHAR; /* UTF-16 character type */
|
||||
#else /* Earlier than C99 */
|
||||
#define FF_INTDEF 1
|
||||
typedef unsigned int UINT; /* int must be 16-bit or 32-bit */
|
||||
typedef unsigned char BYTE; /* char must be 8-bit */
|
||||
typedef unsigned short WORD; /* 16-bit unsigned integer */
|
||||
typedef unsigned long DWORD; /* 32-bit unsigned integer */
|
||||
typedef WORD WCHAR; /* UTF-16 character type */
|
||||
#endif
|
||||
|
||||
|
||||
/* Definitions of volume management */
|
||||
|
||||
#if FF_MULTI_PARTITION /* Multiple partition configuration */
|
||||
typedef struct {
|
||||
BYTE pd; /* Physical drive number */
|
||||
BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */
|
||||
} PARTITION;
|
||||
extern PARTITION VolToPart[]; /* Volume - Partition mapping table */
|
||||
#endif
|
||||
|
||||
#if FF_STR_VOLUME_ID
|
||||
#ifndef FF_VOLUME_STRS
|
||||
extern const char* VolumeStr[FF_VOLUMES]; /* User defied volume ID */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Type of path name strings on FatFs API */
|
||||
|
||||
#ifndef _INC_TCHAR
|
||||
#define _INC_TCHAR
|
||||
|
||||
#if FF_USE_LFN && FF_LFN_UNICODE == 1 /* Unicode in UTF-16 encoding */
|
||||
typedef WCHAR TCHAR;
|
||||
#define _T(x) L ## x
|
||||
#define _TEXT(x) L ## x
|
||||
#elif FF_USE_LFN && FF_LFN_UNICODE == 2 /* Unicode in UTF-8 encoding */
|
||||
typedef char TCHAR;
|
||||
#define _T(x) u8 ## x
|
||||
#define _TEXT(x) u8 ## x
|
||||
#elif FF_USE_LFN && FF_LFN_UNICODE == 3 /* Unicode in UTF-32 encoding */
|
||||
typedef DWORD TCHAR;
|
||||
#define _T(x) U ## x
|
||||
#define _TEXT(x) U ## x
|
||||
#elif FF_USE_LFN && (FF_LFN_UNICODE < 0 || FF_LFN_UNICODE > 3)
|
||||
#error Wrong FF_LFN_UNICODE setting
|
||||
#else /* ANSI/OEM code in SBCS/DBCS */
|
||||
typedef char TCHAR;
|
||||
#define _T(x) x
|
||||
#define _TEXT(x) x
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Type of file size and LBA variables */
|
||||
|
||||
#if FF_FS_EXFAT
|
||||
#if FF_INTDEF != 2
|
||||
#error exFAT feature wants C99 or later
|
||||
#endif
|
||||
typedef QWORD FSIZE_t;
|
||||
#if FF_LBA64
|
||||
typedef QWORD LBA_t;
|
||||
#else
|
||||
typedef DWORD LBA_t;
|
||||
#endif
|
||||
#else
|
||||
#if FF_LBA64
|
||||
#error exFAT needs to be enabled when enable 64-bit LBA
|
||||
#endif
|
||||
typedef DWORD FSIZE_t;
|
||||
typedef DWORD LBA_t;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Filesystem object structure (FATFS) */
|
||||
|
||||
typedef struct {
|
||||
BYTE fs_type; /* Filesystem type (0:not mounted) */
|
||||
BYTE pdrv; /* Associated physical drive */
|
||||
BYTE n_fats; /* Number of FATs (1 or 2) */
|
||||
BYTE wflag; /* win[] flag (b0:dirty) */
|
||||
BYTE fsi_flag; /* FSINFO flags (b7:disabled, b0:dirty) */
|
||||
WORD id; /* Volume mount ID */
|
||||
WORD n_rootdir; /* Number of root directory entries (FAT12/16) */
|
||||
WORD csize; /* Cluster size [sectors] */
|
||||
#if FF_MAX_SS != FF_MIN_SS
|
||||
WORD ssize; /* Sector size (512, 1024, 2048 or 4096) */
|
||||
#endif
|
||||
#if FF_USE_LFN
|
||||
WCHAR* lfnbuf; /* LFN working buffer */
|
||||
#endif
|
||||
#if FF_FS_EXFAT
|
||||
BYTE* dirbuf; /* Directory entry block scratchpad buffer for exFAT */
|
||||
#endif
|
||||
#if FF_FS_REENTRANT
|
||||
FF_SYNC_t sobj; /* Identifier of sync object */
|
||||
#endif
|
||||
#if !FF_FS_READONLY
|
||||
DWORD last_clst; /* Last allocated cluster */
|
||||
DWORD free_clst; /* Number of free clusters */
|
||||
#endif
|
||||
#if FF_FS_RPATH
|
||||
DWORD cdir; /* Current directory start cluster (0:root) */
|
||||
#if FF_FS_EXFAT
|
||||
DWORD cdc_scl; /* Containing directory start cluster (invalid when cdir is 0) */
|
||||
DWORD cdc_size; /* b31-b8:Size of containing directory, b7-b0: Chain status */
|
||||
DWORD cdc_ofs; /* Offset in the containing directory (invalid when cdir is 0) */
|
||||
#endif
|
||||
#endif
|
||||
DWORD n_fatent; /* Number of FAT entries (number of clusters + 2) */
|
||||
DWORD fsize; /* Size of an FAT [sectors] */
|
||||
LBA_t volbase; /* Volume base sector */
|
||||
LBA_t fatbase; /* FAT base sector */
|
||||
LBA_t dirbase; /* Root directory base sector/cluster */
|
||||
LBA_t database; /* Data base sector */
|
||||
#if FF_FS_EXFAT
|
||||
LBA_t bitbase; /* Allocation bitmap base sector */
|
||||
#endif
|
||||
LBA_t winsect; /* Current sector appearing in the win[] */
|
||||
BYTE win[FF_MAX_SS] __attribute__((aligned(16))); /* Disk access window for Directory, FAT (and file data at tiny cfg) */
|
||||
} FATFS;
|
||||
|
||||
|
||||
|
||||
/* Object ID and allocation information (FFOBJID) */
|
||||
|
||||
typedef struct {
|
||||
FATFS* fs; /* Pointer to the hosting volume of this object */
|
||||
WORD id; /* Hosting volume mount ID */
|
||||
BYTE attr; /* Object attribute */
|
||||
BYTE stat; /* Object chain status (b1-0: =0:not contiguous, =2:contiguous, =3:fragmented in this session, b2:sub-directory stretched) */
|
||||
DWORD sclust; /* Object data start cluster (0:no cluster or root directory) */
|
||||
FSIZE_t objsize; /* Object size (valid when sclust != 0) */
|
||||
#if FF_FS_EXFAT
|
||||
DWORD n_cont; /* Size of first fragment - 1 (valid when stat == 3) */
|
||||
DWORD n_frag; /* Size of last fragment needs to be written to FAT (valid when not zero) */
|
||||
DWORD c_scl; /* Containing directory start cluster (valid when sclust != 0) */
|
||||
DWORD c_size; /* b31-b8:Size of containing directory, b7-b0: Chain status (valid when c_scl != 0) */
|
||||
DWORD c_ofs; /* Offset in the containing directory (valid when file object and sclust != 0) */
|
||||
#endif
|
||||
#if FF_FS_LOCK
|
||||
UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */
|
||||
#endif
|
||||
} FFOBJID;
|
||||
|
||||
|
||||
|
||||
/* File object structure (FIL) */
|
||||
|
||||
typedef struct {
|
||||
FFOBJID obj; /* Object identifier (must be the 1st member to detect invalid object pointer) */
|
||||
BYTE flag; /* File status flags */
|
||||
BYTE err; /* Abort flag (error code) */
|
||||
FSIZE_t fptr; /* File read/write pointer (Zeroed on file open) */
|
||||
DWORD clust; /* Current cluster of fpter (invalid when fptr is 0) */
|
||||
LBA_t sect; /* Sector number appearing in buf[] (0:invalid) */
|
||||
#if !FF_FS_READONLY
|
||||
LBA_t dir_sect; /* Sector number containing the directory entry (not used at exFAT) */
|
||||
BYTE* dir_ptr; /* Pointer to the directory entry in the win[] (not used at exFAT) */
|
||||
#endif
|
||||
#if FF_USE_FASTSEEK
|
||||
DWORD* cltbl; /* Pointer to the cluster link map table (nulled on open, set by application) */
|
||||
#endif
|
||||
#if !FF_FS_TINY
|
||||
BYTE buf[FF_MAX_SS] __attribute__((aligned(16))); /* File private data read/write window */
|
||||
#endif
|
||||
} FIL;
|
||||
|
||||
|
||||
|
||||
/* Directory object structure (DIR) */
|
||||
|
||||
typedef struct {
|
||||
FFOBJID obj; /* Object identifier */
|
||||
DWORD dptr; /* Current read/write offset */
|
||||
DWORD clust; /* Current cluster */
|
||||
LBA_t sect; /* Current sector (0:Read operation has terminated) */
|
||||
BYTE* dir; /* Pointer to the directory item in the win[] */
|
||||
BYTE fn[12]; /* SFN (in/out) {body[8],ext[3],status[1]} */
|
||||
#if FF_USE_LFN
|
||||
DWORD blk_ofs; /* Offset of current entry block being processed (0xFFFFFFFF:Invalid) */
|
||||
#endif
|
||||
#if FF_USE_FIND
|
||||
const TCHAR* pat; /* Pointer to the name matching pattern */
|
||||
#endif
|
||||
} DIR;
|
||||
|
||||
|
||||
|
||||
/* File information structure (FILINFO) */
|
||||
|
||||
typedef struct {
|
||||
FSIZE_t fsize; /* File size */
|
||||
WORD fdate; /* Modified date */
|
||||
WORD ftime; /* Modified time */
|
||||
BYTE fattrib; /* File attribute */
|
||||
#if FF_USE_LFN
|
||||
TCHAR altname[FF_SFN_BUF + 1];/* Altenative file name */
|
||||
TCHAR fname[FF_LFN_BUF + 1]; /* Primary file name */
|
||||
#else
|
||||
TCHAR fname[12 + 1]; /* File name */
|
||||
#endif
|
||||
} FILINFO;
|
||||
|
||||
|
||||
|
||||
/* Format parameter structure (MKFS_PARM) */
|
||||
|
||||
typedef struct {
|
||||
BYTE fmt; /* Format option (FM_FAT, FM_FAT32, FM_EXFAT and FM_SFD) */
|
||||
BYTE n_fat; /* Number of FATs */
|
||||
UINT align; /* Data area alignment (sector) */
|
||||
UINT n_root; /* Number of root directory entries */
|
||||
DWORD au_size; /* Cluster size (byte) */
|
||||
} MKFS_PARM;
|
||||
|
||||
|
||||
|
||||
/* File function return code (FRESULT) */
|
||||
|
||||
typedef enum {
|
||||
FR_OK = 0, /* (0) Succeeded */
|
||||
FR_DISK_ERR, /* (1) A hard error occurred in the low level disk I/O layer */
|
||||
FR_INT_ERR, /* (2) Assertion failed */
|
||||
FR_NOT_READY, /* (3) The physical drive cannot work */
|
||||
FR_NO_FILE, /* (4) Could not find the file */
|
||||
FR_NO_PATH, /* (5) Could not find the path */
|
||||
FR_INVALID_NAME, /* (6) The path name format is invalid */
|
||||
FR_DENIED, /* (7) Access denied due to prohibited access or directory full */
|
||||
FR_EXIST, /* (8) Access denied due to prohibited access */
|
||||
FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */
|
||||
FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */
|
||||
FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */
|
||||
FR_NOT_ENABLED, /* (12) The volume has no work area */
|
||||
FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */
|
||||
FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any problem */
|
||||
FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */
|
||||
FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */
|
||||
FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */
|
||||
FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > FF_FS_LOCK */
|
||||
FR_INVALID_PARAMETER /* (19) Given parameter is invalid */
|
||||
} FRESULT;
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* FatFs module application interface */
|
||||
|
||||
FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a file */
|
||||
FRESULT f_close (FIL* fp); /* Close an open file object */
|
||||
FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br); /* Read data from the file */
|
||||
FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to the file */
|
||||
FRESULT f_lseek (FIL* fp, FSIZE_t ofs); /* Move file pointer of the file object */
|
||||
FRESULT f_truncate (FIL* fp); /* Truncate the file */
|
||||
FRESULT f_sync (FIL* fp); /* Flush cached data of the writing file */
|
||||
FRESULT f_opendir (DIR* dp, const TCHAR* path); /* Open a directory */
|
||||
FRESULT f_closedir (DIR* dp); /* Close an open directory */
|
||||
FRESULT f_readdir (DIR* dp, FILINFO* fno); /* Read a directory item */
|
||||
FRESULT f_findfirst (DIR* dp, FILINFO* fno, const TCHAR* path, const TCHAR* pattern); /* Find first file */
|
||||
FRESULT f_findnext (DIR* dp, FILINFO* fno); /* Find next file */
|
||||
FRESULT f_mkdir (const TCHAR* path); /* Create a sub directory */
|
||||
FRESULT f_unlink (const TCHAR* path); /* Delete an existing file or directory */
|
||||
FRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new); /* Rename/Move a file or directory */
|
||||
FRESULT f_stat (const TCHAR* path, FILINFO* fno); /* Get file status */
|
||||
FRESULT f_chmod (const TCHAR* path, BYTE attr, BYTE mask); /* Change attribute of a file/dir */
|
||||
FRESULT f_utime (const TCHAR* path, const FILINFO* fno); /* Change timestamp of a file/dir */
|
||||
FRESULT f_chdir (const TCHAR* path); /* Change current directory */
|
||||
FRESULT f_chdrive (const TCHAR* path); /* Change current drive */
|
||||
FRESULT f_getcwd (TCHAR* buff, UINT len); /* Get current directory */
|
||||
FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs); /* Get number of free clusters on the drive */
|
||||
FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn); /* Get volume label */
|
||||
FRESULT f_setlabel (const TCHAR* label); /* Set volume label */
|
||||
FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */
|
||||
FRESULT f_expand (FIL* fp, FSIZE_t fsz, BYTE opt); /* Allocate a contiguous block to the file */
|
||||
FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */
|
||||
FRESULT f_mkfs (const TCHAR* path, const MKFS_PARM* opt, void* work, UINT len); /* Create a FAT volume */
|
||||
FRESULT f_fdisk (BYTE pdrv, const LBA_t ptbl[], void* work); /* Divide a physical drive into some partitions */
|
||||
FRESULT f_setcp (WORD cp); /* Set current code page */
|
||||
int f_putc (TCHAR c, FIL* fp); /* Put a character to the file */
|
||||
int f_puts (const TCHAR* str, FIL* cp); /* Put a string to the file */
|
||||
int f_printf (FIL* fp, const TCHAR* str, ...); /* Put a formatted string to the file */
|
||||
TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the file */
|
||||
|
||||
#define f_eof(fp) ((int)((fp)->fptr == (fp)->obj.objsize))
|
||||
#define f_error(fp) ((fp)->err)
|
||||
#define f_tell(fp) ((fp)->fptr)
|
||||
#define f_size(fp) ((fp)->obj.objsize)
|
||||
#define f_rewind(fp) f_lseek((fp), 0)
|
||||
#define f_rewinddir(dp) f_readdir((dp), 0)
|
||||
#define f_rmdir(path) f_unlink(path)
|
||||
#define f_unmount(path) f_mount(0, path, 0)
|
||||
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* Additional user defined functions */
|
||||
|
||||
/* RTC function */
|
||||
#if !FF_FS_READONLY && !FF_FS_NORTC
|
||||
DWORD get_fattime (void);
|
||||
#endif
|
||||
|
||||
/* LFN support functions */
|
||||
#if FF_USE_LFN >= 1 /* Code conversion (defined in unicode.c) */
|
||||
WCHAR ff_oem2uni (WCHAR oem, WORD cp); /* OEM code to Unicode conversion */
|
||||
WCHAR ff_uni2oem (DWORD uni, WORD cp); /* Unicode to OEM code conversion */
|
||||
DWORD ff_wtoupper (DWORD uni); /* Unicode upper-case conversion */
|
||||
#endif
|
||||
#if FF_USE_LFN == 3 /* Dynamic memory allocation */
|
||||
void* ff_memalloc (UINT msize); /* Allocate memory block */
|
||||
void ff_memfree (void* mblock); /* Free memory block */
|
||||
#endif
|
||||
|
||||
/* Sync functions */
|
||||
#if FF_FS_REENTRANT
|
||||
int ff_cre_syncobj (BYTE vol, FF_SYNC_t* sobj); /* Create a sync object */
|
||||
int ff_req_grant (FF_SYNC_t sobj); /* Lock sync object */
|
||||
void ff_rel_grant (FF_SYNC_t sobj); /* Unlock sync object */
|
||||
int ff_del_syncobj (FF_SYNC_t sobj); /* Delete a sync object */
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* Flags and offset address */
|
||||
|
||||
|
||||
/* File access mode and open method flags (3rd argument of f_open) */
|
||||
#define FA_READ 0x01
|
||||
#define FA_WRITE 0x02
|
||||
#define FA_OPEN_EXISTING 0x00
|
||||
#define FA_CREATE_NEW 0x04
|
||||
#define FA_CREATE_ALWAYS 0x08
|
||||
#define FA_OPEN_ALWAYS 0x10
|
||||
#define FA_OPEN_APPEND 0x30
|
||||
|
||||
/* Fast seek controls (2nd argument of f_lseek) */
|
||||
#define CREATE_LINKMAP ((FSIZE_t)0 - 1)
|
||||
|
||||
/* Format options (2nd argument of f_mkfs) */
|
||||
#define FM_FAT 0x01
|
||||
#define FM_FAT32 0x02
|
||||
#define FM_EXFAT 0x04
|
||||
#define FM_ANY 0x07
|
||||
#define FM_SFD 0x08
|
||||
|
||||
/* Filesystem type (FATFS.fs_type) */
|
||||
#define FS_FAT12 1
|
||||
#define FS_FAT16 2
|
||||
#define FS_FAT32 3
|
||||
#define FS_EXFAT 4
|
||||
|
||||
/* File attribute bits for directory entry (FILINFO.fattrib) */
|
||||
#define AM_RDO 0x01 /* Read only */
|
||||
#define AM_HID 0x02 /* Hidden */
|
||||
#define AM_SYS 0x04 /* System */
|
||||
#define AM_DIR 0x10 /* Directory */
|
||||
#define AM_ARC 0x20 /* Archive */
|
||||
|
||||
#include "ff_extensions.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* FF_DEFINED */
|
@ -1,82 +0,0 @@
|
||||
FRESULT fe_load(const TCHAR *path, UINT max_length, transfer_function_t transfer_function) {
|
||||
FRESULT fresult;
|
||||
FATFS *fs;
|
||||
FIL fil;
|
||||
UINT bytes_to_read;
|
||||
|
||||
FIL *fp = &fil;
|
||||
|
||||
UINT cluster_sector;
|
||||
DWORD cluster;
|
||||
LBA_t starting_sector;
|
||||
UINT sector_count;
|
||||
UINT bytes_processed;
|
||||
|
||||
|
||||
if ((fresult = f_open(fp, path, FA_READ)) != FR_OK) {
|
||||
return fresult;
|
||||
}
|
||||
|
||||
fresult = validate(&fp->obj, &fs);
|
||||
if (fresult != FR_OK || (fresult = (FRESULT) fp->err) != FR_OK) {
|
||||
LEAVE_FF(fs, fresult);
|
||||
}
|
||||
|
||||
bytes_to_read = (fp->obj.objsize > max_length) ? max_length : fp->obj.objsize;
|
||||
bytes_to_read += ((bytes_to_read % SS(fs)) != 0) ? (SS(fs) - (bytes_to_read % SS(fs))) : 0;
|
||||
|
||||
while (bytes_to_read) {
|
||||
cluster_sector = (UINT) (fp->fptr / SS(fs) & (fs->csize - 1));
|
||||
|
||||
if (cluster_sector == 0) {
|
||||
if (fp->fptr == 0) {
|
||||
cluster = fp->obj.sclust;
|
||||
} else {
|
||||
#if FF_USE_FASTSEEK
|
||||
if (fp->cltbl) {
|
||||
cluster = clmt_clust(fp, fp->fptr);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
cluster = get_fat(&fp->obj, fp->clust);
|
||||
}
|
||||
}
|
||||
|
||||
if (cluster < 2) {
|
||||
LEAVE_FF(fs, FR_INT_ERR);
|
||||
}
|
||||
|
||||
if (cluster == 0xFFFFFFFF) {
|
||||
LEAVE_FF(fs, FR_DISK_ERR);
|
||||
}
|
||||
|
||||
fp->clust = cluster;
|
||||
}
|
||||
|
||||
starting_sector = clst2sect(fs, fp->clust);
|
||||
|
||||
if (starting_sector == 0) {
|
||||
LEAVE_FF(fs, FR_INT_ERR);
|
||||
}
|
||||
|
||||
starting_sector += cluster_sector;
|
||||
|
||||
sector_count = bytes_to_read / SS(fs);
|
||||
|
||||
if (cluster_sector + sector_count > fs->csize) {
|
||||
sector_count = fs->csize - cluster_sector;
|
||||
}
|
||||
|
||||
if (transfer_function(fs->pdrv, fp->fptr, starting_sector, sector_count) != RES_OK) {
|
||||
LEAVE_FF(fs, FR_DISK_ERR);
|
||||
}
|
||||
|
||||
fp->sect = starting_sector;
|
||||
|
||||
bytes_processed = sector_count * SS(fs);
|
||||
fp->fptr += bytes_processed;
|
||||
bytes_to_read -= bytes_processed;
|
||||
}
|
||||
|
||||
LEAVE_FF(fs, FR_OK);
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
#ifndef FF_EXTENSIONS_H__
|
||||
#define FF_EXTENSIONS_H__
|
||||
|
||||
|
||||
#include "diskio.h"
|
||||
|
||||
|
||||
typedef DRESULT (*transfer_function_t)(BYTE, FSIZE_t, LBA_t, UINT);
|
||||
|
||||
|
||||
FRESULT fe_load(const TCHAR *path, UINT max_length, transfer_function_t transfer_function);
|
||||
|
||||
|
||||
#endif
|
@ -1,298 +0,0 @@
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ FatFs Functional Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FFCONF_DEF 80196 /* Revision ID */
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Function Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FF_FS_READONLY 0
|
||||
/* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
|
||||
/ Read-only configuration removes writing API functions, f_write(), f_sync(),
|
||||
/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
|
||||
/ and optional writing functions as well. */
|
||||
|
||||
|
||||
#define FF_FS_MINIMIZE 3
|
||||
/* This option defines minimization level to remove some basic API functions.
|
||||
/
|
||||
/ 0: Basic functions are fully enabled.
|
||||
/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename()
|
||||
/ are removed.
|
||||
/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1.
|
||||
/ 3: f_lseek() function is removed in addition to 2. */
|
||||
|
||||
|
||||
#define FF_USE_STRFUNC 2
|
||||
/* This option switches string functions, f_gets(), f_putc(), f_puts() and f_printf().
|
||||
/
|
||||
/ 0: Disable string functions.
|
||||
/ 1: Enable without LF-CRLF conversion.
|
||||
/ 2: Enable with LF-CRLF conversion. */
|
||||
|
||||
|
||||
#define FF_USE_FIND 0
|
||||
/* This option switches filtered directory read functions, f_findfirst() and
|
||||
/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */
|
||||
|
||||
|
||||
#define FF_USE_MKFS 0
|
||||
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define FF_USE_FASTSEEK 0
|
||||
/* This option switches fast seek function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define FF_USE_EXPAND 0
|
||||
/* This option switches f_expand function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define FF_USE_CHMOD 0
|
||||
/* This option switches attribute manipulation functions, f_chmod() and f_utime().
|
||||
/ (0:Disable or 1:Enable) Also FF_FS_READONLY needs to be 0 to enable this option. */
|
||||
|
||||
|
||||
#define FF_USE_LABEL 0
|
||||
/* This option switches volume label functions, f_getlabel() and f_setlabel().
|
||||
/ (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define FF_USE_FORWARD 0
|
||||
/* This option switches f_forward() function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Locale and Namespace Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FF_CODE_PAGE 437
|
||||
/* This option specifies the OEM code page to be used on the target system.
|
||||
/ Incorrect code page setting can cause a file open failure.
|
||||
/
|
||||
/ 437 - U.S.
|
||||
/ 720 - Arabic
|
||||
/ 737 - Greek
|
||||
/ 771 - KBL
|
||||
/ 775 - Baltic
|
||||
/ 850 - Latin 1
|
||||
/ 852 - Latin 2
|
||||
/ 855 - Cyrillic
|
||||
/ 857 - Turkish
|
||||
/ 860 - Portuguese
|
||||
/ 861 - Icelandic
|
||||
/ 862 - Hebrew
|
||||
/ 863 - Canadian French
|
||||
/ 864 - Arabic
|
||||
/ 865 - Nordic
|
||||
/ 866 - Russian
|
||||
/ 869 - Greek 2
|
||||
/ 932 - Japanese (DBCS)
|
||||
/ 936 - Simplified Chinese (DBCS)
|
||||
/ 949 - Korean (DBCS)
|
||||
/ 950 - Traditional Chinese (DBCS)
|
||||
/ 0 - Include all code pages above and configured by f_setcp()
|
||||
*/
|
||||
|
||||
|
||||
#define FF_USE_LFN 2
|
||||
#define FF_MAX_LFN 255
|
||||
/* The FF_USE_LFN switches the support for LFN (long file name).
|
||||
/
|
||||
/ 0: Disable LFN. FF_MAX_LFN has no effect.
|
||||
/ 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe.
|
||||
/ 2: Enable LFN with dynamic working buffer on the STACK.
|
||||
/ 3: Enable LFN with dynamic working buffer on the HEAP.
|
||||
/
|
||||
/ To enable the LFN, ffunicode.c needs to be added to the project. The LFN function
|
||||
/ requiers certain internal working buffer occupies (FF_MAX_LFN + 1) * 2 bytes and
|
||||
/ additional (FF_MAX_LFN + 44) / 15 * 32 bytes when exFAT is enabled.
|
||||
/ The FF_MAX_LFN defines size of the working buffer in UTF-16 code unit and it can
|
||||
/ be in range of 12 to 255. It is recommended to be set it 255 to fully support LFN
|
||||
/ specification.
|
||||
/ When use stack for the working buffer, take care on stack overflow. When use heap
|
||||
/ memory for the working buffer, memory management functions, ff_memalloc() and
|
||||
/ ff_memfree() exemplified in ffsystem.c, need to be added to the project. */
|
||||
|
||||
|
||||
#define FF_LFN_UNICODE 0
|
||||
/* This option switches the character encoding on the API when LFN is enabled.
|
||||
/
|
||||
/ 0: ANSI/OEM in current CP (TCHAR = char)
|
||||
/ 1: Unicode in UTF-16 (TCHAR = WCHAR)
|
||||
/ 2: Unicode in UTF-8 (TCHAR = char)
|
||||
/ 3: Unicode in UTF-32 (TCHAR = DWORD)
|
||||
/
|
||||
/ Also behavior of string I/O functions will be affected by this option.
|
||||
/ When LFN is not enabled, this option has no effect. */
|
||||
|
||||
|
||||
#define FF_LFN_BUF 255
|
||||
#define FF_SFN_BUF 12
|
||||
/* This set of options defines size of file name members in the FILINFO structure
|
||||
/ which is used to read out directory items. These values should be suffcient for
|
||||
/ the file names to read. The maximum possible length of the read file name depends
|
||||
/ on character encoding. When LFN is not enabled, these options have no effect. */
|
||||
|
||||
|
||||
#define FF_STRF_ENCODE 3
|
||||
/* When FF_LFN_UNICODE >= 1 with LFN enabled, string I/O functions, f_gets(),
|
||||
/ f_putc(), f_puts and f_printf() convert the character encoding in it.
|
||||
/ This option selects assumption of character encoding ON THE FILE to be
|
||||
/ read/written via those functions.
|
||||
/
|
||||
/ 0: ANSI/OEM in current CP
|
||||
/ 1: Unicode in UTF-16LE
|
||||
/ 2: Unicode in UTF-16BE
|
||||
/ 3: Unicode in UTF-8
|
||||
*/
|
||||
|
||||
|
||||
#define FF_FS_RPATH 0
|
||||
/* This option configures support for relative path.
|
||||
/
|
||||
/ 0: Disable relative path and remove related functions.
|
||||
/ 1: Enable relative path. f_chdir() and f_chdrive() are available.
|
||||
/ 2: f_getcwd() function is available in addition to 1.
|
||||
*/
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Drive/Volume Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FF_VOLUMES 1
|
||||
/* Number of volumes (logical drives) to be used. (1-10) */
|
||||
|
||||
|
||||
#define FF_STR_VOLUME_ID 0
|
||||
#define FF_VOLUME_STRS "RAM","NAND","CF","SD","SD2","USB","USB2","USB3"
|
||||
/* FF_STR_VOLUME_ID switches support for volume ID in arbitrary strings.
|
||||
/ When FF_STR_VOLUME_ID is set to 1 or 2, arbitrary strings can be used as drive
|
||||
/ number in the path name. FF_VOLUME_STRS defines the volume ID strings for each
|
||||
/ logical drives. Number of items must not be less than FF_VOLUMES. Valid
|
||||
/ characters for the volume ID strings are A-Z, a-z and 0-9, however, they are
|
||||
/ compared in case-insensitive. If FF_STR_VOLUME_ID >= 1 and FF_VOLUME_STRS is
|
||||
/ not defined, a user defined volume string table needs to be defined as:
|
||||
/
|
||||
/ const char* VolumeStr[FF_VOLUMES] = {"ram","flash","sd","usb",...
|
||||
*/
|
||||
|
||||
|
||||
#define FF_MULTI_PARTITION 0
|
||||
/* This option switches support for multiple volumes on the physical drive.
|
||||
/ By default (0), each logical drive number is bound to the same physical drive
|
||||
/ number and only an FAT volume found on the physical drive will be mounted.
|
||||
/ When this function is enabled (1), each logical drive number can be bound to
|
||||
/ arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk()
|
||||
/ funciton will be available. */
|
||||
|
||||
|
||||
#define FF_MIN_SS 512
|
||||
#define FF_MAX_SS 512
|
||||
/* This set of options configures the range of sector size to be supported. (512,
|
||||
/ 1024, 2048 or 4096) Always set both 512 for most systems, generic memory card and
|
||||
/ harddisk. But a larger value may be required for on-board flash memory and some
|
||||
/ type of optical media. When FF_MAX_SS is larger than FF_MIN_SS, FatFs is configured
|
||||
/ for variable sector size mode and disk_ioctl() function needs to implement
|
||||
/ GET_SECTOR_SIZE command. */
|
||||
|
||||
|
||||
#define FF_LBA64 1
|
||||
/* This option switches support for 64-bit LBA. (0:Disable or 1:Enable)
|
||||
/ To enable the 64-bit LBA, also exFAT needs to be enabled. (FF_FS_EXFAT == 1) */
|
||||
|
||||
|
||||
#define FF_MIN_GPT 0x10000000
|
||||
/* Minimum number of sectors to switch GPT as partitioning format in f_mkfs and
|
||||
/ f_fdisk function. 0x100000000 max. This option has no effect when FF_LBA64 == 0. */
|
||||
|
||||
|
||||
#define FF_USE_TRIM 0
|
||||
/* This option switches support for ATA-TRIM. (0:Disable or 1:Enable)
|
||||
/ To enable Trim function, also CTRL_TRIM command should be implemented to the
|
||||
/ disk_ioctl() function. */
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ System Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FF_FS_TINY 0
|
||||
/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)
|
||||
/ At the tiny configuration, size of file object (FIL) is shrinked FF_MAX_SS bytes.
|
||||
/ Instead of private sector buffer eliminated from the file object, common sector
|
||||
/ buffer in the filesystem object (FATFS) is used for the file data transfer. */
|
||||
|
||||
|
||||
#define FF_FS_EXFAT 1
|
||||
/* This option switches support for exFAT filesystem. (0:Disable or 1:Enable)
|
||||
/ To enable exFAT, also LFN needs to be enabled. (FF_USE_LFN >= 1)
|
||||
/ Note that enabling exFAT discards ANSI C (C89) compatibility. */
|
||||
|
||||
|
||||
#define FF_FS_NORTC 1
|
||||
#define FF_NORTC_MON 1
|
||||
#define FF_NORTC_MDAY 1
|
||||
#define FF_NORTC_YEAR 2020
|
||||
/* The option FF_FS_NORTC switches timestamp functiton. If the system does not have
|
||||
/ any RTC function or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable
|
||||
/ the timestamp function. Every object modified by FatFs will have a fixed timestamp
|
||||
/ defined by FF_NORTC_MON, FF_NORTC_MDAY and FF_NORTC_YEAR in local time.
|
||||
/ To enable timestamp function (FF_FS_NORTC = 0), get_fattime() function need to be
|
||||
/ added to the project to read current time form real-time clock. FF_NORTC_MON,
|
||||
/ FF_NORTC_MDAY and FF_NORTC_YEAR have no effect.
|
||||
/ These options have no effect in read-only configuration (FF_FS_READONLY = 1). */
|
||||
|
||||
|
||||
#define FF_FS_NOFSINFO 0
|
||||
/* If you need to know correct free space on the FAT32 volume, set bit 0 of this
|
||||
/ option, and f_getfree() function at first time after volume mount will force
|
||||
/ a full FAT scan. Bit 1 controls the use of last allocated cluster number.
|
||||
/
|
||||
/ bit0=0: Use free cluster count in the FSINFO if available.
|
||||
/ bit0=1: Do not trust free cluster count in the FSINFO.
|
||||
/ bit1=0: Use last allocated cluster number in the FSINFO if available.
|
||||
/ bit1=1: Do not trust last allocated cluster number in the FSINFO.
|
||||
*/
|
||||
|
||||
|
||||
#define FF_FS_LOCK 0
|
||||
/* The option FF_FS_LOCK switches file lock function to control duplicated file open
|
||||
/ and illegal operation to open objects. This option must be 0 when FF_FS_READONLY
|
||||
/ is 1.
|
||||
/
|
||||
/ 0: Disable file lock function. To avoid volume corruption, application program
|
||||
/ should avoid illegal open, remove and rename to the open objects.
|
||||
/ >0: Enable file lock function. The value defines how many files/sub-directories
|
||||
/ can be opened simultaneously under file lock control. Note that the file
|
||||
/ lock control is independent of re-entrancy. */
|
||||
|
||||
|
||||
/* #include <somertos.h> // O/S definitions */
|
||||
#define FF_FS_REENTRANT 0
|
||||
#define FF_FS_TIMEOUT 1000
|
||||
#define FF_SYNC_t HANDLE
|
||||
/* The option FF_FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs
|
||||
/ module itself. Note that regardless of this option, file access to different
|
||||
/ volume is always re-entrant and volume control functions, f_mount(), f_mkfs()
|
||||
/ and f_fdisk() function, are always not re-entrant. Only file/directory access
|
||||
/ to the same volume is under control of this function.
|
||||
/
|
||||
/ 0: Disable re-entrancy. FF_FS_TIMEOUT and FF_SYNC_t have no effect.
|
||||
/ 1: Enable re-entrancy. Also user provided synchronization handlers,
|
||||
/ ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj()
|
||||
/ function, must be added to the project. Samples are available in
|
||||
/ option/syscall.c.
|
||||
/
|
||||
/ The FF_FS_TIMEOUT defines timeout period in unit of time tick.
|
||||
/ The FF_SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*,
|
||||
/ SemaphoreHandle_t and etc. A header file for O/S definitions needs to be
|
||||
/ included somewhere in the scope of ff.h. */
|
||||
|
||||
|
||||
|
||||
/*--- End of configuration options ---*/
|
@ -1,170 +0,0 @@
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Sample Code of OS Dependent Functions for FatFs */
|
||||
/* (C)ChaN, 2018 */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#include "ff.h"
|
||||
|
||||
|
||||
#if FF_USE_LFN == 3 /* Dynamic memory allocation */
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Allocate a memory block */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
void* ff_memalloc ( /* Returns pointer to the allocated memory block (null if not enough core) */
|
||||
UINT msize /* Number of bytes to allocate */
|
||||
)
|
||||
{
|
||||
return malloc(msize); /* Allocate a new memory block with POSIX API */
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Free a memory block */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
void ff_memfree (
|
||||
void* mblock /* Pointer to the memory block to free (nothing to do if null) */
|
||||
)
|
||||
{
|
||||
free(mblock); /* Free the memory block with POSIX API */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if FF_FS_REENTRANT /* Mutal exclusion */
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Create a Synchronization Object */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* This function is called in f_mount() function to create a new
|
||||
/ synchronization object for the volume, such as semaphore and mutex.
|
||||
/ When a 0 is returned, the f_mount() function fails with FR_INT_ERR.
|
||||
*/
|
||||
|
||||
//const osMutexDef_t Mutex[FF_VOLUMES]; /* Table of CMSIS-RTOS mutex */
|
||||
|
||||
|
||||
int ff_cre_syncobj ( /* 1:Function succeeded, 0:Could not create the sync object */
|
||||
BYTE vol, /* Corresponding volume (logical drive number) */
|
||||
FF_SYNC_t* sobj /* Pointer to return the created sync object */
|
||||
)
|
||||
{
|
||||
/* Win32 */
|
||||
*sobj = CreateMutex(NULL, FALSE, NULL);
|
||||
return (int)(*sobj != INVALID_HANDLE_VALUE);
|
||||
|
||||
/* uITRON */
|
||||
// T_CSEM csem = {TA_TPRI,1,1};
|
||||
// *sobj = acre_sem(&csem);
|
||||
// return (int)(*sobj > 0);
|
||||
|
||||
/* uC/OS-II */
|
||||
// OS_ERR err;
|
||||
// *sobj = OSMutexCreate(0, &err);
|
||||
// return (int)(err == OS_NO_ERR);
|
||||
|
||||
/* FreeRTOS */
|
||||
// *sobj = xSemaphoreCreateMutex();
|
||||
// return (int)(*sobj != NULL);
|
||||
|
||||
/* CMSIS-RTOS */
|
||||
// *sobj = osMutexCreate(&Mutex[vol]);
|
||||
// return (int)(*sobj != NULL);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Delete a Synchronization Object */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* This function is called in f_mount() function to delete a synchronization
|
||||
/ object that created with ff_cre_syncobj() function. When a 0 is returned,
|
||||
/ the f_mount() function fails with FR_INT_ERR.
|
||||
*/
|
||||
|
||||
int ff_del_syncobj ( /* 1:Function succeeded, 0:Could not delete due to an error */
|
||||
FF_SYNC_t sobj /* Sync object tied to the logical drive to be deleted */
|
||||
)
|
||||
{
|
||||
/* Win32 */
|
||||
return (int)CloseHandle(sobj);
|
||||
|
||||
/* uITRON */
|
||||
// return (int)(del_sem(sobj) == E_OK);
|
||||
|
||||
/* uC/OS-II */
|
||||
// OS_ERR err;
|
||||
// OSMutexDel(sobj, OS_DEL_ALWAYS, &err);
|
||||
// return (int)(err == OS_NO_ERR);
|
||||
|
||||
/* FreeRTOS */
|
||||
// vSemaphoreDelete(sobj);
|
||||
// return 1;
|
||||
|
||||
/* CMSIS-RTOS */
|
||||
// return (int)(osMutexDelete(sobj) == osOK);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Request Grant to Access the Volume */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* This function is called on entering file functions to lock the volume.
|
||||
/ When a 0 is returned, the file function fails with FR_TIMEOUT.
|
||||
*/
|
||||
|
||||
int ff_req_grant ( /* 1:Got a grant to access the volume, 0:Could not get a grant */
|
||||
FF_SYNC_t sobj /* Sync object to wait */
|
||||
)
|
||||
{
|
||||
/* Win32 */
|
||||
return (int)(WaitForSingleObject(sobj, FF_FS_TIMEOUT) == WAIT_OBJECT_0);
|
||||
|
||||
/* uITRON */
|
||||
// return (int)(wai_sem(sobj) == E_OK);
|
||||
|
||||
/* uC/OS-II */
|
||||
// OS_ERR err;
|
||||
// OSMutexPend(sobj, FF_FS_TIMEOUT, &err));
|
||||
// return (int)(err == OS_NO_ERR);
|
||||
|
||||
/* FreeRTOS */
|
||||
// return (int)(xSemaphoreTake(sobj, FF_FS_TIMEOUT) == pdTRUE);
|
||||
|
||||
/* CMSIS-RTOS */
|
||||
// return (int)(osMutexWait(sobj, FF_FS_TIMEOUT) == osOK);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Release Grant to Access the Volume */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* This function is called on leaving file functions to unlock the volume.
|
||||
*/
|
||||
|
||||
void ff_rel_grant (
|
||||
FF_SYNC_t sobj /* Sync object to be signaled */
|
||||
)
|
||||
{
|
||||
/* Win32 */
|
||||
ReleaseMutex(sobj);
|
||||
|
||||
/* uITRON */
|
||||
// sig_sem(sobj);
|
||||
|
||||
/* uC/OS-II */
|
||||
// OSMutexPost(sobj);
|
||||
|
||||
/* FreeRTOS */
|
||||
// xSemaphoreGive(sobj);
|
||||
|
||||
/* CMSIS-RTOS */
|
||||
// osMutexRelease(sobj);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,127 +0,0 @@
|
||||
#include <libdragon.h>
|
||||
|
||||
#include "platform.h"
|
||||
#include "assets/assets.h"
|
||||
|
||||
#include "loader.h"
|
||||
|
||||
|
||||
#define X_OFFSET (24)
|
||||
#define Y_OFFSET (16)
|
||||
#define Y_PADDING (12)
|
||||
|
||||
#define LAST_CHAR(s) (sizeof(s) - 1)
|
||||
#define EDIT_CHAR(s, n) s[(n) >= 0 ? 0 : LAST_CHAR((s)) + (n)]
|
||||
#define NTOA(n) ('0' + ((n) % 10))
|
||||
|
||||
|
||||
static bool loader_initialized = false;
|
||||
|
||||
static char version_string[] = "SC64 Bootloader ver. X.X";
|
||||
static char error_number_string[] = "ERROR X";
|
||||
static const char *error_strings[] = {
|
||||
"No error :O",
|
||||
"SummerCart64 not detected",
|
||||
"SD Card not detected",
|
||||
"No filesystem (FAT or exFAT)\nfound on SD Card",
|
||||
"Unable to locate menu file",
|
||||
"Error while reading data from\nSD Card",
|
||||
"Unknown error",
|
||||
};
|
||||
|
||||
static int x_offset = X_OFFSET;
|
||||
static int y_offset = Y_OFFSET;
|
||||
|
||||
|
||||
static display_context_t loader_get_display(bool lock) {
|
||||
display_context_t display;
|
||||
|
||||
do {
|
||||
display = display_lock();
|
||||
} while (!display && lock);
|
||||
|
||||
x_offset = X_OFFSET;
|
||||
y_offset = Y_OFFSET;
|
||||
|
||||
return display;
|
||||
}
|
||||
|
||||
static void loader_draw_version_and_logo(display_context_t display) {
|
||||
EDIT_CHAR(version_string, -3) = NTOA(BOOTLOADER_VERSION_MAJOR);
|
||||
EDIT_CHAR(version_string, -1) = NTOA(BOOTLOADER_VERSION_MINOR);
|
||||
graphics_draw_text(display, x_offset, y_offset, version_string);
|
||||
y_offset += Y_PADDING;
|
||||
|
||||
sprite_t *logo = _binary_build_sc64_logo_sprite_start;
|
||||
|
||||
int center_x = (320 / 2) - (logo->width / 2);
|
||||
int center_y = (240 / 2) - (logo->height / 2);
|
||||
|
||||
graphics_draw_sprite(display, center_x, center_y, logo);
|
||||
}
|
||||
|
||||
static void loader_init(void) {
|
||||
init_interrupts();
|
||||
|
||||
audio_init(44100, 2);
|
||||
audio_write_silence();
|
||||
|
||||
display_init(RESOLUTION_320x240, DEPTH_32_BPP, 2, GAMMA_NONE, ANTIALIAS_OFF);
|
||||
|
||||
loader_initialized = true;
|
||||
}
|
||||
|
||||
void loader_cleanup(void) {
|
||||
audio_close();
|
||||
|
||||
display_close();
|
||||
|
||||
disable_interrupts();
|
||||
|
||||
loader_initialized = false;
|
||||
}
|
||||
|
||||
void loader_display_logo(void) {
|
||||
if (!loader_initialized) {
|
||||
loader_init();
|
||||
}
|
||||
|
||||
display_context_t display;
|
||||
|
||||
display = loader_get_display(true);
|
||||
|
||||
graphics_fill_screen(display, 0);
|
||||
|
||||
loader_draw_version_and_logo(display);
|
||||
|
||||
display_show(display);
|
||||
}
|
||||
|
||||
void loader_display_error_and_halt(menu_load_error_t error, const char *message) {
|
||||
if (!loader_initialized) {
|
||||
loader_init();
|
||||
}
|
||||
|
||||
display_context_t display;
|
||||
|
||||
display = loader_get_display(true);
|
||||
|
||||
graphics_fill_screen(display, 0);
|
||||
|
||||
loader_draw_version_and_logo(display);
|
||||
|
||||
EDIT_CHAR(error_number_string, -1) = NTOA(error);
|
||||
graphics_draw_text(display, x_offset, y_offset, error_number_string);
|
||||
y_offset += Y_PADDING;
|
||||
|
||||
int error_string_index = error >= E_MENU_END ? (E_MENU_END - 1) : error;
|
||||
const char *error_string = error_strings[error_string_index];
|
||||
graphics_draw_text(display, x_offset, y_offset, error_string);
|
||||
y_offset += Y_PADDING * 2;
|
||||
|
||||
graphics_draw_text(display, x_offset, y_offset, message);
|
||||
|
||||
display_show(display);
|
||||
|
||||
while (1);
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
#ifndef LOADER_H__
|
||||
#define LOADER_H__
|
||||
|
||||
|
||||
#include "errors.h"
|
||||
|
||||
|
||||
void loader_cleanup(void);
|
||||
void loader_display_logo(void);
|
||||
void loader_display_error_and_halt(menu_load_error_t error, const char *message);
|
||||
|
||||
|
||||
#endif
|
@ -1,157 +1,45 @@
|
||||
#include "boot/boot.h"
|
||||
#include "loader/loader.h"
|
||||
#include "sc64/sc64.h"
|
||||
#include "sc64/sc64_sd_fs.h"
|
||||
|
||||
typedef struct sc64_cart_registers {
|
||||
__IO reg_t SCR;
|
||||
__IO reg_t COMMAND;
|
||||
__IO reg_t ARG[2];
|
||||
__IO reg_t RESPONSE;
|
||||
__IO reg_t BOOTSTRAP;
|
||||
} sc64_cfg_registers_t;
|
||||
|
||||
#define DEFAULT_MENU_FILE_PATH "SC64/MENU.z64\0";
|
||||
#define SC64_CFG_BASE (0x1FFF0000)
|
||||
|
||||
#define SC64_CFG ((__IO sc64_cfg_registers_t *) SC64_CFG_BASE)
|
||||
|
||||
static const char *CONFIG_FILE_PATH = "SC64/config.txt";
|
||||
|
||||
|
||||
static menu_load_error_t convert_error(sc64_sd_fs_error_t sd_fs_error) {
|
||||
switch (sd_fs_error) {
|
||||
case SC64_SD_FS_NO_CARD:
|
||||
return E_MENU_ERROR_NO_CARD;
|
||||
case SC64_SD_FS_NO_FILESYSTEM:
|
||||
return E_MENU_ERROR_NO_FILESYSTEM;
|
||||
case SC64_SD_FS_NO_FILE:
|
||||
return E_MENU_ERROR_NO_FILE;
|
||||
case SC64_SD_FS_READ_ERROR:
|
||||
return E_MENU_ERROR_READ_ERROR;
|
||||
case SC64_SD_FS_OTHER_ERROR:
|
||||
return E_MENU_ERROR_OTHER_ERROR;
|
||||
default:
|
||||
return E_MENU_OK;
|
||||
}
|
||||
}
|
||||
#define SC64_CFG_SCR_CPU_BOOTSTRAPPED (1 << 31)
|
||||
#define SC64_CFG_SCR_CPU_BUSY (1 << 30)
|
||||
|
||||
#define CMD_SDRAM_SWITCH 'S'
|
||||
|
||||
int main(void) {
|
||||
while (1);
|
||||
// OS_BOOT_CONFIG->tv_type = TV_NTSC;
|
||||
OS_BOOT_CONFIG->tv_type = TV_NTSC;
|
||||
|
||||
// if (sc64_get_version() != SC64_CART_VERSION_A) {
|
||||
// loader_display_error_and_halt(E_MENU_ERROR_NOT_SC64, "");
|
||||
// }
|
||||
uint32_t scr = 0;
|
||||
|
||||
// sc64_enable_rom_switch();
|
||||
do {
|
||||
scr = platform_pi_io_read(&SC64_CFG->SCR);
|
||||
} while (!(scr & SC64_CFG_SCR_CPU_BOOTSTRAPPED));
|
||||
|
||||
// uint32_t boot_mode = sc64_get_boot_mode();
|
||||
do {
|
||||
scr = platform_pi_io_read(&SC64_CFG->SCR);
|
||||
} while (scr & SC64_CFG_SCR_CPU_BUSY);
|
||||
|
||||
// bool skip_menu = (boot_mode & SC64_CART_BOOT_SKIP_MENU);
|
||||
// bool cic_seed_override = (boot_mode & SC64_CART_BOOT_CIC_SEED_OVERRIDE);
|
||||
// bool tv_type_override = (boot_mode & SC64_CART_BOOT_TV_TYPE_OVERRIDE);
|
||||
// bool ddipl_override = (boot_mode & SC64_CART_BOOT_DDIPL_OVERRIDE);
|
||||
// bool rom_loaded = (boot_mode & SC64_CART_BOOT_ROM_LOADED);
|
||||
// tv_type_t tv_type = ((boot_mode & SC64_CART_BOOT_TV_TYPE_MASK) >> SC64_CART_BOOT_TV_TYPE_BIT);
|
||||
// uint16_t cic_seed = ((boot_mode & SC64_CART_BOOT_CIC_SEED_MASK) >> SC64_CART_BOOT_CIC_SEED_BIT);
|
||||
platform_pi_io_write(&SC64_CFG->ARG[0], 1);
|
||||
platform_pi_io_write(&SC64_CFG->COMMAND, (uint32_t) CMD_SDRAM_SWITCH);
|
||||
|
||||
// if (!skip_menu) {
|
||||
// char rom_path[256] = DEFAULT_MENU_FILE_PATH;
|
||||
// char save_path[256] = "\0";
|
||||
// sc64_sd_fs_error_t sd_fs_error;
|
||||
// sc64_sd_fs_config_t config = {
|
||||
// .rom = rom_path,
|
||||
// .rom_reload = false,
|
||||
// .save = save_path,
|
||||
// .save_type = 0,
|
||||
// .save_writeback = false,
|
||||
// .cic_seed = 0xFFFF,
|
||||
// .tv_type = -1,
|
||||
// };
|
||||
do {
|
||||
scr = platform_pi_io_read(&SC64_CFG->SCR);
|
||||
} while (scr & SC64_CFG_SCR_CPU_BUSY);
|
||||
|
||||
// sd_fs_error = sc64_sd_fs_init();
|
||||
// if (sd_fs_error != SC64_SD_FS_OK) {
|
||||
// loader_display_error_and_halt(convert_error(sd_fs_error), "sc64_sd_fs_init");
|
||||
// }
|
||||
cart_header_t *cart_header = boot_load_cart_header();
|
||||
uint16_t cic_seed = boot_get_cic_seed(cart_header);
|
||||
tv_type_t tv_type = boot_get_tv_type(cart_header);
|
||||
|
||||
// sd_fs_error = sc64_sd_fs_load_config(CONFIG_FILE_PATH, &config);
|
||||
// if ((sd_fs_error != SC64_SD_FS_OK) && (sd_fs_error != SC64_SD_FS_NO_FILE)) {
|
||||
// loader_display_error_and_halt(convert_error(sd_fs_error), "sc64_sd_fs_load_config");
|
||||
// }
|
||||
|
||||
// if (config.cic_seed != 0xFFFF) {
|
||||
// cic_seed_override = true;
|
||||
// cic_seed = config.cic_seed;
|
||||
// }
|
||||
|
||||
// if (config.tv_type != -1) {
|
||||
// tv_type_override = true;
|
||||
// tv_type = config.tv_type;
|
||||
// }
|
||||
|
||||
// if (!rom_loaded || config.rom_reload) {
|
||||
// loader_display_logo();
|
||||
// }
|
||||
|
||||
// if (config.save_type > 0) {
|
||||
// sc64_disable_eeprom();
|
||||
// sc64_disable_sram();
|
||||
// sc64_disable_flashram();
|
||||
|
||||
// switch (config.save_type) {
|
||||
// case 1: sc64_enable_eeprom(false); break;
|
||||
// case 2: sc64_enable_eeprom(true); break;
|
||||
// case 3:
|
||||
// case 4: sc64_enable_sram(); break;
|
||||
// case 5:
|
||||
// case 6: sc64_enable_flashram(); break;
|
||||
// }
|
||||
|
||||
// if (config.save_type >= 3 || config.save_type <= 5) {
|
||||
// sc64_set_save_address(SC64_SDRAM_SIZE - (128 * 1024));
|
||||
// } else if (config.save_type == 6) {
|
||||
// sc64_set_save_address(0x01618000);
|
||||
// }
|
||||
|
||||
// if (rom_loaded && (config.save[0] != '\0') && config.save_writeback) {
|
||||
// sd_fs_error = sc64_sd_fs_store_save(config.save);
|
||||
// if (sd_fs_error != SC64_SD_FS_OK) {
|
||||
// loader_display_error_and_halt(convert_error(sd_fs_error), "sc64_sd_fs_store_save");
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (!rom_loaded || config.rom_reload) {
|
||||
// sd_fs_error = sc64_sd_fs_load_rom(config.rom);
|
||||
// if (sd_fs_error != SC64_SD_FS_OK) {
|
||||
// loader_display_error_and_halt(convert_error(sd_fs_error), "sc64_sd_fs_load_rom");
|
||||
// }
|
||||
|
||||
// sc64_set_boot_mode(boot_mode | SC64_CART_BOOT_ROM_LOADED);
|
||||
// }
|
||||
|
||||
// if ((config.save_type > 0) && (config.save[0] != '\0') && !rom_loaded) {
|
||||
// sd_fs_error = sc64_sd_fs_load_save(config.save);
|
||||
// if (sd_fs_error != SC64_SD_FS_OK) {
|
||||
// loader_display_error_and_halt(convert_error(sd_fs_error), "sc64_sd_fs_load_save");
|
||||
// }
|
||||
// }
|
||||
|
||||
// sc64_sd_fs_deinit();
|
||||
|
||||
// if (!rom_loaded || config.rom_reload) {
|
||||
// loader_cleanup();
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (ddipl_override) {
|
||||
// sc64_enable_ddipl();
|
||||
// } else {
|
||||
// sc64_disable_ddipl();
|
||||
// }
|
||||
|
||||
// cart_header_t *cart_header = boot_load_cart_header(ddipl_override);
|
||||
|
||||
// if (!cic_seed_override) {
|
||||
// cic_seed = boot_get_cic_seed(cart_header);
|
||||
// }
|
||||
|
||||
// if (!tv_type_override) {
|
||||
// tv_type = boot_get_tv_type(cart_header);
|
||||
// }
|
||||
|
||||
// boot(cart_header, cic_seed, tv_type, ddipl_override);
|
||||
boot(cart_header, cic_seed, tv_type);
|
||||
}
|
||||
|
@ -1,131 +0,0 @@
|
||||
#include "sc64.h"
|
||||
|
||||
|
||||
static void sc64_enable_peripheral(uint32_t mask) {
|
||||
uint32_t config = platform_pi_io_read(&SC64_CART->SCR);
|
||||
|
||||
config |= mask;
|
||||
|
||||
platform_pi_io_write(&SC64_CART->SCR, config);
|
||||
}
|
||||
|
||||
static void sc64_disable_peripheral(uint32_t mask) {
|
||||
uint32_t config = platform_pi_io_read(&SC64_CART->SCR);
|
||||
|
||||
config &= ~mask;
|
||||
|
||||
platform_pi_io_write(&SC64_CART->SCR, config);
|
||||
}
|
||||
|
||||
uint32_t sc64_get_scr(void) {
|
||||
return platform_pi_io_read(&SC64_CART->SCR);
|
||||
}
|
||||
|
||||
void sc64_set_scr(uint32_t scr) {
|
||||
platform_pi_io_write(&SC64_CART->SCR, scr);
|
||||
}
|
||||
|
||||
void sc64_enable_skip_bootloader(void) {
|
||||
sc64_enable_peripheral(SC64_CART_SCR_SKIP_BOOTLOADER);
|
||||
}
|
||||
|
||||
void sc64_disable_skip_bootloader(void) {
|
||||
sc64_disable_peripheral(SC64_CART_SCR_SKIP_BOOTLOADER);
|
||||
}
|
||||
|
||||
void sc64_enable_flashram(void) {
|
||||
sc64_enable_peripheral(SC64_CART_SCR_FLASHRAM_ENABLE);
|
||||
}
|
||||
|
||||
void sc64_disable_flashram(void) {
|
||||
sc64_disable_peripheral(SC64_CART_SCR_FLASHRAM_ENABLE);
|
||||
}
|
||||
|
||||
void sc64_enable_sram(void) {
|
||||
sc64_enable_peripheral(SC64_CART_SCR_SRAM_ENABLE);
|
||||
}
|
||||
|
||||
void sc64_disable_sram(void) {
|
||||
sc64_disable_peripheral(SC64_CART_SCR_SRAM_ENABLE);
|
||||
}
|
||||
|
||||
void sc64_enable_sd(void) {
|
||||
sc64_enable_peripheral(SC64_CART_SCR_SD_ENABLE);
|
||||
}
|
||||
|
||||
void sc64_disable_sd(void) {
|
||||
sc64_disable_peripheral(SC64_CART_SCR_SD_ENABLE);
|
||||
}
|
||||
|
||||
void sc64_enable_eeprom_pi(void) {
|
||||
sc64_enable_peripheral(SC64_CART_SCR_EEPROM_PI_ENABLE);
|
||||
}
|
||||
|
||||
void sc64_disable_eeprom_pi(void) {
|
||||
sc64_disable_peripheral(SC64_CART_SCR_EEPROM_PI_ENABLE);
|
||||
}
|
||||
|
||||
void sc64_enable_eeprom(bool mode_16k) {
|
||||
sc64_enable_peripheral(SC64_CART_SCR_EEPROM_ENABLE);
|
||||
if (mode_16k) {
|
||||
sc64_enable_peripheral(SC64_CART_SCR_EEPROM_16K_MODE);
|
||||
} else {
|
||||
sc64_disable_peripheral(SC64_CART_SCR_EEPROM_16K_MODE);
|
||||
}
|
||||
}
|
||||
|
||||
void sc64_disable_eeprom(void) {
|
||||
sc64_disable_peripheral(SC64_CART_SCR_EEPROM_ENABLE);
|
||||
}
|
||||
|
||||
void sc64_enable_ddipl(void) {
|
||||
sc64_enable_peripheral(SC64_CART_SCR_DDIPL_ENABLE);
|
||||
}
|
||||
|
||||
void sc64_disable_ddipl(void) {
|
||||
sc64_disable_peripheral(SC64_CART_SCR_DDIPL_ENABLE);
|
||||
}
|
||||
|
||||
void sc64_enable_rom_switch(void) {
|
||||
sc64_enable_peripheral(SC64_CART_SCR_ROM_SWITCH);
|
||||
}
|
||||
|
||||
void sc64_disable_rom_switch(void) {
|
||||
sc64_disable_peripheral(SC64_CART_SCR_ROM_SWITCH);
|
||||
}
|
||||
|
||||
void sc64_enable_sdram_writable(void) {
|
||||
sc64_enable_peripheral(SC64_CART_SCR_SDRAM_WRITABLE);
|
||||
}
|
||||
|
||||
void sc64_disable_sdram_writable(void) {
|
||||
sc64_disable_peripheral(SC64_CART_SCR_SDRAM_WRITABLE);
|
||||
}
|
||||
|
||||
uint32_t sc64_get_boot_mode(void) {
|
||||
return platform_pi_io_read(&SC64_CART->BOOT);
|
||||
}
|
||||
|
||||
void sc64_set_boot_mode(uint32_t boot) {
|
||||
platform_pi_io_write(&SC64_CART->BOOT, boot);
|
||||
}
|
||||
|
||||
uint32_t sc64_get_version(void) {
|
||||
return platform_pi_io_read(&SC64_CART->VERSION);
|
||||
}
|
||||
|
||||
uint32_t sc64_get_ddipl_address(void) {
|
||||
return platform_pi_io_read(&SC64_CART->DDIPL_ADDR) & SC64_CART_DDIPL_ADDR_ADDRESS_MASK;
|
||||
}
|
||||
|
||||
void sc64_set_ddipl_address(uint32_t address) {
|
||||
platform_pi_io_write(&SC64_CART->DDIPL_ADDR, address & SC64_CART_DDIPL_ADDR_ADDRESS_MASK);
|
||||
}
|
||||
|
||||
uint32_t sc64_get_save_address(void) {
|
||||
return platform_pi_io_read(&SC64_CART->SRAM_ADDR) & SC64_CART_SRAM_ADDR_ADDRESS_MASK;
|
||||
}
|
||||
|
||||
void sc64_set_save_address(uint32_t address) {
|
||||
platform_pi_io_write(&SC64_CART->SRAM_ADDR, address & SC64_CART_SRAM_ADDR_ADDRESS_MASK);
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
#ifndef SC64_H__
|
||||
#define SC64_H__
|
||||
|
||||
|
||||
#include "sc64_regs.h"
|
||||
|
||||
|
||||
#define SC64_SDRAM_SIZE (64 * 1024 * 1024)
|
||||
|
||||
|
||||
uint32_t sc64_get_scr(void);
|
||||
void sc64_set_scr(uint32_t scr);
|
||||
void sc64_enable_skip_bootloader(void);
|
||||
void sc64_disable_skip_bootloader(void);
|
||||
void sc64_enable_flashram(void);
|
||||
void sc64_disable_flashram(void);
|
||||
void sc64_enable_sram(void);
|
||||
void sc64_disable_sram(void);
|
||||
void sc64_enable_sd(void);
|
||||
void sc64_disable_sd(void);
|
||||
void sc64_enable_eeprom_pi(void);
|
||||
void sc64_disable_eeprom_pi(void);
|
||||
void sc64_enable_eeprom(bool mode_16k);
|
||||
void sc64_disable_eeprom(void);
|
||||
void sc64_enable_ddipl(void);
|
||||
void sc64_disable_ddipl(void);
|
||||
void sc64_enable_rom_switch(void);
|
||||
void sc64_disable_rom_switch(void);
|
||||
void sc64_enable_sdram_writable(void);
|
||||
void sc64_disable_sdram_writable(void);
|
||||
uint32_t sc64_get_boot_mode(void);
|
||||
void sc64_set_boot_mode(uint32_t boot);
|
||||
uint32_t sc64_get_version(void);
|
||||
uint32_t sc64_get_ddipl_address(void);
|
||||
void sc64_set_ddipl_address(uint32_t address);
|
||||
uint32_t sc64_get_save_address(void);
|
||||
void sc64_set_save_address(uint32_t address);
|
||||
|
||||
|
||||
#endif
|
@ -1,197 +0,0 @@
|
||||
#ifndef SC64_REGS_H__
|
||||
#define SC64_REGS_H__
|
||||
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
|
||||
// Bank definitions
|
||||
|
||||
#define SC64_BANK_INVALID (0)
|
||||
#define SC64_BANK_SDRAM (1)
|
||||
#define SC64_BANK_CART (2)
|
||||
#define SC64_BANK_EEPROM (3)
|
||||
#define SC64_BANK_SD (4)
|
||||
|
||||
|
||||
// Cart Interface Registers
|
||||
|
||||
typedef struct sc64_cart_registers {
|
||||
__IO reg_t SCR; // Cart status and config
|
||||
__IO reg_t BOOT; // Boot behavior override
|
||||
__IO reg_t VERSION; // Cart firmware version
|
||||
__IO reg_t GPIO; // Fixed I/O control
|
||||
__IO reg_t USB_SCR; // USB interface status and control
|
||||
__IO reg_t USB_DMA_ADDR; // USB bank and address for DMA to PC
|
||||
__IO reg_t USB_DMA_LEN; // USB transfer length for DMA to PC
|
||||
__IO reg_t DDIPL_ADDR; // 64 Disk Drive IPL location in SDRAM
|
||||
__IO reg_t SRAM_ADDR; // SRAM save emulation location in SDRAM
|
||||
__IO reg_t ___unused[1015];
|
||||
__IO reg_t USB_FIFO[1024]; // USB data from PC read FIFO memory end
|
||||
} sc64_cart_registers_t;
|
||||
|
||||
#define SC64_CART_BASE (0x1E000000)
|
||||
|
||||
#define SC64_CART ((__IO sc64_cart_registers_t *) SC64_CART_BASE)
|
||||
|
||||
|
||||
#define SC64_CART_SCR_SKIP_BOOTLOADER (1 << 10)
|
||||
#define SC64_CART_SCR_FLASHRAM_ENABLE (1 << 9)
|
||||
#define SC64_CART_SCR_SRAM_768K_MODE (1 << 8)
|
||||
#define SC64_CART_SCR_SRAM_ENABLE (1 << 7)
|
||||
#define SC64_CART_SCR_SD_ENABLE (1 << 6)
|
||||
#define SC64_CART_SCR_EEPROM_PI_ENABLE (1 << 5)
|
||||
#define SC64_CART_SCR_EEPROM_16K_MODE (1 << 4)
|
||||
#define SC64_CART_SCR_EEPROM_ENABLE (1 << 3)
|
||||
#define SC64_CART_SCR_DDIPL_ENABLE (1 << 2)
|
||||
#define SC64_CART_SCR_ROM_SWITCH (1 << 1)
|
||||
#define SC64_CART_SCR_SDRAM_WRITABLE (1 << 0)
|
||||
|
||||
#define SC64_CART_BOOT_SKIP_MENU (1 << 15)
|
||||
#define SC64_CART_BOOT_CIC_SEED_OVERRIDE (1 << 14)
|
||||
#define SC64_CART_BOOT_TV_TYPE_OVERRIDE (1 << 13)
|
||||
#define SC64_CART_BOOT_DDIPL_OVERRIDE (1 << 12)
|
||||
#define SC64_CART_BOOT_TV_TYPE_BIT (10)
|
||||
#define SC64_CART_BOOT_TV_TYPE_MASK (0x3 << SC64_CART_BOOT_TV_TYPE_BIT)
|
||||
#define SC64_CART_BOOT_ROM_LOADED (1 << 9)
|
||||
#define SC64_CART_BOOT_CIC_SEED_BIT (0)
|
||||
#define SC64_CART_BOOT_CIC_SEED_MASK (0x1FF << SC64_CART_BOOT_CIC_SEED_BIT)
|
||||
|
||||
#define SC64_CART_VERSION_A (0x53363461)
|
||||
|
||||
#define SC64_CART_GPIO_RESET_BUTTON (1 << 0)
|
||||
|
||||
#define SC64_CART_USB_SCR_FIFO_ITEMS_BIT (3)
|
||||
#define SC64_CART_USB_SCR_FIFO_ITEMS_MASK (0x7FF << SC64_CART_USB_SCR_FIFO_ITEMS_BIT)
|
||||
#define SC64_CART_USB_SCR_READY (1 << 1)
|
||||
#define SC64_CART_USB_SCR_DMA_BUSY (1 << 0)
|
||||
#define SC64_CART_USB_SCR_FIFO_FLUSH (1 << 2)
|
||||
#define SC64_CART_USB_SCR_DMA_START (1 << 0)
|
||||
|
||||
#define SC64_CART_USB_SCR_FIFO_ITEMS(i) (((i) & SC64_CART_USB_SCR_FIFO_ITEMS_MASK) >> SC64_CART_USB_SCR_FIFO_ITEMS_BIT)
|
||||
|
||||
#define SC64_CART_USB_DMA_ADDR_BANK_BIT (28)
|
||||
#define SC64_CART_USB_DMA_ADDR_BANK_MASK (0xF << SC64_CART_USB_DMA_ADDR_BANK_BIT)
|
||||
#define SC64_CART_USB_DMA_ADDR_ADDRESS_BIT (0)
|
||||
#define SC64_CART_USB_DMA_ADDR_ADDRESS_MASK (0x3FFFFFC << SC64_CART_USB_DMA_ADDR_ADDRESS_BIT)
|
||||
|
||||
#define SC64_CART_USB_DMA_ADDR(b, a) ((((b) << SC64_CART_USB_DMA_ADDR_BANK_BIT) & SC64_CART_USB_DMA_ADDR_BANK_MASK) | (((a) << SC64_CART_USB_DMA_ADDR_ADDRESS_BIT) & SC64_CART_USB_DMA_ADDR_ADDRESS_MASK))
|
||||
|
||||
#define SC64_CART_USB_DMA_LEN_LENGTH_BIT (0)
|
||||
#define SC64_CART_USB_DMA_LEN_LENGTH_MASK (0xFFFFF << SC64_CART_USB_DMA_LEN_LENGTH_BIT)
|
||||
|
||||
#define SC64_CART_USB_DMA_LEN(l) ((((l) - 1) << SC64_CART_USB_DMA_LEN_LENGTH_BIT) & SC64_CART_USB_DMA_LEN_LENGTH_MASK)
|
||||
|
||||
#define SC64_CART_DDIPL_ADDR_ADDRESS_BIT (0)
|
||||
#define SC64_CART_DDIPL_ADDR_ADDRESS_MASK (0x3FFFFFC << SC64_CART_DDIPL_ADDR_ADDRESS_BIT)
|
||||
#define SC64_CART_DDIPL_ADDR_DEFAULT (0x3C00000)
|
||||
|
||||
#define SC64_CART_DDIPL_ADDR(a) (((a) << SC64_CART_DDIPL_ADDR_ADDRESS_BIT) & SC64_CART_DDIPL_ADDR_ADDRESS_MASK)
|
||||
|
||||
#define SC64_CART_SRAM_ADDR_ADDRESS_BIT (0)
|
||||
#define SC64_CART_SRAM_ADDR_ADDRESS_MASK (0x3FFFFFC << SC64_CART_SRAM_ADDR_ADDRESS_BIT)
|
||||
#define SC64_CART_SRAM_ADDR_DEFAULT (0x3FF8000)
|
||||
|
||||
#define SC64_CART_SRAM_ADDR(a) (((a) << SC64_CART_SRAM_ADDR_ADDRESS_BIT) & SC64_CART_SRAM_ADDR_ADDRESS_MASK)
|
||||
|
||||
|
||||
// EEPROM Registers
|
||||
|
||||
typedef struct sc64_eeprom_registers {
|
||||
__IO reg_t MEM[512]; // EEPROM memory
|
||||
} sc64_eeprom_registers_t;
|
||||
|
||||
#define SC64_EEPROM_BASE (0x1E010000)
|
||||
|
||||
#define SC64_EEPROM ((__IO sc64_eeprom_registers_t *) SC64_EEPROM_BASE)
|
||||
|
||||
|
||||
// SD Card Interface Registers
|
||||
|
||||
typedef struct sc64_sd_registers_s {
|
||||
__IO reg_t SCR; // Clock control and bus width selection
|
||||
__IO reg_t ARG; // SD command argument
|
||||
__IO reg_t CMD; // SD command index and flags
|
||||
__IO reg_t RSP; // SD command response
|
||||
__IO reg_t DAT; // SD data path control
|
||||
__IO reg_t DMA_SCR; // DMA status and configuration
|
||||
__IO reg_t DMA_ADDR; // DMA current address
|
||||
__IO reg_t DMA_LEN; // DMA remaining length
|
||||
__IO reg_t ___unused[120];
|
||||
__IO reg_t FIFO[128]; // SD data path FIFO buffer
|
||||
} sc64_sd_registers_t;
|
||||
|
||||
#define SC64_SD_BASE (0x1E020000)
|
||||
|
||||
#define SC64_SD ((__IO sc64_sd_registers_t *) SC64_SD_BASE)
|
||||
|
||||
|
||||
#define SC64_SD_SCR_DAT_WIDTH (1 << 2)
|
||||
#define SC64_SD_SCR_CLK_MASK (0x3 << 0)
|
||||
#define SC64_SD_SCR_CLK_STOP (0 << 0)
|
||||
#define SC64_SD_SCR_CLK_400_KHZ (1 << 0)
|
||||
#define SC64_SD_SCR_CLK_25_MHZ (2 << 0)
|
||||
#define SC64_SD_SCR_CLK_50_MHZ (3 << 0)
|
||||
|
||||
|
||||
#define SC64_SD_CMD_RESPONSE_CRC_ERROR (1 << 8)
|
||||
#define SC64_SD_CMD_TIMEOUT (1 << 7)
|
||||
#define SC64_SD_CMD_BUSY (1 << 6)
|
||||
#define SC64_SD_CMD_INDEX_GET(cmd) ((cmd) & 0x3F)
|
||||
|
||||
#define SC64_SD_CMD_SKIP_RESPONSE (1 << 8)
|
||||
#define SC64_SD_CMD_LONG_RESPONSE (1 << 7)
|
||||
#define SC64_SD_CMD_START (1 << 6)
|
||||
#define SC64_SD_CMD_INDEX(i) ((i) & 0x3F)
|
||||
|
||||
|
||||
#define SC64_SD_DAT_WRITE_OK (1 << 28)
|
||||
#define SC64_SD_DAT_WRITE_ERROR (1 << 27)
|
||||
#define SC64_SD_DAT_WRITE_BUSY (1 << 26)
|
||||
#define SC64_SD_DAT_TX_FIFO_ITEMS_GET(dat) (((dat) >> 17) & 0x1FF)
|
||||
#define SC64_SD_DAT_TX_FIFO_BYTES_GET(dat) (SC64_SD_DAT_TX_FIFO_ITEMS_GET(dat) * 4)
|
||||
#define SC64_SD_DAT_TX_FIFO_FULL (1 << 16)
|
||||
#define SC64_SD_DAT_TX_FIFO_EMPTY (1 << 15)
|
||||
#define SC64_SD_DAT_TX_FIFO_UNDERRUN (1 << 14)
|
||||
#define SC64_SD_DAT_RX_FIFO_ITEMS_GET(dat) (((dat) >> 5) & 0x1FF)
|
||||
#define SC64_SD_DAT_RX_FIFO_BYTES_GET(dat) (SC64_SD_DAT_RX_FIFO_ITEMS_GET(dat) * 4)
|
||||
#define SC64_SD_DAT_RX_FIFO_FULL (1 << 4)
|
||||
#define SC64_SD_DAT_RX_FIFO_EMPTY (1 << 3)
|
||||
#define SC64_SD_DAT_RX_FIFO_OVERRUN (1 << 2)
|
||||
#define SC64_SD_DAT_CRC_ERROR (1 << 1)
|
||||
#define SC64_SD_DAT_BUSY (1 << 0)
|
||||
|
||||
#define SC64_SD_DAT_TX_FIFO_FLUSH (1 << 19)
|
||||
#define SC64_SD_DAT_RX_FIFO_FLUSH (1 << 18)
|
||||
#define SC64_SD_DAT_NUM_BLOCKS(nb) ((((nb) - 1) & 0xFF) << 10)
|
||||
#define SC64_SD_DAT_BLOCK_SIZE(bs) (((((bs) / 4) - 1) & 0x7F) << 3)
|
||||
#define SC64_SD_DAT_DIRECTION (1 << 2)
|
||||
#define SC64_SD_DAT_STOP (1 << 1)
|
||||
#define SC64_SD_DAT_START (1 << 0)
|
||||
|
||||
#define SC64_SD_DAT_FIFO_SIZE_BYTES (1024)
|
||||
#define SC64_SD_DAT_NUM_BLOCKS_MAX (256)
|
||||
#define SC64_SD_DAT_BLOCK_SIZE_MAX (512)
|
||||
|
||||
|
||||
#define SC64_SD_DMA_SCR_BUSY (1 << 0)
|
||||
|
||||
#define SC64_SD_DMA_SCR_DIRECTION (1 << 2)
|
||||
#define SC64_SD_DMA_SCR_STOP (1 << 1)
|
||||
#define SC64_SD_DMA_SCR_START (1 << 0)
|
||||
|
||||
|
||||
#define SC64_SD_DMA_ADDR_GET(addr) ((addr) & 0x3FFFFFC)
|
||||
#define SC64_SD_DMA_BANK_GET(addr) (((addr) >> 28) & 0xF)
|
||||
|
||||
#define SC64_SD_DMA_BANK_ADDR(b, a) ((((b) & 0xF) << 28) | ((a) & 0x3FFFFFC))
|
||||
|
||||
|
||||
#define SC64_SD_DMA_LEN_GET(len) (((len) & 0x7FFF) * 4)
|
||||
|
||||
#define SC64_SD_DMA_LEN(l) ((((l) / 4) - 1) & 0x7FFF)
|
||||
|
||||
#define SC64_SD_DMA_LEN_MAX (0x20000)
|
||||
|
||||
|
||||
#endif
|
@ -1,667 +0,0 @@
|
||||
#include "sc64.h"
|
||||
#include "sc64_sd.h"
|
||||
|
||||
|
||||
#define CMD8_ARG_SUPPLY_VOLTAGE_27_36_V (1 << 8)
|
||||
#define CMD8_ARG_CHECK_PATTERN_AA (0xAA << 0)
|
||||
|
||||
#define ACMD41_ARG_HCS (1 << 30)
|
||||
|
||||
#define R3_CCS (1 << 30)
|
||||
#define R3_BUSY (1 << 31)
|
||||
|
||||
#define R7_SUPPLY_VOLTAGE_27_36_V (1 << 8)
|
||||
#define R7_CHECK_PATTERN_AA (0xAA << 0)
|
||||
|
||||
#define SD_BLOCK_SIZE (512)
|
||||
|
||||
|
||||
typedef enum sc64_sd_clock_e {
|
||||
CLOCK_STOP,
|
||||
CLOCK_400_KHZ,
|
||||
CLOCK_25_MHZ,
|
||||
CLOCK_50_MHZ,
|
||||
} sc64_sd_clock_t;
|
||||
|
||||
typedef enum sc64_sd_dat_width_e {
|
||||
DAT_WIDTH_1BIT,
|
||||
DAT_WIDTH_4BIT,
|
||||
} sc64_sd_dat_width_t;
|
||||
|
||||
typedef enum sc64_sd_cmd_flags_e {
|
||||
NO_FLAGS = 0,
|
||||
ACMD = (1 << 0),
|
||||
SKIP_RESPONSE = (1 << 1),
|
||||
LONG_RESPONSE = (1 << 2),
|
||||
IGNORE_CRC = (1 << 3),
|
||||
IGNORE_INDEX = (1 << 4),
|
||||
} sc64_sd_cmd_flags_t;
|
||||
|
||||
typedef enum sc64_sd_dat_direction_e {
|
||||
DAT_DIR_RX,
|
||||
DAT_DIR_TX,
|
||||
} sc64_sd_dat_direction_t;
|
||||
|
||||
typedef enum sc64_sd_dma_direction_e {
|
||||
DMA_DIR_MEM,
|
||||
DMA_DIR_CARD,
|
||||
} sc64_sd_dma_direction_t;
|
||||
|
||||
|
||||
static bool sd_card_initialized = false;
|
||||
static bool sd_card_type_block = false;
|
||||
static bool sd_card_selected = false;
|
||||
static uint32_t rca = 0;
|
||||
|
||||
|
||||
static void sc64_sd_set_clock(sc64_sd_clock_t clock) {
|
||||
uint32_t scr = platform_pi_io_read(&SC64_SD->SCR);
|
||||
|
||||
scr &= ~SC64_SD_SCR_CLK_MASK;
|
||||
|
||||
switch (clock) {
|
||||
case CLOCK_400_KHZ:
|
||||
scr |= SC64_SD_SCR_CLK_400_KHZ;
|
||||
break;
|
||||
case CLOCK_25_MHZ:
|
||||
scr |= SC64_SD_SCR_CLK_25_MHZ;
|
||||
break;
|
||||
case CLOCK_50_MHZ:
|
||||
scr |= SC64_SD_SCR_CLK_50_MHZ;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
platform_pi_io_write(&SC64_SD->SCR, scr);
|
||||
}
|
||||
|
||||
static void sc64_sd_set_dat_width(sc64_sd_dat_width_t dat_width) {
|
||||
uint32_t scr = platform_pi_io_read(&SC64_SD->SCR);
|
||||
|
||||
scr &= ~SC64_SD_SCR_DAT_WIDTH;
|
||||
|
||||
if (dat_width == DAT_WIDTH_4BIT) {
|
||||
scr |= SC64_SD_SCR_DAT_WIDTH;
|
||||
}
|
||||
|
||||
platform_pi_io_write(&SC64_SD->SCR, scr);
|
||||
}
|
||||
|
||||
static void sc64_sd_hw_reset(void) {
|
||||
while (platform_pi_io_read(&SC64_SD->CMD) & SC64_SD_CMD_BUSY);
|
||||
platform_pi_io_write(&SC64_SD->DMA_SCR, SC64_SD_DMA_SCR_STOP);
|
||||
platform_pi_io_write(&SC64_SD->DAT, SC64_SD_DAT_TX_FIFO_FLUSH | SC64_SD_DAT_RX_FIFO_FLUSH | SC64_SD_DAT_STOP);
|
||||
platform_pi_io_write(&SC64_SD->SCR, 0);
|
||||
}
|
||||
|
||||
static void sc64_sd_hw_init(void) {
|
||||
sc64_enable_sd();
|
||||
sc64_sd_hw_reset();
|
||||
sc64_sd_set_clock(CLOCK_400_KHZ);
|
||||
sc64_sd_set_dat_width(DAT_WIDTH_1BIT);
|
||||
}
|
||||
|
||||
static void sc64_sd_hw_deinit(void) {
|
||||
if (sc64_get_scr() & SC64_CART_SCR_SD_ENABLE) {
|
||||
sc64_sd_hw_reset();
|
||||
}
|
||||
sc64_disable_sd();
|
||||
}
|
||||
|
||||
static sc64_sd_err_t sc64_sd_cmd_send(uint8_t index, uint32_t arg, sc64_sd_cmd_flags_t flags, uint32_t *response) {
|
||||
sc64_sd_err_t error;
|
||||
uint32_t reg;
|
||||
|
||||
if (flags & ACMD) {
|
||||
error = sc64_sd_cmd_send(55, rca, NO_FLAGS, response);
|
||||
|
||||
if (error != E_OK) {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
platform_pi_io_write(&SC64_SD->ARG, arg);
|
||||
|
||||
reg = SC64_SD_CMD_START | SC64_SD_CMD_INDEX(index);
|
||||
|
||||
if (flags & SKIP_RESPONSE) {
|
||||
reg |= SC64_SD_CMD_SKIP_RESPONSE;
|
||||
}
|
||||
|
||||
if (flags & LONG_RESPONSE) {
|
||||
reg |= SC64_SD_CMD_LONG_RESPONSE;
|
||||
}
|
||||
|
||||
platform_pi_io_write(&SC64_SD->CMD, reg);
|
||||
|
||||
do {
|
||||
reg = platform_pi_io_read(&SC64_SD->CMD);
|
||||
} while (reg & SC64_SD_CMD_BUSY);
|
||||
|
||||
*response = platform_pi_io_read(&SC64_SD->RSP);
|
||||
|
||||
if (reg & SC64_SD_CMD_TIMEOUT) {
|
||||
return E_TIMEOUT;
|
||||
}
|
||||
|
||||
if ((!(flags & IGNORE_CRC)) && (!(flags & SKIP_RESPONSE)) && (reg & SC64_SD_CMD_RESPONSE_CRC_ERROR)) {
|
||||
return E_CRC_ERROR;
|
||||
}
|
||||
|
||||
if ((!(flags & SKIP_RESPONSE)) && (!(flags & IGNORE_INDEX)) && (SC64_SD_CMD_INDEX_GET(reg) != index)) {
|
||||
return E_BAD_INDEX;
|
||||
}
|
||||
|
||||
return E_OK;
|
||||
}
|
||||
|
||||
static void sc64_sd_dat_prepare(size_t num_blocks, size_t block_size, sc64_sd_dat_direction_t direction) {
|
||||
uint32_t reg = (
|
||||
SC64_SD_DAT_NUM_BLOCKS(num_blocks) |
|
||||
SC64_SD_DAT_BLOCK_SIZE(block_size) |
|
||||
((direction == DAT_DIR_TX) ? SC64_SD_DAT_DIRECTION : 0) |
|
||||
SC64_SD_DAT_START
|
||||
);
|
||||
|
||||
platform_pi_io_write(&SC64_SD->DAT, reg);
|
||||
}
|
||||
|
||||
static void sc64_sd_dat_abort(void) {
|
||||
uint32_t reg = (
|
||||
SC64_SD_DAT_TX_FIFO_FLUSH |
|
||||
SC64_SD_DAT_RX_FIFO_FLUSH |
|
||||
SC64_SD_DAT_STOP
|
||||
);
|
||||
|
||||
platform_pi_io_write(&SC64_SD->DAT, reg);
|
||||
}
|
||||
|
||||
static sc64_sd_err_t sc64_sd_dat_read(size_t block_size, void *buffer) {
|
||||
int timeout;
|
||||
uint32_t reg;
|
||||
|
||||
timeout = 1000000;
|
||||
do {
|
||||
reg = platform_pi_io_read(&SC64_SD->DAT);
|
||||
if (SC64_SD_DAT_RX_FIFO_BYTES_GET(reg) >= block_size) {
|
||||
break;
|
||||
}
|
||||
} while ((reg & SC64_SD_DAT_BUSY) && (--timeout));
|
||||
|
||||
if (!(reg & SC64_SD_DAT_BUSY)) {
|
||||
if (reg & SC64_SD_DAT_CRC_ERROR) {
|
||||
return E_CRC_ERROR;
|
||||
}
|
||||
|
||||
if (reg & SC64_SD_DAT_RX_FIFO_OVERRUN) {
|
||||
platform_pi_io_write(&SC64_SD->DAT, SC64_SD_DAT_RX_FIFO_FLUSH);
|
||||
|
||||
return E_FIFO_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (timeout == 0) {
|
||||
sc64_sd_dat_abort();
|
||||
|
||||
return E_TIMEOUT;
|
||||
}
|
||||
|
||||
platform_pi_dma_read(buffer, &SC64_SD->FIFO, block_size);
|
||||
platform_cache_invalidate(buffer, block_size);
|
||||
|
||||
return E_OK;
|
||||
}
|
||||
|
||||
static sc64_sd_err_t sc64_sd_dat_write(size_t block_size, void *buffer) {
|
||||
int timeout;
|
||||
uint32_t reg;
|
||||
|
||||
timeout = 1000000;
|
||||
do {
|
||||
reg = platform_pi_io_read(&SC64_SD->DAT);
|
||||
if ((SC64_SD_DAT_FIFO_SIZE_BYTES - SC64_SD_DAT_TX_FIFO_BYTES_GET(reg)) >= block_size) {
|
||||
break;
|
||||
}
|
||||
} while ((reg & SC64_SD_DAT_BUSY) && (--timeout));
|
||||
|
||||
if (timeout == 0) {
|
||||
sc64_sd_dat_abort();
|
||||
|
||||
return E_TIMEOUT;
|
||||
}
|
||||
|
||||
if (!(reg & SC64_SD_DAT_BUSY)) {
|
||||
if (reg & SC64_SD_DAT_CRC_ERROR) {
|
||||
return E_CRC_ERROR;
|
||||
}
|
||||
|
||||
if (reg & SC64_SD_DAT_WRITE_ERROR) {
|
||||
return E_WRITE_ERROR;
|
||||
}
|
||||
|
||||
if (reg & SC64_SD_DAT_TX_FIFO_UNDERRUN) {
|
||||
platform_pi_io_write(&SC64_SD->DAT, SC64_SD_DAT_TX_FIFO_FLUSH);
|
||||
|
||||
return E_FIFO_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
platform_cache_writeback(buffer, block_size);
|
||||
platform_pi_dma_write(buffer, &SC64_SD->FIFO, block_size);
|
||||
|
||||
return E_OK;
|
||||
}
|
||||
|
||||
static void sc64_sd_dma_prepare(size_t num_blocks, size_t block_size, sc64_sd_dma_direction_t direction, uint8_t bank, uint32_t address) {
|
||||
platform_pi_io_write(&SC64_SD->DMA_ADDR, SC64_SD_DMA_BANK_ADDR(bank, address));
|
||||
platform_pi_io_write(&SC64_SD->DMA_LEN, SC64_SD_DMA_LEN(num_blocks * block_size));
|
||||
platform_pi_io_write(&SC64_SD->DMA_SCR, (direction == DMA_DIR_MEM ? SC64_SD_DMA_SCR_DIRECTION : 0) | SC64_SD_DMA_SCR_START);
|
||||
}
|
||||
|
||||
static void sc64_sd_dma_abort(void) {
|
||||
platform_pi_io_write(&SC64_SD->DMA_SCR, SC64_SD_DMA_SCR_STOP);
|
||||
}
|
||||
|
||||
static sc64_sd_err_t sc64_sd_sectors_parameters_check(size_t count, uint8_t *buffer, bool check_buffer) {
|
||||
if (!sd_card_initialized) {
|
||||
return E_NO_INIT;
|
||||
}
|
||||
|
||||
if ((count == 0) || (check_buffer && (buffer == NULL))) {
|
||||
return E_PAR_ERROR;
|
||||
}
|
||||
|
||||
return E_OK;
|
||||
}
|
||||
|
||||
|
||||
bool sc64_sd_init(void) {
|
||||
sc64_sd_err_t error;
|
||||
uint32_t response;
|
||||
uint32_t argument;
|
||||
bool sd_version_2_or_later;
|
||||
uint8_t buffer[64] __attribute__((aligned(16)));
|
||||
|
||||
if (sd_card_initialized) {
|
||||
return true;
|
||||
}
|
||||
|
||||
sc64_sd_hw_init();
|
||||
|
||||
do {
|
||||
error = sc64_sd_cmd_send(0, 0, SKIP_RESPONSE, &response);
|
||||
|
||||
argument = CMD8_ARG_SUPPLY_VOLTAGE_27_36_V | CMD8_ARG_CHECK_PATTERN_AA;
|
||||
error = sc64_sd_cmd_send(8, argument, NO_FLAGS, &response);
|
||||
sd_version_2_or_later = (error == E_OK);
|
||||
if (sd_version_2_or_later && (response != (R7_SUPPLY_VOLTAGE_27_36_V | R7_CHECK_PATTERN_AA))) {
|
||||
break;
|
||||
}
|
||||
|
||||
argument = (sd_version_2_or_later ? ACMD41_ARG_HCS : 0) | 0x00FF8000;
|
||||
for (int i = 0; i < 4000; i++) {
|
||||
error = sc64_sd_cmd_send(41, argument, ACMD | IGNORE_CRC | IGNORE_INDEX, &response);
|
||||
if ((error != E_OK) || (response & R3_BUSY)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((error != E_OK) || ((response & 0x00FF8000) == 0)) {
|
||||
break;
|
||||
}
|
||||
sd_card_type_block = (response & R3_CCS) ? true : false;
|
||||
|
||||
error = sc64_sd_cmd_send(2, 0, LONG_RESPONSE | IGNORE_INDEX, &response);
|
||||
if (error != E_OK) {
|
||||
break;
|
||||
}
|
||||
|
||||
error = sc64_sd_cmd_send(3, 0, NO_FLAGS, &response);
|
||||
if (error != E_OK) {
|
||||
break;
|
||||
}
|
||||
rca = response & 0xFFFF0000;
|
||||
|
||||
error = sc64_sd_cmd_send(7, rca, NO_FLAGS, &response);
|
||||
if (error != E_OK) {
|
||||
break;
|
||||
}
|
||||
sd_card_selected = true;
|
||||
|
||||
error = sc64_sd_cmd_send(6, 2, ACMD, &response);
|
||||
if (error != E_OK) {
|
||||
break;
|
||||
}
|
||||
|
||||
sc64_sd_set_clock(CLOCK_25_MHZ);
|
||||
sc64_sd_set_dat_width(DAT_WIDTH_4BIT);
|
||||
|
||||
sc64_sd_dat_prepare(1, 64, DAT_DIR_RX);
|
||||
error = sc64_sd_cmd_send(6, 0x00000001, NO_FLAGS, &response);
|
||||
if (error != E_OK) {
|
||||
sc64_sd_dat_abort();
|
||||
break;
|
||||
}
|
||||
error = sc64_sd_dat_read(64, buffer);
|
||||
if (error != E_OK) {
|
||||
break;
|
||||
}
|
||||
if (buffer[13] & 0x02) {
|
||||
sc64_sd_dat_prepare(1, 64, DAT_DIR_RX);
|
||||
error = sc64_sd_cmd_send(6, 0x80000001, NO_FLAGS, &response);
|
||||
if (error != E_OK) {
|
||||
sc64_sd_dat_abort();
|
||||
break;
|
||||
}
|
||||
error = sc64_sd_dat_read(64, buffer);
|
||||
if (error != E_OK) {
|
||||
break;
|
||||
}
|
||||
|
||||
sc64_sd_set_clock(CLOCK_50_MHZ);
|
||||
}
|
||||
|
||||
sd_card_initialized = true;
|
||||
|
||||
return true;
|
||||
} while(0);
|
||||
|
||||
sc64_sd_deinit();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void sc64_sd_deinit(void) {
|
||||
uint32_t response;
|
||||
|
||||
if (sd_card_selected) {
|
||||
sc64_sd_cmd_send(7, rca, NO_FLAGS, &response);
|
||||
|
||||
sd_card_selected = false;
|
||||
}
|
||||
|
||||
sc64_sd_cmd_send(0, 0, SKIP_RESPONSE, &response);
|
||||
|
||||
sc64_sd_hw_deinit();
|
||||
}
|
||||
|
||||
bool sc64_sd_status_get(void) {
|
||||
return sd_card_initialized;
|
||||
}
|
||||
|
||||
sc64_sd_err_t sc64_sd_sectors_read(uint32_t starting_sector, size_t count, uint8_t *buffer) {
|
||||
sc64_sd_err_t error;
|
||||
uint32_t response;
|
||||
uint32_t current_sector;
|
||||
|
||||
error = sc64_sd_sectors_parameters_check(count, buffer, true);
|
||||
if (error != E_OK) {
|
||||
return error;
|
||||
}
|
||||
|
||||
current_sector = starting_sector;
|
||||
if (!sd_card_type_block) {
|
||||
current_sector *= SD_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
sc64_sd_dat_prepare(1, SD_BLOCK_SIZE, DAT_DIR_RX);
|
||||
|
||||
error = sc64_sd_cmd_send(17, current_sector, NO_FLAGS, &response);
|
||||
if (error != E_OK) {
|
||||
sc64_sd_dat_abort();
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
error = sc64_sd_dat_read(SD_BLOCK_SIZE, buffer);
|
||||
if (error != E_OK) {
|
||||
return error;
|
||||
}
|
||||
|
||||
buffer += SD_BLOCK_SIZE;
|
||||
current_sector += sd_card_type_block ? 1 : SD_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
return E_OK;
|
||||
}
|
||||
|
||||
sc64_sd_err_t sc64_sd_sectors_write(uint32_t starting_sector, size_t count, uint8_t *buffer) {
|
||||
sc64_sd_err_t error;
|
||||
sc64_sd_err_t write_error;
|
||||
uint32_t response;
|
||||
uint32_t current_sector;
|
||||
size_t sectors_remaining;
|
||||
size_t num_blocks;
|
||||
|
||||
error = sc64_sd_sectors_parameters_check(count, buffer, true);
|
||||
if (error != E_OK) {
|
||||
return error;
|
||||
}
|
||||
|
||||
current_sector = starting_sector;
|
||||
if (!sd_card_type_block) {
|
||||
current_sector *= SD_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
sectors_remaining = count;
|
||||
|
||||
while (sectors_remaining) {
|
||||
num_blocks = (sectors_remaining > SC64_SD_DAT_NUM_BLOCKS_MAX) ? SC64_SD_DAT_NUM_BLOCKS_MAX : sectors_remaining;
|
||||
|
||||
sc64_sd_dat_prepare(num_blocks, SD_BLOCK_SIZE, DAT_DIR_TX);
|
||||
|
||||
error = sc64_sd_cmd_send(25, current_sector, NO_FLAGS, &response);
|
||||
if (error != E_OK) {
|
||||
sc64_sd_dat_abort();
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < num_blocks; i++) {
|
||||
write_error = sc64_sd_dat_write(SD_BLOCK_SIZE, buffer);
|
||||
if (write_error != E_OK) {
|
||||
break;
|
||||
}
|
||||
|
||||
buffer += SD_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
error = sc64_sd_dat_busy_wait();
|
||||
if (error != E_OK) {
|
||||
sc64_sd_dat_abort();
|
||||
return error;
|
||||
}
|
||||
|
||||
error = sc64_sd_cmd_send(12, 0, NO_FLAGS, &response);
|
||||
if (error != E_OK) {
|
||||
return error;
|
||||
}
|
||||
|
||||
error = sc64_sd_dat_busy_wait();
|
||||
if (error != E_OK) {
|
||||
return error;
|
||||
}
|
||||
|
||||
if (write_error != E_OK) {
|
||||
return write_error;
|
||||
}
|
||||
|
||||
current_sector += num_blocks * (sd_card_type_block ? 1 : SD_BLOCK_SIZE);
|
||||
sectors_remaining -= num_blocks;
|
||||
}
|
||||
|
||||
return E_OK;
|
||||
}
|
||||
|
||||
sc64_sd_err_t sc64_sd_sectors_read_dma(uint32_t starting_sector, size_t count, uint8_t bank, uint32_t address) {
|
||||
size_t sectors_left;
|
||||
uint32_t current_sector;
|
||||
uint32_t current_address;
|
||||
uint32_t num_blocks;
|
||||
uint32_t reg;
|
||||
sc64_sd_err_t error;
|
||||
uint32_t response;
|
||||
int timeout;
|
||||
|
||||
error = sc64_sd_sectors_parameters_check(count, NULL, false);
|
||||
if (error != E_OK) {
|
||||
return error;
|
||||
}
|
||||
|
||||
sectors_left = count;
|
||||
current_sector = starting_sector;
|
||||
if (!sd_card_type_block) {
|
||||
current_sector *= SD_BLOCK_SIZE;
|
||||
}
|
||||
current_address = address;
|
||||
|
||||
do {
|
||||
num_blocks = (sectors_left > SC64_SD_DAT_NUM_BLOCKS_MAX) ? SC64_SD_DAT_NUM_BLOCKS_MAX : sectors_left;
|
||||
|
||||
sc64_sd_dma_prepare(num_blocks, SD_BLOCK_SIZE, DMA_DIR_MEM, bank, current_address);
|
||||
sc64_sd_dat_prepare(num_blocks, SD_BLOCK_SIZE, DAT_DIR_RX);
|
||||
|
||||
error = sc64_sd_cmd_send(18, current_sector, NO_FLAGS, &response);
|
||||
if (error != E_OK) {
|
||||
sc64_sd_dat_abort();
|
||||
sc64_sd_dma_abort();
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
timeout = 1000000;
|
||||
do {
|
||||
reg = platform_pi_io_read(&SC64_SD->DAT);
|
||||
} while ((reg & SC64_SD_DAT_BUSY) && (--timeout));
|
||||
|
||||
error = sc64_sd_cmd_send(12, 0, NO_FLAGS, &response);
|
||||
if (error != E_OK) {
|
||||
sc64_sd_dat_abort();
|
||||
sc64_sd_dma_abort();
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
if (reg & SC64_SD_DAT_CRC_ERROR) {
|
||||
sc64_sd_dma_abort();
|
||||
|
||||
return E_CRC_ERROR;
|
||||
}
|
||||
|
||||
if (reg & SC64_SD_DAT_RX_FIFO_OVERRUN) {
|
||||
platform_pi_io_write(&SC64_SD->DAT, SC64_SD_DAT_RX_FIFO_FLUSH);
|
||||
sc64_sd_dma_abort();
|
||||
|
||||
return E_FIFO_ERROR;
|
||||
}
|
||||
|
||||
if (timeout == 0) {
|
||||
sc64_sd_dat_abort();
|
||||
sc64_sd_dma_abort();
|
||||
|
||||
return E_TIMEOUT;
|
||||
}
|
||||
|
||||
while (platform_pi_io_read(&SC64_SD->DMA_SCR) & SC64_SD_DMA_SCR_BUSY);
|
||||
|
||||
sectors_left -= num_blocks;
|
||||
current_sector += num_blocks * (sd_card_type_block ? 1 : SD_BLOCK_SIZE);
|
||||
current_address += num_blocks * SD_BLOCK_SIZE;
|
||||
} while (sectors_left > 0);
|
||||
|
||||
return E_OK;
|
||||
}
|
||||
|
||||
// sc64_sd_err_t sc64_sd_sectors_write_dma(uint32_t starting_sector, size_t count, uint8_t bank, uint32_t address) {
|
||||
// size_t sectors_left;
|
||||
// uint32_t current_sector;
|
||||
// uint32_t current_address;
|
||||
// uint32_t num_blocks;
|
||||
// uint32_t reg;
|
||||
// sc64_sd_err_t error;
|
||||
// uint32_t response;
|
||||
// int timeout;
|
||||
|
||||
// error = sc64_sd_sectors_parameters_check(count, NULL, false);
|
||||
// if (error != E_OK) {
|
||||
// return error;
|
||||
// }
|
||||
|
||||
// sectors_left = count;
|
||||
// current_sector = starting_sector;
|
||||
// if (!sd_card_type_block) {
|
||||
// current_sector *= SD_BLOCK_SIZE;
|
||||
// }
|
||||
// current_address = address;
|
||||
|
||||
// do {
|
||||
// num_blocks = (sectors_left > SC64_SD_DAT_NUM_BLOCKS_MAX) ? SC64_SD_DAT_NUM_BLOCKS_MAX : sectors_left;
|
||||
|
||||
// sc64_sd_dat_prepare(num_blocks, SD_BLOCK_SIZE, DAT_DIR_TX);
|
||||
// sc64_sd_dma_prepare(num_blocks, SD_BLOCK_SIZE, DMA_DIR_CARD, bank, current_address);
|
||||
|
||||
// error = sc64_sd_cmd_send(25, current_sector, NO_FLAGS, &response);
|
||||
// if (error != E_OK) {
|
||||
// sc64_sd_dma_abort();
|
||||
// sc64_sd_dat_abort();
|
||||
|
||||
// return error;
|
||||
// }
|
||||
|
||||
// timeout = 1000000;
|
||||
// do {
|
||||
// reg = platform_pi_io_read(&SC64_SD->DAT);
|
||||
// } while ((reg & SC64_SD_DAT_BUSY) && (--timeout));
|
||||
|
||||
// error = sc64_sd_cmd_send(12, 0, NO_FLAGS, &response);
|
||||
// if (error != E_OK) {
|
||||
// sc64_sd_dma_abort();
|
||||
// sc64_sd_dat_abort();
|
||||
|
||||
// return error;
|
||||
// }
|
||||
|
||||
// if (reg & SC64_SD_DAT_CRC_ERROR) {
|
||||
// sc64_sd_dma_abort();
|
||||
|
||||
// return E_CRC_ERROR;
|
||||
// }
|
||||
|
||||
// if (reg & SC64_SD_DAT_TX_FIFO_UNDERRUN) {
|
||||
// sc64_sd_dma_abort();
|
||||
// platform_pi_io_write(&SC64_SD->DAT, SC64_SD_DAT_TX_FIFO_FLUSH);
|
||||
|
||||
// return E_FIFO_ERROR;
|
||||
// }
|
||||
|
||||
// if (timeout == 0) {
|
||||
// sc64_sd_dma_abort();
|
||||
// sc64_sd_dat_abort();
|
||||
|
||||
// return E_TIMEOUT;
|
||||
// }
|
||||
|
||||
// sectors_left -= num_blocks;
|
||||
// current_sector += num_blocks * (sd_card_type_block ? 1 : SD_BLOCK_SIZE);
|
||||
// current_address += num_blocks * SD_BLOCK_SIZE;
|
||||
// } while (sectors_left > 0);
|
||||
|
||||
// return E_OK;
|
||||
// }
|
||||
|
||||
sc64_sd_err_t sc64_sd_dat_busy_wait(void) {
|
||||
int timeout;
|
||||
uint32_t reg;
|
||||
|
||||
timeout = 1000000;
|
||||
do {
|
||||
reg = platform_pi_io_read(&SC64_SD->DAT);
|
||||
} while ((reg & (SC64_SD_DAT_WRITE_BUSY | SC64_SD_DAT_BUSY)) && (--timeout));
|
||||
|
||||
if (timeout == 0) {
|
||||
return E_TIMEOUT;
|
||||
}
|
||||
|
||||
return E_OK;
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
#ifndef SC64_SD_H__
|
||||
#define SC64_SD_H__
|
||||
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
|
||||
typedef enum sc64_sd_err_e {
|
||||
E_OK,
|
||||
E_TIMEOUT,
|
||||
E_CRC_ERROR,
|
||||
E_BAD_INDEX,
|
||||
E_PAR_ERROR,
|
||||
E_FIFO_ERROR,
|
||||
E_WRITE_ERROR,
|
||||
E_NO_INIT,
|
||||
} sc64_sd_err_t;
|
||||
|
||||
|
||||
bool sc64_sd_init(void);
|
||||
void sc64_sd_deinit(void);
|
||||
bool sc64_sd_status_get(void);
|
||||
sc64_sd_err_t sc64_sd_sectors_read(uint32_t starting_sector, size_t count, uint8_t *buffer);
|
||||
sc64_sd_err_t sc64_sd_sectors_write(uint32_t starting_sector, size_t count, uint8_t *buffer);
|
||||
sc64_sd_err_t sc64_sd_sectors_read_dma(uint32_t starting_sector, size_t count, uint8_t bank, uint32_t address);
|
||||
// sc64_sd_err_t sc64_sd_sectors_write_dma(uint32_t starting_sector, size_t count, uint8_t bank, uint32_t address);
|
||||
sc64_sd_err_t sc64_sd_dat_busy_wait(void);
|
||||
|
||||
|
||||
#endif
|
@ -1,228 +0,0 @@
|
||||
#include "ff.h"
|
||||
#include "diskio.h"
|
||||
|
||||
#include "sc64.h"
|
||||
#include "sc64_sd.h"
|
||||
#include "sc64_sd_fs.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
static uint8_t current_bank = SC64_BANK_INVALID;
|
||||
static uint32_t current_offset = 0;
|
||||
static uint8_t save_buffer[128 * 1024] __attribute__((aligned(16)));
|
||||
static bool fs_initialized = false;
|
||||
static FATFS fatfs;
|
||||
|
||||
|
||||
static DRESULT sc64_sd_fs_load_with_dma(BYTE pdrv, FSIZE_t offset, LBA_t sector, UINT count) {
|
||||
sc64_sd_err_t error;
|
||||
|
||||
if (pdrv > 0) {
|
||||
return RES_PARERR;
|
||||
}
|
||||
|
||||
error = sc64_sd_sectors_read_dma(sector, count, current_bank, current_offset + offset);
|
||||
|
||||
if (error != E_OK) {
|
||||
switch (error) {
|
||||
case E_NO_INIT:
|
||||
return RES_NOTRDY;
|
||||
case E_PAR_ERROR:
|
||||
return RES_PARERR;
|
||||
default:
|
||||
return RES_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return RES_OK;
|
||||
}
|
||||
|
||||
|
||||
sc64_sd_fs_error_t sc64_sd_fs_init(void) {
|
||||
FRESULT fresult;
|
||||
|
||||
fresult = f_mount(&fatfs, "", 1);
|
||||
if (fresult != FR_OK) {
|
||||
switch (fresult) {
|
||||
case FR_DISK_ERR:
|
||||
return SC64_SD_FS_READ_ERROR;
|
||||
case FR_NOT_READY:
|
||||
return SC64_SD_FS_NO_CARD;
|
||||
case FR_NO_FILESYSTEM:
|
||||
return SC64_SD_FS_NO_FILESYSTEM;
|
||||
default:
|
||||
return SC64_SD_FS_OTHER_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
fs_initialized = true;
|
||||
|
||||
return SC64_SD_FS_OK;
|
||||
}
|
||||
|
||||
void sc64_sd_fs_deinit(void) {
|
||||
if (fs_initialized) {
|
||||
f_unmount("");
|
||||
}
|
||||
|
||||
sc64_sd_deinit();
|
||||
}
|
||||
|
||||
sc64_sd_fs_error_t sc64_sd_fs_load_config(const char *path, sc64_sd_fs_config_t *config) {
|
||||
FRESULT fresult;
|
||||
FIL fil;
|
||||
char config_buffer[256];
|
||||
|
||||
fresult = f_open(&fil, path, FA_READ);
|
||||
if (fresult != FR_OK) {
|
||||
switch (fresult) {
|
||||
case FR_DISK_ERR:
|
||||
case FR_NOT_READY:
|
||||
return SC64_SD_FS_READ_ERROR;
|
||||
case FR_NO_FILE:
|
||||
case FR_NO_PATH:
|
||||
return SC64_SD_FS_NO_FILE;
|
||||
default:
|
||||
return SC64_SD_FS_OTHER_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
while (!f_eof(&fil)) {
|
||||
char *line = f_gets(config_buffer, sizeof(config_buffer), &fil);
|
||||
|
||||
if (line == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (strncmp("rom=", line, 4) == 0) {
|
||||
strncpy(config->rom, line + 4, sizeof(config_buffer) - 4);
|
||||
} else if (strncmp("rom_reload=", line, 11) == 0) {
|
||||
config->rom_reload = line[11] != '0';
|
||||
} else if (strncmp("save=", line, 5) == 0) {
|
||||
strncpy(config->save, line + 5, sizeof(config_buffer) - 5);
|
||||
} else if (strncmp("save_type=", line, 10) == 0) {
|
||||
config->save_type = (uint8_t) strtol(line + 10, NULL, 10);
|
||||
} else if (strncmp("save_writeback=", line, 15) == 0) {
|
||||
config->save_writeback = line[15] != '0';
|
||||
} else if (strncmp("cic_seed=", line, 9) == 0) {
|
||||
config->cic_seed = (uint16_t) strtoul(line + 9, NULL, 16);
|
||||
} else if (strncmp("tv_type=", line, 8) == 0) {
|
||||
config->tv_type = (tv_type_t) strtol(line + 8, NULL, 10);
|
||||
}
|
||||
}
|
||||
|
||||
fresult = f_close(&fil);
|
||||
if (fresult != FR_OK) {
|
||||
return SC64_SD_FS_OTHER_ERROR;
|
||||
}
|
||||
|
||||
return SC64_SD_FS_OK;
|
||||
}
|
||||
|
||||
sc64_sd_fs_error_t sc64_sd_fs_load_rom(const char *path) {
|
||||
FRESULT fresult;
|
||||
|
||||
current_bank = SC64_BANK_SDRAM;
|
||||
current_offset = 0;
|
||||
|
||||
fresult = fe_load(path, SC64_SDRAM_SIZE, sc64_sd_fs_load_with_dma);
|
||||
if (fresult != FR_OK) {
|
||||
switch (fresult) {
|
||||
case FR_DISK_ERR:
|
||||
case FR_NOT_READY:
|
||||
return SC64_SD_FS_READ_ERROR;
|
||||
case FR_NO_FILE:
|
||||
case FR_NO_PATH:
|
||||
return SC64_SD_FS_NO_FILE;
|
||||
default:
|
||||
return SC64_SD_FS_OTHER_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return SC64_SD_FS_OK;
|
||||
}
|
||||
|
||||
sc64_sd_fs_error_t sc64_sd_fs_load_save(const char *path) {
|
||||
FRESULT fresult;
|
||||
uint32_t scr;
|
||||
size_t length;
|
||||
|
||||
scr = sc64_get_scr();
|
||||
length = 0;
|
||||
|
||||
if (scr & SC64_CART_SCR_EEPROM_ENABLE) {
|
||||
length = (scr & SC64_CART_SCR_EEPROM_16K_MODE) ? 2048 : 512;
|
||||
current_bank = SC64_BANK_EEPROM;
|
||||
current_offset = 0;
|
||||
} else if (scr & (SC64_CART_SCR_SRAM_ENABLE | SC64_CART_SCR_FLASHRAM_ENABLE)) {
|
||||
length = 128 * 1024;
|
||||
current_bank = SC64_BANK_SDRAM;
|
||||
current_offset = sc64_get_save_address();
|
||||
}
|
||||
|
||||
if ((length == 0) || (path == NULL)) {
|
||||
return SC64_SD_FS_OK;
|
||||
}
|
||||
|
||||
fresult = fe_load(path, length, sc64_sd_fs_load_with_dma);
|
||||
if (fresult != FR_OK) {
|
||||
switch (fresult) {
|
||||
case FR_DISK_ERR:
|
||||
case FR_NOT_READY:
|
||||
return SC64_SD_FS_READ_ERROR;
|
||||
case FR_NO_FILE:
|
||||
case FR_NO_PATH:
|
||||
return SC64_SD_FS_NO_FILE;
|
||||
default:
|
||||
return SC64_SD_FS_OTHER_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return SC64_SD_FS_OK;
|
||||
}
|
||||
|
||||
sc64_sd_fs_error_t sc64_sd_fs_store_save(const char *path) {
|
||||
FRESULT fresult;
|
||||
FIL fil;
|
||||
UINT written;
|
||||
uint32_t scr;
|
||||
size_t length;
|
||||
|
||||
scr = sc64_get_scr();
|
||||
length = 0;
|
||||
|
||||
if (scr & SC64_CART_SCR_EEPROM_ENABLE) {
|
||||
sc64_enable_eeprom_pi();
|
||||
length = (scr & SC64_CART_SCR_EEPROM_16K_MODE) ? 2048 : 512;
|
||||
platform_pi_dma_read(save_buffer, &SC64_EEPROM->MEM, length);
|
||||
platform_cache_invalidate(save_buffer, length);
|
||||
sc64_disable_eeprom_pi();
|
||||
} else if (scr & (SC64_CART_SCR_SRAM_ENABLE | SC64_CART_SCR_FLASHRAM_ENABLE)) {
|
||||
length = 128 * 1024;
|
||||
platform_pi_dma_read(save_buffer, sc64_get_save_address(), length);
|
||||
platform_cache_invalidate(save_buffer, length);
|
||||
}
|
||||
|
||||
if ((length == 0) || (path == NULL)) {
|
||||
return SC64_SD_FS_OK;
|
||||
}
|
||||
|
||||
fresult = f_open(&fil, path, FA_CREATE_ALWAYS | FA_WRITE);
|
||||
if (fresult != FR_OK) {
|
||||
return SC64_SD_FS_WRITE_ERROR;
|
||||
}
|
||||
|
||||
fresult = f_write(&fil, save_buffer, length, &written);
|
||||
if (fresult != FR_OK) {
|
||||
return SC64_SD_FS_WRITE_ERROR;
|
||||
}
|
||||
|
||||
fresult = f_close(&fil);
|
||||
if (fresult != FR_OK) {
|
||||
return SC64_SD_FS_WRITE_ERROR;
|
||||
}
|
||||
|
||||
return SC64_SD_FS_OK;
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
#ifndef SC64_SD_FS_H__
|
||||
#define SC64_SD_FS_H__
|
||||
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
|
||||
typedef enum sc64_sd_fs_error_e {
|
||||
SC64_SD_FS_OK,
|
||||
SC64_SD_FS_NO_CARD,
|
||||
SC64_SD_FS_NO_FILESYSTEM,
|
||||
SC64_SD_FS_NO_FILE,
|
||||
SC64_SD_FS_READ_ERROR,
|
||||
SC64_SD_FS_OTHER_ERROR,
|
||||
SC64_SD_FS_WRITE_ERROR,
|
||||
} sc64_sd_fs_error_t;
|
||||
|
||||
|
||||
typedef struct sc64_sd_fs_config_s {
|
||||
char *rom;
|
||||
char *save;
|
||||
uint8_t save_type;
|
||||
bool save_writeback;
|
||||
bool rom_reload;
|
||||
uint16_t cic_seed;
|
||||
tv_type_t tv_type;
|
||||
} sc64_sd_fs_config_t;
|
||||
|
||||
|
||||
sc64_sd_fs_error_t sc64_sd_fs_init(void);
|
||||
void sc64_sd_fs_deinit(void);
|
||||
sc64_sd_fs_error_t sc64_sd_fs_load_config(const char *path, sc64_sd_fs_config_t *config);
|
||||
sc64_sd_fs_error_t sc64_sd_fs_load_rom(const char *path);
|
||||
sc64_sd_fs_error_t sc64_sd_fs_load_save(const char *path);
|
||||
sc64_sd_fs_error_t sc64_sd_fs_store_save(const char *path);
|
||||
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user