|
|
View previous topic :: View next topic |
Author |
Message |
alimary158
Joined: 26 Jan 2012 Posts: 16
|
Ring buffer writing on SD card |
Posted: Thu Jan 26, 2012 6:41 am |
|
|
Good evening,
I am using Brush electronics library for writing on sd card. The library works great but I am having issues in using a ring buffer in my code.
In my project I would like to have a Timer2 interrupt in which some data is sent into the ring buffer.
Then in the main loop I check the ring buffer tail and head and in case I write on the sd the data.
I have developed a code that unfortunately doesn't seem to work.
In particular the only result I get is that the file into the sd is created and it is written a constant string ("NewTrial") that I write before checking the ring buffer inside, but the values sent from the timer2 into the ring buffer would never be written. The pic I am using is a PIC18F46J50.
Can someone help me please? I don't know what I am doing wrong.
Thanks!!!
Here is my code:
Code: |
* prova_seriale_buffer.c
*
*
* Created by maria rosaria on 24/01/12.
* Copyright 2012 __MyCompanyName__. All rights reserved.
*
*/
#include <PIATTAFORMA.h>
#ifndef DWORD
#define DWORD int32
#endif
#ifndef WORD
#define WORD int16
#endif
DWORD get_fattime(void)
{
return 0;
}
#include <ff.h>
int16 data=85;
char string;
char mesg[32];
#define RxADCQsize 64
volatile BYTE RxBaseADC[RxADCQsize];
// Rx Ring Buffer control
volatile BYTE RxHeadADC;
BYTE RxTailADC;
void init_pic(void)
///////////////////////////////////////////////////////////////////////////
// void init_pic(void)
//
// Initialise the hardware defaults
///////////////////////////////////////////////////////////////////////////
{
setup_spi(FALSE);
setup_wdt(WDT_OFF);
#ifdef PCmp_Def
// setup_comparator
CMCON = PCmp_Def; // initialise comparators
#endif
// initialse port A
output_a(PA_DefData);
set_tris_a(PA_DefTRIS);
// initialise port B
port_b_pullups(TRUE);
output_b(PB_DefData);
set_tris_b(PB_DefTRIS);
// initialise port C
output_c(PC_DefData);
set_tris_c(PC_DefTRIS);
#ifdef PD_DefData
// initialise port D
output_d(PD_DefData);
set_tris_d(PD_DefTRIS);
#endif
#ifdef PE_DefData
// initialise port E
output_e(PE_DefData);
set_tris_e(PE_DefTRIS);
#endif
#ifdef PF_DefData
// initialise port F
output_f(PF_DefData);
set_tris_f(PF_DefTRIS);
#endif
#ifdef PG_DefData
// initialise port G
output_g(PG_DefData);
set_tris_g(PG_DefTRIS);
#endif
#ifdef PH_DefData
// initialise port H
output_h(PH_DefData);
set_tris_h(PH_DefTRIS);
#endif
#ifdef PJ_DefData
// initialise port J
output_j(PJ_DefData);
set_tris_j(PJ_DefTRIS);
#endif
}
#INT_timer2
void timer2_isr()
{
disable_interrupts(global);
string=sprintf(mesg,"%c\n\r",data);
RxBaseADC[RxHeadADC++]=string;
// test if ring buffer wrap is required
if (RxHeadADC >= RxADCQsize)
RxHeadADC = 0;
enable_interrupts(global);
}
void main (){
FIL fsrc; // file structures
FRESULT result; // FatFs function common result code
WORD btw, bw; // File R/W count
FRESULT FS_Status;
char pressure[64];
disable_interrupts(GLOBAL);
restart_wdt();
// Pic Inizialization
init_pic();
setup_timer_2 (T2_DIV_BY_16, 255, 6);
RxHeadADC=0;
RxTailADC=0;
enable_interrupts(int_timer2);
enable_interrupts(GLOBAL);
do
{
FS_Status = f_mountdrv();
}
while (FS_Status);
strcpy(pressure,"pressure.txt");
//F_OPEN(): if the file already exist the datas will be appened. if the file doesnt exsist it is created
result = f_open(&fsrc,&pressure, FA_OPEN_ALWAYS | FA_WRITE);
//Find the end of the file to append datas
result = f_lseek(&fsrc, fsrc.fsize);
//write a string delimiter to each append data log
strcpy(pressure, "\r\nNewTrial \r\n");
btw=strlen(pressure);
result = f_write(&fsrc,pressure, btw, &bw);
//checking the buffer tail and head
while (RxHeadADC != RxTailADC)
{
// here we have data waiting to be written
strcpy(pressure,RxBaseADC[RxTailADC++]);
// test if ring buffer wrap is required
if (RxTailADC >= RxADCQsize)
RxTailADC = 0;
result=f_write(&fsrc,pressure,btw,&bw);
}
result = f_sync(&fsrc);
f_close(&fsrc);
}
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19546
|
|
Posted: Thu Jan 26, 2012 10:52 am |
|
|
Ignoring any other problems, _NEVER_, repeat _NEVER_ enable global interrupts inside an ISR. This _will_ cause major problems.
The interrupt _hardware_ disables the global interrupts when the interrupt is handled. It also automatically re-enables them when the main interrupt handler exits _immediately after the code has returned_. This is the 'RETFIE' instruction used at the end of the interrupt code 'return from interrupt enable'.
It is vital that interrupts are not enabled while you are still inside the handler, because the PIC does not have a traditional variable stack, so if an interrupt gets called while you are still inside the handler all the registers saved and the return address already stored _will_ be lost...
Get rid of this, and you may find that 90% of your problems disappear.
Best Wishes |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9245 Location: Greensville,Ontario
|
|
Posted: Thu Jan 26, 2012 1:59 pm |
|
|
Do you do have correct voltage level conversion chip between PIC and SD card ? |
|
|
alimary158
Joined: 26 Jan 2012 Posts: 16
|
|
Posted: Thu Jan 26, 2012 2:02 pm |
|
|
Hi yes the voltage and the hardware it is right since i checked it already! also the library is all right i have tried my setup by using a different code and writing a constant string on the file in the main loop everything seems to work fine!!!
But in my project i need to use timer2 since i would like to acquire data frm a sensor and type them on the sd so i need to implement a ring buffer! i have changed my code now in this:
Code: |
#include <PIATTAFORMA.h>
#ifndef DWORD
#define DWORD int32
#endif
#ifndef WORD
#define WORD int16
#endif
DWORD get_fattime(void)
{
return 0;
}
#include <ff.h>
int16 data=85;
#define RxADCQsize 32
volatile int16 RxBaseADC[RxADCQsize];
// Rx Ring Buffer control
volatile BYTE RxHeadADC;
BYTE RxTailADC;
void init_pic(void)
///////////////////////////////////////////////////////////////////////////
// void init_pic(void)
//
// Initialise the hardware defaults
///////////////////////////////////////////////////////////////////////////
{ ...}
#INT_timer2
void timer2_isr()
{
RxBaseADC[RxHeadADC++]=data;
// test if ring buffer wrap is required
if (RxHeadADC >= RxADCQsize)
RxHeadADC = 0;
}
void main (){
FIL fsrc; // file structures
FRESULT result; // FatFs function common result code
WORD btw, bw; // File R/W count
FRESULT FS_Status;
char pressure[64];
disable_interrupts(GLOBAL);
restart_wdt();
init_pic();
setup_timer_2 (T2_DIV_BY_16, 255, 6);
RxHeadADC=0;
RxTailADC=0;
enable_interrupts(GLOBAL);
//enable_interrupts(int_timer2);
do
{
FS_Status = f_mountdrv();
}
while (FS_Status);
strcpy(pressure,"prova1.txt");
result = f_open(&fsrc,&pressure, FA_OPEN_ALWAYS | FA_WRITE);
result = f_lseek(&fsrc, fsrc.fsize);
//write a string delimiter to each append data log
strcpy(pressure, "\r\nNewTrial \r\n");
btw=strlen(pressure);
result = f_write(&fsrc,pressure, btw, &bw);
//checking the buffer tail and head
disable_interrupts(int_timer2);
if (RxHeadADC != RxTailADC)
{
enable_interrupts(int_timer2);
sprintf(pressure,"Valore=%lu\r\n",RxBaseADC[RxTailADC++]);
// test if ring buffer wrap is required
if (RxTailADC >= RxADCQsize)
RxTailADC = 0;
f_write(&fsrc,pressure,strlen(pressure),&bw);
}
else
enable_interrupts(int_timer2);
f_close(&fsrc);
}
|
But also in this code in the SD it is created the txt. file but nor the "New Trial " string nor the values in the buffer would be written!
I suppose im placing my interrupts in wrong way! Can you help? I'm really new in programming and I'm finding all this really hard
thank you |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|