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.

CCS/CC2640R2F: CC2640R2 can't print out of my external flash memory

Part Number: CC2640R2F

Tool/software: Code Composer Studio

Hi TI expert

I used MPS432P401R as a MCU,and use CC2640R2 to print out my external sensor value.

All my sensors are normal,but the external flash memory can't be printed out by CC2640R2,

attachments are my flash.c and flash.h and the data sheet of these flash.

My sequence is used senserbooster.c to execute open_flash then execute outputflashdata.

I used enqueue function to connect with CC2640R2 in the outputflashdata of flash.c

I have also used printf to debug all the function of flash.c

and found all function worked normal except the strtohex function and outputflashdata function, the value from these two function were weird.

I have no idea which steps is wrong!

Could you help to analyze for it.

Appreciate for your help!

Best regards,

Brian Chen

/* --COPYRIGHT--,BSD
 * Copyright (c) 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.
 * --/COPYRIGHT--*/
/*******************************************************************************
 *                              INCLUDES
 ******************************************************************************/
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <pthread.h>
#include <mqueue.h>
#include <semaphore.h>
#include <time.h>
#include <unistd.h>
#include <ti/display/Display.h>
#include <ti/drivers/dpl/HwiP.h>
#include <ti/drivers/GPIO.h>
#include <ti/drivers/UART.h>
#include <ti/drivers/Timer.h>
#include <ti/devices/msp432p4xx/driverlib/driverlib.h>
#include <ti/sap/sap.h>
#include <ti/sbl/sbl.h>
#include <ti/sbl/sbl_image.h>

#include <Profile/baseball3xs_service.h>
#include <Profile/baseball6xs_service.h>
#include <Profile/profile_util.h>
#include "flashctrl.h"
#include "sensor_boosterpack_A301.h"
#include "sensor_boosterpack_bhi160.h"
#include "sensor_boosterpack_bmp280.h"
#include "sensor_boosterpack_bma253.h"
#include "sensor_boosterpack_icm20649.h"
#include "sensor_boosterpack.h"
#include "sensor_configuration.h"
#include "Board.h"
#include "platform.h"

/*******************************************************************************
 *                             VARIABLES
 ******************************************************************************/
/* Used to block SNP calls during a synchronous transaction. */
static mqd_t sensQueueRec;
static mqd_t sensQueueSend;

/* Clock instances for internal periodic events. */
static Timer_Handle timer0;

/* Task configuration */
static pthread_t sensTask;

/* SAP Parameters for opening serial port to SNP */
static SAP_Params sapParams;

/* Device Name */
static uint8_t snpDeviceName[] =
        { 'I', '_', 'B', 'a', 's', 'e', 'b', 'a', 'l', 'l' };

/* GAP - SCAN RSP data (max size = 31 bytes) */
static uint8_t scanRspData[] =
{
    /* Complete name */
    0x0a, /* Length */
    SAP_GAP_ADTYPE_LOCAL_NAME_COMPLETE, 'I', '_', 'B', 'a', 's', 'e', 'b', 'a', 'l', 'l',

    /* Connection interval range */
    0x05, /* Length */
    0x12,
    LO_UINT16(DEFAULT_DESIRED_MIN_CONN_INTERVAL),
    HI_UINT16(DEFAULT_DESIRED_MIN_CONN_INTERVAL),
    LO_UINT16(DEFAULT_DESIRED_MAX_CONN_INTERVAL),
    HI_UINT16(DEFAULT_DESIRED_MAX_CONN_INTERVAL),

    /* TX power level */
    0x02, /* Length */
    0x0A,
    0
};

/* GAP - Advertisement data (max size = 31 bytes, though this is
   best kept short to conserve power while advertising) */
static uint8_t advertData[] =
{
    /* Flags; this sets the device to use limited discoverable
       mode (advertises for 30 seconds at a time) instead of general
       discoverable mode (advertises indefinitely) */
    0x02, /* Length */
    SAP_GAP_ADTYPE_FLAGS,
    DEFAULT_DISCOVERABLE_MODE | SAP_GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,

    /* Manufacturer specific advertising data */
    0x06, 0xFF,
    LO_UINT16(TI_COMPANY_ID),
    HI_UINT16(TI_COMPANY_ID),
    TI_ST_DEVICE_ID,
    TI_ST_KEY_DATA_ID, 0x00
};

/* Connection Handle - only one device currently allowed to connect to SNP */
static uint16_t connHandle = AP_DEFAULT_CONN_HANDLE;

/* BD Addr of the NWP */
static char nwpstr[] = "NWP:  0xFFFFFFFFFFFF";
#define nwpstrIDX       8

// BD Addr of peer device in connection
static char peerstr[] = "Peer: 0xFFFFFFFFFFFF";
#define peerstrIDX       8

/* Used for log messages */
extern Display_Handle displayOut;

/* Used for exiting threads */
extern pthread_t bmp280Task;
extern pthread_t bma253Task;
extern pthread_t bhi160Task;
extern pthread_t icm20649Task;

/* Sensor Parameters */

static uint8_t Baseball6xsConfig;
volatile bool Baseball6xs = false;
static uint8_t Baseball3xsConfig;
volatile bool Baseball3xs = false;

volatile bool store_en = false;

/*******************************************************************************
 *                            FUNCTION PROTOTYPES
 ******************************************************************************/
static void AP_init(void);
static void *AP_taskFxn(void *arg0);
static void AP_initServices(void);
static void AP_keyHandler(void);
static void AP_bslKeyHandler(void);
static void AP_asyncCB(uint8_t cmd1, void *pParams);
static void AP_processSNPEventCB(uint16_t event, snpEventParam_t *param);
static void AP_timerHandler(Timer_Handle handle);

static void AP_processBaseball6xsChangeCB(uint8_t charID);
static void AP_processBaseball6xscccdCB(uint8_t charID, uint16_t value);
static void Baseball6xs_processCharChangeEvt(uint8_t paramID);
static void initBaseball6xsCharacteristicValue(uint8_t paramID, uint8_t value, uint8_t paramLen);

static void AP_processBaseball3xsChangeCB(uint8_t charID);
static void AP_processBaseball3xscccdCB(uint8_t charID, uint16_t value);
static void Baseball3xs_processCharChangeEvt(uint8_t paramID);
static void initBaseball3xsCharacteristicValue(uint8_t paramID, uint8_t value, uint8_t paramLen);

static void ALL_Sensor_Disable(void);
/*******************************************************************************
 *                                 PROFILE CALLBACKS
 ******************************************************************************/
/*
 * Characteristic value change callback
 */
static BLEProfileCallbacks_t AP_Baseball6xsSensorCBs =
{
    AP_processBaseball6xsChangeCB,
    AP_processBaseball6xscccdCB
};
static BLEProfileCallbacks_t AP_Baseball3xsSensorCBs =
{
    AP_processBaseball3xsChangeCB,
    AP_processBaseball3xscccdCB
};
/*******************************************************************************
 *                                 PUBLIC FUNCTIONS
 ******************************************************************************/
/*******************************************************************************
 * @fn      AP_createTask
 *
 * @brief   Task creation function for the Simple BLE Peripheral.
 *
 * @param   None.
 *
 * @return  None.
 ******************************************************************************/
void AP_createTask(void)
{
    pthread_attr_t pAttrs;
    struct sched_param priParam;
    int retc;
    int detachState;

    pthread_attr_init(&pAttrs);
    priParam.sched_priority = AP_TASK_PRIORITY;

    detachState = PTHREAD_CREATE_DETACHED;
    retc = pthread_attr_setdetachstate(&pAttrs, detachState);

    if (retc != 0)
    {
        while(1);
    }

    pthread_attr_setschedparam(&pAttrs, &priParam);

    retc |= pthread_attr_setstacksize(&pAttrs, AP_TASK_STACK_SIZE);

    if (retc != 0)
    {
        while(1);
    }

    retc = pthread_create(&sensTask, &pAttrs, AP_taskFxn, NULL);

    if (retc != 0)
    {
        while(1);
    }
}

/*******************************************************************************
 * @fn      AP_init
 *
 * @brief   Called during initialization and contains application
 *          specific initialization (ie. hardware initialization/setup,
 *          table initialization, power up notification, etc), and
 *          profile initialization/setup.
 *
 * @param   None.
 *
 * @return  None.
 ******************************************************************************/
static void AP_init(void)
{
    Timer_Params params;
    struct mq_attr attr;

    /* Create RTOS Queue */
    attr.mq_flags = 0;
    attr.mq_maxmsg = 64;
    attr.mq_msgsize = sizeof(uint32_t);
    attr.mq_curmsgs = 0;

    sensQueueRec = mq_open("SensorHub", O_RDWR | O_CREAT, 0664, &attr);
    sensQueueSend = mq_open("SensorHub", O_RDWR | O_CREAT | O_NONBLOCK, 0664, &attr);

    // Register to receive notifications from temperature if characteristics have been written to
    Baseball6xs_registerAppCBs(&AP_Baseball6xsSensorCBs);
    Baseball3xs_registerAppCBs(&AP_Baseball3xsSensorCBs);

    // Initialize characteristics and sensor driver
    Baseball6xsConfig = SENSORBSP_CFG_SENSOR_DISABLE;
    initBaseball6xsCharacteristicValue(BASEBALL6xs_DATA, 0, BASEBALL6xs_DATA_LEN);
    initBaseball6xsCharacteristicValue(BASEBALL6xs_CONF, SENSORBSP_CFG_SENSOR_DISABLE, sizeof(uint8_t));

    Baseball3xsConfig = SENSORBSP_CFG_SENSOR_DISABLE;
    initBaseball3xsCharacteristicValue(BASEBALL3xs_DATA, 0, BASEBALL3xs_DATA_LEN);
    initBaseball3xsCharacteristicValue(BASEBALL3xs_CONF, SENSORBSP_CFG_SENSOR_DISABLE, sizeof(uint8_t));

    /* Setting up the timer in continuous callback mode that calls the callback
     * functions every 5s.
     */
    Timer_Params_init(&params);
    params.period = AP_PERIODIC_EVT_PERIOD;
    params.periodUnits = TIMER_PERIOD_US;
    params.timerMode = TIMER_CONTINUOUS_CB;
    params.timerCallback = AP_timerHandler;

    timer0 = Timer_open(Board_Timer0, &params);
    if (timer0 == NULL)
    {
        Display_print0(displayOut, 0, 0, "Failed to initialized Timer!\n");
    }

    /* Initialize clock of Flashctrl */
    clock_init();

    /* Register Key Handler */
    GPIO_setCallback(Board_BUTTON0, (GPIO_CallbackFxn) AP_keyHandler);
    GPIO_enableInt (Board_BUTTON0);
    GPIO_setCallback(Board_BUTTON1, (GPIO_CallbackFxn) AP_bslKeyHandler);
    GPIO_enableInt (Board_BUTTON1);


    /* Write to the UART. */
    Display_print0(displayOut,0,0,
            "--------- Sensor Booster Pack Example ---------");
    Display_print0(displayOut,0,0,"Application Processor Initializing... ");
}

/*******************************************************************************
 * @fn      AP_taskFxn
 *
 * @brief   Application task entry point for the Simple BLE Peripheral.
 *
 * @param   a0, a1 - not used.
 *
 * @return  None.
 ******************************************************************************/
static void *AP_taskFxn(void *arg0)
{
    uint32_t apEvent = 0;
    struct timespec ts;
    ap_States_t state = AP_RESET;
    uint8_t enableAdv = 1;
    uint8_t disableAdv = 0;
    uint32_t prio = 0;
    /*
    uint8_t sblSatus;
    SBL_Params params;
    SBL_Image image;
    */

    /* Initialize application */
    AP_init();

    Display_print0(displayOut,0,0,"Done!");

    while(1)
    {
        switch (state)
        {
        case AP_RESET:
        {
            /* Make sure CC26xx is not in BSL */
            GPIO_write(Board_RESET, Board_LED_OFF);
            GPIO_write(Board_MRDY, Board_LED_ON);

            usleep(10000);

            GPIO_write(Board_RESET, Board_LED_ON);

            /* Initialize UART port parameters within SAP parameters */
            SAP_initParams(SAP_PORT_REMOTE_UART, &sapParams);

            sapParams.port.remote.mrdyPinID = Board_MRDY;
            sapParams.port.remote.srdyPinID = Board_SRDY;
            sapParams.port.remote.boardID = Board_UART1;

            /* Setup NP module */
            SAP_open(&sapParams);

            /* Register Application thread's callback to receive
             * asynchronous requests from the NP.
             */
            SAP_setAsyncCB(AP_asyncCB);

            /* Reset the NP, and await a powerup indication.
               Clear any pending power indications received prior to this reset
               call */
            clock_gettime(CLOCK_REALTIME, &ts);
            ts.tv_sec += 1;

            mq_timedreceive(sensQueueRec, (void*) &apEvent, sizeof(uint32_t), &prio,
                    &ts);

            SAP_reset();

            GPIO_clearInt(Board_BUTTON1);
            GPIO_enableInt(Board_BUTTON1);

            do
            {
                apEvent = 0;
                mq_receive(sensQueueRec, (void*) &apEvent, sizeof(uint32_t),
                           &prio);

                if (apEvent != AP_EVT_PUI)
                {
                    Display_printf(displayOut, 0, 0,
                                   "[bleThread] Warning! Unexpected Event %lu",
                                   apEvent);
                }
            }
            while (apEvent != AP_EVT_PUI);
            GPIO_disableInt(Board_BUTTON1);
/*
            if (apEvent == AP_EVT_BSL_BUTTON)
            {
                state = AP_SBL;
            }
*/
            if (apEvent == AP_EVT_PUI)
            {
                /* Read BD ADDR */
                SAP_setParam(SAP_PARAM_HCI, SNP_HCI_OPCODE_READ_BDADDR, 0,
                                NULL);

                /* Setup Services - Service creation is blocking so
                 * no need to pend */
                AP_initServices();

                state = AP_IDLE;
            }

        }
            break;

        case AP_START_ADV:
        {
            /* Turn on user LED to indicate advertising */
            GPIO_write(Board_LED0, Board_LED_ON);
            Display_print0(displayOut,0,0, "Starting advertisement... ");

            /* Setting Advertising Name */
            SAP_setServiceParam(SNP_GGS_SERV_ID, SNP_GGS_DEVICE_NAME_ATT,
                                   sizeof(snpDeviceName), snpDeviceName);

            /* Set advertising data. */
            SAP_setParam(SAP_PARAM_ADV, SAP_ADV_DATA_NOTCONN,
                    sizeof(advertData), advertData);

            /* Set Scan Response data. */
            SAP_setParam(SAP_PARAM_ADV, SAP_ADV_DATA_SCANRSP,
                    sizeof(scanRspData), scanRspData);

            /* Enable Advertising and await NP response */
            SAP_setParam(SAP_PARAM_ADV, SAP_ADV_STATE, 1, &enableAdv);
            
            do
            {
                apEvent = 0;
                mq_receive(sensQueueRec, (void*) &apEvent, sizeof(uint32_t),
                           &prio);

                if (apEvent != AP_EVT_ADV_ENB)
                {
                    Display_printf(displayOut, 0, 0,
                                   "[bleThread] Warning! Unexpected Event %lu",
                                   apEvent);
                }
            }
            while (apEvent != AP_EVT_ADV_ENB);

            Display_print0(displayOut,0,0, "Done!");
            Display_print0(displayOut,0,0,
                    "Waiting for connection (or timeout)... ");

            /* Wait for connection or button press to cancel advertisement */
            clock_gettime(CLOCK_REALTIME, &ts);
            ts.tv_sec += 60;
            apEvent = 0;
            mq_timedreceive(sensQueueRec, (void*) &apEvent, sizeof(uint32_t),
                            &prio, &ts);

            if(apEvent == AP_EVT_CONN_EST)
            {
                state = AP_CONNECTED;
            }
            else
            {
                state = AP_CANCEL_ADV;
                Display_print0(displayOut, 0, 0,"Advertisement Timeout!");
            }
        }
            break;

        case AP_CONNECTED:
            /* Before connecting, NP will send the stop ADV message */
            do
            {
                apEvent = 0;
                mq_receive(sensQueueRec, (void*) &apEvent, sizeof(uint32_t),
                           &prio);

                if (apEvent != AP_EVT_ADV_END)
                {
                    Display_printf(displayOut, 0, 0,
                                   "[bleThread] Warning! Unexpected Event %lu",
                                   apEvent);
                }
            }
            while (apEvent != AP_EVT_ADV_END);

            /* Update State and Characteristic values on LCD */
            Display_print1(displayOut,0,0,"Peer connected! (%s)", peerstr);

            /* Events that can happen during connection - Client Disconnection
                                                        - AP Disconnection */
            do
            {
                apEvent = 0;
                mq_receive(sensQueueRec, (void*) &apEvent, sizeof(uint32_t),
                           &prio);

                if (apEvent != AP_EVT_CONN_TERM)
                {
                    Display_printf(displayOut, 0, 0,
                                   "[bleThread] Warning! Unexpected Event %lu",
                                   apEvent);
                }
            }
            while (apEvent != AP_EVT_CONN_TERM);

            /* Client has disconnected from server */
            SAP_setParam(SAP_PARAM_CONN, SAP_CONN_STATE, sizeof(connHandle),
                    (uint8_t *) &connHandle);

            do
            {
                apEvent = 0;
                mq_receive(sensQueueRec, (void*) &apEvent, sizeof(uint32_t),
                           &prio);

                if ((apEvent != AP_EVT_CONN_TERM)
                        && (apEvent != AP_EVT_ADV_ENB))
                {
                    Display_printf(displayOut, 0, 0,
                                   "[bleThread] Warning! Unexpected Event %lu",
                                   apEvent);
                }
            }
            while ((apEvent != AP_EVT_CONN_TERM)
                    && (apEvent != AP_EVT_ADV_ENB));

            state = AP_CANCEL_ADV;

            break;

        case AP_CANCEL_ADV:
            Display_print0(displayOut,0,0,"Advertisement has been canceled!");

            /* Cancel Advertisement */
            SAP_setParam(SAP_PARAM_ADV, SAP_ADV_STATE, 1, &disableAdv);

            do
            {
                apEvent = 0;
                mq_receive(sensQueueRec, (void*) &apEvent, sizeof(uint32_t),
                           &prio);

                if (apEvent != AP_EVT_ADV_END)
                {
                    Display_printf(displayOut, 0, 0,
                                   "[bleThread] Warning! Unexpected Event %lu",
                                   apEvent);
                }
            }
            while (apEvent != AP_EVT_ADV_END);

            state = AP_IDLE;
            break;

        case AP_IDLE:
            /* Turn off user LED to indicate stop advertising */
            GPIO_write(Board_LED0, Board_LED_OFF);
            /*
            store_en = false;
            SensorBMP280_Deactivate();
            SensorBMA253_Deactivate();
            //SensorBHI160_Deactivate();
            SensorICM20649_Deactivate();
            Timer_stop(timer0);
            HwiP_disableInterrupt(40);
            MAP_ADC14_disableConversion();
            */
            Display_print0(displayOut,0,0,"State set to idle.");
            GPIO_clearInt(Board_BUTTON1);
            GPIO_enableInt(Board_BUTTON1);
            ALL_Sensor_Disable();
            Baseball6xsConfig = 0x00;
            Baseball3xsConfig = 0x00;
            /* Key Press triggers state change from idle */
/*
            do
            {
                apEvent = 0;
                mq_receive(sensQueueRec, (void*) &apEvent, sizeof(uint32_t),
                           &prio);

                if ((apEvent != AP_EVT_BUTTON_RIGHT)
                        && (apEvent != AP_EVT_BSL_BUTTON))
                {
                    Display_printf(displayOut, 0, 0,
                                   "[bleThread] Warning! Unexpected Event %lu",
                                   apEvent);
                }
            }
            while ((apEvent != AP_EVT_BUTTON_RIGHT)
                    && (apEvent != AP_EVT_BSL_BUTTON));
*/
            GPIO_disableInt(Board_BUTTON1);
            state = AP_START_ADV;
            /*
            if (apEvent == AP_EVT_BUTTON_RIGHT)
            {
                state = AP_START_ADV;
            }
            else if (apEvent == AP_EVT_BSL_BUTTON)
            {
                state = AP_SBL;
            }
            */
            break;

        default:
            break;
        }
    }
}

/*******************************************************************************
 * @fn      AP_initServices
 *
 * @brief   Configure SNP and register services.
 *
 * @param   None.
 *
 * @return  None.
 ******************************************************************************/
static void AP_initServices(void)
{
    Baseball3xs_addService();
    Baseball6xs_addService();

    SAP_registerEventCB(AP_processSNPEventCB, 0xFFFF);
}

/*
 * This is a callback operating in the NPI task.
 * These are events this application has registered for.
 *
 */
static void AP_processSNPEventCB(uint16_t event, snpEventParam_t *param)
{
    uint32_t eventPend;

    switch (event)
    {
    case SNP_CONN_EST_EVT:
    {
        snpConnEstEvt_t * connEstEvt = (snpConnEstEvt_t *) param;

        /* Update Peer Addr String */
        connHandle = connEstEvt->connHandle;
        ProfileUtil_convertBdAddr2Str(&peerstr[peerstrIDX], connEstEvt->pAddr);

        /* Notify state machine of established connection */
        eventPend = AP_EVT_CONN_EST;
        mq_send(sensQueueSend, (void*)&eventPend, sizeof(uint32_t), 1);
    }
        break;

    case SNP_CONN_TERM_EVT:
    {
        connHandle = AP_DEFAULT_CONN_HANDLE;
        eventPend = AP_EVT_CONN_TERM;
        mq_send(sensQueueSend, (void*)&eventPend, sizeof(uint32_t), 1);

    }
        break;

    case SNP_ADV_STARTED_EVT:
    {
        snpAdvStatusEvt_t *advEvt = (snpAdvStatusEvt_t *) param;
        if (advEvt->status == SNP_SUCCESS)
        {
            /* Notify state machine of Advertisement Enabled */
            eventPend = AP_EVT_ADV_ENB;
            mq_send(sensQueueSend, (void*)&eventPend, sizeof(uint32_t), 1);
        }
        else
        {
            eventPend = AP_ERROR;
            mq_send(sensQueueSend, (void*)&eventPend, sizeof(uint32_t), 1);
        }
    }
        break;

    case SNP_ADV_ENDED_EVT:
    {
        snpAdvStatusEvt_t *advEvt = (snpAdvStatusEvt_t *) param;
        if (advEvt->status == SNP_SUCCESS)
        {
            /* Notify state machine of Advertisement Disabled */
            eventPend = AP_EVT_ADV_END;
            mq_send(sensQueueSend, (void*)&eventPend, sizeof(uint32_t), 1);
        }
    }
        break;

    default:
        break;
    }
}

/*
 * This is a callback operating in the NPI task.
 * These are Asynchronous indications.
  */
static void AP_asyncCB(uint8_t cmd1, void *pParams)
{
    uint32_t eventPend;

    switch (SNP_GET_OPCODE_HDR_CMD1(cmd1))
    {
    case SNP_DEVICE_GRP:
    {
        switch (cmd1)
        {
        case SNP_POWER_UP_IND:
        {
            eventPend = AP_EVT_PUI;
            mq_send(sensQueueSend, (void*)&eventPend, sizeof(uint32_t), 1);
            break;
        }
        case SNP_HCI_CMD_RSP:
        {
            snpHciCmdRsp_t *hciRsp = (snpHciCmdRsp_t *) pParams;
            switch (hciRsp->opcode)
            {
            case SNP_HCI_OPCODE_READ_BDADDR:
                ProfileUtil_convertBdAddr2Str(&nwpstr[nwpstrIDX],
                        hciRsp->pData);
              default:
                break;
            }
        }
            break;

        case SNP_EVENT_IND:
        {
        }
        default:
            break;
        }
    }
        break;

    default:
        break;
    }
}

/*******************************************************************************
 * @fn      AP_bslKeyHandler
 *
 * @brief   event handler function to notify the app to program the SNP
 *
 * @param   none
 *
 * @return  none
 ******************************************************************************/
void AP_bslKeyHandler(void)
{
    uint32_t delayDebounce = 0;
    uint32_t eventPend;

    GPIO_disableInt(Board_BUTTON1);

    /* Delay for switch debounce */
    for (delayDebounce = 0; delayDebounce < 20000; delayDebounce++);

    GPIO_clearInt(Board_BUTTON1);
    GPIO_enableInt(Board_BUTTON1);

    GPIO_toggle (Board_LED1);

    //eventPend = AP_EVT_BSL_BUTTON;
    mq_send(sensQueueSend, (void*)&eventPend, sizeof(uint32_t), 1);
}

