This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

RTOS/SIMPLELINK-MSP432-SDK: RTOS/MSP432P401R: MCU does not get into deepsleep mode

Part Number: SIMPLELINK-MSP432-SDK

Tool/software: TI-RTOS

Hi Team,

This query was raised around 9 months ago but i did not get a confirm answer for that. 

So I am posting again with reference to the same query.

I am using the SimpleLink MSP432 SDK -V 1.40.00.28 version.

Initially I tried to run the "powerdeepsleep" example and found the when the msp432 goes into deepsleep mode by pressing the SW1 on the launchpad the value of "sleepstate" variable in the function "int_fast16_t Power_sleep(uint_fast16_t sleepState)" found in the PowerMSP432.c file changes to 4 (which is the macro value of PowerMSP432_DEEPSLEEP_1 as defined in the PowerMSP432.h file.

The current still is in milliamps (over 2 mA) as compare to 1.6uA that was mentioned in the post for which I have attached the link above.I have also attached screen shot for the current drawn measured and also when the state is changed.

Now I tried to execute the same concept in my firmware written which also has a watchdog timer based wakeup of unit every 6 hours.

The concept is that every 6 hours the mcu wakes up and does some work and once that task is done I am calling the "Power_setPolicy((Power_PolicyFxn)PowerMSP432_deepSleepPolicy);" which is the same function called in the powerdeepsleep example when the switch SW1 is pressed.

But in my case, the value of the sleepState variable never changes to 4 and always stays 1.

As a result the MCU neither goes into LPM3 nor in LPM4 mode.

Due to this the idle mode current drawn in my application shows 20 mA which is too much since ours is battery operated application.

I am attaching the code for reference.

Please if someone can help me out to get this confusion cleared would be great.

Thank you

Vikram   Demo code for Production board getting into Deepsleep.zip

Many thanks in advance.

  • Hello Vikram,

    The Power Drivers have seen a lot of updates since version 1.40. Please upgrade to version 1.60 for the latest power drivers. Also there is a known issue with the enableParking of the IO's when done via Power Drivers, instead I would advise to use the call back function for low power transition to put the IO's in safe state.
  • Thank you Amit for the reply.

    So do you mean that v1.40 has issues with sleep mode or deep sleep mode execution?

    Also when you say not to use the Power Drivers instead use the callback function for low power transition, can you provide some example?

    Vikram

  • Hello Vikram,

    Yes, we have seen issues with the older version. You may refer to a patch release of the drivers with the latest 1.6 SDK in form of the Reference Design software. Do read the User Guide on how to apply the patch for 1.60 SDK version.

    www.ti.com/.../TIDA-01575
  • Thank you Amit.
    There is one issue.
    I have developed my project on v1.40 so how can I transfer that to v1.60 of SDK.
    Is there any document for that?

    Vikram
  • Hello Vikram,

    You can change the version by goign to Project Settings, General, Products
  • Hi Amit,

    I tried loading the firmware into msp432 board and execute the same.

    But can't see anytime the RTC_C_IRQHandler function getting triggered.

    Do I need to get the entire setup mentioned in the "Reference design" document or can i simply load the program into msp432 board and see how the deepsleep mode is getting executed and have the device become active at RTC interrupt?

    Vikram

  • Hello Vikram,

    The RTC_C_IRQHandler on the RTOS framework needs to be instantiated with a HwiP call. You do not need the entire setup if the intent is only the RTC interrupt call.
  • Thank you Amit.

    that issue is resolved. Dealing with another issue which Chris has mentioned will keep an eye on it.

    When I am using RTC enabled deep sleep mode wake up, after waking up msp432 is neither able to read file from SD card and neither able to communicate with uPulser.

    The f_open always opes FR_DISK_ERR and I saw while debugging, that value of "fmt" in the find_volume function returns a value of 3.

    This never used to happen with earlier version of SDK-RTOS that was 1.40. But in that version, msp432 was not able to go into deep sleep too.

    Thank you

    Vikram

  • Hello Vikram,

    I will check with as well on the issue. Do make sure that you close the file handle before going to deep sleep and the correct IO states are maintained so that Idle can persist on the physical device.
  • Thank you Amit.
    I think this issue is not 100% related to using RTC. Even if I tried using the watchdog approach that I had used in SDK RTOS version 1.40 still it gives the same issue.
    But when I used the watchdog concept to wakeup for next event in SDK version 1.40 I did not had this issue.
    In terms of closing the handle, the function SDFatFS_close(handle) is closed before going into deepsleep.

    Vikram
  • Hello Vikram,

    Is the FAT File System on an external device? If yes then can you please check if the IO lines are in Idle-Inactive state for the external FAT File System, i.e CS is high
  •  Hi Amit,

    Yes the FAT File System is on external device.

    I am attaching the pic of the layout of the board which will give u an idea.

    The center IC is msp432 and you can see the SD card mounted in the SD card reader.

    I will confirm about the CS line.

    Vikram

  • Also additionally, for the first time it always writes into the SD card i.e it is able to open the file #0 but it is only after the first file written when it goes into sleep mode and wakes up after that it never writes to file as it is failing to open the file to write.
    Vikram
  • Hello Vikram,

    My concern is that when it goes to sleep and wake-up, if the CS toggle then it may be creating false select conditions causing the device not to respond. Alternately, it may be something in the software, that ic causing the File Handler to return an error. This must be debugged as well.
  • Hi Amit,

    While debugging I found that the new SDK version has different way of calling the function to open the SDSPI driver handle.
    In the old version of SDK 1.40, as below:
    SDSPI_Handle SDSPI_open(uint_least8_t index, uint_least8_t drv, SDSPI_Params *params)
    {
    SDSPI_Handle handle = NULL;

    if (isInitialized && (index < SDSPI_count)) {
    /* If params are NULL use defaults */
    if (params == NULL) {
    params = (SDSPI_Params *) &SDSPI_defaultParams;
    }

    /* Get handle for this driver instance */
    handle = (SDSPI_Handle)&(SDSPI_config[index]);
    handle = handle->fxnTablePtr->openFxn(handle, drv, params);
    }

    return (handle);
    }
    and in the new version of SDK, 1.60 it is as below:
    SD_Handle SDSPI_open(SD_Handle handle, SD_Params *params)
    {
    uintptr_t key;
    SPI_Params spiParams;
    SDSPI_Object *object = handle->object;
    SDSPI_HWAttrs const *hwAttrs = handle->hwAttrs;

    key = HwiP_disable();

    if (object->isOpen) {
    HwiP_restore(key);

    return (NULL);
    }
    object->isOpen = true;

    HwiP_restore(key);

    object->lockSem = SemaphoreP_createBinary(1);
    if (object->lockSem == NULL) {
    object->isOpen = false;

    return (NULL);
    }

    /*
    * SPI is initially set to 400 kHz to perform SD initialization. This is
    * is done to ensure compatibility with older SD cards. Once the card has
    * been initialized (in SPI mode) the SPI peripheral will be closed &
    * reopened at 2.5 MHz.
    */
    SPI_Params_init(&spiParams);
    spiParams.bitRate = 400000;
    object->spiHandle = SPI_open(hwAttrs->spiIndex, &spiParams);
    if (object->spiHandle == NULL) {
    SDSPI_close(handle);

    return (NULL);
    }

    /* Configure the SPI CS pin as output set high */
    GPIO_setConfig(hwAttrs->spiCsGpioIndex,
    GPIO_CFG_OUT_STD | GPIO_CFG_OUT_HIGH);

    return (handle);
    }

    Now the issue is that I am using GPIO pin P8.0 as a CS line to enable and disable the SD card CS.
    In the new version of SDK 1.60, the line below:
    /* Configure the SPI CS pin as output set high */
    GPIO_setConfig(hwAttrs->spiCsGpioIndex,
    GPIO_CFG_OUT_STD | GPIO_CFG_OUT_HIGH);
    is making that GPIO high.
    This was not there in the earlier SDK version.

    Not sure why is this changed. What advantage this gives.

    Kindly verify.

    Thank you
  • Even in the case of calling function f_mkdir the CS line changes to active high in the new SDK version
  • Hi Amitand Chris,

    I verified with the firmware that I was running on the SDK version 1.40. That firmware works fine without going into sleep mode using watchdog timer to trigger the next event.
    For every time the event occurs by watchdog getting triggered, I am getting the file written into SD card without any problems and even the USART communicates with uPulser.
    I used the same firmware to run on SDK version 1.60 but everytime after the first file is written for any next file the SD card fails to open the file to write into it.
    Kindly verify if there is a major change in both SDK version that is causing this issue.

    Vikram
  • Hello Vikram,

    Sure we can check for the FAT FS Example in the SDK. Did you try the standalone example from the SDK 1.60? Also there were a few other threads on the forum, that may help you

    e2e.ti.com/.../670028
  • Hi Amit,

    Thank you for the response.

    Yes I tried the SD example in V1.60, I am getting the same error that is in the post mentioned in the link.

    I am not using any booster pack.

    The other stuff is that the example uses, P4.6 as the SD card chip select. I am using P8.0 as CS for the SD card since in my firmware I have msp432 as master and the SD card as well as another MCU (radio board) as slave. So I have 2 seperate CS 5.0 and 8.0.

    While debugging I found that the value of the CS is getting high every time either the handle for the SD card is opened or even if the function f_open is called and the value of fmt is always returning 3 for all files after the first file written.

    I am attaching the firmware that I have written using the SDK version 1.40 and version 1.60. Please see if you can find the root cause or the difference that is creating the issue.

    With 1.40 it works fine but with 1.60 it does not.MSP432 with watchdog with SDK 1.40.zipMSP432 with watchdog with SDK1.60.zip

    Your help will be highly appreciated as we are not able to move forward with the project and I am stuck as am facing couple of issues if I used the SDK v1.40 I am not able to execute the deep sleep mode and if I use the SDK v1.60 the USART and the SD card do not work after the first file is written.

    Vikram

  • Hello Vikram,

    It would take me some time to setup the debug session for the FAT File System with the condition specified as I am supporting another customer debug at the moment. I will try to get back to you with a resolution at the earliest possible time.
  • Thank you Amit for the reply.

    I would look forward for your reply and hopefully at the earliest as I am stuck with the project and we are due to release in next week.

    Vikram

  • Hi Amit,

    I am sure you must be very busy with other posts/query just wanted to get an idea will it be possible to get some reply early next week or so?

    Thank you in advance.

    Vikram

  • Hi Amit,

    Just trying to see u got a chance to look into the issue related to SD card problem.

    I am not able to move ahead in the fimrware.

    The issue that I have diagnosed further is whenever I turn off and again turn on the LDO to make the SD card work, the f_mount returns success but the f_open always returns FR_DSK_ERR.

    Please see if you get a change to look into this problem.

    But if I keep the LDO always on and do not pull it down, it works fine.

    I see the GPIOs functioning properly whenever I debug and see in the registers window.

    But the same firmware if I work in the version 1.40 does not show this issue.

    Vikram

  • Hello Vikram,

    Apologies for the delay. I plan to work on the issue this week with the latest SDK to see if I can reproduce the issue. Since the code has to be constructed, it will take a day or two to create a code which can reproduce the issue based on the forum post inputs you have provided.
  • Thank you Amit for understanding.

    I will attach another project too where you can see what happens if I simply enable and disable the LDO and then again enable.fatfs sd card example to write file with disabling LDO & SD card without sleep.zipfgwlt firmware with sleep implemented just to have pulser and sd card functionality.zip

    The firmware that names "fatfs sd card example to write file with disabling LDO & SD card without sleep" simply writes a new file every time and in the current firmware I had to keep the LDO always on or else if I disable and reenable the next time f_open will fail to open a new file.

    In the same firmware if you want to get files to be written for every shot then comment the lines 214,215, 373 and 387. If you uncomment those lines then only first file is written next all files are not written.

    The second firmware "fgwlt firmware with sleep implemented just to have pulser and sd card functionality" is the same except that it has the sleep concept implemented based on RTC.

    Also with this concept, if the UART Tx line is pulled low in sleep mode than next time when device wakes up, the UART Tx functionality does not work too.

    Thank you in advance.

    Hope to hear soon from you.

    Vikram

    Vikram

  • Hello Vikram,

    In the firmware file for the first zip file I am not clear what is meant by GPIO write at line 387 (mentioned in your last post)

    GPIO_write(Fogwise_LDO1, Fogwise_LDO1_OFF);/* Turn off LDO1 */

    Is there some external LDO that is being turned ON and OFF?
  • Sorry I accidently pressed resolved issue can you undo it.
    Yes there are 2 LDOès in the firmware. One is for turning the uPulser on and another is for SD card.
    So after every new file written I have to close both the LDOs and next time when it is ready to write a new file it has to be enabled
  • Hello Vikram,

    It looks that the LDO is an external LDO and is specific to your design (something I cannot emulate with a LaunchPad and a SD Card board). Did you check that the LDO switches on correctly and is providing the correct voltage before the access to the SD Card is performed?
  • Yes I am checking that and it shows correct voltage. I checked using multimeter and it showed 3.42V which is enough for the SD card to work.
    the SD card needs only 2.7V to function.
    The strange thing I see is that the same firmware works fine when I use the SDK version 1.40 but not with the version 1.60.
    The only change that both firmware have is the SD card driver functions.
    Since the new SDK 1.60 uses SDFatFS_open and version 1.40 uses SDSPI_open directly.
    SDSPI used to have 3 arguments in it namely handle, drivernumber and sdspi parameters whereas the SDFatFS_open has only 2 argument handle and the drive number.

    Vikram
  • Hello Vikram,

    Yes, you are correct, that it works in one version and not in another. If I run your example with a LaunchPad and SD Card, without having all the other devices e.g. LDO or sensing probes, will it work? If yes, then I can try it out with the latest SDK release which was done a couple of days back and has Power Driver fixes.
  • Hi Amit,

    In order to run just using the Launch pad and the SD card I will have to use Booster pack for SD card.

    Unfortunately I don't have that.

    Hence I am using the custom build board which turns on the SD card using the LDO.

    And another thing is that if you are only using the Launchpad and SD card using Booster pack you are technically not turning off the power to SD card and it is always on so the scenario will not be same.

    Second problem what I encountered with the version V1.60 is that if the SPI handle is opened to use the SPI line to communicate with another device and after that if I try to mount the SD card to read the file and send the daa from the file over SPI to another device, the function "SDFatFS_open" fails and the drive does not get mounted.

    When debugging I found that the function fails to open the SPI handle for the SDSPI_open function.

    This did not happen with the version SDK V1.40.

    I am not sure what is changed in terms of the opening of the SDSPI handle in both the versions but definitely, V1.40 allows to open the SD card and the SPI together but the V1.60 does not.

    Can you please check this.

    Vikram

  • Hello Vikram,

    So there are 2 instances of the SPI Transaction being called. One is for the SD Card and another is for communicating with another device using the same physical SPI interface. Is that correct?

    Do you close the the 2nd SPI handler before calling the SPI handle to open the SD Card interface?
  • Hi Amit,

    Yes you are correct I am using 2 instances of SPI Transaction. One for SD card (which is done by the SD card driver library itself I am not calling) and another is done by me for the SPI interface.

    In the example that I have sent to you I am not even opening the second SPI instance. It is purely for the SD card SPI instance that is used. I have commented that section of code where I am opening another instance of SPI for the SPI interface.

    And as I said earlier the same piece of firmware worked fine with the SDK version 1.40. the only difference was that in 1.40 I was opening and closing the instances of SPI both for SD card and the SPI for another device whereas in the case of 1.60, it is the SD driver library that opens and close the SPI instance for SD card.

    Vikram

  • Hello Vikram,

    So even if one SPI instance is used (by the SD Card driver), 1.60 does not allow it to work after a low power state of LPM3. Are you sure that the 2nd SPI instance is not being called. This will help me debug the code.

    As for the LDOs, I don't think that is an issue since it is more of the SW not working as expected.
  • Yes I am 100% sure since I am never calling the second task that has the 2nd instance of SPI open. The task is only called if there is an event triggered which never triggers since there is no file written on SD card.

    Vikram
  • Hi Amit,

    The other stuff I debugged and found that in the same version of SDK V1.60, if I use the watchdog concept to wake up the unit after every certain time period, that there is no issue of the SD card opening the file and writing new data to it.

    But with the same SDK version if I am using the RTC concept to wakeup I find the issue that for first time, the firmware writes the data to file and the same file is been transmitted over SPI to another device.

    But next time when the unit wakes up, it always gives FR_DISK_ERR while trying to open a new file.

    The problem is that watchdog concept does not let the unit go into deepsleep which is must for my application and the RTC allows the unit to go into deepsleep.

    Also in the RTC concept I am executing below lines after going into deep sleep and after waking from deep sleep.

    Before going into deep sleep I close the USART handle, SDFatFs handle and the SPI handle and then once into sleep the below function is executed

    unsigned int notifyDeepSleepFxn(unsigned int eventType, unsigned int eventArg,
     unsigned int clientArg)
    {
        if(PowerMSP432_ENTERING_DEEPSLEEP == eventType)
        {
            /* Set the unused IOs to low state */
            MAP_GPIO_setOutputLowOnPin(GPIO_PORT_PA, PIN_ALL16);
            MAP_GPIO_setOutputLowOnPin(GPIO_PORT_PB, PIN_ALL16);
            MAP_GPIO_setOutputLowOnPin(GPIO_PORT_PC, (PIN_ALL16 & ~(GPIO_PIN4|GPIO_PIN5|GPIO_PIN6)));
            MAP_GPIO_setOutputLowOnPin(GPIO_PORT_PD, PIN_ALL16);
            MAP_GPIO_setOutputLowOnPin(GPIO_PORT_PE, PIN_ALL16);
            MAP_GPIO_setOutputLowOnPin(GPIO_PORT_PJ, PIN_ALL16);
            MAP_GPIO_setAsOutputPin(GPIO_PORT_PA, PIN_ALL16);
            MAP_GPIO_setAsOutputPin(GPIO_PORT_PB, PIN_ALL16);
            MAP_GPIO_setAsOutputPin(GPIO_PORT_PC, (PIN_ALL16 & ~(GPIO_PIN4|GPIO_PIN5|GPIO_PIN6)));
            MAP_GPIO_setAsOutputPin(GPIO_PORT_PD, PIN_ALL16);
            MAP_GPIO_setAsOutputPin(GPIO_PORT_PE, PIN_ALL16);
            MAP_GPIO_setAsOutputPin(GPIO_PORT_PJ, PIN_ALL16);
    
    
            /* Turn off PSS high-side supervisors to consume less power in shutdown */
            MAP_PSS_disableHighSide();
        }
        return NULL;
    }
    

    Now when the unit wakes up i.e. once the RTC_interrupt triggers, I execute the following piece of firmware in the handler before I turn on the LDO for the uPulser and the SD card.

    void RTC_C_IRQHandler(UArg arg)
    {
        /* Clear the interrupt status for alarm and timer-0 interrupt */
        MAP_RTC_C_clearInterruptFlag(RTC_C_CLOCK_ALARM_INTERRUPT);
    
        MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P8, GPIO_PIN0);
        MAP_GPIO_setAsOutputPin(GPIO_PORT_P8, GPIO_PIN0);
        MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P3,
                GPIO_PIN2 | GPIO_PIN3, GPIO_PRIMARY_MODULE_FUNCTION);
        MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1,
                GPIO_PIN5 | GPIO_PIN6 | GPIO_PIN7, GPIO_PRIMARY_MODULE_FUNCTION);
    
        uart = UART_open(Board_UART1, &uartParams);
        if (uart == NULL)
        {
            System_abort("Error opening the UART");
        }
        /* Post the semaphore to process the ADCBuf Task and FFT */
        sem_post(&devWakeMutex);
    }
    
    

    Please let me know what difference will it be when using RTC as against the Watchdog while using the FatFs library functions.

    Hope to hear soon from you.

    Vikram

  • Hello Vikram,

    Attached is a snapshot for the current measurement for the fatsd example I modified with the latest SDK for MSP432P4 2.10 to have power drivers enabled.

    What I have done is connected the SPI pins to a SD Card interface and powered the SD Card separately with a common GND since I do not have a LDO to provide separate power. In my main application code (file attached), the RTC wakes up the system every 1 minute. During the time the device is in LPM3 the current consumption drops. Now as I see your code and my code, I specifically reconfigure the pins for the SPI function. To make sure that the pins are correctly configured ensure that enableParking is disabled in the board file for the power manager.

    fatsd.c
    /*
     * Copyright (c) 2015-2017, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    /*
     *  ======== fatsd.c ========
     */
    #include <file.h>
    #include <stdbool.h>
    #include <stddef.h>
    #include <stdint.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <time.h>
    
    /* POSIX Header files */
    #include <pthread.h>
    
    #include <third_party/fatfs/ffcio.h>
    
    #include <ti/display/Display.h>
    #include <ti/drivers/GPIO.h>
    #include <ti/drivers/SDFatFS.h>
    
    #include <ti/devices/msp432p4xx/driverlib/driverlib.h>
    #include <ti/drivers/dpl/HwiP.h>
    #include <semaphore.h>
    #include <ti/drivers/Power.h>
    #include <ti/drivers/power/PowerMSP432.h>
    
    /* Example/Board Header files */
    #include "Board.h"
    
    /* Buffer size used for the file copy process */
    #ifndef CPY_BUFF_SIZE
    #define CPY_BUFF_SIZE       2048
    #endif
    
    /* String conversion macro */
    #define STR_(n)             #n
    #define STR(n)              STR_(n)
    
    /* Drive number used for FatFs */
    #define DRIVE_NUM           0
    
    const char inputfile[] = "fat:"STR(DRIVE_NUM)":input.txt";
    const char outputfile[] = "fat:"STR(DRIVE_NUM)":output.txt";
    
    const char textarray[] = \
    "***********************************************************************\n"
    "0         1         2         3         4         5         6         7\n"
    "01234567890123456789012345678901234567890123456789012345678901234567890\n"
    "This is some text to be inserted into the inputfile if there isn't\n"
    "already an existing file located on the media.\n"
    "If an inputfile already exists, or if the file was already once\n"
    "generated, then the inputfile will NOT be modified.\n"
    "***********************************************************************\n";
    
    static Display_Handle display;
    
    /* Set this to the current UNIX time in seconds */
    const struct timespec ts = {
        .tv_sec = 1469647026,
        .tv_nsec = 0
    };
    
    /* File name prefix for this filesystem for use with TI C RTS */
    char fatfsPrefix[] = "fat";
    
    unsigned char cpy_buff[CPY_BUFF_SIZE + 1];
    
    /* Mutex for indicating wakeup of device */
    sem_t devWakeMutex;
    
    /* Power Policy Object*/
    Power_NotifyObj notifyObj;
    
    void RTC_C_IRQHandler(void);
    
    /* -------------------------------------------------------------------
     * Set up of the current RTC time when the system is first powered up.
     * This is set for April 28th 2017 11:30:00 PM
     * ------------------------------------------------------------------- */
    const RTC_C_Calendar currentTime =
    {
            00,
            30,
            23,
            06,
            28,
            04,
            2017
    };
    
    /* Callback function for Power Policy Manager to perform specific tasks on
     * LMP3 Entry and Wake. During LPM3 Entry, the GPIO for AFE Power Enable and
     * Sensor Enable are made low to reduce current consumption. Also since
     * enableparking is disabled, the unused IO's are configured to output low
     * state so that current consumption is reduced. During LPM3 exit the GPIO for
     * AFE Power Enable and Sensor Enable are made High.
     * */
    uint8_t notifyDeepSleepFxn(uint8_t eventType, uint8_t eventArg, uint8_t clientArg)
    {
        if(PowerMSP432_ENTERING_DEEPSLEEP == eventType)
        {
            /* Set the unused IOs to low state */
            MAP_GPIO_setOutputLowOnPin(GPIO_PORT_PA, (PIN_ALL16 & ~(GPIO_PIN5|GPIO_PIN6|GPIO_PIN7)));
            MAP_GPIO_setOutputLowOnPin(GPIO_PORT_PB, (PIN_ALL16 & ~(GPIO_PIN6)));
            MAP_GPIO_setOutputLowOnPin(GPIO_PORT_PC, PIN_ALL16);
            MAP_GPIO_setOutputLowOnPin(GPIO_PORT_PD, PIN_ALL16);
            MAP_GPIO_setOutputLowOnPin(GPIO_PORT_PE, PIN_ALL16);
            MAP_GPIO_setOutputLowOnPin(GPIO_PORT_PJ, PIN_ALL16);
            MAP_GPIO_setAsOutputPin(GPIO_PORT_PA, (PIN_ALL16 & ~(GPIO_PIN5|GPIO_PIN6|GPIO_PIN7)));
            MAP_GPIO_setAsOutputPin(GPIO_PORT_PB, (PIN_ALL16 & ~(GPIO_PIN6)));
            MAP_GPIO_setAsOutputPin(GPIO_PORT_PC, PIN_ALL16);
            MAP_GPIO_setAsOutputPin(GPIO_PORT_PD, PIN_ALL16);
            MAP_GPIO_setAsOutputPin(GPIO_PORT_PE, PIN_ALL16);
            MAP_GPIO_setAsOutputPin(GPIO_PORT_PJ, PIN_ALL16);
    
    
            /* Turn off PSS high-side supervisors to consume less power in shutdown */
            MAP_PSS_disableHighSide();
        }
        else
        {
            MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1,
                    GPIO_PIN5 | GPIO_PIN6 | GPIO_PIN7, GPIO_PRIMARY_MODULE_FUNCTION);
    
        }
    
        return 0;
    }
    void RTC_C_IRQHandler(void)
    {
        /* Clear the interrupt status for alarm and timer-0 interrupt */
        MAP_RTC_C_clearInterruptFlag(RTC_C_CLOCK_ALARM_INTERRUPT);
    
        /* Post the semaphore to process the ADCBuf Task and FFT */
        sem_post(&devWakeMutex);
    }
    
    /* Function to set the next wakeup time after N Hours and M minutes */
    void predictive_maintenance_setWakeTime(uint8_t Hours, uint8_t Minutes)
    {
        RTC_C_Calendar newTime;
        uint_fast8_t excessHours = 0;
    
        /* Get the current time */
        newTime = MAP_RTC_C_getCalendarTime();
    
        /* Check if the wakeup period parameters are valid
         * Hour interval cannot be more than 24
         * Minute interval cannot be more than 60
         * Hour and Minute both cannot be 0 */
        if((Hours > 24) || (Minutes > 60) || ((Hours == 0) && (Minutes == 0)))
        {
            while(1);
        }
    
        /* Get the current time and check if there is a roll over for minute or
         * hour. If there is a hour roll over, then change the next match time
         * for 0 hrs. If there is a minute roll over, then increment the hour
         * and then set the minute match time. If there is no roll over for
         * either minute or hour then program the next match time with hour
         * unchanged and minute added. */
    
        newTime.minutes = newTime.minutes + Minutes;
    
        if(newTime.minutes > 59)
        {
            newTime.minutes = newTime.minutes - 60;
            excessHours = 1;
        }
    
        newTime.hours = newTime.hours + Hours + excessHours;
    
        if(newTime.hours > 23)
        {
            newTime.hours = newTime.hours - 24;
        }
    
        MAP_RTC_C_setCalendarAlarm(newTime.minutes,
                                   newTime.hours,
                                   RTC_C_ALARMCONDITION_OFF,
                                   RTC_C_ALARMCONDITION_OFF);
    }
    /*
     *  ======== mainThread ========
     *  Thread to perform a file copy
     *
     *  Thread tries to open an existing file inputfile[]. If the file doesn't
     *  exist, create one and write some known content into it.
     *  The contents of the inputfile[] are then copied to an output file
     *  outputfile[]. Once completed, the contents of the output file are
     *  printed onto the system console (stdout).
     */
    void *mainThread(void *arg0)
    {
        SDFatFS_Handle sdfatfsHandle;
        /* Hwi variables */
        HwiP_Handle hwiPRTC = NULL;
        HwiP_Params hwiPRTCParams;
    
        /* Variables for the CIO functions */
        FILE *src, *dst;
    
        /* Variables to keep track of the file copy progress */
        unsigned int bytesRead = 0;
        unsigned int bytesWritten = 0;
        unsigned int filesize;
        unsigned int totalBytesCopied = 0;
    
        /* Call driver init functions */
        GPIO_init();
        Display_init();
        SDFatFS_init();
    
        /* Configure the LED pin */
        GPIO_setConfig(Board_GPIO_LED0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
    
        /* add_device() should be called once and is used for all media types */
        add_device(fatfsPrefix, _MSA, ffcio_open, ffcio_close, ffcio_read,
            ffcio_write, ffcio_lseek, ffcio_unlink, ffcio_rename);
    
        /* Open the display for output */
        display = Display_open(Display_Type_UART, NULL);
        if (display == NULL) {
            /* Failed to open display driver */
            while (1);
        }
    
        /* Initialize real-time clock */
        clock_settime(CLOCK_REALTIME, &ts);
    
        Display_printf(display, 0, 0, "Starting the fatsd example\n");
        Display_printf(display, 0, 0,
            "This example requires a FAT filesystem on the SD card.\n");
        Display_printf(display, 0, 0,
            "You will get errors if your SD card is not formatted with a filesystem.\n");
    
        MAP_RTC_C_initCalendar(&currentTime, RTC_C_FORMAT_BINARY);
        MAP_RTC_C_setPrescaleValue(RTC_C_PRESCALE_0, 0);
        MAP_RTC_C_definePrescaleEvent(RTC_C_PRESCALE_0, RTC_C_PSEVENTDIVIDER_64);
        MAP_RTC_C_clearInterruptFlag(RTC_C_CLOCK_ALARM_INTERRUPT);
        MAP_RTC_C_enableInterrupt(RTC_C_CLOCK_ALARM_INTERRUPT);
        MAP_RTC_C_startClock();
    
        Display_close(display);
    
        /* Enable interrupts from RTC Module. */
        HwiP_Params_init(&hwiPRTCParams);
        hwiPRTCParams.arg = 0;
        hwiPRTCParams.priority = 0x20;
        hwiPRTC = HwiP_create(INT_RTC_C, (HwiP_Fxn)RTC_C_IRQHandler, &hwiPRTCParams);
    
        if (hwiPRTC == NULL)
        {
            while(1);
        }
    
        /* Create Mutex for Device wakeup due to GPIO switch release or RTC
         * wake up */
        sem_init(&devWakeMutex, 1, 0);
    
        Power_setPolicy((Power_PolicyFxn)PowerMSP432_deepSleepPolicy);
    
        Power_setConstraint(PowerMSP432_DISALLOW_DEEPSLEEP_1);
    
        /* Register for entering shutdown notifications */
        Power_registerNotify(&notifyObj, PowerMSP432_ENTERING_DEEPSLEEP | PowerMSP432_AWAKE_DEEPSLEEP,
            (Power_NotifyFxn) notifyDeepSleepFxn, 0);
    
        for(;;)
        {
            /* Turn on user LED */
            GPIO_write(Board_GPIO_LED0, Board_GPIO_LED_ON);
    
            /* Open the display for output */
            display = Display_open(Display_Type_UART, NULL);
            if (display == NULL) {
                /* Failed to open display driver */
                while (1);
            }
    
            /* Mount and register the SD Card */
            sdfatfsHandle = SDFatFS_open(Board_SDFatFS0, DRIVE_NUM);
            if (sdfatfsHandle == NULL) {
                Display_printf(display, 0, 0, "Error starting the SD card\n");
                while (1);
            }
            else {
                Display_printf(display, 0, 0, "Drive %u is mounted\n", DRIVE_NUM);
            }
    
            /* Try to open the source file */
            src = fopen(inputfile, "r");
            if (!src) {
                Display_printf(display, 0, 0, "Creating a new file \"%s\"...",
                    inputfile);
    
                /* Open file for both reading and writing */
                src = fopen(inputfile, "w+");
                if (!src) {
                    Display_printf(display, 0, 0,
                        "Error: \"%s\" could not be created.\nPlease check the "
                        "Getting Started Guide if additional jumpers are necessary.\n",
                        inputfile);
                    Display_printf(display, 0, 0, "Aborting...\n");
                    while (1);
                }
    
                fwrite(textarray, 1, strlen(textarray), src);
                fflush(src);
    
                /* Reset the internal file pointer */
                rewind(src);
    
                Display_printf(display, 0, 0, "done\n");
            }
            else {
                Display_printf(display, 0, 0, "Using existing copy of \"%s\"\n",
                    inputfile);
            }
    
            /* Create a new file object for the file copy */
            dst = fopen(outputfile, "w");
            if (!dst) {
                Display_printf(display, 0, 0, "Error opening \"%s\"\n", outputfile);
                Display_printf(display, 0, 0, "Aborting...\n");
                while (1);
            }
            else {
                Display_printf(display, 0, 0, "Starting file copy\n");
            }
    
            /*  Copy the contents from the src to the dst */
            while (true) {
                /*  Read from source file */
                bytesRead = fread(cpy_buff, 1, CPY_BUFF_SIZE, src);
                if (bytesRead == 0) {
                    break; /* Error or EOF */
                }
    
                /*  Write to dst file */
                bytesWritten = fwrite(cpy_buff, 1, bytesRead, dst);
                if (bytesWritten < bytesRead) {
                    Display_printf(display, 0, 0, "Disk Full\n");
                    break; /* Error or Disk Full */
                }
    
                /*  Update the total number of bytes copied */
                totalBytesCopied += bytesWritten;
            }
    
            fflush(dst);
    
            /* Get the filesize of the source file */
            fseek(src, 0, SEEK_END);
            filesize = ftell(src);
            rewind(src);
    
            /* Close both inputfile[] and outputfile[] */
            fclose(src);
            fclose(dst);
    
            Display_printf(display, 0, 0,
                "File \"%s\" (%u B) copied to \"%s\" (Wrote %u B)\n",
                inputfile, filesize, outputfile, totalBytesCopied);
    
            /* Now output the outputfile[] contents onto the console */
            dst = fopen(outputfile, "r");
            if (!dst) {
                Display_printf(display, 0, 0, "Error opening \"%s\"\n", outputfile);
                Display_printf(display, 0, 0, "Aborting...\n");
                while (1);
            }
    
            /* Print file contents */
            while (true) {
                /* Read from output file */
                bytesRead = fread(cpy_buff, 1, CPY_BUFF_SIZE, dst);
                if (bytesRead == 0) {
                    break; /* Error or EOF */
                }
                cpy_buff[bytesRead] = '\0';
                /* Write output */
                Display_printf(display, 0, 0, "%s", cpy_buff);
            }
    
            /* Close the file */
            fclose(dst);
    
            /* Stopping the SDCard */
            SDFatFS_close(sdfatfsHandle);
            Display_printf(display, 0, 0, "Drive %u unmounted\n", DRIVE_NUM);
    
            /* Turn off user LED */
            GPIO_write(Board_GPIO_LED0, Board_GPIO_LED_OFF);
    
            Display_close(display);
    
            predictive_maintenance_setWakeTime(0, 1);
            sem_wait(&devWakeMutex);
    
        }
    
    }
    
    /*
     *  ======== fatfs_getFatTime ========
     */
    int32_t fatfs_getFatTime(void)
    {
        time_t seconds;
        uint32_t fatTime;
        struct tm *pTime;
    
        /*
         *  TI time() returns seconds elapsed since 1900, while other tools
         *  return seconds from 1970.  However, both TI and GNU localtime()
         *  sets tm tm_year to number of years since 1900.
         */
        seconds = time(NULL);
    
        pTime = localtime(&seconds);
    
        /*
         *  localtime() sets pTime->tm_year to number of years
         *  since 1900, so subtract 80 from tm_year to get FAT time
         *  offset from 1980.
         */
        fatTime = ((uint32_t)(pTime->tm_year - 80) << 25) |
            ((uint32_t)(pTime->tm_mon) << 21) |
            ((uint32_t)(pTime->tm_mday) << 16) |
            ((uint32_t)(pTime->tm_hour) << 11) |
            ((uint32_t)(pTime->tm_min) << 5) |
            ((uint32_t)(pTime->tm_sec) >> 1);
    
        return ((int32_t)fatTime);
    }
    
    5808.MSP_EXP432P401R.c
    /*
     * Copyright (c) 2015-2018, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    /*
     *  ======== MSP_EXP432P401R.c ========
     *  This file is responsible for setting up the board specific items for the
     *  MSP_EXP432P401R board.
     */
    
    #include <stdbool.h>
    #include <stddef.h>
    #include <stdint.h>
    
    #ifndef DeviceFamily_MSP432P401x
    #define DeviceFamily_MSP432P401x
    #endif
    
    #include <ti/devices/DeviceFamily.h>
    
    #include <ti/drivers/Power.h>
    #include <ti/drivers/power/PowerMSP432.h>
    
    #include <ti/devices/msp432p4xx/inc/msp.h>
    #include <ti/devices/msp432p4xx/driverlib/rom.h>
    #include <ti/devices/msp432p4xx/driverlib/rom_map.h>
    #include <ti/devices/msp432p4xx/driverlib/adc14.h>
    #include <ti/devices/msp432p4xx/driverlib/dma.h>
    #include <ti/devices/msp432p4xx/driverlib/gpio.h>
    #include <ti/devices/msp432p4xx/driverlib/i2c.h>
    #include <ti/devices/msp432p4xx/driverlib/interrupt.h>
    #include <ti/devices/msp432p4xx/driverlib/pmap.h>
    #include <ti/devices/msp432p4xx/driverlib/ref_a.h>
    #include <ti/devices/msp432p4xx/driverlib/spi.h>
    #include <ti/devices/msp432p4xx/driverlib/timer_a.h>
    #include <ti/devices/msp432p4xx/driverlib/timer32.h>
    #include <ti/devices/msp432p4xx/driverlib/uart.h>
    #include <ti/devices/msp432p4xx/driverlib/wdt_a.h>
    
    #include "MSP_EXP432P401R.h"
    
    /*
     *  =============================== ADC ===============================
     */
    #include <ti/drivers/ADC.h>
    #include <ti/drivers/adc/ADCMSP432.h>
    
    /* ADC objects */
    ADCMSP432_Object adcMSP432Objects[MSP_EXP432P401R_ADCCOUNT];
    
    /* ADC configuration structure */
    const ADCMSP432_HWAttrsV1 adcMSP432HWAttrs[MSP_EXP432P401R_ADCCOUNT] = {
        {
            .adcPin = ADCMSP432_P5_5_A0,
            .refVoltage = ADCMSP432_REF_VOLTAGE_INT_2_5V,
            .resolution = ADC_14BIT
        },
        {
            .adcPin = ADCMSP432_P5_4_A1,
            .refVoltage = ADCMSP432_REF_VOLTAGE_INT_1_45V,
            .resolution = ADC_8BIT
        }
    };
    
    const ADC_Config ADC_config[MSP_EXP432P401R_ADCCOUNT] = {
        {
            .fxnTablePtr = &ADCMSP432_fxnTable,
            .object = &adcMSP432Objects[MSP_EXP432P401R_ADC0],
            .hwAttrs = &adcMSP432HWAttrs[MSP_EXP432P401R_ADC0]
        },
        {
            .fxnTablePtr = &ADCMSP432_fxnTable,
            .object = &adcMSP432Objects[MSP_EXP432P401R_ADC1],
            .hwAttrs = &adcMSP432HWAttrs[MSP_EXP432P401R_ADC1]
        }
    };
    
    const uint_least8_t ADC_count = MSP_EXP432P401R_ADCCOUNT;
    
    /*
     *  =============================== ADCBuf ===============================
     */
    #include <ti/drivers/ADCBuf.h>
    #include <ti/drivers/adcbuf/ADCBufMSP432.h>
    
    /* ADC objects */
    ADCBufMSP432_Object adcbufMSP432Objects[MSP_EXP432P401R_ADCBUFCOUNT];
    
    ADCBufMSP432_Channels adcBuf0MSP432Channels[MSP_EXP432P401R_ADCBUF0CHANNELCOUNT] = {
        {
            .adcPin = ADCBufMSP432_P5_5_A0,
            .refSource = ADCBufMSP432_VREFPOS_AVCC_VREFNEG_VSS,
            .refVoltage = 3300000,
            .adcInputMode = ADCBufMSP432_SINGLE_ENDED,
            .adcDifferentialPin = ADCBufMSP432_PIN_NONE,
            .adcInternalSource = ADCBufMSP432_INTERNAL_SOURCE_MODE_OFF
        },
        {
            .adcPin = ADCBufMSP432_P5_4_A1,
            .refSource = ADCBufMSP432_VREFPOS_INTBUF_VREFNEG_VSS,
            .refVoltage = 2500000,
            .adcInputMode = ADCBufMSP432_SINGLE_ENDED,
            .adcDifferentialPin = ADCBufMSP432_PIN_NONE,
            .adcInternalSource = ADCBufMSP432_INTERNAL_SOURCE_MODE_OFF
        },
        {
            .adcPin = ADCBufMSP432_P5_5_A0,
            .refSource = ADCBufMSP432_VREFPOS_INTBUF_VREFNEG_VSS,
            .refVoltage = 2500000,
            .adcInputMode = ADCBufMSP432_SINGLE_ENDED,
            .adcDifferentialPin = ADCBufMSP432_PIN_NONE,
            .adcInternalSource = ADCBufMSP432_TEMPERATURE_MODE
        },
        {
            .adcPin = ADCBufMSP432_P5_5_A0,
            .refSource = ADCBufMSP432_VREFPOS_AVCC_VREFNEG_VSS,
            .refVoltage = 3300000,
            .adcInputMode = ADCBufMSP432_DIFFERENTIAL,
            .adcDifferentialPin = ADCBufMSP432_P5_4_A1,
            .adcInternalSource = ADCBufMSP432_INTERNAL_SOURCE_MODE_OFF
        },
    };
    
    /* ADC configuration structure */
    const ADCBufMSP432_HWAttrs adcbufMSP432HWAttrs[MSP_EXP432P401R_ADCBUFCOUNT] = {
        {
            .intPriority =  ~0,
            .channelSetting = adcBuf0MSP432Channels,
            .adcTimerTriggerSource = ADCBufMSP432_TIMERA1_CAPTURECOMPARE2,
            .useDMA = 1,
            .dmaIntNum = DMA_INT0,
            .adcTriggerSource = ADCBufMSP432_TIMER_TRIGGER,
            .timerDutyCycle = 50,
            .clockSource = ADCBufMSP432_ADC_CLOCK
        }
    };
    
    const ADCBuf_Config ADCBuf_config[MSP_EXP432P401R_ADCBUFCOUNT] = {
        {
            .fxnTablePtr = &ADCBufMSP432_fxnTable,
            .object = &adcbufMSP432Objects[MSP_EXP432P401R_ADCBUF0],
            .hwAttrs = &adcbufMSP432HWAttrs[MSP_EXP432P401R_ADCBUF0]
        }
    };
    
    const uint_least8_t ADCBuf_count = MSP_EXP432P401R_ADCBUFCOUNT;
    
    /*
     *  ============================= Capture =============================
     */
    #include <ti/drivers/Capture.h>
    #include <ti/drivers/capture/CaptureMSP432.h>
    
    CaptureMSP432_Object captureMSP432Objects[MSP_EXP432P401R_CAPTURECOUNT];
    
    const CaptureMSP432_HWAttrs captureMSP432HWAttrs[MSP_EXP432P401R_CAPTURECOUNT] = {
        /* Timer_A1 */
        {
            .timerBaseAddress = TIMER_A1_BASE,
            .clockSource = TIMER_A_CLOCKSOURCE_ACLK,
            .clockDivider = TIMER_A_CLOCKSOURCE_DIVIDER_1,
            .capturePort = CaptureMSP432_P7_7_TA1,
            .intPriority = ~0
        },
        /* Timer_A2 */
        {
            .timerBaseAddress = TIMER_A2_BASE,
            .clockSource = TIMER_A_CLOCKSOURCE_ACLK,
            .clockDivider = TIMER_A_CLOCKSOURCE_DIVIDER_1,
            .capturePort = CaptureMSP432_P6_7_TA2,
            .intPriority = ~0
        },
        /* Timer_A3 */
        {
            .timerBaseAddress = TIMER_A3_BASE,
            .clockSource = TIMER_A_CLOCKSOURCE_ACLK,
            .clockDivider = TIMER_A_CLOCKSOURCE_DIVIDER_1,
            .capturePort = CaptureMSP432_P8_2_TA3,
            .intPriority = ~0
        }
    };
    
    const Capture_Config Capture_config[MSP_EXP432P401R_CAPTURECOUNT] = {
        {
            .fxnTablePtr = &CaptureMSP432_captureFxnTable,
            .object = &captureMSP432Objects[MSP_EXP432P401R_CAPTURE_TA1],
            .hwAttrs = &captureMSP432HWAttrs[MSP_EXP432P401R_CAPTURE_TA1]
        },
        {
            .fxnTablePtr = &CaptureMSP432_captureFxnTable,
            .object = &captureMSP432Objects[MSP_EXP432P401R_CAPTURE_TA2],
            .hwAttrs = &captureMSP432HWAttrs[MSP_EXP432P401R_CAPTURE_TA2]
        },
        {
            .fxnTablePtr = &CaptureMSP432_captureFxnTable,
            .object = &captureMSP432Objects[MSP_EXP432P401R_CAPTURE_TA3],
            .hwAttrs = &captureMSP432HWAttrs[MSP_EXP432P401R_CAPTURE_TA3]
        }
    };
    
    const uint_least8_t Capture_count = MSP_EXP432P401R_CAPTURECOUNT;
    
    /*
     *  =============================== DMA ===============================
     */
    #include <ti/drivers/dma/UDMAMSP432.h>
    
    #if defined(__TI_COMPILER_VERSION__)
    #pragma DATA_ALIGN(dmaControlTable, 256)
    #elif defined(__IAR_SYSTEMS_ICC__)
    #pragma data_alignment=256
    #elif defined(__GNUC__)
    __attribute__ ((aligned (256)))
    #endif
    static DMA_ControlTable dmaControlTable[16];
    
    /*
     *  ======== dmaErrorHwi ========
     *  This is the handler for the uDMA error interrupt.
     */
    static void dmaErrorHwi(uintptr_t arg)
    {
        int status = MAP_DMA_getErrorStatus();
        MAP_DMA_clearErrorStatus();
    
        /* Suppress unused variable warning */
        (void)status;
    
        while (1);
    }
    
    UDMAMSP432_Object udmaMSP432Object;
    
    const UDMAMSP432_HWAttrs udmaMSP432HWAttrs = {
        .controlBaseAddr = (void *)dmaControlTable,
        .dmaErrorFxn = (UDMAMSP432_ErrorFxn)dmaErrorHwi,
        .intNum = INT_DMA_ERR,
        .intPriority = (~0)
    };
    
    const UDMAMSP432_Config UDMAMSP432_config = {
        .object = &udmaMSP432Object,
        .hwAttrs = &udmaMSP432HWAttrs
    };
    
    /*
     *  ============================= Display =============================
     */
    #include <ti/display/Display.h>
    #include <ti/display/DisplayUart.h>
    #include <ti/display/DisplaySharp.h>
    #define MAXPRINTLEN 1024
    
    #ifndef BOARD_DISPLAY_SHARP_SIZE
    #define BOARD_DISPLAY_SHARP_SIZE    96
    #endif
    
    DisplayUart_Object displayUartObject;
    DisplaySharp_Object    displaySharpObject;
    
    static char displayBuf[MAXPRINTLEN];
    static uint_least8_t sharpDisplayBuf[BOARD_DISPLAY_SHARP_SIZE * BOARD_DISPLAY_SHARP_SIZE / 8];
    
    const DisplayUart_HWAttrs displayUartHWAttrs = {
        .uartIdx = MSP_EXP432P401R_UARTA0,
        .baudRate = 115200,
        .mutexTimeout = (unsigned int)(-1),
        .strBuf = displayBuf,
        .strBufLen = MAXPRINTLEN
    };
    
    const DisplaySharp_HWAttrsV1 displaySharpHWattrs = {
        .spiIndex    = MSP_EXP432P401R_SPIB0,
        .csPin       = MSP_EXP432P401R_LCD_CS,
        .powerPin    = MSP_EXP432P401R_LCD_POWER,
        .enablePin   = MSP_EXP432P401R_LCD_ENABLE,
        .pixelWidth  = BOARD_DISPLAY_SHARP_SIZE,
        .pixelHeight = BOARD_DISPLAY_SHARP_SIZE,
        .displayBuf  = sharpDisplayBuf,
    };
    
    #ifndef BOARD_DISPLAY_USE_UART
    #define BOARD_DISPLAY_USE_UART 1
    #endif
    #ifndef BOARD_DISPLAY_USE_UART_ANSI
    #define BOARD_DISPLAY_USE_UART_ANSI 0
    #endif
    #ifndef BOARD_DISPLAY_USE_LCD
    #define BOARD_DISPLAY_USE_LCD 0
    #endif
    
    /*
     * This #if/#else is needed to workaround a problem with the
     * IAR compiler. The IAR compiler doesn't like the empty array
     * initialization. (IAR Error[Pe1345])
     */
     #if (BOARD_DISPLAY_USE_UART || BOARD_DISPLAY_USE_LCD)
    const Display_Config Display_config[] = {
        {
    #  if (BOARD_DISPLAY_USE_UART_ANSI)
            .fxnTablePtr = &DisplayUartAnsi_fxnTable,
    #  else /* Default to minimal UART with no cursor placement */
            .fxnTablePtr = &DisplayUartMin_fxnTable,
    #  endif
            .object = &displayUartObject,
            .hwAttrs = &displayUartHWAttrs
        },
    #endif
    #if (BOARD_DISPLAY_USE_LCD)
        {
            .fxnTablePtr = &DisplaySharp_fxnTable,
            .object      = &displaySharpObject,
            .hwAttrs     = &displaySharpHWattrs
        },
    #endif
    };
    
    const uint_least8_t Display_count = sizeof(Display_config) / sizeof(Display_Config);
    
    /*
     *  ======== MSP_EXP432P401R_initGeneral ========
     */
    void MSP_EXP432P401R_initGeneral(void)
    {
        Power_init();
    }
    
    /*
     *  =============================== GPIO ===============================
     */
    #include <ti/drivers/GPIO.h>
    #include <ti/drivers/gpio/GPIOMSP432.h>
    
    /*
     * Array of Pin configurations
     * NOTE: The order of the pin configurations must coincide with what was
     *       defined in MSP_EXP432P401R.h
     * NOTE: Pins not used for interrupts should be placed at the end of the
     *       array.  Callback entries can be omitted from callbacks array to
     *       reduce memory usage.
     */
    GPIO_PinConfig gpioPinConfigs[] = {
        /* Input pins */
        /*
         * NOTE: Specifying FALLING edge triggering for these buttons to ensure the
         * interrupts are signaled immediately.  See the description of the
         * PowerMSP432 driver's automatic pin parking feature for this rationale.
         */
        /* MSP_EXP432P401R_GPIO_S1 */
        GPIOMSP432_P1_1 | GPIO_CFG_IN_PU | GPIO_CFG_IN_INT_FALLING,
        /* MSP_EXP432P401R_GPIO_S2 */
        GPIOMSP432_P1_4 | GPIO_CFG_IN_PU | GPIO_CFG_IN_INT_FALLING,
    
        /* MSP_EXP432P401R_SPI_MASTER_READY */
        GPIOMSP432_P5_7 | GPIO_DO_NOT_CONFIG,
        /* MSP_EXP432P401R_SPI_SLAVE_READY */
        GPIOMSP432_P6_0 | GPIO_DO_NOT_CONFIG,
    
        /* Output pins */
        /* MSP_EXP432P401R_GPIO_LED1 */
        GPIOMSP432_P1_0 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_LOW | GPIO_CFG_OUT_LOW,
        /* MSP_EXP432P401R_GPIO_LED_RED */
        GPIOMSP432_P2_0 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_HIGH | GPIO_CFG_OUT_LOW,
    
        /*
         * MSP_EXP432P401R_GPIO_LED_GREEN & MSP_EXP432P401R_GPIO_LED_BLUE are used for
         * PWM examples.  Uncomment the following lines if you would like to control
         * the LEDs with the GPIO driver.
         */
        /* MSP_EXP432P401R_GPIO_LED_GREEN */
        /* GPIOMSP432_P2_1 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_HIGH | GPIO_CFG_OUT_LOW, */
        /* MSP_EXP432P401R_GPIO_LED_BLUE */
        /* GPIOMSP432_P2_2 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_HIGH | GPIO_CFG_OUT_LOW */
        /* MSP_EXP432P401R_SPI_CS1 */
        GPIOMSP432_P5_4 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_LOW | GPIO_CFG_OUT_HIGH,
        /* MSP_EXP432P401R_SPI_CS2 */
        GPIOMSP432_P5_5 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_LOW | GPIO_CFG_OUT_HIGH,
    
        /* MSP_EXP432P401R_SDSPI_CS */
        GPIOMSP432_P4_6 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_LOW | GPIO_CFG_OUT_HIGH,
    
        /* Sharp Display - GPIO configurations will be done in the Display files */
        GPIOMSP432_P4_3 | GPIO_DO_NOT_CONFIG, /* SPI chip select */
        GPIOMSP432_P4_1 | GPIO_DO_NOT_CONFIG, /* LCD power control */
        GPIOMSP432_P6_0 | GPIO_DO_NOT_CONFIG, /*LCD enable */
    };
    
    /*
     * Array of callback function pointers
     * NOTE: The order of the pin configurations must coincide with what was
     *       defined in MSP_EXP432P401R.h
     * NOTE: Pins not used for interrupts can be omitted from callbacks array to
     *       reduce memory usage (if placed at end of gpioPinConfigs array).
     */
    GPIO_CallbackFxn gpioCallbackFunctions[] = {
        /* MSP_EXP432P401R_GPIO_S1 */
        NULL,
        /* MSP_EXP432P401R_GPIO_S2 */
        NULL,
        /* MSP_EXP432P401R_SPI_MASTER_READY */
        NULL,
        /* MSP_EXP432P401R_SPI_SLAVE_READY */
        NULL
    };
    
    const GPIOMSP432_Config GPIOMSP432_config = {
        .pinConfigs = (GPIO_PinConfig *)gpioPinConfigs,
        .callbacks = (GPIO_CallbackFxn *)gpioCallbackFunctions,
        .numberOfPinConfigs = sizeof(gpioPinConfigs)/sizeof(GPIO_PinConfig),
        .numberOfCallbacks = sizeof(gpioCallbackFunctions)/sizeof(GPIO_CallbackFxn),
        .intPriority = (~0)
    };
    
    /*
     *  =============================== I2C ===============================
     */
    #include <ti/drivers/I2C.h>
    #include <ti/drivers/i2c/I2CMSP432.h>
    
    I2CMSP432_Object i2cMSP432Objects[MSP_EXP432P401R_I2CCOUNT];
    
    const I2CMSP432_HWAttrsV1 i2cMSP432HWAttrs[MSP_EXP432P401R_I2CCOUNT] = {
        {
            .baseAddr = EUSCI_B0_BASE,
            .intNum = INT_EUSCIB0,
            .intPriority = (~0),
            .clockSource = EUSCI_B_I2C_CLOCKSOURCE_SMCLK,
            .dataPin = I2CMSP432_P1_6_UCB0SDA,
            .clkPin = I2CMSP432_P1_7_UCB0SCL
        },
        {
            .baseAddr = EUSCI_B1_BASE,
            .intNum = INT_EUSCIB1,
            .intPriority = (~0),
            .clockSource = EUSCI_B_I2C_CLOCKSOURCE_SMCLK,
            .dataPin = I2CMSP432_P6_4_UCB1SDA,
            .clkPin = I2CMSP432_P6_5_UCB1SCL
        }
    };
    
    const I2C_Config I2C_config[MSP_EXP432P401R_I2CCOUNT] = {
        {
            .fxnTablePtr = &I2CMSP432_fxnTable,
            .object = &i2cMSP432Objects[MSP_EXP432P401R_I2CB0],
            .hwAttrs = &i2cMSP432HWAttrs[MSP_EXP432P401R_I2CB0]
        },
        {
            .fxnTablePtr = &I2CMSP432_fxnTable,
            .object = &i2cMSP432Objects[MSP_EXP432P401R_I2CB1],
            .hwAttrs = &i2cMSP432HWAttrs[MSP_EXP432P401R_I2CB1]
        }
    };
    
    const uint_least8_t I2C_count = MSP_EXP432P401R_I2CCOUNT;
    
    /*
     *  =============================== I2CSlave ===============================
     */
    #include <ti/drivers/I2CSlave.h>
    #include <ti/drivers/i2cslave/I2CSlaveMSP432.h>
    
    I2CSlaveMSP432_Object i2cSlaveMSP432Objects[MSP_EXP432P401R_I2CSLAVECOUNT];
    
    const I2CSlaveMSP432_HWAttrs i2cSlaveMSP432HWAttrs[MSP_EXP432P401R_I2CSLAVECOUNT] = {
        {
            .baseAddr = EUSCI_B0_BASE,
            .intNum = INT_EUSCIB0,
            .intPriority = ~0,
            .slaveAddress = 0x48,
            .dataPin = I2CSLAVEMSP432_P1_6_UCB0SDA,
            .clkPin = I2CSLAVEMSP432_P1_7_UCB0SCL
        }
    };
    
    const I2CSlave_Config I2CSlave_config[MSP_EXP432P401R_I2CSLAVECOUNT] = {
        {
            .fxnTablePtr = &I2CSlaveMSP432_fxnTable,
            .object = &i2cSlaveMSP432Objects[MSP_EXP432P401R_I2CSLAVEB0],
            .hwAttrs = &i2cSlaveMSP432HWAttrs[MSP_EXP432P401R_I2CSLAVEB0]
        }
    };
    
    const uint_least8_t I2CSlave_count = MSP_EXP432P401R_I2CSLAVECOUNT;
    
    /*
     *  =============================== NVS ===============================
     */
    #include <ti/drivers/NVS.h>
    #include <ti/drivers/nvs/NVSMSP432.h>
    
    #define SECTORSIZE       0x1000
    #define NVS_REGIONS_BASE 0x30000
    #define REGIONSIZE       (SECTORSIZE * 16)
    
    /*
     * Reserve flash sectors for NVS driver use
     * by placing an uninitialized byte array
     * at the desired flash address.
     */
    #if defined(__TI_COMPILER_VERSION__)
    
    /*
     * Place uninitialized array at NVS_REGIONS_BASE
     */
    #pragma LOCATION(flashBuf, NVS_REGIONS_BASE);
    #pragma NOINIT(flashBuf);
    static char flashBuf[REGIONSIZE];
    
    #elif defined(__IAR_SYSTEMS_ICC__)
    
    /*
     * Place uninitialized array at NVS_REGIONS_BASE
     */
    static __no_init char flashBuf[REGIONSIZE] @ NVS_REGIONS_BASE;
    
    #elif defined(__GNUC__)
    
    /*
     * Place the flash buffers in the .nvs section created in the gcc linker file.
     * The .nvs section enforces alignment on a sector boundary but may
     * be placed anywhere in flash memory.  If desired the .nvs section can be set
     * to a fixed address by changing the following in the gcc linker file:
     *
     * .nvs (FIXED_FLASH_ADDR) (NOLOAD) : AT (FIXED_FLASH_ADDR) {
     *      *(.nvs)
     * } > REGION_TEXT
     */
    __attribute__ ((section (".nvs")))
    static char flashBuf[REGIONSIZE];
    
    #endif
    
    NVSMSP432_Object nvsMSP432Objects[MSP_EXP432P401R_NVSCOUNT];
    
    const NVSMSP432_HWAttrs nvsMSP432HWAttrs[MSP_EXP432P401R_NVSCOUNT] = {
        {
            .regionBase = (void *) flashBuf,
            .regionSize = REGIONSIZE,
        },
    };
    
    const NVS_Config NVS_config[MSP_EXP432P401R_NVSCOUNT] = {
        {
            .fxnTablePtr = &NVSMSP432_fxnTable,
            .object = &nvsMSP432Objects[MSP_EXP432P401R_NVSMSP4320],
            .hwAttrs = &nvsMSP432HWAttrs[MSP_EXP432P401R_NVSMSP4320],
        },
    };
    
    const uint_least8_t NVS_count = MSP_EXP432P401R_NVSCOUNT;
    
    /*
     *  =============================== Power ===============================
     */
    const PowerMSP432_ConfigV1 PowerMSP432_config = {
        .policyInitFxn = &PowerMSP432_initPolicy,
        .policyFxn = &PowerMSP432_sleepPolicy,
        .initialPerfLevel = 2,
        .enablePolicy = true,
        .enablePerf = true,
        .enableParking = false
    };
    
    /*
     *  =============================== PWM ===============================
     */
    #include <ti/drivers/PWM.h>
    #include <ti/drivers/pwm/PWMTimerMSP432.h>
    
    PWMTimerMSP432_Object pwmTimerMSP432Objects[MSP_EXP432P401R_PWMCOUNT];
    
    const PWMTimerMSP432_HWAttrsV2 pwmTimerMSP432HWAttrs[MSP_EXP432P401R_PWMCOUNT] = {
        {
            .clockSource = TIMER_A_CLOCKSOURCE_SMCLK,
            .pwmPin = PWMTimerMSP432_P2_1_TA1CCR1A
        },
        {
            .clockSource = TIMER_A_CLOCKSOURCE_SMCLK,
            .pwmPin = PWMTimerMSP432_P2_2_TA1CCR2A
        }
    };
    
    const PWM_Config PWM_config[MSP_EXP432P401R_PWMCOUNT] = {
        {
            .fxnTablePtr = &PWMTimerMSP432_fxnTable,
            .object = &pwmTimerMSP432Objects[MSP_EXP432P401R_PWM_TA1_1],
            .hwAttrs = &pwmTimerMSP432HWAttrs[MSP_EXP432P401R_PWM_TA1_1]
        },
        {
            .fxnTablePtr = &PWMTimerMSP432_fxnTable,
            .object = &pwmTimerMSP432Objects[MSP_EXP432P401R_PWM_TA1_2],
            .hwAttrs = &pwmTimerMSP432HWAttrs[MSP_EXP432P401R_PWM_TA1_2]
        }
    };
    
    const uint_least8_t PWM_count = MSP_EXP432P401R_PWMCOUNT;
    
    /*
     *  =============================== SDFatFS ===============================
     */
    #include <ti/drivers/SD.h>
    #include <ti/drivers/SDFatFS.h>
    
    /*
     * Note: The SDFatFS driver provides interface functions to enable FatFs
     * but relies on the SD driver to communicate with SD cards.  Opening a
     * SDFatFs driver instance will internally try to open a SD driver instance
     * reusing the same index number (opening SDFatFs driver at index 0 will try to
     * open SD driver at index 0).  This requires that all SDFatFs driver instances
     * have an accompanying SD driver instance defined with the same index.  It is
     * acceptable to have more SD driver instances than SDFatFs driver instances
     * but the opposite is not supported & the SDFatFs will fail to open.
     */
    SDFatFS_Object sdfatfsObjects[MSP_EXP432P401R_SDFatFSCOUNT];
    
    const SDFatFS_Config SDFatFS_config[MSP_EXP432P401R_SDFatFSCOUNT] = {
        {
            .object = &sdfatfsObjects[MSP_EXP432P401R_SDFatFS0]
        }
    };
    
    const uint_least8_t SDFatFS_count = MSP_EXP432P401R_SDFatFSCOUNT;
    
    /*
     *  =============================== SD ===============================
     */
    #include <ti/drivers/SD.h>
    #include <ti/drivers/sd/SDSPI.h>
    
    SDSPI_Object sdspiObjects[MSP_EXP432P401R_SDCOUNT];
    
    const SDSPI_HWAttrs sdspiHWAttrs[MSP_EXP432P401R_SDCOUNT] = {
        {
            .spiIndex = MSP_EXP432P401R_SPIB0,
            .spiCsGpioIndex = MSP_EXP432P401R_SDSPI_CS
        }
    };
    
    const SD_Config SD_config[MSP_EXP432P401R_SDCOUNT] = {
        {
            .fxnTablePtr = &SDSPI_fxnTable,
            .object = &sdspiObjects[MSP_EXP432P401R_SDSPI0],
            .hwAttrs = &sdspiHWAttrs[MSP_EXP432P401R_SDSPI0]
        },
    };
    
    const uint_least8_t SD_count = MSP_EXP432P401R_SDCOUNT;
    
    /*
     *  =============================== SPI ===============================
     */
    #include <ti/drivers/SPI.h>
    #include <ti/drivers/spi/SPIMSP432DMA.h>
    
    SPIMSP432DMA_Object spiMSP432DMAObjects[MSP_EXP432P401R_SPICOUNT];
    
    /*
     * NOTE: The SPI instances below can be used by the SD driver to communicate
     * with a SD card via SPI.  The 'defaultTxBufValue' fields below are set to 0xFF
     * to satisfy the SDSPI driver requirement.
     */
    const SPIMSP432DMA_HWAttrsV1 spiMSP432DMAHWAttrs[MSP_EXP432P401R_SPICOUNT] = {
        {
            .baseAddr = EUSCI_B0_BASE,
            .bitOrder = EUSCI_B_SPI_MSB_FIRST,
            .clockSource = EUSCI_B_SPI_CLOCKSOURCE_SMCLK,
            .defaultTxBufValue = 0xFF,
            .dmaIntNum = INT_DMA_INT1,
            .intPriority = (~0),
            .rxDMAChannelIndex = DMA_CH1_EUSCIB0RX0,
            .txDMAChannelIndex = DMA_CH0_EUSCIB0TX0,
            .clkPin  = SPIMSP432DMA_P1_5_UCB0CLK,
            .simoPin = SPIMSP432DMA_P1_6_UCB0SIMO,
            .somiPin = SPIMSP432DMA_P1_7_UCB0SOMI,
            .stePin  = SPIMSP432DMA_P1_4_UCB0STE,
            .pinMode  = EUSCI_SPI_3PIN,
            .minDmaTransferSize = 10
        },
        {
            .baseAddr = EUSCI_B2_BASE,
            .bitOrder = EUSCI_B_SPI_MSB_FIRST,
            .clockSource = EUSCI_B_SPI_CLOCKSOURCE_SMCLK,
            .defaultTxBufValue = 0xFF,
            .dmaIntNum = INT_DMA_INT2,
            .intPriority = (~0),
            .rxDMAChannelIndex = DMA_CH5_EUSCIB2RX0,
            .txDMAChannelIndex = DMA_CH4_EUSCIB2TX0,
            .clkPin  = SPIMSP432DMA_P3_5_UCB2CLK,
            .simoPin = SPIMSP432DMA_P3_6_UCB2SIMO,
            .somiPin = SPIMSP432DMA_P3_7_UCB2SOMI,
            .stePin  = SPIMSP432DMA_P3_4_UCB2STE,
            .pinMode  = EUSCI_SPI_3PIN,
            .minDmaTransferSize = 10
        },
        {
            .baseAddr = EUSCI_A1_BASE,
            .bitOrder = EUSCI_A_SPI_MSB_FIRST,
            .clockSource = EUSCI_A_SPI_CLOCKSOURCE_SMCLK,
            .defaultTxBufValue = 0xFF,
            .dmaIntNum = INT_DMA_INT2,
            .intPriority = (~0),
            .rxDMAChannelIndex = DMA_CH3_EUSCIA1RX,
            .txDMAChannelIndex = DMA_CH2_EUSCIA1TX,
            .clkPin  = SPIMSP432DMA_P2_5_UCA1CLK,
            .simoPin = SPIMSP432DMA_P2_6_UCA1SIMO,
            .somiPin = SPIMSP432DMA_P2_7_UCA1SOMI,
            .stePin  = SPIMSP432DMA_P2_3_UCA1STE,
            .pinMode  = EUSCI_SPI_4PIN_UCxSTE_ACTIVE_LOW,
            .minDmaTransferSize = 10
        },
        {
            .baseAddr = EUSCI_B2_BASE,
            .bitOrder = EUSCI_B_SPI_MSB_FIRST,
            .clockSource = EUSCI_B_SPI_CLOCKSOURCE_SMCLK,
            .defaultTxBufValue = 0xFF,
            .dmaIntNum = INT_DMA_INT3,
            .intPriority = (~0),
            .rxDMAChannelIndex = DMA_CH5_EUSCIB2RX0,
            .txDMAChannelIndex = DMA_CH4_EUSCIB2TX0,
            .clkPin  = SPIMSP432DMA_P3_5_UCB2CLK,
            .simoPin = SPIMSP432DMA_P3_6_UCB2SIMO,
            .somiPin = SPIMSP432DMA_P3_7_UCB2SOMI,
            .stePin  = SPIMSP432DMA_P2_4_UCB2STE,
            .pinMode  = EUSCI_SPI_4PIN_UCxSTE_ACTIVE_LOW,
            .minDmaTransferSize = 10
        }
    };
    
    const SPI_Config SPI_config[MSP_EXP432P401R_SPICOUNT] = {
        {
            .fxnTablePtr = &SPIMSP432DMA_fxnTable,
            .object = &spiMSP432DMAObjects[MSP_EXP432P401R_SPIB0],
            .hwAttrs = &spiMSP432DMAHWAttrs[MSP_EXP432P401R_SPIB0]
        },
        {
            .fxnTablePtr = &SPIMSP432DMA_fxnTable,
            .object = &spiMSP432DMAObjects[MSP_EXP432P401R_SPIB2],
            .hwAttrs = &spiMSP432DMAHWAttrs[MSP_EXP432P401R_SPIB2]
        },
        {
            .fxnTablePtr = &SPIMSP432DMA_fxnTable,
            .object = &spiMSP432DMAObjects[MSP_EXP432P401R_SPIB3],
            .hwAttrs = &spiMSP432DMAHWAttrs[MSP_EXP432P401R_SPIB3]
        },
        {
            .fxnTablePtr = &SPIMSP432DMA_fxnTable,
            .object = &spiMSP432DMAObjects[MSP_EXP432P401R_SPIB4],
            .hwAttrs = &spiMSP432DMAHWAttrs[MSP_EXP432P401R_SPIB4]
        }
    };
    
    const uint_least8_t SPI_count = MSP_EXP432P401R_SPICOUNT;
    
    /*
     *  =============================== Timer ===============================
     */
    #include <ti/drivers/Timer.h>
    #include <ti/drivers/timer/TimerMSP432.h>
    
    TimerMSP432_Object timerMSP432Objects[MSP_EXP432P401R_TIMERCOUNT];
    
    const TimerMSP432_HWAttrs timerMSP432HWAttrs[MSP_EXP432P401R_TIMERCOUNT] = {
        /* Timer32_0 */
        {
            .timerBaseAddress = TIMER32_0_BASE,
            .clockSource = TIMER_A_CLOCKSOURCE_SMCLK,
            .intNum = INT_T32_INT1,
            .intPriority = ~0
        },
        {
            .timerBaseAddress = TIMER32_1_BASE,
            .clockSource = TIMER_A_CLOCKSOURCE_SMCLK,
            .intNum = INT_T32_INT2,
            .intPriority = ~0
        },
        /* Timer_A1 */
        {
            .timerBaseAddress = TIMER_A1_BASE,
            .clockSource = TIMER_A_CLOCKSOURCE_ACLK,
            .intNum = INT_TA1_0,
            .intPriority = ~0
        },
        /* Timer_A2 */
        {
            .timerBaseAddress = TIMER_A2_BASE,
            .clockSource = TIMER_A_CLOCKSOURCE_ACLK,
            .intNum = INT_TA2_0,
            .intPriority = ~0
        },
        /* Timer_A3 */
        {
            .timerBaseAddress = TIMER_A3_BASE,
            .clockSource = TIMER_A_CLOCKSOURCE_ACLK,
            .intNum = INT_TA3_0,
            .intPriority = ~0
        }
    };
    
    const Timer_Config Timer_config[MSP_EXP432P401R_TIMERCOUNT] = {
        {
            .fxnTablePtr = &TimerMSP432_Timer32_fxnTable,
            .object = &timerMSP432Objects[MSP_EXP432P401R_TIMER_T32_0],
            .hwAttrs = &timerMSP432HWAttrs[MSP_EXP432P401R_TIMER_T32_0]
        },
        {
            .fxnTablePtr = &TimerMSP432_Timer32_fxnTable,
            .object = &timerMSP432Objects[MSP_EXP432P401R_TIMER_T32_1],
            .hwAttrs = &timerMSP432HWAttrs[MSP_EXP432P401R_TIMER_T32_1]
        },
        {
            .fxnTablePtr = &TimerMSP432_Timer_A_fxnTable,
            .object = &timerMSP432Objects[MSP_EXP432P401R_TIMER_TA_1],
            .hwAttrs = &timerMSP432HWAttrs[MSP_EXP432P401R_TIMER_TA_1]
        },
        {
            .fxnTablePtr = &TimerMSP432_Timer_A_fxnTable,
            .object = &timerMSP432Objects[MSP_EXP432P401R_TIMER_TA_2],
            .hwAttrs = &timerMSP432HWAttrs[MSP_EXP432P401R_TIMER_TA_2]
        },
        {
            .fxnTablePtr = &TimerMSP432_Timer_A_fxnTable,
            .object = &timerMSP432Objects[MSP_EXP432P401R_TIMER_TA_3],
            .hwAttrs = &timerMSP432HWAttrs[MSP_EXP432P401R_TIMER_TA_3]
        }
    };
    
    const uint_least8_t Timer_count = MSP_EXP432P401R_TIMERCOUNT;
    
    /*
     *  =============================== UART ===============================
     */
    #include <ti/drivers/UART.h>
    #include <ti/drivers/uart/UARTMSP432.h>
    
    UARTMSP432_Object uartMSP432Objects[MSP_EXP432P401R_UARTCOUNT];
    unsigned char uartMSP432RingBuffer[MSP_EXP432P401R_UARTCOUNT][32];
    
    /*
     * The baudrate dividers were determined by using the MSP432 baudrate
     * calculator
     * http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/MSP430BaudRateConverter/index.html
     */
    const UARTMSP432_BaudrateConfig uartMSP432Baudrates[] = {
        /* {baudrate, input clock, prescalar, UCBRFx, UCBRSx, oversampling} */
        {
            .outputBaudrate = 115200,
            .inputClockFreq = 24000000,
            .prescalar = 13,
            .hwRegUCBRFx = 0,
            .hwRegUCBRSx = 37,
            .oversampling = 1
        },
        {115200, 12000000,  6,  8,  32, 1},
        {115200, 6000000,   3,  4,   2, 1},
        {115200, 3000000,   1, 10,   0, 1},
        {9600,   24000000, 156,  4,   0, 1},
        {9600,   12000000, 78,  2,   0, 1},
        {9600,   6000000,  39,  1,   0, 1},
        {9600,   3000000,  19,  8,  85, 1},
        {9600,   32768,     3,  0, 146, 0}
    };
    
    const UARTMSP432_HWAttrsV1 uartMSP432HWAttrs[MSP_EXP432P401R_UARTCOUNT] = {
        {
            .baseAddr = EUSCI_A0_BASE,
            .intNum = INT_EUSCIA0,
            .intPriority = (~0),
            .clockSource = EUSCI_A_UART_CLOCKSOURCE_SMCLK,
            .bitOrder = EUSCI_A_UART_LSB_FIRST,
            .numBaudrateEntries = sizeof(uartMSP432Baudrates) /
                sizeof(UARTMSP432_BaudrateConfig),
            .baudrateLUT = uartMSP432Baudrates,
            .ringBufPtr  = uartMSP432RingBuffer[MSP_EXP432P401R_UARTA0],
            .ringBufSize = sizeof(uartMSP432RingBuffer[MSP_EXP432P401R_UARTA0]),
            .rxPin = UARTMSP432_P1_2_UCA0RXD,
            .txPin = UARTMSP432_P1_3_UCA0TXD,
            .errorFxn = NULL
        },
        {
            .baseAddr = EUSCI_A2_BASE,
            .intNum = INT_EUSCIA2,
            .intPriority = (~0),
            .clockSource = EUSCI_A_UART_CLOCKSOURCE_SMCLK,
            .bitOrder = EUSCI_A_UART_LSB_FIRST,
            .numBaudrateEntries = sizeof(uartMSP432Baudrates) /
                sizeof(UARTMSP432_BaudrateConfig),
            .baudrateLUT = uartMSP432Baudrates,
            .ringBufPtr  = uartMSP432RingBuffer[MSP_EXP432P401R_UARTA2],
            .ringBufSize = sizeof(uartMSP432RingBuffer[MSP_EXP432P401R_UARTA2]),
            .rxPin = UARTMSP432_P3_2_UCA2RXD,
            .txPin = UARTMSP432_P3_3_UCA2TXD,
            .errorFxn = NULL
        }
    };
    
    const UART_Config UART_config[MSP_EXP432P401R_UARTCOUNT] = {
        {
            .fxnTablePtr = &UARTMSP432_fxnTable,
            .object = &uartMSP432Objects[MSP_EXP432P401R_UARTA0],
            .hwAttrs = &uartMSP432HWAttrs[MSP_EXP432P401R_UARTA0]
        },
        {
            .fxnTablePtr = &UARTMSP432_fxnTable,
            .object = &uartMSP432Objects[MSP_EXP432P401R_UARTA2],
            .hwAttrs = &uartMSP432HWAttrs[MSP_EXP432P401R_UARTA2]
        }
    };
    
    const uint_least8_t UART_count = MSP_EXP432P401R_UARTCOUNT;
    
    /*
     *  =============================== Watchdog ===============================
     */
    #include <ti/drivers/Watchdog.h>
    #include <ti/drivers/watchdog/WatchdogMSP432.h>
    
    WatchdogMSP432_Object watchdogMSP432Objects[MSP_EXP432P401R_WATCHDOGCOUNT];
    
    const WatchdogMSP432_HWAttrs
        watchdogMSP432HWAttrs[MSP_EXP432P401R_WATCHDOGCOUNT] = {
        {
            .baseAddr = WDT_A_BASE,
            .intNum = INT_WDT_A,
            .intPriority = (~0),
            .clockSource = WDT_A_CLOCKSOURCE_SMCLK,
            .clockDivider = WDT_A_CLOCKDIVIDER_8192K
        }
    };
    
    const Watchdog_Config Watchdog_config[MSP_EXP432P401R_WATCHDOGCOUNT] = {
        {
            .fxnTablePtr = &WatchdogMSP432_fxnTable,
            .object = &watchdogMSP432Objects[MSP_EXP432P401R_WATCHDOG],
            .hwAttrs = &watchdogMSP432HWAttrs[MSP_EXP432P401R_WATCHDOG]
        }
    };
    
    const uint_least8_t Watchdog_count = MSP_EXP432P401R_WATCHDOGCOUNT;
    

  • Hi Amit,

    thank you for this feedback. But i believe you have not tried with the FatFs library and the functions that you have tried are C file library.

    My firmware has to use the FatFs library and that is what creating the issues.

    I had also posted this earlier.

    Not sure whether this is related to the SDK version that you mentioned in your another post.

    Vikram

  • Hello Vikram,

    It uses the Fat FS drivers internally. The FatFS are wrapped in the SDFatFS to make them POSIX compliant.
  • it looks different since in the FatFs approach we have functions such as f_open, f_write and so on whereas the one that you have sent is fopen, fclose and fwrite.
    Also the library used is console library i.e. ffcio.h whereas i have to use the ff.h library
  • Hello Vikram

    If you look at the change log for the latest SDK, it has a history of changes. Somewhere around 1.60 release the change was made.

    If you have the latest SDK, you can at least evaluate the project to see if it is getting you the functionality with the correct power numbers.
  • ok i will install the latest SDK Version 2.10 and CCSv8 and let you know
  • Hello Vikram,

    Please note that my system is not the same as yours, as I am using a Launchpad booster pack header SPI pins and an SD Card board which may be different from your setup in terms of SPI pins connectivity.
  • Hi Amit,

    I tried to install the new CCSv8 and SDK version 2.10.

    But it gives compilation error as below:

    Building file: "../fatsdraw.c"
    Invoking: ARM Compiler
    "C:/ti/ccsv8/tools/compiler/ti-cgt-arm_18.1.1.LTS/bin/armcl" -mv7M4 --code_state=16 --float_support=FPv4SPD16 -me --include_path="C:/Users/vtrivedi/workspace_v8/fatsdraw_MSP_EXP432P401R_tirtos_ccs" --include_path="C:/ti/simplelink_msp432p4_sdk_2_10_00_14/source/third_party/CMSIS/Include" --include_path="C:/ti/simplelink_msp432p4_sdk_2_10_00_14/source/ti/posix/ccs" --include_path="C:/ti/ccsv8/tools/compiler/ti-cgt-arm_18.1.1.LTS/include" --advice:power=none -g --diag_warning=225 --diag_warning=255 --diag_wrap=off --display_error_number --gen_func_subsections=on --preproc_with_compile --preproc_dependency="fatsdraw.d_raw" --cmd_file="C:/Users/vtrivedi/workspace_v8/tirtos_builds_MSP_EXP432P401R_release_ccs/Debug/configPkg/compiler.opt" "../fatsdraw.c"

    >> Compilation failure
    subdir_rules.mk:16: recipe for target 'fatsdraw.obj' failed
    "C:/ti/simplelink_msp432p4_sdk_2_10_00_14/source/ti/devices/msp432p4xx/inc/msp.h", line 76: fatal error #35: #error directive: "Failed to match a default include file"
    1 catastrophic error detected in the compilation of "../fatsdraw.c".
    Compilation terminated.
    gmake: *** [fatsdraw.obj] Error 1
    Building file: "../main_tirtos.c"
    Invoking: ARM Compiler
    "C:/ti/ccsv8/tools/compiler/ti-cgt-arm_18.1.1.LTS/bin/armcl" -mv7M4 --code_state=16 --float_support=FPv4SPD16 -me --include_path="C:/Users/vtrivedi/workspace_v8/fatsdraw_MSP_EXP432P401R_tirtos_ccs" --include_path="C:/ti/simplelink_msp432p4_sdk_2_10_00_14/source/third_party/CMSIS/Include" --include_path="C:/ti/simplelink_msp432p4_sdk_2_10_00_14/source/ti/posix/ccs" --include_path="C:/ti/ccsv8/tools/compiler/ti-cgt-arm_18.1.1.LTS/include" --advice:power=none -g --diag_warning=225 --diag_warning=255 --diag_wrap=off --display_error_number --gen_func_subsections=on --preproc_with_compile --preproc_dependency="main_tirtos.d_raw" --cmd_file="C:/Users/vtrivedi/workspace_v8/tirtos_builds_MSP_EXP432P401R_release_ccs/Debug/configPkg/compiler.opt" "../main_tirtos.c"

    >> Compilation failure
    subdir_rules.mk:23: recipe for target 'main_tirtos.obj' failed
    "C:/ti/simplelink_msp432p4_sdk_2_10_00_14/source/ti/devices/DeviceFamily.h", line 186: fatal error #35: #error directive: "DeviceFamily_XYZ undefined. You must defined DeviceFamily_XYZ!"
    1 catastrophic error detected in the compilation of "../main_tirtos.c".
    Compilation terminated.
    gmake: *** [main_tirtos.obj] Error 1
    Building file: "../probe.c"
    Invoking: ARM Compiler
    "C:/ti/ccsv8/tools/compiler/ti-cgt-arm_18.1.1.LTS/bin/armcl" -mv7M4 --code_state=16 --float_support=FPv4SPD16 -me --include_path="C:/Users/vtrivedi/workspace_v8/fatsdraw_MSP_EXP432P401R_tirtos_ccs" --include_path="C:/ti/simplelink_msp432p4_sdk_2_10_00_14/source/third_party/CMSIS/Include" --include_path="C:/ti/simplelink_msp432p4_sdk_2_10_00_14/source/ti/posix/ccs" --include_path="C:/ti/ccsv8/tools/compiler/ti-cgt-arm_18.1.1.LTS/include" --advice:power=none -g --diag_warning=225 --diag_warning=255 --diag_wrap=off --display_error_number --gen_func_subsections=on --preproc_with_compile --preproc_dependency="probe.d_raw" --cmd_file="C:/Users/vtrivedi/workspace_v8/tirtos_builds_MSP_EXP432P401R_release_ccs/Debug/configPkg/compiler.opt" "../probe.c"

    >> Compilation failure
    subdir_rules.mk:30: recipe for target 'probe.obj' failed
    "C:/ti/simplelink_msp432p4_sdk_2_10_00_14/source/ti/devices/DeviceFamily.h", line 186: fatal error #35: #error directive: "DeviceFamily_XYZ undefined. You must defined DeviceFamily_XYZ!"
    1 catastrophic error detected in the compilation of "../probe.c".
    Compilation terminated.
    gmake: *** [probe.obj] Error 1
    Building file: "../MSP_EXP432P401R.c"
    Invoking: ARM Compiler
    "C:/ti/ccsv8/tools/compiler/ti-cgt-arm_18.1.1.LTS/bin/armcl" -mv7M4 --code_state=16 --float_support=FPv4SPD16 -me --include_path="C:/Users/vtrivedi/workspace_v8/fatsdraw_MSP_EXP432P401R_tirtos_ccs" --include_path="C:/ti/simplelink_msp432p4_sdk_2_10_00_14/source/third_party/CMSIS/Include" --include_path="C:/ti/simplelink_msp432p4_sdk_2_10_00_14/source/ti/posix/ccs" --include_path="C:/ti/ccsv8/tools/compiler/ti-cgt-arm_18.1.1.LTS/include" --advice:power=none -g --diag_warning=225 --diag_warning=255 --diag_wrap=off --display_error_number --gen_func_subsections=on --preproc_with_compile --preproc_dependency="MSP_EXP432P401R.d_raw" --cmd_file="C:/Users/vtrivedi/workspace_v8/tirtos_builds_MSP_EXP432P401R_release_ccs/Debug/configPkg/compiler.opt" "../MSP_EXP432P401R.c"
    Finished building: "../MSP_EXP432P401R.c"

    gmake: Target 'all' not remade because of errors.

    **** Build Finished ****

    See the image above.

    Vikram

  • Hello Vikram,

    Please add the following options in pre-define for the Project Build Settings

    DeviceFamily_MSP432P401x
    __MSP432P401R__
  • Do you mean both lines or just DeviceFamily_MSP432P401x?

    Or
    DeviceFamily_MSP432P401x
    __MSP432P401R__
  • Hello Vikram,

    Both, one per line.
  • Ok now the firmware has built without errors i will execute and let you know
  • Sorry accidently i clicked the issue the issue only got resolved for the debug errors not for the sleep mode
  • The issue with the firmware option that you gave is that when the unit wakes up after sleep mode and the the functions tries to open a new file to write it fails stating FR_DSK_ERR

**Attention** This is a public forum