Main Page   Modules   Data Structures   File List   Data Fields   Globals   Related Pages  

Data logger, sample ADC and save on SD.

// Built with BFTC Rev. 1.0.0, sab 21 marzo 2015 08:43:22
/*
    Copyright 2014-2015 Digital Technology Art SRL
    This file is part of Blackfin Toolchain (BFTC) project.

    BFTC is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    BFTC is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Nome-Programma.  If not, see <http://www.gnu.org/licenses/>.
*/
// Simple data logger the sample from A/D converter and save on SD card
// Enjoy!

#include "main.h"
#include "diskio.h"

typedef struct RTCdata {
    unsigned char   hours;
    unsigned char   minutes;
    unsigned char   seconds;
    unsigned char   day;
    unsigned char   month;
    int             year;
    unsigned char   daysPerMonth[12];
}RTCdata;

typedef unsigned short int U16;
typedef unsigned int U32;
typedef float real;

// GLOBALS *********************************************************************
//

RTCdata rtc;
FATFS   FatFs;      // Work area (file system object) for logical drive
bool    signal;

bool isLeapYear(int yearT) 
{
    if(((yearT % 4) == 0) && ((yearT % 100) != 0) || ((yearT % 400) == 0)) 
        return true;
    return false;
}

void rtcInit(RTCdata * t)
{
    t->daysPerMonth[0]  = 31;    // January
    t->daysPerMonth[1]  = 28;    // February
    t->daysPerMonth[2]  = 31;    // March
    t->daysPerMonth[3]  = 30;    // April
    t->daysPerMonth[4]  = 31;    // May
    t->daysPerMonth[5]  = 30;    // June
    t->daysPerMonth[6]  = 31;    // July
    t->daysPerMonth[7]  = 31;    // August
    t->daysPerMonth[8]  = 30;    // September
    t->daysPerMonth[9]  = 31;    // October
    t->daysPerMonth[10] = 30;    // November
    t->daysPerMonth[11] = 31;    // December
    
    t->hours = 0;
    t->minutes = 0;
    t->seconds = 0;
    t->day = 1;
    t->month = 1;
    t->year = 2000;
}

void RTC(RTCdata * t)
{
    unsigned char dayT;
    t->seconds++;
    if(rtc.seconds > 59) 
    {
        t->seconds = 0;
        t->minutes++;
        if(t->minutes > 59) 
        {
            t->minutes = 0;
            t->hours++;
            if(t->hours > 23) 
            {
                t->hours = 0;
                t->day++;
                if(t->month == 2) 
                { 
                    //february?
                    if(isLeapYear(t->year)) 
                        dayT = 29;
                    else 
                        dayT = 28;
                } 
                else 
                    dayT = t->daysPerMonth[t->month - 1];
                if(t->day > dayT) 
                {
                    t->day = 1;
                    t->month++;
                    if(t->month > 12) 
                    {
                        t->month = 1;
                        t->year++;
                    }
                }
            }
        }
    }
}

void diskCB(BYTE drv, DWORD sector, BYTE count)
{
    if((sector % 1024) == 0)
        printf("Drive: %d, Sector: %8d, Count: %3d\n", drv, sector, count);
}

void DiskFormat()
{
    DRESULT dr;
    FRESULT fr; // FatFs return code
    dr = disk_initialize(0);
    if(dr == RES_OK)
    {
        // Register work area to the default drive
        fr = f_mount(&FatFs, "", 0);
        if(fr == RES_OK)
        {
            printf("FAT on SD ready\n");
            disk_setCallback(diskCB);
            fr = f_mkfs("", 0, 4096);
            disk_setCallback(0);
            printf("SD Format done!\n");
            
            fr = f_mount(0, "", 0);
            disk_ioctl(0, CTRL_POWER_OFF, 0);
            printf("FAT unmounted, SD power OFF\n");
        }
        else
        {
            printf("%s\n", disk_errString(dr));
            disk_ioctl(0, CTRL_POWER_OFF, 0);
        }
    }
}

