diff --git a/firmware/CMakeLists.txt b/firmware/CMakeLists.txt index 0349444f..bcfd9ed2 100644 --- a/firmware/CMakeLists.txt +++ b/firmware/CMakeLists.txt @@ -26,7 +26,6 @@ set(CHIBIOS ${PROJECT_SOURCE_DIR}/chibios) set(CHIBIOS_PORTAPACK ${PROJECT_SOURCE_DIR}/chibios-portapack) set(EXTRACT_CPLD_DATA ${PROJECT_SOURCE_DIR}/tools/extract_cpld_data.py) -set(EXTRACT_SVF_DATA_XC2C64A ${PROJECT_SOURCE_DIR}/tools/extract_svf_data_xc2c64a.py) set(STRIP_DFU ${PROJECT_SOURCE_DIR}/tools/strip_dfu.py) set(MAKE_SPI_IMAGE ${PROJECT_SOURCE_DIR}/tools/make_spi_image.py) set(MAKE_IMAGE_CHUNK ${PROJECT_SOURCE_DIR}/tools/make_image_chunk.py) @@ -40,7 +39,7 @@ ExternalProject_Add(hackrf GIT_REPOSITORY https://github.com/jboone/hackrf.git # SOURCE_SUBDIR firmware # SOURCE_SUBDIR isn't available in CMake 3.5 (Ubuntu 16.04 LTS), so the following is a work-around: - CONFIGURE_COMMAND ${CMAKE_COMMAND} -DUSER_INTERFACE=PORTAPACK "-GUnix Makefiles" ../hackrf/firmware + CONFIGURE_COMMAND ${CMAKE_COMMAND} "-GUnix Makefiles" ../hackrf/firmware BUILD_COMMAND ${MAKE_EXE} hackrf_usb.dfu INSTALL_COMMAND "" ) @@ -54,8 +53,9 @@ set(HACKRF_FIRMWARE_BIN_FILENAME hackrf_usb.bin) set(HACKRF_FIRMWARE_DFU_IMAGE ${hackrf_BINARY_DIR}/hackrf_usb/${HACKRF_FIRMWARE_DFU_FILENAME}) set(HACKRF_FIRMWARE_BIN_IMAGE ${hackrf_BINARY_DIR}/hackrf_usb/${HACKRF_FIRMWARE_BIN_FILENAME}) -set(HACKRF_CPLD_SVF_FILENAME default.svf) -set(HACKRF_CPLD_SVF_PATH ${hackrf_SOURCE_DIR}/firmware/cpld/sgpio_if/${HACKRF_CPLD_SVF_FILENAME}) +set(HACKRF_CPLD_TOOL ${hackrf_SOURCE_DIR}/firmware/tools/cpld_bitstream.py) +set(HACKRF_CPLD_XSVF_FILENAME default.xsvf) +set(HACKRF_CPLD_XSVF_PATH ${hackrf_SOURCE_DIR}/firmware/cpld/sgpio_if/${HACKRF_CPLD_XSVF_FILENAME}) add_subdirectory(application) add_subdirectory(baseband) diff --git a/firmware/application/CMakeLists.txt b/firmware/application/CMakeLists.txt index aa2e721f..9149c88f 100644 --- a/firmware/application/CMakeLists.txt +++ b/firmware/application/CMakeLists.txt @@ -404,9 +404,9 @@ add_custom_command( ) add_custom_command( - OUTPUT ${HACKRF_CPLD_DATA_HPP} ${HACKRF_CPLD_DATA_CPP} - COMMAND ${EXTRACT_SVF_DATA_XC2C64A} ${HACKRF_CPLD_SVF_PATH} hackrf::one::cpld::verify_blocks ${HACKRF_CPLD_DATA_CPP} - DEPENDS ${EXTRACT_SVF_DATA_XC2C64A} hackrf + OUTPUT ${HACKRF_CPLD_DATA_CPP} + COMMAND ${HACKRF_CPLD_TOOL} --xsvf ${HACKRF_CPLD_XSVF_PATH} --portapack-data ${HACKRF_CPLD_DATA_CPP} + DEPENDS ${HACKRF_CPLD_TOOL} ${HACKRF_CPLD_XSVF_PATH} hackrf ) add_executable(${PROJECT_NAME}.elf ${CSRC} ${CPPSRC} ${ASMSRC}) diff --git a/firmware/application/portapack.cpp b/firmware/application/portapack.cpp index 04016b69..50872d9e 100644 --- a/firmware/application/portapack.cpp +++ b/firmware/application/portapack.cpp @@ -311,6 +311,12 @@ bool init() { return false; } + if( !hackrf::cpld::load_sram() ) { + chSysHalt(); + } + + configure_pins_portapack(); + portapack::io.init(); clock_manager.init_clock_generator(); diff --git a/firmware/baseband/CMakeLists.txt b/firmware/baseband/CMakeLists.txt index b56cae86..a31bd07e 100644 --- a/firmware/baseband/CMakeLists.txt +++ b/firmware/baseband/CMakeLists.txt @@ -471,7 +471,7 @@ DeclareTargets(PWFM wfm_audio) add_custom_command( OUTPUT hackrf.bin hackrf.img COMMAND ${STRIP_DFU} ${HACKRF_FIRMWARE_DFU_IMAGE} hackrf.bin - COMMAND ${MAKE_IMAGE_CHUNK} hackrf.bin HRF1 hackrf.img + COMMAND ${MAKE_IMAGE_CHUNK} hackrf.bin HRF1 hackrf.img 98304 DEPENDS hackrf ${STRIP_DFU} ${MAKE_IMAGE_CHUNK} VERBATIM ) diff --git a/firmware/chibios-portapack/boards/PORTAPACK_APPLICATION/board.cpp b/firmware/chibios-portapack/boards/PORTAPACK_APPLICATION/board.cpp index c64bd8d2..fbfe664b 100755 --- a/firmware/chibios-portapack/boards/PORTAPACK_APPLICATION/board.cpp +++ b/firmware/chibios-portapack/boards/PORTAPACK_APPLICATION/board.cpp @@ -50,128 +50,199 @@ const PALConfig pal_default_config = { .P = { { // GPIO0 .data - = (1 << 15) // CS_XCVR - | (1 << 14) // AMP_BYPASS - | (0 << 9) // 10K PD, BOOT1 - | (1 << 8) // 10K PU, BOOT0 + = (1 << 15) // P1_20: CS_XCVR + | (1 << 14) // P2_10: AMP_BYPASS + | (0 << 13) // P1_18: SGPIO12, HOST_Q_INVERT + | (0 << 12) // P1_17: SGPIO11, HOST_DIRECTION + | (1 << 11) // P1_4: SSP1_MOSI + | (1 << 10) // P1_3: SSP1_MISO + | (0 << 9) // P1_2: 10K PD, BOOT1 + | (1 << 8) // P1_1: 10K PU, BOOT0 + | (1 << 7) // P2_7: 10K PU, ISP + | (0 << 6) // P3_6: SPIFI_MISO + | (1 << 5) // P6_6: SGPIO5, HOST_DATA5 + | (1 << 4) // P1_0: SGPIO7, HOST_DATA7 + | (1 << 3) // P1_16: SGPIO3, HOST_DATA3 + | (1 << 2) // P1_15: SGPIO2, HOST_DATA2 + | (1 << 1) // P0_1: SGPIO1, HOST_DATA1 + | (1 << 0) // P0_0: SGPIO0, HOST_DATA0 , .dir - = (1 << 15) // CS_XCVR - | (1 << 14) // AMP_BYPASS - | (0 << 9) // 10K PD, BOOT1 - | (0 << 8) // 10K PU, BOOT0 + = (1 << 15) // P1_20: CS_XCVR + | (1 << 14) // P2_10: AMP_BYPASS + | (1 << 13) // P1_18: SGPIO12, HOST_Q_INVERT + | (0 << 12) // P1_17: SGPIO11, HOST_DIRECTION + | (0 << 11) // P1_4: SSP1_MOSI + | (0 << 10) // P1_3: SSP1_MISO + | (0 << 9) // P1_2: 10K PD, BOOT1 + | (0 << 8) // P1_1: 10K PU, BOOT0 + | (0 << 7) // P2_7: 10K PU, ISP + | (0 << 6) // P3_6: SPIFI_MISO + | (0 << 5) // P6_6: SGPIO5, HOST_DATA5 + | (0 << 4) // P1_0: SGPIO7, HOST_DATA7 + | (0 << 3) // P1_16: SGPIO3, HOST_DATA3 + | (0 << 2) // P1_15: SGPIO2, HOST_DATA2 + | (0 << 1) // P0_1: SGPIO1, HOST_DATA1 + | (0 << 0) // P0_0: SGPIO0, HOST_DATA0 }, { // GPIO1 .data - = (1 << 13) // PortaPack P2_13/DIR - | (1 << 12) // !RX_AMP_PWR - | (0 << 11) // RX_AMP - | (1 << 10) // 10K PD, BOOT3, PortaPack P2_9/LCD_WRX - | (1 << 8) // PortaPack CPLD.TDO(O) - | (1 << 1) // PortaPack CPLD.TMS(I) - | (0 << 0) // !MIX_BYPASS + = (1 << 15) // P3_5: SPIFI_SIO2 + | (1 << 14) // P3_4: SPIFI_SIO3 + | (1 << 13) // P2_13: PortaPack DIR + | (1 << 12) // P2_12: !RX_AMP_PWR + | (0 << 11) // P2_11: RX_AMP + | (0 << 10) // P2_9: 10K PD, BOOT3, PortaPack LCD_WRX + | (1 << 9) // P1_6: SD_CMD + | (1 << 8) // P1_5: SD_POW, PortaPack CPLD.TDO(O) (input with pull up) + | (1 << 7) // P1_14: SGPIO10, HOST_DISABLE + | (1 << 6) // P1_13: SD_CD + | (1 << 5) // P1_12: SD_DAT3 + | (1 << 4) // P1_11: SD_DAT2 + | (1 << 3) // P1_10: SD_DAT1 + | (1 << 2) // P1_9: SD_DAT0 + | (1 << 1) // P1_8: PortaPack CPLD.TMS(I) + | (0 << 0) // P1_7: !MIX_BYPASS , .dir - = (1 << 13) // PortaPack P2_13/DIR - | (1 << 12) // !RX_AMP_PWR - | (1 << 11) // RX_AMP - | (1 << 10) // 10K PD, BOOT3, PortaPack P2_9/LCD_WRX - | (0 << 8) // PortaPack CPLD.TDO(O) (input with pull up) - | (0 << 1) // PortaPack CPLD.TMS(I) (output only when needed, pull up internal to CPLD) - | (1 << 0) // !MIX_BYPASS + = (0 << 15) // P3_5: SPIFI_SIO2 + | (0 << 14) // P3_4: SPIFI_SIO3 + | (0 << 13) // P2_13: PortaPack DIR + | (1 << 12) // P2_12: !RX_AMP_PWR + | (1 << 11) // P2_11: RX_AMP + | (0 << 10) // P2_9: 10K PD, BOOT3, PortaPack LCD_WRX + | (0 << 9) // P1_6: SD_CMD + | (0 << 8) // P1_5: SD_POW, PortaPack CPLD.TDO(O) (input with pull up) + | (0 << 7) // P1_14: SGPIO10, HOST_DISABLE + | (0 << 6) // P1_13: SD_CD + | (0 << 5) // P1_12: SD_DAT3 + | (0 << 4) // P1_11: SD_DAT2 + | (0 << 3) // P1_10: SD_DAT1 + | (0 << 2) // P1_9: SD_DAT0 + | (0 << 1) // P1_8: PortaPack CPLD.TMS(I) (output only when needed, pull up internal to CPLD) + | (1 << 0) // P1_7: !MIX_BYPASS }, { // GPIO2 .data - = (0 << 15) // TX_AMP - | (0 << 11) // TX_MIX_BP - | (1 << 14) // MIXER_RESETX, 10K PU - | (1 << 13) // MIXER_ENX, 10K PU - | (1 << 12) // RX_MIX_BP - | (0 << 10) // LP - | (1 << 9) // !VAA_ENABLE - | (0 << 8) // LED3 (TX) - | (1 << 7) // CS_AD - | (0 << 6) // XCVR_EN, 10K PD - | (0 << 5) // RXENABLE - | (0 << 4) // TXENABLE - | (0 << 2) // LED2 (RX) - | (0 << 1) // LED1 (USB) - | (1 << 0) // HP + = (0 << 15) // P5_6: TX_AMP + | (1 << 14) // P5_5: MIXER_RESETX, 10K PU + | (1 << 13) // P5_4: MIXER_ENX, 10K PU + | (1 << 12) // P5_3: RX_MIX_BP + | (0 << 11) // P5_2: TX_MIX_BP + | (0 << 10) // P5_1: LP + | (1 << 9) // P5_0: !VAA_ENABLE + | (0 << 8) // P6_12: LED3 (TX) + | (1 << 7) // P5_7: CS_AD + | (0 << 6) // P4_6: XCVR_EN, 10K PD + | (0 << 5) // P4_5: RXENABLE + | (0 << 4) // P4_4: TXENABLE + | (1 << 3) // P4_3: SGPIO9, HOST_CAPTURE + | (0 << 2) // P4_2: LED2 (RX) + | (0 << 1) // P4_1: LED1 (USB) + | (1 << 0) // P4_0: HP , .dir - = (1 << 15) // TX_AMP - | (1 << 14) // MIXER_RESETX, 10K PU - | (1 << 13) // MIXER_ENX, 10K PU - | (1 << 12) // RX_MIX_BP - | (1 << 11) // TX_MIX_BP - | (1 << 10) // LP - | (1 << 9) // !VAA_ENABLE - | (1 << 8) // LED3 (TX) - | (1 << 7) // CS_AD - | (1 << 6) // XCVR_EN, 10K PD - | (1 << 5) // RXENABLE - | (1 << 4) // TXENABLE - | (1 << 2) // LED2 (RX) - | (1 << 1) // LED1 (USB) - | (1 << 0) // HP + = (1 << 15) // P5_6: TX_AMP + | (1 << 14) // P5_5: MIXER_RESETX, 10K PU + | (1 << 13) // P5_4: MIXER_ENX, 10K PU + | (1 << 12) // P5_3: RX_MIX_BP + | (1 << 11) // P5_2: TX_MIX_BP + | (1 << 10) // P5_1: LP + | (1 << 9) // P5_0: !VAA_ENABLE + | (1 << 8) // P6_12: LED3 (TX) + | (1 << 7) // P5_7: CS_AD + | (1 << 6) // P4_6: XCVR_EN, 10K PD + | (1 << 5) // P4_5: RXENABLE + | (1 << 4) // P4_4: TXENABLE + | (0 << 3) // P4_3: SGPIO9, HOST_CAPTURE + | (1 << 2) // P4_2: LED2 (RX) + | (1 << 1) // P4_1: LED1 (USB) + | (1 << 0) // P4_0: HP }, { // GPIO3 .data - = (0 << 15) // PortaPack GPIO3_15(IO) - | (0 << 14) // PortaPack GPIO3_14(IO) - | (0 << 13) // PortaPack GPIO3_13(IO) - | (0 << 12) // PortaPack GPIO3_12(IO) - | (0 << 11) // PortaPack GPIO3_11(IO) - | (0 << 10) // PortaPack GPIO3_10(IO) - | (0 << 9) // PortaPack GPIO3_9(IO) - | (0 << 8) // PortaPack GPIO3_8(IO) - | (0 << 7) // VREGMODE - | (1 << 6) // EN1V8, 10K PD - | (1 << 5) // !TX_AMP_PWR, 10K PU - | (1 << 4) // HackRF CPLD.TMS(I) (output only when needed, pull-up internal to CPLD when 1V8 present) - | (1 << 1) // HackRF CPLD.TDI(I), PortaPack I2S0_RX_SDA(O), PortaPack CPLD.TDI(I) (output only when needed, pull-up internal to CPLD when 1V8 present) - | (1 << 0) // HackRF CPLD.TCK(I), PortaPack CPLD.TCK(I) (output only when needed, pull-up internal to CPLD when 1V8 present) + = (1 << 15) // P7_7: PortaPack GPIO3_15(IO) + | (1 << 14) // P7_6: PortaPack GPIO3_14(IO) + | (1 << 13) // P7_5: PortaPack GPIO3_13(IO) + | (1 << 12) // P7_4: PortaPack GPIO3_12(IO) + | (1 << 11) // P7_3: PortaPack GPIO3_11(IO) + | (1 << 10) // P7_2: PortaPack GPIO3_10(IO) + | (1 << 9) // P7_1: PortaPack GPIO3_9(IO) + | (1 << 8) // P7_0: PortaPack GPIO3_8(IO) + | (1 << 7) // P6_11: VREGMODE + | (1 << 6) // P6_10: EN1V8, 10K PD + | (1 << 5) // P6_9: !TX_AMP_PWR, 10K PU + | (1 << 4) // P6_5: HackRF CPLD.TMS(I) (output only when needed, pull-up internal to CPLD when 1V8 present) + | (1 << 3) // P6_4: MIXER_SDATA + | (1 << 2) // P6_3: SGPIO4, HOST_DATA4 + | (1 << 1) // P6_2: HackRF CPLD.TDI(I), PortaPack I2S0_RX_SDA(O), PortaPack CPLD.TDI(I) (output only when needed, pull-up internal to CPLD when 1V8 present) + | (1 << 0) // P6_1: HackRF CPLD.TCK(I), PortaPack CPLD.TCK(I) (output only when needed, pull-up internal to CPLD when 1V8 present) , .dir - = (0 << 15) // PortaPack GPIO3_15(IO) - | (0 << 14) // PortaPack GPIO3_14(IO) - | (0 << 13) // PortaPack GPIO3_13(IO) - | (0 << 12) // PortaPack GPIO3_12(IO) - | (0 << 11) // PortaPack GPIO3_11(IO) - | (0 << 10) // PortaPack GPIO3_10(IO) - | (0 << 9) // PortaPack GPIO3_9(IO) - | (0 << 8) // PortaPack GPIO3_8(IO) - | (1 << 7) // VREGMODE - | (1 << 6) // EN1V8, 10K PD - | (1 << 5) // !TX_AMP_PWR, 10K PU - | (0 << 4) // HackRF CPLD.TMS(I) (output only when needed, pull-up internal to CPLD when 1V8 present) - | (0 << 1) // HackRF CPLD.TDI(I), PortaPack I2S0_RX_SDA(O), PortaPack CPLD.TDI(I) (output only when needed, pull-up internal to CPLD when 1V8 present) - | (0 << 0) // HackRF CPLD.TCK(I), PortaPack CPLD.TCK(I) (output only when needed, pull-up internal to CPLD when 1V8 present) + = (0 << 15) // P7_7: PortaPack GPIO3_15(IO) + | (0 << 14) // P7_6: PortaPack GPIO3_14(IO) + | (0 << 13) // P7_5: PortaPack GPIO3_13(IO) + | (0 << 12) // P7_4: PortaPack GPIO3_12(IO) + | (0 << 11) // P7_3: PortaPack GPIO3_11(IO) + | (0 << 10) // P7_2: PortaPack GPIO3_10(IO) + | (0 << 9) // P7_1: PortaPack GPIO3_9(IO) + | (0 << 8) // P7_0: PortaPack GPIO3_8(IO) + | (1 << 7) // P6_11: VREGMODE + | (1 << 6) // P6_10: EN1V8, 10K PD + | (1 << 5) // P6_9: !TX_AMP_PWR, 10K PU + | (0 << 4) // P6_5: HackRF CPLD.TMS(I) (output only when needed, pull-up internal to CPLD when 1V8 present) + | (0 << 3) // P6_4: MIXER_SDATA + | (0 << 2) // P6_3: SGPIO4, HOST_DATA4 + | (0 << 1) // P6_2: HackRF CPLD.TDI(I), PortaPack I2S0_RX_SDA(O), PortaPack CPLD.TDI(I) (output only when needed, pull-up internal to CPLD when 1V8 present) + | (0 << 0) // P6_1: HackRF CPLD.TCK(I), PortaPack CPLD.TCK(I) (output only when needed, pull-up internal to CPLD when 1V8 present) }, { // GPIO4 - .data = 0, - .dir = 0 + .data + = (1 << 11) // P9_6: SGPIO8, SGPIO_CLK + , + .dir + = (0 << 11) // P9_6: SGPIO8, SGPIO_CLK }, { // GPIO5 .data - = (1 << 18) // HackRF CPLD.TDO(O) (input with pull up) - | (0 << 15) // TX - | (1 << 16) // MIX_BYPASS - | (1 << 5) // RX - | (1 << 4) // PortaPack P2_4/LCD_RDX - | (0 << 3) // PortaPack P2_3/LCD_TE - | (0 << 1) // PortaPack P2_1/ADDR - | (1 << 0) // PortaPack P2_0/IO_STBX + = (1 << 18) // P9:5: HackRF CPLD.TDO(O) (input with pull up) + | (1 << 16) // P6_8: MIX_BYPASS + | (0 << 15) // P6_7: TX + | (1 << 14) // P4_10: SGPIO15, CPLD (unused) + | (1 << 13) // P4_9: SGPIO14, CPLD (unused) + | (0 << 12) // P4_8: SGPIO13, HOST_SYNC_EN + | (1 << 11) // P3_8: SPIFI_CS + | (1 << 10) // P3_7: SPIFI_MOSI + | (1 << 9) // P3_2: I2S0_RX_SDA + | (1 << 8) // P3_1: I2S0_RX_WS + | (0 << 7) // P2_8: BOOT2 + | (0 << 6) // P2_6: MIXER_SCLK + | (1 << 5) // P2_5: RX + | (1 << 4) // P2_4: PortaPack LCD_RDX + | (0 << 3) // P2_3: PortaPack LCD_TE + | (1 << 2) // P2_2: SGPIO6, HOST_DATA6 + | (0 << 1) // P2_1: PortaPack ADDR + | (1 << 0) // P2_0: PortaPack IO_STBX , .dir - = (0 << 18) // HackRF CPLD.TDO(O) (input with pull up) - | (1 << 16) // MIX_BYPASS - | (1 << 15) // TX - | (1 << 5) // RX - | (1 << 4) // PortaPack P2_4/LCD_RDX - | (0 << 3) // PortaPack P2_3/LCD_TE - | (1 << 1) // PortaPack P2_1/ADDR - | (1 << 0) // PortaPack P2_0/IO_STBX + = (0 << 18) // P9_5: HackRF CPLD.TDO(O) (input with pull up) + | (1 << 16) // P6_8: MIX_BYPASS + | (1 << 15) // P6_7: TX + | (0 << 14) // P4_10: SGPIO15, CPLD (unused) + | (0 << 13) // P4_9: SGPIO14, CPLD (unused) + | (0 << 12) // P4_8: SGPIO13, HOST_SYNC_EN + | (0 << 11) // P3_8: SPIFI_CS + | (0 << 10) // P3_7: SPIFI_MOSI + | (0 << 9) // P3_2: I2S0_RX_SDA + | (0 << 8) // P3_1: I2S0_RX_WS + | (0 << 7) // P2_8: BOOT2 + | (0 << 6) // P2_6: MIXER_SCLK + | (1 << 5) // P2_5: RX + | (0 << 4) // P2_4: PortaPack LCD_RDX + | (0 << 3) // P2_3: PortaPack LCD_TE + | (0 << 2) // P2_2: SGPIO6, HOST_DATA6 + | (0 << 1) // P2_1: PortaPack ADDR + | (0 << 0) // P2_0: PortaPack IO_STBX }, { // GPIO6 .data = 0, @@ -186,7 +257,7 @@ const PALConfig pal_default_config = { /* Configure GP_CLKIN as soon as possible. It's an output at boot time, and the Si5351C doesn't * reset when the reset button is pressed, so it could still be output enabled. */ - { 4, 7, scu_config_normal_drive_t { .mode=1, .epd=0, .epun=1, .ehs=0, .ezi=1, .zif=1 } }, /* GP_CLKIN/P72/MCU_CLK: SI5351C.CLK7(O) */ + { 4, 7, scu_config_normal_drive_t { .mode=1, .epd=0, .epun=0, .ehs=0, .ezi=1, .zif=1 } }, /* GP_CLKIN/P72/MCU_CLK: SI5351C.CLK7(O) */ /* HackRF: LEDs. Configured early so we can use them to indicate boot status. */ { 4, 1, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=0, .zif=0 } }, /* LED1: LED1.A(I) */ @@ -221,12 +292,12 @@ const PALConfig pal_default_config = { }, /* Radio section control */ - { 1, 3, scu_config_normal_drive_t { .mode=5, .epd=0, .epun=1, .ehs=0, .ezi=1, .zif=0 } }, /* SSP1_MISO/P41: MAX2837.DOUT(O) */ - { 1, 4, scu_config_normal_drive_t { .mode=5, .epd=1, .epun=1, .ehs=0, .ezi=0, .zif=0 } }, /* SSP1_MOSI/P40: MAX2837.DIN(I), MAX5864.DIN(I) */ + { 1, 3, scu_config_normal_drive_t { .mode=5, .epd=0, .epun=0, .ehs=0, .ezi=1, .zif=0 } }, /* SSP1_MISO/P41: MAX2837.DOUT(O) */ + { 1, 4, scu_config_normal_drive_t { .mode=5, .epd=0, .epun=0, .ehs=0, .ezi=0, .zif=0 } }, /* SSP1_MOSI/P40: MAX2837.DIN(I), MAX5864.DIN(I) */ { 1, 7, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=0, .zif=0 } }, /* !MIX_BYPASS/P35: U1.VCTL1(I), U11.VCTL2(I), U9.V2(I) */ - { 1, 19, scu_config_normal_drive_t { .mode=1, .epd=0, .epun=1, .ehs=0, .ezi=0, .zif=0 } }, /* SSP1_SCK/P39: MAX2837.SCLK(I), MAX5864.SCLK(I) */ + { 1, 19, scu_config_normal_drive_t { .mode=1, .epd=0, .epun=0, .ehs=0, .ezi=0, .zif=0 } }, /* SSP1_SCK/P39: MAX2837.SCLK(I), MAX5864.SCLK(I) */ { 1, 20, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=0, .zif=0 } }, /* CS_XCVR/P53: MAX2837.CS(I) */ - { 2, 5, scu_config_normal_drive_t { .mode=4, .epd=0, .epun=0, .ehs=0, .ezi=0, .zif=0 } }, /* RX/P43: U7.VCTL1(I), U10.VCTL1(I), U2.VCTL1(I) */ + { 2, 5, scu_config_normal_drive_t { .mode=4, .epd=0, .epun=1, .ehs=0, .ezi=0, .zif=0 } }, /* RX/P43: U7.VCTL1(I), U10.VCTL1(I), U2.VCTL1(I) */ { 2, 6, scu_config_normal_drive_t { .mode=4, .epd=0, .epun=1, .ehs=0, .ezi=0, .zif=0 } }, /* MIXER_SCLK/P31: 33pF, RFFC5072.SCLK(I) */ { 2, 10, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=0, .zif=0 } }, /* AMP_BYPASS/P50: U14.V2(I), U12.V2(I) */ { 2, 11, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=0, .zif=0 } }, /* RX_AMP/P49: U12.V1(I), U14.V3(I) */ @@ -242,7 +313,7 @@ const PALConfig pal_default_config = { { 5, 5, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=0, .zif=0 } }, /* MIXER_RESETX/P33: 10K PU, 33pF, RFFC5072.RESETX(I) */ { 5, 6, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=0, .zif=0 } }, /* TX_AMP/P48: U12.V3(I), U14.V1(I) */ { 5, 7, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=0, .zif=0 } }, /* CS_AD/P54: MAX5864.CS(I) */ - { 6, 4, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=1, .zif=0 } }, /* MIXER_SDATA/P27: 33pF, RFFC5072.SDATA(IO) */ + { 6, 4, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=0, .ehs=0, .ezi=1, .zif=0 } }, /* MIXER_SDATA/P27: 33pF, RFFC5072.SDATA(IO) */ { 6, 7, scu_config_normal_drive_t { .mode=4, .epd=0, .epun=1, .ehs=0, .ezi=0, .zif=0 } }, /* TX/P42: U7.VCTL2(I), U10.VCTL2(I), U2.VCTL2(I) */ { 6, 8, scu_config_normal_drive_t { .mode=4, .epd=0, .epun=1, .ehs=0, .ezi=0, .zif=0 } }, /* MIX_BYPASS/P34: U1.VCTL2(I), U11.VCTL1(I) */ { 6, 9, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=0, .zif=0 } }, /* !TX_AMP_PWR/P51: 10K PU, Q2.G(I), power to U25 (TX amp) */ @@ -256,11 +327,11 @@ const PALConfig pal_default_config = { { 6, 6, scu_config_normal_drive_t { .mode=2, .epd=0, .epun=1, .ehs=1, .ezi=1, .zif=1 } }, /* SGPIO5/BANK2F3M15: CPLD.64/HOST_DATA5(IO) */ { 2, 2, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=1, .ezi=1, .zif=1 } }, /* SGPIO6/BANK2F3M16: CPLD.61/HOST_DATA6(IO) */ { 1, 0, scu_config_normal_drive_t { .mode=6, .epd=0, .epun=1, .ehs=1, .ezi=1, .zif=1 } }, /* SGPIO7/P76/BANK2F3M7: CPLD.77/HOST_DATA7(IO) */ - { 9, 6, scu_config_normal_drive_t { .mode=6, .epd=0, .epun=1, .ehs=0, .ezi=1, .zif=1 } }, /* SGPIO8/SGPIO_CLK/P60: SI5351C.CLK2(O) */ + { 9, 6, scu_config_normal_drive_t { .mode=6, .epd=0, .epun=0, .ehs=0, .ezi=1, .zif=1 } }, /* SGPIO8/SGPIO_CLK/P60: SI5351C.CLK2(O) */ { 4, 3, scu_config_normal_drive_t { .mode=7, .epd=0, .epun=1, .ehs=0, .ezi=1, .zif=1 } }, /* SGPIO9/P77/BANK2F3M1: CPLD.91/HOST_CAPTURE(O) */ { 1, 14, scu_config_normal_drive_t { .mode=6, .epd=0, .epun=0, .ehs=1, .ezi=0, .zif=0 } }, /* SGPIO10/P78/BANK2F3M8: CPLD.76/HOST_DISABLE(I) */ - { 1, 17, scu_config_normal_drive_t { .mode=6, .epd=0, .epun=0, .ehs=1, .ezi=0, .zif=0 } }, /* SGPIO11/P79/BANK2F3M11: CPLD.71/HOST_DIRECTION(I) */ - { 1, 18, scu_config_normal_drive_t { .mode=0, .epd=1, .epun=1, .ehs=0, .ezi=0, .zif=0 } }, /* SGPIO12/BANK2F3M12: CPLD.70/HOST_INVERT(I) */ + { 1, 17, scu_config_normal_drive_t { .mode=6, .epd=1, .epun=1, .ehs=1, .ezi=0, .zif=0 } }, /* SGPIO11/P79/BANK2F3M11: CPLD.71/HOST_DIRECTION(I) */ + { 1, 18, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=0, .zif=0 } }, /* SGPIO12/BANK2F3M12: CPLD.70/HOST_INVERT(I) */ { 4, 8, scu_config_normal_drive_t { .mode=4, .epd=1, .epun=1, .ehs=0, .ezi=0, .zif=0 } }, /* SGPIO13/BANK2F3M2: CPLD.90/HOST_SYNC_EN(I) */ { 4, 9, scu_config_normal_drive_t { .mode=4, .epd=0, .epun=0, .ehs=0, .ezi=0, .zif=0 } }, /* SGPIO14/BANK2F3M4: CPLD.81/CPLD_P81 */ { 4, 10, scu_config_normal_drive_t { .mode=4, .epd=0, .epun=0, .ehs=0, .ezi=0, .zif=0 } }, /* SGPIO15/BANK2F3M6: CPLD.78/CPLD_P78 */ @@ -269,11 +340,23 @@ const PALConfig pal_default_config = { { 6, 1, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=0, .zif=0 } }, /* CPLD_TCK: CPLD.TCK(I), PortaPack CPLD.TCK(I) */ { 6, 2, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=1, .zif=0 } }, /* CPLD_TDI: CPLD.TDI(I), PortaPack I2S0_RX_SDA(O), PortaPack CPLD.TDI(I) */ { 6, 5, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=0, .zif=0 } }, /* CPLD_TMS: CPLD.TMS(I) */ - { 9, 5, scu_config_normal_drive_t { .mode=4, .epd=0, .epun=1, .ehs=0, .ezi=1, .zif=0 } }, /* CPLD_TDO: CPLD.TDO(O) */ + { 9, 5, scu_config_normal_drive_t { .mode=4, .epd=0, .epun=0, .ehs=0, .ezi=1, .zif=0 } }, /* CPLD_TDO: CPLD.TDO(O) */ - /* PortaPack */ + /* PortaPack CPLD */ { 1, 5, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=0, .ehs=0, .ezi=1, .zif=0 } }, /* SD_POW: PortaPack CPLD.TDO(O) */ { 1, 8, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=0, .ehs=0, .ezi=0, .zif=0 } }, /* SD_VOLT0: PortaPack CPLD.TMS(I) */ + + /* Miscellaneous */ + { 1, 1, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=0, .zif=0 } }, /* P1_1/P74: 10K PU, BOOT0 */ + { 1, 2, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=0, .zif=0 } }, /* P1_2/P73: 10K PD, BOOT1 */ + { 2, 7, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=0, .zif=0 } }, /* ISP: 10K PU, Unused */ + { 6, 0, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=0, .ehs=0, .ezi=0, .zif=0 } }, /* I2S0_RX_MCLK: Unused */ + { 15, 4, scu_config_normal_drive_t { .mode=7, .epd=0, .epun=0, .ehs=0, .ezi=0, .zif=0 } }, /* I2S0_RX_SCK: Unused */ + } +}; +#endif + +static const std::array pins_setup_portapack { { { 2, 0, scu_config_normal_drive_t { .mode=4, .epd=0, .epun=1, .ehs=0, .ezi=1, .zif=0 } }, /* U0_TXD: PortaPack P2_0/IO_STBX */ { 2, 1, scu_config_normal_drive_t { .mode=4, .epd=0, .epun=1, .ehs=0, .ezi=1, .zif=0 } }, /* U0_RXD: PortaPack P2_1/ADDR */ { 2, 3, scu_config_normal_drive_t { .mode=4, .epd=0, .epun=1, .ehs=0, .ezi=1, .zif=0 } }, /* I2C1_SDA: PortaPack P2_3/LCD_TE */ @@ -281,14 +364,14 @@ const PALConfig pal_default_config = { { 2, 8, scu_config_normal_drive_t { .mode=4, .epd=0, .epun=1, .ehs=0, .ezi=0, .zif=0 } }, /* P2_8: 10K PD, BOOT2, DFU switch, PortaPack P2_8/ */ { 2, 9, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=1, .zif=0 } }, /* P2_9: 10K PD, BOOT3, PortaPack P2_9/LCD_WRX */ { 2, 13, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=1, .zif=0 } }, /* P2_13: PortaPack P2_13/DIR */ - { 7, 0, scu_config_normal_drive_t { .mode=0, .epd=1, .epun=1, .ehs=0, .ezi=1, .zif=0 } }, /* GPIO3_8: PortaPack GPIO3_8(IO) */ - { 7, 1, scu_config_normal_drive_t { .mode=0, .epd=1, .epun=1, .ehs=0, .ezi=1, .zif=0 } }, /* GPIO3_9: PortaPack GPIO3_9(IO) */ - { 7, 2, scu_config_normal_drive_t { .mode=0, .epd=1, .epun=1, .ehs=0, .ezi=1, .zif=0 } }, /* GPIO3_10: PortaPack GPIO3_10(IO) */ - { 7, 3, scu_config_normal_drive_t { .mode=0, .epd=1, .epun=1, .ehs=0, .ezi=1, .zif=0 } }, /* GPIO3_11: PortaPack GPIO3_11(IO) */ - { 7, 4, scu_config_normal_drive_t { .mode=0, .epd=1, .epun=1, .ehs=0, .ezi=1, .zif=0 } }, /* GPIO3_12: PortaPack GPIO3_12(IO) */ - { 7, 5, scu_config_normal_drive_t { .mode=0, .epd=1, .epun=1, .ehs=0, .ezi=1, .zif=0 } }, /* GPIO3_13: PortaPack GPIO3_13(IO) */ - { 7, 6, scu_config_normal_drive_t { .mode=0, .epd=1, .epun=1, .ehs=0, .ezi=1, .zif=0 } }, /* GPIO3_14: PortaPack GPIO3_14(IO) */ - { 7, 7, scu_config_normal_drive_t { .mode=0, .epd=1, .epun=1, .ehs=0, .ezi=1, .zif=0 } }, /* GPIO3_15: PortaPack GPIO3_15(IO) */ + { 7, 0, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=1, .zif=0 } }, /* GPIO3_8: PortaPack GPIO3_8(IO) */ + { 7, 1, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=1, .zif=0 } }, /* GPIO3_9: PortaPack GPIO3_9(IO) */ + { 7, 2, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=1, .zif=0 } }, /* GPIO3_10: PortaPack GPIO3_10(IO) */ + { 7, 3, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=1, .zif=0 } }, /* GPIO3_11: PortaPack GPIO3_11(IO) */ + { 7, 4, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=1, .zif=0 } }, /* GPIO3_12: PortaPack GPIO3_12(IO) */ + { 7, 5, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=1, .zif=0 } }, /* GPIO3_13: PortaPack GPIO3_13(IO) */ + { 7, 6, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=1, .zif=0 } }, /* GPIO3_14: PortaPack GPIO3_14(IO) */ + { 7, 7, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=1, .zif=0 } }, /* GPIO3_15: PortaPack GPIO3_15(IO) */ /* PortaPack: Audio */ { 3, 0, scu_config_normal_drive_t { .mode=2, .epd=0, .epun=0, .ehs=0, .ezi=1, .zif=0 } }, /* I2S0_TX_SCK: PortaPack I2S0_TX_SCK(I) */ @@ -304,16 +387,7 @@ const PALConfig pal_default_config = { { 1, 11, scu_config_normal_drive_t { .mode=7, .epd=0, .epun=0, .ehs=0, .ezi=1, .zif=1 } }, /* SD_DAT2: PortaPack SD.DAT2(IO) */ { 1, 12, scu_config_normal_drive_t { .mode=7, .epd=0, .epun=0, .ehs=0, .ezi=1, .zif=1 } }, /* SD_DAT3: PortaPack SD.DAT3(IO) */ { 1, 13, scu_config_normal_drive_t { .mode=7, .epd=0, .epun=0, .ehs=0, .ezi=1, .zif=0 } }, /* SD_CD: PortaPack SD.CD(O) */ - - /* Miscellaneous */ - { 1, 1, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=0, .zif=0 } }, /* P1_1/P74: 10K PU, BOOT0 */ - { 1, 2, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=0, .zif=0 } }, /* P1_2/P73: 10K PD, BOOT1 */ - { 2, 7, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=1, .ehs=0, .ezi=0, .zif=0 } }, /* ISP: 10K PU, Unused */ - { 6, 0, scu_config_normal_drive_t { .mode=0, .epd=0, .epun=0, .ehs=0, .ezi=0, .zif=0 } }, /* I2S0_RX_MCLK: Unused */ - { 15, 4, scu_config_normal_drive_t { .mode=7, .epd=0, .epun=0, .ehs=0, .ezi=0, .zif=0 } }, /* I2S0_RX_SCK: Unused */ - } -}; -#endif +} }; static const std::array pins_setup_spifi { { { 3, 3, scu_config_normal_drive_t { .mode=3, .epd=0, .epun=1, .ehs=1, .ezi=1, .zif=1 } }, /* SPIFI_SCK: W25Q80BV.CLK(I), enable input buffer for timing feedback */ @@ -361,6 +435,13 @@ static void configure_spifi(void) { ; } +void configure_pins_portapack(void) { + LPC_GPIO->DIR[1] |= (1 << 13) | (1 << 10); + LPC_GPIO->DIR[3] |= (0xff << 8); + LPC_GPIO->DIR[5] |= (1 << 4) | (1 << 1) | (1 << 0); + setup_pins(pins_setup_portapack); +} + static const motocon_pwm_resources_t motocon_pwm_resources = { .base = { .clk = &LPC_CGU->BASE_APB1_CLK, .stat = &LPC_CCU1->BASE_STAT, .stat_mask = (1 << 1) }, .branch = { .cfg = &LPC_CCU1->CLK_APB1_MOTOCON_PWM_CFG, .stat = &LPC_CCU1->CLK_APB1_MOTOCON_PWM_STAT }, diff --git a/firmware/chibios-portapack/boards/PORTAPACK_APPLICATION/board.h b/firmware/chibios-portapack/boards/PORTAPACK_APPLICATION/board.h index c65fa732..972e360f 100755 --- a/firmware/chibios-portapack/boards/PORTAPACK_APPLICATION/board.h +++ b/firmware/chibios-portapack/boards/PORTAPACK_APPLICATION/board.h @@ -35,6 +35,8 @@ extern "C" { #endif void boardInit(void); + void configure_pins_portapack(void); + void vaa_power_on(void); void vaa_power_off(void); #ifdef __cplusplus diff --git a/firmware/chibios-portapack/os/hal/platforms/LPC43xx/pal_lld.h b/firmware/chibios-portapack/os/hal/platforms/LPC43xx/pal_lld.h index 925c60f9..f7669463 100644 --- a/firmware/chibios-portapack/os/hal/platforms/LPC43xx/pal_lld.h +++ b/firmware/chibios-portapack/os/hal/platforms/LPC43xx/pal_lld.h @@ -53,7 +53,7 @@ typedef struct { /** @brief GPIO setup data.*/ gpio_setup_t P[8]; - scu_setup_t SCU[86]; + scu_setup_t SCU[60]; } PALConfig; /** diff --git a/firmware/tools/extract_svf_data_xc2c64a.py b/firmware/tools/extract_svf_data_xc2c64a.py deleted file mode 100755 index a82ca538..00000000 --- a/firmware/tools/extract_svf_data_xc2c64a.py +++ /dev/null @@ -1,343 +0,0 @@ -#!/usr/bin/env python - -# -# Copyright (C) 2016 Jared Boone, ShareBrained Technology, Inc. -# -# This file is part of PortaPack. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, -# Boston, MA 02110-1301, USA. -# - -# Very fragile code to extract data from Xilinx XC2C64A CPLD SVF - -import sys -import re -import os.path -import argparse - -def crack_variable_path(variable_path): - tmp = args.variable_path.split('::') - namespaces, variable_name = tmp[:-1], tmp[-1] - return namespaces, variable_name - -parser = argparse.ArgumentParser() -parser.add_argument('input_file_path', type=str) -parser.add_argument('variable_path', type=str) -# parser.add_argument('header_file_path', type=str) -parser.add_argument('data_file_path', type=str) -args = parser.parse_args() - -f = open(args.input_file_path, 'r') -namespaces, variable_name = crack_variable_path(args.variable_path) - -def to_hex(value, length_bits): - return ('%x' % value).zfill((length_bits + 3) >> 2) - -def long_int_to_bytes(n, bit_count): - byte_count = (bit_count + 7) >> 3 - h = ('%x' % n).zfill(byte_count * 2) - return [int(h[n:n+2], 16) for n in range(0, len(h), 2)] - -re_sdr = re.compile(r'^(?P\d+)\s*TDI\s*\((?P[0-9A-F]+)\)(|\s*SMASK\s*\((?P[0-9A-F]+)\))(|\s*TDO\s*\((?P[0-9A-F]+)\))(|\s*MASK\s*\((?P[0-9A-F]+)\))\s*;$') -re_sir = re_sdr - -class SIR_or_SDR(object): - def __init__(self, name, s): - self.name = name - match = re_sdr.match(s) - self.length = int(match.group('length')) - self.tdi = self._bits(match.group('tdi')) - self.smask = self._optional_bits(match.group('smask')) - self.tdo = self._optional_bits(match.group('tdo')) - self.mask = self._optional_bits(match.group('mask')) - - def __repr__(self): - result = [self.name, str(self.length)] - result.append('TDI (%s)' % to_hex(self.tdi, self.length)) - if self.smask: - result.append('SMASK (%s)' % to_hex(self.smask, self.length)) - if self.tdo: - result.append('TDO (%s)' % to_hex(self.tdo, self.length)) - if self.mask: - result.append('MASK (%s)' % to_hex(self.mask, self.length)) - result.append(';') - return ' '.join(result) - - def _bits(self, matched): - return int(matched, 16) - - def _optional_bits(self, matched): - return self._bits(matched) if matched else None - -class SDR(SIR_or_SDR): - def __init__(self, s): - SIR_or_SDR.__init__(self, 'SDR', s) - -class SIR(SIR_or_SDR): - def __init__(self, s): - SIR_or_SDR.__init__(self, 'SIR', s) - -class SVFParser(object): - instruction_parsers = { - 'SIR': SIR, - 'SDR': SDR, - } - - def parse(self, f, instruction_handler_map): - complete_line = '' - for line in f: - line = line.strip().upper() - if line.startswith('//'): - continue - - complete_line += line - if not line.endswith(';'): - continue - - instruction_name, args_string = complete_line.split(None, 1) - instruction = self.instruction_parser(instruction_name, args_string) - if instruction: - instruction_type = type(instruction) - if instruction_type in instruction_handler_map: - instruction_handler_map[instruction_type](instruction) - - if complete_line.endswith(';'): - complete_line = '' - - def instruction_parser(self, instruction_name, args_string): - if instruction_name in self.instruction_parsers: - parser = self.instruction_parsers[instruction_name] - return parser(args_string) - else: - return None - -class ProgramExtractor(object): - idcode = int('0bXXXX0110111001011XXX000010010011'.replace('X', '0'), 2) - idcode_mask = None - id_bits = 7 - block_bits = 274 - block_ordinals = frozenset(list(range(64)) + list(range(80, 82)) + list(range(96, 128))) - block_count = len(block_ordinals) - - def __init__(self): - self.tap_instruction = None - self.program_data = [] - self.verify_data = [] - self.sdr_smask = None - self.sdr_mask = None - - def map(self): - return { - SIR: self.on_sir, - SDR: self.on_sdr, - } - - def on_sir(self, o): - assert(o.length == 8) - - if o.tdi == 0x01: - self.tap_instruction = 'idcode' - elif o.tdi == 0xea: - self.tap_instruction = 'program' - self.program_data.append([]) - elif o.tdi == 0xee: - self.tap_instruction = 'verify' - self.verify_data.append([]) - self.verify_block_id = None - else: - self.tap_instruction = None - - def on_sdr(self, o): - if o.smask: - self.sdr_smask = o.smask - if o.mask: - self.sdr_mask = o.mask - - if self.tap_instruction == 'idcode': - assert(o.length == 32) - assert(self.sdr_smask == 0xffffffff) - assert((o.tdo & self.sdr_mask) == self.idcode) - if self.idcode_mask is None: - self.idcode_mask = self.sdr_mask - else: - assert(self.idcode_mask == self.sdr_mask) - - elif self.tap_instruction == 'program': - assert(o.length == (self.id_bits + self.block_bits)) - assert(self.sdr_smask == ((1 << o.length) - 1)) - assert(o.tdo is None) - assert(o.mask is None) - block_id = o.tdi >> (o.length - 7) - mask = (1 << (o.length - 7)) - 1 - self.program_data[-1].append({ - 'id': block_id, - 'tdi': o.tdi & mask, - 'length': o.length - 7, - }) - elif self.tap_instruction == 'verify': - assert(o.length in (self.id_bits, self.block_bits)) - - if o.length == self.id_bits: - assert(o.smask == ((1 << self.id_bits) - 1)) - assert(o.tdo is None) - assert(o.mask is None) - self.verify_block_id = o.tdi - - elif o.length == self.block_bits: - assert(o.tdi == (1 << o.length) - 1) - assert(o.smask == (1 << o.length) - 1) - self.verify_data[-1].append({ - 'id': self.verify_block_id, - 'tdo': o.tdo, - 'mask': o.mask, - 'length': o.length, - }) - self.verify_block_id = None - -program_extractor = ProgramExtractor() - -parser = SVFParser() -parser.parse(f, program_extractor.map()) - -def has_all_blocks(blocks): - ordinals = set() - - for block in blocks: - ordinal = int(bin(block['id'])[2:].zfill(7)[::-1], 2) - ordinals.add(ordinal) - - return ordinals == program_extractor.block_ordinals - -def is_verify_blank(blocks): - for block in blocks: - length = block['length'] - mask = (1 << length) - 1 - if block['tdo'] != mask: - return False - if block['mask'] != mask: - return False - return True - -def deduplicate(passes): - result = [passes[0]] - for this_pass in passes[1:]: - if this_pass != result[0]: - result.append(this_pass) - return result - -def program_and_verify_match(program, verify): - for program_block, verify_block in zip(program, verify): - if program_block['tdi'] != verify_block['tdo']: - return False - return True - -program_passes = [blocks for blocks in program_extractor.program_data if has_all_blocks(blocks)] -program_done = [blocks for blocks in program_extractor.program_data if len(blocks) == 1][0] -if len(program_passes) == 0: - raise RuntimeError('no complete program passes') -if len(program_passes) > 1: - raise RuntimeError('too many program passes') -program = program_passes[0] - -verify_passes = [blocks for blocks in program_extractor.verify_data if has_all_blocks(blocks) and not is_verify_blank(blocks)] -verify_passes = deduplicate(verify_passes) -if len(verify_passes) == 0: - raise RuntimeError('no complete verify passes') -if len(verify_passes) > 1: - raise RuntimeError('too many verify passes') -verify = verify_passes[0] - -if not program_and_verify_match(program, verify): - raise RuntimeError('program and verify data do not match') - -class FileGen(object): - def comment_header(self): - return ['/*' , ' * WARNING: Auto-generated file. Do not edit.', '*/'] - - def includes(self, filenames): - return ['#include "%s"' % filename for filename in filenames] - - def _namespaces(self, ns_list, line_format): - return [line_format % ns for ns in ns_list] - - def namespaces_start(self, ns_list): - return self._namespaces(ns_list, 'namespace %s {') - - def namespaces_end(self, ns_list): - return self._namespaces(ns_list, '} /* namespace %s */') - - def verify_block(self, block): - tdo_bytes = long_int_to_bytes(block['tdo'], block['length']) - mask_bytes = long_int_to_bytes(block['mask'], block['length']) - tdo_cpp_s = ', '.join(['0x%02x' % b for b in tdo_bytes]); - mask_cpp_s = ', '.join(['0x%02x' % b for b in mask_bytes]); - return '\t{ 0x%02x, { { %s } }, { { %s } } },' % (block['id'], tdo_cpp_s, mask_cpp_s) - - def verify_blocks_declaration(self, type_name, variable_name): - return ['extern const %s %s;' % (type_name, variable_name)] - - def verify_blocks_definition(self, type_name, variable_name, blocks): - return ['const %s %s { {' % (type_name, variable_name)] \ - + [self.verify_block(block) for block in blocks] \ - + ['} };'] - - # def cpp_program_t(block): - # tdi_bytes = long_int_to_bytes(block['tdi'], block['length']) - # tdi_cpp_s = ', '.join(['0x%02x' % b for b in tdi_bytes]); - # return '0x%02x, { { %s } }' % (block['id'], tdi_cpp_s) - - def __repr__(self): - return '\n'.join(self.lines) - - def to_file(self, file_path): - f = open(file_path, 'w') - f.write(str(self)) - f.close() - -class HeaderGen(FileGen): - def __init__(self, includes, namespaces, type_name, variable_name): - self.lines = self.comment_header() \ - + self.includes(includes) \ - + self.namespaces_start(namespaces) \ - + self.verify_blocks_declaration(type_name, variable_name) \ - + self.namespaces_end(namespaces) \ - + [''] - -class DataGen(FileGen): - def __init__(self, includes, namespaces, type_name, variable_name, verify_blocks): - self.lines = self.comment_header() \ - + self.includes(includes) \ - + self.namespaces_start(namespaces) \ - + self.verify_blocks_definition(type_name, variable_name, verify_blocks) \ - + self.namespaces_end(namespaces) \ - + [''] - -# Tricky (a.k.a. "brittle") code to set DONE bit -for block in verify: - if block['id'] == 0x05: - block['tdo'] = program_done[0]['tdi'] - -# header_file_name = os.path.split(args.header_file_path)[1] -header_file_name = 'hackrf_cpld_data.hpp' - -# header_includes = ('cpld_xilinx.hpp',) -data_includes = (header_file_name,) - -type_name = '::cpld::xilinx::XC2C64A::verify_blocks_t' - -# HeaderGen(header_includes, namespaces, type_name, variable_name).to_file(args.header_file_path) -DataGen(data_includes, namespaces, type_name, variable_name, verify).to_file(args.data_file_path) - diff --git a/firmware/tools/make_image_chunk.py b/firmware/tools/make_image_chunk.py index ed3463bc..5bcf4fb4 100755 --- a/firmware/tools/make_image_chunk.py +++ b/firmware/tools/make_image_chunk.py @@ -27,7 +27,7 @@ import struct usage_message = """ PortaPack image chunk writer -Usage: +Usage: [] """ def read_image(path): @@ -41,10 +41,13 @@ def write_image(data, path): f.write(data) f.close() -if len(sys.argv) == 4: +input_image_max_length = 32768 +if len(sys.argv) in (4, 5): input_image = read_image(sys.argv[1]) tag = tuple(map(ord, sys.argv[2])) output_path = sys.argv[3] + if len(sys.argv) == 5: + input_image_max_length = int(sys.argv[4]) elif len(sys.argv) == 2: input_image = bytearray() tag = (0, 0, 0, 0) @@ -57,7 +60,6 @@ if len(tag) != 4: print(usage_message) sys.exit(-2) -input_image_max_length = 32768 if len(input_image) > input_image_max_length: raise RuntimeError('image size of %d exceeds device size of %d bytes' % (len(input_image), input_image_max_length)) if (len(input_image) & 3) != 0: