SLAZ709A October   2017  – June 2025 MSP432E401Y , MSP432E411Y

 

  1.   1
  2. 1MSP432E4 SimpleLink™ Microcontrollers
    1. 1.1 Introduction
    2. 1.2 Device Nomenclature
    3. 1.3 Device Markings
    4. 1.4 Errata Overview
    5. 1.5 Errata Descriptions
      1.      ADC#13
      2.      ADC#14
      3.      EPI#01
      4.      GPIO#09
      5.      GPTM#09
      6.      GPTM#15
      7.      HIB#10
      8.      HIB#16
      9.      HIB#18
      10.      HIB#19
      11.      MEM#07
      12.      MEM#15
      13.      MEM#16
      14.      PWM#04
      15.      PWM#05
      16.      PWM#06
      17.      QEI#01
      18.      SSI#03
      19.      SSI#05
      20.      SSI#06
      21.      SSI#07
      22.      SSI#08
      23.      SYSCTL#03
      24.      SYSCTL#18
      25.      SYSCTL#24
      26.      USB#04
      27.      WDT#08
    6. 1.6 Appendix 1
    7. 1.7 Appendix 2
  3. 2Trademarks
  4. 3Revision History

Appendix 2

To address the erratum EPI#01 Data reads can be corrupted when the code address space in the EPI module is used , the following code should be added to the epi.h file.

#ifdef rvmdk
//*****************************************************************************
//
// Keil case.
//
//*****************************************************************************
inline void
EPIWorkaroundWordWrite(uint32_t *pui32Addr, uint32_t ui32Value)
{
  uint32_t ui32Scratch;
    __asm
    {
        //
        // Add a NOP to ensure we don’t have a flash read immediately before
        // the EPI read.
        //
        NOP
        //
        // Perform the write we're actually interested in.
        //
        STR ui32Value, [pui32Addr]
        //
        // Read from SRAM to ensure that we don't have an EPI write followed by
        // a flash read.
        //
        LDR ui32Scratch, [__current_sp()]
    }
}
inline uint32_t
EPIWorkaroundWordRead(uint32_t *pui32Addr)
{
  uint32_t ui32Value, ui32Scratch;
    __asm
    {
        //
        // Add a NOP to ensure we don’t have a flash read immediately before
        // the EPI read.
        //
        NOP
        //
        // Perform the read we're actually interested in.
        //
        LDR ui32Value, [pui32Addr]
        //
        // Read from SRAM to ensure that we don't have an EPI read followed by
        // a flash read.
        //
        LDR ui32Scratch, [__current_sp()]
    }
    return(ui32Value);
}
inline void
EPIWorkaroundHWordWrite(uint16_t *pui16Addr, uint16_t ui16Value)
{
    uint32_t ui32Scratch;
    __asm
    {
        //
        // Add a NOP to ensure we don’t have a flash read immediately before
        // the EPI read.
        //
        NOP
        //
        // Perform the write we're actually interested in.
        //
        STRH ui16Value, [pui16Addr]
        //
        // Read from SRAM to ensure that we don't have an EPI write followed by
        // a flash read.
        //
        LDR ui32Scratch, [__current_sp()]
    }
}
inline uint16_t
EPIWorkaroundHWordRead(uint16_t *pui16Addr)
{
    uint32_t ui32Scratch;
    uint16_t ui16Value;
    __asm
    {
        //
        // Add a NOP to ensure we don’t have a flash read immediately before
        // the EPI read.
        //
        NOP
        //
        // Perform the read we're actually interested in.
        //
        LDRH ui16Value, [pui16Addr]
        //
        // Read from SRAM to ensure that we don't have an EPI read followed by
        // a flash read.
        //
        LDR ui32Scratch, [__current_sp()]
    }
    return(ui16Value);
}
inline void
EPIWorkaroundByteWrite(uint8_t *pui8Addr, uint8_t ui8Value)
{
  uint32_t ui32Scratch;
    __asm
    {
        //
        // Add a NOP to ensure we don’t have a flash read immediately before
        // the EPI read.
        //
        NOP
        //
        // Perform the write we're actually interested in.
        //
        STRB ui8Value, [pui8Addr]
        //
        // Read from SRAM to ensure that we don't have an EPI write followed by
        // a flash read.
        //
        LDR ui32Scratch, [__current_sp()]
    }
}
inline uint8_t
EPIWorkaroundByteRead(uint8_t *pui8Addr)
{
    uint32_t ui32Scratch;
    uint8_t ui8Value;
    __asm
    {
        //
        // Add a NOP to ensure we don’t have a flash read immediately before
        // the EPI read.
        //
        NOP
        //
        // Perform the read we're actually interested in.
        //
        LDRB ui8Value, [pui8Addr]
        //
        // Read from SRAM to ensure that we don't have an EPI read followed by
        // a flash read.
        //
        LDR ui32Scratch, [__current_sp()]
    }
    return(ui8Value);
}
#else
#ifdef ccs
//*****************************************************************************
//
// Code Composer Studio versions of these functions can be found in separate
// source file epi_workaround_ccs.s.
//
//*****************************************************************************
extern void EPIWorkaroundWordWrite(uint32_t *pui32Addr, uint32_t ui32Value);
extern uint32_t EPIWorkaroundWordRead(uint32_t *pui32Addr);
extern void EPIWorkaroundHWordWrite(uint16_t *pui16Addr, uint16_t ui16Value);
extern uint16_t EPIWorkaroundHWordRead(uint16_t *pui16Addr);
extern void EPIWorkaroundByteWrite(uint8_t *pui8Addr, uint8_t ui8Value);
extern uint8_t EPIWorkaroundByteRead(uint8_t *pui8Addr);
#else
//*****************************************************************************
//
// GCC and IAR case.
//
//*****************************************************************************
inline void
EPIWorkaroundWordWrite(uint32_t *pui32Addr, uint32_t ui32Value)
{
    volatile register uint32_t ui32Scratch;
    __asm volatile (
        //
        // Add a NOP to ensure we don’t have a flash read immediately before
        // the EPI read.
        //
        "    NOP\n"
        "    STR %[value],[%[addr]]\n"
        "    LDR %[scratch],[sp]\n"
         :  [scratch] "=r" (ui32Scratch)
         :  [addr] "r" (pui32Addr), [value] "r" (ui32Value)
     );
    //
    // Keep the compiler from generating a warning.
    //
    ui32Scratch = ui32Scratch;
}
inline uint32_t
EPIWorkaroundWordRead(uint32_t *pui32Addr)
{
    volatile register uint32_t ui32Data, ui32Scratch;
    //
    // ui32Scratch is not used other than to add a padding read following the
    // "real" read.
    //
    __asm volatile(
        //
        // Add a NOP to ensure we don’t have a flash read immediately before
        // the EPI read.
        //
        "    NOP\n"
        "    LDR %[ret],[%[addr]]\n"
        "    LDR %[scratch],[sp]\n"
         : [ret] "=r" (ui32Data),
           [scratch] "=r" (ui32Scratch)
         : [addr] "r" (pui32Addr)
    );
    //
    // Keep the compiler from generating a warning.
    //
    ui32Scratch = ui32Scratch;
    return(ui32Data);
}
inline void
EPIWorkaroundHWordWrite(uint16_t *pui16Addr, uint16_t ui16Value)
{
    volatile register uint32_t ui32Scratch;
    __asm volatile (
        //
        // Add a NOP to ensure we don’t have a flash read immediately before
        // the EPI read.
        //
        "    NOP\n"
        "    STRH %[value],[%[addr]]\n"
        "    LDR %[scratch],[sp]\n"
         :  [scratch] "=r" (ui32Scratch)
         :  [addr] "r" (pui16Addr), [value] "r" (ui16Value)
     );
    //
    // Keep the compiler from generating a warning.
    //
    ui32Scratch = ui32Scratch;
}
inline uint16_t
EPIWorkaroundHWordRead(uint16_t *pui16Addr)
{
    register uint16_t ui16Data;
    register uint32_t ui32Scratch;
    //
    // ui32Scratch is not used other than to add a padding read following the
    // "real" read.
    //
    __asm volatile(
        //
        // Add a NOP to ensure we don’t have a flash read immediately before
        // the EPI read.
        //
        "    NOP\n"
        "    LDRH %[ret],[%[addr]]\n"
        "    LDR %[scratch],[sp]\n"
         : [ret] "=r" (ui16Data),
           [scratch] "=r" (ui32Scratch)
         : [addr] "r" (pui16Addr)
    );
    //
    // Keep the compiler from generating a warning.
    //
    ui32Scratch = ui32Scratch;
    return(ui16Data);
}
inline void
EPIWorkaroundByteWrite(uint8_t *pui8Addr, uint8_t ui8Value)
{
    volatile register uint32_t ui32Scratch;
    __asm volatile (
        //
        // Add a NOP to ensure we don’t have a flash read immediately before
        // the EPI read.
        //
        "    NOP\n"
        "    STRB %[value],[%[addr]]\n"
        "    LDR %[scratch],[sp]\n"
         :  [scratch] "=r" (ui32Scratch)
         :  [addr] "r" (pui8Addr), [value] "r" (ui8Value)
     );
    //
    // Keep the compiler from generating a warning.
    //
    ui32Scratch = ui32Scratch;
}
inline uint8_t
EPIWorkaroundByteRead(uint8_t *pui8Addr)
{
    register uint8_t ui8Data;
    register uint32_t ui32Scratch;
    //
    // ui32Scratch is not used other than to add a padding read following the
    // "real" read.
    //
    __asm volatile(
        //
        // Add a NOP to ensure we don’t have a flash read immediately before
        // the EPI read.
        //
        "    NOP\n"
        "    LDRB %[ret],[%[addr]]\n"
        "    LDR %[scratch],[sp]\n"
         : [ret] "=r" (ui8Data),
           [scratch] "=r" (ui32Scratch)
         : [addr] "r" (pui8Addr)
    );
    //
    // Keep the compiler from generating a warning.
    //
    ui32Scratch = ui32Scratch;
    return(ui8Data);
}
#endif