/*******************************************************************************
 * @fn      AP_keyHandler
 *
 * @brief   Key event handler function
 *
 * @param   none
 *
 * @return  none
 ******************************************************************************/
void AP_keyHandler(void)
{
    uint32_t delayDebounce = 0;
    uint32_t eventPend;

    GPIO_disableInt (Board_BUTTON0);

    /* Delay for switch debounce */
    for (delayDebounce = 0; delayDebounce < 20000; delayDebounce++)
        ;

    GPIO_clearInt(Board_BUTTON0);
    GPIO_enableInt(Board_BUTTON0);

    eventPend = AP_EVT_BUTTON_RIGHT;
    mq_send(sensQueueSend, (void*)&eventPend, sizeof(uint32_t), 1);
}

/*
 * TimerHandler for the Force Sensor
 */
static void AP_timerHandler(Timer_Handle handle)
{
    /* Toggle a new conversion */
    MAP_ADC14_toggleConversionTrigger();
}

//Callbacks for the ECG9xs characteristic

static void AP_processBaseball6xsChangeCB(uint8_t charID)
{
    Baseball6xs_processCharChangeEvt(charID);
}

static void AP_processBaseball6xscccdCB(uint8_t charID, uint16_t value)
{
    switch (PROFILE_ID_CHAR(charID))
    {
    case BASEBALL6xs_DATA:
        switch (PROFILE_ID_CHARTYPE(charID))
        {
        case PROFILE_CCCD:
            /* If indication or notification flags are set */
            if (value & (SNP_GATT_CLIENT_CFG_NOTIFY | SNP_GATT_CLIENT_CFG_INDICATE))
            {
                if(Baseball3xs == false && Baseball6xs == false)
                {
                    Baseball6xs = true;
                    Display_print0(displayOut,0,0,"Baseball6xs update enabled!");
                }
            }
            else
            {
                if(Baseball6xs == true)
                {
                    Baseball6xs = false;
                    Display_print0(displayOut,0,0,"Baseball6xs update disabled!");
                }
            }
            break;

        default:
            break;
        }
        break;

    default:
        break;
    }
}
/*******************************************************************************
 * @fn      Baseball6xs_processCharChangeEvt
 *
 * @brief   SensorBP ECG9xs event handling
 *
 ******************************************************************************/

static void Baseball6xs_processCharChangeEvt(uint8_t paramID)
{
    uint8_t newValue;
    //uint32_t sendCmd;

    switch (paramID)
    {
    case BASEBALL6xs_CONF:
        if (Baseball6xsConfig != SENSORBSP_ERROR_DATA)
        {
            Baseball6xs_getParameter(BASEBALL6xs_CONF, &newValue);

            if (newValue == SENSORBSP_CFG_SENSOR_DISABLE)
            {
                /* Reset characteristics */
                initBaseball6xsCharacteristicValue(BASEBALL6xs_DATA, 0, BASEBALL6xs_DATA_LEN);

                Display_print0(displayOut, 0, 0, "ADC disabled!");

            }
            else
            {
                //SensorBMP280_Activate();
                //SensorBHI160_Activate();
                /*
                Timer_start(timer0);
                HwiP_enableInterrupt(40);
                MAP_ADC14_enableConversion();
                
                */
                if(Baseball6xsConfig != 0x11 && newValue == 0x11)
                {
                	openflash();
                    store_en = true;
                    SensorA301_Deactivate();
                    Timer_stop(timer0);
                    HwiP_disableInterrupt(40);
                    MAP_ADC14_disableConversion();
                    SensorICM20649_Activate(false);
                }
                else if(Baseball6xsConfig != 0x12 && newValue == 0x12)
                {
                	openflash();
                    store_en = true;
                    SensorICM20649_Deactivate();
                    Timer_start(timer0);
                    HwiP_enableInterrupt(40);
                    MAP_ADC14_enableConversion();
                    SensorA301_Activate(false);
                }
                else if(Baseball6xsConfig != 0x13 && newValue == 0x13)
                {
                    SensorICM20649_Activate(true);
                    Timer_start(timer0);
                    HwiP_enableInterrupt(40);
                    MAP_ADC14_enableConversion();
                    SensorA301_Activate(true);
                }
               
                else if(Baseball6xsConfig == 0x10 && newValue == 0xFF)
                {
                    outputflashdata();
                }
                
                Baseball6xsConfig = newValue;
            }
        } else
        {
            /* Make sure the previous characteristics value is restored */
            initBaseball6xsCharacteristicValue(BASEBALL6xs_CONF, Baseball6xsConfig, sizeof(uint8_t));
        }

        break;

    default:
        break;
    }
}
static void initBaseball6xsCharacteristicValue(uint8_t paramID, uint8_t value, uint8_t paramLen)
{
    uint8_t data[BASEBALL6xs_DATA_LEN];

    memset(data, value, paramLen);
    Baseball6xs_setParameter(paramID, paramLen, data);
}

//Callbacks for the ECG3xs characteristic

static void AP_processBaseball3xsChangeCB(uint8_t charID)
{
    Baseball3xs_processCharChangeEvt(charID);
}

static void AP_processBaseball3xscccdCB(uint8_t charID, uint16_t value)
{
    switch (PROFILE_ID_CHAR(charID))
    {
    case BASEBALL3xs_DATA:
        switch (PROFILE_ID_CHARTYPE(charID))
        {
        case PROFILE_CCCD:
            /* If indication or notification flags are set */
            if (value & (SNP_GATT_CLIENT_CFG_NOTIFY | SNP_GATT_CLIENT_CFG_INDICATE))
            {
                if(Baseball3xs == false && Baseball6xs == false)
                {
                    Baseball3xs = true;
                    Display_print0(displayOut,0,0,"Baseball3xs update enabled!");
                }
            }
            else
            {
                if(Baseball3xs == true)
                {
                    Baseball3xs = false;
                    Display_print0(displayOut,0,0,"Baseball3xs update disabled!");
                }
            }
            break;

        default:
            break;
        }
        break;

    default:
        break;
    }
}
/*******************************************************************************
 * @fn      Baseball3xs_processCharChangeEvt
 *
 * @brief   SensorBP ECG3xs event handling
 *
 ******************************************************************************/

static void Baseball3xs_processCharChangeEvt(uint8_t paramID)
{
    uint8_t newValue;

    switch (paramID)
    {
    case BASEBALL3xs_CONF:
        if (Baseball3xsConfig != SENSORBSP_ERROR_DATA)
        {
            Baseball3xs_getParameter(BASEBALL3xs_CONF, &newValue);

            if (newValue == SENSORBSP_CFG_SENSOR_DISABLE)
            {
                /* Reset characteristics */
                initBaseball3xsCharacteristicValue(BASEBALL3xs_DATA, 0, BASEBALL3xs_DATA_LEN);

                /* Deactivate task */
                SensorBMP280_Deactivate();
                SensorBMA253_Deactivate();
            }
            else
            {
                /* Activate task */
                SensorBMP280_Activate();
                SensorBMA253_Activate();
                Baseball3xsConfig = newValue;
            }
        } else
        {
            /* Make sure the previous characteristics value is restored */
            initBaseball3xsCharacteristicValue(BASEBALL3xs_CONF, Baseball3xsConfig, sizeof(uint8_t));
        }

        break;

    default:
        break;
    }
}
static void initBaseball3xsCharacteristicValue(uint8_t paramID, uint8_t value, uint8_t paramLen)
{
    uint8_t data[BASEBALL3xs_DATA_LEN];

    memset(data, value, paramLen);
    Baseball3xs_setParameter(paramID, paramLen, data);
}

static void ALL_Sensor_Disable(void)
{
    /* Deactivate task */
    //SensorBMP280_Deactivate();
    //SensorBMA253_Deactivate();
    //SensorBHI160_Deactivate();
    SensorICM20649_Deactivate();
    SensorA301_Deactivate();
    Timer_stop(timer0);
    HwiP_disableInterrupt(40);
    MAP_ADC14_disableConversion();
    if(store_en == true)
    {
        closeflash();
        store_en = false;
    }
    Display_print0(displayOut, 0, 0, "All sensor disabled!");
}

/* --COPYRIGHT--,BSD
 * Copyright (c) 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.
 * --/COPYRIGHT--*/
/*******************************************************************************
 *                              INCLUDES
 ******************************************************************************/
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <pthread.h>
#include <mqueue.h>
#include <semaphore.h>
#include <time.h>
#include <unistd.h>
#include <ti/display/Display.h>
#include <ti/drivers/dpl/HwiP.h>
#include <ti/drivers/GPIO.h>
#include <ti/drivers/UART.h>
#include <ti/drivers/Timer.h>
#include <ti/devices/msp432p4xx/driverlib/driverlib.h>
#include <ti/sap/sap.h>
#include <ti/sbl/sbl.h>
#include <ti/sbl/sbl_image.h>

#include <Profile/baseball3xs_service.h>
#include <Profile/baseball6xs_service.h>
#include <Profile/profile_util.h>
#include "flashctrl.h"
#include "sensor_boosterpack_A301.h"
#include "sensor_boosterpack_bhi160.h"
#include "sensor_boosterpack_bmp280.h"
#include "sensor_boosterpack_bma253.h"
#include "sensor_boosterpack_icm20649.h"
#include "sensor_boosterpack.h"
#include "sensor_configuration.h"
#include "Board.h"
#include "platform.h"

/*******************************************************************************
 *                             VARIABLES
 ******************************************************************************/
/* Used to block SNP calls during a synchronous transaction. */
static mqd_t sensQueueRec;
static mqd_t sensQueueSend;

/* Clock instances for internal periodic events. */
static Timer_Handle timer0;

/* Task configuration */
static pthread_t sensTask;

/* SAP Parameters for opening serial port to SNP */
static SAP_Params sapParams;

/* Device Name */
static uint8_t snpDeviceName[] =
        { 'I', '_', 'B', 'a', 's', 'e', 'b', 'a', 'l', 'l' };

/* GAP - SCAN RSP data (max size = 31 bytes) */
static uint8_t scanRspData[] =
{
    /* Complete name */
    0x0a, /* Length */
    SAP_GAP_ADTYPE_LOCAL_NAME_COMPLETE, 'I', '_', 'B', 'a', 's', 'e', 'b', 'a', 'l', 'l',

    /* Connection interval range */
    0x05, /* Length */
    0x12,
    LO_UINT16(DEFAULT_DESIRED_MIN_CONN_INTERVAL),
    HI_UINT16(DEFAULT_DESIRED_MIN_CONN_INTERVAL),
    LO_UINT16(DEFAULT_DESIRED_MAX_CONN_INTERVAL),
    HI_UINT16(DEFAULT_DESIRED_MAX_CONN_INTERVAL),

    /* TX power level */
    0x02, /* Length */
    0x0A,
    0
};

/* GAP - Advertisement data (max size = 31 bytes, though this is
   best kept short to conserve power while advertising) */
static uint8_t advertData[] =
{
    /* Flags; this sets the device to use limited discoverable
       mode (advertises for 30 seconds at a time) instead of general
       discoverable mode (advertises indefinitely) */
    0x02, /* Length */
    SAP_GAP_ADTYPE_FLAGS,
    DEFAULT_DISCOVERABLE_MODE | SAP_GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,

    /* Manufacturer specific advertising data */
    0x06, 0xFF,
    LO_UINT16(TI_COMPANY_ID),
    HI_UINT16(TI_COMPANY_ID),
    TI_ST_DEVICE_ID,
    TI_ST_KEY_DATA_ID, 0x00
};

/* Connection Handle - only one device currently allowed to connect to SNP */
static uint16_t connHandle = AP_DEFAULT_CONN_HANDLE;

/* BD Addr of the NWP */
static char nwpstr[] = "NWP:  0xFFFFFFFFFFFF";
#define nwpstrIDX       8

// BD Addr of peer device in connection
static char peerstr[] = "Peer: 0xFFFFFFFFFFFF";
#define peerstrIDX       8

/* Used for log messages */
extern Display_Handle displayOut;

/* Used for exiting threads */
extern pthread_t bmp280Task;
extern pthread_t bma253Task;
extern pthread_t bhi160Task;
extern pthread_t icm20649Task;

/* Sensor Parameters */

static uint8_t Baseball6xsConfig;
volatile bool Baseball6xs = false;
static uint8_t Baseball3xsConfig;
volatile bool Baseball3xs = false;

volatile bool store_en = false;

