aboutsummaryrefslogtreecommitdiff
path: root/cc3200/fatfs
diff options
context:
space:
mode:
authordanicampora2015-02-06 15:35:48 +0100
committerDamien George2015-02-06 22:10:11 +0000
commit8785645a952c03315dbf93667b5f7c7eec49762f (patch)
tree267e2d572d87e92bfc0bfabf83859231152a2162 /cc3200/fatfs
parent97f14606f528180d1482cffbe3571163a1dd9273 (diff)
cc3200: Add cc3200 port of MicroPython.
The port currently implements support for GPIO, RTC, ExtInt and the WiFi subsystem. A small file system is available in the serial flash. A bootloader which makes OTA updates possible, is also part of this initial implementation.
Diffstat (limited to 'cc3200/fatfs')
-rw-r--r--cc3200/fatfs/src/diskio.c208
-rw-r--r--cc3200/fatfs/src/diskio.h62
-rw-r--r--cc3200/fatfs/src/drivers/sd_diskio.c446
-rw-r--r--cc3200/fatfs/src/drivers/sd_diskio.h28
-rw-r--r--cc3200/fatfs/src/drivers/sflash_diskio.c186
-rw-r--r--cc3200/fatfs/src/drivers/sflash_diskio.h16
-rw-r--r--cc3200/fatfs/src/drivers/stdcmd.h62
-rw-r--r--cc3200/fatfs/src/ffconf.c99
-rw-r--r--cc3200/fatfs/src/ffconf.h276
-rw-r--r--cc3200/fatfs/src/option/syscall.c156
10 files changed, 1539 insertions, 0 deletions
diff --git a/cc3200/fatfs/src/diskio.c b/cc3200/fatfs/src/diskio.c
new file mode 100644
index 000000000..83041d646
--- /dev/null
+++ b/cc3200/fatfs/src/diskio.c
@@ -0,0 +1,208 @@
+/*-----------------------------------------------------------------------*/
+/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2014 */
+/*-----------------------------------------------------------------------*/
+/* If a working storage control module is available, it should be */
+/* attached to the FatFs via a glue function rather than modifying it. */
+/* This is an example of glue functions to attach various exsisting */
+/* storage control modules to the FatFs module with a defined API. */
+/*-----------------------------------------------------------------------*/
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "mpconfig.h"
+#include "diskio.h" /* FatFs lower layer API */
+#include "sflash_diskio.h" /* Serial flash disk IO API */
+#if MICROPY_HW_HAS_SDCARD
+#include "sd_diskio.h" /* SDCARD disk IO API */
+#endif
+#include "modutime.h"
+#include "inc/hw_types.h"
+#include "inc/hw_ints.h"
+#include "inc/hw_memmap.h"
+#include "rom_map.h"
+#include "prcm.h"
+
+/* Definitions of physical drive number for each drive */
+#define SFLASH 0 /* Map SFLASH drive to drive number 0 */
+#define SDCARD 1 /* Map SD card to drive number 1 */
+
+
+/*-----------------------------------------------------------------------*/
+/* Get Drive Status */
+/*-----------------------------------------------------------------------*/
+
+DSTATUS disk_status (
+ BYTE pdrv /* Physical drive nmuber to identify the drive */
+)
+{
+ switch (pdrv) {
+ case SFLASH :
+ return sflash_disk_status();
+#if MICROPY_HW_HAS_SDCARD
+ case SDCARD :
+ return sd_disk_status();
+#endif
+ default:
+ break;
+ }
+ return STA_NODISK;
+}
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Inidialize a Drive */
+/*-----------------------------------------------------------------------*/
+
+DSTATUS disk_initialize (
+ BYTE pdrv /* Physical drive nmuber to identify the drive */
+)
+{
+ DSTATUS stat = 0;
+
+ switch (pdrv) {
+ case SFLASH :
+ if (RES_OK != sflash_disk_init()) {
+ stat = STA_NOINIT;
+ }
+ return stat;
+#if MICROPY_HW_HAS_SDCARD
+ case SDCARD :
+ if (RES_OK != sd_disk_init()) {
+ stat = STA_NOINIT;
+ }
+ return stat;
+#endif
+ default:
+ break;
+ }
+ return STA_NOINIT;
+}
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Read Sector(s) */
+/*-----------------------------------------------------------------------*/
+
+DRESULT disk_read (
+ BYTE pdrv, /* Physical drive nmuber to identify the drive */
+ BYTE *buff, /* Data buffer to store read data */
+ DWORD sector, /* Sector address in LBA */
+ UINT count /* Number of sectors to read */
+)
+{
+ switch (pdrv) {
+ case SFLASH :
+ return sflash_disk_read(buff, sector, count);
+#if MICROPY_HW_HAS_SDCARD
+ case SDCARD :
+ return sd_disk_read(buff, sector, count);
+#endif
+ default:
+ break;
+ }
+
+ return RES_PARERR;
+}
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Write Sector(s) */
+/*-----------------------------------------------------------------------*/
+
+#if _USE_WRITE
+DRESULT disk_write (
+ BYTE pdrv, /* Physical drive nmuber to identify the drive */
+ const BYTE *buff, /* Data to be written */
+ DWORD sector, /* Sector address in LBA */
+ UINT count /* Number of sectors to write */
+)
+{
+ switch (pdrv) {
+ case SFLASH :
+ return sflash_disk_write(buff, sector, count);
+#if MICROPY_HW_HAS_SDCARD
+ case SDCARD :
+ return sd_disk_write(buff, sector, count);
+#endif
+ default:
+ break;
+ }
+
+ return RES_PARERR;
+}
+#endif
+
+
+/*-----------------------------------------------------------------------*/
+/* Miscellaneous Functions */
+/*-----------------------------------------------------------------------*/
+
+#if _USE_IOCTL
+DRESULT disk_ioctl (
+ BYTE pdrv, /* Physical drive nmuber (0..) */
+ BYTE cmd, /* Control code */
+ void *buff /* Buffer to send/receive control data */
+)
+{
+ switch (pdrv) {
+ case SFLASH:
+ switch (cmd) {
+ case CTRL_SYNC:
+ return sflash_disk_flush();
+ case GET_SECTOR_COUNT:
+ *((DWORD*)buff) = SFLASH_SECTOR_COUNT;
+ return RES_OK;
+ break;
+ case GET_SECTOR_SIZE:
+ *((WORD*)buff) = SFLASH_SECTOR_SIZE;
+ return RES_OK;
+ break;
+ case GET_BLOCK_SIZE:
+ *((DWORD*)buff) = 1; // high-level sector erase size in units of the block size
+ return RES_OK;
+ }
+ break;
+#if MICROPY_HW_HAS_SDCARD
+ case SDCARD:
+ switch (cmd) {
+ case CTRL_SYNC:
+ return RES_OK;
+ case GET_SECTOR_COUNT:
+ *(WORD*)buff = sd_disk_info.ulNofBlock;
+ break;
+ case GET_SECTOR_SIZE :
+ *(WORD*)buff = SD_SECTOR_SIZE;
+ break;
+ case GET_BLOCK_SIZE:
+ *((DWORD*)buff) = 1; // high-level sector erase size in units of the block size
+ return RES_OK;
+ }
+ break;
+#endif
+ }
+ return RES_PARERR;
+}
+#endif
+
+#if !_FS_READONLY && !_FS_NORTC
+DWORD get_fattime (
+ void
+)
+{
+ mod_struct_time tm;
+ uint32_t seconds;
+ uint16_t mseconds;
+
+ // Get the time from the on-chip RTC and convert it to struct_time
+ MAP_PRCMRTCGet(&seconds, &mseconds);
+ mod_time_seconds_since_2000_to_struct_time(seconds, &tm);
+
+ return ((tm.tm_year - 1980) << 25) | ((tm.tm_mon) << 21) |
+ ((tm.tm_mday) << 16) | ((tm.tm_hour) << 11) |
+ ((tm.tm_min) << 5) | (tm.tm_sec >> 1);
+}
+#endif
+
diff --git a/cc3200/fatfs/src/diskio.h b/cc3200/fatfs/src/diskio.h
new file mode 100644
index 000000000..6e4a056f0
--- /dev/null
+++ b/cc3200/fatfs/src/diskio.h
@@ -0,0 +1,62 @@
+/*-----------------------------------------------------------------------/
+/ Low level disk interface modlue include file (C)ChaN, 2014 /
+/-----------------------------------------------------------------------*/
+
+#ifndef _DISKIO_DEFINED
+#define _DISKIO_DEFINED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define _USE_WRITE 1 /* 1: Enable disk_write function */
+#define _USE_IOCTL 1 /* 1: Enable disk_ioctl fucntion */
+
+#include "integer.h"
+
+
+/* Status of Disk Functions */
+typedef BYTE DSTATUS;
+
+/* Results of Disk Functions */
+typedef enum {
+ RES_OK = 0, /* 0: Successful */
+ RES_ERROR, /* 1: R/W Error */
+ RES_WRPRT, /* 2: Write Protected */
+ RES_NOTRDY, /* 3: Not Ready */
+ RES_PARERR /* 4: Invalid Parameter */
+} DRESULT;
+
+
+/*---------------------------------------*/
+/* Prototypes for disk control functions */
+
+
+DSTATUS disk_initialize (BYTE pdrv);
+DSTATUS disk_status (BYTE pdrv);
+DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count);
+DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count);
+DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);
+
+
+/* Disk Status Bits (DSTATUS) */
+
+#define STA_NOINIT 0x01 /* Drive not initialized */
+#define STA_NODISK 0x02 /* No medium in the drive */
+#define STA_PROTECT 0x04 /* Write protected */
+
+
+/* Command code for disk_ioctrl fucntion */
+
+/* Generic command (Used by FatFs) */
+#define CTRL_SYNC 0 /* Complete pending write process (needed at _FS_READONLY == 0) */
+#define GET_SECTOR_COUNT 1 /* Get media size (needed at _USE_MKFS == 1) */
+#define GET_SECTOR_SIZE 2 /* Get sector size (needed at _MAX_SS != _MIN_SS) */
+#define GET_BLOCK_SIZE 3 /* Get erase block size (needed at _USE_MKFS == 1) */
+#define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at _USE_TRIM == 1) */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cc3200/fatfs/src/drivers/sd_diskio.c b/cc3200/fatfs/src/drivers/sd_diskio.c
new file mode 100644
index 000000000..29d92dd64
--- /dev/null
+++ b/cc3200/fatfs/src/drivers/sd_diskio.c
@@ -0,0 +1,446 @@
+//*****************************************************************************
+// sd_diskio.c
+//
+// Low level SD Card access hookup for FatFS
+//
+// Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
+//
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the
+// distribution.
+//
+// Neither the name of Texas Instruments Incorporated nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+//*****************************************************************************
+#include <stdbool.h>
+
+#include "mpconfig.h"
+#include MICROPY_HAL_H
+#include "misc.h"
+#include "nlr.h"
+#include "qstr.h"
+#include "obj.h"
+#include "objtuple.h"
+#include "objlist.h"
+#include "runtime.h"
+#include "hw_types.h"
+#include "hw_memmap.h"
+#include "hw_ints.h"
+#include "rom.h"
+#include "rom_map.h"
+#include "diskio.h"
+#include "sd_diskio.h"
+#include "sdhost.h"
+#include "pin.h"
+#include "prcm.h"
+#include "stdcmd.h"
+#include "utils.h"
+
+//*****************************************************************************
+// Macros
+//*****************************************************************************
+#define DISKIO_RETRY_TIMEOUT 0xFFFFFFFF
+
+#define CARD_TYPE_UNKNOWN 0
+#define CARD_TYPE_MMC 1
+#define CARD_TYPE_SDCARD 2
+
+#define CARD_CAP_CLASS_SDSC 0
+#define CARD_CAP_CLASS_SDHC 1
+
+#define CARD_VERSION_1 0
+#define CARD_VERSION_2 1
+
+//*****************************************************************************
+// Disk Info for attached disk
+//*****************************************************************************
+DiskInfo_t sd_disk_info = {CARD_TYPE_UNKNOWN, CARD_VERSION_1, CARD_CAP_CLASS_SDSC, 0, 0, STA_NOINIT, 0};
+
+//*****************************************************************************
+//
+//! Send Command to card
+//!
+//! \param ulCmd is the command to be send
+//! \paran ulArg is the command argument
+//!
+//! This function sends command to attached card and check the response status
+//! if any.
+//!
+//! \return Returns 0 on success, 1 otherwise
+//
+//*****************************************************************************
+static unsigned int CardSendCmd (unsigned int ulCmd, unsigned int ulArg) {
+ unsigned long ulStatus;
+
+ // Clear interrupt status
+ MAP_SDHostIntClear(SDHOST_BASE,0xFFFFFFFF);
+
+ // Send command
+ MAP_SDHostCmdSend(SDHOST_BASE,ulCmd,ulArg);
+
+ // Wait for command complete or error
+ do {
+ ulStatus = MAP_SDHostIntStatus(SDHOST_BASE);
+ ulStatus = (ulStatus & (SDHOST_INT_CC | SDHOST_INT_ERRI));
+ } while (!ulStatus);
+
+ // Check error status
+ if (ulStatus & SDHOST_INT_ERRI) {
+ // Reset the command line
+ MAP_SDHostCmdReset(SDHOST_BASE);
+ return 1;
+ }
+ else {
+ return 0;
+ }
+}
+
+//*****************************************************************************
+//
+//! Get the capacity of specified card
+//!
+//! \param ulRCA is the Relative Card Address (RCA)
+//!
+//! This function gets the capacity of card addressed by \e ulRCA paramaeter.
+//!
+//! \return Returns 0 on success, 1 otherwise.
+//
+//*****************************************************************************
+static unsigned int CardCapacityGet(DiskInfo_t *psDiskInfo) {
+ unsigned long ulRet;
+ unsigned long ulResp[4];
+ unsigned long ulBlockSize;
+ unsigned long ulBlockCount;
+ unsigned long ulCSizeMult;
+ unsigned long ulCSize;
+
+ // Read the CSD register
+ ulRet = CardSendCmd(CMD_SEND_CSD, (psDiskInfo->usRCA << 16));
+
+ if(ulRet == 0) {
+ // Read the response
+ MAP_SDHostRespGet(SDHOST_BASE,ulResp);
+
+ // 136 bit CSD register is read into an array of 4 words.
+ // ulResp[0] = CSD[31:0]
+ // ulResp[1] = CSD[63:32]
+ // ulResp[2] = CSD[95:64]
+ // ulResp[3] = CSD[127:96]
+ if(ulResp[3] >> 30) {
+ ulBlockSize = SD_SECTOR_SIZE * 1024;
+ ulBlockCount = (ulResp[1] >> 16 | ((ulResp[2] & 0x3F) << 16)) + 1;
+ }
+ else {
+ ulBlockSize = 1 << ((ulResp[2] >> 16) & 0xF);
+ ulCSizeMult = ((ulResp[1] >> 15) & 0x7);
+ ulCSize = ((ulResp[1] >> 30) | (ulResp[2] & 0x3FF) << 2);
+ ulBlockCount = (ulCSize + 1) * (1 << (ulCSizeMult + 2));
+ }
+
+ // Calculate the card capacity in bytes
+ psDiskInfo->ulBlockSize = ulBlockSize;
+ psDiskInfo->ulNofBlock = ulBlockCount;
+ }
+
+ return ulRet;
+}
+
+//*****************************************************************************
+//
+//! Select a card for reading or writing
+//!
+//! \param Card is the pointer to card attribute structure.
+//!
+//! This function selects a card for reading or writing using its RCA from
+//! \e Card parameter.
+//!
+//! \return Returns 0 success, 1 otherwise.
+//
+//*****************************************************************************
+static unsigned int CardSelect (DiskInfo_t *sDiskInfo) {
+ unsigned long ulRCA;
+ unsigned long ulRet;
+
+ ulRCA = sDiskInfo->usRCA;
+
+ // Send select command with card's RCA.
+ ulRet = CardSendCmd(CMD_SELECT_CARD, (ulRCA << 16));
+
+ if (ulRet == 0) {
+ while (!(MAP_SDHostIntStatus(SDHOST_BASE) & SDHOST_INT_TC));
+ }
+
+ // Delay 250ms for the card to become ready
+ HAL_Delay (250);
+
+ return ulRet;
+}
+
+//*****************************************************************************
+//
+//! Initializes physical drive
+//!
+//! This function initializes the physical drive
+//!
+//! \return Returns 0 on succeeded.
+//*****************************************************************************
+DSTATUS sd_disk_init (void) {
+ unsigned long ulRet;
+ unsigned long ulResp[4];
+
+ if (sd_disk_info.bStatus != 0) {
+ sd_disk_info.bStatus = STA_NODISK;
+ // Send std GO IDLE command
+ if (CardSendCmd(CMD_GO_IDLE_STATE, 0) == 0) {
+ // Get interface operating condition for the card
+ ulRet = CardSendCmd(CMD_SEND_IF_COND,0x000001A5);
+ MAP_SDHostRespGet(SDHOST_BASE,ulResp);
+
+ // It's a SD ver 2.0 or higher card
+ if (ulRet == 0 && ((ulResp[0] & 0xFF) == 0xA5)) {
+ // Version 1 card do not respond to this command
+ sd_disk_info.ulVersion = CARD_VERSION_2;
+ sd_disk_info.ucCardType = CARD_TYPE_SDCARD;
+
+ // Wait for card to become ready.
+ do {
+ // Send ACMD41
+ CardSendCmd(CMD_APP_CMD, 0);
+ ulRet = CardSendCmd(CMD_SD_SEND_OP_COND, 0x40E00000);
+
+ // Response contains 32-bit OCR register
+ MAP_SDHostRespGet(SDHOST_BASE, ulResp);
+
+ } while (((ulResp[0] >> 31) == 0));
+
+ if (ulResp[0] & (1UL<<30)) {
+ sd_disk_info.ulCapClass = CARD_CAP_CLASS_SDHC;
+ }
+ sd_disk_info.bStatus = 0;
+ }
+ //It's a MMC or SD 1.x card
+ else {
+ // Wait for card to become ready.
+ do {
+ CardSendCmd(CMD_APP_CMD, 0);
+ ulRet = CardSendCmd(CMD_SD_SEND_OP_COND,0x00E00000);
+ if (ulRet == 0) {
+ // Response contains 32-bit OCR register
+ MAP_SDHostRespGet(SDHOST_BASE, ulResp);
+ }
+ } while (((ulRet == 0) && (ulResp[0] >> 31) == 0));
+
+ if (ulRet == 0) {
+ sd_disk_info.ucCardType = CARD_TYPE_SDCARD;
+ sd_disk_info.bStatus = 0;
+ }
+ else {
+ if (CardSendCmd(CMD_SEND_OP_COND, 0) == 0) {
+ // MMC not supported by the controller
+ sd_disk_info.ucCardType = CARD_TYPE_MMC;
+ }
+ }
+ }
+ }
+
+ // Get the RCA of the attached card
+ if (sd_disk_info.bStatus == 0) {
+ ulRet = CardSendCmd(CMD_ALL_SEND_CID, 0);
+ if (ulRet == 0) {
+ CardSendCmd(CMD_SEND_REL_ADDR,0);
+ MAP_SDHostRespGet(SDHOST_BASE, ulResp);
+
+ // Fill in the RCA
+ sd_disk_info.usRCA = (ulResp[0] >> 16);
+
+ // Get tha card capacity
+ CardCapacityGet(&sd_disk_info);
+ }
+
+ // Select the card.
+ ulRet = CardSelect(&sd_disk_info);
+ if (ulRet == 0) {
+ sd_disk_info.bStatus = 0;
+ }
+ }
+ // Set card rd/wr block len
+ MAP_SDHostBlockSizeSet(SDHOST_BASE, SD_SECTOR_SIZE);
+ }
+
+ return sd_disk_info.bStatus;
+}
+
+//*****************************************************************************
+//
+//! Gets the disk status.
+//!
+//! This function gets the current status of the drive.
+//!
+//! \return Returns the current status of the specified drive
+//
+//*****************************************************************************
+DSTATUS sd_disk_status (void) {
+ return sd_disk_info.bStatus;
+}
+
+//*****************************************************************************
+//
+//! Returns wether the sd card is ready to be accessed or not
+//
+//*****************************************************************************
+bool sd_disk_ready (void) {
+ return (!sd_disk_info.bStatus);
+}
+
+//*****************************************************************************
+//
+//! Reads sector(s) from the disk drive.
+//!
+//!
+//! This function reads specified number of sectors from the drive
+//!
+//! \return Returns RES_OK on success.
+//
+//*****************************************************************************
+DRESULT sd_disk_read (BYTE* pBuffer, DWORD ulSectorNumber, UINT SectorCount) {
+ DRESULT Res = RES_ERROR;
+ unsigned long ulSize;
+
+ if (SectorCount > 0) {
+ // Return if disk not initialized
+ if (sd_disk_info.bStatus & STA_NOINIT) {
+ return RES_NOTRDY;
+ }
+
+ // SDSC uses linear address, SDHC uses block address
+ if (sd_disk_info.ulCapClass == CARD_CAP_CLASS_SDSC) {
+ ulSectorNumber = ulSectorNumber * SD_SECTOR_SIZE;
+ }
+
+ // Set the block count
+ MAP_SDHostBlockCountSet(SDHOST_BASE, SectorCount);
+
+ // Compute the number of words
+ ulSize = (SD_SECTOR_SIZE * SectorCount) / 4;
+
+ // Check if 1 block or multi block transfer
+ if (SectorCount == 1) {
+ // Send single block read command
+ if (CardSendCmd(CMD_READ_SINGLE_BLK, ulSectorNumber) == 0) {
+ // Read the block of data
+ while (ulSize--) {
+ MAP_SDHostDataRead(SDHOST_BASE, (unsigned long *)pBuffer);
+ pBuffer += 4;
+ }
+ Res = RES_OK;
+ }
+ }
+ else {
+ // Send multi block read command
+ if (CardSendCmd(CMD_READ_MULTI_BLK, ulSectorNumber) == 0) {
+ // Read the data
+ while (ulSize--) {
+ MAP_SDHostDataRead(SDHOST_BASE, (unsigned long *)pBuffer);
+ pBuffer += 4;
+ }
+ CardSendCmd(CMD_STOP_TRANS, 0);
+ Res = RES_OK;
+ }
+ }
+ }
+
+ return Res;
+}
+
+//*****************************************************************************
+//
+//! Wrties sector(s) to the disk drive.
+//!
+//!
+//! This function writes specified number of sectors to the drive
+//!
+//! \return Returns RES_OK on success.
+//
+//*****************************************************************************
+DRESULT sd_disk_write (const BYTE* pBuffer, DWORD ulSectorNumber, UINT SectorCount) {
+ DRESULT Res = RES_ERROR;
+ unsigned long ulSize;
+
+ if (SectorCount > 0) {
+ // Return if disk not initialized
+ if (sd_disk_info.bStatus & STA_NOINIT) {
+ return RES_NOTRDY;
+ }
+
+ // SDSC uses linear address, SDHC uses block address
+ if (sd_disk_info.ulCapClass == CARD_CAP_CLASS_SDSC) {
+ ulSectorNumber = ulSectorNumber * SD_SECTOR_SIZE;
+ }
+
+ // Set the block count
+ MAP_SDHostBlockCountSet(SDHOST_BASE, SectorCount);
+
+ // Compute the number of words
+ ulSize = (SD_SECTOR_SIZE * SectorCount) / 4;
+
+ // Check if 1 block or multi block transfer
+ if (SectorCount == 1) {
+ // Send single block write command
+ if (CardSendCmd(CMD_WRITE_SINGLE_BLK, ulSectorNumber) == 0) {
+ // Write the data
+ while (ulSize--) {
+ MAP_SDHostDataWrite (SDHOST_BASE, (*(unsigned long *)pBuffer));
+ pBuffer += 4;
+ }
+ // Wait for data transfer complete
+ while (!(MAP_SDHostIntStatus(SDHOST_BASE) & SDHOST_INT_TC));
+ Res = RES_OK;
+ }
+ }
+ else {
+ // Set the card write block count
+ if (sd_disk_info.ucCardType == CARD_TYPE_SDCARD) {
+ CardSendCmd(CMD_APP_CMD,sd_disk_info.usRCA << 16);
+ CardSendCmd(CMD_SET_BLK_CNT, SectorCount);
+ }
+
+ // Send multi block write command
+ if (CardSendCmd(CMD_WRITE_MULTI_BLK, ulSectorNumber) == 0) {
+ // Write the data buffer
+ while (ulSize--) {
+ MAP_SDHostDataWrite(SDHOST_BASE, (*(unsigned long *)pBuffer));
+ pBuffer += 4;
+ }
+ // Wait for transfer complete
+ while (!(MAP_SDHostIntStatus(SDHOST_BASE) & SDHOST_INT_TC));
+ CardSendCmd(CMD_STOP_TRANS, 0);
+ Res = RES_OK;
+ }
+ }
+ }
+
+ return Res;
+}
diff --git a/cc3200/fatfs/src/drivers/sd_diskio.h b/cc3200/fatfs/src/drivers/sd_diskio.h
new file mode 100644
index 000000000..93135c798
--- /dev/null
+++ b/cc3200/fatfs/src/drivers/sd_diskio.h
@@ -0,0 +1,28 @@
+#ifndef SD_DISKIO_H_
+#define SD_DISKIO_H_
+
+#define SD_SECTOR_SIZE 512
+
+//*****************************************************************************
+// Disk Info Structure definition
+//*****************************************************************************
+typedef struct
+{
+ unsigned char ucCardType;
+ unsigned int ulVersion;
+ unsigned int ulCapClass;
+ unsigned int ulNofBlock;
+ unsigned int ulBlockSize;
+ DSTATUS bStatus;
+ unsigned short usRCA;
+}DiskInfo_t;
+
+extern DiskInfo_t sd_disk_info;
+
+DSTATUS sd_disk_init (void);
+DSTATUS sd_disk_status (void);
+bool sd_disk_ready (void);
+DRESULT sd_disk_read (BYTE* pBuffer, DWORD ulSectorNumber, UINT bSectorCount);
+DRESULT sd_disk_write (const BYTE* pBuffer, DWORD ulSectorNumber, UINT bSectorCount);
+
+#endif /* SD_DISKIO_H_ */
diff --git a/cc3200/fatfs/src/drivers/sflash_diskio.c b/cc3200/fatfs/src/drivers/sflash_diskio.c
new file mode 100644
index 000000000..cb28913bf
--- /dev/null
+++ b/cc3200/fatfs/src/drivers/sflash_diskio.c
@@ -0,0 +1,186 @@
+#include <stdint.h>
+#include <stdbool.h>
+#include "std.h"
+
+#include "mpconfig.h"
+#include MICROPY_HAL_H
+#include "simplelink.h"
+#include "diskio.h"
+#include "sflash_diskio.h"
+#include "debug.h"
+#include "modwlan.h"
+
+#ifdef USE_FREERTOS
+#include "FreeRTOS.h"
+#include "task.h"
+#include "semphr.h"
+#endif
+
+#define SFLASH_TIMEOUT_MAX_MS 5500
+#define SFLASH_WAIT_TIME_MS 5
+
+static _u8 sflash_block_name[] = "__NNN__.fsb";
+static _u8 *sflash_block_cache;
+static bool sflash_init_done = false;
+static bool sflash_cache_is_dirty;
+static uint32_t sflash_ublock;
+static uint32_t sflash_prblock;
+
+
+static void print_block_name (_u32 ublock) {
+ char _sblock[4];
+ snprintf (_sblock, sizeof(_sblock), "%03u", ublock);
+ memcpy (&sflash_block_name[2], _sblock, 3);
+}
+
+static bool sflash_access (_u32 mode, _i32 (* sl_FsFunction)(_i32 FileHdl, _u32 Offset, _u8* pData, _u32 Len)) {
+ _i32 fileHandle;
+ bool retval = false;
+
+ // wlan must be enabled in order to access the serial flash
+#ifdef USE_FREERTOS
+ xSemaphoreTake (xWlanSemaphore, portMAX_DELAY);
+#endif
+ if (0 == sl_FsOpen(sflash_block_name, mode, NULL, &fileHandle)) {
+ if (SFLASH_BLOCK_SIZE == sl_FsFunction (fileHandle, 0, sflash_block_cache, SFLASH_BLOCK_SIZE)) {
+ retval = true;
+ }
+ sl_FsClose (fileHandle, NULL, NULL, 0);
+ }
+#ifdef USE_FREERTOS
+ xSemaphoreGive (xWlanSemaphore);
+#endif
+ return retval;
+}
+
+DRESULT sflash_disk_init (void) {
+ _i32 fileHandle;
+ SlFsFileInfo_t FsFileInfo;
+
+ if (!sflash_init_done) {
+ // Allocate space for the block cache
+ ASSERT ((sflash_block_cache = mem_Malloc(SFLASH_BLOCK_SIZE)) != NULL);
+
+ // Proceed to format the memory if not done yet
+ for (int i = 0; i < SFLASH_BLOCK_COUNT; i++) {
+ print_block_name (i);
+ #ifdef USE_FREERTOS
+ xSemaphoreTake (xWlanSemaphore, portMAX_DELAY);
+ #endif
+ // Create the block file if it doesn't exist
+ if (sl_FsGetInfo(sflash_block_name, 0, &FsFileInfo) < 0) {
+ if (!sl_FsOpen(sflash_block_name, FS_MODE_OPEN_CREATE(SFLASH_BLOCK_SIZE, 0), NULL, &fileHandle)) {
+ sl_FsClose(fileHandle, NULL, NULL, 0);
+ #ifdef USE_FREERTOS
+ xSemaphoreGive (xWlanSemaphore);
+ #endif
+ memset(sflash_block_cache, 0xFF, SFLASH_BLOCK_SIZE);
+ if (!sflash_access(FS_MODE_OPEN_WRITE, sl_FsWrite)) {
+ return RES_ERROR;
+ }
+ }
+ else {
+ // Unexpected failure while creating the file
+ #ifdef USE_FREERTOS
+ xSemaphoreGive (xWlanSemaphore);
+ #endif
+ return RES_ERROR;
+ }
+ }
+ #ifdef USE_FREERTOS
+ xSemaphoreGive (xWlanSemaphore);
+ #endif
+ }
+ sflash_init_done = true;
+ sflash_prblock = UINT32_MAX;
+ sflash_cache_is_dirty = false;
+ }
+ return RES_OK;
+}
+
+DRESULT sflash_disk_status(void) {
+ if (!sflash_init_done) {
+ return STA_NOINIT;
+ }
+ return 0;
+}
+
+DRESULT sflash_disk_read(BYTE *buff, DWORD sector, UINT count) {
+ uint32_t secindex;
+
+ if (!sflash_init_done) {
+ return STA_NOINIT;
+ }
+
+ if (sector + count > SFLASH_SECTOR_COUNT || count == 0) {
+ return RES_PARERR;
+ }
+
+ for (int i = 0; i < count; i++) {
+ secindex = (sector + i) % SFLASH_SECTORS_PER_BLOCK;
+ sflash_ublock = (sector + i) / SFLASH_SECTORS_PER_BLOCK;
+ // See if it's time to read a new block
+ if (sflash_prblock != sflash_ublock) {
+ if (sflash_disk_flush() != RES_OK) {
+ return RES_ERROR;
+ }
+ sflash_prblock = sflash_ublock;
+ print_block_name (sflash_ublock);
+ if (!sflash_access(FS_MODE_OPEN_READ, sl_FsRead)) {
+ return RES_ERROR;
+ }
+ }
+ // Copy the requested sector from the block cache
+ memcpy (buff, &sflash_block_cache[(secindex * SFLASH_SECTOR_SIZE)], SFLASH_SECTOR_SIZE);
+ buff += SFLASH_BLOCK_SIZE;
+ }
+ return RES_OK;
+}
+
+DRESULT sflash_disk_write(const BYTE *buff, DWORD sector, UINT count) {
+ uint32_t secindex;
+ int32_t index = 0;
+
+ if (!sflash_init_done) {
+ return STA_NOINIT;
+ }
+
+ if (sector + count > SFLASH_SECTOR_COUNT || count == 0) {
+ return RES_PARERR;
+ }
+
+ do {
+ secindex = (sector + index) % SFLASH_SECTORS_PER_BLOCK;
+ sflash_ublock = (sector + index) / SFLASH_SECTORS_PER_BLOCK;
+ // Check if it's a different block than last time
+ if (sflash_prblock != sflash_ublock) {
+ if (sflash_disk_flush() != RES_OK) {
+ return RES_ERROR;
+ }
+ sflash_prblock = sflash_ublock;
+ print_block_name (sflash_ublock);
+ // Read the block into the cache
+ if (!sflash_access(FS_MODE_OPEN_READ, sl_FsRead)) {
+ return RES_ERROR;
+ }
+ }
+ // Copy the input sector to the block cache
+ memcpy (&sflash_block_cache[(secindex * SFLASH_SECTOR_SIZE)], buff, SFLASH_SECTOR_SIZE);
+ buff += SFLASH_BLOCK_SIZE;
+ sflash_cache_is_dirty = true;
+ } while (++index < count);
+
+ return RES_OK;
+}
+
+DRESULT sflash_disk_flush (void) {
+ // Write back the cache if it's dirty
+ if (sflash_cache_is_dirty) {
+ if (!sflash_access(FS_MODE_OPEN_WRITE, sl_FsWrite)) {
+ return RES_ERROR;
+ }
+ sflash_cache_is_dirty = false;
+ }
+ return RES_OK;
+}
+
diff --git a/cc3200/fatfs/src/drivers/sflash_diskio.h b/cc3200/fatfs/src/drivers/sflash_diskio.h
new file mode 100644
index 000000000..26669f589
--- /dev/null
+++ b/cc3200/fatfs/src/drivers/sflash_diskio.h
@@ -0,0 +1,16 @@
+#ifndef SFLASH_DISKIO_H_
+#define SFLASH_DISKIO_H_
+
+#define SFLASH_BLOCK_SIZE 2048
+#define SFLASH_BLOCK_COUNT 32 // makes for 64KB of space
+#define SFLASH_SECTOR_SIZE 512
+#define SFLASH_SECTOR_COUNT ((SFLASH_BLOCK_SIZE * SFLASH_BLOCK_COUNT) / SFLASH_SECTOR_SIZE)
+#define SFLASH_SECTORS_PER_BLOCK (SFLASH_BLOCK_SIZE / SFLASH_SECTOR_SIZE)
+
+DRESULT sflash_disk_init(void);
+DRESULT sflash_disk_status(void);
+DRESULT sflash_disk_read(BYTE *buff, DWORD sector, UINT count);
+DRESULT sflash_disk_write(const BYTE *buff, DWORD sector, UINT count);
+DRESULT sflash_disk_flush(void);
+
+#endif /* SFLASH_DISKIO_H_ */
diff --git a/cc3200/fatfs/src/drivers/stdcmd.h b/cc3200/fatfs/src/drivers/stdcmd.h
new file mode 100644
index 000000000..464e2ddfa
--- /dev/null
+++ b/cc3200/fatfs/src/drivers/stdcmd.h
@@ -0,0 +1,62 @@
+//*****************************************************************************
+// stdcmd.h
+//
+// Defines standard SD Card commands for CC3200 SDHOST module.
+//
+// Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
+//
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the
+// distribution.
+//
+// Neither the name of Texas Instruments Incorporated nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+//*****************************************************************************
+
+#ifndef __STDCMD_H__
+#define __STDCMD_H__
+
+//*****************************************************************************
+// Standard MMC/SD Card Commands
+//*****************************************************************************
+#define CMD_GO_IDLE_STATE SDHOST_CMD_0
+#define CMD_SEND_IF_COND SDHOST_CMD_8|SDHOST_RESP_LEN_48
+#define CMD_SEND_CSD SDHOST_CMD_9|SDHOST_RESP_LEN_136
+#define CMD_APP_CMD SDHOST_CMD_55|SDHOST_RESP_LEN_48
+#define CMD_SD_SEND_OP_COND SDHOST_CMD_41|SDHOST_RESP_LEN_48
+#define CMD_SEND_OP_COND SDHOST_CMD_1|SDHOST_RESP_LEN_48
+#define CMD_READ_SINGLE_BLK SDHOST_CMD_17|SDHOST_RD_CMD|SDHOST_RESP_LEN_48
+#define CMD_READ_MULTI_BLK SDHOST_CMD_18|SDHOST_RD_CMD|SDHOST_RESP_LEN_48|SDHOST_MULTI_BLK
+#define CMD_WRITE_SINGLE_BLK SDHOST_CMD_24|SDHOST_WR_CMD|SDHOST_RESP_LEN_48
+#define CMD_WRITE_MULTI_BLK SDHOST_CMD_25|SDHOST_WR_CMD|SDHOST_RESP_LEN_48|SDHOST_MULTI_BLK
+#define CMD_SELECT_CARD SDHOST_CMD_7|SDHOST_RESP_LEN_48B
+#define CMD_DESELECT_CARD SDHOST_CMD_7
+#define CMD_STOP_TRANS SDHOST_CMD_12|SDHOST_RESP_LEN_48B
+#define CMD_SET_BLK_CNT SDHOST_CMD_23|SDHOST_RESP_LEN_48
+#define CMD_ALL_SEND_CID SDHOST_CMD_2|SDHOST_RESP_LEN_136
+#define CMD_SEND_REL_ADDR SDHOST_CMD_3|SDHOST_RESP_LEN_48
+
+#endif //__STDCMD_H__
diff --git a/cc3200/fatfs/src/ffconf.c b/cc3200/fatfs/src/ffconf.c
new file mode 100644
index 000000000..a52eed55a
--- /dev/null
+++ b/cc3200/fatfs/src/ffconf.c
@@ -0,0 +1,99 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2013, 2014 Damien P. George
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <string.h>
+#include <std.h>
+
+#include "mpconfig.h"
+#include "misc.h"
+#include "qstr.h"
+#include "obj.h"
+#include "ff.h"
+#include "ffconf.h"
+#include "diskio.h"
+
+#if _FS_RPATH
+extern BYTE ff_CurrVol;
+#endif
+
+STATIC bool check_path(const TCHAR **path, const char *mount_point_str, mp_uint_t mount_point_len) {
+ stoupper ((char *)(*path));
+ if (strncmp(*path, mount_point_str, mount_point_len) == 0) {
+ if ((*path)[mount_point_len] == '/') {
+ *path += mount_point_len;
+ return true;
+ } else if ((*path)[mount_point_len] == '\0') {
+ *path = "/";
+ return true;
+ }
+ }
+ return false;
+}
+
+// "path" is the path to lookup; will advance this pointer beyond the volume name.
+// Returns logical drive number (-1 means invalid path).
+int ff_get_ldnumber (const TCHAR **path) {
+ if (!(*path)) {
+ return -1;
+ }
+
+ if (**path != '/') {
+ #if _FS_RPATH
+ return ff_CurrVol;
+ #else
+ return -1;
+ #endif
+ }
+
+ if (check_path(path, "/SFLASH", 7)) {
+ return 0;
+ }
+#if MICROPY_HW_HAS_SDCARD
+ else if (check_path(path, "/SD", 3)) {
+ return 1;
+ }
+#endif
+ else {
+ return -1;
+ }
+}
+
+void ff_get_volname(BYTE vol, TCHAR **dest) {
+#if MICROPY_HW_HAS_SDCARD
+ if (vol == 0)
+#endif
+ {
+ memcpy(*dest, "/SFLASH", 7);
+ *dest += 7;
+ }
+#if MICROPY_HW_HAS_SDCARD
+ else
+ {
+ memcpy(*dest, "/SD", 3);
+ *dest += 3;
+ }
+#endif
+}
diff --git a/cc3200/fatfs/src/ffconf.h b/cc3200/fatfs/src/ffconf.h
new file mode 100644
index 000000000..d2d123e2e
--- /dev/null
+++ b/cc3200/fatfs/src/ffconf.h
@@ -0,0 +1,276 @@
+/*---------------------------------------------------------------------------/
+/ FatFs - FAT file system module configuration file R0.10c (C)ChaN, 2014
+/---------------------------------------------------------------------------*/
+
+#include <stdint.h>
+#include "mpconfig.h"
+#include "FreeRTOS.h"
+#include "task.h"
+#include "semphr.h"
+
+#define _FFCONF 80376 /* Revision ID */
+
+/*---------------------------------------------------------------------------/
+/ Functions and Buffer Configurations
+/---------------------------------------------------------------------------*/
+
+#define _FS_TINY 1
+/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)
+/ At the tiny configuration, size of the file object (FIL) is reduced _MAX_SS
+/ bytes. Instead of private sector buffer eliminated from the file object,
+/ common sector buffer in the file system object (FATFS) is used for the file
+/ data transfer. */
+
+
+#define _FS_READONLY 0
+/* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
+/ Read-only configuration removes basic writing API functions, f_write(),
+/ f_sync(), f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(),
+/ f_getfree() and optional writing functions as well. */
+
+
+#define _FS_MINIMIZE 0
+/* This option defines minimization level to remove some API functions.
+/
+/ 0: All basic functions are enabled.
+/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_chmod(), f_utime(),
+/ f_truncate() and f_rename() function are removed.
+/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1.
+/ 3: f_lseek() function is removed in addition to 2. */
+
+
+#define _USE_STRFUNC 0
+/* This option switches string functions, f_gets(), f_putc(), f_puts() and
+/ f_printf().
+/
+/ 0: Disable string functions.
+/ 1: Enable without LF-CRLF conversion.
+/ 2: Enable with LF-CRLF conversion. */
+
+
+#define _USE_MKFS 1
+/* This option switches f_mkfs() function. (0:Disable or 1:Enable)
+/ To enable it, also _FS_READONLY need to be set to 0. */
+
+
+#define _USE_FASTSEEK 0
+/* This option switches fast seek feature. (0:Disable or 1:Enable) */
+
+
+#define _USE_LABEL 0
+/* This option switches volume label functions, f_getlabel() and f_setlabel().
+/ (0:Disable or 1:Enable) */
+
+
+#define _USE_FORWARD 0
+/* This option switches f_forward() function. (0:Disable or 1:Enable) */
+/* To enable it, also _FS_TINY need to be set to 1. */
+
+
+/*---------------------------------------------------------------------------/
+/ Locale and Namespace Configurations
+/---------------------------------------------------------------------------*/
+
+#define _CODE_PAGE (MICROPY_LFN_CODE_PAGE)
+/* This option specifies the OEM code page to be used on the target system.
+/ Incorrect setting of the code page can cause a file open failure.
+/
+/ 932 - Japanese Shift_JIS (DBCS, OEM, Windows)
+/ 936 - Simplified Chinese GBK (DBCS, OEM, Windows)
+/ 949 - Korean (DBCS, OEM, Windows)
+/ 950 - Traditional Chinese Big5 (DBCS, OEM, Windows)
+/ 1250 - Central Europe (Windows)
+/ 1251 - Cyrillic (Windows)
+/ 1252 - Latin 1 (Windows)
+/ 1253 - Greek (Windows)
+/ 1254 - Turkish (Windows)
+/ 1255 - Hebrew (Windows)
+/ 1256 - Arabic (Windows)
+/ 1257 - Baltic (Windows)
+/ 1258 - Vietnam (OEM, Windows)
+/ 437 - U.S. (OEM)
+/ 720 - Arabic (OEM)
+/ 737 - Greek (OEM)
+/ 775 - Baltic (OEM)
+/ 850 - Multilingual Latin 1 (OEM)
+/ 858 - Multilingual Latin 1 + Euro (OEM)
+/ 852 - Latin 2 (OEM)
+/ 855 - Cyrillic (OEM)
+/ 866 - Russian (OEM)
+/ 857 - Turkish (OEM)
+/ 862 - Hebrew (OEM)
+/ 874 - Thai (OEM, Windows)
+/ 1 - ASCII (No extended character. Valid for only non-LFN configuration.) */
+
+
+#define _USE_LFN (MICROPY_ENABLE_LFN)
+#define _MAX_LFN (MICROPY_ALLOC_PATH_MAX)
+/* The _USE_LFN option switches the LFN feature.
+/
+/ 0: Disable LFN feature. _MAX_LFN has no effect.
+/ 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe.
+/ 2: Enable LFN with dynamic working buffer on the STACK.
+/ 3: Enable LFN with dynamic working buffer on the HEAP.
+/
+/ When enable the LFN feature, Unicode handling functions (option/unicode.c) must
+/ be added to the project. The LFN working buffer occupies (_MAX_LFN + 1) * 2 bytes.
+/ When use stack for the working buffer, take care on stack overflow. When use heap
+/ memory for the working buffer, memory management functions, ff_memalloc() and
+/ ff_memfree(), must be added to the project. */
+
+
+#define _LFN_UNICODE 0
+/* This option switches character encoding on the API. (0:ANSI/OEM or 1:Unicode)
+/ To use Unicode string for the path name, enable LFN feature and set _LFN_UNICODE
+/ to 1. This option also affects behavior of string I/O functions. */
+
+
+#define _STRF_ENCODE 3
+/* When _LFN_UNICODE is 1, this option selects the character encoding on the file to
+/ be read/written via string I/O functions, f_gets(), f_putc(), f_puts and f_printf().
+/
+/ 0: ANSI/OEM
+/ 1: UTF-16LE
+/ 2: UTF-16BE
+/ 3: UTF-8
+/
+/ When _LFN_UNICODE is 0, this option has no effect. */
+
+
+#define _FS_RPATH 2
+/* This option configures relative path feature.
+/
+/ 0: Disable relative path feature and remove related functions.
+/ 1: Enable relative path feature. f_chdir() and f_chdrive() are available.
+/ 2: f_getcwd() function is available in addition to 1.
+/
+/ Note that directory items read via f_readdir() are affected by this option. */
+
+
+/*---------------------------------------------------------------------------/
+/ Drive/Volume Configurations
+/---------------------------------------------------------------------------*/
+
+#define _VOLUMES 2
+/* Number of volumes (logical drives) to be used. */
+
+
+#define _STR_VOLUME_ID 0
+#define _VOLUME_STRS "RAM","NAND","CF","SD1","SD2","USB1","USB2","USB3"
+/* _STR_VOLUME_ID option switches string volume ID feature.
+/ When _STR_VOLUME_ID is set to 1, also pre-defined strings can be used as drive
+/ number in the path name. _VOLUME_STRS defines the drive ID strings for each
+/ logical drives. Number of items must be equal to _VOLUMES. Valid characters for
+/ the drive ID strings are: A-Z and 0-9. */
+
+
+#define _MULTI_PARTITION 0
+/* This option switches multi-partition feature. By default (0), each logical drive
+/ number is bound to the same physical drive number and only an FAT volume found on
+/ the physical drive will be mounted. When multi-partition feature is enabled (1),
+/ each logical drive number is bound to arbitrary physical drive and partition
+/ listed in the VolToPart[]. Also f_fdisk() funciton will be enabled. */
+
+
+#define _MIN_SS 512
+#define _MAX_SS 512
+/* These options configure the range of sector size to be supported. (512, 1024,
+/ 2048 or 4096) Always set both 512 for most systems, all type of memory cards and
+/ harddisk. But a larger value may be required for on-board flash memory and some
+/ type of optical media. When _MAX_SS is larger than _MIN_SS, FatFs is configured
+/ to variable sector size and GET_SECTOR_SIZE command must be implemented to the
+/ disk_ioctl() function. */
+
+
+#define _USE_TRIM 0
+/* This option switches ATA-TRIM feature. (0:Disable or 1:Enable)
+/ To enable Trim feature, also CTRL_TRIM command should be implemented to the
+/ disk_ioctl() function. */
+
+
+#define _FS_NOFSINFO 0
+/* If you need to know correct free space on the FAT32 volume, set bit 0 of this
+/ option, and f_getfree() function at first time after volume mount will force
+/ a full FAT scan. Bit 1 controls the use of last allocated cluster number.
+/
+/ bit0=0: Use free cluster count in the FSINFO if available.
+/ bit0=1: Do not trust free cluster count in the FSINFO.
+/ bit1=0: Use last allocated cluster number in the FSINFO if available.
+/ bit1=1: Do not trust last allocated cluster number in the FSINFO.
+*/
+
+
+
+/*---------------------------------------------------------------------------/
+/ System Configurations
+/---------------------------------------------------------------------------*/
+
+#define _FS_NORTC 0
+#define _NORTC_MON 11
+#define _NORTC_MDAY 9
+#define _NORTC_YEAR 2014
+/* The _FS_NORTC option switches timestamp feature. If the system does not have
+/ an RTC function or valid timestamp is not needed, set _FS_NORTC to 1 to disable
+/ the timestamp feature. All objects modified by FatFs will have a fixed timestamp
+/ defined by _NORTC_MON, _NORTC_MDAY and _NORTC_YEAR.
+/ When timestamp feature is enabled (_FS_NORTC == 0), get_fattime() function need
+/ to be added to the project to read current time form RTC. _NORTC_MON,
+/ _NORTC_MDAY and _NORTC_YEAR have no effect.
+/ These options have no effect at read-only configuration (_FS_READONLY == 1). */
+
+
+#define _FS_LOCK 2
+/* The _FS_LOCK option switches file lock feature to control duplicated file open
+/ and illegal operation to open objects. This option must be 0 when _FS_READONLY
+/ is 1.
+/
+/ 0: Disable file lock feature. To avoid volume corruption, application program
+/ should avoid illegal open, remove and rename to the open objects.
+/ >0: Enable file lock feature. The value defines how many files/sub-directories
+/ can be opened simultaneously under file lock control. Note that the file
+/ lock feature is independent of re-entrancy. */
+
+
+#define _FS_REENTRANT 1
+#define _FS_TIMEOUT 2000
+#define _SYNC_t SemaphoreHandle_t
+/* The _FS_REENTRANT option switches the re-entrancy (thread safe) of the FatFs
+/ module itself. Note that regardless of this option, file access to different
+/ volume is always re-entrant and volume control functions, f_mount(), f_mkfs()
+/ and f_fdisk() function, are always not re-entrant. Only file/directory access
+/ to the same volume is under control of this feature.
+/
+/ 0: Disable re-entrancy. _FS_TIMEOUT and _SYNC_t have no effect.
+/ 1: Enable re-entrancy. Also user provided synchronization handlers,
+/ ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj()
+/ function, must be added to the project. Samples are available in
+/ option/syscall.c.
+/
+/ The _FS_TIMEOUT defines timeout period in unit of time tick.
+/ The _SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*,
+/ SemaphoreHandle_t and etc.. */
+
+
+#define _WORD_ACCESS 0
+/* The _WORD_ACCESS option is an only platform dependent option. It defines
+/ which access method is used to the word data on the FAT volume.
+/
+/ 0: Byte-by-byte access. Always compatible with all platforms.
+/ 1: Word access. Do not choose this unless under both the following conditions.
+/
+/ * Address misaligned memory access is always allowed to ALL instructions.
+/ * Byte order on the memory is little-endian.
+/
+/ If it is the case, _WORD_ACCESS can also be set to 1 to reduce code size.
+/ Following table shows allowable settings of some processor types.
+/
+/ ARM7TDMI 0 ColdFire 0 V850E 0
+/ Cortex-M3 0 Z80 0/1 V850ES 0/1
+/ Cortex-M0 0 x86 0/1 TLCS-870 0/1
+/ AVR 0/1 RX600(LE) 0/1 TLCS-900 0/1
+/ AVR32 0 RL78 0 R32C 0
+/ PIC18 0/1 SH-2 0 M16C 0/1
+/ PIC24 0 H8S 0 MSP430 0
+/ PIC32 0 H8/300H 0 8051 0/1
+*/
+
diff --git a/cc3200/fatfs/src/option/syscall.c b/cc3200/fatfs/src/option/syscall.c
new file mode 100644
index 000000000..40c22cd75
--- /dev/null
+++ b/cc3200/fatfs/src/option/syscall.c
@@ -0,0 +1,156 @@
+/*------------------------------------------------------------------------*/
+/* Sample code of OS dependent controls for FatFs */
+/* (C)ChaN, 2014 */
+/*------------------------------------------------------------------------*/
+
+#include "mpconfig.h"
+#include MICROPY_HAL_H
+#include "misc.h"
+#include "nlr.h"
+#include "qstr.h"
+#include "obj.h"
+#include "ff.h"
+
+
+#if _FS_REENTRANT
+/*------------------------------------------------------------------------*/
+/* Create a Synchronization Object */
+/*------------------------------------------------------------------------*/
+/* This function is called in f_mount() function to create a new
+/ synchronization object, such as semaphore and mutex. When a 0 is returned,
+/ the f_mount() function fails with FR_INT_ERR.
+*/
+
+int ff_cre_syncobj ( /* !=0:Function succeeded, ==0:Could not create due to any error */
+ BYTE vol, /* Corresponding logical drive being processed */
+ _SYNC_t *sobj /* Pointer to return the created sync object */
+)
+{
+ int ret;
+
+//
+// *sobj = CreateMutex(NULL, FALSE, NULL); /* Win32 */
+// ret = (int)(*sobj != INVALID_HANDLE_VALUE);
+
+// *sobj = SyncObjects[vol]; /* uITRON (give a static created sync object) */
+// ret = 1; /* The initial value of the semaphore must be 1. */
+
+// *sobj = OSMutexCreate(0, &err); /* uC/OS-II */
+// ret = (int)(err == OS_NO_ERR);
+
+ *sobj = xSemaphoreCreateMutex(); /* FreeRTOS */
+ ret = (int)(*sobj != NULL);
+
+ return ret;
+}
+
+
+
+/*------------------------------------------------------------------------*/
+/* Delete a Synchronization Object */
+/*------------------------------------------------------------------------*/
+/* This function is called in f_mount() function to delete a synchronization
+/ object that created with ff_cre_syncobj function. When a 0 is returned,
+/ the f_mount() function fails with FR_INT_ERR.
+*/
+
+int ff_del_syncobj ( /* !=0:Function succeeded, ==0:Could not delete due to any error */
+ _SYNC_t sobj /* Sync object tied to the logical drive to be deleted */
+)
+{
+ int ret;
+
+
+// ret = CloseHandle(sobj); /* Win32 */
+
+// ret = 1; /* uITRON (nothing to do) */
+
+// OSMutexDel(sobj, OS_DEL_ALWAYS, &err); /* uC/OS-II */
+// ret = (int)(err == OS_NO_ERR);
+
+ vSemaphoreDelete(sobj); /* FreeRTOS */
+ ret = 1;
+
+ return ret;
+}
+
+
+
+/*------------------------------------------------------------------------*/
+/* Request Grant to Access the Volume */
+/*------------------------------------------------------------------------*/
+/* This function is called on entering file functions to lock the volume.
+/ When a 0 is returned, the file function fails with FR_TIMEOUT.
+*/
+
+int ff_req_grant ( /* 1:Got a grant to access the volume, 0:Could not get a grant */
+ _SYNC_t sobj /* Sync object to wait */
+)
+{
+ int ret;
+
+// ret = (int)(WaitForSingleObject(sobj, _FS_TIMEOUT) == WAIT_OBJECT_0); /* Win32 */
+
+// ret = (int)(wai_sem(sobj) == E_OK); /* uITRON */
+
+// OSMutexPend(sobj, _FS_TIMEOUT, &err)); /* uC/OS-II */
+// ret = (int)(err == OS_NO_ERR);
+
+ ret = (int)(xSemaphoreTake(sobj, _FS_TIMEOUT) == pdTRUE); /* FreeRTOS */
+
+ return ret;
+}
+
+
+
+/*------------------------------------------------------------------------*/
+/* Release Grant to Access the Volume */
+/*------------------------------------------------------------------------*/
+/* This function is called on leaving file functions to unlock the volume.
+*/
+
+void ff_rel_grant (
+ _SYNC_t sobj /* Sync object to be signaled */
+)
+{
+// ReleaseMutex(sobj); /* Win32 */
+
+// sig_sem(sobj); /* uITRON */
+
+// OSMutexPost(sobj); /* uC/OS-II */
+
+ xSemaphoreGive(sobj); /* FreeRTOS */
+}
+
+#endif
+
+
+
+
+#if _USE_LFN == 3 /* LFN with a working buffer on the heap */
+/*------------------------------------------------------------------------*/
+/* Allocate a memory block */
+/*------------------------------------------------------------------------*/
+/* If a NULL is returned, the file function fails with FR_NOT_ENOUGH_CORE.
+*/
+
+void* ff_memalloc ( /* Returns pointer to the allocated memory block */
+ UINT msize /* Number of bytes to allocate */
+)
+{
+ return malloc(msize); /* Allocate a new memory block with POSIX API */
+}
+
+
+/*------------------------------------------------------------------------*/
+/* Free a memory block */
+/*------------------------------------------------------------------------*/
+
+void ff_memfree (
+ void* mblock /* Pointer to the memory block to free */
+)
+{
+ free(mblock); /* Discard the memory block with POSIX API */
+}
+
+#endif