In addition, if using CCS, the following code should be saved as a file entitled epi_workaround_ccs.s driverlib directory and included in the project:

;*****************************************************************************
;
; epi_workaround_ccs.s - EPI memory access functions.
;
; Copyright (c) 2013 Texas Instruments Incorporated.  All rights reserved.
; TI Information - Selective Disclosure
;
;*****************************************************************************
;*****************************************************************************
;
; void EPIWorkaroundWordWrite(uint32_t *pui32Addr, uint32_t ui32Value)
;
;*****************************************************************************
    .sect ".text:EPIWorkaroundWordWrite"
    .global EPIWorkaroundWordWrite
EPIWorkaroundWordWrite:
    ;
    ; Include a no-op to ensure that we don't have a flash data access
    ; immediately before the EPI access.
    ;
    nop
    ;
    ; Store the word in EPI memory.
    ;
    str r1, [r0]
    ;
    ; Make a dummy read from the stack to ensure that we don't have a flash
    ; data access immediately after the EPI access.
    ;
    ldr r1, [sp]
    ;
    ; Return to the caller.
    ;
    bx lr
    .align 4
;*****************************************************************************
;
; uint32_t EPIWorkaroundWordRead(uint32_t *pui32Addr)
;
;*****************************************************************************
    .sect ".text:EPIWorkaroundWordRead"
    .global EPIWorkaroundWordRead
EPIWorkaroundWordRead:
    ;
    ; Include a no-op to ensure that we don't have a flash data access
    ; immediately before the EPI access.
    ;
    nop
    ;
    ; Read the word from EPI memory.
    ;
    ldr r0, [r0]
    ;
    ; Make a dummy read from the stack to ensure that we don't have a flash
    ; data access immediately after the EPI access.
    ;
    ldr r1, [r13]
    ;
    ; Return to the caller.
    ;
    bx lr
    .align 4
;*****************************************************************************
;
; void EPIWorkaroundHWordWrite(uint16_t *pui16Addr, uint16_t ui16Value)
;
;*****************************************************************************
    .sect ".text:EPIWorkaroundHWordWrite"
    .global EPIWorkaroundHWordWrite
EPIWorkaroundHWordWrite:
    ;
    ; Include a no-op to ensure that we don't have a flash data access
    ; immediately before the EPI access.
    ;
    nop
    ;
    ; Store the word in EPI memory.
    ;
    strh r1, [r0]
    ;
    ; Make a dummy read from the stack to ensure that we don't have a flash
    ; data access immediately after the EPI access.
    ;
    ldr r1, [sp]
    ;
    ; Return to the caller.
    ;
    bx lr
    .align 4
;*****************************************************************************
;
; uint16_t EPIWorkaroundHWordRead(uint16_t *pui16Addr)
;
;*****************************************************************************
    .sect ".text:EPIWorkaroundHWordRead"
    .global EPIWorkaroundHWordRead
EPIWorkaroundHWordRead:
    ;
    ; Include a no-op to ensure that we don't have a flash data access
    ; immediately before the EPI access.
    ;
    nop
    ;
    ; Read the half word from EPI memory.
    ;
    ldrh r0, [r0]
    ;
    ; Make a dummy read from the stack to ensure that we don't have a flash
    ; data access immediately after the EPI access.
    ;
    ldr r1, [r13]
    ;
    ; Return to the caller.
    ;
    bx lr
    .align 4
;*****************************************************************************
;
; void EPIWorkaroundByteWrite(uint8_t *pui8Addr, uint8_t ui8Value)
;
;*****************************************************************************
    .sect ".text:EPIWorkaroundByteWrite"
    .global EPIWorkaroundByteWrite
EPIWorkaroundByteWrite:
    ;
    ; Include a no-op to ensure that we don't have a flash data access
    ; immediately before the EPI access.
    ;
    nop
    ;
    ; Store the byte in EPI memory.
    ;
    strb r1, [r0]
    ;
    ; Make a dummy read from the stack to ensure that we don't have a flash
    ; data access immediately after the EPI access.
    ;
    ldr r1, [sp]
    ;
    ; Return to the caller.
    ;
    bx lr
    .align 4
;*****************************************************************************
;
; uint8_t EPIWorkaroundByteRead(uint8_t *pui8Addr)
;
;*****************************************************************************
    .sect ".text:EPIWorkaroundByteRead"
    .global EPIWorkaroundByteRead
EPIWorkaroundByteRead:
    ;
    ; Include a no-op to ensure that we don't have a flash data access
    ; immediately before the EPI access.
    ;
    nop
    ;
    ; Read the byte from EPI memory.
    ;
    ldrb r0, [r0]
    ;
    ; Make a dummy read from the stack to ensure that we don't have a flash
    ; data access immediately after the EPI access.
    ;
    ldr r1, [r13]
    ;
    ; Return to the caller.
    ;
    bx lr
    .align 4
.end