CCS FAT Driver Bugfix!

January 3, 2017 | Author: Danh_IS4 | Category: N/A
Share Embed Donate


Short Description

Download CCS FAT Driver Bugfix!...

Description

CCS :: View topic - CCS FAT driver bugfix!

1 of 54

FAQ Forum Help Register Profile

http://www.ccsinfo.com/forum/viewtopic.php?t=43417

Official CCS Support

Search

CCS does not monitor this forum on a regular basis. Please do not post bug Reports on this forum. Send them to [email protected]

Log in to check your private messages

Log

in

CCS FAT driver bugfix! CCS Forum Index -> Code Library View previous topic :: View next topic Author andrewg

Message CCS FAT driver bugfix! Posted: Sun Aug 29, 2010 10:46 am

Joined: 17 Aug 2005 Posts: 316 Location: Perth, Western Australia

(See also CCS SD/MMC driver MBR support) The CCS "fat.c" functions "get_next_addr" and "get_prev_addr" do not correctly handle cluster transitions. The following are corrected functions: Code: signed int8 get_next_addr(int32* my_addr) { int32 temp; #ifdef FAT32 int32 c; #else int16 c; #endif // check to make sure that the next iteration will give us a contiguous address temp = *my_addr + 1; if((temp > Data_Start ) && ((temp - Data_Start) % Bytes_Per_Cluster == 0)) { // convert the current address into the address of where information about // the address is stored in the FAT, and put this value into the current address c = addr_to_cluster(temp - 1); if(get_next_cluster(&c) == EOF) return EOF; if (c >= #ifdef FAT32 0x0FFFFFF8 #else 0xFFF8 #endif ) return EOF; temp = cluster_to_addr(c); } *my_addr = temp; return GOODEC; }

and Code: signed int8 get_prev_addr(int32* my_addr) { int32 temp; #ifdef FAT32 int32 c;

3/17/2015 3:49 PM

CCS :: View topic - CCS FAT driver bugfix!

2 of 54

http://www.ccsinfo.com/forum/viewtopic.php?t=43417

#else int16 c; #endif temp = *my_addr; // if we're trying to go backwards one entry from the beginning of the root, // we won't be able to... if(temp = Data_Start ) && ((temp - Data_Start) % Bytes_Per_Cluster == 0)) { c = addr_to_cluster(temp); if(get_prev_cluster(&c) == EOF) return EOF; temp = cluster_to_addr(c) + Bytes_Per_Cluster; } *my_addr = temp - 1; return GOODEC; }

Edit, I've realized the above works because I've slightly altered the "fat_init" function too. The following in "fat_init": Code: #ifdef FAT32 Data_Start = Bytes_Per_Cluster + Root_Dir; #else // FAT16

needs to have "Bytes_Per_Cluster +" deleted. _________________ Andrew Last edited by andrewg on Fri Nov 12, 2010 8:47 pm; edited 2 times in total

andrewg

Posted: Sun Aug 29, 2010 10:54 am

Another one, "get_short_file_name" is also buggy. Fix: Joined: 17 Aug 2005 Posts: 316 Location: Perth, Western Australia

Code: signed int8 get_short_file_name(int32 file_entry_addr, char sname[], int8 type) { int8 buf, i, j = 0; // one short file name has, at the most, 11 characters for(i = 0; i < 11; ++i) { // read in a character if(mmcsd_read_data(i + file_entry_addr, 1, &buf) != GOODEC) return EOF; // convert the character if(buf != ' ') { if (i == 8 && type != 0x10) sname[j++] = '.'; sname[j++] = tolower(buf); } } if (sname[j - 1] == '.') --j; sname[j] = '\0'; return GOODEC; }

_________________ Andrew BugVito

MMCSD FAT: Still hanging despite the few changes Posted: Fri Nov 12, 2010 6:55 pm

Joined: 12 Nov 2010 Posts: 3

3/17/2015 3:49 PM

CCS :: View topic - CCS FAT driver bugfix!

3 of 54

http://www.ccsinfo.com/forum/viewtopic.php?t=43417

Good stuff andrewg. This got me going until I formatted the sd card. It has seen a fair amount of trial and error and procedures before it finally worked, and this was all before applying your changes. Could you explain exactly what is needed for the sd card to work on both a pc and on a board using ccs mmcsd and fat drivers, or simply what format type, etc...? I have tried formatting as FAT32 with default settings, no luck, FAT32 with 512 size blocks, still no luck, completely wiped the card using a hex editor, then format with both options above, still no luck. It is unfortunate that ccs would deploy a crippled/incomplete driver without maintaining it. I've had an ethernet board from ccs for a while, with close to no luck at using the sd card. andrewg

Joined: 17 Aug 2005 Posts: 316 Location: Perth, Western Australia

Posted: Fri Nov 12, 2010 9:25 pm

I've only ever used cards formatted on my PC or in a camera. All my standard SD (not SHDC) cards work fine. After I made my changes (cluster fix and MBR enhancement) the cards have just worked. I have to admit, though, that so far I've only ever had the PIC read a card (I've only used it for firmware updating, so far). Writing is coming soon. Once I've done some writing and made sure it actually works (I don't see why it won't, since reading works fine), then I'm going to write to CCS and give them my new code. When using the CCS code, make sure you've compiled it for the correct FAT16/32 variant for the cards you're using (probably FAT32). Also, so far I've implemented SD cards on pure 3.3V logic, so no 5V 3.3V level translations complicate things. I've also made sure I have pullup resistors on both the CS and MISO (data from card to PIC) lines. _________________ Andrew

BugVito

Posted: Sat Nov 13, 2010 8:21 am

Ahh read only. This is good to know, and may be sufficient for now actually. Joined: 12 Nov 2010 Posts: 3

My test starts by writting a file, appending text to it, and then reading from it. I'll chop those first bits off for now, and test a few different formats. Everything was working, read and write, using the ex_fat.c example and your fixed code. That is before formatting the card. So a fix may not be that far off. I seem to be using the same setup, FAT32, 3.3V, and pullup resistors. Thanks for the info and initiative! Most appreciated! KONAMI

FAT32 Posted: Sat Dec 17, 2011 6:58 am

Joined: 29 Aug 2010 Posts: 8

Did it(CCS C FAT.C bugfix) work in FAT32 file system.

quangtk87

I try this code but nothing appear Posted: Tue Jun 12, 2012 2:42 am

Joined: 10 Jun 2012 Posts: 3

3/17/2015 3:49 PM

CCS :: View topic - CCS FAT driver bugfix!

4 of 54

http://www.ccsinfo.com/forum/viewtopic.php?t=43417

When I repair fat.c and mmcsd.c on ccs follow Andrewg. Every command is good, but it just working on my Hyperterminal. Plug SD card in my PC is nothing, empty. Anybody help me! plz _________________ tinhquang opas

more bug found Posted: Thu Jun 21, 2012 10:09 pm

Joined: 17 Jun 2012 Posts: 2

I tried to use CCS lib to make a data logger. I found a lot of bugs in the lib and need much time to modify it. At last I can make file with text in the card and can read it in Windows. Only one thing I can not fix it : when I put data in cluster 2, Notepad show errors. If someone know the solution, please let me know Next is the lib code mmcsd.c Code: ///////////////////////////////////////////////////////////////////////// //// MMCSD.c //// //// //// //// This is a low-level driver for MMC and SD cards. //// //// //// //// --User Functions-//// //// //// //// mmcsd_init(): Initializes the media. //// //// //// //// mmcsd_read_byte(a, p) //// //// Reads a byte from the MMC/SD card at location a, saves to //// //// pointer p. Returns 0 if OK, non-zero if error. //// //// //// //// mmcsd_read_data(a, n, p) //// //// Reads n bytes of data from the MMC/SD card starting at address //// //// a, saves result to pointer p. Returns 0 if OK, non-zero if //// //// error. //// //// //// //// mmcsd_flush_buffer() //// //// The two user write functions (mmcsd_write_byte() and //// //// mmcsd_write_data()) maintain a buffer to speed up the writing //// //// process. Whenever a read or write is performed, the write //// //// buffer is loaded with the specified page and only the //// //// contents of this buffer is changed. If any future writes //// //// cross a page boundary then the buffer in RAM is written //// //// to the MMC/SD and then the next page is loaded into the //// //// buffer. mmcsd_flush_buffer() forces the contents in RAM //// //// to the MMC/SD card. Returns 0 if OK, non-zero if errror. //// //// //// //// mmcsd_write_byte(a, d) //// //// Writes data byte d to the MMC/SD address a. Intelligently //// //// manages a write buffer, therefore you may need to call //// //// mmcsd_flush_buffer() to flush the buffer. //// //// //// //// mmcsd_write_data(a, n, p) //// //// Writes n bytes of data from pointer p to the MMC/SD card //// //// starting at address a. This function intelligently manages //// //// a write buffer, therefore if you may need to call //// //// mmcsd_flush_buffer() to flush any buffered characters. //// //// returns 0 if OK, non-zero if error. //// //// //// //// mmcsd_read_block(a, s, p) //// //// Reads an entire page from the SD/MMC. Keep in mind that the //// //// start of the read has to be aligned to a block //// //// (Address % 512 = 0). Therefore s must be evenly divisible by //// //// 512. At the application level it is much more effecient to //// //// to use mmcsd_read_data() or mmcsd_read_byte(). Returns 0 //// //// if successful, non-zero if error. //// //// //// //// mmcsd_write_block(a, s, p): //// //// Writes an entire page to the SD/MMC. This will write an //// //// entire page to the SD/MMC, so the address and size must be //// //// evenly divisble by 512. At the application level it is much //// //// more effecient to use mmcsd_write_data() or mmcsd_write_byte().//// //// Returns 0 if successful, non-zero if error. //// //// ////

3/17/2015 3:49 PM

CCS :: View topic - CCS FAT driver bugfix!

5 of 54

http://www.ccsinfo.com/forum/viewtopic.php?t=43417

//// mmcsd_print_cid(): Displays all data in the Card Identification //// //// Register. Note this only works on SD cards. //// //// //// //// mmcsd_print_csd(): Displays all data in the Card Specific Data //// //// Register. Note this only works on SD cards. //// //// //// //// //// //// --Non-User Functions-//// //// //// //// mmcsd_go_idle_state(): Sends the GO_IDLE_STATE command to the //// //// SD/MMC. //// //// mmcsd_send_op_cond(): Sends the SEND_OP_COND command to the //// //// SD. Note this command only works on SD. //// //// mmcsd_send_if_cond(): Sends the SEND_IF_COND command to the //// //// SD. Note this command only works on SD. //// //// mmcsd_sd_status(): Sends the SD_STATUS command to the SD. Note //// //// This command only works on SD cards. //// //// mmcsd_send_status(): Sends the SEND_STATUS command to the //// //// SD/MMC. //// //// mmcsd_set_blocklen(): Sends the SET_BLOCKLEN command along with //// //// the desired block length. //// //// mmcsd_app_cmd(): Sends the APP_CMD command to the SD. This only //// //// works on SD cards and is used just before any //// //// SD-only command (e.g. send_op_cond()). //// //// mmcsd_read_ocr(): Sends the READ_OCR command to the SD/MMC. //// //// mmcsd_crc_on_off(): Sends the CRC_ON_OFF command to the SD/MMC //// //// along with a bit to turn the CRC on/off. //// //// mmcsd_send_cmd(): Sends a command and argument to the SD/MMC. //// //// mmcsd_get_r1(): Waits for an R1 response from the SD/MMC and //// //// then saves the response to a buffer. //// //// mmcsd_get_r2(): Waits for an R2 response from the SD/MMC and //// //// then saves the response to a buffer. //// //// mmcsd_get_r3(): Waits for an R3 response from the SD/MMC and //// //// then saves the response to a buffer. //// //// mmcsd_get_r7(): Waits for an R7 response from the SD/MMC and //// //// then saves the response to a buffer. //// //// mmcsd_wait_for_token(): Waits for a specified token from the //// //// SD/MMC. //// //// mmcsd_crc7(): Generates a CRC7 using a pointer to some data, //// //// and how many bytes long the data is. //// //// mmcsd_crc16(): Generates a CRC16 using a pointer to some data, //// //// and how many bytes long the data is. //// //// //// ///////////////////////////////////////////////////////////////////////// //// (C) Copyright 2007 Custom Computer Services //// //// This source code may only be used by licensed users of the CCS //// //// C compiler. This source code may only be distributed to other //// //// licensed users of the CCS C compiler. No other use, //// //// reproduction or distribution is permitted without written //// //// permission. Derivative programs created using this software //// //// in object code form are not restricted in any way. //// ///////////////////////////////////////////////////////////////////////// #ifndef MMCSD_C #define MMCSD_C ///////////////////// //// //// //// User Config //// //// //// ///////////////////// #include "stdint.h" #ifndef MMCSD_PIN_SCL #define MMCSD_PIN_SCL #define MMCSD_PIN_SDI #define MMCSD_PIN_SDO #define MMCSD_PIN_SELECT #endif

PIN_C3 PIN_C4 PIN_C5 PIN_B4

//o //i //o //o

#use spi(MASTER, DI=MMCSD_PIN_SDI, DO=MMCSD_PIN_SDO, CLK=MMCSD_PIN_SCL, BITS=8, MSB_FIRST, MODE=3, stream=mmcsd_spi,BAUD=4800) //////////////////////// //// //// //// Useful Defines //// //// //// ////////////////////////

3/17/2015 3:49 PM

CCS :: View topic - CCS FAT driver bugfix!

6 of 54

http://www.ccsinfo.com/forum/viewtopic.php?t=43417

enum MMCSD_err {MMCSD_GOODEC = 0, MMCSD_IDLE = 0x01, MMCSD_ERASE_RESET = 0x02, MMCSD_ILLEGAL_CMD = 0x04, MMCSD_CRC_ERR = 0x08, MMCSD_ERASE_SEQ_ERR = 0x10, MMCSD_ADDR_ERR = 0x20, MMCSD_PARAM_ERR = 0x40, RESP_TIMEOUT = 0x80}; #define #define #define #define #define #define #define #define #define #define #define #define #define #define

GO_IDLE_STATE 0 SEND_OP_COND 1 SEND_IF_COND 8 SEND_CSD 9 SEND_CID 10 SD_STATUS 13 SEND_STATUS 13 SET_BLOCKLEN 16 READ_SINGLE_BLOCK 17 WRITE_BLOCK 24 SD_SEND_OP_COND 41 APP_CMD 55 READ_OCR 58 CRC_ON_OFF 59

#define IDLE_TOKEN 0x01 #define DATA_START_TOKEN 0xFE #define MMCSD_MAX_BLOCK_SIZE 512 //////////////////////// /// /// /// Global Variables /// /// /// //////////////////////// uint8_t g_mmcsd_buffer[MMCSD_MAX_BLOCK_SIZE]; int1 g_CRC_enabled; int1 g_MMCSDBufferChanged; uint32_t g_mmcsdBufferAddress; enum _card_type{SD, MMC} g_card_type; uint32_t g_mmcsdPartitionOffset; ///////////////////////////// //// //// //// Function Prototypes //// //// //// ///////////////////////////// MMCSD_err mmcsd_init(int32 offset); MMCSD_err mmcsd_read_data(uint32_t address, uint16_t size, uint8_t* ptr); MMCSD_err mmcsd_read_block(uint32_t address, uint16_t size, uint8_t* ptr); MMCSD_err mmcsd_write_data(uint32_t address, uint16_t size, uint8_t* ptr); MMCSD_err mmcsd_write_block(uint32_t address, uint16_t size, uint8_t* ptr); MMCSD_err mmcsd_go_idle_state(void); MMCSD_err mmcsd_send_op_cond(void); MMCSD_err mmcsd_send_if_cond(uint8_t r7[]); MMCSD_err mmcsd_print_csd(); MMCSD_err mmcsd_print_cid(); MMCSD_err mmcsd_sd_status(uint8_t r2[]); MMCSD_err mmcsd_send_status(uint8_t r2[]); MMCSD_err mmcsd_set_blocklen(uint32_t blocklen); MMCSD_err mmcsd_read_single_block(uint32_t address); MMCSD_err mmcsd_write_single_block(uint32_t address); MMCSD_err mmcsd_sd_send_op_cond(void); MMCSD_err mmcsd_app_cmd(void); MMCSD_err mmcsd_read_ocr(uint8_t* r1); MMCSD_err mmcsd_crc_on_off(int1 crc_enabled); MMCSD_err mmcsd_send_cmd(uint8_t cmd, uint32_t arg); MMCSD_err mmcsd_get_r1(void); MMCSD_err mmcsd_get_r2(uint8_t r2[]); MMCSD_err mmcsd_get_r3(uint8_t r3[]); MMCSD_err mmcsd_get_r7(uint8_t r7[]); MMCSD_err mmcsd_wait_for_token(uint8_t token); uint8_t mmcsd_crc7(char *data, uint8_t length);

3/17/2015 3:49 PM

CCS :: View topic - CCS FAT driver bugfix!

7 of 54

http://www.ccsinfo.com/forum/viewtopic.php?t=43417

uint16_t mmcsd_crc16(char *data, uint8_t length); void mmcsd_select(); void mmcsd_deselect(); /// Fast Functions ! /// MMCSD_err MMCSD_err MMCSD_err MMCSD_err MMCSD_err

mmcsd_load_buffer(void); mmcsd_flush_buffer(void); mmcsd_move_buffer(uint32_t new_addr); mmcsd_read_byte(uint32_t addr, char* data); mmcsd_write_byte(uint32_t addr, char data);

void mmcsd_check_part(uint16_t off) { printf("find offset from physical to logical %X\r\n",g_mmcsd_buffer[off] ) ; if (g_mmcsd_buffer[off + 1] == 0x00) { printf("check part OK \r\n"); g_mmcsdPartitionOffset = g_mmcsd_buffer[off]; // active partition /* uint8_t t; t = g_mmcsd_buffer[off + 4]; if (t == 0x04 || t == 0x06 || t == 0x0B) { // FAT16 or FAT32 partition = make32( g_mmcsd_buffer[off + 11], g_mmcsd_buffer[off + 10], g_mmcsd_buffer[off + 9], g_mmcsd_buffer[off + 8]) * MMCSD_MAX_BLOCK_SIZE; }*/ } } ////////////////////////////////// //// //// //// Function Implementations //// //// //// ////////////////////////////////// MMCSD_err mmcsd_init() { uint8_t i, r1; printf("begin initialization \r\n"); g_CRC_enabled = TRUE; g_mmcsdBufferAddress = 0;

output_drive(MMCSD_PIN_SCL); output_drive(MMCSD_PIN_SDO); output_drive(MMCSD_PIN_SELECT); output_float(MMCSD_PIN_SDI); mmcsd_deselect(); delay_ms(15); /* begin initialization */ i = 0; do { delay_ms(1); mmcsd_select(); r1=mmcsd_go_idle_state(); mmcsd_deselect(); i++; if(i == 0xFF) { mmcsd_deselect(); return r1; } } while(!bit_test(r1, 0)); i = 0; do {

3/17/2015 3:49 PM

CCS :: View topic - CCS FAT driver bugfix!

8 of 54

http://www.ccsinfo.com/forum/viewtopic.php?t=43417

delay_ms(1); mmcsd_select(); r1=mmcsd_send_op_cond(); mmcsd_deselect(); i++; if(i == 0xFF) { mmcsd_deselect(); return r1; } } while(r1 & MMCSD_IDLE); /* figure out if we have an SD or MMC */ mmcsd_select(); r1=mmcsd_app_cmd(); r1=mmcsd_sd_send_op_cond(); mmcsd_deselect(); printf("The card is : 0x%x\r\n",r1); /* an mmc will return an 0x04 here */ if(r1 == 0x04) { g_card_type = MMC; printf("MMC\r\n");} else { g_card_type = SD; printf("SD\r\n"); // mmcsd_print_cid(); // mmcsd_print_csd(); } delay_ms(1000); /* set block length to 512 bytes */ mmcsd_select(); r1 = mmcsd_set_blocklen(MMCSD_MAX_BLOCK_SIZE); //

printf("Set block length --> %X, \n\r", r1) ;

if(r1 != MMCSD_GOODEC) { mmcsd_deselect(); return r1; } mmcsd_deselect(); //if (r1 == 0) printf("Set block length failed !!!!!!!\r\n");

// turn CRCs off to speed up reading/writing mmcsd_select(); r1 = mmcsd_crc_on_off(0); if(r1 != MMCSD_GOODEC) { mmcsd_deselect(); return r1; } mmcsd_deselect(); r1 = mmcsd_load_buffer(); g_mmcsdPartitionOffset = 0; //mmcsd_check_part(0x1EE); //mmcsd_check_part(0x1DE); //mmcsd_check_part(0x1CE); //mmcsd_check_part(0x1BE); //we need to calculate the offset adresss between phy. and logic. address from the offset sector at the address 0x1C6 // printf("find offset from physical to logical %X\r\n",g_mmcsd_buffer[0x1C6] ) ; //more detail at http://www.secure-digital-card-source-code-driver.com/layoutof-a-mmc-or-sd-card-with-fat/the-boot-record

if (g_mmcsd_buffer[0x1C6] < 80 ) g_mmcsdBufferAddress = g_mmcsd_buffer[0x1C6]*0x200; // for card => 1GByte need to add more offset else g_mmcsdBufferAddress = g_mmcsd_buffer[0x1C6]*0x200+0x10000; printf("offset Adr : %lX\r\n",g_mmcsdBufferAddress ) ;

g_mmcsdPartitionOffset=g_mmcsdBufferAddress; ;

3/17/2015 3:49 PM

CCS :: View topic - CCS FAT driver bugfix!

9 of 54

http://www.ccsinfo.com/forum/viewtopic.php?t=43417

r1 = mmcsd_load_buffer(); if (g_mmcsd_buffer[0] == 0xEB) { printf("Boot sector found " ) ; }

return r1; } MMCSD_err mmcsd_read_data(uint32_t address, uint16_t size, uint8_t* ptr) { MMCSD_err r1; uint16_t i; // counter for loops for(i = 0; i < size; i++) { r1 = mmcsd_read_byte(address++, ptr++); if(r1 != MMCSD_GOODEC) return r1; } return MMCSD_GOODEC; } MMCSD_err mmcsd_read_block(uint32_t address, uint16_t size, uint8_t* ptr) { MMCSD_err ec; uint16_t i; // counter for loops // send command mmcsd_select(); ec = mmcsd_read_single_block(address); if(ec != MMCSD_GOODEC) { mmcsd_deselect(); return ec; } // wait for the data start token ec = mmcsd_wait_for_token(DATA_START_TOKEN); if(ec != MMCSD_GOODEC) { mmcsd_deselect(); return ec; } // read in the data for(i = 0; i < size; i += 1) ptr[i] = spi_xfer(mmcsd_spi, 0xFF); if(g_CRC_enabled) { /* check the crc */ if(make16(spi_xfer(mmcsd_spi, 0xFF), spi_xfer(mmcsd_spi, 0xFF)) != mmcsd_crc16(g_mmcsd_buffer, MMCSD_MAX_BLOCK_SIZE)) { mmcsd_deselect(); return MMCSD_CRC_ERR; } } else { /* have the card transmit the CRC, but ignore it */ spi_xfer(mmcsd_spi, 0xFF); spi_xfer(mmcsd_spi, 0xFF); } mmcsd_deselect(); //printf("print block \r\n") ; //for(i = 0; i < 32; i += 1) // printf("adr :%x -> %X \r\n", i, ptr[i] ) ; // printf(" %c ", ptr[i] ) ;

return MMCSD_GOODEC; }

3/17/2015 3:49 PM

CCS :: View topic - CCS FAT driver bugfix!

10 of 54

http://www.ccsinfo.com/forum/viewtopic.php?t=43417

MMCSD_err mmcsd_write_data(uint32_t address, uint16_t size, uint8_t* ptr) { MMCSD_err ec; uint16_t i; // counter for loops for(i = 0; i < size; i++) { ec = mmcsd_write_byte(address++, *ptr++); // if (*ptr++ != 0x00) // printf(" writ data at adr : -> %lX data -> %X address, ptr[i],i,size ) ;

: i = %X, size = %X\r\n",

if(ec != MMCSD_GOODEC) return ec; } return MMCSD_GOODEC; } MMCSD_err mmcsd_write_block(uint32_t address, uint16_t size, uint8_t* ptr) { MMCSD_err ec; uint16_t i; // send command mmcsd_select(); ec = mmcsd_write_single_block(address); if(ec != MMCSD_GOODEC) { mmcsd_deselect(); return ec; } // send a data start token spi_xfer(mmcsd_spi, DATA_START_TOKEN); // send all the data for(i = 0; i < size; i += 1) spi_xfer(mmcsd_spi, ptr[i]); // if the CRC is enabled we have to calculate it, otherwise just send an 0xFFFF if(g_CRC_enabled) spi_xfer(mmcsd_spi, mmcsd_crc16(ptr, size)); else { spi_xfer(mmcsd_spi, 0xFF); spi_xfer(mmcsd_spi, 0xFF); } // get the error code back from the card; "data accepted" is 0bXXX00101 ec = mmcsd_get_r1(); if(ec & 0x0A) { mmcsd_deselect(); return ec; } // wait for the line to go back high, this indicates that the write is complete while(spi_xfer(mmcsd_spi, 0xFF) == 0); mmcsd_deselect(); return MMCSD_GOODEC; } MMCSD_err mmcsd_go_idle_state(void) { mmcsd_send_cmd(GO_IDLE_STATE, 0); return mmcsd_get_r1(); } MMCSD_err mmcsd_send_op_cond(void) { mmcsd_send_cmd(SEND_OP_COND, 0); return mmcsd_get_r1(); } MMCSD_err mmcsd_send_if_cond(uint8_t r7[])

3/17/2015 3:49 PM

CCS :: View topic - CCS FAT driver bugfix!

11 of 54

http://www.ccsinfo.com/forum/viewtopic.php?t=43417

{ mmcsd_send_cmd(SEND_IF_COND, 0x45A); return mmcsd_get_r7(r7); } MMCSD_err mmcsd_print_csd() { uint8_t buf[16], i, r1; // MMCs don't support this command if(g_card_type == MMC) return MMCSD_PARAM_ERR; mmcsd_select(); mmcsd_send_cmd(SEND_CSD, 0); r1 = mmcsd_get_r1(); if(r1 != MMCSD_GOODEC) { mmcsd_deselect(); return r1; } r1 = mmcsd_wait_for_token(DATA_START_TOKEN); if(r1 != MMCSD_GOODEC) { mmcsd_deselect(); return r1; } for(i = 0; i < 16; i++) buf[i] = spi_xfer(mmcsd_spi, 0xFF); mmcsd_deselect(); printf("\r\nCSD_STRUCTURE: %X", (buf[0] & 0x0C) >> 2); printf("\r\nTAAC: %X", buf[1]); printf("\r\nNSAC: %X", buf[2]); printf("\r\nTRAN_SPEED: %X", buf[3]); printf("\r\nCCC: %lX", (make16(buf[4], buf[5]) & 0xFFF0) >> 4); printf("\r\nREAD_BL_LEN: %X", buf[5] & 0x0F); printf("\r\nREAD_BL_PARTIAL: %X", (buf[6] & 0x80) >> 7); printf("\r\nWRITE_BLK_MISALIGN: %X", (buf[6] & 0x40) >> 6); printf("\r\nREAD_BLK_MISALIGN: %X", (buf[6] & 0x20) >> 5); printf("\r\nDSR_IMP: %X", (buf[6] & 0x10) >> 4); printf("\r\nC_SIZE: %lX", (((buf[6] & 0x03) 6))); printf("\r\nVDD_R_CURR_MIN: %X", (buf[8] & 0x38) >> 3); printf("\r\nVDD_R_CURR_MAX: %X", buf[8] & 0x07); printf("\r\nVDD_W_CURR_MIN: %X", (buf[9] & 0xE0) >> 5); printf("\r\nVDD_W_CURR_MAX: %X", (buf[9] & 0x1C) >> 2); printf("\r\nC_SIZE_MULT: %X", ((buf[9] & 0x03) > 7)); printf("\r\nERASE_BLK_EN: %X", (buf[10] & 0x40) >> 6); printf("\r\nSECTOR_SIZE: %X", ((buf[10] & 0x3F) > 7)); printf("\r\nWP_GRP_SIZE: %X", buf[11] & 0x7F); printf("\r\nWP_GRP_ENABLE: %X", (buf[12] & 0x80) >> 7); printf("\r\nR2W_FACTOR: %X", (buf[12] & 0x1C) >> 2); printf("\r\nWRITE_BL_LEN: %X", ((buf[12] & 0x03) > 6)); printf("\r\nWRITE_BL_PARTIAL: %X", (buf[13] & 0x20) >> 5); printf("\r\nFILE_FORMAT_GRP: %X", (buf[14] & 0x80) >> 7); printf("\r\nCOPY: %X", (buf[14] & 0x40) >> 6); printf("\r\nPERM_WRITE_PROTECT: %X", (buf[14] & 0x20) >> 5); printf("\r\nTMP_WRITE_PROTECT: %X", (buf[14] & 0x10) >> 4); printf("\r\nFILE_FORMAT: %X", (buf[14] & 0x0C) >> 2); printf("\r\nCRC: %X", buf[15]); return r1; } MMCSD_err mmcsd_print_cid() { uint8_t buf[16], i, r1;

3/17/2015 3:49 PM

CCS :: View topic - CCS FAT driver bugfix!

12 of 54

http://www.ccsinfo.com/forum/viewtopic.php?t=43417

// MMCs don't support this command if(g_card_type == MMC) return MMCSD_PARAM_ERR; mmcsd_select(); mmcsd_send_cmd(SEND_CID, 0); r1 = mmcsd_get_r1(); if(r1 != MMCSD_GOODEC) { mmcsd_deselect(); return r1; } r1 = mmcsd_wait_for_token(DATA_START_TOKEN); if(r1 != MMCSD_GOODEC) { mmcsd_deselect(); return r1; } for(i = 0; i < 16; i++) buf[i] = spi_xfer(mmcsd_spi, 0xFF); mmcsd_deselect(); printf("\r\nManufacturer ID: %X", buf[0]); printf("\r\nOEM/Application ID: %c%c", buf[1], buf[2]); printf("\r\nOEM/Application ID: %c%c%c%c%c", buf[3], buf[4], buf[5], buf[6], buf[7]); printf("\r\nProduct Revision: %X", buf[8]); printf("\r\nSerial Number: %X%X%X%X", buf[9], buf[10], buf[11], buf[12]); printf("\r\nManufacturer Date Code: %X%X", buf[13] & 0x0F, buf[14]); printf("\r\nCRC-7 Checksum: %X", buf[15]); return r1; } MMCSD_err mmcsd_sd_status(uint8_t r2[]) { uint8_t i; mmcsd_select(); mmcsd_send_cmd(APP_CMD, 0); r2[0]=mmcsd_get_r1(); mmcsd_deselect(); mmcsd_select(); mmcsd_send_cmd(SD_STATUS, 0); for(i = 0; i < 64; i++) spi_xfer(mmcsd_spi, 0xFF); mmcsd_deselect(); return mmcsd_get_r2(r2); } MMCSD_err mmcsd_send_status(uint8_t r2[]) { mmcsd_send_cmd(SEND_STATUS, 0); return mmcsd_get_r2(r2); } MMCSD_err mmcsd_set_blocklen(uint32_t blocklen) { mmcsd_send_cmd(SET_BLOCKLEN, blocklen); return mmcsd_get_r1(); } MMCSD_err mmcsd_read_single_block(uint32_t address) { mmcsd_send_cmd(READ_SINGLE_BLOCK, address); return mmcsd_get_r1(); } MMCSD_err mmcsd_write_single_block(uint32_t address) {

3/17/2015 3:49 PM

CCS :: View topic - CCS FAT driver bugfix!

13 of 54

http://www.ccsinfo.com/forum/viewtopic.php?t=43417

mmcsd_send_cmd(WRITE_BLOCK, address); return mmcsd_get_r1(); } MMCSD_err mmcsd_sd_send_op_cond(void) { mmcsd_send_cmd(SD_SEND_OP_COND, 0); return mmcsd_get_r1(); } MMCSD_err mmcsd_app_cmd(void) { mmcsd_send_cmd(APP_CMD, 0); return mmcsd_get_r1(); } MMCSD_err mmcsd_read_ocr(int r3[]) { mmcsd_send_cmd(READ_OCR, 0); return mmcsd_get_r3(r3); } MMCSD_err mmcsd_crc_on_off(int1 crc_enabled) { mmcsd_send_cmd(CRC_ON_OFF, crc_enabled); g_CRC_enabled = crc_enabled; return mmcsd_get_r1(); } MMCSD_err mmcsd_send_cmd(uint8_t cmd, uint32_t arg) { uint8_t packet[6]; // the entire command, argument, and crc in one variable // construct the packet // every command on an SD card is or'ed with 0x40 packet[0] = cmd | 0x40; packet[1] = make8(arg, 3); packet[2] = make8(arg, 2); packet[3] = make8(arg, 1); packet[4] = make8(arg, 0); // calculate the crc if needed if(g_CRC_enabled) packet[5] = mmcsd_crc7(packet, 5); else packet[5] = 0xFF; // transfer the command and argument, with an extra 0xFF hacked in there spi_xfer(mmcsd_spi, packet[0]); spi_xfer(mmcsd_spi, packet[1]); spi_xfer(mmcsd_spi, packet[2]); spi_xfer(mmcsd_spi, packet[3]); spi_xfer(mmcsd_spi, packet[4]); spi_xfer(mmcsd_spi, packet[5]); //! spi_write2(packet[0]); //! spi_write2(packet[1]); //! spi_write2(packet[2]); //! spi_write2(packet[3]); //! spi_write2(packet[4]); //! spi_write2(packet[5]);

return MMCSD_GOODEC; } MMCSD_err mmcsd_get_r1(void) { uint8_t response = 0, // place to hold the response coming back from the SPI line timeout = 0xFF; // maximum amount loops to wait for idle before getting impatient and leaving the function with an error code // loop until timeout == 0

3/17/2015 3:49 PM

CCS :: View topic - CCS FAT driver bugfix!

14 of 54

http://www.ccsinfo.com/forum/viewtopic.php?t=43417

while(timeout) { // read what's on the SPI line // the SD/MMC requires that you leave the line high when you're waiting for data from it response = spi_xfer(mmcsd_spi, 0xFF); //response = spi_xfer(mmcsd_spi, 0x00);//leave the line idle // check to see if we got a response if(response != 0xFF) { // fill in the response that we got and leave the function return response; } // wait for a little bit longer timeout--; } // for some reason, we didn't get a response back from the card // return the proper error codes return RESP_TIMEOUT; } MMCSD_err mmcsd_get_r2(uint8_t r2[]) { r2[1] = mmcsd_get_r1(); r2[0] = spi_xfer(mmcsd_spi, 0xFF); return 0; } MMCSD_err mmcsd_get_r3(uint8_t r3[]) { return mmcsd_get_r7(r3); } MMCSD_err mmcsd_get_r7(uint8_t r7[]) { uint8_t i; // counter for loop // the top byte of r7 is r1 r7[4]=mmcsd_get_r1(); // fill in the other 4 bytes for(i = 0; i < 4; i++) r7[3 - i] = spi_xfer(mmcsd_spi, 0xFF); return r7[4]; } MMCSD_err mmcsd_wait_for_token(uint8_t token) { MMCSD_err r1; // get a token r1 = mmcsd_get_r1(); // check to see if the token we recieved was the one that we were looking for if(r1 == token) return MMCSD_GOODEC; // if that wasn't right, return the error return r1; } unsigned int8 mmcsd_crc7(char *data,uint8_t length) { uint8_t i, ibit, c, crc; crc = 0x00; Set initial value

//

for (i = 0; i < length; i++, data++) { c = *data; for (ibit = 0; ibit < 8; ibit++)

3/17/2015 3:49 PM

CCS :: View topic - CCS FAT driver bugfix!

15 of 54

http://www.ccsinfo.com/forum/viewtopic.php?t=43417

{ crc = crc Flags & Write) || (stream->Flags & Append)) {

3/17/2015 3:49 PM

CCS :: View topic - CCS FAT driver bugfix!

37 of 54

http://www.ccsinfo.com/forum/viewtopic.php?t=43417

// write the new size of the file if(mmcsd_write_data(stream->Entry_Addr + 0x1C, 4, &(stream->Size)) != GOODEC) { // printf(" fatclose: stream->Entry_Addr --> %lX , stream->Size --> %lX\n\r", stream->Entry_Addr+0x1c, stream->Size) ; stream->Flags |= Write_Error; return EOF; } // check to see if the first cluster is already linked in the file ec += mmcsd_read_data(stream->Entry_Addr + 0x14, 2, (int16*)&first_cluster + 1); ec += mmcsd_read_data(stream->Entry_Addr + 0x1A, 2, &first_cluster); //printf(" fatclose: stream->Entry_Addr+0x14 --> %lX , first_cluster + 1 --> %lX\n\r", stream->Entry_Addr+0x14, first_cluster + 1) ; //printf(" fatclose: stream->Entry_Addr+0x1A --> %lX , first_cluster --> %lX\n\r", stream->Entry_Addr+0x1A, first_cluster) ; if(ec != GOODEC) { stream->Flags |= Read_Error; return EOF; } // write the first cluster to the entry if needed if(first_cluster == 0) { // convert the start address to a cluster number first_cluster = addr_to_cluster(stream->Start_Addr); ec += mmcsd_write_data(stream->Entry_Addr + 0x14, 2, (int16*)&first_cluster + 1); ec += mmcsd_write_data(stream->Entry_Addr + 0x1A, 2, &first_cluster); if(ec != GOODEC) { stream->Flags |= Write_Error; return EOF; } } // dump the remaining buffer to the card if(fatflush(stream) == EOF) return EOF; } // nullify the data stream->Cur_Char = 0; stream->Entry_Addr = 0; stream->Size = 0; stream->Start_Addr = 0; stream->Flags = 0; return 0; } /* signed int fatgetc(FILE* stream) Summary: Gets a character from a stream. Param: The stream to get a character from. Returns: The character that was gotten from the stream,

3/17/2015 3:49 PM

CCS :: View topic - CCS FAT driver bugfix!

38 of 54

http://www.ccsinfo.com/forum/viewtopic.php?t=43417

EOF if the stream has reached the end of the file or doesn't have permissions to read, */ signed int fatgetc(FILE* stream) { char ch; // character read in // check to see if the stream has proper permissions to read if(stream->Flags & Read) { // when the number of bytes until eof hit zero, we know we are at the end of any file if(stream->Bytes_Until_EOF == 0) { stream->Flags |= EOF_Reached; return EOF; } // read in the next byte in the buffer if(read_buffer(stream, &ch) == EOF) return EOF; // a 0x00 will signify the end of a non-binary file if((ch == '\0') && !(stream->Flags & Binary)) { stream->Flags |= EOF_Reached; return EOF; } // get the next contiguous address of the stream if(get_next_addr(&(stream->Cur_Char)) != GOODEC) return EOF; // we just got 1 byte closer to the end of the file stream->Bytes_Until_EOF -= 1; return ch; } // if the stream doesn't have proper permissions to read, return an EOF else return EOF; } /* signed int fatputc(int ch, FILE* stream) Summary: Puts a character into a stream. Param ch: The character to put into the stream. Param stream: The stream to put a character into. Returns: The character that was put into the stream, EOF if the stream doesn't have permissions to write, or if a problem happened. */ signed int fatputc(int ch, FILE* stream) { // check to see if the stream has proper permissions to write if(((stream->Flags & Write) || (stream->Flags & Append)) && (stream->File_Type == Data_File)) { //printf("\r\n Cur_Char = %lX ; Data_Start : %lX",stream->Cur_Char, Data_Start); // if there isn't any space allocated yet, allocate some if(stream->Cur_Char < Data_Start) { // printf("\r\n Get new cluster : "); // printf("\r\n next free cluster = %X\r\n",Next_Free_Clust);

3/17/2015 3:49 PM

CCS :: View topic - CCS FAT driver bugfix!

39 of 54

http://www.ccsinfo.com/forum/viewtopic.php?t=43417

if(get_next_free_cluster(&Next_Free_Clust) == EOF) return EOF; // printf("Next_Free_Clust %X",Next_Free_Clust); #ifdef FAT32 if(write_fat(Next_Free_Clust, 0x0FFFFFFF) == EOF) return EOF; #else // FAT16 if(write_fat(Next_Free_Clust, 0xFFFF) == EOF) return EOF; #endif // #ifdef FAT32 if(clear_cluster(Next_Free_Clust) == EOF) return EOF; stream->Cur_Char = stream->Start_Addr = cluster_to_addr(Next_Free_Clust); } // write the next character to the buffer if(write_buffer(stream, ch) == EOF) return EOF; // get the next address, increment Cur_Char if(get_next_addr(&(stream->Cur_Char)) == EOF) { // write the current buffer to the end of the current cluster if(mmcsd_write_data(stream->Cur_Char - STREAM_BUF_SIZE + 1, STREAM_BUF_SIZE, stream->Buf) != GOODEC) { stream->Flags |= Write_Error; return EOF; } // start looking for a new cluster to allocate if(alloc_clusters(addr_to_cluster(stream->Cur_Char), &(stream->Cur_Char)) == EOF) return EOF; } // our file just got bigger by 1 byte stream->Size += 1; return ch; } // if the stream doesn't have proper permissions to write, return an EOF else return EOF; } /* char* fatgets(char* str, int num, FILE* stream) Summary: Reads characters from a stream into a string. Param str: A pointer to the beginning of the string to put characters into. Param num: The number of characters to put into the string - 1. Param stream: The stream to read from. Returns: A pointer to the most recently added character, or NULL if there was an error. Note: If a newline is read from the stream, then str will be terminated with a newline. If num - 1 or EOF is reached, then str will be null terminated. */ char* fatgets(char* str, int num, FILE* stream) { int i; // counter for loops

3/17/2015 3:49 PM

CCS :: View topic - CCS FAT driver bugfix!

40 of 54

http://www.ccsinfo.com/forum/viewtopic.php?t=43417

// loop until num - 1 for(i = 0; i < num - 1; i += 1) { str[i] = fatgetc(stream); if(str[i] == '\n') return str; if(str[i] == EOF) break; } // close off str with a null terminator str[i] = '\0'; return str; } /* signed int fatputs(char* str, FILE* stream) Summary: Writes characters from a string into a stream. Param str: A pointer to the beginning of the string to write into the stream. Param stream: The stream to write into. Returns: EOF if there was a problem, GOODEC if everything went okay. */ signed int fatputs(char* str, FILE* stream) { int i = 0; // counter for loops // fatputc every character in the stream while(str[i] != '\0') { if(fatputc(str[i], stream) == EOF) return EOF; i += 1; // printf("fatputs : %c : %X \r\n", str[i],str[i]); } return GOODEC; } /* signed int fatprintf(FILE* stream) Summary: This will print off the entire contents of the stream to the console. Param: The stream to print off. Returns: The last character printed off to the console. */ signed int fatprintf(FILE* stream) { signed int ch; // character read in // keep on printf any characters read in as long as we don't run into an end of file or a media error do { ch = fatgetc(stream); printf("%c", ch); } while(ch != EOF); return ch; }

3/17/2015 3:49 PM

CCS :: View topic - CCS FAT driver bugfix!

41 of 54

http://www.ccsinfo.com/forum/viewtopic.php?t=43417

/* signed int fatgetpos(FILE* stream, fatpos_t* position) Summary: Returns the current position of where the stream is pointing to relative to the beginning of the stream. Param stream: The stream to get the position of. Param position: A pointer to a variable put the current position of the pointer into. Returns: 0 on success. */ signed int fatgetpos(FILE* stream, fatpos_t* position) { *position = stream->Size - stream->Bytes_Until_EOF; return 0; } /* signed int fatsetpos(FILE* stream, fatpos_t* position) Summary: Sets the current position of where the stream is pointing to in memory relative to the beginning of the stream. Param stream: The stream to set the position of. Param position: A pointer the a variable that has the value of the new position. Returns: 0 on success, or EOF if there was error. */ signed int fatsetpos(FILE* stream, fatpos_t* position) { #ifndef FAST_FAT #ifdef FAT32 int32 cur_cluster; // the current cluster we're pointing to #else // FAT16 int16 cur_cluster; // the current cluster we're pointing to #endif // #ifdef FAT32 int32 i; // pointer to memory #endif // #ifndef FAST_FAT // check to see if we want to just rewind the file if(*position == 0) { rewind(stream); return GOODEC; } // this whole process is much different and easier if we're writing or appending at a spot after EOF // this will essentially write null characters to the file from EOF to the desired position if(((stream->Flags & Write) || (stream->Flags & Append)) && (stream->Size < *position)) { while(stream->Size < *position) if(fatputc('\0', stream) == EOF) return EOF; return 0; } #ifdef FAST_FAT stream->Cur_Char = stream->Start_Addr + *position; #else // NO FAST_FAT // figure out how many clusters into the file the position is to be set to i = *position / Bytes_Per_Cluster; cur_cluster = addr_to_cluster(stream->Start_Addr);

3/17/2015 3:49 PM

CCS :: View topic - CCS FAT driver bugfix!

42 of 54

http://www.ccsinfo.com/forum/viewtopic.php?t=43417

// head to that cluster while(i > 0) { if(get_next_cluster(&cur_cluster) != GOODEC) return EOF; i -= 1; } // head to the correct cluster stream->Cur_Char = cluster_to_addr(cur_cluster); // now that we're in the correct cluster, tack on the remaining position stream->Cur_Char += (*position % Bytes_Per_Cluster); if(stream->Flags & Read) { // we now need to change how far it is until EOF stream->Bytes_Until_EOF = stream->Size - *position; // fill up the buffer if(mmcsd_read_data(stream->Cur_Char, STREAM_BUF_SIZE, stream->Buf) != GOODEC) { stream->Flags |= Read_Error; return EOF; } } else stream->Size = *position; #endif // #ifdef FAST_FAT return 0; } /* signed int fatseek(FILE* stream, int32 offset, int origin) Summary: This will set the position of the file stream according to the input. The EOF flag will also be cleared. Param stream: The stream to set the position of. Param offset: How many bytes relative of origin the file stream position will be set. Param origin: This will be one of 3 values... SEEK_CUR: Set position relative to the current stream position. SEEK_END: Set position relative to the end of the stream. SEEK_SET: Set position relative to the beginning of the stream. Returns: 0 on success, or EOF if there was error. */ signed int fatseek(FILE* stream, int32 offset, int origin) { int32 myoffset; // since fatsetpos requires a pointer to a variable, we need this here switch(origin) { case SEEK_CUR: myoffset = stream->Cur_Char + offset; if(fatsetpos(stream, &myoffset) != 0) return EOF; break; case SEEK_END: myoffset = stream->Size - offset; if(fatsetpos(stream, &myoffset) != 0)

3/17/2015 3:49 PM

CCS :: View topic - CCS FAT driver bugfix!

43 of 54

http://www.ccsinfo.com/forum/viewtopic.php?t=43417

return EOF; break; case SEEK_SET: myoffset = offset; if(fatsetpos(stream, &myoffset) != 0) return EOF; break; default: return EOF; } // clear the EOF flag stream->Flags &= 0xEF; return GOODEC; } /* signed int fateof(FILE* stream) Summary: Determines whether or not the stream is at the end of the file. Param: The stream to query for EOF. Returns: A non-zero value if the file is at EOF, 0 if the file is not at EOF. */ signed int fateof(FILE* stream) { return stream->Flags & EOF_Reached; } /* signed int fatread(void* buffer, int size, int32 num, FILE* stream) Summary: Fills up an array with data from a stream. Param buffer: A pointer to the beginning of an array of any type. Param size: How many bytes each element in the array is. Param num: How many elements to fill in the array. Param stream: The stream to read from. Returns: How many values were written to the array. */ signed int fatread(void* buffer, int size, int32 num, FILE* stream) { int32 i; // counter for loop // fill up every byte for(i = 0; i < (num * size); i += 1) buffer[i] = fatgetc(stream); return i; } /* signed int fatwrite(void* buffer, int size, int32 count, FILE* stream ) Summary: Fills up a stream with data from an array Param buffer: A pointer to the beginning of an array of any type. Param size: How many bytes each element in the array is. Param num: How many elements to write to the stream. Param stream: The stream to write to. Returns: How many values were written to the stream. */ signed int fatwrite(void* buffer, int size, int32 count, FILE* stream )

3/17/2015 3:49 PM

CCS :: View topic - CCS FAT driver bugfix!

44 of 54

http://www.ccsinfo.com/forum/viewtopic.php?t=43417

{ int32 i; // counter for loop // write every byte for(i = 0; i < (count * (int32)size); i += 1) if(fatputc(buffer[i], stream) == EOF) return EOF; return i; } /* signed int fatflush(FILE* stream) Summary: Flushes the buffer of a given stream. Param: The stream to flush the buffer of. Returns: EOF if there was a problem, 0 if everything went okay */ signed int fatflush(FILE* stream) { int address; // check to see if we have a buffer if((stream->Flags & Write) || (stream->Flags & Append)) { // for( address =0; address Cur_Char-address,stream->Buf[address] );} // { printf (" %X", stream->Buf[address] );}

// check to see if we need to flush the buffer if(stream->Cur_Char % STREAM_BUF_SIZE == 0) { // flush the buffer to the card if(mmcsd_write_data(stream->Cur_Char - STREAM_BUF_SIZE, STREAM_BUF_SIZE, stream->Buf) != GOODEC) { stream->Flags |= Write_Error; return EOF; } } else { // flush the buffer to the card // we need to make sure that the buffer gets flushed into the proper location, hence all this weird % math if(mmcsd_write_data(stream->Cur_Char - (stream->Cur_Char % STREAM_BUF_SIZE), STREAM_BUF_SIZE, stream->Buf) != GOODEC) { stream->Flags |= Write_Error; return EOF; } } return(mmcsd_flush_buffer()); } return 0; } /* signed int remove(char* fname) Summary: Removes a file from disk. Param: The full path of the file to remove.

3/17/2015 3:49 PM

CCS :: View topic - CCS FAT driver bugfix!

45 of 54

http://www.ccsinfo.com/forum/viewtopic.php?t=43417

Returns: 0 on success, or EOF if there was error. Note: This function does not work for removing directories, use rm_dir instead. Note: fname must be in the form of /filename.fil for a file in the root directory /Directory/filename.fil for a file in a subdirectory of root /Directory/Subdirectory/filename.fil and so on... */ signed int remove(char* fname) { if(rm_file(fname) == EOF) return EOF; return 0; } /* signed int faterror(FILE* stream) Summary: Checks for an error in a given stream. Param: The stream to check for an error in. Returns: A non-zero value of there is an error in the stream, 0 if there is no error in the stream */ signed int faterror(FILE* stream) { return stream->Flags & 0xF0; } /* void clearerr(FILE* stream) Summary: Clears off all error in a given stream. Param: The stream to clear off the errors in. Returns: Nothing. */ void clearerr(FILE* stream) { stream->Flags &= 0x0F; } /* void rewind(FILE* stream) Summary: Sets the stream to point back to the beginning of a file. Param: The stream to rewind. Returns: Nothing. */ void rewind(FILE* stream) { // set the stream back to the beginning stream->Cur_Char = stream->Start_Addr; stream->Bytes_Until_EOF = stream->Size; } /* fatpos_t fattell(FILE* stream) Summary: Returns the current position of where the stream is pointing to relative to the beginning of the stream. Param: The stream to return the position of. Returns: The position of where the stream is pointing to relative to the beginning of the stream, or 0 if there was a problem. */ fatpos_t fattell(FILE* stream)

3/17/2015 3:49 PM

CCS :: View topic - CCS FAT driver bugfix!

46 of 54

http://www.ccsinfo.com/forum/viewtopic.php?t=43417

{ fatpos_t retval; if(fatgetpos(stream, &retval) != 0) return 0; return retval; } /// Non-Standard C Functions /// /* signed int rm_file(char fname[]) Summary: Deletes a file. Param: The full path of the file to delete. Returns: GOODEC if everything went okay, EOF if there was a problem. Note: fname must be in the form of /filename.fil for a file in the root directory /Directory/filename.fil for a file in a subdirectory of root /Directory/Subdirectory/filename.fil and so on... */ signed int rm_file(char fname[]) { int order, ulinked_entry = 0xE5; // 0xE5 is put into the file's entry to indicate unlinking int32 i; char mode[] = "r"; // r is the safest mode to remove files with FILE stream; // the stream that we'll be working with // attempt to open the stream if(fatopen(fname, mode, &stream) == EOF) return EOF; // we need to un-link the file's clusters from the FAT if there are clusters allocated if(stream.Start_Addr > Root_Dir) { if(dealloc_clusters(addr_to_cluster(stream.Start_Addr)) == EOF) return EOF; } // get rid of the first entry i = stream.Entry_Addr; if(mmcsd_write_data(i, 1, &ulinked_entry) == EOF) return EOF; // check to see if there is a long file name get_prev_entry(&i); if(mmcsd_read_data(i + 11, 1, &order) == EOF) return EOF; // get rid of all of the long file name entries if they're there while(order == 0x0F) { if(mmcsd_write_data(i, 1, &ulinked_entry) == EOF) return EOF; if(get_prev_entry(&i) == EOF)

3/17/2015 3:49 PM

CCS :: View topic - CCS FAT driver bugfix!

47 of 54

http://www.ccsinfo.com/forum/viewtopic.php?t=43417

return EOF; if(mmcsd_read_data(i + 11, 1, &order) == EOF) return EOF; } if(fatclose(&stream) == EOF) return EOF; return GOODEC; } /* signed int rm_dir(char dname[]) Summary: Deletes a directory. Param: The full path of the directory to delete. Returns: GOODEC if everything went okay, EOF if there was a problem. Note: dname must be in the form of /Dirname/ for a directory in the root directory /Dirname/Subdirname/ for a directory in a subdirectory of root and so on... Note: This function cannot remove all of the files and subdirectories of the directory. Manually remove all subdirectories and files before calling this command. */ signed int rm_dir(char dname[]) { char mode[] = "r"; // r is the safest mode to remove files with FILE stream; // the stream that we'll be working with // attempt to open the stream if(fatopen(dname, mode, &stream) == EOF) return EOF; // jump over the . and .. entries in the directory stream.Entry_Addr = stream.Start_Addr + 64; // check to make sure that there isn't stuff in this directory if(get_next_file(&stream) != EOF) return EOF; // since removing files is a lot like removing directories, we // can just call rm_file if(rm_file(dname) == EOF) return EOF; return GOODEC; } /* signed int mk_file(char fname[]) Summary: Creates a file. Param: The full path of the file to create. Returns: GOODEC if everything went okay, EOF if there was a problem. Note: This function will not create directories if parent directories don't exist. Note: fname must be in the form of /filename.fil for a file in the root directory /Directory/filename.fil for a file in a subdirectory of root /Directory/Subdirectory/filename.fil and so on... */ signed int mk_file(char fname[])

3/17/2015 3:49 PM

CCS :: View topic - CCS FAT driver bugfix!

48 of 54

http://www.ccsinfo.com/forum/viewtopic.php?t=43417

{ char filename[MAX_FILE_NAME_LENGTH], // the file name we're trying to make mode[] = "r"; // reading is the safest mode to work in int buf, value, // buffer to hold values entire_entry[0x20],// entire first entry filename_pos = 0, // the current parse position of the file name we're trying to create fname_pos; // the current parse position of the input the the function int32 i; // pointer to memory FILE stream; // the stream that we'll be working with // attempt to open up to the directory if(fatopen(fname, mode, &stream) == GOODEC) return EOF; // we shouldn't get an GOODEC back from fatopen() // printf("fatopen OK\r\n"); // check to see if the file is already there. if(!(stream.Flags & File_Not_Found)) return EOF; // make a file name fname_pos = strrchr(fname, '/') - fname + 1; while((fname[fname_pos] != '\0') && (filename_pos < MAX_FILE_NAME_LENGTH)) { filename[filename_pos] = fname[fname_pos]; fname_pos += 1; filename_pos += 1; // printf("set file name %c", &filename[filename_pos]); } filename[filename_pos] = '\0'; // write the name if(set_file_name(stream.Start_Addr, &i, filename) == EOF) return EOF; // throw in some values in the file's first entry for(buf = 0; buf < 0x20; buf += 1) entire_entry[buf] = 0; // this is a file entire_entry[0x0B] = 0x20; // entire_entry[14] = 0x40; // entire_entry[15] = 0x92; entire_entry[16] = 0xD3; entire_entry[17] = 0x40; entire_entry[18] = 0xD3; entire_entry[19] = 0x40; entire_entry[24] = 0xD3; entire_entry[25] = 0x40;

// read what set_file_name gave us for the short name if(mmcsd_read_data(i, 11, entire_entry) != GOODEC)

3/17/2015 3:49 PM

CCS :: View topic - CCS FAT driver bugfix!

49 of 54

http://www.ccsinfo.com/forum/viewtopic.php?t=43417

return EOF;

// write the entry if(mmcsd_write_data(i, 0x20, entire_entry) != GOODEC) return EOF;

/* for ( i=0; i Code Library Page 1 of 1 Jump to: Code Library

You cannot post new topics You cannot reply to topics You cannot edit your posts You cannot delete your posts

Go in in in in

this this this this

forum forum forum forum

3/17/2015 3:49 PM

CCS :: View topic - CCS FAT driver bugfix!

54 of 54

http://www.ccsinfo.com/forum/viewtopic.php?t=43417

You cannot vote in polls in this forum

Powered by phpBB © 2001, 2005 phpBB Group

3/17/2015 3:49 PM

View more...

Comments

Copyright ©2017 KUPDF Inc.
SUPPORT KUPDF