Austins SD card logger

Dependencies:   mbed SDFileSystem

main.cpp

Committer:
austinbrown124
Date:
2020-04-04
Revision:
4:4bd2b85412c3
Parent:
3:8d4c12a3b5d4

File content as of revision 4:4bd2b85412c3:

#include "mbed.h"
#include "SDFileSystem.h"
#include "string.h"



/*

F401 Data Logger
Many problems were encountered. It seems that the data logger just needs the 32.7678whe KhZ crystal to run both
the SD card and the RTC. 



Had to split testing code into 2 and real code into 2B. This is because the serials are effectively hardcoded, RIP.
USART6 must be changed to USART2


UNTESTED. But I belive this should work!!

*/
 
/*SD card*/
#define DI PB_5
#define DO PB_4
#define SCK PB_3
#define CS PB_6
 

char fname[255];
char current_time[64];

 
/*Serial buffer*/
#define PAGE_SIZE 4096
#define CHUNK_SIZE (2*PAGE_SIZE)  //double size copy
#define BUF_SIZE (2*CHUNK_SIZE)    //total buffer len
 
//RTC
#define SET_TIME false //true
 
int start = 0, end = 0;
unsigned char buf[BUF_SIZE];
unsigned char last_char = '0';
bool main_log_break = false;





 
/*UART*/
//#define BAUD_RATE 256000
#define BAUD_RATE 2000000

Serial serial4(PA_2, PA_3);         //for actual data logger 7 board
Serial pc(PA_9, PA_10);

//Serial pc(PA_2, PA_3);            //For testing on nucleo-64 boards
//Serial serial4(PA_11, PC_7);

 
/*Test pins*/
DigitalOut led(PA_7);
DigitalOut rx_HT(PC_2);
DigitalOut rx_TC(PC_3);

//int flag=0, flag2=0; 
//bool half_transfer = false;
//bool full_transfer = false;




extern "C" void DMA1_Stream5_IRQHandler(void)
{
        /* half transfer interrupt */
    if (DMA1->HISR & DMA_HISR_HTIF5 )  //if half transfer on DMA1 stream 5
    {
        DMA1->HIFCR = DMA_HIFCR_CHTIF5;  // acknowledge interrupt
        rx_HT = 1;
        fwrite(buf, 1, CHUNK_SIZE, fp);
        rx_HT = 0;
    }
    /* transmission complete interrupt */
    if (DMA1->HISR & DMA_HISR_TCIF5 )  //if transfer complete on DMA1 stream 5
    {
        DMA1->HIFCR = DMA_HIFCR_CTCIF5;  // acknowledge interrupt
        rx_TC = 1;
        fwrite(buf + CHUNK_SIZE, 1, CHUNK_SIZE, fp);
        rx_TC = 0;
    }
}
 
 
int main() {
    pc.baud(256000);
    RCC->CR |= RCC_CR_HSEON;         //turn on the HSE crystal!
    led = 1;

    /*init SD card, wait for card insertion*/
    pc.printf("\n\rconfiging SD card ");     
    SDFileSystem sd(DI, DO, SCK, CS, "sd");
    pc.printf("\n\rtrying status ");     
    while (sd.disk_status()) {
        sd.disk_initialize();
        wait(0.5);
        led = !led;
    }
    pc.printf("disk initialized \r");
    
    if (SET_TIME) {set_time(1557126150);}
    led = !led;
    time_t seconds = time(NULL);
    pc.printf("Time as seconds since January 1, 1970 = %d\n\r", seconds);
    
    strcpy(fname, "/sd/log_");
 
    sprintf(current_time, "%u", seconds );    
    strcat(fname, current_time);
    strcat(fname, ".bin");
    pc.printf("Logging to %s\n", fname);
    led = !led;
    FILE *fp = fopen(fname, "wb");
    pc.printf("file opened \r");
    led = 0;
    
    
    /*init serial*/    
    serial4.baud(BAUD_RATE);
    
    //FOR NUCLEO-64 boards: USART6, DMA2, Stream2, channel 5?
    //for actual data logger: USART2, DMA1, Stream5, Channel 4
    
    
    RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN;

    USART2->CR3 |= USART_CR3_DMAR;                      // enable DMA serial recieve
    DMA1_Stream5->PAR = (uint32_t)&USART2->DR;          // transfer data from UART DR
    DMA1_Stream5->M0AR = (uint32_t)buf;          // transfer data to rx buffer
    DMA1_Stream5->CR |= (4<<25);                       // select channel 5 on stream 5
    DMA1_Stream5->NDTR = BUF_SIZE;                           // tranfer full buffer of datas
    DMA1_Stream5->CR |= DMA_SxCR_MINC;
    NVIC_EnableIRQ(DMA1_Stream5_IRQn);                 //enable interrupts?
    DMA1_Stream5->CR |= DMA_SxCR_TCIE;                 //enable transfer complete interrupt
    DMA1_Stream5->CR |= DMA_SxCR_HTIE;                 //enable half tranfer interrupt
    DMA1_Stream5->CR |= DMA_SxCR_CIRC;                   //enable circular mode
    DMA1_Stream5->CR |= DMA_SxCR_EN;                   //enable DMA
    pc.printf("DMA Enabled\r\n");

    if(serial4.readable()) { }  //necessary to make things work
    

    for (;;) {
        
        
 
    }  
}