From c406d02f3f9919b563ad75af143c2661c8bb25dc Mon Sep 17 00:00:00 2001 From: Chris Anderson Date: Sat, 4 Jan 2025 20:59:12 -0500 Subject: [PATCH] first PT2000 commit, includes the dev studio project, and a loading code which was a slightly modified pt2001/mc33816 with some nuances. microcode changed to signal dc-dc with flag1 instead of flag0, which we use a different status signal. SetTimings is commented out because I haven't used TS to upload the values, and thus persistence is NOT tested. --- .vscode/launch.json | 49 +- GDI-6ch/firmware/Makefile | 26 +- GDI-6ch/firmware/PT2000_LoadData.c | 171 +++++ GDI-6ch/firmware/PT2000_LoadData.h | 62 ++ GDI-6ch/firmware/gdi.ld | 85 +++ GDI-6ch/firmware/halconf.h | 2 +- GDI-6ch/firmware/io_pins.h | 52 ++ GDI-6ch/firmware/main.cpp | 439 ++--------- GDI-6ch/firmware/mc33816_control.cpp | 56 -- GDI-6ch/firmware/mc33816_control.h | 11 - GDI-6ch/firmware/mc33816_data.c | 97 --- GDI-6ch/firmware/mc33816_data.h | 18 - GDI-6ch/firmware/mc33816_memory_map.h | 24 - GDI-6ch/firmware/persistence.cpp | 89 +++ GDI-6ch/firmware/persistence.h | 64 ++ GDI-6ch/firmware/pt2000.cpp | 538 ++++++++++++++ GDI-6ch/firmware/pt2000.h | 130 ++++ GDI-6ch/firmware/pt2000_memory_map.h | 40 + GDI-6ch/firmware/pt2000impl.h | 145 ++++ GDI-6ch/project/Logic_Wave/wave_list.do | 198 +++++ GDI-6ch/project/MicrocodeCh1/ch1.psc | 204 ++++++ GDI-6ch/project/MicrocodeCh1/ch1.psc.bak | 209 ++++++ GDI-6ch/project/MicrocodeCh1/dram1.def | 10 + GDI-6ch/project/MicrocodeCh2/ch2.psc | 117 +++ GDI-6ch/project/MicrocodeCh2/ch2.psc.bak | 28 + GDI-6ch/project/MicrocodeCh2/dram2.def | 10 + GDI-6ch/project/MicrocodeCh3/ch3.psc | 87 +++ GDI-6ch/project/MicrocodeCh3/ch3.psc.bak | 90 +++ GDI-6ch/project/MicrocodeCh3/dram3.def | 8 + GDI-6ch/project/Registers/ch1_config_reg.hex | 28 + GDI-6ch/project/Registers/ch2_config_reg.hex | 28 + GDI-6ch/project/Registers/ch3_config_reg.hex | 28 + GDI-6ch/project/Registers/diag_config_reg.hex | 72 ++ GDI-6ch/project/Registers/dram1.hex | 72 ++ GDI-6ch/project/Registers/dram2.hex | 72 ++ GDI-6ch/project/Registers/dram3.hex | 72 ++ GDI-6ch/project/Registers/io_config_reg.hex | 81 +++ GDI-6ch/project/Registers/main_config_reg.hex | 40 + GDI-6ch/project/SPIGenMC33PT2000Files.txt | 12 + GDI-6ch/project/sample_code/PT2000.c | 687 ++++++++++++++++++ GDI-6ch/project/sample_code/PT2000.h | 86 +++ GDI-6ch/project/sample_code/PT2000_LoadData.c | 171 +++++ GDI-6ch/project/sample_code/PT2000_LoadData.h | 62 ++ GDI-6ch/project/sample_code/PT2000_dram.h | 84 +++ GDI-6ch/project/sample_code/PT2000_irq.c | 641 ++++++++++++++++ GDI-6ch/project/sample_code/PT2000_irq.h | 79 ++ GDI-6ch/project/sample_code/PT2000_spi_map.h | 283 ++++++++ GDI-6ch/project/sample_code/lpspi.c | 88 +++ GDI-6ch/project/sample_code/lpspi.h | 66 ++ GDI-6ch/project/sample_code/main.c | 135 ++++ GDI-6ch/project/sample_code/main.h | 54 ++ GDI-6ch/project/sample_code/system.c | 206 ++++++ GDI-6ch/project/sample_code/system.h | 88 +++ 53 files changed, 5701 insertions(+), 593 deletions(-) create mode 100644 GDI-6ch/firmware/PT2000_LoadData.c create mode 100644 GDI-6ch/firmware/PT2000_LoadData.h create mode 100644 GDI-6ch/firmware/gdi.ld delete mode 100644 GDI-6ch/firmware/mc33816_control.cpp delete mode 100644 GDI-6ch/firmware/mc33816_control.h delete mode 100644 GDI-6ch/firmware/mc33816_data.c delete mode 100644 GDI-6ch/firmware/mc33816_data.h delete mode 100644 GDI-6ch/firmware/mc33816_memory_map.h create mode 100644 GDI-6ch/firmware/persistence.cpp create mode 100644 GDI-6ch/firmware/persistence.h create mode 100644 GDI-6ch/firmware/pt2000.cpp create mode 100644 GDI-6ch/firmware/pt2000.h create mode 100644 GDI-6ch/firmware/pt2000_memory_map.h create mode 100644 GDI-6ch/firmware/pt2000impl.h create mode 100644 GDI-6ch/project/Logic_Wave/wave_list.do create mode 100644 GDI-6ch/project/MicrocodeCh1/ch1.psc create mode 100644 GDI-6ch/project/MicrocodeCh1/ch1.psc.bak create mode 100644 GDI-6ch/project/MicrocodeCh1/dram1.def create mode 100644 GDI-6ch/project/MicrocodeCh2/ch2.psc create mode 100644 GDI-6ch/project/MicrocodeCh2/ch2.psc.bak create mode 100644 GDI-6ch/project/MicrocodeCh2/dram2.def create mode 100644 GDI-6ch/project/MicrocodeCh3/ch3.psc create mode 100644 GDI-6ch/project/MicrocodeCh3/ch3.psc.bak create mode 100644 GDI-6ch/project/MicrocodeCh3/dram3.def create mode 100644 GDI-6ch/project/Registers/ch1_config_reg.hex create mode 100644 GDI-6ch/project/Registers/ch2_config_reg.hex create mode 100644 GDI-6ch/project/Registers/ch3_config_reg.hex create mode 100644 GDI-6ch/project/Registers/diag_config_reg.hex create mode 100644 GDI-6ch/project/Registers/dram1.hex create mode 100644 GDI-6ch/project/Registers/dram2.hex create mode 100644 GDI-6ch/project/Registers/dram3.hex create mode 100644 GDI-6ch/project/Registers/io_config_reg.hex create mode 100644 GDI-6ch/project/Registers/main_config_reg.hex create mode 100644 GDI-6ch/project/SPIGenMC33PT2000Files.txt create mode 100644 GDI-6ch/project/sample_code/PT2000.c create mode 100644 GDI-6ch/project/sample_code/PT2000.h create mode 100644 GDI-6ch/project/sample_code/PT2000_LoadData.c create mode 100644 GDI-6ch/project/sample_code/PT2000_LoadData.h create mode 100644 GDI-6ch/project/sample_code/PT2000_dram.h create mode 100644 GDI-6ch/project/sample_code/PT2000_irq.c create mode 100644 GDI-6ch/project/sample_code/PT2000_irq.h create mode 100644 GDI-6ch/project/sample_code/PT2000_spi_map.h create mode 100644 GDI-6ch/project/sample_code/lpspi.c create mode 100644 GDI-6ch/project/sample_code/lpspi.h create mode 100644 GDI-6ch/project/sample_code/main.c create mode 100644 GDI-6ch/project/sample_code/main.h create mode 100644 GDI-6ch/project/sample_code/system.c create mode 100644 GDI-6ch/project/sample_code/system.h diff --git a/.vscode/launch.json b/.vscode/launch.json index 4ea78409..a1eb45db 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -5,17 +5,54 @@ "version": "0.2.0", "configurations": [ { - "name": "Debug GDI GD32", + "name": "Debug GDI-4 GD32", "type": "cortex-debug", "request": "launch", - "cwd": "${workspaceFolder}/GDI4-ch/firmware", - "executable": "${workspaceFolder}/GDI4-ch/firmware/build/gdi4.elf", + "cwd": "${workspaceFolder}/GDI-4ch/firmware", + "executable": "${workspaceFolder}/GDI-4ch/firmware/build/gdi4.elf", "device": "STM32F103CB", "v1": false, - "svdFile": "${workspaceFolder}/GDI4-ch/firmware/STM32F103xx.svd", - "servertype": "openocd", + "svdFile": "${workspaceFolder}/GDI-4ch/firmware/STM32F103xx.svd", + //"servertype": "openocd", + "servertype": "jlink", + "serverpath": "C:/Program Files/SEGGER/JLink/JLinkGDBServerCL.exe", + "interface": "swd", "configFiles": ["interface/stlink.cfg", "target/stm32f1x.cfg"], - "runToMain": true, + //"runToMain": true, + }, + { + "name": "Debug GDI-6 GD32", + "type": "cortex-debug", + "request": "launch", + "cwd": "${workspaceFolder}/GDI-6ch/firmware", + "executable": "${workspaceFolder}/GDI-6ch/firmware/build/gdi6.elf", + "device": "STM32F103CB", + "v1": false, + "svdFile": "${workspaceFolder}/GDI-6ch/firmware/STM32F103xx.svd", + //"servertype": "openocd", + "servertype": "jlink", + "serverpath": "C:/Program Files/SEGGER/JLink/JLinkGDBServerCL.exe", + "interface": "swd", + "configFiles": ["interface/stlink.cfg", "target/stm32f1x.cfg"], + //"runToMain": true, + } { + "name": "Debug GDI-6 STLINK", + "type": "cortex-debug", + "request": "launch", + "cwd": "${workspaceFolder}/GDI-6ch/firmware", + "executable": "${workspaceFolder}/GDI-6ch/firmware/build/gdi6.elf", + "device": "STM32F103CB", + "v1": false, + "svdFile": "${workspaceFolder}/GDI-6ch/firmware/STM32F103xx.svd", + //"servertype": "openocd", + "servertype": "stlink", + "serverpath": "C:/ST/STM32CubeIDE_1.16.0/STM32CubeIDE/plugins/com.st.stm32cube.ide.mcu.externaltools.stlink-gdb-server.win32_2.1.400.202404281720/tools/bin/ST-LINK_gdbserver.exe", + //"serverArgs": [ + //"-cp C:/ST/STM32CubeIDE_1.16.0/STM32CubeIDE/plugins/com.st.stm32cube.ide.mcu.externaltools.cubeprogrammer.win32_2.1.400.202404281720/tools/bin", + //"-d"], // swd + "interface": "swd", + //"configFiles": ["interface/stlink.cfg", "target/stm32f1x.cfg"], + //"runToMain": true, } ] } \ No newline at end of file diff --git a/GDI-6ch/firmware/Makefile b/GDI-6ch/firmware/Makefile index dc03fe5c..9e887ae1 100644 --- a/GDI-6ch/firmware/Makefile +++ b/GDI-6ch/firmware/Makefile @@ -5,7 +5,7 @@ # Compiler options here. ifeq ($(USE_OPT),) - USE_OPT = -O2 -ggdb -fomit-frame-pointer -falign-functions=16 -fsingle-precision-constant + USE_OPT = -O0 -ggdb -fomit-frame-pointer -falign-functions=16 -fsingle-precision-constant endif # C specific options here (added to USE_OPT). @@ -15,7 +15,7 @@ endif # C++ specific options here (added to USE_OPT). ifeq ($(USE_CPPOPT),) - USE_CPPOPT = -fno-rtti -fno-exceptions -ffast-math -funsafe-math-optimizations -fno-threadsafe-statics -fno-use-cxa-atexit + USE_CPPOPT = -fno-rtti -fno-exceptions -ffast-math -funsafe-math-optimizations -fno-threadsafe-statics -fno-use-cxa-atexit -std=c++17 endif # Enable this if you want the linker to remove unused code and data. @@ -83,7 +83,7 @@ endif # # Define project name here -PROJECT = gdi4 +PROJECT = gdi6 # Target settings. MCU = cortex-m3 @@ -100,6 +100,9 @@ ifeq ("$(wildcard $(CHIBIOS)/os/license/license.mk)","") $(error Please run 'git submodule update --init --recursive' before trying to build!) endif +# Configure libfirmware Paths/Includes +RUSEFI_LIB = ../../ext/libfirmware + # Licensing files. include $(CHIBIOS)/os/license/license.mk # Startup files. @@ -115,25 +118,30 @@ include $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/mk/port_v7m.mk # Auto-build files in ./source recursively. include $(CHIBIOS)/tools/mk/autobuild.mk # Other files (optional). +include $(CHIBIOS)/os/hal/lib/complex/mfs/hal_mfs.mk include $(CHIBIOS)/os/hal/lib/streams/streams.mk # Define linker script file here -LDSCRIPT= $(STARTUPLD)/STM32F103xB.ld +#LDSCRIPT= $(STARTUPLD)/STM32F103xB.ld +LDSCRIPT= gdi.ld # C sources that can be compiled in ARM or THUMB mode depending on the global # setting. CSRC = $(ALLCSRC) \ - mc33816_data.c + $(RUSEFI_LIB_C) \ + PT2000_LoadData.c # C++ sources that can be compiled in ARM or THUMB mode depending on the global # setting. CPPSRC = $(ALLCPPSRC) \ + $(RUSEFI_LIB_CPP) \ uart.cpp \ - mc33816_control.cpp \ + persistence.cpp \ + pt2000.cpp \ can.cpp \ fault.cpp \ - main.cpp + main.cpp # List ASM source files here. ASMSRC = $(ALLASMSRC) @@ -142,7 +150,9 @@ ASMSRC = $(ALLASMSRC) ASMXSRC = $(ALLXASMSRC) # Inclusion directories. -INCDIR = $(CONFDIR) $(ALLINC) +INCDIR = $(CONFDIR) $(ALLINC) \ + $(RUSEFI_LIB_INC) \ + $(RUSEFI_LIB)/can # Define C warning options here. CWARN = -Wall -Wextra -Wundef -Wstrict-prototypes diff --git a/GDI-6ch/firmware/PT2000_LoadData.c b/GDI-6ch/firmware/PT2000_LoadData.c new file mode 100644 index 00000000..4d510f8c --- /dev/null +++ b/GDI-6ch/firmware/PT2000_LoadData.c @@ -0,0 +1,171 @@ +/******************************************************************************* +* Example Code +* +* Copyright(C) 2025 NXP Semiconductors +* NXP Semiconductors Confidential and Proprietary +* +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* NXP products. This software is supplied "AS IS" without any warranties +* of any kind, and NXP Semiconductors and its licensor disclaim any and +* all warranties, express or implied, including all implied warranties of +* merchantability, fitness for a particular purpose and non-infringement of +* intellectual property rights. NXP Semiconductors assumes no responsibility +* or liability for the use of the software, conveys no license or rights +* under any patent, copyright, mask work right, or any other intellectual +* property rights in or to any products. NXP Semiconductors reserves the +* right to make changes in the software without notification. NXP +* Semiconductors also makes no representation or warranty that such +* application will be suitable for the specified use without further testing +* or modification. +* +* IN NO EVENT WILL NXP SEMICONDUCTORS BE LIABLE, WHETHER IN CONTRACT, +* TORT, OR OTHERWISE, FOR ANY INCIDENTAL, SPECIAL, INDIRECT, CONSEQUENTIAL +* OR PUNITIVE DAMAGES, INCLUDING, BUT NOT LIMITED TO, DAMAGES FOR ANY +* LOSS OF USE, LOSS OF TIME, INCONVENIENCE, COMMERCIAL LOSS, OR LOST +* PROFITS, SAVINGS, OR REVENUES, TO THE FULL EXTENT SUCH MAY BE DISCLAIMED +* BY LAW. NXP SEMICONDUCTOR’S TOTAL LIABILITY FOR ALL COSTS, DAMAGES, +* CLAIMS, OR LOSSES WHATSOEVER ARISING OUT OF OR IN CONNECTION WITH THE +* SOFTWARE IS LIMITED TO THE AGGREGATE AMOUNT PAID BY YOU TO NXP SEMICONDUCTORS +* IN CONNECTION WITH THE SOFTWARE TO WHICH LOSSES OR DAMAGES ARE CLAIMED. +* +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' and its +* licensor's relevant copyrights in the software, without fee, provided +* that it is used in conjunction with NXP Semiconductors devices. This +* copyright, permission, and disclaimer notice must appear in all copies +* of this code. +*******************************************************************************/ + +//============================================================================== +// This file contains data arrays that are used to load the code RAM, data RAM +// and registers on the PT2000. +//============================================================================== + +// ECU: IDE Project +// Project: rusefi + +#include "PT2000_LoadData.h" + +// Data to be loaded into the Code RAM 1 memory space +unsigned short PT2000_code_RAM1[116] = +{ + 0x3645, 0xB475, 0x5135, 0x3159, 0x200A, 0x860B, 0x10C4, 0x2F0A, 0x2958, 0x1E87, + 0xC964, 0xD52D, 0xB5C3, 0xDCB5, 0x39F9, 0x76F7, 0x2304, 0x84A7, 0x4729, 0xF6DC, + 0x9E2E, 0x4F10, 0x8BE3, 0x9157, 0x9B94, 0xC8BD, 0x8C8C, 0x5B8E, 0x9338, 0x8214, + 0x9D8B, 0x8D95, 0x71D3, 0xF684, 0x2A29, 0xF503, 0xD61A, 0xC3EB, 0x66FF, 0x84DA, + 0x4D1D, 0x4B20, 0x5A7B, 0x5CB6, 0x3828, 0x75A0, 0x36EC, 0x8097, 0xFED6, 0x8AD2, + 0x96F2, 0xACBE, 0x1F95, 0xA0DC, 0x27BD, 0x9F2C, 0x18BC, 0x7ED1, 0x1877, 0xF4AE, + 0x8B74, 0x0648, 0xF114, 0x6554, 0xCE5F, 0xAE7D, 0x3D7A, 0x9067, 0x3987, 0x8D21, + 0x81BE, 0x4FAC, 0x54EE, 0xFBD0, 0xB38C, 0x16EB, 0x4E72, 0x747E, 0xCC43, 0x191C, + 0xA60F, 0x0B69, 0x75B2, 0xD393, 0x1205, 0x44A4, 0xFF55, 0xC8C4, 0x9C8F, 0x4CBC, + 0xA329, 0x0877, 0x3657, 0x3AEB, 0xEFA1, 0xFA4C, 0x213C, 0xD0D1, 0xCDC9, 0x1405, + 0x18FB, 0xCF49, 0x401A, 0xD5BC, 0x605C, 0x6A2F, 0xAB01, 0x1676, 0x2C83, 0x442D, + 0x3915, 0x08EF, 0x4705, 0x883C, 0xAF0B, 0x8FCD +}; + +// Data to be loaded into the Code RAM 2 memory space +unsigned short PT2000_code_RAM2[62] = +{ + 0x3643, 0xB476, 0x5135, 0x3159, 0x200A, 0x840B, 0x12C4, 0x2F0A, 0x3868, 0x1E87, + 0xD874, 0xD52D, 0xB5DB, 0xDCB5, 0x39F9, 0x76F7, 0x2304, 0x84A7, 0x4729, 0xF6DC, + 0x9E2E, 0x4F10, 0x8BE3, 0x9157, 0x9B94, 0xC8BD, 0x8C8C, 0x5B8E, 0x9338, 0x820C, + 0x9D8B, 0x8D95, 0x71D3, 0xF684, 0x2A29, 0xF503, 0xD61A, 0xC3EB, 0x66FF, 0x84DA, + 0x4D1D, 0x4B20, 0x5A7B, 0x5CB6, 0x3828, 0x75A0, 0x36F4, 0x8097, 0xFED6, 0x8AD2, + 0x96F2, 0xACBE, 0x1F95, 0xA0DC, 0x27BD, 0x9F2C, 0x18BC, 0x7ED1, 0x1465, 0xF8D0, + 0x33FB, 0xB9A9 +}; + +// Data to be loaded into the Code RAM 3 memory space +unsigned short PT2000_code_RAM3[43] = +{ + 0x3647, 0xB47F, 0x51B1, 0x3159, 0x200A, 0x852A, 0x3D25, 0x8D10, 0x8606, 0xB456, + 0x8F79, 0xCE44, 0x00C2, 0x58C3, 0x6595, 0xE89E, 0x2B45, 0x1211, 0xB860, 0xF7F6, + 0xFC33, 0x4F0C, 0x8A62, 0x9CAF, 0x9A45, 0x4333, 0x8D09, 0xEC00, 0x41DE, 0x3652, + 0x99EA, 0x8345, 0x759D, 0x4297, 0xD69B, 0xF515, 0x639E, 0xC3AC, 0x237F, 0x8500, + 0x4C9E, 0x3B9B, 0x4139 +}; + +// Data to be loaded into the Data RAM memory space +unsigned short PT2000_data_RAM[192] = +{ + 0x008D, 0x006D, 0x003A, 0x003C, 0x1068, 0x003C, 0x0168, 0xEA60, 0x0960, 0x0258, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x008D, 0x006D, 0x003A, 0x003C, 0x1068, 0x003C, + 0x0168, 0xEA60, 0x0960, 0x0258, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00C1, 0x00BF, + 0x0040, 0x001D, 0x0000, 0x0046, 0x0037, 0x003C, 0xEA60, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000 +}; + +// Data to be loaded into the Main register memory space +unsigned short PT2000_main_config[32] = +{ + 0x0003, 0x0000, 0x0008, 0xE81F, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000, 0x001D, + 0x0000, 0x0000, 0x0000, 0x0000, 0xBF3F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000 +}; + +// Data to be loaded into the CH1 register memory space +unsigned short PT2000_ch1_config[20] = +{ + 0x0000, 0x0025, 0x0014, 0x0C03, 0x0000, 0x0001, 0x0001, 0x0074, 0x3B52, 0xA28B, + 0x0000, 0x003A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 + +}; + +// Data to be loaded into the CH2 register memory space +unsigned short PT2000_ch2_config[20] = +{ + 0x0000, 0x000C, 0x0070, 0x0030, 0x0000, 0x0002, 0x0002, 0x003E, 0x9F7E, 0x4EEC, + 0x0000, 0x003A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0010, 0x0000 + +}; + +// Data to be loaded into the CH3 register memory space +unsigned short PT2000_ch3_config[20] = +{ + 0x0000, 0x0003, 0x000C, 0x0080, 0x0000, 0x0000, 0x0000, 0x002B, 0x6F0D, 0x3DFF, + 0x0000, 0x0018, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0004, 0x0000 + +}; + +// Data to be loaded into the IO register memory space +unsigned short PT2000_io_config[73] = +{ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0303, 0x0C0C, 0x3030, 0x0000, 0x8040, 0x4000, 0x0201, 0x0040, + 0x3004, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0555, + 0x0555, 0x0050, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0707, 0x0707, + 0x0707, 0x0707, 0x0707, 0x00CD, 0x0020, 0x0000, 0x0000, 0x0017, 0x0016, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0003, + 0x0003, 0x000C, 0x000C, 0x0030, 0x0030, 0x0080, 0x0000, 0x0028, 0x0028, 0x0028, + 0x8110, 0x23C7, 0x0100 +}; + +// Data to be loaded into the Diag register memory space +unsigned short PT2000_diag_config[64] = +{ + 0x0000, 0x0000, 0x003E, 0x0000, 0x0000, 0x003E, 0x0000, 0x0000, 0x003E, 0x0000, + 0x0000, 0x003E, 0x0000, 0x0000, 0x003E, 0x0000, 0x0000, 0x003E, 0x0000, 0x0000, + 0x003E, 0x0000, 0x0000, 0x003E, 0x0000, 0x0000, 0x00FE, 0x0000, 0x0000, 0x00FE, + 0x0000, 0x0000, 0x00FE, 0x0000, 0x0000, 0x00FE, 0x0000, 0x0000, 0x00FE, 0x0000, + 0x0000, 0x00FE, 0x0000, 0x0000, 0x00FE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + diff --git a/GDI-6ch/firmware/PT2000_LoadData.h b/GDI-6ch/firmware/PT2000_LoadData.h new file mode 100644 index 00000000..4ebb167c --- /dev/null +++ b/GDI-6ch/firmware/PT2000_LoadData.h @@ -0,0 +1,62 @@ +/******************************************************************************* +* Example Code +* +* Copyright(C) 2025 NXP Semiconductors +* NXP Semiconductors Confidential and Proprietary +* +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* NXP products. This software is supplied "AS IS" without any warranties +* of any kind, and NXP Semiconductors and its licensor disclaim any and +* all warranties, express or implied, including all implied warranties of +* merchantability, fitness for a particular purpose and non-infringement of +* intellectual property rights. NXP Semiconductors assumes no responsibility +* or liability for the use of the software, conveys no license or rights +* under any patent, copyright, mask work right, or any other intellectual +* property rights in or to any products. NXP Semiconductors reserves the +* right to make changes in the software without notification. NXP +* Semiconductors also makes no representation or warranty that such +* application will be suitable for the specified use without further testing +* or modification. +* +* IN NO EVENT WILL NXP SEMICONDUCTORS BE LIABLE, WHETHER IN CONTRACT, +* TORT, OR OTHERWISE, FOR ANY INCIDENTAL, SPECIAL, INDIRECT, CONSEQUENTIAL +* OR PUNITIVE DAMAGES, INCLUDING, BUT NOT LIMITED TO, DAMAGES FOR ANY +* LOSS OF USE, LOSS OF TIME, INCONVENIENCE, COMMERCIAL LOSS, OR LOST +* PROFITS, SAVINGS, OR REVENUES, TO THE FULL EXTENT SUCH MAY BE DISCLAIMED +* BY LAW. NXP SEMICONDUCTOR’S TOTAL LIABILITY FOR ALL COSTS, DAMAGES, +* CLAIMS, OR LOSSES WHATSOEVER ARISING OUT OF OR IN CONNECTION WITH THE +* SOFTWARE IS LIMITED TO THE AGGREGATE AMOUNT PAID BY YOU TO NXP SEMICONDUCTORS +* IN CONNECTION WITH THE SOFTWARE TO WHICH LOSSES OR DAMAGES ARE CLAIMED. +* +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' and its +* licensor's relevant copyrights in the software, without fee, provided +* that it is used in conjunction with NXP Semiconductors devices. This +* copyright, permission, and disclaimer notice must appear in all copies +* of this code. +*******************************************************************************/ + +//============================================================================== +// This file contains data array declarations for the code RAM, data RAM and +// register arrays for the PT2000. +//============================================================================== + +// ECU: IDE Project +// Project: rusefi + +#ifndef PT2000_DATA_H_ +#define PT2000_DATA_H_ + +extern unsigned short PT2000_code_RAM1[116]; // CODE RAM CH 1 +extern unsigned short PT2000_code_RAM2[62]; // CODE RAM CH 2 +extern unsigned short PT2000_code_RAM3[43]; // CODE RAM CH 3 +extern unsigned short PT2000_data_RAM[192]; // DATA RAM +extern unsigned short PT2000_main_config[32]; // main configurations +extern unsigned short PT2000_ch1_config[20]; // CH 1 configurations +extern unsigned short PT2000_ch2_config[20]; // CH 2 configurations +extern unsigned short PT2000_ch3_config[20]; // CH 3 configurations +extern unsigned short PT2000_io_config[73]; // IO configurations +extern unsigned short PT2000_diag_config[64]; // diag configurations + +#endif /* PT2000_DATA_H_ */ diff --git a/GDI-6ch/firmware/gdi.ld b/GDI-6ch/firmware/gdi.ld new file mode 100644 index 00000000..92003633 --- /dev/null +++ b/GDI-6ch/firmware/gdi.ld @@ -0,0 +1,85 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/* + * ST32F103xB memory setup. + */ +MEMORY +{ + flash0 (rx) : org = 0x08000000, len = 60k + flash1 (rx) : org = 0x00000000, len = 0 + flash2 (rx) : org = 0x00000000, len = 0 + flash3 (rx) : org = 0x00000000, len = 0 + flash4 (rx) : org = 0x00000000, len = 0 + flash5 (rx) : org = 0x00000000, len = 0 + flash6 (rx) : org = 0x00000000, len = 0 + flash7 (rx) : org = 0x00000000, len = 0 + ram0 (wx) : org = 0x20000000, len = 20k + ram1 (wx) : org = 0x00000000, len = 0 + ram2 (wx) : org = 0x00000000, len = 0 + ram3 (wx) : org = 0x00000000, len = 0 + ram4 (wx) : org = 0x00000000, len = 0 + ram5 (wx) : org = 0x00000000, len = 0 + ram6 (wx) : org = 0x00000000, len = 0 + ram7 (wx) : org = 0x00000000, len = 0 +} + +/* For each data/text section two region are defined, a virtual region + and a load region (_LMA suffix).*/ + +/* Flash region to be used for exception vectors.*/ +REGION_ALIAS("VECTORS_FLASH", flash0); +REGION_ALIAS("VECTORS_FLASH_LMA", flash0); + +/* Flash region to be used for constructors and destructors.*/ +REGION_ALIAS("XTORS_FLASH", flash0); +REGION_ALIAS("XTORS_FLASH_LMA", flash0); + +/* Flash region to be used for code text.*/ +REGION_ALIAS("TEXT_FLASH", flash0); +REGION_ALIAS("TEXT_FLASH_LMA", flash0); + +/* Flash region to be used for read only data.*/ +REGION_ALIAS("RODATA_FLASH", flash0); +REGION_ALIAS("RODATA_FLASH_LMA", flash0); + +/* Flash region to be used for various.*/ +REGION_ALIAS("VARIOUS_FLASH", flash0); +REGION_ALIAS("VARIOUS_FLASH_LMA", flash0); + +/* Flash region to be used for RAM(n) initialization data.*/ +REGION_ALIAS("RAM_INIT_FLASH_LMA", flash0); + +/* RAM region to be used for Main stack. This stack accommodates the processing + of all exceptions and interrupts.*/ +REGION_ALIAS("MAIN_STACK_RAM", ram0); + +/* RAM region to be used for the process stack. This is the stack used by + the main() function.*/ +REGION_ALIAS("PROCESS_STACK_RAM", ram0); + +/* RAM region to be used for data segment.*/ +REGION_ALIAS("DATA_RAM", ram0); +REGION_ALIAS("DATA_RAM_LMA", flash0); + +/* RAM region to be used for BSS segment.*/ +REGION_ALIAS("BSS_RAM", ram0); + +/* RAM region to be used for the default heap.*/ +REGION_ALIAS("HEAP_RAM", ram0); + +/* Generic rules inclusion.*/ +INCLUDE rules.ld diff --git a/GDI-6ch/firmware/halconf.h b/GDI-6ch/firmware/halconf.h index 38ae0948..36cd128c 100644 --- a/GDI-6ch/firmware/halconf.h +++ b/GDI-6ch/firmware/halconf.h @@ -72,7 +72,7 @@ * @brief Enables the EFlash subsystem. */ #if !defined(HAL_USE_EFL) || defined(__DOXYGEN__) -#define HAL_USE_EFL FALSE +#define HAL_USE_EFL TRUE #endif /** diff --git a/GDI-6ch/firmware/io_pins.h b/GDI-6ch/firmware/io_pins.h index a07ec806..d7d89af0 100644 --- a/GDI-6ch/firmware/io_pins.h +++ b/GDI-6ch/firmware/io_pins.h @@ -15,3 +15,55 @@ // D21 #define LED_GREEN_PORT GPIOA #define LED_GREEN_PIN 8 + +// UART +#define UART_TX_PORT GPIOA +#define UART_TX_PIN 9 +#define UART_RX_PORT GPIOA +#define UART_RX_PIN 10 + +// CAN +#define CAN_RX_PORT GPIOA +#define CAN_RX_PIN 11 +#define CAN_TX_PORT GPIOA +#define CAN_TX_PIN 12 + +// SPI +#define SPI_SCK_PORT GPIOA +#define SPI_SCK_PIN 5 +#define SPI_MISO_PORT GPIOA +#define SPI_MISO_PIN 6 +#define SPI_MOSI_PORT GPIOA +#define SPI_MOSI_PIN 7 + +// PT2001 specifics +#define SPI_CS_PORT GPIOB +#define SPI_CS_PIN 2 + +#define PT_DRVEN_PORT GPIOB +#define PT_DRVEN_PIN 4 +#define PT_RESET_PORT GPIOB +#define PT_RESET_PIN 5 + +#define PT_FLAG_0_PORT GPIOB +#define PT_FLAG_0_PIN 7 +#define PT_FLAG_1_PORT GPIOB +#define PT_FLAG_1_PIN 10 +#define PT_FLAG_2_PORT GPIOB +#define PT_FLAG_2_PIN 11 +#define PT_FLAG_3_PORT GPIOA +#define PT_FLAG_3_PIN 15 +#define PT_FLAG_4_PORT GPIOD +#define PT_FLAG_4_PIN 0 + +#define PT_OA_1_PORT GPIOB +#define PT_OA_1_PIN 0 +#define PT_OA_2_PORT GPIOB +#define PT_OA_2_PIN 1 +#define PT_OA_3_PORT GPIOA +#define PT_OA_3_PIN 1 + +#define PT_IRQ_PORT GPIOB +#define PT_IRQ_PIN 9 +#define PT_DBG_PORT GPIOB +#define PT_DBG_PIN 12 \ No newline at end of file diff --git a/GDI-6ch/firmware/main.cpp b/GDI-6ch/firmware/main.cpp index 34d66557..3cbad018 100644 --- a/GDI-6ch/firmware/main.cpp +++ b/GDI-6ch/firmware/main.cpp @@ -5,350 +5,107 @@ #include "fault.h" #include "uart.h" #include "io_pins.h" +#include "can_common.h" +#include "persistence.h" -#include "mc33816_control.h" -#include "mc33816_data.h" -#include "mc33816_memory_map.h" +//#include "PT2000_LoadData.h" +//#include "pt2000_memory_map.h" +#include "pt2000impl.h" static void InitPins() { + // UART // stm32 TX - dongle RX often White - palSetPadMode(GPIOA, 9, PAL_MODE_STM32_ALTERNATE_PUSHPULL ); + palSetPadMode(UART_TX_PORT, UART_TX_PIN, PAL_MODE_STM32_ALTERNATE_PUSHPULL ); // stm32 RX - dongle TX often Green - palSetPadMode(GPIOA,10, PAL_MODE_INPUT_PULLUP ); + palSetPadMode(UART_RX_PORT, UART_RX_PIN, PAL_MODE_INPUT_PULLUP ); - // CAN TX - palSetPadMode(GPIOA,12, PAL_MODE_STM32_ALTERNATE_PUSHPULL ); - // CAN RX - palSetPadMode(GPIOA,11, PAL_MODE_INPUT_PULLUP ); -} - - - -const int MC_CK = 6; // PLL x24 / CLK_DIV 4 = 6Mhz - -const int MAX_SPI_MODE_A_TRANSFER_SIZE = 31; //max size for register config transfer + // CAN + palSetPadMode(CAN_TX_PORT, CAN_TX_PIN, PAL_MODE_STM32_ALTERNATE_PUSHPULL ); + palSetPadMode(CAN_RX_PORT, CAN_RX_PIN, PAL_MODE_INPUT_PULLUP ); -enum { - CODE_RAM1, - CODE_RAM2, - DATA_RAM -}; -enum { - REG_MAIN, - REG_CH1, - REG_CH2, - REG_IO, - REG_DIAG -}; + // GD32 errata, PB1 must have certain states for PB2 to work + //palSetPadMode(GPIOB, 1, PAL_MODE_INPUT); + // Set debug pins remap mode to use PB4 as normal pin, we need it for DRVEN + AFIO->MAPR = AFIO_MAPR_SWJ_CFG_JTAGDISABLE; +} static const SPIConfig spiCfg = { .circular = false, .end_cb = nullptr, - .ssport = GPIOB, - .sspad = 2, + .ssport = SPI_CS_PORT, + .sspad = SPI_CS_PIN, .cr1 = - SPI_CR1_DFF | + SPI_CR1_DFF | // 16-bit SPI_CR1_MSTR | SPI_CR1_CPHA | SPI_CR1_BR_1 | SPI_CR1_SPE, .cr2 = SPI_CR2_SSOE }; -auto driver = &SPID1; +void GDIConfiguration::resetToDefaults() { + version = PERSISTENCE_VERSION; + updateCounter = 20; + inputCanID = GDI4_BASE_ADDRESS + 0x10; + outputCanID = GDI4_BASE_ADDRESS; -// Read a single word in Data RAM -unsigned short mcReadDram(MC33816Mem addr) { - unsigned short readValue; - spiSelect(driver); - // Select Channel command, Common Page - spi_writew(0x7FE1); - spi_writew(0x0004); - // read (MSB=1) at data ram x9 (SCV_I_Hold), and 1 word - spi_writew((0x8000 | addr << 5) + 1); - readValue = recv_16bit_spi(); + BoostVoltage = 65; + BoostCurrent = 13; + TBoostMin = 100; + TBoostMax = 400; - spiUnselect(driver); - return readValue; -} + PeakCurrent = 9.4f; + TpeakDuration = 700; // 700us = 0.7ms + TpeakOff = 10; + Tbypass = 10; -// Update a single word in Data RAM -void mcUpdateDram(MC33816Mem addr, unsigned short data) { - spiSelect(driver); - // Select Channel command, Common Page - spi_writew(0x7FE1); - spi_writew(0x0004); - // write (MSB=0) at data ram x9 (SCV_I_Hold), and 1 word - spi_writew((addr << 5) + 1); - spi_writew(data); + HoldCurrent = 3.7f; + TholdOff = 60; + THoldDuration = 10000; // 10000us = 10ms - spiUnselect(driver); + PumpPeakCurrent = 5; + PumpHoldCurrent = 3; + PumpTholdOff = 10; + PumpTholdTot = 10000; // 10000us = 10ms } -static short dacEquation(unsigned short current) { - /* - Current, given in mA->A - I = (DAC_VALUE * V_DAC_LSB - V_DA_BIAS)/(G_DA_DIFF * R_SENSEx) - DAC_VALUE = ((I*G_DA_DIFF * R_SENSEx) + V_DA_BIAS) / V_DAC_LSB - V_DAC_LSB is the DAC resolution = 9.77mv - V_DA_BIAS = 250mV - G_DA_DIFF = Gain: 5.79, 8.68, [12.53], 19.25 - R_SENSE = 10mOhm soldered on board - */ - return (short)(((current/1000.0f * 12.53f * 10) + 250.0f) / 9.77f); -} - -static void setTimings() { - - // Convert mA to DAC values - // mcUpdateDram(MC33816Mem::Iboost, dacEquation(engineConfiguration->mc33_i_boost)); - // mcUpdateDram(MC33816Mem::Ipeak, dacEquation(engineConfiguration->mc33_i_peak)); - // mcUpdateDram(MC33816Mem::Ihold, dacEquation(engineConfiguration->mc33_i_hold)); - - // // uint16_t mc33_t_max_boost; // not yet implemented in microcode - - // // in micro seconds to clock cycles - // mcUpdateDram(MC33816Mem::Tpeak_off, (MC_CK * engineConfiguration->mc33_t_peak_off)); - // mcUpdateDram(MC33816Mem::Tpeak_tot, (MC_CK * engineConfiguration->mc33_t_peak_tot)); - // mcUpdateDram(MC33816Mem::Tbypass, (MC_CK * engineConfiguration->mc33_t_bypass)); - // mcUpdateDram(MC33816Mem::Thold_off, (MC_CK * engineConfiguration->mc33_t_hold_off)); - // mcUpdateDram(MC33816Mem::Thold_tot, (MC_CK * engineConfiguration->mc33_t_hold_tot)); +GDIConfiguration configuration; - // // HPFP solenoid settings - // mcUpdateDram(MC33816Mem::HPFP_Ipeak, - // dacEquation(engineConfiguration->mc33_hpfp_i_peak * 1000)); - // mcUpdateDram(MC33816Mem::HPFP_Ihold, - // dacEquation(engineConfiguration->mc33_hpfp_i_hold * 1000)); - // mcUpdateDram(MC33816Mem::HPFP_Thold_off, - // std::min(MC_CK * engineConfiguration->mc33_hpfp_i_hold_off, - // UINT16_MAX)); - // // Note, if I'm reading this right, the use of the short and the given clock speed means - // // the max time here is approx 10ms. - // mcUpdateDram(MC33816Mem::HPFP_Thold_tot, - // std::min(MC_CK * 1000 * engineConfiguration->mc33_hpfp_max_hold, - // UINT16_MAX)); +GDIConfiguration *getConfiguration() { + return &configuration; } -void setBoostVoltage(float volts) -{ - // Sanity checks, Datasheet says not too high, nor too low - if (volts > 65.0f) { - // firmwareError(OBD_PCM_Processor_Fault, "DI Boost voltage setpoint too high: %.1f", volts); - return; - } - if (volts < 10.0f) { - // firmwareError(OBD_PCM_Processor_Fault, "DI Boost voltage setpoint too low: %.1f", volts); - return; - } - // There's a 1/32 divider on the input, then the DAC's output is 9.77mV per LSB. (1 / 32) / 0.00977 = 3.199 counts per volt. - unsigned short data = volts * 3.2; - mcUpdateDram(MC33816Mem::Vboost_high, data+1); - mcUpdateDram(MC33816Mem::Vboost_low, data /* -1 */); - // Remember to strobe driven!! -} - -static bool check_flash() { - spiSelect(driver); - - // ch1 - // read (MSB=1) at location, and 1 word - spi_writew((0x8000 | 0x100 << 5) + 1); - if (!(recv_16bit_spi() & (1<<5))) { - spiUnselect(driver); - return false; - } - - // ch2 - // read (MSB=1) at location, and 1 word - spi_writew((0x8000 | 0x120 << 5) + 1); - if (!(recv_16bit_spi() & (1<<5))) { - spiUnselect(driver); - return false; - } - spiUnselect(driver); - return true; -} +bool Pt2000::init() { + // SPI + palSetPadMode(SPI_SCK_PORT, SPI_SCK_PIN, PAL_MODE_STM32_ALTERNATE_PUSHPULL); + palSetPadMode(SPI_MISO_PORT, SPI_MISO_PIN, PAL_MODE_INPUT); + palSetPadMode(SPI_MOSI_PORT, SPI_MOSI_PIN, PAL_MODE_STM32_ALTERNATE_PUSHPULL); + // PT Specifics + palSetPadMode(SPI_CS_PORT, SPI_CS_PIN, PAL_MODE_OUTPUT_PUSHPULL); + palSetPadMode(PT_DRVEN_PORT, PT_DRVEN_PIN, PAL_MODE_OUTPUT_PUSHPULL); + palClearPad(PT_DRVEN_PORT, PT_DRVEN_PIN); + palSetPadMode(PT_RESET_PORT, PT_RESET_PIN, PAL_MODE_OUTPUT_PUSHPULL); + palSetPadMode(PT_FLAG_0_PORT, PT_FLAG_0_PIN, PAL_MODE_INPUT); + //palSetPad(PT_FLAG_0_PORT, PT_FLAG_0_PIN); + palSetPadMode(PT_OA_1_PORT, PT_OA_1_PIN, PAL_MODE_INPUT); + palSetPadMode(PT_OA_2_PORT, PT_OA_2_PIN, PAL_MODE_INPUT); + palSetPadMode(PT_OA_3_PORT, PT_OA_3_PIN, PAL_MODE_INPUT); -static unsigned short readDriverStatus(){ - unsigned short driverStatus; - setup_spi(); // ensure on common page? - spiSelect(driver); - spi_writew((0x8000 | 0x1D2 << 5) + 1); - driverStatus = recv_16bit_spi(); + driver = &SPID1; + spiStart(driver, &spiCfg); spiUnselect(driver); - return driverStatus; -} - -static bool checkUndervoltVccP(unsigned short driverStatus){ - return (driverStatus & (1<<0)); -} -static bool checkUndervoltV5(unsigned short driverStatus){ - return (driverStatus & (1<<1)); -} + // Wait 1/2 second for things to wake up + chThdSleepMilliseconds(500); -static bool checkOverTemp(unsigned short driverStatus){ - return (driverStatus & (1<<3)); + return restart(); } -static bool checkDrivenEnabled(unsigned short driverStatus){ - return (driverStatus & (1<<4)); -} - -static void enable_flash() { - spiSelect(driver); - spi_writew(0x2001); //ch1 - spi_writew(0x0018); //enable flash - spi_writew(0x2401); //ch2 - spi_writew(0x0018); // enable flash - spiUnselect(driver); -} -static void download_RAM(int target) { - uint16_t memory_area = 0; // memory area - uint16_t start_address = 0; // start address - uint16_t codeWidthRegAddr = 0; // code width register address - uint16_t size = 0; // size of RAM data - uint16_t command = 0; // command data - const uint16_t *RAM_ptr; // pointer to array of data to be sent to the chip +Pt2000 chip; - //Why Again? For Every time, just in case? - setup_spi(); - - switch(target) // selects target - { - case CODE_RAM1: - memory_area = 0x1; - start_address = 0; - codeWidthRegAddr = 0x107; - RAM_ptr = MC33816_code_RAM1; - size = sizeof(MC33816_code_RAM1) / 2; - break; - - case CODE_RAM2: - memory_area = 0x2; - start_address = 0; - codeWidthRegAddr = 0x127; - RAM_ptr = MC33816_code_RAM2; - size = sizeof(MC33816_code_RAM2) / 2; - break; - - case DATA_RAM: // ch1 only? - memory_area = 0x4; - start_address = 0; - RAM_ptr = MC33816_data_RAM; - size = sizeof(MC33816_data_RAM) / 2; - break; -// optional, both data_rams with 0x3, writes same code to both - default: - break; - } - - // Chip-Select high - spiSelect(driver); - - if (target != DATA_RAM) - { - command = codeWidthRegAddr << 5; // control width register address - command |= 1; // number of words to follow - spi_writew(command); // sends code_width command - spi_writew(size); // sends size (Code Width) - } - - // Select Channel command - spi_writew(0x7FE1); - // RAM1, RAM2, or Common Page (Data RAM) - spi_writew(memory_area); - - // "Command" of starting address - // up to 0x03FE of code ram - // up to 0x0080 of data ram - command = start_address << 5; - spi_writew(command); // sends start address command - - spiSend(driver, size, RAM_ptr); - spiUnselect(driver); -} - -static void download_register(int r_target) { - uint16_t r_start_address = 0; // start address - uint16_t r_size = 0; // size of configuration data - uint16_t r_command = 0; // command data - uint16_t remainder_size = 0; // remainder size - const uint16_t *reg_ptr; // pointer to array of data to be sent to the chip - - switch(r_target) // selects target - { - case REG_CH1: // channel 1 configurations - r_start_address = 0x100; - reg_ptr = MC33816_ch1_config; - r_size = sizeof(MC33816_ch1_config) / 2; // gets number of words to be sent - break; - - case REG_CH2: // channel 2 configurations - r_start_address = 0x120; - reg_ptr = MC33816_ch2_config; - r_size = sizeof(MC33816_ch2_config) / 2; // gets number of words to be sent - break; - - case REG_DIAG: // diagnostic configurations - r_start_address = 0x140; - reg_ptr = MC33816_diag_config; - r_size = sizeof(MC33816_diag_config) / 2; // gets number of words to be sent - break; - - case REG_IO: // IO configurations - r_start_address = 0x180; - reg_ptr = MC33816_io_config; - r_size = sizeof(MC33816_io_config) / 2; // gets number of words to be sent - break; - - case REG_MAIN: // main configurations - r_start_address = 0x1C0; - reg_ptr = MC33816_main_config; - r_size = sizeof(MC33816_main_config) / 2; // gets number of words to be sent - break; - - default: - break; - } - - //for location < size(remainder?) - // is location == 0? or past max xfer, send command + expected size - // if location = max xfer - // - // retrieve data, send it, increase pointer - // increase - - if (r_size > MAX_SPI_MODE_A_TRANSFER_SIZE) //if size is too large, split into two sections ... MULTIPLE sections.. - { - remainder_size = r_size - MAX_SPI_MODE_A_TRANSFER_SIZE; // creates remaining size - r_size = MAX_SPI_MODE_A_TRANSFER_SIZE; // sets first size - } - - r_command = r_start_address << 5; // start address - r_command += r_size; // number of words to follow - - spiSelect(driver); // Chip - - spi_writew(r_command); // sends address and number of words to be sent - - spiSend(driver, r_size, reg_ptr); - - if (remainder_size > 0) // if remainder size is greater than 0, download the rest - { - r_start_address += r_size; // new start address - r_command = r_start_address << 5; // start address - r_command += remainder_size; // number of words to follow - - spi_writew(r_command); // sends address and number of words to be sent - spiSend(driver, remainder_size, reg_ptr + r_size); - } - spiUnselect(driver); -} - /* * Application entry point. */ @@ -357,72 +114,18 @@ int main() { chSysInit(); // Fire up all of our threads - InitPins(); InitCan(); InitUart(); - palSetPadMode(GPIOA, 5, PAL_MODE_STM32_ALTERNATE_PUSHPULL); // sck - palSetPadMode(GPIOA, 6, PAL_MODE_INPUT); // miso - palSetPadMode(GPIOA, 7, PAL_MODE_STM32_ALTERNATE_PUSHPULL); // mosi - // GD32 errata, PB1 must have certain states for PB2 to work - palSetPadMode(GPIOB, 1, PAL_MODE_INPUT); - palSetPadMode(GPIOB, 2, PAL_MODE_OUTPUT_PUSHPULL); // chip select - palSetPad(GPIOB, 2); + bool isOverallHappyStatus = false; - palSetPadMode(GPIOB, 4, PAL_MODE_OUTPUT_PUSHPULL); // DRVEN - palClearPad(GPIOB, 4); - - palSetPadMode(GPIOB, 5, PAL_MODE_OUTPUT_PUSHPULL); // reset - palSetPad(GPIOB, 5); - - spiStart(driver, &spiCfg); - spiUnselect(driver); - - palClearPad(GPIOB, 5); // reset - chThdSleepMilliseconds(10); - palSetPad(GPIOB, 5); // take out of reset - chThdSleepMilliseconds(10); - - setup_spi(); - - mcClearDriverStatus(); // Initial clear necessary - auto mcDriverStatus = readDriverStatus(); - if (checkUndervoltV5(mcDriverStatus)) { - // TODO - } - - download_RAM(CODE_RAM1); // transfers code RAM1 - download_RAM(CODE_RAM2); // transfers code RAM2 - download_RAM(DATA_RAM); // transfers data RAM - /** - * current configuration of REG_MAIN would toggle flag0 from LOW to HIGH - */ - download_register(REG_MAIN); // download main register configurations - - download_register(REG_CH1); // download channel 1 register configurations - download_register(REG_CH2); // download channel 2 register configurations - download_register(REG_IO); // download IO register configurations - download_register(REG_DIAG); // download diag register configuration - - setTimings(); - - // Finished downloading, let's run the code - enable_flash(); - - // Set boost voltage - setBoostVoltage(65); - - // TURN ON THE BOOST CONVERTER! - palSetPad(GPIOB, 4); + // reminder that +12v is required for PT2001 to start + isOverallHappyStatus = chip.init(); while (true) { - auto id = readId(); - - palSetPadMode(LED_BLUE_PORT, LED_BLUE_PIN, PAL_MODE_OUTPUT_PUSHPULL); - - if ((id >> 8) == 0x9D) { + if (isOverallHappyStatus) { // happy board - green D21 blinking palTogglePad(LED_GREEN_PORT, LED_GREEN_PIN); } else { @@ -431,12 +134,4 @@ int main() { chThdSleepMilliseconds(100); } - - while(true) - { - //auto fault = GetCurrentFault(); - - //palTogglePad(LED_BLUE_PORT, LED_BLUE_PIN); - chThdSleepMilliseconds(100); - } } diff --git a/GDI-6ch/firmware/mc33816_control.cpp b/GDI-6ch/firmware/mc33816_control.cpp deleted file mode 100644 index c9704534..00000000 --- a/GDI-6ch/firmware/mc33816_control.cpp +++ /dev/null @@ -1,56 +0,0 @@ - -#include "mc33816_control.h" - -static auto spiDriver = &SPID1; - -// Receive 16bits -unsigned short recv_16bit_spi() { - return spiPolledExchange(spiDriver, 0xFFFF); -} - -// This could be used to detect if check byte is wrong.. or use a FLAG after init -unsigned short txrx_16bit_spi(const unsigned short param) { - return spiPolledExchange(spiDriver, param); -} - -void mcClearDriverStatus() { - // Note: There is a config at 0x1CE & 1 that can reset this status config register on read - // otherwise the reload/recheck occurs with this write - // resetting it is necessary to clear default reset behavoir, as well as if an issue has been resolved - setup_spi(); // ensure on common page? - spiSelect(spiDriver); - spi_writew((0x0000 | 0x1D2 << 5) + 1); // write, location, one word - spi_writew(0x0000); // anything to clear - spiUnselect(spiDriver); -} - -void setup_spi() { - spiSelect(spiDriver); - // Select Channel command - spi_writew(0x7FE1); - // Common Page - spi_writew(0x0004); - - - // Configure SPI command - spi_writew(0x3901); - // Mode A + Watchdog timer full - //spi_writew(0x001F); - spi_writew(0x009F); // + fast slew rate on miso - spiUnselect(spiDriver); -} - -// Send 16bits -void spi_writew(unsigned short param) { - //spiSelect(spiDriver); - spiPolledExchange(spiDriver, param); - //spiUnselect(spiDriver); -} - -unsigned short readId() { - spiSelect(spiDriver); - spi_writew(0xBAA1); - unsigned short ID = recv_16bit_spi(); - spiUnselect(spiDriver); - return ID; -} diff --git a/GDI-6ch/firmware/mc33816_control.h b/GDI-6ch/firmware/mc33816_control.h deleted file mode 100644 index 0847b48f..00000000 --- a/GDI-6ch/firmware/mc33816_control.h +++ /dev/null @@ -1,11 +0,0 @@ -#include "ch.h" -#include "hal.h" - -// generic helper methods -void setup_spi(); -unsigned short recv_16bit_spi(); -void spi_writew(unsigned short param); -unsigned short txrx_16bit_spi(const unsigned short param); - -void mcClearDriverStatus(); -unsigned short readId(); \ No newline at end of file diff --git a/GDI-6ch/firmware/mc33816_data.c b/GDI-6ch/firmware/mc33816_data.c deleted file mode 100644 index 659178d7..00000000 --- a/GDI-6ch/firmware/mc33816_data.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * mc33816_data.c - * - * For historic reasons rusEFI source code refers to all this as mc33816 while the microcode - * is signed with MC33PT2001 key. to use real mc33816 you would have to replace binary data with true mc33816 version - * - * this is manual copy-paste of sample_code/PT2001_LoadData.c - * see mc33816/rusefi/readme.md - */ - -// Data to be loaded into the Code RAM 1 memory space -const unsigned short MC33816_code_RAM1[88] = -{ - 0x7612, 0x6C2B, 0x917F, 0xA514, 0x8DD1, 0xC289, 0x7C38, 0xA73B, 0xF359, 0x56C3, - 0xEE73, 0x812F, 0xDFA9, 0x2ED5, 0x2722, 0xBC58, 0x649B, 0xFB66, 0xFAD7, 0xBB51, - 0xBD0C, 0xBEA9, 0x2F34, 0xDA2C, 0x41CF, 0x8DDD, 0xB4F4, 0xCA54, 0xAF19, 0x6707, - 0xDA8A, 0x1D69, 0x6015, 0xA215, 0xB473, 0xF3AB, 0x6CC1, 0xE620, 0x8D0F, 0x5FC6, - 0x3DA2, 0x4662, 0x0EF2, 0x63A6, 0xEFAD, 0x9915, 0xA134, 0xBB55, 0xD6E8, 0xBDC9, - 0x433D, 0x3943, 0x4AEA, 0xCD3C, 0xE90A, 0xC413, 0xD3A3, 0xF690, 0xE423, 0x0106, - 0x72BC, 0xD39A, 0x0329, 0x3AF3, 0x9F62, 0x9FA6, 0xD615, 0xEF1D, 0xAF32, 0x31BF, - 0x5A43, 0x2FAD, 0xFD4E, 0xB35B, 0x56F3, 0xFAB7, 0x5ADE, 0x3A4C, 0xCA7D, 0x20AF, - 0x24CE, 0x808E, 0x43CD, 0xDF83, 0xE8DF, 0x7CC1, 0xE738, 0x1B09 -}; - -// Data to be loaded into the Code RAM 2 memory space -const unsigned short MC33816_code_RAM2[43] = -{ - 0x761B, 0x6F45, 0x838D, 0x80B4, 0x53F2, 0x0EBC, 0x8F2D, 0xA78E, 0xE8AB, 0xE3DB, - 0xF477, 0x800F, 0x2336, 0x2F77, 0x267B, 0xBC19, 0x007E, 0x4E55, 0x28AA, 0x52E4, - 0x40CF, 0x0AFD, 0x8B32, 0xFF03, 0x3D8E, 0x802E, 0x1340, 0x95D0, 0x1E86, 0x6591, - 0xDBEB, 0x786D, 0xB2DF, 0xF4BF, 0xBEB2, 0xF1F4, 0x9E53, 0xE743, 0xE842, 0x3DD7, - 0x3DA2, 0x4663, 0x03AF -}; - -// Data to be loaded into the Data RAM memory space -const unsigned short MC33816_data_RAM[128] = -{ - 0x00F0, 0x00F0, 0x008C, 0x2000, 0x01F4, 0x00B4, 0x003C, 0xEA60, 0x0000, 0x003D, - 0x6000, 0x003C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x00C1, 0x00BF, 0x002F, 0x001D, 0x0000, 0x0046, - 0x0037, 0x003C, 0xEA60, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 -}; - -// 0x1CE -// if set to '1' Driver_status register is reset on read. -#define Rsetbr 1 - -// Data to be loaded into the Main register memory space -const unsigned short MC33816_main_config[29] = -{ - 0x0003, 0x1FFE, 0x0000, 0x1200, 0x0000, 0x0000, 0x0001, 0x0000, 0x001F, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, Rsetbr, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 -}; - -// Data to be loaded into the CH1 register memory space -const unsigned short MC33816_ch1_config[19] = -{ - 0x0008, 0x0000, 0x0000, 0x0000, 0x0303, 0x0000, 0x0000, 0x0058, 0x8E62, 0x7B23, - 0x0000, 0x002C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 -}; - -// Data to be loaded into the CH2 register memory space -const unsigned short MC33816_ch2_config[19] = -{ - 0x0008, 0x0000, 0x0000, 0x0000, 0x0C00, 0x0000, 0x0000, 0x002B, 0x218C, 0xDCB6, - 0x0000, 0x0014, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 -}; - -// Data to be loaded into the IO register memory space -const unsigned short MC33816_io_config[44] = -{ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0063, 0x018C, 0x0800, 0x0410, 0x0041, 0x0098, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0041, 0x0041, 0x0041, 0x0000, 0x0004, 0x1000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7F7F, 0x7F7F, - 0x007F, 0x0000, 0x0000, 0x0000 -}; - -// Data to be loaded into the Diag register memory space -const unsigned short MC33816_diag_config[44] = -{ - 0x0000, 0x0000, 0x001E, 0x0000, 0x0000, 0x001E, 0x0000, 0x0000, 0x001E, 0x0000, - 0x0000, 0x001E, 0x0000, 0x0000, 0x001E, 0x0000, 0x0000, 0x001E, 0x001E, 0x0000, - 0x0000, 0x001E, 0x0000, 0x0000, 0x001E, 0x0000, 0x0000, 0x001E, 0x0000, 0x0000, - 0x001E, 0x0000, 0x0000, 0x001E, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0001 -}; diff --git a/GDI-6ch/firmware/mc33816_data.h b/GDI-6ch/firmware/mc33816_data.h deleted file mode 100644 index d838ad9f..00000000 --- a/GDI-6ch/firmware/mc33816_data.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * mc33816_data.h - * - * @date May 3, 2019 - * @author Andrey Belomutskiy, (c) 2012-2020 - */ - -#pragma once - -extern const unsigned short MC33816_code_RAM1[88]; // CODE RAM CH 1 -extern const unsigned short MC33816_code_RAM2[43]; // CODE RAM CH 2 -extern const unsigned short MC33816_data_RAM[128]; // DATA RAM -extern const unsigned short MC33816_main_config[29]; // main configurations -extern const unsigned short MC33816_ch1_config[19]; // CH 1 configurations -extern const unsigned short MC33816_ch2_config[19]; // CH 2 configurations -extern const unsigned short MC33816_io_config[44]; // IO configurations -extern const unsigned short MC33816_diag_config[44]; // diag configurations - diff --git a/GDI-6ch/firmware/mc33816_memory_map.h b/GDI-6ch/firmware/mc33816_memory_map.h deleted file mode 100644 index b1ddd837..00000000 --- a/GDI-6ch/firmware/mc33816_memory_map.h +++ /dev/null @@ -1,24 +0,0 @@ -/** - * see mc33816/rusefi/readme.md -*/ - -typedef enum { - // see dram1.def values - Iboost = 0, - Ipeak = 1, - Ihold = 2, - Tpeak_off = 3, - Tpeak_tot = 4, - Tbypass = 5, - Thold_off = 6, - Thold_tot = 7, - // see dram2.def values, base 64 for channel 2 - Vboost_high = 64, - Vboost_low = 65, - Isense4_high = 66, - Isense4_low = 67, - HPFP_Ipeak = 69, - HPFP_Ihold = 70, - HPFP_Thold_off = 71, - HPFP_Thold_tot = 72, -} MC33816Mem; diff --git a/GDI-6ch/firmware/persistence.cpp b/GDI-6ch/firmware/persistence.cpp new file mode 100644 index 00000000..d85fd34d --- /dev/null +++ b/GDI-6ch/firmware/persistence.cpp @@ -0,0 +1,89 @@ +#include "ch.h" +#include "hal.h" + +#include "persistence.h" + +#define MFS_RECORD_ID 1 + +static const MFSConfig mfscfg_1k = { + .flashp = (BaseFlash *)&EFLD1, + .erased = 0xFFFFFFFFU, +// 1k page * 1 sector = 1024 + .bank_size = 1024U, + .bank0_start = 62U, + .bank0_sectors = 1U, + .bank1_start = 63U, + .bank1_sectors = 1U +}; + +static const MFSConfig mfscfg_2k = { + .flashp = (BaseFlash *)&EFLD1, + .erased = 0xFFFFFFFFU, + /* 256K flash device with 2K pages + * use last 8 pages for settings + * one bank is 8K */ +// 2k page * 4 sectors = 8096 + .bank_size = 8096U, + .bank0_start = 120U, + .bank0_sectors = 4U, + .bank1_start = 124U, + .bank1_sectors = 4U +}; + +static MFSDriver mfs1; +uint8_t mfs_buffer[512]; + +/** + * @return true if mfsStart is well + */ +mfs_error_t InitFlash() { + eflStart(&EFLD1, NULL); + mfsObjectInit(&mfs1); + mfs_error_t err; +#define FLASH_SIZE_IN_K_ADDRESS 0x1FFFF7E0 + int flashSize = (*(uint16_t*)FLASH_SIZE_IN_K_ADDRESS); + int flashPageSize = (flashSize > 128) ? 2048 : 1024; + if (flashSize > 128) { + err = mfsStart(&mfs1, &mfscfg_2k); + } else { + err = mfsStart(&mfs1, &mfscfg_1k); + } + return err; +} + +static bool isMfsOkIsh(mfs_error_t state) { + return state == MFS_NO_ERROR || state == MFS_WARN_REPAIR || state == MFS_WARN_GC; +} + +extern GDIConfiguration configuration; +extern mfs_error_t flashState; + +static uint8_t *GetConfigurationPtr() { + return (uint8_t *)&configuration; +} + +static size_t GetConfigurationSize() { + return sizeof(GDIConfiguration); +} + +void ReadOrDefault() { + size_t size = GetConfigurationSize(); + flashState = mfsReadRecord(&mfs1, MFS_RECORD_ID, &size, GetConfigurationPtr()); + if (!isMfsOkIsh(flashState) || size != GetConfigurationSize() || !configuration.IsValid()) { + /* load defaults */ + configuration.resetToDefaults(); + } +} + +void saveConfiguration() { + configuration.updateCounter++; + flashState = mfsWriteRecord(&mfs1, MFS_RECORD_ID, GetConfigurationSize(), GetConfigurationPtr()); +} + +uint16_t float2short128(float value) { + return FIXED_POINT * value; +} + +float short2float128(uint16_t value) { + return value / 1.0 / FIXED_POINT; +} diff --git a/GDI-6ch/firmware/persistence.h b/GDI-6ch/firmware/persistence.h new file mode 100644 index 00000000..9ea15f8b --- /dev/null +++ b/GDI-6ch/firmware/persistence.h @@ -0,0 +1,64 @@ +/** + * @file persistence.h + */ + +#include "hal_mfs.h" + +#pragma once + +/** + * @return true if OK, false if broken + */ +mfs_error_t InitFlash(); +void saveConfiguration(); +void ReadOrDefault(); + +#define PERSISTENCE_VERSION 7 + +struct GDIConfiguration { + bool IsValid() const { + return version == PERSISTENCE_VERSION; + } + void resetToDefaults(); + int version; + int updateCounter; + + // CAN protocol: packet 0, offset 1 + uint16_t BoostVoltage; + // CAN protocol: packet 0, offset 3 + // Amps + float BoostCurrent; + // CAN protocol: packet 0, offset 5 + uint16_t TBoostMin; + // CAN protocol: packet 1, offset 1 + uint16_t TBoostMax; + + // CAN protocol: packet 1, offset 3 + float PeakCurrent; + // CAN protocol: packet 1, offset 5 + uint16_t TpeakDuration; + // CAN protocol: packet 2, offset 1 + uint16_t TpeakOff; + // CAN protocol: packet 2, offset 3 + uint16_t Tbypass; + + // CAN protocol: packet 2, offset 5 + float HoldCurrent; + // CAN protocol: packet 3, offset 1 + uint16_t TholdOff; + // CAN protocol: packet 3, offset 3 + uint16_t THoldDuration; + + float PumpPeakCurrent; + float PumpHoldCurrent; + uint16_t PumpTholdOff; + uint16_t PumpTholdTot; + + int inputCanID; + int outputCanID; +}; + +#define FIXED_POINT 128 + +uint16_t float2short128(float value); +float short2float128(uint16_t value); diff --git a/GDI-6ch/firmware/pt2000.cpp b/GDI-6ch/firmware/pt2000.cpp new file mode 100644 index 00000000..c9416307 --- /dev/null +++ b/GDI-6ch/firmware/pt2000.cpp @@ -0,0 +1,538 @@ +/* + * @file pt2001.cpp + * + * The NXP PT2001 is a programmable gate driver IC for precision solenoid control applications. + * + * Useful wires: + * 5v, 3(3.3v), Gnd, 12v, VccIO(3v) SPI, DRVEN, RSTB + * + * For MC33816 vs PT2000 differences see + * https://www.nxp.com/docs/en/application-note/AN5203.pdf + * + * @date May 3, 2019 + * @author Andrey Belomutskiy, (c) 2012-2020 + * @author Matthew Kennedy + */ + +#include "pt2000.h" +//#include + +#include "PT2000_LoadData.h" + +const int MC_CK = 6; // PLL x24 / CLK_DIV 4 = 6Mhz + +const int MAX_SPI_MODE_A_TRANSFER_SIZE = 31; //max size for register config transfer + +enum { + CODE_RAM1, + CODE_RAM2, + CODE_RAM3, + DATA_RAM +}; +enum { + REG_MAIN, + REG_CH1, + REG_CH2, + REG_CH3, + REG_IO, + REG_DIAG +}; + +static bool validateChipId(uint16_t id) { + return (id >> 8) == 0xAE; +} + +void Pt2000Base::setupSpi() { + select(); + // Select Channel command + send(0x7FE1); // 0x3FF << 5 + // Common Page + send(0x0100); + + // Configure SPI command + send(0x1A9 << 5 | 1); // spi_config + // Mode A + Watchdog timer full + //send(0x001F); + send(0x009F); // + fast slew rate on miso + deselect(); +} + +uint16_t Pt2000Base::readReg(int reg) { + setupSpi(); // ensure on common page? + select(); + send((0x8000 | reg << 5) + 1); + uint16_t ret = recv(); + deselect(); + return ret; +} + +void Pt2000Base::writeReg(int reg, uint16_t data) { + setupSpi(); // ensure on common page? + select(); + send((reg << 5) + 1); + send(data); + deselect(); +} + +uint16_t Pt2000Base::readId() { + /* + select(); + send(0xBAA1); + uint16_t ID = recv(); + deselect(); + return ID; + */ + return readReg(0x1B6); +} + +// Read a single word in Data RAM +uint16_t Pt2000Base::readDram(MC33PT2000Mem addr) { + uint16_t addrInt = static_cast(addr); + + select(); + // Select Channel command, Common Page + send(0x7FE1); // 0x3FF << 5 + send(0x0100); + // read (MSB=1) at addr, and 1 word + send((0x8000 | addrInt << 5) + 1); + uint16_t readValue = recv(); + + deselect(); + return readValue; +} + +// Update a single word in Data RAM +void Pt2000Base::writeDram(MC33PT2000Mem addr, uint16_t data) { + uint16_t addrInt = static_cast(addr); + + select(); + // Select Channel command, Common Page + send(0x7FE1); // 0x3FF << 5 + send(0x0100); + // write (MSB=0) at addr, and 1 word + send((addrInt << 5) + 1); + send(data); + + deselect(); + + // DRAM2 is duplicated from DRAM1 for all timings + if(addr < 64) + writeDram((MC33PT2000Mem)(addr + 64), data); + +} + +static uint16_t dacEquation(volatile float current) { + /* + Current, given in A + I = (DAC_VALUE * V_DAC_LSB - V_DA_BIAS)/(G_DA_DIFF * R_SENSEx) + DAC_VALUE = ((I*G_DA_DIFF * R_SENSEx) + V_DA_BIAS) / V_DAC_LSB + V_DAC_LSB is the DAC resolution = 9.77mv + V_DA_BIAS = 250mV + G_DA_DIFF = Gain: 5.79, [8.68], 12.53, 19.25 + R_SENSE = 10mOhm soldered on board + */ + return ((current * 8.68f * 10) + 250.0f) / 9.77f; +} + +void Pt2000Base::setTimings() { + setBoostVoltage(getBoostVoltage()); + + // Convert mA to DAC values + + writeDram(MC33PT2000Mem::Iboost, dacEquation(getBoostCurrent())); + writeDram(MC33PT2000Mem::Ipeak, dacEquation(getPeakCurrent())); + writeDram(MC33PT2000Mem::Ihold, dacEquation(getHoldCurrent())); + + // in micro seconds to clock cycles + writeDram(MC33PT2000Mem::Tpeak_off, (MC_CK * getTpeakOff())); + writeDram(MC33PT2000Mem::Tpeak_tot, (MC_CK * getTpeakTot())); + writeDram(MC33PT2000Mem::Tbypass, (MC_CK * getTbypass())); + writeDram(MC33PT2000Mem::Thold_off, (MC_CK * getTholdOff())); + writeDram(MC33PT2000Mem::Thold_tot, (MC_CK * getTHoldTot())); + writeDram(MC33PT2000Mem::Tboost_min, (MC_CK * getTBoostMin())); + writeDram(MC33PT2000Mem::Tboost_max, (MC_CK * getTBoostMax())); + + // HPFP solenoid settings + writeDram(MC33PT2000Mem::HPFP_Ipeak, dacEquation(getPumpPeakCurrent())); + writeDram(MC33PT2000Mem::HPFP_Ihold, dacEquation(getPumpHoldCurrent())); + writeDram(MC33PT2000Mem::HPFP_Thold_off, MC_CK * getPumpTholdOff()); + writeDram(MC33PT2000Mem::HPFP_Thold_tot, MC_CK * getPumpTholdTot()); + +} + +void Pt2000Base::setBoostVoltage(float volts) { + // Sanity checks, Datasheet says not too high, nor too low + if (volts > 65.0f) { + onError("DI Boost voltage setpoint too high"); + return; + } + if (volts < 12.0f) { + onError("DI Boost voltage setpoint too low"); + return; + } + + // There's a 1/32 divider on the input, then the DAC's output is 9.77mV per LSB. (1 / 32) / 0.00977 = 3.199 counts per volt. + // .. more accurately 3.25 * volts + 1.584 + uint16_t data = (volts * 3.25f) + 1.584f; + // 3.125 according to PT2000 datasheet + //unsigned short data = volts / 0.3125f; + + writeDram(MC33PT2000Mem::Vboost_high, data+1); + writeDram(MC33PT2000Mem::Vboost_low, data-1); + // Remember to strobe driven!! ( this is an older statement, and reloading should occur every time the dc-dc will turn on) +} + +bool Pt2000Base::checkFlash() { + select(); + uint16_t status; + // ch1 + // read (MSB=1) at location, and 1 word + status = readReg(0x100); + if (!(status & (1<<5))) { + deselect(); + return false; + } + + // ch2 + // read (MSB=1) at location, and 1 word + status = readReg(0x120); + if (!(status & (1<<5))) { + deselect(); + return false; + } + + // ch3 + // read (MSB=1) at location, and 1 word + status = readReg(0x140); + if (!(status & (1<<5))) { + deselect(); + return false; + } + deselect(); + return true; +} + +void Pt2000Base::clearDriverStatus(){ + // Note: There is a config at 0x1CE(for pt2001) & 1 that can reset this status config register on read + // otherwise the reload/recheck occurs with this write + // resetting it is necessary to clear default reset behavoir, as well as if an issue has been resolved + setupSpi(); // ensure on common page? + select(); + send((0x0000 | 0x1B2 << 5) + 1); // write, location, one word + send(0x0000); // anything to clear + deselect(); +} + +uint16_t Pt2000Base::readStatus(int reg) { + setupSpi(); // ensure on common page? + select(); + send((0x8000 | reg << 5) + 1); + uint16_t driverStatus = recv(); + deselect(); + return driverStatus; +} + +uint16_t Pt2000Base::readDriverStatus() { + return readStatus(0x1B2); +} + +static bool checkUndervoltVccP(uint16_t driverStatus){ + return (driverStatus & (1<<0)); +} + +static bool checkUndervoltV5(uint16_t driverStatus){ + return (driverStatus & (1<<1)); +} + +// static bool checkOverTemp(uint16_t driverStatus){ +// return (driverStatus & (1<<3)); +// } + +static bool checkDrivenEnabled(uint16_t driverStatus){ + return (driverStatus & (1<<4)); +} + +void Pt2000Base::enableFlash() { + select(); + writeReg(0x100, 0x0018); //ch1 + writeReg(0x120, 0x0018); //ch2 + writeReg(0x140, 0x0018); //ch3 + deselect(); +} + + +//static void disable_flash() { + //spiSelect(driver); + //writeReg(0x140, 0x0000); + //spiUnselect(driver); +//} + +void Pt2000Base::downloadRam(int target) { + uint16_t memory_area = 0; // memory area + uint16_t start_address = 0; // start address + uint16_t codeWidthRegAddr = 0; // code width register address + uint16_t size = 0; // size of RAM data + uint16_t command = 0; // command data + const uint16_t *RAM_ptr; // pointer to array of data to be sent to the chip + + + //Why Again? For Every time, just in case? + setupSpi(); + + switch(target) // selects target + { + case CODE_RAM1: + memory_area = 0x1; + start_address = 0; + codeWidthRegAddr = 0x107; + RAM_ptr = PT2000_code_RAM1; + size = sizeof(PT2000_code_RAM1) / 2; + break; + + case CODE_RAM2: + memory_area = 0x2; + start_address = 0; + codeWidthRegAddr = 0x127; + RAM_ptr = PT2000_code_RAM2; + size = sizeof(PT2000_code_RAM2) / 2; + break; + + case CODE_RAM3: + memory_area = 0x4; + start_address = 0; + codeWidthRegAddr = 0x147; + RAM_ptr = PT2000_code_RAM3; + size = sizeof(PT2000_code_RAM3) / 2; + break; + + case DATA_RAM: // ch1 only? + memory_area = 0x100; + start_address = 0; + RAM_ptr = PT2000_data_RAM; + size = sizeof(PT2000_data_RAM) / 2; + break; +// optional, both data_rams with 0x3, writes same code to both, or 0x7 to all three + default: + break; + } + + // Chip-Select high + select(); + + if (target != DATA_RAM) + { + command = codeWidthRegAddr << 5; // control width register address + command |= 1; // number of words to follow + send(command); // sends code_width command + send(size); // sends size (Code Width) + } + + // Select Channel command + send(0x7FE1); + // CRAM1, CRAM2, CRAM3, or Common Page (Data RAM) + send(memory_area); + + // "Command" of starting address + // up to 0x03FE of code ram + // up to 0x0080 of data ram + command = start_address << 5; + send(command); // sends start address command + + sendLarge(RAM_ptr, size); + deselect(); +} + +void Pt2000Base::downloadRegister(int r_target) +{ + uint16_t r_start_address = 0; // start address + uint16_t r_size = 0; // size of configuration data + uint16_t r_command = 0; // command data + uint16_t remainder_size = 0; // remainder size + const uint16_t *reg_ptr; // pointer to array of data to be sent to the chip + + switch (r_target) // selects target + { + case REG_CH1: // channel 1 configurations + r_start_address = 0x100; + reg_ptr = PT2000_ch1_config; + r_size = sizeof(PT2000_ch1_config) / 2; // gets number of words to be sent + break; + + case REG_CH2: // channel 2 configurations + r_start_address = 0x120; + reg_ptr = PT2000_ch2_config; + r_size = sizeof(PT2000_ch2_config) / 2; // gets number of words to be sent + break; + + case REG_CH3: // channel 3 configurations + r_start_address = 0x140; + reg_ptr = PT2000_ch3_config; + r_size = sizeof(PT2000_ch3_config) / 2; // gets number of words to be sent + break; + + case REG_DIAG: // diagnostic configurations + r_start_address = 0x1C0; + reg_ptr = PT2000_diag_config; + r_size = sizeof(PT2000_diag_config) / 2; // gets number of words to be sent + break; + + case REG_IO: // IO configurations + r_start_address = 0x154; + reg_ptr = PT2000_io_config; + r_size = sizeof(PT2000_io_config) / 2; // gets number of words to be sent + break; + + case REG_MAIN: // main configurations + r_start_address = 0x1A0; + reg_ptr = PT2000_main_config; + r_size = sizeof(PT2000_main_config) / 2; // gets number of words to be sent + break; + + default: + break; + } + + // for location < size(remainder?) + // is location == 0? or past max xfer, send command + expected size + // if location = max xfer + // + // retrieve data, send it, increase pointer + // increase + + do + { + if (r_size > MAX_SPI_MODE_A_TRANSFER_SIZE) // if size is too large, split into two sections ... MULTIPLE sections.. + { + remainder_size = r_size - MAX_SPI_MODE_A_TRANSFER_SIZE; // creates remaining size + r_size = MAX_SPI_MODE_A_TRANSFER_SIZE; // sets first size + } + else + { + remainder_size = 0; + } + + r_command = r_start_address << 5; // start address + r_command += r_size; // number of words to follow + + select(); // Chip + + send(r_command); // sends address and number of words to be sent + + sendLarge(reg_ptr, r_size); + + // if (remainder_size > 0) // if remainder size is greater than 0, download the rest + { + reg_ptr += r_size; + r_start_address += r_size; // new start address + r_size = remainder_size; + } + } while (remainder_size > 0); + deselect(); +} + +void Pt2000Base::shutdown() { + setDriveEN(false); // ensure HV is off + setResetB(false); // turn off the chip +} + +bool Pt2000Base::restart() { + bool flag0before = false; + bool flag0after = false; + + // Start with everything off + shutdown(); + deselect(); + + if (getVbatt() < 8) { + onError("GDI not Restarting until we see VBatt"); + return false; + } + + // Wait for chip to reset, then release reset and wait again + sleepMs(1); + setResetB(true); + sleepMs(1); + + // Flag0 should be floating - pulldown means it should read low + flag0before = readFlag0(); + + setupSpi(); + + clearDriverStatus(); // Initial clear necessary + status = readDriverStatus(); + if (checkUndervoltV5(status)) { + onError(McFault::UnderVoltage5); + shutdown(); + return false; + } + + uint16_t chipId = readId(); + if (!validateChipId(chipId)) { + onError(McFault::NoComm); + shutdown(); + return false; + } + + downloadRam(CODE_RAM1); // transfers code RAM1 + downloadRam(CODE_RAM2); // transfers code RAM2 + downloadRam(CODE_RAM3); // transfers code RAM3 + downloadRam(DATA_RAM); // transfers data RAM + downloadRegister(REG_MAIN); // download main register configurations + + // current configuration of REG_MAIN would toggle flag0 from LOW to HIGH + flag0after = readFlag0(); + if (flag0before || !flag0after) { + onError(McFault::flag0); + shutdown(); + return false; + } + + downloadRegister(REG_CH1); // download channel 1 register configurations + downloadRegister(REG_CH2); // download channel 2 register configurations + downloadRegister(REG_CH3); // download channel 3 register configurations + downloadRegister(REG_IO); // download IO register configurations + downloadRegister(REG_DIAG); // download diag register configuration + + //setTimings(); + + // Finished downloading, let's run the code + enableFlash(); + + // give it a moment to take effect + sleepMs(10); + + if (!checkFlash()) { + onError(McFault::NoFlash); + shutdown(); + return false; + } + + clearDriverStatus(); + sleepMs(5); + + status = readDriverStatus(); + if (checkUndervoltVccP(status)) { + onError(McFault::UnderVoltage7); + shutdown(); + return false; + } + + // Drive High Voltage + setDriveEN(true); // driven = HV + sleepMs(10); // Give it a moment + status = readDriverStatus(); + if (!checkDrivenEnabled(status)) { + onError(McFault::Driven); + shutdown(); + return false; + } +status = readStatus(0x186); + + status = readDriverStatus(); + if (checkUndervoltVccP(status)) { + onError(McFault::UnderVoltageAfter); // Likely DC-DC LS is dead! + shutdown(); + return false; + } + return true; +} diff --git a/GDI-6ch/firmware/pt2000.h b/GDI-6ch/firmware/pt2000.h new file mode 100644 index 00000000..972828e8 --- /dev/null +++ b/GDI-6ch/firmware/pt2000.h @@ -0,0 +1,130 @@ +/* + * @file pt2000.h + * + * chris is altering the original pt2001 for gdi6 without internal submodules, will merge as one peak-hold class at a later date + */ + +#pragma once + +#include +#include + +#include "pt2000_memory_map.h" +#include "ch.h" +#include "hal.h" + + +//extern "C" void __cxa_pure_virtual(void) { while(1); } + + +enum class McFault : uint8_t +{ + None = 0, + NoFlash = 1, + UnderVoltageAfter = 2, + NoComm = 3, + flag0 = 4, + UnderVoltage5 = 5, + Driven = 6, + UnderVoltage7 = 7, +}; + +class Pt2000Base { +public: + // Reinitialize the PT2000 chip, returns true if successful + // or do we check the return is within range to prevent overflow + bool restart(); + + // Disable the PT2001 chip. + void shutdown(); + + void onError(McFault p_fault) { + fault = p_fault; + } + + // Re-read timing configuration and reconfigure the chip. This is safe to call while operating. + void setTimings(); + + // Set the boost voltage target. This is safe to call while operating. + void setBoostVoltage(float volts); + + McFault fault = McFault::None; + uint16_t status = 0; + + uint16_t readStatus(int reg); + +private: + // SPI tx/rx helpers + void send(uint16_t tx) { + sendRecv(tx); + } + + uint16_t recv() { + return sendRecv(0xFFFF); + } + + // Chip init logic + void setupSpi(); + uint16_t readReg(int reg); + void writeReg(int reg, uint16_t data); + uint16_t readId(); + + void enableFlash(); + bool checkFlash(); + + void downloadRam(int target); + void downloadRegister(int target); + + // Chip IO helpers + uint16_t readDram(MC33PT2000Mem addr); + void writeDram(MC33PT2000Mem addr, uint16_t data); + uint16_t readDriverStatus(); + void clearDriverStatus(); + +protected: + // The consuming app must implement these functions! + virtual void select() = 0; + virtual void deselect() = 0; + virtual uint16_t sendRecv(uint16_t tx) = 0; + // Send `count` number of 16 bit words from `data` + virtual void sendLarge(const uint16_t* data, size_t count) = 0; + + // GPIO reset and enable pins + virtual void setResetB(bool state) = 0; + virtual void setDriveEN(bool state) = 0; + + // GPIO inputs for various pins we need + virtual bool readFlag0() const = 0; + + // Get battery voltage - only try to init chip when powered + virtual float getVbatt() const = 0; + + // CONFIGURATIONS: currents, timings, voltages + virtual float getBoostVoltage() const = 0; + + // Currents in amps + virtual float getBoostCurrent() const = 0; + virtual float getPeakCurrent() const = 0; + virtual float getHoldCurrent() const = 0; + + virtual float getPumpPeakCurrent() const = 0; + virtual float getPumpHoldCurrent() const = 0; + + // Timings in microseconds + virtual uint16_t getTpeakOff() const = 0; + virtual uint16_t getTpeakTot() const = 0; + virtual uint16_t getTbypass() const = 0; + virtual uint16_t getTholdOff() const = 0; + virtual uint16_t getTHoldTot() const = 0; + virtual uint16_t getTBoostMin() const = 0; + virtual uint16_t getTBoostMax() const = 0; + + virtual uint16_t getPumpTholdOff() const = 0; + virtual uint16_t getPumpTholdTot() const = 0; + + // Print out an error message + virtual void onError(const char* why) = 0; + + // Sleep for some number of milliseconds + virtual void sleepMs(size_t ms) = 0; +}; diff --git a/GDI-6ch/firmware/pt2000_memory_map.h b/GDI-6ch/firmware/pt2000_memory_map.h new file mode 100644 index 00000000..38929e3a --- /dev/null +++ b/GDI-6ch/firmware/pt2000_memory_map.h @@ -0,0 +1,40 @@ +/** + * see mc33816/rusefi/readme.md +*/ + +typedef enum { + // see dram1.def values + Iboost = 0, + Ipeak = 1, + Ihold = 2, + Tpeak_off = 3, + Tpeak_tot = 4, + Tbypass = 5, + Thold_off = 6, + Thold_tot = 7, + Tboost_max = 8, + Tboost_min = 9, + // see dram2.def values, base 64 for channel 2 + Iboost_2 = 64, + Ipeak_2 = 65, + Ihold_2 = 66, + Tpeak_off_2 = 67, + Tpeak_tot_2 = 68, + Tbypass_2 = 69, + Thold_off_2 = 70, + Thold_tot_2 = 71, + Tboost_max_2 = 72, + Tboost_min_2 = 73, + // see dram3.def values, base 64 for channel 3 + Vboost_high = 128, + Vboost_low = 129, + Isense4_high = 130, + Isense4_low = 131, + HPFP_Ipeak = 133, + HPFP_Ihold = 134, + HPFP_Thold_off = 135, + HPFP_Thold_tot = 136, + + + BLANK = 140, +} MC33PT2000Mem; diff --git a/GDI-6ch/firmware/pt2000impl.h b/GDI-6ch/firmware/pt2000impl.h new file mode 100644 index 00000000..8e49edd8 --- /dev/null +++ b/GDI-6ch/firmware/pt2000impl.h @@ -0,0 +1,145 @@ +#include "ch.h" +#include "hal.h" +#include "persistence.h" +#include "io_pins.h" + +#include "pt2000.h" + +GDIConfiguration *getConfiguration(); + +class Pt2000 : public Pt2000Base { +public: + // returns true if init successful + bool init(); + +protected: + //void acquireBus() override { + //} + + //void releaseBus() override { + //} + + void select() override { + spiSelect(driver); + } + + void deselect() override { + spiUnselect(driver); + } + + //bool errorOnUnexpectedFlag() override { + //} + + uint16_t sendRecv(uint16_t tx) override { + return spiPolledExchange(driver, tx); + } + + // Send `count` number of 16 bit words from `data` + void sendLarge(const uint16_t* data, size_t count) override { + spiSend(driver, count, data); + } + + // GPIO reset and enable pins + void setResetB(bool state) override { + if (state) { + palSetPad(PT_RESET_PORT, PT_RESET_PIN); + } else { + palClearPad(PT_RESET_PORT, PT_RESET_PIN); + } + } + + void setDriveEN(bool state) override { + if (state) { + palSetPad(PT_DRVEN_PORT, PT_DRVEN_PIN); + } else { + palClearPad(PT_DRVEN_PORT, PT_DRVEN_PIN); + } + } + + // GPIO inputs for various pins we need + bool readFlag0() const override { + return palReadPad(PT_FLAG_0_PORT, PT_FLAG_0_PIN); + } + + // Get battery voltage - only try to init chip when powered + float getVbatt() const override { + // TODO return real vbatt + // TODO: maybe do not bother with getVbatt() at all? only used for conditional restart, this does not seem to justify any effort + return 12; + } + + // CONFIGURATIONS: currents, timings, voltages + float getBoostVoltage() const override { + return getConfiguration()->BoostVoltage; + } + + // Currents in amps + float getBoostCurrent() const override { + return getConfiguration()->BoostCurrent; + } + + float getPeakCurrent() const override { + return getConfiguration()->PeakCurrent; + } + + float getHoldCurrent() const override { + return getConfiguration()->HoldCurrent; + } + + float getPumpPeakCurrent() const override { + return getConfiguration()->PumpPeakCurrent; + } + + float getPumpHoldCurrent() const override { + return getConfiguration()->PumpHoldCurrent; + } + + // Timings in microseconds + uint16_t getTpeakOff() const override { + return getConfiguration()->TpeakOff; + } + + uint16_t getTpeakTot() const override { + return getConfiguration()->TpeakDuration; + } + + uint16_t getTbypass() const override { + return getConfiguration()->Tbypass; + } + + uint16_t getTholdOff() const override { + return getConfiguration()->TholdOff; + } + + uint16_t getTHoldTot() const override { + return getConfiguration()->THoldDuration; + } + + uint16_t getTBoostMin() const override { + return getConfiguration()->TBoostMin; + } + + uint16_t getTBoostMax() const override { + return getConfiguration()->TBoostMax; + } + + uint16_t getPumpTholdOff() const override { + return getConfiguration()->PumpTholdOff; + } + + uint16_t getPumpTholdTot() const override { + return getConfiguration()->PumpTholdTot; + } + + // Print out an error message + void onError(const char* why) override { + // efiPrintf("PT2001 error: %s", why); + } + + void sleepMs(size_t durationMs) override { + chThdSleepMilliseconds(durationMs); + } + +private: + SPIDriver* driver; +}; diff --git a/GDI-6ch/project/Logic_Wave/wave_list.do b/GDI-6ch/project/Logic_Wave/wave_list.do new file mode 100644 index 00000000..c9f06122 --- /dev/null +++ b/GDI-6ch/project/Logic_Wave/wave_list.do @@ -0,0 +1,198 @@ + + + STARTx + + + Start1 + + PT2000 + + 8 + Input + Decimal + + + Start2 + + PT2000 + + 9 + Input + Decimal + + + Start3 + + PT2000 + + 10 + Input + Decimal + + + Start4 + + PT2000 + + 11 + Input + Decimal + + + Start5 + + PT2000 + + 12 + Input + Decimal + + + Start6 + + PT2000 + + 13 + Input + Decimal + + + Start7 + + PT2000 + + 14 + Input + Decimal + + + INJ1 + + + Hs1Command + + PT2000 + + 6 + Output + Decimal + + + Hs2Command + + PT2000 + + 7 + Output + Decimal + + + Ls1Command + + PT2000 + + 13 + Output + Decimal + + + CurrentFeedback1 + + PT2000 + + 0 + Internal + Decimal + + + FeedbackHs1Vds + + PT2000 + + 10 + Internal + Decimal + + + FeedbackHs1Vsrc + + PT2000 + + 11 + Internal + Decimal + + + FeedbackLs1Vds + + PT2000 + + 24 + Internal + Decimal + + + DCDC + + + BoostFeedback + + PT2000 + + 35 + Internal + Decimal + + + Ls7Command + + PT2000 + + 19 + Output + Decimal + + + Ls8Command + + PT2000 + + 20 + Output + Decimal + + + Flag0Out + + PT2000 + + 4 + Output + Decimal + + + DEBUG + + + Irq + + PT2000 + + 5 + Output + Decimal + + + irqSource + + PT2000 + Injection Channel 1 + ChSequencers + MicroMachineSeq0 + UProgramCounter + + 7 + Output + Decimal + + \ No newline at end of file diff --git a/GDI-6ch/project/MicrocodeCh1/ch1.psc b/GDI-6ch/project/MicrocodeCh1/ch1.psc new file mode 100644 index 00000000..733834c4 --- /dev/null +++ b/GDI-6ch/project/MicrocodeCh1/ch1.psc @@ -0,0 +1,204 @@ +* This microcore will control BANK1 +#include "dram1.def"; + +* uc0ch1 uses DAC1 +* uc1ch1 uses DAC2 + +* ### Initialization phase ### +init0: dfcsct dac1; + stgn gain8.68 sssc; * Set the gain of the opamp of the current measure block 1 + ldjr1 eoinj0; * Load the eoinj line label Code RAM address into the register jr1 + ldjr2 idle0; * Load the idle line label Code RAM address into the register jr2 + cwef jr1 _start row1; * If the start signal goes low, go to eoinj phase + +* ### Idle phase- the uPC loops here until start signal is present ### +idle0: joslr inj1_start start1; * Jump to inj1 if start 1 is high + joslr inj2_start start2; * Jump to inj2 if start 2 is high + jmpf jr1; + +* ### Shortcuts definition per the injector to be actuated ### +inj1_start: dfsct hs1 hs2 ls1; * Set the 3 shortcuts: VBAT, VBOOST, LS2 + jmpr boost0; * Jump to launch phase +inj2_start: dfsct hs1 hs2 ls2; * Set the 3 shortcuts: VBAT, VBOOST, LS2 + jmpr boost0; * Jump to launch phase + +* ### Launch phase enable boost ### +* Row1 - !start: injection ended +* Row2 - Overcurrent, jump to error case (threshold is reached early) +* Row3 - Overcurrent, jump to peak phase (threshold is reached on time) +* Row4 - timer1: Minimum boost time reached - switch to row3 instead of row2 to allow peak phase +* Row5 - timer2: Boost phase timeout - boost took too long, go to error phase +boost0: load Iboost dac_sssc _ofs; * Load the boost phase current threshold in the current DAC + cwer boost0_err ocur row2; * On overcurrent, go to boost error case + cwer peak0 ocur row3; * Jump to peak phase when current is over threshold + + ldcd rst _ofs keep keep Tboost_min c1; * Start boost counter to switch out of error behavior if threshold reached + cwer boost0_mintime tc1 row4; * On timer timeout, go allow overcurrent without error (ie, end of boost) + + ldcd rst _ofs keep keep Tboost_max c2; * Start boost counter in case Iboost never reached + cwer boost0_err tc2 row5; * Jump to boost0_err in case boost phase takes too long + + stf low b1; * set flag1 low to force the DC-DC converter in idle mode + stos off on on; * Turn VBAT off, BOOST on, LS on + wait row1245; * Wait for one of the previously defined conditions + +* ### Boost phase - minimum time reached ### +boost0_mintime: wait row135; * Minimum time for boost phase has been reached, now wait for !start, overcurrent or timeout + +boost0_err: stos off off off; * Turn off all drivers + stf low b0; * Set ch1 error flag0 to signal MCU + stf high b1; * set flag1 high to release the DC-DC converter idle mode + wait row1; * Wait for start signal to go low for the next injection attempt + + +* ### Peak phase continue on Vbat ### +peak0: stos keep off keep; * Turn VBAT off (keep), BOOST off, LS on (keep) + ldcd rst _ofs keep keep Tpeak_tot c1; * Load the length of the total peak phase in counter 1 + load Ipeak dac_sssc _ofs; * Load the peak current threshold in the current DAC + cwer bypass0 tc1 row2; * Jump to bypass phase when tc1 reaches end of count + cwer peak_on0 tc2 row3; * Jump to peak_on when tc2 reaches end of count + cwer peak_off0 ocur row4; * Jump to peak_off when own-current is over threshold + + stf high b1; * set flag1 high to release the DC-DC converter idle mode + + * discharge down to a known current + cwer peak_off0 _ocur row5; * Jump to peak_off when own-current is discharged + wait row125; + +* attempt to toggle this later +peak_on0: stos on off on; * Turn VBAT on, BOOST off, LS on + wait row124; * Wait for one of the previously defined conditions + +peak_off0: ldcd rst ofs keep keep Tpeak_off c2; * Load in the counter 2 the length of the peak_off phase + stos off off on; * Turn VBAT off, BOOST off, LS on + wait row123; + +* ### Bypass phase ### +bypass0: ldcd rst ofs keep keep Tbypass c3; * Load in the counter 3 the length of the off_phase phase + stos off off off; * Turn VBAT off, BOOST off, LS off + cwer hold0 tc3 row4; * Jump to hold when tc3 reaches end of count + wait row14; * Wait for one of the previously defined conditions + +* ### Hold phase on Vbat ### +hold0: ldcd rst _ofs keep keep Thold_tot c1; * Load the length of the total hold phase in counter 2 + load Ihold dac_sssc _ofs; * Load the hold current threshold in the DAC + cwer eoinj0 tc1 row2; * Jump to eoinj phase when tc1 reaches end of count + cwer hold_on0 tc2 row3; * Jump to hold_on when tc2 reaches end of count + cwer hold_off0 ocur row4; * Jump to hold_off when current is over threshold + +hold_on0: stos on off on; * Turn VBAT on, BOOST off, LS on + wait row124; * Wait for one of the previously defined conditions + +hold_off0: ldcd rst _ofs keep keep Thold_off c2; * Load the length of the hold_off phase in counter 1 + stos off off on; * Turn VBAT off, BOOST off, LS on + wait row123; + + +* ### End of injection phase ### +eoinj0: stos off off off; * Turn VBAT off, BOOST off, LS off + stf high b1; * set flag1 to high to release the DC-DC converter idle mode + *debug + *stf low b2; + jmpf jr2; * Jump back to idle phase + +* ### End of Channel 1 - uCore0 code ### + + +*############################################################################################################################### +* ### Initialization phase ### +init1: dfcsct dac2; + stgn gain8.68 sssc; * Set the gain of the opamp of the current measure block 1 + ldjr1 eoinj1; * Load the eoinj line label Code RAM address into the register jr1 + ldjr2 idle1; * Load the idle line label Code RAM address into the register jr2 + cwef jr1 _start row1; * If the start signal goes low, go to eoinj phase + +* ### Idle phase- the uPC loops here until start signal is present ### +idle1: joslr inj3_start start3; * Jump to inj1 if start 1 is high + joslr inj4_start start4; * Jump to inj2 if start 2 is high + jmpf jr1; + +* ### Shortcuts definition per the injector to be actuated ### +inj3_start: dfsct hs3 hs4 ls3; * Set the 3 shortcuts: VBAT, VBOOST, LS3 + jmpr boost1; * Jump to launch phase +inj4_start: dfsct hs3 hs4 ls4; * Set the 3 shortcuts: VBAT, VBOOST, LS4 + jmpr boost1; * Jump to launch phase + +* ### Launch phase enable boost ### +* Row1 - !start: injection ended +* Row2 - Overcurrent, jump to error case (threshold is reached early) +* Row3 - Overcurrent, jump to peak phase (threshold is reached on time) +* Row4 - timer1: Minimum boost time reached - switch to row3 instead of row2 to allow peak phase +* Row5 - timer2: Boost phase timeout - boost took too long, go to error phase +boost1: load Iboost dac_sssc _ofs; * Load the boost phase current threshold in the current DAC + cwer boost1_err ocur row2; * On overcurrent, go to boost error case + cwer peak1 ocur row3; * Jump to peak phase when current is over threshold + + ldcd rst _ofs keep keep Tboost_min c1; * Start boost counter to switch out of error behavior if threshold reached + cwer boost1_mintime tc1 row4; * On timer timeout, go allow overcurrent without error (ie, end of boost) + + ldcd rst _ofs keep keep Tboost_max c2; * Start boost counter in case Iboost never reached + cwer boost1_err tc2 row5; * Jump to boostN_err in case boost phase takes too long + + stf low b1; * set flag1 low to force the DC-DC converter in idle mode + stos off on on; * Turn VBAT off, BOOST on, LS on + wait row1245; * Wait for one of the previously defined conditions + +* ### Boost phase - minimum time reached ### +boost1_mintime: wait row135; * Minimum time for boost phase has been reached, now wait for !start, overcurrent or timeout + +boost1_err: stos off off off; * Turn off all drivers + stf low b0; * Set ch1 error flag0 to signal MCU + stf high b1; * set flag1 high to release the DC-DC converter idle mode + wait row1; * Wait for start signal to go low for the next injection attempt + + +* ### Peak phase continue on Vbat ### +peak1: ldcd rst _ofs keep keep Tpeak_tot c1; * Load the length of the total peak phase in counter 1 + load Ipeak dac_sssc _ofs; * Load the peak current threshold in the current DAC + stos off off on; * Turn VBAT off, BOOST off, LS on + cwer bypass1 tc1 row2; * Jump to bypass phase when tc1 reaches end of count + cwer peak_on1 tc2 row3; * Jump to peak_on when tc2 reaches end of count + cwer peak_off1 ocur row4; * Jump to peak_off when own-current is over threshold + + stf high b1; * set flag1 high to release the DC-DC converter idle mode + + * discharge down to a known current + cwer peak_off1 _ocur row5; * Jump to peak_off when own-current is discharged + wait row125; + +peak_on1: stos on off on; * Turn VBAT on, BOOST off, LS on + wait row124; * Wait for one of the previously defined conditions + +peak_off1: ldcd rst ofs keep keep Tpeak_off c2; * Load in the counter 2 the length of the peak_off phase + stos off off on; * Turn VBAT off, BOOST off, LS on + wait row123; + + + +* ### Bypass phase ### +bypass1: ldcd rst ofs keep keep Tbypass c3; * Load in the counter 3 the length of the off_phase phase + stos off off off; * Turn VBAT off, BOOST off, LS off + cwer hold1 tc3 row4; * Jump to hold when tc3 reaches end of count + wait row14; * Wait for one of the previously defined conditions + +* ### Hold phase on Vbat ### +hold1: ldcd rst _ofs keep keep Thold_tot c1; * Load the length of the total hold phase in counter 2 + load Ihold dac_sssc _ofs; * Load the hold current threshold in the DAC + cwer eoinj1 tc1 row2; * Jump to eoinj phase when tc1 reaches end of count + cwer hold_on1 tc2 row3; * Jump to hold_on when tc2 reaches end of count + cwer hold_off1 ocur row4; * Jump to hold_off when current is over threshold + +hold_on1: stos on off on; * Turn VBAT on, BOOST off, LS on + wait row124; * Wait for one of the previously defined conditions + +hold_off1: ldcd rst _ofs keep keep Thold_off c2; * Load the length of the hold_off phase in counter 1 + stos off off on; * Turn VBAT off, BOOST off, LS on + wait row123; + + +* ### End of injection phase ### +eoinj1: stos off off off; * Turn VBAT off, BOOST off, LS off + stf high b1; * set flag1 to high to release the DC-DC converter idle mode + jmpf jr2; * Jump back to idle phase + +* ### End of Channel 1 - uCore1 code ### \ No newline at end of file diff --git a/GDI-6ch/project/MicrocodeCh1/ch1.psc.bak b/GDI-6ch/project/MicrocodeCh1/ch1.psc.bak new file mode 100644 index 00000000..74912f43 --- /dev/null +++ b/GDI-6ch/project/MicrocodeCh1/ch1.psc.bak @@ -0,0 +1,209 @@ +* This microcore will control BANK1 +#include "..\DRAM\injectors.def"; + +* ### Initialization phase ### +init0: stgn gain8.68 sssc; * Set the gain of the opamp of the current measure block 1 + ldjr1 eoinj0; * Load the eoinj line label Code RAM address into the register jr1 + ldjr2 idle0; * Load the idle line label Code RAM address into the register jr2 + cwef jr1 _start row1; * If the start signal goes low, go to eoinj phase + +* ### Idle phase- the uPC loops here until start signal is present ### +idle0: joslr inj1_start start1; * Jump to inj1 if start 1 is high + joslr inj2_start start2; * Jump to inj2 if start 2 is high + jmpf jr1; + +* ### Shortcuts definition per the injector to be actuated ### +inj1_start: dfsct hs1 hs2 ls1; * Set the 3 shortcuts: VBAT, VBOOST, LS2 + +*debug +* stos on off on; +* wait row1; + + + + jmpr boost0; * Jump to launch phase +inj2_start: dfsct hs1 hs2 ls2; * Set the 3 shortcuts: VBAT, VBOOST, LS2 + jmpr boost0; * Jump to launch phase + +* ### Launch phase enable boost ### +* Row1 - !start: injection ended +* Row2 - Overcurrent, jump to error case (threshold is reached early) +* Row3 - Overcurrent, jump to peak phase (threshold is reached on time) +* Row4 - timer1: Minimum boost time reached - switch to row3 instead of row2 to allow peak phase +* Row5 - timer2: Boost phase timeout - boost took too long, go to error phase +boost0: load Iboost dac_sssc _ofs; * Load the boost phase current threshold in the current DAC + cwer boost0_err ocur row2; * On overcurrent, go to boost error case + cwer peak0 ocur row3; * Jump to peak phase when current is over threshold + + ldcd rst _ofs keep keep Tboost_min c1; * Start boost counter to switch out of error behavior if threshold reached + cwer boost0_mintime tc1 row4; * On timer timeout, go allow overcurrent without error (ie, end of boost) + + ldcd rst _ofs keep keep Tboost_max c2; * Start boost counter in case Iboost never reached + cwer boost0_err tc2 row5; * Jump to boost0_err in case boost phase takes too long + + stf low b1; * set flag1 low to force the DC-DC converter in idle mode + stos off on on; * Turn VBAT off, BOOST on, LS on + wait row1245; * Wait for one of the previously defined conditions + +* ### Boost phase - minimum time reached ### +boost0_mintime: wait row135; * Minimum time for boost phase has been reached, now wait for !start, overcurrent or timeout + +boost0_err: stos off off off; * Turn off all drivers + stf low b0; * Set ch1 error flag0 to signal MCU + stf high b1; * set flag1 high to release the DC-DC converter idle mode + wait row1; * Wait for start signal to go low for the next injection attempt + + +* ### Peak phase continue on Vbat ### +peak0: stos keep off keep; * Turn VBAT off (keep), BOOST off, LS on (keep) + ldcd rst _ofs keep keep Tpeak_tot c1; * Load the length of the total peak phase in counter 1 + load Ipeak dac_sssc _ofs; * Load the peak current threshold in the current DAC + cwer bypass0 tc1 row2; * Jump to bypass phase when tc1 reaches end of count + cwer peak_on0 tc2 row3; * Jump to peak_on when tc2 reaches end of count + cwer peak_off0 ocur row4; * Jump to peak_off when own-current is over threshold + + stf high b1; * set flag1 high to release the DC-DC converter idle mode + + * discharge down to a known current + cwer peak_off0 _ocur row5; * Jump to peak_off when own-current is discharged + wait row125; + +* attempt to toggle this later +peak_on0: stos on off on; * Turn VBAT on, BOOST off, LS on + wait row124; * Wait for one of the previously defined conditions + +peak_off0: ldcd rst ofs keep keep Tpeak_off c2; * Load in the counter 2 the length of the peak_off phase + stos off off on; * Turn VBAT off, BOOST off, LS on + wait row123; + + + +* ### Bypass phase ### +bypass0: ldcd rst ofs keep keep Tbypass c3; * Load in the counter 3 the length of the off_phase phase + stos off off off; * Turn VBAT off, BOOST off, LS off + cwer hold0 tc3 row4; * Jump to hold when tc3 reaches end of count + wait row14; * Wait for one of the previously defined conditions + +* ### Hold phase on Vbat ### +hold0: ldcd rst _ofs keep keep Thold_tot c1; * Load the length of the total hold phase in counter 2 + load Ihold dac_sssc _ofs; * Load the hold current threshold in the DAC + cwer eoinj0 tc1 row2; * Jump to eoinj phase when tc1 reaches end of count + cwer hold_on0 tc2 row3; * Jump to hold_on when tc2 reaches end of count + cwer hold_off0 ocur row4; * Jump to hold_off when current is over threshold + +hold_on0: stos on off on; * Turn VBAT on, BOOST off, LS on + wait row124; * Wait for one of the previously defined conditions + +hold_off0: ldcd rst _ofs keep keep Thold_off c2; * Load the length of the hold_off phase in counter 1 + stos off off on; * Turn VBAT off, BOOST off, LS on + wait row123; + + +* ### End of injection phase ### +eoinj0: stos off off off; * Turn VBAT off, BOOST off, LS off + stf high b1; * set flag1 to high to release the DC-DC converter idle mode + jmpf jr2; * Jump back to idle phase + +* ### End of Channel 1 - uCore0 code ### + + + + +*############################################################################################################################### +* ### Initialization phase ### +* ### Initialization phase ### +init1: stgn gain8.68 sssc; * Set the gain of the opamp of the current measure block 1 + ldjr1 eoinj1; * Load the eoinj line label Code RAM address into the register jr1 + ldjr2 idle1; * Load the idle line label Code RAM address into the register jr2 + cwef jr1 _start row1; * If the start signal goes low, go to eoinj phase + +* ### Idle phase- the uPC loops here until start signal is present ### +idle1: joslr inj3_start start3; * Jump to inj1 if start 1 is high + joslr inj4_start start4; * Jump to inj2 if start 2 is high + jmpf jr1; + +* ### Shortcuts definition per the injector to be actuated ### +inj3_start: dfsct hs3 hs4 ls3; * Set the 3 shortcuts: VBAT, VBOOST, LS3 + jmpr boost1; * Jump to launch phase +inj4_start: dfsct hs3 hs4 ls4; * Set the 3 shortcuts: VBAT, VBOOST, LS4 + jmpr boost1; * Jump to launch phase + +* ### Launch phase enable boost ### +* Row1 - !start: injection ended +* Row2 - Overcurrent, jump to error case (threshold is reached early) +* Row3 - Overcurrent, jump to peak phase (threshold is reached on time) +* Row4 - timer1: Minimum boost time reached - switch to row3 instead of row2 to allow peak phase +* Row5 - timer2: Boost phase timeout - boost took too long, go to error phase +boost1: load Iboost dac_sssc _ofs; * Load the boost phase current threshold in the current DAC + cwer boost1_err ocur row2; * On overcurrent, go to boost error case + cwer peak1 ocur row3; * Jump to peak phase when current is over threshold + + ldcd rst _ofs keep keep Tboost_min c1; * Start boost counter to switch out of error behavior if threshold reached + cwer boost1_mintime tc1 row4; * On timer timeout, go allow overcurrent without error (ie, end of boost) + + ldcd rst _ofs keep keep Tboost_max c2; * Start boost counter in case Iboost never reached + cwer boost1_err tc2 row5; * Jump to boost0_err in case boost phase takes too long + + stf low b1; * set flag1 low to force the DC-DC converter in idle mode + stos off on on; * Turn VBAT off, BOOST on, LS on + wait row1245; * Wait for one of the previously defined conditions + +* ### Boost phase - minimum time reached ### +boost1_mintime: wait row135; * Minimum time for boost phase has been reached, now wait for !start, overcurrent or timeout + +boost1_err: stos off off off; * Turn off all drivers + stf low b0; * Set ch1 error flag0 to signal MCU + stf high b1; * set flag1 high to release the DC-DC converter idle mode + wait row1; * Wait for start signal to go low for the next injection attempt + + +* ### Peak phase continue on Vbat ### +peak1: ldcd rst _ofs keep keep Tpeak_tot c1; * Load the length of the total peak phase in counter 1 + load Ipeak dac_sssc _ofs; * Load the peak current threshold in the current DAC + *stos off off on; ** Turn VBAT off, BOOST off, LS on + cwer bypass1 tc1 row2; * Jump to bypass phase when tc1 reaches end of count + cwer peak_on1 tc2 row3; * Jump to peak_on when tc2 reaches end of count + cwer peak_off1 ocur row4; * Jump to peak_off when own-current is over threshold + + stf high b1; * set flag1 high to release the DC-DC converter idle mode + + * discharge down to a known current + cwer peak_off1 _ocur row5; * Jump to peak_off when own-current is discharged + wait row125; + +peak_on1: stos on off on; * Turn VBAT on, BOOST off, LS on + wait row124; * Wait for one of the previously defined conditions + +peak_off1: ldcd rst ofs keep keep Tpeak_off c2; * Load in the counter 2 the length of the peak_off phase + stos off off on; * Turn VBAT off, BOOST off, LS on + wait row123; + + + +* ### Bypass phase ### +bypass1: ldcd rst ofs keep keep Tbypass c3; * Load in the counter 3 the length of the off_phase phase + stos off off off; * Turn VBAT off, BOOST off, LS off + cwer hold1 tc3 row4; * Jump to hold when tc3 reaches end of count + wait row14; * Wait for one of the previously defined conditions + +* ### Hold phase on Vbat ### +hold1: ldcd rst _ofs keep keep Thold_tot c1; * Load the length of the total hold phase in counter 2 + load Ihold dac_sssc _ofs; * Load the hold current threshold in the DAC + cwer eoinj1 tc1 row2; * Jump to eoinj phase when tc1 reaches end of count + cwer hold_on1 tc2 row3; * Jump to hold_on when tc2 reaches end of count + cwer hold_off1 ocur row4; * Jump to hold_off when current is over threshold + +hold_on1: stos on off on; * Turn VBAT on, BOOST off, LS on + wait row124; * Wait for one of the previously defined conditions + +hold_off1: ldcd rst _ofs keep keep Thold_off c2; * Load the length of the hold_off phase in counter 1 + stos off off on; * Turn VBAT off, BOOST off, LS on + wait row123; + + +* ### End of injection phase ### +eoinj1: stos off off off; * Turn VBAT off, BOOST off, LS off + stf high b1; * set flag1 to high to release the DC-DC converter idle mode + jmpf jr2; * Jump back to idle phase + +* ### End of Channel 1 - uCore1 code ### \ No newline at end of file diff --git a/GDI-6ch/project/MicrocodeCh1/dram1.def b/GDI-6ch/project/MicrocodeCh1/dram1.def new file mode 100644 index 00000000..3551deac --- /dev/null +++ b/GDI-6ch/project/MicrocodeCh1/dram1.def @@ -0,0 +1,10 @@ +#define Iboost 0; +#define Ipeak 1; +#define Ihold 2; +#define Tpeak_off 3; +#define Tpeak_tot 4; +#define Tbypass 5; +#define Thold_off 6; +#define Thold_tot 7; +#define Tboost_max 8; +#define Tboost_min 9; diff --git a/GDI-6ch/project/MicrocodeCh2/ch2.psc b/GDI-6ch/project/MicrocodeCh2/ch2.psc new file mode 100644 index 00000000..78b1904d --- /dev/null +++ b/GDI-6ch/project/MicrocodeCh2/ch2.psc @@ -0,0 +1,117 @@ +* we use the same timings across all injectors but the DRAM space is not sharable +#include "dram2.def"; + +* uc0ch2 uses DAC6 (low?) +* uc1ch2 not used + + +* ### Initialization phase ### +init0: dfcsct dac6l; + stgn gain8.68 osoc; * Set the gain of the opamp of the current measure block 1 + ldjr1 eoinj0; * Load the eoinj line label Code RAM address into the register jr1 + ldjr2 idle0; * Load the idle line label Code RAM address into the register jr2 + cwef jr1 _start row1; * If the start signal goes low, go to eoinj phase + +* ### Idle phase- the uPC loops here until start signal is present ### +idle0: joslr inj5_start start5; * Jump to inj1 if start 1 is high + joslr inj6_start start6; * Jump to inj2 if start 2 is high + jmpf jr1; + +* ### Shortcuts definition per the injector to be actuated ### +inj5_start: dfsct hs5 hs6 ls5; * Set the 3 shortcuts: VBAT, VBOOST, LS2 + jmpr boost0; * Jump to launch phase +inj6_start: dfsct hs5 hs6 ls6; * Set the 3 shortcuts: VBAT, VBOOST, LS2 + jmpr boost0; * Jump to launch phase + +* ### Launch phase enable boost ### +* Row1 - !start: injection ended +* Row2 - Overcurrent, jump to error case (threshold is reached early) +* Row3 - Overcurrent, jump to peak phase (threshold is reached on time) +* Row4 - timer1: Minimum boost time reached - switch to row3 instead of row2 to allow peak phase +* Row5 - timer2: Boost phase timeout - boost took too long, go to error phase +boost0: load Iboost dac_osoc _ofs; * Load the boost phase current threshold in the current DAC + cwer boost0_err ocur row2; * On overcurrent, go to boost error case + cwer peak0 ocur row3; * Jump to peak phase when current is over threshold + + ldcd rst _ofs keep keep Tboost_min c1; * Start boost counter to switch out of error behavior if threshold reached + cwer boost0_mintime tc1 row4; * On timer timeout, go allow overcurrent without error (ie, end of boost) + + ldcd rst _ofs keep keep Tboost_max c2; * Start boost counter in case Iboost never reached + cwer boost0_err tc2 row5; * Jump to boost0_err in case boost phase takes too long + + stf low b1; * set flag1 low to force the DC-DC converter in idle mode + stos off on on; * Turn VBAT off, BOOST on, LS on + wait row1245; * Wait for one of the previously defined conditions + +* ### Boost phase - minimum time reached ### +boost0_mintime: wait row135; * Minimum time for boost phase has been reached, now wait for !start, overcurrent or timeout + +boost0_err: stos off off off; * Turn off all drivers + stf low b0; * Set ch1 error flag0 to signal MCU + stf high b1; * set flag1 high to release the DC-DC converter idle mode + wait row1; * Wait for start signal to go low for the next injection attempt + + +* ### Peak phase continue on Vbat ### +peak0: stos keep off keep; * Turn VBAT off (keep), BOOST off, LS on (keep) + ldcd rst _ofs keep keep Tpeak_tot c1; * Load the length of the total peak phase in counter 1 + load Ipeak dac_osoc _ofs; * Load the peak current threshold in the current DAC + cwer bypass0 tc1 row2; * Jump to bypass phase when tc1 reaches end of count + cwer peak_on0 tc2 row3; * Jump to peak_on when tc2 reaches end of count + cwer peak_off0 ocur row4; * Jump to peak_off when own-current is over threshold + + stf high b1; * set flag1 high to release the DC-DC converter idle mode + + * discharge down to a known current + cwer peak_off0 _ocur row5; * Jump to peak_off when own-current is discharged + wait row125; + +* attempt to toggle this later +peak_on0: stos on off on; * Turn VBAT on, BOOST off, LS on + wait row124; * Wait for one of the previously defined conditions + +peak_off0: ldcd rst ofs keep keep Tpeak_off c2; * Load in the counter 2 the length of the peak_off phase + stos off off on; * Turn VBAT off, BOOST off, LS on + wait row123; + + + +* ### Bypass phase ### +bypass0: ldcd rst ofs keep keep Tbypass c3; * Load in the counter 3 the length of the off_phase phase + stos off off off; * Turn VBAT off, BOOST off, LS off + cwer hold0 tc3 row4; * Jump to hold when tc3 reaches end of count + wait row14; * Wait for one of the previously defined conditions + +* ### Hold phase on Vbat ### +hold0: ldcd rst _ofs keep keep Thold_tot c1; * Load the length of the total hold phase in counter 2 + load Ihold dac_osoc _ofs; * Load the hold current threshold in the DAC + cwer eoinj0 tc1 row2; * Jump to eoinj phase when tc1 reaches end of count + cwer hold_on0 tc2 row3; * Jump to hold_on when tc2 reaches end of count + cwer hold_off0 ocur row4; * Jump to hold_off when current is over threshold + +hold_on0: stos on off on; * Turn VBAT on, BOOST off, LS on + wait row124; * Wait for one of the previously defined conditions + +hold_off0: ldcd rst _ofs keep keep Thold_off c2; * Load the length of the hold_off phase in counter 1 + stos off off on; * Turn VBAT off, BOOST off, LS on + wait row123; + + +* ### End of injection phase ### +eoinj0: stos off off off; * Turn VBAT off, BOOST off, LS off + stf high b1; * set flag1 to high to release the DC-DC converter idle mode + jmpf jr2; * Jump back to idle phase + +* ### End of Channel 2 - uCore0 code ### + + + + + +* ### CHANNEL2 UCORE1 useless code (only here to avoid issue when dual core are enabled) ##### +* Unable to find reference of enabling only a single core + +init1: ldirh 52h _rst; + ldirl 52h _rst; + ldirh 52h _rst; + jmpr init1; diff --git a/GDI-6ch/project/MicrocodeCh2/ch2.psc.bak b/GDI-6ch/project/MicrocodeCh2/ch2.psc.bak new file mode 100644 index 00000000..22535570 --- /dev/null +++ b/GDI-6ch/project/MicrocodeCh2/ch2.psc.bak @@ -0,0 +1,28 @@ +* Because we use the same timings across all injectors +* it doesn't make sense to keep track of uploading it twice +* .. so instead let's just include the first channel's dram +#include "..\DRAM\injectors.def"; + +* This microcore will control BANK3 + +#define HSBatB3 hs5 ; +#define HSBoostB3 hs6 ; +#define LS1B3 ls5 ; +#define LS2B3 ls6 ; + +*cur5L for uCore0 +*ucore1 not used + + +* ### Initialization phase ### +init0: stgn gain8.68 osoc; * Set the gain of the opamp of the current measure block 1 + jmpr init0; + +* ### End of Channel 1 - uCore0 code ### + +* ### CHANNEL2 UCORE1 useless code (only here to avoid issue when dual core are enabled) ##### + +init1: ldirh 52h _rst; + ldirl 52h _rst; + ldirh 52h _rst; + jmpr init1; diff --git a/GDI-6ch/project/MicrocodeCh2/dram2.def b/GDI-6ch/project/MicrocodeCh2/dram2.def new file mode 100644 index 00000000..3551deac --- /dev/null +++ b/GDI-6ch/project/MicrocodeCh2/dram2.def @@ -0,0 +1,10 @@ +#define Iboost 0; +#define Ipeak 1; +#define Ihold 2; +#define Tpeak_off 3; +#define Tpeak_tot 4; +#define Tbypass 5; +#define Thold_off 6; +#define Thold_tot 7; +#define Tboost_max 8; +#define Tboost_min 9; diff --git a/GDI-6ch/project/MicrocodeCh3/ch3.psc b/GDI-6ch/project/MicrocodeCh3/ch3.psc new file mode 100644 index 00000000..aaa9dfb6 --- /dev/null +++ b/GDI-6ch/project/MicrocodeCh3/ch3.psc @@ -0,0 +1,87 @@ +#include "dram3.def"; +* This channel will control Fuel Pump and DCDC + +#define LSDCDC ls7; +*ucore0 cur3 use for Fuel pump +*ucore1 cur6 use for DCDC + + +*############################################################################################################################### + +*### uc0 controls Fuel Pump using start 7 ######## + +* ### Initialization phase ### +init0: dfcsct dac3; + stgn gain19.3 ssoc; * Set the gain of the opamp of the current measure block 1 + ldjr1 eofp0; * Load the eoinj line label Code RAM address into the register jr1 + ldjr2 idle0; * Load the idle line label Code RAM address into the register jr2 + cwef jr1 _start row1; * If the start signal goes low, go to eoinj phase + +* ### Idle phase- the uPC loops here until start signal is present ### +idle0: joslr fp_start start8; * Perform an actuation + jmpf jr1; * If more than 1 start active at the same time(or none), no actuation + +fp_start: dfsct hs7 ls8 undef; * Set the 2 shortcuts: VBAT, LS + jmpr peak0; * Jump to launch phase + +* ### Launch peak phase on bat ### +peak0: load HPFP_Ipeak dac_ssoc _ofs; * Load the boost phase current threshold in the current DAC + cwer hold0 ocur row2; * Jump to hold phase when current is over threshold + stos on on keep; * Turn VBAT on, LS on + wait row12; * Wait for one of the previously defined conditions + +* ### Hold phase on Vbat ### +hold0: ldcd rst _ofs keep keep HPFP_Thold_tot c1; * Load the length of the total hold phase in counter 1 + load HPFP_Ihold dac_ssoc _ofs; * Load the hold current threshold in the DAC + cwer eofp0 tc1 row2; * Jump to eoinj phase when tc1 reaches end of count + cwer hold_on0 tc2 row3; * Jump to hold_on when tc2 reaches end of count + cwer hold_off0 ocur row4; * Jump to hold_off when current is over threshold + +hold_on0: stos on on keep; * Turn VBAT on, LS on + wait row124; * Wait for one of the previously defined conditions + +hold_off0: ldcd rst _ofs off on HPFP_Thold_off c2; * Load the length of the hold_off phase in counter 2 and turn VBAT off, LS on + wait row123; * Wait for one of the previously defined conditions + +* ### End of injection phase ### +eofp0: stos off off keep; * Turn VBAT off, LS off + jmpf jr2; * Jump back to idle phase + +*############################################################################################################################### + +*#### uc1 DCDC control ### + +* ### Initialization phase ### +init1: stgn gain5.8 ossc; * Set the gain of the opamp of the current measure block 56 + * stf low b1; + dfsct undef LSDCDC undef; + stos keep off keep; + load Iboost_L dac_ossc _ofs; + load Iboost_H dac56h56n _ofs; + stdm null; * Set the boost voltage DAC access mode + cwer dcdc_idle _f1 row1; * Wait table entry for flag1 going low + cwer dcdc_on _vb row2; * Wait table entry for Vboost under Vboost_low threshold condition + cwer dcdc_off vb row3; * Wait table entry for Vboost over Vboost_high threshold condition + +* ### Asynchronous phase ### +dcdc_on: load Vboost_high boost _ofs; * Load the upper Vboost threshold in vboost_dac register + stdcctl async; + * we may stop here if voltage never goes high + * for instance if DrvEn is held low + * and as such no updated DRAM will be loaded as we dont loop, we wait + wait row13; + +* ### Synchronous phase ### +dcdc_off: load Vboost_low boost _ofs; * Load the upper Vboost threshold in vboost_dac register + stdcctl sync; * Enable synchronous mode + wait row12; + +* ### Idle phase ### +dcdc_idle: stdcctl sync; * Enable synchronous mode + * stf low b0; + stos keep off keep; + jocr dcdc_idle _f1; + jmpr dcdc_on; * force the DC-DC converter on when flag 0 goes high + +* ### End of Channel 3 - uCore0 code ### + diff --git a/GDI-6ch/project/MicrocodeCh3/ch3.psc.bak b/GDI-6ch/project/MicrocodeCh3/ch3.psc.bak new file mode 100644 index 00000000..ff7bb652 --- /dev/null +++ b/GDI-6ch/project/MicrocodeCh3/ch3.psc.bak @@ -0,0 +1,90 @@ +* We include dram2 to be consistent with the PT2001 locations +#include "..\DRAM\dcdc_hpfp.def"; +* This channel will control Fuel Pump and DCDC + +#define HSBatB4 hs7; +#define LSB4 ls8; + +#define LSDCDC ls7; +*ucore0 cur3 use for Fuel pump +*ucore1 cur6 use for DCDC + + +*############################################################################################################################### + +*### uc0 controls Fuel Pump using start 7 ######## + +* ### Initialization phase ### +init0: stgn gain19.3 ossc; * Set the gain of the opamp of the current measure block 1 + ldjr1 eoact0; * Load the eoinj line label Code RAM address into the register jr1 + ldjr2 idle0; * Load the idle line label Code RAM address into the register jr2 + cwef jr1 _start row1; * If the start signal goes low, go to eoinj phase + +* ### Idle phase- the uPC loops here until start signal is present ### +idle0: joslr act7_start start7; * Perform an actuation on act6 if start 6 (only) is active + jmpf jr1; * If more than 1 start active at the same time(or none), no actuation + +act7_start: dfsct hs7 ls8 undef; * Set the 2 shortcuts: VBAT, LS + jmpr peak0; * Jump to launch phase + +* ### Launch peak phase on bat ### +peak0: load HPFP_Ipeak dac_ossc _ofs; * Load the boost phase current threshold in the current DAC + cwer hold0 cur3 row2; * Jump to hold phase when current is over threshold + stos on on keep; * Turn VBAT on, LS on + wait row12; * Wait for one of the previously defined conditions + +* ### Hold phase on Vbat ### +hold0: ldcd rst _ofs keep keep HPFP_Thold_tot c1; * Load the length of the total hold phase in counter 1 + load HPFP_Ihold dac_ossc _ofs; * Load the hold current threshold in the DAC + cwer eoact0 tc1 row2; * Jump to eoinj phase when tc1 reaches end of count + cwer hold_on0 tc2 row3; * Jump to hold_on when tc2 reaches end of count + cwer hold_off0 cur3 row4; * Jump to hold_off when current is over threshold + +hold_on0: stos on on keep; * Turn VBAT on, LS on + wait row124; * Wait for one of the previously defined conditions + +hold_off0: ldcd rst _ofs off on HPFP_Thold_off c2; * Load the length of the hold_off phase in counter 2 and turn VBAT off, LS on + wait row123; * Wait for one of the previously defined conditions + +* ### End of injection phase ### +eoact0: stos off off keep; * Turn VBAT off, LS off + jmpf jr2; * Jump back to idle phase + +*############################################################################################################################### + +*#### uc1 DCDC control ### + +* ### Initialization phase ### +init1: stgn gain5.8 ossc; * Set the gain of the opamp of the current measure block 56 + * stf low b1; + dfsct undef LSDCDC undef; + stos keep off keep; + load Iboost_L dac_ossc _ofs; + load Iboost_H dac56h56n _ofs; + stdm null; * Set the boost voltage DAC access mode + cwer dcdc_idle _f1 row1; * Wait table entry for flag1 going low + cwer dcdc_on _vb row2; * Wait table entry for Vboost under Vboost_low threshold condition + cwer dcdc_off vb row3; * Wait table entry for Vboost over Vboost_high threshold condition + +* ### Asynchronous phase ### +dcdc_on: load Vboost_high boost _ofs; * Load the upper Vboost threshold in vboost_dac register + stdcctl async; + * we may stop here if voltage never goes high + * for instance if DrvEn is held low + * and as such no updated DRAM will be loaded as we dont loop, we wait + wait row13; + +* ### Synchronous phase ### +dcdc_off: load Vboost_low boost _ofs; * Load the upper Vboost threshold in vboost_dac register + stdcctl sync; * Enable synchronous mode + wait row12; + +* ### Idle phase ### +dcdc_idle: stdcctl sync; * Enable synchronous mode + * stf low b0; + stos keep off keep; + jocr dcdc_idle _f1; + jmpr dcdc_on; * force the DC-DC converter on when flag 0 goes high + +* ### End of Channel 3 - uCore0 code ### + diff --git a/GDI-6ch/project/MicrocodeCh3/dram3.def b/GDI-6ch/project/MicrocodeCh3/dram3.def new file mode 100644 index 00000000..6c22b767 --- /dev/null +++ b/GDI-6ch/project/MicrocodeCh3/dram3.def @@ -0,0 +1,8 @@ +#define Vboost_high 0; +#define Vboost_low 1; +#define Iboost_H 2; +#define Iboost_L 3; +#define HPFP_Ipeak 5; +#define HPFP_Ihold 6; +#define HPFP_Thold_off 7; +#define HPFP_Thold_tot 8; diff --git a/GDI-6ch/project/Registers/ch1_config_reg.hex b/GDI-6ch/project/Registers/ch1_config_reg.hex new file mode 100644 index 00000000..197df72f --- /dev/null +++ b/GDI-6ch/project/Registers/ch1_config_reg.hex @@ -0,0 +1,28 @@ +// +// Application: +// Asic ID: PT2000 +// Version: +// Ch1 Configuration Registers (C1PR) +// Date: Saturday, January 4, 2025 +// Author: windo +// +0x0000, // (0x100) +0x0025, // (0x101) +0x0014, // (0x102) +0x0C03, // (0x103) +0x0000, // (0x104) +0x0001, // (0x105) +0x0001, // (0x106) +0x0074, // (0x107) +0x3B52, // (0x108) +0xA28B, // (0x109) +0x0000, // (0x10A) +0x003A, // (0x10B) +0x0000, // (0x10C) +0x0000, // (0x10D) +0x0000, // (0x10E) +0x0000, // (0x10F) +0x0000, // (0x110) +0x0000, // (0x111) +0x0000, // (0x112) +0x0000 // (0x113) diff --git a/GDI-6ch/project/Registers/ch2_config_reg.hex b/GDI-6ch/project/Registers/ch2_config_reg.hex new file mode 100644 index 00000000..7592e3d2 --- /dev/null +++ b/GDI-6ch/project/Registers/ch2_config_reg.hex @@ -0,0 +1,28 @@ +// +// Application: +// Asic ID: PT2000 +// Version: +// Ch2 Configuration Registers (C2PR) +// Date: Saturday, January 4, 2025 +// Author: windo +// +0x0000, // (0x120) +0x000C, // (0x121) +0x0070, // (0x122) +0x0030, // (0x123) +0x0000, // (0x124) +0x0002, // (0x125) +0x0002, // (0x126) +0x003E, // (0x127) +0x9F7E, // (0x128) +0x4EEC, // (0x129) +0x0000, // (0x12A) +0x003A, // (0x12B) +0x0000, // (0x12C) +0x0000, // (0x12D) +0x0000, // (0x12E) +0x0000, // (0x12F) +0x0000, // (0x130) +0x0000, // (0x131) +0x0010, // (0x132) +0x0000 // (0x133) diff --git a/GDI-6ch/project/Registers/ch3_config_reg.hex b/GDI-6ch/project/Registers/ch3_config_reg.hex new file mode 100644 index 00000000..b9f19bca --- /dev/null +++ b/GDI-6ch/project/Registers/ch3_config_reg.hex @@ -0,0 +1,28 @@ +// +// Application: +// Asic ID: PT2000 +// Version: +// Ch3 Configuration Registers (C3PR) +// Date: Saturday, January 4, 2025 +// Author: windo +// +0x0000, // (0x140) +0x0003, // (0x141) +0x000C, // (0x142) +0x0080, // (0x143) +0x0000, // (0x144) +0x0000, // (0x145) +0x0000, // (0x146) +0x002B, // (0x147) +0x6F0D, // (0x148) +0x3DFF, // (0x149) +0x0000, // (0x14A) +0x0018, // (0x14B) +0x0000, // (0x14C) +0x0000, // (0x14D) +0x0000, // (0x14E) +0x0000, // (0x14F) +0x0000, // (0x150) +0x0000, // (0x151) +0x0004, // (0x152) +0x0000 // (0x153) diff --git a/GDI-6ch/project/Registers/diag_config_reg.hex b/GDI-6ch/project/Registers/diag_config_reg.hex new file mode 100644 index 00000000..ce7fab84 --- /dev/null +++ b/GDI-6ch/project/Registers/diag_config_reg.hex @@ -0,0 +1,72 @@ +// +// Application: +// Asic ID: PT2000 +// Version: +// Diagnosis Configuration Registers (DCR) +// Date: Saturday, January 4, 2025 +// Author: windo +// +0x0000, // (0x1C0) +0x0000, // (0x1C1) +0x003E, // (0x1C2) +0x0000, // (0x1C3) +0x0000, // (0x1C4) +0x003E, // (0x1C5) +0x0000, // (0x1C6) +0x0000, // (0x1C7) +0x003E, // (0x1C8) +0x0000, // (0x1C9) +0x0000, // (0x1CA) +0x003E, // (0x1CB) +0x0000, // (0x1CC) +0x0000, // (0x1CD) +0x003E, // (0x1CE) +0x0000, // (0x1CF) +0x0000, // (0x1D0) +0x003E, // (0x1D1) +0x0000, // (0x1D2) +0x0000, // (0x1D3) +0x003E, // (0x1D4) +0x0000, // (0x1D5) +0x0000, // (0x1D6) +0x003E, // (0x1D7) +0x0000, // (0x1D8) +0x0000, // (0x1D9) +0x00FE, // (0x1DA) +0x0000, // (0x1DB) +0x0000, // (0x1DC) +0x00FE, // (0x1DD) +0x0000, // (0x1DE) +0x0000, // (0x1DF) +0x00FE, // (0x1E0) +0x0000, // (0x1E1) +0x0000, // (0x1E2) +0x00FE, // (0x1E3) +0x0000, // (0x1E4) +0x0000, // (0x1E5) +0x00FE, // (0x1E6) +0x0000, // (0x1E7) +0x0000, // (0x1E8) +0x00FE, // (0x1E9) +0x0000, // (0x1EA) +0x0000, // (0x1EB) +0x00FE, // (0x1EC) +0x0000, // (0x1ED) +0x0000, // (0x1EE) +0x0000, // (0x1EF) +0x0000, // (0x1F0) +0x0000, // (0x1F1) +0x0000, // (0x1F2) +0x0000, // (0x1F3) +0x0000, // (0x1F4) +0x0000, // (0x1F5) +0x0000, // (0x1F6) +0x0000, // (0x1F7) +0x0000, // (0x1F8) +0x0000, // (0x1F9) +0x0000, // (0x1FA) +0x0000, // (0x1FB) +0x0000, // (0x1FC) +0x0000, // (0x1FD) +0x0000, // (0x1FE) +0x0000 // (0x1FF) diff --git a/GDI-6ch/project/Registers/dram1.hex b/GDI-6ch/project/Registers/dram1.hex new file mode 100644 index 00000000..85275340 --- /dev/null +++ b/GDI-6ch/project/Registers/dram1.hex @@ -0,0 +1,72 @@ +// +// Application: +// Asic ID: PT2000 +// Version: +// DRAM +// Date: Saturday, January 4, 2025 +// Author: windo +// +0x008D, +0x006D, +0x003A, +0x003C, +0x1068, +0x003C, +0x0168, +0xEA60, +0x0960, +0x0258, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000 diff --git a/GDI-6ch/project/Registers/dram2.hex b/GDI-6ch/project/Registers/dram2.hex new file mode 100644 index 00000000..85275340 --- /dev/null +++ b/GDI-6ch/project/Registers/dram2.hex @@ -0,0 +1,72 @@ +// +// Application: +// Asic ID: PT2000 +// Version: +// DRAM +// Date: Saturday, January 4, 2025 +// Author: windo +// +0x008D, +0x006D, +0x003A, +0x003C, +0x1068, +0x003C, +0x0168, +0xEA60, +0x0960, +0x0258, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000 diff --git a/GDI-6ch/project/Registers/dram3.hex b/GDI-6ch/project/Registers/dram3.hex new file mode 100644 index 00000000..3d70cfb6 --- /dev/null +++ b/GDI-6ch/project/Registers/dram3.hex @@ -0,0 +1,72 @@ +// +// Application: +// Asic ID: PT2000 +// Version: +// DRAM +// Date: Saturday, January 4, 2025 +// Author: windo +// +0x00C1, +0x00BF, +0x0040, +0x001D, +0x0000, +0x0046, +0x0037, +0x003C, +0xEA60, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000 diff --git a/GDI-6ch/project/Registers/io_config_reg.hex b/GDI-6ch/project/Registers/io_config_reg.hex new file mode 100644 index 00000000..f848a2ce --- /dev/null +++ b/GDI-6ch/project/Registers/io_config_reg.hex @@ -0,0 +1,81 @@ +// +// Application: +// Asic ID: PT2000 +// Version: +// IO Configuration Registers (IOR) +// Date: Saturday, January 4, 2025 +// Author: windo +// +0x0000, // (0x154) +0x0000, // (0x155) +0x0000, // (0x156) +0x0000, // (0x157) +0x0000, // (0x158) +0x0000, // (0x159) +0x0000, // (0x15A) +0x0000, // (0x15B) +0x0000, // (0x15C) +0x0000, // (0x15D) +0x0000, // (0x15E) +0x0000, // (0x15F) +0x0303, // (0x160) +0x0C0C, // (0x161) +0x3030, // (0x162) +0x0000, // (0x163) +0x8040, // (0x164) +0x4000, // (0x165) +0x0201, // (0x166) +0x0040, // (0x167) +0x3004, // (0x168) +0x0000, // (0x169) +0x0000, // (0x16A) +0x0000, // (0x16B) +0x0000, // (0x16C) +0x0000, // (0x16D) +0x0000, // (0x16E) +0x0000, // (0x16F) +0x0000, // (0x170) +0x0555, // (0x171) +0x0555, // (0x172) +0x0050, // (0x173) +0x0000, // (0x174) +0x0000, // (0x175) +0x0000, // (0x176) +0x0000, // (0x177) +0x0000, // (0x178) +0x0000, // (0x179) +0x0707, // (0x17A) +0x0707, // (0x17B) +0x0707, // (0x17C) +0x0707, // (0x17D) +0x0707, // (0x17E) +0x00CD, // (0x17F) +0x0020, // (0x180) +0x0000, // (0x181) +0x0000, // (0x182) +0x0017, // (0x183) +0x0016, // (0x184) +0x0000, // (0x185) +0x0000, // (0x186) +0x0000, // (0x187) +0x0000, // (0x188) +0x0000, // (0x189) +0x0000, // (0x18A) +0x0000, // (0x18B) +0x0000, // (0x18C) +0x0000, // (0x18D) +0x0000, // (0x18E) +0x0003, // (0x18F) +0x0003, // (0x190) +0x000C, // (0x191) +0x000C, // (0x192) +0x0030, // (0x193) +0x0030, // (0x194) +0x0080, // (0x195) +0x0000, // (0x196) +0x0028, // (0x197) +0x0028, // (0x198) +0x0028, // (0x199) +0x8110, // (0x19A) +0x23C7, // (0x19B) +0x0100 // (0x19C) diff --git a/GDI-6ch/project/Registers/main_config_reg.hex b/GDI-6ch/project/Registers/main_config_reg.hex new file mode 100644 index 00000000..31e230b4 --- /dev/null +++ b/GDI-6ch/project/Registers/main_config_reg.hex @@ -0,0 +1,40 @@ +// +// Application: +// Asic ID: PT2000 +// Version: +// Main Configuration Registers (MCR) +// Date: Saturday, January 4, 2025 +// Author: windo +// +0x0003, // (0x1A0) +0x0000, // (0x1A1) +0x0008, // (0x1A2) +0xE81F, // (0x1A3) +0x0000, // (0x1A4) +0x0000, // (0x1A5) +0x0000, // (0x1A6) +0x0001, // (0x1A7) +0x0000, // (0x1A8) +0x001D, // (0x1A9) +0x0000, // (0x1AA) +0x0000, // (0x1AB) +0x0000, // (0x1AC) +0x0000, // (0x1AD) +0xBF3F, // (0x1AE) +0x0000, // (0x1AF) +0x0000, // (0x1B0) +0x0000, // (0x1B1) +0x0000, // (0x1B2) +0x0000, // (0x1B3) +0x0000, // (0x1B4) +0x0000, // (0x1B5) +0x0000, // (0x1B6) +0x0000, // (0x1B7) +0x0000, // (0x1B8) +0x0000, // (0x1B9) +0x0000, // (0x1BA) +0x0000, // (0x1BB) +0x0000, // (0x1BC) +0x0000, // (0x1BD) +0x0000, // (0x1BE) +0x0000 // (0x1BF) diff --git a/GDI-6ch/project/SPIGenMC33PT2000Files.txt b/GDI-6ch/project/SPIGenMC33PT2000Files.txt new file mode 100644 index 00000000..d2a37d25 --- /dev/null +++ b/GDI-6ch/project/SPIGenMC33PT2000Files.txt @@ -0,0 +1,12 @@ +bin\ch1.cip.bin +bin\ch2.cip.bin +bin\ch3.cip.bin +registers\dram1.bin +registers\dram2.bin +registers\dram3.bin +registers\main_config_reg.bin +registers\ch1_config_reg.bin +registers\ch2_config_reg.bin +registers\ch3_config_reg.bin +registers\io_config_reg.bin +registers\diag_config_reg.bin diff --git a/GDI-6ch/project/sample_code/PT2000.c b/GDI-6ch/project/sample_code/PT2000.c new file mode 100644 index 00000000..00de0c99 --- /dev/null +++ b/GDI-6ch/project/sample_code/PT2000.c @@ -0,0 +1,687 @@ +/******************************************************************************* +* Example Code +* +* Copyright(C) 2025 NXP Semiconductors +* NXP Semiconductors Confidential and Proprietary +* +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* NXP products. This software is supplied "AS IS" without any warranties +* of any kind, and NXP Semiconductors and its licensor disclaim any and +* all warranties, express or implied, including all implied warranties of +* merchantability, fitness for a particular purpose and non-infringement of +* intellectual property rights. NXP Semiconductors assumes no responsibility +* or liability for the use of the software, conveys no license or rights +* under any patent, copyright, mask work right, or any other intellectual +* property rights in or to any products. NXP Semiconductors reserves the +* right to make changes in the software without notification. NXP +* Semiconductors also makes no representation or warranty that such +* application will be suitable for the specified use without further testing +* or modification. +* +* IN NO EVENT WILL NXP SEMICONDUCTORS BE LIABLE, WHETHER IN CONTRACT, +* TORT, OR OTHERWISE, FOR ANY INCIDENTAL, SPECIAL, INDIRECT, CONSEQUENTIAL +* OR PUNITIVE DAMAGES, INCLUDING, BUT NOT LIMITED TO, DAMAGES FOR ANY +* LOSS OF USE, LOSS OF TIME, INCONVENIENCE, COMMERCIAL LOSS, OR LOST +* PROFITS, SAVINGS, OR REVENUES, TO THE FULL EXTENT SUCH MAY BE DISCLAIMED +* BY LAW. NXP SEMICONDUCTOR’S TOTAL LIABILITY FOR ALL COSTS, DAMAGES, +* CLAIMS, OR LOSSES WHATSOEVER ARISING OUT OF OR IN CONNECTION WITH THE +* SOFTWARE IS LIMITED TO THE AGGREGATE AMOUNT PAID BY YOU TO NXP SEMICONDUCTORS +* IN CONNECTION WITH THE SOFTWARE TO WHICH LOSSES OR DAMAGES ARE CLAIMED. +* +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' and its +* licensor's relevant copyrights in the software, without fee, provided +* that it is used in conjunction with NXP Semiconductors devices. This +* copyright, permission, and disclaimer notice must appear in all copies +* of this code. +*******************************************************************************/ + +#include "stddef.h" +#include "system.h" +#include "PT2000.h" +#include "PT2000_spi_map.h" +#include "PT2000_irq.h" +#include "lpspi.h" + +const int MAX_SPI_MODE_A_TRANSFER_SIZE = 31; // max size for register config transfer + +///////////////////////////////////////////////////////////////////////////////////////////////// +// Function name : send_PT2000_SPI_Cmd +// Description : Sends a SPI command using the PT2000 SPI protocol +// Return type : bool - true = send was successful, false = send failed +// Argument : bool bRead - true for a read command, false for a write command +// Argument : unsigned short offset - Start address for sending data +// Argument : unsigned short length - Number of 16 bit words to be sent +// Argument : unsigned short* pTxData - Buffer for transmit data +// Argument : unsigned short* pRxData - Buffer for receive data +///////////////////////////////////////////////////////////////////////////////////////////////// +bool send_PT2000_SPI_Cmd(bool bRead, unsigned short offset, unsigned short length, unsigned short* pTxData, unsigned short* pRxData) +{ + int i = 0; + unsigned short command = 0; + + // Return false if the length is out of range + if ((length < 1) || (length > 31)) { return false; } + + // Return false if either of the data arrays are not allocated + if ((pTxData == NULL) || (pRxData == NULL)) { return false; } + + // If the start address is out of range, return false + if (offset > 1031) { return false; } + + // Set the read bit if specified + if (bRead == true) + { + command |= 0x8000; + } + + // Set the command address and length + command |= offset << 5; + command |= length; + + // Send the command word + send_16bit_SPI(command); + + // Send the data word(s) + for (i = 0; i < length; i++) + { + *(pRxData++) = send_16bit_SPI(*(pTxData++)); + } + + return true; +} + +///////////////////////////////////////////////////////////////////////////////////////////////// +// Function name : send_single_PT2000_SPI_Cmd +// Description : Sends a SPI command using the PT2000 SPI protocol +// Return type : unsigned short - Data read from the SPI interface +// Argument : bool bRead - READ for a read command, WRITE for a write command +// Argument : unsigned short offset - Start address for sending data +// Argument : unsigned short txData - Transmit data +///////////////////////////////////////////////////////////////////////////////////////////////// +unsigned short send_single_PT2000_SPI_Cmd(bool bRead, unsigned short offset, unsigned short txData) +{ + const unsigned short length = 1; + unsigned short rxData = 0; + unsigned short command = 0; + + // If the start address is out of range, return false + if (offset > 1031) { return 0; } + + // Set the read bit if specified + if (bRead == true) + { + command |= 0x8000; + } + + // Set the command address and length + command |= offset << 5; + command |= length; + + // Send the command word + send_16bit_SPI(command); + + // Send the data word + rxData = send_16bit_SPI(txData); + + return rxData; +} + +///////////////////////////////////////////////////////////////////////////////////////////////// +// Function name : ProgramDevice +// Description : Programs the PT2000 code RAM, data RAM and registers. +// Return type : void +///////////////////////////////////////////////////////////////////////////////////////////////// +void ProgramDevice() +{ + download_register(MAIN_REG); // download main register configurations + download_RAM(CODE_RAM1); // transfers code RAM1 + download_RAM(CODE_RAM2); // transfers code RAM2 + download_RAM(CODE_RAM3); // transfers code RAM3 + download_RAM(DATA_RAM); // transfers data RAM + + download_register(IO_REG); // download IO register configurations + download_register(DIAG_REG); // download diag register configurations + download_register(CH1_REG); // download channel 1 register configurations + download_register(CH2_REG); // download channel 2 register configurations + download_register(CH3_REG); // download channel 3 register configurations +} + +///////////////////////////////////////////////////////////////////////////////////////////////// +// Function name : download_RAM +// Description : Downloads code RAM or data RAM via SPI. +// Return type : void +// Argument : int target +///////////////////////////////////////////////////////////////////////////////////////////////// +void download_RAM(int target) +{ + unsigned short memory_area = 0; // memory area + unsigned short start_address = 0; // start address + unsigned short codeWidthRegAddr = 0; // code width register address + unsigned short size = 0; // size of RAM data + unsigned short command = 0; // command data + unsigned short data = 0; // RAM data + unsigned int k = 0; // used in loop for writing RAM data to the chip + unsigned short * RAM_ptr = NULL; // pointer to array of data to be sent to the chip + + // Select common page memory area + send_single_PT2000_SPI_Cmd(WRITE, selection_register, 0x0100); + + // Set the maximum watchdog timeout + send_single_PT2000_SPI_Cmd(WRITE, main_SPI_config, 0x1F); + + // Select target + switch (target) + { + case CODE_RAM1: + memory_area = 0x1; + start_address = 0; + codeWidthRegAddr = ch1_code_width; + RAM_ptr = PT2000_code_RAM1; + size = sizeof(PT2000_code_RAM1) / 2; // gets number of words to be sent + break; + + case CODE_RAM2: + memory_area = 0x2; + start_address = 0; + codeWidthRegAddr = ch2_code_width; + RAM_ptr = PT2000_code_RAM2; + size = sizeof(PT2000_code_RAM2) / 2; // gets number of words to be sent + break; + + case CODE_RAM3: + memory_area = 0x4; + start_address = 0; + codeWidthRegAddr = ch3_code_width; + RAM_ptr = PT2000_code_RAM3; + size = sizeof(PT2000_code_RAM3) / 2; // gets number of words to be sent + break; + + case DATA_RAM: + memory_area = 0x0100; + start_address = 0; + RAM_ptr = PT2000_data_RAM; + size = sizeof(PT2000_data_RAM) / 2; // gets number of words to be sent + break; + + default: + break; + } + + // Set the code width register only if code RAM is being downloaded + if (target != DATA_RAM) + { + // Set the code width register with the size of the download + send_single_PT2000_SPI_Cmd(WRITE, codeWidthRegAddr, size); + } + + // Send command for memory area selection + send_single_PT2000_SPI_Cmd(WRITE, selection_register, memory_area); + + command = start_address << 5; + send_16bit_SPI(command); // sends start address command + + for (k = 0; k < size; k++) // downloads RAM + { + data = *RAM_ptr; // retrieves data to be sent + send_16bit_SPI(data); // sends data + RAM_ptr++; + } +} //end download_RAM + +///////////////////////////////////////////////////////////////////////////////////////////////// +// Function name : download_register +// Description : Downloads register configurations via SPI. +// Return type : void +// Argument : int r_target +///////////////////////////////////////////////////////////////////////////////////////////////// +void download_register(int r_target) +{ + int n = 0; // used for loop for writing data to the chip + unsigned short r_start_address = 0; // start address + unsigned short r_size = 0; // size of configuration data + unsigned short r_command = 0; // command data + unsigned short r_data = 0; // configuration data + unsigned short remainder_size = 0; // remainder size + unsigned short *reg_ptr = NULL; // pointer to array of data to be sent to the chip + + switch (r_target) // selects target + { + case CH1_REG: // channel 1 configurations + r_start_address = ch1_flash_enable; + reg_ptr = PT2000_ch1_config; + r_size = sizeof(PT2000_ch1_config) / 2; // number of words to be sent + break; + + case CH2_REG: // channel 2 configurations + r_start_address = ch2_flash_enable; + reg_ptr = PT2000_ch2_config; + r_size = sizeof(PT2000_ch2_config) / 2; // number of words to be sent + break; + + case CH3_REG: // channel 3 configurations + r_start_address = ch3_flash_enable; + reg_ptr = PT2000_ch3_config; + r_size = sizeof(PT2000_ch3_config) / 2; // number of words to be sent + break; + + case DIAG_REG: // diagnostic configurations + r_start_address = diag_ls1_diag_config1; + reg_ptr = PT2000_diag_config; + r_size = sizeof(PT2000_diag_config) / 2; // number of words to be sent + break; + + case IO_REG: // IO configurations + r_start_address = io_fbk_sens_uc0_ch1_part1; + reg_ptr = PT2000_io_config; + r_size = sizeof(PT2000_io_config) / 2; // number of words to be sent + break; + + case MAIN_REG: // main configurations + r_start_address = main_Clock_Prescaler; + reg_ptr = PT2000_main_config; + r_size = sizeof(PT2000_main_config) / 2; // number of words to be sent + break; + + default: + break; + } + + // Select common page memory area + send_single_PT2000_SPI_Cmd(WRITE, selection_register, 0x0100); + + // Set the maximum watchdog timeout + send_single_PT2000_SPI_Cmd(WRITE, main_SPI_config, 0x1F); + + do + { + // If the size of the transfer is greater than the maximum SPI burst + // transfer size, set the size to the maximum SPI burst size and store + // the remainder size for use in the next SPI transfer + if (r_size > MAX_SPI_MODE_A_TRANSFER_SIZE) + { + remainder_size = r_size - MAX_SPI_MODE_A_TRANSFER_SIZE; + r_size = MAX_SPI_MODE_A_TRANSFER_SIZE; + } + else + { + // The size is <= MAX_SPI_MODE_A_TRANSFER_SIZE + // so there is no remaining data to be sent + remainder_size = 0; + } + + // Build the control word to be sent + r_command = r_start_address << 5; + r_command += r_size; + + // Write a control word indicating the address and the number of words to be sent + send_16bit_SPI(r_command); + + for (n = 0; n < r_size; n++) + { + // If this is the first register for ch1, ch2, or ch3 send 0 so the flash and dual + // microcores are not enabled + if( (n == 0) && ((r_target == CH1_REG) || (r_target == CH2_REG) || (r_target == CH3_REG)) ) + { + r_data = 0; + } + else + { + r_data = *reg_ptr; // set data to be sent + } + send_16bit_SPI(r_data); // send data + reg_ptr++; // update data pointer + } + + r_start_address += r_size; // update the start address + r_size = remainder_size; // set size to the remaining amount of data + } while (remainder_size > 0); + + + // For channels 1, 2, & 3 program the flash enable register using the the + // first entry in the channel's configuration table + switch (r_target) + { + case CH1_REG: + // Program the ch1 flash enable register + send_single_PT2000_SPI_Cmd(WRITE, ch1_flash_enable, PT2000_ch1_config[0]); + break; + + case CH2_REG: + // Program the ch2 flash enable register + send_single_PT2000_SPI_Cmd(WRITE, ch2_flash_enable, PT2000_ch2_config[0]); + break; + + case CH3_REG: + // Program the ch3 flash enable register + send_single_PT2000_SPI_Cmd(WRITE, ch3_flash_enable, PT2000_ch3_config[0]); + break; + + default: + break; + } + +} // end download_register + +///////////////////////////////////////////////////////////////////////////////////////////////// +// Function name : CLK_check +// Description : Check if the 1MHz CLK is connected to PT200x +// Return type : bool: 1 if CLK is present and 0 if no CLK detected (run on backup CLK) +///////////////////////////////////////////////////////////////////////////////////////////////// +bool CLK_check() +{ + unsigned short cksys_missing; + bool CLK_results = true; + + // Check CLK 1MHz + send_single_PT2000_SPI_Cmd(WRITE, selection_register, 0x100); // Select common page + cksys_missing = send_single_PT2000_SPI_Cmd(READ, main_Backup_Clock_Status, 0x00); // Read backup_clock_status 1A8h + + if ((cksys_missing & 0x1) != 0) { CLK_results = false; } // If 1MHz CLK not there set results to 0 + + return CLK_results; +} + +///////////////////////////////////////////////////////////////////////////////////////////////// +// Function name : Driver_Status_Init +// Description : Read Driver status register to make sure no UV or OT present +// Return type : bool: 1 if no issue, 0 if issue +////////////////////////////////////////////////////////////////////////////////////////////////// +bool Driver_Status_Init () +{ + unsigned short rxData = 0; + bool Driver_Status_results; + + Driver_Status_results = 1; + send_single_PT2000_SPI_Cmd(WRITE, selection_register, 0x100); // Select common page + send_single_PT2000_SPI_Cmd(READ, 0x1B2, 0); // Read driver status register + rxData = send_single_PT2000_SPI_Cmd(READ, main_Driver_Status, 0); // Read driver status second time to past faults + + if ( (rxData & 0x4F) != 0) { Driver_Status_results = 0; } // Error if different than 0 + + return Driver_Status_results; +} + +///////////////////////////////////////////////////////////////////////////////////////////////// +// Function name : DRVEN_check +// Description : Check if the DRVEN SPI monitoring works and if MCU can drive it +// Return type : bool: 1 is DRVEN test pass and 0 if it fails +///////////////////////////////////////////////////////////////////////////////////////////////// +bool DRVEN_check() +{ + //DRVEN safe state test + bool DRVEN_results; + DRVEN_results = 1; + unsigned short rxData = 0; + + SET_DRVEN_LOW; + send_single_PT2000_SPI_Cmd(WRITE, selection_register, 0x100); // Select common page + + // Check if DRVEN monitoring works using SPI register 1B2h + rxData = send_single_PT2000_SPI_Cmd(READ, main_Driver_Status, 0x00); + + // If bit DrvEn value is not 0, exit loop and do nothing since it will not be safe + if ((rxData & 0x10) != 0) { DRVEN_results=0; } + + // Sets drive enable signal high (enables outputs and vboost) + SET_DRVEN_HIGH; + + // Check if DRVEN monitoring works using SPI register 1B2h + rxData = send_single_PT2000_SPI_Cmd(READ, main_Driver_Status, 0x00); + + // If bit DrvEn value is not 1, exit loop and do nothing since it will not be safe + if ((rxData & 0x10) != 0x10) { DRVEN_results=0; } + + SET_DRVEN_LOW; + + return DRVEN_results; +} + +///////////////////////////////////////////////////////////////////////////////////////////////// +// Function name : BIST_check +// Description : make sure memory and logic works properly +// Return type : bool: 1 if BIST OK and 0 if BIST failed +///////////////////////////////////////////////////////////////////////////////////////////////// +bool BIST_check(_Bool MBIST_run, _Bool LBIST_run) +{ + unsigned short rxData = 0; + bool MBIST_results=1; + bool LBIST_results=1; + bool BIST_results=0; + + if(MBIST_run ==1) + { + // Run MBIST + rxData = 1; + send_single_PT2000_SPI_Cmd(WRITE, selection_register, 0x100); // Select common page + send_single_PT2000_SPI_Cmd(WRITE, main_BIST_interface, 0xB157); + delay100us(40); // wait 4 ms until MBIST complete + + while (rxData == 0x1) + { + rxData = send_single_PT2000_SPI_Cmd(READ, main_BIST_interface, 0); + delay100us(1); + } + + if (rxData == 0x2) + { + MBIST_results=1; + } + else + { + MBIST_results=0; + } + } + + if(LBIST_run ==1) + { + // Run LBIST + rxData = 0; + send_single_PT2000_SPI_Cmd(WRITE, main_BIST_interface, 0x666); + delay100us(350); // wait 35ms (24MHz PLL used) until LBIST complete + send_single_PT2000_SPI_Cmd(WRITE, selection_register, 0x100); // Select common page since LBIST removed it + rxData = send_single_PT2000_SPI_Cmd(READ, main_BIST_interface, 0); // LBIST results + + if (rxData == 0x8) + { + LBIST_results=1; + // Clear LBIST to reenable logic + send_single_PT2000_SPI_Cmd(WRITE, main_BIST_interface, 0xC1A0); + rxData = send_single_PT2000_SPI_Cmd(READ, main_BIST_interface, 0); + if (rxData == 0x0) LBIST_results=1; // make sure you are exiting the BIST mode + else LBIST_results=0; + } + else LBIST_results=0; + } + + // BIST result + BIST_results = MBIST_results & LBIST_results; + + return BIST_results; //if 1 OK else failure occurred on BIST +} + +///////////////////////////////////////////////////////////////////////////////////////////////// +// Function name : OA_path_check +// Description : make sure that OA are connected to MCU +// Return type : bool: 1 if OA 1 2 3 are connected to MCU, 0 if not +///////////////////////////////////////////////////////////////////////////////////////////////// +bool OA_path_check(_Bool OA1_check, _Bool OA2_check, _Bool OA3_check) +{ + bool OA_results=0; + int OA_value=0; + bool OA1_test=1; + bool OA2_test=1; + bool OA3_test=1; + unsigned char ch1 = 1; + unsigned char ch2 = 2; + unsigned char ch3 = 3; + + send_single_PT2000_SPI_Cmd(WRITE, selection_register, 0x100); // Select common page + + // Check OA connection to MCU using internal 2.5V + + if(OA1_check == 1) // OA1 + { + send_single_PT2000_SPI_Cmd(WRITE, io_oa_out1_config, 0x2B); //This will set the OA gain to 2.0, voltage on OA will be 5V + OA_value = read_ADC(ch1); + if ( OA_value > 0xF5) OA1_test =1; // No fault F5x19.6mV = 4.8V on OA meaning VCC2P5 > 2.4V (gain of 2) + else OA1_test =0; + } + if(OA2_check == 1) // OA2 + { + send_single_PT2000_SPI_Cmd(WRITE, io_oa_out2_config, 0x2B); //This will set the OA gain to 2.0, voltage on OA will be 5V + OA_value = read_ADC1(ch2); + if ( OA_value > 0xF5) OA2_test =1; + else OA2_test =0; + } + if(OA3_check == 1) // OA3 + { + send_single_PT2000_SPI_Cmd(WRITE, io_oa_out3_config, 0x2B); //This will set the OA gain to 2.0, voltage on OA will be 5V + OA_value = read_ADC1(ch3); + if ( OA_value > 0xF5) OA3_test =1; + else OA3_test =0; + } + + OA_results = OA1_test & OA2_test & OA3_test; + + return OA_results; +} + +///////////////////////////////////////////////////////////////////////////////////////////////// +// Function name : Checksum_check +// Description : Check if the flash enable works properly. To be run after programming device +// Return type : bool: 1 if flash enable is OK and 0 if checksum error occurred (check key used) +////////////////////////////////////////////////////////////////////////////////////////////////// +bool Checksum_check() +{ + unsigned short rxData = 0; + bool Checksum_results = true; + + send_single_PT2000_SPI_Cmd(WRITE, selection_register, 0x100); // Select common page + + // Checksum test + // Channel 1 + rxData = send_single_PT2000_SPI_Cmd(READ, ch1_flash_enable, 0x00); + // If bit checksum failure value is not 0, exit loop and do nothing since it will not be safe + if (((rxData & 0x01) == 1) | ((rxData & 0x30) != 0x30)) { Checksum_results = 0; } + + // Channel 2 + rxData = send_single_PT2000_SPI_Cmd(READ, ch2_flash_enable, 0x00); + // If bit checksum failure value is not 0, exit loop and do nothing since it will not be safe + if (((rxData & 0x01) == 1) | ((rxData & 0x30) != 0x30)) { Checksum_results = 0; } + + // Channel 3 + rxData = send_single_PT2000_SPI_Cmd(READ, ch3_flash_enable, 0x00); + // If bit checksum failure value is not 0, exit loop and do nothing since it will not be safe + if (((rxData & 0x01) == 1) | ((rxData & 0x30) != 0x30)) { Checksum_results = 0; } + + return Checksum_results; +} + +///////////////////////////////////////////////////////////////////////////////////////////////// +// Function name : Device_Lock_Unlock +// Description : Lock some SPI register or unlock them. Used only for safety purpose +// If Lock_Unlock is set to 1 then spi will be locked if set to 0 it will unlock +// Return type : void +////////////////////////////////////////////////////////////////////////////////////////////////// +void Device_Lock_Unlock (unsigned char Lock_Unlock) +{ + send_single_PT2000_SPI_Cmd(WRITE, selection_register, 0x100); // Select common page + + if (Lock_Unlock ==1) // Lock device + { + send_single_PT2000_SPI_Cmd(WRITE, main_Device_lock, 0x01); // Just SPI is locked not the DRAM private + } + else // unlock device + { + send_single_PT2000_SPI_Cmd(WRITE, main_Device_unlock, 0x1337); // Unlock device + } +} + +///////////////////////////////////////////////////////////////////////////////////////////////// +// Function name : Read_VbatADC +// Description : Read Vbat voltage using PT2000x ADC. Make sure off comp prescaler is set +// properly to 500kHz max +// Return type : Vbat value +////////////////////////////////////////////////////////////////////////////////////////////////// +unsigned short Read_VbatADC () +{ + unsigned short VBAT_value = 0; + + send_single_PT2000_SPI_Cmd(WRITE, selection_register, 0x100); // Select common page + VBAT_value = send_single_PT2000_SPI_Cmd(READ, io_batt_result, 0); // Read adc vbat register + VBAT_value = VBAT_value * 0.03906 * 16; // LSB 39.06mV, ratio 16 + + return VBAT_value; +} + +///////////////////////////////////////////////////////////////////////////////////////////////// +// Function name : ID_Check +// Description : Used to check if SPI works properly and if device connected match with MCU code +// Return type : bool: 1 if OK and 0 if fails +////////////////////////////////////////////////////////////////////////////////////////////////// +bool ID_Check () +{ + unsigned short rxData = 0; + bool ID_results = true; + + // Check if SPI works and that device is the good one + send_single_PT2000_SPI_Cmd(WRITE, selection_register, 0x100); // Set common page + rxData = send_single_PT2000_SPI_Cmd(READ, main_Device_Identifier, 0x00); // Read back device ID (value will be in rxData) + + // If device ID is wrong, return 0 + if (rxData != 0xAE32) { ID_results = false; } + + return ID_results; +} + +///////////////////////////////////////////////////////////////////////////////////////////////// +// Function name : Bootstrap_check +// Description : Used to check if bootstrap capacitor are charged before starting actuation +// make sure hsx_ls_act are set properly +// Return type : unsigned long: timer value if charged meaning >0 and 0 if not charged +////////////////////////////////////////////////////////////////////////////////////////////////// +unsigned long Bootstrap_check () +{ + unsigned short rxData = 0; + unsigned long Bootstrap_results = 1; + + send_single_PT2000_SPI_Cmd(WRITE, selection_register, 0x100); // Set common page + rxData = send_single_PT2000_SPI_Cmd(READ, io_bootstrap_charged, 0x00); + + if((rxData & 0x7F) != 0) + { + delay(300); // wait 300ms to see if it is finally charged this timing depend on bootstrap charge strategy + rxData = send_single_PT2000_SPI_Cmd(READ, io_bootstrap_charged, 0x00); + + if((rxData & 0x7F) != 0) {Bootstrap_results =0;} // error if still not charged + + } + else + { + rxData = send_single_PT2000_SPI_Cmd(READ, io_bootstrap_timer, 0x00); + Bootstrap_results = (rxData << 14) * 4.16666666666667E-08; // data * 2^14 * (1/24MHz) + } + + return Bootstrap_results; +} + +///////////////////////////////////////////////////////////////////////////////////////////////// +// Function name : Trace_config +// Description : Used to configure and enable the trace. +// External tracer KITPSCDEBUGEVM to be turned ON before executing this +// function (see IDE) +// Return type : void +////////////////////////////////////////////////////////////////////////////////////////////////// +void Tracer (unsigned int trace_start, unsigned int trace_stop, _Bool ucore, unsigned char channel , unsigned char post_trigger_length, _Bool trace_enable) +{ + unsigned short uc_select; + unsigned short trace_config; + + send_single_PT2000_SPI_Cmd(WRITE, main_Trace_start, trace_start); // Set trace start + send_single_PT2000_SPI_Cmd(WRITE, main_Trace_stop, trace_stop); // Set trace stop + uc_select = ((channel-1) << 1) + ucore; // 000 uc0 channel1, 001 uc1 ch1, 100 uc0 ch3... + trace_config = post_trigger_length + (uc_select << 8) + (trace_enable << 15); + send_single_PT2000_SPI_Cmd(WRITE, main_Trace_config, trace_config); // Set trace config +} diff --git a/GDI-6ch/project/sample_code/PT2000.h b/GDI-6ch/project/sample_code/PT2000.h new file mode 100644 index 00000000..f31c07a1 --- /dev/null +++ b/GDI-6ch/project/sample_code/PT2000.h @@ -0,0 +1,86 @@ +/******************************************************************************* +* Example Code +* +* Copyright(C) 2025 NXP Semiconductors +* NXP Semiconductors Confidential and Proprietary +* +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* NXP products. This software is supplied "AS IS" without any warranties +* of any kind, and NXP Semiconductors and its licensor disclaim any and +* all warranties, express or implied, including all implied warranties of +* merchantability, fitness for a particular purpose and non-infringement of +* intellectual property rights. NXP Semiconductors assumes no responsibility +* or liability for the use of the software, conveys no license or rights +* under any patent, copyright, mask work right, or any other intellectual +* property rights in or to any products. NXP Semiconductors reserves the +* right to make changes in the software without notification. NXP +* Semiconductors also makes no representation or warranty that such +* application will be suitable for the specified use without further testing +* or modification. +* +* IN NO EVENT WILL NXP SEMICONDUCTORS BE LIABLE, WHETHER IN CONTRACT, +* TORT, OR OTHERWISE, FOR ANY INCIDENTAL, SPECIAL, INDIRECT, CONSEQUENTIAL +* OR PUNITIVE DAMAGES, INCLUDING, BUT NOT LIMITED TO, DAMAGES FOR ANY +* LOSS OF USE, LOSS OF TIME, INCONVENIENCE, COMMERCIAL LOSS, OR LOST +* PROFITS, SAVINGS, OR REVENUES, TO THE FULL EXTENT SUCH MAY BE DISCLAIMED +* BY LAW. NXP SEMICONDUCTOR’S TOTAL LIABILITY FOR ALL COSTS, DAMAGES, +* CLAIMS, OR LOSSES WHATSOEVER ARISING OUT OF OR IN CONNECTION WITH THE +* SOFTWARE IS LIMITED TO THE AGGREGATE AMOUNT PAID BY YOU TO NXP SEMICONDUCTORS +* IN CONNECTION WITH THE SOFTWARE TO WHICH LOSSES OR DAMAGES ARE CLAIMED. +* +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' and its +* licensor's relevant copyrights in the software, without fee, provided +* that it is used in conjunction with NXP Semiconductors devices. This +* copyright, permission, and disclaimer notice must appear in all copies +* of this code. +*******************************************************************************/ + +/* + * PT2000.h + * + * PT2000 Header File + * + */ + +#ifndef PT2000_H_ +#define PT2000_H_ + +#include "stdint.h" +#include "stdbool.h" +#include "PT2000_LoadData.h" + +#define CODE_RAM1 0 +#define CODE_RAM2 1 +#define CODE_RAM3 2 +#define DATA_RAM 3 + +#define CH1_REG 0 +#define CH2_REG 1 +#define CH3_REG 2 +#define DIAG_REG 3 +#define IO_REG 4 +#define MAIN_REG 5 + +uint16_t send_single_PT2000_SPI_Cmd(bool bRead, uint16_t offset, uint16_t txData); +bool send_PT2000_SPI_Cmd(bool bRead, uint16_t start_addr, uint16_t length, uint16_t* pTxData, uint16_t* pRxData); + + +void ProgramDevice(); +void download_RAM(int target); +void download_register(int r_target); + +bool ID_Check (); +bool CLK_check(); +bool Driver_Status_Init (); +bool DRVEN_check(); +bool BIST_check(_Bool MBIST_run, _Bool LBIST_run); +bool OA_path_check(_Bool OA1_check, _Bool OA2_check, _Bool OA3_check); +bool Checksum_check(); +uint16_t Read_VbatADC (); +unsigned long Bootstrap_check (); +void Device_Lock_Unlock (unsigned char Lock_Unlock); +void Tracer (unsigned int trace_start, unsigned int trace_stop, _Bool ucore, unsigned char channel , unsigned char post_trigger_length, _Bool trace_enable); + +#endif /* PT2000_H_ */ diff --git a/GDI-6ch/project/sample_code/PT2000_LoadData.c b/GDI-6ch/project/sample_code/PT2000_LoadData.c new file mode 100644 index 00000000..4d510f8c --- /dev/null +++ b/GDI-6ch/project/sample_code/PT2000_LoadData.c @@ -0,0 +1,171 @@ +/******************************************************************************* +* Example Code +* +* Copyright(C) 2025 NXP Semiconductors +* NXP Semiconductors Confidential and Proprietary +* +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* NXP products. This software is supplied "AS IS" without any warranties +* of any kind, and NXP Semiconductors and its licensor disclaim any and +* all warranties, express or implied, including all implied warranties of +* merchantability, fitness for a particular purpose and non-infringement of +* intellectual property rights. NXP Semiconductors assumes no responsibility +* or liability for the use of the software, conveys no license or rights +* under any patent, copyright, mask work right, or any other intellectual +* property rights in or to any products. NXP Semiconductors reserves the +* right to make changes in the software without notification. NXP +* Semiconductors also makes no representation or warranty that such +* application will be suitable for the specified use without further testing +* or modification. +* +* IN NO EVENT WILL NXP SEMICONDUCTORS BE LIABLE, WHETHER IN CONTRACT, +* TORT, OR OTHERWISE, FOR ANY INCIDENTAL, SPECIAL, INDIRECT, CONSEQUENTIAL +* OR PUNITIVE DAMAGES, INCLUDING, BUT NOT LIMITED TO, DAMAGES FOR ANY +* LOSS OF USE, LOSS OF TIME, INCONVENIENCE, COMMERCIAL LOSS, OR LOST +* PROFITS, SAVINGS, OR REVENUES, TO THE FULL EXTENT SUCH MAY BE DISCLAIMED +* BY LAW. NXP SEMICONDUCTOR’S TOTAL LIABILITY FOR ALL COSTS, DAMAGES, +* CLAIMS, OR LOSSES WHATSOEVER ARISING OUT OF OR IN CONNECTION WITH THE +* SOFTWARE IS LIMITED TO THE AGGREGATE AMOUNT PAID BY YOU TO NXP SEMICONDUCTORS +* IN CONNECTION WITH THE SOFTWARE TO WHICH LOSSES OR DAMAGES ARE CLAIMED. +* +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' and its +* licensor's relevant copyrights in the software, without fee, provided +* that it is used in conjunction with NXP Semiconductors devices. This +* copyright, permission, and disclaimer notice must appear in all copies +* of this code. +*******************************************************************************/ + +//============================================================================== +// This file contains data arrays that are used to load the code RAM, data RAM +// and registers on the PT2000. +//============================================================================== + +// ECU: IDE Project +// Project: rusefi + +#include "PT2000_LoadData.h" + +// Data to be loaded into the Code RAM 1 memory space +unsigned short PT2000_code_RAM1[116] = +{ + 0x3645, 0xB475, 0x5135, 0x3159, 0x200A, 0x860B, 0x10C4, 0x2F0A, 0x2958, 0x1E87, + 0xC964, 0xD52D, 0xB5C3, 0xDCB5, 0x39F9, 0x76F7, 0x2304, 0x84A7, 0x4729, 0xF6DC, + 0x9E2E, 0x4F10, 0x8BE3, 0x9157, 0x9B94, 0xC8BD, 0x8C8C, 0x5B8E, 0x9338, 0x8214, + 0x9D8B, 0x8D95, 0x71D3, 0xF684, 0x2A29, 0xF503, 0xD61A, 0xC3EB, 0x66FF, 0x84DA, + 0x4D1D, 0x4B20, 0x5A7B, 0x5CB6, 0x3828, 0x75A0, 0x36EC, 0x8097, 0xFED6, 0x8AD2, + 0x96F2, 0xACBE, 0x1F95, 0xA0DC, 0x27BD, 0x9F2C, 0x18BC, 0x7ED1, 0x1877, 0xF4AE, + 0x8B74, 0x0648, 0xF114, 0x6554, 0xCE5F, 0xAE7D, 0x3D7A, 0x9067, 0x3987, 0x8D21, + 0x81BE, 0x4FAC, 0x54EE, 0xFBD0, 0xB38C, 0x16EB, 0x4E72, 0x747E, 0xCC43, 0x191C, + 0xA60F, 0x0B69, 0x75B2, 0xD393, 0x1205, 0x44A4, 0xFF55, 0xC8C4, 0x9C8F, 0x4CBC, + 0xA329, 0x0877, 0x3657, 0x3AEB, 0xEFA1, 0xFA4C, 0x213C, 0xD0D1, 0xCDC9, 0x1405, + 0x18FB, 0xCF49, 0x401A, 0xD5BC, 0x605C, 0x6A2F, 0xAB01, 0x1676, 0x2C83, 0x442D, + 0x3915, 0x08EF, 0x4705, 0x883C, 0xAF0B, 0x8FCD +}; + +// Data to be loaded into the Code RAM 2 memory space +unsigned short PT2000_code_RAM2[62] = +{ + 0x3643, 0xB476, 0x5135, 0x3159, 0x200A, 0x840B, 0x12C4, 0x2F0A, 0x3868, 0x1E87, + 0xD874, 0xD52D, 0xB5DB, 0xDCB5, 0x39F9, 0x76F7, 0x2304, 0x84A7, 0x4729, 0xF6DC, + 0x9E2E, 0x4F10, 0x8BE3, 0x9157, 0x9B94, 0xC8BD, 0x8C8C, 0x5B8E, 0x9338, 0x820C, + 0x9D8B, 0x8D95, 0x71D3, 0xF684, 0x2A29, 0xF503, 0xD61A, 0xC3EB, 0x66FF, 0x84DA, + 0x4D1D, 0x4B20, 0x5A7B, 0x5CB6, 0x3828, 0x75A0, 0x36F4, 0x8097, 0xFED6, 0x8AD2, + 0x96F2, 0xACBE, 0x1F95, 0xA0DC, 0x27BD, 0x9F2C, 0x18BC, 0x7ED1, 0x1465, 0xF8D0, + 0x33FB, 0xB9A9 +}; + +// Data to be loaded into the Code RAM 3 memory space +unsigned short PT2000_code_RAM3[43] = +{ + 0x3647, 0xB47F, 0x51B1, 0x3159, 0x200A, 0x852A, 0x3D25, 0x8D10, 0x8606, 0xB456, + 0x8F79, 0xCE44, 0x00C2, 0x58C3, 0x6595, 0xE89E, 0x2B45, 0x1211, 0xB860, 0xF7F6, + 0xFC33, 0x4F0C, 0x8A62, 0x9CAF, 0x9A45, 0x4333, 0x8D09, 0xEC00, 0x41DE, 0x3652, + 0x99EA, 0x8345, 0x759D, 0x4297, 0xD69B, 0xF515, 0x639E, 0xC3AC, 0x237F, 0x8500, + 0x4C9E, 0x3B9B, 0x4139 +}; + +// Data to be loaded into the Data RAM memory space +unsigned short PT2000_data_RAM[192] = +{ + 0x008D, 0x006D, 0x003A, 0x003C, 0x1068, 0x003C, 0x0168, 0xEA60, 0x0960, 0x0258, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x008D, 0x006D, 0x003A, 0x003C, 0x1068, 0x003C, + 0x0168, 0xEA60, 0x0960, 0x0258, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00C1, 0x00BF, + 0x0040, 0x001D, 0x0000, 0x0046, 0x0037, 0x003C, 0xEA60, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000 +}; + +// Data to be loaded into the Main register memory space +unsigned short PT2000_main_config[32] = +{ + 0x0003, 0x0000, 0x0008, 0xE81F, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000, 0x001D, + 0x0000, 0x0000, 0x0000, 0x0000, 0xBF3F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000 +}; + +// Data to be loaded into the CH1 register memory space +unsigned short PT2000_ch1_config[20] = +{ + 0x0000, 0x0025, 0x0014, 0x0C03, 0x0000, 0x0001, 0x0001, 0x0074, 0x3B52, 0xA28B, + 0x0000, 0x003A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 + +}; + +// Data to be loaded into the CH2 register memory space +unsigned short PT2000_ch2_config[20] = +{ + 0x0000, 0x000C, 0x0070, 0x0030, 0x0000, 0x0002, 0x0002, 0x003E, 0x9F7E, 0x4EEC, + 0x0000, 0x003A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0010, 0x0000 + +}; + +// Data to be loaded into the CH3 register memory space +unsigned short PT2000_ch3_config[20] = +{ + 0x0000, 0x0003, 0x000C, 0x0080, 0x0000, 0x0000, 0x0000, 0x002B, 0x6F0D, 0x3DFF, + 0x0000, 0x0018, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0004, 0x0000 + +}; + +// Data to be loaded into the IO register memory space +unsigned short PT2000_io_config[73] = +{ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0303, 0x0C0C, 0x3030, 0x0000, 0x8040, 0x4000, 0x0201, 0x0040, + 0x3004, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0555, + 0x0555, 0x0050, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0707, 0x0707, + 0x0707, 0x0707, 0x0707, 0x00CD, 0x0020, 0x0000, 0x0000, 0x0017, 0x0016, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0003, + 0x0003, 0x000C, 0x000C, 0x0030, 0x0030, 0x0080, 0x0000, 0x0028, 0x0028, 0x0028, + 0x8110, 0x23C7, 0x0100 +}; + +// Data to be loaded into the Diag register memory space +unsigned short PT2000_diag_config[64] = +{ + 0x0000, 0x0000, 0x003E, 0x0000, 0x0000, 0x003E, 0x0000, 0x0000, 0x003E, 0x0000, + 0x0000, 0x003E, 0x0000, 0x0000, 0x003E, 0x0000, 0x0000, 0x003E, 0x0000, 0x0000, + 0x003E, 0x0000, 0x0000, 0x003E, 0x0000, 0x0000, 0x00FE, 0x0000, 0x0000, 0x00FE, + 0x0000, 0x0000, 0x00FE, 0x0000, 0x0000, 0x00FE, 0x0000, 0x0000, 0x00FE, 0x0000, + 0x0000, 0x00FE, 0x0000, 0x0000, 0x00FE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 +}; + diff --git a/GDI-6ch/project/sample_code/PT2000_LoadData.h b/GDI-6ch/project/sample_code/PT2000_LoadData.h new file mode 100644 index 00000000..4ebb167c --- /dev/null +++ b/GDI-6ch/project/sample_code/PT2000_LoadData.h @@ -0,0 +1,62 @@ +/******************************************************************************* +* Example Code +* +* Copyright(C) 2025 NXP Semiconductors +* NXP Semiconductors Confidential and Proprietary +* +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* NXP products. This software is supplied "AS IS" without any warranties +* of any kind, and NXP Semiconductors and its licensor disclaim any and +* all warranties, express or implied, including all implied warranties of +* merchantability, fitness for a particular purpose and non-infringement of +* intellectual property rights. NXP Semiconductors assumes no responsibility +* or liability for the use of the software, conveys no license or rights +* under any patent, copyright, mask work right, or any other intellectual +* property rights in or to any products. NXP Semiconductors reserves the +* right to make changes in the software without notification. NXP +* Semiconductors also makes no representation or warranty that such +* application will be suitable for the specified use without further testing +* or modification. +* +* IN NO EVENT WILL NXP SEMICONDUCTORS BE LIABLE, WHETHER IN CONTRACT, +* TORT, OR OTHERWISE, FOR ANY INCIDENTAL, SPECIAL, INDIRECT, CONSEQUENTIAL +* OR PUNITIVE DAMAGES, INCLUDING, BUT NOT LIMITED TO, DAMAGES FOR ANY +* LOSS OF USE, LOSS OF TIME, INCONVENIENCE, COMMERCIAL LOSS, OR LOST +* PROFITS, SAVINGS, OR REVENUES, TO THE FULL EXTENT SUCH MAY BE DISCLAIMED +* BY LAW. NXP SEMICONDUCTOR’S TOTAL LIABILITY FOR ALL COSTS, DAMAGES, +* CLAIMS, OR LOSSES WHATSOEVER ARISING OUT OF OR IN CONNECTION WITH THE +* SOFTWARE IS LIMITED TO THE AGGREGATE AMOUNT PAID BY YOU TO NXP SEMICONDUCTORS +* IN CONNECTION WITH THE SOFTWARE TO WHICH LOSSES OR DAMAGES ARE CLAIMED. +* +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' and its +* licensor's relevant copyrights in the software, without fee, provided +* that it is used in conjunction with NXP Semiconductors devices. This +* copyright, permission, and disclaimer notice must appear in all copies +* of this code. +*******************************************************************************/ + +//============================================================================== +// This file contains data array declarations for the code RAM, data RAM and +// register arrays for the PT2000. +//============================================================================== + +// ECU: IDE Project +// Project: rusefi + +#ifndef PT2000_DATA_H_ +#define PT2000_DATA_H_ + +extern unsigned short PT2000_code_RAM1[116]; // CODE RAM CH 1 +extern unsigned short PT2000_code_RAM2[62]; // CODE RAM CH 2 +extern unsigned short PT2000_code_RAM3[43]; // CODE RAM CH 3 +extern unsigned short PT2000_data_RAM[192]; // DATA RAM +extern unsigned short PT2000_main_config[32]; // main configurations +extern unsigned short PT2000_ch1_config[20]; // CH 1 configurations +extern unsigned short PT2000_ch2_config[20]; // CH 2 configurations +extern unsigned short PT2000_ch3_config[20]; // CH 3 configurations +extern unsigned short PT2000_io_config[73]; // IO configurations +extern unsigned short PT2000_diag_config[64]; // diag configurations + +#endif /* PT2000_DATA_H_ */ diff --git a/GDI-6ch/project/sample_code/PT2000_dram.h b/GDI-6ch/project/sample_code/PT2000_dram.h new file mode 100644 index 00000000..b1ee22ab --- /dev/null +++ b/GDI-6ch/project/sample_code/PT2000_dram.h @@ -0,0 +1,84 @@ +/******************************************************************************* +* Example Code +* +* Copyright(C) 2025 NXP Semiconductors +* NXP Semiconductors Confidential and Proprietary +* +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* NXP products. This software is supplied "AS IS" without any warranties +* of any kind, and NXP Semiconductors and its licensor disclaim any and +* all warranties, express or implied, including all implied warranties of +* merchantability, fitness for a particular purpose and non-infringement of +* intellectual property rights. NXP Semiconductors assumes no responsibility +* or liability for the use of the software, conveys no license or rights +* under any patent, copyright, mask work right, or any other intellectual +* property rights in or to any products. NXP Semiconductors reserves the +* right to make changes in the software without notification. NXP +* Semiconductors also makes no representation or warranty that such +* application will be suitable for the specified use without further testing +* or modification. +* +* IN NO EVENT WILL NXP SEMICONDUCTORS BE LIABLE, WHETHER IN CONTRACT, +* TORT, OR OTHERWISE, FOR ANY INCIDENTAL, SPECIAL, INDIRECT, CONSEQUENTIAL +* OR PUNITIVE DAMAGES, INCLUDING, BUT NOT LIMITED TO, DAMAGES FOR ANY +* LOSS OF USE, LOSS OF TIME, INCONVENIENCE, COMMERCIAL LOSS, OR LOST +* PROFITS, SAVINGS, OR REVENUES, TO THE FULL EXTENT SUCH MAY BE DISCLAIMED +* BY LAW. NXP SEMICONDUCTOR’S TOTAL LIABILITY FOR ALL COSTS, DAMAGES, +* CLAIMS, OR LOSSES WHATSOEVER ARISING OUT OF OR IN CONNECTION WITH THE +* SOFTWARE IS LIMITED TO THE AGGREGATE AMOUNT PAID BY YOU TO NXP SEMICONDUCTORS +* IN CONNECTION WITH THE SOFTWARE TO WHICH LOSSES OR DAMAGES ARE CLAIMED. +* +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' and its +* licensor's relevant copyrights in the software, without fee, provided +* that it is used in conjunction with NXP Semiconductors devices. This +* copyright, permission, and disclaimer notice must appear in all copies +* of this code. +*******************************************************************************/ + +/* + * PT2000_dram.h + * + * DRAM Header File + * + */ + +#ifndef PT2000_DRAM_H_ +#define PT2000_DRAM_H_ + +// DRAM 1 Parameter Addresses +#define PT2000_D1_Iboost 0x00 +#define PT2000_D1_Ipeak 0x01 +#define PT2000_D1_Ihold 0x02 +#define PT2000_D1_Tpeak_off 0x03 +#define PT2000_D1_Tpeak_tot 0x04 +#define PT2000_D1_Tbypass 0x05 +#define PT2000_D1_Thold_off 0x06 +#define PT2000_D1_Thold_tot 0x07 +#define PT2000_D1_Tboost_max 0x08 +#define PT2000_D1_Tboost_min 0x09 + +// DRAM 2 Parameter Addresses +#define PT2000_D2_Iboost 0x40 +#define PT2000_D2_Ipeak 0x41 +#define PT2000_D2_Ihold 0x42 +#define PT2000_D2_Tpeak_off 0x43 +#define PT2000_D2_Tpeak_tot 0x44 +#define PT2000_D2_Tbypass 0x45 +#define PT2000_D2_Thold_off 0x46 +#define PT2000_D2_Thold_tot 0x47 +#define PT2000_D2_Tboost_max 0x48 +#define PT2000_D2_Tboost_min 0x49 + +// DRAM 3 Parameter Addresses +#define PT2000_D3_Vboost_high 0x80 +#define PT2000_D3_Vboost_low 0x81 +#define PT2000_D3_Iboost_H 0x82 +#define PT2000_D3_Iboost_L 0x83 +#define PT2000_D3_HPFP_Ipeak 0x85 +#define PT2000_D3_HPFP_Ihold 0x86 +#define PT2000_D3_HPFP_Thold_off 0x87 +#define PT2000_D3_HPFP_Thold_tot 0x88 + +#endif /* PT2000_DRAM_H_ */ diff --git a/GDI-6ch/project/sample_code/PT2000_irq.c b/GDI-6ch/project/sample_code/PT2000_irq.c new file mode 100644 index 00000000..1a97d287 --- /dev/null +++ b/GDI-6ch/project/sample_code/PT2000_irq.c @@ -0,0 +1,641 @@ +/******************************************************************************* +* Example Code +* +* Copyright(C) 2025 NXP Semiconductors +* NXP Semiconductors Confidential and Proprietary +* +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* NXP products. This software is supplied "AS IS" without any warranties +* of any kind, and NXP Semiconductors and its licensor disclaim any and +* all warranties, express or implied, including all implied warranties of +* merchantability, fitness for a particular purpose and non-infringement of +* intellectual property rights. NXP Semiconductors assumes no responsibility +* or liability for the use of the software, conveys no license or rights +* under any patent, copyright, mask work right, or any other intellectual +* property rights in or to any products. NXP Semiconductors reserves the +* right to make changes in the software without notification. NXP +* Semiconductors also makes no representation or warranty that such +* application will be suitable for the specified use without further testing +* or modification. +* +* IN NO EVENT WILL NXP SEMICONDUCTORS BE LIABLE, WHETHER IN CONTRACT, +* TORT, OR OTHERWISE, FOR ANY INCIDENTAL, SPECIAL, INDIRECT, CONSEQUENTIAL +* OR PUNITIVE DAMAGES, INCLUDING, BUT NOT LIMITED TO, DAMAGES FOR ANY +* LOSS OF USE, LOSS OF TIME, INCONVENIENCE, COMMERCIAL LOSS, OR LOST +* PROFITS, SAVINGS, OR REVENUES, TO THE FULL EXTENT SUCH MAY BE DISCLAIMED +* BY LAW. NXP SEMICONDUCTOR’S TOTAL LIABILITY FOR ALL COSTS, DAMAGES, +* CLAIMS, OR LOSSES WHATSOEVER ARISING OUT OF OR IN CONNECTION WITH THE +* SOFTWARE IS LIMITED TO THE AGGREGATE AMOUNT PAID BY YOU TO NXP SEMICONDUCTORS +* IN CONNECTION WITH THE SOFTWARE TO WHICH LOSSES OR DAMAGES ARE CLAIMED. +* +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' and its +* licensor's relevant copyrights in the software, without fee, provided +* that it is used in conjunction with NXP Semiconductors devices. This +* copyright, permission, and disclaimer notice must appear in all copies +* of this code. +*******************************************************************************/ + +#include "lpspi.h" +#include "system.h" +#include "PT2000.h" +#include "PT2000_irq.h" +#include "PT2000_spi_map.h" + +extern int flag_IRQB; +extern int drv_int_counter; +extern const int sw_retry; +extern const int auto_retry; +extern uint16_t rxData; +extern uint16_t cksys_missing_error; +extern uint16_t cksys_missing; +extern uint16_t drv_irq; +extern uint16_t checksum_irq; +extern uint16_t drv_status; +extern uint16_t spi_irq; +extern uint16_t auto_irq; +extern uint16_t sw_irq; +extern uint16_t inj1_error; +extern uint16_t inj2_error; +extern uint16_t inj3_error; +extern uint16_t inj4_error; +extern uint16_t inj5_error; +extern uint16_t inj6_error; +extern uint16_t fp_error; +extern uint16_t dcdc_error; +volatile bool flag_start1_fail; +volatile bool flag_start2_fail; +volatile bool flag_start3_fail; +volatile bool flag_start4_fail; +volatile bool flag_start5_fail; +volatile bool flag_start6_fail; +volatile bool flag_start7_fail; +uint16_t AutoErrStatus; +uint16_t interrupt_reg1 = 0; +uint16_t interrupt_reg2 = 0; + +// Interrupt Handlers + +///////////////////////////////////////////////////////////////////////////////////////////////// +// Function name : ProcessPT2000Interrupts +// Description : +// Return type : void +///////////////////////////////////////////////////////////////////////////////////////////////// +void ProcessPT2000Interrupts() +{ + flag_IRQB = 0; + + // Read interrupt register 2 Address 1B5h + interrupt_reg2 = send_single_PT2000_SPI_Cmd(READ, main_Interrupt_register_part2, 0x00); + if (interrupt_reg2 != 0) + { + ProcessDriverInterrupts(); + + } // END of interrupt on 1B5h UV, OT + + // Read interrupt register 1 Address 1B4h (Auto and SW interrupt from microcore) + interrupt_reg1 = send_single_PT2000_SPI_Cmd(READ, main_Interrupt_register_part1, 0x00); + if (interrupt_reg1 != 0) + { + // Automatic IRQ (halt bits) + auto_irq = interrupt_reg1 & 0x003F; // only select b0-5 + if (auto_irq != 0) // One of the halt bits is at 1 + { + ProcessAutomaticInterrupts(); + ProcessSoftwareInterrupts(); // Needed in case a SW interrupt also happened + } + + // Software IRQ (irq bits) + sw_irq = interrupt_reg1 & 0x3F00; // only select b8-13 + if (sw_irq != 0) // One of the irq bits is at 1 + { + ProcessSoftwareInterrupts(); + ProcessAutomaticInterrupts(); + } + } // End of Interrupt 1B4 auto SW interrupt +} + +///////////////////////////////////////////////////////////////////////////////////////////////// +// Function name : ProcessDriverInterrupts +// Description : +// Return type : void +///////////////////////////////////////////////////////////////////////////////////////////////// +void ProcessDriverInterrupts() +{ + // DRV IRQ + drv_irq = interrupt_reg2 & 0x0100; // only select b8 + if (drv_irq != 0) + { + // drv interrupt occurred need to check which one + drv_status = send_single_PT2000_SPI_Cmd(READ, main_Driver_Status, 0x00); // Read driver_status 1B2h + if ((drv_status & 0xF) != 0) // only select OT, and 3 UV + { + send_single_PT2000_SPI_Cmd(WRITE, main_Driver_Status, 0xF); // Try to clear the fault by writing a 1 + // Check if fault is still there + drv_status = send_single_PT2000_SPI_Cmd(READ, main_Driver_Status, 0x00); // Read driver_status 1B2h + + if ((drv_status & 0xF) != 0) + { + // Error is still there a full reset is tried + } + else + { + drv_int_counter++; + } + } // End of OT UV loop + } // End driver status interrupt + + // SPI error IRQ + spi_irq = interrupt_reg2 & 0x0200; // only select b9 SPI IRQ + if (spi_irq != 0) + { + send_single_PT2000_SPI_Cmd(READ, main_SPI_error_code, 0x00); // Read driver_status 1B3h, ONLY word accepted if SPI error occurred + send_single_PT2000_SPI_Cmd(WRITE, selection_register, 0x100); // Select common page + rxData = send_single_PT2000_SPI_Cmd(READ, main_SPI_error_code, 0x00); // Check and clear error + + // Add code to do a full restart of the MCU using SW reset + + } // End of IRQB SPI + + // cksys missing case IRQB + cksys_missing = interrupt_reg2 & 0x0400; // only select b10 CLK missing + if (cksys_missing != 0) + { + cksys_missing = send_single_PT2000_SPI_Cmd(READ, main_Backup_Clock_Status, 0x00); // Read backup_clock_status 1A8h, IRQB goes High again + if ((cksys_missing & 0x1) != 0) // Keep only bit 0 + { + PWM_1MHz(); // Reinitialize the 1MHz PWM + cksys_missing_error++; + if (cksys_missing_error > 100) + { + // Error is still there a full reset is tried + SET_DRVEN_LOW; + SET_RESETB_LOW; + delay(1); + SET_RESETB_HIGH; + ProgramDevice(); + delay(1); + SET_DRVEN_HIGH; + cksys_missing_error = 0; + } + send_single_PT2000_SPI_Cmd(WRITE, main_Backup_Clock_Status, 0x7); // Switch to CLK pin, in this case IRQB will be low again another interrupt will occurred + delay(1); // Need this delay to let PLL relock properly + } + if ((cksys_missing & 0x1) == 0) // Run on main CLK again + { + // Set LED GREEN ON + } + } // END OF IRQ CLK + + // Checksum case + checksum_irq = interrupt_reg2 & 0x3800; // only select b11 to b13 checksum error + if (checksum_irq != 0) + { + if ((checksum_irq & 0x0800) == 0x0800) // Error on Channel 1 + { + download_RAM(CODE_RAM1); // transfers code RAM1 + download_register(CH1_REG); // send channel registers + send_single_PT2000_SPI_Cmd(WRITE, ch1_flash_enable, 0x001A); // enable flash and dual sequence ch1 (address = 0x100) + } + if ((checksum_irq & 0x1000) == 0x1000) // Error on Channel 1 + { + download_RAM(CODE_RAM2); // transfers code RAM1 + download_register(CH2_REG); // send channel registers + send_single_PT2000_SPI_Cmd(WRITE, ch2_flash_enable, 0x001A); // enable flash and dual sequence ch1 (address = 0x100) + } + if ((checksum_irq & 0x2000) == 0x2000) // Error on Channel 1 + { + download_RAM(CODE_RAM3); // transfers code RAM1 + download_register(CH3_REG); // send channel registers + send_single_PT2000_SPI_Cmd(WRITE, ch3_flash_enable, 0x001A); // enable flash and dual sequence ch1 (address = 0x100) + } + if (Checksum_check() == 0) + { + // Add code to reset MCU if checksum fails again + + } + else + { + // Set LED GREEN ON + } + } +} + +///////////////////////////////////////////////////////////////////////////////////////////////// +// Function name : ProcessAutomaticInterrupts +// Description : +// Return type : void +///////////////////////////////////////////////////////////////////////////////////////////////// +void ProcessAutomaticInterrupts() +{ + uint16_t status = 0; + auto_irq = send_single_PT2000_SPI_Cmd(READ, main_Interrupt_register_part1, 0x00) & 0x003F; // since this register is latched on first IRQ need to check if other occured + // ERROR uc0ch1 + if ((auto_irq & 0x1) == 1) // Error occurred on uc0ch1 + { + status = send_single_PT2000_SPI_Cmd(READ, ch1_status_reg_uc0, 0x00); // Read Status register 105h uc0ch1 to check which injector failed + if ((status & 0x1) == 1) // INJ1 fails b0 at 1 + { + inj1_error++; + AutoErrStatus = AutoErr(INJ1); // Check which fault happened + if (inj1_error > auto_retry) // Shutdown INJ1 + { + send_single_PT2000_SPI_Cmd(WRITE, ch1_ctrl_reg_uc0, 0x40); // Clear the fault by writing the control register b6 + flag_start1_fail = 1; // Put start1 flag high in order to stop Start1 pulse + } + else + { + send_single_PT2000_SPI_Cmd(WRITE, ch1_ctrl_reg_uc0, 0x40); // Clear the fault by writing the control register b6 + } + } + if ((status & 0x2) == 2) // INJ2 fails b0 at 1 + { + inj2_error++; + AutoErrStatus = AutoErr(INJ2); // Check which fault happened + if (inj2_error > auto_retry) // Shutdown INJ1 + { + send_single_PT2000_SPI_Cmd(WRITE, ch1_ctrl_reg_uc0, 0x40); // Clear the fault by writing the control register b6 + flag_start2_fail = 1; // Put start1 flag high in order to stop Start2 pulse + } + else + { + send_single_PT2000_SPI_Cmd(WRITE, ch1_ctrl_reg_uc0, 0x40); // Clear the fault by writing the control register b6 + } + } + } + + // ERROR uc1ch1 + auto_irq = send_single_PT2000_SPI_Cmd(READ, main_Interrupt_register_part1, 0x00) & 0x003F; // since this register is latched on first IRQ need to check if other occured + if ((auto_irq & 0x2) == 1) // Error occurred on uc1ch1 + { + status = send_single_PT2000_SPI_Cmd(READ, ch1_status_reg_uc1, 0x00); // Read Status register 1 to check which injector failed + if ((status & 0x1) == 1) // INJ3 fails b0 at 1 + { + inj3_error++; + AutoErrStatus = AutoErr(INJ3); // Check which fault happened + if (inj3_error > auto_retry) // Shutdown INJ1 + { + send_single_PT2000_SPI_Cmd(WRITE, ch1_ctrl_reg_uc1, 0x40); // Clear the fault by writing the control register + flag_start3_fail = 1; // Put start1 flag high in order to stop Start3 pulse + } + else + { + send_single_PT2000_SPI_Cmd(WRITE, ch1_ctrl_reg_uc1, 0x40); // Clear the fault by writing the control register b6 + } + } + if ((status & 0x2) == 2) // INJ4 fails b0 at 1 + { + inj4_error++; + AutoErrStatus = AutoErr(INJ4); // Check which fault happened + if (inj4_error > auto_retry) // Shutdown INJ1 + { + send_single_PT2000_SPI_Cmd(WRITE, ch1_ctrl_reg_uc1, 0x40); // Clear the fault by writing the control register + flag_start4_fail = 1; // Put start1 flag high in order to stop Start4 pulse + } + else + { + send_single_PT2000_SPI_Cmd(WRITE, ch1_ctrl_reg_uc1, 0x40); // Clear the fault by writing the control register b6 + } + } + } + + // ERROR uc1ch2 + auto_irq = send_single_PT2000_SPI_Cmd(READ, main_Interrupt_register_part1, 0x00) & 0x003F; // since this register is latched on first IRQ need to check if other occured + if ((auto_irq & 0x4) == 1) // Error occurred on uc0ch2 + { + status = send_single_PT2000_SPI_Cmd(READ, ch2_status_reg_uc0, 0x00); // Read Status register to check which injector failed + if ((status & 0x1) == 1) // INJ5 fails b0 at 1 + { + inj5_error++; + AutoErrStatus = AutoErr(INJ5); // Check which fault happened + if (inj5_error > auto_retry) // Shutdown INJ5 + { + send_single_PT2000_SPI_Cmd(WRITE, ch2_ctrl_reg_uc0, 0x40); // Clear the fault by writing the control register + flag_start5_fail = 1; // Put start1 flag high in order to stop Start5 pulse + } + else + { + send_single_PT2000_SPI_Cmd(WRITE, ch2_ctrl_reg_uc0, 0x40); // Clear the fault by writing the control register b6 + } + } + if ((status & 0x2) == 2) // INJ6 fails b0 at 1 + { + inj6_error++; + AutoErrStatus = AutoErr(INJ6); // Check which fault happened + if (inj6_error > auto_retry) // Shutdown INJ6 + { + send_single_PT2000_SPI_Cmd(WRITE, ch2_ctrl_reg_uc0, 0x40); // Clear the fault by writing the control register + flag_start6_fail = 1; // Put start1 flag high in order to stop Start6 pulse + } + else + { + send_single_PT2000_SPI_Cmd(WRITE, ch2_ctrl_reg_uc0, 0x40); // Clear the fault by writing the control register b6 + } + } + } + + // ERROR uc0ch3 + auto_irq = send_single_PT2000_SPI_Cmd(READ, main_Interrupt_register_part1, 0x00) & 0x003F; // since this register is latched on first IRQ need to check if other occured + if ((auto_irq & 0x10) == 1) // Error occurred on uc0ch3 + { + status = send_single_PT2000_SPI_Cmd(READ, ch3_status_reg_uc0, 0x00); // Read Status register to check which injector failed + if ((status & 0x1) == 1) // FP fails b0 at 1 + { + fp_error++; + AutoErrStatus = AutoErr(FP); // Check which fault happened + if (fp_error > auto_retry) // Shutdown FP + { + send_single_PT2000_SPI_Cmd(WRITE, ch3_ctrl_reg_uc0, 0x40); // Clear the fault by writing the control register + flag_start7_fail = 1; // Put start1 flag high in order to stop Start7 pulse + } + else + { + send_single_PT2000_SPI_Cmd(WRITE, ch3_ctrl_reg_uc0, 0x40); // Clear the fault by writing the control register b6 + } + } + } +} + +///////////////////////////////////////////////////////////////////////////////////////////////// +// Function name : ProcessSoftwareInterrupts +// Description : REad interrupt reg to detect whihc ucore fails. This reg is latch so need read it after clearing each +// to make sure that none of them are in the queue. This behavior also depends on how microcode is written +// Return type : void +///////////////////////////////////////////////////////////////////////////////////////////////// +void ProcessSoftwareInterrupts() +{ + uint16_t status = 0; + sw_irq = send_single_PT2000_SPI_Cmd(READ, main_Interrupt_register_part1, 0x00) & 0x3F00; // since this register is latched on first IRQ need to check if other occured + if ((sw_irq & 0x100) == 0x100) // Error occurred on uc0ch1 + { + status = send_single_PT2000_SPI_Cmd(READ, ch1_status_reg_uc0, 0x00); // Read Status register 105h uc0ch1 to check which injector failed + if ((status & 0x1) == 1) // INJ1 fails b0 at 1 + { + inj1_error++; + if (inj1_error > sw_retry) // Shutdown INJ1 + { + send_single_PT2000_SPI_Cmd(WRITE, ch1_ctrl_reg_uc0, 0x1A0); // Clear the fault by writing the control register + flag_start1_fail = 1; // Put start1 flag high in order to stop Start1 pulse + } + else + { + send_single_PT2000_SPI_Cmd(WRITE, ch1_ctrl_reg_uc0, 0x1A0); // Clear the fault by writing the control register b578 + } + } + if ((status & 0x2) == 0x2) // INJ2 fails b1 at 1 + { + inj2_error++; + if (inj2_error > sw_retry) // Shutdown INJ2 + { + send_single_PT2000_SPI_Cmd(WRITE, ch1_ctrl_reg_uc0, 0x1A0); // Clear the fault by writing the control register + flag_start2_fail = 1; // Put start1 flag high in order to stop Start2 pulse + } + else + { + // Set LED GREEN ON + send_single_PT2000_SPI_Cmd(WRITE, ch1_ctrl_reg_uc0, 0x1A0); // Clear the fault by writing the control register b578 + } + } + } // End uc0ch1 + + sw_irq = send_single_PT2000_SPI_Cmd(READ, main_Interrupt_register_part1, 0x00) & 0x3F00; // since this register is latched on first IRQ need to check if other occured + if ((sw_irq & 0x200) == 0x200) // Error occurred on uc1ch1 + { + status = send_single_PT2000_SPI_Cmd(READ, ch1_status_reg_uc1, 0x00); // Read Status register to check which injector failed + if ((status & 0x1) == 1) // INJ3 fails b0 at 1 + { + inj3_error++; + if (inj3_error > sw_retry) // Shutdown INJ3 + { + send_single_PT2000_SPI_Cmd(WRITE, ch1_ctrl_reg_uc1, 0x1A0); // Clear the fault by writing the control register + flag_start3_fail = 1; // Put start1 flag high in order to stop Start3 pulse + } + else + { + send_single_PT2000_SPI_Cmd(WRITE, ch1_ctrl_reg_uc1, 0x1A0); // Clear the fault by writing the control register + } + } + if ((status & 0x2) == 0x2) // INJ4 fails b1 at 1 + { + inj4_error++; + if (inj4_error > sw_retry) // Shutdown INJ4 + { + send_single_PT2000_SPI_Cmd(WRITE, ch1_ctrl_reg_uc1, 0x1A0); // Clear the fault by writing the control register + flag_start4_fail = 1; // Put start1 flag high in order to stop Start4 pulse + } + else + { + send_single_PT2000_SPI_Cmd(WRITE, ch1_ctrl_reg_uc1, 0x1A0); // Clear the fault by writing the control register b578 + } + } + } // End uc1ch1 + + sw_irq = send_single_PT2000_SPI_Cmd(READ, main_Interrupt_register_part1, 0x00) & 0x3F00; // since this register is latched on first IRQ need to check if other occured + if ((sw_irq & 0x400) == 0x400) // Error occurred on uc0ch2 + { + status = send_single_PT2000_SPI_Cmd(READ, ch2_status_reg_uc0, 0x00); // Read Status register to check which injector failed + + if ((status & 0x1) == 1) // INJ5 fails b0 at 1 + { + inj5_error++; + if (inj5_error > sw_retry) // Shutdown INJ5 + { + send_single_PT2000_SPI_Cmd(WRITE, ch2_ctrl_reg_uc0, 0x1A0); // Clear the fault by writing the control register + flag_start5_fail = 1; // Put start1 flag high in order to stop Start5 pulse + } + else + { + send_single_PT2000_SPI_Cmd(WRITE, ch2_ctrl_reg_uc0, 0x1A0); // Clear the fault by writing the control register b578 + } + } + if ((status & 0x2) == 0x2) // INJ6 fails b1 at 1 + { + inj6_error++; + if (inj6_error > sw_retry) // Shutdown INJ6 + { + send_single_PT2000_SPI_Cmd(WRITE, ch2_ctrl_reg_uc0, 0x1A0); // Clear the fault by writing the control register + flag_start6_fail = 1; // Put start1 flag high in order to stop Start6 pulse + } + else + { + send_single_PT2000_SPI_Cmd(WRITE, ch2_ctrl_reg_uc0, 0x1A0); // Clear the fault by writing the control register b578 + } + } + } // End uc0ch2 + + sw_irq = send_single_PT2000_SPI_Cmd(READ, main_Interrupt_register_part1, 0x00) & 0x3F00; // since this register is latched on first IRQ need to check if other occured + + if ((sw_irq & 0x1000) == 0x1000) // Error occurred on uc0ch3 + { + status = send_single_PT2000_SPI_Cmd(READ, ch3_status_reg_uc0, 0x00); // Read Status register to check which injector failed + + if ((status & 0x1) == 1) // FP fails b0 at 1 + { + fp_error++; + if (fp_error > sw_retry) // Shutdown INJ3 + { + send_single_PT2000_SPI_Cmd(WRITE, ch3_ctrl_reg_uc0, 0x1A0); // Clear the fault by writing the control register + flag_start7_fail = 1; // Put start1 flag high in order to stop Start7 pulse + } + else + { + send_single_PT2000_SPI_Cmd(WRITE, ch3_ctrl_reg_uc0, 0x1A0); // Clear the fault by writing the control register b578 + } + } + if ((status & 0x2) == 2) // DCDC fails b1 at 1 + { + dcdc_error++; + if (dcdc_error > sw_retry) // Shutdown DCDC and all injections + { + // ConfigureGPIO(PORTB, 8, PTB, GPIO_INPUT_DIRECTION); // START1 force as INPUT so low... + } + else + { + send_single_PT2000_SPI_Cmd(WRITE, ch1_ctrl_reg_uc1, 0x1A0); // Clear the fault by writing the control register b578 + } + } + } // End ch3 +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Function name : AutoErr +// Description : Will determine what kind of error happened and which HS LS failed +// Return type : HS number failed (0 means no fail), LS number failed (0 means no fail), type of error +/////////////////////////////////////////////////////////////////////////////////////////////////////////// +uint16_t AutoErr(unsigned char INJ) +{ + unsigned char HS_Boost_error=0; + unsigned char HS_Bat_error=0; + unsigned char LS_error=0; + unsigned int Fault_signature=0; //0 no fault, 1 Short to GND, 2 Short to Bat, 4 INJ Open, 8 MOSFET Open + unsigned int HSxData; + unsigned int LSxData; + _Bool FuelPump =0; + + switch (INJ) + { + case INJ1: // HS1 HS2 LS1 uc0ch1 + { + rxData = send_single_PT2000_SPI_Cmd(READ, diag_err_uc0ch1_part1, 0x00); + HSxData = rxData; + rxData = send_single_PT2000_SPI_Cmd(READ, diag_err_uc0ch1_part_3, 0x00); + LSxData = rxData; + break; + } + + case INJ2: // HS1 HS2 LS2 uc0ch1 + { + rxData = send_single_PT2000_SPI_Cmd(READ, diag_err_uc0ch1_part1, 0x00); + HSxData = rxData; + rxData = send_single_PT2000_SPI_Cmd(READ, diag_err_uc0ch1_part_3, 0x00); + LSxData = rxData >> 2; + break; + } + + case INJ3: // HS3 HS4 LS3 uc1ch1 + { + rxData = send_single_PT2000_SPI_Cmd(READ, diag_err_uc1ch1_part1, 0x00); + HSxData = rxData >> 6; + rxData = send_single_PT2000_SPI_Cmd(READ, diag_err_uc1ch1_part_3, 0x00); + LSxData = rxData >> 4; + break; + } + case INJ4: // HS3 HS4 LS4 uc1ch1 + { + rxData = send_single_PT2000_SPI_Cmd(READ, diag_err_uc1ch1_part1, 0x00); + HSxData = rxData >> 6; + + rxData = send_single_PT2000_SPI_Cmd(READ, diag_err_uc1ch1_part_3, 0x00); + LSxData = rxData >> 6; + break; + } + case INJ5: // HS5 HS6 LS5 uc0ch2 + { + rxData = send_single_PT2000_SPI_Cmd(READ, diag_err_uc0ch2_part1, 0x00); //Only HS5 accessible on this reg + HSxData = rxData >> 12; + rxData = send_single_PT2000_SPI_Cmd(READ, diag_err_uc0ch2_part2, 0x00); // read part2 to get HS6 + HSxData = HSxData + (rxData >> 3); // shift HS6 to have 6 bits with HS5 and HS6 same as other + + rxData = send_single_PT2000_SPI_Cmd(READ, diag_err_uc0ch2_part_3, 0x00); + LSxData = rxData >> 8; + break; + } + case FP: // HS7 LS7 uc0ch3 + { + rxData = send_single_PT2000_SPI_Cmd(READ, diag_err_uc0ch3_part2, 0x00); + HSxData = rxData >> 3; + + rxData = send_single_PT2000_SPI_Cmd(READ, diag_err_uc0ch3_part_3, 0x00); + LSxData = rxData >> 12; + + FuelPump=1; + break; + } + } + + // The following example is a simplified way to check which error occurred + + // HS Bat error + if ((HSxData & 0x4) == 0x4) // HSx was ON when fault occurred + { + if ((HSxData & 0x1) != 0) // VDS should be 0 if no error + { + HS_Bat_error = 1; + if ((HSxData & 0x2) != 0) Fault_signature = MOS_OPEN; // HS gate open or HS disconnected + else Fault_signature = GND_SHORT; // HS shorted to GND + } + } + else // HSx was OFF when fault occurred + { + if ((HSxData & 0x1) == 0) // VDS should be 1 if no error + { + HS_Bat_error = 1; + Fault_signature = INJ_OPEN; + } + } + + // HS Boost error + if (FuelPump==0) // no Boost FET on the fuel pump + { + if ((HSxData & 0x20) == 0x20) // HSx was ON when fault occurred + { + if ((HSxData & 0x8) != 0) // VDS should be 0 if no error + { + HS_Boost_error = 1; + if ((HSxData & 0x10) != 0) Fault_signature = MOS_OPEN; // MOSOPEN or shorted to VBAT(but this should be detected in idle) + else Fault_signature = GND_SHORT; // HS shorted to GND + } + } + else // HSx was OFF when fault occurred + { + if ((HSxData & 0x8) == 0) // VDS should be 1 if no error + { + HS_Boost_error = 1; + Fault_signature = INJ_OPEN; // This can also be gate HS Boost open + } + } + } + + //LS error + if ((LSxData & 0x2) == 0x2) // LSx was ON when fault occurred + { + if ((LSxData & 0x1) != 0) + { + LS_error = 1; // LSx failed short to Bat or Low side open + Fault_signature = MOS_OPEN; + } + } + else // LSx was OFF when fault occurred + { + if ((LSxData & 0x1) == 0) + { + LS_error = 1; // LSx failed Low side shorted to GND + Fault_signature = GND_SHORT; + } + } + + FuelPump=0; + AutoErrStatus = (HS_Boost_error) + (HS_Bat_error << 1) + (LS_error << 2) + (Fault_signature <<3) ; + return (AutoErrStatus); +} diff --git a/GDI-6ch/project/sample_code/PT2000_irq.h b/GDI-6ch/project/sample_code/PT2000_irq.h new file mode 100644 index 00000000..559ffb8b --- /dev/null +++ b/GDI-6ch/project/sample_code/PT2000_irq.h @@ -0,0 +1,79 @@ +/******************************************************************************* +* Example Code +* +* Copyright(C) 2025 NXP Semiconductors +* NXP Semiconductors Confidential and Proprietary +* +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* NXP products. This software is supplied "AS IS" without any warranties +* of any kind, and NXP Semiconductors and its licensor disclaim any and +* all warranties, express or implied, including all implied warranties of +* merchantability, fitness for a particular purpose and non-infringement of +* intellectual property rights. NXP Semiconductors assumes no responsibility +* or liability for the use of the software, conveys no license or rights +* under any patent, copyright, mask work right, or any other intellectual +* property rights in or to any products. NXP Semiconductors reserves the +* right to make changes in the software without notification. NXP +* Semiconductors also makes no representation or warranty that such +* application will be suitable for the specified use without further testing +* or modification. +* +* IN NO EVENT WILL NXP SEMICONDUCTORS BE LIABLE, WHETHER IN CONTRACT, +* TORT, OR OTHERWISE, FOR ANY INCIDENTAL, SPECIAL, INDIRECT, CONSEQUENTIAL +* OR PUNITIVE DAMAGES, INCLUDING, BUT NOT LIMITED TO, DAMAGES FOR ANY +* LOSS OF USE, LOSS OF TIME, INCONVENIENCE, COMMERCIAL LOSS, OR LOST +* PROFITS, SAVINGS, OR REVENUES, TO THE FULL EXTENT SUCH MAY BE DISCLAIMED +* BY LAW. NXP SEMICONDUCTOR’S TOTAL LIABILITY FOR ALL COSTS, DAMAGES, +* CLAIMS, OR LOSSES WHATSOEVER ARISING OUT OF OR IN CONNECTION WITH THE +* SOFTWARE IS LIMITED TO THE AGGREGATE AMOUNT PAID BY YOU TO NXP SEMICONDUCTORS +* IN CONNECTION WITH THE SOFTWARE TO WHICH LOSSES OR DAMAGES ARE CLAIMED. +* +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' and its +* licensor's relevant copyrights in the software, without fee, provided +* that it is used in conjunction with NXP Semiconductors devices. This +* copyright, permission, and disclaimer notice must appear in all copies +* of this code. +*******************************************************************************/ + +/* + * PT2000_irq.h + * + * PT2000 Interrupt Header File + * + */ + +#ifndef PT2000_IRQ_H_ +#define PT2000_IRQ_H_ + +#include "stdint.h" + +//======================================================================================== +// extern Function Declarations +//======================================================================================== +extern void ProcessPT2000Interrupts(); +extern void ProcessDriverInterrupts(); +extern void ProcessAutomaticInterrupts(); +extern void ProcessSoftwareInterrupts(); +uint16_t AutoErr(unsigned char INJ); + +const typedef enum { + INJ1 = 1, + INJ2, + INJ3, + INJ4, + INJ5, + INJ6, + FP, +}INJ; + +#define NOFAULT 0 +#define GND_SHORT 1 +#define BAT_SHORT 2 +#define INJ_OPEN 4 +#define MOS_OPEN 8 + + + +#endif /* PT2000_IRQ_H_ */ diff --git a/GDI-6ch/project/sample_code/PT2000_spi_map.h b/GDI-6ch/project/sample_code/PT2000_spi_map.h new file mode 100644 index 00000000..73b8581c --- /dev/null +++ b/GDI-6ch/project/sample_code/PT2000_spi_map.h @@ -0,0 +1,283 @@ +/******************************************************************************* +* Example Code +* +* Copyright(C) 2025 NXP Semiconductors +* NXP Semiconductors Confidential and Proprietary +* +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* NXP products. This software is supplied "AS IS" without any warranties +* of any kind, and NXP Semiconductors and its licensor disclaim any and +* all warranties, express or implied, including all implied warranties of +* merchantability, fitness for a particular purpose and non-infringement of +* intellectual property rights. NXP Semiconductors assumes no responsibility +* or liability for the use of the software, conveys no license or rights +* under any patent, copyright, mask work right, or any other intellectual +* property rights in or to any products. NXP Semiconductors reserves the +* right to make changes in the software without notification. NXP +* Semiconductors also makes no representation or warranty that such +* application will be suitable for the specified use without further testing +* or modification. +* +* IN NO EVENT WILL NXP SEMICONDUCTORS BE LIABLE, WHETHER IN CONTRACT, +* TORT, OR OTHERWISE, FOR ANY INCIDENTAL, SPECIAL, INDIRECT, CONSEQUENTIAL +* OR PUNITIVE DAMAGES, INCLUDING, BUT NOT LIMITED TO, DAMAGES FOR ANY +* LOSS OF USE, LOSS OF TIME, INCONVENIENCE, COMMERCIAL LOSS, OR LOST +* PROFITS, SAVINGS, OR REVENUES, TO THE FULL EXTENT SUCH MAY BE DISCLAIMED +* BY LAW. NXP SEMICONDUCTOR’S TOTAL LIABILITY FOR ALL COSTS, DAMAGES, +* CLAIMS, OR LOSSES WHATSOEVER ARISING OUT OF OR IN CONNECTION WITH THE +* SOFTWARE IS LIMITED TO THE AGGREGATE AMOUNT PAID BY YOU TO NXP SEMICONDUCTORS +* IN CONNECTION WITH THE SOFTWARE TO WHICH LOSSES OR DAMAGES ARE CLAIMED. +* +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' and its +* licensor's relevant copyrights in the software, without fee, provided +* that it is used in conjunction with NXP Semiconductors devices. This +* copyright, permission, and disclaimer notice must appear in all copies +* of this code. +*******************************************************************************/ + +// +// PT2000_spi_map.h +// +// PT2000 SPI Register Addresses +// +// + +#ifndef PT2000_SPI_MAP_H_ +#define PT2000_SPI_MAP_H_ + +// PT2000 Channel 1 Register Addresses +#define ch1_flash_enable 0x100 +#define ch1_ctrl_reg_uc0 0x101 +#define ch1_ctrl_reg_uc1 0x102 +#define ch1_start_config_reg_part1 0x103 +#define ch1_start_config_reg_part2 0x104 +#define ch1_status_reg_uc0 0x105 +#define ch1_status_reg_uc1 0x106 +#define ch1_code_width 0x107 +#define ch1_checksum_h 0x108 +#define ch1_checksum_l 0x109 +#define ch1_uc0_entry_point 0x10A +#define ch1_uc1_entry_point 0x10B +#define ch1_diag_routine_addr 0x10C +#define ch1_driver_disabled_routine_addr 0x10D +#define ch1_sw_interrupt_routine_addr 0x10E +#define ch1_uc0_irq_status 0x10F +#define ch1_uc1_irq_status 0x110 +#define ch1_counter34_prescaler 0x111 +#define ch1_dac_rxtx_cr_config 0x112 +#define ch1_unlock_word 0x113 + +// PT2000 Channel 2 Register Addresses +#define ch2_flash_enable 0x120 +#define ch2_ctrl_reg_uc0 0x121 +#define ch2_ctrl_reg_uc1 0x122 +#define ch2_start_config_reg_part1 0x123 +#define ch2_start_config_reg_part2 0x124 +#define ch2_status_reg_uc0 0x125 +#define ch2_status_reg_uc1 0x126 +#define ch2_code_width 0x127 +#define ch2_checksum_h 0x128 +#define ch2_checksum_l 0x129 +#define ch2_uc0_entry_point 0x12A +#define ch2_uc1_entry_point 0x12B +#define ch2_diag_routine_addr 0x12C +#define ch2_driver_disabled_routine_addr 0x12D +#define ch2_sw_interrupt_routine_addr 0x12E +#define ch2_uc0_irq_status 0x12F +#define ch2_uc1_irq_status 0x130 +#define ch2_counter34_prescaler 0x131 +#define ch2_dac_rxtx_cr_config 0x132 +#define ch2_unlock_word 0x133 + +// PT2000 Channel 3 Register Addresses +#define ch3_flash_enable 0x140 +#define ch3_ctrl_reg_uc0 0x141 +#define ch3_ctrl_reg_uc1 0x142 +#define ch3_start_config_reg_part1 0x143 +#define ch3_start_config_reg_part2 0x144 +#define ch3_status_reg_uc0 0x145 +#define ch3_status_reg_uc1 0x146 +#define ch3_code_width 0x147 +#define ch3_checksum_h 0x148 +#define ch3_checksum_l 0x149 +#define ch3_uc0_entry_point 0x14A +#define ch3_uc1_entry_point 0x14B +#define ch3_diag_routine_addr 0x14C +#define ch3_driver_disabled_routine_addr 0x14D +#define ch3_sw_interrupt_routine_addr 0x14E +#define ch3_uc0_irq_status 0x14F +#define ch3_uc1_irq_status 0x150 +#define ch3_counter34_prescaler 0x151 +#define ch3_dac_rxtx_cr_config 0x152 +#define ch3_unlock_word 0x153 + +// PT2000 IO Register Addresses +#define io_fbk_sens_uc0_ch1_part1 0x154 +#define io_fbk_sens_uc0_ch1_part2 0x155 +#define io_fbk_sens_uc1_ch1_part1 0x156 +#define io_fbk_sens_uc1_ch1_part2 0x157 +#define io_fbk_sens_uc0_ch2_part1 0x158 +#define io_fbk_sens_uc0_ch2_part2 0x159 +#define io_fbk_sens_uc1_ch2_part1 0x15A +#define io_fbk_sens_uc1_ch2_part2 0x15B +#define io_fbk_sens_uc0_ch3_part1 0x15C +#define io_fbk_sens_uc0_ch3_part2 0x15D +#define io_fbk_sens_uc1_ch3_part1 0x15E +#define io_fbk_sens_uc1_ch3_part2 0x15F +#define io_out_acc_uc0_ch1 0x160 +#define io_out_acc_uc1_ch1 0x161 +#define io_out_acc_uc0_ch2 0x162 +#define io_out_acc_uc1_ch2 0x163 +#define io_out_acc_uc0_ch3 0x164 +#define io_out_acc_uc1_ch3 0x165 +#define io_cur_block_access_part1 0x166 +#define io_cur_block_access_part2 0x167 +#define io_cur_block_access_part_3 0x168 +#define io_fw_link 0x169 +#define io_fw_ext_req 0x16A +#define io_vds_thresholds_hs_part1 0x16B +#define io_vds_thresholds_hs_part2 0x16C +#define io_vsrc_thresholds_hs_part1 0x16D +#define io_vsrc_thresholds_hs_part2 0x16E +#define io_vds_thresholds_ls_part1 0x16F +#define io_vds_thresholds_ls_part2 0x170 +#define io_hs_slewrate 0x171 +#define io_ls_slewrate_part1 0x172 +#define io_ls_slewrate_part2 0x173 +#define io_offset_compensation12 0x174 +#define io_offset_compensation34 0x175 +#define io_offset_compensation56 0x176 +#define io_adc12_result 0x177 +#define io_adc34_result 0x178 +#define io_adc56_result 0x179 +#define io_current_filter12 0x17A +#define io_current_filter34 0x17B +#define io_current_filter5l5h 0x17C +#define io_current_filter6l6h 0x17D +#define io_current_filter5neg6neg 0x17E +#define io_boost_dac 0x17F +#define io_boost_dac_access 0x180 +#define io_boost_filter 0x181 +#define io_vds7_dcdc_config 0x182 +#define io_vds8_dcdc_config 0x183 +#define io_batt_result 0x184 +#define io_dac12_value 0x185 +#define io_dac34_value 0x186 +#define io_dac5l5h_value 0x187 +#define io_dac5neg_value 0x188 +#define io_dac6l6h_value 0x189 +#define io_dac6neg_value 0x18A +#define io_hs_bias_config 0x18B +#define io_ls_bias_config 0x18C +#define io_bootstrap_charged 0x18D +#define io_bootstrap_timer 0x18E +#define io_hs1_ls_act 0x18F +#define io_hs2_ls_act 0x190 +#define io_hs3_ls_act 0x191 +#define io_hs4_ls_act 0x192 +#define io_hs5_ls_act 0x193 +#define io_hs6_ls_act 0x194 +#define io_hs7_ls_act 0x195 +#define io_dac_settling_time 0x196 +#define io_oa_out1_config 0x197 +#define io_oa_out2_config 0x198 +#define io_oa_out3_config 0x199 + +// PT2000 Main Register Addresses +#define main_Clock_Prescaler 0x1A0 +#define main_Flags_Direction 0x1A1 +#define main_Flags_Polarity 0x1A2 +#define main_Flags_source 0x1A3 +#define main_compensation_prescaler 0x1A4 +#define main_Driver_Config_part1 0x1A5 +#define main_Driver_Config_part2 0x1A6 +#define main_PLL_config 0x1A7 +#define main_Backup_Clock_Status 0x1A8 +#define main_SPI_config 0x1A9 +#define main_Trace_start 0x1AA +#define main_Trace_stop 0x1AB +#define main_Trace_config 0x1AC +#define main_Device_lock 0x1AD +#define main_Reset_behavior 0x1AE +#define main_Device_unlock 0x1AF +#define main_Global_reset_code_part1 0x1B0 +#define main_Global_reset_code_part2 0x1B1 +#define main_Driver_Status 0x1B2 +#define main_SPI_error_code 0x1B3 +#define main_Interrupt_register_part1 0x1B4 +#define main_Interrupt_register_part2 0x1B5 +#define main_Device_Identifier 0x1B6 +#define main_Reset_source 0x1B7 +#define main_BIST_interface 0x1BD + +// PT2000 Diag Register Addresses +#define diag_ls1_diag_config1 0x1C0 +#define diag_ls1_diag_config2 0x1C1 +#define diag_ls1_output_config 0x1C2 +#define diag_ls2_diag_config1 0x1C3 +#define diag_ls2_diag_config2 0x1C4 +#define diag_ls2_output_config 0x1C5 +#define diag_ls3_diag_config1 0x1C6 +#define diag_ls3_diag_config2 0x1C7 +#define diag_ls3_output_config 0x1C8 +#define diag_ls4_diag_config1 0x1C9 +#define diag_ls4_diag_config2 0x1CA +#define diag_ls4_output_config 0x1CB +#define diag_ls5_diag_config1 0x1CC +#define diag_ls5_diag_config2 0x1CD +#define diag_ls5_output_config 0x1CE +#define diag_ls6_diag_config1 0x1CF +#define diag_ls6_diag_config2 0x1D0 +#define diag_ls6_output_config 0x1D1 +#define diag_ls7_diag_config1 0x1D2 +#define diag_ls7_diag_config2 0x1D3 +#define diag_ls7_output_config 0x1D4 +#define diag_ls8_diag_config1 0x1D5 +#define diag_ls8_diag_config2 0x1D6 +#define diag_ls8_output_config 0x1D7 +#define diag_hs1_diag_config1 0x1D8 +#define diag_hs1_diag_config2 0x1D9 +#define diag_hs1_output_config 0x1DA +#define diag_hs2_diag_config1 0x1DB +#define diag_hs2_diag_config2 0x1DC +#define diag_hs2_output_config 0x1DD +#define diag_hs3_diag_config1 0x1DE +#define diag_hs3_diag_config2 0x1DF +#define diag_hs3_output_config 0x1E0 +#define diag_hs4_diag_config1 0x1E1 +#define diag_hs4_diag_config2 0x1E2 +#define diag_hs4_output_config 0x1E3 +#define diag_hs5_diag_config1 0x1E4 +#define diag_hs5_diag_config2 0x1E5 +#define diag_hs5_output_config 0x1E6 +#define diag_hs6_diag_config1 0x1E7 +#define diag_hs6_diag_config2 0x1E8 +#define diag_hs6_output_config 0x1E9 +#define diag_hs7_diag_config1 0x1EA +#define diag_hs7_diag_config2 0x1EB +#define diag_hs7_output_config 0x1EC +#define diag_err_uc0ch1_part1 0x1ED +#define diag_err_uc0ch1_part2 0x1EE +#define diag_err_uc0ch1_part_3 0x1EF +#define diag_err_uc1ch1_part1 0x1F0 +#define diag_err_uc1ch1_part2 0x1F1 +#define diag_err_uc1ch1_part_3 0x1F2 +#define diag_err_uc0ch2_part1 0x1F3 +#define diag_err_uc0ch2_part2 0x1F4 +#define diag_err_uc0ch2_part_3 0x1F5 +#define diag_err_uc1ch2_part1 0x1F6 +#define diag_err_uc1ch2_part2 0x1F7 +#define diag_err_uc1ch2_part_3 0x1F8 +#define diag_err_uc0ch3_part1 0x1F9 +#define diag_err_uc0ch3_part2 0x1FA +#define diag_err_uc0ch3_part_3 0x1FB +#define diag_err_uc1ch3_part1 0x1FC +#define diag_err_uc1ch3_part2 0x1FD +#define diag_err_uc1ch3_part_3 0x1FE +#define diag_diagnostics_option 0x1FF + +#define selection_register 0x3FF + +#endif // PT2000_SPI_MAP_H_ diff --git a/GDI-6ch/project/sample_code/lpspi.c b/GDI-6ch/project/sample_code/lpspi.c new file mode 100644 index 00000000..b2264ed6 --- /dev/null +++ b/GDI-6ch/project/sample_code/lpspi.c @@ -0,0 +1,88 @@ +/******************************************************************************* +* Example Code +* +* Copyright(C) 2025 NXP Semiconductors +* NXP Semiconductors Confidential and Proprietary +* +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* NXP products. This software is supplied "AS IS" without any warranties +* of any kind, and NXP Semiconductors and its licensor disclaim any and +* all warranties, express or implied, including all implied warranties of +* merchantability, fitness for a particular purpose and non-infringement of +* intellectual property rights. NXP Semiconductors assumes no responsibility +* or liability for the use of the software, conveys no license or rights +* under any patent, copyright, mask work right, or any other intellectual +* property rights in or to any products. NXP Semiconductors reserves the +* right to make changes in the software without notification. NXP +* Semiconductors also makes no representation or warranty that such +* application will be suitable for the specified use without further testing +* or modification. +* +* IN NO EVENT WILL NXP SEMICONDUCTORS BE LIABLE, WHETHER IN CONTRACT, +* TORT, OR OTHERWISE, FOR ANY INCIDENTAL, SPECIAL, INDIRECT, CONSEQUENTIAL +* OR PUNITIVE DAMAGES, INCLUDING, BUT NOT LIMITED TO, DAMAGES FOR ANY +* LOSS OF USE, LOSS OF TIME, INCONVENIENCE, COMMERCIAL LOSS, OR LOST +* PROFITS, SAVINGS, OR REVENUES, TO THE FULL EXTENT SUCH MAY BE DISCLAIMED +* BY LAW. NXP SEMICONDUCTOR’S TOTAL LIABILITY FOR ALL COSTS, DAMAGES, +* CLAIMS, OR LOSSES WHATSOEVER ARISING OUT OF OR IN CONNECTION WITH THE +* SOFTWARE IS LIMITED TO THE AGGREGATE AMOUNT PAID BY YOU TO NXP SEMICONDUCTORS +* IN CONNECTION WITH THE SOFTWARE TO WHICH LOSSES OR DAMAGES ARE CLAIMED. +* +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' and its +* licensor's relevant copyrights in the software, without fee, provided +* that it is used in conjunction with NXP Semiconductors devices. This +* copyright, permission, and disclaimer notice must appear in all copies +* of this code. +*******************************************************************************/ + +/* + * lpspi.c + * + * SPI Source File + * + */ + +#include "stddef.h" +#include "lpspi.h" + +// SPI transfer constants +const unsigned short TIMEOUT = 1000; +const size_t transferByteCount = 2U; + +// SPI transmit and receive buffers +unsigned char masterDataSend[2]; +unsigned char masterDataReceive[2]; + + +///////////////////////////////////////////////////////////////////////////////////////////////// +// Function name : init_SPI +// Description : Initializes the SPI interface +// Return type : void +// Argument : void +///////////////////////////////////////////////////////////////////////////////////////////////// +void init_SPI(void) +{ + // Add code to initialize the SPI interface +} + +///////////////////////////////////////////////////////////////////////////////////////////////// +// Function name : send_16bit_SPI +// Description : Sends a 16 bit SPI word to the device +// Return type : uint16_t - Data received from the device +// Argument : unsigned short data16 - Data to send to the device +///////////////////////////////////////////////////////////////////////////////////////////////// +unsigned short send_16bit_SPI(unsigned short data16) +{ + unsigned short rxData = 0; + + // Send data from master + masterDataSend[0] = data16 & 0xFF; + masterDataSend[1] = (data16 >> 8) & 0xFF; + + // Add code to send a SPI word + + rxData = ((masterDataReceive[1] << 8) & 0xFF00) | masterDataReceive[0]; + return rxData; +} diff --git a/GDI-6ch/project/sample_code/lpspi.h b/GDI-6ch/project/sample_code/lpspi.h new file mode 100644 index 00000000..53f0af24 --- /dev/null +++ b/GDI-6ch/project/sample_code/lpspi.h @@ -0,0 +1,66 @@ +/******************************************************************************* +* Example Code +* +* Copyright(C) 2025 NXP Semiconductors +* NXP Semiconductors Confidential and Proprietary +* +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* NXP products. This software is supplied "AS IS" without any warranties +* of any kind, and NXP Semiconductors and its licensor disclaim any and +* all warranties, express or implied, including all implied warranties of +* merchantability, fitness for a particular purpose and non-infringement of +* intellectual property rights. NXP Semiconductors assumes no responsibility +* or liability for the use of the software, conveys no license or rights +* under any patent, copyright, mask work right, or any other intellectual +* property rights in or to any products. NXP Semiconductors reserves the +* right to make changes in the software without notification. NXP +* Semiconductors also makes no representation or warranty that such +* application will be suitable for the specified use without further testing +* or modification. +* +* IN NO EVENT WILL NXP SEMICONDUCTORS BE LIABLE, WHETHER IN CONTRACT, +* TORT, OR OTHERWISE, FOR ANY INCIDENTAL, SPECIAL, INDIRECT, CONSEQUENTIAL +* OR PUNITIVE DAMAGES, INCLUDING, BUT NOT LIMITED TO, DAMAGES FOR ANY +* LOSS OF USE, LOSS OF TIME, INCONVENIENCE, COMMERCIAL LOSS, OR LOST +* PROFITS, SAVINGS, OR REVENUES, TO THE FULL EXTENT SUCH MAY BE DISCLAIMED +* BY LAW. NXP SEMICONDUCTOR’S TOTAL LIABILITY FOR ALL COSTS, DAMAGES, +* CLAIMS, OR LOSSES WHATSOEVER ARISING OUT OF OR IN CONNECTION WITH THE +* SOFTWARE IS LIMITED TO THE AGGREGATE AMOUNT PAID BY YOU TO NXP SEMICONDUCTORS +* IN CONNECTION WITH THE SOFTWARE TO WHICH LOSSES OR DAMAGES ARE CLAIMED. +* +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' and its +* licensor's relevant copyrights in the software, without fee, provided +* that it is used in conjunction with NXP Semiconductors devices. This +* copyright, permission, and disclaimer notice must appear in all copies +* of this code. +*******************************************************************************/ + +/* + * lpspi.h + * + * SPI Header File + * + */ + +#ifndef LPSPI_H_ +#define LPSPI_H_ + +#include "stdbool.h" + +#define LPSPI_0 0 +#define READ true +#define WRITE false + +unsigned short SPIread; +extern bool flag_spi; +extern unsigned char masterDataSend[2]; +extern unsigned char masterDataReceive[2]; + +void init_SPI(void); +void Lpspi0_Send(unsigned char spiMsg); +unsigned short send_16bit_SPI(unsigned short data16); + + +#endif /* LPSPI_H_ */ diff --git a/GDI-6ch/project/sample_code/main.c b/GDI-6ch/project/sample_code/main.c new file mode 100644 index 00000000..5aef5bdf --- /dev/null +++ b/GDI-6ch/project/sample_code/main.c @@ -0,0 +1,135 @@ +/******************************************************************************* +* Example Code +* +* Copyright(C) 2025 NXP Semiconductors +* NXP Semiconductors Confidential and Proprietary +* +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* NXP products. This software is supplied "AS IS" without any warranties +* of any kind, and NXP Semiconductors and its licensor disclaim any and +* all warranties, express or implied, including all implied warranties of +* merchantability, fitness for a particular purpose and non-infringement of +* intellectual property rights. NXP Semiconductors assumes no responsibility +* or liability for the use of the software, conveys no license or rights +* under any patent, copyright, mask work right, or any other intellectual +* property rights in or to any products. NXP Semiconductors reserves the +* right to make changes in the software without notification. NXP +* Semiconductors also makes no representation or warranty that such +* application will be suitable for the specified use without further testing +* or modification. +* +* IN NO EVENT WILL NXP SEMICONDUCTORS BE LIABLE, WHETHER IN CONTRACT, +* TORT, OR OTHERWISE, FOR ANY INCIDENTAL, SPECIAL, INDIRECT, CONSEQUENTIAL +* OR PUNITIVE DAMAGES, INCLUDING, BUT NOT LIMITED TO, DAMAGES FOR ANY +* LOSS OF USE, LOSS OF TIME, INCONVENIENCE, COMMERCIAL LOSS, OR LOST +* PROFITS, SAVINGS, OR REVENUES, TO THE FULL EXTENT SUCH MAY BE DISCLAIMED +* BY LAW. NXP SEMICONDUCTOR’S TOTAL LIABILITY FOR ALL COSTS, DAMAGES, +* CLAIMS, OR LOSSES WHATSOEVER ARISING OUT OF OR IN CONNECTION WITH THE +* SOFTWARE IS LIMITED TO THE AGGREGATE AMOUNT PAID BY YOU TO NXP SEMICONDUCTORS +* IN CONNECTION WITH THE SOFTWARE TO WHICH LOSSES OR DAMAGES ARE CLAIMED. +* +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' and its +* licensor's relevant copyrights in the software, without fee, provided +* that it is used in conjunction with NXP Semiconductors devices. This +* copyright, permission, and disclaimer notice must appear in all copies +* of this code. +*******************************************************************************/ + +/* + * main implementation: use this 'C' sample to create your own application + * + */ + +#include "main.h" +#include "PT2000_irq.h" +#include "PT2000_spi_map.h" + +//======================================================================================== +// Global Variables +//======================================================================================== +const int sw_retry = 5; +const int auto_retry = 2; +int result = 0; +int iprof_counter = 0; +int count = 0; +int drv_int_counter = 0; +volatile char states = 0; +volatile int flag_IRQB = 0; +volatile int flag_EOI = 0; +volatile int seq_counter = 0; +unsigned short rxData = 0; +unsigned short cksys_missing_error = 0; +unsigned short cksys_missing = 0; +unsigned short drv_irq = 0; +unsigned short checksum_irq =0; +unsigned short drv_status = 0; +unsigned short spi_irq = 0; +unsigned short auto_irq = 0; +unsigned short sw_irq = 0; +unsigned short inj1_error = 0; +unsigned short inj2_error = 0; +unsigned short inj3_error = 0; +unsigned short inj4_error = 0; +unsigned short inj5_error = 0; +unsigned short inj6_error = 0; +unsigned short fp_error = 0; +unsigned short dcdc_error = 0; + +///////////////////////////////////////////////////////////////////////////////////////////////// +// Function name : main +// Description : Program entry point. Programs the PT2000 and runs an injection +// sequence. +// Return type : int +// Argument : void +///////////////////////////////////////////////////////////////////////////////////////////////// +int main(void) +{ + // Initialize the hardware + init_CLOCK(); + init_GPIO(); + init_SPI(); + init_ADC(); + PWM_1MHz(); + + // Reset the PT2000 device + SET_RESETB_LOW; + delay(1); + SET_RESETB_HIGH; + delay100us(1); // wait for the PLL time to lock + + if (ID_Check () == 0) { return -1; }; // Check if SPI works and that device is the good one + if (CLK_check() == 0) { return -1; }; // Check if 1MHz CLK is properly connected + if (DRVEN_check() == 0) { return -1; }; // Check if DRVEN monitoring works using SPI register 1B2h + if (BIST_check(1,1) == 0) { return -1; }; // Run LBIST and MBIST + if (OA_path_check(1,1,1) == 0) { return -1; }; // Check OA pin connection to MCU ADC + + // Program the device + ProgramDevice(); + + if (Checksum_check() == 0) { return -1; }; // Checksum pass or fail + if (Driver_Status_Init() == 0) { return -1; }; // Check if all regulators are at ON + if (Bootstrap_check() == 0) { return -1; }; // Check if bootstrap caps are charged (should be done after 35ms) + + // Add code to enable interrupts + + if (Read_VbatADC () < 6) { return -1; }; // Check if SPI works and that device is the good one + + SET_DRVEN_HIGH; + delay(100); // Wait before sending start pulse to let DCDC reach 65V + + for (;;) + { + + //======================================================================================== + // START OF IRQB CHECK + //======================================================================================== + if (flag_IRQB == 1) + { + ProcessPT2000Interrupts(); + } + } // End of for loop (main) + + return 0; +} // end of main diff --git a/GDI-6ch/project/sample_code/main.h b/GDI-6ch/project/sample_code/main.h new file mode 100644 index 00000000..5fc8a2bf --- /dev/null +++ b/GDI-6ch/project/sample_code/main.h @@ -0,0 +1,54 @@ +/******************************************************************************* +* Example Code +* +* Copyright(C) 2025 NXP Semiconductors +* NXP Semiconductors Confidential and Proprietary +* +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* NXP products. This software is supplied "AS IS" without any warranties +* of any kind, and NXP Semiconductors and its licensor disclaim any and +* all warranties, express or implied, including all implied warranties of +* merchantability, fitness for a particular purpose and non-infringement of +* intellectual property rights. NXP Semiconductors assumes no responsibility +* or liability for the use of the software, conveys no license or rights +* under any patent, copyright, mask work right, or any other intellectual +* property rights in or to any products. NXP Semiconductors reserves the +* right to make changes in the software without notification. NXP +* Semiconductors also makes no representation or warranty that such +* application will be suitable for the specified use without further testing +* or modification. +* +* IN NO EVENT WILL NXP SEMICONDUCTORS BE LIABLE, WHETHER IN CONTRACT, +* TORT, OR OTHERWISE, FOR ANY INCIDENTAL, SPECIAL, INDIRECT, CONSEQUENTIAL +* OR PUNITIVE DAMAGES, INCLUDING, BUT NOT LIMITED TO, DAMAGES FOR ANY +* LOSS OF USE, LOSS OF TIME, INCONVENIENCE, COMMERCIAL LOSS, OR LOST +* PROFITS, SAVINGS, OR REVENUES, TO THE FULL EXTENT SUCH MAY BE DISCLAIMED +* BY LAW. NXP SEMICONDUCTOR’S TOTAL LIABILITY FOR ALL COSTS, DAMAGES, +* CLAIMS, OR LOSSES WHATSOEVER ARISING OUT OF OR IN CONNECTION WITH THE +* SOFTWARE IS LIMITED TO THE AGGREGATE AMOUNT PAID BY YOU TO NXP SEMICONDUCTORS +* IN CONNECTION WITH THE SOFTWARE TO WHICH LOSSES OR DAMAGES ARE CLAIMED. +* +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' and its +* licensor's relevant copyrights in the software, without fee, provided +* that it is used in conjunction with NXP Semiconductors devices. This +* copyright, permission, and disclaimer notice must appear in all copies +* of this code. +*******************************************************************************/ + +/* + * main.h + * + * Main Header File + * + */ + +#ifndef MAIN_H_ +#define MAIN_H_ + +#include "lpspi.h" +#include "PT2000.h" +#include "system.h" + +#endif /* MAIN_H_ */ diff --git a/GDI-6ch/project/sample_code/system.c b/GDI-6ch/project/sample_code/system.c new file mode 100644 index 00000000..80277068 --- /dev/null +++ b/GDI-6ch/project/sample_code/system.c @@ -0,0 +1,206 @@ +/******************************************************************************* +* Example Code +* +* Copyright(C) 2025 NXP Semiconductors +* NXP Semiconductors Confidential and Proprietary +* +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* NXP products. This software is supplied "AS IS" without any warranties +* of any kind, and NXP Semiconductors and its licensor disclaim any and +* all warranties, express or implied, including all implied warranties of +* merchantability, fitness for a particular purpose and non-infringement of +* intellectual property rights. NXP Semiconductors assumes no responsibility +* or liability for the use of the software, conveys no license or rights +* under any patent, copyright, mask work right, or any other intellectual +* property rights in or to any products. NXP Semiconductors reserves the +* right to make changes in the software without notification. NXP +* Semiconductors also makes no representation or warranty that such +* application will be suitable for the specified use without further testing +* or modification. +* +* IN NO EVENT WILL NXP SEMICONDUCTORS BE LIABLE, WHETHER IN CONTRACT, +* TORT, OR OTHERWISE, FOR ANY INCIDENTAL, SPECIAL, INDIRECT, CONSEQUENTIAL +* OR PUNITIVE DAMAGES, INCLUDING, BUT NOT LIMITED TO, DAMAGES FOR ANY +* LOSS OF USE, LOSS OF TIME, INCONVENIENCE, COMMERCIAL LOSS, OR LOST +* PROFITS, SAVINGS, OR REVENUES, TO THE FULL EXTENT SUCH MAY BE DISCLAIMED +* BY LAW. NXP SEMICONDUCTOR’S TOTAL LIABILITY FOR ALL COSTS, DAMAGES, +* CLAIMS, OR LOSSES WHATSOEVER ARISING OUT OF OR IN CONNECTION WITH THE +* SOFTWARE IS LIMITED TO THE AGGREGATE AMOUNT PAID BY YOU TO NXP SEMICONDUCTORS +* IN CONNECTION WITH THE SOFTWARE TO WHICH LOSSES OR DAMAGES ARE CLAIMED. +* +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' and its +* licensor's relevant copyrights in the software, without fee, provided +* that it is used in conjunction with NXP Semiconductors devices. This +* copyright, permission, and disclaimer notice must appear in all copies +* of this code. +*******************************************************************************/ + +#include "system.h" + +const unsigned long DELAY_FACTOR = 1599; // This needs to be set for the specific MCU being used +const unsigned long DELAY_FACTOR2 = 159; +extern volatile int flag_IRQB; + +///////////////////////////////////////////////////////////////////////////////////////////////// +// Function name : init_ADC +// Description : Initializes the ADC subsystem. +// Return type : void +// Argument : void +///////////////////////////////////////////////////////////////////////////////////////////////// +void init_ADC(void) +{ + // Add MCU specific ADC initialization code here +} + +///////////////////////////////////////////////////////////////////////////////////////////////// +// Function name : read_ADC +// Description : Read from ADC module 0 +// Return type : uint16_t +// Argument : unsigned char channel +///////////////////////////////////////////////////////////////////////////////////////////////// +unsigned short read_ADC(unsigned char channel) +{ + unsigned short result = 0; + + // Add MCU specific ADC read code here + + return result; +} + +///////////////////////////////////////////////////////////////////////////////////////////////// +// Function name : read_ADC1 +// Description : Read from ADC module 1 +// Return type : uint16_t +// Argument : unsigned char channel +///////////////////////////////////////////////////////////////////////////////////////////////// +unsigned short read_ADC1(unsigned char channel) +{ + unsigned short result = 0; + + // Add MCU specific ADC read code here + + return result; +} + + +///////////////////////////////////////////////////////////////////////////////////////////////// +// Function name : init_CLOCK +// Description : Initializes the system clock +// Return type : void +// Argument : void +///////////////////////////////////////////////////////////////////////////////////////////////// +void init_CLOCK(void) +{ + // Add code here to initialize the system clock +} + + +///////////////////////////////////////////////////////////////////////////////////////////////// +// Function name : delay +// Description : Delays for the specified number of milliseconds. +// Return type : void +// Argument : unsigned long msDelay +///////////////////////////////////////////////////////////////////////////////////////////////// +void delay(unsigned long msDelay) // RICARDO HELP TO GET SOMETHING ACCURATE +{ + unsigned int i = 0; + + for (i = 0; i < (msDelay * DELAY_FACTOR); i++); +} + +///////////////////////////////////////////////////////////////////////////////////////////////// +// Function name : delay100us +// Description : Delays for the specified number of 100us increments. +// Return type : void +// Argument : unsigned long delay +///////////////////////////////////////////////////////////////////////////////////////////////// +void delay100us(unsigned long delay) // RICARDO HELP TO GET SOMETHING ACCURATE IN 1us or 10us not 100us +{ + unsigned int i = 0; + + for (i = 0; i < (delay * DELAY_FACTOR2); i++); +} + +///////////////////////////////////////////////////////////////////////////////////////////////// +// Function name : init_GPIO +// Description : Initializes the GPIO pins +// Return type : void +// Argument : void +///////////////////////////////////////////////////////////////////////////////////////////////// +void init_GPIO(void) +{ + // Add GPIO initialization code here +} + +///////////////////////////////////////////////////////////////////////////////////////////////// +// Function name : set_reset_pin +// Description : Sets the state of the PT2000 reset pin (HIGH or LOW) +// Return type : void +// Argument : int state +///////////////////////////////////////////////////////////////////////////////////////////////// +void set_reset_pin(int state) +{ + if (state == HIGH) + { + // Set the reset GPIO pin high + SET_RESETB_HIGH; + } + else if (state == LOW) + { + // Set the reset GPIO pin low + SET_RESETB_LOW; + } +} + +///////////////////////////////////////////////////////////////////////////////////////////////// +// Function name : set_drven_pin +// Description : Sets the state of the Drive Enable pin (HIGH or LOW) +// Return type : void +// Argument : int state +///////////////////////////////////////////////////////////////////////////////////////////////// +void set_drven_pin(int state) +{ + if (state == HIGH) + { + // Set the drive enable GPIO pin high + SET_DRVEN_HIGH; + } + else if (state == LOW) + { + // Set the drive enable GPIO pin low + SET_DRVEN_LOW; + } +} + +///////////////////////////////////////////////////////////////////////////////////////////////// +// Function name : PWM_1MHz +// Description : Initialize the 1MHz PWM signal +// Return type : void +// Argument : void +///////////////////////////////////////////////////////////////////////////////////////////////// +void PWM_1MHz(void) +{ + // Add code to initialize the 1MHz PWM signal +} + +///////////////////////////////////////////////////////////////////////////////////////////////// +// Function name : PORTA_IRQHandler +// Description : This interrupt is enabled when PT2000 IRQB pin is low +// Return type : void +// Argument : void +///////////////////////////////////////////////////////////////////////////////////////////////// +void PORTA_IRQHandler(void) //IRQB +{ + char ISF_status = 0; // Add code to get interrupt status + + // Off_sequence(); Optional since PT2000 will shutdown output by itself + + if (ISF_status == PTA3) + { + flag_IRQB = 1; + + // Add code to clear interrupt + } +} diff --git a/GDI-6ch/project/sample_code/system.h b/GDI-6ch/project/sample_code/system.h new file mode 100644 index 00000000..f7e27255 --- /dev/null +++ b/GDI-6ch/project/sample_code/system.h @@ -0,0 +1,88 @@ +/******************************************************************************* +* Example Code +* +* Copyright(C) 2025 NXP Semiconductors +* NXP Semiconductors Confidential and Proprietary +* +* Software that is described herein is for illustrative purposes only +* which provides customers with programming information regarding the +* NXP products. This software is supplied "AS IS" without any warranties +* of any kind, and NXP Semiconductors and its licensor disclaim any and +* all warranties, express or implied, including all implied warranties of +* merchantability, fitness for a particular purpose and non-infringement of +* intellectual property rights. NXP Semiconductors assumes no responsibility +* or liability for the use of the software, conveys no license or rights +* under any patent, copyright, mask work right, or any other intellectual +* property rights in or to any products. NXP Semiconductors reserves the +* right to make changes in the software without notification. NXP +* Semiconductors also makes no representation or warranty that such +* application will be suitable for the specified use without further testing +* or modification. +* +* IN NO EVENT WILL NXP SEMICONDUCTORS BE LIABLE, WHETHER IN CONTRACT, +* TORT, OR OTHERWISE, FOR ANY INCIDENTAL, SPECIAL, INDIRECT, CONSEQUENTIAL +* OR PUNITIVE DAMAGES, INCLUDING, BUT NOT LIMITED TO, DAMAGES FOR ANY +* LOSS OF USE, LOSS OF TIME, INCONVENIENCE, COMMERCIAL LOSS, OR LOST +* PROFITS, SAVINGS, OR REVENUES, TO THE FULL EXTENT SUCH MAY BE DISCLAIMED +* BY LAW. NXP SEMICONDUCTOR’S TOTAL LIABILITY FOR ALL COSTS, DAMAGES, +* CLAIMS, OR LOSSES WHATSOEVER ARISING OUT OF OR IN CONNECTION WITH THE +* SOFTWARE IS LIMITED TO THE AGGREGATE AMOUNT PAID BY YOU TO NXP SEMICONDUCTORS +* IN CONNECTION WITH THE SOFTWARE TO WHICH LOSSES OR DAMAGES ARE CLAIMED. +* +* Permission to use, copy, modify, and distribute this software and its +* documentation is hereby granted, under NXP Semiconductors' and its +* licensor's relevant copyrights in the software, without fee, provided +* that it is used in conjunction with NXP Semiconductors devices. This +* copyright, permission, and disclaimer notice must appear in all copies +* of this code. +*******************************************************************************/ + +#ifndef SYSTEM_H_ +#define SYSTEM_H_ + +#define LOW 0 +#define HIGH 1 + +extern void init_GPIO(void); +extern void set_reset_pin(int state); +extern void set_drven_pin(int state); + +#define SET_RESETB_HIGH // Add code to set GPIO pin +#define SET_RESETB_LOW // Add code to set GPIO pin +#define SET_DRVEN_HIGH // Add code to set GPIO pin +#define SET_DRVEN_LOW // Add code to set GPIO pin +#define SET_START1_HIGH // Add code to set GPIO pin +#define SET_START1_LOW // Add code to set GPIO pin +#define SET_START2_HIGH // Add code to set GPIO pin +#define SET_START2_LOW // Add code to set GPIO pin +#define SET_START3_HIGH // Add code to set GPIO pin +#define SET_START3_LOW // Add code to set GPIO pin +#define SET_START4_HIGH // Add code to set GPIO pin +#define SET_START4_LOW // Add code to set GPIO pin +#define SET_START5_HIGH // Add code to set GPIO pin +#define SET_START5_LOW // Add code to set GPIO pin +#define SET_START6_HIGH // Add code to set GPIO pin +#define SET_START6_LOW // Add code to set GPIO pin +#define SET_START7_HIGH // Add code to set GPIO pin +#define SET_START7_LOW // Add code to set GPIO pin +#define SET_START8_HIGH // Add code to set GPIO pin +#define SET_START8_LOW // Add code to set GPIO pin + +#define PTC12 0x1000 +#define PTC13 0x2000 +#define PTA3 0x8 +#define Flag1 0x100 + +void init_ADC(void); +unsigned short read_ADC(unsigned char channel); +unsigned short read_ADC1(unsigned char channel); + +void init_CLOCK(void); + +void delay(unsigned long msDelay); +void delay100us(unsigned long delay); + +extern void PWM_1MHz (void); +extern void InputCaptureTimer_init(void); + +#endif /* SYSTEM_H_ */