void Sampling(unsigned numSamples, unsigned chans, unsigned delay, unsigned average, const char * fileName)
{
    FRESULT     fr;    // FatFs return code
    DRESULT     dr;
    FIL         fil;   // File object
    char        buff[128], ch;
    unsigned    dly = delay, i, avg, ns = numSamples;
    U32         ad[8];
    
    sprintf(buff, "%s.txt", fileName);
    printf("Init SD and open %s\n", fileName);
    dr = disk_initialize(0);
    if(dr == RES_OK)
    {
        // Register work area to the default drive
        fr = f_mount(&FatFs, "", 0);
        if(fr == RES_OK)
        {
            fr = f_open(&fil, buff, FA_CREATE_ALWAYS | FA_WRITE);
            if(fr) 
            {
                printf("Can't open [%s]\n", buff);
                return;
            }
        }
        else
        {
            printf("%s\n", disk_errString(dr));
            disk_ioctl(0, CTRL_POWER_OFF, 0);
            return;
        }
    }
    signal = false;
    ch = 0;
    printf("Acquisition started: numSamples = %d, chans = %d, delay = %d, average = %d\n", numSamples, chans, delay, average);
    // Acquisition loop
    while(ns && ch != 'X')
    {
        if(signal)
        {
            signal = false;
            dly--;
            if(dly == 0)
            {
                dly = delay;
                // Acquire ****************************************
                Set_SPI(SPI_AD);    // Redirect SPI on AD converter
                // Scan selected channels
                for(i = 0; i < chans; i++)
                {
                    ad[i] = 0;
                    for(avg = 0; avg < average; avg++)
                        ad[i] += Get_AD(1, i);
                    ad[i] /= average;
                }
                // Save sampled data
                Set_SPI(SPI_SD);    // Redirect SPI on SD
                for(i = 0; i < chans; i++)
                {
                    sprintf(buff, "%08d.%d = %04d, %4d/%02d/%02d - %02d:%02d:%02d\n", numSamples - ns, i, ad[i], rtc.year, rtc.month, rtc.day, rtc.hours, rtc.minutes, rtc.seconds);
                    // Save
                    f_puts(buff, &fil);
                    // Dump on video
                    printf("%s", buff);
                }
                ns--;
            }
        }
        // Check if the user request a stop
        if(Signal_Uart0())
            ch = GetChar_Uart0();
    }
    f_close(&fil);
    fr = f_mount(0, "", 0);
    disk_ioctl(0, CTRL_POWER_OFF, 0);
}

void BackgroundProcess()
{
    RTC(&rtc);
    signal = true;
}

int GetInt(const char * label, int low, int high)
{
    int     ret;
    printf("\n%s ", label);
    _scanf("%d", &ret);
    if(ret < low) ret = low;
    if(ret > high) ret = high;
    printf("\n");
    return ret;
}

int Menu()
{
    printf("%4d/%02d/%02d - %02d:%02d:%02d\n", rtc.year, rtc.month, rtc.day, rtc.hours, rtc.minutes, rtc.seconds);
    printf("----- M E N U ---------\n");
    printf("D - Set date\n");
    printf("T - Set time\n");
    printf("F - SD Format\n");
    printf("S - Start sampling\n");
    printf("\n> ");
    return (GetChar_Uart0());
}

int main(void)
{
    int         com;
    char        fileName[12];
    Set_PLL(16, 4);             // CORE: 25MHz * 16 = 400MHz, SCLK: 400MHz / 4 = 100MHz
    Set_Port();                 // Set the port according to project set
    Set_Uart0(115200);  // printf is redirected to UART0
    
    Set_TimerInterruptService(TIMER_0, &BackgroundProcess, 1000000);
    rtcInit(&rtc);
    
    // My default date!
    rtc.year = 2015;
    rtc.month = 3;
    rtc.day = 21;
    rtc.hours = 12;
    rtc.minutes = 0;
    rtc.seconds = 0;
    // Start background process
    Set_TimerEnable(TIMER_0, true);
    
    while(1)                    // Main loop
    {
        com = Menu();
        printf("\n");
        switch(com)
        {
            case 'D':   rtc.year = GetInt("Current year [2015] =", 2015, 2099);
                        rtc.month = GetInt("Current month [1:12] =", 1, 12);
                        rtc.day = GetInt("Current day [1:31] =", 1, 31);
                        break;
            case 'T':   rtc.hours = GetInt("Hour [0:23] =", 0, 23);
                        rtc.minutes = GetInt("Minute [0:59] =", 0, 59);
                        rtc.seconds = GetInt("Second [0:59] =", 0, 59);
                        break;
            case 'F':   DiskFormat();
                        break;
            case 'S':   printf("File name without extension (max 8 chars): ");
                        _scanf("%s", fileName);
                        if(_strlen(fileName) > 8)   // Don't accept long file name!
                            fileName[8] = 0;
                        Sampling(
                                    GetInt("Number of samples  [1:1000000] =", 1, 1000000),
                                    GetInt("Number of channels [1:8]       =", 1, 8),
                                    GetInt("Interval delay (s) [1:3600]    =", 1, 3600),
                                    GetInt("Samples average    [1:100]     =", 1, 1000000),
                                    fileName);
                        break;
            default:    printf("\nUnknown command\n");
        }
    }
    return 0;
}

Generated on Tue Apr 7 20:07:44 2015 for BF592A Library by doxygen 1.3.1