/*******************************************************************************
 *                            FUNCTION PROTOTYPES
 ******************************************************************************/
static void AP_init(void);
static void *AP_taskFxn(void *arg0);
static void AP_initServices(void);
static void AP_keyHandler(void);
static void AP_bslKeyHandler(void);
static void AP_asyncCB(uint8_t cmd1, void *pParams);
static void AP_processSNPEventCB(uint16_t event, snpEventParam_t *param);
static void AP_timerHandler(Timer_Handle handle);

static void AP_processBaseball6xsChangeCB(uint8_t charID);
static void AP_processBaseball6xscccdCB(uint8_t charID, uint16_t value);
static void Baseball6xs_processCharChangeEvt(uint8_t paramID);
static void initBaseball6xsCharacteristicValue(uint8_t paramID, uint8_t value, uint8_t paramLen);

static void AP_processBaseball3xsChangeCB(uint8_t charID);
static void AP_processBaseball3xscccdCB(uint8_t charID, uint16_t value);
static void Baseball3xs_processCharChangeEvt(uint8_t paramID);
static void initBaseball3xsCharacteristicValue(uint8_t paramID, uint8_t value, uint8_t paramLen);

static void ALL_Sensor_Disable(void);
/*******************************************************************************
 *                                 PROFILE CALLBACKS
 ******************************************************************************/
/*
 * Characteristic value change callback
 */
static BLEProfileCallbacks_t AP_Baseball6xsSensorCBs =
{
    AP_processBaseball6xsChangeCB,
    AP_processBaseball6xscccdCB
};
static BLEProfileCallbacks_t AP_Baseball3xsSensorCBs =
{
    AP_processBaseball3xsChangeCB,
    AP_processBaseball3xscccdCB
};
/*******************************************************************************
 *                                 PUBLIC FUNCTIONS
 ******************************************************************************/
/*******************************************************************************
 * @fn      AP_createTask
 *
 * @brief   Task creation function for the Simple BLE Peripheral.
 *
 * @param   None.
 *
 * @return  None.
 ******************************************************************************/
void AP_createTask(void)
{
    pthread_attr_t pAttrs;
    struct sched_param priParam;
    int retc;
    int detachState;

    pthread_attr_init(&pAttrs);
    priParam.sched_priority = AP_TASK_PRIORITY;

    detachState = PTHREAD_CREATE_DETACHED;
    retc = pthread_attr_setdetachstate(&pAttrs, detachState);

    if (retc != 0)
    {
        while(1);
    }

    pthread_attr_setschedparam(&pAttrs, &priParam);

    retc |= pthread_attr_setstacksize(&pAttrs, AP_TASK_STACK_SIZE);

    if (retc != 0)
    {
        while(1);
    }

    retc = pthread_create(&sensTask, &pAttrs, AP_taskFxn, NULL);

    if (retc != 0)
    {
        while(1);
    }
}

/*******************************************************************************
 * @fn      AP_init
 *
 * @brief   Called during initialization and contains application
 *          specific initialization (ie. hardware initialization/setup,
 *          table initialization, power up notification, etc), and
 *          profile initialization/setup.
 *
 * @param   None.
 *
 * @return  None.
 ******************************************************************************/
static void AP_init(void)
{
    Timer_Params params;
    struct mq_attr attr;

    /* Create RTOS Queue */
    attr.mq_flags = 0;
    attr.mq_maxmsg = 64;
    attr.mq_msgsize = sizeof(uint32_t);
    attr.mq_curmsgs = 0;

    sensQueueRec = mq_open("SensorHub", O_RDWR | O_CREAT, 0664, &attr);
    sensQueueSend = mq_open("SensorHub", O_RDWR | O_CREAT | O_NONBLOCK, 0664, &attr);

    // Register to receive notifications from temperature if characteristics have been written to
    Baseball6xs_registerAppCBs(&AP_Baseball6xsSensorCBs);
    Baseball3xs_registerAppCBs(&AP_Baseball3xsSensorCBs);

    // Initialize characteristics and sensor driver
    Baseball6xsConfig = SENSORBSP_CFG_SENSOR_DISABLE;
    initBaseball6xsCharacteristicValue(BASEBALL6xs_DATA, 0, BASEBALL6xs_DATA_LEN);
    initBaseball6xsCharacteristicValue(BASEBALL6xs_CONF, SENSORBSP_CFG_SENSOR_DISABLE, sizeof(uint8_t));

    Baseball3xsConfig = SENSORBSP_CFG_SENSOR_DISABLE;
    initBaseball3xsCharacteristicValue(BASEBALL3xs_DATA, 0, BASEBALL3xs_DATA_LEN);
    initBaseball3xsCharacteristicValue(BASEBALL3xs_CONF, SENSORBSP_CFG_SENSOR_DISABLE, sizeof(uint8_t));

    /* Setting up the timer in continuous callback mode that calls the callback
     * functions every 5s.
     */
    Timer_Params_init(&params);
    params.period = AP_PERIODIC_EVT_PERIOD;
    params.periodUnits = TIMER_PERIOD_US;
    params.timerMode = TIMER_CONTINUOUS_CB;
    params.timerCallback = AP_timerHandler;

    timer0 = Timer_open(Board_Timer0, &params);
    if (timer0 == NULL)
    {
        Display_print0(displayOut, 0, 0, "Failed to initialized Timer!\n");
    }

    /* Initialize clock of Flashctrl */
    clock_init();

    /* Register Key Handler */
    GPIO_setCallback(Board_BUTTON0, (GPIO_CallbackFxn) AP_keyHandler);
    GPIO_enableInt (Board_BUTTON0);
    GPIO_setCallback(Board_BUTTON1, (GPIO_CallbackFxn) AP_bslKeyHandler);
    GPIO_enableInt (Board_BUTTON1);


    /* Write to the UART. */
    Display_print0(displayOut,0,0,
            "--------- Sensor Booster Pack Example ---------");
    Display_print0(displayOut,0,0,"Application Processor Initializing... ");
}

/*******************************************************************************
 * @fn      AP_taskFxn
 *
 * @brief   Application task entry point for the Simple BLE Peripheral.
 *
 * @param   a0, a1 - not used.
 *
 * @return  None.
 ******************************************************************************/
static void *AP_taskFxn(void *arg0)
{
    uint32_t apEvent = 0;
    struct timespec ts;
    ap_States_t state = AP_RESET;
    uint8_t enableAdv = 1;
    uint8_t disableAdv = 0;
    uint32_t prio = 0;
    /*
    uint8_t sblSatus;
    SBL_Params params;
    SBL_Image image;
    */

    /* Initialize application */
    AP_init();

    Display_print0(displayOut,0,0,"Done!");

    while(1)
    {
        switch (state)
        {
        case AP_RESET:
        {
            /* Make sure CC26xx is not in BSL */
            GPIO_write(Board_RESET, Board_LED_OFF);
            GPIO_write(Board_MRDY, Board_LED_ON);

            usleep(10000);

            GPIO_write(Board_RESET, Board_LED_ON);

            /* Initialize UART port parameters within SAP parameters */
            SAP_initParams(SAP_PORT_REMOTE_UART, &sapParams);

            sapParams.port.remote.mrdyPinID = Board_MRDY;
            sapParams.port.remote.srdyPinID = Board_SRDY;
            sapParams.port.remote.boardID = Board_UART1;

            /* Setup NP module */
            SAP_open(&sapParams);

            /* Register Application thread's callback to receive
             * asynchronous requests from the NP.
             */
            SAP_setAsyncCB(AP_asyncCB);

            /* Reset the NP, and await a powerup indication.
               Clear any pending power indications received prior to this reset
               call */
            clock_gettime(CLOCK_REALTIME, &ts);
            ts.tv_sec += 1;

            mq_timedreceive(sensQueueRec, (void*) &apEvent, sizeof(uint32_t), &prio,
                    &ts);

            SAP_reset();

            GPIO_clearInt(Board_BUTTON1);
            GPIO_enableInt(Board_BUTTON1);

            do
            {
                apEvent = 0;
                mq_receive(sensQueueRec, (void*) &apEvent, sizeof(uint32_t),
                           &prio);

                if (apEvent != AP_EVT_PUI)
                {
                    Display_printf(displayOut, 0, 0,
                                   "[bleThread] Warning! Unexpected Event %lu",
                                   apEvent);
                }
            }
            while (apEvent != AP_EVT_PUI);
            GPIO_disableInt(Board_BUTTON1);
/*
            if (apEvent == AP_EVT_BSL_BUTTON)
            {
                state = AP_SBL;
            }
*/
            if (apEvent == AP_EVT_PUI)
            {
                /* Read BD ADDR */
                SAP_setParam(SAP_PARAM_HCI, SNP_HCI_OPCODE_READ_BDADDR, 0,
                                NULL);

                /* Setup Services - Service creation is blocking so
                 * no need to pend */
                AP_initServices();

                state = AP_IDLE;
            }

        }
            break;

        case AP_START_ADV:
        {
            /* Turn on user LED to indicate advertising */
            GPIO_write(Board_LED0, Board_LED_ON);
            Display_print0(displayOut,0,0, "Starting advertisement... ");

            /* Setting Advertising Name */
            SAP_setServiceParam(SNP_GGS_SERV_ID, SNP_GGS_DEVICE_NAME_ATT,
                                   sizeof(snpDeviceName), snpDeviceName);

            /* Set advertising data. */
            SAP_setParam(SAP_PARAM_ADV, SAP_ADV_DATA_NOTCONN,
                    sizeof(advertData), advertData);

            /* Set Scan Response data. */
            SAP_setParam(SAP_PARAM_ADV, SAP_ADV_DATA_SCANRSP,
                    sizeof(scanRspData), scanRspData);

            /* Enable Advertising and await NP response */
            SAP_setParam(SAP_PARAM_ADV, SAP_ADV_STATE, 1, &enableAdv);
            
            do
            {
                apEvent = 0;
                mq_receive(sensQueueRec, (void*) &apEvent, sizeof(uint32_t),
                           &prio);

                if (apEvent != AP_EVT_ADV_ENB)
                {
                    Display_printf(displayOut, 0, 0,
                                   "[bleThread] Warning! Unexpected Event %lu",
                                   apEvent);
                }
            }
            while (apEvent != AP_EVT_ADV_ENB);

            Display_print0(displayOut,0,0, "Done!");
            Display_print0(displayOut,0,0,
                    "Waiting for connection (or timeout)... ");

            /* Wait for connection or button press to cancel advertisement */
            clock_gettime(CLOCK_REALTIME, &ts);
            ts.tv_sec += 60;
            apEvent = 0;
            mq_timedreceive(sensQueueRec, (void*) &apEvent, sizeof(uint32_t),
                            &prio, &ts);

            if(apEvent == AP_EVT_CONN_EST)
            {
                state = AP_CONNECTED;
            }
            else
            {
                state = AP_CANCEL_ADV;
                Display_print0(displayOut, 0, 0,"Advertisement Timeout!");
            }
        }
            break;

        case AP_CONNECTED:
            /* Before connecting, NP will send the stop ADV message */
            do
            {
                apEvent = 0;
                mq_receive(sensQueueRec, (void*) &apEvent, sizeof(uint32_t),
                           &prio);

                if (apEvent != AP_EVT_ADV_END)
                {
                    Display_printf(displayOut, 0, 0,
                                   "[bleThread] Warning! Unexpected Event %lu",
                                   apEvent);
                }
            }
            while (apEvent != AP_EVT_ADV_END);

            /* Update State and Characteristic values on LCD */
            Display_print1(displayOut,0,0,"Peer connected! (%s)", peerstr);

            /* Events that can happen during connection - Client Disconnection
                                                        - AP Disconnection */
            do
            {
                apEvent = 0;
                mq_receive(sensQueueRec, (void*) &apEvent, sizeof(uint32_t),
                           &prio);

                if (apEvent != AP_EVT_CONN_TERM)
                {
                    Display_printf(displayOut, 0, 0,
                                   "[bleThread] Warning! Unexpected Event %lu",
                                   apEvent);
                }
            }
            while (apEvent != AP_EVT_CONN_TERM);

            /* Client has disconnected from server */
            SAP_setParam(SAP_PARAM_CONN, SAP_CONN_STATE, sizeof(connHandle),
                    (uint8_t *) &connHandle);

            do
            {
                apEvent = 0;
                mq_receive(sensQueueRec, (void*) &apEvent, sizeof(uint32_t),
                           &prio);

                if ((apEvent != AP_EVT_CONN_TERM)
                        && (apEvent != AP_EVT_ADV_ENB))
                {
                    Display_printf(displayOut, 0, 0,
                                   "[bleThread] Warning! Unexpected Event %lu",
                                   apEvent);
                }
            }
            while ((apEvent != AP_EVT_CONN_TERM)
                    && (apEvent != AP_EVT_ADV_ENB));

            state = AP_CANCEL_ADV;

            break;

        case AP_CANCEL_ADV:
            Display_print0(displayOut,0,0,"Advertisement has been canceled!");

            /* Cancel Advertisement */
            SAP_setParam(SAP_PARAM_ADV, SAP_ADV_STATE, 1, &disableAdv);

            do
            {
                apEvent = 0;
                mq_receive(sensQueueRec, (void*) &apEvent, sizeof(uint32_t),
                           &prio);

                if (apEvent != AP_EVT_ADV_END)
                {
                    Display_printf(displayOut, 0, 0,
                                   "[bleThread] Warning! Unexpected Event %lu",
                                   apEvent);
                }
            }
            while (apEvent != AP_EVT_ADV_END);

            state = AP_IDLE;
            break;

        case AP_IDLE:
            /* Turn off user LED to indicate stop advertising */
            GPIO_write(Board_LED0, Board_LED_OFF);
            /*
            store_en = false;
            SensorBMP280_Deactivate();
            SensorBMA253_Deactivate();
            //SensorBHI160_Deactivate();
            SensorICM20649_Deactivate();
            Timer_stop(timer0);
            HwiP_disableInterrupt(40);
            MAP_ADC14_disableConversion();
            */
            Display_print0(displayOut,0,0,"State set to idle.");
            GPIO_clearInt(Board_BUTTON1);
            GPIO_enableInt(Board_BUTTON1);
            ALL_Sensor_Disable();
            Baseball6xsConfig = 0x00;
            Baseball3xsConfig = 0x00;
            /* Key Press triggers state change from idle */
/*
            do
            {
                apEvent = 0;
                mq_receive(sensQueueRec, (void*) &apEvent, sizeof(uint32_t),
                           &prio);

                if ((apEvent != AP_EVT_BUTTON_RIGHT)
                        && (apEvent != AP_EVT_BSL_BUTTON))
                {
                    Display_printf(displayOut, 0, 0,
                                   "[bleThread] Warning! Unexpected Event %lu",
                                   apEvent);
                }
            }
            while ((apEvent != AP_EVT_BUTTON_RIGHT)
                    && (apEvent != AP_EVT_BSL_BUTTON));
*/
            GPIO_disableInt(Board_BUTTON1);
            state = AP_START_ADV;
            /*
            if (apEvent == AP_EVT_BUTTON_RIGHT)
            {
                state = AP_START_ADV;
            }
            else if (apEvent == AP_EVT_BSL_BUTTON)
            {
                state = AP_SBL;
            }
            */
            break;

        default:
            break;
        }
    }
}

