Skip to content
Permalink
Browse files

SD: Enable user access

The VM can now access files from the sd in read/write.
Each access is done in word-size (16bits).
  • Loading branch information...
Philippe Rétornaz
Philippe Rétornaz committed Aug 12, 2013
1 parent b765095 commit d3685fae80afb653c25bcc8a25226699c5a3b44b
Showing with 183 additions and 4 deletions.
  1. +58 −0 sd.c
  2. +5 −0 sd.h
  3. +98 −2 thymio_natives.c
  4. +22 −2 thymio_natives.h
58 sd.c
@@ -35,6 +35,7 @@
static FATFS fs; // SD fat
static FIL read_file; // Read handle
static FIL write_file; // Write handle
static __attribute((far)) FIL user_file; // Read/write file accessible from the VM
static unsigned char l;

#define SD_PRIO 2
@@ -63,6 +64,7 @@ void sd_shutdown(void) {

f_close(&read_file);
f_close(&write_file);
f_close(&user_file);
f_mount(0,0);

_TRISB14 = 1;
@@ -233,3 +235,59 @@ int sd_load_aseba_code(void) {
return ret;
}

int sd_user_open(char * name) {
int ret = 0;
unsigned int flags;

RAISE_IPL(flags, SD_PRIO);
f_close(&user_file);
if(name) {
if(f_open(&user_file, name, FA_READ | FA_WRITE | FA_OPEN_ALWAYS) != FR_OK) {
ret = -1;
}
}
IRQ_ENABLE(flags);
return ret;
}

int sd_user_seek(unsigned long offset) {
int ret;
unsigned int flags;

RAISE_IPL(flags, SD_PRIO);
if(f_lseek(&user_file, offset) == FR_OK)
ret = 0;
else
ret = -1;
IRQ_ENABLE(flags);
return ret;
}

unsigned int sd_user_read(unsigned char * data, unsigned int size) {
unsigned int ret;
unsigned int flags;
unsigned int read;

RAISE_IPL(flags, SD_PRIO);

if(f_read(&user_file, data, size, &read) == FR_OK)
ret = read;
else
ret = 0;

IRQ_ENABLE(flags);
return ret;
}

unsigned int sd_user_write(unsigned char * data, unsigned int size) {
unsigned int ret;
unsigned int flags;
unsigned int written;
RAISE_IPL(flags, SD_PRIO);
if(f_write(&user_file, data, size, &written) == FR_OK)
ret = written;
else
ret = 0;
IRQ_ENABLE(flags);
return ret;
}
5 sd.h
@@ -34,4 +34,9 @@
int sd_load_aseba_code(void);

void sd_log_file(void);

int sd_user_open(char * name);
int sd_user_seek(unsigned long offset);
unsigned int sd_user_read(unsigned char * data, unsigned int size);
unsigned int sd_user_write(unsigned char * data, unsigned int size);
#endif
@@ -86,8 +86,7 @@ AsebaNativeFunctionDescription AsebaNativeDescription_sound_system = {
}
};


