summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--example/apps/icssg_pwm/firmware/src/AM654x_PRU.cmd83
-rw-r--r--example/apps/icssg_pwm/firmware/src/Makefile131
-rw-r--r--example/apps/icssg_pwm/firmware/src/firmware_version.h80
-rw-r--r--example/apps/icssg_pwm/firmware/src/icssg_iep_pwm.h307
-rw-r--r--example/apps/icssg_pwm/firmware/src/iepPwm.c2770
-rw-r--r--example/apps/icssg_pwm/firmware/src/iepPwm.h247
-rw-r--r--example/apps/icssg_pwm/firmware/src/iepPwmFwRegs.c136
-rw-r--r--example/apps/icssg_pwm/firmware/src/iepPwmFwRegs.h83
-rw-r--r--example/apps/icssg_pwm/firmware/src/iepPwmHwRegs.h76
-rw-r--r--example/apps/icssg_pwm/firmware/src/main.c174
-rw-r--r--example/apps/icssg_pwm/firmware/src/resource_table_empty.h72
11 files changed, 4159 insertions, 0 deletions
diff --git a/example/apps/icssg_pwm/firmware/src/AM654x_PRU.cmd b/example/apps/icssg_pwm/firmware/src/AM654x_PRU.cmd
new file mode 100644
index 0000000..a89c42c
--- /dev/null
+++ b/example/apps/icssg_pwm/firmware/src/AM654x_PRU.cmd
@@ -0,0 +1,83 @@
1/****************************************************************************/
2/* AM654x_PRU.cmd */
3/* Copyright (c) 2019 Texas Instruments Incorporated */
4/* */
5/* Description: This file is a linker command file that can be used for */
6/* linking PRU programs built with the C compiler and */
7/* the resulting .out file on an AM57xx device. */
8/****************************************************************************/
9
10-cr /* Link using C conventions */
11-stack 0x100
12
13/* Specify the System Memory Map */
14MEMORY
15{
16 PAGE 0:
17 PRU_IMEM : org = 0x00000000 len = 0x00004000 /* 16kB ICSSG_PRU Instruction RAM */
18
19 PAGE 1:
20
21 /* RAM */
22
23 PRU_DMEM_0_1_LOW : org = 0x00000000 len = 0x00001000 /* 4kB ICSSG Data RAM 0_1 for PRU*/
24 PRU_DMEM_0_1_HIGH : org = 0x00001000 len = 0x00001000 /* 4kB ICSSG Data RAM 0_1 for RTU*/
25 PRU_DMEM_1_0 : org = 0x00002000 len = 0x00002000 /* 8kB ICSSG Data RAM 1_0 */
26
27 PAGE 2:
28 PRU_SHAREDMEM : org = 0x00010000 len = 0x00010000 CREGISTER=28 /* 64kB Shared RAM */
29
30 /* Peripherals */
31
32 PRU_CFG : org = 0x00026000 len = 0x00000120 CREGISTER=4
33
34 RSVD0 : org = 0x00020000 len = 0x00001504 CREGISTER=0
35 RSVD1 : org = 0x48040000 len = 0x0000005C CREGISTER=1
36 RSVD2 : org = 0x4802A000 len = 0x000000D8 CREGISTER=2
37 RSVD3 : org = 0x00030000 len = 0x00000060 CREGISTER=3
38 RSVD5 : org = 0x48060000 len = 0x00000300 CREGISTER=5
39 RSVD6 : org = 0x48030000 len = 0x000001A4 CREGISTER=6
40 RSVD7 : org = 0x00028000 len = 0x00000038 CREGISTER=7
41 RSVD8 : org = 0x46000000 len = 0x00000100 CREGISTER=8
42 RSVD9 : org = 0x4A100000 len = 0x0000128C CREGISTER=9
43 RSVD10 : org = 0x48318000 len = 0x00000100 CREGISTER=10
44 RSVD11 : org = 0x48022000 len = 0x00000088 CREGISTER=11
45 RSVD12 : org = 0x48024000 len = 0x00000088 CREGISTER=12
46 RSVD13 : org = 0x48310000 len = 0x00000100 CREGISTER=13
47 RSVD14 : org = 0x481CC000 len = 0x000001E8 CREGISTER=14
48 RSVD15 : org = 0x481D0000 len = 0x000001E8 CREGISTER=15
49 RSVD16 : org = 0x481A0000 len = 0x000001A4 CREGISTER=16
50 RSVD17 : org = 0x4819C000 len = 0x000000D8 CREGISTER=17
51 RSVD18 : org = 0x48300000 len = 0x000002C4 CREGISTER=18
52 RSVD19 : org = 0x48302000 len = 0x000002C4 CREGISTER=19
53 RSVD20 : org = 0x48304000 len = 0x000002C4 CREGISTER=20
54 RSVD21 : org = 0x00032400 len = 0x00000100 CREGISTER=21
55 RSVD22 : org = 0x480C8000 len = 0x00000140 CREGISTER=22
56 RSVD23 : org = 0x480CA000 len = 0x00000880 CREGISTER=23
57 RSVD26 : org = 0x0002E000 len = 0x0000031C CREGISTER=26
58 RSVD27 : org = 0x00032000 len = 0x00000100 CREGISTER=27
59 RSVD29 : org = 0x49000000 len = 0x00001098 CREGISTER=29
60}
61
62/* Specify the sections allocation into memory */
63SECTIONS {
64 /* Forces _c_int00 to the start of PRU IRAM. Not necessary when loading
65 an ELF file, but useful when loading a binary */
66 .text:_c_int00* > 0x0, PAGE 0
67
68 .text > PRU_IMEM, PAGE 0
69 .stack > PRU_DMEM_0_1_LOW, PAGE 1
70 .bss > PRU_DMEM_0_1_LOW, PAGE 1
71 .cio > PRU_DMEM_0_1_LOW, PAGE 1
72 .data > PRU_DMEM_0_1_LOW, PAGE 1
73 .switch > PRU_DMEM_0_1_LOW, PAGE 1
74 .sysmem > PRU_DMEM_0_1_LOW, PAGE 1
75 .cinit > PRU_DMEM_0_1_LOW, PAGE 1
76 .rodata > PRU_DMEM_0_1_LOW, PAGE 1
77 .rofardata > PRU_DMEM_0_1_LOW, PAGE 1
78 .farbss > PRU_DMEM_0_1_LOW, PAGE 1
79 .fardata > PRU_DMEM_0_1_LOW, PAGE 1
80
81 .initDataFwRegs > 0x0, PAGE 1
82 .resource_table > 0x200, PAGE 1
83}
diff --git a/example/apps/icssg_pwm/firmware/src/Makefile b/example/apps/icssg_pwm/firmware/src/Makefile
new file mode 100644
index 0000000..d2d41b6
--- /dev/null
+++ b/example/apps/icssg_pwm/firmware/src/Makefile
@@ -0,0 +1,131 @@
1# PRU_CGT environment variable must point to the TI PRU code gen tools directory. E.g.:
2#(Desktop Linux) export PRU_CGT=/path/to/pru/code/gen/tools/ti-cgt-pru_2.x.y
3#(Windows) set PRU_CGT=C:/path/to/pru/code/gen/tools/ti-cgt-pru_2.x.y
4#(ARM Linux*) export PRU_CGT=/usr/share/ti/cgt-pru
5#
6# *ARM Linux also needs to create a symbolic link to the /usr/bin/ directory in
7# order to use the same Makefile
8#(ARM Linux) ln -s /usr/bin/ /usr/share/ti/cgt-pru/bin
9
10ifndef PRU_CGT
11define ERROR_BODY
12
13*******************************************************************************
14PRU_CGT environment variable is not set. Examples given:
15(Desktop Linux) export PRU_CGT=/path/to/pru/code/gen/tools/ti-cgt-pru_2.1.2
16(Windows) set PRU_CGT=C:/path/to/pru/code/gen/tools/ti-cgt-pru_2.1.2
17(ARM Linux*) export PRU_CGT=/usr/share/ti/cgt-pru
18
19*ARM Linux also needs to create a symbolic link to the /usr/bin/ directory in
20order to use the same Makefile
21(ARM Linux) ln -s /usr/bin/ /usr/share/ti/cgt-pru/bin
22*******************************************************************************
23
24endef
25$(error $(ERROR_BODY))
26endif
27
28MKFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST)))
29CURRENT_DIR := $(notdir $(patsubst %/,%,$(dir $(MKFILE_PATH))))
30PROJ_NAME=pwm
31
32LINKER_COMMAND_FILE=./AM654x_PRU.cmd
33
34LIBS=
35
36PDK_INSTALL_DIR ?= $(PRSDK_INSTALL_DIR)/pdk_am65xx_1_0_5/packages
37
38INCLUDE=--include_path=$(PDK_INSTALL_DIR)
39STACK_SIZE=0x100
40HEAP_SIZE=0x100
41GEN_DIR=gen
42
43CDEFINES = -DSOC_AM65XX
44
45#Common compiler and linker flags (Defined in 'PRU Optimizing C/C++ Compiler User's Guide)
46#CFLAGS=-v3 -o2 --display_error_number --endian=little --hardware_mac=on --asm_directory=$(GEN_DIR) --obj_directory=$(GEN_DIR) --pp_directory=$(GEN_DIR) -ppd -ppa
47CFLAGS= $(CDEFINES) -v3 -o2 --display_error_number --endian=little --hardware_mac=on --asm_directory=$(GEN_DIR) --obj_directory=$(GEN_DIR) --pp_directory=$(GEN_DIR) -ppd -ppa
48#CFLAGS= $(CDEFINES) -v3 -o2 --opt_for_speed=0 --display_error_number --endian=little --hardware_mac=on --asm_directory=$(GEN_DIR) --obj_directory=$(GEN_DIR) --pp_directory=$(GEN_DIR) -ppd -ppa
49#CFLAGS= $(CDEFINES) -v3 -g --display_error_number --endian=little --hardware_mac=on --asm_directory=$(GEN_DIR) --obj_directory=$(GEN_DIR) --pp_directory=$(GEN_DIR) -ppd -ppa
50
51#Linker flags (Defined in 'PRU Optimizing C/C++ Compiler User's Guide)
52#LFLAGS=--reread_libs --warn_sections --stack_size=$(STACK_SIZE) --heap_size=$(HEAP_SIZE) --entry_point=SDDF_ENTRY
53LFLAGS=--reread_libs --warn_sections --stack_size=$(STACK_SIZE) --heap_size=$(HEAP_SIZE)
54
55TARGET=$(GEN_DIR)/$(PROJ_NAME)_array.h
56PRU_IMAGE_PREFIX=pru_$(PROJ_NAME)_image
57
58EXE=$(GEN_DIR)/$(PROJ_NAME).out
59MAP=$(GEN_DIR)/$(PROJ_NAME).map
60OBJECTS=$(patsubst %.asm,$(GEN_DIR)/%.object,$(wildcard *.asm))
61OBJECTS+=$(patsubst %.c,$(GEN_DIR)/%.object,$(wildcard *.c))
62
63
64all: printStart $(TARGET) printEnd
65
66printStart:
67 @echo ''
68 @echo '************************************************************'
69 @echo 'Building project: $(PROJ_NAME)'
70
71printEnd:
72 @echo ''
73 @echo 'Output files can be found in the "$(GEN_DIR)" directory'
74 @echo ''
75 @echo 'Finished building project: $(PROJ_NAME)'
76 @echo '************************************************************'
77 @echo ''
78
79
80# Invoke the hex format converter to translate the .out file to a C header file
81$(TARGET): $(EXE)
82 @echo ''
83 @echo 'Building image header file: $@'
84 @echo 'Invoking: PRU Hex Format Converter'
85 $(PRU_CGT)/bin/hexpru --array --array:name_prefix=$(PRU_IMAGE_PREFIX) $(EXE)
86 mv $(subst .h,.c,$(PROJ_NAME)_array.h) $(TARGET)
87 @echo 'Finished image header file: $@'
88
89# Invokes the linker (-z flag) to make the .out file
90$(EXE): $(OBJECTS) $(LINKER_COMMAND_FILE)
91 @echo ''
92 @echo 'Building executable: $@'
93 @echo 'Invoking: PRU Linker'
94 $(PRU_CGT)/bin/clpru $(CFLAGS) -z -i$(PRU_CGT)/lib -i$(PRU_CGT)/include $(LFLAGS) -o $(EXE) $(OBJECTS) -m$(MAP) $(LINKER_COMMAND_FILE) --library=libc.a $(LIBS)
95 @echo 'Finished building executable: $@'
96
97# Invokes the compiler on all assembly files in the directory to create the object files
98$(GEN_DIR)/%.object: %.asm
99 @mkdir -p $(GEN_DIR)
100 @echo ''
101 @echo 'Building file: $<'
102 @echo 'Invoking: PRU Compiler'
103 $(PRU_CGT)/bin/clpru --include_path=$(PRU_CGT)/include $(INCLUDE) $(CFLAGS) -fe $@ $<
104
105# Invokes the compiler on all c files in the directory to create the object files
106$(GEN_DIR)/%.object: %.c
107 @mkdir -p $(GEN_DIR)
108 @echo ''
109 @echo 'Building file: $<'
110 @echo 'Invoking: PRU Compiler'
111 $(PRU_CGT)/bin/clpru -k --include_path=$(PRU_CGT)/include $(INCLUDE) $(CFLAGS) -fe $@ $<
112
113.PHONY: all clean
114
115# Remove the $(GEN_DIR) directory
116clean:
117 @echo ''
118 @echo '************************************************************'
119 @echo 'Cleaning project: $(PROJ_NAME)'
120 @echo ''
121 @echo 'Removing files in the "$(GEN_DIR)" directory'
122 @rm -rf $(GEN_DIR)
123 @rm -f $(subst .h,.c,$(PROJ_NAME)_array.h)
124 @echo ''
125 @echo 'Finished cleaning project: $(PROJ_NAME)'
126 @echo '************************************************************'
127 @echo ''
128
129# Includes the dependencies that the compiler creates (-ppd and -ppa flags)
130-include $(OBJECTS:%.object=%.pp)
131
diff --git a/example/apps/icssg_pwm/firmware/src/firmware_version.h b/example/apps/icssg_pwm/firmware/src/firmware_version.h
new file mode 100644
index 0000000..5aac062
--- /dev/null
+++ b/example/apps/icssg_pwm/firmware/src/firmware_version.h
@@ -0,0 +1,80 @@
1/*
2 * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
3 *
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the
15 * distribution.
16 *
17 * * Neither the name of Texas Instruments Incorporated nor the names of
18 * its contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34#ifndef _FIRMWARE_VERSION_H_
35#define _FIRMWARE_VERSION_H_
36
37/*
38 ICSSG_PWM_FIRMWARE_DEVICE_VERSION:
39 bit31..24 Device type
40*/
41#define FIRMWARE_DEVICE_ICSS_REV1 0
42#define FIRMWARE_DEVICE_ICSS_REV2 1
43
44/*
45 bit23..0 protocol type
46*/
47#define FIRMWARE_PROTOCOL_CONTROL_CLASS 0x02
48#define FIRMWARE_PROTOCOL_TYPE_ICSSG_PWM_VERSION1 0x01
49
50/*
51 bit31 release or internal version
52*/
53#define FIRMWARE_VERSION_INTERNAL 1
54#define FIRMWARE_VERSION_RELEASE 0
55/*
56 bit30..24 major version number, for major IP changes.
57*/
58#define FIRMWARE_VERSION_MAJOR 0x01
59/*
60 bit23..16 minor version number, for feature additions to firmware.
61*/
62#define FIRMWARE_VERSION_MINOR 0x00
63/*
64 bit15..0 build number, for all other minor changes.
65*/
66#define FIRMWARE_VERSION_BUILD 0x00
67
68/* macro for indicating type of firmware and device */
69#define ICSSG_PWM_FIRMWARE_TYPE ((FIRMWARE_DEVICE_ICSS_REV2 << 24) | (FIRMWARE_PROTOCOL_CONTROL_CLASS << 8) | (FIRMWARE_PROTOCOL_TYPE_ICSSG_PWM_VERSION1 << 0))
70
71/* macro for indicating version of firmware */
72#define ICSSG_PWM_FIRMWARE_VERSION ((FIRMWARE_VERSION_RELEASE << 31) | (FIRMWARE_VERSION_MAJOR << 24) | (FIRMWARE_VERSION_MINOR << 16) | (FIRMWARE_VERSION_BUILD << 0))
73
74/* Bitmap for various feature supported in firmware */
75#define ICSSG_PWM_FIRMWARE_FEATURE ( 0x00001998 ) /* Firmware Feature - support for 24 PWMs, 12 IEP0 PWMs, 12 IEP1 PWMs */
76
77/* Offset to an extended feature structure for future use. */
78#define ICSSG_PWM_FIRMWARE_EXTENDED_FEATURE_PTR ( 0 ) /* Firmware Extended Feature - Reserved for future use */
79
80#endif /* _FIRMWARE_VERSION_H_ */
diff --git a/example/apps/icssg_pwm/firmware/src/icssg_iep_pwm.h b/example/apps/icssg_pwm/firmware/src/icssg_iep_pwm.h
new file mode 100644
index 0000000..c85bb89
--- /dev/null
+++ b/example/apps/icssg_pwm/firmware/src/icssg_iep_pwm.h
@@ -0,0 +1,307 @@
1/*
2 * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
3 *
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the
15 * distribution.
16 *
17 * * Neither the name of Texas Instruments Incorporated nor the names of
18 * its contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34#ifndef _ICSSG_IEP_PWM_H_
35#define _ICSSG_IEP_PWM_H_
36
37/* ICSSG INTC events */
38/* Compile-time Host event for IEP0 CMP0 event, pr0_pru_mst_intr[2]_intr_req,
39 ideally Host would provide this to FW */
40#define TRIGGER_HOST_EVT ( 18 ) /* 2+16 */
41
42/*
43 * Firmware global registers
44 */
45
46/* Firmware Information Registers */
47#define ICSSG_IEPPWM_FW_MAGIC_NUMBER_ADDR ( 0x0000 )
48#define ICSSG_IEPPWM_FW_TYPE_ADDR ( 0x0004 )
49#define ICSSG_IEPPWM_FW_VERSION_ADDR ( 0x0008 )
50#define ICSSG_IEPPWM_FW_FEATURE_ADDR ( 0x000C )
51#define ICSSG_IEPPWM_FW_EXT_FEATURE_ADDR ( 0x0010 )
52
53/* PWM Control/Status Registers */
54#define ICSSG_IEPPWM_PWM_CTRL_ADDR ( 0x0014 )
55#define ICSSG_IEPPWM_PWM_STAT_ADDR ( 0x0018 )
56
57/*
58 * Firmware global register bit fields
59 */
60/* Firmware Magic Number */
61#define FW_MAGIC_NUM_BYTE0_MASK ( 0xF )
62#define FW_MAGIC_NUM_BYTE1_MASK ( 0xF )
63#define FW_MAGIC_NUM_BYTE2_MASK ( 0xF )
64#define FW_MAGIC_NUM_BYTE3_MASK ( 0xF )
65#define FW_MAGIC_NUM_MN_BYTE0_SHIFT ( 0 )
66#define FW_MAGIC_NUM_MN_BYTE0_MASK ( FW_MAGIC_NUM_BYTE0_MASK << FW_MAGIC_NUM_MN_BYTE0_SHIFT )
67#define FW_MAGIC_NUM_MN_BYTE1_SHIFT ( 8 )
68#define FW_MAGIC_NUM_MN_BYTE1_MASK ( FW_MAGIC_NUM_BYTE1_MASK << FW_MAGIC_NUM_MN_BYTE1_SHIFT )
69#define FW_MAGIC_NUM_MN_BYTE2_SHIFT ( 16 )
70#define FW_MAGIC_NUM_MN_BYTE2_MASK ( FW_MAGIC_NUM_BYTE2_MASK << FW_MAGIC_NUM_MN_BYTE2_SHIFT )
71#define FW_MAGIC_NUM_MN_BYTE3_SHIFT ( 24 )
72#define FW_MAGIC_NUM_MN_BYTE3_MASK ( FW_MAGIC_NUM_BYTE3_MASK << FW_MAGIC_NUM_MN_BYTE3_SHIFT )
73
74/* Firmware Type */
75#define FW_PROTOCOL_TYPE_VERSION_MASK ( 0xF )
76#define FW_PROTOCOL_TYPE_MASK ( 0xFF )
77#define FW_ICSS_VERSION_MASK ( 0xF )
78#define FW_TYPE_FW_PROTOCOL_TYPE_VERSION_SHIFT ( 0 )
79#define FW_TYPE_FW_PROTOCOL_TYPE_VERSION_MASK ( FW_PROTOCOL_TYPE_VERSION_MASK << FW_TYPE_FW_PROTOCOL_TYPE_VERSION_SHIFT )
80#define FW_TYPE_FW_PROTOCOL_TYPE_SHIFT ( 8 )
81#define FW_TYPE_FW_PROTOCOL_TYPE_MASK ( FW_PROTOCOL_TYPE_MASK << FW_TYPE_FW_PROTOCOL_TYPE_SHIFT )
82#define FW_TYPE_FW_ICSS_VERSION_SHIFT ( 24 )
83#define FW_TYPE_FW_ICSS_VERSION_MASK ( FW_ICSS_VERSION_MASK << FW_TYPE_FW_ICSS_VERSION_SHIFT )
84
85/* Firmware Version */
86#define FW_VER_BUILD_MASK ( 0xF )
87#define FW_VER_MINOR_MASK ( 0xFF )
88#define FW_VER_MAJOR_MASK ( 0x7F )
89#define FW_REL_OR_INT_VER_MASK ( 0x1 )
90#define FW_VERSION_FW_VER_BUILD_SHIFT ( 0 )
91#define FW_VERSION_FW_VER_BUILD_MASK ( FW_VER_BUILD_MASK << FW_VERSION_FW_VER_BUILD_SHIFT )
92#define FW_VERSION_FW_VER_MINOR_SHIFT ( 8 )
93#define FW_VERSION_FW_VER_MINOR_MASK ( FW_VER_MINOR_MASK << FW_VERSION_FW_VER_MINOR_SHIFT )
94#define FW_VERSION_FW_VER_MAJOR_SHIFT ( 24 )
95#define FW_VERSION_FW_VER_MAJOR_MASK ( FW_VER_MAJOR_MASK << FW_VERSION_FW_VER_MAJOR_SHIFT )
96#define FW_VERSION_FW_REL_OR_INT_VER_SHIFT ( 31 )
97#define FW_VERSION_FW_REL_OR_INT_VER_MASK ( FW_REL_OR_INT_VER_MASK << FW_VERSION_FW_REL_OR_INT_VER_SHIFT )
98
99/* Firmware Feature */
100#define FW_NUM_PWMS_MASK ( 0x1F )
101#define FW_IEP0_NUM_PWMS_MASK ( 0xF )
102#define FW_IEP1_NUM_PWMS_MASK ( 0xF )
103#define FW_FEATURE_FW_NUM_PWMS_SHIFT ( 0 )
104#define FW_FEATURE_FW_NUM_PWMS_MASK ( FW_NUM_PWMS_MASK << FW_FEATURE_FW_NUM_PWMS_SHIFT )
105#define FW_FEATURE_FW_IEP0_NUM_PWMS_SHIFT ( 5 )
106#define FW_FEATURE_FW_IEP0_NUM_PWMS_MASK ( FW_IEP0_NUM_PWMS_MASK << FW_FEATURE_FW_IEP0_NUM_PWMS_SHIFT )
107#define FW_FEATURE_FW_IEP1_NUM_PWMS_SHIFT ( 9 )
108#define FW_FEATURE_FW_IEP1_NUM_PWMS_MASK ( FW_IEP1_NUM_PWMS_MASK << FW_FEATURE_FW_IEP1_NUM_PWMS_SHIFT )
109
110/* PWM_CTRL */
111#define BF_PWM_EN_DISABLE ( 0 ) /* PWM Enable bit field disable setting */
112#define BF_PWM_EN_ENABLE ( 1 ) /* PWM Enable bit field enable setting */
113#define BF_PWM_GBL_EN_DISABLE ( 0 ) /* Global Enable bit field disabled setting */
114#define BF_PWM_GBL_EN_ENABLE ( 1 ) /* Global Enable bit field enabled setting */
115#define PWM_EN_MASK ( 0x1 )
116#define IEP_PWM_GBL_EN_MASK ( 0x1 )
117#define PWM_CTRL_PWM_EN_SHIFT ( 0 )
118#define PWM_CTRL_PWM_EN_MASK ( PWM_EN_MASK << PWM_CTRL_PWM_EN_SHIFT )
119#define PWM_CTRL_IEP0_PWM_GBL_EN_SHIFT ( 1 )
120#define PWM_CTRL_IEP0_PWM_GBL_EN_MASK ( IEP_PWM_GBL_EN_MASK << PWM_CTRL_IEP0_PWM_GBL_EN_SHIFT )
121#define PWM_CTRL_IEP1_PWM_GBL_EN_SHIFT ( 2 )
122#define PWM_CTRL_IEP1_PWM_GBL_EN_MASK ( IEP_PWM_GBL_EN_MASK << PWM_CTRL_IEP1_PWM_GBL_EN_SHIFT )
123
124/* PWM_STAT */
125#define BF_PWM_EN_ACK_DISABLE ( 0 ) /* PWM Enable ACK bit field disabled setting */
126#define BF_PWM_EN_ACK_ENABLE ( 1 ) /* PWM Enable ACK bit field enabled setting */
127#define BF_PWM_GBL_EN_ACK_DISABLE ( 0 ) /* Global Enable ACK bit field disabled setting */
128#define BF_PWM_GBL_EN_ACK_ENABLE ( 1 ) /* Global Enable ACK bit field enabled setting */
129#define BF_PWM_FW_INIT_UNINIT ( 0 ) /* FW initialized bit field uninitialized setting */
130#define BF_PWM_FW_INIT_INIT ( 1 ) /* FW initialized bit field initialized setting */
131#define PWM_EN_ACK_MASK ( 0x1 )
132#define IEP_PWM_GBL_EN_ACK_MASK ( 0x1 )
133#define FW_INIT_MASK ( 0x1 )
134#define PWM_STAT_PWM_EN_ACK_SHIFT ( 0 )
135#define PWM_STAT_PWM_EN_ACK_MASK ( PWM_EN_ACK_MASK << PWM_STAT_PWM_EN_ACK_SHIFT )
136#define PWM_STAT_IEP0_PWM_GBL_EN_ACK_SHIFT ( 1 )
137#define PWM_STAT_IEP0_PWM_GBL_EN_ACK_MASK ( IEP_PWM_GBL_EN_ACK_MASK << PWM_STAT_IEP0_PWM_GBL_EN_ACK_SHIFT )
138#define PWM_STAT_IEP1_PWM_GBL_EN_ACK_SHIFT ( 2 )
139#define PWM_STAT_IEP1_PWM_GBL_EN_ACK_MASK ( IEP_PWM_GBL_EN_ACK_MASK << PWM_STAT_IEP1_PWM_GBL_EN_ACK_SHIFT )
140#define PWM_STAT_FW_INIT_SHIFT ( 3 )
141#define PWM_STAT_FW_INIT_MASK ( FW_INIT_MASK << PWM_STAT_FW_INIT_SHIFT )
142
143/*
144 * Firmware IEP PWM instance registers
145 */
146
147/* IEP PWM register offsets */
148#define IEP_PWM_RECFG_OFFSET ( 0 )
149#define IEP_PWM_MODE_OFFSET ( 4 )
150#define IEP_PWM_EN_OFFSET ( 8 )
151#define IEP_PWM_PRD_COUNT_OFFSET ( 12 )
152#define IEP_PWM0_DC_COUNT_OFFSET ( 16 )
153#define IEP_PWM1_DC_COUNT_OFFSET ( 20 )
154#define IEP_PWM2_DC_COUNT_OFFSET ( 24 )
155#define IEP_PWM3_DC_COUNT_OFFSET ( 28 )
156#define IEP_PWM4_DC_COUNT_OFFSET ( 32 )
157#define IEP_PWM5_DC_COUNT_OFFSET ( 36 )
158#define IEP_PWM6_DC_COUNT_OFFSET ( 40 )
159#define IEP_PWM7_DC_COUNT_OFFSET ( 44 )
160#define IEP_PWM8_DC_COUNT_OFFSET ( 48 )
161#define IEP_PWM9_DC_COUNT_OFFSET ( 52 )
162#define IEP_PWM10_DC_COUNT_OFFSET ( 56 )
163#define IEP_PWM11_DC_COUNT_OFFSET ( 60 )
164#define IEP_PWM0_1_DB_COUNT_OFFSET ( 62 )
165#define IEP_PWM2_3_DB_COUNT_OFFSET ( 64 )
166#define IEP_PWM4_5_DB_COUNT_OFFSET ( 68 )
167#define IEP_PWM6_7_DB_COUNT_OFFSET ( 70 )
168#define IEP_PWM8_9_DB_COUNT_OFFSET ( 72 )
169#define IEP_PWM10_11_DB_COUNT_OFFSET ( 74 )
170
171/* IEP0 PWM register addresses */
172#define ICSSG_PWM_IEP0_PWM_BASE_ADDR ( 0x001C )
173#define ICSSG_PWM_IEP0_PWM_RECFG ( ICSSG_PWM_IEP0_PWM_BASE_ADDR + IEP_PWM_RECFG_OFFSET )
174#define ICSSG_PWM_IEP0_PWM_MODE ( ICSSG_PWM_IEP0_PWM_BASE_ADDR + IEP_PWM_MODE_OFFSET )
175#define ICSSG_PWM_IEP0_PWM_EN ( ICSSG_PWM_IEP0_PWM_BASE_ADDR + IEP_PWM_EN_OFFSET )
176#define ICSSG_PWM_IEP0_PWM_PRD_COUNT ( ICSSG_PWM_IEP0_PWM_BASE_ADDR + IEP_PWM_PRD_COUNT_OFFSET )
177#define ICSSG_PWM_IEP0_PWM0_DC_COUNT ( ICSSG_PWM_IEP0_PWM_BASE_ADDR + IEP_PWM0_DC_COUNT_OFFSET )
178#define ICSSG_PWM_IEP0_PWM1_DC_COUNT ( ICSSG_PWM_IEP0_PWM_BASE_ADDR + IEP_PWM1_DC_COUNT_OFFSET )
179#define ICSSG_PWM_IEP0_PWM2_DC_COUNT ( ICSSG_PWM_IEP0_PWM_BASE_ADDR + IEP_PWM2_DC_COUNT_OFFSET )
180#define ICSSG_PWM_IEP0_PWM3_DC_COUNT ( ICSSG_PWM_IEP0_PWM_BASE_ADDR + IEP_PWM3_DC_COUNT_OFFSET )
181#define ICSSG_PWM_IEP0_PWM4_DC_COUNT ( ICSSG_PWM_IEP0_PWM_BASE_ADDR + IEP_PWM4_DC_COUNT_OFFSET )
182#define ICSSG_PWM_IEP0_PWM5_DC_COUNT ( ICSSG_PWM_IEP0_PWM_BASE_ADDR + IEP_PWM5_DC_COUNT_OFFSET )
183#define ICSSG_PWM_IEP0_PWM6_DC_COUNT ( ICSSG_PWM_IEP0_PWM_BASE_ADDR + IEP_PWM6_DC_COUNT_OFFSET )
184#define ICSSG_PWM_IEP0_PWM7_DC_COUNT ( ICSSG_PWM_IEP0_PWM_BASE_ADDR + IEP_PWM7_DC_COUNT_OFFSET )
185#define ICSSG_PWM_IEP0_PWM8_DC_COUNT ( ICSSG_PWM_IEP0_PWM_BASE_ADDR + IEP_PWM8_DC_COUNT_OFFSET )
186#define ICSSG_PWM_IEP0_PWM9_DC_COUNT ( ICSSG_PWM_IEP0_PWM_BASE_ADDR + IEP_PWM9_DC_COUNT_OFFSET )
187#define ICSSG_PWM_IEP0_PWM10_DC_COUNT ( ICSSG_PWM_IEP0_PWM_BASE_ADDR + IEP_PWM10_DC_COUNT_OFFSET )
188#define ICSSG_PWM_IEP0_PWM11_DC_COUNT ( ICSSG_PWM_IEP0_PWM_BASE_ADDR + IEP_PWM11_DC_COUNT_OFFSET )
189#define ICSSG_PWM_IEP0_PWM0_1_DB_COUNT ( ICSSG_PWM_IEP0_PWM_BASE_ADDR + IEP_PWM0_1_DB_COUNT_OFFSET )
190#define ICSSG_PWM_IEP0_PWM2_3_DB_COUNT ( ICSSG_PWM_IEP0_PWM_BASE_ADDR + IEP_PWM2_3_DB_COUNT_OFFSET )
191#define ICSSG_PWM_IEP0_PWM4_5_DB_COUNT ( ICSSG_PWM_IEP0_PWM_BASE_ADDR + IEP_PWM4_5_DB_COUNT_OFFSET )
192#define ICSSG_PWM_IEP0_PWM6_7_DB_COUNT ( ICSSG_PWM_IEP0_PWM_BASE_ADDR + IEP_PWM6_7_DB_COUNT_OFFSET )
193#define ICSSG_PWM_IEP0_PWM8_9_DB_COUNT ( ICSSG_PWM_IEP0_PWM_BASE_ADDR + IEP_PWM8_9_DB_COUNT_OFFSET )
194#define ICSSG_PWM_IEP0_PWM10_11_DB_COUNT ( ICSSG_PWM_IEP0_PWM_BASE_ADDR + IEP_PWM10_11_DB_COUNT_OFFSET )
195
196/* IEP1 PWM register addresses */
197#define ICSSG_PWM_IEP1_PWM_BASE_ADDR ( 0x0068 )
198#define ICSSG_PWM_IEP1_PWM_RECFG ( ICSSG_PWM_IEP1_PWM_BASE_ADDR + IEP_PWM_RECFG_OFFSET )
199#define ICSSG_PWM_IEP1_PWM_MODE ( ICSSG_PWM_IEP1_PWM_BASE_ADDR + IEP_PWM_MODE_OFFSET )
200#define ICSSG_PWM_IEP1_PWM_EN ( ICSSG_PWM_IEP1_PWM_BASE_ADDR + IEP_PWM_EN_OFFSET )
201#define ICSSG_PWM_IEP1_PWM_PRD_COUNT ( ICSSG_PWM_IEP1_PWM_BASE_ADDR + IEP_PWM_PRD_COUNT_OFFSET )
202#define ICSSG_PWM_IEP1_PWM0_DC_COUNT ( ICSSG_PWM_IEP1_PWM_BASE_ADDR + IEP_PWM0_DC_COUNT_OFFSET )
203#define ICSSG_PWM_IEP1_PWM1_DC_COUNT ( ICSSG_PWM_IEP1_PWM_BASE_ADDR + IEP_PWM1_DC_COUNT_OFFSET )
204#define ICSSG_PWM_IEP1_PWM2_DC_COUNT ( ICSSG_PWM_IEP1_PWM_BASE_ADDR + IEP_PWM2_DC_COUNT_OFFSET )
205#define ICSSG_PWM_IEP1_PWM3_DC_COUNT ( ICSSG_PWM_IEP1_PWM_BASE_ADDR + IEP_PWM3_DC_COUNT_OFFSET )
206#define ICSSG_PWM_IEP1_PWM4_DC_COUNT ( ICSSG_PWM_IEP1_PWM_BASE_ADDR + IEP_PWM4_DC_COUNT_OFFSET )
207#define ICSSG_PWM_IEP1_PWM5_DC_COUNT ( ICSSG_PWM_IEP1_PWM_BASE_ADDR + IEP_PWM5_DC_COUNT_OFFSET )
208#define ICSSG_PWM_IEP1_PWM6_DC_COUNT ( ICSSG_PWM_IEP1_PWM_BASE_ADDR + IEP_PWM6_DC_COUNT_OFFSET )
209#define ICSSG_PWM_IEP1_PWM7_DC_COUNT ( ICSSG_PWM_IEP1_PWM_BASE_ADDR + IEP_PWM7_DC_COUNT_OFFSET )
210#define ICSSG_PWM_IEP1_PWM8_DC_COUNT ( ICSSG_PWM_IEP1_PWM_BASE_ADDR + IEP_PWM8_DC_COUNT_OFFSET )
211#define ICSSG_PWM_IEP1_PWM9_DC_COUNT ( ICSSG_PWM_IEP1_PWM_BASE_ADDR + IEP_PWM9_DC_COUNT_OFFSET )
212#define ICSSG_PWM_IEP1_PWM10_DC_COUNT ( ICSSG_PWM_IEP1_PWM_BASE_ADDR + IEP_PWM10_DC_COUNT_OFFSET )
213#define ICSSG_PWM_IEP1_PWM11_DC_COUNT ( ICSSG_PWM_IEP1_PWM_BASE_ADDR + IEP_PWM11_DC_COUNT_OFFSET )
214#define ICSSG_PWM_IEP1_PWM0_1_DB_COUNT ( ICSSG_PWM_IEP1_PWM_BASE_ADDR + IEP_PWM0_1_DB_COUNT_OFFSET )
215#define ICSSG_PWM_IEP1_PWM2_3_DB_COUNT ( ICSSG_PWM_IEP1_PWM_BASE_ADDR + IEP_PWM2_3_DB_COUNT_OFFSET )
216#define ICSSG_PWM_IEP1_PWM4_5_DB_COUNT ( ICSSG_PWM_IEP1_PWM_BASE_ADDR + IEP_PWM4_5_DB_COUNT_OFFSET )
217#define ICSSG_PWM_IEP1_PWM6_7_DB_COUNT ( ICSSG_PWM_IEP1_PWM_BASE_ADDR + IEP_PWM6_7_DB_COUNT_OFFSET )
218#define ICSSG_PWM_IEP1_PWM8_9_DB_COUNT ( ICSSG_PWM_IEP1_PWM_BASE_ADDR + IEP_PWM8_9_DB_COUNT_OFFSET )
219#define ICSSG_PWM_IEP1_PWM10_11_DB_COUNT ( ICSSG_PWM_IEP1_PWM_BASE_ADDR + IEP_PWM10_11_DB_COUNT_OFFSET )
220
221/*
222 * Firmware IEP PWM instance register bit fields
223 */
224
225/* IEPx_PWM_RECFG */
226#define RECFG_IEP_PWM_EN_MASK ( 0x1 )
227#define RECFG_IEP_PWM_PRD_COUNT_MASK ( 0x1 )
228#define RECFG_IEP_PWM_DC_COUNT_MASK ( 0xFFF )
229#define RECFG_IEP_PWM_DB_COUNT_MASK ( 0x3F )
230#define IEP_PWM_RECFG_RECFG_IEP_PWM_EN_SHIFT ( 0 )
231#define IEP_PWM_RECFG_RECFG_IEP_PWM_EN_MASK ( RECFG_IEP_PWM_EN_MASK << IEP_PWM_RECFG_RECFG_IEP_PWM_EN_SHIFT )
232#define IEP_PWM_RECFG_RECFG_IEP_PWM_PRD_COUNT_SHIFT ( 1 )
233#define IEP_PWM_RECFG_RECFG_IEP_PWM_PRD_COUNT_MASK ( RECFG_IEP_PWM_PRD_COUNT_MASK << IEP_PWM_RECFG_RECFG_IEP_PWM_PRD_COUNT_SHIFT )
234#define IEP_PWM_RECFG_RECFG_IEP_PWM_DC_COUNT_SHIFT ( 2 )
235#define IEP_PWM_RECFG_RECFG_IEP_PWM_DC_COUNT_MASK ( RECFG_IEP_PWM_DC_COUNT_MASK << IEP_PWM_RECFG_RECFG_IEP_PWM_DC_COUNT_SHIFT )
236#define IEP_PWM_RECFG_RECFG_IEP_PWM_DB_COUNT_SHIFT ( 14 )
237#define IEP_PWM_RECFG_RECFG_IEP_PWM_DB_COUNT_MASK ( RECFG_IEP_PWM_DB_COUNT_MASK << IEP_PWM_RECFG_RECFG_IEP_PWM_DB_COUNT_SHIFT )
238/* Aggregate Reconfiguration bit field mask */
239#define IEP_PWM_RECFG_MASK \
240 ( IEP_PWM_RECFG_RECFG_IEP_PWM_EN_MASK | \
241 IEP_PWM_RECFG_RECFG_IEP_PWM_PRD_COUNT_MASK | \
242 IEP_PWM_RECFG_RECFG_IEP_PWM_DC_COUNT_MASK | \
243 IEP_PWM_RECFG_RECFG_IEP_PWM_DB_COUNT_MASK )
244
245/* IEPx_PWM_MODE */
246#define BF_PWM_MODE_SNGL ( 0 ) /* PWM mode bit field Single-Ended PWM setting */
247#define BF_PWM_MODE_COMP ( 1 ) /* PWM mode bit field Complementary PWM setting */
248#define PWM_MODE_MASK ( 0x1 )
249#define IEP_PWM_MODE_PWM0_1_MODE_SHIFT ( 0 )
250#define IEP_PWM_MODE_PWM0_1_MODE_MASK ( PWM_MODE_MASK << IEP_PWM_MODE_PWM0_1_MODE_SHIFT )
251#define IEP_PWM_MODE_PWM2_3_MODE_SHIFT ( 1 )
252#define IEP_PWM_MODE_PWM2_3_MODE_MASK ( PWM_MODE_MASK << IEP_PWM_MODE_PWM2_3_MODE_SHIFT )
253#define IEP_PWM_MODE_PWM4_5_MODE_SHIFT ( 2 )
254#define IEP_PWM_MODE_PWM4_5_MODE_MASK ( PWM_MODE_MASK << IEP_PWM_MODE_PWM4_5_MODE_SHIFT )
255#define IEP_PWM_MODE_PWM6_7_MODE_SHIFT ( 3 )
256#define IEP_PWM_MODE_PWM6_7_MODE_MASK ( PWM_MODE_MASK << IEP_PWM_MODE_PWM6_7_MODE_SHIFT )
257#define IEP_PWM_MODE_PWM8_9_MODE_SHIFT ( 4 )
258#define IEP_PWM_MODE_PWM8_9_MODE_MASK ( PWM_MODE_MASK << IEP_PWM_MODE_PWM8_9_MODE_SHIFT )
259#define IEP_PWM_MODE_PWM10_11_MODE_SHIFT ( 5 )
260#define IEP_PWM_MODE_PWM10_11_MODE_MASK ( PWM_MODE_MASK << IEP_PWM_MODE_PWM10_11_MODE_SHIFT )
261
262/* IEPx_PWM_EN */
263#define BF_PWM_EN_DISABLE ( 0 ) /* PWM enable bit field disabled setting */
264#define BF_PWM_EN_ENABLE ( 1 ) /* PWM enable bit field enabled setting */
265#define PWM_EN_MASK ( 0x1 )
266#define IEP_PWM_EN_PWM0_EN_SHIFT ( 0 )
267#define IEP_PWM_EN_PWM0_EN_MASK ( PWM_EN_MASK << IEP_PWM_EN_PWM0_EN_SHIFT )
268#define IEP_PWM_EN_PWM1_EN_SHIFT ( 1 )
269#define IEP_PWM_EN_PWM1_EN_MASK ( PWM_EN_MASK << IEP_PWM_EN_PWM1_EN_SHIFT )
270#define IEP_PWM_EN_PWM2_EN_SHIFT ( 2 )
271#define IEP_PWM_EN_PWM2_EN_MASK ( PWM_EN_MASK << IEP_PWM_EN_PWM2_EN_SHIFT )
272#define IEP_PWM_EN_PWM3_EN_SHIFT ( 3 )
273#define IEP_PWM_EN_PWM3_EN_MASK ( PWM_EN_MASK << IEP_PWM_EN_PWM3_EN_SHIFT )
274#define IEP_PWM_EN_PWM4_EN_SHIFT ( 4 )
275#define IEP_PWM_EN_PWM4_EN_MASK ( PWM_EN_MASK << IEP_PWM_EN_PWM4_EN_SHIFT )
276#define IEP_PWM_EN_PWM5_EN_SHIFT ( 5 )
277#define IEP_PWM_EN_PWM5_EN_MASK ( PWM_EN_MASK << IEP_PWM_EN_PWM5_EN_SHIFT )
278#define IEP_PWM_EN_PWM6_EN_SHIFT ( 6 )
279#define IEP_PWM_EN_PWM6_EN_MASK ( PWM_EN_MASK << IEP_PWM_EN_PWM6_EN_SHIFT )
280#define IEP_PWM_EN_PWM7_EN_SHIFT ( 7 )
281#define IEP_PWM_EN_PWM7_EN_MASK ( PWM_EN_MASK << IEP_PWM_EN_PWM7_EN_SHIFT )
282#define IEP_PWM_EN_PWM8_EN_SHIFT ( 8 )
283#define IEP_PWM_EN_PWM8_EN_MASK ( PWM_EN_MASK << IEP_PWM_EN_PWM8_EN_SHIFT )
284#define IEP_PWM_EN_PWM9_EN_SHIFT ( 9 )
285#define IEP_PWM_EN_PWM9_EN_MASK ( PWM_EN_MASK << IEP_PWM_EN_PWM9_EN_SHIFT )
286#define IEP_PWM_EN_PWM10_EN_SHIFT ( 10 )
287#define IEP_PWM_EN_PWM10_EN_MASK ( PWM_EN_MASK << IEP_PWM_EN_PWM10_EN_SHIFT )
288#define IEP_PWM_EN_PWM11_EN_SHIFT ( 11 )
289#define IEP_PWM_EN_PWM11_EN_MASK ( PWM_EN_MASK << IEP_PWM_EN_PWM11_EN_SHIFT )
290
291/* IEPx_PWM_PRD_COUNT */
292#define PRD_COUNT_MASK ( 0xFFFFFFFF )
293#define IEP_PWM_PRD_COUNT_SHIFT ( 0 )
294#define IEP_PWM_PRD_COUNT_MASK ( PRD_COUNT_MASK << IEP_PWM_PRD_COUNT_SHIFT )
295
296/* IEPx_PWMm_DC_COUNT */
297#define DC_COUNT_MASK ( 0xFFFFFFFF )
298#define IEP_PWM_DC_COUNT_SHIFT ( 0 )
299#define IEP_PWM_DC_COUNT_MASK ( DC_COUNT_MASK << IEP_PWM_DC_COUNT_SHIFT )
300
301/* IEPx_PWMn_n+1_DB_COUNT */
302#define DB_COUNT_MASK ( 0xFFFF )
303#define IEP_PWM_DB_COUNT_SHIFT ( 0 )
304#define IEP_PWM_DB_COUNT_MASK ( DB_COUNT_MASK << IEP_PWM_DB_COUNT_SHIFT )
305
306
307#endif /* _ICSSG_IEP_PWM_H_ */
diff --git a/example/apps/icssg_pwm/firmware/src/iepPwm.c b/example/apps/icssg_pwm/firmware/src/iepPwm.c
new file mode 100644
index 0000000..a1a999a
--- /dev/null
+++ b/example/apps/icssg_pwm/firmware/src/iepPwm.c
@@ -0,0 +1,2770 @@
1/*
2 * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
3 *
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the
15 * distribution.
16 *
17 * * Neither the name of Texas Instruments Incorporated nor the names of
18 * its contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34#include <string.h>
35#include <ti/csl/soc.h>
36#include "icssg_iep_pwm.h"
37#include "iepPwmFwRegs.h"
38#include "iepPwmHwRegs.h"
39#include "iepPwm.h"
40
41/* Define to synchronize IEP0 & 1 clocks. */
42//#define IEP_SYNC_CLK_EN
43/* Define to enable Tx Host interrupt on IEP0 CMP0 */
44//#define TX_HOST_INT
45
46
47#define CLK_TO_COUNT(x) ( DEF_COUNT_INC_PER_CLK * x ) /* For default increment per clock, compute count corresponding to number of IEP clocks */
48#define COUNT_TO_CLK(x) ( x / DEF_COUNT_INC_PER_CLK ) /* For default increment per clock, compute IEP clocks corresponding to count */
49
50#define CMP_SR_EARLY_VAL ( DEF_COUNT_INC_PER_CLK ) /* CMP "Early in Period" value */
51
52/* Index of "sacrificial" PWM in set */
53#define SACR_PWM_IDX ( 0 )
54
55/* Single-Ended PWM Initial State Configuration register */
56/* Active state Toggle:0000, Trip state HiZ:0000, Initial state L/L:0101 */
57#define SNGL_PWM_STATE_INIT \
58 ((PWM_ACT_TOGGLE<<10) | (PWM_ACT_TOGGLE<<8) | (PWM_TRIP_HIZ<<6) | (PWM_TRIP_HIZ<<4) | (PWM_INIT_LO<<2) | (PWM_INIT_LO<<0))
59/* Differential PWM Initial State Configuration register */
60/* Active state Toggle:0000, Trip state HiZ:0000, Initial state H/L:1001 */
61#define DIFF_PWM_STATE_INIT \
62 ((PWM_ACT_TOGGLE<<10) | (PWM_ACT_TOGGLE<<8) | (PWM_TRIP_HIZ<<6) | (PWM_TRIP_HIZ<<4) | (PWM_INIT_HI<<2) | (PWM_INIT_LO<<0))
63
64/* Action Table Rows.
65 * Each Action Table Row corresponds to a requested Duty Cycle update.
66 * DC_old: latched (current) Duty Cycle
67 * DC_new: requested (new) Duty Cycle
68 */
69typedef enum IepPwmActionTableRow_e
70{
71 AT_Row01_DcOldX_DcNewX = 0, /* DC_old=x, DC_new=x */
72 AT_Row02_DcOldX_DcNewY = 1, /* DC_old=x, DC_new=y */
73 AT_Row03_DcOldX_DcNew0 = 2, /* DC old=x, DC_new=0 */
74 AT_Row04_DcOldX_DcNew100 = 3, /* DC_old=x, DC_new=100 */
75 AT_Row05_DcOld0_DcNewY = 4, /* DC_old=0, DC_new=y */
76 AT_Row06_DcOld0_DcNew0 = 5, /* DC_old=0, DC_new=0 */
77 AT_Row07_DcOld0_DcNew100 = 6, /* DC_old=0, DC_new=100 */
78 AT_Row08_DcOld100_DcNewY = 7, /* DC_old=100, DC_new=y */
79 AT_Row09_DcOld100_DcNew0 = 8, /* DC_old=100, DC_new=0 */
80 AT_Row10_DcOld100_DcNew100 = 9, /* DC_old=100, DC_new=100 */
81 AT_NROW
82} IepPwmActionTableRow;
83
84/* Action Table Entry.
85 * Latch, Left-Hand Side, and Right-Hand Side actions to take
86 * for a requested Duty Cycle update.
87 */
88typedef struct IepPwmActionTableEntry_s
89{
90 IepLatchAction latchAction;
91 IepPwmLhsAction lhsAction;
92 IepPwmRhsAction rhsAction;
93} IepPwmActionTableEntry;
94
95/* Action Table: no Enable reconfiguration & En_old==Disabled */
96static const IepPwmActionTableEntry gActT1_EnRecfgNo_EnOldDisable[AT_NROW] =
97{
98 /* DC_old = DC_new = x */
99 {LATCH_ACTION_None,
100 LHS_ACTION_None,
101 RHS_ACTION_None},
102 /* DC_old = x, DC_new = y */
103 {LATCH_ACTION_Latch_New,
104 LHS_ACTION_None,
105 RHS_ACTION_None},
106 /* DC_old = x, DC_new = 0 */
107 {LATCH_ACTION_Latch_0,
108 LHS_ACTION_None,
109 RHS_ACTION_None},
110 /* DC_old = x, DC_new = 100 */
111 {LATCH_ACTION_Latch_100,
112 LHS_ACTION_None,
113 RHS_ACTION_None},
114 /* DC_old = 0, DC_new = y */
115 {LATCH_ACTION_Latch_New,
116 LHS_ACTION_None,
117 RHS_ACTION_None},
118 /* DC_old = 0, DC_new = 0 */
119 {LATCH_ACTION_None,
120 LHS_ACTION_None,
121 RHS_ACTION_None},
122 /* DC_old = 0, DC_new = 100 */
123 {LATCH_ACTION_Latch_100,
124 LHS_ACTION_None,
125 RHS_ACTION_None},
126 /* DC_old = 100, DC_new = y */
127 {LATCH_ACTION_Latch_New,
128 LHS_ACTION_None,
129 RHS_ACTION_None},
130 /* DC_old = 100, DC_new = 0 */
131 {LATCH_ACTION_Latch_0,
132 LHS_ACTION_None,
133 RHS_ACTION_None},
134 /* DC_old = 100, DC_new = 100 */
135 {LATCH_ACTION_None,
136 LHS_ACTION_None,
137 RHS_ACTION_None},
138};
139
140/* Action table: no Enable reconfiguration, En_old==Enabled */
141static const IepPwmActionTableEntry gActT2_EnRecfgNo_EnOldEnable[AT_NROW] =
142{
143 /* DC_old = DC_new = x */
144 {LATCH_ACTION_None,
145 LHS_ACTION_None,
146 RHS_ACTION_None},
147 /* DC_old = x, DC_new = y */
148 {LATCH_ACTION_Latch_New,
149 LHS_ACTION_Set_CmpSr_DcLhsY,
150 RHS_ACTION_None},
151 /* DC_old = x, DC_new = 0 */
152 {LATCH_ACTION_Latch_0,
153 LHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate,
154 RHS_ACTION_None},
155 /* DC_old = x, DC_new = 100 */
156 {LATCH_ACTION_Latch_100,
157 LHS_ACTION_None,
158 RHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate},
159 /* DC_old = 0, DC_new = y */
160 {LATCH_ACTION_Latch_New,
161 LHS_ACTION_Set_CmpSr_DcLhsY_And_EnableSrUpdate,
162 RHS_ACTION_None},
163 /* DC_old = 0, DC_new = 0 */
164 {LATCH_ACTION_None,
165 LHS_ACTION_None,
166 RHS_ACTION_None},
167 /* DC_old = 0, DC_new = 100 */
168 {LATCH_ACTION_Latch_100,
169 LHS_ACTION_Set_CmpSr_EarlyInPrd_And_EnableSrUpdate,
170 RHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate},
171 /* DC_old = 100, DC_new = y */
172 {LATCH_ACTION_Latch_New,
173 LHS_ACTION_None,
174 RHS_ACTION_Set_CmpSr_DcRhsY_And_EnableSrUpdate},
175 /* DC_old = 100, DC_new = 0 */
176 {LATCH_ACTION_Latch_0,
177 LHS_ACTION_Set_CmpSr_EarlyInPrd_And_EnableSrUpdate,
178 RHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate},
179 /* DC_old = 100, DC_new = 100 */
180 {LATCH_ACTION_None,
181 LHS_ACTION_None,
182 RHS_ACTION_None}
183};
184
185/* Action table: Enable reconfiguration, En_new==Enabled */
186static const IepPwmActionTableEntry gActT3_EnRecfgYes_EnNewEnable[AT_NROW] =
187{
188 /* DC_old = DC_new = x */
189 {LATCH_ACTION_None,
190 LHS_ACTION_Set_CmpSr_DcLhsX_And_EnableSrUpdate,
191 RHS_ACTION_None},
192 /* DC_old = x, DC_new = y */
193 {LATCH_ACTION_Latch_New,
194 LHS_ACTION_Set_CmpSr_DcLhsY_And_EnableSrUpdate,
195 RHS_ACTION_None},
196 /* DC_old = x, DC_new = 0 */
197 {LATCH_ACTION_Latch_0,
198 LHS_ACTION_None,
199 RHS_ACTION_None},
200 /* DC_old = x, DC_new = 100 */
201 {LATCH_ACTION_Latch_100,
202 LHS_ACTION_Set_CmpSr_EarlyInPrd_And_EnableSrUpdate,
203 RHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate},
204 /* DC_old = 0, DC_new = y */
205 {LATCH_ACTION_Latch_New,
206 LHS_ACTION_Set_CmpSr_DcLhsY_And_EnableSrUpdate,
207 RHS_ACTION_None},
208 /* DC_old = 0, DC_new = 0 */
209 {LATCH_ACTION_None,
210 LHS_ACTION_None,
211 RHS_ACTION_None},
212 /* DC_old = 0, DC_new = 100 */
213 {LATCH_ACTION_Latch_100,
214 LHS_ACTION_Set_CmpSr_EarlyInPrd_And_EnableSrUpdate,
215 RHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate},
216 /* DC_old = 100, DC_new = y */
217 {LATCH_ACTION_Latch_New,
218 LHS_ACTION_Set_CmpSr_DcLhsY_And_EnableSrUpdate,
219 RHS_ACTION_None},
220 /* DC_old = 100, DC_new = 0 */
221 {LATCH_ACTION_Latch_0,
222 LHS_ACTION_None,
223 RHS_ACTION_None},
224 /* DC_old = 100, DC_new = 100 */
225 {LATCH_ACTION_None,
226 LHS_ACTION_Set_CmpSr_EarlyInPrd_And_EnableSrUpdate,
227 RHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate}
228};
229
230/* Action table: Enable reconfiguration, En_new==Enabled */
231static const IepPwmActionTableEntry gActT4_EnRecfgYes_EnNewDisable[AT_NROW] =
232{
233 /* DC_old = DC_new = x */
234 {LATCH_ACTION_None,
235 LHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate,
236 RHS_ACTION_None},
237 /* DC_old = x, DC_new = y */
238 {LATCH_ACTION_Latch_New,
239 LHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate,
240 RHS_ACTION_None},
241 /* DC_old = x, DC_new = 0 */
242 {LATCH_ACTION_Latch_0,
243 LHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate,
244 RHS_ACTION_None},
245 /* DC_old = x, DC_new = 100 */
246 {LATCH_ACTION_Latch_100,
247 LHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate,
248 RHS_ACTION_None},
249 /* DC_old = 0, DC_new = y */
250 {LATCH_ACTION_Latch_New,
251 LHS_ACTION_None,
252 RHS_ACTION_None},
253 /* DC_old = 0, DC_new = 0 */
254 {LATCH_ACTION_None,
255 LHS_ACTION_None,
256 RHS_ACTION_None},
257 /* DC_old = 0, DC_new = 100 */
258 {LATCH_ACTION_Latch_100,
259 LHS_ACTION_None,
260 RHS_ACTION_None},
261 /* DC_old = 100, DC_new = y */
262 {LATCH_ACTION_Latch_New,
263 LHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate,
264 RHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate},
265 /* DC_old = 100, DC_new = 0 */
266 {LATCH_ACTION_Latch_0,
267 LHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate,
268 RHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate},
269 /* DC_old = 100, DC_new = 100 */
270 {LATCH_ACTION_None,
271 LHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate,
272 RHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate}
273};
274
275
276IcssgIepPwmCtrlObj gIcssgIepPwmCtrlObj; /* IEP PWM control object */
277IcssgIepPwmObj gIcssgIep0PwmObj; /* IEP 0 PWM object */
278IcssgIepPwmObj gIcssgIep1PwmObj; /* IEP 1 PWM object */
279
280/* State Machine function, perform LHS processing */
281static void iepPwmLhs(
282 IcssgIepPwmObj *pIcssgIepPwmObj
283);
284
285/* State Machine function, perform RHS processing */
286static void iepPwmRhs(
287 IcssgIepPwmObj *pIcssgIepPwmObj
288);
289
290/* State Machine function, perform LHS reconfiguration.
291 Check Host reconfiguration request.
292 Perform Initialization reconfiguration. */
293static Int32 iepPwmConfigLhs(
294 IcssgIepPwmObj *pIcssgIepPwmObj
295);
296
297/* State Machine Function, perform RHS reconfiguration.
298 Apply pending Host reconfiguration request.
299 Perform Initialization reconfiguration.
300
301 IEP PWM object has private information required to perform RHS update.
302 This information is set appropriately in LHS (Host) Reconfiguration. */
303static Int32 iepPwmConfigRhs(
304 IcssgIepPwmObj *pIcssgIepPwmObj
305);
306
307/* Latch IEP PWM mode.
308 IEP PWM mode can't change after Initialization. */
309static void latchIepPwmMode(
310 IcssgIepPwmObj *pIcssgIepPwmObj
311);
312
313/* Update IEP Period Count */
314static void updateIepPwmPeriodCount(
315 IcssgIepPwmObj *pIcssgIepPwmObj
316);
317
318/* Reset IEP CMPx.
319 - Set CMPx inside CMP0 period for 1/6 of PWMs in each Set. This forces PWM Set Initial->Active State.
320 - Set CMPx outside CMP0 period for other 5/6 PWMs in each Set. */
321static void resetIepPwmCmpx(
322 IcssgIepPwmObj *pIcssgIepPwmObj
323);
324
325/* Initialize PWMs */
326static void initPwm(
327 IcssgIepPwmObj *pIcssgIepPwmObj
328);
329
330/* Reinitialize PWMs */
331static void reinitPwm(
332 IcssgIepPwmObj *pIcssgIepPwmObj
333);
334
335/* Latch IEP PWM Enable */
336static void latchIepPwmEn(
337 IcssgIepPwmObj *pIcssgIepPwmObj
338);
339
340/* Latch IEP PWM Period Count */
341static void latchIepPwmPeriodCount(
342 IcssgIepPwmObj *pIcssgIepPwmObj
343);
344
345/* Latch IEP PWM Duty Cycle Counts */
346static void latchIepPwmDcCounts(
347 IcssgIepPwmObj *pIcssgIepPwmObj,
348 Bool recfgFlag
349);
350
351/* Latch IEP PWM Deadband Counts */
352static void latchIepPwmDbCount(
353 IcssgIepPwmObj *pIcssgIepPwmObj,
354 Bool recfgFlag
355);
356
357/* Calculate IEP PWM Single-Ended and Differential Enable
358 *
359 * pIcssgIepPwmObj (I): Pointer to IEP PWM object
360 * pIepPwmSnglEn (O): Pointer to IEP PWM single-ended enable
361 * pIepPwmDiffEn (O): Pointer to IEP PWM differential enable
362 *
363 * IEP_PWM_MODE & IEP_PWM_EN: Host I/F FW Regs.
364 * iepPwmSnglEn & iepPwmDiffEn: FW private Regs (or PRU registers), used for processing PWMs.
365 *
366 */
367static void calcIepPwmSnglDiffEn(
368 IcssgIepPwmObj *pIcssgIepPwmObj,
369 Uint16 *pIepPwmSnglEn,
370 Uint8 *pIepPwmDiffEn
371);
372
373/* Latch IEP PWM Single-Ended and Differential Enable */
374static void latchIepPwmSnglDiffEn(
375 IcssgIepPwmObj *pIcssgIepPwmObj,
376 Uint16 iepPwmSnglEn,
377 Uint8 iepPwmDiffEn
378);
379
380/* Calculate & Latch IEP PWM LHS/RHS Duty Cycle Counts */
381static Int32 calcAndLatchIepPwmDcLhsRhsCount(
382 IcssgIepPwmObj *pIcssgIepPwmObj,
383 Bool recfgFlag
384);
385
386/* Initialize IEP PWM CMPx Shadow Registers */
387static Int32 initIepPwmCmpxShReg(
388 IcssgIepPwmObj *pIcssgIepPwmObj
389);
390
391/* Determine initial LHS/RHS actions */
392static Int32 getInitLhsAction(
393 Bool initToActPwm,
394 Bool pwmEn,
395 Uint32 iepPwmDcCount,
396 Uint32 pwmPeriodCount,
397 IepPwmLhsAction *pActionLhs,
398 IepPwmRhsAction *pActionRhs
399);
400
401/* Initial update IEP PWM CMPx Shadow Register, Single-Ended Mode */
402static void execInitLhsActionSngl(
403 IepPwmLhsAction actionLhs,
404 Uint32 iepPwmPeriodCount,
405 Uint32 iepPwmDcCountLhs,
406 volatile uint32_t **pIepCmpSrAddr,
407 Uint16 *pIepPwmSnglUpdEn,
408 Uint8 pwmIdx
409);
410
411/* Initial update IEP PWM CMPx Shadow Registers, Differential Mode */
412static void execInitLhsActionDiff(
413 IepPwmLhsAction actionLhs,
414 Uint32 iepPwmPeriodCount,
415 Uint32 iepPwmDcCountLhs,
416 volatile uint32_t **pIepCmpSrAddr,
417 Uint8 *pIepPwmDiffUpdEn,
418 Uint8 dPwmIdx
419);
420
421/* Update IEP PWM CMPx Shadow Registers.
422 PWM Enable and DC Count reconfiguration handled jointly. */
423static Int32 updateIepPwmCmpxShRegPwmEnDc(
424 IcssgIepPwmObj *pIcssgIepPwmObj
425);
426
427/* Stash RHS action */
428static void stashRhsAction(
429 IepPwmRhsAction actionRhs,
430 Bool *pIepPwmRhsRecfgFlag,
431 IepPwmRhsAction *pIepPwmRhsAction
432);
433
434/* Get Action Table row, Single-Ended PWM
435 * recfgIepPwmDcCount : (I) IEP PWM DC count reconfiguration mask
436 * iepPwmDcCountOld : (I) Old (latched) IEP PWM DC count
437 * iepPwmDcCountNew : (I) New (input) IEP PWM DC count
438 * pwmIdx : (I) Single-Ended PWM index, 0...IEP_PWM_MODE_SNGL-1
439 * pwmPeriodCount : (I) PWM period count
440 * pRowIdx : (O) address of row index
441 */
442static Int32 getActionTableRowSngl(
443 Uint16 recfgDcCount,
444 Uint8 pwmIdx,
445 Uint32 iepPwmDcCountOld,
446 Uint32 iepPwmDcCountNew,
447 Uint32 pwmPeriodCount,
448 Uint8 *pRowIdx
449);
450
451/* Get Action Table row, Differential PWM
452 * recfgDcCount : (I) IEP PWM DC count reconfiguration mask
453 * iepPwmDcCountOld : (I) Old (latched) IEP PWM DC count
454 * iepPwmDcCountNew : (I) New (input) IEP PWM DC count
455 * pwmIdx : (I) Differential PWM index, 0...IEP_PWM_MODE_DIFF-1
456 * pwmPeriodCount : (I) PWM period
457 * pRowIdx : (O) address of row index
458 */
459static Int32 getActionTableRowDiff(
460 Uint16 recfgDcCount,
461 Uint8 dPwmIdx,
462 Uint32 iepPwmDcCountOld,
463 Uint32 iepPwmDcCountNew,
464 Uint32 pwmPeriodCount,
465 Uint8 *pRowIdx
466);
467
468/* Calculate IEP PWM LHS/RHS Duty Cycle Counts
469 * actionLatch : (I) Latch Action
470 * iepPwmDcCountNew : (I) New (input) IEP PWM DC count
471 * pIepPwmDcCountLhsNew : (O) IEP PWM DC LHS count
472 * pIepPwmDcCountRhsNew : (O) IEP PWM DC RHS count
473 */
474static void calcDcLatchAction(
475 IepLatchAction actionLatch,
476 Uint32 iepPwmDcCountNew,
477 Uint32 *pIepPwmDcCountLhsNew,
478 Uint32 *pIepPwmDcCountRhsNew
479);
480
481/* Calculate DC LHS/RHS for DC */
482static void calcDcLhsRhs(
483 Uint32 dcCount,
484 Uint32 *pDcCountLhs,
485 Uint32 *pDcCountRhs
486);
487
488/* Execute LHS action, Single-Ended PWM
489 * iepPwmDcCountLhsOld : (I) scalar, old DC LHS
490 * iepPwmDcCountLhsNew : (I) scalar, new DC LHS
491 * pIepCmpSrBase : (I) base pointer for CMP SRs
492 * pIepPwmSnglUpdEn : (I) single-ended signal update enable
493 * pwmIdx : (I) 0...IEP_MAX_NUM_SNGL_PWM-1
494 * iepPwmPeriodCount : (I) IEP CMP0 period count
495 */
496static void execLhsActionSngl(
497 IepPwmLhsAction lhsAction,
498 Uint32 iepPwmDcCountLhsOld,
499 Uint32 iepPwmDcCountLhsNew,
500 volatile uint32_t **pIepCmpSrAddr,
501 Uint16 *pIepPwmSnglUpdEn,
502 Uint8 pwmIdx,
503 Uint32 iepPwmPeriodCount
504);
505
506/* Execute LHS action, Differential PWM
507 * iepPwmDcCountLhsOld : (I) scalar, old DC LHS
508 * iepPwmDcCountLhsNew : (I) scalar, new DC LHS
509 * pIepCmpSrBase : (I) base pointer for CMP SRs
510 * pIepPwmDiffUpdEn : (I) single-ended signal update enable
511 * dPwmIdx : (I) 0...IEP_MAX_NUM_DIFF_PWM-1
512 * iepPwmPeriodCount : (I) IEP CMP0 period count
513 */
514static void execLhsActionDiff(
515 IepPwmLhsAction lhsAction,
516 Uint32 iepPwmDcCountLhsOld,
517 Uint32 iepPwmDcCountLhsNew,
518 volatile uint32_t **pIepCmpSrAddr,
519 Uint8 *pIepPwmDiffUpdEn,
520 Uint8 dPwmIdx,
521 Uint32 iepPwmPeriodCount
522);
523
524
525/* Execute (LHS) DC latch action
526 * actionLatch : (I) Latch Action
527 * pIepPwmDcCountOld : (I) Pointer to old (latched) IEP PWM DC count
528 * pIepPwmDcCountLhsOld : (I) Pointer to IEP PWM DC LHS count
529 * pIepPwmDcCountRhsOld : (I) Pointer to IEP PWM DC RHS count
530 * iepPwmDcCountNew : (I) new IEP PWM DC count
531 * iepPwmDcCountLhsNew : (I) new IEP PWM DC LHS count
532 * iepPwmDcCountRhsNew : (I) new IEP PWM DC RHS count
533 */
534static void execDcLatchAction(
535 IepLatchAction actionLatch,
536 Uint32 *pIepPwmDcCountOld,
537 Uint32 *pIepPwmDcCountLhsOld,
538 Uint32 *pIepPwmDcCountRhsOld,
539 Uint32 iepPwmDcCountNew,
540 Uint32 iepPwmDcCountLhsNew,
541 Uint32 iepPwmDcCountRhsNew
542);
543
544/* Execute stashed RHS actions */
545static void execRhsActionStash(
546 IcssgIepPwmObj *pIcssgIepPwmObj
547);
548
549/* Update IEP PWM CMPx Shadow Registers for DB reconfiguration. */
550static Int32 updateIepPwmCmpxShRegDb(
551 IcssgIepPwmObj *pIcssgIepPwmObj
552);
553
554#ifdef TX_HOST_INT
555volatile register uint32_t __R31;
556#endif
557
558/* ------------------------------------------------------------------------- *
559 * External Functions *
560 * ------------------------------------------------------------------------- */
561
562/* Reset PWM FW control object */
563Int32 resetPwmCtrlObj(
564 IcssgIepPwmCtrlObj *pIcssgIepPwmCtrlObj
565)
566{
567 Uint8 i;
568
569 for (i = 0; i < ICSSG_NUM_IEP; i++)
570 {
571 pIcssgIepPwmCtrlObj->iepPwmGblEn[i] = FALSE;
572 }
573
574 pIcssgIepPwmCtrlObj->pIcssgCfgHwRegs = (CSL_icss_g_pr1_cfg_slvRegs *)CSL_ICSS_CFG_BASE;
575 pIcssgIepPwmCtrlObj->pIepPwmCtrlFwRegs = (IepPwmCtrlFwRegs *)ICSSG_IEPPWM_PWM_CTRL_ADDR;
576 return IEP_STS_NERR;
577}
578
579/* Reset IEP PWM object */
580Int32 resetIepPwmObj(
581 IcssgIepPwmObj *pIcssgIepPwmObj,
582 IepId iepId
583)
584{
585 CSL_icss_g_pr1_cfg_slvRegs *pruIcssgCfg = (CSL_icss_g_pr1_cfg_slvRegs *)CSL_ICSS_CFG_BASE;
586 CSL_icss_g_pr1_iep1_slvRegs *pIepHwRegs;
587 volatile uint32_t *pIepCmpSr;
588 Uint8 pwmIdx;
589
590 memset(pIcssgIepPwmObj, 0, sizeof(IcssgIepPwmObj));
591 pIcssgIepPwmObj->iepId = iepId;
592 if (iepId == IEP_ID_0) {
593 pIcssgIepPwmObj->pIepPwmFwRegs = (IepPwmFwRegs *)ICSSG_PWM_IEP0_PWM_BASE_ADDR;
594 pIcssgIepPwmObj->pIepHwRegs = (CSL_icss_g_pr1_iep1_slvRegs *)ICSS_IEP0_CFG_BASE;
595 pIcssgIepPwmObj->pIepPwmTripHwRegs = (IepPwmTripHwRegs *)(&pruIcssgCfg->PWM0);
596 pIcssgIepPwmObj->pPwmStateCfgHwRegs = (IepPwmStateCfgHwRegs *)(&pruIcssgCfg->PWM0_0);
597 }
598 else if (iepId == IEP_ID_1) {
599 pIcssgIepPwmObj->pIepPwmFwRegs = (IepPwmFwRegs *)ICSSG_PWM_IEP1_PWM_BASE_ADDR;
600 pIcssgIepPwmObj->pIepHwRegs = (CSL_icss_g_pr1_iep1_slvRegs *)ICSS_IEP1_CFG_BASE;
601 pIcssgIepPwmObj->pIepPwmTripHwRegs = (IepPwmTripHwRegs *)(&pruIcssgCfg->PWM2);
602 pIcssgIepPwmObj->pPwmStateCfgHwRegs = (IepPwmStateCfgHwRegs *)(&pruIcssgCfg->PWM2_0);
603 }
604 else {
605 return IEP_STS_ERR_INV_IEP_ID;
606 }
607
608 pIepHwRegs = pIcssgIepPwmObj->pIepHwRegs;
609
610 /* Initialize CMP Shadow Register address table */
611 /* CMP1-6 */
612 pIepCmpSr = &pIepHwRegs->CMP1_REG1;
613 for (pwmIdx = 0; pwmIdx < SNGL_PWM_PER_SET; pwmIdx++)
614 {
615 pIcssgIepPwmObj->iepCmpSrAddr[pwmIdx] = pIepCmpSr;
616 pIepCmpSr += 2; /* CMP regs are 64 bit */
617 }
618 pIcssgIepPwmObj->iepCmpSrAddr[pwmIdx] = pIepCmpSr; /* CMP7 SR */
619 pIepCmpSr += 4; /* account for 64-bit gap in CMP register MM */
620 /* CMP7-12 */
621 for (pwmIdx = SNGL_PWM_PER_SET+1; pwmIdx < IEP_MAX_NUM_SNGL_PWM; pwmIdx++)
622 {
623 pIcssgIepPwmObj->iepCmpSrAddr[pwmIdx] = pIepCmpSr;
624 pIepCmpSr += 2; /* CMP regs are 64 bit */
625 }
626
627 return IEP_STS_NERR;
628}
629
630/* Wait for PWM enable flag from Host.
631 Flag indicates to FW that initialization can commence. */
632Int32 waitPwmEnFlag(
633 IcssgIepPwmCtrlObj *pIcssgIepPwmCtrlObj
634)
635{
636 IepPwmCtrlFwRegs *pIepPwmCtrlFwRegs = pIcssgIepPwmCtrlObj->pIepPwmCtrlFwRegs;
637 Uint8 pwmEn;
638
639 do {
640 pwmEn = (pIepPwmCtrlFwRegs->PWM_CTRL & PWM_CTRL_PWM_EN_MASK) >> PWM_CTRL_PWM_EN_SHIFT;
641 } while (pwmEn == BF_PWM_EN_DISABLE);
642
643 pIepPwmCtrlFwRegs->PWM_STAT |= BF_PWM_EN_ACK_ENABLE << PWM_STAT_PWM_EN_ACK_SHIFT; /* PWM_STAT:PWM_EN_ACK=1 */
644
645 return IEP_STS_NERR;
646}
647
648/* Initialize PWM FW control */
649Int32 initPwmCtrl(
650 IcssgIepPwmCtrlObj *pIcssgIepPwmCtrlObj
651)
652{
653 IepPwmCtrlFwRegs *pIepPwmCtrlFwRegs = pIcssgIepPwmCtrlObj->pIepPwmCtrlFwRegs;
654 volatile Uint32 iepClkReg;
655 Uint8 i;
656#ifdef IEP_SYNC_CLK_EN
657 Bool iepSync;
658#endif
659
660 for (i = 0; i < ICSSG_NUM_IEP; i++)
661 {
662 /* Latch IEP PWM global enable.
663 Global enable can't change after Initialization. */
664 pIcssgIepPwmCtrlObj->iepPwmGblEn[i] =
665 (Bool)((pIepPwmCtrlFwRegs->PWM_CTRL >> (PWM_CTRL_IEP0_PWM_GBL_EN_SHIFT+i) ) & IEP_PWM_GBL_EN_MASK);
666 /* Acknowledge IEP PWM global enable */
667 pIepPwmCtrlFwRegs->PWM_STAT |= (Uint32)pIcssgIepPwmCtrlObj->iepPwmGblEn[i] << (PWM_CTRL_IEP0_PWM_GBL_EN_SHIFT+i);
668 }
669
670#ifdef IEP_SYNC_CLK_EN
671 iepSync = TRUE;
672 for (i = 0; i < ICSSG_NUM_IEP; i++)
673 {
674 /* Update IEP clock synchronization flag.
675 All IEPs must be enabled for IEP clock synchronization to be enabled. */
676 iepSync = iepSync && pIcssgIepPwmCtrlObj->iepPwmGblEn[i];
677 }
678 if (iepSync == TRUE) {
679 /* Set IEP0 & 1 synchronization */
680
681 /* Read ICSSG_IEPCLK_REG HW register */
682 iepClkReg = pIcssgIepPwmCtrlObj->pIcssgCfgHwRegs->IEPCLK_REG;
683 /* ICSSG_IEPCLK_REG:IEP1_SLV_EN=0 */
684 iepClkReg &= ~CSL_ICSS_G_PR1_CFG_SLV_IEPCLK_REG_IEP1_SLV_EN_MASK;
685 /* ICSSG_IEPCLK_REG:IEP1_SLV_EN=1,
686 IEP1 Master Counter Slave enable is Enabled */
687 iepClkReg |= 1<< CSL_ICSS_G_PR1_CFG_SLV_IEPCLK_REG_IEP1_SLV_EN_SHIFT;
688 /* Write ICSSG_IEPCLK_REG HW register */
689 pIcssgIepPwmCtrlObj->pIcssgCfgHwRegs->IEPCLK_REG = iepClkReg;
690 }
691#endif
692
693 return IEP_STS_NERR;
694}
695
696/* Initialize IEP PWM object
697 *
698 * Initial Configuration is located in Host I/F FW Regs.
699 * Default Initial Configuration is loaded in DMEM load (static data).
700 * Host can overwrite Default Initial Configuration *before* FW execution.
701 *
702 * Initial Configuration Applied whether Host_RECFG != 0 or not, i.e. Host_RECFG not checked.
703 * Initial Configuration is only place PWM MODE is configured.
704*/
705Int32 initIepPwm(
706 IcssgIepPwmCtrlObj *pIcssgIepPwmCtrlObj,
707 IcssgIepPwmObj *pIcssgIepPwmObj
708)
709{
710 IepId iepId = pIcssgIepPwmObj->iepId;
711 IepPwmFwRegs *pIepPwmFwRegs = pIcssgIepPwmObj->pIepPwmFwRegs;
712 Uint16 iepPwmSnglEn;
713 Uint8 iepPwmDiffEn;
714 Int32 status = IEP_STS_NERR;
715
716 /* Latch IEP PWM global enable.
717 Global enable can't change after Initialization. */
718 /* Acknowledge IEP PWM global enable */
719
720 /* Configure PWMs */
721
722 if (pIcssgIepPwmCtrlObj->iepPwmGblEn[iepId] == TRUE) {
723 /* Latch IEP PWM mode.
724 IEP PWM mode can't change after Initialization. */
725 latchIepPwmMode(pIcssgIepPwmObj);
726
727 /* Update IEP Period Count */
728 updateIepPwmPeriodCount(pIcssgIepPwmObj);
729
730 /* Reset IEP0 CMPx.
731 - Set CMPx inside CMP0 period for 1/6 of PWMs in each Set. This forces PWM Set Initial->Active State.
732 - Set CMPx outside CMP0 period for other 5/6 PWMs in each Set. */
733 resetIepPwmCmpx(pIcssgIepPwmObj);
734
735 /* Initialize PWMs */
736 initPwm(pIcssgIepPwmObj);
737
738 /* Latch IEP PWM Enable */
739 latchIepPwmEn(pIcssgIepPwmObj);
740
741 /* Latch Period Count */
742 latchIepPwmPeriodCount(pIcssgIepPwmObj);
743
744 /* Latch IEP PWM Duty Cycle Counts */
745 latchIepPwmDcCounts(pIcssgIepPwmObj, FALSE);
746
747 /* Latch IEP PWM Deadband Counts */
748 latchIepPwmDbCount(pIcssgIepPwmObj, FALSE);
749
750 /* Calculate & Latch Single-Ended and Differential PWM Enable */
751 calcIepPwmSnglDiffEn(pIcssgIepPwmObj, &iepPwmSnglEn, &iepPwmDiffEn);
752 latchIepPwmSnglDiffEn(pIcssgIepPwmObj, iepPwmSnglEn, iepPwmDiffEn);
753
754 /* Calculate & Latch LHS/RHS Duty Cycle Counts */
755 calcAndLatchIepPwmDcLhsRhsCount(pIcssgIepPwmObj, FALSE);
756
757 /* Clear reconfiguration flags whether set or not */
758 pIepPwmFwRegs->IEP_PWM_RECFG = 0;
759 }
760
761 return status;
762}
763
764/* Set PWM FW initialization flag.
765 Flag indicates to Host that FW initialization is complete. */
766Int32 setPwmFwInitFlag(
767 IcssgIepPwmCtrlObj *pIcssgIepPwmCtrlObj
768)
769{
770 IepPwmCtrlFwRegs *pIepPwmCtrlFwRegs = pIcssgIepPwmCtrlObj->pIepPwmCtrlFwRegs;
771 pIepPwmCtrlFwRegs->PWM_STAT |= BF_PWM_FW_INIT_INIT << PWM_STAT_FW_INIT_SHIFT; /* PWM_STAT:FW_INIT=1 */
772
773 return IEP_STS_NERR;
774}
775
776/* Get IEP PWM State Machine configuration:
777 - IEP0 disabled, IEP1 disabled
778 - IEP0 disabled, IEP1 enabled
779 - IEP0 enabled, IEP1 disabled
780 - IEP0 enabled, IEP1 enabled */
781IepSm_Config getIepPwmSmConfig(
782 IcssgIepPwmCtrlObj *pIcssgIepPwmCtrlObj
783)
784{
785 Bool iep0PwmGblEn, iep1PwmGblEn;
786 IepSm_Config ret;
787
788
789 iep0PwmGblEn = pIcssgIepPwmCtrlObj->iepPwmGblEn[0];
790 iep1PwmGblEn = pIcssgIepPwmCtrlObj->iepPwmGblEn[1];
791
792 if (iep0PwmGblEn == FALSE) {
793 ret = (iep1PwmGblEn == FALSE) ? IEP_SM_CONFIG_NONE : IEP_SM_CONFIG_IEP1;
794 }
795 else {
796 ret = (iep1PwmGblEn == FALSE) ? IEP_SM_CONFIG_IEP0 : IEP_SM_CONFIG_IEP0_1;
797 }
798
799 return ret;
800}
801
802/* Initialize IEP PWM State Machine */
803void initIepPwmSm(
804 IcssgIepPwmObj *pIcssgIepPwmObj
805)
806{
807 pIcssgIepPwmObj->iepPwmState = IEP_SM_STATE_INIT;
808
809 /* Enable IEP Counter */
810 pIcssgIepPwmObj->pIepHwRegs->GLOBAL_CFG_REG |= 0x1;
811}
812
813/* Execute IEP PWM State Machine */
814Int32 execIepPwmSm(
815 IcssgIepPwmObj *pIcssgIepPwmObj,
816 Bool txHostEvt
817)
818{
819 CSL_icss_g_pr1_iep1_slvRegs *pIepHwRegs = pIcssgIepPwmObj->pIepHwRegs;
820 uint32_t cmpStatus;
821 Int32 status = IEP_STS_NERR;
822
823 cmpStatus = pIepHwRegs->CMP_STATUS_REG;
824 if (pIcssgIepPwmObj->iepPwmState == IEP_SM_STATE_INIT) {
825 if ((cmpStatus & IEP_CMP_STATUS_CMP0_MASK) == IEP_CMP_STATUS_CMP0_MASK) { /* CMP0 event has occurred */
826 pIepHwRegs->CMP_STATUS_REG = IEP_CMP_STATUS_CMP0_12_MASK; /* clear CMP0-12 events */
827#ifdef TX_HOST_INT
828 if (txHostEvt == TRUE) {
829 __R31 = 16 + TRIGGER_HOST_EVT; /* trigger Host interrupt on IEP CMP0 event */
830 }
831#endif
832
833 /* Initialize IEP PWM CMPx Shadow Registers */
834 status = initIepPwmCmpxShReg(pIcssgIepPwmObj);
835
836 if (status == IEP_STS_NERR) {
837 /* Update State to Left-Hand Side */
838 pIcssgIepPwmObj->iepPwmState = IEP_SM_STATE_LHS;
839 }
840 else {
841 /* Update state to Left-Hand Side (Host) Reconfiguration */
842 pIcssgIepPwmObj->iepPwmState = IEP_SM_STATE_LHS_RECFG;
843 }
844 }
845 }
846 if (pIcssgIepPwmObj->iepPwmState == IEP_SM_STATE_LHS) {
847 if ((cmpStatus & IEP_CMP_STATUS_CMP0_MASK) == IEP_CMP_STATUS_CMP0_MASK) { /* CMP0 event has occurred */
848 pIepHwRegs->CMP_STATUS_REG = IEP_CMP_STATUS_CMP0_12_MASK; /* clear CMP0-12 events */
849#ifdef TX_HOST_INT
850 if (txHostEvt == TRUE) {
851 __R31 = 16 + TRIGGER_HOST_EVT; /* trigger Host interrupt on IEP CMP0 event */
852 }
853#endif
854 /* Perform LHS processing */
855 iepPwmLhs(pIcssgIepPwmObj);
856
857 /* Update state to Left-Hand Side (Host) Reconfiguration */
858 pIcssgIepPwmObj->iepPwmState = IEP_SM_STATE_LHS_RECFG;
859 }
860 }
861 else if (pIcssgIepPwmObj->iepPwmState == IEP_SM_STATE_RHS) {
862 if ((cmpStatus & IEP_CMP_STATUS_CMP0_MASK) == IEP_CMP_STATUS_CMP0_MASK) { /* CMP0 event has occurred */
863 pIepHwRegs->CMP_STATUS_REG = IEP_CMP_STATUS_CMP0_12_MASK; /* clear CMP0-12 events */
864#ifdef TX_HOST_INT
865 if (txHostEvt == TRUE) {
866 __R31 = 16 + TRIGGER_HOST_EVT; /* trigger Host interrupt on IEP CMP0 event */
867 }
868#endif
869
870 /* Perform RHS processing */
871 iepPwmRhs(pIcssgIepPwmObj);
872
873 /* Update state to Right-Hand Side Reconfiguration */
874 pIcssgIepPwmObj->iepPwmState = IEP_SM_STATE_RHS_RECFG;
875 }
876 }
877 else if (pIcssgIepPwmObj->iepPwmState == IEP_SM_STATE_LHS_RECFG) {
878 /* Perform PWM reconfiguration, if requested by Host.
879 Reconfiguration can only occur at start of PWM cycle after LHS.
880 Reconfiguration actions:
881 - PRU FW updates internal state using information in Host I/F FW Regs corresponding to RECFG bit mask.
882 - PRU FW performs required writes to HW registers.
883 */
884
885 /* Perform LHS reconfiguration */
886 status = iepPwmConfigLhs(pIcssgIepPwmObj);
887
888 if (status < 0) {
889 /* Update state to Left-Hand Side (Host) Reconfiguration */
890 pIcssgIepPwmObj->iepPwmState = IEP_SM_STATE_LHS_RECFG;
891 }
892 else if (status == IEP_STS_NERR) {
893 /* Update state to Right-Hand Side */
894 pIcssgIepPwmObj->iepPwmState = IEP_SM_STATE_RHS;
895 }
896 else { /* IEP_STS_RECFG_PRD_COUNT */
897 /* Update State to Init */
898 pIcssgIepPwmObj->iepPwmState = IEP_SM_STATE_INIT;
899 }
900 }
901 else if (pIcssgIepPwmObj->iepPwmState == IEP_SM_STATE_RHS_RECFG) {
902 /* Perform PWM RHS reconfiguration, if required by pending Host reconfiguration request.
903 Reconfiguration can only occur in middle of PWM cycle before RHS.
904 Reconfiguration actions:
905 - PRU FW updates internal state.
906 - PRU FW performs required writes to HW registers.
907 */
908
909 /* Perform RHS reconfiguration */
910 status = iepPwmConfigRhs(pIcssgIepPwmObj);
911
912 if (status == IEP_STS_NERR) {
913 /* Update State to Left-Hand Side */
914 pIcssgIepPwmObj->iepPwmState = IEP_SM_STATE_LHS;
915 }
916 else {
917 /* Update state to Left-Hand Side (Host) Reconfiguration */
918 pIcssgIepPwmObj->iepPwmState = IEP_SM_STATE_LHS_RECFG;
919 }
920 }
921
922 return status;
923}
924
925
926/* ------------------------------------------------------------------------- *
927 * Private Functions *
928 * ------------------------------------------------------------------------- */
929
930/* State Machine function, perform LHS processing */
931static void iepPwmLhs(
932 IcssgIepPwmObj *pIcssgIepPwmObj
933)
934{
935 Uint32 *pIepPwmDcCount;
936 Uint16 *pIepPwmDbCount;
937 volatile uint32_t *pShadowReg;
938 Uint8 pwmIdx, dPwmIdx;
939
940 /* Process Left-Hand Side CMP Shadow Registers */
941
942 /* Process Single-Ended PWMs */
943 pIepPwmDcCount = &pIcssgIepPwmObj->iepPwmDcCountLhs[0]; /* init pointer to PWM Duty Cycle Count */
944 for (pwmIdx = 0; pwmIdx < IEP_MAX_NUM_SNGL_PWM; pwmIdx++)
945 {
946 if (((pIcssgIepPwmObj->iepPwmSnglUpdEn >> pwmIdx) & 0x1) == 1) { /* check PWM update enabled */
947 /* Write to CMP SR for PWM */
948 pShadowReg = pIcssgIepPwmObj->iepCmpSrAddr[pwmIdx]; /* set pointer to CMP Shadow Register */
949 *pShadowReg = pIcssgIepPwmObj->iepPwmPeriodCount - *pIepPwmDcCount;
950 }
951 pIepPwmDcCount++;
952 }
953
954 /* Process Differential PWMs */
955 pIepPwmDcCount = &pIcssgIepPwmObj->iepPwmDcCountLhs[0]; /* init pointer to PWM Duty Cycle Count */
956 pIepPwmDbCount = &pIcssgIepPwmObj->iepPwmDbCount[0]; /* init pointer to PWM Deadband Count */
957 for (dPwmIdx = 0; dPwmIdx < IEP_MAX_NUM_DIFF_PWM; dPwmIdx++)
958 {
959 if (((pIcssgIepPwmObj->iepPwmDiffUpdEn >> dPwmIdx) & 0x1) == 1) { /* check PWM update enabled */
960 /* Write CMP SR for POS PWM */
961 pwmIdx = dPwmIdx << 1;
962 pShadowReg = pIcssgIepPwmObj->iepCmpSrAddr[pwmIdx]; /* set pointer to CMP Shadow Register */
963 *pShadowReg = pIcssgIepPwmObj->iepPwmPeriodCount - *pIepPwmDcCount;
964 /* Write CMP SR for NEG PWM.
965 Increment CMP SR pointer by 2 since CMP registers are 64 bit. */
966 pwmIdx++;
967 pShadowReg = pIcssgIepPwmObj->iepCmpSrAddr[pwmIdx]; /* set pointer to CMP Shadow Register */
968 *pShadowReg = pIcssgIepPwmObj->iepPwmPeriodCount - *pIepPwmDcCount - *pIepPwmDbCount;
969 }
970 pIepPwmDcCount += 2; /* differential pair use same Duty Cycle Count */
971 pIepPwmDbCount++;
972 }
973}
974
975/* State Machine function, perform RHS processing */
976static void iepPwmRhs(
977 IcssgIepPwmObj *pIcssgIepPwmObj
978)
979{
980 Uint32 *pIepPwmDcCount;
981 Uint16 *pIepPwmDbCount;
982 volatile uint32_t *pShadowReg;
983 Uint8 pwmIdx, dPwmIdx;
984
985 /* Process Right-Hand Side CMP Shadow Registers */
986
987 /* Process Single-Ended PWMs */
988 pIepPwmDcCount = &pIcssgIepPwmObj->iepPwmDcCountRhs[0]; /* init pointer to PWM Duty Cycle Count */
989 for (pwmIdx = 0; pwmIdx < IEP_MAX_NUM_SNGL_PWM; pwmIdx++)
990 {
991 if (((pIcssgIepPwmObj->iepPwmSnglUpdEn >> pwmIdx) & 0x1) == 1) { /* check PWM update enabled */
992 /* Write to CMP SR for PWM */
993 pShadowReg = pIcssgIepPwmObj->iepCmpSrAddr[pwmIdx]; /* set pointer to CMP Shadow Register */
994 *pShadowReg = *pIepPwmDcCount;
995 }
996 pIepPwmDcCount++;
997 pShadowReg += 2; /* CMP registers are 64 bit */
998 }
999
1000 /* Process Differential PWMs */
1001 pIepPwmDcCount = &pIcssgIepPwmObj->iepPwmDcCountRhs[0]; /* init pointer to PWM Duty Cycle Count */
1002 pIepPwmDbCount = &pIcssgIepPwmObj->iepPwmDbCount[0]; /* init pointer to PWM Deadband Count */
1003 for (dPwmIdx = 0; dPwmIdx < IEP_MAX_NUM_DIFF_PWM; dPwmIdx++)
1004 {
1005 if (((pIcssgIepPwmObj->iepPwmDiffUpdEn >> dPwmIdx) & 0x1) == 1) { /* check PWM update enabled */
1006 /* Write CMP SR for POS PWM */
1007 pwmIdx = dPwmIdx << 1;
1008 pShadowReg = pIcssgIepPwmObj->iepCmpSrAddr[pwmIdx]; /* set pointer to CMP Shadow Register */
1009 *pShadowReg = *pIepPwmDcCount;
1010 /* Write CMP SR for NEG PWM.
1011 Increment CMP SR pointer by 2 since CMP registers are 64 bit. */
1012 pwmIdx++;
1013 pShadowReg = pIcssgIepPwmObj->iepCmpSrAddr[pwmIdx]; /* set pointer to CMP Shadow Register */
1014 *pShadowReg = *pIepPwmDcCount + *pIepPwmDbCount;
1015 }
1016 pIepPwmDcCount += 2; /* differential pair use same Duty Cycle Count */
1017 pIepPwmDbCount++;
1018 }
1019}
1020
1021/* State Machine function, perform LHS reconfiguration.
1022 Check Host reconfiguration request.
1023 Perform Initialization reconfiguration. */
1024static Int32 iepPwmConfigLhs(
1025 IcssgIepPwmObj *pIcssgIepPwmObj
1026)
1027{
1028 IepPwmFwRegs *pIepPwmFwRegs = pIcssgIepPwmObj->pIepPwmFwRegs;
1029 CSL_icss_g_pr1_iep1_slvRegs *pIepHwRegs = pIcssgIepPwmObj->pIepHwRegs;
1030 Uint16 iepPwmSnglEn;
1031 Uint8 iepPwmDiffEn;
1032 Int32 status = IEP_STS_NERR;
1033
1034 /* Check for Host reconfiguration request.
1035 Host reconfiguration isn't allowed during Initialization. */
1036
1037 if (pIepPwmFwRegs->IEP_PWM_RECFG != 0) {
1038 /* Perform LHS Reconfiguration */
1039
1040 if (pIepPwmFwRegs->IEP_PWM_RECFG & IEP_PWM_RECFG_RECFG_IEP_PWM_PRD_COUNT_MASK) {
1041 /* PWM Period Count reconfiguration -- affects all PWM for IEP.
1042 Note: reconfiguration flag is cleared below because of
1043 dependencies on other reconfigurations on Period Count
1044 reconfiguration.
1045 */
1046
1047 /* Update IEP PWM Period Count */
1048 updateIepPwmPeriodCount(pIcssgIepPwmObj);
1049
1050 /* Reset IEP0 CMPx.
1051 - Set CMPx inside CMP0 period for 1/6 of PWMs in each Set. This forces PWM Set Initial->Active State.
1052 - Set CMPx outside CMP0 period for other 5/6 PWMs in each Set. */
1053 resetIepPwmCmpx(pIcssgIepPwmObj);
1054
1055 /* Re-initialize PWMs.
1056 Place PWMs in Init State. */
1057 reinitPwm(pIcssgIepPwmObj);
1058
1059 if (pIepPwmFwRegs->IEP_PWM_RECFG & IEP_PWM_RECFG_RECFG_IEP_PWM_EN_MASK) {
1060
1061 /* Latch IEP PWM Enable */
1062 latchIepPwmEn(pIcssgIepPwmObj);
1063
1064 /* Calculate & Latch Single-Ended and Differential PWM Enable */
1065 calcIepPwmSnglDiffEn(pIcssgIepPwmObj, &iepPwmSnglEn, &iepPwmDiffEn);
1066 latchIepPwmSnglDiffEn(pIcssgIepPwmObj, iepPwmSnglEn, iepPwmDiffEn);
1067
1068 pIepPwmFwRegs->IEP_PWM_RECFG &= ~IEP_PWM_RECFG_RECFG_IEP_PWM_EN_MASK;
1069 }
1070
1071 if (pIepPwmFwRegs->IEP_PWM_RECFG & IEP_PWM_RECFG_RECFG_IEP_PWM_DC_COUNT_MASK) {
1072 /* Latch IEP PWM Duty Cycle Counts */
1073 latchIepPwmDcCounts(pIcssgIepPwmObj, TRUE);
1074
1075 /* Calculate & Latch LHS/RHS Duty Cycle Counts */
1076 calcAndLatchIepPwmDcLhsRhsCount(pIcssgIepPwmObj, FALSE);
1077
1078 pIepPwmFwRegs->IEP_PWM_RECFG &= ~IEP_PWM_RECFG_RECFG_IEP_PWM_DC_COUNT_MASK;
1079 }
1080
1081 /* Set return status so State Machine executes INIT state */
1082 status = IEP_STS_RECFG_PRD_COUNT;
1083 }
1084 else {
1085 /* Enable/Disable & DC Count reconfiguration.
1086 Enable and DC Count reconfiguration must be handled jointly.
1087
1088 Skip this reconfiguration if Period Count reconfigured
1089 since all CMPx already updated as part of Period Count reconfiguration.
1090 */
1091 if (pIepPwmFwRegs->IEP_PWM_RECFG & (IEP_PWM_RECFG_RECFG_IEP_PWM_EN_MASK | IEP_PWM_RECFG_RECFG_IEP_PWM_DC_COUNT_MASK)) {
1092 /* PWM Enable and Duty Cycle Count reconfiguration.
1093 Update IEP PWM CMPx Shadow Registers. */
1094 updateIepPwmCmpxShRegPwmEnDc(pIcssgIepPwmObj);
1095
1096 if (pIepPwmFwRegs->IEP_PWM_RECFG & IEP_PWM_RECFG_RECFG_IEP_PWM_EN_MASK) {
1097 pIepPwmFwRegs->IEP_PWM_RECFG &= ~IEP_PWM_RECFG_RECFG_IEP_PWM_EN_MASK;
1098 }
1099 if (pIepPwmFwRegs->IEP_PWM_RECFG & IEP_PWM_RECFG_RECFG_IEP_PWM_DC_COUNT_MASK) {
1100 pIepPwmFwRegs->IEP_PWM_RECFG &= ~IEP_PWM_RECFG_RECFG_IEP_PWM_DC_COUNT_MASK;
1101 }
1102 }
1103 }
1104
1105 if (pIepPwmFwRegs->IEP_PWM_RECFG & IEP_PWM_RECFG_RECFG_IEP_PWM_DB_COUNT_MASK) {
1106 /* PWM Deadband Count reconfiguration.
1107 Update IEP PWM CMPx Shadow Registers. */
1108 updateIepPwmCmpxShRegDb(pIcssgIepPwmObj);
1109
1110 pIepPwmFwRegs->IEP_PWM_RECFG &= ~IEP_PWM_RECFG_RECFG_IEP_PWM_DB_COUNT_MASK;
1111 }
1112
1113 if (pIepPwmFwRegs->IEP_PWM_RECFG & IEP_PWM_RECFG_RECFG_IEP_PWM_PRD_COUNT_MASK) {
1114 /* Latch Period */
1115 latchIepPwmPeriodCount(pIcssgIepPwmObj);
1116 /* Enable IEP0 Counter */
1117 pIepHwRegs->GLOBAL_CFG_REG |= 0x1;
1118
1119 pIepPwmFwRegs->IEP_PWM_RECFG &= ~IEP_PWM_RECFG_RECFG_IEP_PWM_PRD_COUNT_MASK;
1120 }
1121 }
1122
1123 return status;
1124}
1125
1126/* State Machine Function, perform RHS reconfiguration.
1127 Apply pending Host reconfiguration request.
1128 Perform Initialization reconfiguration.
1129
1130 IEP PWM object has private information required to perform RHS update.
1131 This information is set appropriately in LHS (Host) Reconfiguration. */
1132static Int32 iepPwmConfigRhs(
1133 IcssgIepPwmObj *pIcssgIepPwmObj
1134)
1135{
1136 Int32 status = IEP_STS_NERR;
1137
1138 if (pIcssgIepPwmObj->iepPwmRhsRecfgFlag == TRUE) {
1139 /* Perform RHS Reconfiguration for pending Host reconfiguration */
1140 execRhsActionStash(pIcssgIepPwmObj);
1141
1142 pIcssgIepPwmObj->iepPwmRhsRecfgFlag = FALSE;
1143 }
1144
1145 return status;
1146}
1147
1148/* Latch IEP PWM mode.
1149 IEP PWM mode can't change after Initialization. */
1150static void latchIepPwmMode(
1151 IcssgIepPwmObj *pIcssgIepPwmObj
1152)
1153{
1154 IepPwmFwRegs *pIepPwmFwRegs = pIcssgIepPwmObj->pIepPwmFwRegs;
1155 pIcssgIepPwmObj->iepPwmMode = pIepPwmFwRegs->IEP_PWM_MODE;
1156}
1157
1158/* Update IEP Period Count */
1159static void updateIepPwmPeriodCount(
1160 IcssgIepPwmObj *pIcssgIepPwmObj
1161)
1162{
1163 IepPwmFwRegs *pIepPwmFwRegs = pIcssgIepPwmObj->pIepPwmFwRegs;
1164 CSL_icss_g_pr1_iep1_slvRegs *pIepHwRegs = pIcssgIepPwmObj->pIepHwRegs;
1165
1166 /* Disable IEP Counter */
1167 pIepHwRegs->GLOBAL_CFG_REG &= ~(0x1);
1168 //HW_WR_FIELD32(pIepHwRegs->GLOBAL_CFG_REG, CSL_ICSS_G_PR1_IEP1_SLV_GLOBAL_CFG_REG_CNT_ENABLE, ~(0x1)); // *** CSL call
1169
1170 /* Set Counter value to 1 */
1171 pIepHwRegs->COUNT_REG0 = 0x1;
1172 pIepHwRegs->COUNT_REG1 = 0;
1173 //HW_WR_REG32(pIepHwRegs->COUNT_REG0, 0x1); // *** CSL call
1174 //HW_WR_REG32(pIepHwRegs->COUNT_REG1, 0x0); // *** CSL call
1175
1176 /* Clear shadow mode in order to be able to write to the Active registers */
1177 pIepHwRegs->CMP_CFG_REG &= ~(0x1 << CSL_ICSS_G_PR1_IEP1_SLV_CMP_CFG_REG_SHADOW_EN_SHIFT);
1178
1179 /* Load the Period Shadow/Active registers */
1180 pIepHwRegs->CMP0_REG0 = pIepPwmFwRegs->IEP_PWM_PRD_COUNT - DEF_COUNT_INC_PER_CLK;
1181 pIepHwRegs->CMP0_REG1 = pIepPwmFwRegs->IEP_PWM_PRD_COUNT - DEF_COUNT_INC_PER_CLK;
1182
1183 /* Enable Shadow Mode */
1184 pIepHwRegs->CMP_CFG_REG |= (0x1 << CSL_ICSS_G_PR1_IEP1_SLV_CMP_CFG_REG_SHADOW_EN_SHIFT);
1185
1186 /* Clear CMP0 Compare Events */
1187 pIepHwRegs->CMP_STATUS_REG = 0x1;
1188
1189 /* Enable Counter Reset on CMP0 event */
1190 /* Enable CMP0 Compare Events */
1191 pIepHwRegs->CMP_CFG_REG |= (0x1 << CSL_ICSS_G_PR1_IEP1_SLV_CMP_CFG_REG_CMP0_RST_CNT_EN_SHIFT
1192 | (0x1 << CSL_ICSS_G_PR1_IEP1_SLV_CMP_CFG_REG_CMP_EN_SHIFT));
1193}
1194
1195/* Reset IEP CMPx.
1196 - Set CMPx inside CMP0 period for 1/6 of PWMs in each Set. This forces PWM Set Initial->Active State.
1197 - Set CMPx outside CMP0 period for other 5/6 PWMs in each Set. */
1198static void resetIepPwmCmpx(
1199 IcssgIepPwmObj *pIcssgIepPwmObj
1200)
1201{
1202 IepPwmFwRegs *pIepPwmFwRegs = pIcssgIepPwmObj->pIepPwmFwRegs;
1203 CSL_icss_g_pr1_iep1_slvRegs *pIepHwRegs = pIcssgIepPwmObj->pIepHwRegs;
1204 volatile Uint32 *pIepCmpReg;
1205 Uint8 pwmIdx;
1206
1207 /* Clear shadow mode in order to be able to write to the Active registers */
1208 pIepHwRegs->CMP_CFG_REG &= ~(0x1 << CSL_ICSS_G_PR1_IEP1_SLV_CMP_CFG_REG_SHADOW_EN_SHIFT);
1209
1210 /* Set 0 PWMs */
1211 pIepCmpReg = &pIepHwRegs->CMP1_REG0;
1212 for (pwmIdx = 0; pwmIdx < SNGL_PWM_PER_SET; pwmIdx++)
1213 {
1214 *pIepCmpReg = pIepPwmFwRegs->IEP_PWM_PRD_COUNT+5; /* outside period */
1215 pIepCmpReg++;
1216 *pIepCmpReg = pIepPwmFwRegs->IEP_PWM_PRD_COUNT+5; /* outside period */
1217 pIepCmpReg++;
1218 }
1219 pIepCmpReg = &pIepHwRegs->CMP1_REG0 + (SACR_PWM_IDX << 1);
1220 *pIepCmpReg = pIepPwmFwRegs->IEP_PWM_PRD_COUNT/2; /* inside period for "sacrificial" toggle */
1221 pIepCmpReg++;
1222 *pIepCmpReg = pIepPwmFwRegs->IEP_PWM_PRD_COUNT/2; /* inside period for "sacrificial" toggle */
1223
1224 /* Set 1 PWMs */
1225 pIepHwRegs->CMP7_REG0 = pIepPwmFwRegs->IEP_PWM_PRD_COUNT+5; /* inside period for "sacrificial" toggle */
1226 pIepHwRegs->CMP7_REG1 = pIepPwmFwRegs->IEP_PWM_PRD_COUNT+5; /* inside period for "sacrificial" toggle */
1227 pIepCmpReg = &pIepHwRegs->CMP8_REG0;
1228 for (pwmIdx = 1; pwmIdx < SNGL_PWM_PER_SET; pwmIdx++)
1229 {
1230 *pIepCmpReg = pIepPwmFwRegs->IEP_PWM_PRD_COUNT+5; /* outside period */
1231 pIepCmpReg++;
1232 *pIepCmpReg = pIepPwmFwRegs->IEP_PWM_PRD_COUNT+5; /* outside period */
1233 pIepCmpReg++;
1234 }
1235 if (SACR_PWM_IDX != 0) {
1236 pIepCmpReg = &pIepHwRegs->CMP8_REG0 + ((SACR_PWM_IDX-1) << 1);
1237 }
1238 else {
1239 pIepCmpReg = &pIepHwRegs->CMP7_REG0;
1240 }
1241 *pIepCmpReg = pIepPwmFwRegs->IEP_PWM_PRD_COUNT/2; /* inside period for "sacrificial" toggle */
1242 pIepCmpReg++;
1243 *pIepCmpReg = pIepPwmFwRegs->IEP_PWM_PRD_COUNT/2; /* inside period for "sacrificial" toggle */
1244
1245 /* Enable Shadow Mode */
1246 pIepHwRegs->CMP_CFG_REG |= (0x1 << CSL_ICSS_G_PR1_IEP1_SLV_CMP_CFG_REG_SHADOW_EN_SHIFT);
1247
1248 /* Clear CMP1-12 Compare Events */
1249 pIepHwRegs->CMP_STATUS_REG = 0x1FFE;
1250
1251 /* Enable CMP1-12 Compare Events */
1252 pIepHwRegs->CMP_CFG_REG |= (0x1FFE << 1);
1253
1254 /* Reset Single-Ended and Differential PWM Update Enable */
1255 pIcssgIepPwmObj->iepPwmDiffUpdEn = 0;
1256 pIcssgIepPwmObj->iepPwmSnglUpdEn = 0;
1257}
1258
1259/* Initialize PWMs */
1260static void initPwm(
1261 IcssgIepPwmObj *pIcssgIepPwmObj
1262)
1263{
1264 IepPwmTripHwRegs *pIepPwmTripHwRegs = pIcssgIepPwmObj->pIepPwmTripHwRegs;
1265 IepPwmStateCfgHwRegs *pPwmStateCfgHwRegs = pIcssgIepPwmObj->pPwmStateCfgHwRegs;
1266 volatile Uint32 *pPwmStateCfgReg;
1267 Uint8 i, j, dPwmIdx;
1268 Uint8 offset, regOffset;
1269 Uint32 pwmStateCfgReg;
1270
1271 /* Default state */
1272 pIepPwmTripHwRegs->ICSSG_PWM0 = 0; /* PWM 0-5 */
1273 pIepPwmTripHwRegs->ICSSG_PWM1 = 0; /* PWM 6-11 */
1274
1275 /* Configure PWM (Active, Trip, Init) State.
1276 - ICSSG_PWM0_0,1,2
1277 - ICSSG_PWM1_0,1,2 */
1278 pPwmStateCfgReg = &pPwmStateCfgHwRegs->ICSSG_PWM0_0;
1279 for (i = 0; i < IEP_NUM_PWM_SET; i++)
1280 {
1281 dPwmIdx = i * DIFF_PWM_PER_SET;
1282 for (j = 0; j < DIFF_PWM_PER_SET; j++)
1283 {
1284 if ((pIcssgIepPwmObj->iepPwmMode >> (dPwmIdx+j)) & 0x1) {
1285 /* Differential PWMs */
1286 *pPwmStateCfgReg = DIFF_PWM_STATE_INIT;
1287 }
1288 else {
1289 /* Single-Ended PWMs */
1290 *pPwmStateCfgReg = SNGL_PWM_STATE_INIT;
1291 }
1292 pPwmStateCfgReg++;
1293 }
1294 }
1295
1296 /* Update PWM State configuration for "sacrificial" PWMs.
1297 * Index of sacrificial PWM is the same for both PWM Sets.
1298 * Sacrificial PWM initial state is normal PWM state inverted.
1299 *
1300 * Index Sacrificial PWM PWM State Config Reg Bits in Config Reg Bits to Write, SE PWM Bits to Write, Diff PWM
1301 * 0 0 0-1 10b (INIT HI) 10b (INIT HI)
1302 * 1 0 2-3 10b (INIT HI) 01b (INIT LO)
1303 * 2 1 0-1 10b (INIT HI) 10b (INIT HI)
1304 * 3 1 2-3 10b (INIT HI) 01b (INIT LO)
1305 * 4 2 0-1 10b (INIT HI) 10b (INIT HI)
1306 * 5 2 2-3 10b (INIT HI) 01b (INIT LO)
1307 */
1308 /* Set 0 */
1309 dPwmIdx = SACR_PWM_IDX/2;
1310 offset = SACR_PWM_IDX & 0x1;
1311 regOffset = offset << 1;
1312 pPwmStateCfgReg = &pPwmStateCfgHwRegs->ICSSG_PWM0_0 + dPwmIdx;
1313 pwmStateCfgReg = *pPwmStateCfgReg;
1314 pwmStateCfgReg &= ~(0x3 << regOffset);
1315 if ((pIcssgIepPwmObj->iepPwmMode >> dPwmIdx) & 0x1) {
1316 /* Differential PWM */
1317 if (offset & 0x1) {
1318 pwmStateCfgReg |= (PWM_INIT_LO << regOffset);
1319 }
1320 else {
1321 pwmStateCfgReg |= (PWM_INIT_HI << regOffset);
1322 }
1323 }
1324 else {
1325 /* Single-Ended PWM */
1326 pwmStateCfgReg |= (PWM_INIT_HI << regOffset);
1327 }
1328 *pPwmStateCfgReg = pwmStateCfgReg; /* write config */
1329 /* Set 1 */
1330 dPwmIdx = DIFF_PWM_PER_SET + SACR_PWM_IDX/2;
1331 offset = SACR_PWM_IDX & 0x1;
1332 regOffset = offset << 1;
1333 pPwmStateCfgReg = &pPwmStateCfgHwRegs->ICSSG_PWM0_0 + dPwmIdx;
1334 pwmStateCfgReg = *pPwmStateCfgReg;
1335 pwmStateCfgReg &= ~(0x3 << regOffset);
1336 if ((pIcssgIepPwmObj->iepPwmMode >> dPwmIdx) & 0x1) {
1337 /* Differential PWM */
1338 if (offset & 0x1) {
1339 pwmStateCfgReg |= (PWM_INIT_LO << regOffset);
1340 }
1341 else {
1342 pwmStateCfgReg |= (PWM_INIT_HI << regOffset);
1343 }
1344 }
1345 else {
1346 /* Single-Ended PWM */
1347 pwmStateCfgReg |= (PWM_INIT_HI << regOffset);
1348 }
1349 *pPwmStateCfgReg = pwmStateCfgReg; /* write config */
1350
1351 /* Create a trip reset event to put all signals into the Init state */
1352 pIepPwmTripHwRegs->ICSSG_PWM0 = PWM_TRIP_RESET_MASK; /* PWM 0-5 */
1353 pIepPwmTripHwRegs->ICSSG_PWM1 = PWM_TRIP_RESET_MASK; /* PWM 6-11 */
1354 /* Clear the trip event to allow signals to leave the init state (when a CMP occurs) */
1355 pIepPwmTripHwRegs->ICSSG_PWM0 = 0; /* PWM 0-5 */
1356 pIepPwmTripHwRegs->ICSSG_PWM1 = 0; /* PWM 6-11 */
1357}
1358
1359/* Reinitialize PWMs */
1360static void reinitPwm(
1361 IcssgIepPwmObj *pIcssgIepPwmObj
1362)
1363{
1364 IepPwmTripHwRegs *pIepPwmTripHwRegs = pIcssgIepPwmObj->pIepPwmTripHwRegs;
1365
1366 /* Create a trip reset event to put all signals into the Init state */
1367 pIepPwmTripHwRegs->ICSSG_PWM0 = PWM_TRIP_RESET_MASK; /* PWM 0-5 */
1368 pIepPwmTripHwRegs->ICSSG_PWM1 = PWM_TRIP_RESET_MASK; /* PWM 6-11 */
1369 /* Clear the trip event to allow signals to leave the init state (when a CMP occurs) */
1370 pIepPwmTripHwRegs->ICSSG_PWM0 = 0; /* PWM 0-5 */
1371 pIepPwmTripHwRegs->ICSSG_PWM1 = 0; /* PWM 6-11 */
1372}
1373
1374/* Latch IEP PWM Enable */
1375static void latchIepPwmEn(
1376 IcssgIepPwmObj *pIcssgIepPwmObj
1377)
1378{
1379 IepPwmFwRegs *pIepPwmFwRegs = pIcssgIepPwmObj->pIepPwmFwRegs;
1380 pIcssgIepPwmObj->iepPwmEn = pIepPwmFwRegs->IEP_PWM_EN;
1381}
1382
1383/* Latch IEP PWM Period Count */
1384static void latchIepPwmPeriodCount(
1385 IcssgIepPwmObj *pIcssgIepPwmObj
1386)
1387{
1388 IepPwmFwRegs *pIepPwmFwRegs = pIcssgIepPwmObj->pIepPwmFwRegs;
1389 pIcssgIepPwmObj->iepPwmPeriodCount = pIepPwmFwRegs->IEP_PWM_PRD_COUNT;
1390}
1391
1392/* Latch IEP PWM Duty Cycle Counts */
1393static void latchIepPwmDcCounts(
1394 IcssgIepPwmObj *pIcssgIepPwmObj,
1395 Bool recfgFlag
1396)
1397{
1398 IepPwmFwRegs *pIepPwmFwRegs = pIcssgIepPwmObj->pIepPwmFwRegs;
1399 volatile Uint32 *pIepPwmDcCount;
1400 Uint16 recfgDcCount;
1401 Uint8 dPwmIdx, pwmIdx;
1402
1403 if (recfgFlag == TRUE) {
1404 /* Get Duty Cycle reconfiguration */
1405 recfgDcCount = (pIepPwmFwRegs->IEP_PWM_RECFG & IEP_PWM_RECFG_RECFG_IEP_PWM_DC_COUNT_MASK) >> IEP_PWM_RECFG_RECFG_IEP_PWM_DC_COUNT_SHIFT;
1406 }
1407 else {
1408 /* Set Duty Cycle reconfiguration reconfiguration to full mask */
1409 recfgDcCount = IEP_PWM_RECFG_RECFG_IEP_PWM_DC_COUNT_MASK >> IEP_PWM_RECFG_RECFG_IEP_PWM_DC_COUNT_SHIFT;
1410 }
1411
1412 /* Compute LHS/RHS Duty Cycle counts */
1413 pIepPwmDcCount = &pIepPwmFwRegs->IEP_PWM0_DC_COUNT; /* Init pointer to IEP PWM Duty Cycle Count */
1414 for (dPwmIdx = 0; dPwmIdx < IEP_MAX_NUM_DIFF_PWM; dPwmIdx++)
1415 {
1416 pwmIdx = dPwmIdx << 1;
1417 if ((pIcssgIepPwmObj->iepPwmMode >> dPwmIdx) & 0x1) {
1418 /* Differential PWM */
1419
1420 /* Check if reconfiguration bit set.
1421 For Differential PWM, only "even" reconfiguration bits checked for each PWM pair. */
1422 if ((recfgDcCount >> pwmIdx) & 0x1) {
1423 /* LHS 2*i, POS/NEG */
1424 pIcssgIepPwmObj->iepPwmDcCount[pwmIdx] = *pIepPwmDcCount;
1425 }
1426 }
1427 else {
1428 /* Single-Ended PWM */
1429
1430 /* Check if reconfiguration bit set.
1431 For Single-Ended PWM, all reconfiguration bits checked. */
1432 if ((recfgDcCount >> pwmIdx) & 0x1) {
1433 /* LHS 2*i, POS */
1434 pIcssgIepPwmObj->iepPwmDcCount[pwmIdx] = *pIepPwmDcCount;
1435 }
1436 if ((recfgDcCount >> (pwmIdx+1)) & 0x1) {
1437 /* LHS 2*i+1, NEG */
1438 pIcssgIepPwmObj->iepPwmDcCount[pwmIdx+1] = *(pIepPwmDcCount+1);
1439 }
1440 }
1441
1442 pIepPwmDcCount += 2; /* update pointer to IEP PWM Duty Cycle Count */
1443 }
1444}
1445
1446/* Latch IEP PWM Deadband Counts */
1447static void latchIepPwmDbCount(
1448 IcssgIepPwmObj *pIcssgIepPwmObj,
1449 Bool recfgFlag
1450)
1451{
1452 IepPwmFwRegs *pIepPwmFwRegs = pIcssgIepPwmObj->pIepPwmFwRegs;
1453 volatile Uint16 *pIepPwmDbCount;
1454 Uint8 dbCountRecfg;
1455 Uint8 dPwmIdx;
1456
1457 if (recfgFlag == TRUE) {
1458 /* Get Deadband reconfiguration register */
1459 dbCountRecfg = (pIepPwmFwRegs->IEP_PWM_RECFG & IEP_PWM_RECFG_RECFG_IEP_PWM_DB_COUNT_MASK) >> IEP_PWM_RECFG_RECFG_IEP_PWM_DB_COUNT_SHIFT;
1460 }
1461 else {
1462 /* Set Deadband reconfiguration register to full mask */
1463 dbCountRecfg = IEP_PWM_RECFG_RECFG_IEP_PWM_DB_COUNT_MASK >> IEP_PWM_RECFG_RECFG_IEP_PWM_DB_COUNT_SHIFT;
1464 }
1465
1466 pIepPwmDbCount = &pIepPwmFwRegs->IEP_PWM0_1_DB_COUNT; /* init pointer to IEP PWM Deadband Count */
1467 for (dPwmIdx = 0; dPwmIdx < IEP_MAX_NUM_DIFF_PWM; dPwmIdx++)
1468 {
1469 if ( (dbCountRecfg >> dPwmIdx) & 0x1 ) {
1470 /* Latch updated PWM Deadband Count IEP PWM object */
1471 pIcssgIepPwmObj->iepPwmDbCount[dPwmIdx] = *pIepPwmDbCount;
1472 }
1473 pIepPwmDbCount++;
1474 }
1475}
1476
1477/* Calculate IEP PWM Single-Ended and Differential Enable */
1478static void calcIepPwmSnglDiffEn(
1479 IcssgIepPwmObj *pIcssgIepPwmObj,
1480 Uint16 *pIepPwmSnglEn,
1481 Uint8 *pIepPwmDiffEn
1482)
1483{
1484 IepPwmFwRegs *pIepPwmFwRegs = pIcssgIepPwmObj->pIepPwmFwRegs;
1485 Uint16 iepPwmSnglEn;
1486 Uint8 iepPwmDiffEn;
1487 Uint8 dPwmIdx, pwmIdx;
1488
1489 iepPwmSnglEn = 0;
1490 iepPwmDiffEn = 0;
1491 for (dPwmIdx = 0; dPwmIdx < IEP_MAX_NUM_DIFF_PWM; dPwmIdx++)
1492 {
1493 pwmIdx = dPwmIdx << 1;
1494 if ((pIcssgIepPwmObj->iepPwmMode >> dPwmIdx) & 0x1) {
1495 /* Differential PWM */
1496 if ((pIepPwmFwRegs->IEP_PWM_EN >> pwmIdx) & 0x1) {
1497 /* Differential PWM enabled */
1498 iepPwmDiffEn |= 1 << dPwmIdx;
1499 }
1500 }
1501 else {
1502 /* Single-Ended PWM */
1503 if ((pIepPwmFwRegs->IEP_PWM_EN >> pwmIdx) & 0x1) {
1504 /* Single-Ended PWM enabled */
1505 iepPwmSnglEn |= 1 << pwmIdx;
1506 }
1507 if ((pIepPwmFwRegs->IEP_PWM_EN >> (pwmIdx+1)) & 0x1) {
1508 /* Single-Ended PWM enabled */
1509 iepPwmSnglEn |= 1 << (pwmIdx+1);
1510 }
1511 }
1512 }
1513
1514 *pIepPwmSnglEn = iepPwmSnglEn;
1515 *pIepPwmDiffEn = iepPwmDiffEn;
1516}
1517
1518/* Latch IEP PWM Single-Ended and Differential Enable */
1519static void latchIepPwmSnglDiffEn(
1520 IcssgIepPwmObj *pIcssgIepPwmObj,
1521 Uint16 iepPwmSnglEn,
1522 Uint8 iepPwmDiffEn
1523)
1524{
1525 pIcssgIepPwmObj->iepPwmSnglEn = iepPwmSnglEn;
1526 pIcssgIepPwmObj->iepPwmDiffEn = iepPwmDiffEn;
1527}
1528
1529/* Calculate & Latch IEP PWM LHS/RHS Duty Cycle Counts */
1530static Int32 calcAndLatchIepPwmDcLhsRhsCount(
1531 IcssgIepPwmObj *pIcssgIepPwmObj,
1532 Bool recfgFlag
1533)
1534{
1535 IepPwmFwRegs *pIepPwmFwRegs = pIcssgIepPwmObj->pIepPwmFwRegs;
1536 Uint16 recfgDcCount;
1537 Uint32 pwmPeriodCount;
1538 volatile Uint32 *pIepPwmDcCount;
1539 Uint8 dPwmIdx, pwmIdx;
1540 Uint32 dcCount, temp;
1541 Int32 status = IEP_STS_NERR;
1542
1543
1544 if (recfgFlag == TRUE) {
1545 /* Get Duty Cycle reconfiguration */
1546 recfgDcCount = (pIepPwmFwRegs->IEP_PWM_RECFG & IEP_PWM_RECFG_RECFG_IEP_PWM_DC_COUNT_MASK) >> IEP_PWM_RECFG_RECFG_IEP_PWM_DC_COUNT_SHIFT;
1547 }
1548 else {
1549 /* Set Duty Cycle reconfiguration to full mask */
1550 recfgDcCount = IEP_PWM_RECFG_RECFG_IEP_PWM_DC_COUNT_MASK >> IEP_PWM_RECFG_RECFG_IEP_PWM_DC_COUNT_SHIFT;
1551 }
1552
1553 /* Calculate PWM period.
1554 PWM period is 2 IEP CMP0 periods. */
1555 pwmPeriodCount = pIcssgIepPwmObj->iepPwmPeriodCount << 1;
1556
1557 /* Compute LHS/RHS Duty Cycle counts */
1558 pIepPwmDcCount = &pIepPwmFwRegs->IEP_PWM0_DC_COUNT; /* Init pointer to IEP PWM Duty Cycle Count */
1559 for (dPwmIdx = 0; dPwmIdx < IEP_MAX_NUM_DIFF_PWM; dPwmIdx++)
1560 {
1561 pwmIdx = dPwmIdx << 1;
1562 if ((pIcssgIepPwmObj->iepPwmMode >> dPwmIdx) & 0x1) {
1563 /* Differential PWM */
1564
1565 /* Check if reconfiguration bit set.
1566 For Differential PWM, only "even" reconfiguration bits checked for each PWM pair. */
1567 if ((recfgDcCount >> pwmIdx) & 0x1) {
1568 dcCount = *pIepPwmDcCount;
1569 if ((dcCount > 0) && (dcCount < pwmPeriodCount)) {
1570 /* Calculate and latch DC count LHS/RHS */
1571 temp = COUNT_TO_CLK(dcCount)/2;
1572 temp = CLK_TO_COUNT(temp);
1573 pIcssgIepPwmObj->iepPwmDcCountLhs[pwmIdx] = temp; /* LHS 2*i, POS/NEG */
1574 pIcssgIepPwmObj->iepPwmDcCountRhs[pwmIdx] = temp; /* LHS 2*i, POS/NEG */
1575 if ((COUNT_TO_CLK(dcCount) & 0x1) == 1) {
1576 pIcssgIepPwmObj->iepPwmDcCountRhs[pwmIdx] += DEF_COUNT_INC_PER_CLK; /* RHS 2*i, POS/NEG */
1577 }
1578 }
1579 else if ((dcCount == 0) || (dcCount == pwmPeriodCount)) {
1580 /* No LHS/RHS in case DC count 0 or 100 */
1581 ;
1582 }
1583 else {
1584 /* error, invalid DC count */
1585 status = IPE_STS_ERR_INV_DC_COUNT;
1586 }
1587 }
1588 }
1589 else {
1590 /* Single-Ended PWM */
1591
1592 /* Check if reconfiguration bit set.
1593 For Single-Ended PWM, all reconfiguration bits checked. */
1594 if ((recfgDcCount >> pwmIdx) & 0x1) {
1595 dcCount = *pIepPwmDcCount;
1596 if ((dcCount > 0) && (dcCount < pwmPeriodCount)) {
1597 temp = COUNT_TO_CLK(dcCount)/2;
1598 temp = CLK_TO_COUNT(temp);
1599 pIcssgIepPwmObj->iepPwmDcCountLhs[pwmIdx] = temp; /* LHS 2*i, POS */
1600 pIcssgIepPwmObj->iepPwmDcCountRhs[pwmIdx] = temp; /* RHS 2*i, POS */
1601 if ((COUNT_TO_CLK(dcCount) & 0x1) == 1) {
1602 pIcssgIepPwmObj->iepPwmDcCountRhs[pwmIdx] += DEF_COUNT_INC_PER_CLK; /* RHS 2*i, POS */
1603 }
1604 }
1605 else if ((dcCount == 0) || (dcCount == pwmPeriodCount)) {
1606 /* No LHS/RHS in case DC count 0 or 100 */
1607 ;
1608 }
1609 else {
1610 /* error, invalid DC count */
1611 status = IPE_STS_ERR_INV_DC_COUNT;
1612 }
1613 }
1614 if ((recfgDcCount >> (pwmIdx+1)) & 0x1) {
1615 dcCount = *(pIepPwmDcCount+1);
1616 if ((dcCount > 0) && (dcCount < pwmPeriodCount)) {
1617 temp = COUNT_TO_CLK(dcCount)/2;
1618 temp = CLK_TO_COUNT(temp);
1619 pIcssgIepPwmObj->iepPwmDcCountLhs[pwmIdx+1] = temp; /* LHS 2*i+1, NEG */
1620 pIcssgIepPwmObj->iepPwmDcCountRhs[pwmIdx+1] = temp; /* RHS 2*i+1, NEG */
1621 if ((COUNT_TO_CLK(dcCount) & 0x1) == 1) {
1622 pIcssgIepPwmObj->iepPwmDcCountRhs[pwmIdx+1] += DEF_COUNT_INC_PER_CLK; /* RHS 2*i+1, NEG */
1623 }
1624 }
1625 else if ((dcCount == 0) || (dcCount == pwmPeriodCount)) {
1626 /* No LHS/RHS in case DC count 0 or 100 */
1627 ;
1628 }
1629 else {
1630 /* error, invalid DC count */
1631 status = IPE_STS_ERR_INV_DC_COUNT;
1632 }
1633 }
1634 }
1635
1636 pIepPwmDcCount += 2;
1637 }
1638
1639 return status;
1640}
1641
1642/* Initialize IEP PWM CMPx Shadow Registers */
1643static Int32 initIepPwmCmpxShReg(
1644 IcssgIepPwmObj *pIcssgIepPwmObj
1645)
1646{
1647 Uint32 *pIepPwmDcCount;
1648 Uint32 *pIepPwmDcCountLhs;
1649 IepPwmRhsAction *pIepPwmRhsAction;
1650 Bool *pIepPwmRhsRecfgFlag;
1651 Uint32 iepPwmPeriodCount, pwmPeriodCount;
1652 Uint16 *pIepPwmSnglUpdEn;
1653 Uint8 *pIepPwmDiffUpdEn;
1654 volatile uint32_t **pIepCmpSrAddr;
1655 IepPwmLhsAction actionLhs;
1656 IepPwmRhsAction actionRhs;
1657 Uint8 dPwmIdx, pwmIdx;
1658 Bool pwmEn;
1659
1660 /* Get latched IEP PWM DC count array */
1661 pIepPwmDcCount = &pIcssgIepPwmObj->iepPwmDcCount[0];
1662 /* Get latched IEP PWM DC LHS count array */
1663 pIepPwmDcCountLhs = &pIcssgIepPwmObj->iepPwmDcCountLhs[0];
1664 /* Get RHS action array */
1665 pIepPwmRhsAction = &pIcssgIepPwmObj->iepPwmRhsAction[0];
1666 /* Get pointer to RHS reconfiguration flag */
1667 pIepPwmRhsRecfgFlag = &pIcssgIepPwmObj->iepPwmRhsRecfgFlag;
1668 /* Get Single-Ended & Differential PWM Update Enable */
1669 pIepPwmSnglUpdEn = &pIcssgIepPwmObj->iepPwmSnglUpdEn;
1670 pIepPwmDiffUpdEn = &pIcssgIepPwmObj->iepPwmDiffUpdEn;
1671 /* Get IEP CMP Shadow Registers array */
1672 pIepCmpSrAddr = &pIcssgIepPwmObj->iepCmpSrAddr[0];
1673
1674 /* Get IEP CMP0 period */
1675 iepPwmPeriodCount = pIcssgIepPwmObj->iepPwmPeriodCount;
1676 /* Calculate PWM period.
1677 PWM period is 2 IEP CMP0 periods. */
1678 pwmPeriodCount = iepPwmPeriodCount << 1;
1679
1680 /* Initialize flag to disable execution of RHS Reconfiguration */
1681 *pIepPwmRhsRecfgFlag = FALSE;
1682
1683 for (dPwmIdx = 0; dPwmIdx < IEP_MAX_NUM_DIFF_PWM; dPwmIdx++)
1684 {
1685 if ((pIcssgIepPwmObj->iepPwmMode >> dPwmIdx) & 0x1) {
1686 /* Process Differential PWM */
1687
1688 /* Get PWM enable */
1689 pwmEn = (Bool)((pIcssgIepPwmObj->iepPwmDiffEn >> dPwmIdx) & 0x1);
1690
1691 pwmIdx = dPwmIdx << 1; /* multiply by 2 for differential PWM */
1692
1693 /* Determine Initial LHS/RHS actions */
1694 getInitLhsAction(FALSE, pwmEn, pIepPwmDcCount[pwmIdx], pwmPeriodCount,
1695 &actionLhs, &actionRhs);
1696
1697 /* Execute LHS action */
1698 execInitLhsActionDiff(actionLhs,
1699 iepPwmPeriodCount,
1700 pIepPwmDcCountLhs[pwmIdx],
1701 pIepCmpSrAddr,
1702 pIepPwmDiffUpdEn,
1703 dPwmIdx);
1704
1705 /* Stash RHS action */
1706 stashRhsAction(actionRhs, pIepPwmRhsRecfgFlag, &pIepPwmRhsAction[pwmIdx]);
1707 }
1708 else {
1709 /* Process Single-Ended PWMs */
1710
1711 for (pwmIdx = dPwmIdx<<1; pwmIdx < ((dPwmIdx<<1) + NUM_PWM_PER_DIFF_PWM); pwmIdx++)
1712 {
1713 /* Get PWM enable */
1714 pwmEn = (Bool)((pIcssgIepPwmObj->iepPwmSnglEn >> pwmIdx) & 0x1);
1715
1716 /* Determine Initial LHS/RHS actions */
1717 getInitLhsAction(FALSE, pwmEn, pIepPwmDcCount[pwmIdx], pwmPeriodCount,
1718 &actionLhs, &actionRhs);
1719
1720 /* Execute LHS action */
1721 execInitLhsActionSngl(actionLhs,
1722 iepPwmPeriodCount,
1723 pIepPwmDcCountLhs[pwmIdx],
1724 pIepCmpSrAddr,
1725 pIepPwmSnglUpdEn,
1726 pwmIdx);
1727
1728 /* Stash RHS action */
1729 stashRhsAction(actionRhs, pIepPwmRhsRecfgFlag, &pIepPwmRhsAction[pwmIdx]);
1730 }
1731 }
1732 }
1733
1734 /* Process "sacrificial PWMs".
1735 Previously applied settings are overwritten for these PWMs. */
1736 /* Determine Initial LHS/RHS actions */
1737
1738 pwmIdx = SACR_PWM_IDX; /* "sacrificial" PWM index */
1739 /* Get PWM enable */
1740 pwmEn = (Bool)((pIcssgIepPwmObj->iepPwmSnglEn >> pwmIdx) & 0x1);
1741 getInitLhsAction(TRUE, pwmEn, pIepPwmDcCount[pwmIdx], pwmPeriodCount,
1742 &actionLhs, &actionRhs);
1743 /* Execute LHS action */
1744 execInitLhsActionSngl(actionLhs,
1745 iepPwmPeriodCount,
1746 pIepPwmDcCountLhs[pwmIdx],
1747 pIepCmpSrAddr,
1748 pIepPwmSnglUpdEn,
1749 pwmIdx);
1750 /* Stash RHS action */
1751 stashRhsAction(actionRhs, pIepPwmRhsRecfgFlag, &pIepPwmRhsAction[pwmIdx]);
1752
1753 pwmIdx = SNGL_PWM_PER_SET + SACR_PWM_IDX; /* "sacrificial" PWM index */
1754 /* Get PWM enable */
1755 pwmEn = (Bool)((pIcssgIepPwmObj->iepPwmSnglEn >> pwmIdx) & 0x1);
1756 getInitLhsAction(TRUE, pwmEn, pIepPwmDcCount[pwmIdx], pwmPeriodCount,
1757 &actionLhs, &actionRhs);
1758 /* Execute LHS action */
1759 execInitLhsActionSngl(actionLhs,
1760 iepPwmPeriodCount,
1761 pIepPwmDcCountLhs[pwmIdx],
1762 pIepCmpSrAddr,
1763 pIepPwmSnglUpdEn,
1764 pwmIdx);
1765 /* Stash RHS action */
1766 stashRhsAction(actionRhs, pIepPwmRhsRecfgFlag, &pIepPwmRhsAction[pwmIdx]);
1767
1768 return IEP_STS_NERR;
1769}
1770
1771/* Determine initial LHS/RHS actions */
1772static Int32 getInitLhsAction(
1773 Bool initToActPwm,
1774 Bool pwmEn,
1775 Uint32 iepPwmDcCount,
1776 Uint32 pwmPeriodCount,
1777 IepPwmLhsAction *pActionLhs,
1778 IepPwmRhsAction *pActionRhs
1779)
1780{
1781 if (initToActPwm == FALSE) {
1782 /* Determine LHS/RHS actions for non "sacrificial" PWMs */
1783
1784 if (pwmEn == TRUE) {
1785 if ((iepPwmDcCount > 0) &&
1786 (iepPwmDcCount < pwmPeriodCount)) {
1787 /* DC = x, x!=0, x!=100 */
1788 *pActionLhs = LHS_ACTION_Set_CmpSr_DcLhsX_And_EnableSrUpdate;
1789 *pActionRhs = RHS_ACTION_None;
1790 }
1791 else if (iepPwmDcCount == 0) {
1792 /* DC count is 0 */
1793 *pActionLhs = LHS_ACTION_None;
1794 *pActionRhs = RHS_ACTION_None;
1795 }
1796 else if (iepPwmDcCount == pwmPeriodCount) {
1797 /* DC count is 100 */
1798 *pActionLhs = LHS_ACTION_Set_CmpSr_EarlyInPrd_And_EnableSrUpdate;
1799 *pActionRhs = RHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate;
1800 }
1801 else {
1802 /* Error, invalid DC count */
1803
1804 /* PWM disabled in case of invalid DC count */
1805 *pActionLhs = LHS_ACTION_None;
1806 *pActionRhs = RHS_ACTION_None;
1807 /* Indicate error to caller */
1808 return IPE_STS_ERR_INV_DC_COUNT;
1809 }
1810 }
1811 else {
1812 /* PWM disabled, no action required */
1813 *pActionLhs = LHS_ACTION_None;
1814 *pActionRhs = RHS_ACTION_None;
1815 }
1816 }
1817 else {
1818 /* Determine LHS/RHS actions for "sacrificial" PWMs */
1819
1820 if (pwmEn == TRUE) {
1821 if ((iepPwmDcCount > 0) &&
1822 (iepPwmDcCount < pwmPeriodCount)) {
1823 /* DC = x, x!=0, x!=100 */
1824 *pActionLhs = LHS_ACTION_Set_CmpSr_DcLhsX_And_EnableSrUpdate;
1825 *pActionRhs = RHS_ACTION_None;
1826 }
1827 else if (iepPwmDcCount == 0) {
1828 /* DC count is 0 */
1829 *pActionLhs = LHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate;
1830 *pActionRhs = RHS_ACTION_None;
1831 }
1832 else if (iepPwmDcCount == pwmPeriodCount) {
1833 /* DC count is 100 */
1834 *pActionLhs = LHS_ACTION_None;
1835 *pActionRhs = RHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate;
1836 }
1837 else {
1838 /* Error, invalid DC count */
1839
1840 /* PWM disabled in case of invalid DC count */
1841 *pActionLhs = LHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate;
1842 *pActionRhs = RHS_ACTION_None;
1843 /* Indicate error to caller */
1844 return IPE_STS_ERR_INV_DC_COUNT;
1845 }
1846 }
1847 else {
1848 /* PWM disabled */
1849 *pActionLhs = LHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate;
1850 *pActionRhs = RHS_ACTION_None;
1851 }
1852 }
1853
1854 return IEP_STS_NERR;
1855}
1856
1857/* Initial update IEP PWM CMPx Shadow Register, Single-Ended Mode */
1858static void execInitLhsActionSngl(
1859 IepPwmLhsAction actionLhs,
1860 Uint32 iepPwmPeriodCount,
1861 Uint32 iepPwmDcCountLhs,
1862 volatile uint32_t **pIepCmpSrAddr,
1863 Uint16 *pIepPwmSnglUpdEn,
1864 Uint8 pwmIdx
1865)
1866{
1867 volatile uint32_t *pCmpSr;
1868
1869 pCmpSr = pIepCmpSrAddr[pwmIdx];
1870
1871 switch (actionLhs)
1872 {
1873 case LHS_ACTION_Set_CmpSr_DcLhsX_And_EnableSrUpdate:
1874 *pCmpSr = iepPwmPeriodCount - iepPwmDcCountLhs; /* Write LHS value to CMP Shadow Register */
1875 *pIepPwmSnglUpdEn |= 1<<pwmIdx; /* Enable CMP SR update */
1876 break;
1877
1878 case LHS_ACTION_Set_CmpSr_EarlyInPrd_And_EnableSrUpdate:
1879 *pCmpSr = CMP_SR_EARLY_VAL; /* Write LHS value to CMP Shadow Register */
1880 *pIepPwmSnglUpdEn |= 1<<pwmIdx; /* Enable CMP SR update */
1881 break;
1882
1883 case LHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate:
1884 *pCmpSr = iepPwmPeriodCount; /* Write LHS value to CMP Shadow Register */
1885 *pIepPwmSnglUpdEn &= ~(1<<pwmIdx); /* Enable CMP SR update */
1886 break;
1887
1888 case LHS_ACTION_None:
1889 case LHS_ACTION_Set_CmpSr_DcLhsY:
1890 case LHS_ACTION_Set_CmpSr_DcLhsY_And_EnableSrUpdate:
1891 default:
1892 break;
1893 }
1894}
1895
1896/* Initial update IEP PWM CMPx Shadow Registers, Differential Mode */
1897static void execInitLhsActionDiff(
1898 IepPwmLhsAction actionLhs,
1899 Uint32 iepPwmPeriodCount,
1900 Uint32 iepPwmDcCountLhs,
1901 volatile uint32_t **pIepCmpSrAddr,
1902 Uint8 *pIepPwmDiffUpdEn,
1903 Uint8 dPwmIdx
1904)
1905{
1906 volatile uint32_t *pCmpSrPos, *pCmpSrNeg;
1907 Uint8 pwmIdx;
1908 Uint32 temp;
1909
1910 pwmIdx = dPwmIdx << 1; /* multiply by 2 for differential PWM */
1911 pCmpSrPos = pIepCmpSrAddr[pwmIdx];
1912 pCmpSrNeg = pIepCmpSrAddr[pwmIdx+1];
1913
1914 switch (actionLhs)
1915 {
1916 case LHS_ACTION_Set_CmpSr_DcLhsX_And_EnableSrUpdate:
1917 temp = iepPwmPeriodCount - iepPwmDcCountLhs; /* Compute LHS SR value */
1918 *pCmpSrPos = temp; /* Write LHS value to CMP Shadow Register, POS */
1919 *pCmpSrNeg = temp; /* Write LHS value to CMP Shadow Register, NEG */
1920 *pIepPwmDiffUpdEn |= 1<<dPwmIdx; /* Enable CMP SR update */
1921 break;
1922
1923 case LHS_ACTION_Set_CmpSr_EarlyInPrd_And_EnableSrUpdate:
1924 *pCmpSrPos = CMP_SR_EARLY_VAL; /* Write LHS value to CMP Shadow Register, POS */
1925 *pCmpSrNeg = CMP_SR_EARLY_VAL; /* Write LHS value to CMP Shadow Register, NEG */
1926 *pIepPwmDiffUpdEn |= 1<<dPwmIdx; /* Enable CMP SR update */
1927 break;
1928
1929 case LHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate:
1930 /* Write same LHS value to both CMP Shadow Registers in differential pair */
1931 *pCmpSrPos = iepPwmPeriodCount; /* Write LHS value to CMP Shadow Register, POS */
1932 *pCmpSrNeg = iepPwmPeriodCount; /* Write LHS value to CMP Shadow Register, NEG */
1933 /* Disable CMP SR update */
1934 *pIepPwmDiffUpdEn &= ~(1<<dPwmIdx); /* Disable CMP SR update */
1935 break;
1936
1937 case LHS_ACTION_None:
1938 case LHS_ACTION_Set_CmpSr_DcLhsY:
1939 case LHS_ACTION_Set_CmpSr_DcLhsY_And_EnableSrUpdate:
1940 default:
1941 break;
1942 }
1943}
1944
1945/* Update IEP PWM CMPx Shadow Registers.
1946 PWM Enable and DC Count reconfiguration handled jointly. */
1947static Int32 updateIepPwmCmpxShRegPwmEnDc(
1948 IcssgIepPwmObj *pIcssgIepPwmObj
1949)
1950{
1951 IepPwmFwRegs *pIepPwmFwRegs = pIcssgIepPwmObj->pIepPwmFwRegs;
1952 Uint16 recfgDcCount;
1953 volatile uint32_t *pIepPwmDcCountNew;
1954 Uint32 *pIepPwmDcCountOld, *pIepPwmDcCountLhsOld, *pIepPwmDcCountRhsOld;
1955 IepPwmRhsAction *pIepPwmRhsAction;
1956 Bool *pIepPwmRhsRecfgFlag;
1957 Uint16 *pIepPwmSnglUpdEn;
1958 Uint8 *pIepPwmDiffUpdEn;
1959 volatile uint32_t **pIepCmpSrAddr;
1960 Uint32 iepPwmPeriodCount, pwmPeriodCount;
1961 Uint8 pwmIdx, dPwmIdx;
1962 const IepPwmActionTableEntry *pTable;
1963 Uint8 rowIdx;
1964 Uint32 iepPwmDcCountLhsNew, iepPwmDcCountRhsNew;
1965 Uint16 iepPwmSnglEn;
1966 Uint8 iepPwmDiffEn;
1967 Int32 status = IEP_STS_NERR;
1968
1969 /* Get Duty Cycle reconfiguration */
1970 recfgDcCount = (pIepPwmFwRegs->IEP_PWM_RECFG & IEP_PWM_RECFG_RECFG_IEP_PWM_DC_COUNT_MASK) >> IEP_PWM_RECFG_RECFG_IEP_PWM_DC_COUNT_SHIFT;
1971 /* Get input (new) IEP PWM DC count array */
1972 pIepPwmDcCountNew = &pIepPwmFwRegs->IEP_PWM0_DC_COUNT;
1973 /* Get latched (old) IEP PWM DC count array */
1974 pIepPwmDcCountOld = &pIcssgIepPwmObj->iepPwmDcCount[0];
1975 /* Get latched (old) IEP PWM DC LHS/RHS count arrays */
1976 pIepPwmDcCountLhsOld = &pIcssgIepPwmObj->iepPwmDcCountLhs[0];
1977 pIepPwmDcCountRhsOld = &pIcssgIepPwmObj->iepPwmDcCountRhs[0];
1978 /* Get RHS action array */
1979 pIepPwmRhsAction = &pIcssgIepPwmObj->iepPwmRhsAction[0];
1980 /* Get pointer to RHS reconfiguration flag */
1981 pIepPwmRhsRecfgFlag = &pIcssgIepPwmObj->iepPwmRhsRecfgFlag;
1982 /* Get Single-Ended & Differential PWM Update Enable */
1983 pIepPwmSnglUpdEn = &pIcssgIepPwmObj->iepPwmSnglUpdEn;
1984 pIepPwmDiffUpdEn = &pIcssgIepPwmObj->iepPwmDiffUpdEn;
1985 /* Get IEP CMP Shadow Registers array */
1986 pIepCmpSrAddr = &pIcssgIepPwmObj->iepCmpSrAddr[0];
1987
1988 /* Get IEP CMP0 period */
1989 iepPwmPeriodCount = pIcssgIepPwmObj->iepPwmPeriodCount;
1990 /* Calculate PWM period.
1991 PWM period is 2 IEP CMP0 periods. */
1992 pwmPeriodCount = pIcssgIepPwmObj->iepPwmPeriodCount << 1;
1993
1994 /* Init flag to disable execution of RHS Reconfiguration */
1995 *pIepPwmRhsRecfgFlag = FALSE;
1996
1997 if ((pIepPwmFwRegs->IEP_PWM_RECFG & IEP_PWM_RECFG_RECFG_IEP_PWM_EN_MASK) == 0) {
1998 /* No change to PWM Enable */
1999
2000 for (dPwmIdx = 0; dPwmIdx < IEP_MAX_NUM_DIFF_PWM; dPwmIdx++)
2001 {
2002 if ((pIcssgIepPwmObj->iepPwmMode >> dPwmIdx) & 0x1) {
2003 /* Process Differential PWM */
2004
2005 /* Select Action Table */
2006 if ((pIcssgIepPwmObj->iepPwmDiffEn >> dPwmIdx) & 0x1) {
2007 /* No Enable Reconfiguration, PWM enabled */
2008 pTable = gActT2_EnRecfgNo_EnOldEnable;
2009 }
2010 else {
2011 /* No Enable Reconfiguration, PWM disabled */
2012 pTable = gActT1_EnRecfgNo_EnOldDisable;
2013 }
2014
2015 pwmIdx = dPwmIdx << 1; /* multiply by 2 for differential PWM */
2016
2017 /* Determine Action Table Row */
2018 status = getActionTableRowDiff(recfgDcCount, dPwmIdx,
2019 pIepPwmDcCountOld[pwmIdx], pIepPwmDcCountNew[pwmIdx],
2020 pwmPeriodCount, &rowIdx);
2021 if (status != IEP_STS_NERR) {
2022 return status;
2023 }
2024
2025 /* Calculate new LHS/RHS */
2026 calcDcLatchAction(pTable[rowIdx].latchAction,
2027 pIepPwmDcCountNew[pwmIdx],
2028 &iepPwmDcCountLhsNew,
2029 &iepPwmDcCountRhsNew);
2030
2031 /* Execute LHS action */
2032 execLhsActionDiff(pTable[rowIdx].lhsAction,
2033 pIepPwmDcCountLhsOld[pwmIdx], iepPwmDcCountLhsNew,
2034 pIepCmpSrAddr,
2035 pIepPwmDiffUpdEn,
2036 dPwmIdx,
2037 iepPwmPeriodCount);
2038
2039 /* Stash RHS action */
2040 stashRhsAction(pTable[rowIdx].rhsAction, pIepPwmRhsRecfgFlag, &pIepPwmRhsAction[pwmIdx]);
2041
2042 /* Execute DC latch */
2043 execDcLatchAction(pTable[rowIdx].latchAction,
2044 &pIepPwmDcCountOld[pwmIdx], &pIepPwmDcCountLhsOld[pwmIdx], &pIepPwmDcCountRhsOld[pwmIdx],
2045 pIepPwmDcCountNew[pwmIdx], iepPwmDcCountLhsNew, iepPwmDcCountRhsNew);
2046 }
2047 else {
2048 /* Process Single-Ended PWMs */
2049
2050 for (pwmIdx = dPwmIdx<<1; pwmIdx < ((dPwmIdx<<1) + NUM_PWM_PER_DIFF_PWM); pwmIdx++)
2051 {
2052 /* Select Action Table */
2053 if ((pIcssgIepPwmObj->iepPwmSnglEn >> pwmIdx) & 0x1) {
2054 /* No Enable Reconfiguration, PWM enabled */
2055 pTable = gActT2_EnRecfgNo_EnOldEnable;
2056 }
2057 else {
2058 /* No Enable Reconfiguration, PWM disabled */
2059 pTable = gActT1_EnRecfgNo_EnOldDisable;
2060 }
2061
2062 /* Determine Action Table Row */
2063 status = getActionTableRowSngl(recfgDcCount, pwmIdx,
2064 pIepPwmDcCountOld[pwmIdx], pIepPwmDcCountNew[pwmIdx],
2065 pwmPeriodCount, &rowIdx);
2066 if (status != IEP_STS_NERR) {
2067 return status;
2068 }
2069
2070 /* Calculate new LHS/RHS */
2071 calcDcLatchAction(pTable[rowIdx].latchAction,
2072 pIepPwmDcCountNew[pwmIdx],
2073 &iepPwmDcCountLhsNew,
2074 &iepPwmDcCountRhsNew);
2075
2076 /* Execute LHS action */
2077 execLhsActionSngl(pTable[rowIdx].lhsAction,
2078 pIepPwmDcCountLhsOld[pwmIdx], iepPwmDcCountLhsNew,
2079 pIepCmpSrAddr,
2080 pIepPwmSnglUpdEn,
2081 pwmIdx,
2082 iepPwmPeriodCount);
2083
2084 /* Stash RHS action */
2085 stashRhsAction(pTable[rowIdx].rhsAction, pIepPwmRhsRecfgFlag, &pIepPwmRhsAction[pwmIdx]);
2086
2087 /* Execute DC latch */
2088 execDcLatchAction(pTable[rowIdx].latchAction,
2089 &pIepPwmDcCountOld[pwmIdx], &pIepPwmDcCountLhsOld[pwmIdx], &pIepPwmDcCountRhsOld[pwmIdx],
2090 pIepPwmDcCountNew[pwmIdx], iepPwmDcCountLhsNew, iepPwmDcCountRhsNew);
2091 }
2092 }
2093 }
2094 }
2095 else {
2096 /* Change to PWM Enable */
2097
2098 /* Calculate Single-Ended and Differential PWM Enable */
2099 calcIepPwmSnglDiffEn(pIcssgIepPwmObj, &iepPwmSnglEn, &iepPwmDiffEn);
2100
2101 for (dPwmIdx = 0; dPwmIdx < IEP_MAX_NUM_DIFF_PWM; dPwmIdx++)
2102 {
2103 if ((pIcssgIepPwmObj->iepPwmMode >> dPwmIdx) & 0x1) {
2104 /* Process Differential PWM */
2105
2106 /* Select Action Table */
2107 if (!((pIcssgIepPwmObj->iepPwmDiffEn >> dPwmIdx) & 0x1) &&
2108 ((iepPwmDiffEn >> dPwmIdx) & 0x1)) {
2109 /* Enable Reconfiguration, PWM enabled */
2110 pTable = gActT3_EnRecfgYes_EnNewEnable;
2111 }
2112 else if (((pIcssgIepPwmObj->iepPwmDiffEn >> dPwmIdx) & 0x1) &&
2113 !((iepPwmDiffEn >> dPwmIdx) & 0x1)) {
2114 /* Enable Reconfiguration, PWM disabled */
2115 pTable = gActT4_EnRecfgYes_EnNewDisable;
2116 }
2117 else if (!((pIcssgIepPwmObj->iepPwmDiffEn >> dPwmIdx) & 0x1) &&
2118 !((iepPwmDiffEn >> dPwmIdx) & 0x1)) {
2119 /* No Enable Reconfiguration, PWM disabled */
2120 pTable = gActT1_EnRecfgNo_EnOldDisable;
2121 }
2122 else {
2123 /* No Enable Reconfiguration, PWM enabled */
2124 pTable = gActT2_EnRecfgNo_EnOldEnable;
2125 }
2126
2127 pwmIdx = dPwmIdx << 1;
2128
2129 /* Determine Action Table Row */
2130 status = getActionTableRowDiff(recfgDcCount, dPwmIdx,
2131 pIepPwmDcCountLhsOld[pwmIdx], pIepPwmDcCountNew[pwmIdx],
2132 pwmPeriodCount, &rowIdx);
2133 if (status != IEP_STS_NERR) {
2134 return status;
2135 }
2136
2137 /* Calculate new LHS/RHS */
2138 calcDcLatchAction(pTable[rowIdx].latchAction,
2139 pIepPwmDcCountNew[pwmIdx],
2140 &iepPwmDcCountLhsNew,
2141 &iepPwmDcCountRhsNew);
2142
2143 /* Execute LHS action */
2144 execLhsActionDiff(pTable[rowIdx].lhsAction,
2145 pIepPwmDcCountLhsOld[pwmIdx], iepPwmDcCountLhsNew,
2146 pIepCmpSrAddr,
2147 pIepPwmDiffUpdEn,
2148 dPwmIdx,
2149 iepPwmPeriodCount);
2150
2151 /* Stash RHS action */
2152 stashRhsAction(pTable[rowIdx].rhsAction, pIepPwmRhsRecfgFlag, &pIepPwmRhsAction[pwmIdx]);
2153
2154 /* Execute DC latch */
2155 execDcLatchAction(pTable[rowIdx].latchAction,
2156 &pIepPwmDcCountOld[pwmIdx], &pIepPwmDcCountLhsOld[pwmIdx], &pIepPwmDcCountRhsOld[pwmIdx],
2157 pIepPwmDcCountNew[pwmIdx], iepPwmDcCountLhsNew, iepPwmDcCountRhsNew);
2158
2159 }
2160 else {
2161 /* Process Single-Ended PWMs */
2162
2163 for (pwmIdx = dPwmIdx<<1; pwmIdx < ((dPwmIdx<<1) + NUM_PWM_PER_DIFF_PWM); pwmIdx++)
2164 {
2165 /* Select Action Table */
2166 if (!((pIcssgIepPwmObj->iepPwmSnglEn >> pwmIdx) & 0x1) &&
2167 ((iepPwmSnglEn >> pwmIdx) & 0x1)) {
2168 /* Enable Reconfiguration, PWM enabled */
2169 pTable = gActT3_EnRecfgYes_EnNewEnable;
2170 }
2171 else if (((pIcssgIepPwmObj->iepPwmSnglEn >> pwmIdx) & 0x1) &&
2172 !((iepPwmSnglEn >> pwmIdx) & 0x1)) {
2173 /* Enable Reconfiguration, PWM disabled */
2174 pTable = gActT4_EnRecfgYes_EnNewDisable;
2175 }
2176 else if (!((pIcssgIepPwmObj->iepPwmSnglEn >> pwmIdx) & 0x1) &&
2177 (!(iepPwmSnglEn >> pwmIdx) & 0x1)) {
2178 /* No Enable Reconfiguration, PWM disabled */
2179 pTable = gActT1_EnRecfgNo_EnOldDisable;
2180 }
2181 else {
2182 /* No Enable Reconfiguration, PWM enabled */
2183 pTable = gActT2_EnRecfgNo_EnOldEnable;
2184 }
2185
2186 /* Determine Action Table Row */
2187 status = getActionTableRowSngl(recfgDcCount, pwmIdx,
2188 pIepPwmDcCountOld[pwmIdx], pIepPwmDcCountNew[pwmIdx],
2189 pwmPeriodCount, &rowIdx);
2190 if (status != IEP_STS_NERR) {
2191 return status;
2192 }
2193
2194 /* Calculate new LHS/RHS */
2195 calcDcLatchAction(pTable[rowIdx].latchAction,
2196 pIepPwmDcCountNew[pwmIdx],
2197 &iepPwmDcCountLhsNew,
2198 &iepPwmDcCountRhsNew);
2199
2200 /* Execute LHS action */
2201 execLhsActionSngl(pTable[rowIdx].lhsAction,
2202 pIepPwmDcCountLhsOld[pwmIdx], iepPwmDcCountLhsNew,
2203 pIepCmpSrAddr,
2204 pIepPwmSnglUpdEn,
2205 pwmIdx,
2206 iepPwmPeriodCount);
2207
2208 /* Stash RHS action */
2209 stashRhsAction(pTable[rowIdx].rhsAction, pIepPwmRhsRecfgFlag, &pIepPwmRhsAction[pwmIdx]);
2210
2211 /* Execute DC latch */
2212 execDcLatchAction(pTable[rowIdx].latchAction,
2213 &pIepPwmDcCountOld[pwmIdx], &pIepPwmDcCountLhsOld[pwmIdx], &pIepPwmDcCountRhsOld[pwmIdx],
2214 pIepPwmDcCountNew[pwmIdx], iepPwmDcCountLhsNew, iepPwmDcCountRhsNew);
2215 }
2216 }
2217 }
2218
2219 /* Latch Single-Ended and Differential PWM Enable */
2220 latchIepPwmSnglDiffEn(pIcssgIepPwmObj, iepPwmSnglEn, iepPwmDiffEn);
2221 }
2222
2223 return status;
2224}
2225
2226/* Get Action Table row, Single-Ended PWM */
2227static Int32 getActionTableRowSngl(
2228 Uint16 recfgDcCount,
2229 Uint8 pwmIdx,
2230 Uint32 iepPwmDcCountOld,
2231 Uint32 iepPwmDcCountNew,
2232 Uint32 pwmPeriodCount,
2233 Uint8 *pRowIdx
2234)
2235{
2236 Int32 status = IEP_STS_NERR;
2237
2238 if ((recfgDcCount >> pwmIdx) & 0x1) {
2239 /* Possible change to PWM DC count */
2240 if ((iepPwmDcCountOld > 0) && (iepPwmDcCountOld < pwmPeriodCount)) {
2241 if (iepPwmDcCountNew == iepPwmDcCountOld) {
2242 /* new DC count is x */
2243 *pRowIdx = AT_Row01_DcOldX_DcNewX;
2244 }
2245 else if ((iepPwmDcCountNew > 0) && (iepPwmDcCountNew < pwmPeriodCount)) {
2246 /* new DC count is y, x!=y */
2247 *pRowIdx = AT_Row02_DcOldX_DcNewY;
2248 }
2249 else if (iepPwmDcCountNew == 0) {
2250 /* new DC count is 0 */
2251 *pRowIdx = AT_Row03_DcOldX_DcNew0;
2252 }
2253 else if (iepPwmDcCountNew == pwmPeriodCount) {
2254 /* new DC count is 100 */
2255 *pRowIdx = AT_Row04_DcOldX_DcNew100;
2256 }
2257 else {
2258 /* error, invalid DC count */
2259 status = IPE_STS_ERR_INV_DC_COUNT;
2260 }
2261 }
2262 else if (iepPwmDcCountOld == 0) { /* old DC count is 0 */
2263 if ((iepPwmDcCountNew > 0) && (iepPwmDcCountNew < pwmPeriodCount)) {
2264 /* new DC count !=0, !=100 */
2265 *pRowIdx = AT_Row05_DcOld0_DcNewY;
2266 }
2267 else if (iepPwmDcCountNew == 0) {
2268 /* new DC count is 0 */
2269 *pRowIdx = AT_Row06_DcOld0_DcNew0;
2270 }
2271 else if (iepPwmDcCountNew == pwmPeriodCount) {
2272 /* new DC count is 100 */
2273 *pRowIdx = AT_Row10_DcOld100_DcNew100;
2274 }
2275 else {
2276 /* error, invalid DC count */
2277 status = IPE_STS_ERR_INV_DC_COUNT;
2278 }
2279 }
2280 else if (iepPwmDcCountOld == pwmPeriodCount) { /* old DC count is 100 */
2281 if ((iepPwmDcCountNew > 0) && (iepPwmDcCountNew < pwmPeriodCount)) {
2282 /* new DC count !=0, !=100 */
2283 *pRowIdx = AT_Row08_DcOld100_DcNewY;
2284 }
2285 else if (iepPwmDcCountNew == 0) {
2286 /* new DC count is 0 */
2287 *pRowIdx = AT_Row09_DcOld100_DcNew0;
2288 }
2289 else if (iepPwmDcCountNew == pwmPeriodCount) {
2290 /* new DC count is 100 */
2291 *pRowIdx = AT_Row10_DcOld100_DcNew100;
2292 }
2293 else {
2294 /* error, invalid DC count */
2295 status = IPE_STS_ERR_INV_DC_COUNT;
2296 }
2297 }
2298 else {
2299 /* error, invalid DC count */
2300 status = IPE_STS_ERR_INV_DC_COUNT;
2301 }
2302 }
2303 else {
2304 /* No change to PWM DC count */
2305 if ((iepPwmDcCountOld > 0) && (iepPwmDcCountOld < pwmPeriodCount)) {
2306 /* latched DC count !=0, !=100 */
2307 *pRowIdx = AT_Row01_DcOldX_DcNewX;
2308 }
2309 else if (iepPwmDcCountOld == 0) {
2310 /* old DC count is 0 */
2311 *pRowIdx = AT_Row06_DcOld0_DcNew0;
2312 }
2313 else if (iepPwmDcCountOld == pwmPeriodCount) {
2314 /* old DC count is 100 */
2315 *pRowIdx = AT_Row10_DcOld100_DcNew100;
2316 }
2317 else {
2318 /* error, invalid DC count */
2319 status = IPE_STS_ERR_INV_DC_COUNT;
2320 }
2321 }
2322
2323 return status;
2324}
2325
2326/* Get Action Table row, Differential PWM */
2327static Int32 getActionTableRowDiff(
2328 Uint16 recfgDcCount,
2329 Uint8 dPwmIdx,
2330 Uint32 iepPwmDcCountOld,
2331 Uint32 iepPwmDcCountNew,
2332 Uint32 pwmPeriodCount,
2333 Uint8 *pRowIdx
2334)
2335{
2336 Int32 status = IEP_STS_NERR;
2337 Uint8 pwmIdx;
2338
2339 pwmIdx = dPwmIdx << 1; /* multiply by 2 for differential PWM */
2340
2341 if ((recfgDcCount >> pwmIdx) & 0x1) {
2342 /* Possible change to PWM DC count */
2343 if ((iepPwmDcCountOld > 0) && (iepPwmDcCountOld < pwmPeriodCount)) {
2344 if (iepPwmDcCountNew == iepPwmDcCountOld) {
2345 /* new DC count is x */
2346 *pRowIdx = AT_Row01_DcOldX_DcNewX;
2347 }
2348 else if ((iepPwmDcCountNew > 0) && (iepPwmDcCountNew < pwmPeriodCount)) {
2349 /* new DC count is y, x!=y */
2350 *pRowIdx = AT_Row02_DcOldX_DcNewY;
2351 }
2352 else if (iepPwmDcCountNew == 0) {
2353 /* new DC count is 0 */
2354 *pRowIdx = AT_Row03_DcOldX_DcNew0;
2355 }
2356 else if (iepPwmDcCountNew == pwmPeriodCount) {
2357 /* new DC count is 100 */
2358 *pRowIdx = AT_Row04_DcOldX_DcNew100;
2359 }
2360 else {
2361 /* error, invalid DC count */
2362 status = IPE_STS_ERR_INV_DC_COUNT;
2363 }
2364 }
2365 else if (iepPwmDcCountOld == 0) { /* old DC count is 0 */
2366 if ((iepPwmDcCountNew > 0) && (iepPwmDcCountNew < pwmPeriodCount)) {
2367 /* new DC count !=0, !=100 */
2368 *pRowIdx = AT_Row05_DcOld0_DcNewY;
2369 }
2370 else if (iepPwmDcCountNew == 0) {
2371 /* new DC count is 0 */
2372 *pRowIdx = AT_Row06_DcOld0_DcNew0;
2373 }
2374 else if (iepPwmDcCountNew == pwmPeriodCount) {
2375 /* new DC count is 100 */
2376 *pRowIdx = AT_Row10_DcOld100_DcNew100;
2377 }
2378 else {
2379 /* error, invalid DC count */
2380 status = IPE_STS_ERR_INV_DC_COUNT;
2381 }
2382 }
2383 else if (iepPwmDcCountOld == pwmPeriodCount) { /* old DC count is 100 */
2384 if ((iepPwmDcCountNew > 0) && (iepPwmDcCountNew < pwmPeriodCount)) {
2385 /* new DC count !=0, !=100 */
2386 *pRowIdx = AT_Row08_DcOld100_DcNewY;
2387 }
2388 else if (iepPwmDcCountNew == 0) {
2389 /* new DC count is 0 */
2390 *pRowIdx = AT_Row09_DcOld100_DcNew0;
2391 }
2392 else if (iepPwmDcCountNew == pwmPeriodCount) {
2393 /* new DC count is 100 */
2394 *pRowIdx = AT_Row10_DcOld100_DcNew100;
2395 }
2396 else {
2397 /* error, invalid DC count */
2398 status = IPE_STS_ERR_INV_DC_COUNT;
2399 }
2400 }
2401 else {
2402 /* error, invalid DC count */
2403 status = IPE_STS_ERR_INV_DC_COUNT;
2404 }
2405 }
2406 else {
2407 /* No change to PWM DC count */
2408 if ((iepPwmDcCountOld > 0) && (iepPwmDcCountOld < pwmPeriodCount)) {
2409 /* latched DC count !=0, !=100 */
2410 *pRowIdx = AT_Row01_DcOldX_DcNewX;
2411 }
2412 else if (iepPwmDcCountOld == 0) {
2413 /* old DC count is 0 */
2414 *pRowIdx = AT_Row06_DcOld0_DcNew0;
2415 }
2416 else if (iepPwmDcCountOld == pwmPeriodCount) {
2417 /* old DC count is 100 */
2418 *pRowIdx = AT_Row10_DcOld100_DcNew100;
2419 }
2420 }
2421
2422 return status;
2423}
2424
2425/* Calculate IEP PWM LHS/RHS Duty Cycle Counts */
2426static void calcDcLatchAction(
2427 IepLatchAction actionLatch,
2428 Uint32 iepPwmDcCountNew,
2429 Uint32 *pIepPwmDcCountLhsNew,
2430 Uint32 *pIepPwmDcCountRhsNew
2431)
2432{
2433 Uint32 dcCountLhs, dcCountRhs;
2434
2435 switch (actionLatch)
2436 {
2437 /* New DC count is 0 or 100.
2438 Don't calculate LHS/RHS. */
2439 case LATCH_ACTION_Latch_0:
2440 case LATCH_ACTION_Latch_100:
2441 break;
2442 /* New DC count !=0, !=100.
2443 Calculate LHS/RHS. */
2444 case LATCH_ACTION_Latch_New:
2445 calcDcLhsRhs(iepPwmDcCountNew, &dcCountLhs, &dcCountRhs);
2446 *pIepPwmDcCountLhsNew = dcCountLhs;
2447 *pIepPwmDcCountRhsNew = dcCountRhs;
2448 break;
2449 case LATCH_ACTION_None:
2450 default:
2451 break;
2452 }
2453}
2454
2455/* Calculate DC LHS/RHS for DC */
2456static void calcDcLhsRhs(
2457 Uint32 dcCount,
2458 Uint32 *pDcCountLhs,
2459 Uint32 *pDcCountRhs
2460)
2461{
2462 Uint32 dcCountLhs, dcCountRhs;
2463
2464 dcCountLhs = COUNT_TO_CLK(dcCount)/2;
2465 dcCountLhs = CLK_TO_COUNT(dcCountLhs);
2466 dcCountRhs = dcCountLhs;
2467 if ((COUNT_TO_CLK(dcCount) & 0x1) == 1) { /* DC count is odd, distribute extra clocks to RHS */
2468 dcCountRhs += DEF_COUNT_INC_PER_CLK;
2469 }
2470
2471 *pDcCountLhs = dcCountLhs;
2472 *pDcCountRhs = dcCountRhs;
2473}
2474
2475/* Execute LHS action, Single-Ended PWM */
2476static void execLhsActionSngl(
2477 IepPwmLhsAction lhsAction,
2478 Uint32 iepPwmDcCountLhsOld,
2479 Uint32 iepPwmDcCountLhsNew,
2480 volatile uint32_t **pIepCmpSrAddr,
2481 Uint16 *pIepPwmSnglUpdEn,
2482 Uint8 pwmIdx,
2483 Uint32 iepPwmPeriodCount
2484)
2485{
2486 volatile uint32_t *pCmpSr;
2487
2488 pCmpSr = pIepCmpSrAddr[pwmIdx];
2489
2490 switch (lhsAction)
2491 {
2492 case LHS_ACTION_Set_CmpSr_DcLhsY:
2493 *pCmpSr = iepPwmPeriodCount - iepPwmDcCountLhsNew; /* Write LHS value to CMP Shadow Register */
2494 break;
2495
2496 case LHS_ACTION_Set_CmpSr_DcLhsX_And_EnableSrUpdate:
2497 *pCmpSr = iepPwmPeriodCount - iepPwmDcCountLhsOld; /* Write LHS value to CMP Shadow Register */
2498 *pIepPwmSnglUpdEn |= 1<<pwmIdx; /* Enable CMP SR update */
2499
2500 break;
2501 case LHS_ACTION_Set_CmpSr_DcLhsY_And_EnableSrUpdate:
2502 *pCmpSr = iepPwmPeriodCount - iepPwmDcCountLhsNew; /* Write LHS value to CMP Shadow Register */
2503 *pIepPwmSnglUpdEn |= 1<<pwmIdx; /* Enable CMP SR update */
2504 break;
2505
2506 case LHS_ACTION_Set_CmpSr_EarlyInPrd_And_EnableSrUpdate:
2507 *pCmpSr = CMP_SR_EARLY_VAL; /* Write LHS value to CMP Shadow Register */
2508 *pIepPwmSnglUpdEn |= 1<<pwmIdx; /* Enable CMP SR update */
2509 break;
2510
2511 case LHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate:
2512 *pCmpSr = iepPwmPeriodCount; /* Write LHS value to CMP Shadow Register */
2513 *pIepPwmSnglUpdEn &= ~(1<<pwmIdx); /* Enable CMP SR update */
2514 break;
2515
2516 case LHS_ACTION_None:
2517 default:
2518 break;
2519 }
2520}
2521
2522/* Execute LHS action, Differential PWM */
2523static void execLhsActionDiff(
2524 IepPwmLhsAction lhsAction,
2525 Uint32 iepPwmDcCountLhsOld,
2526 Uint32 iepPwmDcCountLhsNew,
2527 volatile uint32_t **pIepCmpSrAddr,
2528 Uint8 *pIepPwmDiffUpdEn,
2529 Uint8 dPwmIdx,
2530 Uint32 iepPwmPeriodCount
2531)
2532{
2533 volatile uint32_t *pCmpSrPos, *pCmpSrNeg;
2534 Uint8 pwmIdx;
2535 Uint32 temp;
2536
2537 pwmIdx = dPwmIdx << 1; /* multiply by 2 for differential PWM */
2538 pCmpSrPos = pIepCmpSrAddr[pwmIdx];
2539 pCmpSrNeg = pIepCmpSrAddr[pwmIdx+1];
2540
2541 switch (lhsAction)
2542 {
2543 case LHS_ACTION_Set_CmpSr_DcLhsY:
2544 /* Write same LHS value to both CMP Shadow Registers in differential pair */
2545 temp = iepPwmPeriodCount - iepPwmDcCountLhsNew;
2546 *pCmpSrPos = temp;
2547 *pCmpSrNeg = temp;
2548 break;
2549
2550 case LHS_ACTION_Set_CmpSr_DcLhsX_And_EnableSrUpdate:
2551 /* Write same LHS value to both CMP Shadow Registers in differential pair */
2552 temp = iepPwmPeriodCount - iepPwmDcCountLhsOld;
2553 *pCmpSrPos = temp;
2554 *pCmpSrNeg = temp;
2555 /* Enable CMP SR update */
2556 *pIepPwmDiffUpdEn |= 1<<dPwmIdx;
2557 break;
2558
2559 case LHS_ACTION_Set_CmpSr_DcLhsY_And_EnableSrUpdate:
2560 /* Write same LHS value to both CMP Shadow Registers in differential pair */
2561 temp = iepPwmPeriodCount - iepPwmDcCountLhsNew;
2562 *pCmpSrPos = temp;
2563 *pCmpSrNeg = temp;
2564 /* Enable CMP SR update */
2565 *pIepPwmDiffUpdEn |= 1<<dPwmIdx;
2566 break;
2567
2568 case LHS_ACTION_Set_CmpSr_EarlyInPrd_And_EnableSrUpdate:
2569 /* Write same LHS value to both CMP Shadow Registers in differential pair */
2570 *pCmpSrPos = CMP_SR_EARLY_VAL;
2571 *pCmpSrNeg = CMP_SR_EARLY_VAL;
2572 /* Enable CMP SR update */
2573 *pIepPwmDiffUpdEn |= 1<<dPwmIdx;
2574 break;
2575
2576 case LHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate:
2577 /* Write same LHS value to both CMP Shadow Registers in differential pair */
2578 *pCmpSrPos = iepPwmPeriodCount;
2579 *pCmpSrNeg = iepPwmPeriodCount;
2580 /* Disable CMP SR update */
2581 *pIepPwmDiffUpdEn &= ~(1<<dPwmIdx);
2582 break;
2583
2584 case LHS_ACTION_None:
2585 default:
2586 break;
2587 }
2588}
2589
2590/* Stash RHS action */
2591static void stashRhsAction(
2592 IepPwmRhsAction actionRhs,
2593 Bool *pIepPwmRhsRecfgFlag,
2594 IepPwmRhsAction *pIepPwmRhsAction
2595)
2596{
2597 if (actionRhs != RHS_ACTION_None) {
2598 *pIepPwmRhsRecfgFlag = TRUE;
2599 }
2600
2601 *pIepPwmRhsAction = actionRhs;
2602}
2603
2604/* Execute (LHS) DC latch action */
2605static void execDcLatchAction(
2606 IepLatchAction actionLatch,
2607 Uint32 *pIepPwmDcCountOld,
2608 Uint32 *pIepPwmDcCountLhsOld,
2609 Uint32 *pIepPwmDcCountRhsOld,
2610 Uint32 iepPwmDcCountNew,
2611 Uint32 iepPwmDcCountLhsNew,
2612 Uint32 iepPwmDcCountRhsNew
2613)
2614{
2615 switch (actionLatch)
2616 {
2617 /* New DC count is 0 or 100.
2618 Latch new DC, don't calculate & latch corresponding LHS/RHS. */
2619 case LATCH_ACTION_Latch_0:
2620 case LATCH_ACTION_Latch_100:
2621 *pIepPwmDcCountOld = iepPwmDcCountNew;
2622 break;
2623 /* New DC count !=0, !=100.
2624 Latch new DC latch corresponding LHS/RHS DC. */
2625 case LATCH_ACTION_Latch_New:
2626 *pIepPwmDcCountOld = iepPwmDcCountNew;
2627 *pIepPwmDcCountLhsOld = iepPwmDcCountLhsNew;
2628 *pIepPwmDcCountRhsOld = iepPwmDcCountRhsNew;
2629 break;
2630 case LATCH_ACTION_None:
2631 default:
2632 break;
2633 }
2634}
2635
2636/* Execute stashed RHS actions */
2637static void execRhsActionStash(
2638 IcssgIepPwmObj *pIcssgIepPwmObj
2639)
2640{
2641 Uint32 *pIepPwmDcCountRhs;
2642 Uint16 *pIepPwmDbCount;
2643 Uint16 *pIepPwmSnglUpdEn;
2644 Uint8 *pIepPwmDiffUpdEn;
2645 volatile uint32_t **pIepCmpSrAddr;
2646 Uint32 iepPwmPeriodCount;
2647 IepPwmRhsAction *pIepPwmRhsAction;
2648 Uint32 dcRhsY;
2649 volatile uint32_t *pCmpSr;
2650 Uint8 pwmIdx, dPwmIdx;
2651
2652 /* Get latched IEP PWM DC RHS count array */
2653 pIepPwmDcCountRhs = &pIcssgIepPwmObj->iepPwmDcCountRhs[0];
2654 /* Get Deadband count array */
2655 pIepPwmDbCount = &pIcssgIepPwmObj->iepPwmDbCount[0];
2656 /* Get Single-Ended & Differential PWM Update Enable */
2657 pIepPwmSnglUpdEn = &pIcssgIepPwmObj->iepPwmSnglUpdEn;
2658 pIepPwmDiffUpdEn = &pIcssgIepPwmObj->iepPwmDiffUpdEn;
2659 /* Get IEP CMP Shadow Registers array */
2660 pIepCmpSrAddr = &pIcssgIepPwmObj->iepCmpSrAddr[0];
2661 /* Get period */
2662 iepPwmPeriodCount = pIcssgIepPwmObj->iepPwmPeriodCount;
2663 /* Get RHS action array */
2664 pIepPwmRhsAction = &pIcssgIepPwmObj->iepPwmRhsAction[0];
2665
2666 if (pIcssgIepPwmObj->iepPwmRhsRecfgFlag == TRUE) {
2667 for (dPwmIdx = 0; dPwmIdx < IEP_MAX_NUM_DIFF_PWM; dPwmIdx++)
2668 {
2669 if ((pIcssgIepPwmObj->iepPwmMode >> dPwmIdx) & 0x1) {
2670 /* Process Differential PWM */
2671
2672 pwmIdx = dPwmIdx << 1;
2673 switch(pIepPwmRhsAction[pwmIdx])
2674 {
2675 case RHS_ACTION_Set_CmpSr_DcRhsY_And_EnableSrUpdate:
2676 dcRhsY = pIepPwmDcCountRhs[pwmIdx];
2677
2678 pCmpSr = pIepCmpSrAddr[pwmIdx];
2679 *pCmpSr = dcRhsY; /* Write RHS value to CMP Shadow Register */
2680 pwmIdx++;
2681 pCmpSr = pIepCmpSrAddr[pwmIdx];
2682 *pCmpSr = dcRhsY + pIepPwmDbCount[dPwmIdx]; /* Write RHS value to CMP Shadow Register */
2683
2684 *pIepPwmDiffUpdEn |= 1<<dPwmIdx; /* Enable CMP SR update */
2685 break;
2686
2687 case RHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate:
2688 dcRhsY = pIepPwmDcCountRhs[pwmIdx];
2689
2690 /* Write same LHS value to both CMP Shadow Registers in differential pair */
2691 pCmpSr = pIepCmpSrAddr[pwmIdx];
2692 *pCmpSr = iepPwmPeriodCount; /* Write value greater than Period to Shadow Register */
2693 pwmIdx++;
2694 pCmpSr = pIepCmpSrAddr[pwmIdx];
2695 *pCmpSr = iepPwmPeriodCount; /* Write value greater than Period to Shadow Register */
2696
2697 /* Enable CMP SR update */
2698 *pIepPwmDiffUpdEn &= ~(1<<dPwmIdx); /* Disable CMP SR update */
2699 break;
2700
2701 case RHS_ACTION_None:
2702 default:
2703 break;
2704 }
2705 pIepPwmRhsAction[pwmIdx] = RHS_ACTION_None;
2706 }
2707 else {
2708 /* Process Single-Ended PWMs */
2709
2710 for (pwmIdx = dPwmIdx<<1; pwmIdx < ((dPwmIdx<<1) + NUM_PWM_PER_DIFF_PWM); pwmIdx++)
2711 {
2712 switch (pIepPwmRhsAction[pwmIdx])
2713 {
2714 case RHS_ACTION_Set_CmpSr_DcRhsY_And_EnableSrUpdate:
2715 dcRhsY = pIepPwmDcCountRhs[pwmIdx];
2716 pCmpSr = pIepCmpSrAddr[pwmIdx];
2717 *pCmpSr = dcRhsY; /* Write RHS value to CMP Shadow Register */
2718 *pIepPwmSnglUpdEn |= 1<<pwmIdx; /* Enable CMP SR update */
2719 break;
2720 case RHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate:
2721 pCmpSr = pIepCmpSrAddr[pwmIdx];
2722 *pCmpSr = iepPwmPeriodCount; /* Write value greater than Period to CMP Shadow Register */
2723 *pIepPwmSnglUpdEn &= ~(1<<pwmIdx); /* Disable CMP SR update */
2724 break;
2725 case RHS_ACTION_None:
2726 default:
2727 break;
2728 }
2729 pIepPwmRhsAction[pwmIdx] = RHS_ACTION_None;
2730 }
2731 }
2732 }
2733 }
2734}
2735
2736/* Update IEP PWM CMPx Shadow Registers for DB reconfiguration. */
2737static Int32 updateIepPwmCmpxShRegDb(
2738 IcssgIepPwmObj *pIcssgIepPwmObj
2739)
2740{
2741 IepPwmFwRegs *pIepPwmFwRegs = pIcssgIepPwmObj->pIepPwmFwRegs;
2742 Uint32 *pIepPwmDcCount;
2743 volatile Uint16 *pIepPwmDbCount;
2744 volatile uint32_t *pShadowReg;
2745 Uint8 pwmIdx, dPwmIdx;
2746
2747 pIepPwmDcCount = &pIcssgIepPwmObj->iepPwmDcCountLhs[0]; /* init pointer to PWM Duty Cycle Count */
2748 pIepPwmDbCount = &pIepPwmFwRegs->IEP_PWM0_1_DB_COUNT; /* init pointer to PWM Deadband Count */
2749 for (dPwmIdx = 0; dPwmIdx < IEP_MAX_NUM_DIFF_PWM; dPwmIdx++)
2750 {
2751 if (((pIcssgIepPwmObj->iepPwmDiffUpdEn >> dPwmIdx) & 0x1) == 1) { /* check PWM update enabled */
2752 /* Write CMP SR for POS PWM */
2753 pwmIdx = dPwmIdx << 1;
2754 pShadowReg = pIcssgIepPwmObj->iepCmpSrAddr[pwmIdx]; /* set pointer to CMP Shadow Register */
2755 *pShadowReg = pIcssgIepPwmObj->iepPwmPeriodCount - *pIepPwmDcCount;
2756 /* Write CMP SR for NEG PWM.
2757 Increment CMP SR pointer by 2 since CMP registers are 64 bit. */
2758 pwmIdx++;
2759 pShadowReg = pIcssgIepPwmObj->iepCmpSrAddr[pwmIdx]; /* set pointer to CMP Shadow Register */
2760 *pShadowReg = pIcssgIepPwmObj->iepPwmPeriodCount - *pIepPwmDcCount - *pIepPwmDbCount;
2761 }
2762 pIepPwmDcCount += 2; /* differential pair use same Duty Cycle Count */
2763 pIepPwmDbCount++;
2764 }
2765
2766 /* Latch IEP PWM Deadband Count */
2767 latchIepPwmDbCount(pIcssgIepPwmObj, TRUE);
2768
2769 return IEP_STS_NERR;
2770}
diff --git a/example/apps/icssg_pwm/firmware/src/iepPwm.h b/example/apps/icssg_pwm/firmware/src/iepPwm.h
new file mode 100644
index 0000000..61673a8
--- /dev/null
+++ b/example/apps/icssg_pwm/firmware/src/iepPwm.h
@@ -0,0 +1,247 @@
1/*
2 * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
3 *
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the
15 * distribution.
16 *
17 * * Neither the name of Texas Instruments Incorporated nor the names of
18 * its contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34#ifndef _IEP_PWM_H_
35#define _IEP_PWM_H_
36
37#include <ti/csl/tistdtypes.h>
38#include "iepPwmFwRegs.h"
39#include "iepPwmHwRegs.h"
40
41/* Return status codes */
42#define IEP_STS_RECFG_PRD_COUNT ( 1 ) /* no error, IEP Period Count reconfiguration */
43#define IEP_STS_NERR ( 0 ) /* no error */
44#define IEP_STS_ERR_INV_IEP_ID ( -1 ) /* error, invalid IEP ID */
45#define IPE_STS_ERR_INV_DC_COUNT ( -2 ) /* error, invalid Duty Cycle Count */
46
47/* IEPs per ICSSG */
48#define ICSSG_NUM_IEP ( 2 )
49
50/* PWM sets per IEP */
51#define IEP_NUM_PWM_SET ( 2 )
52
53/* Number of PWMs per Differential PWM pair */
54#define NUM_PWM_PER_DIFF_PWM ( 2 )
55/* Number of differential PWMs per PWM set */
56#define DIFF_PWM_PER_SET ( 3 )
57/* Number of single-ended PWMs per PWM set, two sets per IEP */
58#define SNGL_PWM_PER_SET ( DIFF_PWM_PER_SET * NUM_PWM_PER_DIFF_PWM )
59
60/* IEP maximum number of Differential PWMs */
61#define IEP_MAX_NUM_DIFF_PWM ( IEP_NUM_PWM_SET * DIFF_PWM_PER_SET )
62/* IEP maximum number of Single-Ended PWMs */
63#define IEP_MAX_NUM_SNGL_PWM ( IEP_NUM_PWM_SET * SNGL_PWM_PER_SET )
64
65#define DEF_COUNT_INC_PER_CLK ( 5 ) /* IEP counter default increments per tick */
66
67#define IEP_CMP_STATUS_CMP0_MASK ( 0x1 )
68#define IEP_CMP_STATUS_CMP1_12_MASK ( 0x1FFE )
69#define IEP_CMP_STATUS_CMP0_12_MASK ( IEP_CMP_STATUS_CMP0_MASK | IEP_CMP_STATUS_CMP1_12_MASK )
70
71
72/* IEP IDs */
73typedef enum IepId_e
74{
75 IEP_ID_0 = 0, /* IEP 0 ID */
76 IEP_ID_1 = 1 /* IEP 1 ID */
77} IepId;
78
79/* Latch Actions */
80typedef enum IepLatchAction_e
81{
82 /* Latch Action: None */
83 LATCH_ACTION_None = 0,
84 /* Latch Action: Latch 0 -- don't calculate LHS/RHS DC*/
85 LATCH_ACTION_Latch_0 = 1,
86 /* Latch Action: Latch 100 -- don't calculate LHS/RHS DC */
87 LATCH_ACTION_Latch_100 = 2,
88 /* Latch Action: Latch x, x!=0, x!=100, calculate LHS/RHS DC */
89 LATCH_ACTION_Latch_New = 3
90} IepLatchAction;
91
92/* Left-Hand Side Actions */
93typedef enum IepPwmLhsAction_e
94{
95 /* LHS Action: None */
96 LHS_ACTION_None = 0,
97 /* LHS Action: Set IEP CMP Shadow Register to new value Y */
98 LHS_ACTION_Set_CmpSr_DcLhsY = 1,
99 /* LHS Action: Set IEP CMP Shadow Register to old (latched) value X &
100 enable Shadow Register update */
101 LHS_ACTION_Set_CmpSr_DcLhsX_And_EnableSrUpdate = 2,
102 /* LHS Action: Set IEP CMP Shadow Register to new value Y &
103 enable Shadow Register update */
104 LHS_ACTION_Set_CmpSr_DcLhsY_And_EnableSrUpdate = 3,
105 /* RHS Action: Set IEP CMP Shadow Register early in CMP0 Period &
106 enable Shadow Register update */
107 LHS_ACTION_Set_CmpSr_EarlyInPrd_And_EnableSrUpdate = 4,
108 /* RHS Action: Set IEP CMP Shadow Register > CMP0 Period &
109 enable Shadow Register update */
110 LHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate = 5
111} IepPwmLhsAction;
112
113/* Right-Hand Side Actions */
114typedef enum IepPwmRhsAction_e
115{
116 /* RHS Action: None */
117 RHS_ACTION_None = 0,
118 /* RHS Action: Set IEP CMP Shadow Register to new value Y &
119 enable Shadow Register update */
120 RHS_ACTION_Set_CmpSr_DcRhsY_And_EnableSrUpdate = 1,
121 /* RHS Action: Set IEP CMP Shadow Register > CMP0 Period &
122 enable Shadow Register update */
123 RHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate = 2
124} IepPwmRhsAction;
125
126/* IEP PWM State Machine configurations */
127typedef enum IepSm_Config_e
128{
129 IEP_SM_CONFIG_NONE = 0, /* IEP SM Configuration, IEP0 & 1 disabled */
130 IEP_SM_CONFIG_IEP1 = 1, /* IEP SM Configuration, IEP0 disabled, IEP1 enabled */
131 IEP_SM_CONFIG_IEP0 = 2, /* IEP SM Configuration, IEP0 enabled, IEP1 disabled */
132 IEP_SM_CONFIG_IEP0_1 = 3 /* IEP SM Configuration, IEP0 & 1 enabled */
133} IepSm_Config;
134
135/* IEP PWM State Machine states */
136typedef enum IepSm_States_e
137{
138 IEP_SM_STATE_UNINIT = 0, /* IEP SM State, Uninitialized */
139 IEP_SM_STATE_INIT = 1, /* IEP SM State, Initialization */
140 IEP_SM_STATE_LHS = 2, /* IEP SM State, Left-Hand Side */
141 IEP_SM_STATE_RHS = 3, /* IEP SM State, Right-Hand Side */
142 IEP_SM_STATE_LHS_RECFG = 4, /* IEP SM State, Left-Hand Side Reconfiguration */
143 IEP_SM_STATE_RHS_RECFG = 5, /* IEP SM State, Right-Hand Side Reconfiguration */
144} IepSm_States;
145
146
147/* ICSSG IEP PWM control object */
148typedef struct IcssgIepPwmCtrlObj_s
149{
150 Bool iepPwmGblEn[ICSSG_NUM_IEP]; /* IEP PWM global disable/enable flags */
151 CSL_icss_g_pr1_cfg_slvRegs *pIcssgCfgHwRegs; /* ICSSG CFG registers, init to CSL_ICSS_CFG_BASE */
152 IepPwmCtrlFwRegs *pIepPwmCtrlFwRegs; /* IEP PWM FW control registers, init to &PWM_CTRL */
153} IcssgIepPwmCtrlObj;
154
155/* ICSSG IEP PWM object */
156typedef struct IcssgIepPwmObj_s
157{
158 IepId iepId; /* IEP ID, init to 0 or 1 */
159 Uint32 iepPwmMode; /* IEP mode */
160 Uint32 iepPwmEn; /* IEP enable */
161 Uint32 iepPwmPeriodCount; /* IEP period count */
162 Uint32 iepPwmDcCount[IEP_MAX_NUM_SNGL_PWM]; /* IEP PWM calculated duty cycle count for Symmetric PWM */
163 Uint16 iepPwmDbCount[IEP_MAX_NUM_DIFF_PWM]; /* IEP PWM dead band cycle count for differential mode PWM */
164 Uint16 iepPwmSnglEn; /* Bits 11-0 determine if single-ended mode enabled */
165 Uint8 iepPwmDiffEn; /* Bits 5-0 determine if differential mode enabled */
166 Uint16 iepPwmSnglUpdEn; /* Bits 11-0 determine if single-ended mode update enabled */
167 Uint8 iepPwmDiffUpdEn; /* Bits 5-0 determine if differential mode update enabled */
168 Uint32 iepPwmDcCountLhs[IEP_MAX_NUM_SNGL_PWM]; /* IEP PWM calculated duty cycle count for Left-Hand Side of Symmetric PWM */
169 Uint32 iepPwmDcCountRhs[IEP_MAX_NUM_SNGL_PWM]; /* IEP PWM calculated duty cycle count for Right-Hand Side of Symmetric PWM */
170 IepSm_States iepPwmState; /* State Machine current state */
171 Bool iepPwmRhsRecfgFlag; /* init to FALSE, set to TRUE if RHS reconfig required */
172 IepPwmRhsAction iepPwmRhsAction[IEP_MAX_NUM_SNGL_PWM]; /* IEP PWM RHS action */
173 IepPwmFwRegs *pIepPwmFwRegs; /* IEP PWM FW registers, init to &IEPx_PWM_RECFG */
174 CSL_icss_g_pr1_iep1_slvRegs *pIepHwRegs; /* IEP hardware registers base address, init to CSL_ICSS_IEP_CFG_BASE */
175 IepPwmTripHwRegs *pIepPwmTripHwRegs; /* IEP PWM Trip Configuration hardware registers base address. IEP0: init to ICSSG_PWM0, IEP1: init to ICSSG_PWM2. */
176 IepPwmStateCfgHwRegs *pPwmStateCfgHwRegs; /* IEP PWM State Configuration hardware registers base address. IEP0: init to ICSSG_PWM0_0, IEP1: init to ICSSG_PWM2_0. */
177 volatile uint32_t *iepCmpSrAddr[IEP_MAX_NUM_SNGL_PWM]; /* IEP CMP Shadow Register address table -- used to circumvent gap in CMP SR MM addresses */
178
179} IcssgIepPwmObj;
180
181extern IcssgIepPwmCtrlObj gIcssgIepPwmCtrlObj; /* IEP PWM control object */
182extern IcssgIepPwmObj gIcssgIep0PwmObj; /* IEP 0 PWM object */
183extern IcssgIepPwmObj gIcssgIep1PwmObj; /* IEP 1 PWM object */
184
185/* Reset PWM FW control object */
186Int32 resetPwmCtrlObj(
187 IcssgIepPwmCtrlObj *pIcssgIepPwmCtrlObj
188);
189
190/* Wait for PWM enable flag from Host.
191 Flag indicates to FW that initialization can commence. */
192Int32 waitPwmEnFlag(
193 IcssgIepPwmCtrlObj *pIcssgIepPwmCtrlObj
194);
195
196/* Initialize PWM FW control */
197Int32 initPwmCtrl(
198 IcssgIepPwmCtrlObj *pIcssgIepPwmCtrlObj
199);
200
201/* Reset IEP PWM object */
202Int32 resetIepPwmObj(
203 IcssgIepPwmObj *pIcssgIepPwmObj,
204 IepId iepId
205);
206
207/* Initialize IEP PWM object
208 *
209 * Initial Configuration is located in Host I/F FW Regs.
210 * Default Initial Configuration is loaded in DMEM load (static data).
211 * Host can overwrite Default Initial Configuration *before* FW execution.
212 *
213 * Initial Configuration Applied whether Host_RECFG != 0 or not, i.e. Host_RECFG not checked.
214 * Initial Configuration is only place PWM MODE is configured.
215*/
216Int32 initIepPwm(
217 IcssgIepPwmCtrlObj *pIcssgIepPwmCtrlObj,
218 IcssgIepPwmObj *pIcssgIepPwmObj
219);
220
221/* Set PWM FW initialization flag.
222 Flag indicates to Host that FW initialization is complete. */
223Int32 setPwmFwInitFlag(
224 IcssgIepPwmCtrlObj *pIcssgIepPwmCtrlObj
225);
226
227/* Get IEP PWM State Machine configuration:
228 - IEP0 disabled, IEP1 disabled
229 - IEP0 disabled, IEP1 enabled
230 - IEP0 enabled, IEP1 disabled
231 - IEP0 enabled, IEP1 enabled */
232IepSm_Config getIepPwmSmConfig(
233 IcssgIepPwmCtrlObj *pIcssgIepPwmCtrlObj
234);
235
236/* Initialize IEP PWM State Machine */
237void initIepPwmSm(
238 IcssgIepPwmObj *pIcssgIepPwmObj
239);
240
241/* Execute IEP PWM State Machine */
242Int32 execIepPwmSm(
243 IcssgIepPwmObj *pIcssgIepPwmObj,
244 Bool txHostEvt
245);
246
247#endif /* _IEP_PWM_H_ */
diff --git a/example/apps/icssg_pwm/firmware/src/iepPwmFwRegs.c b/example/apps/icssg_pwm/firmware/src/iepPwmFwRegs.c
new file mode 100644
index 0000000..b1388c0
--- /dev/null
+++ b/example/apps/icssg_pwm/firmware/src/iepPwmFwRegs.c
@@ -0,0 +1,136 @@
1/*
2 * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
3 *
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the
15 * distribution.
16 *
17 * * Neither the name of Texas Instruments Incorporated nor the names of
18 * its contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34#include <ti/csl/tistdtypes.h>
35#include "firmware_version.h"
36#include "iepPwmFwRegs.h"
37
38/* PWM Info defaults */
39#define DEF_FW_MAGIC_NUMBER ( 0x4D575047 ) /* Firmware Magic Number - GPWM */
40#define DEF_FW_TYPE ( ICSSG_PWM_FIRMWARE_TYPE ) /* Firmware Type */
41#define DEF_FW_VERSION ( ICSSG_PWM_FIRMWARE_VERSION ) /* Firmware Version */
42#define DEF_FW_FEATURE ( ICSSG_PWM_FIRMWARE_FEATURE ) /* Firmware Feature */
43#define DEF_FW_EXTENDED_FEATURE ( ICSSG_PWM_FIRMWARE_EXTENDED_FEATURE_PTR ) /* Firmware Extended Feature */
44
45/* PWM control defaults */
46#define DEF_PWM_CTRL ( 0x00000000 ) /* PWM control - IEP0 & IEP1 PWMs disabled */
47#define DEF_PWM_STAT ( 0x00000000 ) /* PWM status - IEP0 & IEP1 PWM ACK disabled, FW initialization flag uninitialized */
48#define DEF_PWM_RECFG ( 0x00000000 ) /* Default no reconfiguration request */
49
50#define DEF_PWM_MODE ( 0x00000000 ) /* Default all PWMs are Single-Ended */
51#define DEF_PWM_EN ( 0x00000000 ) /* Default all PWMs are disabled */
52
53/* IEP clock @ 200 MHz */
54#define DEF_PRD_COUNT ( 0x0007A120 ) /* Default Period Count, PWM freq 1 kHz */
55#define DEF_DC_COUNT ( 0x0007A120 ) /* Default DC Count, 50% Duty Cycle PWM freq 1 kHz */
56#define DEF_DB_COUNT ( 0x0A00 ) /* Default DB Count, 2.56 usec. */
57
58/* FW Info register defaults */
59#pragma RETAIN(gIepPwmInfoFwRegs)
60#pragma DATA_SECTION(gIepPwmInfoFwRegs, ".initDataFwRegs")
61const IepPwmInfoFwRegs gIepPwmInfoFwRegs =
62{
63 DEF_FW_MAGIC_NUMBER, /* FwMagicNumber */
64 DEF_FW_TYPE, /* FwType */
65 DEF_FW_VERSION, /* FwVersion */
66 DEF_FW_FEATURE, /* FwFeature */
67 DEF_FW_EXTENDED_FEATURE /* FwExtendedFeature - Reserved for future use */
68};
69
70/* FW PWM Control/Status register defaults */
71#pragma RETAIN(gIepPwmCtrlFwRegs)
72#pragma DATA_SECTION(gIepPwmCtrlFwRegs, ".initDataFwRegs")
73const IepPwmCtrlFwRegs gIepPwmCtrlFwRegs =
74{
75 DEF_PWM_CTRL, /* PWM_CTRL */
76 DEF_PWM_STAT /* PWM_STAT */
77};
78
79/* FW IEP0 PWM register defaults */
80#pragma RETAIN(gIep0PwmFwRegs)
81#pragma DATA_SECTION(gIep0PwmFwRegs, ".initDataFwRegs")
82const IepPwmFwRegs gIep0PwmFwRegs =
83{
84 DEF_PWM_RECFG, /* IEP0_PWM_RECFG */
85 DEF_PWM_MODE, /* IEP0_PWM_MODE */
86 DEF_PWM_EN, /* IEP0_PWM_EN */
87 DEF_PRD_COUNT, /* IEP0_PWM_PRD_COUNT */
88 DEF_DC_COUNT, /* IEP0_PWM0_DC_COUNT */
89 DEF_DC_COUNT, /* IEP0_PWM1_DC_COUNT */
90 DEF_DC_COUNT, /* IEP0_PWM2_DC_COUNT */
91 DEF_DC_COUNT, /* IEP0_PWM3_DC_COUNT */
92 DEF_DC_COUNT, /* IEP0_PWM4_DC_COUNT */
93 DEF_DC_COUNT, /* IEP0_PWM5_DC_COUNT */
94 DEF_DC_COUNT, /* IEP0_PWM6_DC_COUNT */
95 DEF_DC_COUNT, /* IEP0_PWM7_DC_COUNT */
96 DEF_DC_COUNT, /* IEP0_PWM8_DC_COUNT */
97 DEF_DC_COUNT, /* IEP0_PWM9_DC_COUNT */
98 DEF_DC_COUNT, /* IEP0_PWM10_DC_COUNT */
99 DEF_DC_COUNT, /* IEP0_PWM11_DC_COUNT */
100 DEF_DB_COUNT, /* IEP0_PWM0_1_DEADBAND */
101 DEF_DB_COUNT, /* IEP0_PWM2_3_DEADBAND */
102 DEF_DB_COUNT, /* IEP0_PWM4_5_DEADBAND */
103 DEF_DB_COUNT, /* IEP0_PWM6_7_DEADBAND */
104 DEF_DB_COUNT, /* IEP0_PWM8_9_DEADBAND */
105 DEF_DB_COUNT, /* IEP0_PWM10_11_DEADBAND */
106};
107
108/* FW IEP1 PWM register defaults */
109#pragma RETAIN(gIep1PwmFwRegs)
110#pragma DATA_SECTION(gIep1PwmFwRegs, ".initDataFwRegs")
111const IepPwmFwRegs gIep1PwmFwRegs =
112{
113 DEF_PWM_RECFG, /* IEP1_PWM_RECFG */
114 DEF_PWM_MODE, /* IEP1_PWM_MODE */
115 DEF_PWM_EN, /* IEP1_PWM_EN */
116 DEF_PRD_COUNT, /* IEP1_PWM_PRD_COUNT */
117 DEF_DC_COUNT, /* IEP1_PWM0_DC_COUNT */
118 DEF_DC_COUNT, /* IEP1_PWM1_DC_COUNT */
119 DEF_DC_COUNT, /* IEP1_PWM2_DC_COUNT */
120 DEF_DC_COUNT, /* IEP1_PWM3_DC_COUNT */
121 DEF_DC_COUNT, /* IEP1_PWM4_DC_COUNT */
122 DEF_DC_COUNT, /* IEP1_PWM5_DC_COUNT */
123 DEF_DC_COUNT, /* IEP1_PWM6_DC_COUNT */
124 DEF_DC_COUNT, /* IEP1_PWM7_DC_COUNT */
125 DEF_DC_COUNT, /* IEP1_PWM8_DC_COUNT */
126 DEF_DC_COUNT, /* IEP1_PWM9_DC_COUNT */
127 DEF_DC_COUNT, /* IEP1_PWM10_DC_COUNT */
128 DEF_DC_COUNT, /* IEP1_PWM11_DC_COUNT */
129 DEF_DB_COUNT, /* IEP1_PWM0_1_DEADBAND */
130 DEF_DB_COUNT, /* IEP1_PWM2_3_DEADBAND */
131 DEF_DB_COUNT, /* IEP1_PWM4_5_DEADBAND */
132 DEF_DB_COUNT, /* IEP1_PWM6_7_DEADBAND */
133 DEF_DB_COUNT, /* IEP1_PWM8_9_DEADBAND */
134 DEF_DB_COUNT, /* IEP1_PWM10_11_DEADBAND */
135};
136
diff --git a/example/apps/icssg_pwm/firmware/src/iepPwmFwRegs.h b/example/apps/icssg_pwm/firmware/src/iepPwmFwRegs.h
new file mode 100644
index 0000000..73b125e
--- /dev/null
+++ b/example/apps/icssg_pwm/firmware/src/iepPwmFwRegs.h
@@ -0,0 +1,83 @@
1/*
2 * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
3 *
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the
15 * distribution.
16 *
17 * * Neither the name of Texas Instruments Incorporated nor the names of
18 * its contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34#ifndef _IEP_PWM_FW_REGS_H_
35#define _IEP_PWM_FW_REGS_H_
36
37#include <ti/csl/cslr_icss.h>
38
39/* PWM Firmware information registers */
40typedef struct IepPwmInfoFwRegs_s
41{
42 volatile Uint32 FwMagicNumber; /* Firmware Magic Number Fw Reg */
43 volatile Uint32 FwType; /* Firmware Type Information Fw Reg */
44 volatile Uint32 FwVersion; /* Firmware Version Information Fw Reg */
45 volatile Uint32 FwFeature; /* Firmware Feature Information Fw Reg */
46 volatile Uint32 FwExtendedFeature; /* Firmware Extended Feature Information Fw Reg */
47} IepPwmInfoFwRegs;
48
49/* PWM Firmware Control/Status registers */
50typedef struct IepPwmCtrlFwRegs_s
51{
52 volatile Uint32 PWM_CTRL; /* PWM Control Fw Reg */
53 volatile Uint32 PWM_STAT; /* PWM Status Fw Reg */
54} IepPwmCtrlFwRegs;
55
56/* IEP PWM Firmware registers */
57typedef struct IepPwmFwRegs_s
58{
59 volatile Uint32 IEP_PWM_RECFG; /* IEP PWM Reconfiguration Fw Reg */
60 volatile Uint32 IEP_PWM_MODE; /* IEP PWM Mode Fw Reg */
61 volatile Uint32 IEP_PWM_EN; /* IEP PWM Enable Fw Reg */
62 volatile Uint32 IEP_PWM_PRD_COUNT; /* IEP PWM Period Count Fw Reg */
63 volatile Uint32 IEP_PWM0_DC_COUNT; /* IEP PWM0 Duty Cycle Count Fw Reg */
64 volatile Uint32 IEP_PWM1_DC_COUNT; /* IEP PWM1 Duty Cycle Count Fw Reg */
65 volatile Uint32 IEP_PWM2_DC_COUNT; /* IEP PWM2 Duty Cycle Count Fw Reg */
66 volatile Uint32 IEP_PWM3_DC_COUNT; /* IEP PWM3 Duty Cycle Count Fw Reg */
67 volatile Uint32 IEP_PWM4_DC_COUNT; /* IEP PWM4 Duty Cycle Count Fw Reg */
68 volatile Uint32 IEP_PWM5_DC_COUNT; /* IEP PWM5 Duty Cycle Count Fw Reg */
69 volatile Uint32 IEP_PWM6_DC_COUNT; /* IEP PWM6 Duty Cycle Count Fw Reg */
70 volatile Uint32 IEP_PWM7_DC_COUNT; /* IEP PWM7 Duty Cycle Count Fw Reg */
71 volatile Uint32 IEP_PWM8_DC_COUNT; /* IEP PWM8 Duty Cycle Count Fw Reg */
72 volatile Uint32 IEP_PWM9_DC_COUNT; /* IEP PWM9 Duty Cycle Count Fw Reg */
73 volatile Uint32 IEP_PWM10_DC_COUNT; /* IEP PWM10 Duty Cycle Count Fw Reg */
74 volatile Uint32 IEP_PWM11_DC_COUNT; /* IEP PWM11 Duty Cycle Count Fw Reg */
75 volatile Uint16 IEP_PWM0_1_DB_COUNT; /* IEP PWM0/1 Dead Band Cycle Count Fw Reg */
76 volatile Uint16 IEP_PWM2_3_DB_COUNT; /* IEP PWM2/3 Dead Band Cycle Count Fw Reg */
77 volatile Uint16 IEP_PWM4_5_DB_COUNT; /* IEP PWM4/5 Dead Band Cycle Count Fw Reg */
78 volatile Uint16 IEP_PWM6_7_DB_COUNT; /* IEP PWM6/7 Dead Band Cycle Count Fw Reg */
79 volatile Uint16 IEP_PWM8_9_DB_COUNT; /* IEP PWM8/9 Dead Band Cycle Count Fw Reg */
80 volatile Uint16 IEP_PWM10_11_DB_COUNT; /* IEP PWM10/11 Dead Band Cycle Count Fw Reg */
81} IepPwmFwRegs;
82
83#endif /* _IEP_PWM_FW_REGS_H_ */
diff --git a/example/apps/icssg_pwm/firmware/src/iepPwmHwRegs.h b/example/apps/icssg_pwm/firmware/src/iepPwmHwRegs.h
new file mode 100644
index 0000000..88529bd
--- /dev/null
+++ b/example/apps/icssg_pwm/firmware/src/iepPwmHwRegs.h
@@ -0,0 +1,76 @@
1/*
2 * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
3 *
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the
15 * distribution.
16 *
17 * * Neither the name of Texas Instruments Incorporated nor the names of
18 * its contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34#ifndef _IEP_PWM_HW_REGS_H_
35#define _IEP_PWM_HW_REGS_H_
36
37#include <ti/csl/tistdtypes.h>
38#include <ti/csl/soc.h>
39
40/* IEP0/1 HW register base addresses */
41#define ICSS_IEP0_CFG_BASE ( CSL_ICSS_IEP_CFG_BASE )
42#define ICSS_IEP1_CFG_BASE ( ICSS_IEP0_CFG_BASE + CSL_ICSS_IEP_CFG_SIZE )
43
44/* PWM trip reset event mask */
45#define PWM_TRIP_RESET_MASK ( CSL_ICSS_G_PR1_CFG_SLV_PWM0_PWM0_TRIP_RESET_MASK )
46
47/* ICSSG_PWM0m_n, set m=0...4, pos/neg signal n=0...3 */
48#define PWM_INIT_HIZ ( 0 )
49#define PWM_INIT_LO ( 1 )
50#define PWM_INIT_HI ( 2 )
51#define PWM_TRIP_HIZ ( 0 )
52#define PMW_TRIP_LO ( 1 )
53#define PWM_TRIP_HI ( 2 )
54#define PWM_ACT_TOGGLE ( 0 )
55#define PMW_ACT_LO ( 1 )
56#define PWM_ACT_HI ( 2 )
57
58/* IEP PWM Trip Configuration hardware registers */
59typedef struct IepPwmTripHwRegs_s
60{
61 volatile Uint32 ICSSG_PWM0; /* IEP PWM Set 1/2 */
62 volatile Uint32 ICSSG_PWM1; /* IEP PWM Set 2/2 */
63} IepPwmTripHwRegs;
64
65/* IEP PWM State Configuration hardware registers */
66typedef struct IepPwmStateCfgHwRegs_s
67{
68 volatile Uint32 ICSSG_PWM0_0; /* IEP PWM Set 1, PWM0 */
69 volatile Uint32 ICSSG_PWM0_1; /* IEP PWM Set 1, PWM1 */
70 volatile Uint32 ICSSG_PWM0_2; /* IEP PWM Set 1, PWM2 */
71 volatile Uint32 ICSSG_PWM1_0; /* IEP PWM Set 2, PWM0 */
72 volatile Uint32 ICSSG_PWM1_1; /* IEP PWM Set 2, PWM1 */
73 volatile Uint32 ICSSG_PWM1_2; /* IEP PWM Set 2, PWM2 */
74} IepPwmStateCfgHwRegs;
75
76#endif /* #define _IEP_PWM_HW_REGS_H_ */
diff --git a/example/apps/icssg_pwm/firmware/src/main.c b/example/apps/icssg_pwm/firmware/src/main.c
new file mode 100644
index 0000000..b877781
--- /dev/null
+++ b/example/apps/icssg_pwm/firmware/src/main.c
@@ -0,0 +1,174 @@
1/*
2 * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
3 *
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the
15 * distribution.
16 *
17 * * Neither the name of Texas Instruments Incorporated nor the names of
18 * its contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34#include "iepPwmFwRegs.h"
35#include "iepPwmHwRegs.h"
36#include "iepPwm.h"
37#include "icssg_iep_pwm.h"
38#include "resource_table_empty.h"
39
40void main(void)
41{
42 Int32 status;
43 IepSm_Config iepSmConfig;
44
45 /* Reset PWM FW control object */
46 status = resetPwmCtrlObj(&gIcssgIepPwmCtrlObj);
47 if (status != IEP_STS_NERR)
48 {
49 /* Indicate Error to Host */
50 ;
51 }
52
53 /* Reset IEP 0 PWM object */
54 status = resetIepPwmObj(&gIcssgIep0PwmObj, IEP_ID_0);
55 if (status != IEP_STS_NERR)
56 {
57 /* Indicate Error to Host */
58 ;
59 }
60
61 /* Reset IEP 1 PWM object */
62 status = resetIepPwmObj(&gIcssgIep1PwmObj, IEP_ID_1);
63 if (status != IEP_STS_NERR)
64 {
65 /* Indicate Error to Host */
66 ;
67 }
68
69 /* Wait for PWM enable flag from Host, indicates FW init can commence */
70 status = waitPwmEnFlag(&gIcssgIepPwmCtrlObj);
71 if (status != IEP_STS_NERR)
72 {
73 /* Indicate Error to Host */
74 ;
75 }
76
77 /* Initialize PWM FW control */
78 status = initPwmCtrl(&gIcssgIepPwmCtrlObj);
79 if (status != IEP_STS_NERR)
80 {
81 /* Indicate Error to Host */
82 ;
83 }
84
85 /* Initialize IEP0 PWM */
86 status = initIepPwm(&gIcssgIepPwmCtrlObj, &gIcssgIep0PwmObj);
87 if (status != IEP_STS_NERR)
88 {
89 /* Indicate Error to Host */
90 ;
91 }
92
93 /* Initialize IEP1 PWM */
94 status = initIepPwm(&gIcssgIepPwmCtrlObj, &gIcssgIep1PwmObj);
95 if (status != IEP_STS_NERR)
96 {
97 /* Indicate Error to Host */
98 ;
99 }
100
101 /* Set PWM FW init flag, indicate FW init complete to Host */
102 status = setPwmFwInitFlag(&gIcssgIepPwmCtrlObj);
103 if (status != IEP_STS_NERR)
104 {
105 /* Indicate Error to Host */
106 ;
107 }
108
109 /* Get State Machine configuration */
110 iepSmConfig = getIepPwmSmConfig(&gIcssgIepPwmCtrlObj);
111
112 /* Execute State Machine(s) */
113 if (iepSmConfig == IEP_SM_CONFIG_IEP0)
114 {
115 /* IEP0 PWM enabled */
116 initIepPwmSm(&gIcssgIep0PwmObj);
117 while (1)
118 {
119 gIcssgIep0PwmObj.pIepHwRegs->CMP_STATUS_REG = IEP_CMP_STATUS_CMP1_12_MASK; /* clear all but CMP0 events */
120 status = execIepPwmSm(&gIcssgIep0PwmObj, TRUE);
121 if (status != IEP_STS_NERR)
122 {
123 /* Indicate Error to Host */
124 ;
125 }
126 }
127 }
128 else if (iepSmConfig == IEP_SM_CONFIG_IEP1)
129 {
130 /* IEP1 PWM enabled */
131 initIepPwmSm(&gIcssgIep1PwmObj);
132 while (1)
133 {
134 gIcssgIep1PwmObj.pIepHwRegs->CMP_STATUS_REG = IEP_CMP_STATUS_CMP1_12_MASK; /* clear all but CMP0 events */
135 status = execIepPwmSm(&gIcssgIep1PwmObj, TRUE);
136 if (status != IEP_STS_NERR)
137 {
138 /* Indicate Error to Host */
139 ;
140 }
141 }
142 }
143 else if (iepSmConfig == IEP_SM_CONFIG_IEP0_1)
144 {
145 /* IEP0 & IEP1 PWM enabled */
146 initIepPwmSm(&gIcssgIep0PwmObj);
147 initIepPwmSm(&gIcssgIep1PwmObj);
148 while (1)
149 {
150 gIcssgIep0PwmObj.pIepHwRegs->CMP_STATUS_REG = IEP_CMP_STATUS_CMP1_12_MASK; /* clear all but CMP0 events */
151 gIcssgIep1PwmObj.pIepHwRegs->CMP_STATUS_REG = IEP_CMP_STATUS_CMP1_12_MASK; /* clear all but CMP0 events */
152
153 status = execIepPwmSm(&gIcssgIep0PwmObj, TRUE);
154 if (status != IEP_STS_NERR)
155 {
156 /* Indicate Error to Host */
157 ;
158 }
159
160 status = execIepPwmSm(&gIcssgIep1PwmObj, FALSE);
161 if (status != IEP_STS_NERR)
162 {
163 /* Indicate Error to Host */
164 ;
165 }
166 }
167 }
168 else /* iepSmConfig == IEP_SM_CONFIG_NONE */
169 {
170 /* Nothing to do */
171 while (1)
172 ;
173 }
174}
diff --git a/example/apps/icssg_pwm/firmware/src/resource_table_empty.h b/example/apps/icssg_pwm/firmware/src/resource_table_empty.h
new file mode 100644
index 0000000..9d9d20f
--- /dev/null
+++ b/example/apps/icssg_pwm/firmware/src/resource_table_empty.h
@@ -0,0 +1,72 @@
1/*
2 * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
3 *
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the
15 * distribution.
16 *
17 * * Neither the name of Texas Instruments Incorporated nor the names of
18 * its contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34/*
35 * ======== resource_table_empty.h ========
36 *
37 * Define the resource table entries for all PRU cores. This will be
38 * incorporated into corresponding base images, and used by the remoteproc
39 * on the host-side to allocated/reserve resources. Note the remoteproc
40 * driver requires that all PRU firmware be built with a resource table.
41 *
42 * This file contains an empty resource table. It can be used either as:
43 *
44 * 1) A template, or
45 * 2) As-is if a PRU application does not need to configure PRU_INTC
46 * or interact with the rpmsg driver
47 *
48 */
49
50#ifndef _RSC_TABLE_PRU_H_
51#define _RSC_TABLE_PRU_H_
52
53#include <stddef.h>
54
55struct my_resource_table {
56 uint32_t ver;
57 uint32_t num;
58 uint32_t reserved[2];
59 uint32_t offset[1]; /* Should match 'num' in actual definition */
60};
61
62#pragma DATA_SECTION(pru_remoteproc_ResourceTable, ".resource_table")
63#pragma RETAIN(pru_remoteproc_ResourceTable)
64struct my_resource_table pru_remoteproc_ResourceTable = {
65 1, /* we're the first version that implements this */
66 0, /* number of entries in the table */
67 0, 0, /* reserved, must be zero */
68 0, /* offset[0] */
69};
70
71#endif /* _RSC_TABLE_PRU_H_ */
72