/*******************************************************************************
 * @fn      AP_initServices
 *
 * @brief   Configure SNP and register services.
 *
 * @param   None.
 *
 * @return  None.
 ******************************************************************************/
static void AP_initServices(void)
{
    Baseball3xs_addService();
    Baseball6xs_addService();

    SAP_registerEventCB(AP_processSNPEventCB, 0xFFFF);
}

/*
 * This is a callback operating in the NPI task.
 * These are events this application has registered for.
 *
 */
static void AP_processSNPEventCB(uint16_t event, snpEventParam_t *param)
{
    uint32_t eventPend;

    switch (event)
    {
    case SNP_CONN_EST_EVT:
    {
        snpConnEstEvt_t * connEstEvt = (snpConnEstEvt_t *) param;

        /* Update Peer Addr String */
        connHandle = connEstEvt->connHandle;
        ProfileUtil_convertBdAddr2Str(&peerstr[peerstrIDX], connEstEvt->pAddr);

        /* Notify state machine of established connection */
        eventPend = AP_EVT_CONN_EST;
        mq_send(sensQueueSend, (void*)&eventPend, sizeof(uint32_t), 1);
    }
        break;

    case SNP_CONN_TERM_EVT:
    {
        connHandle = AP_DEFAULT_CONN_HANDLE;
        eventPend = AP_EVT_CONN_TERM;
        mq_send(sensQueueSend, (void*)&eventPend, sizeof(uint32_t), 1);

    }
        break;

    case SNP_ADV_STARTED_EVT:
    {
        snpAdvStatusEvt_t *advEvt = (snpAdvStatusEvt_t *) param;
        if (advEvt->status == SNP_SUCCESS)
        {
            /* Notify state machine of Advertisement Enabled */
            eventPend = AP_EVT_ADV_ENB;
            mq_send(sensQueueSend, (void*)&eventPend, sizeof(uint32_t), 1);
        }
        else
        {
            eventPend = AP_ERROR;
            mq_send(sensQueueSend, (void*)&eventPend, sizeof(uint32_t), 1);
        }
    }
        break;

    case SNP_ADV_ENDED_EVT:
    {
        snpAdvStatusEvt_t *advEvt = (snpAdvStatusEvt_t *) param;
        if (advEvt->status == SNP_SUCCESS)
        {
            /* Notify state machine of Advertisement Disabled */
            eventPend = AP_EVT_ADV_END;
            mq_send(sensQueueSend, (void*)&eventPend, sizeof(uint32_t), 1);
        }
    }
        break;

    default:
        break;
    }
}

/*
 * This is a callback operating in the NPI task.
 * These are Asynchronous indications.
  */
static void AP_asyncCB(uint8_t cmd1, void *pParams)
{
    uint32_t eventPend;

    switch (SNP_GET_OPCODE_HDR_CMD1(cmd1))
    {
    case SNP_DEVICE_GRP:
    {
        switch (cmd1)
        {
        case SNP_POWER_UP_IND:
        {
            eventPend = AP_EVT_PUI;
            mq_send(sensQueueSend, (void*)&eventPend, sizeof(uint32_t), 1);
            break;
        }
        case SNP_HCI_CMD_RSP:
        {
            snpHciCmdRsp_t *hciRsp = (snpHciCmdRsp_t *) pParams;
            switch (hciRsp->opcode)
            {
            case SNP_HCI_OPCODE_READ_BDADDR:
                ProfileUtil_convertBdAddr2Str(&nwpstr[nwpstrIDX],
                        hciRsp->pData);
              default:
                break;
            }
        }
            break;

        case SNP_EVENT_IND:
        {
        }
        default:
            break;
        }
    }
        break;

    default:
        break;
    }
}

/*******************************************************************************
 * @fn      AP_bslKeyHandler
 *
 * @brief   event handler function to notify the app to program the SNP
 *
 * @param   none
 *
 * @return  none
 ******************************************************************************/
void AP_bslKeyHandler(void)
{
    uint32_t delayDebounce = 0;
    uint32_t eventPend;

    GPIO_disableInt(Board_BUTTON1);

    /* Delay for switch debounce */
    for (delayDebounce = 0; delayDebounce < 20000; delayDebounce++);

    GPIO_clearInt(Board_BUTTON1);
    GPIO_enableInt(Board_BUTTON1);

    GPIO_toggle (Board_LED1);

    //eventPend = AP_EVT_BSL_BUTTON;
    mq_send(sensQueueSend, (void*)&eventPend, sizeof(uint32_t), 1);
}

/*******************************************************************************
 * @fn      AP_keyHandler
 *
 * @brief   Key event handler function
 *
 * @param   none
 *
 * @return  none
 ******************************************************************************/
void AP_keyHandler(void)
{
    uint32_t delayDebounce = 0;
    uint32_t eventPend;

    GPIO_disableInt (Board_BUTTON0);

    /* Delay for switch debounce */
    for (delayDebounce = 0; delayDebounce < 20000; delayDebounce++)
        ;

    GPIO_clearInt(Board_BUTTON0);
    GPIO_enableInt(Board_BUTTON0);

    eventPend = AP_EVT_BUTTON_RIGHT;
    mq_send(sensQueueSend, (void*)&eventPend, sizeof(uint32_t), 1);
}

/*
 * TimerHandler for the Force Sensor
 */
static void AP_timerHandler(Timer_Handle handle)
{
    /* Toggle a new conversion */
    MAP_ADC14_toggleConversionTrigger();
}

//Callbacks for the ECG9xs characteristic

static void AP_processBaseball6xsChangeCB(uint8_t charID)
{
    Baseball6xs_processCharChangeEvt(charID);
}

static void AP_processBaseball6xscccdCB(uint8_t charID, uint16_t value)
{
    switch (PROFILE_ID_CHAR(charID))
    {
    case BASEBALL6xs_DATA:
        switch (PROFILE_ID_CHARTYPE(charID))
        {
        case PROFILE_CCCD:
            /* If indication or notification flags are set */
            if (value & (SNP_GATT_CLIENT_CFG_NOTIFY | SNP_GATT_CLIENT_CFG_INDICATE))
            {
                if(Baseball3xs == false && Baseball6xs == false)
                {
                    Baseball6xs = true;
                    Display_print0(displayOut,0,0,"Baseball6xs update enabled!");
                }
            }
            else
            {
                if(Baseball6xs == true)
                {
                    Baseball6xs = false;
                    Display_print0(displayOut,0,0,"Baseball6xs update disabled!");
                }
            }
            break;

        default:
            break;
        }
        break;

    default:
        break;
    }
}
/*******************************************************************************
 * @fn      Baseball6xs_processCharChangeEvt
 *
 * @brief   SensorBP ECG9xs event handling
 *
 ******************************************************************************/

static void Baseball6xs_processCharChangeEvt(uint8_t paramID)
{
    uint8_t newValue;
    //uint32_t sendCmd;

    switch (paramID)
    {
    case BASEBALL6xs_CONF:
        if (Baseball6xsConfig != SENSORBSP_ERROR_DATA)
        {
            Baseball6xs_getParameter(BASEBALL6xs_CONF, &newValue);

            if (newValue == SENSORBSP_CFG_SENSOR_DISABLE)
            {
                /* Reset characteristics */
                initBaseball6xsCharacteristicValue(BASEBALL6xs_DATA, 0, BASEBALL6xs_DATA_LEN);

                Display_print0(displayOut, 0, 0, "ADC disabled!");

            }
            else
            {
                //SensorBMP280_Activate();
                //SensorBHI160_Activate();
                /*
                Timer_start(timer0);
                HwiP_enableInterrupt(40);
                MAP_ADC14_enableConversion();
                
                */
                if(Baseball6xsConfig != 0x11 && newValue == 0x11)
                {
                	openflash();
                    store_en = true;
                    SensorA301_Deactivate();
                    Timer_stop(timer0);
                    HwiP_disableInterrupt(40);
                    MAP_ADC14_disableConversion();
                    SensorICM20649_Activate(false);
                }
                else if(Baseball6xsConfig != 0x12 && newValue == 0x12)
                {
                	openflash();
                    store_en = true;
                    SensorICM20649_Deactivate();
                    Timer_start(timer0);
                    HwiP_enableInterrupt(40);
                    MAP_ADC14_enableConversion();
                    SensorA301_Activate(false);
                }
                else if(Baseball6xsConfig != 0x13 && newValue == 0x13)
                {
                    SensorICM20649_Activate(true);
                    Timer_start(timer0);
                    HwiP_enableInterrupt(40);
                    MAP_ADC14_enableConversion();
                    SensorA301_Activate(true);
                }
               
                else if(Baseball6xsConfig == 0x10 && newValue == 0xFF)
                {
                    outputflashdata();
                }
                
                Baseball6xsConfig = newValue;
            }
        } else
        {
            /* Make sure the previous characteristics value is restored */
            initBaseball6xsCharacteristicValue(BASEBALL6xs_CONF, Baseball6xsConfig, sizeof(uint8_t));
        }

        break;

    default:
        break;
    }
}
static void initBaseball6xsCharacteristicValue(uint8_t paramID, uint8_t value, uint8_t paramLen)
{
    uint8_t data[BASEBALL6xs_DATA_LEN];

    memset(data, value, paramLen);
    Baseball6xs_setParameter(paramID, paramLen, data);
}

//Callbacks for the ECG3xs characteristic

static void AP_processBaseball3xsChangeCB(uint8_t charID)
{
    Baseball3xs_processCharChangeEvt(charID);
}

