From 8f2e1e59ace5e182c34c7f6b71e5ef5e293f2b77 Mon Sep 17 00:00:00 2001 From: Michael Moon Date: Sat, 30 Apr 2011 00:50:43 +1000 Subject: [PATCH] SD card: initial shoehorning of SD code, part 1. Part 1 is, implement - M20: List SD card. - M21: Initialize SD card (has to be done before listing). - M22: Release SD card. Do all this in one chunk, splitting this up wouldn't allow to test the result. --- gcode_process.c | 26 ++++++++++++++++++++++ pff_conf.h | 2 +- sd.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++ sd.h | 6 ++++++ 4 files changed, 90 insertions(+), 1 deletion(-) diff --git a/gcode_process.c b/gcode_process.c index 4784004..3a29400 100644 --- a/gcode_process.c +++ b/gcode_process.c @@ -26,6 +26,8 @@ #include "clock.h" #include "config_wrapper.h" #include "home.h" +#include "sd.h" + /// the current tool uint8_t tool; @@ -374,6 +376,30 @@ void process_gcode_command() { tool = next_tool; break; + #ifdef SD + case 20: + //? --- M20: list SD card. --- + sd_list("/"); + break; + + case 21: + //? --- M21: initialise SD card. --- + //? + //? Has to be done before doing any other operation, including M20. + sd_mount(); + break; + + case 22: + //? --- M22: release SD card. --- + //? + //? Not mandatory. Just removing the card is fine, but results in + //? odd behaviour when trying to read from the card anyways. M22 + //? makes also sure SD card printing is disabled, even with the card + //? inserted. + sd_unmount(); + break; + #endif /* SD */ + case 82: //? --- M82 - Set E codes absolute --- //? diff --git a/pff_conf.h b/pff_conf.h index dd4d1f2..59ec26b 100644 --- a/pff_conf.h +++ b/pff_conf.h @@ -11,7 +11,7 @@ /---------------------------------------------------------------------------*/ #define _USE_READ 1 /* Enable pf_read() function */ -#define _USE_DIR 0 /* Enable pf_opendir() and pf_readdir() function */ +#define _USE_DIR 1 /* Enable pf_opendir() and pf_readdir() function */ #define _USE_LSEEK 0 /* Enable pf_lseek() function */ #define _USE_WRITE 0 /* Enable pf_write() function */ diff --git a/sd.c b/sd.c index 3d4f3f9..9339a30 100644 --- a/sd.c +++ b/sd.c @@ -6,10 +6,67 @@ #ifdef SD +#include "delay.h" +#include "serial.h" +#include "sersendf.h" + +static FATFS sdfile; +static FRESULT result; + +/** Initialize SPI for SD card reading. +*/ void sd_init(void) { WRITE(SD_CARD_SELECT_PIN, 1); SET_OUTPUT(SD_CARD_SELECT_PIN); } +/** Mount the SD card. +*/ +void sd_mount(void) { + result = pf_mount(&sdfile); + if (result != FR_OK) + sersendf_P(PSTR("E: SD init failed. (%su)"), result); +} + +/** Unmount the SD card. + + This makes just sure subsequent reads to the card do nothing, instead of + trying and failing. Not mandatory, just removing the card is fine, as well + as inserting and mounting another one without previous unmounting. +*/ +void sd_unmount(void) { + pf_unmount(&sdfile); +} + +/** List a given directory. + + \param path The path to list. Toplevel path is "/". + + A slash is added to directory names, to make it easier for users to + recognize them. +*/ +void sd_list(const char* path) { + FILINFO fno; + DIR dir; + + serial_writechar('\n'); + result = pf_opendir(&dir, path); + if (result == FR_OK) { + for (;;) { + result = pf_readdir(&dir, &fno); + if (result != FR_OK || fno.fname[0] == 0) + break; + serial_writestr((uint8_t *)fno.fname); + if (fno.fattrib & AM_DIR) + serial_writechar('/'); + serial_writechar('\n'); + delay_ms(2); // Time for sending the characters. + } + } + else { + sersendf_P(PSTR("E: failed to open dir. (%su)"), result); + } +} + #endif /* SD */ diff --git a/sd.h b/sd.h index 7e7a6d4..df4a39b 100644 --- a/sd.h +++ b/sd.h @@ -17,6 +17,12 @@ void sd_init(void); +void sd_mount(void); + +void sd_unmount(void); + +void sd_list(const char* path); + #endif /* SD_CARD_SELECT_PIN */ #endif /* _SD_H */