diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/application/hart0/e51.c b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/application/hart0/e51.c index 62cf721..e468db6 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/application/hart0/e51.c +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/application/hart0/e51.c @@ -1,9 +1,13 @@ /******************************************************************************* - * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions. + * Copyright 2019 Microchip FPGA Embedded Systems Solutions. * * SPDX-License-Identifier: MIT * - * Application code running on E51 + * @file e51.c + * + * @author Microchip FPGA Embedded Systems Solutions + * + * @brief Application code running on E51 * * PolarFire SoC MSS RTC interrupt example project */ diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/application/hart1/u54_1.c b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/application/hart1/u54_1.c index 1ac1648..a8c7a7d 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/application/hart1/u54_1.c +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/application/hart1/u54_1.c @@ -1,11 +1,13 @@ /******************************************************************************* - * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions. + * Copyright 2019 Microchip FPGA Embedded Systems Solutions. * * SPDX-License-Identifier: MIT * - * MPFS HAL Embedded Software example + * @file u54_1.c * - * Application code running on U54_1 + * @author Microchip FPGA Embedded Systems Solutions + * + * @brief Application code running on U54_1. */ #include "mpfs_hal/mss_hal.h" diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/application/hart2/u54_2.c b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/application/hart2/u54_2.c index ee87c89..e4f00fd 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/application/hart2/u54_2.c +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/application/hart2/u54_2.c @@ -1,11 +1,13 @@ /******************************************************************************* - * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions. + * Copyright 2019 Microchip FPGA Embedded Systems Solutions. * * SPDX-License-Identifier: MIT * - * MPFS HAL Embedded Software example + * @file u54_2.c * - * Application code running on U54_2 + * @author Microchip FPGA Embedded Systems Solutions + * + * @brief Application code running on U54_2 */ #include diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/application/hart3/u54_3.c b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/application/hart3/u54_3.c index a4684eb..aad8ee9 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/application/hart3/u54_3.c +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/application/hart3/u54_3.c @@ -1,11 +1,13 @@ /******************************************************************************* - * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions. + * Copyright 2019 Microchip FPGA Embedded Systems Solutions. * * SPDX-License-Identifier: MIT * - * MPFS HAL Embedded Software example + * @file u54_3.c * - * Application code running on U54_3 + * @author Microchip FPGA Embedded Systems Solutions + * + * @brief Application code running on U54_3 */ #include diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/application/hart4/u54_4.c b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/application/hart4/u54_4.c index 5d3cd5b..0d95bff 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/application/hart4/u54_4.c +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/application/hart4/u54_4.c @@ -1,11 +1,13 @@ /******************************************************************************* - * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions. + * Copyright 2019 Microchip FPGA Embedded Systems Solutions. * * SPDX-License-Identifier: MIT * - * MPFS HAL Embedded Software example + * @file u54_4.c * - * Application code running on U54_4 + * @author Microchip FPGA Embedded Systems Solutions + * + * @brief Application code running on U54_4 */ #include diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/application/inc/common.h b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/application/inc/common.h index 7c9b923..4db9426 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/application/inc/common.h +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/application/inc/common.h @@ -1,7 +1,11 @@ /******************************************************************************* - * Copyright 2019-2021 Microchip FPGA Embedded Systems Solution. + * Copyright 2019 Microchip FPGA Embedded Systems Solution. * * SPDX-License-Identifier: MIT + * + * @file common.h + * + * @author Microchip FPGA Embedded Systems Solutions */ #ifndef COMMON_H_ diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/boards/icicle-kit-es/platform_config/mpfs_hal_config/mss_sw_config.h b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/boards/icicle-kit-es/platform_config/mpfs_hal_config/mss_sw_config.h index 01e5922..c42b991 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/boards/icicle-kit-es/platform_config/mpfs_hal_config/mss_sw_config.h +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/boards/icicle-kit-es/platform_config/mpfs_hal_config/mss_sw_config.h @@ -1,10 +1,13 @@ /******************************************************************************* - * Copyright 2019-2022 Microchip FPGA Embedded Systems Solutions. + * Copyright 2019 Microchip FPGA Embedded Systems Solutions. * * SPDX-License-Identifier: MIT * - * MPFS HAL Embedded Software + * @file mss_sw_config.h * + * @author Microchip FPGA Embedded Systems Solutions + * + * @brief MPFS HAL Embedded Software */ /******************************************************************************* diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/boards/icicle-kit-es/platform_config_ddr/mpfs_hal_config/mss_sw_config.h b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/boards/icicle-kit-es/platform_config_ddr/mpfs_hal_config/mss_sw_config.h index a258d2a..a61eb0b 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/boards/icicle-kit-es/platform_config_ddr/mpfs_hal_config/mss_sw_config.h +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/boards/icicle-kit-es/platform_config_ddr/mpfs_hal_config/mss_sw_config.h @@ -1,10 +1,13 @@ /******************************************************************************* - * Copyright 2019-2022 Microchip FPGA Embedded Systems Solutions. + * Copyright 2019 Microchip FPGA Embedded Systems Solutions. * * SPDX-License-Identifier: MIT * - * MPFS HAL Embedded Software + * @file mss_sw_config.h * + * @author Microchip FPGA Embedded Systems Solutions + * + * @brief MPFS HAL Embedded Software */ /******************************************************************************* diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/drivers/mss/mss_mmuart/mss_uart.c b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/drivers/mss/mss_mmuart/mss_uart.c index 3c63ce7..7cd22d2 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/drivers/mss/mss_mmuart/mss_uart.c +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/drivers/mss/mss_mmuart/mss_uart.c @@ -1,12 +1,15 @@ /******************************************************************************* - * Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions. + * Copyright 2019 Microchip FPGA Embedded Systems Solutions. * * SPDX-License-Identifier: MIT - * - * PolarFire SoC Microprocessor Subsystem MMUART bare metal software driver - * implementation. + * + * @file mss_uart.c + * @author Microchip FPGA Embedded Systems Solutions + * @brief PolarFire SoC Microprocessor Subsystem (MSS) MMUART bare metal + * software driver implementation. * */ + #include "mpfs_hal/mss_hal.h" #include "mss_uart_regs.h" #include "mss_uart.h" @@ -62,6 +65,7 @@ static uint32_t g_uart_axi_pos = 0x0u; #define FCR_TRIG_LEVEL_MASK 0xC0u #define IIRF_MASK 0x0Fu +#define IER_MASK 0x0Du #define INVALID_INTERRUPT 0u #define INVALID_IRQ_HANDLER ((mss_uart_irq_handler_t) 0) @@ -350,8 +354,11 @@ MSS_UART_irq_tx { ASSERT(pbuff != ((uint8_t*)0)); ASSERT(tx_size > 0u); + ASSERT(TX_COMPLETE == this_uart->tx_buff_size); - if ((tx_size > 0u) && (pbuff != ((uint8_t*)0))) + if ((tx_size > 0u) && + (pbuff != ((uint8_t*)0)) && + (TX_COMPLETE == this_uart->tx_buff_size)) { /* Initialize the transmit info for the UART instance with the * arguments */ @@ -359,10 +366,7 @@ MSS_UART_irq_tx this_uart->tx_buff_size = tx_size; this_uart->tx_idx = 0u; - /* assign default handler for data transfer */ - this_uart->tx_handler = default_tx_handler; - - /* enables TX interrupt */ + /* Enables TX interrupt */ this_uart->hw_reg->IER |= ETBEI_MASK; enable_irq(this_uart); } @@ -439,8 +443,6 @@ MSS_UART_enable_irq { ASSERT(MSS_UART_INVALID_IRQ > irq_mask); - enable_irq(this_uart); - if (MSS_UART_INVALID_IRQ > irq_mask) { /* irq_mask encoding: 1- enable @@ -448,10 +450,13 @@ MSS_UART_enable_irq * bit 1 - Transmitter Holding Register Empty Interrupt * bit 2 - Receiver Line Status Interrupt * bit 3 - Modem Status Interrupt + * + * The use of the IER_MASK macro is to prevent the THRE to be + * set at this point of the design flow and to lead to a break + * later on. */ this_uart->hw_reg->IER |= ((uint8_t)(((uint32_t)irq_mask & - (uint32_t)IIRF_MASK))); - + (uint32_t)IER_MASK))); /* * bit 4 - Receiver time-out interrupt @@ -493,15 +498,6 @@ MSS_UART_disable_irq */ this_uart->hw_reg->IEM &= (uint8_t)(~(((uint32_t)irq_mask >> 4u) & ((uint32_t)IIRF_MASK))); - - if(1 == this_uart->local_irq_enabled) - { - __disable_local_irq((int8_t)MMUART0_E51_INT); - } - else - { - disable_irq(this_uart); - } } /***************************************************************************//** @@ -752,19 +748,13 @@ MSS_UART_set_tx_handler mss_uart_irq_handler_t handler ) { - ASSERT(handler != INVALID_IRQ_HANDLER); - - if (handler != INVALID_IRQ_HANDLER) + if (handler != NULL_HANDLER) { this_uart->tx_handler = handler; - - /* Make TX buffer info invalid */ - this_uart->tx_buffer = (const uint8_t*)0; - this_uart->tx_buff_size = 0u; - - /* Enable transmitter holding register Empty interrupt. */ - this_uart->hw_reg->IER |= ETBEI_MASK; - enable_irq(this_uart); + } + else + { + this_uart->tx_handler = default_tx_handler; } } @@ -1610,6 +1600,11 @@ uart_isr { (*(this_uart->tx_handler))(this_uart); } + if (this_uart->tx_idx == this_uart->tx_buff_size) + { + MSS_UART_disable_irq(this_uart, MSS_UART_TBE_IRQ); + this_uart->tx_buff_size = TX_COMPLETE; + } } break; @@ -1650,7 +1645,7 @@ uart_isr } /* NACK interrupt */ - if (this_uart->hw_reg->IIM &ENACKI) + if (this_uart->hw_reg->IIM & ENACKI_MASK) { ASSERT(NULL_HANDLER != this_uart->nack_handler); @@ -1661,7 +1656,7 @@ uart_isr } /* PID parity error interrupt */ - if (this_uart->hw_reg->IIM & EPID_PEI) + if (this_uart->hw_reg->IIM & EPID_PEI_MASK) { ASSERT(NULL_HANDLER != this_uart->pid_pei_handler); @@ -1672,7 +1667,7 @@ uart_isr } /* LIN break detection interrupt */ - if (this_uart->hw_reg->IIM & ELINBI) + if (this_uart->hw_reg->IIM & ELINBI_MASK) { ASSERT(NULL_HANDLER != this_uart->break_handler); @@ -1683,7 +1678,7 @@ uart_isr } /* LIN Sync detection interrupt */ - if (this_uart->hw_reg->IIM & ELINSI) + if (this_uart->hw_reg->IIM & ELINSI_MASK) { ASSERT(NULL_HANDLER != this_uart->sync_handler); @@ -1747,15 +1742,6 @@ default_tx_handler ++this_uart->tx_idx; } } - - /* Flag Tx as complete if all data has been pushed into the Tx FIFO. */ - if (this_uart->tx_idx == this_uart->tx_buff_size) - { - this_uart->tx_buff_size = TX_COMPLETE; - - /* disables TX interrupt */ - this_uart->hw_reg->IER &= ~ETBEI_MASK; - } } } diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/drivers/mss/mss_mmuart/mss_uart.h b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/drivers/mss/mss_mmuart/mss_uart.h index 49e1844..8bafb16 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/drivers/mss/mss_mmuart/mss_uart.h +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/drivers/mss/mss_mmuart/mss_uart.h @@ -1,87 +1,71 @@ /******************************************************************************* - * Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions. + * Copyright 2019 Microchip FPGA Embedded Systems Solutions. * * SPDX-License-Identifier: MIT * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - * - * PolarFire SoC Microprocessor Subsystem MMUART bare metal software driver - * public API. + * @file mss_uart.h + * @author Microchip FPGA Embedded Systems Solutions + * @brief PolarFire SoC Microprocessor Subsystem (MSS) MMUART bare metal + * software driver public API. * */ + /*=========================================================================*//** - @mainpage PolarFire SoC MSS UART Bare Metal Driver. - + @mainpage PolarFire® SoC MSS UART Bare Metal Driver. + ============================================================================== Introduction ============================================================================== - The PolarFire SoC Microprocessor subsystem (MSS) includes five multi-mode UART - (MMUART) peripherals for serial communication. This driver provides a set of - functions for controlling the MSS MMUARTs as part of a bare metal system + The PolarFire® SoC Microprocessor Subsystem (MSS) includes five multi-mode + UART(MMUART) peripherals for serial communication. This driver provides a set + of functions to control the MSS MMUARTs as part of a bare metal system where no operating system is available. These drivers can be adapted for use as part of an operating system, but the implementation of the adaptation layer between this driver and the operating system's driver model is outside the scope of this driver. - Note: MSS UART is synonymous with MSS MMUART in this document. - + Note: MSS UART and MSS MMUART are synonymous in this document. + ============================================================================== Hardware Flow Dependencies ============================================================================== The configuration of all features of the MSS MMUART peripherals is covered by - this driver with the exception of the PolarFire SoC IOMUX configuration. - PolarFire SoC allows multiple non-concurrent uses of some external pins - through IOMUX configuration. This feature allows optimization of external pin + this driver with the exception of the PolarFire® SoC IOMUX configuration. + PolarFire® SoC allows multiple non-concurrent uses of external pins + through IOMUX configuration. This feature allows optimization of external pin usage by assigning external pins for use by either the microprocessor subsystem or the FPGA fabric. The MSS MMUART serial signals are routed through - IOMUXs to the PolarFire SoC device external pins. The MSS MMUART serial - signals may also be routed through IOMUXs to the PolarFire SoC FPGA fabric. - For more information on IOMUX, refer to the I/O Configuration section of the - PolarFire SoC Microprocessor Subsystem (MSS) User's Guide. + IOMUXs to the PolarFire® SoC device external pins. The MSS MMUART serial + signals may also be routed through IOMUXs to the PolarFire® SoC FPGA fabric. + For more information on IOMUX, see the I/O Configuration section of the + PolarFire® SoC Microprocessor Subsystem (MSS) User's Guide. - The IOMUXs are configured using the PolarFire SoC MSS configurator tool. You + The IOMUXs are configured using the PolarFire® SoC MSS configurator tool. You must ensure that the MSS MMUART peripherals are enabled and configured in the - PolarFire SoC MSS configurator if you wish to use them. For more information - on IOMUXs, refer to the IOMUX section of the PolarFire SoC microprocessor + PolarFire® SoC MSS configurator if you wish to use them. For more information + on IOMUXs, see the IOMUX section of the PolarFire® SoC Microprocessor Subsystem (MSS) User's Guide. - On PolarFire SoC an AXI switch forms a bus matrix interconnect among multiple - masters and multiple slaves. Five RISC-V CPUs connect to the Master ports - M10 to M14 of the AXI switch. By default, all the APB peripherals are - accessible on AXI-Slave 5 of the AXI switch via the AXI to AHB and AHB to APB - bridges (referred as main APB bus). However, to support logical separation in - the Asymmetric Multi-Processing (AMP) mode of operation, the APB peripherals - can alternatively be accessed on the AXI-Slave 6 via the AXI to AHB and AHB to + On PolarFire® SoC, an AXI switch forms a bus matrix interconnect among + multiple masters and multiple slaves. Five RISC-V CPUs connect to the Master + ports M10 to M14 of the AXI switch. By default, all the APB peripherals are + accessible on AXI-Slave 5 of the AXI switch using the AXI to AHB and AHB to APB + bridges (referred as main APB bus). However, to support logical separation in + the Asymmetric Multi-Processing (AMP) mode of operation, the APB peripherals + can alternatively be accessed on the AXI-Slave 6 using the AXI to AHB and AHB to APB bridges (referred as the AMP APB bus). - - Application must make sure that the desired MMUART instance is appropriately - configured on one of the APB bus described above by configuring the PolarFire - SoC system registers (SYSREG) as per the application need and that the - appropriate data structures are provided to this driver as parameter to the - functions provided by this driver. - - The base address and register addresses are defined in this driver as - constants. The interrupt number assignment for the MSS MMUART peripherals are - defined as constants in the MPFS HAL. You must ensure that the latest MPFS HAL - is included in the project settings of the SoftConsole tool chain and that it + + Application must make sure that the desired MMUART instance is appropriately + configured on one of the APB bus as described above by configuring the + PolarFire® SoC system registers (SYSREG) as per the application need and that + the appropriate data structures are provided to this driver as parameter to + the functions provided by this driver. + + The base address and register addresses are defined in this driver as + constants. The interrupt number assignment for the MSS MMUART peripherals are + defined as constants in the MPFS HAL. You must ensure that the latest MPFS HAL + is included in the project settings of the SoftConsole tool chain and that it is generated into your project. - + ============================================================================== Theory of Operation ============================================================================== @@ -89,7 +73,7 @@ - Initialization and configuration functions - Polled transmit and receive functions - Interrupt driven transmit and receive functions - + -------------------------------- Initialization and Configuration -------------------------------- @@ -98,17 +82,17 @@ - LIN mode - IrDA mode - Smartcard or ISO 7816 mode - + The MSS MMUART driver provides the MSS_UART_init(), MSS_UART_lin_init(), - MSS_UART_irda_init() and MSS_UART_smartcard_init() functions to initialize the + MSS_UART_irda_init(), and MSS_UART_smartcard_init() functions to initialize the MSS MMUARTs for operation in one of these modes. One of these initialization - functions must be called before any other MSS MMUART driver functions can be - called. The MSS MMUART operating modes are mutually exclusive; therefore only - one of the initialization functions must be called. The first parameter of the - initialization functions is a pointer to one of ten global data structures + functions must be called before calling any other MSS MMUART driver functions. + The MSS MMUART operating modes are mutually exclusive; therefore, + only one of the initialization functions can be called. The first parameter of + the initialization functions is a pointer to one of ten global data structures used to store state information for each MSS MMUART. A pointer to these data structures is also used as the first parameter to many of the driver functions - to identify which MSS MMUART will be used by the called function. The names of + to identify which MSS MMUART is used by the called function. The names of these data structures are: - g_mss_uart0_lo - g_mss_uart1_lo @@ -120,27 +104,27 @@ - g_mss_uart2_hi - g_mss_uart3_hi - g_mss_uart4_hi - - Therefore, any call to an MSS MMUART function should be of the form + + Therefore, any call to an MSS MMUART function should be of the form MSS_UART_function_name( &g_mss_uart0_lo, ... ) or MSS_UART_function_name( &g_mss_uart1_hi, ... ). - - UART or USART Mode - For the UART or USART modes of operation, the MSS MMUART driver is initialized - through a call to the MSS_UART_init() function. This function takes the UART's + + UART or USART Mode + For the UART or USART modes of operation, call the MSS_UART_init() function to + initialize the MSS MMUART instance. This function takes the UART's configuration as its parameters. The MSS_UART_init() function must be called - before any other MSS MMUART driver functions can be called. + before calling any other MSS MMUART driver functions. The MSS_UART_init() function configures the baud rate based on the input baud - rate parameter and if possible uses a fractional baud rate for greater - precision. This function disables the LIN, IrDA and SmartCard modes. - - LIN mode - For the LIN mode of operation, the MSS MMUART driver is initialized through a - call to the MSS_UART_lin_init() function. This function takes the LIN node's + rate parameter and, if possible, uses a fractional baud rate for greater + precision. This function disables the LIN, IrDA, and SmartCard modes. + + LIN Mode + For the LIN mode of operation, call the MSS_UART_lin_init() function to + initialize the MSS MMUART instance. This function takes the LIN node's configuration as its parameters. The MSS_UART_lin_init() function must be - called before any other MSS MMUART driver functions can be called. The + called before calling any other MSS MMUART driver functions. The MSS_UART_lin_init() function configures the baud rate based on the input baud - rate parameter and if possible uses a fractional baud rate for greater + rate parameter and, if possible, uses a fractional baud rate for greater precision. This function disables the IrDA and SmartCard modes. The driver also provides the following LIN mode configuration functions: - MSS_UART_set_break() @@ -148,36 +132,37 @@ - MSS_UART_set_pidpei_handler() - MSS_UART_set_linbreak_handler() - MSS_UART_set_linsync_handler() - - Note: These LIN mode configuration functions can only be called after the - MSS_UART_lin_init() function is called. - - IrDA mode - For the IrDA mode of operation, the driver is initialized through a call to - the MSS_UART_irda_init() function. This function takes the IrDA node's + + Note: These LIN mode configuration functions can only be called after calling + the MSS_UART_lin_init() function. + + IrDA Mode + For the IrDA mode of operation, call the MSS_UART_irda_init() function to + initialize the MSS MMUART instance. This function takes the IrDA node's configuration as its parameters. The MSS_UART_irda_init() function must be - called before any other MSS MMUART driver functions can be called. The + called before calling any other MSS MMUART driver functions. The MSS_UART_irda_init() function configures the baud rate based on the input baud - rate parameter and if possible uses a fractional baud rate for greater + rate parameter and, if possible, uses a fractional baud rate for greater precision. This function disables the LIN and SmartCard modes. - - Smartcard or ISO 7816 mode - For the Smartcard or ISO 7816 mode of operation, the driver is initialized - through a call to the MSS_UART_smartcard_init() function. This function takes - the smartcard configuration as its parameters. The MSS_UART_smartcard_init() - function must be called before any other MSS MMUART driver functions can be - called. The MSS_UART_smartcard_init() function configures the baud rate based - on the input baud rate parameter and if possible uses a fractional baud rate - for greater precision. This function disables the LIN and IrDA modes. - The driver also provides the following Smartcard mode configuration functions: + + Smartcard or ISO 7816 Mode + For the Smartcard or ISO 7816 mode of operation, call the + MSS_UART_smartcard_init() function to initialize the MSS MMUART instance. This + function takes the smartcard configuration as its parameters. The + MSS_UART_smartcard_init() function must be called before calling any other + MSS MMUART driver functions. The MSS_UART_smartcard_init() function configures + the baud rate based on the input baud rate parameter and, if possible, uses a + fractional baud rate for greater precision. This function disables the LIN and + IrDA modes. The driver also provides the following Smartcard mode + configuration functions: - MSS_UART_enable_halfduplex() - MSS_UART_disable_halfduplex() - MSS_UART_set_nack_handler() - + Note: These Smartcard mode configuration functions can only be called after - the MSS_UART_smartcard_init() function is called. - - Common Configuration Functions + calling the MSS_UART_smartcard_init() function. + + Common Configuration Functions The driver also provides the configuration functions that can be used with all MSS MMUART operating modes. These common configuration functions are as follows: @@ -195,47 +180,47 @@ - MSS_UART_set_filter_length() - MSS_UART_enable_afm() - MSS_UART_disable_afm() - - Note: These configuration functions can only be called after one of the - MSS_UART_init(), MSS_UART_lin_init(), MSS_UART_irda_init() or - MSS_UART_smartcard_init() functions is called. - - -------------------------------------- + + Note: These configuration functions can only be called after calling one of + the MSS_UART_init(), MSS_UART_lin_init(), MSS_UART_irda_init(), or + MSS_UART_smartcard_init() function. + + -------------------------------------- Polled Transmit and Receive Operations -------------------------------------- - The driver can be used to transmit and receive data once initialized. + The driver can be used to transmit and receive data once initialized. Data is transmitted using the MSS_UART_polled_tx() function. This function is - blocking, meaning that it will only return once the data passed to the + blocking, which means that it will only return once the data passed to the function has been sent to the MSS MMUART hardware transmitter. Data received by the MSS MMUART hardware receiver can be read by the MSS_UART_get_rx() - function. + function. The MSS_UART_polled_tx_string() function is provided to transmit a NUL ('\0') - terminated string in polled mode. This function is blocking, meaning that it - will only return once the data passed to the function has been sent to the MSS - MMUART hardware transmitter. + terminated string in polled mode. This function is blocking, which means that + it will only return once the data passed to the function has been sent to the + MSS MMUART hardware transmitter. The MSS_UART_fill_tx_fifo() function fills the MSS MMUART hardware transmit FIFO with data from a buffer passed as a parameter and returns the number of bytes transferred to the FIFO. If the transmit FIFO is not empty when the - MSS_UART_fill_tx_fifo() function is called it returns immediately without + MSS_UART_fill_tx_fifo() function is called, it returns immediately without transferring any data to the FIFO. - + --------------------------- Interrupt Driven Operations --------------------------- - The driver can also transmit or receive data under interrupt control, freeing - your application to perform other tasks until an interrupt occurs indicating - that the driver's attention is required. - - Local or PLIC interrupt: - PolarFire SoC architecture provides flexibility in terms of how the MMUART - interrupt is seen by the PolarFire SoC Core Complex. Each of the 5 MMUART - instance interrupt line is connected to the PolarFire SoC Core Complex PLIC. + The driver can also transmit or receive data under interrupt control, which + frees your application to perform other tasks until an interrupt occurs, + which indicates that the driver's attention is required. + + Local or PLIC Interrupt + PolarFire® SoC architecture provides flexibility in terms of how the MMUART + interrupt is seen by the PolarFire® SoC Core Complex. Each of the five MMUART + instance interrupt lines is connected to the PolarFire® SoC Core Complex PLIC. The MMUART0 instance interrupt line is also available as local interrupt on E51 processor. The MMUART1 instance interrupt onwards are available as local - interrupt on the U54_1 processor onwards. e.g. MMUART2 interrupt is available - as local interrupt on U54_2. + interrupt on the U54_1 processor onwards. For example MMUART2 interrupt is + available as local interrupt on U54_2 and so on. - Interrupt Handlers + Interrupt Handlers The MSS MMUART driver supports all types of interrupt triggered by the MSS MMUART. The driver's internal top level interrupt handler identifies the source of the MSS MMUART interrupt and calls the corresponding lower level @@ -243,73 +228,69 @@ to the MSS_UART_set_rx_handler(), MSS_UART_set_tx_handler(), MSS_UART_set_rxstatus_handler(), and MSS_UART_set_modemstatus_handler() functions. You are responsible for creating these lower level interrupt - handlers as part of your application program and registering them with the - driver. - Note: The PolarFire SoC HAL defines the interrupt handler functions for all - 5 MMUART instances(with weak linkage) and assigns them as the interrupt - service routines (ISR) for the MSS MMUART interrupt inputs to the - PolarFire SoC Core Complex PLIC or the Local interrupts on each of the - respective CPUs. The MSS MMUART driver provides the implementation - functions all these ISRs from which it calls its own internal top level, - interrupt handler function. - + handlers as part of your application and registering them with the + driver. + Note: The PolarFire® SoC HAL defines the interrupt handler functions for all + five MMUART instances (with weak linkage) and assigns them as the + interrupt service routines (ISR) for the MSS MMUART interrupt inputs to + the PolarFire® SoC Core Complex PLIC or the Local interrupts on each of + the respective CPUs. The MSS MMUART driver provides the implementation + functions to all these ISRs from which it calls its own internal top + level, interrupt handler function. + The MSS_UART_enable_irq() and MSS_UART_disable_irq() functions are used to enable or disable the received line status, received data available/character - time-out, transmit holding register empty and modem status interrupts at the - MSS MMUART level. The MSS_UART_enable_irq() function also enables the MSS - MMUART instance interrupt at the PolarFire SoC Core Complex level. - - Note that the MSS_UART_enable_irq() and MSS_UART_disable_irq() and all the + time-out, transmit holding register empty, and modem status interrupts at the + MSS MMUART level. + + Note: MSS_UART_enable_irq(), MSS_UART_disable_irq(), and all the calls to set the handler functions assume that the MMUART interrupt is - connected to the PolarFire SoC Core Complex PLIC. If you want the MMUART - interrupt to appear as a local interrupt to the corresponding HART then you + connected to the PolarFire® SoC Core Complex PLIC. If you want the MMUART + interrupt to appear as a local interrupt to the corresponding hart then you must explicitly call the MSS_UART_enable_local_irq() function. This function - will disable the PLIC interrupt (if it was previously enable) and enable the - local interrupt on the HART on which this function is being executed. + disables the PLIC interrupt (if it was previously enable) and enable the + local interrupt on the hart on which this function is being executed. - Transmitting Data - Interrupt-driven transmit is initiated by a call to MSS_UART_irq_tx(), - specifying the block of data to transmit. Your application is then free to - perform other tasks and inquire later whether transmit has completed by + Transmitting Data + Interrupt-driven transmit is initiated by calling MSS_UART_irq_tx(), + that specifies the block of data to transmit. Your application is then free to + perform other tasks and inquire later whether transmit is complete by calling the MSS_UART_tx_complete() function. The MSS_UART_irq_tx() function enables the UART's transmit holding register empty (THRE) interrupt and then, - when the interrupt goes active, the driver's default THRE interrupt handler - transfers the data block to the UART until the entire block is transmitted. + when the interrupt goes active, the driver's THRE interrupt handler + transfers the data block to the UART until the entire block is transmitted. Note: You can use the MSS_UART_set_tx_handler() function to assign an - alternative handler to the THRE interrupt. In this case, you must not - use the MSS_UART_irq_tx() function to initiate the transmit, as this - will re-assign the driver's default THRE interrupt handler to the THRE - interrupt. Instead, your alternative THRE interrupt handler must include - a call to the MSS_UART_fill_tx_fifo() function to transfer the data to - the UART. - - Receiving Data + alternative handler to the THRE interrupt. In this case, your + alternative THRE interrupt handler must call MSS_UART_fill_tx_fifo() + to transfer the data to the UART. + + Receiving Data Interrupt-driven receive is performed by first calling - MSS_UART_set_rx_handler() to register a receive handler function that will be + MSS_UART_set_rx_handler() to register a receive handler function that is called by the driver whenever receive data is available. You must provide this - receive handler function which must include a call to the MSS_UART_get_rx() + receive handler function which must call the MSS_UART_get_rx() function to actually read the received data. - + ----------- UART Status ----------- - The function MSS_UART_get_rx_status() is used to read the receiver error + The function MSS_UART_get_rx_status() reads the receiver error status. This function returns the overrun, parity, framing, break, and FIFO - error status of the receiver. - The function MSS_UART_get_tx_status() is used to read the transmitter status. + error status of the receiver. + The function MSS_UART_get_tx_status() reads the transmitter status. This function returns the transmit empty (TEMT) and transmit holding register - empty (THRE) status of the transmitter. - The function MSS_UART_get_modem_status() is used to read the modem status + empty (THRE) status of the transmitter. + The function MSS_UART_get_modem_status() reads the modem status flags. This function returns the current value of the modem status register. - + -------- Loopback -------- - The MSS_UART_set_loopback() function can be used to locally loopback the Tx + The MSS_UART_set_loopback() function is used to locally loopback the Tx and Rx lines of a UART. This is not to be confused with the loopback of UART0 to UART1, which can be achieved through the microprocessor subsystem's system registers. - + *//*=========================================================================*/ #ifndef __MSS_UART_H_ #define __MSS_UART_H_ 1 @@ -326,8 +307,9 @@ extern "C" { Baud rates ========== The following definitions are used to specify standard baud rates as a - parameter to the MSS_UART_init() function. - + parameter to the MSS_UART_init(), MSS_UART_lin_init(), MSS_UART_irda_init(), + and MSS_UART_smartcard_init() functions. + | Constant | Description | |----------------------|------------------| | MSS_UART_110_BAUD | 110 baud rate | @@ -344,7 +326,7 @@ extern "C" { | MSS_UART_230400_BAUD | 230400 baud rate | | MSS_UART_460800_BAUD | 460800 baud rate | | MSS_UART_921600_BAUD | 921600 baud rate | - + */ #define MSS_UART_110_BAUD 110U #define MSS_UART_300_BAUD 300U @@ -364,16 +346,17 @@ extern "C" { /***************************************************************************//** Data Bits Length ================ - The following defines are used to build the value of the MSS_UART_init() - function line_config parameter. - + The following defines are used to build the value of the MSS_UART_init(), + MSS_UART_lin_init(), MSS_UART_irda_init(), and MSS_UART_smartcard_init() + functions line_config parameter. + | Constant | Description | |----------------------|----------------------------| | MSS_UART_DATA_5_BITS | 5 bits of data transmitted | | MSS_UART_DATA_6_BITS | 6 bits of data transmitted | | MSS_UART_DATA_7_BITS | 7 bits of data transmitted | | MSS_UART_DATA_8_BITS | 8 bits of data transmitted | - + */ #define MSS_UART_DATA_5_BITS ((uint8_t) 0x00) #define MSS_UART_DATA_6_BITS ((uint8_t) 0x01) @@ -383,9 +366,10 @@ extern "C" { /***************************************************************************//** Parity ====== - The following defines are used to build the value of the MSS_UART_init() - function line_config parameter. - + The following defines are used to build the value of the MSS_UART_init(), + MSS_UART_lin_init(), MSS_UART_irda_init(), and MSS_UART_smartcard_init() + functions line_config parameter. + | Constant | Description | |-------------------------|--------------------------| | MSS_UART_NO_PARITY | No parity | @@ -404,15 +388,16 @@ extern "C" { /***************************************************************************//** Number of Stop Bits =================== - The following defines are used to build the value of the MSS_UART_init() - function line_config parameter. - + The following defines are used to build the value of the MSS_UART_init(), + MSS_UART_lin_init(), MSS_UART_irda_init(), and MSS_UART_smartcard_init() + functions line_config parameter. + | Constant | Description | |---------------------------|--------------------------| - | MSS_UART_ONE_STOP_BIT | One stop bit | - | MSS_UART_ONEHALF_STOP_BIT | One and a half stop bits | - | MSS_UART_TWO_STOP_BITS | Two stop bits | - + | MSS_UART_ONE_STOP_BIT | One Stop bit | + | MSS_UART_ONEHALF_STOP_BIT | One and a half Stop bits | + | MSS_UART_TWO_STOP_BITS | Two Stop bits | + */ #define MSS_UART_ONE_STOP_BIT ((uint8_t) 0x00) #define MSS_UART_ONEHALF_STOP_BIT ((uint8_t) 0x04) @@ -425,8 +410,8 @@ extern "C" { These bit mask constants are used with the return value of the MSS_UART_get_rx_status() function to find out if any errors occurred while receiving data. - - + + | Constant | Description | |------------------------|--------------------------------------------| | MSS_UART_NO_ERROR | No error bit mask (0x00) | @@ -452,13 +437,13 @@ extern "C" { The following definitions are used to determine the UART transmitter status. These bit mask constants are used with the return value of the MSS_UART_get_tx_status() function to find out the status of the transmitter. - + | Constant | Description | |------------------|----------------------------------------------------| | MSS_UART_TX_BUSY | Transmitter busy (0x00) | | MSS_UART_THRE | Transmitter holding register empty bit mask (0x20) | | MSS_UART_TEMT | Transmitter empty bit mask (0x40) | - + */ #define MSS_UART_TX_BUSY ((uint8_t) 0x00) #define MSS_UART_THRE ((uint8_t) 0x20) @@ -471,7 +456,7 @@ extern "C" { mask constants are used with the return value of the MSS_UART_get_modem_status() function to find out the modem status of the UART. - + | Constant | Description | |---------------|-------------------------------------------------| | MSS_UART_DCTS | Delta clear to send bit mask (0x01) | @@ -508,8 +493,8 @@ typedef uint16_t mss_uart_irq_t; MMUART interrupts. They are used to build the value of the irq_mask parameter for the MSS_UART_enable_irq() and MSS_UART_disable_irq() functions. A bitwise OR of these constants is used to enable or disable multiple interrupts. - - + + | Constant | Description | |--------------------|---------------------------------------------------------------| | MSS_UART_RBF_IRQ | Receive Data Available Interrupt bit mask (0x001) | @@ -569,7 +554,7 @@ typedef enum { /***************************************************************************//** IrDA input / output polarity. - This enumeration specifies the RZI modem polarity for input and output signals. + This enumeration specifies the RZI modem polarity for input and output signals. This is passed as parameters in MSS_UART_irda_init() function. */ typedef enum { @@ -581,7 +566,7 @@ typedef enum { /***************************************************************************//** IrDA input / output pulse width. - This enumeration specifies the RZI modem pulse width for input and output + This enumeration specifies the RZI modem pulse width for input and output signals. This is passed as parameters in MSS_UART_irda_init() function. */ typedef enum { @@ -593,8 +578,8 @@ typedef enum { /***************************************************************************//** Tx / Rx endianess. - This enumeration specifies the MSB first or LSB first for MSS UART transmitter - and receiver. The parameter of this type shall be passed in + This enumeration specifies the MSB first or LSB first for MSS UART transmitter + and receiver. The parameter of this type shall be passed in MSS_UART_set_rx_endian()and MSS_UART_set_tx_endian() functions. */ typedef enum { @@ -606,7 +591,7 @@ typedef enum { /***************************************************************************//** Glitch filter length. - This enumeration specifies the glitch filter length. The function + This enumeration specifies the glitch filter length. The function MSS_UART_set_filter_length() accepts the parameter of this type. */ typedef enum { @@ -624,7 +609,7 @@ typedef enum { /***************************************************************************//** TXRDY and RXRDY mode. - This enumeration specifies the TXRDY and RXRDY signal modes. The function + This enumeration specifies the TXRDY and RXRDY signal modes. The function MSS_UART_set_ready_mode() accepts the parameter of this type. */ typedef enum { @@ -636,8 +621,8 @@ typedef enum { /***************************************************************************//** USART mode of operation. - This enumeration specifies the mode of operation of MSS UART when operating - as USART. The function MSS_UART_set_usart_mode() accepts the parameter of this + This enumeration specifies the mode of operation of MSS UART when operating + as USART. The function MSS_UART_set_usart_mode() accepts the parameter of this type. */ typedef enum { @@ -666,23 +651,21 @@ typedef enum { } mss_uart_num_t; /***************************************************************************//** - MSS UART instance type. - This is type definition for MSS UART instance. You need to create and + This is the type definition for MSS UART instance. You need to create and maintain a record of this type. This holds all data regarding the MSS UART - instance + instance. */ typedef struct mss_uart_instance mss_uart_instance_t; /***************************************************************************//** - Interrupt handler prototype. This typedef specifies the function prototype for MSS UART interrupt handlers. All interrupt handlers registered with the MSS UART driver must be of this type. The interrupt handlers are registered with the driver through the MSS_UART_set_rx_handler(), MSS_UART_set_tx_handler(), MSS_UART_set_rxstatus_handler(), and MSS_UART_set_modemstatus_handler() - functions. - The this_uart parameter is a pointer to either g_mss_uart0 or g_mss_uart1 to - identify the MSS UART to associate with the handler function. + functions. + The this_uart parameter is a pointer to the MMUART instance to + associate with the handler function. */ typedef void (*mss_uart_irq_handler_t)( mss_uart_instance_t * this_uart ); @@ -778,6 +761,9 @@ struct mss_uart_instance{ uint8_t lineconfig; /*!< Line configuration parameters. */ uint8_t status; /*!< Sticky line status. */ + /* Padding bytes for data alignment. */ + uint8_t padding0[2]; /*!< Padding bytes for data alignment. */ + /* transmit related info (used with interrupt driven transmit): */ const uint8_t * tx_buffer; /*!< Pointer to transmit buffer. */ uint32_t tx_buff_size; /*!< Transmit buffer size. */ @@ -801,7 +787,8 @@ struct mss_uart_instance{ mss_uart_irq_handler_t break_handler; /*!< Pointer to user registered LIN break handler. */ /* LIN sync detection interrupt handler */ mss_uart_irq_handler_t sync_handler; /*!< Pointer to user registered LIN sync detection handler. */ - uint8_t local_irq_enabled; /*!< check if local interrupt were enabled on this instance*/ + uint8_t local_irq_enabled; /*!< Check if local interrupt were enabled on this instance. */ + uint8_t padding1[7]; /*!< Padding bytes for data alignment. */ void* user_data; /*!< Pointer to user provided pointer for user specific use. */ }; @@ -827,24 +814,23 @@ extern mss_uart_instance_t g_mss_uart4_hi; /***************************************************************************//** - The MSS_UART_init() function initializes and configures one of the PolarFire SoC - MSS UARTs with the configuration passed as a parameter. The configuration - parameters are the baud_rate which is used to generate the baud value and the - line_config which is used to specify the line configuration (bit length, - stop bits and parity). - + The MSS_UART_init() function initializes and configures one of the PolarFire® + SoC MSS UARTs with the configuration passed as parameters. The configuration + parameters are the baud_rate, which generates the baud value, and + the line_config, which specifies the line configuration (bit length, + Stop bits, and parity). + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. - - Note that if you are using the UART on the AMP APB bus, the hardware + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware configuration to connect UART on AMP APB bus must already be done by the application using SYSREG registers before initializing the UART instance structure. @@ -865,40 +851,35 @@ extern mss_uart_instance_t g_mss_uart4_hi; - MSS_UART_115200_BAUD - MSS_UART_230400_BAUD - MSS_UART_460800_BAUD - - MSS_UART_921600_BAUD - + - MSS_UART_921600_BAUD Alternatively, any nonstandard baud rate can be specified by simply passing the actual required baud rate as the value for this parameter. @param line_config - The line_config parameter is the line configuration specifying the bit length, - number of stop bits and parity settings. - + The line_config parameter is the line configuration that specifies the bit + length, number of Stop bits, and parity settings. This is a bitwise OR of one value from each of the following groups of allowed values: - - One of the following to specify the transmit/receive data bit length: - - MSS_UART_DATA_5_BITS - - MSS_UART_DATA_6_BITS, - - MSS_UART_DATA_7_BITS - - MSS_UART_DATA_8_BITS - - One of the following to specify the parity setting: - - MSS_UART_NO_PARITY - - MSS_UART_EVEN_PARITY - - MSS_UART_ODD_PARITY - - MSS_UART_STICK_PARITY_0 - - MSS_UART_STICK_PARITY_1 - - One of the following to specify the number of stop bits: - - MSS_UART_ONE_STOP_BIT - - MSS_UART_ONEHALF_STOP_BIT - - MSS_UART_TWO_STOP_BITS + - One of the following to specify the transmit/receive data bit length: + - MSS_UART_DATA_5_BITS + - MSS_UART_DATA_6_BITS + - MSS_UART_DATA_7_BITS + - MSS_UART_DATA_8_BITS + - One of the following to specify the parity setting: + - MSS_UART_EVEN_PARITY + - MSS_UART_NO_PARITY + - MSS_UART_ODD_PARITY + - MSS_UART_STICK_PARITY_0 + - MSS_UART_STICK_PARITY_1 + - One of the following to specify the number of Stop bits: + - MSS_UART_ONE_STOP_BIT + - MSS_UART_ONEHALF_STOP_BIT + - MSS_UART_TWO_STOP_BITS @return This function does not return a value. - Example: + @example @code #include "mss_uart.h" @@ -907,7 +888,7 @@ extern mss_uart_instance_t g_mss_uart4_hi; MSS_UART_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT); - + return(0); } @endcode @@ -921,23 +902,22 @@ MSS_UART_init ); /***************************************************************************//** - The MSS_UART_lin_init() function is used to initialize the MSS UART for - LIN mode of operation. The configuration parameters are the baud_rate which is - used to generate the baud value and the line_config which is used to specify - the line configuration (bit length, stop bits and parity). - + The MSS_UART_lin_init() function initializes the MSS UART for + LIN mode of operation. The configuration parameters are the baud_rate, which is + used to generate the baud value, and the line_config, which specifies + the line configuration (bit length, Stop bits and parity). + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. - - Note that if you are using the UART on the AMP APB bus, the hardware + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware configuration to connect UART on AMP APB bus must already be done by the application using SYSREG registers before initializing the UART instance structure. @@ -958,40 +938,35 @@ MSS_UART_init - MSS_UART_115200_BAUD - MSS_UART_230400_BAUD - MSS_UART_460800_BAUD - - MSS_UART_921600_BAUD - + - MSS_UART_921600_BAUD Alternatively, any nonstandard baud rate can be specified by simply passing the actual required baud rate as the value for this parameter. @param line_config - The line_config parameter is the line configuration specifying the bit length, - number of stop bits and parity settings. - + The line_config parameter is the line configuration that specifies the bit + length, number of Stop bits, and parity settings. This is a bitwise OR of one value from each of the following groups of allowed values: - - One of the following to specify the transmit/receive data bit length: - - MSS_UART_DATA_5_BITS - - MSS_UART_DATA_6_BITS, - - MSS_UART_DATA_7_BITS - - MSS_UART_DATA_8_BITS - - One of the following to specify the parity setting: - - MSS_UART_NO_PARITY - - MSS_UART_EVEN_PARITY - - MSS_UART_ODD_PARITY - - MSS_UART_STICK_PARITY_0 - - MSS_UART_STICK_PARITY_1 - - One of the following to specify the number of stop bits: - - MSS_UART_ONE_STOP_BIT - - MSS_UART_ONEHALF_STOP_BIT - - MSS_UART_TWO_STOP_BITS + - One of the following to specify the transmit/receive data bit length: + - MSS_UART_DATA_5_BITS + - MSS_UART_DATA_6_BITS + - MSS_UART_DATA_7_BITS + - MSS_UART_DATA_8_BITS + - One of the following to specify the parity setting: + - MSS_UART_EVEN_PARITY + - MSS_UART_NO_PARITY + - MSS_UART_ODD_PARITY + - MSS_UART_STICK_PARITY_0 + - MSS_UART_STICK_PARITY_1 + - One of the following to specify the number of Stop bits: + - MSS_UART_ONE_STOP_BIT + - MSS_UART_ONEHALF_STOP_BIT + - MSS_UART_TWO_STOP_BITS @return This function does not return a value. - Example: + @example @code #include "mss_uart.h" @@ -1000,37 +975,35 @@ MSS_UART_init MSS_UART_lin_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT); - + return(0); } @endcode */ -void +void MSS_UART_lin_init ( - mss_uart_instance_t* this_uart, + mss_uart_instance_t* this_uart, uint32_t baud_rate, uint8_t line_config ); /***************************************************************************//** - The MSS_UART_irda_init() function is used to initialize the MSS UART instance - referenced by the parameter this_uart for IrDA mode of operation. This - function must be called before calling any other IrDA functionality specific - functions. - + The MSS_UART_irda_init() function initializes the MSS UART instance + referenced by the this_uart parameter for IrDA mode of operation. This + function must be called before calling any other IrDA specific functions. + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. - - Note that if you are using the UART on the AMP APB bus, the hardware + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware configuration to connect UART on AMP APB bus must already be done by the application using SYSREG registers before initializing the UART instance structure. @@ -1051,40 +1024,35 @@ MSS_UART_lin_init - MSS_UART_115200_BAUD - MSS_UART_230400_BAUD - MSS_UART_460800_BAUD - - MSS_UART_921600_BAUD - + - MSS_UART_921600_BAUD Alternatively, any nonstandard baud rate can be specified by simply passing the actual required baud rate as the value for this parameter. @param line_config - The line_config parameter is the line configuration specifying the bit - length, number of stop bits and parity settings. - + The line_config parameter is the line configuration that specifies the bit + length, number of Stop bits, and parity settings. This is a bitwise OR of one value from each of the following groups of allowed values: - - One of the following to specify the transmit/receive data bit length: - - MSS_UART_DATA_5_BITS - - MSS_UART_DATA_6_BITS, - - MSS_UART_DATA_7_BITS - - MSS_UART_DATA_8_BITS - - One of the following to specify the parity setting: - - MSS_UART_NO_PARITY - - MSS_UART_EVEN_PARITY - - MSS_UART_ODD_PARITY - - MSS_UART_STICK_PARITY_0 - - MSS_UART_STICK_PARITY_1 - - One of the following to specify the number of stop bits: - - MSS_UART_ONE_STOP_BIT - - MSS_UART_ONEHALF_STOP_BIT - - MSS_UART_TWO_STOP_BITS + - One of the following to specify the transmit/receive data bit length: + - MSS_UART_DATA_5_BITS + - MSS_UART_DATA_6_BITS + - MSS_UART_DATA_7_BITS + - MSS_UART_DATA_8_BITS + - One of the following to specify the parity setting: + - MSS_UART_EVEN_PARITY + - MSS_UART_NO_PARITY + - MSS_UART_ODD_PARITY + - MSS_UART_STICK_PARITY_0 + - MSS_UART_STICK_PARITY_1 + - One of the following to specify the number of Stop bits: + - MSS_UART_ONE_STOP_BIT + - MSS_UART_ONEHALF_STOP_BIT + - MSS_UART_TWO_STOP_BITS @return This function does not return a value. - Example: + @example @code MSS_UART_irda_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, @@ -1094,10 +1062,10 @@ MSS_UART_lin_init MSS_UART_3_BY_16); @endcode */ -void +void MSS_UART_irda_init ( - mss_uart_instance_t* this_uart, + mss_uart_instance_t* this_uart, uint32_t baud_rate, uint8_t line_config, mss_uart_rzi_polarity_t rxpol, @@ -1106,25 +1074,24 @@ MSS_UART_irda_init ); /***************************************************************************//** - The MSS_UART_smartcard_init() function is used to initialize the MSS UART - for ISO 7816 (smartcard) mode of operation. The configuration parameters are - the baud_rate which is used to generate the baud value and the line_config - which is used to specify the line configuration (bit length, stop bits and + The MSS_UART_smartcard_init() function initializes the MSS UART + for ISO 7816 (smartcard) mode of operation. The configuration parameters are + the baud_rate, which generates the baud value, and the line_config, + which specifies the line configuration (bit length, Stop bits and parity). This function disables all other modes of the MSS UART instance - pointed by the parameter this_uart. + pointed by the this_uart parameter. @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. - - Note that if you are using the UART on the AMP APB bus, the hardware + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware configuration to connect UART on AMP APB bus must already be done by the application using SYSREG registers before initializing the UART instance structure. @@ -1145,40 +1112,35 @@ MSS_UART_irda_init - MSS_UART_115200_BAUD - MSS_UART_230400_BAUD - MSS_UART_460800_BAUD - - MSS_UART_921600_BAUD - + - MSS_UART_921600_BAUD Alternatively, any nonstandard baud rate can be specified by simply passing the actual required baud rate as the value for this parameter. @param line_config - The line_config parameter is the line configuration specifying the bit - length, number of stop bits and parity settings. - + The line_config parameter is the line configuration that specifies the bit + length, number of Stop bits, and parity settings. This is a bitwise OR of one value from each of the following groups of allowed values: - - One of the following to specify the transmit/receive data bit length: - - MSS_UART_DATA_5_BITS - - MSS_UART_DATA_6_BITS, - - MSS_UART_DATA_7_BITS - - MSS_UART_DATA_8_BITS - - One of the following to specify the parity setting: - - MSS_UART_NO_PARITY - - MSS_UART_EVEN_PARITY - - MSS_UART_ODD_PARITY - - MSS_UART_STICK_PARITY_0 - - MSS_UART_STICK_PARITY_1 - - One of the following to specify the number of stop bits: - - MSS_UART_ONE_STOP_BIT - - MSS_UART_ONEHALF_STOP_BIT - - MSS_UART_TWO_STOP_BITS + - One of the following to specify the transmit/receive data bit length: + - MSS_UART_DATA_5_BITS + - MSS_UART_DATA_6_BITS + - MSS_UART_DATA_7_BITS + - MSS_UART_DATA_8_BITS + - One of the following to specify the parity setting: + - MSS_UART_EVEN_PARITY + - MSS_UART_NO_PARITY + - MSS_UART_ODD_PARITY + - MSS_UART_STICK_PARITY_0 + - MSS_UART_STICK_PARITY_1 + - One of the following to specify the number of Stop bits: + - MSS_UART_ONE_STOP_BIT + - MSS_UART_ONEHALF_STOP_BIT + - MSS_UART_TWO_STOP_BITS @return This function does not return a value. - Example: + @example @code #include "mss_uart.h" @@ -1187,24 +1149,24 @@ MSS_UART_irda_init MSS_UART_smartcard_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT); - + return(0); } @endcode */ -void +void MSS_UART_smartcard_init ( - mss_uart_instance_t* this_uart, + mss_uart_instance_t* this_uart, uint32_t baud_rate, uint8_t line_config ); /***************************************************************************//** - The function MSS_UART_polled_tx() is used to transmit data. It transfers the - contents of the transmitter data buffer, passed as a function parameter, into + The function MSS_UART_polled_tx() transmits data. It transfers the + content of the transmitter data buffer, passed as a function parameter, into the UART's hardware transmitter FIFO. It returns when the full content of the - transmit data buffer has been transferred to the UART's transmit FIFO. It is + transmit data buffer is transferred to the UART's transmit FIFO. It is safe to release or reuse the memory used as the transmitter data buffer once this function returns. @@ -1214,33 +1176,37 @@ MSS_UART_smartcard_init transfers data to the transmitter FIFO in blocks of 16 bytes or less and allows the FIFO to empty before transferring the next block of data. - Note: The actual transmission over the serial connection will still be + Note: The actual transmission over the serial connection is still in progress when this function returns. Use the MSS_UART_get_tx_status() function if you need to know when the transmitter is empty. - + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @param pbuff The pbuff parameter is a pointer to a buffer containing the data to - be transmitted. + transmit. @param tx_size The tx_size parameter specifies the size, in bytes, of the data to - be transmitted. + transmit. @return This function does not return a value. - Example: + @example @code #include "mss_uart.h" @@ -1253,7 +1219,7 @@ MSS_UART_smartcard_init SS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT); MSS_UART_polled_tx(&g_mss_uart0_lo, message, sizeof(message)); - + return(0); } @endcode @@ -1267,10 +1233,10 @@ MSS_UART_polled_tx ); /***************************************************************************//** - The function MSS_UART_polled_tx_string() is used to transmit a NUL ('\0') - terminated string. It transfers the text string, from the buffer starting at - the address pointed to by p_sz_string into the UART's hardware transmitter - FIFO. It returns when the complete string has been transferred to the UART's + The function MSS_UART_polled_tx_string() transmits a NULL ('\0') + terminated string. It transfers the text string, located at + the address pointed to by p_sz_string, to the UART's hardware transmitter + FIFO. It returns when the complete string is transferred to the UART's transmit FIFO. It is safe to release or reuse the memory used as the string buffer once this function returns. @@ -1280,29 +1246,33 @@ MSS_UART_polled_tx transfers data to the transmitter FIFO in blocks of 16 bytes or less and allows the FIFO to empty before transferring the next block of data. - Note: The actual transmission over the serial connection will still be + Note: The actual transmission over the serial connection is still in progress when this function returns. Use the MSS_UART_get_tx_status() function if you need to know when the transmitter is empty. - + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @param p_sz_string - The p_sz_string parameter is a pointer to a buffer containing the NUL ('\0') - terminated string to be transmitted. + The p_sz_string parameter is a pointer to a buffer containing the NULL + ('\0') terminated string to transmit. @return This function does not return a value. - Example: + @example @code #include "mss_uart.h" @@ -1313,9 +1283,9 @@ MSS_UART_polled_tx MSS_UART_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT); - + MSS_UART_polled_tx_string(&g_mss_uart0_lo, message); - + return(0); } @endcode @@ -1329,67 +1299,61 @@ MSS_UART_polled_tx_string ); /***************************************************************************//** - The function MSS_UART_irq_tx() is used to initiate an interrupt-driven - transmit. It returns immediately after making a note of the transmit buffer - location and enabling transmit interrupts both at the UART and the PolarFire - SoC Core Complex PLIC level. This function takes a pointer via the pbuff - parameter to a memory buffer containing the data to transmit. The memory - buffer specified through this pointer must remain allocated and contain the - data to transmit until the transmit completion has been detected through calls - to function MSS_UART_tx_complete(). The actual transmission over the serial - connection is still in progress until calls to the MSS_UART_tx_complete() + The function MSS_UART_irq_tx() initiates an interrupt-driven + transmit. It returns immediately after passing the transmit buffer location + to the MMUART instance and enabling transmit interrupts both at the UART and + the PolarFire® SoC Core Complex PLIC level. This function takes a pointer, + the pbuff parameter, to a memory buffer containing the data to transmit. The + memory buffer specified through this pointer must remain allocated and contain + the data to transmit until the transmit completion is detected through calling + the MSS_UART_tx_complete() function. The actual transmission over the serial + connection is still in progress until calls to the MSS_UART_tx_complete() function indicate transmit completion. Note: The MSS_UART_irq_tx() function enables both the transmit holding register empty (THRE) interrupt in the UART and the MSS UART instance - interrupt in the PolarFire SoC Core Complex PLIC as part of its implementation. - - Note: The MSS_UART_irq_tx() function assigns an internal default transmit - interrupt handler function to the UART's THRE interrupt. This interrupt - handler overrides any custom interrupt handler that you may have previously - registered using the MSS_UART_set_tx_handler() function. - - Note: The MSS_UART_irq_tx() function's default transmit interrupt - handler disables the UART's THRE interrupt when all of the data has - been transferred to the UART's transmit FIFO. - - + interrupt in the PolarFire® SoC Core Complex PLIC as part of its implementation. + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @param pbuff The pbuff parameter is a pointer to a buffer containing the data - to be transmitted. + to transmit. @param tx_size The tx_size parameter specifies the size, in bytes, of the data - to be transmitted. + to transmit. @return This function does not return a value. - Example: + @example @code #include "mss_uart.h" int main(void) { uint8_t tx_buff[10] = "abcdefghi"; - + MSS_UART_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT); - + MSS_UART_irq_tx(&g_mss_uart0_lo, tx_buff, sizeof(tx_buff)); - + while(0 == MSS_UART_tx_complete(&g_mss_uart0_lo)) { ; @@ -1416,23 +1380,27 @@ MSS_UART_irq_tx transmit FIFO and the actual transmission over the serial connection are both complete when a call to the MSS_UART_tx_complete() function indicates transmit completion. - + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @return - This function return a non-zero value if transmit has completed, otherwise - it returns zero. + This function return a non-zero value if transmit is complete, it returns + zero otherwise. - Example: + @example See the MSS_UART_irq_tx() function for an example that uses the MSS_UART_tx_complete() function. @@ -1445,20 +1413,20 @@ MSS_UART_tx_complete /***************************************************************************//** The MSS_UART_get_rx() function reads the content of the UART receiver's FIFO - and stores it in the receive buffer that is passed via the rx_buff function - parameter. It copies either the full contents of the FIFO into the receive + and stores it in the receive buffer that is passed using the rx_buff + parameter. It copies either the full content of the FIFO into the receive buffer, or just enough data from the FIFO to fill the receive buffer, - dependent upon the size of the receive buffer passed by the buff_size + depending on the size of the receive buffer passed by the buff_size parameter. The MSS_UART_get_rx() function returns the number of bytes copied - into the receive buffer .This function is non-blocking and will return 0 - immediately if no data has been received. + into the receive buffer. This function is non-blocking and returns 0 + immediately if no data is received. Note: The MSS_UART_get_rx() function reads and accumulates the receiver status of the MSS UART instance before reading each byte from the receiver's data register/FIFO. This allows the driver to maintain a sticky record of any receiver errors that occur as the UART receives each data byte; receiver errors would otherwise be lost after each read from the receiver's data - register. A call to the MSS_UART_get_rx_status() function returns any receiver + register. Calling the MSS_UART_get_rx_status() function returns any receiver errors accumulated during the execution of the MSS_UART_get_rx() function. Note: If you need to read the error status for each byte received, set @@ -1466,25 +1434,28 @@ MSS_UART_tx_complete using the MSS_UART_get_rx_status() function. The MSS_UART_get_rx() function can be used in polled mode, where it is called - at regular intervals to find out if any data has been received, or in + at regular intervals to find out if any data is received, or in interrupt driven-mode, where it is called as part of a receive handler that is called by the driver as a result of data being received. - Note: In interrupt driven mode you should call the MSS_UART_get_rx() + Note: In interrupt driven mode, call the MSS_UART_get_rx() function as part of the receive handler function that you register with - the MSS UART driver through a call to MSS_UART_set_rx_handler(). - + the MSS UART driver through calling MSS_UART_set_rx_handler(). + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. - + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @param rx_buff The rx_buff parameter is a pointer to a buffer where the received data is copied. @@ -1494,9 +1465,10 @@ MSS_UART_tx_complete @return This function returns the number of bytes that were copied into the - rx_buff buffer. It returns 0 if no data has been received. + rx_buff buffer. It returns 0 if no data is received. Polled mode example: + @example @code int main( void ) { @@ -1506,7 +1478,7 @@ MSS_UART_tx_complete MSS_UART_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT); - + while(1) { rx_size = MSS_UART_get_rx(&g_mss_uart0_lo, rx_buff, sizeof(rx_buff)); @@ -1522,17 +1494,18 @@ MSS_UART_tx_complete @endcode Interrupt driven example: + @example @code int main( void ) { MSS_UART_init(&g_mss_uart1, MSS_UART_57600_BAUD, MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT); - + MSS_UART_set_rx_handler(&g_mss_uart1, uart1_rx_handler, MSS_UART_FIFO_SINGLE_BYTE); - + while(1) { task_a(); @@ -1559,36 +1532,44 @@ MSS_UART_get_rx ); /***************************************************************************//** - The MSS_UART_set_rx_handler() function is used to register a receive handler + The MSS_UART_set_rx_handler() function registers a receive handler function that is called by the driver when a UART receive data available (RDA) interrupt occurs. You must create and register the receive handler function - to suit your application and it must include a call to the MSS_UART_get_rx() + to suit your application and it must call the MSS_UART_get_rx() function to actually read the received data. Note: The MSS_UART_set_rx_handler() function enables both the RDA - interrupt in the MSS UART instance. It also enables the corresponding - MSS UART instance interrupt in the PolarFire SoC Core Complex PLIC as part + interrupt in the MSS UART instance and in the corresponding + MSS UART instance interrupt in the PolarFire® SoC Core Complex PLIC as part of its implementation. - Note: You can disable the RDA interrupt when required by calling the + Note: You can disable the RDA interrupt when required by calling the MSS_UART_disable_irq() function. This is your choice and is dependent upon your application. + + Note: The trigger level is actually applied only if the this_uart is set + to ready mode 1. For more information, see the MSS_UART_set_ready_mode() + function. @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @param handler The handler parameter is a pointer to a receive interrupt handler function - provided by your application that will be called as a result of a UART RDA - interrupt. This handler function must be of type mss_uart_irq_handler_t. + provided by your application that is called when a UART RDA interrupt + is triggered. This handler function must be of type mss_uart_irq_handler_t. @param trigger_level The trigger_level parameter is the receive FIFO trigger level. This @@ -1598,7 +1579,7 @@ MSS_UART_get_rx @return This function does not return a value. - Example: + @example @code #include "mss_uart.h" @@ -1616,11 +1597,11 @@ MSS_UART_get_rx MSS_UART_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT); - + MSS_UART_set_rx_handler(&g_mss_uart0_lo, uart0_rx_handler, MSS_UART_FIFO_SINGLE_BYTE); - + while(1) { ; @@ -1642,32 +1623,36 @@ MSS_UART_set_rx_handler Rx lines of a UART. This is not to be confused with the loop-back of UART0 to UART1, which can be achieved through the microprocessor subsystem's system registers. - + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @param loopback - The loopback parameter indicates whether or not the UART's transmit and - receive lines should be looped back. Allowed values are as follows: + The loopback parameter indicates whether or not the UART's transmit and + receive lines should be looped back. Following are the allowed values: - MSS_UART_LOCAL_LOOPBACK_ON - - MSS_UART_LOCAL_LOOPBACK_OFF + - MSS_UART_LOCAL_LOOPBACK_OFF - MSS_UART_REMOTE_LOOPBACK_ON - - MSS_UART_REMOTE_LOOPBACK_OFF + - MSS_UART_REMOTE_LOOPBACK_OFF - MSS_UART_AUTO_ECHO_ON - MSS_UART_AUTO_ECHO_OFF - + @return This function does not return a value. - Example: + @example @code MSS_UART_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, @@ -1688,25 +1673,28 @@ MSS_UART_set_loopback by the irq_mask parameter. The irq_mask parameter identifies the MSS UART interrupts by bit position, as defined in the interrupt enable register (IER) of MSS UART. The MSS UART interrupts and their identifying irq_mask bit - positions are as follows: - When an irq_mask bit position is set to 1, this function enables the - corresponding MSS UART interrupt in the IER register. When an irq_mask bit - position is set to 0, the state of the corresponding interrupt remains - unchanged in the IER register. + positions are as follows: when an irq_mask bit position is set to 1, this + function enables the corresponding MSS UART interrupt in the IER register. + + Note: the Transmit Buffer Empty interrupt is not enabled in this API. Indeed, + enabling it here leads to an interrupt occuring before any data is passed to + the UART, causing a crash. The TBE bit in the IER register is set + in the MSS_UART_irq_tx() function, that actually starts the transmission. - Note: The MSS_UART_enable_irq() function also enables the MSS UART instance - interrupt in the PolarFire SoC Core Complex PLIC. - @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @param irq_mask The irq_mask parameter is used to select which of the MSS UART's interrupts @@ -1721,23 +1709,29 @@ MSS_UART_set_loopback - MSS_UART_PIDPE_IRQ (bit mask = 0x040) - MSS_UART_LINB_IRQ (bit mask = 0x080) - MSS_UART_LINS_IRQ (bit mask = 0x100) - + + @return This function does not return a value. - Example: + @example @code #include "mss_uart.h" int main(void) { uint8_t tx_buff[10] = "abcdefghi"; + uint32_t interrupt_priority = 4; + enable_interrupts(); + (void) mss_config_clk_rst(MSS_PERIPH_MMUART0, (uint8_t) 1, PERIPHERAL_ON); MSS_UART_init(&g_mss_uart0_lo, - MSS_UART_57600_BAUD, - MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT); - - MSS_UART_enable_irq(&g_mss_uart0_lo,(MSS_UART_RBF_IRQ | MSS_UART_TBE_IRQ)); + MSS_UART_57600_BAUD, + MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT); + PLIC_init(); + MSS_UART_enable_irq(&g_mss_uart0_lo, (MSS_UART_RBF_IRQ | MSS_UART_TBE_IRQ)); + PLIC_SetPriority(MMUART0_PLIC_77, interrupt_priority); + PLIC_SetPriority_Threshold(0); return(0); } @@ -1756,26 +1750,25 @@ MSS_UART_enable_irq by the irq_mask parameter. The irq_mask parameter identifies the MSS UART interrupts by bit position, as defined in the interrupt enable register (IER) of MSS UART. The MSS UART interrupts and their identifying bit positions are - as follows: - When an irq_mask bit position is set to 1, this function disables the - corresponding MSS UART interrupt in the IER register. When an irq_mask bit - position is set to 0, the state of the corresponding interrupt remains + as follows: when an irq_mask bit position is set to 1, this function disables + the corresponding MSS UART interrupt in the IER register. When an irq_mask bit + position is set to 0, the state of the corresponding interrupt remains unchanged in the IER register. - Note: If you disable all four of the UART's interrupts, the - MSS_UART_disable_irq() function also disables the MSS UART instance - interrupt in the PolarFire SoC Core Complex PLIC. - @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @param irq_mask The irq_mask parameter is used to select which of the MSS UART's interrupts @@ -1790,11 +1783,11 @@ MSS_UART_enable_irq - MSS_UART_PIDPE_IRQ (bit mask = 0x040) - MSS_UART_LINB_IRQ (bit mask = 0x080) - MSS_UART_LINS_IRQ (bit mask = 0x100) - + @return This function does not return a value. - Example: + @example @code #include "mss_uart.h" @@ -1821,38 +1814,42 @@ MSS_UART_disable_irq ); /***************************************************************************//** - The MSS_UART_set_pidpei_handler() function is used assign a custom interrupt - handler for the PIDPEI (PID parity error interrupt) when the MSS UART is - operating in LIN mode. + The MSS_UART_set_pidpei_handler() function assigns a custom + interrupt handler for the PIDPEI (PID parity error interrupt) when the MSS + UART is operating in LIN mode. - Note: The MSS_UART_set_pidpei_handler() function enables both the PIDPEI - interrupt in the MSS UART instance. It also enables the corresponding - MSS UART instance interrupt in the PolarFire SoC Core Complex PLIC as part of + Note: The MSS_UART_set_pidpei_handler() function enables both the PIDPEI + interrupt in the MSS UART instance and the corresponding + MSS UART instance interrupt in the PolarFire® SoC Core Complex PLIC as part of its implementation. - Note: You can disable the PIDPEI interrupt when required by calling the - MSS_UART_disable_irq() function. This is your choice and is dependent upon + Note: You can disable the PIDPEI interrupt when required by calling the + MSS_UART_disable_irq() function. This is your choice and it depends upon your application. @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @param handler - The handler parameter is the pointer to the custom handler function. - This parameter is of type mss_uart_irq_handler_t. + The handler parameter is the pointer to the custom handler function. + This parameter is of mss_uart_irq_handler_t type. @return This function does not return a value. - Example: + @example @code #include "mss_uart.h" @@ -1878,37 +1875,41 @@ MSS_UART_set_pidpei_handler ); /***************************************************************************//** - The MSS_UART_set_linbreak_handler () function is used assign a custom - interrupt handler for the LIN Break detection interrupt when the MSS UART + The MSS_UART_set_linbreak_handler () function assigns a custom + interrupt handler for the LIN Break detection interrupt when the MSS UART is operating in LIN mode. Note: The MSS_UART_set_linbreak_handler() function enables both the LIN - BREAK interrupt in the MSS UART instance. It also enables the corresponding - MSS UART instance interrupt in the PolarFire SoC Core Complex PLIC as part of + BREAK interrupt in the MSS UART instance and the corresponding + MSS UART instance interrupt in the PolarFire® SoC Core Complex PLIC as part of its implementation. - Note: You can disable the LIN BREAK interrupt when required by calling the - MSS_UART_disable_irq() function. This is your choice and is dependent upon + Note: You can disable the LIN BREAK interrupt when required by calling the + MSS_UART_disable_irq() function. This is your choice and it depends upon your application. @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @param handler - The handler parameter is the pointer to the custom handler function. - This parameter is of type mss_uart_irq_handler_t. + The handler parameter is the pointer to the custom handler function. + This parameter is of mss_uart_irq_handler_t type. @return This function does not return a value. - Example: + @example @code #include "mss_uart.h" @@ -1935,38 +1936,42 @@ MSS_UART_set_linbreak_handler ); /***************************************************************************//** - The MSS_UART_set_linsync_handler() function is used assign a custom interrupt - handler for the LIN Sync character detection interrupt when the MSS UART is - operating in LIN mode. + The MSS_UART_set_linsync_handler() function assigns a custom + interrupt handler for the LIN Sync character detection interrupt when the + MSS UART is operating in LIN mode. Note: The MSS_UART_set_linsync_handler() function enables both the LIN - SYNC interrupt in the MSS UART instance. It also enables the corresponding - MSS UART instance interrupt in the PolarFire SoC Core Complex PLIC as part of + SYNC interrupt in the MSS UART instance and the corresponding + MSS UART instance interrupt in the PolarFire® SoC Core Complex PLIC as part of its implementation. - Note: You can disable the LIN SYNC interrupt when required by calling the - MSS_UART_disable_irq() function. This is your choice and is dependent upon + Note: You can disable the LIN SYNC interrupt when required by calling the + MSS_UART_disable_irq() function. This is your choice and it depends upon your application. @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @param handler - The handler parameter is the pointer to the custom handler function. - This parameter is of type mss_uart_irq_handler_t. + The handler parameter is the pointer to the custom handler function. + This parameter is of mss_uart_irq_handler_t type. @return This function does not return a value. - - Example: + + @example @code #include "mss_uart.h" @@ -1993,38 +1998,42 @@ MSS_UART_set_linsync_handler ); /***************************************************************************//** - The MSS_UART_set_nack_handler() function is used assign a custom interrupt - handler for the NACK character detection interrupt when the MSS UART + The MSS_UART_set_nack_handler() function assigns a custom interrupt + handler for the NACK character detection interrupt when the MSS UART is operating in Smartcard mode. - Note: The MSS_UART_set_nack_handler() function enables both the NAK - interrupt in the MSS UART instance. It also enables the corresponding - MSS UART instance interrupt in the PolarFire SoC Core Complex PLIC as part of + Note: The MSS_UART_set_nack_handler() function enables both the NACK + interrupt in the MSS UART instance and the corresponding + MSS UART instance interrupt in the PolarFire® SoC Core Complex PLIC as part of its implementation. - Note: You can disable the NAK interrupt when required by calling the - MSS_UART_disable_irq() function. This is your choice and is dependent upon + Note: You can disable the NACK interrupt when required by calling the + MSS_UART_disable_irq() function. This is your choice and it depends upon your application. @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @param handler - The handler parameter is the pointer to the custom handler function. - This parameter is of type mss_uart_irq_handler_t. + The handler parameter is the pointer to the custom handler function. + This parameter is of mss_uart_irq_handler_t type. @return This function does not return a value. - - Example: + + @example @code #include "mss_uart.h" @@ -2051,38 +2060,42 @@ MSS_UART_set_nack_handler ); /***************************************************************************//** - The MSS_UART_set_rx_timeout_handler() function is used assign a custom - interrupt handler for the receiver timeout interrupt when the MSS UART is - operating in mode. It finds application in IrDA mode of operation. - - Note: The MSS_UART_set_rx_timeout_handler() function enables both the - time-out interrupt in the MSS UART instance. It also enables the corresponding - MSS UART instance interrupt in the PolarFire SoC Core Complex PLIC as part of + The MSS_UART_set_rx_timeout_handler() function assigns a custom + interrupt handler for the receiver timeout interrupt when the MSS UART is + operating in IrDA mode of operation. + + Note: The MSS_UART_set_rx_timeout_handler() function enables both the + time-out interrupt in the MSS UART instance and the corresponding + MSS UART instance interrupt in the PolarFire® SoC Core Complex PLIC as part of its implementation. - Note: You can disable the RX time-out interrupt when required by calling - the MSS_UART_disable_irq() function. This is your choice and is dependent upon + Note: You can disable the RX time-out interrupt when required by calling + the MSS_UART_disable_irq() function. This is your choice and it depends upon your application. @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @param handler - The handler parameter is the pointer to the custom handler function. + The handler parameter is the pointer to the custom handler function. This parameter is of type mss_uart_irq_handler_t. @return This function does not return a value. - - Example: + + @example @code #include "mss_uart.h" @@ -2109,41 +2122,45 @@ MSS_UART_set_rx_timeout_handler ); /***************************************************************************//** - The MSS_UART_set_rxstatus_handler() function is used to register a receiver + The MSS_UART_set_rxstatus_handler() function registers a receiver status handler function that is called by the driver when a UART receiver line status (RLS) interrupt occurs. You must create and register the handler function to suit your application. Note: The MSS_UART_set_rxstatus_handler() function enables both the RLS - interrupt in the MSS UART instance. It also enables the corresponding MSS UART - instance interrupt in the PolarFire SoC Core Complex PLIC as part of its + interrupt in the MSS UART instance and the corresponding MSS UART + instance interrupt in the PolarFire® SoC Core Complex PLIC as part of its implementation. Note: You can disable the RLS interrupt when required by calling the - MSS_UART_disable_irq() function. This is your choice and is dependent upon + MSS_UART_disable_irq() function. This is your choice and it depends upon your application. - + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @param handler - The handler parameter is a pointer to a receiver line status interrupt - handler function provided by your application that will be called as a - result of a UART RLS interrupt. This handler function must be of type - mss_uart_irq_handler_t. + The handler parameter is a pointer to a receiver line status interrupt + handler function, which is provided by your application and is called when a + UART RLS interrupt is triggered. This handler function must be of + mss_uart_irq_handler_t type. @return - This function does not return a value. + This function does not return a value. - Example: + @example @code #include "mss_uart.h" @@ -2162,7 +2179,7 @@ MSS_UART_set_rx_timeout_handler MSS_UART_init( &g_mss_uart0_lo, MSS_UART_57600_BAUD, MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT); - + MSS_UART_set_rxstatus_handler(&g_mss_uart0_lo, uart_rxsts_handler); while(1) @@ -2181,73 +2198,66 @@ MSS_UART_set_rxstatus_handler ); /***************************************************************************//** - The MSS_UART_set_tx_handler() function is used to register a transmit handler + The MSS_UART_set_tx_handler() function registers a transmit handler function that is called by the driver when a UART transmit holding register empty (THRE) interrupt occurs. You must create and register the transmit - handler function to suit your application. You can use the - MSS_UART_fill_tx_fifo() function in your transmit handler function to - write data to the transmitter. + handler function to suit your application. You can then use MSS_UART_irq_tx() + to trigger the interrupt and pass the data you want to transmit. - Note: The MSS_UART_set_tx_handler() function enables both the THRE - interrupt in the MSS UART instance. It also enables the corresponding MSS UART - instance interrupt in the PolarFire SoC Core Complex PLIC as part of its - implementation. - - - Note: You can disable the THRE interrupt when required by calling the - MSS_UART_disable_irq() function. This is your choice and is dependent upon - your application. - - Note: The MSS_UART_irq_tx() function does not use the transmit handler - function that you register with the MSS_UART_set_tx_handler() function. - It uses its own internal THRE interrupt handler function that overrides - any custom interrupt handler that you register using the - MSS_UART_set_tx_handler() function. + Note: If handler is NULL_HANDLER (or ((mss_uart_irq_handler_t)0)), the Tx + interrupt handler is the default_tx_handler(). + Note: Your alternative THRE interrupt handler must include a call to the + MSS_UART_fill_tx_fifo() function to transfer the data to the UART. + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @param handler - The handler parameter is a pointer to a transmit interrupt handler - function provided by your application that will be called as a result - of a UART THRE interrupt. This handler function must be of type - mss_uart_irq_handler_t. + The handler parameter is a pointer to a transmit interrupt handler + function provided by your application that is called when a UART THRE + interrupt is triggered. This handler function must be of + mss_uart_irq_handler_t type. If this parameter is NULL_HANDLER (or + ((mss_uart_irq_handler_t)0)), the default_tx_handler() is assigned as + the Tx interrupt handler. @return - This function does not return a value. + This function does not return a value. - Example: + @example @code #include "mss_uart.h" - uint8_t * g_tx_buffer; - size_t g_tx_size = 0; + uint8_t * g_tx_buffer = "Message from Tx irq handler"; + size_t g_tx_size = 27; void uart_tx_handler(mss_uart_instance_t * this_uart) { size_t size_in_fifo; - size_in_fifo = MSS_UART_fill_tx_fifo(this_uart, - (const uint8_t *)g_tx_buffer, - g_tx_size); - - if(size_in_fifo == g_tx_size) - { - g_tx_size = 0; - MSS_UART_disable_irq(this_uart, MSS_UART_TBE_IRQ); - } - else - { - g_tx_buffer = &g_tx_buffer[size_in_fifo]; - g_tx_size = g_tx_size - size_in_fifo; - } + const uint8_t * sub_buffer = &this_uart->tx_buffer[this_uart->tx_idx]; + uint32_t sub_buffer_size = this_uart->tx_buff_size - this_uart->tx_idx; + + ASSERT(( (uint8_t*)0 ) != this_uart->tx_buffer); + ASSERT(0u < this_uart->tx_buff_size); + + size_in_fifo = MSS_UART_fill_tx_fifo(this_uart, + sub_buffer, + sub_buffer_size); + this_uart->tx_idx += size_in_fifo; + + // Additional user code can be added here } int main(void) @@ -2262,6 +2272,7 @@ MSS_UART_set_rxstatus_handler g_tx_size = sizeof(message); MSS_UART_set_tx_handler(&g_mss_uart0_lo, uart_tx_handler); + MSS_UART_irq_tx(&g_mss_uart0_lo, g_tx_buffer, g_tx_size); while(1) { @@ -2279,41 +2290,45 @@ MSS_UART_set_tx_handler ); /***************************************************************************//** - The MSS_UART_set_modemstatus_handler() function is used to register a modem + The MSS_UART_set_modemstatus_handler() function registers a modem status handler function that is called by the driver when a UART modem status (MS) interrupt occurs. You must create and register the handler function to suit your application. Note: The MSS_UART_set_modemstatus_handler() function enables both the MS - interrupt in the MSS UART instance. It also enables the corresponding MSS UART - instance interrupt in the PolarFire SoC Core Complex PLIC as part of its + interrupt in the MSS UART instance and the corresponding MSS UART + instance interrupt in the PolarFire® SoC Core Complex PLIC as part of its implementation. Note: You can disable the MS interrupt when required by calling the - MSS_UART_disable_irq() function. This is your choice and is dependent + MSS_UART_disable_irq() function. This is your choice and it depends upon your application. - + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @param handler - The handler parameter is a pointer to a modem status interrupt handler - function provided by your application that will be called as a result - of a UART MS interrupt. This handler function must be of type - mss_uart_irq_handler_t. + The handler parameter is a pointer to a modem status interrupt handler + function provided by your application that is called when a UART MS + interrupt is triggered. This handler function must be of type + mss_uart_irq_handler_t. @return - This function does not return a value. + This function does not return a value. - Example: + @example @code #include "mss_uart.h" @@ -2353,12 +2368,12 @@ MSS_UART_set_modemstatus_handler /***************************************************************************//** The MSS_UART_fill_tx_fifo() function fills the UART's hardware transmitter - FIFO with the data found in the transmitter buffer that is passed via the + FIFO with the data found in the transmitter buffer that is passed using the tx_buffer function parameter. If the transmitter FIFO is not empty when the function is called, the function returns immediately without transferring any data to the FIFO; otherwise, the function transfers data from the - transmitter buffer to the FIFO until it is full or until the complete - contents of the transmitter buffer have been copied into the FIFO. The + transmitter buffer to the FIFO until it is filled or until the full + content of the transmitter buffer is copied into the FIFO. The function returns the number of bytes copied into the UART's transmitter FIFO. Note: This function reads the UART's line status register (LSR) to check @@ -2371,21 +2386,25 @@ MSS_UART_set_modemstatus_handler Note: The actual transmission over the serial connection will still be in progress when this function returns. Use the MSS_UART_get_tx_status() function if you need to know when the transmitter is empty. - + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @param tx_buffer The tx_buffer parameter is a pointer to a buffer containing the data - to be transmitted. + to transmit. @param tx_size The tx_size parameter is the size in bytes, of the data to be transmitted. @@ -2394,7 +2413,7 @@ MSS_UART_set_modemstatus_handler This function returns the number of bytes copied into the UART's transmitter FIFO. - Example: + @example @code void send_using_interrupt(uint8_t * pbuff, size_t tx_size) { @@ -2433,21 +2452,25 @@ MSS_UART_fill_tx_fifo result in the driver losing receiver errors. To avoid any loss of receiver errors, the transmit functions also update the driver's sticky record of the cumulative receiver error status whenever they read the LSR. - + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @return This function returns the UART's receiver error status as an 8-bit unsigned - integer. The returned value is 0 if no receiver errors occurred. The driver + integer. The returned value is 0, if no receiver errors occurred. The driver provides a set of bit mask constants that should be compared with and/or used to mask the returned value to determine the receiver error status. When the return value is compared to the following bit masks, a non-zero @@ -2456,16 +2479,16 @@ MSS_UART_fill_tx_fifo - MSS_UART_PARITY_ERROR (bit mask = 0x04) - MSS_UART_FRAMING_ERROR (bit mask = 0x08) - MSS_UART_BREAK_ERROR (bit mask = 0x10) - - MSS_UART_FIFO_ERROR (bit mask = 0x80) - + - MSS_UART_FIFO_ERROR (bit mask = 0x80) + When the return value is compared to the following bit mask, a non-zero result indicates that no error occurred: - - MSS_UART_NO_ERROR (bit mask = 0x00) - + - MSS_UART_NO_ERROR (bit mask = 0x00) + Upon unsuccessful execution, this function returns: - MSS_UART_INVALID_PARAM (bit mask = 0xFF) - Example: + @example @code uint8_t rx_data[MAX_RX_DATA_SIZE]; uint8_t err_status; @@ -2486,22 +2509,26 @@ MSS_UART_get_rx_status /***************************************************************************//** The MSS_UART_get_modem_status() function returns the modem status of the MSS UART instance. It reads the modem status register (MSR) and returns - the 8 bit value. The bit encoding of the returned value is exactly the + the 8-bit value. The bit encoding of the returned value is exactly the same as the definition of the bits in the MSR. - + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @return - This function returns current state of the UART's MSR as an 8 bit + This function returns current state of the UART's MSR as an 8-bit unsigned integer. The driver provides the following set of bit mask constants that should be compared with and/or used to mask the returned value to determine the modem status: @@ -2514,7 +2541,7 @@ MSS_UART_get_rx_status - MSS_UART_RI (bit mask = 0x40) - MSS_UART_DCD (bit mask = 0x80) - Example: + @example @code void uart_modem_status_isr(mss_uart_instance_t * this_uart) { @@ -2542,35 +2569,39 @@ MSS_UART_get_modem_status MSS UART instance. It reads both the UART's line status register (LSR) and returns the status of the transmit holding register empty (THRE) and transmitter empty (TEMT) bits. - + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @return This function returns the UART's transmitter status as an 8-bit unsigned - integer. The returned value is 0 if the transmitter status bits are not + integer. The returned value is 0, if the transmitter status bits are not set or the function execution failed. The driver provides a set of bit mask constants that should be compared with and/or used to mask the returned value to determine the transmitter status. When the return value is compared to the following bit mask, a non-zero result indicates that the corresponding transmitter status bit is set: - MSS_UART_THRE (bit mask = 0x20) - - MSS_UART_TEMT (bit mask = 0x40) - + - MSS_UART_TEMT (bit mask = 0x40) + When the return value is compared to the following bit mask, a non-zero result indicates that the transmitter is busy or the function execution - failed. + failed: - MSS_UART_TX_BUSY (bit mask = 0x00) - Example: + @example @code uint8_t tx_buff[10] = "abcdefghi"; MSS_UART_init(&g_mss_uart0_lo, @@ -2592,30 +2623,34 @@ MSS_UART_get_tx_status ); /***************************************************************************//** - The MSS_UART_set_break() function is used to send the break - (9 zeros after stop bit) signal on the TX line. This function can be used + The MSS_UART_set_break() function sends the break + (9 zeros after Stop bit) signal on the Tx line. This function can be used only when the MSS UART is initialized in LIN mode by using MSS_UART_lin_init(). - + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @return - This function does not return a value. + This function does not return a value. - Example: + @example @code MSS_UART_lin_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT); - + MSS_UART_set_break(&g_mss_uart0); @endcode */ @@ -2626,25 +2661,29 @@ MSS_UART_set_break ); /***************************************************************************//** - The MSS_UART_clear_break() function is used to remove the break signal on the - TX line. This function can be used only when the MSS UART is initialized in + The MSS_UART_clear_break() function removes the break signal on the + Tx line. This function can be used only when the MSS UART is initialized in LIN mode by using MSS_UART_lin_init(). - + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @return - This function does not return a value. + This function does not return a value. - Example: + @example @code MSS_UART_lin_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, @@ -2660,25 +2699,29 @@ MSS_UART_clear_break ); /***************************************************************************//** - The MSS_UART_enable_half_duplex() function is used to enable the half-duplex - (single wire) mode for the MSS UART. Though it finds application in Smartcard + The MSS_UART_enable_half_duplex() function enables the half-duplex + (single wire) mode for the MSS UART. Though it finds application in Smartcard mode, half-duplex mode can be used in other modes as well. - + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @return This function does not return a value. - Example: + @example @code MSS_UART_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, @@ -2687,32 +2730,36 @@ MSS_UART_clear_break MSS_UART_enable_half_duplex(&g_mss_uart0_lo); @endcode */ -void +void MSS_UART_enable_half_duplex ( mss_uart_instance_t * this_uart ); /***************************************************************************//** - The MSS_UART_disable_half_duplex() function is used to disable the half-duplex - (single wire) mode for the MSS UART. Though it finds application in Smartcard + The MSS_UART_disable_half_duplex() function disables the half-duplex + (single wire) mode for the MSS UART. Though it finds application in Smartcard mode, half-duplex mode can be used in other modes as well. - + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @return This function does not return a value. - Example: + @example @code MSS_UART_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, @@ -2721,35 +2768,41 @@ MSS_UART_enable_half_duplex MSS_UART_disable_half_duplex(&g_mss_uart0_lo); @endcode */ -void +void MSS_UART_disable_half_duplex ( mss_uart_instance_t * this_uart ); /***************************************************************************//** - The MSS_UART_set_rx_endian() function is used to configure the LSB first or - MSB first setting for MSS UART receiver - + The MSS_UART_set_rx_endian() function configures the LSB first or + MSB first setting for MSS UART receiver. + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @param endian - The endian parameter tells the LSB first or MSB first configuration. - This parameter is of type mss_uart_endian_t. + The endian parameter tells if the LSB or MSB is received first. + This parameter is of type mss_uart_endian_t. The allowed values are: + - MSS_UART_LITTLEEND + - MSS_UART_BIGEND @return This function does not return a value. - Example: + @example @code MSS_UART_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, @@ -2762,32 +2815,38 @@ void MSS_UART_set_rx_endian ( mss_uart_instance_t * this_uart, - mss_uart_endian_t endian + mss_uart_endian_t endian ); /***************************************************************************//** - The MSS_UART_set_tx_endian() function is used to configure the LSB first or + The MSS_UART_set_tx_endian() function configures the LSB first or MSB first setting for MSS UART transmitter. - + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @param endian - The endian parameter tells the LSB first or MSB first configuration. - This parameter is of type mss_uart_endian_t. + The endian parameter tells if the LSB or MSB is transmitted first. + This parameter is of type mss_uart_endian_t. The allowed values are: + - MSS_UART_LITTLEEND + - MSS_UART_BIGEND @return This function does not return a value. - Example: + @example @code MSS_UART_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, @@ -2800,33 +2859,37 @@ void MSS_UART_set_tx_endian ( mss_uart_instance_t * this_uart, - mss_uart_endian_t endian + mss_uart_endian_t endian ); /***************************************************************************//** - The MSS_UART_set_filter_length () function is used to configure the glitch - filter length of the MSS UART. This should be configured in accordance with + The MSS_UART_set_filter_length() function configures the glitch + filter length of the MSS UART. This should be configured in accordance with the chosen baud rate. - + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @param length - The length parameter is of mss_uart_filter_length_t type that determines + The length parameter is of mss_uart_filter_length_t type and it determines the length of the glitch filter. @return This function does not return a value. - Example: + @example @code MSS_UART_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, @@ -2843,24 +2906,28 @@ MSS_UART_set_filter_length ); /***************************************************************************//** - The MSS_UART_enable_afm() function is used to enable address flag detection - mode of the MSS UART - + The MSS_UART_enable_afm() function enables address flag detection + mode of the MSS UART. + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @return This function does not return a value. - Example: + @example @code MSS_UART_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, @@ -2876,21 +2943,20 @@ MSS_UART_enable_afm ); /***************************************************************************//** - The MSS_UART_disable_afm() function is used to disable address flag detection + The MSS_UART_disable_afm() function disables address flag detection mode of the MSS UART. - + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. - - Note that if you are using the UART on the AMP APB bus, the hardware + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware configuration to connect UART on AMP APB bus must already be done by the application using SYSREG registers before initializing the UART instance structure. @@ -2898,7 +2964,7 @@ MSS_UART_enable_afm @return This function does not return a value. - Example: + @example @code MSS_UART_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, @@ -2914,25 +2980,29 @@ MSS_UART_disable_afm ); /***************************************************************************//** - The MSS_UART_enable_afclear () function is used to enable address flag clear - of the MSS UART. This should be used in conjunction with address flag + The MSS_UART_enable_afclear() function enables address flag clear + of the MSS UART. This should be used in conjunction with address flag detection mode (AFM). - + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @return This function does not return a value. - Example: + @example @code MSS_UART_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, @@ -2948,30 +3018,29 @@ MSS_UART_enable_afclear ); /***************************************************************************//** - The MSS_UART_disable_afclear () function is used to disable address flag - clear of the MSS UART. This should be used in conjunction with address flag + The MSS_UART_disable_afclear() function disables address flag + clear of the MSS UART. This should be used in conjunction with address flag detection mode (AFM). - + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. - - Note that if you are using the UART on the AMP APB bus, the hardware + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware configuration to connect UART on AMP APB bus must already be done by the application using SYSREG registers before initializing the UART instance structure. @return This function does not return a value. - - Example: + + @example @code MSS_UART_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, @@ -2987,30 +3056,34 @@ MSS_UART_disable_afclear ); /***************************************************************************//** - The MSS_UART_enable_rx_timeout() function is used to enable and configure - the receiver timeout functionality of MSS UART. This function accepts the - timeout parameter and applies the timeout based up on the baud rate as per + The MSS_UART_enable_rx_timeout() function enables and configures + the receiver timeout functionality of MSS UART. This function accepts the + timeout parameter and applies the timeout based up on the baud rate as per the formula 4 x timeout x bit time. - + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @param timeout - The timeout parameter specifies the receiver timeout multiple. + The timeout parameter specifies the receiver timeout multiple. It should be configured according to the baud rate in use. @return This function does not return a value. - Example: + @example @code MSS_UART_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, @@ -3019,7 +3092,7 @@ MSS_UART_disable_afclear MSS_UART_enable_rx_timeout(&g_mss_uart0_lo, 24); @endcode */ -void +void MSS_UART_enable_rx_timeout ( mss_uart_instance_t * this_uart, @@ -3027,21 +3100,20 @@ MSS_UART_enable_rx_timeout ); /***************************************************************************//** - The MSS_UART_disable_rx_timeout() function is used to disable the receiver - timeout functionality of MSS UART. - + The MSS_UART_disable_rx_timeout() function disables the receiver + timeout functionality of MSS UART. + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. - - Note that if you are using the UART on the AMP APB bus, the hardware + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware configuration to connect UART on AMP APB bus must already be done by the application using SYSREG registers before initializing the UART instance structure. @@ -3049,7 +3121,7 @@ MSS_UART_enable_rx_timeout @return This function does not return a value. - Example: + @example @code MSS_UART_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, @@ -3058,42 +3130,41 @@ MSS_UART_enable_rx_timeout MSS_UART_disable_rx_timeout(&g_mss_uart0_lo); @endcode */ -void +void MSS_UART_disable_rx_timeout ( mss_uart_instance_t * this_uart ); /***************************************************************************//** - The MSS_UART_enable_tx_time_guard() function is used to enable and configure - the transmitter time guard functionality of MSS UART. This function accepts - the timeguard parameter and applies the timeguard based up on the baud rate + The MSS_UART_enable_tx_time_guard() function enables and configures + the transmitter timeguard functionality of MSS UART. This function accepts + the timeguard parameter and applies the timeguard based on the baud rate as per the formula timeguard x bit time. - + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. - - Note that if you are using the UART on the AMP APB bus, the hardware + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware configuration to connect UART on AMP APB bus must already be done by the application using SYSREG registers before initializing the UART instance structure. @param timeguard - The timeguard parameter specifies the transmitter time guard multiple. + The timeguard parameter specifies the transmitter timeguard multiple. It should be configured according to the baud rate in use. @return This function does not return a value. - Example: + @example @code MSS_UART_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, @@ -3102,7 +3173,7 @@ MSS_UART_disable_rx_timeout MSS_UART_enable_tx_time_guard(&g_mss_uart0_lo, 24); @endcode */ -void +void MSS_UART_enable_tx_time_guard ( mss_uart_instance_t * this_uart, @@ -3110,21 +3181,20 @@ MSS_UART_enable_tx_time_guard ); /***************************************************************************//** - The MSS_UART_disable_tx_time_guard() function is used to disable the - transmitter time guard functionality of MSS UART. - + The MSS_UART_disable_tx_time_guard() function disables the + transmitter timeguard functionality of MSS UART. + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. - - Note that if you are using the UART on the AMP APB bus, the hardware + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware configuration to connect UART on AMP APB bus must already be done by the application using SYSREG registers before initializing the UART instance structure. @@ -3132,49 +3202,53 @@ MSS_UART_enable_tx_time_guard @return This function does not return a value. - Example: + @example @code MSS_UART_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT); - + MSS_UART_disable_tx_time_guard(&g_mss_uart0_lo); @endcode */ -void +void MSS_UART_disable_tx_time_guard ( mss_uart_instance_t * this_uart ); /***************************************************************************//** - The MSS_UART_set_address() function is used to set the 8-bit address for - the MSS UART referenced by this_uart parameter. - + The MSS_UART_set_address() function sets the 8-bit address for + the MSS UART, which is referenced by this_uart parameter. + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @param address - The address parameter is the 8-bit address which is to be configured - to the MSS UART referenced by this_uart parameter. + The address parameter is the 8-bit address allocated + to the MSS UART, which is referenced by this_uart parameter. @return This function does not return a value. - Example: + @example @code MSS_UART_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT); - + MSS_UART_set_address(&g_mss_uart0_lo, 0xAA); @endcode */ @@ -3186,29 +3260,40 @@ MSS_UART_set_address ); /***************************************************************************//** - The MSS_UART_set_ready_mode() function is used to configure the MODE0 or MODE1 - to the TXRDY and RXRDY signals of the MSS UART referenced by this_uart - parameter. The mode parameter is used to provide the mode to be configured. - + The MSS_UART_set_ready_mode() function configures the MODE0 or MODE1 + to the TXRDY and RXRDY signals of the MSS UART, which is referenced by + this_uart parameter. The mode parameter is used to provide the mode to be + configured. See the following details for the MODE0 and MODE1 description. + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @param mode - The mode parameter is the mss_uart_ready_mode_t type which is used to - configure the TXRDY and RXRDY signal modes. + The mode parameter is the mss_uart_ready_mode_t type which is used to + configure the TXRDY and RXRDY signal modes. + MODE0: RXRDY goes high (active) when there is at least one character + in the RX FIFO (that is, the RDA is triggered when there is at least one + character in the RX FIFO). TXRDY goes inactive after the first character is + loaded in the Tx FIFO. + MODE1: RXRDY goes high (active) when the trigger level or the timeout is + reached. TXRDY goes inactive when the Tx FIFO is completely full. @return This function does not return a value. - Example: + @example @code MSS_UART_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, @@ -3217,38 +3302,47 @@ MSS_UART_set_address MSS_UART_set_ready_mode(&g_mss_uart0_lo, MSS_UART_READY_MODE0); @endcode */ -void +void MSS_UART_set_ready_mode ( mss_uart_instance_t * this_uart, - mss_uart_ready_mode_t mode + mss_uart_ready_mode_t mode ); /***************************************************************************//** - The MSS_UART_set_usart_mode() function is used to configure the MSS UART - referenced by the parameter this_uart in USART mode. Various USART modes - are supported which can be configured by the parameter mode of type - mss_uart_usart_mode_t. - + The MSS_UART_set_usart_mode() function configures the MSS UART, which is + referenced by the this_uart parameter in USART mode. Various USART modes + are supported which can be configured by the parameter mode of + mss_uart_usart_mode_t type. + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @param mode - The mode parameter is the USART mode to be configured. - This parameter is of type mss_uart_usart_mode_t. + The mode parameter is the USART mode to be configured. + This parameter is of mss_uart_usart_mode_t type. The allowed values are: + - MSS_UART_ASYNC_MODE + - MSS_UART_SYNC_SLAVE_POS_EDGE_CLK + - MSS_UART_SYNC_SLAVE_NEG_EDGE_CLK + - MSS_UART_SYNC_MASTER_POS_EDGE_CLK + - MSS_UART_SYNC_MASTER_NEG_EDGE_CLK @return This function does not return a value. - Example: + @example @code MSS_UART_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, @@ -3257,7 +3351,7 @@ MSS_UART_set_ready_mode MSS_UART_set_usart_mode(&g_mss_uart0_lo, MSS_UART_SYNC_MASTER_POS_EDGE_CLK); @endcode */ -void +void MSS_UART_set_usart_mode ( mss_uart_instance_t * this_uart, @@ -3265,47 +3359,47 @@ MSS_UART_set_usart_mode ); /***************************************************************************//** - The MSS_UART_enable_local_irq() function is used to enable the MMUART - interrupt as a local interrupt to the hart rather than via PLIC. - MMUART interrupt can be configured to trigger an interrupt via PLIC or it + The MSS_UART_enable_local_irq() function enables the MMUART + interrupt as a local interrupt to the hart rather than as a PLIC interrupt. + MMUART interrupt can be configured to trigger a PLIC interrupt or it can be configured to trigger a local interrupt. The arrangement is such that the UART0 interrupt can appear as local interrupt on E51. The UART1 to UART4 - interrupts can appear as local interrupt to U51_1 to U54_4 respectively. - The UART0 to UART4 can appear as PLIC interrupt. Multiple HARTs can enable - and receive the PLIC interrupt, the HART that claims the interrupt processes - it. For rest of the HARTs the IRQ gets silently skipped as the interrupt - claim has already been taken. - - By default, the PLIC interrupt is enabled by this driver when - MSS_UART_enable_irq() or the APIs to set the interrupt handler is called. - To enable the local interrupt application must explicitly call + interrupts can appear as local interrupt to U51_1 to U54_4, respectively. + The UART0 to UART4 can appear as PLIC interrupt. Multiple harts can enable + and receive the PLIC interrupt, the hart that claims the interrupt processes + it. For rest of the harts, the IRQ gets silently skipped as the interrupt + claim has already been taken. + To enable the local interrupt, application must explicitly call MSS_UART_enable_local_irq() function. Note that this function disables the - interrupt over PLIC if it was previously enabled. - + interrupt over PLIC if it was previously enabled. This function must be called after the MMUART is initialized, the required - interrupt hander functions are set and before initiating any data transfers. - If you want to register multiple register handlers such as tx handler, rx - handler etc. then this function must be called after all such handlers are set. - + interrupt handler functions are set and before initiating any data transfers. + If you want to register multiple interrupt handlers such as Tx handler, rx + handler and so on, then this function must be called after all such handlers + are set. Call to this function is treated as one time activity. The driver gives no option to disable the local interrupt and enable the PLIC interrupt again at runtime. - + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @return This function does not return a value. - Example: + @example @code diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/drivers/mss/mss_mmuart/mss_uart_regs.h b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/drivers/mss/mss_mmuart/mss_uart_regs.h index d550810..7a556a0 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/drivers/mss/mss_mmuart/mss_uart_regs.h +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/drivers/mss/mss_mmuart/mss_uart_regs.h @@ -1,10 +1,13 @@ - /******************************************************************************* - * Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions. +/******************************************************************************* + * Copyright 2019 Microchip FPGA Embedded Systems Solutions. * * SPDX-License-Identifier: MIT - * - * Register bit offsets and masks definitions for PolarFire SoC MSS MMUART - * + * + * @file mss_uart_regs.h + * @author Microchip FPGA Embedded Systems Solutions + * @brief Register bit offsets and masks definitions for PolarFire SoC + * Microprocessor Subsystem (MSS) MMUART + * */ #ifndef MSS_UART_REGS_H_ diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/common/mss_l2_cache.c b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/common/mss_l2_cache.c index af4b00e..a41e1d8 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/common/mss_l2_cache.c +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/common/mss_l2_cache.c @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright 2019-2022 Microchip FPGA Embedded Systems Solutions. + * Copyright 2019-2023 Microchip FPGA Embedded Systems Solutions. * * SPDX-License-Identifier: MIT * @@ -36,14 +36,53 @@ static const uint64_t g_init_marker = INIT_MARKER; */ static void check_config_l2_scratchpad(void); +/***************************************************************************//** + * See hw_l2_scratch.h for details of how to use this function. + */ +__attribute__((weak)) uint64_t end_l2_scratchpad_address(void) +{ + return (uint64_t)(ZERO_DEVICE_BOTTOM + (LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS + * WAY_BYTE_LENGTH)); +} -/*============================================================================== - * This code should only be executed from E51 to be functional. - * Configure the L2 cache memory: - * - Set the number of cache ways used as cache based on the MSS Configurator - * settings. - * - Configure some of the enabled ways as scratchpad based on linker - * configuration and space allocated by configurator. +/***************************************************************************//** + * See hw_l2_scratch.h for details of how to use this function. + */ +__attribute__((weak)) uint32_t num_cache_ways(void) +{ + static_assert(LIBERO_SETTING_WAY_ENABLE > + LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS, + "Invalid way configuration"); + return (uint64_t)((LIBERO_SETTING_WAY_ENABLE + 1U) - + LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS); +} + +/***************************************************************************//** + * See hw_l2_scratch.h for details of how to use this function. + */ +__attribute__((weak)) uint32_t my_num_cache_ways(void) +{ + uint32_t num_ways = 0U; + uint32_t way_enable; + uint32_t bit_index; + + //todo: return for my hart, assuming e51 here + way_enable = (uint32_t)LIBERO_SETTING_WAY_MASK_E51_DCACHE; + bit_index = 0U; + + while(bit_index < 16U) + { + if( way_enable & (1U<WAY_ENABLE = LIBERO_SETTING_WAY_ENABLE; + __atomic_store_8 (&CACHE_CTRL->WAY_ENABLE , LIBERO_SETTING_WAY_ENABLE, __ATOMIC_RELAXED); /* * shutdown L2 as directed */ SYSREG->L2_SHUTDOWN_CR = LIBERO_SETTING_L2_SHUTDOWN_CR; - /* The scratchpad has already been set-up, first check enough space before copying */ + /* The scratchpad has already been set-up, first check enough space before + * copying */ check_config_l2_scratchpad(); /* If you are not using scratchpad, no need to include the following code */ - static_assert(LIBERO_SETTING_WAY_ENABLE >= LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS, "Scratchpad Missing"); + static_assert(LIBERO_SETTING_WAY_ENABLE >= + LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS, "Scratchpad Missing"); /* - * Compute the mask (In HSS CONFIG_SERVICE_SCRUB=y) used to specify ways that will be used by the - * scratchpad. + * Compute the mask (In HSS CONFIG_SERVICE_SCRUB=y) used to specify ways + * that will be used by the scratchpad */ uint32_t scratchpad_ways_mask = 0U; @@ -111,20 +152,22 @@ __attribute__((weak)) void config_l2_cache(void) /* * Setup all masters, apart from one we are using to setup scratch */ - CACHE_CTRL->WAY_MASK_DMA = LIBERO_SETTING_WAY_MASK_DMA; - CACHE_CTRL->WAY_MASK_AXI4_SLAVE_PORT_0 = LIBERO_SETTING_WAY_MASK_AXI4_PORT_0; - CACHE_CTRL->WAY_MASK_AXI4_SLAVE_PORT_1 = LIBERO_SETTING_WAY_MASK_AXI4_PORT_1; - CACHE_CTRL->WAY_MASK_AXI4_SLAVE_PORT_2 = LIBERO_SETTING_WAY_MASK_AXI4_PORT_2; - CACHE_CTRL->WAY_MASK_AXI4_SLAVE_PORT_3 = LIBERO_SETTING_WAY_MASK_AXI4_PORT_3; - CACHE_CTRL->WAY_MASK_E51_ICACHE = LIBERO_SETTING_WAY_MASK_E51_ICACHE; - CACHE_CTRL->WAY_MASK_U54_1_DCACHE = LIBERO_SETTING_WAY_MASK_U54_1_DCACHE; - CACHE_CTRL->WAY_MASK_U54_1_ICACHE = LIBERO_SETTING_WAY_MASK_U54_1_ICACHE; - CACHE_CTRL->WAY_MASK_U54_2_DCACHE = LIBERO_SETTING_WAY_MASK_U54_2_DCACHE; - CACHE_CTRL->WAY_MASK_U54_2_ICACHE = LIBERO_SETTING_WAY_MASK_U54_2_ICACHE; - CACHE_CTRL->WAY_MASK_U54_3_DCACHE = LIBERO_SETTING_WAY_MASK_U54_3_DCACHE; - CACHE_CTRL->WAY_MASK_U54_3_ICACHE = LIBERO_SETTING_WAY_MASK_U54_3_ICACHE; - CACHE_CTRL->WAY_MASK_U54_4_DCACHE = LIBERO_SETTING_WAY_MASK_U54_4_DCACHE; - CACHE_CTRL->WAY_MASK_U54_4_ICACHE = LIBERO_SETTING_WAY_MASK_U54_4_ICACHE; + + __atomic_store_8 (&CACHE_CTRL->WAY_MASK_DMA , LIBERO_SETTING_WAY_MASK_DMA, __ATOMIC_RELAXED); + __atomic_store_8 (&CACHE_CTRL->WAY_MASK_AXI4_SLAVE_PORT_0 , LIBERO_SETTING_WAY_MASK_AXI4_PORT_0, __ATOMIC_RELAXED); + __atomic_store_8 (&CACHE_CTRL->WAY_MASK_AXI4_SLAVE_PORT_1 , LIBERO_SETTING_WAY_MASK_AXI4_PORT_1, __ATOMIC_RELAXED); + __atomic_store_8 (&CACHE_CTRL->WAY_MASK_AXI4_SLAVE_PORT_2 , LIBERO_SETTING_WAY_MASK_AXI4_PORT_2, __ATOMIC_RELAXED); + __atomic_store_8 (&CACHE_CTRL->WAY_MASK_AXI4_SLAVE_PORT_3 , LIBERO_SETTING_WAY_MASK_AXI4_PORT_3, __ATOMIC_RELAXED); + __atomic_store_8 (&CACHE_CTRL->WAY_MASK_E51_ICACHE , LIBERO_SETTING_WAY_MASK_E51_ICACHE, __ATOMIC_RELAXED); + __atomic_store_8 (&CACHE_CTRL->WAY_MASK_U54_1_DCACHE , LIBERO_SETTING_WAY_MASK_U54_1_DCACHE, __ATOMIC_RELAXED); + __atomic_store_8 (&CACHE_CTRL->WAY_MASK_U54_1_ICACHE , LIBERO_SETTING_WAY_MASK_U54_1_ICACHE, __ATOMIC_RELAXED); + __atomic_store_8 (&CACHE_CTRL->WAY_MASK_U54_2_DCACHE , LIBERO_SETTING_WAY_MASK_U54_2_DCACHE, __ATOMIC_RELAXED); + __atomic_store_8 (&CACHE_CTRL->WAY_MASK_U54_2_ICACHE , LIBERO_SETTING_WAY_MASK_U54_2_ICACHE, __ATOMIC_RELAXED); + __atomic_store_8 (&CACHE_CTRL->WAY_MASK_U54_3_DCACHE , LIBERO_SETTING_WAY_MASK_U54_3_DCACHE, __ATOMIC_RELAXED); + __atomic_store_8 (&CACHE_CTRL->WAY_MASK_U54_3_ICACHE , LIBERO_SETTING_WAY_MASK_U54_3_ICACHE, __ATOMIC_RELAXED); + __atomic_store_8 (&CACHE_CTRL->WAY_MASK_U54_4_DCACHE , LIBERO_SETTING_WAY_MASK_U54_4_DCACHE, __ATOMIC_RELAXED); + __atomic_store_8 (&CACHE_CTRL->WAY_MASK_U54_4_ICACHE , LIBERO_SETTING_WAY_MASK_U54_4_ICACHE, __ATOMIC_RELAXED); + #if (LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS != 0) /* @@ -133,19 +176,21 @@ __attribute__((weak)) void config_l2_cache(void) uint64_t * p_scratchpad = (uint64_t *)ZERO_DEVICE_BOTTOM; uint32_t ways_inc; uint64_t current_way = 0x1U << (((LIBERO_SETTING_WAY_ENABLE + 1U) - LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS) ); + for(ways_inc = 0; ways_inc < LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS; ++ways_inc) { /* * Populate the scratchpad memory one way at a time. */ - CACHE_CTRL->WAY_MASK_E51_DCACHE = current_way; + __atomic_store_8 (&CACHE_CTRL->WAY_MASK_E51_DCACHE, current_way, __ATOMIC_RELAXED); mb(); /* * Write to the first 64-bit location of each cache block. */ for(inc = 0; inc < (WAY_BYTE_LENGTH / CACHE_BLOCK_BYTE_LENGTH); ++inc) { - *p_scratchpad = g_init_marker + inc; + + *p_scratchpad = g_init_marker /* + inc */; p_scratchpad += CACHE_BLOCK_BYTE_LENGTH / UINT64_BYTE_LENGTH; } current_way = current_way << 1U; @@ -155,9 +200,8 @@ __attribute__((weak)) void config_l2_cache(void) /* * Prevent E51 from evicting from scratchpad ways. */ - CACHE_CTRL->WAY_MASK_E51_DCACHE = LIBERO_SETTING_WAY_MASK_E51_DCACHE; + __atomic_store_8 (&CACHE_CTRL->WAY_MASK_E51_DCACHE , LIBERO_SETTING_WAY_MASK_E51_DCACHE, __ATOMIC_RELAXED); mb(); - } diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/common/mss_l2_cache.h b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/common/mss_l2_cache.h index d25bb15..4d92ec4 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/common/mss_l2_cache.h +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/common/mss_l2_cache.h @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright 2019-2022 Microchip FPGA Embedded Systems Solutions. + * Copyright 2019-2023 Microchip FPGA Embedded Systems Solutions. * * SPDX-License-Identifier: MIT * @@ -522,9 +522,61 @@ typedef struct { #define CACHE_CTRL ((volatile CACHE_CTRL_typedef *) CACHE_CTRL_BASE) + +/***************************************************************************//** + The end_l2_scratchpad_address() function is used to return the end address of + the initialised scratchpad. It is used in the startup code. + + @return + This end address of the allocated scratchpad. + + Example: + @code + // When called from assembly + call config_l2_cache + call end_l2_scratchpad_address # end address returned in a0 + call .clear_scratchpad + @endcode + */ +uint64_t end_l2_scratchpad_address(void); + +/***************************************************************************//** + The config_l2_cache() function is used to setup scratchpad. It will be used by + bootloader. e.g. Hart Software Services (HSS) + This code should only be executed from E51 to be functional. + Configure the L2 cache memory: + - Set the number of cache ways used as cache based on the MSS Configurator + settings. + - Configure some of the enabled ways as scratchpad based on space allocated + by the MSS configurator. + + Example: + @code + // When called from assembly + call config_l2_cache + call end_l2_scratchpad_address # end address returned in a0 + call .clear_scratchpad + @endcode + */ void config_l2_cache(void); + +/***************************************************************************//** + The check_num_scratch_ways() function is used tocheck that the linker script + has not allocated more ways than has been allocated by the MSS Configurator. + + Example: + @code + // When called from assembly + call config_l2_cache + call end_l2_scratchpad_address # end address returned in a0 + call .clear_scratchpad + @endcode + */ uint8_t check_num_scratch_ways(uint64_t *start, uint64_t *end); +uint32_t num_cache_ways(void); +uint32_t my_num_cache_ways(void); + #ifdef __cplusplus } #endif diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/common/nwc/mss_ddr.c b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/common/nwc/mss_ddr.c index c67539a..6216252 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/common/nwc/mss_ddr.c +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/common/nwc/mss_ddr.c @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright 2019-2022 Microchip FPGA Embedded Systems Solutions. + * Copyright 2019-2023 Microchip FPGA Embedded Systems Solutions. * * SPDX-License-Identifier: MIT * @@ -13,28 +13,40 @@ * @brief DDR related code * */ -//#define PRINT_CA_VREF_WINDOW "1" +/* #define PRINT_CA_VREF_WINDOW "1" */ #define MOVE_CK #define MANUAL_ADDCMD_TRAINIG -//#define FABRIC_NOISE_TEST +/* #define FABRIC_NOISE_TEST */ #include #include #include "mpfs_hal/mss_hal.h" #include "mss_nwc_init.h" #ifdef DDR_SUPPORT #include "mss_ddr_debug.h" -#include "simulation.h" #ifdef FABRIC_NOISE_TEST -#include "drivers/mss_gpio/mss_gpio.h" +#include "drivers/mss/mss_gpio/mss_gpio.h" #endif /******************************************************************************* * Local Defines */ /* This string is updated if any change to ddr driver */ -#define DDR_DRIVER_VERSION_STRING "0.4.019" +#define DDR_DRIVER_VERSION_STRING "0.4.023" const char DDR_DRIVER_VERSION[] = DDR_DRIVER_VERSION_STRING; /* Version | Comment */ +/* 0.4.023 | Changed default ADDCMD CLK push order for DDR4 to 0,45,90 */ +/* 0.4.022 | Tidied comments and simulation reference- no code change */ +/* 0.4.021 | Added options to increase post training tests during */ +/* | verification. The following defines can be added to */ +/* | mss_sw_config.h during verification of a new hardware */ +/* | design to overwrite the default values: */ +/* | (#define PATTERN_TEST_NUM_PATTERN_IN_CACHE_READS 2U) */ +/* | (#define PATTERN_TEST_NUM_OFFSET_INCS 16U) */ +/* | (#define PATTERN_TEST_SIZE 0x40000000U) */ +/* 0.4.020 | Added user option to turn on clk push during addcmd */ +/* | training for DDR4 and lpddr3. The following define enables: */ +/* | (#define LIBERO_SETTING_USE_CK_PUSH_DDR4_LPDDR3 1U) */ +/* | It is enabled by default */ /* 0.4.019 | Added full memory initalization function */ /* 0.4.018 | Corrected error introduced for DDR3 in 0.4.14 */ /* 0.4.017 | made SW_TRAING_BCLK_SCLK_OFFSET seperate for each mem type */ @@ -206,8 +218,10 @@ static void config_ddr_io_pull_up_downs_rpc_bits(DDR_TYPE ddr_type); static uint8_t ddr_manual_addcmd_refclk_offset(DDR_TYPE ddr_type, uint8_t * refclk_sweep_index); #endif static void lpddr4_manual_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_index, uint32_t retry_count, uint8_t *refclk_offset); +#if (LIBERO_SETTING_USE_CK_PUSH_DDR4_LPDDR3 == 0U) static void non_lpddr4_address_cmd_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_index, uint32_t *bclk_phase, uint32_t *bclk90_phase, uint32_t *refclk_phase ); -static void ddr3_address_cmd_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_index, uint32_t retry_count, uint32_t *bclk_phase, uint32_t *bclk90_phase, uint32_t *refclk_phase, uint8_t *refclk_offset); +#endif +static void address_cmd_training_with_ck_push(DDR_TYPE ddr_type, uint8_t * refclk_sweep_index, uint32_t retry_count, uint32_t *bclk_phase, uint32_t *bclk90_phase, uint32_t *refclk_phase, uint8_t *refclk_offset); /******************************************************************************* * External function declarations @@ -222,7 +236,7 @@ void debug_read_ddrcfg(void); #ifdef FABRIC_NOISE_TEST uint32_t fabric_noise_en = 1; uint32_t fabric_noise_en_log = 1; -uint32_t num_of_noise_blocks_en = 3; /* do not set less than 1 */ +uint32_t num_of_noise_blocks_en = 4; /* do not set less than 1 */ uint32_t noise_ena = 0x0; #endif @@ -249,8 +263,7 @@ uint32_t ddr_state_machine(DDR_SS_COMMAND command) { ddr_state = DDR_STATE_INIT; } - SIM_FEEDBACK0(100U + ddr_state); - SIM_FEEDBACK1(ddr_state); + switch (ddr_state) { default: @@ -271,10 +284,8 @@ uint32_t ddr_state_machine(DDR_SS_COMMAND command) * 1. Periodically check DDR access * 2. Run any tests, as directed */ -// return_status = ddr_monitor(); break; } - SIM_FEEDBACK1(0xFF000000UL + return_status); return (return_status); } @@ -314,12 +325,10 @@ static uint32_t ddr_setup(void) uint32_t ret_status = 0U; uint8_t number_of_lanes_to_calibrate; uint64_t mem_size; + volatile PATTERN_TEST_PARAMS pattern_test; ddr_type = LIBERO_SETTING_DDRPHY_MODE & DDRPHY_MODE_MASK; - SIM_FEEDBACK0(200U + ddr_training_state); - SIM_FEEDBACK1(0U); - switch (ddr_training_state) { case DDR_TRAINING_INIT: @@ -671,10 +680,8 @@ static uint32_t ddr_setup(void) //ALISTER 7/16/21 DDRCFG->MC_BASE2.INIT_AUTOINIT_DISABLE.INIT_AUTOINIT_DISABLE=0x1; } - DDRCFG->MC_BASE2.CTRLR_SOFT_RESET_N.CTRLR_SOFT_RESET_N =\ - 0x00000000U; - DDRCFG->MC_BASE2.CTRLR_SOFT_RESET_N.CTRLR_SOFT_RESET_N =\ - 0x00000001U; + DDRCFG->MC_BASE2.CTRLR_SOFT_RESET_N.CTRLR_SOFT_RESET_N = 0x00000000U; + DDRCFG->MC_BASE2.CTRLR_SOFT_RESET_N.CTRLR_SOFT_RESET_N = 0x00000001U; #endif /* !SOFT_RESET_PRE_TAG_172 */ #else /* Disable CKE */ @@ -692,7 +699,7 @@ static uint32_t ddr_setup(void) delay(DELAY_CYCLES_50_MICRO); /* reset pin is bit [1] */ - CFG_DDR_SGMII_PHY->training_reset.training_reset = 0x00000002U; + CFG_DDR_SGMII_PHY->training_reset.training_reset = 0x00000002U; #endif ddr_training_state = DDR_TRAINING_ROTATE_CLK; @@ -928,12 +935,12 @@ static uint32_t ddr_setup(void) CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x00000001U; for (uint32_t ca_indly=0;ca_indly < 30; ca_indly=ca_indly+5) { - CFG_DDR_SGMII_PHY->rpc145.rpc145 = ca_indly;//TEMPORARY - CFG_DDR_SGMII_PHY->rpc147.rpc147 = ca_indly;//TEMPORARY + CFG_DDR_SGMII_PHY->rpc145.rpc145 = ca_indly;/* TEMPORARY */ + CFG_DDR_SGMII_PHY->rpc147.rpc147 = ca_indly;/* TEMPORARY */ uint32_t break_loop=1; uint32_t in_window=0; vref_answer=128; - for (uint32_t vref=5;vref <30;vref++) //begin vref training + for (uint32_t vref=5;vref <30;vref++) /* begin vref training */ { uint32_t transition_a5_max=0; uint32_t transition_a5_min=128; @@ -947,7 +954,7 @@ static uint32_t ddr_setup(void) } IOSCB_BANKCONT_DDR->soft_reset = 0U; /* DPC_BITS NV_MAP reset */ - //SET VREF HERE + /* SET VREF HERE */ delay(DELAY_CYCLES_500_NS); dpc_bits_new=( CFG_DDR_SGMII_PHY->DPC_BITS.DPC_BITS & 0xFFFC0FFF ) | (vref <<12) | (0x1<<18); CFG_DDR_SGMII_PHY->DPC_BITS.DPC_BITS=dpc_bits_new; @@ -955,28 +962,22 @@ static uint32_t ddr_setup(void) IOSCB_BANKCONT_DDR->soft_reset = 1U; /* DPC_BITS NV_MAP reset */ delay(DELAY_CYCLES_500_NS); - - //ADDCMD Training improvement , adds delay on A9 loopback path - Suggested by Alister - //CFG_DDR_SGMII_PHY->rpc145.rpc145 = 0x8U; - uint32_t deltat = 128UL; - for (uint32_t j = 0; j<20 ; j++) { - //LOAD INDLY + /* LOAD INDLY */ CFG_DDR_SGMII_PHY->expert_dlycnt_direction_reg1.expert_dlycnt_direction_reg1 = 0x000000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x000000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x180000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x000000U; - //LOAD OUTDLY + /* LOAD OUTDLY */ CFG_DDR_SGMII_PHY->expert_dlycnt_direction_reg1.expert_dlycnt_direction_reg1 = 0x180000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x000000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x180000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x000000U; - // rx_a5_last=0x0; rx_a5_last=0xF; transition_a5=0; deltat=128; @@ -991,34 +992,31 @@ static uint32_t ddr_setup(void) rx_a5 = (CFG_DDR_SGMII_PHY->expert_addcmd_ln_readback.expert_addcmd_ln_readback & 0x0300) >> 8; if (transition_a5 != 0){ - if (((i - transition_a5) > 8) ){ //was 8 //////////// + if (((i - transition_a5) > 8) ){ break; } } if (transition_a5 ==0) { - // if ( ((rx_a5 ^ rx_a5_last) & (~rx_a5) ) ){ if ( ((rx_a5 ^ rx_a5_last) & rx_a5 ) ){ transition_a5 = i; } else{ - rx_a5_last=rx_a5; + rx_a5_last=rx_a5; } } else { - if ((i - transition_a5) == 4) //was 4 //////////// - //if (rx_a5!=rx_a5_last) //IF rx_ca not stable after 4 increments, set transition detected to 0 (false transition) - // if(!((rx_a5 ^ rx_a5_last) & (~rx_a5) )) + if ((i - transition_a5) == 4) if(!((rx_a5 ^ rx_a5_last) & rx_a5 )) { - transition_a5=0; //Continue looking for transition + transition_a5=0; /* Continue looking for transition */ rx_a5_last=rx_a5; } } - }//delay loop ends here + }/* delay loop ends here */ if (transition_a5 !=0) { if (transition_a5 > transition_a5_max) @@ -1031,7 +1029,7 @@ static uint32_t ddr_setup(void) transition_a5_min = transition_a5; } } - }//Sample loop ends here + } /* Sample loop ends here */ range_a5=transition_a5_max-transition_a5_min; if (transition_a5_min < 10){ break_loop=0; @@ -1040,7 +1038,6 @@ static uint32_t ddr_setup(void) if (range_a5 <=5) { - //(min(transition_a5_min - transition_a5_min_last,transition_a5_min_last-transition_a5_min) <=4)) if (transition_a5_min > transition_a5_min_last) { deltat=transition_a5_min-transition_a5_min_last; @@ -1072,9 +1069,9 @@ static uint32_t ddr_setup(void) #endif if(vref_answer==128) { - if ((in_window &0x3)==0x3) //ALISTER CHANGE 2/17/2021 + if ((in_window &0x3)==0x3) { - vref_answer=vref; //ALISTER CHANGE + vref_answer=vref; #ifndef PRINT_CA_VREF_WINDOW break; #endif @@ -1120,11 +1117,21 @@ static uint32_t ddr_setup(void) if ((ddr_type == DDR3)||(ddr_type == DDR3L)) { - ddr3_address_cmd_training(ddr_type, &refclk_sweep_index, retry_count, &bclk_phase, &bclk90_phase, &refclk_phase, &refclk_offset ); + address_cmd_training_with_ck_push(ddr_type,\ + &refclk_sweep_index, retry_count, &bclk_phase,\ + &bclk90_phase, &refclk_phase, &refclk_offset ); } else if (ddr_type != LPDDR4) { - non_lpddr4_address_cmd_training(ddr_type, &refclk_sweep_index, &bclk_phase, &bclk90_phase, &refclk_phase); +#if (LIBERO_SETTING_USE_CK_PUSH_DDR4_LPDDR3 == 1U) + address_cmd_training_with_ck_push(ddr_type,\ + &refclk_sweep_index, retry_count, &bclk_phase,\ + &bclk90_phase, &refclk_phase, &refclk_offset ); +#else + non_lpddr4_address_cmd_training(ddr_type,\ + &refclk_sweep_index, &bclk_phase, &bclk90_phase,\ + &refclk_phase); +#endif } /* END MANUAL BCLKSCLK TRAINING */ else /* LPDDR4 */ { @@ -1151,7 +1158,7 @@ static uint32_t ddr_setup(void) IOSCB_BANKCONT_DDR->soft_reset = 1U; /* DPC_BITS NV_MAP reset */ delay(DELAY_CYCLES_500_NS); /* SET CA DRV BACK TO CONFIGURED VALUE */ - CFG_DDR_SGMII_PHY->rpc1_DRV.rpc1_DRV=ca_drv; //return ca_drv to original value + CFG_DDR_SGMII_PHY->rpc1_DRV.rpc1_DRV=ca_drv; /* return ca_drv to original value */ ddr_training_state = DDR_TRAINING_IP_SM_START; } } @@ -1285,7 +1292,7 @@ static uint32_t ddr_setup(void) } break; case DDR_TRAINING_IP_SM_WRLVL: - //END VREFTRN + /* END VREFTRN */ if(LIBERO_SETTING_TRAINING_SKIP_SETTING & WRLVL_BIT) { timeout = 0xFFFF; @@ -1350,11 +1357,8 @@ static uint32_t ddr_setup(void) for (lane_sel=0U; lane_sel< \ LIBERO_SETTING_DATA_LANES_USED; lane_sel++) { - SIM_FEEDBACK1(1000U); delay(10U); - SIM_FEEDBACK1(1001U); - CFG_DDR_SGMII_PHY->lane_select.lane_select =\ - lane_sel; + CFG_DDR_SGMII_PHY->lane_select.lane_select = lane_sel; delay(10U); /* * verify cmd address results @@ -1451,7 +1455,8 @@ static uint32_t ddr_setup(void) #define DCT_EXTRA_CHECKS #ifdef DCT_EXTRA_CHECKS uint32_t temp = 0U, gt_clk_sel = (CFG_DDR_SGMII_PHY->gt_clk_sel.gt_clk_sel & 3U); - if(((CFG_DDR_SGMII_PHY->gt_txdly.gt_txdly)&0xFFU) == 0U) // Gate training tx_dly check: AL + /* Gate training tx_dly check: */ + if(((CFG_DDR_SGMII_PHY->gt_txdly.gt_txdly)&0xFFU) == 0U) { temp++; if(gt_clk_sel == 0) @@ -1511,7 +1516,6 @@ static uint32_t ddr_setup(void) #endif if(t_status == 0U) { - SIM_FEEDBACK1(21U); /* * We can now set vref on the memory * mode register for lpddr4 @@ -1529,7 +1533,6 @@ static uint32_t ddr_setup(void) } else /* fail, try again */ { - SIM_FEEDBACK1(20U); ddr_training_state = DDR_TRAINING_FAIL_SM_VERIFY; } } @@ -1601,21 +1604,19 @@ static uint32_t ddr_setup(void) uint32_t dly_firstpass=0xFF; uint32_t dly_right_edge=20U; uint32_t pass=0U; - for(lane = 0U; lane < number_of_lanes_to_calibrate; lane++) //load DQ + for(lane = 0U; lane < number_of_lanes_to_calibrate; lane++) /* load DQ */ { load_dq(lane); } delay(DELAY_CYCLES_50_MICRO); for (uint32_t dq_dly=0U;dq_dly < 20U ; dq_dly=dq_dly+1U){ - CFG_DDR_SGMII_PHY->rpc220.rpc220 = dq_dly; //set DQ load value - for(lane = 0U; lane < number_of_lanes_to_calibrate; lane++) //load DQ + CFG_DDR_SGMII_PHY->rpc220.rpc220 = dq_dly; /* set DQ load value */ + for(lane = 0U; lane < number_of_lanes_to_calibrate; lane++) /* load DQ */ { load_dq(lane); } - SIM_FEEDBACK1(1U); - - delay(DELAY_CYCLES_50_MICRO); + delay(DELAY_CYCLES_50_MICRO); pass =\ write_calibration_using_mtc(\ number_of_lanes_to_calibrate); @@ -1654,11 +1655,10 @@ static uint32_t ddr_setup(void) #ifdef DEBUG_DDR_INIT (void)uprint32(g_debug_uart, "\n\r dq_dly_answer ",\ CFG_DDR_SGMII_PHY->rpc220.rpc220); - //(void)uprint32(g_debug_uart, " vrefdq_answer ", (vref_firstpass + vref_right_edge)/2); (void)uprint32(g_debug_uart, " wr calib result ",\ calib_data.write_cal.lane_calib_result); #endif - for(lane = 0U; lane < number_of_lanes_to_calibrate; lane++) //load DQ + for(lane = 0U; lane < number_of_lanes_to_calibrate; lane++) /* load DQ */ { load_dq(lane); } @@ -1683,7 +1683,6 @@ static uint32_t ddr_setup(void) } else { - SIM_FEEDBACK1(2U); error =\ write_calibration_using_mtc(number_of_lanes_to_calibrate); } @@ -1691,8 +1690,7 @@ static uint32_t ddr_setup(void) if(error) { ddr_error_count++; - SIM_FEEDBACK1(106U); - } + } } if(error == 0U) @@ -1862,7 +1860,7 @@ static uint32_t ddr_setup(void) #ifdef SKIP_VERIFY_PATTERN_IN_CACHE ddr_training_state = DDR_FULL_32BIT_WRC_CHECK; #else - ddr_training_state = DDR_LOAD_PATTERN_TO_CACHE; + ddr_training_state = DDR_LOAD_PATTERN_TO_CACHE_SETUP; #endif } else @@ -1870,10 +1868,17 @@ static uint32_t ddr_setup(void) ddr_training_state = DDR_TRAINING_FAIL_32BIT_CACHE_CHECK; } break; + case DDR_LOAD_PATTERN_TO_CACHE_SETUP: + pattern_test.base = LIBERO_SETTING_DDR_32_CACHE; + pattern_test.size = PATTERN_TEST_SIZE; + pattern_test.pattern_type = DDR_TEST_FILL; + pattern_test.pattern_offset = PATTERN_TEST_START_OFFSET; + pattern_test.num_offsets_to_try = PATTERN_TEST_NUM_OFFSET_INCS; + pattern_test.offset_cnt = 0U; + ddr_training_state = DDR_LOAD_PATTERN_TO_CACHE; + break; case DDR_LOAD_PATTERN_TO_CACHE: - load_ddr_pattern(LIBERO_SETTING_DDR_32_CACHE,\ - SIZE_OF_PATTERN_TEST*2, DDR_TEST_FILL,\ - SIZE_OF_PATTERN_OFFSET); + load_ddr_pattern(&pattern_test); if(error == 0U) { ddr_training_state = DDR_VERIFY_PATTERN_IN_CACHE; @@ -1884,22 +1889,22 @@ static uint32_t ddr_setup(void) } break; case DDR_VERIFY_PATTERN_IN_CACHE: - error = test_ddr(NO_PATTERN_IN_CACHE_READS, SIZE_OF_PATTERN_TEST); + error = test_ddr(PATTERN_TEST_NUM_PATTERN_IN_CACHE_READS, &pattern_test); #if ((LIBERO_FAST_START & 0x04) == 0U) - error = error | test_ddr(NO_PATTERN_IN_CACHE_READS, SIZE_OF_PATTERN_TEST); - error = error | test_ddr(NO_PATTERN_IN_CACHE_READS, SIZE_OF_PATTERN_TEST); + error = error | test_ddr(PATTERN_TEST_NUM_PATTERN_IN_CACHE_READS, &pattern_test); + error = error | test_ddr(PATTERN_TEST_NUM_PATTERN_IN_CACHE_READS, &pattern_test); #endif if(error == 0U) { -#ifdef DEBUG_DDR_INIT - (void)uprint32(g_debug_uart, "\n\r\n\r wr write latency ",\ - DDRCFG->DFI.CFG_DFI_T_PHY_WRLAT.CFG_DFI_T_PHY_WRLAT); -#if (TUNE_RPC_166_VALUE == 1) - (void)uprint32(g_debug_uart, "\n\r rpc_166_fifo_offset: ",\ - rpc_166_fifo_offset); -#endif -#endif - ddr_training_state = DDR_FULL_32BIT_WRC_CHECK; + if(++pattern_test.offset_cnt < pattern_test.num_offsets_to_try) + { + pattern_test.pattern_offset++; + ddr_training_state = DDR_LOAD_PATTERN_TO_CACHE; + } + else + { + ddr_training_state = DDR_FULL_32BIT_WRC_CHECK; + } } else { @@ -1932,7 +1937,6 @@ static uint32_t ddr_setup(void) CFG_DDR_SGMII_PHY->rpc166.rpc166 = rpc_166_fifo_offset; /* PAUSE to reset fifo (loads new RXPTR value).*/ - //CFG_DDR_SGMII_PHY->expert_dfi_status_override_to_shim.expert_dfi_status_override_to_shim = 0x07U; CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x1U; CFG_DDR_SGMII_PHY->expert_dlycnt_pause.expert_dlycnt_pause =\ 0x0000003EU ; @@ -1940,7 +1944,7 @@ static uint32_t ddr_setup(void) 0x00000000U; CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x8U; delay(DELAY_CYCLES_50_MICRO); - //END PAUSE + /* END PAUSE */ #else if(num_rpc_166_retires < NUM_RPC_166_VALUES) { @@ -1966,6 +1970,14 @@ static uint32_t ddr_setup(void) } break; case DDR_FULL_32BIT_WRC_CHECK: +#ifdef DEBUG_DDR_INIT + (void)uprint32(g_debug_uart, "\n\r\n\r wr write latency ",\ + DDRCFG->DFI.CFG_DFI_T_PHY_WRLAT.CFG_DFI_T_PHY_WRLAT); +#if (TUNE_RPC_166_VALUE == 1) + (void)uprint32(g_debug_uart, "\n\r rpc_166_fifo_offset: ",\ + rpc_166_fifo_offset); +#endif +#endif if(error == 0U) { ddr_training_state = DDR_FULL_64BIT_NC_CHECK; @@ -2050,8 +2062,12 @@ static uint32_t ddr_setup(void) { mem_size = LIBERO_SETTING_CFG_AXI_END_ADDRESS_AXI2_1 +\ (LIBERO_SETTING_CFG_AXI_END_ADDRESS_AXI2_0 + 1U); - load_ddr_pattern(LIBERO_SETTING_DDR_64_NON_CACHE, mem_size,\ - DDR_INIT_FILL, 0U); + pattern_test.base = LIBERO_SETTING_DDR_64_NON_CACHE; + pattern_test.size = mem_size; + pattern_test.pattern_type = DDR_INIT_FILL; + pattern_test.pattern_offset = 0U; + + load_ddr_pattern(&pattern_test); } #else mem_size = LIBERO_SETTING_CFG_AXI_END_ADDRESS_AXI2_1 +\ @@ -2092,6 +2108,18 @@ static uint32_t ddr_setup(void) * Configure Segments- address mapping, CFG0/CFG1 */ setup_ddr_segments(LIBERO_SEG_SETUP); + /* + * Clear the cache. Cache may have residue of writes related to the previous + * seg setup. These can endup being written back to DDR, so make sure cache + * is flushed. The cache is flushed by reading 2MB from cached backed memory + * We need to read from each master that has accessed the cache, as all + * masters may not have access to all the cache ways. + * When this function is being called, it is fair to assume only this hart + * and the PDMA has accessed the cache. + * We also assume this is in the bootloader and we have sole access to the + * PDMA + */ + clear_bootup_cache_ways(); } ret_status |= DDR_SETUP_DONE; ddr_training_state = DDR_TRAINING_FINISHED; @@ -2637,40 +2665,34 @@ static uint8_t memory_tests(void) uint64_t shift_walking_one = 4U; uint64_t start_address = 0x0000000000000000U; uint8_t error = 0U; - SIM_FEEDBACK1(199U); /* * Verify seg1 reg 2, datapath through AXI4 switch */ while(shift_walking_one <= 28U) /* 28 => 1G, as 2**28 == 256K and this is mult by (4 lanes) */ { - SIM_FEEDBACK1(shift_walking_one); start_address = (uint64_t)(BASE_ADDRESS_NON_CACHED_32_DDR + (0x1U< 1G + while(shift_walking_one <= 28U) /* 28 => 1G */ { - SIM_FEEDBACK1(shift_walking_one); start_address = (uint64_t)(BASE_ADDRESS_NON_CACHED_64_DDR + (0x1U<= 4U) @@ -2682,7 +2704,6 @@ static uint8_t memory_tests(void) if(error) { ddr_error_count++; - SIM_FEEDBACK1(201U); } } @@ -2691,19 +2712,16 @@ static uint8_t memory_tests(void) /* * Verify mtc */ - SIM_FEEDBACK1(600U); shift_walking_one = 4U; - while(shift_walking_one <= 28U) //28 => 1G + while(shift_walking_one <= 28U) /* 28 => 1G */ { - SIM_FEEDBACK1(shift_walking_one); start_address = (uint64_t)(0x1U<= 4U) @@ -2715,8 +2733,7 @@ static uint8_t memory_tests(void) if(error) { ddr_error_count++; - SIM_FEEDBACK1(204U); - } + } } shift_walking_one++; } @@ -2724,43 +2741,19 @@ static uint8_t memory_tests(void) /* * Verify seg0 reg 0, datapath through cache */ - SIM_FEEDBACK1(700U); shift_walking_one = 4U; - while(shift_walking_one <= 27U) //28 => 1G + while(shift_walking_one <= 27U) /* 28 => 1G */ { - SIM_FEEDBACK1(shift_walking_one); start_address = (uint64_t)(0x80000000U + (0x1U< 1G (0x10000000(address) * 4 (32bits wide)) - { - SIM_FEEDBACK1(shift_walking_one); - start_address = (uint64_t)(0x1000000000U + (0x1U<expert_dlycnt_move_reg0.expert_dlycnt_move_reg0 = 0U; @@ -2869,11 +2862,11 @@ static void load_dq(uint8_t lane) (CFG_DDR_SGMII_PHY->expert_dlycnt_move_reg1.expert_dlycnt_move_reg1\ & (uint32_t)~0x0FU); } - //set expert_dfi_status_override_to_shim = 0x7 + /* set expert_dfi_status_override_to_shim = 0x7 */ CFG_DDR_SGMII_PHY->expert_dfi_status_override_to_shim.expert_dfi_status_override_to_shim = 0x07U; - //set expert_mode_en = 0x21 + /* set expert_mode_en = 0x21 */ CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x21U; - //set dyn_ovr_dlycnt_dq_load* = 1 + /* set dyn_ovr_dlycnt_dq_load* = 1 */ if(lane < 4U) { CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg0.expert_dlycnt_load_reg0 =\ @@ -2884,7 +2877,7 @@ static void load_dq(uint8_t lane) CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 |=\ 0x0FU; } - //set dyn_ovr_dlycnt_dq_load* = 0 + /* set dyn_ovr_dlycnt_dq_load* = 0 */ CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg0.expert_dlycnt_load_reg0 = 0U; if(lane < 4U) { @@ -2896,7 +2889,7 @@ static void load_dq(uint8_t lane) (CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1\ & (uint32_t)~0x0FU); } - //set expert_mode_en = 0x8 + /* set expert_mode_en = 0x8 */ CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x8U; } @@ -2918,7 +2911,7 @@ static void load_dq(uint8_t lane) #ifdef SW_CONFIG_LPDDR_WR_CALIB_FN static void increment_dq(uint8_t lane, uint32_t move_count) { - //set dyn_ovr_dlycnt_dq_move* = 0 + /* set dyn_ovr_dlycnt_dq_move* = 0 */ if(lane < 4U) { CFG_DDR_SGMII_PHY->expert_dlycnt_move_reg0.expert_dlycnt_move_reg0 = 0U; @@ -2929,7 +2922,7 @@ static void increment_dq(uint8_t lane, uint32_t move_count) (CFG_DDR_SGMII_PHY->expert_dlycnt_move_reg1.expert_dlycnt_move_reg1\ & ~0x0FU); } - //set dyn_ovr_dlycnt_dq_direction* = 1 + /* set dyn_ovr_dlycnt_dq_direction* = 1 */ if(lane < 4U) { CFG_DDR_SGMII_PHY->expert_dlycnt_direction_reg0.expert_dlycnt_direction_reg0\ @@ -2948,7 +2941,7 @@ static void increment_dq(uint8_t lane, uint32_t move_count) move_count = move_count + move_count + move_count; while(move_count) { - // set dyn_ovr_dlycnt_dq_move* = 1 + /* set dyn_ovr_dlycnt_dq_move* = 1 */ if(lane < 4U) { CFG_DDR_SGMII_PHY->expert_dlycnt_move_reg0.expert_dlycnt_move_reg0\ @@ -2959,7 +2952,7 @@ static void increment_dq(uint8_t lane, uint32_t move_count) CFG_DDR_SGMII_PHY->expert_dlycnt_move_reg1.expert_dlycnt_move_reg1\ |= 0x0FU; } - // set dyn_ovr_dlycnt_dq_move* = 0 + /* set dyn_ovr_dlycnt_dq_move* = 0 */ CFG_DDR_SGMII_PHY->expert_dlycnt_move_reg0.expert_dlycnt_move_reg0 = 0U; if(lane < 4U) { @@ -3007,10 +3000,6 @@ static void set_write_calib(uint8_t user_lanes) */ CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x00000008U; - SIM_FEEDBACK1(0xFF000000); - SIM_FEEDBACK1(calib_data.write_cal.lane_calib_result); - SIM_FEEDBACK1(0xFF000000); - /* set the calibrated value */ CFG_DDR_SGMII_PHY->expert_wrcalib.expert_wrcalib =\ calib_data.write_cal.lane_calib_result; @@ -3152,8 +3141,7 @@ static uint8_t \ if(result == 0U) /* if true, we are good for all lanes, can stop looking */ { - SIM_FEEDBACK1(0xF7000000); - break; + break; } } else @@ -3167,25 +3155,10 @@ static uint8_t \ } /* end laneToTest */ if(result == 0U) /* if true, we are good for all lanes, can stop */ { /* looking */ - SIM_FEEDBACK1(0xF8000000); break; } } /* end cal_data */ - SIM_FEEDBACK1(0x01000000); - SIM_FEEDBACK1(calib_data.write_cal.lower[0]); - SIM_FEEDBACK1(0x02000000); - SIM_FEEDBACK1(calib_data.write_cal.lower[1]); - SIM_FEEDBACK1(0x03000000); - SIM_FEEDBACK1(calib_data.write_cal.lower[2]); - SIM_FEEDBACK1(0x04000000); - SIM_FEEDBACK1(calib_data.write_cal.lower[3]); - SIM_FEEDBACK1(0x05000000); - SIM_FEEDBACK1(calib_data.write_cal.lower[4]); - SIM_FEEDBACK1(0x06000000); - SIM_FEEDBACK1(calib_data.write_cal.lower[5]); - SIM_FEEDBACK1(0x07000000); - /* if calibration successful, calculate and set the value */ if(result == 0U) { @@ -3193,9 +3166,6 @@ static uint8_t \ set_write_calib(number_of_lanes_to_calibrate); } - SIM_FEEDBACK1(0x08000000); - SIM_FEEDBACK1(result); - SIM_FEEDBACK1(0x08000000); return (uint8_t)result; } @@ -3214,7 +3184,6 @@ static uint8_t mode_register_write(uint32_t MR_ADDR, uint32_t MR_DATA) /* * */ - //DDRCFG->MC_BASE2.INIT_MRR_MODE.INIT_MRR_MODE = 0x01; DDRCFG->MC_BASE2.INIT_MR_ADDR.INIT_MR_ADDR = MR_ADDR ; /* * next: @@ -4377,6 +4346,13 @@ static void init_ddrc(void) /** * setup_ddr_segments(void) * setup segment registers- translated DDR address as user requires + * + * This should only be called by the boot-loader + * + * Assumption: We are calling this during early boot. + * We have complete control of the PDMA. + * Only the PDMS and the hart calling this function have written to the DDR + * at this point. */ void setup_ddr_segments(SEG_SETUP option) { @@ -4408,6 +4384,33 @@ void setup_ddr_segments(SEG_SETUP option) SEG[0].u[7].raw = 0x01U; } +/** + * Clear cache ways used buring boot. + * These are the ways associated with the PDMA and the current hart being run + * + * Assumption: We are calling this during early boot. + * We have complete control of the PDMA. + * Only the PDMA and the hart calling this function have written to the DDR + * at this point. + */ +__attribute__((weak)) void clear_bootup_cache_ways(void) +{ + volatile PATTERN_TEST_PARAMS pattern_test; + + /* clear using pdma routine, uses the 4 channels */ + pattern_test.base = LIBERO_SETTING_DDR_32_CACHE; + pattern_test.size = TWO_MBYTES*4; + pattern_test.pattern_type = DDR_INIT_FILL; + pattern_test.pattern_offset = 0U; + + load_ddr_pattern(&pattern_test); + + /* clear using my d-cache ways */ + fill_cache_new_seg_address((void *)BASE_ADDRESS_CACHED_32_DDR, + (void *)(BASE_ADDRESS_CACHED_32_DDR + + TWO_MBYTES)); +} + /** * use_software_bclk_sclk_training() * @param ddr_type @@ -4856,8 +4859,6 @@ static uint8_t ddr_manual_addcmd_refclk_offset(DDR_TYPE ddr_type, uint8_t * refc } #endif - -//ALISTER 7/16/21 static uint32_t mode_register_masked_write(uint32_t address) { DDRCFG->MC_BASE2.INIT_CS.INIT_CS = 0x1; @@ -4928,6 +4929,42 @@ static uint32_t zq_cal(void) } #endif +uint32_t ddr_add_cmd_inc_feq[]={\ + ADD_CMD_INC_FREQ_DDR3,\ + ADD_CMD_INC_FREQ_DDR3L,\ + ADD_CMD_INC_FREQ_DDR4,\ + ADD_CMD_INC_FREQ_LPDDR3,\ + ADD_CMD_INC_FREQ_LPDDR4 }; + +uint32_t ddr_add_cmd_trans_a5_threshold[]={\ + ADD_CMD_TRANS_A5_THRES_DDR3,\ + ADD_CMD_TRANS_A5_THRES_DDR3L,\ + ADD_CMD_TRANS_A5_THRES_DDR4,\ + ADD_CMD_TRANS_A5_THRES_LPDDR3,\ + ADD_CMD_TRANS_A5_THRES_LPDDR4 }; + +uint32_t add_cmd_move_order_0_deg[]={\ + LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_0_DEG_DDR3,\ + LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_0_DEG_DDR3L,\ + LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_0_DEG_DDR4,\ + LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_0_DEG_LPDDR3,\ + LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_0_DEG_LPDDR4 }; + +uint32_t add_cmd_move_order_45_deg[]={\ + LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_45_DEG_DDR3,\ + LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_45_DEG_DDR3L,\ + LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_45_DEG_DDR4,\ + LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_45_DEG_LPDDR3,\ + LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_45_DEG_LPDDR4 }; + +uint32_t add_cmd_move_order_90_deg[]={\ + LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_90_DEG_DDR3,\ + LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_90_DEG_DDR3L,\ + LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_90_DEG_DDR4,\ + LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_90_DEG_LPDDR3,\ + LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_90_DEG_LPDDR4 }; + + /** * LPDDR4 traing exclusive * @param ddr_type @@ -4935,9 +4972,8 @@ static uint32_t zq_cal(void) */ static void lpddr4_manual_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_index, uint32_t retry_count, uint8_t *refclk_offset) { - //ALISTER 7/16/2021 DDRCFG->MC_BASE2.INIT_CS.INIT_CS = 0x1; - DDRCFG->MC_BASE2.INIT_DISABLE_CKE.INIT_DISABLE_CKE = 0x1; //moved up from below jan7th + DDRCFG->MC_BASE2.INIT_DISABLE_CKE.INIT_DISABLE_CKE = 0x1; delay(DELAY_CYCLES_5_MICRO); DDRCFG->MC_BASE2.INIT_FORCE_RESET.INIT_FORCE_RESET = 0x1; @@ -4987,7 +5023,7 @@ static void lpddr4_manual_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ind #endif DDRCFG->MC_BASE2.INIT_CS.INIT_CS = 0x1; - DDRCFG->MC_BASE2.INIT_DISABLE_CKE.INIT_DISABLE_CKE = 0x1; //moved up from below jan7th + DDRCFG->MC_BASE2.INIT_DISABLE_CKE.INIT_DISABLE_CKE = 0x1; delay(DELAY_CYCLES_5_MICRO); DDRCFG->MC_BASE2.INIT_FORCE_RESET.INIT_FORCE_RESET = 0x1; @@ -5048,12 +5084,12 @@ static void lpddr4_manual_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ind CFG_DDR_SGMII_PHY->expert_dfi_status_override_to_shim.expert_dfi_status_override_to_shim = 0x00000000U; for (uint32_t ca_indly=0;ca_indly < 30; ca_indly=ca_indly+5) { - CFG_DDR_SGMII_PHY->rpc145.rpc145 = ca_indly;//TEMPORARY - CFG_DDR_SGMII_PHY->rpc147.rpc147 = ca_indly;//TEMPORARY + CFG_DDR_SGMII_PHY->rpc145.rpc145 = ca_indly;/* TEMPORARY */ + CFG_DDR_SGMII_PHY->rpc147.rpc147 = ca_indly;/* TEMPORARY */ uint32_t break_loop=1; uint32_t in_window=0; vref_answer=128; - for (uint32_t vref=5;vref <30;vref++) //begin vref training + for (uint32_t vref=5;vref <30;vref++) /* begin vref training */ { uint32_t transition_a5_max=0; uint32_t transition_a5_min=128; @@ -5067,7 +5103,7 @@ static void lpddr4_manual_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ind } IOSCB_BANKCONT_DDR->soft_reset = 0U; /* DPC_BITS NV_MAP reset */ - //SET VREF HERE + /* SET VREF HERE */ delay(DELAY_CYCLES_500_NS); dpc_bits_new=( CFG_DDR_SGMII_PHY->DPC_BITS.DPC_BITS & 0xFFFC0FFF ) | (vref <<12) | (0x1<<18); CFG_DDR_SGMII_PHY->DPC_BITS.DPC_BITS=dpc_bits_new; @@ -5078,20 +5114,18 @@ static void lpddr4_manual_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ind uint32_t deltat = 128UL; for (uint32_t j = 0; j<20 ; j++) { - - //LOAD INDLY + /* LOAD INDLY */ CFG_DDR_SGMII_PHY->expert_dlycnt_direction_reg1.expert_dlycnt_direction_reg1 = 0x000000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x000000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x180000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x000000U; - //LOAD OUTDLY + /* LOAD OUTDLY */ CFG_DDR_SGMII_PHY->expert_dlycnt_direction_reg1.expert_dlycnt_direction_reg1 = 0x180000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x000000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x180000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x000000U; - // rx_a5_last=0x0; rx_a5_last=0xF; transition_a5=0; deltat=128; @@ -5106,7 +5140,7 @@ static void lpddr4_manual_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ind rx_a5 = (CFG_DDR_SGMII_PHY->expert_addcmd_ln_readback.expert_addcmd_ln_readback & 0x0300) >> 8; if (transition_a5 != 0){ - if (((i - transition_a5) > 8) ){ //was 8 //////////// + if (((i - transition_a5) > 8) ){ break; } } @@ -5120,14 +5154,14 @@ static void lpddr4_manual_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ind } } else { - if ((i - transition_a5) == 4) //was 4 //////////// + if ((i - transition_a5) == 4) if(!((rx_a5 ^ rx_a5_last) & rx_a5 )) { - transition_a5=0; //Continue looking for transition + transition_a5=0; /* Continue looking for transition */ rx_a5_last=rx_a5; } } - }//delay loop ends here + }/* delay loop ends here */ if (transition_a5 !=0) { if (transition_a5 > transition_a5_max) @@ -5140,14 +5174,13 @@ static void lpddr4_manual_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ind transition_a5_min = transition_a5; } } - }//Sample loop ends here + }/* Sample loop ends here */ range_a5=transition_a5_max-transition_a5_min; if (transition_a5_min < 10){ break_loop=0; } if (range_a5 <=5) { - //(min(transition_a5_min - transition_a5_min_last,transition_a5_min_last-transition_a5_min) <=4)) if (transition_a5_min > transition_a5_min_last) { deltat=transition_a5_min-transition_a5_min_last; @@ -5179,9 +5212,9 @@ static void lpddr4_manual_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ind #endif if(vref_answer==128) { - if ((in_window &0x3)==0x3) //ALISTER CHANGE 2/17/2021 + if ((in_window &0x3)==0x3) { - vref_answer=vref; //ALISTER CHANGE + vref_answer=vref; #ifndef PRINT_CA_VREF_WINDOW break; #endif @@ -5235,8 +5268,8 @@ static void lpddr4_manual_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ind uint32_t bclk90_phase=MSS_SCB_DDR_PLL->PLL_PHADJ & 0x3800; uint32_t refclk_phase; - //ALISTER 1/12/2022 SWEEPING CK OFFSET BEFORE CHANING refclk_offset - if ((retry_count % 6) == 0){ + /* SWEEPING CK OFFSET BEFORE CHANING refclk_offset */ + if ((retry_count % ddr_add_cmd_inc_feq[ddr_type]) == 0){ *refclk_offset = ddr_manual_addcmd_refclk_offset(ddr_type, refclk_sweep_index); } @@ -5244,13 +5277,13 @@ static void lpddr4_manual_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ind while(a5_offset_status != DDR_ADD_CMD_A5_OFFSET_PASS) { a5_offset_status = DDR_ADD_CMD_A5_OFFSET_PASS; - //ADDCMD Training improvement , adds delay on DDR clock loopback path + /* ADDCMD Training improvement , adds delay on DDR clock loopback path */ CFG_DDR_SGMII_PHY->rpc147.rpc147 = init_del_offset + rpc147_offset; - //ADDCMD Training improvement , adds delay on A9 loopback path + /* ADDCMD Training improvement , adds delay on A9 loopback path */ CFG_DDR_SGMII_PHY->rpc145.rpc145 = init_del_offset + rpc145_offset; - CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x00000023U; //ENABLE DLY Control & PLL Control + CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x00000023U; /* ENABLE DLY Control & PLL Control */ uint32_t rx_a5; uint32_t rx_a5_last; @@ -5267,15 +5300,15 @@ static void lpddr4_manual_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ind uint32_t transition_a5_max = 0U; for (j = 0U; j<16U ; j++) - { //Increase J loop to increase number of samples on transition_a5 (for noisy CA in LPDDR4) - //LOAD INDLY + { /* Increase J loop to increase number of samples on transition_a5 (for noisy CA in LPDDR4) */ + /* LOAD INDLY */ CFG_DDR_SGMII_PHY->expert_dlycnt_direction_reg1.expert_dlycnt_direction_reg1 = 0x000000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x000000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x180000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x000000U; - //LOAD OUTDLY + /* LOAD OUTDLY */ CFG_DDR_SGMII_PHY->expert_dlycnt_direction_reg1.expert_dlycnt_direction_reg1 = 0x180000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x000000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x180000U; @@ -5306,22 +5339,21 @@ static void lpddr4_manual_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ind { if (((i - transition_a5) > 8U) && ((i - transition_ck) > 8U)) { - //break; transitions_found = 1U; } } if (transition_ck == 0U) { - if (rx_ck_last != 0x5U) //IF EDGE DETECTED + if (rx_ck_last != 0x5U) /* IF EDGE DETECTED */ if (rx_ck == 0x5U) - transition_ck=i; //SET TRANSITION DETECTED AT I + transition_ck=i; /* SET TRANSITION DETECTED AT I */ rx_ck_last=rx_ck; } else { if ( (i - transition_ck ) == 4U) - if (rx_ck != rx_ck_last) //IF rx_ck not stable after 4 increments, set transition detected to 0 (false transition) + if (rx_ck != rx_ck_last) /* IF rx_ck not stable after 4 increments, set transition detected to 0 (false transition) */ { - transition_ck = 0U; //Continue looking for transition + transition_ck = 0U; /* Continue looking for transition */ rx_ck_last=rx_ck; } } @@ -5339,7 +5371,7 @@ static void lpddr4_manual_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ind { if(!((rx_a5 ^ rx_a5_last) & rx_a5 )) { - transition_a5=0; //Continue looking for transition + transition_a5=0; /* Continue looking for transition */ rx_a5_last=rx_a5; } } @@ -5392,7 +5424,7 @@ static void lpddr4_manual_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ind uint32_t min_refclkp1=0x8U; uint32_t min_refclkp2=0x8U; - if(transition_a5_max < TRANSITION_A5_THRESHOLD) + if(transition_a5_max < ddr_add_cmd_trans_a5_threshold[ddr_type]) { a5_offset_status |= DDR_ADD_CMD_A5_OFFSET_FAIL; } @@ -5408,7 +5440,6 @@ static void lpddr4_manual_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ind { if (difference[k] < min_diff){ - //updated on Jan10 min_refclk=k; min_refclkp1=(k+1)&0x7UL; min_refclkp2=(k+2)&0x7UL; @@ -5427,28 +5458,26 @@ static void lpddr4_manual_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ind a5_offset_status |= DDR_ADD_CMD_A5_OFFSET_FAIL; } if (min_refclk==0x8U) - { //If ADDCMD training fails due to extremely low frequency, use PLL to provide offset. + { /* If ADDCMD training fails due to extremely low frequency, use PLL to provide offset. */ a5_offset_status |= DDR_ADD_CMD_A5_OFFSET_FAIL_LOW_FREQ; } #ifdef MOVE_CK - if ((retry_count%3) == LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_ZERO){ //toggles between minimum CA delay and second smallest every 4 retrains. - //min_diff=second_diff; + /* toggles between minimum CA delay and second smallest every 4 retrains. */ + if ((retry_count%3) == add_cmd_move_order_0_deg[ddr_type]){ min_diffp1=min_diff; - //min_refclk=(min_refclk-0x1UL)&&(0x7UL); min_refclk=(min_refclk-0x1UL)&(0x7UL); #ifdef DEBUG_DDR_INIT (void)uprint32(g_debug_uart, "\n\r CK_PUSH = 0 degrees", 0x0UL); #endif } - else if ((retry_count%3) == LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_ONE){ + else if ((retry_count%3) == add_cmd_move_order_45_deg[ddr_type]){ #ifdef DEBUG_DDR_INIT (void)uprint32(g_debug_uart, "\n\r CK_PUSH = 45 degrees", 0x0UL); #endif } - else if ((retry_count%3) == LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_TWO){ //toggles between minimum CA delay and second smallest every 4 retrains. - //min_diff=second_diff; + else if ((retry_count%3) == add_cmd_move_order_90_deg[ddr_type]){ + /* toggles between minimum CA delay and second smallest every 4 retrains. */ min_diffp1=min_diffp2; - //min_refclk=(min_refclk-0x1UL)&&(0x7UL); min_refclk=min_refclkp1; #ifdef DEBUG_DDR_INIT (void)uprint32(g_debug_uart, "\n\r CK_PUSH = 90 degrees", 0x0UL); @@ -5461,13 +5490,13 @@ static void lpddr4_manual_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ind MSS_SCB_DDR_PLL->PLL_PHADJ = (0x00004003UL | bclk_phase | bclk90_phase | refclk_phase); MSS_SCB_DDR_PLL->PLL_PHADJ = (0x00000003UL | bclk_phase | bclk90_phase | refclk_phase); MSS_SCB_DDR_PLL->PLL_PHADJ = (0x00004003UL | bclk_phase | bclk90_phase | refclk_phase); - //LOAD INDLY + /* LOAD INDLY */ CFG_DDR_SGMII_PHY->expert_dlycnt_direction_reg1.expert_dlycnt_direction_reg1 = 0x000000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x000000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x180000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x000000U; - //LOAD OUTDLY + /* LOAD OUTDLY */ CFG_DDR_SGMII_PHY->expert_dlycnt_direction_reg1.expert_dlycnt_direction_reg1 = 0x180000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x000000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x180000U; @@ -5479,7 +5508,7 @@ static void lpddr4_manual_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ind CFG_DDR_SGMII_PHY->expert_dlycnt_move_reg1.expert_dlycnt_move_reg1 = 0x0U; } CFG_DDR_SGMII_PHY->expert_dlycnt_direction_reg1.expert_dlycnt_direction_reg1 = 0x000000U; - CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x00000000U; //DISABLE DLY Control & PLL Control + CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x00000000U; /* DISABLE DLY Control & PLL Control */ #ifdef DEBUG_DDR_INIT (void)uprint32(g_debug_uart, "\n\r MANUAL ADDCMD TRAINING Results:\r\n PLL OFFSET: ",min_refclk); (void)uprint32(g_debug_uart, "\n\r transition_a5_max: ", transition_a5_max); @@ -5493,7 +5522,8 @@ static void lpddr4_manual_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ind { if(init_del_offset < 0xFFU ) { - init_del_offset = init_del_offset + (transition_a5_max) + 5U; //if transition_a5 too low, increase indly offset on CK and CA and retrain + /* if transition_a5 too low, increase indly offset on CK and CA and retrain */ + init_del_offset = init_del_offset + (transition_a5_max) + 5U; } else { @@ -5501,13 +5531,13 @@ static void lpddr4_manual_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ind } } } /* end of for (j = 0U; j<16U ; j++) */ - } // while(a5_offset_status != DDR_ADD_CMD_A5_OFFSET_PASS) - } //END MANUAL ADDCMD TRAINING + } /* while(a5_offset_status != DDR_ADD_CMD_A5_OFFSET_PASS) */ + } /* END MANUAL ADDCMD TRAINING */ CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x0000008U; CFG_DDR_SGMII_PHY->expert_dfi_status_override_to_shim.expert_dfi_status_override_to_shim = 0x00000000U; - //POST_INITIALIZATION + /* POST_INITIALIZATION */ CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x9U; CFG_DDR_SGMII_PHY->expert_dlycnt_pause.expert_dlycnt_pause = 0x0000003FU ; CFG_DDR_SGMII_PHY->expert_dlycnt_pause.expert_dlycnt_pause = 0x00000000U; @@ -5564,14 +5594,15 @@ static void lpddr4_manual_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ind * @param bclk90_phase * @param refclk_phase */ +#if (LIBERO_SETTING_USE_CK_PUSH_DDR4_LPDDR3 == 0U) static void non_lpddr4_address_cmd_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_index, uint32_t *bclk_phase, uint32_t *bclk90_phase, uint32_t *refclk_phase ) { /* Begin MANUAL ADDCMD TRAINING */ uint8_t refclk_offset; uint32_t init_del_offset = 0x8U; uint32_t a5_offset_status; - uint32_t rpc147_offset = 0x2U; //4 //0 - uint32_t rpc145_offset = 0x0U; //0 //4 + uint32_t rpc147_offset = 0x2U; + uint32_t rpc145_offset = 0x0U; refclk_offset = ddr_manual_addcmd_refclk_offset(ddr_type, refclk_sweep_index); a5_offset_status = DDR_ADD_CMD_A5_OFFSET_FAIL; @@ -5579,13 +5610,13 @@ static void non_lpddr4_address_cmd_training(DDR_TYPE ddr_type, uint8_t * refclk_ { a5_offset_status = DDR_ADD_CMD_A5_OFFSET_PASS; - //ADDCMD Training improvement , adds delay on DDR clock loopback path - Suggested by Alister + /* ADDCMD Training improvement , adds delay on DDR clock loopback path */ CFG_DDR_SGMII_PHY->rpc147.rpc147 = init_del_offset + rpc147_offset; - //ADDCMD Training improvement , adds delay on A9 loopback path - Suggested by Alister + /* ADDCMD Training improvement , adds delay on A9 loopback path */ CFG_DDR_SGMII_PHY->rpc145.rpc145 = init_del_offset + rpc145_offset; - CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x00000003U; //ENABLE DLY Control & PLL Control + CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x00000003U; /* ENABLE DLY Control & PLL Control */ uint32_t rx_a5; uint32_t rx_a5_last; @@ -5602,14 +5633,14 @@ static void non_lpddr4_address_cmd_training(DDR_TYPE ddr_type, uint8_t * refclk_ uint32_t transition_a5_max = 0U; for (j = 0U; j<16U ; j++) - { //Increase J loop to increase number of samples on transition_a5 (for noisy CA in LPDDR4) - //LOAD INDLY + { /* Increase J loop to increase number of samples on transition_a5 (for noisy CA in LPDDR4) */ + /* LOAD INDLY */ CFG_DDR_SGMII_PHY->expert_dlycnt_direction_reg1.expert_dlycnt_direction_reg1 = 0x000000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x000000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x180000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x000000U; - //LOAD OUTDLY + /* LOAD OUTDLY */ CFG_DDR_SGMII_PHY->expert_dlycnt_direction_reg1.expert_dlycnt_direction_reg1 = 0x180000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x000000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x180000U; @@ -5640,22 +5671,22 @@ static void non_lpddr4_address_cmd_training(DDR_TYPE ddr_type, uint8_t * refclk_ { if (((i - transition_a5) > 8U) && ((i - transition_ck) > 8U)) { - //break; transitions_found = 1U; } } if (transition_ck == 0U) { - if (rx_ck_last != 0x5U) //IF EDGE DETECTED + if (rx_ck_last != 0x5U) /* IF EDGE DETECTED */ if (rx_ck == 0x5U) - transition_ck=i; //SET TRANSITION DETECTED AT I + transition_ck=i; /* SET TRANSITION DETECTED AT I */ rx_ck_last=rx_ck; } else { if ( (i - transition_ck ) == 4U) - if (rx_ck != rx_ck_last) //IF rx_ck not stable after 4 increments, set transition detected to 0 (false transition) + /* IF rx_ck not stable after 4 increments, set transition detected to 0 (false transition) */ + if (rx_ck != rx_ck_last) { - transition_ck = 0U; //Continue looking for transition + transition_ck = 0U; /* Continue looking for transition */ rx_ck_last=rx_ck; } } @@ -5672,7 +5703,7 @@ static void non_lpddr4_address_cmd_training(DDR_TYPE ddr_type, uint8_t * refclk_ if ((i - transition_a5) == 4U) if(!((rx_a5 ^ rx_a5_last) & rx_a5 )) { - transition_a5=0; //Continue looking for transition + transition_a5=0; /* Continue looking for transition */ rx_a5_last=rx_a5; } } @@ -5745,7 +5776,7 @@ static void non_lpddr4_address_cmd_training(DDR_TYPE ddr_type, uint8_t * refclk_ a5_offset_status |= DDR_ADD_CMD_A5_OFFSET_FAIL; } if (min_refclk==0x8U) - { //If ADDCMD training fails due to extremely low frequency, use PLL to provide offset. + { /* If ADDCMD training fails due to extremely low frequency, use PLL to provide offset. */ a5_offset_status |= DDR_ADD_CMD_A5_OFFSET_FAIL_LOW_FREQ; } if(a5_offset_status == DDR_ADD_CMD_A5_OFFSET_PASS) @@ -5754,13 +5785,13 @@ static void non_lpddr4_address_cmd_training(DDR_TYPE ddr_type, uint8_t * refclk_ MSS_SCB_DDR_PLL->PLL_PHADJ = (0x00004003UL | *bclk_phase | *bclk90_phase | *refclk_phase); MSS_SCB_DDR_PLL->PLL_PHADJ = (0x00000003UL | *bclk_phase | *bclk90_phase | *refclk_phase); MSS_SCB_DDR_PLL->PLL_PHADJ = (0x00004003UL | *bclk_phase | *bclk90_phase | *refclk_phase); - //LOAD INDLY + /* LOAD INDLY */ CFG_DDR_SGMII_PHY->expert_dlycnt_direction_reg1.expert_dlycnt_direction_reg1 = 0x000000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x000000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x180000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x000000U; - //LOAD OUTDLY + /* LOAD OUTDLY */ CFG_DDR_SGMII_PHY->expert_dlycnt_direction_reg1.expert_dlycnt_direction_reg1 = 0x180000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x000000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x180000U; @@ -5772,7 +5803,7 @@ static void non_lpddr4_address_cmd_training(DDR_TYPE ddr_type, uint8_t * refclk_ CFG_DDR_SGMII_PHY->expert_dlycnt_move_reg1.expert_dlycnt_move_reg1 = 0x0U; } CFG_DDR_SGMII_PHY->expert_dlycnt_direction_reg1.expert_dlycnt_direction_reg1 = 0x000000U; - CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x00000000U; //DISABLE DLY Control & PLL Control + CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x00000000U; /* DISABLE DLY Control & PLL Control */ #ifdef DEBUG_DDR_INIT (void)uprint32(g_debug_uart, "\n\r MANUAL ADDCMD TRAINING Results:\r\n PLL OFFSET: ",min_refclk); (void)uprint32(g_debug_uart, "\n\r transition_a5_max: ", transition_a5_max); @@ -5785,7 +5816,7 @@ static void non_lpddr4_address_cmd_training(DDR_TYPE ddr_type, uint8_t * refclk_ { if(init_del_offset < 0xFFU ) { - //if transition_a5 too low, increase indly offset on CK and CA and retrain + /* if transition_a5 too low, increase indly offset on CK and CA and retrain */ init_del_offset = init_del_offset + (transition_a5_max) + 5U; } else @@ -5796,11 +5827,11 @@ static void non_lpddr4_address_cmd_training(DDR_TYPE ddr_type, uint8_t * refclk_ } } } /* END MANUAL BCLKSCLK TRAINING */ - +#endif /** - * ddr3_address_cmd_training() - * @param ddr_type DDR3 + * address_cmd_training_with_ck_push() + * @param ddr_type DDR3, DDR4 and LPDDR3 * @param refclk_sweep_index * @param retry_count * @param bclk_phase @@ -5808,15 +5839,15 @@ static void non_lpddr4_address_cmd_training(DDR_TYPE ddr_type, uint8_t * refclk_ * @param refclk_phase * @param refclk_offset */ -static void ddr3_address_cmd_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_index, uint32_t retry_count, uint32_t *bclk_phase, uint32_t *bclk90_phase, uint32_t *refclk_phase, uint8_t *refclk_offset ) +static void address_cmd_training_with_ck_push(DDR_TYPE ddr_type, uint8_t * refclk_sweep_index, uint32_t retry_count, uint32_t *bclk_phase, uint32_t *bclk90_phase, uint32_t *refclk_phase, uint8_t *refclk_offset ) { /* Begin MANUAL ADDCMD TRAINING */ uint32_t init_del_offset = 0x8U; uint32_t a5_offset_status; - uint32_t rpc147_offset = 0x2U; //4 //0 input delays, cmd and clk - uint32_t rpc145_offset = 0x0U; //0 //4 + uint32_t rpc147_offset = 0x2U; /* input delays, cmd and clk */ + uint32_t rpc145_offset = 0x0U; - if( (retry_count%3)==0) + if( (retry_count % ddr_add_cmd_inc_feq[ddr_type])==0) { *refclk_offset = ddr_manual_addcmd_refclk_offset(ddr_type, refclk_sweep_index); } @@ -5829,11 +5860,11 @@ static void ddr3_address_cmd_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ while(a5_offset_status != DDR_ADD_CMD_A5_OFFSET_PASS) { a5_offset_status = DDR_ADD_CMD_A5_OFFSET_PASS; - //ADDCMD Training improvement , adds delay on DDR clock loopback path + /* ADDCMD Training improvement , adds delay on DDR clock loopback path */ CFG_DDR_SGMII_PHY->rpc147.rpc147 = init_del_offset + rpc147_offset; - //ADDCMD Training improvement , adds delay on A9 loopback path + /* ADDCMD Training improvement , adds delay on A9 loopback path */ CFG_DDR_SGMII_PHY->rpc145.rpc145 = init_del_offset + rpc145_offset; - CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x00000003U; //ENABLE DLY Control & PLL Control + CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x00000003U; /* ENABLE DLY Control & PLL Control */ uint32_t rx_a5; uint32_t rx_a5_last; @@ -5849,14 +5880,14 @@ static void ddr3_address_cmd_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ uint32_t transition_a5_max = 0U; for (j = 0U; j<16U ; j++) - { //Increase J loop to increase number of samples on transition_a5 (for noisy CA in LPDDR4) - //LOAD INDLY + { /* Increase J loop to increase number of samples on transition_a5 (for noisy CA in LPDDR4) */ + /* LOAD INDLY */ CFG_DDR_SGMII_PHY->expert_dlycnt_direction_reg1.expert_dlycnt_direction_reg1 = 0x000000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x000000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x180000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x000000U; - //LOAD OUTDLY + /* LOAD OUTDLY */ CFG_DDR_SGMII_PHY->expert_dlycnt_direction_reg1.expert_dlycnt_direction_reg1 = 0x180000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x000000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x180000U; @@ -5887,22 +5918,22 @@ static void ddr3_address_cmd_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ { if (((i - transition_a5) > 8U) && ((i - transition_ck) > 8U)) { - //break; transitions_found = 1U; } } if (transition_ck == 0U) { - if (rx_ck_last != 0x5U) //IF EDGE DETECTED + if (rx_ck_last != 0x5U) /* IF EDGE DETECTED */ if (rx_ck == 0x5U) - transition_ck=i; //SET TRANSITION DETECTED AT I + transition_ck=i; /* SET TRANSITION DETECTED AT I */ rx_ck_last=rx_ck; } else { if ( (i - transition_ck ) == 4U) - if (rx_ck != rx_ck_last) //IF rx_ck not stable after 4 increments, set transition detected to 0 (false transition) + /* IF rx_ck not stable after 4 increments, set transition detected to 0 (false transition) */ + if (rx_ck != rx_ck_last) { - transition_ck = 0U; //Continue looking for transition + transition_ck = 0U; /* Continue looking for transition */ rx_ck_last=rx_ck; } } @@ -5919,7 +5950,7 @@ static void ddr3_address_cmd_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ if ((i - transition_a5) == 4U) if(!((rx_a5 ^ rx_a5_last) & rx_a5 )) { - transition_a5=0; //Continue looking for transition + transition_a5=0; /* Continue looking for transition */ rx_a5_last=rx_a5; } } @@ -5974,7 +6005,7 @@ static void ddr3_address_cmd_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ uint32_t third_refclk=0x8U; #endif - if(transition_a5_max < TRANSITION_A5_THRESHOLD) + if(transition_a5_max < ddr_add_cmd_trans_a5_threshold[ddr_type]) { a5_offset_status |= DDR_ADD_CMD_A5_OFFSET_FAIL; } @@ -5991,7 +6022,7 @@ static void ddr3_address_cmd_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ { uint32_t k=7-l; if (difference[k] < min_diff){ - //ALISTER ADDED TO MOVE CK without changing CK/CA offset + /* MOVE CK without changing CK/CA offset */ #ifdef MOVE_CK second_refclk=(k+1)&0x7UL; second_diff=difference[second_refclk]; @@ -6008,26 +6039,40 @@ static void ddr3_address_cmd_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ #endif } #ifdef MOVE_CK - if (((retry_count)%3) == 0x1){ + if (((retry_count)%3) == add_cmd_move_order_45_deg[ddr_type]) + { min_diff=second_diff; min_refclk=second_refclk; #ifdef DEBUG_DDR_INIT - (void)uprint32(g_debug_uart, "\n\r CK_PUSH = 45 degrees", 0x0UL); + (void)uprint32(g_debug_uart, "\n\r CK_PUSH = 45 degrees",\ + add_cmd_move_order_45_deg[ddr_type]); #endif - } else if (((retry_count )%3) == 0x2){ + } + else if (((retry_count )%3) == add_cmd_move_order_90_deg[ddr_type]) + { min_diff=third_diff; min_refclk=third_refclk; #ifdef DEBUG_DDR_INIT - (void)uprint32(g_debug_uart, "\n\r CK_PUSH = 90 degrees", 0x0UL); + (void)uprint32(g_debug_uart, "\n\r CK_PUSH = 90 degrees",\ + add_cmd_move_order_90_deg[ddr_type]); #endif } +#ifdef DEBUG_DDR_INIT + else if (((retry_count )%3) == add_cmd_move_order_0_deg[ddr_type]) + { + + (void)uprint32(g_debug_uart, "\n\r CK_PUSH = 0 degrees",\ + add_cmd_move_order_0_deg[ddr_type]); + } #endif +#endif /* MOVE_CK */ + if(min_diff == 0xFFU) { a5_offset_status |= DDR_ADD_CMD_A5_OFFSET_FAIL; } if (min_refclk==0x8U) - { //If ADDCMD training fails due to extremely low frequency, use PLL to provide offset. + { /* If ADDCMD training fails due to extremely low frequency, use PLL to provide offset. */ a5_offset_status |= DDR_ADD_CMD_A5_OFFSET_FAIL_LOW_FREQ; } if(a5_offset_status == DDR_ADD_CMD_A5_OFFSET_PASS) @@ -6036,13 +6081,13 @@ static void ddr3_address_cmd_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ MSS_SCB_DDR_PLL->PLL_PHADJ = (0x00004003UL | *bclk_phase | *bclk90_phase | *refclk_phase); MSS_SCB_DDR_PLL->PLL_PHADJ = (0x00000003UL | *bclk_phase | *bclk90_phase | *refclk_phase); MSS_SCB_DDR_PLL->PLL_PHADJ = (0x00004003UL | *bclk_phase | *bclk90_phase | *refclk_phase); - //LOAD INDLY + /* LOAD INDLY */ CFG_DDR_SGMII_PHY->expert_dlycnt_direction_reg1.expert_dlycnt_direction_reg1 = 0x000000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x000000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x180000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x000000U; - //LOAD OUTDLY + /* LOAD OUTDLY */ CFG_DDR_SGMII_PHY->expert_dlycnt_direction_reg1.expert_dlycnt_direction_reg1 = 0x180000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x000000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x180000U; @@ -6054,7 +6099,7 @@ static void ddr3_address_cmd_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ CFG_DDR_SGMII_PHY->expert_dlycnt_move_reg1.expert_dlycnt_move_reg1 = 0x0U; } CFG_DDR_SGMII_PHY->expert_dlycnt_direction_reg1.expert_dlycnt_direction_reg1 = 0x000000U; - CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x00000000U; //DISABLE DLY Control & PLL Control + CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x00000000U; /* DISABLE DLY Control & PLL Control */ #ifdef DEBUG_DDR_INIT (void)uprint32(g_debug_uart, "\n\r MANUAL ADDCMD TRAINING Results:\r\n PLL OFFSET: ",min_refclk); (void)uprint32(g_debug_uart, "\n\r transition_a5_max: ", transition_a5_max); diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/common/nwc/mss_ddr.h b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/common/nwc/mss_ddr.h index f75bf85..8f4dd0f 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/common/nwc/mss_ddr.h +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/common/nwc/mss_ddr.h @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright 2019-2022 Microchip FPGA Embedded Systems Solutions. + * Copyright 2019-2023 Microchip FPGA Embedded Systems Solutions. * * SPDX-License-Identifier: MIT * @@ -437,6 +437,38 @@ typedef enum DDR_MEMORY_ACCESS_ #define TRANSITION_A5_THRESHOLD 18U #endif +#ifndef ADD_CMD_INC_FREQ_DDR3 +#define ADD_CMD_INC_FREQ_DDR3 3U +#endif +#ifndef ADD_CMD_INC_FREQ_DDR3L +#define ADD_CMD_INC_FREQ_DDR3L 3U +#endif +#ifndef ADD_CMD_INC_FREQ_DDR4 +#define ADD_CMD_INC_FREQ_DDR4 3U +#endif +#ifndef ADD_CMD_INC_FREQ_LPDDR3 +#define ADD_CMD_INC_FREQ_LPDDR3 3U +#endif +#ifndef ADD_CMD_INC_FREQ_LPDDR4 +#define ADD_CMD_INC_FREQ_LPDDR4 6U +#endif + +#ifndef ADD_CMD_TRANS_A5_THRES_DDR3 +#define ADD_CMD_TRANS_A5_THRES_DDR3 18U +#endif +#ifndef ADD_CMD_TRANS_A5_THRES_DDR3L +#define ADD_CMD_TRANS_A5_THRES_DDR3L 18U +#endif +#ifndef ADD_CMD_TRANS_A5_THRES_DDR4 +#define ADD_CMD_TRANS_A5_THRES_DDR4 18U +#endif +#ifndef ADD_CMD_TRANS_A5_THRES_LPDDR3 +#define ADD_CMD_TRANS_A5_THRES_LPDDR3 18U +#endif +#ifndef ADD_CMD_TRANS_A5_THRES_LPDDR4 +#define ADD_CMD_TRANS_A5_THRES_LPDDR4 18U +#endif + /* Value used during write leveling */ #ifndef DPC_VRGEN_H_LPDDR4_WR_LVL_VAL #define DPC_VRGEN_H_LPDDR4_WR_LVL_VAL 0x5U @@ -454,16 +486,27 @@ typedef enum DDR_MEMORY_ACCESS_ #define DDR_FULL_32BIT_CACHED_CHECK_EN 0 #endif -#if !defined (NO_PATTERN_IN_CACHE_READS) -#define NO_PATTERN_IN_CACHE_READS 1 +#if !defined (PATTERN_TEST_NUM_PATTERN_IN_CACHE_READS) +#define PATTERN_TEST_NUM_PATTERN_IN_CACHE_READS 1 #endif -#if !defined (SIZE_OF_PATTERN_TEST) -#define SIZE_OF_PATTERN_TEST 0x02000000UL +#if !defined (PATTERN_TEST_SIZE) +#define PATTERN_TEST_SIZE 0x02000000UL #endif -#if !defined (SIZE_OF_PATTERN_OFFSET) -#define SIZE_OF_PATTERN_OFFSET 12U +#if !defined (PATTERN_TEST_START_OFFSET) +#define PATTERN_TEST_START_OFFSET 12U +#endif + +#if !defined (PATTERN_TEST_NUM_OFFSET_INCS) +#define PATTERN_TEST_NUM_OFFSET_INCS 1U +#endif + +#define PATTERN_TEST_MIN_OFFSET 1U +#define PATTERN_TEST_MAX_OFFSET 16U + +#if !defined (LIBERO_SETTING_USE_CK_PUSH_DDR4_LPDDR3) +#define LIBERO_SETTING_USE_CK_PUSH_DDR4_LPDDR3 1U #endif #if !defined (DEFAULT_RPC_166_VALUE) @@ -544,24 +587,100 @@ typedef enum DDR_MEMORY_ACCESS_ * Define in mss_sw_config.h will take precedence */ #if (LIBERO_SETTING_DDR_CLK == DDR_1600_MHZ) -#if !defined (LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_ZERO) -#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_ZERO 1U +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_0_DEG_DDR3 +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_0_DEG_DDR3 0U +#endif +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_0_DEG_DDR3L +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_0_DEG_DDR3L 0U +#endif +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_0_DEG_DDR4 +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_0_DEG_DDR4 0U +#endif +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_0_DEG_LPDDR3 +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_0_DEG_LPDDR3 2U +#endif +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_0_DEG_LPDDR4 +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_0_DEG_LPDDR4 1U +#endif + +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_45_DEG_DDR3 +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_45_DEG_DDR3 1U +#endif +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_45_DEG_DDR3L +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_45_DEG_DDR3L 1U #endif -#if !defined (LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_ONE) -#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_ONE 2U +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_45_DEG_DDR4 +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_45_DEG_DDR4 1U #endif -#if !defined (LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_TWO) -#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_TWO 0U +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_45_DEG_LPDDR3 +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_45_DEG_LPDDR3 0U +#endif +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_45_DEG_LPDDR4 +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_45_DEG_LPDDR4 2U +#endif + +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_90_DEG_DDR3 +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_90_DEG_DDR3 2U +#endif +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_90_DEG_DDR3L +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_90_DEG_DDR3L 2U +#endif +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_90_DEG_DDR4 +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_90_DEG_DDR4 2U +#endif +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_90_DEG_LPDDR3 +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_90_DEG_LPDDR3 1U +#endif +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_90_DEG_LPDDR4 +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_90_DEG_LPDDR4 0U #endif #else -#if !defined (LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_ZERO) -#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_ZERO 0U +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_0_DEG_DDR3 +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_0_DEG_DDR3 0U +#endif +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_0_DEG_DDR3L +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_0_DEG_DDR3L 0U +#endif +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_0_DEG_DDR4 +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_0_DEG_DDR4 0U +#endif +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_0_DEG_LPDDR3 +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_0_DEG_LPDDR3 2U +#endif +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_0_DEG_LPDDR4 +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_0_DEG_LPDDR4 0U +#endif + +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_45_DEG_DDR3 +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_45_DEG_DDR3 1U +#endif +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_45_DEG_DDR3L +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_45_DEG_DDR3L 1U +#endif +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_45_DEG_DDR4 +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_45_DEG_DDR4 1U +#endif +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_45_DEG_LPDDR3 +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_45_DEG_LPDDR3 0U +#endif +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_45_DEG_LPDDR4 +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_45_DEG_LPDDR4 1U +#endif + +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_90_DEG_DDR3 +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_90_DEG_DDR3 2U +#endif +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_90_DEG_DDR3L +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_90_DEG_DDR3L 2U +#endif +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_90_DEG_DDR4 +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_90_DEG_DDR4 2U #endif -#if !defined (LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_ONE) -#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_ONE 1U +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_90_DEG_LPDDR3 +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_90_DEG_LPDDR3 1U #endif -#if !defined (LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_TWO) -#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_TWO 2U +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_90_DEG_LPDDR4 +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_90_DEG_LPDDR4 2U #endif #endif @@ -858,6 +977,10 @@ typedef enum DDR_MEMORY_ACCESS_ /* RESERVED [15:16] RW value= 0x0 */ /* LOCKED [31:1] RW value= 0x0 */ +#ifndef TWO_MBYTES +#define TWO_MBYTES 0x200000 +#endif + /***************************************************************************//** */ @@ -959,6 +1082,7 @@ typedef enum DDR_TRAINING_SM_ DDR_FULL_MTC_CHECK, DDR_FULL_32BIT_NC_CHECK, DDR_FULL_32BIT_CACHE_CHECK, + DDR_LOAD_PATTERN_TO_CACHE_SETUP, DDR_LOAD_PATTERN_TO_CACHE, DDR_VERIFY_PATTERN_IN_CACHE, DDR_FULL_32BIT_WRC_CHECK, @@ -1217,6 +1341,9 @@ setup_ddr_segments SEG_SETUP option ); +char * fill_cache_new_seg_address(void *dest, void *dest_end); +void clear_bootup_cache_ways(void); + #ifdef __cplusplus } diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/common/nwc/mss_ddr_debug.c b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/common/nwc/mss_ddr_debug.c index 5c8589b..afc1748 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/common/nwc/mss_ddr_debug.c +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/common/nwc/mss_ddr_debug.c @@ -668,15 +668,14 @@ uint32_t tip_register_status (mss_uart_instance_t *g_mss_uart_debug_pt) /** * Load a pattern to DDR */ -void load_ddr_pattern(uint64_t base, uint64_t size, uint32_t pattern_type, \ - volatile uint8_t pattern_offset) +void load_ddr_pattern(volatile PATTERN_TEST_PARAMS *pattern_test) { int alive = 0; uint32_t *pattern; - volatile uint32_t pattern_size; - uint8_t *p_ddr = (uint8_t *)base; + uint32_t pattern_size; + uint8_t *p_ddr = (uint8_t *)pattern_test->base; - if (pattern_type == DDR_TEST_FILL) + if (pattern_test->pattern_type == DDR_TEST_FILL) { pattern = (uint32_t *)ddr_test_pattern; pattern_size = sizeof(ddr_test_pattern); @@ -687,14 +686,19 @@ void load_ddr_pattern(uint64_t base, uint64_t size, uint32_t pattern_type, \ pattern_size = sizeof(ddr_init_pattern); } - uint32_t pattern_length = (uint32_t)(pattern_size - pattern_offset) ; + uint32_t pattern_length = (uint32_t)(pattern_size - pattern_test->pattern_offset) ; #ifdef DEBUG_DDR_INIT - uprint(g_debug_uart, (const char*)(const uint8_t*)"\r\nLoading test pattern\r\n"); - uprint32(g_debug_uart, (const char*)(const uint8_t*)"\r\npattern_length = \r\n",pattern_length); + uprint(g_debug_uart, (const char*)(const uint8_t*)\ + "\r\nLoading test pattern\r\n"); + uprint64(g_debug_uart, (const char*)(const uint8_t*)\ + "\r\npattern size = ",pattern_test->size); + uprint32(g_debug_uart, (const char*)(const uint8_t*)\ + "\r\npattern offset = ",pattern_test->pattern_offset); #endif - while(((uint64_t)p_ddr + pattern_length) <= (base + size)) + while(((uint64_t)p_ddr + pattern_length) <\ + (pattern_test->base + pattern_test->size)) { switch ( ((uint64_t)p_ddr)%8U ) @@ -702,22 +706,26 @@ void load_ddr_pattern(uint64_t base, uint64_t size, uint32_t pattern_type, \ case 0: case 4: pdma_transfer_complete(PDMA_CHANNEL0_BASE_ADDRESS); - pdma_transfer((uint64_t)p_ddr, (uint64_t)pattern, pattern_length, PDMA_CHANNEL0_BASE_ADDRESS); + pdma_transfer((uint64_t)p_ddr, (uint64_t)pattern,\ + pattern_length, PDMA_CHANNEL0_BASE_ADDRESS); break; case 1: case 5: pdma_transfer_complete(PDMA_CHANNEL1_BASE_ADDRESS); - pdma_transfer((uint64_t)p_ddr, (uint64_t)pattern, pattern_length, PDMA_CHANNEL1_BASE_ADDRESS); + pdma_transfer((uint64_t)p_ddr, (uint64_t)pattern,\ + pattern_length, PDMA_CHANNEL1_BASE_ADDRESS); break; case 2: case 6: pdma_transfer_complete(PDMA_CHANNEL2_BASE_ADDRESS); - pdma_transfer((uint64_t)p_ddr, (uint64_t)pattern, pattern_length, PDMA_CHANNEL2_BASE_ADDRESS); + pdma_transfer((uint64_t)p_ddr, (uint64_t)pattern,\ + pattern_length, PDMA_CHANNEL2_BASE_ADDRESS); break; case 3: case 7: pdma_transfer_complete(PDMA_CHANNEL3_BASE_ADDRESS); - pdma_transfer((uint64_t)p_ddr, (uint64_t)pattern, pattern_length, PDMA_CHANNEL3_BASE_ADDRESS); + pdma_transfer((uint64_t)p_ddr, (uint64_t)pattern,\ + pattern_length, PDMA_CHANNEL3_BASE_ADDRESS); break; } @@ -776,7 +784,7 @@ static void load_test_buffers(uint32_t * p_cached_ddr, uint32_t * p_not_cached_d * @param size * @return returns 1 if compare fails */ -uint32_t test_ddr(uint32_t no_of_iterations, uint32_t size) +uint32_t test_ddr(uint32_t no_of_iterations, volatile PATTERN_TEST_PARAMS *pattern_test) { uint32_t pattern_length = sizeof(ddr_test_pattern) - (3 * sizeof(uint32_t)); uint32_t * p_ddr_cached = (uint32_t *)BASE_ADDRESS_CACHED_32_DDR; @@ -821,7 +829,7 @@ uint32_t test_ddr(uint32_t no_of_iterations, uint32_t size) return error; } - if (((uint64_t)p_ddr_cached + ( 2 * pattern_length)) < (LIBERO_SETTING_DDR_32_CACHE + size)) + if (((uint64_t)p_ddr_cached + ( 2 * pattern_length)) < (LIBERO_SETTING_DDR_32_CACHE + pattern_test->size)) { p_ddr_cached += (pattern_length / sizeof(uint32_t)); p_ddr_noncached += (pattern_length / sizeof(uint32_t)); diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/common/nwc/mss_ddr_debug.h b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/common/nwc/mss_ddr_debug.h index 3bb0af8..fb1a621 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/common/nwc/mss_ddr_debug.h +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/common/nwc/mss_ddr_debug.h @@ -235,10 +235,7 @@ uint32_t no_of_regs void load_ddr_pattern ( -uint64_t base, -uint64_t size, -uint32_t pattern_type, -volatile uint8_t pattern_offset +volatile PATTERN_TEST_PARAMS *pattern_test ); /***************************************************************************//** @@ -248,7 +245,7 @@ uint32_t test_ddr ( uint32_t no_of_iterations, -uint32_t size +volatile PATTERN_TEST_PARAMS *pattern_test ); /***************************************************************************//** diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/common/nwc/mss_ddr_defs.h b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/common/nwc/mss_ddr_defs.h index 1263bc7..92857b9 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/common/nwc/mss_ddr_defs.h +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/common/nwc/mss_ddr_defs.h @@ -17,6 +17,18 @@ #ifndef SRC_PLATFORM_MPFS_HAL_NWC_MSS_DDR_DEFS_H_ #define SRC_PLATFORM_MPFS_HAL_NWC_MSS_DDR_DEFS_H_ +typedef struct PATTERN_TEST_PARAMS_ +{ + uint64_t base; + uint64_t size; + uint32_t pattern_type; + uint8_t pattern_offset; + uint8_t offset_cnt; + uint8_t num_offsets_to_try; + uint8_t padding; +} PATTERN_TEST_PARAMS; + + #define PATTERN_INCREMENTAL (0x01U << 0U) #define PATTERN_WALKING_ONE (0x01U << 1U) #define PATTERN_WALKING_ZERO (0x01U << 2U) diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/common/nwc/mss_nwc_init.c b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/common/nwc/mss_nwc_init.c index 27bde36..3ef5565 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/common/nwc/mss_nwc_init.c +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/common/nwc/mss_nwc_init.c @@ -18,7 +18,6 @@ #include #include "mpfs_hal/mss_hal.h" #include "mss_nwc_init.h" -#include "simulation.h" #ifdef DEBUG_DDR_INIT #include "drivers/mss/mss_mmuart/mss_uart.h" @@ -300,13 +299,11 @@ uint8_t mss_nwc_init(void) * The SGMII set-upset configures the external clock reference so this must * be called before configuring the MSS PLL */ - SIM_FEEDBACK0(2); sgmii_setup(); /* * Setup the MSS PLL */ - SIM_FEEDBACK0(3); mss_pll_config(); return error; diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/common/nwc/mss_sgmii.c b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/common/nwc/mss_sgmii.c index fb3f7b7..38c7e36 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/common/nwc/mss_sgmii.c +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/common/nwc/mss_sgmii.c @@ -17,7 +17,6 @@ #include #include #include "mpfs_hal/mss_hal.h" -#include "simulation.h" #ifdef MPFS_HAL_HW_CONFIG diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/common/nwc/simulation.h b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/common/nwc/simulation.h deleted file mode 100644 index a6bdf76..0000000 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/common/nwc/simulation.h +++ /dev/null @@ -1,74 +0,0 @@ -/******************************************************************************* - * Copyright 2019-2022 Microchip FPGA Embedded Systems Solutions. - * - * SPDX-License-Identifier: MIT - * - * MPFS HAL Embedded Software - * - */ - -/******************************************************************************* - * @file simulation.h - * @author Microchip-FPGA Embedded Systems Solutions - * @brief SGMII defines - */ - -#ifndef MSS_DDR_SGMII_SIMULATION_H_ -#define MSS_DDR_SGMII_SIMULATION_H_ - -/* todo: remove this file before customer distribution */ - -/***************************************************************************//** - Simulation Test commands - */ -#define DDR_SIM 0x01 -#define FLASH_FREEZE_SIM 0x02 -#define DESIGN_INF_TEST_SIM 0x04 -#define MMSIO_SIM 0x08 -#define SGMII_SIM 0x10 -#define BUS_ERROR_UNIT 0x20 -#define D_CACHE_TEST 0x40 -#define EXT_CLK_CHOICE 0x80 - -/***************************************************************************//** - SGMii Test commands -* List from Eugene -* 1. Full SGMII test- both channels enabled, external loopback and rx_lock for -* both channels. (This test is written) -* (Will do a version of this for refclk = 125 mhz also- already supported -* in sw) -* 2. SGMII test, similar to 1 , except chan1 is off. -* 3. TEST with both CHAn0 and CHAn 1 off. This is the default state for sgmii -* anyway. The SGMII PLL will not be turned on either. This is our SGMII OFF -* MODE test. -* 4. RECALIB mode on (RECAL_CNTL-reg_recal_start_en =1). Both chans off. As I -* understand this is for DDR IO recalibration. I am not sure what I check -* for here. SO I will ask Jeff. -* 5. PVT recalibration..as per Srikanths presentation...SCB reg_calib_start =1 -* and APB calib_start =1 (see my earlier email.) This allows us check status -* of calib_start and calib_lock and calib_intrpt to be checked as per -* Srikanths presentation. -* -*/ -#define SGMII_ALL_ON 0x00 -#define SGMII_CH1_OFF 0x01 -#define SGMII_ALL_OFF 0x02 -#define SGMII_RECALIB 0x03 -#define SGMII_PVT_MONITOR 0x04 -#define SGMII_CH0_OFF_CH1_ON 0x05 -#define SGMII_MAC0_LOOPBACK_TEST 0x06 -#define SGMII_TRIM_IO 0x07 -#define SGMII_RECALIB_IO 0x08 -#define SGMII_MAC1_LOOPBACK_TEST 0x09 -#define SGMII_ALL_OFF_INC_CLK 0x0A - - -#ifdef SIMULATION_TEST_FEEDBACK -#define SIM_FEEDBACK0(x) (SYSREG->TEMP0 = (uint32_t)x) -#define SIM_FEEDBACK1(x) (SYSREG->TEMP1 = (uint32_t)x) -#else -#define SIM_FEEDBACK0(x) -#define SIM_FEEDBACK1(x) -#endif - -#endif /* MSS_DDR_SGMII_SIMULATION_H_ */ diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/mpfs_hal_version.h b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/mpfs_hal_version.h index 7220857..d06ba97 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/mpfs_hal_version.h +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/mpfs_hal_version.h @@ -40,8 +40,8 @@ extern "C" { #endif #define MPFS_HAL_VERSION_MAJOR 2 -#define MPFS_HAL_VERSION_MINOR 1 -#define MPFS_HAL_VERSION_PATCH 103 +#define MPFS_HAL_VERSION_MINOR 2 +#define MPFS_HAL_VERSION_PATCH 105 #ifdef __cplusplus } diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/startup_gcc/mss_entry.S b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/startup_gcc/mss_entry.S index b1c94ab..12c3eb3 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/startup_gcc/mss_entry.S +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/startup_gcc/mss_entry.S @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright 2019-2022 Microchip FPGA Embedded Systems Solutions. + * Copyright 2019-2023 Microchip FPGA Embedded Systems Solutions. * * SPDX-License-Identifier: MIT * @@ -20,6 +20,8 @@ #include "system_startup_defs.h" #include "mpfs_hal_config/mss_sw_config.h" +#define NUM_CACHEWAYS_AT_RESET 1 + .option norvc .section .text.init,"ax", %progbits .globl reset_vector @@ -178,14 +180,6 @@ _start: csrr a0, mhartid li a1, MPFS_HAL_FIRST_HART bne a0, a1, .LOtherHartstoWFI - # clear the common heap - la a4, __heap_start - la a5, __heap_end -.init_heap: - #csrw mepc, zero - STORE x0, 0(a4) - add a4, a4, __SIZEOF_POINTER__ - blt a4, a5, .init_heap # # clear DTIM - this is required to stop memory errors on initial access by # cache @@ -197,6 +191,20 @@ _start: call .clear_dtim call .clear_l2lim .skip_mem_clear: + li a0, NUM_CACHEWAYS_AT_RESET # flush default way in case it has already + # been used by system controller loader + # (bootmode2 or 3) + call .flush_early_caching + call config_l2_cache + call end_l2_scratchpad_address # end address returned in a0 + call .clear_scratchpad + # place pattern in the common heap + la a4, __heap_start + la a5, __heap_end +.init_heap: + STORE x0, 0(a4) + add a4, a4, __SIZEOF_POINTER__ + blt a4, a5, .init_heap /* * Clear bus error unit accrued register on start-up * This is cleared by the first hart only @@ -682,8 +690,19 @@ copy_switch_code: #define END__OF_LIM 0x08200000 #define START__OF_DTM 0x01000000 #define END__OF_DTM 0x01002000 +#define START_OF_SCRATCH 0x0A000000 - +.clear_scratchpad: + // Clear the scratchpad + // + // a0 = end of scratchpad addr passed from caller + // + // Note: This must be called post calling config_l2_cache() + // + la a4, START_OF_SCRATCH # start of l2 scratchpad + mv a5, a0 # end of l2 scratchpad + // common loop used to clear memory + j 1f .clear_l2lim: // Clear the LIM // @@ -714,6 +733,54 @@ copy_switch_code: .done_clear: ret +/******************************************************************************* + * + */ + .equ L2_ZERO_DEVICE_ADDR, 0x0A000000 + .equ L2_CCACHE_ADDR, 0x02010000 + .equ FLUSH64_OFFSET, 0x200 + + // + // We want to flush anything that may be inadvertently cached + // by the actions of G5C at startup... + // + // The cache block is 64-bytes wide, and there are 4 banks * 512 sets * 16 + // ways. + // From power on, only a single way is enabled as cache (the remaining + // 15 are LIM), but this function is parameterisable (number of ways is + // passed via a0)... + // + // First, load the cache with "known" addresses by walking up L2 scratch + // with a 64-byte stride. We need to read (4 banks * 512 sets) to fill + // a single way. + // +.flush_early_caching: + // a0 = num_ways + slli a0, a0, 17 // a0' = a0 * (4 * 512 * 64) + li a5, L2_ZERO_DEVICE_ADDR + add a0, a0, a5 // a0'' = a0' + (4 * 512 * 64 * a0) + // = 0x0A000000 + (4 * 512 * 64 * num_ways) + beq a0, a5, .early_exit + +.preload_cache_with_known_addrs: + ld a3, 0(a5) + addi a5, a5, 64 + bne a5, a0, .preload_cache_with_known_addrs + + // + // Now that the cache is filled with known addresses, we can simply flush each + // known address to end up with an empty cache... + // + li a5, L2_ZERO_DEVICE_ADDR + li a3, L2_CCACHE_ADDR +.flush_known_addrs_from_cache: + sd a5, FLUSH64_OFFSET(a3) // write address to 0x02010200 (FLUSH64) + addi a5, a5, 64 + bne a5, a0, .flush_known_addrs_from_cache + +.early_exit: + ret + /* * record_ecc_error_counts on reset * These are non-zero in the coreplex. diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/startup_gcc/mss_utils.S b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/startup_gcc/mss_utils.S index 846b79f..8483a83 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/startup_gcc/mss_utils.S +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/startup_gcc/mss_utils.S @@ -185,4 +185,79 @@ config_64_copy: 2: ret + /*********************************************************************************** + * + * fill_cache_new_seg_address and flush + */ + .equ L2_CCACHE_ADDR, 0x02010000 + .equ FLUSH64_OFFSET, 0x200 + // + // We want to flush anything that may be cached + // with previous seg settings + // + // The cache block is 64-bytes wide, and there are 4 banks * 512 sets * 16 + // ways. + // We just write to the DDR cache backed address passed by the caller + // Once start and end address range covers the size of the cache, the + // previous contents of cache will be overwritten. + // + // fill_cache_new_seg_address + // a0 = dest + // a1 = dest end address + .globl fill_cache_new_seg_address + .type fill_cache_new_seg_address @function +fill_cache_new_seg_address: + mv t1,a0 + mv t2,a1 + mv t3,a0 + +.preload_cache_with_known_addrs: + sd x0, 0(t1) + ld t4, 0(t1) + addi t1, t1, 64 + blt t1, t2, .preload_cache_with_known_addrs + + // + // Now that the cache is filled with known addresses, we can simply flush + // each known address to end up with an empty cache. + // There is no requirement to clear the cache, but we will as a belt and + // braces excercise before we continue with the boot process + // + li t1, L2_CCACHE_ADDR +.flush_known_addrs_from_cache: + sd t3, FLUSH64_OFFSET(t1) // write address to 0x02010200 (FLUSH64) + addi t3, t3, 64 + blt t3, t2, .flush_known_addrs_from_cache + +.early_exit: + ret + +/*********************************************************************************** + * + * clear_64_mem - clear memory using 64 bit writes, addresses must be on 64 bit + * boundary + * + * Note: This function is useful for initializing LIM as 64 bit writes are + * required to initialize ECC. The MPFS HAL does initialize all LIM on boot from + * eNVM, but when debugging bare metal projects from LIM, only the memory associated + * with the footprint of the program is initialised. So when debugging, if LIM memory + * outside the program itself is accessed, it must be initialized if it has not been + * initialized previously by a bootloader. + * + * clear_64_mem helper function: + * a0 = start address + * a1 = end address + * + */ + .globl clear_64_mem + .type clear_64_mem @function + clear_64_mem: + mv t1, a0 # start address to clear + mv t2, a1 # end address to clear +1: + sd x0, 0(t1) + add t1, t1, __SIZEOF_POINTER__ + blt t1, t2, 1b +.done_clear: + ret diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/startup_gcc/system_startup.c b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/startup_gcc/system_startup.c index d3839d9..b89dc8c 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/startup_gcc/system_startup.c +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/startup_gcc/system_startup.c @@ -1,5 +1,5 @@ /****************************************************************************************** - * Copyright 2019-2022 Microchip FPGA Embedded Systems Solutions. + * Copyright 2019-2023 Microchip FPGA Embedded Systems Solutions. * * SPDX-License-Identifier: MIT * @@ -65,10 +65,6 @@ __attribute__((weak)) int main_first_hart(HLS_DATA* hls) * src/boards/my_hart_id = MPFS_HAL_FIRST_HART; diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/startup_gcc/system_startup.h b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/startup_gcc/system_startup.h index ff2b620..0fcc34e 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/startup_gcc/system_startup.h +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/mpfs_hal/startup_gcc/system_startup.h @@ -133,6 +133,7 @@ char * config_copy(void *dest, const void * src, size_t len); char * config_16_copy(void *dest, const void * src, size_t len); char * config_32_copy(void *dest, const void * src, size_t len); char * config_64_copy(void *dest, const void * src, size_t len); +char * clear_64_mem(uint64_t *start_address, uint64_t *end_address); void copy_section ( diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/platform_config_reference/LICENSE.md b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/platform_config_reference/LICENSE.md new file mode 100644 index 0000000..8e95095 --- /dev/null +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/platform_config_reference/LICENSE.md @@ -0,0 +1,26 @@ +# The MPFS MSS Platform Config Reference Software License + +The MPFS MSS Platform Config Reference software is released under the following +software license: + + Copyright 2019-2023 Microchip FPGA Embedded Systems Solutions. + + SPDX-License-Identifier: MIT + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/platform_config_reference/drivers_config/mss/mss_usb/mss_usb_sw_config.h b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/platform_config_reference/drivers_config/mss/mss_usb/mss_usb_sw_config.h new file mode 100644 index 0000000..b90a5dc --- /dev/null +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/platform_config_reference/drivers_config/mss/mss_usb/mss_usb_sw_config.h @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright 2019-2023 Microchip FPGA Embedded Systems Solutions. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * PolarFire SoC MSS USB Driver Stack + * + * MSS USB Driver stack configuration parameters. + * User must choose the constant definitions in this file to select the mode of + * operation. + * The constants defined in this file are used by MSS USB driver stack to + * function as per configuration. + * + * mss_usb_sw_config.h + */ + +#ifndef MSS_USB_SW_CONFIG_H_ +#define MSS_USB_SW_CONFIG_H_ + +/*-------------------------------------------------------------------------*//** + User should choose the Mode in which PolarFire SoC MSS USB should operate +*/ +/* #define MSS_USB_OTG_DUAL_ROLE_MODE */ +/* #define MSS_USB_OTG_PERIPHERAL_MODE*/ + +/* Configures the MSS USB Driver Stack to operate in USB Host mode. */ +/* #define MSS_USB_OTG_HOST_MODE */ + +/* Configures the MSS USB Driver Stack to operate in USB Device mode. */ +/* #define MSS_USB_PERIPHERAL_MODE */ + +/* Used for internal testing of the driver. Not for Application use. */ +/* #define MSS_USB_DEVICE_TEST_MODE */ + + +#endif /* MSS_USB_SW_CONFIG_H_ */ diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/platform_config_reference/linker/mpfs-ddr-loaded-by-boot-loader.ld b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/platform_config_reference/linker/mpfs-ddr-loaded-by-boot-loader.ld index 88af43e..2e4d2c4 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/platform_config_reference/linker/mpfs-ddr-loaded-by-boot-loader.ld +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/platform_config_reference/linker/mpfs-ddr-loaded-by-boot-loader.ld @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright 2019-2022 Microchip FPGA Embedded Systems Solutions. + * Copyright 2019-2023 Microchip FPGA Embedded Systems Solutions. * * SPDX-License-Identifier: MIT * diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/platform_config_reference/linker/mpfs-envm-lma-scratchpad-vma.ld b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/platform_config_reference/linker/mpfs-envm-lma-scratchpad-vma.ld index 2a5f0a3..9d1f8b0 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/platform_config_reference/linker/mpfs-envm-lma-scratchpad-vma.ld +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/platform_config_reference/linker/mpfs-envm-lma-scratchpad-vma.ld @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright 2019-2022 Microchip FPGA Embedded Systems Solutions. + * Copyright 2019-2023 Microchip FPGA Embedded Systems Solutions. * * SPDX-License-Identifier: MIT * @@ -369,7 +369,7 @@ SECTIONS * This can not be done when running from envm * This will need to be copied to ram, before any of this code is run. */ - .ram_code : + .ram_code : ALIGN(0x10) { . = ALIGN (4); __sc_load = LOADADDR (.ram_code); diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/platform_config_reference/linker/mpfs-envm.ld b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/platform_config_reference/linker/mpfs-envm.ld index c4a16ad..c4aae15 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/platform_config_reference/linker/mpfs-envm.ld +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/platform_config_reference/linker/mpfs-envm.ld @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright 2019-2022 Microchip FPGA Embedded Systems Solutions. + * Copyright 2019-2023 Microchip FPGA Embedded Systems Solutions. * * SPDX-License-Identifier: MIT * @@ -132,6 +132,17 @@ SECTIONS PROVIDE(__u54_4_itim_end = ORIGIN(u54_4_itim) + LENGTH(u54_4_itim)); . = __envm_start; + + .text_init : ALIGN(0x10) + { + *(.text.init) + *system_startup.o (.text .text* .rodata .rodata* .srodata*) + *mtrap.o (.text .text* .rodata .rodata* .srodata*) + *mss_h2f.o (.text .text* .rodata .rodata* .srodata*) + *mss_l2_cache.o (.text .text* .rodata .rodata* .srodata*) + . = ALIGN(0x10); + } >envm + .text : ALIGN(0x10) { __text_load = LOADADDR(.text); @@ -196,7 +207,7 @@ SECTIONS * This can not be done when running from envm * This will need to be copied to ram, before any of this code is run. */ - .ram_code : + .ram_code : ALIGN(0x10) { . = ALIGN (4); __sc_load = LOADADDR (.ram_code); @@ -216,7 +227,7 @@ SECTIONS .ddr_code : { . = ALIGN (4); - __ddr_load = LOADADDR (.ram_code); + __ddr_load = LOADADDR (.ddr_code); __ddr_start = .; *(.ddr_codetext) /* .ram_codetext sections (code) */ *(.ddr_codetext*) /* .ram_codetext* sections (code) */ diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/platform_config_reference/linker/mpfs-lim-lma-scratchpad-vma.ld b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/platform_config_reference/linker/mpfs-lim-lma-scratchpad-vma.ld index 7e3980f..34af389 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/platform_config_reference/linker/mpfs-lim-lma-scratchpad-vma.ld +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/platform_config_reference/linker/mpfs-lim-lma-scratchpad-vma.ld @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright 2019-2022 Microchip FPGA Embedded Systems Solutions. + * Copyright 2019-2023 Microchip FPGA Embedded Systems Solutions. * * SPDX-License-Identifier: MIT * @@ -360,7 +360,7 @@ SECTIONS * This can not be done when running from envm * This will need to be copied to ram, before any of this code is run. */ - .ram_code : + .ram_code : ALIGN(0x10) { . = ALIGN (4); __sc_load = LOADADDR (.ram_code); diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/platform_config_reference/linker/mpfs-lim.ld b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/platform_config_reference/linker/mpfs-lim.ld index 8b40be2..d1a4c71 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/platform_config_reference/linker/mpfs-lim.ld +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/platform_config_reference/linker/mpfs-lim.ld @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright 2019-2022 Microchip FPGA Embedded Systems Solutions. + * Copyright 2019-2023 Microchip FPGA Embedded Systems Solutions. * * SPDX-License-Identifier: MIT * @@ -123,6 +123,17 @@ SECTIONS PROVIDE(__u54_4_itim_end = ORIGIN(u54_4_itim) + LENGTH(u54_4_itim)); /* text: text code section */ . = __l2lim_start; + + .text_init : ALIGN(0x10) + { + *(.text.init) + *system_startup.o (.text .text* .rodata .rodata* .srodata*) + *mtrap.o (.text .text* .rodata .rodata* .srodata*) + *mss_h2f.o (.text .text* .rodata .rodata* .srodata*) + *mss_l2_cache.o (.text .text* .rodata .rodata* .srodata*) + . = ALIGN(0x10); + } > l2lim + .text : ALIGN(0x10) { __text_load = LOADADDR(.text); @@ -187,7 +198,7 @@ SECTIONS * This can not be done when running from eNVM * This will need to be copied to ram, before any of this code is run. */ - .ram_code : + .ram_code : ALIGN(0x10) { . = ALIGN (4); __sc_load = LOADADDR (.ram_code); diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/platform_config_reference/mpfs_hal_config/mss_sw_config.h b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/platform_config_reference/mpfs_hal_config/mss_sw_config.h index 29a9407..a2360a3 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/platform_config_reference/mpfs_hal_config/mss_sw_config.h +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/platform_config_reference/mpfs_hal_config/mss_sw_config.h @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright 2019-2022 Microchip FPGA Embedded Systems Solutions. + * Copyright 2019-2023 Microchip FPGA Embedded Systems Solutions. * * SPDX-License-Identifier: MIT * diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/readme.md b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/readme.md new file mode 100644 index 0000000..93db00e --- /dev/null +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/readme.md @@ -0,0 +1,56 @@ +# PolarFire® SoC platform source code + +## Repo organization + +``` + + | + |-- drivers + | |- fpga_ip + | | | . + | | | . + | |- mss + | | |- mss-ethernet-mac + | | |- mss-can + | | |- mss-gpio + | | | . + | | | . + | | | . + | | |- mss-mmc + | | |- mss-watchdog + | | |- mss-watchdog.c + | | |- mss-watchdog.h + | | + | |- off_chip + | | | . + | | | . + | | + |-- hal + | | + |-- mpfs_hal + | | + |-- platform_config_reference + | | |- linker + | | | |- mpfs-ddr-loaded-by-boot-loader.ld + | | | |- mpfs-envm-lma-scratchpad-vma.ld + | | | |- mpfs-envm.ld + | | | |- mpfs-lim-lma-scratchpad-vma.ld + | | | |- mpfs-lim.ld + | | | + | | | + | | |- mpfs_hal_config + | | |- mss_sw_config.h + | | + |-- soc_config_generator + | | + | |- mpfs_configuration_generator.py + +``` + +This repository will always contain the latest and greatest of the platform contents. Some of the example projects under [polarfire-soc-bare-metal-examples](https://mi-v-ecosystem.github.io/redirects/repo-polarfire-soc-bare-metal-examples) +may not contain all the contents or latest versions of of the contents from this repository. In such cases, please download this repository and replace the src/platform repository in the project with it. + +When you update the _platform_ repository in your project, you must make sure that the reference design (and the xml configuration) is compatible with it. + +For detailed description about the contents of the platform sub-directories and the overall bare metal software project folder structure, please refer to the +[Bare Metal Software Projects Structure](https://mi-v-ecosystem.github.io/redirects/bare-metal-project-structure_bare-metal-software-project-structure) diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/soc_config_generator/mpfs_configuration_generator.py b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/soc_config_generator/mpfs_configuration_generator.py index 3394bdb..46c6267 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/soc_config_generator/mpfs_configuration_generator.py +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-interrupt/src/platform/soc_config_generator/mpfs_configuration_generator.py @@ -15,11 +15,14 @@ # -------------------------------------------------------------------------------------------- # mpfs_configuration_generator.py version # +# 0.6.4 Added the following generated files: +# hw_mssio_mux_alternate.h +# hw_nvm_map.h # 0.6.3 target folder name change from "fpga_config" -> fpga_design config, filename -# hw_platform.h changed to fpga_design_config.h , -# bug fix related to multiple xml file selection and added libero design information -# constants in fpga_design_config.h/ removed date,version and design information from all the files -# except fpga_design_config.h +# hw_platform.h changed to fpga_design_config.h , +# bug fix related to multiple xml file selection and added libero design information +# constants in fpga_design_config.h/ removed date,version and design information from all the files +# except fpga_design_config.h # # 0.6.2 added support for multiple xml file found in input folder # /empty xml file check/ xml filename arg in current folder/ @@ -49,7 +52,7 @@ def get_script_ver(): get_xml_ver() :return: script version ''' - return "0.6.3" + return "0.6.4" @@ -71,6 +74,8 @@ def get_script_ver(): # Please note: The tag in the first column ( mss_xxx) is the same as the # directory name (/fpga_design_config/mss_xxx) # the fourth item lets program know how to format info in header file +# fm_reg - appears as reg with fields +# fm_define - appears as define with value, no fields # the six item lets program know how to format value, decimal or hex # ----------------------------------------------------------------------------- xml_tags = ('mss_memory_map,map,mem_elements,fm_define,none,hex', @@ -91,7 +96,9 @@ def get_script_ver(): 'mss_memory_map,mpu_mmc,registers,fm_struct,MMC_,hex64', 'mss_memory_map,mpu_scb,registers,fm_struct,SCB_,hex64', 'mss_memory_map,mpu_trace,registers,fm_struct,TRACE_,hex64', + 'mss_memory_map,nvm_map,registers,fm_define,none,decimal', 'mss_io,io_mux,registers,fm_reg,none,hex', + 'mss_io,io_mux_alt,registers,fm_reg,none,hex', 'mss_io,hsio,registers,fm_reg,none,hex', 'mss_sgmii,tip,registers,fm_reg,none,hex', 'mss_ddr,options,registers,fm_reg,none,hex', @@ -112,7 +119,7 @@ def get_script_ver(): # ----------------------------------------------------------------------------- # Header files to generate -# ----------------------------------------------------------------------------- +#------------------------------------------------------------------------------ header_files = ('fpga_design_config,memory_map,hw_memory.h', 'fpga_design_config,memory_map,hw_apb_split.h', 'fpga_design_config,memory_map,hw_cache.h', @@ -131,7 +138,9 @@ def get_script_ver(): 'fpga_design_config,memory_map,hw_mpu_mmc.h', 'fpga_design_config,memory_map,hw_mpu_scb.h', 'fpga_design_config,memory_map,hw_mpu_trace.h', + 'fpga_design_config,memory_map,hw_nvm_map.h', 'fpga_design_config,io,hw_mssio_mux.h', + 'fpga_design_config,io,hw_mssio_mux_alternate.h', 'fpga_design_config,io,hw_hsio_mux.h', 'fpga_design_config,sgmii,hw_sgmii_tip.h', 'fpga_design_config,ddr,hw_ddr_options.h', @@ -417,14 +426,18 @@ def generate_header( file, real_root, root, file_name, tags): WriteCopyright(real_root, headerFile, file_name, creator) start_define(headerFile, file_name) start_cplus(headerFile, file_name) - for child in root: - if child.tag == "registers": - generate_register(headerFile, child, tags) - if child.tag == "mem_elements": - generate_mem_elements(headerFile, child, tags) - for child2 in child: - if child2.tag == "registers": - generate_register(headerFile, child2, tags) + if tags != None : + for child in root: + if child.tag == "registers": + generate_register(headerFile, child, tags) + if child.tag == "mem_elements": + generate_mem_elements(headerFile, child, tags) + for child2 in child: + if child2.tag == "registers": + generate_register(headerFile, child2, tags) + else: + headerFile.write('/* No content from MSS Configurator generated for this file. */\n') + headerFile.write('/* An older version of MSS Configurator has been used. */\n') end_cplus(headerFile, file_name) end_define(headerFile, file_name) @@ -527,6 +540,8 @@ def generate_header_files(output_header_files, input_xml_file, input_xml_tags): # if found_match == 1: generate_header(file_dir, root, child1, file_name, ref_tags) + else: + generate_header(file_dir, root, child1, file_name, None) index += 1 ''' diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/application/hart0/e51.c b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/application/hart0/e51.c index 526873b..9120977 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/application/hart0/e51.c +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/application/hart0/e51.c @@ -1,9 +1,13 @@ /******************************************************************************* - * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions. + * Copyright 2019 Microchip FPGA Embedded Systems Solutions. * * SPDX-License-Identifier: MIT * - * Application code running on E51 + * @file e51.c + * + * @author Microchip FPGA Embedded Systems Solutions + * + * @brief Application code running on E51 * */ diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/application/hart1/u54_1.c b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/application/hart1/u54_1.c index 1e7353c..5bec3be 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/application/hart1/u54_1.c +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/application/hart1/u54_1.c @@ -1,12 +1,15 @@ /******************************************************************************* - * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions. + * Copyright 2019 Microchip FPGA Embedded Systems Solutions. * * SPDX-License-Identifier: MIT * - * MPFS HAL Embedded Software example + * @file u54_1.c * + * @author Microchip FPGA Embedded Systems Solutions + * + * @brief Application code running on U54_1. * PolarFire SoC MSS RTC Time example project - * Application code running on U54_1 + * */ #include diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/application/hart2/u54_2.c b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/application/hart2/u54_2.c index ee87c89..771a12b 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/application/hart2/u54_2.c +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/application/hart2/u54_2.c @@ -1,11 +1,13 @@ /******************************************************************************* - * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions. + * Copyright 2019 Microchip FPGA Embedded Systems Solutions. * * SPDX-License-Identifier: MIT * - * MPFS HAL Embedded Software example + * @file u54_2.c * - * Application code running on U54_2 + * @author Microchip FPGA Embedded Systems Solutions + * + * @brief Application code running on U54_2 */ #include diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/application/hart3/u54_3.c b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/application/hart3/u54_3.c index a4684eb..aad8ee9 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/application/hart3/u54_3.c +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/application/hart3/u54_3.c @@ -1,11 +1,13 @@ /******************************************************************************* - * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions. + * Copyright 2019 Microchip FPGA Embedded Systems Solutions. * * SPDX-License-Identifier: MIT * - * MPFS HAL Embedded Software example + * @file u54_3.c * - * Application code running on U54_3 + * @author Microchip FPGA Embedded Systems Solutions + * + * @brief Application code running on U54_3 */ #include diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/application/hart4/u54_4.c b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/application/hart4/u54_4.c index 5d3cd5b..0d95bff 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/application/hart4/u54_4.c +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/application/hart4/u54_4.c @@ -1,11 +1,13 @@ /******************************************************************************* - * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions. + * Copyright 2019 Microchip FPGA Embedded Systems Solutions. * * SPDX-License-Identifier: MIT * - * MPFS HAL Embedded Software example + * @file u54_4.c * - * Application code running on U54_4 + * @author Microchip FPGA Embedded Systems Solutions + * + * @brief Application code running on U54_4 */ #include diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/application/inc/common.h b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/application/inc/common.h index 7c9b923..4db9426 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/application/inc/common.h +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/application/inc/common.h @@ -1,7 +1,11 @@ /******************************************************************************* - * Copyright 2019-2021 Microchip FPGA Embedded Systems Solution. + * Copyright 2019 Microchip FPGA Embedded Systems Solution. * * SPDX-License-Identifier: MIT + * + * @file common.h + * + * @author Microchip FPGA Embedded Systems Solutions */ #ifndef COMMON_H_ diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/boards/icicle-kit-es/platform_config/mpfs_hal_config/mss_sw_config.h b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/boards/icicle-kit-es/platform_config/mpfs_hal_config/mss_sw_config.h index 01e5922..c42b991 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/boards/icicle-kit-es/platform_config/mpfs_hal_config/mss_sw_config.h +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/boards/icicle-kit-es/platform_config/mpfs_hal_config/mss_sw_config.h @@ -1,10 +1,13 @@ /******************************************************************************* - * Copyright 2019-2022 Microchip FPGA Embedded Systems Solutions. + * Copyright 2019 Microchip FPGA Embedded Systems Solutions. * * SPDX-License-Identifier: MIT * - * MPFS HAL Embedded Software + * @file mss_sw_config.h * + * @author Microchip FPGA Embedded Systems Solutions + * + * @brief MPFS HAL Embedded Software */ /******************************************************************************* diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/boards/icicle-kit-es/platform_config_ddr/mpfs_hal_config/mss_sw_config.h b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/boards/icicle-kit-es/platform_config_ddr/mpfs_hal_config/mss_sw_config.h index a258d2a..eb10cdb 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/boards/icicle-kit-es/platform_config_ddr/mpfs_hal_config/mss_sw_config.h +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/boards/icicle-kit-es/platform_config_ddr/mpfs_hal_config/mss_sw_config.h @@ -1,9 +1,13 @@ /******************************************************************************* - * Copyright 2019-2022 Microchip FPGA Embedded Systems Solutions. + * Copyright 2019 Microchip FPGA Embedded Systems Solutions. * * SPDX-License-Identifier: MIT * - * MPFS HAL Embedded Software + * @file mss_sw_config.h + * + * @author Microchip FPGA Embedded Systems Solutions + * + * @brief MPFS HAL Embedded Software * */ diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/drivers/mss/mss_mmuart/mss_uart.c b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/drivers/mss/mss_mmuart/mss_uart.c index a427fa0..7cd22d2 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/drivers/mss/mss_mmuart/mss_uart.c +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/drivers/mss/mss_mmuart/mss_uart.c @@ -1,12 +1,15 @@ /******************************************************************************* - * Copyright 2019-2022 Microchip FPGA Embedded Systems Solutions. + * Copyright 2019 Microchip FPGA Embedded Systems Solutions. * * SPDX-License-Identifier: MIT - * - * PolarFire SoC Microprocessor Subsystem MMUART bare metal software driver - * implementation. + * + * @file mss_uart.c + * @author Microchip FPGA Embedded Systems Solutions + * @brief PolarFire SoC Microprocessor Subsystem (MSS) MMUART bare metal + * software driver implementation. * */ + #include "mpfs_hal/mss_hal.h" #include "mss_uart_regs.h" #include "mss_uart.h" @@ -351,8 +354,11 @@ MSS_UART_irq_tx { ASSERT(pbuff != ((uint8_t*)0)); ASSERT(tx_size > 0u); + ASSERT(TX_COMPLETE == this_uart->tx_buff_size); - if ((tx_size > 0u) && (pbuff != ((uint8_t*)0))) + if ((tx_size > 0u) && + (pbuff != ((uint8_t*)0)) && + (TX_COMPLETE == this_uart->tx_buff_size)) { /* Initialize the transmit info for the UART instance with the * arguments */ @@ -360,10 +366,7 @@ MSS_UART_irq_tx this_uart->tx_buff_size = tx_size; this_uart->tx_idx = 0u; - /* assign default handler for data transfer */ - this_uart->tx_handler = default_tx_handler; - - /* enables TX interrupt */ + /* Enables TX interrupt */ this_uart->hw_reg->IER |= ETBEI_MASK; enable_irq(this_uart); } @@ -495,15 +498,6 @@ MSS_UART_disable_irq */ this_uart->hw_reg->IEM &= (uint8_t)(~(((uint32_t)irq_mask >> 4u) & ((uint32_t)IIRF_MASK))); - - if(1 == this_uart->local_irq_enabled) - { - __disable_local_irq((int8_t)MMUART0_E51_INT); - } - else - { - disable_irq(this_uart); - } } /***************************************************************************//** @@ -754,19 +748,13 @@ MSS_UART_set_tx_handler mss_uart_irq_handler_t handler ) { - ASSERT(handler != INVALID_IRQ_HANDLER); - - if (handler != INVALID_IRQ_HANDLER) + if (handler != NULL_HANDLER) { this_uart->tx_handler = handler; - - /* Make TX buffer info invalid */ - this_uart->tx_buffer = (const uint8_t*)0; - this_uart->tx_buff_size = 0u; - - /* Enable transmitter holding register Empty interrupt. */ - this_uart->hw_reg->IER |= ETBEI_MASK; - enable_irq(this_uart); + } + else + { + this_uart->tx_handler = default_tx_handler; } } @@ -1612,6 +1600,11 @@ uart_isr { (*(this_uart->tx_handler))(this_uart); } + if (this_uart->tx_idx == this_uart->tx_buff_size) + { + MSS_UART_disable_irq(this_uart, MSS_UART_TBE_IRQ); + this_uart->tx_buff_size = TX_COMPLETE; + } } break; @@ -1749,15 +1742,6 @@ default_tx_handler ++this_uart->tx_idx; } } - - /* Flag Tx as complete if all data has been pushed into the Tx FIFO. */ - if (this_uart->tx_idx == this_uart->tx_buff_size) - { - this_uart->tx_buff_size = TX_COMPLETE; - - /* disables TX interrupt */ - this_uart->hw_reg->IER &= ~ETBEI_MASK; - } } } diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/drivers/mss/mss_mmuart/mss_uart.h b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/drivers/mss/mss_mmuart/mss_uart.h index 0910aac..8bafb16 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/drivers/mss/mss_mmuart/mss_uart.h +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/drivers/mss/mss_mmuart/mss_uart.h @@ -1,87 +1,71 @@ /******************************************************************************* - * Copyright 2019-2022 Microchip FPGA Embedded Systems Solutions. + * Copyright 2019 Microchip FPGA Embedded Systems Solutions. * * SPDX-License-Identifier: MIT * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - * - * PolarFire SoC Microprocessor Subsystem MMUART bare metal software driver - * public API. + * @file mss_uart.h + * @author Microchip FPGA Embedded Systems Solutions + * @brief PolarFire SoC Microprocessor Subsystem (MSS) MMUART bare metal + * software driver public API. * */ + /*=========================================================================*//** - @mainpage PolarFire SoC MSS UART Bare Metal Driver. - + @mainpage PolarFire® SoC MSS UART Bare Metal Driver. + ============================================================================== Introduction ============================================================================== - The PolarFire SoC Microprocessor subsystem (MSS) includes five multi-mode UART - (MMUART) peripherals for serial communication. This driver provides a set of - functions for controlling the MSS MMUARTs as part of a bare metal system + The PolarFire® SoC Microprocessor Subsystem (MSS) includes five multi-mode + UART(MMUART) peripherals for serial communication. This driver provides a set + of functions to control the MSS MMUARTs as part of a bare metal system where no operating system is available. These drivers can be adapted for use as part of an operating system, but the implementation of the adaptation layer between this driver and the operating system's driver model is outside the scope of this driver. - Note: MSS UART is synonymous with MSS MMUART in this document. - + Note: MSS UART and MSS MMUART are synonymous in this document. + ============================================================================== Hardware Flow Dependencies ============================================================================== The configuration of all features of the MSS MMUART peripherals is covered by - this driver with the exception of the PolarFire SoC IOMUX configuration. - PolarFire SoC allows multiple non-concurrent uses of some external pins - through IOMUX configuration. This feature allows optimization of external pin + this driver with the exception of the PolarFire® SoC IOMUX configuration. + PolarFire® SoC allows multiple non-concurrent uses of external pins + through IOMUX configuration. This feature allows optimization of external pin usage by assigning external pins for use by either the microprocessor subsystem or the FPGA fabric. The MSS MMUART serial signals are routed through - IOMUXs to the PolarFire SoC device external pins. The MSS MMUART serial - signals may also be routed through IOMUXs to the PolarFire SoC FPGA fabric. - For more information on IOMUX, refer to the I/O Configuration section of the - PolarFire SoC Microprocessor Subsystem (MSS) User's Guide. + IOMUXs to the PolarFire® SoC device external pins. The MSS MMUART serial + signals may also be routed through IOMUXs to the PolarFire® SoC FPGA fabric. + For more information on IOMUX, see the I/O Configuration section of the + PolarFire® SoC Microprocessor Subsystem (MSS) User's Guide. - The IOMUXs are configured using the PolarFire SoC MSS configurator tool. You + The IOMUXs are configured using the PolarFire® SoC MSS configurator tool. You must ensure that the MSS MMUART peripherals are enabled and configured in the - PolarFire SoC MSS configurator if you wish to use them. For more information - on IOMUXs, refer to the IOMUX section of the PolarFire SoC microprocessor + PolarFire® SoC MSS configurator if you wish to use them. For more information + on IOMUXs, see the IOMUX section of the PolarFire® SoC Microprocessor Subsystem (MSS) User's Guide. - On PolarFire SoC an AXI switch forms a bus matrix interconnect among multiple - masters and multiple slaves. Five RISC-V CPUs connect to the Master ports - M10 to M14 of the AXI switch. By default, all the APB peripherals are - accessible on AXI-Slave 5 of the AXI switch via the AXI to AHB and AHB to APB - bridges (referred as main APB bus). However, to support logical separation in - the Asymmetric Multi-Processing (AMP) mode of operation, the APB peripherals - can alternatively be accessed on the AXI-Slave 6 via the AXI to AHB and AHB to + On PolarFire® SoC, an AXI switch forms a bus matrix interconnect among + multiple masters and multiple slaves. Five RISC-V CPUs connect to the Master + ports M10 to M14 of the AXI switch. By default, all the APB peripherals are + accessible on AXI-Slave 5 of the AXI switch using the AXI to AHB and AHB to APB + bridges (referred as main APB bus). However, to support logical separation in + the Asymmetric Multi-Processing (AMP) mode of operation, the APB peripherals + can alternatively be accessed on the AXI-Slave 6 using the AXI to AHB and AHB to APB bridges (referred as the AMP APB bus). - - Application must make sure that the desired MMUART instance is appropriately - configured on one of the APB bus described above by configuring the PolarFire - SoC system registers (SYSREG) as per the application need and that the - appropriate data structures are provided to this driver as parameter to the - functions provided by this driver. - - The base address and register addresses are defined in this driver as - constants. The interrupt number assignment for the MSS MMUART peripherals are - defined as constants in the MPFS HAL. You must ensure that the latest MPFS HAL - is included in the project settings of the SoftConsole tool chain and that it + + Application must make sure that the desired MMUART instance is appropriately + configured on one of the APB bus as described above by configuring the + PolarFire® SoC system registers (SYSREG) as per the application need and that + the appropriate data structures are provided to this driver as parameter to + the functions provided by this driver. + + The base address and register addresses are defined in this driver as + constants. The interrupt number assignment for the MSS MMUART peripherals are + defined as constants in the MPFS HAL. You must ensure that the latest MPFS HAL + is included in the project settings of the SoftConsole tool chain and that it is generated into your project. - + ============================================================================== Theory of Operation ============================================================================== @@ -89,7 +73,7 @@ - Initialization and configuration functions - Polled transmit and receive functions - Interrupt driven transmit and receive functions - + -------------------------------- Initialization and Configuration -------------------------------- @@ -98,17 +82,17 @@ - LIN mode - IrDA mode - Smartcard or ISO 7816 mode - + The MSS MMUART driver provides the MSS_UART_init(), MSS_UART_lin_init(), - MSS_UART_irda_init() and MSS_UART_smartcard_init() functions to initialize the + MSS_UART_irda_init(), and MSS_UART_smartcard_init() functions to initialize the MSS MMUARTs for operation in one of these modes. One of these initialization - functions must be called before any other MSS MMUART driver functions can be - called. The MSS MMUART operating modes are mutually exclusive; therefore only - one of the initialization functions must be called. The first parameter of the - initialization functions is a pointer to one of ten global data structures + functions must be called before calling any other MSS MMUART driver functions. + The MSS MMUART operating modes are mutually exclusive; therefore, + only one of the initialization functions can be called. The first parameter of + the initialization functions is a pointer to one of ten global data structures used to store state information for each MSS MMUART. A pointer to these data structures is also used as the first parameter to many of the driver functions - to identify which MSS MMUART will be used by the called function. The names of + to identify which MSS MMUART is used by the called function. The names of these data structures are: - g_mss_uart0_lo - g_mss_uart1_lo @@ -120,27 +104,27 @@ - g_mss_uart2_hi - g_mss_uart3_hi - g_mss_uart4_hi - - Therefore, any call to an MSS MMUART function should be of the form + + Therefore, any call to an MSS MMUART function should be of the form MSS_UART_function_name( &g_mss_uart0_lo, ... ) or MSS_UART_function_name( &g_mss_uart1_hi, ... ). - - UART or USART Mode - For the UART or USART modes of operation, the MSS MMUART driver is initialized - through a call to the MSS_UART_init() function. This function takes the UART's + + UART or USART Mode + For the UART or USART modes of operation, call the MSS_UART_init() function to + initialize the MSS MMUART instance. This function takes the UART's configuration as its parameters. The MSS_UART_init() function must be called - before any other MSS MMUART driver functions can be called. + before calling any other MSS MMUART driver functions. The MSS_UART_init() function configures the baud rate based on the input baud - rate parameter and if possible uses a fractional baud rate for greater - precision. This function disables the LIN, IrDA and SmartCard modes. - - LIN mode - For the LIN mode of operation, the MSS MMUART driver is initialized through a - call to the MSS_UART_lin_init() function. This function takes the LIN node's + rate parameter and, if possible, uses a fractional baud rate for greater + precision. This function disables the LIN, IrDA, and SmartCard modes. + + LIN Mode + For the LIN mode of operation, call the MSS_UART_lin_init() function to + initialize the MSS MMUART instance. This function takes the LIN node's configuration as its parameters. The MSS_UART_lin_init() function must be - called before any other MSS MMUART driver functions can be called. The + called before calling any other MSS MMUART driver functions. The MSS_UART_lin_init() function configures the baud rate based on the input baud - rate parameter and if possible uses a fractional baud rate for greater + rate parameter and, if possible, uses a fractional baud rate for greater precision. This function disables the IrDA and SmartCard modes. The driver also provides the following LIN mode configuration functions: - MSS_UART_set_break() @@ -148,36 +132,37 @@ - MSS_UART_set_pidpei_handler() - MSS_UART_set_linbreak_handler() - MSS_UART_set_linsync_handler() - - Note: These LIN mode configuration functions can only be called after the - MSS_UART_lin_init() function is called. - - IrDA mode - For the IrDA mode of operation, the driver is initialized through a call to - the MSS_UART_irda_init() function. This function takes the IrDA node's + + Note: These LIN mode configuration functions can only be called after calling + the MSS_UART_lin_init() function. + + IrDA Mode + For the IrDA mode of operation, call the MSS_UART_irda_init() function to + initialize the MSS MMUART instance. This function takes the IrDA node's configuration as its parameters. The MSS_UART_irda_init() function must be - called before any other MSS MMUART driver functions can be called. The + called before calling any other MSS MMUART driver functions. The MSS_UART_irda_init() function configures the baud rate based on the input baud - rate parameter and if possible uses a fractional baud rate for greater + rate parameter and, if possible, uses a fractional baud rate for greater precision. This function disables the LIN and SmartCard modes. - - Smartcard or ISO 7816 mode - For the Smartcard or ISO 7816 mode of operation, the driver is initialized - through a call to the MSS_UART_smartcard_init() function. This function takes - the smartcard configuration as its parameters. The MSS_UART_smartcard_init() - function must be called before any other MSS MMUART driver functions can be - called. The MSS_UART_smartcard_init() function configures the baud rate based - on the input baud rate parameter and if possible uses a fractional baud rate - for greater precision. This function disables the LIN and IrDA modes. - The driver also provides the following Smartcard mode configuration functions: + + Smartcard or ISO 7816 Mode + For the Smartcard or ISO 7816 mode of operation, call the + MSS_UART_smartcard_init() function to initialize the MSS MMUART instance. This + function takes the smartcard configuration as its parameters. The + MSS_UART_smartcard_init() function must be called before calling any other + MSS MMUART driver functions. The MSS_UART_smartcard_init() function configures + the baud rate based on the input baud rate parameter and, if possible, uses a + fractional baud rate for greater precision. This function disables the LIN and + IrDA modes. The driver also provides the following Smartcard mode + configuration functions: - MSS_UART_enable_halfduplex() - MSS_UART_disable_halfduplex() - MSS_UART_set_nack_handler() - + Note: These Smartcard mode configuration functions can only be called after - the MSS_UART_smartcard_init() function is called. - - Common Configuration Functions + calling the MSS_UART_smartcard_init() function. + + Common Configuration Functions The driver also provides the configuration functions that can be used with all MSS MMUART operating modes. These common configuration functions are as follows: @@ -195,47 +180,47 @@ - MSS_UART_set_filter_length() - MSS_UART_enable_afm() - MSS_UART_disable_afm() - - Note: These configuration functions can only be called after one of the - MSS_UART_init(), MSS_UART_lin_init(), MSS_UART_irda_init() or - MSS_UART_smartcard_init() functions is called. - - -------------------------------------- + + Note: These configuration functions can only be called after calling one of + the MSS_UART_init(), MSS_UART_lin_init(), MSS_UART_irda_init(), or + MSS_UART_smartcard_init() function. + + -------------------------------------- Polled Transmit and Receive Operations -------------------------------------- - The driver can be used to transmit and receive data once initialized. + The driver can be used to transmit and receive data once initialized. Data is transmitted using the MSS_UART_polled_tx() function. This function is - blocking, meaning that it will only return once the data passed to the + blocking, which means that it will only return once the data passed to the function has been sent to the MSS MMUART hardware transmitter. Data received by the MSS MMUART hardware receiver can be read by the MSS_UART_get_rx() - function. + function. The MSS_UART_polled_tx_string() function is provided to transmit a NUL ('\0') - terminated string in polled mode. This function is blocking, meaning that it - will only return once the data passed to the function has been sent to the MSS - MMUART hardware transmitter. + terminated string in polled mode. This function is blocking, which means that + it will only return once the data passed to the function has been sent to the + MSS MMUART hardware transmitter. The MSS_UART_fill_tx_fifo() function fills the MSS MMUART hardware transmit FIFO with data from a buffer passed as a parameter and returns the number of bytes transferred to the FIFO. If the transmit FIFO is not empty when the - MSS_UART_fill_tx_fifo() function is called it returns immediately without + MSS_UART_fill_tx_fifo() function is called, it returns immediately without transferring any data to the FIFO. - + --------------------------- Interrupt Driven Operations --------------------------- - The driver can also transmit or receive data under interrupt control, freeing - your application to perform other tasks until an interrupt occurs indicating - that the driver's attention is required. - - Local or PLIC interrupt: - PolarFire SoC architecture provides flexibility in terms of how the MMUART - interrupt is seen by the PolarFire SoC Core Complex. Each of the 5 MMUART - instance interrupt line is connected to the PolarFire SoC Core Complex PLIC. + The driver can also transmit or receive data under interrupt control, which + frees your application to perform other tasks until an interrupt occurs, + which indicates that the driver's attention is required. + + Local or PLIC Interrupt + PolarFire® SoC architecture provides flexibility in terms of how the MMUART + interrupt is seen by the PolarFire® SoC Core Complex. Each of the five MMUART + instance interrupt lines is connected to the PolarFire® SoC Core Complex PLIC. The MMUART0 instance interrupt line is also available as local interrupt on E51 processor. The MMUART1 instance interrupt onwards are available as local - interrupt on the U54_1 processor onwards. e.g. MMUART2 interrupt is available - as local interrupt on U54_2. + interrupt on the U54_1 processor onwards. For example MMUART2 interrupt is + available as local interrupt on U54_2 and so on. - Interrupt Handlers + Interrupt Handlers The MSS MMUART driver supports all types of interrupt triggered by the MSS MMUART. The driver's internal top level interrupt handler identifies the source of the MSS MMUART interrupt and calls the corresponding lower level @@ -243,73 +228,69 @@ to the MSS_UART_set_rx_handler(), MSS_UART_set_tx_handler(), MSS_UART_set_rxstatus_handler(), and MSS_UART_set_modemstatus_handler() functions. You are responsible for creating these lower level interrupt - handlers as part of your application program and registering them with the - driver. - Note: The PolarFire SoC HAL defines the interrupt handler functions for all - 5 MMUART instances(with weak linkage) and assigns them as the interrupt - service routines (ISR) for the MSS MMUART interrupt inputs to the - PolarFire SoC Core Complex PLIC or the Local interrupts on each of the - respective CPUs. The MSS MMUART driver provides the implementation - functions all these ISRs from which it calls its own internal top level, - interrupt handler function. - + handlers as part of your application and registering them with the + driver. + Note: The PolarFire® SoC HAL defines the interrupt handler functions for all + five MMUART instances (with weak linkage) and assigns them as the + interrupt service routines (ISR) for the MSS MMUART interrupt inputs to + the PolarFire® SoC Core Complex PLIC or the Local interrupts on each of + the respective CPUs. The MSS MMUART driver provides the implementation + functions to all these ISRs from which it calls its own internal top + level, interrupt handler function. + The MSS_UART_enable_irq() and MSS_UART_disable_irq() functions are used to enable or disable the received line status, received data available/character - time-out, transmit holding register empty and modem status interrupts at the - MSS MMUART level. The MSS_UART_enable_irq() function also enables the MSS - MMUART instance interrupt at the PolarFire SoC Core Complex level. - - Note that the MSS_UART_enable_irq() and MSS_UART_disable_irq() and all the + time-out, transmit holding register empty, and modem status interrupts at the + MSS MMUART level. + + Note: MSS_UART_enable_irq(), MSS_UART_disable_irq(), and all the calls to set the handler functions assume that the MMUART interrupt is - connected to the PolarFire SoC Core Complex PLIC. If you want the MMUART - interrupt to appear as a local interrupt to the corresponding HART then you + connected to the PolarFire® SoC Core Complex PLIC. If you want the MMUART + interrupt to appear as a local interrupt to the corresponding hart then you must explicitly call the MSS_UART_enable_local_irq() function. This function - will disable the PLIC interrupt (if it was previously enable) and enable the - local interrupt on the HART on which this function is being executed. + disables the PLIC interrupt (if it was previously enable) and enable the + local interrupt on the hart on which this function is being executed. - Transmitting Data - Interrupt-driven transmit is initiated by a call to MSS_UART_irq_tx(), - specifying the block of data to transmit. Your application is then free to - perform other tasks and inquire later whether transmit has completed by + Transmitting Data + Interrupt-driven transmit is initiated by calling MSS_UART_irq_tx(), + that specifies the block of data to transmit. Your application is then free to + perform other tasks and inquire later whether transmit is complete by calling the MSS_UART_tx_complete() function. The MSS_UART_irq_tx() function enables the UART's transmit holding register empty (THRE) interrupt and then, - when the interrupt goes active, the driver's default THRE interrupt handler - transfers the data block to the UART until the entire block is transmitted. + when the interrupt goes active, the driver's THRE interrupt handler + transfers the data block to the UART until the entire block is transmitted. Note: You can use the MSS_UART_set_tx_handler() function to assign an - alternative handler to the THRE interrupt. In this case, you must not - use the MSS_UART_irq_tx() function to initiate the transmit, as this - will re-assign the driver's default THRE interrupt handler to the THRE - interrupt. Instead, your alternative THRE interrupt handler must include - a call to the MSS_UART_fill_tx_fifo() function to transfer the data to - the UART. - - Receiving Data + alternative handler to the THRE interrupt. In this case, your + alternative THRE interrupt handler must call MSS_UART_fill_tx_fifo() + to transfer the data to the UART. + + Receiving Data Interrupt-driven receive is performed by first calling - MSS_UART_set_rx_handler() to register a receive handler function that will be + MSS_UART_set_rx_handler() to register a receive handler function that is called by the driver whenever receive data is available. You must provide this - receive handler function which must include a call to the MSS_UART_get_rx() + receive handler function which must call the MSS_UART_get_rx() function to actually read the received data. - + ----------- UART Status ----------- - The function MSS_UART_get_rx_status() is used to read the receiver error + The function MSS_UART_get_rx_status() reads the receiver error status. This function returns the overrun, parity, framing, break, and FIFO - error status of the receiver. - The function MSS_UART_get_tx_status() is used to read the transmitter status. + error status of the receiver. + The function MSS_UART_get_tx_status() reads the transmitter status. This function returns the transmit empty (TEMT) and transmit holding register - empty (THRE) status of the transmitter. - The function MSS_UART_get_modem_status() is used to read the modem status + empty (THRE) status of the transmitter. + The function MSS_UART_get_modem_status() reads the modem status flags. This function returns the current value of the modem status register. - + -------- Loopback -------- - The MSS_UART_set_loopback() function can be used to locally loopback the Tx + The MSS_UART_set_loopback() function is used to locally loopback the Tx and Rx lines of a UART. This is not to be confused with the loopback of UART0 to UART1, which can be achieved through the microprocessor subsystem's system registers. - + *//*=========================================================================*/ #ifndef __MSS_UART_H_ #define __MSS_UART_H_ 1 @@ -326,8 +307,9 @@ extern "C" { Baud rates ========== The following definitions are used to specify standard baud rates as a - parameter to the MSS_UART_init() function. - + parameter to the MSS_UART_init(), MSS_UART_lin_init(), MSS_UART_irda_init(), + and MSS_UART_smartcard_init() functions. + | Constant | Description | |----------------------|------------------| | MSS_UART_110_BAUD | 110 baud rate | @@ -344,7 +326,7 @@ extern "C" { | MSS_UART_230400_BAUD | 230400 baud rate | | MSS_UART_460800_BAUD | 460800 baud rate | | MSS_UART_921600_BAUD | 921600 baud rate | - + */ #define MSS_UART_110_BAUD 110U #define MSS_UART_300_BAUD 300U @@ -364,16 +346,17 @@ extern "C" { /***************************************************************************//** Data Bits Length ================ - The following defines are used to build the value of the MSS_UART_init() - function line_config parameter. - + The following defines are used to build the value of the MSS_UART_init(), + MSS_UART_lin_init(), MSS_UART_irda_init(), and MSS_UART_smartcard_init() + functions line_config parameter. + | Constant | Description | |----------------------|----------------------------| | MSS_UART_DATA_5_BITS | 5 bits of data transmitted | | MSS_UART_DATA_6_BITS | 6 bits of data transmitted | | MSS_UART_DATA_7_BITS | 7 bits of data transmitted | | MSS_UART_DATA_8_BITS | 8 bits of data transmitted | - + */ #define MSS_UART_DATA_5_BITS ((uint8_t) 0x00) #define MSS_UART_DATA_6_BITS ((uint8_t) 0x01) @@ -383,9 +366,10 @@ extern "C" { /***************************************************************************//** Parity ====== - The following defines are used to build the value of the MSS_UART_init() - function line_config parameter. - + The following defines are used to build the value of the MSS_UART_init(), + MSS_UART_lin_init(), MSS_UART_irda_init(), and MSS_UART_smartcard_init() + functions line_config parameter. + | Constant | Description | |-------------------------|--------------------------| | MSS_UART_NO_PARITY | No parity | @@ -404,15 +388,16 @@ extern "C" { /***************************************************************************//** Number of Stop Bits =================== - The following defines are used to build the value of the MSS_UART_init() - function line_config parameter. - + The following defines are used to build the value of the MSS_UART_init(), + MSS_UART_lin_init(), MSS_UART_irda_init(), and MSS_UART_smartcard_init() + functions line_config parameter. + | Constant | Description | |---------------------------|--------------------------| - | MSS_UART_ONE_STOP_BIT | One stop bit | - | MSS_UART_ONEHALF_STOP_BIT | One and a half stop bits | - | MSS_UART_TWO_STOP_BITS | Two stop bits | - + | MSS_UART_ONE_STOP_BIT | One Stop bit | + | MSS_UART_ONEHALF_STOP_BIT | One and a half Stop bits | + | MSS_UART_TWO_STOP_BITS | Two Stop bits | + */ #define MSS_UART_ONE_STOP_BIT ((uint8_t) 0x00) #define MSS_UART_ONEHALF_STOP_BIT ((uint8_t) 0x04) @@ -425,8 +410,8 @@ extern "C" { These bit mask constants are used with the return value of the MSS_UART_get_rx_status() function to find out if any errors occurred while receiving data. - - + + | Constant | Description | |------------------------|--------------------------------------------| | MSS_UART_NO_ERROR | No error bit mask (0x00) | @@ -452,13 +437,13 @@ extern "C" { The following definitions are used to determine the UART transmitter status. These bit mask constants are used with the return value of the MSS_UART_get_tx_status() function to find out the status of the transmitter. - + | Constant | Description | |------------------|----------------------------------------------------| | MSS_UART_TX_BUSY | Transmitter busy (0x00) | | MSS_UART_THRE | Transmitter holding register empty bit mask (0x20) | | MSS_UART_TEMT | Transmitter empty bit mask (0x40) | - + */ #define MSS_UART_TX_BUSY ((uint8_t) 0x00) #define MSS_UART_THRE ((uint8_t) 0x20) @@ -471,7 +456,7 @@ extern "C" { mask constants are used with the return value of the MSS_UART_get_modem_status() function to find out the modem status of the UART. - + | Constant | Description | |---------------|-------------------------------------------------| | MSS_UART_DCTS | Delta clear to send bit mask (0x01) | @@ -508,8 +493,8 @@ typedef uint16_t mss_uart_irq_t; MMUART interrupts. They are used to build the value of the irq_mask parameter for the MSS_UART_enable_irq() and MSS_UART_disable_irq() functions. A bitwise OR of these constants is used to enable or disable multiple interrupts. - - + + | Constant | Description | |--------------------|---------------------------------------------------------------| | MSS_UART_RBF_IRQ | Receive Data Available Interrupt bit mask (0x001) | @@ -569,7 +554,7 @@ typedef enum { /***************************************************************************//** IrDA input / output polarity. - This enumeration specifies the RZI modem polarity for input and output signals. + This enumeration specifies the RZI modem polarity for input and output signals. This is passed as parameters in MSS_UART_irda_init() function. */ typedef enum { @@ -581,7 +566,7 @@ typedef enum { /***************************************************************************//** IrDA input / output pulse width. - This enumeration specifies the RZI modem pulse width for input and output + This enumeration specifies the RZI modem pulse width for input and output signals. This is passed as parameters in MSS_UART_irda_init() function. */ typedef enum { @@ -593,8 +578,8 @@ typedef enum { /***************************************************************************//** Tx / Rx endianess. - This enumeration specifies the MSB first or LSB first for MSS UART transmitter - and receiver. The parameter of this type shall be passed in + This enumeration specifies the MSB first or LSB first for MSS UART transmitter + and receiver. The parameter of this type shall be passed in MSS_UART_set_rx_endian()and MSS_UART_set_tx_endian() functions. */ typedef enum { @@ -606,7 +591,7 @@ typedef enum { /***************************************************************************//** Glitch filter length. - This enumeration specifies the glitch filter length. The function + This enumeration specifies the glitch filter length. The function MSS_UART_set_filter_length() accepts the parameter of this type. */ typedef enum { @@ -624,7 +609,7 @@ typedef enum { /***************************************************************************//** TXRDY and RXRDY mode. - This enumeration specifies the TXRDY and RXRDY signal modes. The function + This enumeration specifies the TXRDY and RXRDY signal modes. The function MSS_UART_set_ready_mode() accepts the parameter of this type. */ typedef enum { @@ -636,8 +621,8 @@ typedef enum { /***************************************************************************//** USART mode of operation. - This enumeration specifies the mode of operation of MSS UART when operating - as USART. The function MSS_UART_set_usart_mode() accepts the parameter of this + This enumeration specifies the mode of operation of MSS UART when operating + as USART. The function MSS_UART_set_usart_mode() accepts the parameter of this type. */ typedef enum { @@ -666,23 +651,21 @@ typedef enum { } mss_uart_num_t; /***************************************************************************//** - MSS UART instance type. - This is type definition for MSS UART instance. You need to create and + This is the type definition for MSS UART instance. You need to create and maintain a record of this type. This holds all data regarding the MSS UART - instance + instance. */ typedef struct mss_uart_instance mss_uart_instance_t; /***************************************************************************//** - Interrupt handler prototype. This typedef specifies the function prototype for MSS UART interrupt handlers. All interrupt handlers registered with the MSS UART driver must be of this type. The interrupt handlers are registered with the driver through the MSS_UART_set_rx_handler(), MSS_UART_set_tx_handler(), MSS_UART_set_rxstatus_handler(), and MSS_UART_set_modemstatus_handler() - functions. - The this_uart parameter is a pointer to either g_mss_uart0 or g_mss_uart1 to - identify the MSS UART to associate with the handler function. + functions. + The this_uart parameter is a pointer to the MMUART instance to + associate with the handler function. */ typedef void (*mss_uart_irq_handler_t)( mss_uart_instance_t * this_uart ); @@ -778,6 +761,9 @@ struct mss_uart_instance{ uint8_t lineconfig; /*!< Line configuration parameters. */ uint8_t status; /*!< Sticky line status. */ + /* Padding bytes for data alignment. */ + uint8_t padding0[2]; /*!< Padding bytes for data alignment. */ + /* transmit related info (used with interrupt driven transmit): */ const uint8_t * tx_buffer; /*!< Pointer to transmit buffer. */ uint32_t tx_buff_size; /*!< Transmit buffer size. */ @@ -801,7 +787,8 @@ struct mss_uart_instance{ mss_uart_irq_handler_t break_handler; /*!< Pointer to user registered LIN break handler. */ /* LIN sync detection interrupt handler */ mss_uart_irq_handler_t sync_handler; /*!< Pointer to user registered LIN sync detection handler. */ - uint8_t local_irq_enabled; /*!< check if local interrupt were enabled on this instance*/ + uint8_t local_irq_enabled; /*!< Check if local interrupt were enabled on this instance. */ + uint8_t padding1[7]; /*!< Padding bytes for data alignment. */ void* user_data; /*!< Pointer to user provided pointer for user specific use. */ }; @@ -827,24 +814,23 @@ extern mss_uart_instance_t g_mss_uart4_hi; /***************************************************************************//** - The MSS_UART_init() function initializes and configures one of the PolarFire SoC - MSS UARTs with the configuration passed as a parameter. The configuration - parameters are the baud_rate which is used to generate the baud value and the - line_config which is used to specify the line configuration (bit length, - stop bits and parity). - + The MSS_UART_init() function initializes and configures one of the PolarFire® + SoC MSS UARTs with the configuration passed as parameters. The configuration + parameters are the baud_rate, which generates the baud value, and + the line_config, which specifies the line configuration (bit length, + Stop bits, and parity). + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. - - Note that if you are using the UART on the AMP APB bus, the hardware + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware configuration to connect UART on AMP APB bus must already be done by the application using SYSREG registers before initializing the UART instance structure. @@ -865,40 +851,35 @@ extern mss_uart_instance_t g_mss_uart4_hi; - MSS_UART_115200_BAUD - MSS_UART_230400_BAUD - MSS_UART_460800_BAUD - - MSS_UART_921600_BAUD - + - MSS_UART_921600_BAUD Alternatively, any nonstandard baud rate can be specified by simply passing the actual required baud rate as the value for this parameter. @param line_config - The line_config parameter is the line configuration specifying the bit length, - number of stop bits and parity settings. - + The line_config parameter is the line configuration that specifies the bit + length, number of Stop bits, and parity settings. This is a bitwise OR of one value from each of the following groups of allowed values: - - One of the following to specify the transmit/receive data bit length: - - MSS_UART_DATA_5_BITS - - MSS_UART_DATA_6_BITS, - - MSS_UART_DATA_7_BITS - - MSS_UART_DATA_8_BITS - - One of the following to specify the parity setting: - - MSS_UART_NO_PARITY - - MSS_UART_EVEN_PARITY - - MSS_UART_ODD_PARITY - - MSS_UART_STICK_PARITY_0 - - MSS_UART_STICK_PARITY_1 - - One of the following to specify the number of stop bits: - - MSS_UART_ONE_STOP_BIT - - MSS_UART_ONEHALF_STOP_BIT - - MSS_UART_TWO_STOP_BITS + - One of the following to specify the transmit/receive data bit length: + - MSS_UART_DATA_5_BITS + - MSS_UART_DATA_6_BITS + - MSS_UART_DATA_7_BITS + - MSS_UART_DATA_8_BITS + - One of the following to specify the parity setting: + - MSS_UART_EVEN_PARITY + - MSS_UART_NO_PARITY + - MSS_UART_ODD_PARITY + - MSS_UART_STICK_PARITY_0 + - MSS_UART_STICK_PARITY_1 + - One of the following to specify the number of Stop bits: + - MSS_UART_ONE_STOP_BIT + - MSS_UART_ONEHALF_STOP_BIT + - MSS_UART_TWO_STOP_BITS @return This function does not return a value. - Example: + @example @code #include "mss_uart.h" @@ -907,7 +888,7 @@ extern mss_uart_instance_t g_mss_uart4_hi; MSS_UART_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT); - + return(0); } @endcode @@ -921,23 +902,22 @@ MSS_UART_init ); /***************************************************************************//** - The MSS_UART_lin_init() function is used to initialize the MSS UART for - LIN mode of operation. The configuration parameters are the baud_rate which is - used to generate the baud value and the line_config which is used to specify - the line configuration (bit length, stop bits and parity). - + The MSS_UART_lin_init() function initializes the MSS UART for + LIN mode of operation. The configuration parameters are the baud_rate, which is + used to generate the baud value, and the line_config, which specifies + the line configuration (bit length, Stop bits and parity). + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. - - Note that if you are using the UART on the AMP APB bus, the hardware + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware configuration to connect UART on AMP APB bus must already be done by the application using SYSREG registers before initializing the UART instance structure. @@ -958,40 +938,35 @@ MSS_UART_init - MSS_UART_115200_BAUD - MSS_UART_230400_BAUD - MSS_UART_460800_BAUD - - MSS_UART_921600_BAUD - + - MSS_UART_921600_BAUD Alternatively, any nonstandard baud rate can be specified by simply passing the actual required baud rate as the value for this parameter. @param line_config - The line_config parameter is the line configuration specifying the bit length, - number of stop bits and parity settings. - + The line_config parameter is the line configuration that specifies the bit + length, number of Stop bits, and parity settings. This is a bitwise OR of one value from each of the following groups of allowed values: - - One of the following to specify the transmit/receive data bit length: - - MSS_UART_DATA_5_BITS - - MSS_UART_DATA_6_BITS, - - MSS_UART_DATA_7_BITS - - MSS_UART_DATA_8_BITS - - One of the following to specify the parity setting: - - MSS_UART_NO_PARITY - - MSS_UART_EVEN_PARITY - - MSS_UART_ODD_PARITY - - MSS_UART_STICK_PARITY_0 - - MSS_UART_STICK_PARITY_1 - - One of the following to specify the number of stop bits: - - MSS_UART_ONE_STOP_BIT - - MSS_UART_ONEHALF_STOP_BIT - - MSS_UART_TWO_STOP_BITS + - One of the following to specify the transmit/receive data bit length: + - MSS_UART_DATA_5_BITS + - MSS_UART_DATA_6_BITS + - MSS_UART_DATA_7_BITS + - MSS_UART_DATA_8_BITS + - One of the following to specify the parity setting: + - MSS_UART_EVEN_PARITY + - MSS_UART_NO_PARITY + - MSS_UART_ODD_PARITY + - MSS_UART_STICK_PARITY_0 + - MSS_UART_STICK_PARITY_1 + - One of the following to specify the number of Stop bits: + - MSS_UART_ONE_STOP_BIT + - MSS_UART_ONEHALF_STOP_BIT + - MSS_UART_TWO_STOP_BITS @return This function does not return a value. - Example: + @example @code #include "mss_uart.h" @@ -1000,37 +975,35 @@ MSS_UART_init MSS_UART_lin_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT); - + return(0); } @endcode */ -void +void MSS_UART_lin_init ( - mss_uart_instance_t* this_uart, + mss_uart_instance_t* this_uart, uint32_t baud_rate, uint8_t line_config ); /***************************************************************************//** - The MSS_UART_irda_init() function is used to initialize the MSS UART instance - referenced by the parameter this_uart for IrDA mode of operation. This - function must be called before calling any other IrDA functionality specific - functions. - + The MSS_UART_irda_init() function initializes the MSS UART instance + referenced by the this_uart parameter for IrDA mode of operation. This + function must be called before calling any other IrDA specific functions. + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. - - Note that if you are using the UART on the AMP APB bus, the hardware + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware configuration to connect UART on AMP APB bus must already be done by the application using SYSREG registers before initializing the UART instance structure. @@ -1051,40 +1024,35 @@ MSS_UART_lin_init - MSS_UART_115200_BAUD - MSS_UART_230400_BAUD - MSS_UART_460800_BAUD - - MSS_UART_921600_BAUD - + - MSS_UART_921600_BAUD Alternatively, any nonstandard baud rate can be specified by simply passing the actual required baud rate as the value for this parameter. @param line_config - The line_config parameter is the line configuration specifying the bit - length, number of stop bits and parity settings. - + The line_config parameter is the line configuration that specifies the bit + length, number of Stop bits, and parity settings. This is a bitwise OR of one value from each of the following groups of allowed values: - - One of the following to specify the transmit/receive data bit length: - - MSS_UART_DATA_5_BITS - - MSS_UART_DATA_6_BITS, - - MSS_UART_DATA_7_BITS - - MSS_UART_DATA_8_BITS - - One of the following to specify the parity setting: - - MSS_UART_NO_PARITY - - MSS_UART_EVEN_PARITY - - MSS_UART_ODD_PARITY - - MSS_UART_STICK_PARITY_0 - - MSS_UART_STICK_PARITY_1 - - One of the following to specify the number of stop bits: - - MSS_UART_ONE_STOP_BIT - - MSS_UART_ONEHALF_STOP_BIT - - MSS_UART_TWO_STOP_BITS + - One of the following to specify the transmit/receive data bit length: + - MSS_UART_DATA_5_BITS + - MSS_UART_DATA_6_BITS + - MSS_UART_DATA_7_BITS + - MSS_UART_DATA_8_BITS + - One of the following to specify the parity setting: + - MSS_UART_EVEN_PARITY + - MSS_UART_NO_PARITY + - MSS_UART_ODD_PARITY + - MSS_UART_STICK_PARITY_0 + - MSS_UART_STICK_PARITY_1 + - One of the following to specify the number of Stop bits: + - MSS_UART_ONE_STOP_BIT + - MSS_UART_ONEHALF_STOP_BIT + - MSS_UART_TWO_STOP_BITS @return This function does not return a value. - Example: + @example @code MSS_UART_irda_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, @@ -1094,10 +1062,10 @@ MSS_UART_lin_init MSS_UART_3_BY_16); @endcode */ -void +void MSS_UART_irda_init ( - mss_uart_instance_t* this_uart, + mss_uart_instance_t* this_uart, uint32_t baud_rate, uint8_t line_config, mss_uart_rzi_polarity_t rxpol, @@ -1106,25 +1074,24 @@ MSS_UART_irda_init ); /***************************************************************************//** - The MSS_UART_smartcard_init() function is used to initialize the MSS UART - for ISO 7816 (smartcard) mode of operation. The configuration parameters are - the baud_rate which is used to generate the baud value and the line_config - which is used to specify the line configuration (bit length, stop bits and + The MSS_UART_smartcard_init() function initializes the MSS UART + for ISO 7816 (smartcard) mode of operation. The configuration parameters are + the baud_rate, which generates the baud value, and the line_config, + which specifies the line configuration (bit length, Stop bits and parity). This function disables all other modes of the MSS UART instance - pointed by the parameter this_uart. + pointed by the this_uart parameter. @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. - - Note that if you are using the UART on the AMP APB bus, the hardware + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware configuration to connect UART on AMP APB bus must already be done by the application using SYSREG registers before initializing the UART instance structure. @@ -1145,40 +1112,35 @@ MSS_UART_irda_init - MSS_UART_115200_BAUD - MSS_UART_230400_BAUD - MSS_UART_460800_BAUD - - MSS_UART_921600_BAUD - + - MSS_UART_921600_BAUD Alternatively, any nonstandard baud rate can be specified by simply passing the actual required baud rate as the value for this parameter. @param line_config - The line_config parameter is the line configuration specifying the bit - length, number of stop bits and parity settings. - + The line_config parameter is the line configuration that specifies the bit + length, number of Stop bits, and parity settings. This is a bitwise OR of one value from each of the following groups of allowed values: - - One of the following to specify the transmit/receive data bit length: - - MSS_UART_DATA_5_BITS - - MSS_UART_DATA_6_BITS, - - MSS_UART_DATA_7_BITS - - MSS_UART_DATA_8_BITS - - One of the following to specify the parity setting: - - MSS_UART_NO_PARITY - - MSS_UART_EVEN_PARITY - - MSS_UART_ODD_PARITY - - MSS_UART_STICK_PARITY_0 - - MSS_UART_STICK_PARITY_1 - - One of the following to specify the number of stop bits: - - MSS_UART_ONE_STOP_BIT - - MSS_UART_ONEHALF_STOP_BIT - - MSS_UART_TWO_STOP_BITS + - One of the following to specify the transmit/receive data bit length: + - MSS_UART_DATA_5_BITS + - MSS_UART_DATA_6_BITS + - MSS_UART_DATA_7_BITS + - MSS_UART_DATA_8_BITS + - One of the following to specify the parity setting: + - MSS_UART_EVEN_PARITY + - MSS_UART_NO_PARITY + - MSS_UART_ODD_PARITY + - MSS_UART_STICK_PARITY_0 + - MSS_UART_STICK_PARITY_1 + - One of the following to specify the number of Stop bits: + - MSS_UART_ONE_STOP_BIT + - MSS_UART_ONEHALF_STOP_BIT + - MSS_UART_TWO_STOP_BITS @return This function does not return a value. - Example: + @example @code #include "mss_uart.h" @@ -1187,24 +1149,24 @@ MSS_UART_irda_init MSS_UART_smartcard_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT); - + return(0); } @endcode */ -void +void MSS_UART_smartcard_init ( - mss_uart_instance_t* this_uart, + mss_uart_instance_t* this_uart, uint32_t baud_rate, uint8_t line_config ); /***************************************************************************//** - The function MSS_UART_polled_tx() is used to transmit data. It transfers the - contents of the transmitter data buffer, passed as a function parameter, into + The function MSS_UART_polled_tx() transmits data. It transfers the + content of the transmitter data buffer, passed as a function parameter, into the UART's hardware transmitter FIFO. It returns when the full content of the - transmit data buffer has been transferred to the UART's transmit FIFO. It is + transmit data buffer is transferred to the UART's transmit FIFO. It is safe to release or reuse the memory used as the transmitter data buffer once this function returns. @@ -1214,33 +1176,37 @@ MSS_UART_smartcard_init transfers data to the transmitter FIFO in blocks of 16 bytes or less and allows the FIFO to empty before transferring the next block of data. - Note: The actual transmission over the serial connection will still be + Note: The actual transmission over the serial connection is still in progress when this function returns. Use the MSS_UART_get_tx_status() function if you need to know when the transmitter is empty. - + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @param pbuff The pbuff parameter is a pointer to a buffer containing the data to - be transmitted. + transmit. @param tx_size The tx_size parameter specifies the size, in bytes, of the data to - be transmitted. + transmit. @return This function does not return a value. - Example: + @example @code #include "mss_uart.h" @@ -1253,7 +1219,7 @@ MSS_UART_smartcard_init SS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT); MSS_UART_polled_tx(&g_mss_uart0_lo, message, sizeof(message)); - + return(0); } @endcode @@ -1267,10 +1233,10 @@ MSS_UART_polled_tx ); /***************************************************************************//** - The function MSS_UART_polled_tx_string() is used to transmit a NUL ('\0') - terminated string. It transfers the text string, from the buffer starting at - the address pointed to by p_sz_string into the UART's hardware transmitter - FIFO. It returns when the complete string has been transferred to the UART's + The function MSS_UART_polled_tx_string() transmits a NULL ('\0') + terminated string. It transfers the text string, located at + the address pointed to by p_sz_string, to the UART's hardware transmitter + FIFO. It returns when the complete string is transferred to the UART's transmit FIFO. It is safe to release or reuse the memory used as the string buffer once this function returns. @@ -1280,29 +1246,33 @@ MSS_UART_polled_tx transfers data to the transmitter FIFO in blocks of 16 bytes or less and allows the FIFO to empty before transferring the next block of data. - Note: The actual transmission over the serial connection will still be + Note: The actual transmission over the serial connection is still in progress when this function returns. Use the MSS_UART_get_tx_status() function if you need to know when the transmitter is empty. - + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @param p_sz_string - The p_sz_string parameter is a pointer to a buffer containing the NUL ('\0') - terminated string to be transmitted. + The p_sz_string parameter is a pointer to a buffer containing the NULL + ('\0') terminated string to transmit. @return This function does not return a value. - Example: + @example @code #include "mss_uart.h" @@ -1313,9 +1283,9 @@ MSS_UART_polled_tx MSS_UART_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT); - + MSS_UART_polled_tx_string(&g_mss_uart0_lo, message); - + return(0); } @endcode @@ -1329,67 +1299,61 @@ MSS_UART_polled_tx_string ); /***************************************************************************//** - The function MSS_UART_irq_tx() is used to initiate an interrupt-driven - transmit. It returns immediately after making a note of the transmit buffer - location and enabling transmit interrupts both at the UART and the PolarFire - SoC Core Complex PLIC level. This function takes a pointer via the pbuff - parameter to a memory buffer containing the data to transmit. The memory - buffer specified through this pointer must remain allocated and contain the - data to transmit until the transmit completion has been detected through calls - to function MSS_UART_tx_complete(). The actual transmission over the serial - connection is still in progress until calls to the MSS_UART_tx_complete() + The function MSS_UART_irq_tx() initiates an interrupt-driven + transmit. It returns immediately after passing the transmit buffer location + to the MMUART instance and enabling transmit interrupts both at the UART and + the PolarFire® SoC Core Complex PLIC level. This function takes a pointer, + the pbuff parameter, to a memory buffer containing the data to transmit. The + memory buffer specified through this pointer must remain allocated and contain + the data to transmit until the transmit completion is detected through calling + the MSS_UART_tx_complete() function. The actual transmission over the serial + connection is still in progress until calls to the MSS_UART_tx_complete() function indicate transmit completion. Note: The MSS_UART_irq_tx() function enables both the transmit holding register empty (THRE) interrupt in the UART and the MSS UART instance - interrupt in the PolarFire SoC Core Complex PLIC as part of its implementation. - - Note: The MSS_UART_irq_tx() function assigns an internal default transmit - interrupt handler function to the UART's THRE interrupt. This interrupt - handler overrides any custom interrupt handler that you may have previously - registered using the MSS_UART_set_tx_handler() function. - - Note: The MSS_UART_irq_tx() function's default transmit interrupt - handler disables the UART's THRE interrupt when all of the data has - been transferred to the UART's transmit FIFO. - - + interrupt in the PolarFire® SoC Core Complex PLIC as part of its implementation. + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @param pbuff The pbuff parameter is a pointer to a buffer containing the data - to be transmitted. + to transmit. @param tx_size The tx_size parameter specifies the size, in bytes, of the data - to be transmitted. + to transmit. @return This function does not return a value. - Example: + @example @code #include "mss_uart.h" int main(void) { uint8_t tx_buff[10] = "abcdefghi"; - + MSS_UART_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT); - + MSS_UART_irq_tx(&g_mss_uart0_lo, tx_buff, sizeof(tx_buff)); - + while(0 == MSS_UART_tx_complete(&g_mss_uart0_lo)) { ; @@ -1416,23 +1380,27 @@ MSS_UART_irq_tx transmit FIFO and the actual transmission over the serial connection are both complete when a call to the MSS_UART_tx_complete() function indicates transmit completion. - + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @return - This function return a non-zero value if transmit has completed, otherwise - it returns zero. + This function return a non-zero value if transmit is complete, it returns + zero otherwise. - Example: + @example See the MSS_UART_irq_tx() function for an example that uses the MSS_UART_tx_complete() function. @@ -1445,20 +1413,20 @@ MSS_UART_tx_complete /***************************************************************************//** The MSS_UART_get_rx() function reads the content of the UART receiver's FIFO - and stores it in the receive buffer that is passed via the rx_buff function - parameter. It copies either the full contents of the FIFO into the receive + and stores it in the receive buffer that is passed using the rx_buff + parameter. It copies either the full content of the FIFO into the receive buffer, or just enough data from the FIFO to fill the receive buffer, - dependent upon the size of the receive buffer passed by the buff_size + depending on the size of the receive buffer passed by the buff_size parameter. The MSS_UART_get_rx() function returns the number of bytes copied - into the receive buffer .This function is non-blocking and will return 0 - immediately if no data has been received. + into the receive buffer. This function is non-blocking and returns 0 + immediately if no data is received. Note: The MSS_UART_get_rx() function reads and accumulates the receiver status of the MSS UART instance before reading each byte from the receiver's data register/FIFO. This allows the driver to maintain a sticky record of any receiver errors that occur as the UART receives each data byte; receiver errors would otherwise be lost after each read from the receiver's data - register. A call to the MSS_UART_get_rx_status() function returns any receiver + register. Calling the MSS_UART_get_rx_status() function returns any receiver errors accumulated during the execution of the MSS_UART_get_rx() function. Note: If you need to read the error status for each byte received, set @@ -1466,25 +1434,28 @@ MSS_UART_tx_complete using the MSS_UART_get_rx_status() function. The MSS_UART_get_rx() function can be used in polled mode, where it is called - at regular intervals to find out if any data has been received, or in + at regular intervals to find out if any data is received, or in interrupt driven-mode, where it is called as part of a receive handler that is called by the driver as a result of data being received. - Note: In interrupt driven mode you should call the MSS_UART_get_rx() + Note: In interrupt driven mode, call the MSS_UART_get_rx() function as part of the receive handler function that you register with - the MSS UART driver through a call to MSS_UART_set_rx_handler(). - + the MSS UART driver through calling MSS_UART_set_rx_handler(). + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. - + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @param rx_buff The rx_buff parameter is a pointer to a buffer where the received data is copied. @@ -1494,9 +1465,10 @@ MSS_UART_tx_complete @return This function returns the number of bytes that were copied into the - rx_buff buffer. It returns 0 if no data has been received. + rx_buff buffer. It returns 0 if no data is received. Polled mode example: + @example @code int main( void ) { @@ -1506,7 +1478,7 @@ MSS_UART_tx_complete MSS_UART_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT); - + while(1) { rx_size = MSS_UART_get_rx(&g_mss_uart0_lo, rx_buff, sizeof(rx_buff)); @@ -1522,17 +1494,18 @@ MSS_UART_tx_complete @endcode Interrupt driven example: + @example @code int main( void ) { MSS_UART_init(&g_mss_uart1, MSS_UART_57600_BAUD, MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT); - + MSS_UART_set_rx_handler(&g_mss_uart1, uart1_rx_handler, MSS_UART_FIFO_SINGLE_BYTE); - + while(1) { task_a(); @@ -1559,36 +1532,44 @@ MSS_UART_get_rx ); /***************************************************************************//** - The MSS_UART_set_rx_handler() function is used to register a receive handler + The MSS_UART_set_rx_handler() function registers a receive handler function that is called by the driver when a UART receive data available (RDA) interrupt occurs. You must create and register the receive handler function - to suit your application and it must include a call to the MSS_UART_get_rx() + to suit your application and it must call the MSS_UART_get_rx() function to actually read the received data. Note: The MSS_UART_set_rx_handler() function enables both the RDA - interrupt in the MSS UART instance. It also enables the corresponding - MSS UART instance interrupt in the PolarFire SoC Core Complex PLIC as part + interrupt in the MSS UART instance and in the corresponding + MSS UART instance interrupt in the PolarFire® SoC Core Complex PLIC as part of its implementation. - Note: You can disable the RDA interrupt when required by calling the + Note: You can disable the RDA interrupt when required by calling the MSS_UART_disable_irq() function. This is your choice and is dependent upon your application. + + Note: The trigger level is actually applied only if the this_uart is set + to ready mode 1. For more information, see the MSS_UART_set_ready_mode() + function. @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @param handler The handler parameter is a pointer to a receive interrupt handler function - provided by your application that will be called as a result of a UART RDA - interrupt. This handler function must be of type mss_uart_irq_handler_t. + provided by your application that is called when a UART RDA interrupt + is triggered. This handler function must be of type mss_uart_irq_handler_t. @param trigger_level The trigger_level parameter is the receive FIFO trigger level. This @@ -1598,7 +1579,7 @@ MSS_UART_get_rx @return This function does not return a value. - Example: + @example @code #include "mss_uart.h" @@ -1616,11 +1597,11 @@ MSS_UART_get_rx MSS_UART_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT); - + MSS_UART_set_rx_handler(&g_mss_uart0_lo, uart0_rx_handler, MSS_UART_FIFO_SINGLE_BYTE); - + while(1) { ; @@ -1642,32 +1623,36 @@ MSS_UART_set_rx_handler Rx lines of a UART. This is not to be confused with the loop-back of UART0 to UART1, which can be achieved through the microprocessor subsystem's system registers. - + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @param loopback - The loopback parameter indicates whether or not the UART's transmit and - receive lines should be looped back. Allowed values are as follows: + The loopback parameter indicates whether or not the UART's transmit and + receive lines should be looped back. Following are the allowed values: - MSS_UART_LOCAL_LOOPBACK_ON - - MSS_UART_LOCAL_LOOPBACK_OFF + - MSS_UART_LOCAL_LOOPBACK_OFF - MSS_UART_REMOTE_LOOPBACK_ON - - MSS_UART_REMOTE_LOOPBACK_OFF + - MSS_UART_REMOTE_LOOPBACK_OFF - MSS_UART_AUTO_ECHO_ON - MSS_UART_AUTO_ECHO_OFF - + @return This function does not return a value. - Example: + @example @code MSS_UART_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, @@ -1685,28 +1670,31 @@ MSS_UART_set_loopback /***************************************************************************//** The MSS_UART_enable_irq() function enables the MSS UART interrupts specified - by the irq_mask parameter. The irq_mask parameter identifies the MSS UART - interrupts by bit position, as defined in the interrupt enable register (IER) - of MSS UART. The MSS UART interrupts and their identifying irq_mask bit - positions are as follows: When an irq_mask bit position is set to 1, this + by the irq_mask parameter. The irq_mask parameter identifies the MSS UART + interrupts by bit position, as defined in the interrupt enable register (IER) + of MSS UART. The MSS UART interrupts and their identifying irq_mask bit + positions are as follows: when an irq_mask bit position is set to 1, this function enables the corresponding MSS UART interrupt in the IER register. - Note: the Transmit Buffer Empty interrupt is not enabled in this API. Indeed, - enabling it here leads to an interrupt occuring before any data is passed to - the UART, causing a crash. The TBE bit in the IER register is set + Note: the Transmit Buffer Empty interrupt is not enabled in this API. Indeed, + enabling it here leads to an interrupt occuring before any data is passed to + the UART, causing a crash. The TBE bit in the IER register is set in the MSS_UART_irq_tx() function, that actually starts the transmission. - - + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @param irq_mask The irq_mask parameter is used to select which of the MSS UART's interrupts @@ -1722,11 +1710,11 @@ MSS_UART_set_loopback - MSS_UART_LINB_IRQ (bit mask = 0x080) - MSS_UART_LINS_IRQ (bit mask = 0x100) - + @return This function does not return a value. - Example: + @example @code #include "mss_uart.h" @@ -1762,26 +1750,25 @@ MSS_UART_enable_irq by the irq_mask parameter. The irq_mask parameter identifies the MSS UART interrupts by bit position, as defined in the interrupt enable register (IER) of MSS UART. The MSS UART interrupts and their identifying bit positions are - as follows: - When an irq_mask bit position is set to 1, this function disables the - corresponding MSS UART interrupt in the IER register. When an irq_mask bit - position is set to 0, the state of the corresponding interrupt remains + as follows: when an irq_mask bit position is set to 1, this function disables + the corresponding MSS UART interrupt in the IER register. When an irq_mask bit + position is set to 0, the state of the corresponding interrupt remains unchanged in the IER register. - Note: If you disable all four of the UART's interrupts, the - MSS_UART_disable_irq() function also disables the MSS UART instance - interrupt in the PolarFire SoC Core Complex PLIC. - @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @param irq_mask The irq_mask parameter is used to select which of the MSS UART's interrupts @@ -1796,11 +1783,11 @@ MSS_UART_enable_irq - MSS_UART_PIDPE_IRQ (bit mask = 0x040) - MSS_UART_LINB_IRQ (bit mask = 0x080) - MSS_UART_LINS_IRQ (bit mask = 0x100) - + @return This function does not return a value. - Example: + @example @code #include "mss_uart.h" @@ -1827,38 +1814,42 @@ MSS_UART_disable_irq ); /***************************************************************************//** - The MSS_UART_set_pidpei_handler() function is used assign a custom interrupt - handler for the PIDPEI (PID parity error interrupt) when the MSS UART is - operating in LIN mode. + The MSS_UART_set_pidpei_handler() function assigns a custom + interrupt handler for the PIDPEI (PID parity error interrupt) when the MSS + UART is operating in LIN mode. - Note: The MSS_UART_set_pidpei_handler() function enables both the PIDPEI - interrupt in the MSS UART instance. It also enables the corresponding - MSS UART instance interrupt in the PolarFire SoC Core Complex PLIC as part of + Note: The MSS_UART_set_pidpei_handler() function enables both the PIDPEI + interrupt in the MSS UART instance and the corresponding + MSS UART instance interrupt in the PolarFire® SoC Core Complex PLIC as part of its implementation. - Note: You can disable the PIDPEI interrupt when required by calling the - MSS_UART_disable_irq() function. This is your choice and is dependent upon + Note: You can disable the PIDPEI interrupt when required by calling the + MSS_UART_disable_irq() function. This is your choice and it depends upon your application. @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @param handler - The handler parameter is the pointer to the custom handler function. - This parameter is of type mss_uart_irq_handler_t. + The handler parameter is the pointer to the custom handler function. + This parameter is of mss_uart_irq_handler_t type. @return This function does not return a value. - Example: + @example @code #include "mss_uart.h" @@ -1884,37 +1875,41 @@ MSS_UART_set_pidpei_handler ); /***************************************************************************//** - The MSS_UART_set_linbreak_handler () function is used assign a custom - interrupt handler for the LIN Break detection interrupt when the MSS UART + The MSS_UART_set_linbreak_handler () function assigns a custom + interrupt handler for the LIN Break detection interrupt when the MSS UART is operating in LIN mode. Note: The MSS_UART_set_linbreak_handler() function enables both the LIN - BREAK interrupt in the MSS UART instance. It also enables the corresponding - MSS UART instance interrupt in the PolarFire SoC Core Complex PLIC as part of + BREAK interrupt in the MSS UART instance and the corresponding + MSS UART instance interrupt in the PolarFire® SoC Core Complex PLIC as part of its implementation. - Note: You can disable the LIN BREAK interrupt when required by calling the - MSS_UART_disable_irq() function. This is your choice and is dependent upon + Note: You can disable the LIN BREAK interrupt when required by calling the + MSS_UART_disable_irq() function. This is your choice and it depends upon your application. @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @param handler - The handler parameter is the pointer to the custom handler function. - This parameter is of type mss_uart_irq_handler_t. + The handler parameter is the pointer to the custom handler function. + This parameter is of mss_uart_irq_handler_t type. @return This function does not return a value. - Example: + @example @code #include "mss_uart.h" @@ -1941,38 +1936,42 @@ MSS_UART_set_linbreak_handler ); /***************************************************************************//** - The MSS_UART_set_linsync_handler() function is used assign a custom interrupt - handler for the LIN Sync character detection interrupt when the MSS UART is - operating in LIN mode. + The MSS_UART_set_linsync_handler() function assigns a custom + interrupt handler for the LIN Sync character detection interrupt when the + MSS UART is operating in LIN mode. Note: The MSS_UART_set_linsync_handler() function enables both the LIN - SYNC interrupt in the MSS UART instance. It also enables the corresponding - MSS UART instance interrupt in the PolarFire SoC Core Complex PLIC as part of + SYNC interrupt in the MSS UART instance and the corresponding + MSS UART instance interrupt in the PolarFire® SoC Core Complex PLIC as part of its implementation. - Note: You can disable the LIN SYNC interrupt when required by calling the - MSS_UART_disable_irq() function. This is your choice and is dependent upon + Note: You can disable the LIN SYNC interrupt when required by calling the + MSS_UART_disable_irq() function. This is your choice and it depends upon your application. @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @param handler - The handler parameter is the pointer to the custom handler function. - This parameter is of type mss_uart_irq_handler_t. + The handler parameter is the pointer to the custom handler function. + This parameter is of mss_uart_irq_handler_t type. @return This function does not return a value. - - Example: + + @example @code #include "mss_uart.h" @@ -1999,38 +1998,42 @@ MSS_UART_set_linsync_handler ); /***************************************************************************//** - The MSS_UART_set_nack_handler() function is used assign a custom interrupt - handler for the NACK character detection interrupt when the MSS UART + The MSS_UART_set_nack_handler() function assigns a custom interrupt + handler for the NACK character detection interrupt when the MSS UART is operating in Smartcard mode. - Note: The MSS_UART_set_nack_handler() function enables both the NAK - interrupt in the MSS UART instance. It also enables the corresponding - MSS UART instance interrupt in the PolarFire SoC Core Complex PLIC as part of + Note: The MSS_UART_set_nack_handler() function enables both the NACK + interrupt in the MSS UART instance and the corresponding + MSS UART instance interrupt in the PolarFire® SoC Core Complex PLIC as part of its implementation. - Note: You can disable the NAK interrupt when required by calling the - MSS_UART_disable_irq() function. This is your choice and is dependent upon + Note: You can disable the NACK interrupt when required by calling the + MSS_UART_disable_irq() function. This is your choice and it depends upon your application. @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @param handler - The handler parameter is the pointer to the custom handler function. - This parameter is of type mss_uart_irq_handler_t. + The handler parameter is the pointer to the custom handler function. + This parameter is of mss_uart_irq_handler_t type. @return This function does not return a value. - - Example: + + @example @code #include "mss_uart.h" @@ -2057,38 +2060,42 @@ MSS_UART_set_nack_handler ); /***************************************************************************//** - The MSS_UART_set_rx_timeout_handler() function is used assign a custom - interrupt handler for the receiver timeout interrupt when the MSS UART is - operating in mode. It finds application in IrDA mode of operation. - - Note: The MSS_UART_set_rx_timeout_handler() function enables both the - time-out interrupt in the MSS UART instance. It also enables the corresponding - MSS UART instance interrupt in the PolarFire SoC Core Complex PLIC as part of + The MSS_UART_set_rx_timeout_handler() function assigns a custom + interrupt handler for the receiver timeout interrupt when the MSS UART is + operating in IrDA mode of operation. + + Note: The MSS_UART_set_rx_timeout_handler() function enables both the + time-out interrupt in the MSS UART instance and the corresponding + MSS UART instance interrupt in the PolarFire® SoC Core Complex PLIC as part of its implementation. - Note: You can disable the RX time-out interrupt when required by calling - the MSS_UART_disable_irq() function. This is your choice and is dependent upon + Note: You can disable the RX time-out interrupt when required by calling + the MSS_UART_disable_irq() function. This is your choice and it depends upon your application. @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @param handler - The handler parameter is the pointer to the custom handler function. + The handler parameter is the pointer to the custom handler function. This parameter is of type mss_uart_irq_handler_t. @return This function does not return a value. - - Example: + + @example @code #include "mss_uart.h" @@ -2115,41 +2122,45 @@ MSS_UART_set_rx_timeout_handler ); /***************************************************************************//** - The MSS_UART_set_rxstatus_handler() function is used to register a receiver + The MSS_UART_set_rxstatus_handler() function registers a receiver status handler function that is called by the driver when a UART receiver line status (RLS) interrupt occurs. You must create and register the handler function to suit your application. Note: The MSS_UART_set_rxstatus_handler() function enables both the RLS - interrupt in the MSS UART instance. It also enables the corresponding MSS UART - instance interrupt in the PolarFire SoC Core Complex PLIC as part of its + interrupt in the MSS UART instance and the corresponding MSS UART + instance interrupt in the PolarFire® SoC Core Complex PLIC as part of its implementation. Note: You can disable the RLS interrupt when required by calling the - MSS_UART_disable_irq() function. This is your choice and is dependent upon + MSS_UART_disable_irq() function. This is your choice and it depends upon your application. - + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @param handler - The handler parameter is a pointer to a receiver line status interrupt - handler function provided by your application that will be called as a - result of a UART RLS interrupt. This handler function must be of type - mss_uart_irq_handler_t. + The handler parameter is a pointer to a receiver line status interrupt + handler function, which is provided by your application and is called when a + UART RLS interrupt is triggered. This handler function must be of + mss_uart_irq_handler_t type. @return - This function does not return a value. + This function does not return a value. - Example: + @example @code #include "mss_uart.h" @@ -2168,7 +2179,7 @@ MSS_UART_set_rx_timeout_handler MSS_UART_init( &g_mss_uart0_lo, MSS_UART_57600_BAUD, MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT); - + MSS_UART_set_rxstatus_handler(&g_mss_uart0_lo, uart_rxsts_handler); while(1) @@ -2187,73 +2198,66 @@ MSS_UART_set_rxstatus_handler ); /***************************************************************************//** - The MSS_UART_set_tx_handler() function is used to register a transmit handler + The MSS_UART_set_tx_handler() function registers a transmit handler function that is called by the driver when a UART transmit holding register empty (THRE) interrupt occurs. You must create and register the transmit - handler function to suit your application. You can use the - MSS_UART_fill_tx_fifo() function in your transmit handler function to - write data to the transmitter. + handler function to suit your application. You can then use MSS_UART_irq_tx() + to trigger the interrupt and pass the data you want to transmit. - Note: The MSS_UART_set_tx_handler() function enables both the THRE - interrupt in the MSS UART instance. It also enables the corresponding MSS UART - instance interrupt in the PolarFire SoC Core Complex PLIC as part of its - implementation. - - - Note: You can disable the THRE interrupt when required by calling the - MSS_UART_disable_irq() function. This is your choice and is dependent upon - your application. - - Note: The MSS_UART_irq_tx() function does not use the transmit handler - function that you register with the MSS_UART_set_tx_handler() function. - It uses its own internal THRE interrupt handler function that overrides - any custom interrupt handler that you register using the - MSS_UART_set_tx_handler() function. + Note: If handler is NULL_HANDLER (or ((mss_uart_irq_handler_t)0)), the Tx + interrupt handler is the default_tx_handler(). + Note: Your alternative THRE interrupt handler must include a call to the + MSS_UART_fill_tx_fifo() function to transfer the data to the UART. + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @param handler - The handler parameter is a pointer to a transmit interrupt handler - function provided by your application that will be called as a result - of a UART THRE interrupt. This handler function must be of type - mss_uart_irq_handler_t. + The handler parameter is a pointer to a transmit interrupt handler + function provided by your application that is called when a UART THRE + interrupt is triggered. This handler function must be of + mss_uart_irq_handler_t type. If this parameter is NULL_HANDLER (or + ((mss_uart_irq_handler_t)0)), the default_tx_handler() is assigned as + the Tx interrupt handler. @return - This function does not return a value. + This function does not return a value. - Example: + @example @code #include "mss_uart.h" - uint8_t * g_tx_buffer; - size_t g_tx_size = 0; + uint8_t * g_tx_buffer = "Message from Tx irq handler"; + size_t g_tx_size = 27; void uart_tx_handler(mss_uart_instance_t * this_uart) { size_t size_in_fifo; - size_in_fifo = MSS_UART_fill_tx_fifo(this_uart, - (const uint8_t *)g_tx_buffer, - g_tx_size); - - if(size_in_fifo == g_tx_size) - { - g_tx_size = 0; - MSS_UART_disable_irq(this_uart, MSS_UART_TBE_IRQ); - } - else - { - g_tx_buffer = &g_tx_buffer[size_in_fifo]; - g_tx_size = g_tx_size - size_in_fifo; - } + const uint8_t * sub_buffer = &this_uart->tx_buffer[this_uart->tx_idx]; + uint32_t sub_buffer_size = this_uart->tx_buff_size - this_uart->tx_idx; + + ASSERT(( (uint8_t*)0 ) != this_uart->tx_buffer); + ASSERT(0u < this_uart->tx_buff_size); + + size_in_fifo = MSS_UART_fill_tx_fifo(this_uart, + sub_buffer, + sub_buffer_size); + this_uart->tx_idx += size_in_fifo; + + // Additional user code can be added here } int main(void) @@ -2268,6 +2272,7 @@ MSS_UART_set_rxstatus_handler g_tx_size = sizeof(message); MSS_UART_set_tx_handler(&g_mss_uart0_lo, uart_tx_handler); + MSS_UART_irq_tx(&g_mss_uart0_lo, g_tx_buffer, g_tx_size); while(1) { @@ -2285,41 +2290,45 @@ MSS_UART_set_tx_handler ); /***************************************************************************//** - The MSS_UART_set_modemstatus_handler() function is used to register a modem + The MSS_UART_set_modemstatus_handler() function registers a modem status handler function that is called by the driver when a UART modem status (MS) interrupt occurs. You must create and register the handler function to suit your application. Note: The MSS_UART_set_modemstatus_handler() function enables both the MS - interrupt in the MSS UART instance. It also enables the corresponding MSS UART - instance interrupt in the PolarFire SoC Core Complex PLIC as part of its + interrupt in the MSS UART instance and the corresponding MSS UART + instance interrupt in the PolarFire® SoC Core Complex PLIC as part of its implementation. Note: You can disable the MS interrupt when required by calling the - MSS_UART_disable_irq() function. This is your choice and is dependent + MSS_UART_disable_irq() function. This is your choice and it depends upon your application. - + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @param handler - The handler parameter is a pointer to a modem status interrupt handler - function provided by your application that will be called as a result - of a UART MS interrupt. This handler function must be of type - mss_uart_irq_handler_t. + The handler parameter is a pointer to a modem status interrupt handler + function provided by your application that is called when a UART MS + interrupt is triggered. This handler function must be of type + mss_uart_irq_handler_t. @return - This function does not return a value. + This function does not return a value. - Example: + @example @code #include "mss_uart.h" @@ -2359,12 +2368,12 @@ MSS_UART_set_modemstatus_handler /***************************************************************************//** The MSS_UART_fill_tx_fifo() function fills the UART's hardware transmitter - FIFO with the data found in the transmitter buffer that is passed via the + FIFO with the data found in the transmitter buffer that is passed using the tx_buffer function parameter. If the transmitter FIFO is not empty when the function is called, the function returns immediately without transferring any data to the FIFO; otherwise, the function transfers data from the - transmitter buffer to the FIFO until it is full or until the complete - contents of the transmitter buffer have been copied into the FIFO. The + transmitter buffer to the FIFO until it is filled or until the full + content of the transmitter buffer is copied into the FIFO. The function returns the number of bytes copied into the UART's transmitter FIFO. Note: This function reads the UART's line status register (LSR) to check @@ -2377,21 +2386,25 @@ MSS_UART_set_modemstatus_handler Note: The actual transmission over the serial connection will still be in progress when this function returns. Use the MSS_UART_get_tx_status() function if you need to know when the transmitter is empty. - + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @param tx_buffer The tx_buffer parameter is a pointer to a buffer containing the data - to be transmitted. + to transmit. @param tx_size The tx_size parameter is the size in bytes, of the data to be transmitted. @@ -2400,7 +2413,7 @@ MSS_UART_set_modemstatus_handler This function returns the number of bytes copied into the UART's transmitter FIFO. - Example: + @example @code void send_using_interrupt(uint8_t * pbuff, size_t tx_size) { @@ -2439,21 +2452,25 @@ MSS_UART_fill_tx_fifo result in the driver losing receiver errors. To avoid any loss of receiver errors, the transmit functions also update the driver's sticky record of the cumulative receiver error status whenever they read the LSR. - + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @return This function returns the UART's receiver error status as an 8-bit unsigned - integer. The returned value is 0 if no receiver errors occurred. The driver + integer. The returned value is 0, if no receiver errors occurred. The driver provides a set of bit mask constants that should be compared with and/or used to mask the returned value to determine the receiver error status. When the return value is compared to the following bit masks, a non-zero @@ -2462,16 +2479,16 @@ MSS_UART_fill_tx_fifo - MSS_UART_PARITY_ERROR (bit mask = 0x04) - MSS_UART_FRAMING_ERROR (bit mask = 0x08) - MSS_UART_BREAK_ERROR (bit mask = 0x10) - - MSS_UART_FIFO_ERROR (bit mask = 0x80) - + - MSS_UART_FIFO_ERROR (bit mask = 0x80) + When the return value is compared to the following bit mask, a non-zero result indicates that no error occurred: - - MSS_UART_NO_ERROR (bit mask = 0x00) - + - MSS_UART_NO_ERROR (bit mask = 0x00) + Upon unsuccessful execution, this function returns: - MSS_UART_INVALID_PARAM (bit mask = 0xFF) - Example: + @example @code uint8_t rx_data[MAX_RX_DATA_SIZE]; uint8_t err_status; @@ -2492,22 +2509,26 @@ MSS_UART_get_rx_status /***************************************************************************//** The MSS_UART_get_modem_status() function returns the modem status of the MSS UART instance. It reads the modem status register (MSR) and returns - the 8 bit value. The bit encoding of the returned value is exactly the + the 8-bit value. The bit encoding of the returned value is exactly the same as the definition of the bits in the MSR. - + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @return - This function returns current state of the UART's MSR as an 8 bit + This function returns current state of the UART's MSR as an 8-bit unsigned integer. The driver provides the following set of bit mask constants that should be compared with and/or used to mask the returned value to determine the modem status: @@ -2520,7 +2541,7 @@ MSS_UART_get_rx_status - MSS_UART_RI (bit mask = 0x40) - MSS_UART_DCD (bit mask = 0x80) - Example: + @example @code void uart_modem_status_isr(mss_uart_instance_t * this_uart) { @@ -2548,35 +2569,39 @@ MSS_UART_get_modem_status MSS UART instance. It reads both the UART's line status register (LSR) and returns the status of the transmit holding register empty (THRE) and transmitter empty (TEMT) bits. - + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @return This function returns the UART's transmitter status as an 8-bit unsigned - integer. The returned value is 0 if the transmitter status bits are not + integer. The returned value is 0, if the transmitter status bits are not set or the function execution failed. The driver provides a set of bit mask constants that should be compared with and/or used to mask the returned value to determine the transmitter status. When the return value is compared to the following bit mask, a non-zero result indicates that the corresponding transmitter status bit is set: - MSS_UART_THRE (bit mask = 0x20) - - MSS_UART_TEMT (bit mask = 0x40) - + - MSS_UART_TEMT (bit mask = 0x40) + When the return value is compared to the following bit mask, a non-zero result indicates that the transmitter is busy or the function execution - failed. + failed: - MSS_UART_TX_BUSY (bit mask = 0x00) - Example: + @example @code uint8_t tx_buff[10] = "abcdefghi"; MSS_UART_init(&g_mss_uart0_lo, @@ -2598,30 +2623,34 @@ MSS_UART_get_tx_status ); /***************************************************************************//** - The MSS_UART_set_break() function is used to send the break - (9 zeros after stop bit) signal on the TX line. This function can be used + The MSS_UART_set_break() function sends the break + (9 zeros after Stop bit) signal on the Tx line. This function can be used only when the MSS UART is initialized in LIN mode by using MSS_UART_lin_init(). - + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @return - This function does not return a value. + This function does not return a value. - Example: + @example @code MSS_UART_lin_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT); - + MSS_UART_set_break(&g_mss_uart0); @endcode */ @@ -2632,25 +2661,29 @@ MSS_UART_set_break ); /***************************************************************************//** - The MSS_UART_clear_break() function is used to remove the break signal on the - TX line. This function can be used only when the MSS UART is initialized in + The MSS_UART_clear_break() function removes the break signal on the + Tx line. This function can be used only when the MSS UART is initialized in LIN mode by using MSS_UART_lin_init(). - + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @return - This function does not return a value. + This function does not return a value. - Example: + @example @code MSS_UART_lin_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, @@ -2666,25 +2699,29 @@ MSS_UART_clear_break ); /***************************************************************************//** - The MSS_UART_enable_half_duplex() function is used to enable the half-duplex - (single wire) mode for the MSS UART. Though it finds application in Smartcard + The MSS_UART_enable_half_duplex() function enables the half-duplex + (single wire) mode for the MSS UART. Though it finds application in Smartcard mode, half-duplex mode can be used in other modes as well. - + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @return This function does not return a value. - Example: + @example @code MSS_UART_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, @@ -2693,32 +2730,36 @@ MSS_UART_clear_break MSS_UART_enable_half_duplex(&g_mss_uart0_lo); @endcode */ -void +void MSS_UART_enable_half_duplex ( mss_uart_instance_t * this_uart ); /***************************************************************************//** - The MSS_UART_disable_half_duplex() function is used to disable the half-duplex - (single wire) mode for the MSS UART. Though it finds application in Smartcard + The MSS_UART_disable_half_duplex() function disables the half-duplex + (single wire) mode for the MSS UART. Though it finds application in Smartcard mode, half-duplex mode can be used in other modes as well. - + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @return This function does not return a value. - Example: + @example @code MSS_UART_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, @@ -2727,35 +2768,41 @@ MSS_UART_enable_half_duplex MSS_UART_disable_half_duplex(&g_mss_uart0_lo); @endcode */ -void +void MSS_UART_disable_half_duplex ( mss_uart_instance_t * this_uart ); /***************************************************************************//** - The MSS_UART_set_rx_endian() function is used to configure the LSB first or - MSB first setting for MSS UART receiver - + The MSS_UART_set_rx_endian() function configures the LSB first or + MSB first setting for MSS UART receiver. + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @param endian - The endian parameter tells the LSB first or MSB first configuration. - This parameter is of type mss_uart_endian_t. + The endian parameter tells if the LSB or MSB is received first. + This parameter is of type mss_uart_endian_t. The allowed values are: + - MSS_UART_LITTLEEND + - MSS_UART_BIGEND @return This function does not return a value. - Example: + @example @code MSS_UART_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, @@ -2768,32 +2815,38 @@ void MSS_UART_set_rx_endian ( mss_uart_instance_t * this_uart, - mss_uart_endian_t endian + mss_uart_endian_t endian ); /***************************************************************************//** - The MSS_UART_set_tx_endian() function is used to configure the LSB first or + The MSS_UART_set_tx_endian() function configures the LSB first or MSB first setting for MSS UART transmitter. - + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @param endian - The endian parameter tells the LSB first or MSB first configuration. - This parameter is of type mss_uart_endian_t. + The endian parameter tells if the LSB or MSB is transmitted first. + This parameter is of type mss_uart_endian_t. The allowed values are: + - MSS_UART_LITTLEEND + - MSS_UART_BIGEND @return This function does not return a value. - Example: + @example @code MSS_UART_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, @@ -2806,33 +2859,37 @@ void MSS_UART_set_tx_endian ( mss_uart_instance_t * this_uart, - mss_uart_endian_t endian + mss_uart_endian_t endian ); /***************************************************************************//** - The MSS_UART_set_filter_length () function is used to configure the glitch - filter length of the MSS UART. This should be configured in accordance with + The MSS_UART_set_filter_length() function configures the glitch + filter length of the MSS UART. This should be configured in accordance with the chosen baud rate. - + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @param length - The length parameter is of mss_uart_filter_length_t type that determines + The length parameter is of mss_uart_filter_length_t type and it determines the length of the glitch filter. @return This function does not return a value. - Example: + @example @code MSS_UART_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, @@ -2849,24 +2906,28 @@ MSS_UART_set_filter_length ); /***************************************************************************//** - The MSS_UART_enable_afm() function is used to enable address flag detection - mode of the MSS UART - + The MSS_UART_enable_afm() function enables address flag detection + mode of the MSS UART. + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @return This function does not return a value. - Example: + @example @code MSS_UART_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, @@ -2882,21 +2943,20 @@ MSS_UART_enable_afm ); /***************************************************************************//** - The MSS_UART_disable_afm() function is used to disable address flag detection + The MSS_UART_disable_afm() function disables address flag detection mode of the MSS UART. - + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. - - Note that if you are using the UART on the AMP APB bus, the hardware + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware configuration to connect UART on AMP APB bus must already be done by the application using SYSREG registers before initializing the UART instance structure. @@ -2904,7 +2964,7 @@ MSS_UART_enable_afm @return This function does not return a value. - Example: + @example @code MSS_UART_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, @@ -2920,25 +2980,29 @@ MSS_UART_disable_afm ); /***************************************************************************//** - The MSS_UART_enable_afclear () function is used to enable address flag clear - of the MSS UART. This should be used in conjunction with address flag + The MSS_UART_enable_afclear() function enables address flag clear + of the MSS UART. This should be used in conjunction with address flag detection mode (AFM). - + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @return This function does not return a value. - Example: + @example @code MSS_UART_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, @@ -2954,30 +3018,29 @@ MSS_UART_enable_afclear ); /***************************************************************************//** - The MSS_UART_disable_afclear () function is used to disable address flag - clear of the MSS UART. This should be used in conjunction with address flag + The MSS_UART_disable_afclear() function disables address flag + clear of the MSS UART. This should be used in conjunction with address flag detection mode (AFM). - + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. - - Note that if you are using the UART on the AMP APB bus, the hardware + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware configuration to connect UART on AMP APB bus must already be done by the application using SYSREG registers before initializing the UART instance structure. @return This function does not return a value. - - Example: + + @example @code MSS_UART_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, @@ -2993,30 +3056,34 @@ MSS_UART_disable_afclear ); /***************************************************************************//** - The MSS_UART_enable_rx_timeout() function is used to enable and configure - the receiver timeout functionality of MSS UART. This function accepts the - timeout parameter and applies the timeout based up on the baud rate as per + The MSS_UART_enable_rx_timeout() function enables and configures + the receiver timeout functionality of MSS UART. This function accepts the + timeout parameter and applies the timeout based up on the baud rate as per the formula 4 x timeout x bit time. - + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @param timeout - The timeout parameter specifies the receiver timeout multiple. + The timeout parameter specifies the receiver timeout multiple. It should be configured according to the baud rate in use. @return This function does not return a value. - Example: + @example @code MSS_UART_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, @@ -3025,7 +3092,7 @@ MSS_UART_disable_afclear MSS_UART_enable_rx_timeout(&g_mss_uart0_lo, 24); @endcode */ -void +void MSS_UART_enable_rx_timeout ( mss_uart_instance_t * this_uart, @@ -3033,21 +3100,20 @@ MSS_UART_enable_rx_timeout ); /***************************************************************************//** - The MSS_UART_disable_rx_timeout() function is used to disable the receiver - timeout functionality of MSS UART. - + The MSS_UART_disable_rx_timeout() function disables the receiver + timeout functionality of MSS UART. + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. - - Note that if you are using the UART on the AMP APB bus, the hardware + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware configuration to connect UART on AMP APB bus must already be done by the application using SYSREG registers before initializing the UART instance structure. @@ -3055,7 +3121,7 @@ MSS_UART_enable_rx_timeout @return This function does not return a value. - Example: + @example @code MSS_UART_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, @@ -3064,42 +3130,41 @@ MSS_UART_enable_rx_timeout MSS_UART_disable_rx_timeout(&g_mss_uart0_lo); @endcode */ -void +void MSS_UART_disable_rx_timeout ( mss_uart_instance_t * this_uart ); /***************************************************************************//** - The MSS_UART_enable_tx_time_guard() function is used to enable and configure - the transmitter time guard functionality of MSS UART. This function accepts - the timeguard parameter and applies the timeguard based up on the baud rate + The MSS_UART_enable_tx_time_guard() function enables and configures + the transmitter timeguard functionality of MSS UART. This function accepts + the timeguard parameter and applies the timeguard based on the baud rate as per the formula timeguard x bit time. - + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. - - Note that if you are using the UART on the AMP APB bus, the hardware + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware configuration to connect UART on AMP APB bus must already be done by the application using SYSREG registers before initializing the UART instance structure. @param timeguard - The timeguard parameter specifies the transmitter time guard multiple. + The timeguard parameter specifies the transmitter timeguard multiple. It should be configured according to the baud rate in use. @return This function does not return a value. - Example: + @example @code MSS_UART_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, @@ -3108,7 +3173,7 @@ MSS_UART_disable_rx_timeout MSS_UART_enable_tx_time_guard(&g_mss_uart0_lo, 24); @endcode */ -void +void MSS_UART_enable_tx_time_guard ( mss_uart_instance_t * this_uart, @@ -3116,21 +3181,20 @@ MSS_UART_enable_tx_time_guard ); /***************************************************************************//** - The MSS_UART_disable_tx_time_guard() function is used to disable the - transmitter time guard functionality of MSS UART. - + The MSS_UART_disable_tx_time_guard() function disables the + transmitter timeguard functionality of MSS UART. + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. - - Note that if you are using the UART on the AMP APB bus, the hardware + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware configuration to connect UART on AMP APB bus must already be done by the application using SYSREG registers before initializing the UART instance structure. @@ -3138,49 +3202,53 @@ MSS_UART_enable_tx_time_guard @return This function does not return a value. - Example: + @example @code MSS_UART_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT); - + MSS_UART_disable_tx_time_guard(&g_mss_uart0_lo); @endcode */ -void +void MSS_UART_disable_tx_time_guard ( mss_uart_instance_t * this_uart ); /***************************************************************************//** - The MSS_UART_set_address() function is used to set the 8-bit address for - the MSS UART referenced by this_uart parameter. - + The MSS_UART_set_address() function sets the 8-bit address for + the MSS UART, which is referenced by this_uart parameter. + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @param address - The address parameter is the 8-bit address which is to be configured - to the MSS UART referenced by this_uart parameter. + The address parameter is the 8-bit address allocated + to the MSS UART, which is referenced by this_uart parameter. @return This function does not return a value. - Example: + @example @code MSS_UART_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT); - + MSS_UART_set_address(&g_mss_uart0_lo, 0xAA); @endcode */ @@ -3192,29 +3260,40 @@ MSS_UART_set_address ); /***************************************************************************//** - The MSS_UART_set_ready_mode() function is used to configure the MODE0 or MODE1 - to the TXRDY and RXRDY signals of the MSS UART referenced by this_uart - parameter. The mode parameter is used to provide the mode to be configured. - + The MSS_UART_set_ready_mode() function configures the MODE0 or MODE1 + to the TXRDY and RXRDY signals of the MSS UART, which is referenced by + this_uart parameter. The mode parameter is used to provide the mode to be + configured. See the following details for the MODE0 and MODE1 description. + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @param mode - The mode parameter is the mss_uart_ready_mode_t type which is used to - configure the TXRDY and RXRDY signal modes. + The mode parameter is the mss_uart_ready_mode_t type which is used to + configure the TXRDY and RXRDY signal modes. + MODE0: RXRDY goes high (active) when there is at least one character + in the RX FIFO (that is, the RDA is triggered when there is at least one + character in the RX FIFO). TXRDY goes inactive after the first character is + loaded in the Tx FIFO. + MODE1: RXRDY goes high (active) when the trigger level or the timeout is + reached. TXRDY goes inactive when the Tx FIFO is completely full. @return This function does not return a value. - Example: + @example @code MSS_UART_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, @@ -3223,38 +3302,47 @@ MSS_UART_set_address MSS_UART_set_ready_mode(&g_mss_uart0_lo, MSS_UART_READY_MODE0); @endcode */ -void +void MSS_UART_set_ready_mode ( mss_uart_instance_t * this_uart, - mss_uart_ready_mode_t mode + mss_uart_ready_mode_t mode ); /***************************************************************************//** - The MSS_UART_set_usart_mode() function is used to configure the MSS UART - referenced by the parameter this_uart in USART mode. Various USART modes - are supported which can be configured by the parameter mode of type - mss_uart_usart_mode_t. - + The MSS_UART_set_usart_mode() function configures the MSS UART, which is + referenced by the this_uart parameter in USART mode. Various USART modes + are supported which can be configured by the parameter mode of + mss_uart_usart_mode_t type. + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @param mode - The mode parameter is the USART mode to be configured. - This parameter is of type mss_uart_usart_mode_t. + The mode parameter is the USART mode to be configured. + This parameter is of mss_uart_usart_mode_t type. The allowed values are: + - MSS_UART_ASYNC_MODE + - MSS_UART_SYNC_SLAVE_POS_EDGE_CLK + - MSS_UART_SYNC_SLAVE_NEG_EDGE_CLK + - MSS_UART_SYNC_MASTER_POS_EDGE_CLK + - MSS_UART_SYNC_MASTER_NEG_EDGE_CLK @return This function does not return a value. - Example: + @example @code MSS_UART_init(&g_mss_uart0_lo, MSS_UART_57600_BAUD, @@ -3263,7 +3351,7 @@ MSS_UART_set_ready_mode MSS_UART_set_usart_mode(&g_mss_uart0_lo, MSS_UART_SYNC_MASTER_POS_EDGE_CLK); @endcode */ -void +void MSS_UART_set_usart_mode ( mss_uart_instance_t * this_uart, @@ -3271,47 +3359,47 @@ MSS_UART_set_usart_mode ); /***************************************************************************//** - The MSS_UART_enable_local_irq() function is used to enable the MMUART - interrupt as a local interrupt to the hart rather than via PLIC. - MMUART interrupt can be configured to trigger an interrupt via PLIC or it + The MSS_UART_enable_local_irq() function enables the MMUART + interrupt as a local interrupt to the hart rather than as a PLIC interrupt. + MMUART interrupt can be configured to trigger a PLIC interrupt or it can be configured to trigger a local interrupt. The arrangement is such that the UART0 interrupt can appear as local interrupt on E51. The UART1 to UART4 - interrupts can appear as local interrupt to U51_1 to U54_4 respectively. - The UART0 to UART4 can appear as PLIC interrupt. Multiple HARTs can enable - and receive the PLIC interrupt, the HART that claims the interrupt processes - it. For rest of the HARTs the IRQ gets silently skipped as the interrupt - claim has already been taken. - - By default, the PLIC interrupt is enabled by this driver when - MSS_UART_enable_irq() or the APIs to set the interrupt handler is called. - To enable the local interrupt application must explicitly call + interrupts can appear as local interrupt to U51_1 to U54_4, respectively. + The UART0 to UART4 can appear as PLIC interrupt. Multiple harts can enable + and receive the PLIC interrupt, the hart that claims the interrupt processes + it. For rest of the harts, the IRQ gets silently skipped as the interrupt + claim has already been taken. + To enable the local interrupt, application must explicitly call MSS_UART_enable_local_irq() function. Note that this function disables the - interrupt over PLIC if it was previously enabled. - + interrupt over PLIC if it was previously enabled. This function must be called after the MMUART is initialized, the required - interrupt hander functions are set and before initiating any data transfers. - If you want to register multiple register handlers such as tx handler, rx - handler etc. then this function must be called after all such handlers are set. - + interrupt handler functions are set and before initiating any data transfers. + If you want to register multiple interrupt handlers such as Tx handler, rx + handler and so on, then this function must be called after all such handlers + are set. Call to this function is treated as one time activity. The driver gives no option to disable the local interrupt and enable the PLIC interrupt again at runtime. - + @param this_uart The this_uart parameter is a pointer to an mss_uart_instance_t - structure identifying the MSS UART hardware block that will perform - the requested function. There are ten such data structures, - g_mss_uart0_lo to g_mss_uart4_lo, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 5 (main APB bus) and - g_mss_uart0_hi to g_mss_uart4_hi, associated with MSS UART0 to MSS UART4 - when they are connected on the AXI switch slave 6 (AMP APB bus). - This parameter must point to one of these ten global data structure defined - within the UART driver. + structure that identifies the MSS UART hardware block performing + the requested function. There are ten such data structures. The data + structures from g_mss_uart0_lo to g_mss_uart4_lo are associated with + MSS UART0 to MSS UART4 when they are connected on the AXI switch slave 5 + (main APB bus). The data structures g_mss_uart0_hi to g_mss_uart4_hi are + associated with MSS UART0 to MSS UART4 when they are connected on the AXI + switch slave 6 (AMP APB bus). This parameter must point to one of these ten + global data structure defined within the UART driver. + Note: If you are using the UART on the AMP APB bus, the hardware + configuration to connect UART on AMP APB bus must already be done by the + application using SYSREG registers before initializing the UART instance + structure. @return This function does not return a value. - Example: + @example @code diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/drivers/mss/mss_mmuart/mss_uart_regs.h b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/drivers/mss/mss_mmuart/mss_uart_regs.h index bb1561a..7a556a0 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/drivers/mss/mss_mmuart/mss_uart_regs.h +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/drivers/mss/mss_mmuart/mss_uart_regs.h @@ -1,10 +1,13 @@ - /******************************************************************************* - * Copyright 2019-2022 Microchip FPGA Embedded Systems Solutions. +/******************************************************************************* + * Copyright 2019 Microchip FPGA Embedded Systems Solutions. * * SPDX-License-Identifier: MIT - * - * Register bit offsets and masks definitions for PolarFire SoC MSS MMUART - * + * + * @file mss_uart_regs.h + * @author Microchip FPGA Embedded Systems Solutions + * @brief Register bit offsets and masks definitions for PolarFire SoC + * Microprocessor Subsystem (MSS) MMUART + * */ #ifndef MSS_UART_REGS_H_ diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/common/mss_l2_cache.c b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/common/mss_l2_cache.c index af4b00e..a41e1d8 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/common/mss_l2_cache.c +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/common/mss_l2_cache.c @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright 2019-2022 Microchip FPGA Embedded Systems Solutions. + * Copyright 2019-2023 Microchip FPGA Embedded Systems Solutions. * * SPDX-License-Identifier: MIT * @@ -36,14 +36,53 @@ static const uint64_t g_init_marker = INIT_MARKER; */ static void check_config_l2_scratchpad(void); +/***************************************************************************//** + * See hw_l2_scratch.h for details of how to use this function. + */ +__attribute__((weak)) uint64_t end_l2_scratchpad_address(void) +{ + return (uint64_t)(ZERO_DEVICE_BOTTOM + (LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS + * WAY_BYTE_LENGTH)); +} -/*============================================================================== - * This code should only be executed from E51 to be functional. - * Configure the L2 cache memory: - * - Set the number of cache ways used as cache based on the MSS Configurator - * settings. - * - Configure some of the enabled ways as scratchpad based on linker - * configuration and space allocated by configurator. +/***************************************************************************//** + * See hw_l2_scratch.h for details of how to use this function. + */ +__attribute__((weak)) uint32_t num_cache_ways(void) +{ + static_assert(LIBERO_SETTING_WAY_ENABLE > + LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS, + "Invalid way configuration"); + return (uint64_t)((LIBERO_SETTING_WAY_ENABLE + 1U) - + LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS); +} + +/***************************************************************************//** + * See hw_l2_scratch.h for details of how to use this function. + */ +__attribute__((weak)) uint32_t my_num_cache_ways(void) +{ + uint32_t num_ways = 0U; + uint32_t way_enable; + uint32_t bit_index; + + //todo: return for my hart, assuming e51 here + way_enable = (uint32_t)LIBERO_SETTING_WAY_MASK_E51_DCACHE; + bit_index = 0U; + + while(bit_index < 16U) + { + if( way_enable & (1U<WAY_ENABLE = LIBERO_SETTING_WAY_ENABLE; + __atomic_store_8 (&CACHE_CTRL->WAY_ENABLE , LIBERO_SETTING_WAY_ENABLE, __ATOMIC_RELAXED); /* * shutdown L2 as directed */ SYSREG->L2_SHUTDOWN_CR = LIBERO_SETTING_L2_SHUTDOWN_CR; - /* The scratchpad has already been set-up, first check enough space before copying */ + /* The scratchpad has already been set-up, first check enough space before + * copying */ check_config_l2_scratchpad(); /* If you are not using scratchpad, no need to include the following code */ - static_assert(LIBERO_SETTING_WAY_ENABLE >= LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS, "Scratchpad Missing"); + static_assert(LIBERO_SETTING_WAY_ENABLE >= + LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS, "Scratchpad Missing"); /* - * Compute the mask (In HSS CONFIG_SERVICE_SCRUB=y) used to specify ways that will be used by the - * scratchpad. + * Compute the mask (In HSS CONFIG_SERVICE_SCRUB=y) used to specify ways + * that will be used by the scratchpad */ uint32_t scratchpad_ways_mask = 0U; @@ -111,20 +152,22 @@ __attribute__((weak)) void config_l2_cache(void) /* * Setup all masters, apart from one we are using to setup scratch */ - CACHE_CTRL->WAY_MASK_DMA = LIBERO_SETTING_WAY_MASK_DMA; - CACHE_CTRL->WAY_MASK_AXI4_SLAVE_PORT_0 = LIBERO_SETTING_WAY_MASK_AXI4_PORT_0; - CACHE_CTRL->WAY_MASK_AXI4_SLAVE_PORT_1 = LIBERO_SETTING_WAY_MASK_AXI4_PORT_1; - CACHE_CTRL->WAY_MASK_AXI4_SLAVE_PORT_2 = LIBERO_SETTING_WAY_MASK_AXI4_PORT_2; - CACHE_CTRL->WAY_MASK_AXI4_SLAVE_PORT_3 = LIBERO_SETTING_WAY_MASK_AXI4_PORT_3; - CACHE_CTRL->WAY_MASK_E51_ICACHE = LIBERO_SETTING_WAY_MASK_E51_ICACHE; - CACHE_CTRL->WAY_MASK_U54_1_DCACHE = LIBERO_SETTING_WAY_MASK_U54_1_DCACHE; - CACHE_CTRL->WAY_MASK_U54_1_ICACHE = LIBERO_SETTING_WAY_MASK_U54_1_ICACHE; - CACHE_CTRL->WAY_MASK_U54_2_DCACHE = LIBERO_SETTING_WAY_MASK_U54_2_DCACHE; - CACHE_CTRL->WAY_MASK_U54_2_ICACHE = LIBERO_SETTING_WAY_MASK_U54_2_ICACHE; - CACHE_CTRL->WAY_MASK_U54_3_DCACHE = LIBERO_SETTING_WAY_MASK_U54_3_DCACHE; - CACHE_CTRL->WAY_MASK_U54_3_ICACHE = LIBERO_SETTING_WAY_MASK_U54_3_ICACHE; - CACHE_CTRL->WAY_MASK_U54_4_DCACHE = LIBERO_SETTING_WAY_MASK_U54_4_DCACHE; - CACHE_CTRL->WAY_MASK_U54_4_ICACHE = LIBERO_SETTING_WAY_MASK_U54_4_ICACHE; + + __atomic_store_8 (&CACHE_CTRL->WAY_MASK_DMA , LIBERO_SETTING_WAY_MASK_DMA, __ATOMIC_RELAXED); + __atomic_store_8 (&CACHE_CTRL->WAY_MASK_AXI4_SLAVE_PORT_0 , LIBERO_SETTING_WAY_MASK_AXI4_PORT_0, __ATOMIC_RELAXED); + __atomic_store_8 (&CACHE_CTRL->WAY_MASK_AXI4_SLAVE_PORT_1 , LIBERO_SETTING_WAY_MASK_AXI4_PORT_1, __ATOMIC_RELAXED); + __atomic_store_8 (&CACHE_CTRL->WAY_MASK_AXI4_SLAVE_PORT_2 , LIBERO_SETTING_WAY_MASK_AXI4_PORT_2, __ATOMIC_RELAXED); + __atomic_store_8 (&CACHE_CTRL->WAY_MASK_AXI4_SLAVE_PORT_3 , LIBERO_SETTING_WAY_MASK_AXI4_PORT_3, __ATOMIC_RELAXED); + __atomic_store_8 (&CACHE_CTRL->WAY_MASK_E51_ICACHE , LIBERO_SETTING_WAY_MASK_E51_ICACHE, __ATOMIC_RELAXED); + __atomic_store_8 (&CACHE_CTRL->WAY_MASK_U54_1_DCACHE , LIBERO_SETTING_WAY_MASK_U54_1_DCACHE, __ATOMIC_RELAXED); + __atomic_store_8 (&CACHE_CTRL->WAY_MASK_U54_1_ICACHE , LIBERO_SETTING_WAY_MASK_U54_1_ICACHE, __ATOMIC_RELAXED); + __atomic_store_8 (&CACHE_CTRL->WAY_MASK_U54_2_DCACHE , LIBERO_SETTING_WAY_MASK_U54_2_DCACHE, __ATOMIC_RELAXED); + __atomic_store_8 (&CACHE_CTRL->WAY_MASK_U54_2_ICACHE , LIBERO_SETTING_WAY_MASK_U54_2_ICACHE, __ATOMIC_RELAXED); + __atomic_store_8 (&CACHE_CTRL->WAY_MASK_U54_3_DCACHE , LIBERO_SETTING_WAY_MASK_U54_3_DCACHE, __ATOMIC_RELAXED); + __atomic_store_8 (&CACHE_CTRL->WAY_MASK_U54_3_ICACHE , LIBERO_SETTING_WAY_MASK_U54_3_ICACHE, __ATOMIC_RELAXED); + __atomic_store_8 (&CACHE_CTRL->WAY_MASK_U54_4_DCACHE , LIBERO_SETTING_WAY_MASK_U54_4_DCACHE, __ATOMIC_RELAXED); + __atomic_store_8 (&CACHE_CTRL->WAY_MASK_U54_4_ICACHE , LIBERO_SETTING_WAY_MASK_U54_4_ICACHE, __ATOMIC_RELAXED); + #if (LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS != 0) /* @@ -133,19 +176,21 @@ __attribute__((weak)) void config_l2_cache(void) uint64_t * p_scratchpad = (uint64_t *)ZERO_DEVICE_BOTTOM; uint32_t ways_inc; uint64_t current_way = 0x1U << (((LIBERO_SETTING_WAY_ENABLE + 1U) - LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS) ); + for(ways_inc = 0; ways_inc < LIBERO_SETTING_NUM_SCRATCH_PAD_WAYS; ++ways_inc) { /* * Populate the scratchpad memory one way at a time. */ - CACHE_CTRL->WAY_MASK_E51_DCACHE = current_way; + __atomic_store_8 (&CACHE_CTRL->WAY_MASK_E51_DCACHE, current_way, __ATOMIC_RELAXED); mb(); /* * Write to the first 64-bit location of each cache block. */ for(inc = 0; inc < (WAY_BYTE_LENGTH / CACHE_BLOCK_BYTE_LENGTH); ++inc) { - *p_scratchpad = g_init_marker + inc; + + *p_scratchpad = g_init_marker /* + inc */; p_scratchpad += CACHE_BLOCK_BYTE_LENGTH / UINT64_BYTE_LENGTH; } current_way = current_way << 1U; @@ -155,9 +200,8 @@ __attribute__((weak)) void config_l2_cache(void) /* * Prevent E51 from evicting from scratchpad ways. */ - CACHE_CTRL->WAY_MASK_E51_DCACHE = LIBERO_SETTING_WAY_MASK_E51_DCACHE; + __atomic_store_8 (&CACHE_CTRL->WAY_MASK_E51_DCACHE , LIBERO_SETTING_WAY_MASK_E51_DCACHE, __ATOMIC_RELAXED); mb(); - } diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/common/mss_l2_cache.h b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/common/mss_l2_cache.h index d25bb15..4d92ec4 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/common/mss_l2_cache.h +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/common/mss_l2_cache.h @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright 2019-2022 Microchip FPGA Embedded Systems Solutions. + * Copyright 2019-2023 Microchip FPGA Embedded Systems Solutions. * * SPDX-License-Identifier: MIT * @@ -522,9 +522,61 @@ typedef struct { #define CACHE_CTRL ((volatile CACHE_CTRL_typedef *) CACHE_CTRL_BASE) + +/***************************************************************************//** + The end_l2_scratchpad_address() function is used to return the end address of + the initialised scratchpad. It is used in the startup code. + + @return + This end address of the allocated scratchpad. + + Example: + @code + // When called from assembly + call config_l2_cache + call end_l2_scratchpad_address # end address returned in a0 + call .clear_scratchpad + @endcode + */ +uint64_t end_l2_scratchpad_address(void); + +/***************************************************************************//** + The config_l2_cache() function is used to setup scratchpad. It will be used by + bootloader. e.g. Hart Software Services (HSS) + This code should only be executed from E51 to be functional. + Configure the L2 cache memory: + - Set the number of cache ways used as cache based on the MSS Configurator + settings. + - Configure some of the enabled ways as scratchpad based on space allocated + by the MSS configurator. + + Example: + @code + // When called from assembly + call config_l2_cache + call end_l2_scratchpad_address # end address returned in a0 + call .clear_scratchpad + @endcode + */ void config_l2_cache(void); + +/***************************************************************************//** + The check_num_scratch_ways() function is used tocheck that the linker script + has not allocated more ways than has been allocated by the MSS Configurator. + + Example: + @code + // When called from assembly + call config_l2_cache + call end_l2_scratchpad_address # end address returned in a0 + call .clear_scratchpad + @endcode + */ uint8_t check_num_scratch_ways(uint64_t *start, uint64_t *end); +uint32_t num_cache_ways(void); +uint32_t my_num_cache_ways(void); + #ifdef __cplusplus } #endif diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/common/nwc/mss_ddr.c b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/common/nwc/mss_ddr.c index c67539a..6216252 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/common/nwc/mss_ddr.c +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/common/nwc/mss_ddr.c @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright 2019-2022 Microchip FPGA Embedded Systems Solutions. + * Copyright 2019-2023 Microchip FPGA Embedded Systems Solutions. * * SPDX-License-Identifier: MIT * @@ -13,28 +13,40 @@ * @brief DDR related code * */ -//#define PRINT_CA_VREF_WINDOW "1" +/* #define PRINT_CA_VREF_WINDOW "1" */ #define MOVE_CK #define MANUAL_ADDCMD_TRAINIG -//#define FABRIC_NOISE_TEST +/* #define FABRIC_NOISE_TEST */ #include #include #include "mpfs_hal/mss_hal.h" #include "mss_nwc_init.h" #ifdef DDR_SUPPORT #include "mss_ddr_debug.h" -#include "simulation.h" #ifdef FABRIC_NOISE_TEST -#include "drivers/mss_gpio/mss_gpio.h" +#include "drivers/mss/mss_gpio/mss_gpio.h" #endif /******************************************************************************* * Local Defines */ /* This string is updated if any change to ddr driver */ -#define DDR_DRIVER_VERSION_STRING "0.4.019" +#define DDR_DRIVER_VERSION_STRING "0.4.023" const char DDR_DRIVER_VERSION[] = DDR_DRIVER_VERSION_STRING; /* Version | Comment */ +/* 0.4.023 | Changed default ADDCMD CLK push order for DDR4 to 0,45,90 */ +/* 0.4.022 | Tidied comments and simulation reference- no code change */ +/* 0.4.021 | Added options to increase post training tests during */ +/* | verification. The following defines can be added to */ +/* | mss_sw_config.h during verification of a new hardware */ +/* | design to overwrite the default values: */ +/* | (#define PATTERN_TEST_NUM_PATTERN_IN_CACHE_READS 2U) */ +/* | (#define PATTERN_TEST_NUM_OFFSET_INCS 16U) */ +/* | (#define PATTERN_TEST_SIZE 0x40000000U) */ +/* 0.4.020 | Added user option to turn on clk push during addcmd */ +/* | training for DDR4 and lpddr3. The following define enables: */ +/* | (#define LIBERO_SETTING_USE_CK_PUSH_DDR4_LPDDR3 1U) */ +/* | It is enabled by default */ /* 0.4.019 | Added full memory initalization function */ /* 0.4.018 | Corrected error introduced for DDR3 in 0.4.14 */ /* 0.4.017 | made SW_TRAING_BCLK_SCLK_OFFSET seperate for each mem type */ @@ -206,8 +218,10 @@ static void config_ddr_io_pull_up_downs_rpc_bits(DDR_TYPE ddr_type); static uint8_t ddr_manual_addcmd_refclk_offset(DDR_TYPE ddr_type, uint8_t * refclk_sweep_index); #endif static void lpddr4_manual_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_index, uint32_t retry_count, uint8_t *refclk_offset); +#if (LIBERO_SETTING_USE_CK_PUSH_DDR4_LPDDR3 == 0U) static void non_lpddr4_address_cmd_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_index, uint32_t *bclk_phase, uint32_t *bclk90_phase, uint32_t *refclk_phase ); -static void ddr3_address_cmd_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_index, uint32_t retry_count, uint32_t *bclk_phase, uint32_t *bclk90_phase, uint32_t *refclk_phase, uint8_t *refclk_offset); +#endif +static void address_cmd_training_with_ck_push(DDR_TYPE ddr_type, uint8_t * refclk_sweep_index, uint32_t retry_count, uint32_t *bclk_phase, uint32_t *bclk90_phase, uint32_t *refclk_phase, uint8_t *refclk_offset); /******************************************************************************* * External function declarations @@ -222,7 +236,7 @@ void debug_read_ddrcfg(void); #ifdef FABRIC_NOISE_TEST uint32_t fabric_noise_en = 1; uint32_t fabric_noise_en_log = 1; -uint32_t num_of_noise_blocks_en = 3; /* do not set less than 1 */ +uint32_t num_of_noise_blocks_en = 4; /* do not set less than 1 */ uint32_t noise_ena = 0x0; #endif @@ -249,8 +263,7 @@ uint32_t ddr_state_machine(DDR_SS_COMMAND command) { ddr_state = DDR_STATE_INIT; } - SIM_FEEDBACK0(100U + ddr_state); - SIM_FEEDBACK1(ddr_state); + switch (ddr_state) { default: @@ -271,10 +284,8 @@ uint32_t ddr_state_machine(DDR_SS_COMMAND command) * 1. Periodically check DDR access * 2. Run any tests, as directed */ -// return_status = ddr_monitor(); break; } - SIM_FEEDBACK1(0xFF000000UL + return_status); return (return_status); } @@ -314,12 +325,10 @@ static uint32_t ddr_setup(void) uint32_t ret_status = 0U; uint8_t number_of_lanes_to_calibrate; uint64_t mem_size; + volatile PATTERN_TEST_PARAMS pattern_test; ddr_type = LIBERO_SETTING_DDRPHY_MODE & DDRPHY_MODE_MASK; - SIM_FEEDBACK0(200U + ddr_training_state); - SIM_FEEDBACK1(0U); - switch (ddr_training_state) { case DDR_TRAINING_INIT: @@ -671,10 +680,8 @@ static uint32_t ddr_setup(void) //ALISTER 7/16/21 DDRCFG->MC_BASE2.INIT_AUTOINIT_DISABLE.INIT_AUTOINIT_DISABLE=0x1; } - DDRCFG->MC_BASE2.CTRLR_SOFT_RESET_N.CTRLR_SOFT_RESET_N =\ - 0x00000000U; - DDRCFG->MC_BASE2.CTRLR_SOFT_RESET_N.CTRLR_SOFT_RESET_N =\ - 0x00000001U; + DDRCFG->MC_BASE2.CTRLR_SOFT_RESET_N.CTRLR_SOFT_RESET_N = 0x00000000U; + DDRCFG->MC_BASE2.CTRLR_SOFT_RESET_N.CTRLR_SOFT_RESET_N = 0x00000001U; #endif /* !SOFT_RESET_PRE_TAG_172 */ #else /* Disable CKE */ @@ -692,7 +699,7 @@ static uint32_t ddr_setup(void) delay(DELAY_CYCLES_50_MICRO); /* reset pin is bit [1] */ - CFG_DDR_SGMII_PHY->training_reset.training_reset = 0x00000002U; + CFG_DDR_SGMII_PHY->training_reset.training_reset = 0x00000002U; #endif ddr_training_state = DDR_TRAINING_ROTATE_CLK; @@ -928,12 +935,12 @@ static uint32_t ddr_setup(void) CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x00000001U; for (uint32_t ca_indly=0;ca_indly < 30; ca_indly=ca_indly+5) { - CFG_DDR_SGMII_PHY->rpc145.rpc145 = ca_indly;//TEMPORARY - CFG_DDR_SGMII_PHY->rpc147.rpc147 = ca_indly;//TEMPORARY + CFG_DDR_SGMII_PHY->rpc145.rpc145 = ca_indly;/* TEMPORARY */ + CFG_DDR_SGMII_PHY->rpc147.rpc147 = ca_indly;/* TEMPORARY */ uint32_t break_loop=1; uint32_t in_window=0; vref_answer=128; - for (uint32_t vref=5;vref <30;vref++) //begin vref training + for (uint32_t vref=5;vref <30;vref++) /* begin vref training */ { uint32_t transition_a5_max=0; uint32_t transition_a5_min=128; @@ -947,7 +954,7 @@ static uint32_t ddr_setup(void) } IOSCB_BANKCONT_DDR->soft_reset = 0U; /* DPC_BITS NV_MAP reset */ - //SET VREF HERE + /* SET VREF HERE */ delay(DELAY_CYCLES_500_NS); dpc_bits_new=( CFG_DDR_SGMII_PHY->DPC_BITS.DPC_BITS & 0xFFFC0FFF ) | (vref <<12) | (0x1<<18); CFG_DDR_SGMII_PHY->DPC_BITS.DPC_BITS=dpc_bits_new; @@ -955,28 +962,22 @@ static uint32_t ddr_setup(void) IOSCB_BANKCONT_DDR->soft_reset = 1U; /* DPC_BITS NV_MAP reset */ delay(DELAY_CYCLES_500_NS); - - //ADDCMD Training improvement , adds delay on A9 loopback path - Suggested by Alister - //CFG_DDR_SGMII_PHY->rpc145.rpc145 = 0x8U; - uint32_t deltat = 128UL; - for (uint32_t j = 0; j<20 ; j++) { - //LOAD INDLY + /* LOAD INDLY */ CFG_DDR_SGMII_PHY->expert_dlycnt_direction_reg1.expert_dlycnt_direction_reg1 = 0x000000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x000000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x180000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x000000U; - //LOAD OUTDLY + /* LOAD OUTDLY */ CFG_DDR_SGMII_PHY->expert_dlycnt_direction_reg1.expert_dlycnt_direction_reg1 = 0x180000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x000000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x180000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x000000U; - // rx_a5_last=0x0; rx_a5_last=0xF; transition_a5=0; deltat=128; @@ -991,34 +992,31 @@ static uint32_t ddr_setup(void) rx_a5 = (CFG_DDR_SGMII_PHY->expert_addcmd_ln_readback.expert_addcmd_ln_readback & 0x0300) >> 8; if (transition_a5 != 0){ - if (((i - transition_a5) > 8) ){ //was 8 //////////// + if (((i - transition_a5) > 8) ){ break; } } if (transition_a5 ==0) { - // if ( ((rx_a5 ^ rx_a5_last) & (~rx_a5) ) ){ if ( ((rx_a5 ^ rx_a5_last) & rx_a5 ) ){ transition_a5 = i; } else{ - rx_a5_last=rx_a5; + rx_a5_last=rx_a5; } } else { - if ((i - transition_a5) == 4) //was 4 //////////// - //if (rx_a5!=rx_a5_last) //IF rx_ca not stable after 4 increments, set transition detected to 0 (false transition) - // if(!((rx_a5 ^ rx_a5_last) & (~rx_a5) )) + if ((i - transition_a5) == 4) if(!((rx_a5 ^ rx_a5_last) & rx_a5 )) { - transition_a5=0; //Continue looking for transition + transition_a5=0; /* Continue looking for transition */ rx_a5_last=rx_a5; } } - }//delay loop ends here + }/* delay loop ends here */ if (transition_a5 !=0) { if (transition_a5 > transition_a5_max) @@ -1031,7 +1029,7 @@ static uint32_t ddr_setup(void) transition_a5_min = transition_a5; } } - }//Sample loop ends here + } /* Sample loop ends here */ range_a5=transition_a5_max-transition_a5_min; if (transition_a5_min < 10){ break_loop=0; @@ -1040,7 +1038,6 @@ static uint32_t ddr_setup(void) if (range_a5 <=5) { - //(min(transition_a5_min - transition_a5_min_last,transition_a5_min_last-transition_a5_min) <=4)) if (transition_a5_min > transition_a5_min_last) { deltat=transition_a5_min-transition_a5_min_last; @@ -1072,9 +1069,9 @@ static uint32_t ddr_setup(void) #endif if(vref_answer==128) { - if ((in_window &0x3)==0x3) //ALISTER CHANGE 2/17/2021 + if ((in_window &0x3)==0x3) { - vref_answer=vref; //ALISTER CHANGE + vref_answer=vref; #ifndef PRINT_CA_VREF_WINDOW break; #endif @@ -1120,11 +1117,21 @@ static uint32_t ddr_setup(void) if ((ddr_type == DDR3)||(ddr_type == DDR3L)) { - ddr3_address_cmd_training(ddr_type, &refclk_sweep_index, retry_count, &bclk_phase, &bclk90_phase, &refclk_phase, &refclk_offset ); + address_cmd_training_with_ck_push(ddr_type,\ + &refclk_sweep_index, retry_count, &bclk_phase,\ + &bclk90_phase, &refclk_phase, &refclk_offset ); } else if (ddr_type != LPDDR4) { - non_lpddr4_address_cmd_training(ddr_type, &refclk_sweep_index, &bclk_phase, &bclk90_phase, &refclk_phase); +#if (LIBERO_SETTING_USE_CK_PUSH_DDR4_LPDDR3 == 1U) + address_cmd_training_with_ck_push(ddr_type,\ + &refclk_sweep_index, retry_count, &bclk_phase,\ + &bclk90_phase, &refclk_phase, &refclk_offset ); +#else + non_lpddr4_address_cmd_training(ddr_type,\ + &refclk_sweep_index, &bclk_phase, &bclk90_phase,\ + &refclk_phase); +#endif } /* END MANUAL BCLKSCLK TRAINING */ else /* LPDDR4 */ { @@ -1151,7 +1158,7 @@ static uint32_t ddr_setup(void) IOSCB_BANKCONT_DDR->soft_reset = 1U; /* DPC_BITS NV_MAP reset */ delay(DELAY_CYCLES_500_NS); /* SET CA DRV BACK TO CONFIGURED VALUE */ - CFG_DDR_SGMII_PHY->rpc1_DRV.rpc1_DRV=ca_drv; //return ca_drv to original value + CFG_DDR_SGMII_PHY->rpc1_DRV.rpc1_DRV=ca_drv; /* return ca_drv to original value */ ddr_training_state = DDR_TRAINING_IP_SM_START; } } @@ -1285,7 +1292,7 @@ static uint32_t ddr_setup(void) } break; case DDR_TRAINING_IP_SM_WRLVL: - //END VREFTRN + /* END VREFTRN */ if(LIBERO_SETTING_TRAINING_SKIP_SETTING & WRLVL_BIT) { timeout = 0xFFFF; @@ -1350,11 +1357,8 @@ static uint32_t ddr_setup(void) for (lane_sel=0U; lane_sel< \ LIBERO_SETTING_DATA_LANES_USED; lane_sel++) { - SIM_FEEDBACK1(1000U); delay(10U); - SIM_FEEDBACK1(1001U); - CFG_DDR_SGMII_PHY->lane_select.lane_select =\ - lane_sel; + CFG_DDR_SGMII_PHY->lane_select.lane_select = lane_sel; delay(10U); /* * verify cmd address results @@ -1451,7 +1455,8 @@ static uint32_t ddr_setup(void) #define DCT_EXTRA_CHECKS #ifdef DCT_EXTRA_CHECKS uint32_t temp = 0U, gt_clk_sel = (CFG_DDR_SGMII_PHY->gt_clk_sel.gt_clk_sel & 3U); - if(((CFG_DDR_SGMII_PHY->gt_txdly.gt_txdly)&0xFFU) == 0U) // Gate training tx_dly check: AL + /* Gate training tx_dly check: */ + if(((CFG_DDR_SGMII_PHY->gt_txdly.gt_txdly)&0xFFU) == 0U) { temp++; if(gt_clk_sel == 0) @@ -1511,7 +1516,6 @@ static uint32_t ddr_setup(void) #endif if(t_status == 0U) { - SIM_FEEDBACK1(21U); /* * We can now set vref on the memory * mode register for lpddr4 @@ -1529,7 +1533,6 @@ static uint32_t ddr_setup(void) } else /* fail, try again */ { - SIM_FEEDBACK1(20U); ddr_training_state = DDR_TRAINING_FAIL_SM_VERIFY; } } @@ -1601,21 +1604,19 @@ static uint32_t ddr_setup(void) uint32_t dly_firstpass=0xFF; uint32_t dly_right_edge=20U; uint32_t pass=0U; - for(lane = 0U; lane < number_of_lanes_to_calibrate; lane++) //load DQ + for(lane = 0U; lane < number_of_lanes_to_calibrate; lane++) /* load DQ */ { load_dq(lane); } delay(DELAY_CYCLES_50_MICRO); for (uint32_t dq_dly=0U;dq_dly < 20U ; dq_dly=dq_dly+1U){ - CFG_DDR_SGMII_PHY->rpc220.rpc220 = dq_dly; //set DQ load value - for(lane = 0U; lane < number_of_lanes_to_calibrate; lane++) //load DQ + CFG_DDR_SGMII_PHY->rpc220.rpc220 = dq_dly; /* set DQ load value */ + for(lane = 0U; lane < number_of_lanes_to_calibrate; lane++) /* load DQ */ { load_dq(lane); } - SIM_FEEDBACK1(1U); - - delay(DELAY_CYCLES_50_MICRO); + delay(DELAY_CYCLES_50_MICRO); pass =\ write_calibration_using_mtc(\ number_of_lanes_to_calibrate); @@ -1654,11 +1655,10 @@ static uint32_t ddr_setup(void) #ifdef DEBUG_DDR_INIT (void)uprint32(g_debug_uart, "\n\r dq_dly_answer ",\ CFG_DDR_SGMII_PHY->rpc220.rpc220); - //(void)uprint32(g_debug_uart, " vrefdq_answer ", (vref_firstpass + vref_right_edge)/2); (void)uprint32(g_debug_uart, " wr calib result ",\ calib_data.write_cal.lane_calib_result); #endif - for(lane = 0U; lane < number_of_lanes_to_calibrate; lane++) //load DQ + for(lane = 0U; lane < number_of_lanes_to_calibrate; lane++) /* load DQ */ { load_dq(lane); } @@ -1683,7 +1683,6 @@ static uint32_t ddr_setup(void) } else { - SIM_FEEDBACK1(2U); error =\ write_calibration_using_mtc(number_of_lanes_to_calibrate); } @@ -1691,8 +1690,7 @@ static uint32_t ddr_setup(void) if(error) { ddr_error_count++; - SIM_FEEDBACK1(106U); - } + } } if(error == 0U) @@ -1862,7 +1860,7 @@ static uint32_t ddr_setup(void) #ifdef SKIP_VERIFY_PATTERN_IN_CACHE ddr_training_state = DDR_FULL_32BIT_WRC_CHECK; #else - ddr_training_state = DDR_LOAD_PATTERN_TO_CACHE; + ddr_training_state = DDR_LOAD_PATTERN_TO_CACHE_SETUP; #endif } else @@ -1870,10 +1868,17 @@ static uint32_t ddr_setup(void) ddr_training_state = DDR_TRAINING_FAIL_32BIT_CACHE_CHECK; } break; + case DDR_LOAD_PATTERN_TO_CACHE_SETUP: + pattern_test.base = LIBERO_SETTING_DDR_32_CACHE; + pattern_test.size = PATTERN_TEST_SIZE; + pattern_test.pattern_type = DDR_TEST_FILL; + pattern_test.pattern_offset = PATTERN_TEST_START_OFFSET; + pattern_test.num_offsets_to_try = PATTERN_TEST_NUM_OFFSET_INCS; + pattern_test.offset_cnt = 0U; + ddr_training_state = DDR_LOAD_PATTERN_TO_CACHE; + break; case DDR_LOAD_PATTERN_TO_CACHE: - load_ddr_pattern(LIBERO_SETTING_DDR_32_CACHE,\ - SIZE_OF_PATTERN_TEST*2, DDR_TEST_FILL,\ - SIZE_OF_PATTERN_OFFSET); + load_ddr_pattern(&pattern_test); if(error == 0U) { ddr_training_state = DDR_VERIFY_PATTERN_IN_CACHE; @@ -1884,22 +1889,22 @@ static uint32_t ddr_setup(void) } break; case DDR_VERIFY_PATTERN_IN_CACHE: - error = test_ddr(NO_PATTERN_IN_CACHE_READS, SIZE_OF_PATTERN_TEST); + error = test_ddr(PATTERN_TEST_NUM_PATTERN_IN_CACHE_READS, &pattern_test); #if ((LIBERO_FAST_START & 0x04) == 0U) - error = error | test_ddr(NO_PATTERN_IN_CACHE_READS, SIZE_OF_PATTERN_TEST); - error = error | test_ddr(NO_PATTERN_IN_CACHE_READS, SIZE_OF_PATTERN_TEST); + error = error | test_ddr(PATTERN_TEST_NUM_PATTERN_IN_CACHE_READS, &pattern_test); + error = error | test_ddr(PATTERN_TEST_NUM_PATTERN_IN_CACHE_READS, &pattern_test); #endif if(error == 0U) { -#ifdef DEBUG_DDR_INIT - (void)uprint32(g_debug_uart, "\n\r\n\r wr write latency ",\ - DDRCFG->DFI.CFG_DFI_T_PHY_WRLAT.CFG_DFI_T_PHY_WRLAT); -#if (TUNE_RPC_166_VALUE == 1) - (void)uprint32(g_debug_uart, "\n\r rpc_166_fifo_offset: ",\ - rpc_166_fifo_offset); -#endif -#endif - ddr_training_state = DDR_FULL_32BIT_WRC_CHECK; + if(++pattern_test.offset_cnt < pattern_test.num_offsets_to_try) + { + pattern_test.pattern_offset++; + ddr_training_state = DDR_LOAD_PATTERN_TO_CACHE; + } + else + { + ddr_training_state = DDR_FULL_32BIT_WRC_CHECK; + } } else { @@ -1932,7 +1937,6 @@ static uint32_t ddr_setup(void) CFG_DDR_SGMII_PHY->rpc166.rpc166 = rpc_166_fifo_offset; /* PAUSE to reset fifo (loads new RXPTR value).*/ - //CFG_DDR_SGMII_PHY->expert_dfi_status_override_to_shim.expert_dfi_status_override_to_shim = 0x07U; CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x1U; CFG_DDR_SGMII_PHY->expert_dlycnt_pause.expert_dlycnt_pause =\ 0x0000003EU ; @@ -1940,7 +1944,7 @@ static uint32_t ddr_setup(void) 0x00000000U; CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x8U; delay(DELAY_CYCLES_50_MICRO); - //END PAUSE + /* END PAUSE */ #else if(num_rpc_166_retires < NUM_RPC_166_VALUES) { @@ -1966,6 +1970,14 @@ static uint32_t ddr_setup(void) } break; case DDR_FULL_32BIT_WRC_CHECK: +#ifdef DEBUG_DDR_INIT + (void)uprint32(g_debug_uart, "\n\r\n\r wr write latency ",\ + DDRCFG->DFI.CFG_DFI_T_PHY_WRLAT.CFG_DFI_T_PHY_WRLAT); +#if (TUNE_RPC_166_VALUE == 1) + (void)uprint32(g_debug_uart, "\n\r rpc_166_fifo_offset: ",\ + rpc_166_fifo_offset); +#endif +#endif if(error == 0U) { ddr_training_state = DDR_FULL_64BIT_NC_CHECK; @@ -2050,8 +2062,12 @@ static uint32_t ddr_setup(void) { mem_size = LIBERO_SETTING_CFG_AXI_END_ADDRESS_AXI2_1 +\ (LIBERO_SETTING_CFG_AXI_END_ADDRESS_AXI2_0 + 1U); - load_ddr_pattern(LIBERO_SETTING_DDR_64_NON_CACHE, mem_size,\ - DDR_INIT_FILL, 0U); + pattern_test.base = LIBERO_SETTING_DDR_64_NON_CACHE; + pattern_test.size = mem_size; + pattern_test.pattern_type = DDR_INIT_FILL; + pattern_test.pattern_offset = 0U; + + load_ddr_pattern(&pattern_test); } #else mem_size = LIBERO_SETTING_CFG_AXI_END_ADDRESS_AXI2_1 +\ @@ -2092,6 +2108,18 @@ static uint32_t ddr_setup(void) * Configure Segments- address mapping, CFG0/CFG1 */ setup_ddr_segments(LIBERO_SEG_SETUP); + /* + * Clear the cache. Cache may have residue of writes related to the previous + * seg setup. These can endup being written back to DDR, so make sure cache + * is flushed. The cache is flushed by reading 2MB from cached backed memory + * We need to read from each master that has accessed the cache, as all + * masters may not have access to all the cache ways. + * When this function is being called, it is fair to assume only this hart + * and the PDMA has accessed the cache. + * We also assume this is in the bootloader and we have sole access to the + * PDMA + */ + clear_bootup_cache_ways(); } ret_status |= DDR_SETUP_DONE; ddr_training_state = DDR_TRAINING_FINISHED; @@ -2637,40 +2665,34 @@ static uint8_t memory_tests(void) uint64_t shift_walking_one = 4U; uint64_t start_address = 0x0000000000000000U; uint8_t error = 0U; - SIM_FEEDBACK1(199U); /* * Verify seg1 reg 2, datapath through AXI4 switch */ while(shift_walking_one <= 28U) /* 28 => 1G, as 2**28 == 256K and this is mult by (4 lanes) */ { - SIM_FEEDBACK1(shift_walking_one); start_address = (uint64_t)(BASE_ADDRESS_NON_CACHED_32_DDR + (0x1U< 1G + while(shift_walking_one <= 28U) /* 28 => 1G */ { - SIM_FEEDBACK1(shift_walking_one); start_address = (uint64_t)(BASE_ADDRESS_NON_CACHED_64_DDR + (0x1U<= 4U) @@ -2682,7 +2704,6 @@ static uint8_t memory_tests(void) if(error) { ddr_error_count++; - SIM_FEEDBACK1(201U); } } @@ -2691,19 +2712,16 @@ static uint8_t memory_tests(void) /* * Verify mtc */ - SIM_FEEDBACK1(600U); shift_walking_one = 4U; - while(shift_walking_one <= 28U) //28 => 1G + while(shift_walking_one <= 28U) /* 28 => 1G */ { - SIM_FEEDBACK1(shift_walking_one); start_address = (uint64_t)(0x1U<= 4U) @@ -2715,8 +2733,7 @@ static uint8_t memory_tests(void) if(error) { ddr_error_count++; - SIM_FEEDBACK1(204U); - } + } } shift_walking_one++; } @@ -2724,43 +2741,19 @@ static uint8_t memory_tests(void) /* * Verify seg0 reg 0, datapath through cache */ - SIM_FEEDBACK1(700U); shift_walking_one = 4U; - while(shift_walking_one <= 27U) //28 => 1G + while(shift_walking_one <= 27U) /* 28 => 1G */ { - SIM_FEEDBACK1(shift_walking_one); start_address = (uint64_t)(0x80000000U + (0x1U< 1G (0x10000000(address) * 4 (32bits wide)) - { - SIM_FEEDBACK1(shift_walking_one); - start_address = (uint64_t)(0x1000000000U + (0x1U<expert_dlycnt_move_reg0.expert_dlycnt_move_reg0 = 0U; @@ -2869,11 +2862,11 @@ static void load_dq(uint8_t lane) (CFG_DDR_SGMII_PHY->expert_dlycnt_move_reg1.expert_dlycnt_move_reg1\ & (uint32_t)~0x0FU); } - //set expert_dfi_status_override_to_shim = 0x7 + /* set expert_dfi_status_override_to_shim = 0x7 */ CFG_DDR_SGMII_PHY->expert_dfi_status_override_to_shim.expert_dfi_status_override_to_shim = 0x07U; - //set expert_mode_en = 0x21 + /* set expert_mode_en = 0x21 */ CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x21U; - //set dyn_ovr_dlycnt_dq_load* = 1 + /* set dyn_ovr_dlycnt_dq_load* = 1 */ if(lane < 4U) { CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg0.expert_dlycnt_load_reg0 =\ @@ -2884,7 +2877,7 @@ static void load_dq(uint8_t lane) CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 |=\ 0x0FU; } - //set dyn_ovr_dlycnt_dq_load* = 0 + /* set dyn_ovr_dlycnt_dq_load* = 0 */ CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg0.expert_dlycnt_load_reg0 = 0U; if(lane < 4U) { @@ -2896,7 +2889,7 @@ static void load_dq(uint8_t lane) (CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1\ & (uint32_t)~0x0FU); } - //set expert_mode_en = 0x8 + /* set expert_mode_en = 0x8 */ CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x8U; } @@ -2918,7 +2911,7 @@ static void load_dq(uint8_t lane) #ifdef SW_CONFIG_LPDDR_WR_CALIB_FN static void increment_dq(uint8_t lane, uint32_t move_count) { - //set dyn_ovr_dlycnt_dq_move* = 0 + /* set dyn_ovr_dlycnt_dq_move* = 0 */ if(lane < 4U) { CFG_DDR_SGMII_PHY->expert_dlycnt_move_reg0.expert_dlycnt_move_reg0 = 0U; @@ -2929,7 +2922,7 @@ static void increment_dq(uint8_t lane, uint32_t move_count) (CFG_DDR_SGMII_PHY->expert_dlycnt_move_reg1.expert_dlycnt_move_reg1\ & ~0x0FU); } - //set dyn_ovr_dlycnt_dq_direction* = 1 + /* set dyn_ovr_dlycnt_dq_direction* = 1 */ if(lane < 4U) { CFG_DDR_SGMII_PHY->expert_dlycnt_direction_reg0.expert_dlycnt_direction_reg0\ @@ -2948,7 +2941,7 @@ static void increment_dq(uint8_t lane, uint32_t move_count) move_count = move_count + move_count + move_count; while(move_count) { - // set dyn_ovr_dlycnt_dq_move* = 1 + /* set dyn_ovr_dlycnt_dq_move* = 1 */ if(lane < 4U) { CFG_DDR_SGMII_PHY->expert_dlycnt_move_reg0.expert_dlycnt_move_reg0\ @@ -2959,7 +2952,7 @@ static void increment_dq(uint8_t lane, uint32_t move_count) CFG_DDR_SGMII_PHY->expert_dlycnt_move_reg1.expert_dlycnt_move_reg1\ |= 0x0FU; } - // set dyn_ovr_dlycnt_dq_move* = 0 + /* set dyn_ovr_dlycnt_dq_move* = 0 */ CFG_DDR_SGMII_PHY->expert_dlycnt_move_reg0.expert_dlycnt_move_reg0 = 0U; if(lane < 4U) { @@ -3007,10 +3000,6 @@ static void set_write_calib(uint8_t user_lanes) */ CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x00000008U; - SIM_FEEDBACK1(0xFF000000); - SIM_FEEDBACK1(calib_data.write_cal.lane_calib_result); - SIM_FEEDBACK1(0xFF000000); - /* set the calibrated value */ CFG_DDR_SGMII_PHY->expert_wrcalib.expert_wrcalib =\ calib_data.write_cal.lane_calib_result; @@ -3152,8 +3141,7 @@ static uint8_t \ if(result == 0U) /* if true, we are good for all lanes, can stop looking */ { - SIM_FEEDBACK1(0xF7000000); - break; + break; } } else @@ -3167,25 +3155,10 @@ static uint8_t \ } /* end laneToTest */ if(result == 0U) /* if true, we are good for all lanes, can stop */ { /* looking */ - SIM_FEEDBACK1(0xF8000000); break; } } /* end cal_data */ - SIM_FEEDBACK1(0x01000000); - SIM_FEEDBACK1(calib_data.write_cal.lower[0]); - SIM_FEEDBACK1(0x02000000); - SIM_FEEDBACK1(calib_data.write_cal.lower[1]); - SIM_FEEDBACK1(0x03000000); - SIM_FEEDBACK1(calib_data.write_cal.lower[2]); - SIM_FEEDBACK1(0x04000000); - SIM_FEEDBACK1(calib_data.write_cal.lower[3]); - SIM_FEEDBACK1(0x05000000); - SIM_FEEDBACK1(calib_data.write_cal.lower[4]); - SIM_FEEDBACK1(0x06000000); - SIM_FEEDBACK1(calib_data.write_cal.lower[5]); - SIM_FEEDBACK1(0x07000000); - /* if calibration successful, calculate and set the value */ if(result == 0U) { @@ -3193,9 +3166,6 @@ static uint8_t \ set_write_calib(number_of_lanes_to_calibrate); } - SIM_FEEDBACK1(0x08000000); - SIM_FEEDBACK1(result); - SIM_FEEDBACK1(0x08000000); return (uint8_t)result; } @@ -3214,7 +3184,6 @@ static uint8_t mode_register_write(uint32_t MR_ADDR, uint32_t MR_DATA) /* * */ - //DDRCFG->MC_BASE2.INIT_MRR_MODE.INIT_MRR_MODE = 0x01; DDRCFG->MC_BASE2.INIT_MR_ADDR.INIT_MR_ADDR = MR_ADDR ; /* * next: @@ -4377,6 +4346,13 @@ static void init_ddrc(void) /** * setup_ddr_segments(void) * setup segment registers- translated DDR address as user requires + * + * This should only be called by the boot-loader + * + * Assumption: We are calling this during early boot. + * We have complete control of the PDMA. + * Only the PDMS and the hart calling this function have written to the DDR + * at this point. */ void setup_ddr_segments(SEG_SETUP option) { @@ -4408,6 +4384,33 @@ void setup_ddr_segments(SEG_SETUP option) SEG[0].u[7].raw = 0x01U; } +/** + * Clear cache ways used buring boot. + * These are the ways associated with the PDMA and the current hart being run + * + * Assumption: We are calling this during early boot. + * We have complete control of the PDMA. + * Only the PDMA and the hart calling this function have written to the DDR + * at this point. + */ +__attribute__((weak)) void clear_bootup_cache_ways(void) +{ + volatile PATTERN_TEST_PARAMS pattern_test; + + /* clear using pdma routine, uses the 4 channels */ + pattern_test.base = LIBERO_SETTING_DDR_32_CACHE; + pattern_test.size = TWO_MBYTES*4; + pattern_test.pattern_type = DDR_INIT_FILL; + pattern_test.pattern_offset = 0U; + + load_ddr_pattern(&pattern_test); + + /* clear using my d-cache ways */ + fill_cache_new_seg_address((void *)BASE_ADDRESS_CACHED_32_DDR, + (void *)(BASE_ADDRESS_CACHED_32_DDR + + TWO_MBYTES)); +} + /** * use_software_bclk_sclk_training() * @param ddr_type @@ -4856,8 +4859,6 @@ static uint8_t ddr_manual_addcmd_refclk_offset(DDR_TYPE ddr_type, uint8_t * refc } #endif - -//ALISTER 7/16/21 static uint32_t mode_register_masked_write(uint32_t address) { DDRCFG->MC_BASE2.INIT_CS.INIT_CS = 0x1; @@ -4928,6 +4929,42 @@ static uint32_t zq_cal(void) } #endif +uint32_t ddr_add_cmd_inc_feq[]={\ + ADD_CMD_INC_FREQ_DDR3,\ + ADD_CMD_INC_FREQ_DDR3L,\ + ADD_CMD_INC_FREQ_DDR4,\ + ADD_CMD_INC_FREQ_LPDDR3,\ + ADD_CMD_INC_FREQ_LPDDR4 }; + +uint32_t ddr_add_cmd_trans_a5_threshold[]={\ + ADD_CMD_TRANS_A5_THRES_DDR3,\ + ADD_CMD_TRANS_A5_THRES_DDR3L,\ + ADD_CMD_TRANS_A5_THRES_DDR4,\ + ADD_CMD_TRANS_A5_THRES_LPDDR3,\ + ADD_CMD_TRANS_A5_THRES_LPDDR4 }; + +uint32_t add_cmd_move_order_0_deg[]={\ + LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_0_DEG_DDR3,\ + LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_0_DEG_DDR3L,\ + LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_0_DEG_DDR4,\ + LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_0_DEG_LPDDR3,\ + LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_0_DEG_LPDDR4 }; + +uint32_t add_cmd_move_order_45_deg[]={\ + LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_45_DEG_DDR3,\ + LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_45_DEG_DDR3L,\ + LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_45_DEG_DDR4,\ + LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_45_DEG_LPDDR3,\ + LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_45_DEG_LPDDR4 }; + +uint32_t add_cmd_move_order_90_deg[]={\ + LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_90_DEG_DDR3,\ + LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_90_DEG_DDR3L,\ + LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_90_DEG_DDR4,\ + LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_90_DEG_LPDDR3,\ + LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_90_DEG_LPDDR4 }; + + /** * LPDDR4 traing exclusive * @param ddr_type @@ -4935,9 +4972,8 @@ static uint32_t zq_cal(void) */ static void lpddr4_manual_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_index, uint32_t retry_count, uint8_t *refclk_offset) { - //ALISTER 7/16/2021 DDRCFG->MC_BASE2.INIT_CS.INIT_CS = 0x1; - DDRCFG->MC_BASE2.INIT_DISABLE_CKE.INIT_DISABLE_CKE = 0x1; //moved up from below jan7th + DDRCFG->MC_BASE2.INIT_DISABLE_CKE.INIT_DISABLE_CKE = 0x1; delay(DELAY_CYCLES_5_MICRO); DDRCFG->MC_BASE2.INIT_FORCE_RESET.INIT_FORCE_RESET = 0x1; @@ -4987,7 +5023,7 @@ static void lpddr4_manual_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ind #endif DDRCFG->MC_BASE2.INIT_CS.INIT_CS = 0x1; - DDRCFG->MC_BASE2.INIT_DISABLE_CKE.INIT_DISABLE_CKE = 0x1; //moved up from below jan7th + DDRCFG->MC_BASE2.INIT_DISABLE_CKE.INIT_DISABLE_CKE = 0x1; delay(DELAY_CYCLES_5_MICRO); DDRCFG->MC_BASE2.INIT_FORCE_RESET.INIT_FORCE_RESET = 0x1; @@ -5048,12 +5084,12 @@ static void lpddr4_manual_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ind CFG_DDR_SGMII_PHY->expert_dfi_status_override_to_shim.expert_dfi_status_override_to_shim = 0x00000000U; for (uint32_t ca_indly=0;ca_indly < 30; ca_indly=ca_indly+5) { - CFG_DDR_SGMII_PHY->rpc145.rpc145 = ca_indly;//TEMPORARY - CFG_DDR_SGMII_PHY->rpc147.rpc147 = ca_indly;//TEMPORARY + CFG_DDR_SGMII_PHY->rpc145.rpc145 = ca_indly;/* TEMPORARY */ + CFG_DDR_SGMII_PHY->rpc147.rpc147 = ca_indly;/* TEMPORARY */ uint32_t break_loop=1; uint32_t in_window=0; vref_answer=128; - for (uint32_t vref=5;vref <30;vref++) //begin vref training + for (uint32_t vref=5;vref <30;vref++) /* begin vref training */ { uint32_t transition_a5_max=0; uint32_t transition_a5_min=128; @@ -5067,7 +5103,7 @@ static void lpddr4_manual_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ind } IOSCB_BANKCONT_DDR->soft_reset = 0U; /* DPC_BITS NV_MAP reset */ - //SET VREF HERE + /* SET VREF HERE */ delay(DELAY_CYCLES_500_NS); dpc_bits_new=( CFG_DDR_SGMII_PHY->DPC_BITS.DPC_BITS & 0xFFFC0FFF ) | (vref <<12) | (0x1<<18); CFG_DDR_SGMII_PHY->DPC_BITS.DPC_BITS=dpc_bits_new; @@ -5078,20 +5114,18 @@ static void lpddr4_manual_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ind uint32_t deltat = 128UL; for (uint32_t j = 0; j<20 ; j++) { - - //LOAD INDLY + /* LOAD INDLY */ CFG_DDR_SGMII_PHY->expert_dlycnt_direction_reg1.expert_dlycnt_direction_reg1 = 0x000000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x000000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x180000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x000000U; - //LOAD OUTDLY + /* LOAD OUTDLY */ CFG_DDR_SGMII_PHY->expert_dlycnt_direction_reg1.expert_dlycnt_direction_reg1 = 0x180000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x000000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x180000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x000000U; - // rx_a5_last=0x0; rx_a5_last=0xF; transition_a5=0; deltat=128; @@ -5106,7 +5140,7 @@ static void lpddr4_manual_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ind rx_a5 = (CFG_DDR_SGMII_PHY->expert_addcmd_ln_readback.expert_addcmd_ln_readback & 0x0300) >> 8; if (transition_a5 != 0){ - if (((i - transition_a5) > 8) ){ //was 8 //////////// + if (((i - transition_a5) > 8) ){ break; } } @@ -5120,14 +5154,14 @@ static void lpddr4_manual_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ind } } else { - if ((i - transition_a5) == 4) //was 4 //////////// + if ((i - transition_a5) == 4) if(!((rx_a5 ^ rx_a5_last) & rx_a5 )) { - transition_a5=0; //Continue looking for transition + transition_a5=0; /* Continue looking for transition */ rx_a5_last=rx_a5; } } - }//delay loop ends here + }/* delay loop ends here */ if (transition_a5 !=0) { if (transition_a5 > transition_a5_max) @@ -5140,14 +5174,13 @@ static void lpddr4_manual_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ind transition_a5_min = transition_a5; } } - }//Sample loop ends here + }/* Sample loop ends here */ range_a5=transition_a5_max-transition_a5_min; if (transition_a5_min < 10){ break_loop=0; } if (range_a5 <=5) { - //(min(transition_a5_min - transition_a5_min_last,transition_a5_min_last-transition_a5_min) <=4)) if (transition_a5_min > transition_a5_min_last) { deltat=transition_a5_min-transition_a5_min_last; @@ -5179,9 +5212,9 @@ static void lpddr4_manual_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ind #endif if(vref_answer==128) { - if ((in_window &0x3)==0x3) //ALISTER CHANGE 2/17/2021 + if ((in_window &0x3)==0x3) { - vref_answer=vref; //ALISTER CHANGE + vref_answer=vref; #ifndef PRINT_CA_VREF_WINDOW break; #endif @@ -5235,8 +5268,8 @@ static void lpddr4_manual_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ind uint32_t bclk90_phase=MSS_SCB_DDR_PLL->PLL_PHADJ & 0x3800; uint32_t refclk_phase; - //ALISTER 1/12/2022 SWEEPING CK OFFSET BEFORE CHANING refclk_offset - if ((retry_count % 6) == 0){ + /* SWEEPING CK OFFSET BEFORE CHANING refclk_offset */ + if ((retry_count % ddr_add_cmd_inc_feq[ddr_type]) == 0){ *refclk_offset = ddr_manual_addcmd_refclk_offset(ddr_type, refclk_sweep_index); } @@ -5244,13 +5277,13 @@ static void lpddr4_manual_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ind while(a5_offset_status != DDR_ADD_CMD_A5_OFFSET_PASS) { a5_offset_status = DDR_ADD_CMD_A5_OFFSET_PASS; - //ADDCMD Training improvement , adds delay on DDR clock loopback path + /* ADDCMD Training improvement , adds delay on DDR clock loopback path */ CFG_DDR_SGMII_PHY->rpc147.rpc147 = init_del_offset + rpc147_offset; - //ADDCMD Training improvement , adds delay on A9 loopback path + /* ADDCMD Training improvement , adds delay on A9 loopback path */ CFG_DDR_SGMII_PHY->rpc145.rpc145 = init_del_offset + rpc145_offset; - CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x00000023U; //ENABLE DLY Control & PLL Control + CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x00000023U; /* ENABLE DLY Control & PLL Control */ uint32_t rx_a5; uint32_t rx_a5_last; @@ -5267,15 +5300,15 @@ static void lpddr4_manual_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ind uint32_t transition_a5_max = 0U; for (j = 0U; j<16U ; j++) - { //Increase J loop to increase number of samples on transition_a5 (for noisy CA in LPDDR4) - //LOAD INDLY + { /* Increase J loop to increase number of samples on transition_a5 (for noisy CA in LPDDR4) */ + /* LOAD INDLY */ CFG_DDR_SGMII_PHY->expert_dlycnt_direction_reg1.expert_dlycnt_direction_reg1 = 0x000000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x000000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x180000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x000000U; - //LOAD OUTDLY + /* LOAD OUTDLY */ CFG_DDR_SGMII_PHY->expert_dlycnt_direction_reg1.expert_dlycnt_direction_reg1 = 0x180000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x000000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x180000U; @@ -5306,22 +5339,21 @@ static void lpddr4_manual_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ind { if (((i - transition_a5) > 8U) && ((i - transition_ck) > 8U)) { - //break; transitions_found = 1U; } } if (transition_ck == 0U) { - if (rx_ck_last != 0x5U) //IF EDGE DETECTED + if (rx_ck_last != 0x5U) /* IF EDGE DETECTED */ if (rx_ck == 0x5U) - transition_ck=i; //SET TRANSITION DETECTED AT I + transition_ck=i; /* SET TRANSITION DETECTED AT I */ rx_ck_last=rx_ck; } else { if ( (i - transition_ck ) == 4U) - if (rx_ck != rx_ck_last) //IF rx_ck not stable after 4 increments, set transition detected to 0 (false transition) + if (rx_ck != rx_ck_last) /* IF rx_ck not stable after 4 increments, set transition detected to 0 (false transition) */ { - transition_ck = 0U; //Continue looking for transition + transition_ck = 0U; /* Continue looking for transition */ rx_ck_last=rx_ck; } } @@ -5339,7 +5371,7 @@ static void lpddr4_manual_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ind { if(!((rx_a5 ^ rx_a5_last) & rx_a5 )) { - transition_a5=0; //Continue looking for transition + transition_a5=0; /* Continue looking for transition */ rx_a5_last=rx_a5; } } @@ -5392,7 +5424,7 @@ static void lpddr4_manual_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ind uint32_t min_refclkp1=0x8U; uint32_t min_refclkp2=0x8U; - if(transition_a5_max < TRANSITION_A5_THRESHOLD) + if(transition_a5_max < ddr_add_cmd_trans_a5_threshold[ddr_type]) { a5_offset_status |= DDR_ADD_CMD_A5_OFFSET_FAIL; } @@ -5408,7 +5440,6 @@ static void lpddr4_manual_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ind { if (difference[k] < min_diff){ - //updated on Jan10 min_refclk=k; min_refclkp1=(k+1)&0x7UL; min_refclkp2=(k+2)&0x7UL; @@ -5427,28 +5458,26 @@ static void lpddr4_manual_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ind a5_offset_status |= DDR_ADD_CMD_A5_OFFSET_FAIL; } if (min_refclk==0x8U) - { //If ADDCMD training fails due to extremely low frequency, use PLL to provide offset. + { /* If ADDCMD training fails due to extremely low frequency, use PLL to provide offset. */ a5_offset_status |= DDR_ADD_CMD_A5_OFFSET_FAIL_LOW_FREQ; } #ifdef MOVE_CK - if ((retry_count%3) == LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_ZERO){ //toggles between minimum CA delay and second smallest every 4 retrains. - //min_diff=second_diff; + /* toggles between minimum CA delay and second smallest every 4 retrains. */ + if ((retry_count%3) == add_cmd_move_order_0_deg[ddr_type]){ min_diffp1=min_diff; - //min_refclk=(min_refclk-0x1UL)&&(0x7UL); min_refclk=(min_refclk-0x1UL)&(0x7UL); #ifdef DEBUG_DDR_INIT (void)uprint32(g_debug_uart, "\n\r CK_PUSH = 0 degrees", 0x0UL); #endif } - else if ((retry_count%3) == LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_ONE){ + else if ((retry_count%3) == add_cmd_move_order_45_deg[ddr_type]){ #ifdef DEBUG_DDR_INIT (void)uprint32(g_debug_uart, "\n\r CK_PUSH = 45 degrees", 0x0UL); #endif } - else if ((retry_count%3) == LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_TWO){ //toggles between minimum CA delay and second smallest every 4 retrains. - //min_diff=second_diff; + else if ((retry_count%3) == add_cmd_move_order_90_deg[ddr_type]){ + /* toggles between minimum CA delay and second smallest every 4 retrains. */ min_diffp1=min_diffp2; - //min_refclk=(min_refclk-0x1UL)&&(0x7UL); min_refclk=min_refclkp1; #ifdef DEBUG_DDR_INIT (void)uprint32(g_debug_uart, "\n\r CK_PUSH = 90 degrees", 0x0UL); @@ -5461,13 +5490,13 @@ static void lpddr4_manual_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ind MSS_SCB_DDR_PLL->PLL_PHADJ = (0x00004003UL | bclk_phase | bclk90_phase | refclk_phase); MSS_SCB_DDR_PLL->PLL_PHADJ = (0x00000003UL | bclk_phase | bclk90_phase | refclk_phase); MSS_SCB_DDR_PLL->PLL_PHADJ = (0x00004003UL | bclk_phase | bclk90_phase | refclk_phase); - //LOAD INDLY + /* LOAD INDLY */ CFG_DDR_SGMII_PHY->expert_dlycnt_direction_reg1.expert_dlycnt_direction_reg1 = 0x000000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x000000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x180000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x000000U; - //LOAD OUTDLY + /* LOAD OUTDLY */ CFG_DDR_SGMII_PHY->expert_dlycnt_direction_reg1.expert_dlycnt_direction_reg1 = 0x180000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x000000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x180000U; @@ -5479,7 +5508,7 @@ static void lpddr4_manual_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ind CFG_DDR_SGMII_PHY->expert_dlycnt_move_reg1.expert_dlycnt_move_reg1 = 0x0U; } CFG_DDR_SGMII_PHY->expert_dlycnt_direction_reg1.expert_dlycnt_direction_reg1 = 0x000000U; - CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x00000000U; //DISABLE DLY Control & PLL Control + CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x00000000U; /* DISABLE DLY Control & PLL Control */ #ifdef DEBUG_DDR_INIT (void)uprint32(g_debug_uart, "\n\r MANUAL ADDCMD TRAINING Results:\r\n PLL OFFSET: ",min_refclk); (void)uprint32(g_debug_uart, "\n\r transition_a5_max: ", transition_a5_max); @@ -5493,7 +5522,8 @@ static void lpddr4_manual_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ind { if(init_del_offset < 0xFFU ) { - init_del_offset = init_del_offset + (transition_a5_max) + 5U; //if transition_a5 too low, increase indly offset on CK and CA and retrain + /* if transition_a5 too low, increase indly offset on CK and CA and retrain */ + init_del_offset = init_del_offset + (transition_a5_max) + 5U; } else { @@ -5501,13 +5531,13 @@ static void lpddr4_manual_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ind } } } /* end of for (j = 0U; j<16U ; j++) */ - } // while(a5_offset_status != DDR_ADD_CMD_A5_OFFSET_PASS) - } //END MANUAL ADDCMD TRAINING + } /* while(a5_offset_status != DDR_ADD_CMD_A5_OFFSET_PASS) */ + } /* END MANUAL ADDCMD TRAINING */ CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x0000008U; CFG_DDR_SGMII_PHY->expert_dfi_status_override_to_shim.expert_dfi_status_override_to_shim = 0x00000000U; - //POST_INITIALIZATION + /* POST_INITIALIZATION */ CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x9U; CFG_DDR_SGMII_PHY->expert_dlycnt_pause.expert_dlycnt_pause = 0x0000003FU ; CFG_DDR_SGMII_PHY->expert_dlycnt_pause.expert_dlycnt_pause = 0x00000000U; @@ -5564,14 +5594,15 @@ static void lpddr4_manual_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ind * @param bclk90_phase * @param refclk_phase */ +#if (LIBERO_SETTING_USE_CK_PUSH_DDR4_LPDDR3 == 0U) static void non_lpddr4_address_cmd_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_index, uint32_t *bclk_phase, uint32_t *bclk90_phase, uint32_t *refclk_phase ) { /* Begin MANUAL ADDCMD TRAINING */ uint8_t refclk_offset; uint32_t init_del_offset = 0x8U; uint32_t a5_offset_status; - uint32_t rpc147_offset = 0x2U; //4 //0 - uint32_t rpc145_offset = 0x0U; //0 //4 + uint32_t rpc147_offset = 0x2U; + uint32_t rpc145_offset = 0x0U; refclk_offset = ddr_manual_addcmd_refclk_offset(ddr_type, refclk_sweep_index); a5_offset_status = DDR_ADD_CMD_A5_OFFSET_FAIL; @@ -5579,13 +5610,13 @@ static void non_lpddr4_address_cmd_training(DDR_TYPE ddr_type, uint8_t * refclk_ { a5_offset_status = DDR_ADD_CMD_A5_OFFSET_PASS; - //ADDCMD Training improvement , adds delay on DDR clock loopback path - Suggested by Alister + /* ADDCMD Training improvement , adds delay on DDR clock loopback path */ CFG_DDR_SGMII_PHY->rpc147.rpc147 = init_del_offset + rpc147_offset; - //ADDCMD Training improvement , adds delay on A9 loopback path - Suggested by Alister + /* ADDCMD Training improvement , adds delay on A9 loopback path */ CFG_DDR_SGMII_PHY->rpc145.rpc145 = init_del_offset + rpc145_offset; - CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x00000003U; //ENABLE DLY Control & PLL Control + CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x00000003U; /* ENABLE DLY Control & PLL Control */ uint32_t rx_a5; uint32_t rx_a5_last; @@ -5602,14 +5633,14 @@ static void non_lpddr4_address_cmd_training(DDR_TYPE ddr_type, uint8_t * refclk_ uint32_t transition_a5_max = 0U; for (j = 0U; j<16U ; j++) - { //Increase J loop to increase number of samples on transition_a5 (for noisy CA in LPDDR4) - //LOAD INDLY + { /* Increase J loop to increase number of samples on transition_a5 (for noisy CA in LPDDR4) */ + /* LOAD INDLY */ CFG_DDR_SGMII_PHY->expert_dlycnt_direction_reg1.expert_dlycnt_direction_reg1 = 0x000000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x000000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x180000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x000000U; - //LOAD OUTDLY + /* LOAD OUTDLY */ CFG_DDR_SGMII_PHY->expert_dlycnt_direction_reg1.expert_dlycnt_direction_reg1 = 0x180000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x000000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x180000U; @@ -5640,22 +5671,22 @@ static void non_lpddr4_address_cmd_training(DDR_TYPE ddr_type, uint8_t * refclk_ { if (((i - transition_a5) > 8U) && ((i - transition_ck) > 8U)) { - //break; transitions_found = 1U; } } if (transition_ck == 0U) { - if (rx_ck_last != 0x5U) //IF EDGE DETECTED + if (rx_ck_last != 0x5U) /* IF EDGE DETECTED */ if (rx_ck == 0x5U) - transition_ck=i; //SET TRANSITION DETECTED AT I + transition_ck=i; /* SET TRANSITION DETECTED AT I */ rx_ck_last=rx_ck; } else { if ( (i - transition_ck ) == 4U) - if (rx_ck != rx_ck_last) //IF rx_ck not stable after 4 increments, set transition detected to 0 (false transition) + /* IF rx_ck not stable after 4 increments, set transition detected to 0 (false transition) */ + if (rx_ck != rx_ck_last) { - transition_ck = 0U; //Continue looking for transition + transition_ck = 0U; /* Continue looking for transition */ rx_ck_last=rx_ck; } } @@ -5672,7 +5703,7 @@ static void non_lpddr4_address_cmd_training(DDR_TYPE ddr_type, uint8_t * refclk_ if ((i - transition_a5) == 4U) if(!((rx_a5 ^ rx_a5_last) & rx_a5 )) { - transition_a5=0; //Continue looking for transition + transition_a5=0; /* Continue looking for transition */ rx_a5_last=rx_a5; } } @@ -5745,7 +5776,7 @@ static void non_lpddr4_address_cmd_training(DDR_TYPE ddr_type, uint8_t * refclk_ a5_offset_status |= DDR_ADD_CMD_A5_OFFSET_FAIL; } if (min_refclk==0x8U) - { //If ADDCMD training fails due to extremely low frequency, use PLL to provide offset. + { /* If ADDCMD training fails due to extremely low frequency, use PLL to provide offset. */ a5_offset_status |= DDR_ADD_CMD_A5_OFFSET_FAIL_LOW_FREQ; } if(a5_offset_status == DDR_ADD_CMD_A5_OFFSET_PASS) @@ -5754,13 +5785,13 @@ static void non_lpddr4_address_cmd_training(DDR_TYPE ddr_type, uint8_t * refclk_ MSS_SCB_DDR_PLL->PLL_PHADJ = (0x00004003UL | *bclk_phase | *bclk90_phase | *refclk_phase); MSS_SCB_DDR_PLL->PLL_PHADJ = (0x00000003UL | *bclk_phase | *bclk90_phase | *refclk_phase); MSS_SCB_DDR_PLL->PLL_PHADJ = (0x00004003UL | *bclk_phase | *bclk90_phase | *refclk_phase); - //LOAD INDLY + /* LOAD INDLY */ CFG_DDR_SGMII_PHY->expert_dlycnt_direction_reg1.expert_dlycnt_direction_reg1 = 0x000000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x000000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x180000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x000000U; - //LOAD OUTDLY + /* LOAD OUTDLY */ CFG_DDR_SGMII_PHY->expert_dlycnt_direction_reg1.expert_dlycnt_direction_reg1 = 0x180000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x000000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x180000U; @@ -5772,7 +5803,7 @@ static void non_lpddr4_address_cmd_training(DDR_TYPE ddr_type, uint8_t * refclk_ CFG_DDR_SGMII_PHY->expert_dlycnt_move_reg1.expert_dlycnt_move_reg1 = 0x0U; } CFG_DDR_SGMII_PHY->expert_dlycnt_direction_reg1.expert_dlycnt_direction_reg1 = 0x000000U; - CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x00000000U; //DISABLE DLY Control & PLL Control + CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x00000000U; /* DISABLE DLY Control & PLL Control */ #ifdef DEBUG_DDR_INIT (void)uprint32(g_debug_uart, "\n\r MANUAL ADDCMD TRAINING Results:\r\n PLL OFFSET: ",min_refclk); (void)uprint32(g_debug_uart, "\n\r transition_a5_max: ", transition_a5_max); @@ -5785,7 +5816,7 @@ static void non_lpddr4_address_cmd_training(DDR_TYPE ddr_type, uint8_t * refclk_ { if(init_del_offset < 0xFFU ) { - //if transition_a5 too low, increase indly offset on CK and CA and retrain + /* if transition_a5 too low, increase indly offset on CK and CA and retrain */ init_del_offset = init_del_offset + (transition_a5_max) + 5U; } else @@ -5796,11 +5827,11 @@ static void non_lpddr4_address_cmd_training(DDR_TYPE ddr_type, uint8_t * refclk_ } } } /* END MANUAL BCLKSCLK TRAINING */ - +#endif /** - * ddr3_address_cmd_training() - * @param ddr_type DDR3 + * address_cmd_training_with_ck_push() + * @param ddr_type DDR3, DDR4 and LPDDR3 * @param refclk_sweep_index * @param retry_count * @param bclk_phase @@ -5808,15 +5839,15 @@ static void non_lpddr4_address_cmd_training(DDR_TYPE ddr_type, uint8_t * refclk_ * @param refclk_phase * @param refclk_offset */ -static void ddr3_address_cmd_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_index, uint32_t retry_count, uint32_t *bclk_phase, uint32_t *bclk90_phase, uint32_t *refclk_phase, uint8_t *refclk_offset ) +static void address_cmd_training_with_ck_push(DDR_TYPE ddr_type, uint8_t * refclk_sweep_index, uint32_t retry_count, uint32_t *bclk_phase, uint32_t *bclk90_phase, uint32_t *refclk_phase, uint8_t *refclk_offset ) { /* Begin MANUAL ADDCMD TRAINING */ uint32_t init_del_offset = 0x8U; uint32_t a5_offset_status; - uint32_t rpc147_offset = 0x2U; //4 //0 input delays, cmd and clk - uint32_t rpc145_offset = 0x0U; //0 //4 + uint32_t rpc147_offset = 0x2U; /* input delays, cmd and clk */ + uint32_t rpc145_offset = 0x0U; - if( (retry_count%3)==0) + if( (retry_count % ddr_add_cmd_inc_feq[ddr_type])==0) { *refclk_offset = ddr_manual_addcmd_refclk_offset(ddr_type, refclk_sweep_index); } @@ -5829,11 +5860,11 @@ static void ddr3_address_cmd_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ while(a5_offset_status != DDR_ADD_CMD_A5_OFFSET_PASS) { a5_offset_status = DDR_ADD_CMD_A5_OFFSET_PASS; - //ADDCMD Training improvement , adds delay on DDR clock loopback path + /* ADDCMD Training improvement , adds delay on DDR clock loopback path */ CFG_DDR_SGMII_PHY->rpc147.rpc147 = init_del_offset + rpc147_offset; - //ADDCMD Training improvement , adds delay on A9 loopback path + /* ADDCMD Training improvement , adds delay on A9 loopback path */ CFG_DDR_SGMII_PHY->rpc145.rpc145 = init_del_offset + rpc145_offset; - CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x00000003U; //ENABLE DLY Control & PLL Control + CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x00000003U; /* ENABLE DLY Control & PLL Control */ uint32_t rx_a5; uint32_t rx_a5_last; @@ -5849,14 +5880,14 @@ static void ddr3_address_cmd_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ uint32_t transition_a5_max = 0U; for (j = 0U; j<16U ; j++) - { //Increase J loop to increase number of samples on transition_a5 (for noisy CA in LPDDR4) - //LOAD INDLY + { /* Increase J loop to increase number of samples on transition_a5 (for noisy CA in LPDDR4) */ + /* LOAD INDLY */ CFG_DDR_SGMII_PHY->expert_dlycnt_direction_reg1.expert_dlycnt_direction_reg1 = 0x000000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x000000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x180000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x000000U; - //LOAD OUTDLY + /* LOAD OUTDLY */ CFG_DDR_SGMII_PHY->expert_dlycnt_direction_reg1.expert_dlycnt_direction_reg1 = 0x180000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x000000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x180000U; @@ -5887,22 +5918,22 @@ static void ddr3_address_cmd_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ { if (((i - transition_a5) > 8U) && ((i - transition_ck) > 8U)) { - //break; transitions_found = 1U; } } if (transition_ck == 0U) { - if (rx_ck_last != 0x5U) //IF EDGE DETECTED + if (rx_ck_last != 0x5U) /* IF EDGE DETECTED */ if (rx_ck == 0x5U) - transition_ck=i; //SET TRANSITION DETECTED AT I + transition_ck=i; /* SET TRANSITION DETECTED AT I */ rx_ck_last=rx_ck; } else { if ( (i - transition_ck ) == 4U) - if (rx_ck != rx_ck_last) //IF rx_ck not stable after 4 increments, set transition detected to 0 (false transition) + /* IF rx_ck not stable after 4 increments, set transition detected to 0 (false transition) */ + if (rx_ck != rx_ck_last) { - transition_ck = 0U; //Continue looking for transition + transition_ck = 0U; /* Continue looking for transition */ rx_ck_last=rx_ck; } } @@ -5919,7 +5950,7 @@ static void ddr3_address_cmd_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ if ((i - transition_a5) == 4U) if(!((rx_a5 ^ rx_a5_last) & rx_a5 )) { - transition_a5=0; //Continue looking for transition + transition_a5=0; /* Continue looking for transition */ rx_a5_last=rx_a5; } } @@ -5974,7 +6005,7 @@ static void ddr3_address_cmd_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ uint32_t third_refclk=0x8U; #endif - if(transition_a5_max < TRANSITION_A5_THRESHOLD) + if(transition_a5_max < ddr_add_cmd_trans_a5_threshold[ddr_type]) { a5_offset_status |= DDR_ADD_CMD_A5_OFFSET_FAIL; } @@ -5991,7 +6022,7 @@ static void ddr3_address_cmd_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ { uint32_t k=7-l; if (difference[k] < min_diff){ - //ALISTER ADDED TO MOVE CK without changing CK/CA offset + /* MOVE CK without changing CK/CA offset */ #ifdef MOVE_CK second_refclk=(k+1)&0x7UL; second_diff=difference[second_refclk]; @@ -6008,26 +6039,40 @@ static void ddr3_address_cmd_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ #endif } #ifdef MOVE_CK - if (((retry_count)%3) == 0x1){ + if (((retry_count)%3) == add_cmd_move_order_45_deg[ddr_type]) + { min_diff=second_diff; min_refclk=second_refclk; #ifdef DEBUG_DDR_INIT - (void)uprint32(g_debug_uart, "\n\r CK_PUSH = 45 degrees", 0x0UL); + (void)uprint32(g_debug_uart, "\n\r CK_PUSH = 45 degrees",\ + add_cmd_move_order_45_deg[ddr_type]); #endif - } else if (((retry_count )%3) == 0x2){ + } + else if (((retry_count )%3) == add_cmd_move_order_90_deg[ddr_type]) + { min_diff=third_diff; min_refclk=third_refclk; #ifdef DEBUG_DDR_INIT - (void)uprint32(g_debug_uart, "\n\r CK_PUSH = 90 degrees", 0x0UL); + (void)uprint32(g_debug_uart, "\n\r CK_PUSH = 90 degrees",\ + add_cmd_move_order_90_deg[ddr_type]); #endif } +#ifdef DEBUG_DDR_INIT + else if (((retry_count )%3) == add_cmd_move_order_0_deg[ddr_type]) + { + + (void)uprint32(g_debug_uart, "\n\r CK_PUSH = 0 degrees",\ + add_cmd_move_order_0_deg[ddr_type]); + } #endif +#endif /* MOVE_CK */ + if(min_diff == 0xFFU) { a5_offset_status |= DDR_ADD_CMD_A5_OFFSET_FAIL; } if (min_refclk==0x8U) - { //If ADDCMD training fails due to extremely low frequency, use PLL to provide offset. + { /* If ADDCMD training fails due to extremely low frequency, use PLL to provide offset. */ a5_offset_status |= DDR_ADD_CMD_A5_OFFSET_FAIL_LOW_FREQ; } if(a5_offset_status == DDR_ADD_CMD_A5_OFFSET_PASS) @@ -6036,13 +6081,13 @@ static void ddr3_address_cmd_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ MSS_SCB_DDR_PLL->PLL_PHADJ = (0x00004003UL | *bclk_phase | *bclk90_phase | *refclk_phase); MSS_SCB_DDR_PLL->PLL_PHADJ = (0x00000003UL | *bclk_phase | *bclk90_phase | *refclk_phase); MSS_SCB_DDR_PLL->PLL_PHADJ = (0x00004003UL | *bclk_phase | *bclk90_phase | *refclk_phase); - //LOAD INDLY + /* LOAD INDLY */ CFG_DDR_SGMII_PHY->expert_dlycnt_direction_reg1.expert_dlycnt_direction_reg1 = 0x000000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x000000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x180000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x000000U; - //LOAD OUTDLY + /* LOAD OUTDLY */ CFG_DDR_SGMII_PHY->expert_dlycnt_direction_reg1.expert_dlycnt_direction_reg1 = 0x180000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x000000U; CFG_DDR_SGMII_PHY->expert_dlycnt_load_reg1.expert_dlycnt_load_reg1 = 0x180000U; @@ -6054,7 +6099,7 @@ static void ddr3_address_cmd_training(DDR_TYPE ddr_type, uint8_t * refclk_sweep_ CFG_DDR_SGMII_PHY->expert_dlycnt_move_reg1.expert_dlycnt_move_reg1 = 0x0U; } CFG_DDR_SGMII_PHY->expert_dlycnt_direction_reg1.expert_dlycnt_direction_reg1 = 0x000000U; - CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x00000000U; //DISABLE DLY Control & PLL Control + CFG_DDR_SGMII_PHY->expert_mode_en.expert_mode_en = 0x00000000U; /* DISABLE DLY Control & PLL Control */ #ifdef DEBUG_DDR_INIT (void)uprint32(g_debug_uart, "\n\r MANUAL ADDCMD TRAINING Results:\r\n PLL OFFSET: ",min_refclk); (void)uprint32(g_debug_uart, "\n\r transition_a5_max: ", transition_a5_max); diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/common/nwc/mss_ddr.h b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/common/nwc/mss_ddr.h index f75bf85..8f4dd0f 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/common/nwc/mss_ddr.h +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/common/nwc/mss_ddr.h @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright 2019-2022 Microchip FPGA Embedded Systems Solutions. + * Copyright 2019-2023 Microchip FPGA Embedded Systems Solutions. * * SPDX-License-Identifier: MIT * @@ -437,6 +437,38 @@ typedef enum DDR_MEMORY_ACCESS_ #define TRANSITION_A5_THRESHOLD 18U #endif +#ifndef ADD_CMD_INC_FREQ_DDR3 +#define ADD_CMD_INC_FREQ_DDR3 3U +#endif +#ifndef ADD_CMD_INC_FREQ_DDR3L +#define ADD_CMD_INC_FREQ_DDR3L 3U +#endif +#ifndef ADD_CMD_INC_FREQ_DDR4 +#define ADD_CMD_INC_FREQ_DDR4 3U +#endif +#ifndef ADD_CMD_INC_FREQ_LPDDR3 +#define ADD_CMD_INC_FREQ_LPDDR3 3U +#endif +#ifndef ADD_CMD_INC_FREQ_LPDDR4 +#define ADD_CMD_INC_FREQ_LPDDR4 6U +#endif + +#ifndef ADD_CMD_TRANS_A5_THRES_DDR3 +#define ADD_CMD_TRANS_A5_THRES_DDR3 18U +#endif +#ifndef ADD_CMD_TRANS_A5_THRES_DDR3L +#define ADD_CMD_TRANS_A5_THRES_DDR3L 18U +#endif +#ifndef ADD_CMD_TRANS_A5_THRES_DDR4 +#define ADD_CMD_TRANS_A5_THRES_DDR4 18U +#endif +#ifndef ADD_CMD_TRANS_A5_THRES_LPDDR3 +#define ADD_CMD_TRANS_A5_THRES_LPDDR3 18U +#endif +#ifndef ADD_CMD_TRANS_A5_THRES_LPDDR4 +#define ADD_CMD_TRANS_A5_THRES_LPDDR4 18U +#endif + /* Value used during write leveling */ #ifndef DPC_VRGEN_H_LPDDR4_WR_LVL_VAL #define DPC_VRGEN_H_LPDDR4_WR_LVL_VAL 0x5U @@ -454,16 +486,27 @@ typedef enum DDR_MEMORY_ACCESS_ #define DDR_FULL_32BIT_CACHED_CHECK_EN 0 #endif -#if !defined (NO_PATTERN_IN_CACHE_READS) -#define NO_PATTERN_IN_CACHE_READS 1 +#if !defined (PATTERN_TEST_NUM_PATTERN_IN_CACHE_READS) +#define PATTERN_TEST_NUM_PATTERN_IN_CACHE_READS 1 #endif -#if !defined (SIZE_OF_PATTERN_TEST) -#define SIZE_OF_PATTERN_TEST 0x02000000UL +#if !defined (PATTERN_TEST_SIZE) +#define PATTERN_TEST_SIZE 0x02000000UL #endif -#if !defined (SIZE_OF_PATTERN_OFFSET) -#define SIZE_OF_PATTERN_OFFSET 12U +#if !defined (PATTERN_TEST_START_OFFSET) +#define PATTERN_TEST_START_OFFSET 12U +#endif + +#if !defined (PATTERN_TEST_NUM_OFFSET_INCS) +#define PATTERN_TEST_NUM_OFFSET_INCS 1U +#endif + +#define PATTERN_TEST_MIN_OFFSET 1U +#define PATTERN_TEST_MAX_OFFSET 16U + +#if !defined (LIBERO_SETTING_USE_CK_PUSH_DDR4_LPDDR3) +#define LIBERO_SETTING_USE_CK_PUSH_DDR4_LPDDR3 1U #endif #if !defined (DEFAULT_RPC_166_VALUE) @@ -544,24 +587,100 @@ typedef enum DDR_MEMORY_ACCESS_ * Define in mss_sw_config.h will take precedence */ #if (LIBERO_SETTING_DDR_CLK == DDR_1600_MHZ) -#if !defined (LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_ZERO) -#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_ZERO 1U +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_0_DEG_DDR3 +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_0_DEG_DDR3 0U +#endif +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_0_DEG_DDR3L +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_0_DEG_DDR3L 0U +#endif +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_0_DEG_DDR4 +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_0_DEG_DDR4 0U +#endif +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_0_DEG_LPDDR3 +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_0_DEG_LPDDR3 2U +#endif +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_0_DEG_LPDDR4 +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_0_DEG_LPDDR4 1U +#endif + +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_45_DEG_DDR3 +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_45_DEG_DDR3 1U +#endif +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_45_DEG_DDR3L +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_45_DEG_DDR3L 1U #endif -#if !defined (LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_ONE) -#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_ONE 2U +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_45_DEG_DDR4 +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_45_DEG_DDR4 1U #endif -#if !defined (LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_TWO) -#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_TWO 0U +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_45_DEG_LPDDR3 +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_45_DEG_LPDDR3 0U +#endif +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_45_DEG_LPDDR4 +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_45_DEG_LPDDR4 2U +#endif + +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_90_DEG_DDR3 +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_90_DEG_DDR3 2U +#endif +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_90_DEG_DDR3L +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_90_DEG_DDR3L 2U +#endif +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_90_DEG_DDR4 +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_90_DEG_DDR4 2U +#endif +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_90_DEG_LPDDR3 +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_90_DEG_LPDDR3 1U +#endif +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_90_DEG_LPDDR4 +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_90_DEG_LPDDR4 0U #endif #else -#if !defined (LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_ZERO) -#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_ZERO 0U +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_0_DEG_DDR3 +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_0_DEG_DDR3 0U +#endif +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_0_DEG_DDR3L +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_0_DEG_DDR3L 0U +#endif +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_0_DEG_DDR4 +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_0_DEG_DDR4 0U +#endif +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_0_DEG_LPDDR3 +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_0_DEG_LPDDR3 2U +#endif +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_0_DEG_LPDDR4 +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_0_DEG_LPDDR4 0U +#endif + +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_45_DEG_DDR3 +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_45_DEG_DDR3 1U +#endif +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_45_DEG_DDR3L +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_45_DEG_DDR3L 1U +#endif +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_45_DEG_DDR4 +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_45_DEG_DDR4 1U +#endif +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_45_DEG_LPDDR3 +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_45_DEG_LPDDR3 0U +#endif +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_45_DEG_LPDDR4 +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_45_DEG_LPDDR4 1U +#endif + +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_90_DEG_DDR3 +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_90_DEG_DDR3 2U +#endif +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_90_DEG_DDR3L +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_90_DEG_DDR3L 2U +#endif +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_90_DEG_DDR4 +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_90_DEG_DDR4 2U #endif -#if !defined (LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_ONE) -#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_ONE 1U +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_90_DEG_LPDDR3 +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_90_DEG_LPDDR3 1U #endif -#if !defined (LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_TWO) -#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_TWO 2U +#ifndef LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_90_DEG_LPDDR4 +#define LIBERO_SETTING_ADD_CMD_CLK_MOVE_ORDER_90_DEG_LPDDR4 2U #endif #endif @@ -858,6 +977,10 @@ typedef enum DDR_MEMORY_ACCESS_ /* RESERVED [15:16] RW value= 0x0 */ /* LOCKED [31:1] RW value= 0x0 */ +#ifndef TWO_MBYTES +#define TWO_MBYTES 0x200000 +#endif + /***************************************************************************//** */ @@ -959,6 +1082,7 @@ typedef enum DDR_TRAINING_SM_ DDR_FULL_MTC_CHECK, DDR_FULL_32BIT_NC_CHECK, DDR_FULL_32BIT_CACHE_CHECK, + DDR_LOAD_PATTERN_TO_CACHE_SETUP, DDR_LOAD_PATTERN_TO_CACHE, DDR_VERIFY_PATTERN_IN_CACHE, DDR_FULL_32BIT_WRC_CHECK, @@ -1217,6 +1341,9 @@ setup_ddr_segments SEG_SETUP option ); +char * fill_cache_new_seg_address(void *dest, void *dest_end); +void clear_bootup_cache_ways(void); + #ifdef __cplusplus } diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/common/nwc/mss_ddr_debug.c b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/common/nwc/mss_ddr_debug.c index 5c8589b..afc1748 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/common/nwc/mss_ddr_debug.c +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/common/nwc/mss_ddr_debug.c @@ -668,15 +668,14 @@ uint32_t tip_register_status (mss_uart_instance_t *g_mss_uart_debug_pt) /** * Load a pattern to DDR */ -void load_ddr_pattern(uint64_t base, uint64_t size, uint32_t pattern_type, \ - volatile uint8_t pattern_offset) +void load_ddr_pattern(volatile PATTERN_TEST_PARAMS *pattern_test) { int alive = 0; uint32_t *pattern; - volatile uint32_t pattern_size; - uint8_t *p_ddr = (uint8_t *)base; + uint32_t pattern_size; + uint8_t *p_ddr = (uint8_t *)pattern_test->base; - if (pattern_type == DDR_TEST_FILL) + if (pattern_test->pattern_type == DDR_TEST_FILL) { pattern = (uint32_t *)ddr_test_pattern; pattern_size = sizeof(ddr_test_pattern); @@ -687,14 +686,19 @@ void load_ddr_pattern(uint64_t base, uint64_t size, uint32_t pattern_type, \ pattern_size = sizeof(ddr_init_pattern); } - uint32_t pattern_length = (uint32_t)(pattern_size - pattern_offset) ; + uint32_t pattern_length = (uint32_t)(pattern_size - pattern_test->pattern_offset) ; #ifdef DEBUG_DDR_INIT - uprint(g_debug_uart, (const char*)(const uint8_t*)"\r\nLoading test pattern\r\n"); - uprint32(g_debug_uart, (const char*)(const uint8_t*)"\r\npattern_length = \r\n",pattern_length); + uprint(g_debug_uart, (const char*)(const uint8_t*)\ + "\r\nLoading test pattern\r\n"); + uprint64(g_debug_uart, (const char*)(const uint8_t*)\ + "\r\npattern size = ",pattern_test->size); + uprint32(g_debug_uart, (const char*)(const uint8_t*)\ + "\r\npattern offset = ",pattern_test->pattern_offset); #endif - while(((uint64_t)p_ddr + pattern_length) <= (base + size)) + while(((uint64_t)p_ddr + pattern_length) <\ + (pattern_test->base + pattern_test->size)) { switch ( ((uint64_t)p_ddr)%8U ) @@ -702,22 +706,26 @@ void load_ddr_pattern(uint64_t base, uint64_t size, uint32_t pattern_type, \ case 0: case 4: pdma_transfer_complete(PDMA_CHANNEL0_BASE_ADDRESS); - pdma_transfer((uint64_t)p_ddr, (uint64_t)pattern, pattern_length, PDMA_CHANNEL0_BASE_ADDRESS); + pdma_transfer((uint64_t)p_ddr, (uint64_t)pattern,\ + pattern_length, PDMA_CHANNEL0_BASE_ADDRESS); break; case 1: case 5: pdma_transfer_complete(PDMA_CHANNEL1_BASE_ADDRESS); - pdma_transfer((uint64_t)p_ddr, (uint64_t)pattern, pattern_length, PDMA_CHANNEL1_BASE_ADDRESS); + pdma_transfer((uint64_t)p_ddr, (uint64_t)pattern,\ + pattern_length, PDMA_CHANNEL1_BASE_ADDRESS); break; case 2: case 6: pdma_transfer_complete(PDMA_CHANNEL2_BASE_ADDRESS); - pdma_transfer((uint64_t)p_ddr, (uint64_t)pattern, pattern_length, PDMA_CHANNEL2_BASE_ADDRESS); + pdma_transfer((uint64_t)p_ddr, (uint64_t)pattern,\ + pattern_length, PDMA_CHANNEL2_BASE_ADDRESS); break; case 3: case 7: pdma_transfer_complete(PDMA_CHANNEL3_BASE_ADDRESS); - pdma_transfer((uint64_t)p_ddr, (uint64_t)pattern, pattern_length, PDMA_CHANNEL3_BASE_ADDRESS); + pdma_transfer((uint64_t)p_ddr, (uint64_t)pattern,\ + pattern_length, PDMA_CHANNEL3_BASE_ADDRESS); break; } @@ -776,7 +784,7 @@ static void load_test_buffers(uint32_t * p_cached_ddr, uint32_t * p_not_cached_d * @param size * @return returns 1 if compare fails */ -uint32_t test_ddr(uint32_t no_of_iterations, uint32_t size) +uint32_t test_ddr(uint32_t no_of_iterations, volatile PATTERN_TEST_PARAMS *pattern_test) { uint32_t pattern_length = sizeof(ddr_test_pattern) - (3 * sizeof(uint32_t)); uint32_t * p_ddr_cached = (uint32_t *)BASE_ADDRESS_CACHED_32_DDR; @@ -821,7 +829,7 @@ uint32_t test_ddr(uint32_t no_of_iterations, uint32_t size) return error; } - if (((uint64_t)p_ddr_cached + ( 2 * pattern_length)) < (LIBERO_SETTING_DDR_32_CACHE + size)) + if (((uint64_t)p_ddr_cached + ( 2 * pattern_length)) < (LIBERO_SETTING_DDR_32_CACHE + pattern_test->size)) { p_ddr_cached += (pattern_length / sizeof(uint32_t)); p_ddr_noncached += (pattern_length / sizeof(uint32_t)); diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/common/nwc/mss_ddr_debug.h b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/common/nwc/mss_ddr_debug.h index 3bb0af8..fb1a621 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/common/nwc/mss_ddr_debug.h +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/common/nwc/mss_ddr_debug.h @@ -235,10 +235,7 @@ uint32_t no_of_regs void load_ddr_pattern ( -uint64_t base, -uint64_t size, -uint32_t pattern_type, -volatile uint8_t pattern_offset +volatile PATTERN_TEST_PARAMS *pattern_test ); /***************************************************************************//** @@ -248,7 +245,7 @@ uint32_t test_ddr ( uint32_t no_of_iterations, -uint32_t size +volatile PATTERN_TEST_PARAMS *pattern_test ); /***************************************************************************//** diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/common/nwc/mss_ddr_defs.h b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/common/nwc/mss_ddr_defs.h index 1263bc7..92857b9 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/common/nwc/mss_ddr_defs.h +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/common/nwc/mss_ddr_defs.h @@ -17,6 +17,18 @@ #ifndef SRC_PLATFORM_MPFS_HAL_NWC_MSS_DDR_DEFS_H_ #define SRC_PLATFORM_MPFS_HAL_NWC_MSS_DDR_DEFS_H_ +typedef struct PATTERN_TEST_PARAMS_ +{ + uint64_t base; + uint64_t size; + uint32_t pattern_type; + uint8_t pattern_offset; + uint8_t offset_cnt; + uint8_t num_offsets_to_try; + uint8_t padding; +} PATTERN_TEST_PARAMS; + + #define PATTERN_INCREMENTAL (0x01U << 0U) #define PATTERN_WALKING_ONE (0x01U << 1U) #define PATTERN_WALKING_ZERO (0x01U << 2U) diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/common/nwc/mss_nwc_init.c b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/common/nwc/mss_nwc_init.c index 27bde36..3ef5565 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/common/nwc/mss_nwc_init.c +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/common/nwc/mss_nwc_init.c @@ -18,7 +18,6 @@ #include #include "mpfs_hal/mss_hal.h" #include "mss_nwc_init.h" -#include "simulation.h" #ifdef DEBUG_DDR_INIT #include "drivers/mss/mss_mmuart/mss_uart.h" @@ -300,13 +299,11 @@ uint8_t mss_nwc_init(void) * The SGMII set-upset configures the external clock reference so this must * be called before configuring the MSS PLL */ - SIM_FEEDBACK0(2); sgmii_setup(); /* * Setup the MSS PLL */ - SIM_FEEDBACK0(3); mss_pll_config(); return error; diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/common/nwc/mss_sgmii.c b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/common/nwc/mss_sgmii.c index fb3f7b7..38c7e36 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/common/nwc/mss_sgmii.c +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/common/nwc/mss_sgmii.c @@ -17,7 +17,6 @@ #include #include #include "mpfs_hal/mss_hal.h" -#include "simulation.h" #ifdef MPFS_HAL_HW_CONFIG diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/common/nwc/simulation.h b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/common/nwc/simulation.h deleted file mode 100644 index a6bdf76..0000000 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/common/nwc/simulation.h +++ /dev/null @@ -1,74 +0,0 @@ -/******************************************************************************* - * Copyright 2019-2022 Microchip FPGA Embedded Systems Solutions. - * - * SPDX-License-Identifier: MIT - * - * MPFS HAL Embedded Software - * - */ - -/******************************************************************************* - * @file simulation.h - * @author Microchip-FPGA Embedded Systems Solutions - * @brief SGMII defines - */ - -#ifndef MSS_DDR_SGMII_SIMULATION_H_ -#define MSS_DDR_SGMII_SIMULATION_H_ - -/* todo: remove this file before customer distribution */ - -/***************************************************************************//** - Simulation Test commands - */ -#define DDR_SIM 0x01 -#define FLASH_FREEZE_SIM 0x02 -#define DESIGN_INF_TEST_SIM 0x04 -#define MMSIO_SIM 0x08 -#define SGMII_SIM 0x10 -#define BUS_ERROR_UNIT 0x20 -#define D_CACHE_TEST 0x40 -#define EXT_CLK_CHOICE 0x80 - -/***************************************************************************//** - SGMii Test commands -* List from Eugene -* 1. Full SGMII test- both channels enabled, external loopback and rx_lock for -* both channels. (This test is written) -* (Will do a version of this for refclk = 125 mhz also- already supported -* in sw) -* 2. SGMII test, similar to 1 , except chan1 is off. -* 3. TEST with both CHAn0 and CHAn 1 off. This is the default state for sgmii -* anyway. The SGMII PLL will not be turned on either. This is our SGMII OFF -* MODE test. -* 4. RECALIB mode on (RECAL_CNTL-reg_recal_start_en =1). Both chans off. As I -* understand this is for DDR IO recalibration. I am not sure what I check -* for here. SO I will ask Jeff. -* 5. PVT recalibration..as per Srikanths presentation...SCB reg_calib_start =1 -* and APB calib_start =1 (see my earlier email.) This allows us check status -* of calib_start and calib_lock and calib_intrpt to be checked as per -* Srikanths presentation. -* -*/ -#define SGMII_ALL_ON 0x00 -#define SGMII_CH1_OFF 0x01 -#define SGMII_ALL_OFF 0x02 -#define SGMII_RECALIB 0x03 -#define SGMII_PVT_MONITOR 0x04 -#define SGMII_CH0_OFF_CH1_ON 0x05 -#define SGMII_MAC0_LOOPBACK_TEST 0x06 -#define SGMII_TRIM_IO 0x07 -#define SGMII_RECALIB_IO 0x08 -#define SGMII_MAC1_LOOPBACK_TEST 0x09 -#define SGMII_ALL_OFF_INC_CLK 0x0A - - -#ifdef SIMULATION_TEST_FEEDBACK -#define SIM_FEEDBACK0(x) (SYSREG->TEMP0 = (uint32_t)x) -#define SIM_FEEDBACK1(x) (SYSREG->TEMP1 = (uint32_t)x) -#else -#define SIM_FEEDBACK0(x) -#define SIM_FEEDBACK1(x) -#endif - -#endif /* MSS_DDR_SGMII_SIMULATION_H_ */ diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/mpfs_hal_version.h b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/mpfs_hal_version.h index 7220857..d06ba97 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/mpfs_hal_version.h +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/mpfs_hal_version.h @@ -40,8 +40,8 @@ extern "C" { #endif #define MPFS_HAL_VERSION_MAJOR 2 -#define MPFS_HAL_VERSION_MINOR 1 -#define MPFS_HAL_VERSION_PATCH 103 +#define MPFS_HAL_VERSION_MINOR 2 +#define MPFS_HAL_VERSION_PATCH 105 #ifdef __cplusplus } diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/startup_gcc/mss_entry.S b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/startup_gcc/mss_entry.S index b1c94ab..12c3eb3 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/startup_gcc/mss_entry.S +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/startup_gcc/mss_entry.S @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright 2019-2022 Microchip FPGA Embedded Systems Solutions. + * Copyright 2019-2023 Microchip FPGA Embedded Systems Solutions. * * SPDX-License-Identifier: MIT * @@ -20,6 +20,8 @@ #include "system_startup_defs.h" #include "mpfs_hal_config/mss_sw_config.h" +#define NUM_CACHEWAYS_AT_RESET 1 + .option norvc .section .text.init,"ax", %progbits .globl reset_vector @@ -178,14 +180,6 @@ _start: csrr a0, mhartid li a1, MPFS_HAL_FIRST_HART bne a0, a1, .LOtherHartstoWFI - # clear the common heap - la a4, __heap_start - la a5, __heap_end -.init_heap: - #csrw mepc, zero - STORE x0, 0(a4) - add a4, a4, __SIZEOF_POINTER__ - blt a4, a5, .init_heap # # clear DTIM - this is required to stop memory errors on initial access by # cache @@ -197,6 +191,20 @@ _start: call .clear_dtim call .clear_l2lim .skip_mem_clear: + li a0, NUM_CACHEWAYS_AT_RESET # flush default way in case it has already + # been used by system controller loader + # (bootmode2 or 3) + call .flush_early_caching + call config_l2_cache + call end_l2_scratchpad_address # end address returned in a0 + call .clear_scratchpad + # place pattern in the common heap + la a4, __heap_start + la a5, __heap_end +.init_heap: + STORE x0, 0(a4) + add a4, a4, __SIZEOF_POINTER__ + blt a4, a5, .init_heap /* * Clear bus error unit accrued register on start-up * This is cleared by the first hart only @@ -682,8 +690,19 @@ copy_switch_code: #define END__OF_LIM 0x08200000 #define START__OF_DTM 0x01000000 #define END__OF_DTM 0x01002000 +#define START_OF_SCRATCH 0x0A000000 - +.clear_scratchpad: + // Clear the scratchpad + // + // a0 = end of scratchpad addr passed from caller + // + // Note: This must be called post calling config_l2_cache() + // + la a4, START_OF_SCRATCH # start of l2 scratchpad + mv a5, a0 # end of l2 scratchpad + // common loop used to clear memory + j 1f .clear_l2lim: // Clear the LIM // @@ -714,6 +733,54 @@ copy_switch_code: .done_clear: ret +/******************************************************************************* + * + */ + .equ L2_ZERO_DEVICE_ADDR, 0x0A000000 + .equ L2_CCACHE_ADDR, 0x02010000 + .equ FLUSH64_OFFSET, 0x200 + + // + // We want to flush anything that may be inadvertently cached + // by the actions of G5C at startup... + // + // The cache block is 64-bytes wide, and there are 4 banks * 512 sets * 16 + // ways. + // From power on, only a single way is enabled as cache (the remaining + // 15 are LIM), but this function is parameterisable (number of ways is + // passed via a0)... + // + // First, load the cache with "known" addresses by walking up L2 scratch + // with a 64-byte stride. We need to read (4 banks * 512 sets) to fill + // a single way. + // +.flush_early_caching: + // a0 = num_ways + slli a0, a0, 17 // a0' = a0 * (4 * 512 * 64) + li a5, L2_ZERO_DEVICE_ADDR + add a0, a0, a5 // a0'' = a0' + (4 * 512 * 64 * a0) + // = 0x0A000000 + (4 * 512 * 64 * num_ways) + beq a0, a5, .early_exit + +.preload_cache_with_known_addrs: + ld a3, 0(a5) + addi a5, a5, 64 + bne a5, a0, .preload_cache_with_known_addrs + + // + // Now that the cache is filled with known addresses, we can simply flush each + // known address to end up with an empty cache... + // + li a5, L2_ZERO_DEVICE_ADDR + li a3, L2_CCACHE_ADDR +.flush_known_addrs_from_cache: + sd a5, FLUSH64_OFFSET(a3) // write address to 0x02010200 (FLUSH64) + addi a5, a5, 64 + bne a5, a0, .flush_known_addrs_from_cache + +.early_exit: + ret + /* * record_ecc_error_counts on reset * These are non-zero in the coreplex. diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/startup_gcc/mss_utils.S b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/startup_gcc/mss_utils.S index 846b79f..8483a83 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/startup_gcc/mss_utils.S +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/startup_gcc/mss_utils.S @@ -185,4 +185,79 @@ config_64_copy: 2: ret + /*********************************************************************************** + * + * fill_cache_new_seg_address and flush + */ + .equ L2_CCACHE_ADDR, 0x02010000 + .equ FLUSH64_OFFSET, 0x200 + // + // We want to flush anything that may be cached + // with previous seg settings + // + // The cache block is 64-bytes wide, and there are 4 banks * 512 sets * 16 + // ways. + // We just write to the DDR cache backed address passed by the caller + // Once start and end address range covers the size of the cache, the + // previous contents of cache will be overwritten. + // + // fill_cache_new_seg_address + // a0 = dest + // a1 = dest end address + .globl fill_cache_new_seg_address + .type fill_cache_new_seg_address @function +fill_cache_new_seg_address: + mv t1,a0 + mv t2,a1 + mv t3,a0 + +.preload_cache_with_known_addrs: + sd x0, 0(t1) + ld t4, 0(t1) + addi t1, t1, 64 + blt t1, t2, .preload_cache_with_known_addrs + + // + // Now that the cache is filled with known addresses, we can simply flush + // each known address to end up with an empty cache. + // There is no requirement to clear the cache, but we will as a belt and + // braces excercise before we continue with the boot process + // + li t1, L2_CCACHE_ADDR +.flush_known_addrs_from_cache: + sd t3, FLUSH64_OFFSET(t1) // write address to 0x02010200 (FLUSH64) + addi t3, t3, 64 + blt t3, t2, .flush_known_addrs_from_cache + +.early_exit: + ret + +/*********************************************************************************** + * + * clear_64_mem - clear memory using 64 bit writes, addresses must be on 64 bit + * boundary + * + * Note: This function is useful for initializing LIM as 64 bit writes are + * required to initialize ECC. The MPFS HAL does initialize all LIM on boot from + * eNVM, but when debugging bare metal projects from LIM, only the memory associated + * with the footprint of the program is initialised. So when debugging, if LIM memory + * outside the program itself is accessed, it must be initialized if it has not been + * initialized previously by a bootloader. + * + * clear_64_mem helper function: + * a0 = start address + * a1 = end address + * + */ + .globl clear_64_mem + .type clear_64_mem @function + clear_64_mem: + mv t1, a0 # start address to clear + mv t2, a1 # end address to clear +1: + sd x0, 0(t1) + add t1, t1, __SIZEOF_POINTER__ + blt t1, t2, 1b +.done_clear: + ret diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/startup_gcc/system_startup.c b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/startup_gcc/system_startup.c index d3839d9..b89dc8c 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/startup_gcc/system_startup.c +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/startup_gcc/system_startup.c @@ -1,5 +1,5 @@ /****************************************************************************************** - * Copyright 2019-2022 Microchip FPGA Embedded Systems Solutions. + * Copyright 2019-2023 Microchip FPGA Embedded Systems Solutions. * * SPDX-License-Identifier: MIT * @@ -65,10 +65,6 @@ __attribute__((weak)) int main_first_hart(HLS_DATA* hls) * src/boards/my_hart_id = MPFS_HAL_FIRST_HART; diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/startup_gcc/system_startup.h b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/startup_gcc/system_startup.h index ff2b620..0fcc34e 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/startup_gcc/system_startup.h +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/mpfs_hal/startup_gcc/system_startup.h @@ -133,6 +133,7 @@ char * config_copy(void *dest, const void * src, size_t len); char * config_16_copy(void *dest, const void * src, size_t len); char * config_32_copy(void *dest, const void * src, size_t len); char * config_64_copy(void *dest, const void * src, size_t len); +char * clear_64_mem(uint64_t *start_address, uint64_t *end_address); void copy_section ( diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/platform_config_reference/LICENSE.md b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/platform_config_reference/LICENSE.md new file mode 100644 index 0000000..8e95095 --- /dev/null +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/platform_config_reference/LICENSE.md @@ -0,0 +1,26 @@ +# The MPFS MSS Platform Config Reference Software License + +The MPFS MSS Platform Config Reference software is released under the following +software license: + + Copyright 2019-2023 Microchip FPGA Embedded Systems Solutions. + + SPDX-License-Identifier: MIT + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/platform_config_reference/drivers_config/mss/mss_usb/mss_usb_sw_config.h b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/platform_config_reference/drivers_config/mss/mss_usb/mss_usb_sw_config.h new file mode 100644 index 0000000..b90a5dc --- /dev/null +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/platform_config_reference/drivers_config/mss/mss_usb/mss_usb_sw_config.h @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright 2019-2023 Microchip FPGA Embedded Systems Solutions. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * PolarFire SoC MSS USB Driver Stack + * + * MSS USB Driver stack configuration parameters. + * User must choose the constant definitions in this file to select the mode of + * operation. + * The constants defined in this file are used by MSS USB driver stack to + * function as per configuration. + * + * mss_usb_sw_config.h + */ + +#ifndef MSS_USB_SW_CONFIG_H_ +#define MSS_USB_SW_CONFIG_H_ + +/*-------------------------------------------------------------------------*//** + User should choose the Mode in which PolarFire SoC MSS USB should operate +*/ +/* #define MSS_USB_OTG_DUAL_ROLE_MODE */ +/* #define MSS_USB_OTG_PERIPHERAL_MODE*/ + +/* Configures the MSS USB Driver Stack to operate in USB Host mode. */ +/* #define MSS_USB_OTG_HOST_MODE */ + +/* Configures the MSS USB Driver Stack to operate in USB Device mode. */ +/* #define MSS_USB_PERIPHERAL_MODE */ + +/* Used for internal testing of the driver. Not for Application use. */ +/* #define MSS_USB_DEVICE_TEST_MODE */ + + +#endif /* MSS_USB_SW_CONFIG_H_ */ diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/platform_config_reference/linker/mpfs-ddr-loaded-by-boot-loader.ld b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/platform_config_reference/linker/mpfs-ddr-loaded-by-boot-loader.ld index 88af43e..2e4d2c4 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/platform_config_reference/linker/mpfs-ddr-loaded-by-boot-loader.ld +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/platform_config_reference/linker/mpfs-ddr-loaded-by-boot-loader.ld @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright 2019-2022 Microchip FPGA Embedded Systems Solutions. + * Copyright 2019-2023 Microchip FPGA Embedded Systems Solutions. * * SPDX-License-Identifier: MIT * diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/platform_config_reference/linker/mpfs-envm-lma-scratchpad-vma.ld b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/platform_config_reference/linker/mpfs-envm-lma-scratchpad-vma.ld index 2a5f0a3..9d1f8b0 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/platform_config_reference/linker/mpfs-envm-lma-scratchpad-vma.ld +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/platform_config_reference/linker/mpfs-envm-lma-scratchpad-vma.ld @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright 2019-2022 Microchip FPGA Embedded Systems Solutions. + * Copyright 2019-2023 Microchip FPGA Embedded Systems Solutions. * * SPDX-License-Identifier: MIT * @@ -369,7 +369,7 @@ SECTIONS * This can not be done when running from envm * This will need to be copied to ram, before any of this code is run. */ - .ram_code : + .ram_code : ALIGN(0x10) { . = ALIGN (4); __sc_load = LOADADDR (.ram_code); diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/platform_config_reference/linker/mpfs-envm.ld b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/platform_config_reference/linker/mpfs-envm.ld index c4a16ad..c4aae15 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/platform_config_reference/linker/mpfs-envm.ld +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/platform_config_reference/linker/mpfs-envm.ld @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright 2019-2022 Microchip FPGA Embedded Systems Solutions. + * Copyright 2019-2023 Microchip FPGA Embedded Systems Solutions. * * SPDX-License-Identifier: MIT * @@ -132,6 +132,17 @@ SECTIONS PROVIDE(__u54_4_itim_end = ORIGIN(u54_4_itim) + LENGTH(u54_4_itim)); . = __envm_start; + + .text_init : ALIGN(0x10) + { + *(.text.init) + *system_startup.o (.text .text* .rodata .rodata* .srodata*) + *mtrap.o (.text .text* .rodata .rodata* .srodata*) + *mss_h2f.o (.text .text* .rodata .rodata* .srodata*) + *mss_l2_cache.o (.text .text* .rodata .rodata* .srodata*) + . = ALIGN(0x10); + } >envm + .text : ALIGN(0x10) { __text_load = LOADADDR(.text); @@ -196,7 +207,7 @@ SECTIONS * This can not be done when running from envm * This will need to be copied to ram, before any of this code is run. */ - .ram_code : + .ram_code : ALIGN(0x10) { . = ALIGN (4); __sc_load = LOADADDR (.ram_code); @@ -216,7 +227,7 @@ SECTIONS .ddr_code : { . = ALIGN (4); - __ddr_load = LOADADDR (.ram_code); + __ddr_load = LOADADDR (.ddr_code); __ddr_start = .; *(.ddr_codetext) /* .ram_codetext sections (code) */ *(.ddr_codetext*) /* .ram_codetext* sections (code) */ diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/platform_config_reference/linker/mpfs-lim-lma-scratchpad-vma.ld b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/platform_config_reference/linker/mpfs-lim-lma-scratchpad-vma.ld index 7e3980f..34af389 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/platform_config_reference/linker/mpfs-lim-lma-scratchpad-vma.ld +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/platform_config_reference/linker/mpfs-lim-lma-scratchpad-vma.ld @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright 2019-2022 Microchip FPGA Embedded Systems Solutions. + * Copyright 2019-2023 Microchip FPGA Embedded Systems Solutions. * * SPDX-License-Identifier: MIT * @@ -360,7 +360,7 @@ SECTIONS * This can not be done when running from envm * This will need to be copied to ram, before any of this code is run. */ - .ram_code : + .ram_code : ALIGN(0x10) { . = ALIGN (4); __sc_load = LOADADDR (.ram_code); diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/platform_config_reference/linker/mpfs-lim.ld b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/platform_config_reference/linker/mpfs-lim.ld index 8b40be2..d1a4c71 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/platform_config_reference/linker/mpfs-lim.ld +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/platform_config_reference/linker/mpfs-lim.ld @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright 2019-2022 Microchip FPGA Embedded Systems Solutions. + * Copyright 2019-2023 Microchip FPGA Embedded Systems Solutions. * * SPDX-License-Identifier: MIT * @@ -123,6 +123,17 @@ SECTIONS PROVIDE(__u54_4_itim_end = ORIGIN(u54_4_itim) + LENGTH(u54_4_itim)); /* text: text code section */ . = __l2lim_start; + + .text_init : ALIGN(0x10) + { + *(.text.init) + *system_startup.o (.text .text* .rodata .rodata* .srodata*) + *mtrap.o (.text .text* .rodata .rodata* .srodata*) + *mss_h2f.o (.text .text* .rodata .rodata* .srodata*) + *mss_l2_cache.o (.text .text* .rodata .rodata* .srodata*) + . = ALIGN(0x10); + } > l2lim + .text : ALIGN(0x10) { __text_load = LOADADDR(.text); @@ -187,7 +198,7 @@ SECTIONS * This can not be done when running from eNVM * This will need to be copied to ram, before any of this code is run. */ - .ram_code : + .ram_code : ALIGN(0x10) { . = ALIGN (4); __sc_load = LOADADDR (.ram_code); diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/platform_config_reference/mpfs_hal_config/mss_sw_config.h b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/platform_config_reference/mpfs_hal_config/mss_sw_config.h index 29a9407..a2360a3 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/platform_config_reference/mpfs_hal_config/mss_sw_config.h +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/platform_config_reference/mpfs_hal_config/mss_sw_config.h @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright 2019-2022 Microchip FPGA Embedded Systems Solutions. + * Copyright 2019-2023 Microchip FPGA Embedded Systems Solutions. * * SPDX-License-Identifier: MIT * diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/readme.md b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/readme.md new file mode 100644 index 0000000..93db00e --- /dev/null +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/readme.md @@ -0,0 +1,56 @@ +# PolarFire® SoC platform source code + +## Repo organization + +``` + + | + |-- drivers + | |- fpga_ip + | | | . + | | | . + | |- mss + | | |- mss-ethernet-mac + | | |- mss-can + | | |- mss-gpio + | | | . + | | | . + | | | . + | | |- mss-mmc + | | |- mss-watchdog + | | |- mss-watchdog.c + | | |- mss-watchdog.h + | | + | |- off_chip + | | | . + | | | . + | | + |-- hal + | | + |-- mpfs_hal + | | + |-- platform_config_reference + | | |- linker + | | | |- mpfs-ddr-loaded-by-boot-loader.ld + | | | |- mpfs-envm-lma-scratchpad-vma.ld + | | | |- mpfs-envm.ld + | | | |- mpfs-lim-lma-scratchpad-vma.ld + | | | |- mpfs-lim.ld + | | | + | | | + | | |- mpfs_hal_config + | | |- mss_sw_config.h + | | + |-- soc_config_generator + | | + | |- mpfs_configuration_generator.py + +``` + +This repository will always contain the latest and greatest of the platform contents. Some of the example projects under [polarfire-soc-bare-metal-examples](https://mi-v-ecosystem.github.io/redirects/repo-polarfire-soc-bare-metal-examples) +may not contain all the contents or latest versions of of the contents from this repository. In such cases, please download this repository and replace the src/platform repository in the project with it. + +When you update the _platform_ repository in your project, you must make sure that the reference design (and the xml configuration) is compatible with it. + +For detailed description about the contents of the platform sub-directories and the overall bare metal software project folder structure, please refer to the +[Bare Metal Software Projects Structure](https://mi-v-ecosystem.github.io/redirects/bare-metal-project-structure_bare-metal-software-project-structure) diff --git a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/soc_config_generator/mpfs_configuration_generator.py b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/soc_config_generator/mpfs_configuration_generator.py index 3394bdb..46c6267 100644 --- a/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/soc_config_generator/mpfs_configuration_generator.py +++ b/driver-examples/mss/mss-rtc/mpfs-rtc-time/src/platform/soc_config_generator/mpfs_configuration_generator.py @@ -15,11 +15,14 @@ # -------------------------------------------------------------------------------------------- # mpfs_configuration_generator.py version # +# 0.6.4 Added the following generated files: +# hw_mssio_mux_alternate.h +# hw_nvm_map.h # 0.6.3 target folder name change from "fpga_config" -> fpga_design config, filename -# hw_platform.h changed to fpga_design_config.h , -# bug fix related to multiple xml file selection and added libero design information -# constants in fpga_design_config.h/ removed date,version and design information from all the files -# except fpga_design_config.h +# hw_platform.h changed to fpga_design_config.h , +# bug fix related to multiple xml file selection and added libero design information +# constants in fpga_design_config.h/ removed date,version and design information from all the files +# except fpga_design_config.h # # 0.6.2 added support for multiple xml file found in input folder # /empty xml file check/ xml filename arg in current folder/ @@ -49,7 +52,7 @@ def get_script_ver(): get_xml_ver() :return: script version ''' - return "0.6.3" + return "0.6.4" @@ -71,6 +74,8 @@ def get_script_ver(): # Please note: The tag in the first column ( mss_xxx) is the same as the # directory name (/fpga_design_config/mss_xxx) # the fourth item lets program know how to format info in header file +# fm_reg - appears as reg with fields +# fm_define - appears as define with value, no fields # the six item lets program know how to format value, decimal or hex # ----------------------------------------------------------------------------- xml_tags = ('mss_memory_map,map,mem_elements,fm_define,none,hex', @@ -91,7 +96,9 @@ def get_script_ver(): 'mss_memory_map,mpu_mmc,registers,fm_struct,MMC_,hex64', 'mss_memory_map,mpu_scb,registers,fm_struct,SCB_,hex64', 'mss_memory_map,mpu_trace,registers,fm_struct,TRACE_,hex64', + 'mss_memory_map,nvm_map,registers,fm_define,none,decimal', 'mss_io,io_mux,registers,fm_reg,none,hex', + 'mss_io,io_mux_alt,registers,fm_reg,none,hex', 'mss_io,hsio,registers,fm_reg,none,hex', 'mss_sgmii,tip,registers,fm_reg,none,hex', 'mss_ddr,options,registers,fm_reg,none,hex', @@ -112,7 +119,7 @@ def get_script_ver(): # ----------------------------------------------------------------------------- # Header files to generate -# ----------------------------------------------------------------------------- +#------------------------------------------------------------------------------ header_files = ('fpga_design_config,memory_map,hw_memory.h', 'fpga_design_config,memory_map,hw_apb_split.h', 'fpga_design_config,memory_map,hw_cache.h', @@ -131,7 +138,9 @@ def get_script_ver(): 'fpga_design_config,memory_map,hw_mpu_mmc.h', 'fpga_design_config,memory_map,hw_mpu_scb.h', 'fpga_design_config,memory_map,hw_mpu_trace.h', + 'fpga_design_config,memory_map,hw_nvm_map.h', 'fpga_design_config,io,hw_mssio_mux.h', + 'fpga_design_config,io,hw_mssio_mux_alternate.h', 'fpga_design_config,io,hw_hsio_mux.h', 'fpga_design_config,sgmii,hw_sgmii_tip.h', 'fpga_design_config,ddr,hw_ddr_options.h', @@ -417,14 +426,18 @@ def generate_header( file, real_root, root, file_name, tags): WriteCopyright(real_root, headerFile, file_name, creator) start_define(headerFile, file_name) start_cplus(headerFile, file_name) - for child in root: - if child.tag == "registers": - generate_register(headerFile, child, tags) - if child.tag == "mem_elements": - generate_mem_elements(headerFile, child, tags) - for child2 in child: - if child2.tag == "registers": - generate_register(headerFile, child2, tags) + if tags != None : + for child in root: + if child.tag == "registers": + generate_register(headerFile, child, tags) + if child.tag == "mem_elements": + generate_mem_elements(headerFile, child, tags) + for child2 in child: + if child2.tag == "registers": + generate_register(headerFile, child2, tags) + else: + headerFile.write('/* No content from MSS Configurator generated for this file. */\n') + headerFile.write('/* An older version of MSS Configurator has been used. */\n') end_cplus(headerFile, file_name) end_define(headerFile, file_name) @@ -527,6 +540,8 @@ def generate_header_files(output_header_files, input_xml_file, input_xml_tags): # if found_match == 1: generate_header(file_dir, root, child1, file_name, ref_tags) + else: + generate_header(file_dir, root, child1, file_name, None) index += 1 '''