
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/fpu.h"
#include "driverlib/gpio.h"
#include "driverlib/interrupt.h"
#include "driverlib/pin_map.h"
#include "driverlib/rom.h"
#include "driverlib/sysctl.h"
#include "driverlib/systick.h"
#include "driverlib/ssi.h"
#include "driverlib/uart.h"
#include "utils/cmdline.h"
#include "utils/uartstdio.h"
#include "fatfs/src/ff.h"
#include "fatfs/src/diskio.h"

#include "inc/hw_can.h"
#include "inc/hw_ints.h"
#include "driverlib/can.h"
#include "driverlib/uart.h"
#include "utils/uartstdio.h"

#include "uart_api.h"
#include "can_api.h"
#include "sd_card.h"

int nStatus;
unsigned int i = 0;
FRESULT iFResult;
FIL fil;
uint32_t count = 8*512;

init_sys()
{
            ROM_FPULazyStackingEnable();
            ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI0);
            ROM_SysTickPeriodSet(ROM_SysCtlClockGet() / 100);
            ROM_SysTickEnable();
            ROM_SysTickIntEnable();
            ROM_IntMasterEnable();
            ConfigureUART();
            InitCAN0();
}

init_sd()
{
            iFResult = f_mount(0, &g_sFatFs);
            if(iFResult != FR_OK)
            {
                UARTprintf("f_mount error: %s\n", StringFromFResult(iFResult));
                return(1);
            }

            power_on();
            BOOL a = wait_ready();
            DSTATUS errd;
            if(a) {
                send_initial_clock_train();
                errd = disk_initialize(0);
                UARTprintf("\nInitialising disk 0. Status = %i\n", errd);
            }
            iFResult = f_open(&fil, "CAN_dlog1.hex", FA_CREATE_ALWAYS|FA_WRITE);
            SysCtlDelay(SysCtlClockGet()/3);
            if(iFResult != FR_OK) {UARTprintf("fresult: %s\n", StringFromFResult(iFResult)); }
            else{UARTprintf("\nOpened SD card\n");}

            iFResult = f_write(&fil, "Count,MID,MIDMask,Flags,MLen,MData \n", 36, &count);
            if(iFResult != FR_OK) {UARTprintf("Error writing to file: %s\n", StringFromFResult(iFResult));}
}


void poll_can()
{
                    if(g_bRXFlag)
                    {
                        g_sCAN0RxMessage.pui8MsgData = (uint8_t *) &g_ui8RXMsgData;
                        CANMessageGet(CAN0_BASE, RXOBJECT, &g_sCAN0RxMessage, 0);
                        g_bRXFlag = 0;

                        if(g_sCAN0RxMessage.ui32Flags & MSG_OBJ_DATA_LOST)
                        {
                            UARTprintf("\nCAN message loss detected\n");
                        }

                                    UARTprintf("%u,",msg_count );
                                    UARTprintf("%u,",g_sCAN0RxMessage.ui32MsgID );
                                    UARTprintf("%u,",g_sCAN0RxMessage.ui32MsgIDMask);
                                    UARTprintf("%u,",g_sCAN0RxMessage.ui32Flags);
                                    UARTprintf("%u,",g_sCAN0RxMessage.ui32MsgLen);
                                    for(i = 0; i < g_sCAN0RxMessage.ui32MsgLen; i++)
                                        UARTprintf("%c", (g_ui8RXMsgData+i));
                                    UARTprintf("\n",1);


                                    iFResult = f_write(&fil, &msg_count, 4, &count);
                                    iFResult = f_write(&fil, &g_sCAN0RxMessage, 16, &count);
                                    iFResult = f_write(&fil, (void *)g_sCAN0RxMessage.pui8MsgData, g_sCAN0RxMessage.ui32MsgLen, &count);
                                    iFResult = f_write(&fil, "...", 3, &count);

                                    msg_count = msg_count + 1;

                    }
                    else
                    {
                        if(g_ui32ErrFlag != 0)
                        {
                            CANErrorHandler();
                        }

                        while(ROM_UARTCharsAvail(UART0_BASE))
                        {
                            if(ROM_UARTCharGetNonBlocking(UART0_BASE)=='s')
                            {
                                iFResult = f_close(&fil);
                                UARTprintf("\nSaving File fresult: %s\n", StringFromFResult(iFResult));
                                f_mount(0, NULL);
                                while(1);
                            }

                    }
         }
}

//*****************************************************************************
//
// The program main function.  It performs initialization, then runs a
// processing loop to read CAN messages, print on console and log on SD card
//
//*****************************************************************************
int main(void)
{
        init_sys();
        UARTprintf("CAN Bus Data Logger\n");
        UARTprintf("Waiting for CAN messages\n");
        while(1)
            {
                poll_can();
            }
 }