static void AP_processBaseball3xscccdCB(uint8_t charID, uint16_t value)
{
    switch (PROFILE_ID_CHAR(charID))
    {
    case BASEBALL3xs_DATA:
        switch (PROFILE_ID_CHARTYPE(charID))
        {
        case PROFILE_CCCD:
            /* If indication or notification flags are set */
            if (value & (SNP_GATT_CLIENT_CFG_NOTIFY | SNP_GATT_CLIENT_CFG_INDICATE))
            {
                if(Baseball3xs == false && Baseball6xs == false)
                {
                    Baseball3xs = true;
                    Display_print0(displayOut,0,0,"Baseball3xs update enabled!");
                }
            }
            else
            {
                if(Baseball3xs == true)
                {
                    Baseball3xs = false;
                    Display_print0(displayOut,0,0,"Baseball3xs update disabled!");
                }
            }
            break;

        default:
            break;
        }
        break;

    default:
        break;
    }
}
/*******************************************************************************
 * @fn      Baseball3xs_processCharChangeEvt
 *
 * @brief   SensorBP ECG3xs event handling
 *
 ******************************************************************************/

static void Baseball3xs_processCharChangeEvt(uint8_t paramID)
{
    uint8_t newValue;

    switch (paramID)
    {
    case BASEBALL3xs_CONF:
        if (Baseball3xsConfig != SENSORBSP_ERROR_DATA)
        {
            Baseball3xs_getParameter(BASEBALL3xs_CONF, &newValue);

            if (newValue == SENSORBSP_CFG_SENSOR_DISABLE)
            {
                /* Reset characteristics */
                initBaseball3xsCharacteristicValue(BASEBALL3xs_DATA, 0, BASEBALL3xs_DATA_LEN);

                /* Deactivate task */
                SensorBMP280_Deactivate();
                SensorBMA253_Deactivate();
            }
            else
            {
                /* Activate task */
                SensorBMP280_Activate();
                SensorBMA253_Activate();
                Baseball3xsConfig = newValue;
            }
        } else
        {
            /* Make sure the previous characteristics value is restored */
            initBaseball3xsCharacteristicValue(BASEBALL3xs_CONF, Baseball3xsConfig, sizeof(uint8_t));
        }

        break;

    default:
        break;
    }
}
static void initBaseball3xsCharacteristicValue(uint8_t paramID, uint8_t value, uint8_t paramLen)
{
    uint8_t data[BASEBALL3xs_DATA_LEN];

    memset(data, value, paramLen);
    Baseball3xs_setParameter(paramID, paramLen, data);
}

static void ALL_Sensor_Disable(void)
{
    /* Deactivate task */
    //SensorBMP280_Deactivate();
    //SensorBMA253_Deactivate();
    //SensorBHI160_Deactivate();
    SensorICM20649_Deactivate();
    SensorA301_Deactivate();
    Timer_stop(timer0);
    HwiP_disableInterrupt(40);
    MAP_ADC14_disableConversion();
    if(store_en == true)
    {
        closeflash();
        store_en = false;
    }
    Display_print0(displayOut, 0, 0, "All sensor disabled!");
}



DS-00242-GD5F1GQ4xBxIG-Rev1.3.pdf

#include <file.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <mqueue.h>
#include <semaphore.h>
#include <pthread.h>
#include <unistd.h>
#include <ti/display/Display.h>
#include "BLEsend.h"
#include "flash_driver/MT29Flash.h"
#include "Board.h"
#include "flashctrl.h"

//Set this to the current UNIX time in seconds
const struct timespec flashts = {
    .tv_sec = 1470009600, //1469647026(2016/06/27/ 19:17:09)//1469923197
    .tv_nsec = 0
};

static SPI_Handle      spihandle;
static pthread_t       flashTask;

static volatile bool   Sampledata = false;
static volatile bool   write_init = true;

static pthread_mutex_t lockbuffer;
static pthread_mutex_t lockflash;
static pthread_cond_t  condflash;

static sem_t spaceFlashsem;
static sem_t countFlashsem;

static uint8_t  ringbuffer[NUMFLASH][DATA_LEN];


static uint16_t in  = 0;
static uint16_t out = 0;

/* Variables for the CIO functions */

static uint32_t day;
static uint32_t hour;
static uint32_t min;
static uint32_t sec;

extern Display_Handle displayOut;

static int_fast32_t udAddr = 0;
/*******************************************************************************
 *                                  LOCAL FUNCTIONS
 ******************************************************************************/
static void *flashTaskFxn(void *arg0);
static void getdata(uint8_t *result);
static void hextostr(uint8_t *value, char *result);
static void strtohex(char *value, uint8_t *result);
void flasheraseall(void);
//int_fast16_t FLASH_read(SPI_Handle handle);
//int_fast16_t FLASH_write(SPI_Handle handle, const void *buf, uint16_t count);

void flash_createTask(void)
{
    pthread_attr_t      attrs;
    struct sched_param  priParam;
    int                 retc;
    int                 detachState;

    /* Set priority and stack size attributes */
    pthread_attr_init(&attrs);
    priParam.sched_priority = FLASH_TASK_PRIORITY;

    detachState = PTHREAD_CREATE_DETACHED;
    retc = pthread_attr_setdetachstate(&attrs, detachState);
    if (retc != 0)
    {
        while (1);
    }

    pthread_attr_setschedparam(&attrs, &priParam);

    retc |= pthread_attr_setstacksize(&attrs, FLASH_TASK_STACK_SIZE);
    if (retc != 0)
    {
        while (1);
    }

    retc = pthread_create(&flashTask, &attrs, flashTaskFxn, NULL);
    if (retc != 0)
    {
        while (1);
    }

    // Initializing the semaphore
    sem_init(&spaceFlashsem,0,NUMFLASH);
    sem_init(&countFlashsem,0,0);
}

static void flashTaskInit(void)
{

    SPI_Params spiParams;

    SPI_Params_init(&spiParams);
    spiParams.frameFormat = SPI_POL0_PHA0;
    spiParams.bitRate = 2500000;//2.5M 2500000
    spihandle = SPI_open(Board_SPI0, &spiParams);
    if (spihandle == NULL) {
        Display_printf(displayOut, 0, 0, "Error Flash initializing SPI");
        while (1);
    }
    else {
        Display_printf(displayOut, 0, 0, "Flash SPI initialized");
    }
    usleep(250);//a minimum of 250us must elapse before issuing a RESET (FFh) command

    FLASH_initialize(spihandle);

    /*
    while(udAddr < NUM_BLOCKS * NUM_PAGE_BLOCK * PAGE_DATA_SIZE)
    {
        FlashBlockErase(handle, udAddr);
        udAddr =+ NUM_PAGE_BLOCK * PAGE_DATA_SIZE;
    }
    */

    udAddr = 0;
    pthread_mutex_init(&lockbuffer, NULL);
    pthread_mutex_init(&lockflash, NULL);
    pthread_cond_init(&condflash, NULL);
}

static void *flashTaskFxn(void *arg0)
{
    /* Variables to keep track of the file copy progress */
    //unsigned int   bytesWritten = 0;
    char    array[DATA_LEN*2+1];
    uint8_t sendData[20];


    flashTaskInit();
    while (1) {
        pthread_mutex_lock(&lockflash);
        while(!Sampledata)
        {
            pthread_cond_wait(&condflash, &lockflash);//wait pthread_cond_signal() to wake up
        }
        pthread_mutex_unlock(&lockflash);
/*#ifdef debug
        //this should be closed when using, or it will cause surge output signal
        getTime();
#endif*/
        getdata(sendData);
/*
#ifdef debug
        Display_printf(displayOut, 0, 0, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
                       sendData[0],sendData[1],sendData[2],sendData[3],sendData[4],sendData[5],sendData[6],sendData[7],sendData[8],sendData[9],
                       sendData[10],sendData[11],sendData[12],sendData[13],sendData[14],sendData[15],sendData[16],sendData[17],sendData[18],sendData[19]);
#endif
*/
        hextostr(sendData, array);
        FLASH_write(spihandle, &array, DATA_LEN*2+1);
        udAddr += DATA_LEN*2+1;

        if (udAddr >=  NUM_BLOCKS * NUM_PAGE_BLOCK * PAGE_DATA_SIZE)
        {
            Display_printf(displayOut, 0, 0, "Disk Full!");
        }
    }
}

/*
 *  ======== fatfs_getFatTime ========
 */
int clock_init(void)
{
    int clock_set = 1;
    clock_set = clock_settime(CLOCK_REALTIME, &flashts);
    return clock_set;
}

void getTime(void)
{
    time_t seconds;
    struct tm *pTime;

    seconds = time(NULL);
    pTime = localtime(&seconds);


    Display_printf(displayOut, 0, 0, "%02d %02d:%02d:%02d",pTime->tm_mday,pTime->tm_hour,pTime->tm_min,pTime->tm_sec);


    day  = pTime->tm_mday;
    hour = pTime->tm_hour;
    min  = pTime->tm_min;
    sec  = pTime->tm_sec;
}

void openflash(void)
{

    //uint8_t  i = 1;
    //char *deletfile;
    char time[13];
    //write the begining time
 /*   if(write_init)  //orignal have
    {
        getTime();
        time[0]  = ' ';
        time[1]  = day/10  + '0';
        time[2]  = day%10-1  + '0';
        time[3]  = ' ';
        time[4]  = hour/10 + '0';
        time[5]  = hour%10 + '0';
        time[6]  = ':';
        time[7]  = min/10  + '0';
        time[8]  = min%10  + '0';
        time[9]  = ':';
        time[10] = sec/10  + '0';
        time[11] = sec%10  + '0';
        time[12] = '\n';
        //FlashPageProgram(handle, udAddr, *time, 13);
        FLASH_write(handle, &time, 13);
        udAddr += 13;
        write_init = false;
    }*/
///////////  orignal haven't  //////////////////////
    getTime();
    time[0]  = ' ';
    time[1]  = day/10  + '0';
    time[2]  = day%10-1  + '0';
    time[3]  = ' ';
    time[4]  = hour/10 + '0';
    time[5]  = hour%10 + '0';
    time[6]  = ':';
    time[7]  = min/10  + '0';
    time[8]  = min%10  + '0';
    time[9]  = ':';
    time[10] = sec/10  + '0';
    time[11] = sec%10  + '0';
    time[12] = '\n';
    //FLASH_write(spihandle, &time, 13);
    //udAddr += 13;
////////////////////////////////////
    pthread_mutex_lock(&lockflash);
    Sampledata = true;
    pthread_cond_signal(&condflash);
    pthread_mutex_unlock(&lockflash);
}

void closeflash(void)
{
    char time[13];

    pthread_mutex_lock(&lockflash);
    Sampledata = false;
    pthread_mutex_unlock(&lockflash);

    getTime();
    time[0] = ' ';
    time[1] = day/10  + '0';
    time[2] = day%10-1  + '0';
    time[3] = ' ';
    time[4] = hour/10 + '0';
    time[5] = hour%10 + '0';
    time[6] = ':';
    time[7] = min/10  + '0';
    time[8] = min%10  + '0';
    time[9] = ':';
    time[10] = sec/10  + '0';
    time[11] = sec%10  + '0';
    time[12] = '\n';

    //FlashPageProgram(handle, udAddr, *time, 13);
    FLASH_write(spihandle, &time, 2048-(udAddr%2048));//13
    udAddr += 2048-(udAddr%2048); //orignal haven't
    //FlashWriteDisable(handle);
    //udAddr += 13;
    //flash_change_flag = false;  //orignal haven't
    //write_init = true;  //orignal haven't
}

void sendtoStore(uint8_t *value)
{
    // wait if there is no space left:
    sem_wait(&spaceFlashsem);

    pthread_mutex_lock(&lockbuffer);
    memcpy(ringbuffer + ((in++) & (NUMFLASH-1)), value, 20);
    pthread_mutex_unlock(&lockbuffer);

    // increment the count of the number of items
    sem_post(&countFlashsem);
}