static void prepare_name(unsigned int n, char * buf) {
static char * _prepare_name(unsigned int n, char * buf) {
unsigned int div;
unsigned int z = 0;
for(div=10000; div > 0; div /= 10) {
@@ -98,6 +97,11 @@ static void prepare_name(unsigned int n, char * buf) {
*buf++ = '0' + disp;
}
}
return buf;
}

static void prepare_name(unsigned int n, char * buf) {
buf = _prepare_name(n, buf);

*buf++ = '.';
*buf++ = 'w';
@@ -439,3 +443,95 @@ void set_wave(AsebaVMState * vm) {

tone_set_waveform(wave);
}

AsebaNativeFunctionDescription AsebaNativeDescription_sd_open = {
"sd.open",
"Open a file on the sd card",
{
{1, "number"},
{1, "status"},
{0,0},
}
};

void thymio_native_sd_open(AsebaVMState * vm) {
int no = vm->variables[AsebaNativePopArg(vm)];
unsigned int status = AsebaNativePopArg(vm);
char name[13] = {'u'};
char * p;


if(no == -1) {
sd_user_open(NULL);
vm->variables[status] = 0;
} else {
p = _prepare_name(no, &name[1]);
*p++ = '.';
*p++ = 'd';
*p++ = 'a';
*p++ = 't';
*p++ = 0;
vm->variables[status] = sd_user_open(name);
}
}

AsebaNativeFunctionDescription AsebaNativeDescription_sd_write = {
"sd.write",
"Write data on the sd card",
{
{-1, "data"},
{1, "written"},
{0,0},
}
};


void thymio_native_sd_write(AsebaVMState * vm) {
// variable pos
unsigned char * data = (unsigned char *) (vm->variables + AsebaNativePopArg(vm));
uint16 status = AsebaNativePopArg(vm);

// variable size
uint16 length = AsebaNativePopArg(vm) * 2;

vm->variables[status] = sd_user_write(data,length) / 2;
}

AsebaNativeFunctionDescription AsebaNativeDescription_sd_read = {
"sd.read",
"Read data on the sd card",
{
{-1, "data"},
{1, "read"},
{0,0},
}
};


void thymio_native_sd_read(AsebaVMState * vm) {
// variable pos
unsigned char * data = (unsigned char *) (vm->variables + AsebaNativePopArg(vm));
uint16 status = AsebaNativePopArg(vm);

// variable size
uint16 length = AsebaNativePopArg(vm) * 2;

vm->variables[status] = sd_user_read(data,length) / 2;
}

AsebaNativeFunctionDescription AsebaNativeDescription_sd_seek = {
"sd.seek",
"Seek",
{
{1, "position"},
{1, "status"},
{0,0},
}
};

void thymio_native_sd_seek(AsebaVMState * vm) {
unsigned long seek = vm->variables[AsebaNativePopArg(vm)];
unsigned int status = AsebaNativePopArg(vm);

vm->variables[status] = sd_user_seek(seek * 2);
}
@@ -74,6 +74,18 @@ void set_ntc_leds(AsebaVMState *vm);
extern AsebaNativeFunctionDescription AsebaNativeDescription_set_wave;
void set_wave(AsebaVMState *vm);

extern AsebaNativeFunctionDescription AsebaNativeDescription_sd_open;
void thymio_native_sd_open(AsebaVMState * vm);

extern AsebaNativeFunctionDescription AsebaNativeDescription_sd_write;
void thymio_native_sd_write(AsebaVMState * vm);

extern AsebaNativeFunctionDescription AsebaNativeDescription_sd_read;
void thymio_native_sd_read(AsebaVMState * vm);

extern AsebaNativeFunctionDescription AsebaNativeDescription_sd_seek;
void thymio_native_sd_seek(AsebaVMState * vm);

#define THYMIO_NATIVES_DESCRIPTIONS \
&AsebaNativeDescription_set_led, \
&AsebaNativeDescription_record, \
@@ -91,7 +103,11 @@ void set_wave(AsebaVMState *vm);
&AsebaNativeDescription_set_rc_leds, \
&AsebaNativeDescription_set_sound_leds, \
&AsebaNativeDescription_set_ntc_leds, \
&AsebaNativeDescription_set_wave
&AsebaNativeDescription_set_wave, \
&AsebaNativeDescription_sd_open, \
&AsebaNativeDescription_sd_write, \
&AsebaNativeDescription_sd_read, \
&AsebaNativeDescription_sd_seek

#define THYMIO_NATIVES_FUNCTIONS \
set_led, \
@@ -110,7 +126,11 @@ void set_wave(AsebaVMState *vm);
set_rc_leds, \
set_sound_leds, \
set_ntc_leds, \
set_wave
set_wave, \
thymio_native_sd_open, \
thymio_native_sd_write, \
thymio_native_sd_read, \
thymio_native_sd_seek


#endif

0 comments on commit d3685fa

Please sign in to comment.
You can’t perform that action at this time.