From fc9595ae9662dda7311f872874ddbcbab639574c Mon Sep 17 00:00:00 2001 From: Jukka Laitinen Date: Wed, 27 Mar 2024 10:46:24 +0200 Subject: [PATCH] arch/arm64/src/imx9: Flex-IO based PWM driver for imx9 This is a high resolution PWM driver, utilizing one 16-bit Flex-IO timer for generating PWM period and the rest of the timers to generate PWM duty cycles. This means that the period has to be the same for every PWM generated from one FLEXIO block, but this way we can get 16-bit resolution for the PWM signals. For a typical IMX9 HW there are 8 timers for each Flex-IO block, which means that by using this driver one can get 7 PWM outputs from one block. This driver can be later extended to have configuration options to use all 8 channels per flex-io by either using 8+8 -bit timer (less resolution) or by using an external trigger from an LPIT. Signed-off-by: Jukka Laitinen --- arch/arm64/src/imx9/Kconfig | 41 + arch/arm64/src/imx9/Make.defs | 4 + arch/arm64/src/imx9/hardware/imx9_flexio.h | 823 +++++++++++++++++++++ arch/arm64/src/imx9/imx9_flexio_pwm.c | 756 +++++++++++++++++++ arch/arm64/src/imx9/imx9_flexio_pwm.h | 104 +++ 5 files changed, 1728 insertions(+) create mode 100644 arch/arm64/src/imx9/hardware/imx9_flexio.h create mode 100644 arch/arm64/src/imx9/imx9_flexio_pwm.c create mode 100644 arch/arm64/src/imx9/imx9_flexio_pwm.h diff --git a/arch/arm64/src/imx9/Kconfig b/arch/arm64/src/imx9/Kconfig index 64a266865aa84..18183cdde58b5 100644 --- a/arch/arm64/src/imx9/Kconfig +++ b/arch/arm64/src/imx9/Kconfig @@ -16,16 +16,57 @@ config ARCH_CHIP_IMX93 select ARCH_HAVE_MULTICPU select ARMV8A_HAVE_GICv3 select ARCH_CORTEX_A55 + select ARCH_HAVE_PWM_MULTICHAN endchoice # i.MX9 Chip Selection endmenu # "i.MX9 Chip Selection" +config IMX9_FLEXIO_PWM + bool + select PWM_MULTICHAN + default n + menu "i.MX9 Peripheral Selection" config IMX9_UART1 bool "UART1" default n select UART1_SERIALDRIVER + +config IMX9_FLEXIO1_PWM + depends on PWM + bool "Enable FLEXIO1 based PWM generation" + select IMX9_FLEXIO_PWM + default n + +config IMX9_FLEXIO2_PWM + depends on PWM + bool "Enable FLEXIO2 based PWM generation" + select IMX9_FLEXIO_PWM + default n + +config IMX9_FLEXIO1_PWM_NCHANNELS + depends on IMX9_FLEXIO1_PWM + int "Number of channels for FLEXIO1" + default 4 + range 1 7 + +config IMX9_FLEXIO1_PWM_CHANNEL_PINS + depends on IMX9_FLEXIO1_PWM + hex "FlexIO outputs used for FLEXIO1 timers" + default 0x0000000007060504 + +config IMX9_FLEXIO2_PWM_NCHANNELS + depends on IMX9_FLEXIO2_PWM + int "Number of channels for FLEXIO2" + default 1 + range 1 7 + +config IMX9_FLEXIO2_PWM_CHANNEL_PINS + depends on IMX9_FLEXIO2_PWM + hex "FlexIO outputs used for FLEXIO2 timers" + default 0x0000000000000000 + endmenu # iMX Peripheral Selection config IMX9_GPIO_IRQ diff --git a/arch/arm64/src/imx9/Make.defs b/arch/arm64/src/imx9/Make.defs index 15128654abaed..d7f26f8d91fbf 100644 --- a/arch/arm64/src/imx9/Make.defs +++ b/arch/arm64/src/imx9/Make.defs @@ -34,3 +34,7 @@ endif ifeq ($(CONFIG_IMX9_GPIO_IRQ),y) CHIP_CSRCS += imx9_gpioirq.c endif + +ifeq ($(CONFIG_IMX9_FLEXIO_PWM),y) + CHIP_CSRCS += imx9_flexio_pwm.c +endif diff --git a/arch/arm64/src/imx9/hardware/imx9_flexio.h b/arch/arm64/src/imx9/hardware/imx9_flexio.h new file mode 100644 index 0000000000000..2d1c9cabe5410 --- /dev/null +++ b/arch/arm64/src/imx9/hardware/imx9_flexio.h @@ -0,0 +1,823 @@ +/**************************************************************************** + * arch/arm64/src/imx9/hardware/imx9_flexio.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM64_SRC_IMX9_HARDWARE_IMX9_FLEXIO_H +#define __ARCH_ARM64_SRC_IMX9_HARDWARE_IMX9_FLEXIO_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "hardware/imx9_memorymap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define IMX9_FLEXIO_VERID_OFFSET 0x0000 /* Version ID Register, offset: 0x0 */ +#define IMX9_FLEXIO_PARAM_OFFSET 0x0004 /* Parameter Register, offset: 0x4 */ +#define IMX9_FLEXIO_CTRL_OFFSET 0x0008 /* FlexIO Control Register, offset: 0x8 */ +#define IMX9_FLEXIO_PIN_OFFSET 0x000c /* Pin State Register, offset: 0xC */ +#define IMX9_FLEXIO_SHIFTSTAT_OFFSET 0x0010 /* Shifter Status Register, offset: 0x10 */ +#define IMX9_FLEXIO_SHIFTERR_OFFSET 0x0014 /* Shifter Error Register, offset: 0x14 */ +#define IMX9_FLEXIO_TIMSTAT_OFFSET 0x0018 /* Timer Status Register, offset: 0x18 */ +#define IMX9_FLEXIO_SHIFTSIEN_OFFSET 0x0020 /* Shifter Status Interrupt Enable, offset: 0x20 */ +#define IMX9_FLEXIO_SHIFTEIEN_OFFSET 0x0024 /* Shifter Error Interrupt Enable, offset: 0x24 */ +#define IMX9_FLEXIO_TIMIEN_OFFSET 0x0028 /* Timer Interrupt Enable Register, offset: 0x28 */ +#define IMX9_FLEXIO_SHIFTSDEN_OFFSET 0x0030 /* Shifter Status DMA Enable, offset: 0x30 */ +#define IMX9_FLEXIO_SHIFTSTATE_OFFSET 0x0040 /* Shifter State Register, offset: 0x40 */ +#define IMX9_FLEXIO_TRGSTAT_OFFSET 0x0048 /* Trigger Status */ +#define IMX9_FLEXIO_TRIGIEN_OFFSET 0x004c /* External Trigger Interrupt Enable */ +#define IMX9_FLEXIO_PINSTAT_OFFSET 0x0050 /* Pin Status */ +#define IMX9_FLEXIO_PINIEN_OFFSET 0x0054 /* Pin Interrupt Enable */ +#define IMX9_FLEXIO_PINREN_OFFSET 0x0058 /* Pin Rising Edge Enable */ +#define IMX9_FLEXIO_PINFEN_OFFSET 0x005c /* Pin Falling Edge Enable */ +#define IMX9_FLEXIO_PINOUTD_OFFSET 0x0060 /* Pin Output Data */ +#define IMX9_FLEXIO_PINOUTE_OFFSET 0x0064 /* Pin Output Enable */ +#define IMX9_FLEXIO_PINOUTDIS_OFFSET 0x0068 /* Pin Output Disable */ +#define IMX9_FLEXIO_PINOUTCLR_OFFSET 0x006c /* Pin Output Clear */ +#define IMX9_FLEXIO_PINOUTSET_OFFSET 0x0070 /* Pin Output Set */ +#define IMX9_FLEXIO_PINOUTTOG_OFFSET 0x0074 /* Pin Output Toggle */ +#define IMX9_FLEXIO_SHIFTCTL0_OFFSET 0x0080 /* Shifter Control N Register, array offset: 0x80, array step: 0x4 */ +#define IMX9_FLEXIO_SHIFTCTL1_OFFSET 0x0084 +#define IMX9_FLEXIO_SHIFTCTL2_OFFSET 0x0088 +#define IMX9_FLEXIO_SHIFTCTL3_OFFSET 0x008c +#define IMX9_FLEXIO_SHIFTCTL4_OFFSET 0x0090 +#define IMX9_FLEXIO_SHIFTCTL5_OFFSET 0x0094 +#define IMX9_FLEXIO_SHIFTCTL6_OFFSET 0x0098 +#define IMX9_FLEXIO_SHIFTCTL7_OFFSET 0x009c +#define IMX9_FLEXIO_SHIFTCFG0_OFFSET 0x0100 /* Shifter Configuration N Register, array offset: 0x100, array step: 0x4 */ +#define IMX9_FLEXIO_SHIFTCFG1_OFFSET 0x0104 +#define IMX9_FLEXIO_SHIFTCFG2_OFFSET 0x0108 +#define IMX9_FLEXIO_SHIFTCFG3_OFFSET 0x010c +#define IMX9_FLEXIO_SHIFTCFG4_OFFSET 0x0110 +#define IMX9_FLEXIO_SHIFTCFG5_OFFSET 0x0114 +#define IMX9_FLEXIO_SHIFTCFG6_OFFSET 0x0118 +#define IMX9_FLEXIO_SHIFTCFG7_OFFSET 0x011c +#define IMX9_FLEXIO_SHIFTBUF0_OFFSET 0x0200 /* Shifter Buffer N Register, array offset: 0x200, array step: 0x4 */ +#define IMX9_FLEXIO_SHIFTBUF1_OFFSET 0x0204 +#define IMX9_FLEXIO_SHIFTBUF2_OFFSET 0x0208 +#define IMX9_FLEXIO_SHIFTBUF3_OFFSET 0x020c +#define IMX9_FLEXIO_SHIFTBUF4_OFFSET 0x0210 +#define IMX9_FLEXIO_SHIFTBUF5_OFFSET 0x0214 +#define IMX9_FLEXIO_SHIFTBUF6_OFFSET 0x0218 +#define IMX9_FLEXIO_SHIFTBUF7_OFFSET 0x021c +#define IMX9_FLEXIO_SHIFTBUFBIS0_OFFSET 0x0280 /* Shifter Buffer N Bit Swapped Register, array offset: 0x280, array step: 0x4 */ +#define IMX9_FLEXIO_SHIFTBUFBIS1_OFFSET 0x0284 +#define IMX9_FLEXIO_SHIFTBUFBIS2_OFFSET 0x0288 +#define IMX9_FLEXIO_SHIFTBUFBIS3_OFFSET 0x028c +#define IMX9_FLEXIO_SHIFTBUFBIS4_OFFSET 0x0290 +#define IMX9_FLEXIO_SHIFTBUFBIS5_OFFSET 0x0294 +#define IMX9_FLEXIO_SHIFTBUFBIS6_OFFSET 0x0298 +#define IMX9_FLEXIO_SHIFTBUFBIS7_OFFSET 0x029c +#define IMX9_FLEXIO_SHIFTBUFBYS0_OFFSET 0x0300 /* Shifter Buffer N Byte Swapped Register, array offset: 0x300, array step: 0x4 */ +#define IMX9_FLEXIO_SHIFTBUFBYS1_OFFSET 0x0304 +#define IMX9_FLEXIO_SHIFTBUFBYS2_OFFSET 0x0308 +#define IMX9_FLEXIO_SHIFTBUFBYS3_OFFSET 0x030c +#define IMX9_FLEXIO_SHIFTBUFBYS4_OFFSET 0x0310 +#define IMX9_FLEXIO_SHIFTBUFBYS5_OFFSET 0x0314 +#define IMX9_FLEXIO_SHIFTBUFBYS6_OFFSET 0x0318 +#define IMX9_FLEXIO_SHIFTBUFBYS7_OFFSET 0x031c +#define IMX9_FLEXIO_SHIFTBUFBBS0_OFFSET 0x0380 /* Shifter Buffer N Bit Byte Swapped Register, array offset: 0x380, array step: 0x4 */ +#define IMX9_FLEXIO_SHIFTBUFBBS1_OFFSET 0x0384 +#define IMX9_FLEXIO_SHIFTBUFBBS2_OFFSET 0x0388 +#define IMX9_FLEXIO_SHIFTBUFBBS3_OFFSET 0x038c +#define IMX9_FLEXIO_SHIFTBUFBBS4_OFFSET 0x0390 +#define IMX9_FLEXIO_SHIFTBUFBBS5_OFFSET 0x0394 +#define IMX9_FLEXIO_SHIFTBUFBBS6_OFFSET 0x0398 +#define IMX9_FLEXIO_SHIFTBUFBBS7_OFFSET 0x039c +#define IMX9_FLEXIO_TIMCTL0_OFFSET 0x0400 /* Timer Control N Register, array offset: 0x400, array step: 0x4 */ +#define IMX9_FLEXIO_TIMCTL1_OFFSET 0x0404 +#define IMX9_FLEXIO_TIMCTL2_OFFSET 0x0408 +#define IMX9_FLEXIO_TIMCTL3_OFFSET 0x040c +#define IMX9_FLEXIO_TIMCTL4_OFFSET 0x0410 +#define IMX9_FLEXIO_TIMCTL5_OFFSET 0x0414 +#define IMX9_FLEXIO_TIMCTL6_OFFSET 0x0418 +#define IMX9_FLEXIO_TIMCTL7_OFFSET 0x041c +#define IMX9_FLEXIO_TIMCTL_OFFSET(x) (IMX9_FLEXIO_TIMCTL0_OFFSET + (x) * 4) +#define IMX9_FLEXIO_TIMCFG0_OFFSET 0x0480 /* Timer Configuration N Register, array offset: 0x480, array step: 0x4 */ +#define IMX9_FLEXIO_TIMCFG1_OFFSET 0x0484 +#define IMX9_FLEXIO_TIMCFG2_OFFSET 0x0488 +#define IMX9_FLEXIO_TIMCFG3_OFFSET 0x048c +#define IMX9_FLEXIO_TIMCFG4_OFFSET 0x0490 +#define IMX9_FLEXIO_TIMCFG5_OFFSET 0x0494 +#define IMX9_FLEXIO_TIMCFG6_OFFSET 0x0498 +#define IMX9_FLEXIO_TIMCFG7_OFFSET 0x049c +#define IMX9_FLEXIO_TIMCFG_OFFSET(x) (IMX9_FLEXIO_TIMCFG0_OFFSET + (x) * 4) +#define IMX9_FLEXIO_TIMCMP0_OFFSET 0x0500 /* Timer Compare N Register, array offset: 0x500, array step: 0x4 */ +#define IMX9_FLEXIO_TIMCMP1_OFFSET 0x0504 +#define IMX9_FLEXIO_TIMCMP2_OFFSET 0x0508 +#define IMX9_FLEXIO_TIMCMP3_OFFSET 0x050c +#define IMX9_FLEXIO_TIMCMP4_OFFSET 0x0510 +#define IMX9_FLEXIO_TIMCMP5_OFFSET 0x0514 +#define IMX9_FLEXIO_TIMCMP6_OFFSET 0x0518 +#define IMX9_FLEXIO_TIMCMP7_OFFSET 0x051c +#define IMX9_FLEXIO_TIMCMP_OFFSET(x) (IMX9_FLEXIO_TIMCMP0_OFFSET + (x) * 4) +#define IMX9_FLEXIO_SHIFTBUFNBS0_OFFSET 0x0680 /* Shifter Buffer N Nibble Byte Swapped Register, array offset: 0x680, array step: 0x4 */ +#define IMX9_FLEXIO_SHIFTBUFNBS1_OFFSET 0x0684 +#define IMX9_FLEXIO_SHIFTBUFNBS2_OFFSET 0x0688 +#define IMX9_FLEXIO_SHIFTBUFNBS3_OFFSET 0x068c +#define IMX9_FLEXIO_SHIFTBUFNBS4_OFFSET 0x0690 +#define IMX9_FLEXIO_SHIFTBUFNBS5_OFFSET 0x0694 +#define IMX9_FLEXIO_SHIFTBUFNBS6_OFFSET 0x0698 +#define IMX9_FLEXIO_SHIFTBUFNBS7_OFFSET 0x069c +#define IMX9_FLEXIO_SHIFTBUFHWS0_OFFSET 0x0700 /* Shifter Buffer N Half Word Swapped Register, array offset: 0x700, array step: 0x4 */ +#define IMX9_FLEXIO_SHIFTBUFHWS1_OFFSET 0x0704 +#define IMX9_FLEXIO_SHIFTBUFHWS2_OFFSET 0x0708 +#define IMX9_FLEXIO_SHIFTBUFHWS3_OFFSET 0x070c +#define IMX9_FLEXIO_SHIFTBUFHWS4_OFFSET 0x0710 +#define IMX9_FLEXIO_SHIFTBUFHWS5_OFFSET 0x0714 +#define IMX9_FLEXIO_SHIFTBUFHWS6_OFFSET 0x0718 +#define IMX9_FLEXIO_SHIFTBUFHWS7_OFFSET 0x071c +#define IMX9_FLEXIO_SHIFTBUFNIS0_OFFSET 0x0780 /* Shifter Buffer N Nibble Swapped Register, array offset: 0x780, array step: 0x4 */ +#define IMX9_FLEXIO_SHIFTBUFNIS1_OFFSET 0x0784 +#define IMX9_FLEXIO_SHIFTBUFNIS2_OFFSET 0x0788 +#define IMX9_FLEXIO_SHIFTBUFNIS3_OFFSET 0x078c +#define IMX9_FLEXIO_SHIFTBUFNIS4_OFFSET 0x0790 +#define IMX9_FLEXIO_SHIFTBUFNIS5_OFFSET 0x0794 +#define IMX9_FLEXIO_SHIFTBUFNIS6_OFFSET 0x0798 +#define IMX9_FLEXIO_SHIFTBUFNIS7_OFFSET 0x079c +#define IMX9_FLEXIO_SHIFTBUFOES0_OFFSET 0x0800 /* Shifter Buffer N Odd Even Swapped, array offset: 0x800, array step: 0x4 */ +#define IMX9_FLEXIO_SHIFTBUFOES1_OFFSET 0x0804 +#define IMX9_FLEXIO_SHIFTBUFOES2_OFFSET 0x0808 +#define IMX9_FLEXIO_SHIFTBUFOES3_OFFSET 0x080c +#define IMX9_FLEXIO_SHIFTBUFOES4_OFFSET 0x0810 +#define IMX9_FLEXIO_SHIFTBUFOES5_OFFSET 0x0814 +#define IMX9_FLEXIO_SHIFTBUFOES6_OFFSET 0x0818 +#define IMX9_FLEXIO_SHIFTBUFOES7_OFFSET 0x081c +#define IMX9_FLEXIO_SHIFTBUFEOS0_OFFSET 0x0880 /* Shifter Buffer N Even Odd Swapped, array offset: 0x880, array step: 0x4 */ +#define IMX9_FLEXIO_SHIFTBUFEOS1_OFFSET 0x0884 +#define IMX9_FLEXIO_SHIFTBUFEOS2_OFFSET 0x0888 +#define IMX9_FLEXIO_SHIFTBUFEOS3_OFFSET 0x088c +#define IMX9_FLEXIO_SHIFTBUFEOS4_OFFSET 0x0890 +#define IMX9_FLEXIO_SHIFTBUFEOS5_OFFSET 0x0894 +#define IMX9_FLEXIO_SHIFTBUFEOS6_OFFSET 0x0898 +#define IMX9_FLEXIO_SHIFTBUFEOS7_OFFSET 0x089c +#define IMX9_FLEXIO_SHIFTBUFHBS0_OFFSET 0x0900 /* Shifter Buffer N Halfword Byte Swapped, array offset: 0x900, array step: 0x4 */ +#define IMX9_FLEXIO_SHIFTBUFHBS1_OFFSET 0x0904 +#define IMX9_FLEXIO_SHIFTBUFHBS2_OFFSET 0x0908 +#define IMX9_FLEXIO_SHIFTBUFHBS3_OFFSET 0x090c +#define IMX9_FLEXIO_SHIFTBUFHBS4_OFFSET 0x0910 +#define IMX9_FLEXIO_SHIFTBUFHBS5_OFFSET 0x0914 +#define IMX9_FLEXIO_SHIFTBUFHBS6_OFFSET 0x0918 +#define IMX9_FLEXIO_SHIFTBUFHBS7_OFFSET 0x091c + +/* VERID - Version ID Register */ + +#define FLEXIO_VERID_FEATURE_MASK (0xffffu) +#define FLEXIO_VERID_FEATURE_SHIFT (0u) + +/* FEATURE - Feature Specification Number + * 0b0000000000000000..Standard features implemented. + * 0b0000000000000001..Supports state, logic and parallel modes. + */ + +#define FLEXIO_VERID_FEATURE(x) ((((uint32_t)(x)) << FLEXIO_VERID_FEATURE_SHIFT) & FLEXIO_VERID_FEATURE_MASK) + +#define FLEXIO_VERID_MINOR_MASK (0xff0000u) +#define FLEXIO_VERID_MINOR_SHIFT (16u) + +/* MINOR - Minor Version Number */ + +#define FLEXIO_VERID_MINOR(x) ((((uint32_t)(x)) << FLEXIO_VERID_MINOR_SHIFT) & FLEXIO_VERID_MINOR_MASK) + +#define FLEXIO_VERID_MAJOR_MASK (0xff000000u) +#define FLEXIO_VERID_MAJOR_SHIFT (24u) + +/* MAJOR - Major Version Number */ +#define FLEXIO_VERID_MAJOR(x) ((((uint32_t)(x)) << FLEXIO_VERID_MAJOR_SHIFT) & FLEXIO_VERID_MAJOR_MASK) + +/* PARAM - Parameter Register */ + +#define FLEXIO_PARAM_SHIFTER_MASK (0xffu) +#define FLEXIO_PARAM_SHIFTER_SHIFT (0u) + +/* SHIFTER - Shifter Number */ +#define FLEXIO_PARAM_SHIFTER(x) ((((uint32_t)(x)) << FLEXIO_PARAM_SHIFTER_SHIFT) & FLEXIO_PARAM_SHIFTER_MASK) + +#define FLEXIO_PARAM_TIMER_MASK (0xff00u) +#define FLEXIO_PARAM_TIMER_SHIFT (8u) + +/* TIMER - Timer Number */ + +#define FLEXIO_PARAM_TIMER(x) ((((uint32_t)(x)) << FLEXIO_PARAM_TIMER_SHIFT) & FLEXIO_PARAM_TIMER_MASK) + +#define FLEXIO_PARAM_PIN_MASK (0xff0000u) +#define FLEXIO_PARAM_PIN_SHIFT (16u) + +/* PIN - Pin Number */ +#define FLEXIO_PARAM_PIN(x) ((((uint32_t)(x)) << FLEXIO_PARAM_PIN_SHIFT) & FLEXIO_PARAM_PIN_MASK) + +#define FLEXIO_PARAM_TRIGGER_MASK (0xff000000u) +#define FLEXIO_PARAM_TRIGGER_SHIFT (24u) + +/* TRIGGER - Trigger Number */ + +#define FLEXIO_PARAM_TRIGGER(x) ((((uint32_t)(x)) << FLEXIO_PARAM_TRIGGER_SHIFT) & FLEXIO_PARAM_TRIGGER_MASK) + +/* CTRL - FlexIO Control Register */ + +#define FLEXIO_CTRL_FLEXEN_MASK (0x1u) +#define FLEXIO_CTRL_FLEXEN_SHIFT (0u) + +/* FLEXEN - FlexIO Enable + * 0b0..FlexIO module is disabled. + * 0b1..FlexIO module is enabled. + */ + +#define FLEXIO_CTRL_FLEXEN(x) ((((uint32_t)(x)) << FLEXIO_CTRL_FLEXEN_SHIFT) & FLEXIO_CTRL_FLEXEN_MASK) + +#define FLEXIO_CTRL_SWRST_MASK (0x2u) +#define FLEXIO_CTRL_SWRST_SHIFT (1u) + +/* SWRST - Software Reset + * 0b0..Software reset is disabled + * 0b1..Software reset is enabled, all FlexIO registers except the Control + * Register are reset. + */ + +#define FLEXIO_CTRL_SWRST(x) ((((uint32_t)(x)) << FLEXIO_CTRL_SWRST_SHIFT) & FLEXIO_CTRL_SWRST_MASK) + +#define FLEXIO_CTRL_FASTACC_MASK (0x4u) +#define FLEXIO_CTRL_FASTACC_SHIFT (2u) + +/* FASTACC - Fast Access + * 0b0..Configures for normal register accesses to FlexIO + * 0b1..Configures for fast register accesses to FlexIO + */ + +#define FLEXIO_CTRL_FASTACC(x) ((((uint32_t)(x)) << FLEXIO_CTRL_FASTACC_SHIFT) & FLEXIO_CTRL_FASTACC_MASK) + +#define FLEXIO_CTRL_DBGE_MASK (0x40000000u) +#define FLEXIO_CTRL_DBGE_SHIFT (30u) + +/* DBGE - Debug Enable + * 0b0..FlexIO is disabled in debug modes. + * 0b1..FlexIO is enabled in debug modes + */ + +#define FLEXIO_CTRL_DBGE(x) ((((uint32_t)(x)) << FLEXIO_CTRL_DBGE_SHIFT) & FLEXIO_CTRL_DBGE_MASK) + +#define FLEXIO_CTRL_DOZEN_MASK (0x80000000u) +#define FLEXIO_CTRL_DOZEN_SHIFT (31u) + +/* DOZEN - Doze Enable + * 0b0..FlexIO enabled in Doze modes. + * 0b1..FlexIO disabled in Doze modes. + */ + +#define FLEXIO_CTRL_DOZEN(x) ((((uint32_t)(x)) << FLEXIO_CTRL_DOZEN_SHIFT) & FLEXIO_CTRL_DOZEN_MASK) + +/* PIN - Pin State Register */ + +#define FLEXIO_PIN_PDI_MASK (0xffffffffu) /* Merged from fields with different position or width, of widths (16, 32), largest definition used */ +#define FLEXIO_PIN_PDI_SHIFT (0u) + +/* PDI - Pin Data Input */ + +#define FLEXIO_PIN_PDI(x) ((((uint32_t)(x)) << FLEXIO_PIN_PDI_SHIFT) & FLEXIO_PIN_PDI_MASK) /* Merged from fields with different position or width, of widths (16, 32), largest definition used */ + +/* SHIFTSTAT - Shifter Status Register */ + +#define FLEXIO_SHIFTSTAT_SSF_MASK (0xffu) +#define FLEXIO_SHIFTSTAT_SSF_SHIFT (0u) + +/* SSF - Shifter Status Flag */ + +#define FLEXIO_SHIFTSTAT_SSF(x) ((((uint32_t)(x)) << FLEXIO_SHIFTSTAT_SSF_SHIFT) & FLEXIO_SHIFTSTAT_SSF_MASK) + +/* SHIFTERR - Shifter Error Register */ + +#define FLEXIO_SHIFTERR_SEF_MASK (0xffu) +#define FLEXIO_SHIFTERR_SEF_SHIFT (0u) + +/* SEF - Shifter Error Flags */ + +#define FLEXIO_SHIFTERR_SEF(x) ((((uint32_t)(x)) << FLEXIO_SHIFTERR_SEF_SHIFT) & FLEXIO_SHIFTERR_SEF_MASK) + +/* TIMSTAT - Timer Status Register */ + +#define FLEXIO_TIMSTAT_TSF_MASK (0xffu) +#define FLEXIO_TIMSTAT_TSF_SHIFT (0u) + +/* TSF - Timer Status Flags */ + +#define FLEXIO_TIMSTAT_TSF(x) ((((uint32_t)(x)) << FLEXIO_TIMSTAT_TSF_SHIFT) & FLEXIO_TIMSTAT_TSF_MASK) + +/* SHIFTSIEN - Shifter Status Interrupt Enable */ + +#define FLEXIO_SHIFTSIEN_SSIE_MASK (0xffu) +#define FLEXIO_SHIFTSIEN_SSIE_SHIFT (0u) + +/* SSIE - Shifter Status Interrupt Enable */ + +#define FLEXIO_SHIFTSIEN_SSIE(x) ((((uint32_t)(x)) << FLEXIO_SHIFTSIEN_SSIE_SHIFT) & FLEXIO_SHIFTSIEN_SSIE_MASK) + +/* SHIFTEIEN - Shifter Error Interrupt Enable */ + +#define FLEXIO_SHIFTEIEN_SEIE_MASK (0xffu) +#define FLEXIO_SHIFTEIEN_SEIE_SHIFT (0u) + +/* SEIE - Shifter Error Interrupt Enable */ + +#define FLEXIO_SHIFTEIEN_SEIE(x) ((((uint32_t)(x)) << FLEXIO_SHIFTEIEN_SEIE_SHIFT) & FLEXIO_SHIFTEIEN_SEIE_MASK) + +/* TIMIEN - Timer Interrupt Enable Register */ + +#define FLEXIO_TIMIEN_TEIE_MASK (0xffu) +#define FLEXIO_TIMIEN_TEIE_SHIFT (0u) + +/* TEIE - Timer Status Interrupt Enable */ + +#define FLEXIO_TIMIEN_TEIE(x) ((((uint32_t)(x)) << FLEXIO_TIMIEN_TEIE_SHIFT) & FLEXIO_TIMIEN_TEIE_MASK) + +/* SHIFTSDEN - Shifter Status DMA Enable */ + +#define FLEXIO_SHIFTSDEN_SSDE_MASK (0xffu) +#define FLEXIO_SHIFTSDEN_SSDE_SHIFT (0u) + +/* SSDE - Shifter Status DMA Enable */ + +#define FLEXIO_SHIFTSDEN_SSDE(x) ((((uint32_t)(x)) << FLEXIO_SHIFTSDEN_SSDE_SHIFT) & FLEXIO_SHIFTSDEN_SSDE_MASK) + +/* TIMERSDEN - Timer Status DMA Enable */ + +#define FLEXIO_TIMERSDEN_TSDE_MASK (0xffu) +#define FLEXIO_TIMERSDEN_TSDE_SHIFT (0u) + +/* TSDE - Timer Status DMA Enable */ + +#define FLEXIO_TIMERSDEN_TSDE(x) ((((uint32_t)(x)) << FLEXIO_TIMERSDEN_TSDE_SHIFT) & FLEXIO_TIMERSDEN_TSDE_MASK) + +/* SHIFTSTATE - Shifter State Register */ + +#define FLEXIO_SHIFTSTATE_STATE_MASK (0x7u) +#define FLEXIO_SHIFTSTATE_STATE_SHIFT (0u) + +/* STATE - Current State Pointer */ + +#define FLEXIO_SHIFTSTATE_STATE(x) ((((uint32_t)(x)) << FLEXIO_SHIFTSTATE_STATE_SHIFT) & FLEXIO_SHIFTSTATE_STATE_MASK) + +/* TRGSTAT - Trigger Status */ + +#define FLEXIO_TRGSTAT_ETSF_MASK (0xfu) +#define FLEXIO_TRGSTAT_ETSF_SHIFT (0u) + +#define FLEXIO_TRGSTAT_ETSF(x) ((((uint32_t)(x)) << FLEXIO_TRGSTAT_ETSF_SHIFT) & FLEXIO_TRGSTAT_ETSF_MASK) + +/* TRIGIEN - External Trigger Interrupt Enable */ + +#define FLEXIO_TRIGIEN_TRIE_MASK (0xfu) +#define FLEXIO_TRIGIEN_TRIE_SHIFT (0u) + +#define FLEXIO_TRIGIEN_TRIE(x) ((((uint32_t)(x)) << FLEXIO_TRIGIEN_TRIE_SHIFT) & FLEXIO_TRIGIEN_TRIE_MASK) + +/* SHIFTCTL - Shifter Control N Register */ + +#define FLEXIO_SHIFTCTL_SMOD_MASK (0x7u) +#define FLEXIO_SHIFTCTL_SMOD_SHIFT (0u) + +/* SMOD - Shifter Mode + * 0b000..Disabled. + * 0b001..Receive mode. Captures the current Shifter content into the + * SHIFTBUF on expiration of the Timer. + * 0b010..Transmit mode. Load SHIFTBUF contents into the Shifter on + * expiration of the Timer. + * 0b011..Reserved. + * 0b100..Match Store mode. Shifter data is compared to SHIFTBUF content on + * expiration of the Timer. + * 0b101..Match Continuous mode. Shifter data is continuously compared to + * SHIFTBUF contents. + * 0b110..State mode. SHIFTBUF contents are used for storing programmable + * state attributes. + * 0b111..Logic mode. SHIFTBUF contents are used for implementing + * programmable logic look up table. + */ + +#define FLEXIO_SHIFTCTL_SMOD(x) ((((uint32_t)(x)) << FLEXIO_SHIFTCTL_SMOD_SHIFT) & FLEXIO_SHIFTCTL_SMOD_MASK) + +#define FLEXIO_SHIFTCTL_PINPOL_MASK (0x80u) +#define FLEXIO_SHIFTCTL_PINPOL_SHIFT (7u) + +/* PINPOL - Shifter Pin Polarity + * 0b0..Pin is active high + * 0b1..Pin is active low + */ + +#define FLEXIO_SHIFTCTL_PINPOL(x) ((((uint32_t)(x)) << FLEXIO_SHIFTCTL_PINPOL_SHIFT) & FLEXIO_SHIFTCTL_PINPOL_MASK) + +#define FLEXIO_SHIFTCTL_PINSEL_MASK (0x1f00u) /* Merged from fields with different position or width, of widths (4, 5), largest definition used */ +#define FLEXIO_SHIFTCTL_PINSEL_SHIFT (8u) + +/* PINSEL - Shifter Pin Select */ + +#define FLEXIO_SHIFTCTL_PINSEL(x) ((((uint32_t)(x)) << FLEXIO_SHIFTCTL_PINSEL_SHIFT) & FLEXIO_SHIFTCTL_PINSEL_MASK) /* Merged from fields with different position or width, of widths (4, 5), largest definition used */ + +#define FLEXIO_SHIFTCTL_PINCFG_MASK (0x30000u) +#define FLEXIO_SHIFTCTL_PINCFG_SHIFT (16u) + +/* PINCFG - Shifter Pin Configuration + * 0b00..Shifter pin output disabled + * 0b01..Shifter pin open drain or bidirectional output enable + * 0b10..Shifter pin bidirectional output data + * 0b11..Shifter pin output + */ + +#define FLEXIO_SHIFTCTL_PINCFG(x) ((((uint32_t)(x)) << FLEXIO_SHIFTCTL_PINCFG_SHIFT) & FLEXIO_SHIFTCTL_PINCFG_MASK) + +#define FLEXIO_SHIFTCTL_TIMPOL_MASK (0x800000u) +#define FLEXIO_SHIFTCTL_TIMPOL_SHIFT (23u) + +/* TIMPOL - Timer Polarity + * 0b0..Shift on posedge of Shift clock + * 0b1..Shift on negedge of Shift clock + */ + +#define FLEXIO_SHIFTCTL_TIMPOL(x) ((((uint32_t)(x)) << FLEXIO_SHIFTCTL_TIMPOL_SHIFT) & FLEXIO_SHIFTCTL_TIMPOL_MASK) + +#define FLEXIO_SHIFTCTL_TIMSEL_MASK (0x7000000u) +#define FLEXIO_SHIFTCTL_TIMSEL_SHIFT (24u) + +/* TIMSEL - Timer Select */ + +#define FLEXIO_SHIFTCTL_TIMSEL(x) ((((uint32_t)(x)) << FLEXIO_SHIFTCTL_TIMSEL_SHIFT) & FLEXIO_SHIFTCTL_TIMSEL_MASK) + +/* The count of FLEXIO_SHIFTCTL */ + +#define FLEXIO_SHIFTCTL_COUNT (8u) + +/* SHIFTCFG - Shifter Configuration N Register */ + +#define FLEXIO_SHIFTCFG_SSTART_MASK (0x3u) +#define FLEXIO_SHIFTCFG_SSTART_SHIFT (0u) + +/* SSTART - Shifter Start bit + * 0b00..Start bit disabled for transmitter/receiver/match store, + * transmitter loads data on enable + * 0b01..Start bit disabled for transmitter/receiver/match store, + * transmitter loads data on first shift + * 0b10..Transmitter outputs start bit value 0 before loading data on first + * shift, receiver/match store sets error flag if start bit is not 0 + * 0b11..Transmitter outputs start bit value 1 before loading data on first + * shift, receiver/match store sets error flag if start bit is not 1 + */ + +#define FLEXIO_SHIFTCFG_SSTART(x) ((((uint32_t)(x)) << FLEXIO_SHIFTCFG_SSTART_SHIFT) & FLEXIO_SHIFTCFG_SSTART_MASK) + +#define FLEXIO_SHIFTCFG_SSTOP_MASK (0x30u) +#define FLEXIO_SHIFTCFG_SSTOP_SHIFT (4u) + +/* SSTOP - Shifter Stop bit + * 0b00..Stop bit disabled for transmitter/receiver/match store + * 0b01..Reserved for transmitter/receiver/match store + * 0b10..Transmitter outputs stop bit value 0 on store, receiver/match store + * sets error flag if stop bit is not 0 + * 0b11..Transmitter outputs stop bit value 1 on store, receiver/match store + * sets error flag if stop bit is not 1 + */ + +#define FLEXIO_SHIFTCFG_SSTOP(x) ((((uint32_t)(x)) << FLEXIO_SHIFTCFG_SSTOP_SHIFT) & FLEXIO_SHIFTCFG_SSTOP_MASK) + +#define FLEXIO_SHIFTCFG_INSRC_MASK (0x100u) +#define FLEXIO_SHIFTCFG_INSRC_SHIFT (8u) + +/* INSRC - Input Source + * 0b0..Pin + * 0b1..Shifter N+1 Output + */ + +#define FLEXIO_SHIFTCFG_INSRC(x) ((((uint32_t)(x)) << FLEXIO_SHIFTCFG_INSRC_SHIFT) & FLEXIO_SHIFTCFG_INSRC_MASK) + +/* LATST - Late Store */ + +#define FLEXIO_SHIFTCFG_LATST_MASK (0x200u) +#define FLEXIO_SHIFTCFG_LATST_SHIFT (9u) + +#define FLEXIO_SHIFTCFG_LATST(x) ((((uint32_t)(x)) << FLEXIO_SHIFTCFG_LATST_SHIFT) & FLEXIO_SHIFTCFG_LATST_MASK) + +/* SSIZE - Shifter Size */ + +#define FLEXIO_SHIFTCFG_SSIZE_MASK (0x1000u) +#define FLEXIO_SHIFTCFG_SSIZE_SHIFT (12u) + +#define FLEXIO_SHIFTCFG_SSIZE(x) ((((uint32_t)(x)) << FLEXIO_SHIFTCFG_SSIZE_SHIFT) & FLEXIO_SHIFTCFG_SSIZE_MASK) + +#define FLEXIO_SHIFTCFG_PWIDTH_MASK (0x1f0000u) /* Merged from fields with different position or width, of widths (4, 5), largest definition used */ +#define FLEXIO_SHIFTCFG_PWIDTH_SHIFT (16u) + +/* PWIDTH - Parallel Width */ + +#define FLEXIO_SHIFTCFG_PWIDTH(x) ((((uint32_t)(x)) << FLEXIO_SHIFTCFG_PWIDTH_SHIFT) & FLEXIO_SHIFTCFG_PWIDTH_MASK) /* Merged from fields with different position or width, of widths (4, 5), largest definition used */ + +/* The count of FLEXIO_SHIFTCFG */ + +#define FLEXIO_SHIFTCFG_COUNT (8u) + +/* SHIFTBUF - Shifter Buffer N Register */ + +#define FLEXIO_SHIFTBUF_SHIFTBUF_MASK (0xffffffffu) +#define FLEXIO_SHIFTBUF_SHIFTBUF_SHIFT (0u) + +/* SHIFTBUF - Shift Buffer */ + +#define FLEXIO_SHIFTBUF_SHIFTBUF(x) ((((uint32_t)(x)) << FLEXIO_SHIFTBUF_SHIFTBUF_SHIFT) & FLEXIO_SHIFTBUF_SHIFTBUF_MASK) + +/* The count of FLEXIO_SHIFTBUF */ + +#define FLEXIO_SHIFTBUF_COUNT (8u) + +/* SHIFTBUFBIS - Shifter Buffer N Bit Swapped Register */ + +#define FLEXIO_SHIFTBUFBIS_SHIFTBUFBIS_MASK (0xffffffffu) +#define FLEXIO_SHIFTBUFBIS_SHIFTBUFBIS_SHIFT (0u) + +/* SHIFTBUFBIS - Shift Buffer */ + +#define FLEXIO_SHIFTBUFBIS_SHIFTBUFBIS(x) ((((uint32_t)(x)) << FLEXIO_SHIFTBUFBIS_SHIFTBUFBIS_SHIFT) & FLEXIO_SHIFTBUFBIS_SHIFTBUFBIS_MASK) + +/* The count of FLEXIO_SHIFTBUFBIS */ + +#define FLEXIO_SHIFTBUFBIS_COUNT (8u) + +/* SHIFTBUFBYS - Shifter Buffer N Byte Swapped Register */ + +#define FLEXIO_SHIFTBUFBYS_SHIFTBUFBYS_MASK (0xffffffffu) +#define FLEXIO_SHIFTBUFBYS_SHIFTBUFBYS_SHIFT (0u) + +/* SHIFTBUFBYS - Shift Buffer */ + +#define FLEXIO_SHIFTBUFBYS_SHIFTBUFBYS(x) ((((uint32_t)(x)) << FLEXIO_SHIFTBUFBYS_SHIFTBUFBYS_SHIFT) & FLEXIO_SHIFTBUFBYS_SHIFTBUFBYS_MASK) + +/* The count of FLEXIO_SHIFTBUFBYS */ + +#define FLEXIO_SHIFTBUFBYS_COUNT (8u) + +/* SHIFTBUFBBS - Shifter Buffer N Bit Byte Swapped Register */ + +#define FLEXIO_SHIFTBUFBBS_SHIFTBUFBBS_MASK (0xffffffffu) +#define FLEXIO_SHIFTBUFBBS_SHIFTBUFBBS_SHIFT (0u) + +/* SHIFTBUFBBS - Shift Buffer */ + +#define FLEXIO_SHIFTBUFBBS_SHIFTBUFBBS(x) ((((uint32_t)(x)) << FLEXIO_SHIFTBUFBBS_SHIFTBUFBBS_SHIFT) & FLEXIO_SHIFTBUFBBS_SHIFTBUFBBS_MASK) + +/* The count of FLEXIO_SHIFTBUFBBS */ + +#define FLEXIO_SHIFTBUFBBS_COUNT (8u) + +/* TIMCTL - Timer Control N Register */ + +#define FLEXIO_TIMCTL_TIMOD_MASK (0x3u) +#define FLEXIO_TIMCTL_TIMOD_SHIFT (0u) + +/* TIMOD - Timer Mode + * 0b000..Timer Disabled. + * 0b001..Dual 8-bit counters baud mode. + * 0b010..Dual 8-bit counters PWM high mode. + * 0b011..Single 16-bit counter mode. + * 0b100..Single 16-bit counter disable mode. + * 0b101..Dual 8-bit counters word mode. + * 0b110..Dual 8-bit counters PWM low mode. + * 0b111..Single 16-bit input capture mode. + */ + +#define FLEXIO_TIMCTL_TIMOD(x) ((((uint32_t)(x)) << FLEXIO_TIMCTL_TIMOD_SHIFT) & FLEXIO_TIMCTL_TIMOD_MASK) + +#define FLEXIO_TIMCTL_PINPOL_MASK (0x80u) +#define FLEXIO_TIMCTL_PINPOL_SHIFT (7u) + +/* PINPOL - Timer Pin Polarity + * 0b0..Pin is active high + * 0b1..Pin is active low + */ + +#define FLEXIO_TIMCTL_PINPOL(x) ((((uint32_t)(x)) << FLEXIO_TIMCTL_PINPOL_SHIFT) & FLEXIO_TIMCTL_PINPOL_MASK) + +#define FLEXIO_TIMCTL_PINSEL_MASK (0x1f00u) /* Merged from fields with different position or width, of widths (4, 5), largest definition used */ +#define FLEXIO_TIMCTL_PINSEL_SHIFT (8u) + +/* PINSEL - Timer Pin Select */ + +#define FLEXIO_TIMCTL_PINSEL(x) ((((uint32_t)(x)) << FLEXIO_TIMCTL_PINSEL_SHIFT) & FLEXIO_TIMCTL_PINSEL_MASK) /* Merged from fields with different position or width, of widths (4, 5), largest definition used */ + +#define FLEXIO_TIMCTL_PINCFG_MASK (0x30000u) +#define FLEXIO_TIMCTL_PINCFG_SHIFT (16u) + +/* PINCFG - Timer Pin Configuration + * 0b00..Timer pin output disabled + * 0b01..Timer pin open drain or bidirectional output enable + * 0b10..Timer pin bidirectional output data + * 0b11..Timer pin output + */ + +#define FLEXIO_TIMCTL_PINCFG(x) ((((uint32_t)(x)) << FLEXIO_TIMCTL_PINCFG_SHIFT) & FLEXIO_TIMCTL_PINCFG_MASK) + +#define FLEXIO_TIMCTL_TRGSRC_MASK (0x400000u) +#define FLEXIO_TIMCTL_TRGSRC_SHIFT (22u) + +/* TRGSRC - Trigger Source + * 0b0..External trigger selected + * 0b1..Internal trigger selected + */ + +#define FLEXIO_TIMCTL_TRGSRC(x) ((((uint32_t)(x)) << FLEXIO_TIMCTL_TRGSRC_SHIFT) & FLEXIO_TIMCTL_TRGSRC_MASK) + +#define FLEXIO_TIMCTL_TRGPOL_MASK (0x800000u) +#define FLEXIO_TIMCTL_TRGPOL_SHIFT (23u) + +/* TRGPOL - Trigger Polarity + * 0b0..Trigger active high + * 0b1..Trigger active low + */ + +#define FLEXIO_TIMCTL_TRGPOL(x) ((((uint32_t)(x)) << FLEXIO_TIMCTL_TRGPOL_SHIFT) & FLEXIO_TIMCTL_TRGPOL_MASK) + +#define FLEXIO_TIMCTL_TRGSEL_MASK (0x3f000000u) /* Merged from fields with different position or width, of widths (5, 6), largest definition used */ +#define FLEXIO_TIMCTL_TRGSEL_SHIFT (24u) + +/* TRGSEL - Trigger Select */ + +#define FLEXIO_TIMCTL_TRGSEL(x) ((((uint32_t)(x)) << FLEXIO_TIMCTL_TRGSEL_SHIFT) & FLEXIO_TIMCTL_TRGSEL_MASK) /* Merged from fields with different position or width, of widths (5, 6), largest definition used */ + +/* The count of FLEXIO_TIMCTL */ + +#define FLEXIO_TIMCTL_COUNT (8u) + +/* TIMCFG - Timer Configuration N Register */ + +#define FLEXIO_TIMCFG_TSTART_MASK (0x2u) +#define FLEXIO_TIMCFG_TSTART_SHIFT (1u) + +/* TSTART - Timer Start Bit + * 0b0..Start bit disabled + * 0b1..Start bit enabled + */ + +#define FLEXIO_TIMCFG_TSTART(x) ((((uint32_t)(x)) << FLEXIO_TIMCFG_TSTART_SHIFT) & FLEXIO_TIMCFG_TSTART_MASK) + +#define FLEXIO_TIMCFG_TSTOP_MASK (0x30u) +#define FLEXIO_TIMCFG_TSTOP_SHIFT (4u) + +/* TSTOP - Timer Stop Bit + * 0b00..Stop bit disabled + * 0b01..Stop bit is enabled on timer compare + * 0b10..Stop bit is enabled on timer disable + * 0b11..Stop bit is enabled on timer compare and timer disable + */ + +#define FLEXIO_TIMCFG_TSTOP(x) ((((uint32_t)(x)) << FLEXIO_TIMCFG_TSTOP_SHIFT) & FLEXIO_TIMCFG_TSTOP_MASK) + +#define FLEXIO_TIMCFG_TIMENA_MASK (0x700u) +#define FLEXIO_TIMCFG_TIMENA_SHIFT (8u) + +/* TIMENA - Timer Enable + * 0b000..Timer always enabled + * 0b001..Timer enabled on Timer N-1 enable + * 0b010..Timer enabled on Trigger high + * 0b011..Timer enabled on Trigger high and Pin high + * 0b100..Timer enabled on Pin rising edge + * 0b101..Timer enabled on Pin rising edge and Trigger high + * 0b110..Timer enabled on Trigger rising edge + * 0b111..Timer enabled on Trigger rising or falling edge + */ + +#define FLEXIO_TIMCFG_TIMENA(x) ((((uint32_t)(x)) << FLEXIO_TIMCFG_TIMENA_SHIFT) & FLEXIO_TIMCFG_TIMENA_MASK) + +#define FLEXIO_TIMCFG_TIMDIS_MASK (0x7000u) +#define FLEXIO_TIMCFG_TIMDIS_SHIFT (12u) + +/* TIMDIS - Timer Disable + * 0b000..Timer never disabled + * 0b001..Timer disabled on Timer N-1 disable + * 0b010..Timer disabled on Timer compare (upper 8-bits match and decrement) + * 0b011..Timer disabled on Timer compare (upper 8-bits match and decrement) + * and Trigger Low + * 0b100..Timer disabled on Pin rising or falling edge + * 0b101..Timer disabled on Pin rising or falling edge provided Trigger is + * high + * 0b110..Timer disabled on Trigger falling edge + * 0b111..Reserved + */ + +#define FLEXIO_TIMCFG_TIMDIS(x) ((((uint32_t)(x)) << FLEXIO_TIMCFG_TIMDIS_SHIFT) & FLEXIO_TIMCFG_TIMDIS_MASK) + +#define FLEXIO_TIMCFG_TIMRST_MASK (0x70000u) +#define FLEXIO_TIMCFG_TIMRST_SHIFT (16u) + +/* TIMRST - Timer Reset + * 0b000..Timer never reset + * 0b001..Reserved + * 0b010..Timer reset on Timer Pin equal to Timer Output + * 0b011..Timer reset on Timer Trigger equal to Timer Output + * 0b100..Timer reset on Timer Pin rising edge + * 0b101..Reserved + * 0b110..Timer reset on Trigger rising edge + * 0b111..Timer reset on Trigger rising or falling edge + */ + +#define FLEXIO_TIMCFG_TIMRST(x) ((((uint32_t)(x)) << FLEXIO_TIMCFG_TIMRST_SHIFT) & FLEXIO_TIMCFG_TIMRST_MASK) + +#define FLEXIO_TIMCFG_TIMDEC_MASK (0x300000u) +#define FLEXIO_TIMCFG_TIMDEC_SHIFT (20U) + +/* TIMDEC - Timer Decrement + * 0b00..Decrement counter on FlexIO clock, Shift clock equals Timer output. + * 0b01..Decrement counter on Trigger input (both edges), Shift clock equals + * Timer output. + * 0b10..Decrement counter on Pin input (both edges), Shift clock equals Pin + * input. + * 0b11..Decrement counter on Trigger input (both edges), Shift clock equals + * Trigger input. + */ + +#define FLEXIO_TIMCFG_TIMDEC(x) ((((uint32_t)(x)) << FLEXIO_TIMCFG_TIMDEC_SHIFT) & FLEXIO_TIMCFG_TIMDEC_MASK) + +#define FLEXIO_TIMCFG_TIMOUT_MASK (0x3000000u) +#define FLEXIO_TIMCFG_TIMOUT_SHIFT (24u) + +/* TIMOUT - Timer Output + * 0b00..Timer output is logic one when enabled and is not affected by timer + * reset + * 0b01..Timer output is logic zero when enabled and is not affected by + * timer reset + * 0b10..Timer output is logic one when enabled and on timer reset + * 0b11..Timer output is logic zero when enabled and on timer reset + */ + +#define FLEXIO_TIMCFG_TIMOUT(x) ((((uint32_t)(x)) << FLEXIO_TIMCFG_TIMOUT_SHIFT) & FLEXIO_TIMCFG_TIMOUT_MASK) + +/* The count of FLEXIO_TIMCFG */ + +#define FLEXIO_TIMCFG_COUNT (8u) + +/* TIMCMP - Timer Compare N Register */ + +#define FLEXIO_TIMCMP_CMP_MASK (0xffffu) +#define FLEXIO_TIMCMP_CMP_SHIFT (0u) + +/* CMP - Timer Compare Value */ + +#define FLEXIO_TIMCMP_CMP(x) ((((uint32_t)(x)) << FLEXIO_TIMCMP_CMP_SHIFT) & FLEXIO_TIMCMP_CMP_MASK) + +/* The count of FLEXIO_TIMCMP */ + +#define FLEXIO_TIMCMP_COUNT (8u) + +/* SHIFTBUFNBS - Shifter Buffer N Nibble Byte Swapped Register */ + +#define FLEXIO_SHIFTBUFNBS_SHIFTBUFNBS_MASK (0xffffffffu) +#define FLEXIO_SHIFTBUFNBS_SHIFTBUFNBS_SHIFT (0u) + +/* SHIFTBUFNBS - Shift Buffer */ + +#define FLEXIO_SHIFTBUFNBS_SHIFTBUFNBS(x) ((((uint32_t)(x)) << FLEXIO_SHIFTBUFNBS_SHIFTBUFNBS_SHIFT) & FLEXIO_SHIFTBUFNBS_SHIFTBUFNBS_MASK) + +/* The count of FLEXIO_SHIFTBUFNBS */ + +#define FLEXIO_SHIFTBUFNBS_COUNT (8u) + +/* SHIFTBUFHWS - Shifter Buffer N Half Word Swapped Register */ + +#define FLEXIO_SHIFTBUFHWS_SHIFTBUFHWS_MASK (0xffffffffu) +#define FLEXIO_SHIFTBUFHWS_SHIFTBUFHWS_SHIFT (0u) + +/* SHIFTBUFHWS - Shift Buffer */ + +#define FLEXIO_SHIFTBUFHWS_SHIFTBUFHWS(x) ((((uint32_t)(x)) << FLEXIO_SHIFTBUFHWS_SHIFTBUFHWS_SHIFT) & FLEXIO_SHIFTBUFHWS_SHIFTBUFHWS_MASK) + +/* The count of FLEXIO_SHIFTBUFHWS */ + +#define FLEXIO_SHIFTBUFHWS_COUNT (8u) + +/* SHIFTBUFNIS - Shifter Buffer N Nibble Swapped Register */ + +#define FLEXIO_SHIFTBUFNIS_SHIFTBUFNIS_MASK (0xffffffffu) +#define FLEXIO_SHIFTBUFNIS_SHIFTBUFNIS_SHIFT (0u) + +/* SHIFTBUFNIS - Shift Buffer */ + +#define FLEXIO_SHIFTBUFNIS_SHIFTBUFNIS(x) ((((uint32_t)(x)) << FLEXIO_SHIFTBUFNIS_SHIFTBUFNIS_SHIFT) & FLEXIO_SHIFTBUFNIS_SHIFTBUFNIS_MASK) + +/* The count of FLEXIO_SHIFTBUFNIS */ + +#define FLEXIO_SHIFTBUFNIS_COUNT (8u) + +#endif /* __ARCH_ARM64_SRC_IMX9_HARDWARE_IMX9_FLEXIO_H */ diff --git a/arch/arm64/src/imx9/imx9_flexio_pwm.c b/arch/arm64/src/imx9/imx9_flexio_pwm.c new file mode 100644 index 0000000000000..f213c1e5acab8 --- /dev/null +++ b/arch/arm64/src/imx9/imx9_flexio_pwm.c @@ -0,0 +1,756 @@ +/**************************************************************************** + * arch/arm64/src/imx9/imx9_flexio_pwm.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "imx9_flexio_pwm.h" +#include "arm64_arch.h" +#include "imx9_ccm.h" +#include "imx9_iomuxc.h" +#include "hardware/imx9_ccm.h" +#include "hardware/imx9_pinmux.h" +#include "hardware/imx9_flexio.h" + +#ifdef CONFIG_IMX9_FLEXIO_PWM + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define PIN_FOR_TIMER(priv, timer) ((uint8_t)(priv->pins >> (timer * 8))) + +#ifdef CONFIG_IMX9_FLEXIO1_PWM +# if (CONFIG_PWM_NCHANNELS < CONFIG_IMX9_FLEXIO1_PWM_NCHANNELS) +# error CONFIG_PWM_NCHANNELS < CONFIG_IMX9_FLEXIO1_PWM_NCHANNELS +# endif +#endif + +#ifdef CONFIG_IMX9_FLEXIO2_PWM +# if (CONFIG_PWM_NCHANNELS < CONFIG_IMX9_FLEXIO2_PWM_NCHANNELS) +# error CONFIG_PWM_NCHANNELS < CONFIG_IMX9_FLEXIO2_PWM_NCHANNELS +# endif +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This structure represents the state of one PWM timer */ + +struct imx9_pwmtimer_s +{ + const struct pwm_ops_s *ops; /* PWM operations */ + const flexio_pwm_id_t id; /* PWM_FLEXIO1 or PWM_FLEXIO2 */ + const int nchannels; /* Number of channels used */ + const uintptr_t base; /* The base address of the FLEXIO */ + const uint64_t pins; /* Mapping of timer outputs to flexio outputs */ + const int int_trigger; /* Uses flex-io internal timer for frequency */ + int trigger_ch; /* Trigger channel */ + unsigned frequency; /* Current frequency setting */ + int period; /* PWM period in ticks of functional clock */ +}; + +/**************************************************************************** + * Static Function Prototypes + ****************************************************************************/ + +/* PWM driver methods */ + +static int pwm_setup(struct pwm_lowerhalf_s *dev); +static int pwm_shutdown(struct pwm_lowerhalf_s *dev); + +static int pwm_start(struct pwm_lowerhalf_s *dev, + const struct pwm_info_s *info); + +static int pwm_stop(struct pwm_lowerhalf_s *dev); +static int pwm_ioctl(struct pwm_lowerhalf_s *dev, + int cmd, unsigned long arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* This is the list of lower half PWM driver methods used by the upper half + * driver + */ + +static const struct pwm_ops_s g_pwmops = +{ + .setup = pwm_setup, + .shutdown = pwm_shutdown, + .start = pwm_start, + .stop = pwm_stop, + .ioctl = pwm_ioctl, +}; + +static struct imx9_pwmtimer_s g_pwmdev[] = +{ +#ifdef CONFIG_IMX9_FLEXIO1_PWM + { + .ops = &g_pwmops, + .id = PWM_FLEXIO1, + .nchannels = CONFIG_IMX9_FLEXIO1_PWM_NCHANNELS, + .base = IMX9_FLEXIO1_BASE, + .pins = CONFIG_IMX9_FLEXIO1_PWM_CHANNEL_PINS, + .int_trigger = 1, + }, +#endif + +#ifdef CONFIG_IMX9_FLEXIO2_PWM + { + .ops = &g_pwmops, + .id = PWM_FLEXIO2, + .nchannels = CONFIG_IMX9_FLEXIO2_PWM_NCHANNELS, + .base = IMX9_FLEXIO2_BASE, + .pins = CONFIG_IMX9_FLEXIO2_PWM_CHANNEL_PINS, + .int_trigger = 1, + }, +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: flexio_getreg + * + * Description: + * Read the value of a flex-io register. + * + * Input Parameters: + * priv - A reference to the PWM block + * offset - The offset to the register to read + * + * Returned Value: + * The current contents of the specified register + * + ****************************************************************************/ + +static inline uint32_t flexio_getreg(struct imx9_pwmtimer_s *priv, + int offset) +{ + return getreg32(priv->base + offset); +} + +/**************************************************************************** + * Name: flexio_putreg + * + * Description: + * Read the value of an PWM timer register. + * + * Input Parameters: + * priv - A reference to the PWM block status + * offset - The offset to the register to read + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void flexio_putreg(struct imx9_pwmtimer_s *priv, int offset, + uint32_t value) +{ + putreg32(value, priv->base + offset); +} + +/**************************************************************************** + * Name: flexio_mux + * + * Description: + * Mux the flex-io output pins to pads. The macros FLEXIOn_PWMx_MUX + * need to be defined in the board.h file + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void flexio_mux(void) +{ +#ifdef CONFIG_IMX9_FLEXIO1_PWM + +# ifdef FLEXIO1_PWM0_MUX + imx9_iomux_configure(FLEXIO1_PWM0_MUX); +# endif + +# ifdef FLEXIO1_PWM1_MUX + imx9_iomux_configure(FLEXIO1_PWM1_MUX); +# endif + +# ifdef FLEXIO1_PWM2_MUX + imx9_iomux_configure(FLEXIO1_PWM2_MUX); +# endif + +# ifdef FLEXIO1_PWM3_MUX + imx9_iomux_configure(FLEXIO1_PWM3_MUX); +# endif + +# ifdef FLEXIO1_PWM4_MUX + imx9_iomux_configure(FLEXIO1_PWM4_MUX); +# endif + +# ifdef FLEXIO1_PWM5_MUX + imx9_iomux_configure(FLEXIO1_PWM5_MUX); +# endif + +# ifdef FLEXIO1_PWM6_MUX + imx9_iomux_configure(FLEXIO1_PWM6_MUX); +# endif + +# ifdef FLEXIO1_PWM7_MUX + imx9_iomux_configure(FLEXIO1_PWM7_MUX); +# endif + +#endif + +#ifdef CONFIG_IMX9_FLEXIO2_PWM + +# ifdef FLEXIO2_PWM0_MUX + imx9_iomux_configure(FLEXIO2_PWM0_MUX); +# endif + +# ifdef FLEXIO2_PWM1_MUX + imx9_iomux_configure(FLEXIO2_PWM1_MUX); +# endif + +# ifdef FLEXIO2_PWM2_MUX + imx9_iomux_configure(FLEXIO2_PWM2_MUX); +# endif + +# ifdef FLEXIO2_PWM3_MUX + imx9_iomux_configure(FLEXIO2_PWM3_MUX); +# endif + +# ifdef FLEXIO2_PWM4_MUX + imx9_iomux_configure(FLEXIO2_PWM4_MUX); +# endif + +# ifdef FLEXIO2_PWM5_MUX + imx9_iomux_configure(FLEXIO2_PWM5_MUX); +# endif + +# ifdef FLEXIO2_PWM6_MUX + imx9_iomux_configure(FLEXIO2_PWM6_MUX); +# endif + +# ifdef FLEXIO2_PWM7_MUX + imx9_iomux_configure(FLEXIO2_PWM7_MUX); +# endif + +#endif +} + +/**************************************************************************** + * Name: pwm_init_trigger_timer + * + * Description: + * Initialize the timer trigger, generating the PWM frequency + * + * Input Parameters: + * priv - A reference to the lower half PWM driver state structure + * + * Returned Value: + * OK on success, ERROR if the timer initialization fails + * + ****************************************************************************/ + +static int pwm_init_trigger_timer(struct imx9_pwmtimer_s *priv) +{ + uint32_t reg; + int num_timers; + + /* For now, use the last available flexio timer to produce internal + * trigger. This can be later expanded to use external trigger from + * LPIT timer, if one more PWM channel is required + */ + + /* Get parameter register and number of supported timers */ + + reg = flexio_getreg(priv, IMX9_FLEXIO_PARAM_OFFSET); + num_timers = (reg & FLEXIO_PARAM_TIMER_MASK) >> FLEXIO_PARAM_TIMER_SHIFT; + + num_timers--; + if (num_timers < priv->nchannels) + { + pwmerr("PWM%d max channels %d\n", priv->id, num_timers); + return ERROR; + } + + priv->trigger_ch = num_timers; + + return OK; +} + +/**************************************************************************** + * Name: pwm_select_func_clock + * + * Description: + * Select best suitable functional clock for the flexio + * + * Input Parameters: + * priv - A reference to the lower half PWM driver state structure + * freq - The requested PWM frequency for this flexio block + * + * Returned Value: + * Zero on success, negated error value on failure + * + ****************************************************************************/ + +static int pwm_select_func_clock(struct imx9_pwmtimer_s *priv, int freq) +{ + const int max_div = 24000000 / 65536 + 1; /* for 1 Hz */ + int div; + uint32_t period; + + if (freq == 0) + { + priv->period = 0; + return 0; + } + + /* Use the 24MHz OSC clock, and find the best divider to get as much + * resolution as possible using 16 bit timer + */ + + for (div = 1; div < max_div; div++) + { + period = 24000000 / div / freq; + if (period < 65536) + { + priv->period = period; + break; + } + } + + imx9_ccm_configure_root_clock(CCM_CR_FLEXIO1 + priv->id, OSC_24M, div); + + /* Enable peripheral clock */ + + imx9_ccm_gate_on(CCM_LPCG_FLEXIO1 + priv->id , true); + + return 0; +} + +/**************************************************************************** + * Name: pwm_update_frequency + * + * Description: + * Initialize the timer trigger, generating the PWM freuency + * + * Input Parameters: + * priv - A reference to the lower half PWM driver state structure + * freq - The requested PWM frequency for this flexio block + * + * Returned Value: + * Zero on success, negated error value on failure + * + ****************************************************************************/ + +static int pwm_update_frequency(struct imx9_pwmtimer_s *priv, int freq) +{ + int ret = pwm_select_func_clock(priv, freq); + if (ret < 0) + { + return ret; + } + + /* Configure the timer to produce internal trigger. The following + * setting produces 50/50 pulse where duty cycle is defined by + * TIMCMP: + * + * TIMCFG: + * TIMOUT = 0 Timer output is logic one when enabled and not + * affected by timer reset + * TIMDEC = 0 Decrement counter on FLEXIO clock + * TIMRST = 0x0 Timer never reset + * TIMDIS = 0x0 Timer never disabled + * TIMENA = 0x0 Timer always enabled + * TIMCTL: + * TIMOD = 0x3 Single 16-bit counter + * PINCFG = 0x0 Output pin disabled + * TIMCMP: frequency / 2 + */ + + flexio_putreg(priv, IMX9_FLEXIO_TIMCMP_OFFSET(priv->trigger_ch), + priv->period / 2); + + /* Enable / disable timer */ + + flexio_putreg(priv, IMX9_FLEXIO_TIMCTL_OFFSET(priv->trigger_ch), + freq > 0 ? FLEXIO_TIMCTL_TIMOD(0x3) : + FLEXIO_TIMCTL_TIMOD(0x0)); + + return ret; +} + +/**************************************************************************** + * Name: pwm_update_duty + * + * Description: + * Change the channel duty cycle. + * + * Input Parameters: + * priv - A reference to the lower half PWM driver state structure + * channel - Channel to by updated + * duty - New duty cycle as fraction of 65536 + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int pwm_update_duty(struct imx9_pwmtimer_s *priv, int pwm_ch, + ub16_t duty16) +{ + uint64_t duty = ub16toi(duty16); + uint32_t edge = (duty * priv->period + 0x8000) >> 16; + int timer = pwm_ch - 1; /* map pwm ch 1 to timer 0 etc.. */ + uint32_t regval; + + if (pwm_ch == 0 || pwm_ch > priv->nchannels) + { + pwmerr("ERROR: PWM%d has no such channel: %u\n", priv->id, pwm_ch); + return -EINVAL; + } + + /* Now configure the flexio timers in 16-bit counter mode */ + + /* Timers 0-6: + * TIMCFG: + * TIMOUT = 0 Timer output is 1 when enabled and not affected by reset + * TIMDEC = 0 Decrement counter on FLEXIO clock + * TIMRST = 0x0 Timer never reset + * TIMDIS = 0x2 Timer disabled on counter 0 + * TIMENA = 0x6 Timer enabled on Trigger rising edge + * TIMCTL: + * TIMOD = 0x3 single 16-bit counter + * TRGSEL = 4 * trg_ch + 3 timer "trg_ch" trigger output + * TRGSRC = 1 internal trigger + * PINCFG = 0x3 Timer pin output + * PINSEL = timer number + mux conf + * TIMCMP: duty cycle + */ + + /* If this is the first time configuring the PWMs, configure the + * timer fully, otherwise just update the duty cycle + */ + + flexio_putreg(priv, IMX9_FLEXIO_TIMCMP_OFFSET(timer), duty); + + if (priv->frequency == 0) + { + flexio_putreg(priv, IMX9_FLEXIO_TIMCFG_OFFSET(timer), + FLEXIO_TIMCFG_TIMDIS(0x2) | + FLEXIO_TIMCFG_TIMENA(0x6)); + + /* When initially configuring PINCFG=11b, FLEXIO may briefly drive the + * pin low. To avoid this, configure PINCFG=10b along with the rest of + * the control register and then perform a subsequent write to set + * PINCFG=11b + */ + + regval = (FLEXIO_TIMCTL_TIMOD(0x3) | + FLEXIO_TIMCTL_TRGSEL(4 * priv->trigger_ch + 3) | + FLEXIO_TIMCTL_TRGSRC(priv->int_trigger) | + FLEXIO_TIMCTL_PINSEL(PIN_FOR_TIMER(priv, timer))); + + flexio_putreg(priv, IMX9_FLEXIO_TIMCTL_OFFSET(timer), + regval | FLEXIO_TIMCTL_PINCFG(0x2)); + + flexio_putreg(priv, IMX9_FLEXIO_TIMCTL_OFFSET(timer), + regval | FLEXIO_TIMCTL_PINCFG(0x3)); + } + + pwminfo("PWM%d channel %d, p: %d e: %" PRIu32 "\n", priv->id, pwm_ch, + priv->period, edge); + + return 0; +} + +/**************************************************************************** + * Name: pwm_setup + * + * Description: + * This method is called when the driver is opened. The lower half driver + * should configure and initialize the device so that it is ready for use. + * It should not, however, output pulses until the start method is called. + * + * Input Parameters: + * dev - A reference to the lower half PWM driver state structure + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + * Assumptions: + * + ****************************************************************************/ + +static int pwm_setup(struct pwm_lowerhalf_s *dev) +{ + return OK; +} + +/**************************************************************************** + * Name: pwm_shutdown + * + * Description: + * This method is called when the driver is closed. The lower half driver + * stop pulsed output, free any resources, disable the timer hardware, and + * put the system into the lowest possible power usage state + * + * Input Parameters: + * dev - A reference to the lower half PWM driver state structure + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int pwm_shutdown(struct pwm_lowerhalf_s *dev) +{ + /* Make sure that the output has been stopped */ + + pwm_stop(dev); + + return OK; +} + +/**************************************************************************** + * Name: pwm_start + * + * Description: + * (Re-)initialize the timer resources and start the pulsed output + * + * Input Parameters: + * dev - A reference to the lower half PWM driver state structure + * info - A reference to the characteristics of the pulsed output + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int pwm_start(struct pwm_lowerhalf_s *dev, + const struct pwm_info_s *info) +{ + struct imx9_pwmtimer_s *priv = (struct imx9_pwmtimer_s *)dev; + int ret = OK; + int i; + + if (priv == NULL || info == NULL || info->frequency == 0) + { + return -EINVAL; + } + + /* Set the frequency if not changed */ + + if (info->frequency != priv->frequency) + { + ret = pwm_update_frequency(priv, info->frequency); + } + + /* Handle channel specific setup */ + + for (i = 0; i < CONFIG_PWM_NCHANNELS; i++) + { + if (ret != OK || info->channels[i].channel == -1) + { + break; + } + + ret = pwm_update_duty(priv, info->channels[i].channel, + info->channels[i].duty); + } + + if (ret == OK) + { + priv->frequency = info->frequency; + } + + return ret; +} + +/**************************************************************************** + * Name: pwm_stop + * + * Description: + * Stop the pulsed output and reset the timer resources + * + * Input Parameters: + * dev - A reference to the lower half PWM driver state structure + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + * Assumptions: + * This function is called to stop the pulsed output at anytime. + * + ****************************************************************************/ + +static int pwm_stop(struct pwm_lowerhalf_s *dev) +{ + struct imx9_pwmtimer_s *priv = (struct imx9_pwmtimer_s *)dev; + int i; + + pwminfo("PWM%d stop\n", priv->id); + + /* Check that timer is valid */ + + if (priv == NULL) + { + return -EINVAL; + } + + /* Disable all the channels */ + + for (i = 0; i < priv->nchannels; i++) + { + flexio_putreg(priv, IMX9_FLEXIO_TIMCTL_OFFSET(i), + FLEXIO_TIMCTL_PINCFG(0x2)); + flexio_putreg(priv, IMX9_FLEXIO_TIMCTL_OFFSET(i), 0); + } + + /* Setting frequency to zero disables trigger clock */ + + return pwm_update_frequency(priv, 0); +} + +/**************************************************************************** + * Name: pwm_ioctl + * + * Description: + * Lower-half logic may support platform-specific ioctl commands + * + * Input Parameters: + * dev - A reference to the lower half PWM driver state structure + * cmd - The ioctl command + * arg - The argument accompanying the ioctl command + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int pwm_ioctl(struct pwm_lowerhalf_s *dev, int cmd, + unsigned long arg) +{ + return -ENOTTY; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: imx9_flexio_pwm_init + * + * Description: + * Initialize flexio blocks to generate EPWM. + * + * Input Parameters: + * pwmid - A number identifying the pwm block. The number of valid + * IDs varies depending on the configuration. + * + * Returned Value: + * On success, a pointer to the lower half PWM driver is + * returned. NULL is returned on any failure. + * + ****************************************************************************/ + +struct pwm_lowerhalf_s *imx9_flexio_pwm_init(flexio_pwm_id_t pwmid) +{ + struct imx9_pwmtimer_s *lower = NULL; + int i; + + for (i = 0; i < sizeof(g_pwmdev) / sizeof(struct imx9_pwmtimer_s); i++) + { + if (pwmid == g_pwmdev[i].id) + { + lower = &g_pwmdev[i]; + break; + } + } + + if (lower) + { + /* IO mux */ + + flexio_mux(); + + /* Reset FlexIO */ + + flexio_putreg(lower, IMX9_FLEXIO_CTRL_OFFSET, FLEXIO_CTRL_SWRST(1)); + + /* Enable FlexIO and de-assert reset */ + + flexio_putreg(lower, IMX9_FLEXIO_CTRL_OFFSET, FLEXIO_CTRL_FLEXEN(1)); + + /* Make sure that FlexIO is enabled and reset is cleared */ + + while (flexio_getreg(lower, IMX9_FLEXIO_CTRL_OFFSET) != + FLEXIO_CTRL_FLEXEN_MASK); + + /* Initialize the trigger timer used for PWM period generation */ + + if (pwm_init_trigger_timer(lower) != OK) + { + /* Disable FlexIO */ + + flexio_putreg(lower, IMX9_FLEXIO_CTRL_OFFSET, 0); + + return NULL; + } + + pwminfo("PWM%d at 0x%" PRIxPTR " configured\n", pwmid, lower->base); + } + else + { + pwmerr("ERROR: No such timer configured %d\n", pwmid); + } + + return (struct pwm_lowerhalf_s *)lower; +} + +#endif diff --git a/arch/arm64/src/imx9/imx9_flexio_pwm.h b/arch/arm64/src/imx9/imx9_flexio_pwm.h new file mode 100644 index 0000000000000..a4b3f8d97d529 --- /dev/null +++ b/arch/arm64/src/imx9/imx9_flexio_pwm.h @@ -0,0 +1,104 @@ +/**************************************************************************** + * arch/arm64/src/imx9/imx9_flexio_pwm.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM64_SRC_IMX9_IMX9_FLEXIO_PWM_H +#define __ARCH_ARM64_SRC_IMX9_IMX9_FLEXIO_PWM_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +/* Check if PWM support for any channel is enabled. */ + +#ifdef CONFIG_IMX9_FLEXIO_PWM + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "hardware/imx9_flexio.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +typedef enum +{ + PWM_FLEXIO1 = 0, + PWM_FLEXIO2 = 1, +} flexio_pwm_id_t; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: imx9_flexio_pwm_init + * + * Description: + * Initialize a FLEXIO block for EPWM usage. + * + * Input Parameters: + * pwmid - A number identifying the pwm block. + * + * Returned Value: + * On success, a pointer to the lower half of the PWM driver is + * returned. NULL is returned on any failure. + * + ****************************************************************************/ + +struct pwm_lowerhalf_s *imx9_flexio_pwm_init(flexio_pwm_id_t pwmid); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_IMX9_FLEXIO_PWM */ +#endif /* __ARCH_ARM64_SRC_IMX9_IMX9_FLEXIO_PWM_H */