static void getdata(uint8_t *result)
{
    // Wait if there are no items in the buffer
    sem_wait(&countFlashsem);

    pthread_mutex_lock(&lockbuffer);
    memcpy(result, ringbuffer + ((out++) & (NUMFLASH-1)), 20);
    pthread_mutex_unlock(&lockbuffer);

    // Increment the count of the number of spaces
    sem_post(&spaceFlashsem);

}
static void hextostr(uint8_t *value, char *result)
{
    int i;
    uint8_t n0,n1;

    for(i = 0; i < DATA_LEN; i++)
    {
        n0 = (value[i]>>4) & 0x0f;
        n1 = value[i] & 0x0f;
        switch(n0)
        {
            case 0x00:
            result[2*i]='0';break;
            case 0x01:
            result[2*i]='1';break;
            case 0x02:
            result[2*i]='2';break;
            case 0x03:
            result[2*i]='3';break;
            case 0x04:
            result[2*i]='4';break;
            case 0x05:
            result[2*i]='5';break;
            case 0x06:
            result[2*i]='6';break;
            case 0x07:
            result[2*i]='7';break;
            case 0x08:
            result[2*i]='8';break;
            case 0x09:
            result[2*i]='9';break;
            case 0x0a:
            result[2*i]='a';break;
            case 0x0b:
            result[2*i]='b';break;
            case 0x0c:
            result[2*i]='c';break;
            case 0x0d:
            result[2*i]='d';break;
            case 0x0e:
            result[2*i]='e';break;
            case 0x0f:
            result[2*i]='f';break;
            default:
            result[2*i]='f';break;
        }
        switch(n1)
        {
            case 0x00:
            result[2*i+1]='0';break;
            case 0x01:
            result[2*i+1]='1';break;
            case 0x02:
            result[2*i+1]='2';break;
            case 0x03:
            result[2*i+1]='3';break;
            case 0x04:
            result[2*i+1]='4';break;
            case 0x05:
            result[2*i+1]='5';break;
            case 0x06:
            result[2*i+1]='6';break;
            case 0x07:
            result[2*i+1]='7';break;
            case 0x08:
            result[2*i+1]='8';break;
            case 0x09:
            result[2*i+1]='9';break;
            case 0x0a:
            result[2*i+1]='a';break;
            case 0x0b:
            result[2*i+1]='b';break;
            case 0x0c:
            result[2*i+1]='c';break;
            case 0x0d:
            result[2*i+1]='d';break;
            case 0x0e:
            result[2*i+1]='e';break;
            case 0x0f:
            result[2*i+1]='f';break;
            default:
            result[2*i+1]='f';break;
        }
    }
    result[2*DATA_LEN]   = '\n';
}
static void strtohex(char *value, uint8_t *result)
{
    int i;
    uint8_t n0,n1;

    for(i = 0; i < DATA_LEN*2; i=i+2)
    {
        n0 = value[i];
        n1 = value[i+1];
        result[i/2] = 0x00;
        switch(n0)
        {
            case '0':
                result[i/2] = result[i/2] | 0x00; break;
            case '1':
                result[i/2] = result[i/2] | 0x10; break;
            case '2':
                result[i/2] = result[i/2] | 0x20; break;
            case '3':
                result[i/2] = result[i/2] | 0x30; break;
            case '4':
                result[i/2] = result[i/2] | 0x40; break;
            case '5':
                result[i/2] = result[i/2] | 0x50; break;
            case '6':
                result[i/2] = result[i/2] | 0x60; break;
            case '7':
                result[i/2] = result[i/2] | 0x70; break;
            case '8':
                result[i/2] = result[i/2] | 0x80; break;
            case '9':
                result[i/2] = result[i/2] | 0x90; break;
            case 'a':
                result[i/2] = result[i/2] | 0xa0; break;
            case 'b':
                result[i/2] = result[i/2] | 0xb0; break;
            case 'c':
                result[i/2] = result[i/2] | 0xc0; break;
            case 'd':
                result[i/2] = result[i/2] | 0xd0; break;
            case 'e':
                result[i/2] = result[i/2] | 0xe0; break;
            case 'f':
                result[i/2] = result[i/2] | 0xf0; break;
            default:
                result[i/2] = result[i/2] | 0x00; break;
        }
        switch(n1)
        {
            case '0':
                result[i/2] = result[i/2] | 0x00; break;
            case '1':
                result[i/2] = result[i/2] | 0x01; break;
            case '2':
                result[i/2] = result[i/2] | 0x02; break;
            case '3':
                result[i/2] = result[i/2] | 0x03; break;
            case '4':
                result[i/2] = result[i/2] | 0x04; break;
            case '5':
                result[i/2] = result[i/2] | 0x05; break;
            case '6':
                result[i/2] = result[i/2] | 0x06; break;
            case '7':
                result[i/2] = result[i/2] | 0x07; break;
            case '8':
                result[i/2] = result[i/2] | 0x08; break;
            case '9':
                result[i/2] = result[i/2] | 0x09; break;
            case 'a':
                result[i/2] = result[i/2] | 0x0a; break;
            case 'b':
                result[i/2] = result[i/2] | 0x0b; break;
            case 'c':
                result[i/2] = result[i/2] | 0x0c; break;
            case 'd':
                result[i/2] = result[i/2] | 0x0d; break;
            case 'e':
                result[i/2] = result[i/2] | 0x0e; break;
            case 'f':
                result[i/2] = result[i/2] | 0x0f; break;
            default:
                result[i/2] = result[i/2] | 0x00; break;
        }
    }
}

