Commit dffa9f6d authored by Daniel Campora's avatar Daniel Campora
Browse files

cc3200: New SD and RTC API plus os and time modules' extensions.

parent 660f8613
......@@ -30,9 +30,6 @@
#define MICROPY_HW_BOARD_NAME "LaunchPad"
#define MICROPY_HW_MCU_NAME "CC3200"
#define MICROPY_HW_HAS_SDCARD (0)
#define MICROPY_HW_ENABLE_RNG (1)
#define MICROPY_HW_ENABLE_RTC (1)
#define MICROPY_HW_ANTENNA_DIVERSITY (0)
#define MICROPY_STDIO_UART 0
......
......@@ -30,9 +30,6 @@
#define MICROPY_HW_BOARD_NAME "WiPy"
#define MICROPY_HW_MCU_NAME "CC3200"
#define MICROPY_HW_HAS_SDCARD (1)
#define MICROPY_HW_ENABLE_RNG (1)
#define MICROPY_HW_ENABLE_RTC (1)
#define MICROPY_HW_ANTENNA_DIVERSITY (1)
#define MICROPY_SYS_LED_PRCM PRCM_GPIOA3
......
......@@ -10,12 +10,11 @@
#include <stdbool.h>
#include "py/mpconfig.h"
#include "py/runtime.h"
#include "py/obj.h"
#include "diskio.h" /* FatFs lower layer API */
#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 "sd_diskio.h" /* SDCARD disk IO API */
#include "inc/hw_types.h"
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
......@@ -23,10 +22,9 @@
#include "prcm.h"
#include "pybrtc.h"
#include "timeutils.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 */
#include "ff.h"
#include "pybsd.h"
#include "moduos.h"
/*-----------------------------------------------------------------------*/
......@@ -37,21 +35,20 @@ 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;
if (pdrv == FLASH) {
return sflash_disk_status();
} else {
os_fs_mount_t *mount_obj;
if ((mount_obj = osmount_find_by_volume(pdrv))) {
if (mount_obj->writeblocks[0] == MP_OBJ_NULL) {
return STA_PROTECT;
}
return 0;
}
}
return STA_NODISK;
}
/*-----------------------------------------------------------------------*/
/* Inidialize a Drive */
/*-----------------------------------------------------------------------*/
......@@ -60,29 +57,22 @@ 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;
if (pdrv == FLASH) {
if (RES_OK != sflash_disk_init()) {
return STA_NOINIT;
}
return stat;
#endif
default:
break;
}
return STA_NOINIT;
} else {
os_fs_mount_t *mount_obj;
if ((mount_obj = osmount_find_by_volume(pdrv))) {
if (mount_obj->writeblocks[0] == MP_OBJ_NULL) {
return STA_PROTECT;
}
return 0;
}
}
return STA_NODISK;
}
/*-----------------------------------------------------------------------*/
/* Read Sector(s) */
/*-----------------------------------------------------------------------*/
......@@ -94,22 +84,25 @@ DRESULT disk_read (
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;
if (pdrv == FLASH) {
return sflash_disk_read(buff, sector, count);
} else {
os_fs_mount_t *mount_obj;
if ((mount_obj = osmount_find_by_volume(pdrv))) {
// optimization for the built-in sd card device
if (mount_obj->device == (mp_obj_t)&pybsd_obj) {
return sd_disk_read(buff, sector, count);
}
mount_obj->readblocks[2] = MP_OBJ_NEW_SMALL_INT(sector);
mount_obj->readblocks[3] = mp_obj_new_bytearray_by_ref(count * 512, buff);
return mp_obj_get_int(mp_call_method_n_kw(2, 0, mount_obj->readblocks));
}
// nothing mounted
return RES_ERROR;
}
return RES_PARERR;
}
/*-----------------------------------------------------------------------*/
/* Write Sector(s) */
/*-----------------------------------------------------------------------*/
......@@ -122,18 +115,23 @@ DRESULT disk_write (
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;
if (pdrv == FLASH) {
return sflash_disk_write(buff, sector, count);
} else {
os_fs_mount_t *mount_obj;
if ((mount_obj = osmount_find_by_volume(pdrv))) {
// optimization for the built-in sd card device
if (mount_obj->device == (mp_obj_t)&pybsd_obj) {
return sd_disk_write(buff, sector, count);
}
mount_obj->writeblocks[2] = MP_OBJ_NEW_SMALL_INT(sector);
mount_obj->writeblocks[3] = mp_obj_new_bytearray_by_ref(count * 512, (void *)buff);
return mp_obj_get_int(mp_call_method_n_kw(2, 0, mount_obj->writeblocks));
}
// nothing mounted
return RES_ERROR;
}
return RES_PARERR;
}
#endif
......@@ -149,41 +147,47 @@ DRESULT disk_ioctl (
void *buff /* Buffer to send/receive control data */
)
{
switch (pdrv) {
case SFLASH:
if (pdrv == FLASH) {
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;
*((DWORD*)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;
} else {
os_fs_mount_t *mount_obj;
if ((mount_obj = osmount_find_by_volume(pdrv))) {
switch (cmd) {
case CTRL_SYNC:
if (mount_obj->sync[0] != MP_OBJ_NULL) {
mp_call_method_n_kw(0, 0, mount_obj->sync);
}
return RES_OK;
case GET_SECTOR_COUNT:
// optimization for the built-in sd card device
if (mount_obj->device == (mp_obj_t)&pybsd_obj) {
*((DWORD*)buff) = sd_disk_info.ulNofBlock * (sd_disk_info.ulBlockSize / 512);
} else {
*((DWORD*)buff) = mp_obj_get_int(mp_call_method_n_kw(0, 0, mount_obj->count));
}
return RES_OK;
case GET_SECTOR_SIZE:
*((DWORD*)buff) = SD_SECTOR_SIZE; // Sector size is fixed to 512 bytes, as with SD cards
return RES_OK;
case GET_BLOCK_SIZE:
*((DWORD*)buff) = 1; // high-level sector erase size in units of the block size
return RES_OK;
}
}
break;
#endif
// nothing mounted
return RES_ERROR;
}
return RES_PARERR;
}
......@@ -195,7 +199,7 @@ DWORD get_fattime (
)
{
timeutils_struct_time_t tm;
timeutils_seconds_since_2000_to_struct_time(pybrtc_get_seconds(), &tm);
timeutils_seconds_since_2000_to_struct_time(pyb_rtc_get_seconds(), &tm);
return ((tm.tm_year - 1980) << 25) | ((tm.tm_mon) << 21) |
((tm.tm_mday) << 16) | ((tm.tm_hour) << 11) |
......
......@@ -38,6 +38,8 @@ 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);
/* Definitions of physical drive number for each drive */
#define FLASH 0 /* Map FLASH drive to drive number 0 */
/* Disk Status Bits (DSTATUS) */
......
......@@ -300,19 +300,6 @@ void sd_disk_deinit (void) {
sd_disk_info.usRCA = 0;
}
//*****************************************************************************
//
//! 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;
}
//*****************************************************************************
//
//! Reads sector(s) from the disk drive.
......@@ -365,6 +352,7 @@ DRESULT sd_disk_read (BYTE* pBuffer, DWORD ulSectorNumber, UINT SectorCount) {
pBuffer += 4;
}
CardSendCmd(CMD_STOP_TRANS, 0);
while (!(MAP_SDHostIntStatus(SDHOST_BASE) & SDHOST_INT_TC));
Res = RES_OK;
}
}
......@@ -384,61 +372,62 @@ DRESULT sd_disk_read (BYTE* pBuffer, DWORD ulSectorNumber, UINT SectorCount) {
//
//*****************************************************************************
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;
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);
while (!(MAP_SDHostIntStatus(SDHOST_BASE) & SDHOST_INT_TC));
Res = RES_OK;
}
}
}
return Res;
}
......@@ -21,7 +21,6 @@ extern DiskInfo_t sd_disk_info;
DSTATUS sd_disk_init (void);
void sd_disk_deinit (void);
DSTATUS sd_disk_status (void);
DRESULT sd_disk_read (BYTE* pBuffer, DWORD ulSectorNumber, UINT bSectorCount);
DRESULT sd_disk_write (const BYTE* pBuffer, DWORD ulSectorNumber, UINT bSectorCount);
......
......@@ -26,11 +26,11 @@
#include <string.h>
#include "py/mpconfig.h"
#include "py/misc.h"
#include "py/mpstate.h"
#include "ff.h"
#include "ffconf.h"
#include "diskio.h"
#include "moduos.h"
#if _FS_RPATH
extern BYTE ff_CurrVol;
......@@ -65,31 +65,29 @@ int ff_get_ldnumber (const TCHAR **path) {
}
if (check_path(path, "/flash", 6)) {
return 0;
return FLASH;
}
#if MICROPY_HW_HAS_SDCARD
else if (check_path(path, "/sd", 3)) {
return 1;
}
#endif
else {
return -1;
for (mp_uint_t i = 0; i < MP_STATE_PORT(mount_obj_list).len; i++) {
os_fs_mount_t *mount_obj = ((os_fs_mount_t *)(MP_STATE_PORT(mount_obj_list).items[i]));
if (check_path(path, mount_obj->path, mount_obj->pathlen)) {
return mount_obj->vol;
}
}
}
return -1;
}
void ff_get_volname(BYTE vol, TCHAR **dest) {
#if MICROPY_HW_HAS_SDCARD
if (vol == 0)
#endif
{
if (vol == FLASH) {
memcpy(*dest, "/flash", 6);
*dest += 6;
} else {
os_fs_mount_t *mount_obj;
if ((mount_obj = osmount_find_by_volume(vol))) {
memcpy(*dest, mount_obj->path, mount_obj->pathlen);
*dest += mount_obj->pathlen;
}
}
#if MICROPY_HW_HAS_SDCARD
else
{
memcpy(*dest, "/sd", 3);
*dest += 3;
}
#endif
}
......@@ -28,7 +28,7 @@
#include <ctype.h>
#include "std.h"
#include "py/mpconfig.h"
#include "py/mpstate.h"
#include MICROPY_HAL_H
#include "py/obj.h"
#include "inc/hw_types.h"
......@@ -47,9 +47,9 @@
#include "ff.h"
#include "fifo.h"
#include "socketfifo.h"
#include "pybsd.h"
#include "updater.h"
#include "timeutils.h"
#include "moduos.h"
/******************************************************************************
DEFINE PRIVATE CONSTANTS
......@@ -93,16 +93,12 @@ typedef enum {
E_FTP_STE_SUB_DISCONNECTED = 0,
E_FTP_STE_SUB_LISTEN_FOR_DATA,
E_FTP_STE_SUB_DATA_CONNECTED
} ftp_data_substate_t;
typedef union {
ftp_data_substate_t data;
} ftp_substate_t;
typedef struct {
bool uservalid : 1;
bool passvalid : 1;
}ftp_loggin_t;
} ftp_loggin_t;
typedef enum {
E_FTP_NOTHING_OPEN = 0,
......@@ -128,8 +124,9 @@ typedef struct {
int16_t c_sd;
int16_t d_sd;
int16_t dtimeout;
ftp_state_t state;
ftp_substate_t substate;
uint16_t volcount;
uint8_t state;
uint8_t substate;
uint8_t txRetries;
uint8_t logginRetries;
ftp_loggin_t loggin;
......@@ -137,6 +134,7 @@ typedef struct {
bool closechild;
bool enabled;
bool special_file;
bool listroot;
} ftp_data_t;
typedef struct {
......@@ -217,7 +215,7 @@ static int ftp_print_eplf_drive (char *dest, uint32_t destsize, char *name);
static bool ftp_open_file (const char *path, int mode);
static ftp_result_t ftp_read_file (char *filebuf, uint32_t desiredsize, uint32_t *actualsize);
static ftp_result_t ftp_write_file (char *filebuf, uint32_t size);
static ftp_result_t ftp_open_dir_for_listing (const char *path, char *list, uint32_t maxlistsize, uint32_t *listsize);
static ftp_result_t ftp_open_dir_for_listing (const char *path);
static ftp_result_t ftp_list_dir (char *list, uint32_t maxlistsize, uint32_t *listsize);
static void ftp_open_child (char *pwd, char *dir);
static void ftp_close_child (char *pwd);
......@@ -239,8 +237,9 @@ void ftp_init (void) {
ftp_data.ld_sd = -1;
ftp_data.e_open = E_FTP_NOTHING_OPEN;
ftp_data.state = E_FTP_STE_DISABLED;
ftp_data.substate.data = E_FTP_STE_SUB_DISCONNECTED;
ftp_data.substate = E_FTP_STE_SUB_DISCONNECTED;
ftp_data.special_file = false;
ftp_data.volcount = 0;
}
void ftp_run (void) {
......@@ -254,7 +253,7 @@ void ftp_run (void) {
}
break;
case E_FTP_STE_READY:
if (ftp_data.c_sd < 0 && ftp_data.substate.data == E_FTP_STE_SUB_DISCONNECTED) {
if (ftp_data.c_sd < 0 && ftp_data.substate == E_FTP_STE_SUB_DISCONNECTED) {
if (E_FTP_RESULT_OK == ftp_wait_for_connection(ftp_data.lc_sd, &ftp_data.c_sd)) {
ftp_data.txRetries = 0;
ftp_data.logginRetries = 0;
......@@ -267,7 +266,7 @@ void ftp_run (void) {
}
}
if (SOCKETFIFO_IsEmpty()) {
if (ftp_data.c_sd > 0 && ftp_data.substate.data != E_FTP_STE_SUB_LISTEN_FOR_DATA) {
if (ftp_data.c_sd > 0 && ftp_data.substate != E_FTP_STE_SUB_LISTEN_FOR_DATA) {
ftp_process_cmd();
if (ftp_data.state != E_FTP_STE_READY) {
break;
......@@ -284,8 +283,7 @@ void ftp_run (void) {
ftp_list_dir((char *)ftp_data.dBuffer, FTP_BUFFER_SIZE, &listsize);
if (listsize > 0) {
ftp_send_data(listsize);
}
else {
} else {
ftp_send_reply(226, NULL);
ftp_data.state = E_FTP_STE_END_TRANSFER;
}
......@@ -356,19 +354,19 @@ void ftp_run (void) {
break;
}
switch (ftp_data.substate.data) {
switch (ftp_data.substate) {
case E_FTP_STE_SUB_DISCONNECTED:
break;
case E_FTP_STE_SUB_LISTEN_FOR_DATA:
if (E_FTP_RESULT_OK == ftp_wait_for_connection(ftp_data.ld_sd, &ftp_data.d_sd)) {
ftp_data.dtimeout = 0;
ftp_data.substate.data = E_FTP_STE_SUB_DATA_CONNECTED;