void outputflashdata(void)
{
    //FLASH_read(spihandle);

    bool empty = false;
    int i;

    char    array[DATA_LEN*2+1];
    uint8_t sendData[DATA_LEN];
    while(!empty)
    {
        empty = FLASH_read(spihandle, array);
        Display_printf(displayOut, 0, 0, "char = %s", array);
        strtohex(array, sendData);
/*
        Display_printf(displayOut, 0, 0, "hex = %x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x", sendData[0], sendData[1], sendData[2], sendData[3], sendData[4], sendData[5], sendData[6],
                                                                                           sendData[7], sendData[8], sendData[9], sendData[10], sendData[11], sendData[12], sendData[13],
                                                                                           sendData[14], sendData[15], sendData[16], sendData[17], sendData[18], sendData[19]);
*/
        enqueue(sendData);
        usleep(6000);
    }

}
void flasheraseall(void)
{
    udAddr = 0;
    //uint8_t statusregister;
    while(udAddr < (NUM_BLOCKS-2) * NUM_PAGE_BLOCK * PAGE_DATA_SIZE)
    {
        FlashBlockErase(spihandle, udAddr);
        //FlashReadStatusRegister(handle, &statusregister);
        //Display_printf(display, 0, 0, "after %d erase, status = %02x",udAddr, statusregister);
        udAddr += NUM_PAGE_BLOCK * PAGE_DATA_SIZE;
    }
    Display_printf(displayOut, 0, 0, "erase finish!");
    udAddr = 0;
}
flashctrl.h

  • Hi Brian,

    Could you clarify where these files comes from, is the "FLASH" driver something you written or something you found somewhere else (it was also not attached to the thread if this was what you intended)?

  • Hi TI expert

    Could you see my attachment?

    It is from my senior's written.

    #include <file.h>
    #include <stdbool.h>
    #include <stddef.h>
    #include <stdint.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <time.h>
    #include <mqueue.h>
    #include <semaphore.h>
    #include <pthread.h>
    #include <unistd.h>
    #include <ti/display/Display.h>
    #include "BLEsend.h"
    #include "flash_driver/MT29Flash.h"
    #include "Board.h"
    #include "flashctrl.h"
    
    //Set this to the current UNIX time in seconds
    const struct timespec flashts = {
        .tv_sec = 1470009600, //1469647026(2016/06/27/ 19:17:09)//1469923197
        .tv_nsec = 0
    };
    
    static SPI_Handle      spihandle;
    static pthread_t       flashTask;
    
    static volatile bool   Sampledata = false;
    static volatile bool   write_init = true;
    
    static pthread_mutex_t lockbuffer;
    static pthread_mutex_t lockflash;
    static pthread_cond_t  condflash;
    
    static sem_t spaceFlashsem;
    static sem_t countFlashsem;
    
    static uint8_t  ringbuffer[NUMFLASH][DATA_LEN];
    
    
    static uint16_t in  = 0;
    static uint16_t out = 0;
    
    /* Variables for the CIO functions */
    
    static uint32_t day;
    static uint32_t hour;
    static uint32_t min;
    static uint32_t sec;
    
    extern Display_Handle displayOut;
    
    static int_fast32_t udAddr = 0;
    /*******************************************************************************
     *                                  LOCAL FUNCTIONS
     ******************************************************************************/
    static void *flashTaskFxn(void *arg0);
    static void getdata(uint8_t *result);
    static void hextostr(uint8_t *value, char *result);
    static void strtohex(char *value, uint8_t *result);
    void flasheraseall(void);
    //int_fast16_t FLASH_read(SPI_Handle handle);
    //int_fast16_t FLASH_write(SPI_Handle handle, const void *buf, uint16_t count);
    
    void flash_createTask(void)
    {
        pthread_attr_t      attrs;
        struct sched_param  priParam;
        int                 retc;
        int                 detachState;
    
        /* Set priority and stack size attributes */
        pthread_attr_init(&attrs);
        priParam.sched_priority = FLASH_TASK_PRIORITY;
    
        detachState = PTHREAD_CREATE_DETACHED;
        retc = pthread_attr_setdetachstate(&attrs, detachState);
        if (retc != 0)
        {
            while (1);
        }
    
        pthread_attr_setschedparam(&attrs, &priParam);
    
        retc |= pthread_attr_setstacksize(&attrs, FLASH_TASK_STACK_SIZE);
        if (retc != 0)
        {
            while (1);
        }
    
        retc = pthread_create(&flashTask, &attrs, flashTaskFxn, NULL);
        if (retc != 0)
        {
            while (1);
        }
    
        // Initializing the semaphore
        sem_init(&spaceFlashsem,0,NUMFLASH);
        sem_init(&countFlashsem,0,0);
    }
    
    static void flashTaskInit(void)
    {
    
        SPI_Params spiParams;
    
        SPI_Params_init(&spiParams);
        spiParams.frameFormat = SPI_POL0_PHA0;
        spiParams.bitRate = 2500000;//2.5M 2500000
        spihandle = SPI_open(Board_SPI0, &spiParams);
        if (spihandle == NULL) {
            Display_printf(displayOut, 0, 0, "Error Flash initializing SPI");
            while (1);
        }
        else {
            Display_printf(displayOut, 0, 0, "Flash SPI initialized");
        }
        usleep(250);//a minimum of 250us must elapse before issuing a RESET (FFh) command
    
        FLASH_initialize(spihandle);
    
        /*
        while(udAddr < NUM_BLOCKS * NUM_PAGE_BLOCK * PAGE_DATA_SIZE)
        {
            FlashBlockErase(handle, udAddr);
            udAddr =+ NUM_PAGE_BLOCK * PAGE_DATA_SIZE;
        }
        */
    
        udAddr = 0;
        pthread_mutex_init(&lockbuffer, NULL);
        pthread_mutex_init(&lockflash, NULL);
        pthread_cond_init(&condflash, NULL);
    }
    
    static void *flashTaskFxn(void *arg0)
    {
        /* Variables to keep track of the file copy progress */
        //unsigned int   bytesWritten = 0;
        char    array[DATA_LEN*2+1];
        uint8_t sendData[20];
    
    
        flashTaskInit();
        while (1) {
            pthread_mutex_lock(&lockflash);
            while(!Sampledata)
            {
                pthread_cond_wait(&condflash, &lockflash);//wait pthread_cond_signal() to wake up
            }
            pthread_mutex_unlock(&lockflash);
    /*#ifdef debug
            //this should be closed when using, or it will cause surge output signal
            getTime();
    #endif*/
            getdata(sendData);
    /*
    #ifdef debug
            Display_printf(displayOut, 0, 0, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
                           sendData[0],sendData[1],sendData[2],sendData[3],sendData[4],sendData[5],sendData[6],sendData[7],sendData[8],sendData[9],
                           sendData[10],sendData[11],sendData[12],sendData[13],sendData[14],sendData[15],sendData[16],sendData[17],sendData[18],sendData[19]);
    #endif
    */
            hextostr(sendData, array);
            FLASH_write(spihandle, &array, DATA_LEN*2+1);
            udAddr += DATA_LEN*2+1;
    
            if (udAddr >=  NUM_BLOCKS * NUM_PAGE_BLOCK * PAGE_DATA_SIZE)
            {
                Display_printf(displayOut, 0, 0, "Disk Full!");
            }
        }
    }
    
    /*
     *  ======== fatfs_getFatTime ========
     */
    int clock_init(void)
    {
        int clock_set = 1;
        clock_set = clock_settime(CLOCK_REALTIME, &flashts);
        return clock_set;
    }
    
    void getTime(void)
    {
        time_t seconds;
        struct tm *pTime;
    
        seconds = time(NULL);
        pTime = localtime(&seconds);
    
    
        Display_printf(displayOut, 0, 0, "%02d %02d:%02d:%02d",pTime->tm_mday,pTime->tm_hour,pTime->tm_min,pTime->tm_sec);
    
    
        day  = pTime->tm_mday;
        hour = pTime->tm_hour;
        min  = pTime->tm_min;
        sec  = pTime->tm_sec;
    }
    
    void openflash(void)
    {
    
        //uint8_t  i = 1;
        //char *deletfile;
        char time[13];
        //write the begining time
     /*   if(write_init)  //orignal have
        {
            getTime();
            time[0]  = ' ';
            time[1]  = day/10  + '0';
            time[2]  = day%10-1  + '0';
            time[3]  = ' ';
            time[4]  = hour/10 + '0';
            time[5]  = hour%10 + '0';
            time[6]  = ':';
            time[7]  = min/10  + '0';
            time[8]  = min%10  + '0';
            time[9]  = ':';
            time[10] = sec/10  + '0';
            time[11] = sec%10  + '0';
            time[12] = '\n';
            //FlashPageProgram(handle, udAddr, *time, 13);
            FLASH_write(handle, &time, 13);
            udAddr += 13;
            write_init = false;
        }*/
    ///////////  orignal haven't  //////////////////////
        getTime();
        time[0]  = ' ';
        time[1]  = day/10  + '0';
        time[2]  = day%10-1  + '0';
        time[3]  = ' ';
        time[4]  = hour/10 + '0';
        time[5]  = hour%10 + '0';
        time[6]  = ':';
        time[7]  = min/10  + '0';
        time[8]  = min%10  + '0';
        time[9]  = ':';
        time[10] = sec/10  + '0';
        time[11] = sec%10  + '0';
        time[12] = '\n';
        //FLASH_write(spihandle, &time, 13);
        //udAddr += 13;
    ////////////////////////////////////
        pthread_mutex_lock(&lockflash);
        Sampledata = true;
        pthread_cond_signal(&condflash);
        pthread_mutex_unlock(&lockflash);
    }
    
    void closeflash(void)
    {
        char time[13];
    
        pthread_mutex_lock(&lockflash);
        Sampledata = false;
        pthread_mutex_unlock(&lockflash);
    
        getTime();
        time[0] = ' ';
        time[1] = day/10  + '0';
        time[2] = day%10-1  + '0';
        time[3] = ' ';
        time[4] = hour/10 + '0';
        time[5] = hour%10 + '0';
        time[6] = ':';
        time[7] = min/10  + '0';
        time[8] = min%10  + '0';
        time[9] = ':';
        time[10] = sec/10  + '0';
        time[11] = sec%10  + '0';
        time[12] = '\n';
    
        //FlashPageProgram(handle, udAddr, *time, 13);
        FLASH_write(spihandle, &time, 2048-(udAddr%2048));//13
        udAddr += 2048-(udAddr%2048); //orignal haven't
        //FlashWriteDisable(handle);
        //udAddr += 13;
        //flash_change_flag = false;  //orignal haven't
        //write_init = true;  //orignal haven't
    }
    
    void sendtoStore(uint8_t *value)
    {
        // wait if there is no space left:
        sem_wait(&spaceFlashsem);
    
        pthread_mutex_lock(&lockbuffer);
        memcpy(ringbuffer + ((in++) & (NUMFLASH-1)), value, 20);
        pthread_mutex_unlock(&lockbuffer);
    
        // increment the count of the number of items
        sem_post(&countFlashsem);
    }
    
    static void getdata(uint8_t *result)
    {
        // Wait if there are no items in the buffer
        sem_wait(&countFlashsem);
    
        pthread_mutex_lock(&lockbuffer);
        memcpy(result, ringbuffer + ((out++) & (NUMFLASH-1)), 20);
        pthread_mutex_unlock(&lockbuffer);
    
        // Increment the count of the number of spaces
        sem_post(&spaceFlashsem);
    
    }
    static void hextostr(uint8_t *value, char *result)
    {
        int i;
        uint8_t n0,n1;
    
        for(i = 0; i < DATA_LEN; i++)
        {
            n0 = (value[i]>>4) & 0x0f;
            n1 = value[i] & 0x0f;
            switch(n0)
            {
                case 0x00:
                result[2*i]='0';break;
                case 0x01:
                result[2*i]='1';break;
                case 0x02:
                result[2*i]='2';break;
                case 0x03:
                result[2*i]='3';break;
                case 0x04:
                result[2*i]='4';break;
                case 0x05:
                result[2*i]='5';break;
                case 0x06:
                result[2*i]='6';break;
                case 0x07:
                result[2*i]='7';break;
                case 0x08:
                result[2*i]='8';break;
                case 0x09:
                result[2*i]='9';break;
                case 0x0a:
                result[2*i]='a';break;
                case 0x0b:
                result[2*i]='b';break;
                case 0x0c:
                result[2*i]='c';break;
                case 0x0d:
                result[2*i]='d';break;
                case 0x0e:
                result[2*i]='e';break;
                case 0x0f:
                result[2*i]='f';break;
                default:
                result[2*i]='f';break;
            }
            switch(n1)
            {
                case 0x00:
                result[2*i+1]='0';break;
                case 0x01:
                result[2*i+1]='1';break;
                case 0x02:
                result[2*i+1]='2';break;
                case 0x03:
                result[2*i+1]='3';break;
                case 0x04:
                result[2*i+1]='4';break;
                case 0x05:
                result[2*i+1]='5';break;
                case 0x06:
                result[2*i+1]='6';break;
                case 0x07:
                result[2*i+1]='7';break;
                case 0x08:
                result[2*i+1]='8';break;
                case 0x09:
                result[2*i+1]='9';break;
                case 0x0a:
                result[2*i+1]='a';break;
                case 0x0b:
                result[2*i+1]='b';break;
                case 0x0c:
                result[2*i+1]='c';break;
                case 0x0d:
                result[2*i+1]='d';break;
                case 0x0e:
                result[2*i+1]='e';break;
                case 0x0f:
                result[2*i+1]='f';break;
                default:
                result[2*i+1]='f';break;
            }
        }
        result[2*DATA_LEN]   = '\n';
    }
    static void strtohex(char *value, uint8_t *result)
    {
        int i;
        uint8_t n0,n1;
    
        for(i = 0; i < DATA_LEN*2; i=i+2)
        {
            n0 = value[i];
            n1 = value[i+1];
            result[i/2] = 0x00;
            switch(n0)
            {
                case '0':
                    result[i/2] = result[i/2] | 0x00; break;
                case '1':
                    result[i/2] = result[i/2] | 0x10; break;
                case '2':
                    result[i/2] = result[i/2] | 0x20; break;
                case '3':
                    result[i/2] = result[i/2] | 0x30; break;
                case '4':
                    result[i/2] = result[i/2] | 0x40; break;
                case '5':
                    result[i/2] = result[i/2] | 0x50; break;
                case '6':
                    result[i/2] = result[i/2] | 0x60; break;
                case '7':
                    result[i/2] = result[i/2] | 0x70; break;
                case '8':
                    result[i/2] = result[i/2] | 0x80; break;
                case '9':
                    result[i/2] = result[i/2] | 0x90; break;
                case 'a':
                    result[i/2] = result[i/2] | 0xa0; break;
                case 'b':
                    result[i/2] = result[i/2] | 0xb0; break;
                case 'c':
                    result[i/2] = result[i/2] | 0xc0; break;
                case 'd':
                    result[i/2] = result[i/2] | 0xd0; break;
                case 'e':
                    result[i/2] = result[i/2] | 0xe0; break;
                case 'f':
                    result[i/2] = result[i/2] | 0xf0; break;
                default:
                    result[i/2] = result[i/2] | 0x00; break;
            }
            switch(n1)
            {
                case '0':
                    result[i/2] = result[i/2] | 0x00; break;
                case '1':
                    result[i/2] = result[i/2] | 0x01; break;
                case '2':
                    result[i/2] = result[i/2] | 0x02; break;
                case '3':
                    result[i/2] = result[i/2] | 0x03; break;
                case '4':
                    result[i/2] = result[i/2] | 0x04; break;
                case '5':
                    result[i/2] = result[i/2] | 0x05; break;
                case '6':
                    result[i/2] = result[i/2] | 0x06; break;
                case '7':
                    result[i/2] = result[i/2] | 0x07; break;
                case '8':
                    result[i/2] = result[i/2] | 0x08; break;
                case '9':
                    result[i/2] = result[i/2] | 0x09; break;
                case 'a':
                    result[i/2] = result[i/2] | 0x0a; break;
                case 'b':
                    result[i/2] = result[i/2] | 0x0b; break;
                case 'c':
                    result[i/2] = result[i/2] | 0x0c; break;
                case 'd':
                    result[i/2] = result[i/2] | 0x0d; break;
                case 'e':
                    result[i/2] = result[i/2] | 0x0e; break;
                case 'f':
                    result[i/2] = result[i/2] | 0x0f; break;
                default:
                    result[i/2] = result[i/2] | 0x00; break;
            }
        }
    }
    
    void outputflashdata(void)
    {
        //FLASH_read(spihandle);
    
        bool empty = false;
        int i;
    
        char    array[DATA_LEN*2+1];
        uint8_t sendData[DATA_LEN];
        while(!empty)
        {
            empty = FLASH_read(spihandle, array);
            Display_printf(displayOut, 0, 0, "char = %s", array);
            strtohex(array, sendData);
    
            enqueue(sendData);
    usleep(6000); } } void flasheraseall(void) { udAddr = 0; //uint8_t statusregister; while(udAddr < (NUM_BLOCKS-2) * NUM_PAGE_BLOCK * PAGE_DATA_SIZE) { FlashBlockErase(spihandle, udAddr); //FlashReadStatusRegister(handle, &statusregister); //Display_printf(display, 0, 0, "after %d erase, status = %02x",udAddr, statusregister); udAddr += NUM_PAGE_BLOCK * PAGE_DATA_SIZE; } Display_printf(displayOut, 0, 0, "erase finish!"); udAddr = 0; }

  • I can see the code, but I know what the "FLASH_*" API is and where it comes from. Is this something you have written yourself?

  • Hi TI expert

    I used Code Composer Studio 7.4.0,and this code is almost from my senior graduate student,

    thanks~

    Best regards,

    Brian Chen

  • Hi Brian,

    It is hard for me to give you support on software that is not from TI and that I do not know anything about.

    I would advice you to make a small test example to just setup the read/write interface to you flash.

    You could also experiment with our NVS driver. Even tho it was not made for this type of external flash, you might be able to tweak it to work for you as well.

  • Hi TI expert

    Thank you for your kindly assistance,

    Finally I can use my external flash memory to print out the accurate data on the CCS console while I write/read the sample case,

    but I  want to use blue tooth CC2640R2 to unload the flash data, but it failed.

    Could you help to analyze for it,

    or do you have any ideas to help me to print out the data from external flash by wireless.

    many thanks~

    void outputflashdata(void)
    {
    
        char    array[DATA_LEN*2+1];
        uint8_t sendData[DATA_LEN];
    
        while(1)
        {
          
            FLASH_read(spihandle, array);
            strtohex(array, sendData);
    
         //   printf("%x",sendData[0]);
        //    printf("%x\n",sendData[1]);
    
           enqueue(sendData);                        //////////////load Data to CC2640R2 //////////
    
          
        }
    
    }

     

  • Hi,

    There is a lot of things to consider when wanting to send data over BLE (like for example how you plan to communicate with the other side).

    I would recommend you read up on the BLE modules in Simplelink Acadamy, they will cover all the basics you need to setup your own custom BLE profiles and send data etc:

    http://dev.ti.com/tirex/explore/node?node=AO9tDQs88Bcw33.wxV2moA__krol.2c__LATEST

  • Hi, 

           I have already setup my own custom BLE profiles and send data,I can use BLE to send data including other sensor,like pressure sensor、

    accerleration、gyroscope and also the ADC from MSP432P401R.

     All of them can sent by BLE except external flash memory can't connect with BLE.

           My question is why the external flash can't connect with BLE,not how to setup BLE.

    Best regards,

    Brian Chen

  • I'm sorry Brian, but I do not understand what you mean with "why the external flash can't connect with BLE". This would be entirely up to you and your application to interface the flash over BLE. If you say you are able to read data from the flash but not able to send it over the BLE conenction, then I suggest you look into how you provide this data to your BLE profile.