cc3200: New SD and RTC API plus os and time modules' extensions.
This commit is contained in:
parent
660f8613fd
commit
dffa9f6da6
|
@ -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;
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
// 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);
|
||||
// Set the block count
|
||||
MAP_SDHostBlockCountSet(SDHOST_BASE, SectorCount);
|
||||
|
||||
// Compute the number of words
|
||||
ulSize = (SD_SECTOR_SIZE * SectorCount) / 4;
|
||||
// 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);
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 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;
|
||||
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
|
||||
}
|
||||
|
|
140
cc3200/ftp/ftp.c
140
cc3200/ftp/ftp.c
|
@ -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;
|
||||
ftp_data.substate = E_FTP_STE_SUB_DATA_CONNECTED;
|
||||
}
|
||||
else if (ftp_data.dtimeout++ > FTP_DATA_TIMEOUT_MS / FTP_CYCLE_TIME_MS) {
|
||||
ftp_data.dtimeout = 0;
|
||||
// close the listening socket
|
||||
servers_close_socket(&ftp_data.ld_sd);
|
||||
ftp_data.substate.data = E_FTP_STE_SUB_DISCONNECTED;
|
||||
ftp_data.substate = E_FTP_STE_SUB_DISCONNECTED;
|
||||
}
|
||||
break;
|
||||
case E_FTP_STE_SUB_DATA_CONNECTED:
|
||||
|
@ -377,7 +375,7 @@ void ftp_run (void) {
|
|||
servers_close_socket(&ftp_data.ld_sd);
|
||||
servers_close_socket(&ftp_data.d_sd);
|
||||
ftp_close_filesystem_on_error ();
|
||||
ftp_data.substate.data = E_FTP_STE_SUB_DISCONNECTED;
|
||||
ftp_data.substate = E_FTP_STE_SUB_DISCONNECTED;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -389,7 +387,7 @@ void ftp_run (void) {
|
|||
|
||||
// check the state of the data sockets
|
||||
if (ftp_data.d_sd < 0 && (ftp_data.state > E_FTP_STE_READY)) {
|
||||
ftp_data.substate.data = E_FTP_STE_SUB_DISCONNECTED;
|
||||
ftp_data.substate = E_FTP_STE_SUB_DISCONNECTED;
|
||||
ftp_data.state = E_FTP_STE_READY;
|
||||
}
|
||||
}
|
||||
|
@ -410,7 +408,8 @@ void ftp_reset (void) {
|
|||
servers_close_socket(&ftp_data.ld_sd);
|
||||
ftp_close_cmd_data();
|
||||
ftp_data.state = E_FTP_STE_START;
|
||||
ftp_data.substate.data = E_FTP_STE_SUB_DISCONNECTED;
|
||||
ftp_data.substate = E_FTP_STE_SUB_DISCONNECTED;
|
||||
ftp_data.volcount = 0;
|
||||
SOCKETFIFO_Flush();
|
||||
}
|
||||
|
||||
|
@ -554,7 +553,7 @@ static void ftp_send_from_fifo (void) {
|
|||
servers_close_socket(&ftp_data.ld_sd);
|
||||
// this one is the command socket
|
||||
servers_close_socket(fifoelement.sd);
|
||||
ftp_data.substate.data = E_FTP_STE_SUB_DISCONNECTED;
|
||||
ftp_data.substate = E_FTP_STE_SUB_DISCONNECTED;
|
||||
}
|
||||
ftp_close_filesystem_on_error();
|
||||
}
|
||||
|
@ -604,7 +603,6 @@ static void ftp_process_cmd (void) {
|
|||
_i32 len;
|
||||
char *bufptr = (char *)ftp_cmd_buffer;
|
||||
ftp_result_t result;
|
||||
uint32_t listsize;
|
||||
FRESULT fres;
|
||||
FILINFO fno;
|
||||
#if _USE_LFN
|
||||
|
@ -706,7 +704,7 @@ static void ftp_process_cmd (void) {
|
|||
{
|
||||
// some servers (e.g. google chrome) send PASV several times very quickly
|
||||
servers_close_socket(&ftp_data.d_sd);
|
||||
ftp_data.substate.data = E_FTP_STE_SUB_DISCONNECTED;
|
||||
ftp_data.substate = E_FTP_STE_SUB_DISCONNECTED;
|
||||
bool socketcreated = true;
|
||||
if (ftp_data.ld_sd < 0) {
|
||||
socketcreated = ftp_create_listening_socket(&ftp_data.ld_sd, FTP_PASIVE_DATA_PORT, FTP_DATA_CLIENTS_MAX);
|
||||
|
@ -718,7 +716,7 @@ static void ftp_process_cmd (void) {
|
|||
wlan_get_ip(&ip);
|
||||
snprintf((char *)ftp_data.dBuffer, FTP_BUFFER_SIZE, "(%u,%u,%u,%u,%u,%u)",
|
||||
pip[3], pip[2], pip[1], pip[0], (FTP_PASIVE_DATA_PORT >> 8), (FTP_PASIVE_DATA_PORT & 0xFF));
|
||||
ftp_data.substate.data = E_FTP_STE_SUB_LISTEN_FOR_DATA;
|
||||
ftp_data.substate = E_FTP_STE_SUB_LISTEN_FOR_DATA;
|
||||
ftp_send_reply(227, (char *)ftp_data.dBuffer);
|
||||
}
|
||||
else {
|
||||
|
@ -727,13 +725,7 @@ static void ftp_process_cmd (void) {
|
|||
}
|
||||
break;
|
||||
case E_FTP_CMD_LIST:
|
||||
if ((result = ftp_open_dir_for_listing(ftp_path, (char *)ftp_data.dBuffer, FTP_BUFFER_SIZE, &listsize)) == E_FTP_RESULT_OK) {
|
||||
ftp_data.state = E_FTP_STE_END_TRANSFER;
|
||||
ftp_send_reply(150, NULL);
|
||||
ftp_send_data(listsize);
|
||||
ftp_send_reply(226, NULL);
|
||||
}
|
||||
else if (result == E_FTP_RESULT_CONTINUE) {
|
||||
if (ftp_open_dir_for_listing(ftp_path) == E_FTP_RESULT_CONTINUE) {
|
||||
ftp_data.state = E_FTP_STE_CONTINUE_LISTING;
|
||||
ftp_send_reply(150, NULL);
|
||||
}
|
||||
|
@ -903,7 +895,7 @@ static int ftp_print_eplf_item (char *dest, uint32_t destsize, FILINFO *fno) {
|
|||
(fno->ftime >> 11) & 0x1f,
|
||||
(fno->ftime >> 5) & 0x3f,
|
||||
2 * (fno->ftime & 0x1f));
|
||||
tseconds = pybrtc_get_seconds();
|
||||
tseconds = pyb_rtc_get_seconds();
|
||||
if (FTP_UNIX_SECONDS_180_DAYS < tseconds - fseconds) {
|
||||
return snprintf(dest, destsize, "%srw-rw-r-- 1 root root %9u %s %2u %5u %s\r\n",
|
||||
type, (_u32)fno->fsize, ftp_month[mindex].month, day,
|
||||
|
@ -931,7 +923,7 @@ static int ftp_print_eplf_drive (char *dest, uint32_t destsize, char *name) {
|
|||
|
||||
timeutils_seconds_since_2000_to_struct_time((FTP_UNIX_TIME_20150101 - FTP_UNIX_TIME_20000101), &tm);
|
||||
|
||||
tseconds = pybrtc_get_seconds();
|
||||
tseconds = pyb_rtc_get_seconds();
|
||||
if (FTP_UNIX_SECONDS_180_DAYS < tseconds - (FTP_UNIX_TIME_20150101 - FTP_UNIX_TIME_20000101)) {
|
||||
return snprintf(dest, destsize, "%srw-rw-r-- 1 root root %9u %s %2u %5u %s\r\n",
|
||||
type, 0, ftp_month[(tm.tm_mon - 1)].month, tm.tm_mday, tm.tm_year, name);
|
||||
|
@ -979,32 +971,25 @@ static ftp_result_t ftp_write_file (char *filebuf, uint32_t size) {
|
|||
return result;
|
||||
}
|
||||
|
||||
static ftp_result_t ftp_open_dir_for_listing (const char *path, char *list, uint32_t maxlistsize, uint32_t *listsize) {
|
||||
uint next = 0;
|
||||
// "hack" to list root directory
|
||||
static ftp_result_t ftp_open_dir_for_listing (const char *path) {
|
||||
// "hack" to detect the root directory
|
||||
if (path[0] == '/' && path[1] == '\0') {
|
||||
next += ftp_print_eplf_drive((list + next), (maxlistsize - next), "flash");
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
if (pybsd_is_mounted()) {
|
||||
next += ftp_print_eplf_drive((list + next), (maxlistsize - next), "sd");
|
||||
ftp_data.listroot = true;
|
||||
} else {
|
||||
FRESULT res;
|
||||
res = f_opendir(&ftp_data.dp, path); /* Open the directory */
|
||||
if (res != FR_OK) {
|
||||
return E_FTP_RESULT_FAILED;
|
||||
}
|
||||
#endif
|
||||
*listsize = next;
|
||||
return E_FTP_RESULT_OK;
|
||||
ftp_data.e_open = E_FTP_DIR_OPEN;
|
||||
ftp_data.listroot = false;
|
||||
}
|
||||
|
||||
FRESULT res;
|
||||
res = f_opendir(&ftp_data.dp, path); /* Open the directory */
|
||||
if (res != FR_OK) {
|
||||
return E_FTP_RESULT_FAILED;
|
||||
}
|
||||
ftp_data.e_open = E_FTP_DIR_OPEN;
|
||||
return E_FTP_RESULT_CONTINUE;
|
||||
}
|
||||
|
||||
static ftp_result_t ftp_list_dir (char *list, uint32_t maxlistsize, uint32_t *listsize) {
|
||||
uint next = 0;
|
||||
uint count = 0;
|
||||
uint listcount = 0;
|
||||
FRESULT res;
|
||||
ftp_result_t result = E_FTP_RESULT_CONTINUE;
|
||||
FILINFO fno;
|
||||
|
@ -1013,22 +998,40 @@ static ftp_result_t ftp_list_dir (char *list, uint32_t maxlistsize, uint32_t *li
|
|||
fno.lfsize = _MAX_LFN;
|
||||
|
||||
// read up to 2 directory items
|
||||
while (count < 2) {
|
||||
while (listcount < 2) {
|
||||
#else
|
||||
// read up to 4 directory items
|
||||
while (count < 4) {
|
||||
while (listcount < 4) {
|
||||
#endif
|
||||
res = f_readdir(&ftp_data.dp, &fno); /* Read a directory item */
|
||||
if (res != FR_OK || fno.fname[0] == 0) {
|
||||
result = E_FTP_RESULT_OK;
|
||||
break; /* Break on error or end of dp */
|
||||
}
|
||||
if (fno.fname[0] == '.' && fno.fname[1] == 0) continue; /* Ignore . entry */
|
||||
if (fno.fname[0] == '.' && fno.fname[1] == '.' && fno.fname[2] == 0) continue; /* Ignore .. entry */
|
||||
if (ftp_data.listroot) {
|
||||
// root directory "hack"
|
||||
if (0 == ftp_data.volcount) {
|
||||
next += ftp_print_eplf_drive((list + next), (maxlistsize - next), "flash");
|
||||
} else if (ftp_data.volcount <= MP_STATE_PORT(mount_obj_list).len) {
|
||||
os_fs_mount_t *mount_obj = ((os_fs_mount_t *)(MP_STATE_PORT(mount_obj_list).items[(ftp_data.volcount - 1)]));
|
||||
next += ftp_print_eplf_drive((list + next), (maxlistsize - next), (char *)&mount_obj->path[1]);
|
||||
} else {
|
||||
if (!next) {
|
||||
// no volume found this time, we are done
|
||||
ftp_data.volcount = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
ftp_data.volcount++;
|
||||
} else {
|
||||
// a "normal" directory
|
||||
res = f_readdir(&ftp_data.dp, &fno); /* Read a directory item */
|
||||
if (res != FR_OK || fno.fname[0] == 0) {
|
||||
result = E_FTP_RESULT_OK;
|
||||
break; /* Break on error or end of dp */
|
||||
}
|
||||
if (fno.fname[0] == '.' && fno.fname[1] == 0) continue; /* Ignore . entry */
|
||||
if (fno.fname[0] == '.' && fno.fname[1] == '.' && fno.fname[2] == 0) continue; /* Ignore .. entry */
|
||||
|
||||
// add the entry to the list
|
||||
next += ftp_print_eplf_item((list + next), (maxlistsize - next), &fno);
|
||||
count++;
|
||||
// add the entry to the list
|
||||
next += ftp_print_eplf_item((list + next), (maxlistsize - next), &fno);
|
||||
}
|
||||
listcount++;
|
||||
}
|
||||
if (result == E_FTP_RESULT_OK) {
|
||||
ftp_close_files();
|
||||
|
@ -1043,8 +1046,7 @@ static ftp_result_t ftp_list_dir (char *list, uint32_t maxlistsize, uint32_t *li
|
|||
static void ftp_open_child (char *pwd, char *dir) {
|
||||
if (dir[0] == '/') {
|
||||
strcpy (pwd, dir);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (strlen(pwd) > 1) {
|
||||
strcat (pwd, "/");
|
||||
}
|
||||
|
@ -1064,8 +1066,7 @@ static void ftp_close_child (char *pwd) {
|
|||
}
|
||||
if (len == 0) {
|
||||
strcpy (pwd, "/");
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
pwd[len] = '\0';
|
||||
}
|
||||
}
|
||||
|
@ -1078,8 +1079,7 @@ static void ftp_return_to_previous_path (char *pwd, char *dir) {
|
|||
else {
|
||||
if (newlen == 0) {
|
||||
strcpy (pwd, "/");
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
pwd[newlen] = '\0';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ uint32_t sys_tick_get_microseconds(void) {
|
|||
enable_irq(irq_state);
|
||||
|
||||
// It's still possible for the countflag bit to get set if the counter was
|
||||
// reloaded between reading VAL and reading CTRL. With interrupts disabled
|
||||
// reloaded between reading VAL and reading CTRL. With interrupts disabled
|
||||
// it definitely takes less than 50 HCLK cycles between reading VAL and
|
||||
// reading CTRL, so the test (counter > 50) is to cover the case where VAL
|
||||
// is +ve and very close to zero, and the COUNTFLAG bit is also set.
|
||||
|
|
|
@ -40,6 +40,9 @@
|
|||
#include "rom_map.h"
|
||||
#include "prcm.h"
|
||||
#include "pyexec.h"
|
||||
#include "ff.h"
|
||||
#include "diskio.h"
|
||||
#include "sflash_diskio.h"
|
||||
#include "pybuart.h"
|
||||
#include "pybpin.h"
|
||||
#include "pybrtc.h"
|
||||
|
@ -49,9 +52,6 @@
|
|||
#include "modwlan.h"
|
||||
#include "moduos.h"
|
||||
#include "telnet.h"
|
||||
#include "ff.h"
|
||||
#include "diskio.h"
|
||||
#include "sflash_diskio.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "portable.h"
|
||||
#include "task.h"
|
||||
|
@ -141,90 +141,6 @@ STATIC mp_obj_t pyb_unique_id(void) {
|
|||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(pyb_unique_id_obj, pyb_unique_id);
|
||||
|
||||
/// \function millis()
|
||||
/// Returns the number of milliseconds since the board was last reset.
|
||||
///
|
||||
/// The result is always a micropython smallint (31-bit signed number), so
|
||||
/// after 2^30 milliseconds (about 12.4 days) this will start to return
|
||||
/// negative numbers.
|
||||
STATIC mp_obj_t pyb_millis(void) {
|
||||
// We want to "cast" the 32 bit unsigned into a small-int. This means
|
||||
// copying the MSB down 1 bit (extending the sign down), which is
|
||||
// equivalent to just using the MP_OBJ_NEW_SMALL_INT macro.
|
||||
return MP_OBJ_NEW_SMALL_INT(HAL_GetTick());
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(pyb_millis_obj, pyb_millis);
|
||||
|
||||
/// \function elapsed_millis(start)
|
||||
/// Returns the number of milliseconds which have elapsed since `start`.
|
||||
///
|
||||
/// This function takes care of counter wrap, and always returns a positive
|
||||
/// number. This means it can be used to measure periods upto about 12.4 days.
|
||||
///
|
||||
/// Example:
|
||||
/// start = pyb.millis()
|
||||
/// while pyb.elapsed_millis(start) < 1000:
|
||||
/// # Perform some operation
|
||||
STATIC mp_obj_t pyb_elapsed_millis(mp_obj_t start) {
|
||||
uint32_t startMillis = mp_obj_get_int(start);
|
||||
uint32_t currMillis = HAL_GetTick();
|
||||
return MP_OBJ_NEW_SMALL_INT((currMillis - startMillis) & 0x3fffffff);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_elapsed_millis_obj, pyb_elapsed_millis);
|
||||
|
||||
/// \function micros()
|
||||
/// Returns the number of microseconds since the board was last reset.
|
||||
///
|
||||
/// The result is always a micropython smallint (31-bit signed number), so
|
||||
/// after 2^30 microseconds (about 17.8 minutes) this will start to return
|
||||
/// negative numbers.
|
||||
STATIC mp_obj_t pyb_micros(void) {
|
||||
// We want to "cast" the 32 bit unsigned into a small-int. This means
|
||||
// copying the MSB down 1 bit (extending the sign down), which is
|
||||
// equivalent to just using the MP_OBJ_NEW_SMALL_INT macro.
|
||||
return MP_OBJ_NEW_SMALL_INT(sys_tick_get_microseconds());
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(pyb_micros_obj, pyb_micros);
|
||||
|
||||
/// \function elapsed_micros(start)
|
||||
/// Returns the number of microseconds which have elapsed since `start`.
|
||||
///
|
||||
/// This function takes care of counter wrap, and always returns a positive
|
||||
/// number. This means it can be used to measure periods upto about 17.8 minutes.
|
||||
///
|
||||
/// Example:
|
||||
/// start = pyb.micros()
|
||||
/// while pyb.elapsed_micros(start) < 1000:
|
||||
/// # Perform some operation
|
||||
STATIC mp_obj_t pyb_elapsed_micros(mp_obj_t start) {
|
||||
uint32_t startMicros = mp_obj_get_int(start);
|
||||
uint32_t currMicros = sys_tick_get_microseconds();
|
||||
return MP_OBJ_NEW_SMALL_INT((currMicros - startMicros) & 0x3fffffff);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_elapsed_micros_obj, pyb_elapsed_micros);
|
||||
|
||||
/// \function delay(ms)
|
||||
/// Delay for the given number of milliseconds.
|
||||
STATIC mp_obj_t pyb_delay(mp_obj_t ms_in) {
|
||||
mp_int_t ms = mp_obj_get_int(ms_in);
|
||||
if (ms > 0) {
|
||||
HAL_Delay(ms);
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_delay_obj, pyb_delay);
|
||||
|
||||
/// \function udelay(us)
|
||||
/// Delay for the given number of microseconds.
|
||||
STATIC mp_obj_t pyb_udelay(mp_obj_t usec_in) {
|
||||
mp_int_t usec = mp_obj_get_int(usec_in);
|
||||
if (usec > 0) {
|
||||
UtilsDelay(UTILS_DELAY_US_TO_COUNT(usec));
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_udelay_obj, pyb_udelay);
|
||||
|
||||
/// \function repl_uart(uart)
|
||||
/// Get or set the UART object that the REPL is repeated on.
|
||||
STATIC mp_obj_t pyb_repl_uart(uint n_args, const mp_obj_t *args) {
|
||||
|
@ -258,29 +174,15 @@ STATIC const mp_map_elem_t pyb_module_globals_table[] = {
|
|||
#endif
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_freq), (mp_obj_t)&pyb_freq_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_unique_id), (mp_obj_t)&pyb_unique_id_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_repl_info), (mp_obj_t)&pyb_set_repl_info_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_repl_uart), (mp_obj_t)&pyb_repl_uart_obj },
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_disable_irq), (mp_obj_t)&pyb_disable_irq_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_enable_irq), (mp_obj_t)&pyb_enable_irq_obj },
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_main), (mp_obj_t)&pyb_main_obj },
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_millis), (mp_obj_t)&pyb_millis_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_elapsed_millis), (mp_obj_t)&pyb_elapsed_millis_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_micros), (mp_obj_t)&pyb_micros_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_elapsed_micros), (mp_obj_t)&pyb_elapsed_micros_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_delay), (mp_obj_t)&pyb_delay_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_udelay), (mp_obj_t)&pyb_udelay_obj },
|
||||
|
||||
#if MICROPY_HW_ENABLE_RNG
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_rng), (mp_obj_t)&pyb_rng_get_obj },
|
||||
#endif
|
||||
|
||||
#if MICROPY_HW_ENABLE_RTC
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_RTC), (mp_obj_t)&pyb_rtc_type },
|
||||
#endif
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_Pin), (mp_obj_t)&pin_type },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ADC), (mp_obj_t)&pyb_adc_type },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_I2C), (mp_obj_t)&pyb_i2c_type },
|
||||
|
@ -290,10 +192,7 @@ STATIC const mp_map_elem_t pyb_module_globals_table[] = {
|
|||
{ MP_OBJ_NEW_QSTR(MP_QSTR_WDT), (mp_obj_t)&pyb_wdt_type },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_Sleep), (mp_obj_t)&pyb_sleep_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_HeartBeat), (mp_obj_t)&pyb_heartbeat_type },
|
||||
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_SD), (mp_obj_t)&pyb_sd_type },
|
||||
#endif
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(pyb_module_globals, pyb_module_globals_table);
|
||||
|
|
|
@ -28,21 +28,22 @@
|
|||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#include "py/mpstate.h"
|
||||
#include "py/nlr.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/objtuple.h"
|
||||
#include "py/objstr.h"
|
||||
#include "py/runtime.h"
|
||||
#include "genhdr/mpversion.h"
|
||||
#include "ff.h"
|
||||
#include "diskio.h"
|
||||
#include "sflash_diskio.h"
|
||||
#include "file.h"
|
||||
#include "random.h"
|
||||
#include "pybsd.h"
|
||||
#include "mpexception.h"
|
||||
#include "version.h"
|
||||
#include "timeutils.h"
|
||||
#include "moduos.h"
|
||||
#include "pybsd.h"
|
||||
|
||||
/// \module os - basic "operating system" services
|
||||
///
|
||||
|
@ -52,15 +53,155 @@
|
|||
/// drives are accessible from here. They are currently:
|
||||
///
|
||||
/// /flash -- the serial flash filesystem
|
||||
/// /sd -- the SD card (if it exists)
|
||||
///
|
||||
/// On boot up, the current directory is `/flash` if no SD card is inserted,
|
||||
/// otherwise it is `/sd`.
|
||||
/// On boot up, the current directory is `/flash`.
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE DATA
|
||||
******************************************************************************/
|
||||
STATIC uint32_t os_num_mounted_devices;
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PUBLIC FUNCTIONS
|
||||
******************************************************************************/
|
||||
|
||||
void moduos_init0 (void) {
|
||||
// initialize the mount objects list
|
||||
mp_obj_list_init(&MP_STATE_PORT(mount_obj_list), 0);
|
||||
os_num_mounted_devices = 0;
|
||||
}
|
||||
|
||||
os_fs_mount_t *osmount_find_by_path (const char *path) {
|
||||
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 (!strcmp(path, mount_obj->path)) {
|
||||
return mount_obj;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
os_fs_mount_t *osmount_find_by_volume (uint8_t vol) {
|
||||
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 (vol == mount_obj->vol) {
|
||||
return mount_obj;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
os_fs_mount_t *osmount_find_by_device (mp_obj_t device) {
|
||||
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 (device == mount_obj->device) {
|
||||
return mount_obj;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PRIVATE FUNCTIONS
|
||||
******************************************************************************/
|
||||
|
||||
// Checks for path equality, ignoring trailing slashes:
|
||||
// path_equal(/, /) -> true
|
||||
// path_equal(/flash//, /flash) -> true
|
||||
// second argument must be in canonical form (meaning no trailing slash, unless it's just /)
|
||||
STATIC bool path_equal(const char *path, const char *path_canonical) {
|
||||
for (; *path_canonical != '\0' && *path == *path_canonical; ++path, ++path_canonical) {
|
||||
}
|
||||
if (*path_canonical != '\0') {
|
||||
return false;
|
||||
}
|
||||
for (; *path == '/'; ++path) {
|
||||
}
|
||||
return *path == '\0';
|
||||
}
|
||||
|
||||
STATIC void append_dir_item (mp_obj_t dirlist, const char *item, bool string) {
|
||||
// make a string object for this entry
|
||||
mp_obj_t entry_o;
|
||||
if (string) {
|
||||
entry_o = mp_obj_new_str(item, strlen(item), false);
|
||||
} else {
|
||||
entry_o = mp_obj_new_bytes((const byte*)item, strlen(item));
|
||||
}
|
||||
|
||||
// add the entry to the list
|
||||
mp_obj_list_append(dirlist, entry_o);
|
||||
}
|
||||
|
||||
STATIC void mount (mp_obj_t device, const char *path, uint pathlen, bool readonly) {
|
||||
// is the mount point already in use?
|
||||
FILINFO fno;
|
||||
#if _USE_LFN
|
||||
fno.lfname = NULL;
|
||||
fno.lfsize = 0;
|
||||
#endif
|
||||
// cannot mount twice or on existing paths
|
||||
if (f_stat(path, &fno) == FR_OK || osmount_find_by_device(device)) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
|
||||
}
|
||||
|
||||
// create a new object
|
||||
os_fs_mount_t *self = m_new_obj(os_fs_mount_t);
|
||||
self->device = device;
|
||||
self->path = path;
|
||||
self->pathlen = pathlen;
|
||||
self->vol = os_num_mounted_devices + 1; // '/flash' is volume 0
|
||||
|
||||
if (device == (mp_obj_t)&pybsd_obj) {
|
||||
// need to make it different to NULL, otherwise it's read only by default
|
||||
self->writeblocks[0] = mp_const_none;
|
||||
self->sync[0] = MP_OBJ_NULL; // no need to sync the SD card
|
||||
self->count[0] = MP_OBJ_NULL;
|
||||
} else {
|
||||
// load block protocol methods
|
||||
mp_load_method(device, MP_QSTR_readblocks, self->readblocks);
|
||||
mp_load_method_maybe(device, MP_QSTR_writeblocks, self->writeblocks);
|
||||
mp_load_method_maybe(device, MP_QSTR_sync, self->sync);
|
||||
mp_load_method(device, MP_QSTR_count, self->count);
|
||||
}
|
||||
|
||||
// Read-only device indicated by writeblocks[0] == MP_OBJ_NULL.
|
||||
// User can specify read-only device by:
|
||||
// 1. readonly=True keyword argument
|
||||
// 2. nonexistent writeblocks method (then writeblocks[0] == MP_OBJ_NULL already)
|
||||
if (readonly) {
|
||||
self->writeblocks[0] = MP_OBJ_NULL;
|
||||
}
|
||||
|
||||
// we need to add it before doing the actual mount, so that the volume can be found
|
||||
mp_obj_list_append(&MP_STATE_PORT(mount_obj_list), self);
|
||||
|
||||
// actually mount it
|
||||
if (f_mount(&self->fatfs, self->path, 1) != FR_OK) {
|
||||
// remove it and raise
|
||||
mp_obj_list_remove(&MP_STATE_PORT(mount_obj_list), self);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
|
||||
// mount succeeded, increment the count
|
||||
os_num_mounted_devices++;
|
||||
}
|
||||
|
||||
STATIC void unmount (const char *path) {
|
||||
if (FR_OK != f_mount (NULL, path, 1)) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
|
||||
// remove from the list after the actual unmount
|
||||
os_fs_mount_t *mount_obj;
|
||||
if ((mount_obj = osmount_find_by_path(path))) {
|
||||
mp_obj_list_remove(&MP_STATE_PORT(mount_obj_list), mount_obj);
|
||||
os_num_mounted_devices--;
|
||||
} else {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
// Micro Python bindings
|
||||
//
|
||||
|
@ -110,25 +251,20 @@ STATIC mp_obj_t os_chdir(mp_obj_t path_in) {
|
|||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_chdir_obj, os_chdir);
|
||||
|
||||
/// \function getcwd()
|
||||
/// Get the current directory.
|
||||
STATIC mp_obj_t os_getcwd(void) {
|
||||
char buf[MICROPY_ALLOC_PATH_MAX + 1];
|
||||
FRESULT res = f_getcwd(buf, sizeof buf);
|
||||
|
||||
if (res != FR_OK) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(fresult_to_errno_table[res])));
|
||||
}
|
||||
|
||||
return mp_obj_new_str(buf, strlen(buf), false);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(os_getcwd_obj, os_getcwd);
|
||||
|
||||
/// \function listdir([dir])
|
||||
/// With no argument, list the current directory. Otherwise list the given directory.
|
||||
STATIC mp_obj_t os_listdir(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
bool is_str_type = true;
|
||||
const char *path;
|
||||
mp_obj_t dir_list = mp_obj_new_list(0, NULL);
|
||||
|
||||
if (n_args == 1) {
|
||||
if (mp_obj_get_type(args[0]) == &mp_type_bytes) {
|
||||
|
@ -139,66 +275,51 @@ STATIC mp_obj_t os_listdir(mp_uint_t n_args, const mp_obj_t *args) {
|
|||
path = "";
|
||||
}
|
||||
|
||||
// "hack" to list root directory
|
||||
// "hack" to list the root directory
|
||||
if (path[0] == '/' && path[1] == '\0') {
|
||||
mp_obj_t dir_list = mp_obj_new_list(0, NULL);
|
||||
mp_obj_list_append(dir_list, MP_OBJ_NEW_QSTR(MP_QSTR_flash));
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
if (pybsd_is_mounted()) {
|
||||
mp_obj_list_append(dir_list, MP_OBJ_NEW_QSTR(MP_QSTR_sd));
|
||||
// add 'flash' to the list
|
||||
append_dir_item (dir_list, "flash", is_str_type);
|
||||
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]));
|
||||
append_dir_item (dir_list, &mount_obj->path[1], is_str_type);
|
||||
}
|
||||
#endif
|
||||
return dir_list;
|
||||
}
|
||||
} else {
|
||||
FRESULT res;
|
||||
DIR dir;
|
||||
FILINFO fno;
|
||||
#if _USE_LFN
|
||||
char lfn_buf[_MAX_LFN + 1];
|
||||
fno.lfname = lfn_buf;
|
||||
fno.lfsize = sizeof(lfn_buf);
|
||||
#endif
|
||||
|
||||
FRESULT res;
|
||||
DIR dir;
|
||||
FILINFO fno;
|
||||
#if _USE_LFN
|
||||
char lfn_buf[_MAX_LFN + 1];
|
||||
fno.lfname = lfn_buf;
|
||||
fno.lfsize = sizeof(lfn_buf);
|
||||
#endif
|
||||
|
||||
res = f_opendir(&dir, path); /* Open the directory */
|
||||
if (res != FR_OK) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
|
||||
mp_obj_t dir_list = mp_obj_new_list(0, NULL);
|
||||
|
||||
for (;;) {
|
||||
res = f_readdir(&dir, &fno); /* Read a directory item */
|
||||
if (res != FR_OK || fno.fname[0] == 0) break; /* Break on error or end of dir */
|
||||
if (fno.fname[0] == '.' && fno.fname[1] == 0) continue; /* Ignore . entry */
|
||||
if (fno.fname[0] == '.' && fno.fname[1] == '.' && fno.fname[2] == 0) continue; /* Ignore .. entry */
|
||||
|
||||
#if _USE_LFN
|
||||
char *fn = *fno.lfname ? fno.lfname : fno.fname;
|
||||
#else
|
||||
char *fn = fno.fname;
|
||||
#endif
|
||||
|
||||
// make a string object for this entry
|
||||
mp_obj_t entry_o;
|
||||
if (is_str_type) {
|
||||
entry_o = mp_obj_new_str(fn, strlen(fn), false);
|
||||
} else {
|
||||
entry_o = mp_obj_new_bytes((const byte*)fn, strlen(fn));
|
||||
res = f_opendir(&dir, path); /* Open the directory */
|
||||
if (res != FR_OK) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
|
||||
// add the entry to the list
|
||||
mp_obj_list_append(dir_list, entry_o);
|
||||
}
|
||||
for ( ; ; ) {
|
||||
res = f_readdir(&dir, &fno); /* Read a directory item */
|
||||
if (res != FR_OK || fno.fname[0] == 0) break; /* Break on error or end of dir */
|
||||
if (fno.fname[0] == '.' && fno.fname[1] == 0) continue; /* Ignore . entry */
|
||||
if (fno.fname[0] == '.' && fno.fname[1] == '.' && fno.fname[2] == 0) continue; /* Ignore .. entry */
|
||||
|
||||
f_closedir(&dir);
|
||||
#if _USE_LFN
|
||||
char *fn = *fno.lfname ? fno.lfname : fno.fname;
|
||||
#else
|
||||
char *fn = fno.fname;
|
||||
#endif
|
||||
|
||||
// add the entry to the list
|
||||
append_dir_item (dir_list, fn, is_str_type);
|
||||
}
|
||||
f_closedir(&dir);
|
||||
}
|
||||
|
||||
return dir_list;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(os_listdir_obj, 0, 1, os_listdir);
|
||||
|
||||
/// \function mkdir(path)
|
||||
/// Create a new directory.
|
||||
STATIC mp_obj_t os_mkdir(mp_obj_t path_o) {
|
||||
const char *path = mp_obj_str_get_str(path_o);
|
||||
FRESULT res = f_mkdir(path);
|
||||
|
@ -214,8 +335,6 @@ STATIC mp_obj_t os_mkdir(mp_obj_t path_o) {
|
|||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_mkdir_obj, os_mkdir);
|
||||
|
||||
/// \function rename(old_path, new_path)
|
||||
/// Rename a file
|
||||
STATIC mp_obj_t os_rename(mp_obj_t path_in, mp_obj_t path_out) {
|
||||
const char *old_path = mp_obj_str_get_str(path_in);
|
||||
const char *new_path = mp_obj_str_get_str(path_out);
|
||||
|
@ -226,12 +345,9 @@ STATIC mp_obj_t os_rename(mp_obj_t path_in, mp_obj_t path_out) {
|
|||
default:
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(os_rename_obj, os_rename);
|
||||
|
||||
/// \function remove(path)
|
||||
/// Remove a file or a directory
|
||||
STATIC mp_obj_t os_remove(mp_obj_t path_o) {
|
||||
const char *path = mp_obj_str_get_str(path_o);
|
||||
FRESULT res = f_unlink(path);
|
||||
|
@ -244,53 +360,33 @@ STATIC mp_obj_t os_remove(mp_obj_t path_o) {
|
|||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_remove_obj, os_remove);
|
||||
|
||||
// Checks for path equality, ignoring trailing slashes:
|
||||
// path_equal(/, /) -> true
|
||||
// path_equal(/flash//, /flash) -> true
|
||||
// second argument must be in canonical form (meaning no trailing slash, unless it's just /)
|
||||
STATIC bool path_equal(const char *path, const char *path_canonical) {
|
||||
for (; *path_canonical != '\0' && *path == *path_canonical; ++path, ++path_canonical) {
|
||||
}
|
||||
if (*path_canonical != '\0') {
|
||||
return false;
|
||||
}
|
||||
for (; *path == '/'; ++path) {
|
||||
}
|
||||
return *path == '\0';
|
||||
}
|
||||
|
||||
/// \function stat(path)
|
||||
/// Get the status of a file or directory.
|
||||
STATIC mp_obj_t os_stat(mp_obj_t path_in) {
|
||||
const char *path = mp_obj_str_get_str(path_in);
|
||||
|
||||
FRESULT res;
|
||||
bool isbuilt_in = false;
|
||||
FILINFO fno;
|
||||
FRESULT res;
|
||||
#if _USE_LFN
|
||||
fno.lfname = NULL;
|
||||
fno.lfsize = 0;
|
||||
#endif
|
||||
|
||||
if (path_equal(path, "/") || path_equal(path, "/flash") || path_equal(path, "/sd")) {
|
||||
// check on the user mounted devices
|
||||
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 (path_equal(path, mount_obj->path)) {
|
||||
isbuilt_in = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (path_equal(path, "/") || path_equal(path, "/flash") || isbuilt_in) {
|
||||
// stat built-in directory
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
if (path[1] == 's' && !pybsd_is_mounted()) {
|
||||
#else
|
||||
if (path[1] == 's') {
|
||||
#endif
|
||||
// no /sd directory
|
||||
res = FR_NO_PATH;
|
||||
goto error;
|
||||
}
|
||||
fno.fsize = 0;
|
||||
fno.fdate = 0;
|
||||
fno.ftime = 0;
|
||||
fno.fattrib = AM_DIR;
|
||||
} else {
|
||||
res = f_stat(path, &fno);
|
||||
if (res != FR_OK) {
|
||||
goto error;
|
||||
}
|
||||
fno.fsize = 0;
|
||||
fno.fdate = 0;
|
||||
fno.ftime = 0;
|
||||
fno.fattrib = AM_DIR;
|
||||
} else if ((res = f_stat(path, &fno)) != FR_OK) {
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(fresult_to_errno_table[res])));
|
||||
}
|
||||
|
||||
mp_obj_tuple_t *t = mp_obj_new_tuple(10, NULL);
|
||||
|
@ -318,26 +414,16 @@ STATIC mp_obj_t os_stat(mp_obj_t path_in) {
|
|||
t->items[7] = mp_obj_new_int(seconds); // st_atime
|
||||
t->items[8] = t->items[7]; // st_mtime
|
||||
t->items[9] = t->items[7]; // st_ctime
|
||||
|
||||
return t;
|
||||
|
||||
error:
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(fresult_to_errno_table[res])));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_stat_obj, os_stat);
|
||||
|
||||
/// \function sync()
|
||||
/// Sync all filesystems.
|
||||
STATIC mp_obj_t os_sync(void) {
|
||||
sflash_disk_flush();
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(os_sync_obj, os_sync);
|
||||
|
||||
#if MICROPY_HW_ENABLE_RNG
|
||||
/// \function urandom(n)
|
||||
/// Return a bytes object with n random bytes, generated by the hardware
|
||||
/// random number generator.
|
||||
STATIC mp_obj_t os_urandom(mp_obj_t num) {
|
||||
mp_int_t n = mp_obj_get_int(num);
|
||||
vstr_t vstr;
|
||||
|
@ -348,23 +434,102 @@ STATIC mp_obj_t os_urandom(mp_obj_t num) {
|
|||
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_urandom_obj, os_urandom);
|
||||
#endif
|
||||
|
||||
/// \function mkfs('drive')
|
||||
/// Formats the selected drive, useful when the filesystem has been damaged beyond repair.
|
||||
/// Path must be either '/sd' or '/flash'
|
||||
STATIC mp_obj_t os_mkfs(mp_obj_t path_o) {
|
||||
const char *path = mp_obj_str_get_str(path_o);
|
||||
uint8_t sfd;
|
||||
STATIC mp_obj_t os_mount(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
static const mp_arg_t mount_args[] = {
|
||||
{ MP_QSTR_readonly, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
|
||||
};
|
||||
|
||||
if (!strcmp(path, "/flash")) {
|
||||
sfd = 1;
|
||||
} else if (!strcmp(path, "/sd")) {
|
||||
sfd = 0;
|
||||
} else {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
// parse args
|
||||
mp_obj_t device = pos_args[0];
|
||||
mp_obj_t mount_point = pos_args[1];
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(mount_args)];
|
||||
mp_arg_parse_all(n_args - 2, pos_args + 2, kw_args, MP_ARRAY_SIZE(mount_args), mount_args, args);
|
||||
|
||||
// get the mount point
|
||||
mp_uint_t pathlen;
|
||||
const char *path_in = mp_obj_str_get_data(mount_point, &pathlen);
|
||||
if (pathlen == 0) {
|
||||
goto invalid_args;
|
||||
}
|
||||
if (FR_OK != f_mkfs(path, sfd, 0)) {
|
||||
|
||||
char *path = m_new(char, pathlen + 1);
|
||||
memcpy(path, path_in, pathlen);
|
||||
path[pathlen] = '\0';
|
||||
|
||||
// "remove" any extra slahes at the end
|
||||
while (path[(pathlen - 1)] == '/') {
|
||||
path[--pathlen] = '\0';
|
||||
}
|
||||
|
||||
// is the mount point valid?
|
||||
if (pathlen < 2 || path[0] !='/' || strchr(&path[1], '/')) {
|
||||
goto invalid_args;
|
||||
}
|
||||
|
||||
// now mount it
|
||||
mount(device, path, pathlen, args[0].u_bool);
|
||||
|
||||
return mp_const_none;
|
||||
|
||||
invalid_args:
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_KW(os_mount_obj, 2, os_mount);
|
||||
|
||||
STATIC mp_obj_t os_unmount(mp_obj_t path_o) {
|
||||
const char *path = mp_obj_str_get_str(path_o);
|
||||
|
||||
// '/flash' cannot be unmounted, also not the current working directory
|
||||
if (path_equal(path, "/flash")) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
|
||||
}
|
||||
|
||||
// now unmount it
|
||||
unmount (path);
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_unmount_obj, os_unmount);
|
||||
|
||||
STATIC mp_obj_t os_mkfs(mp_obj_t device) {
|
||||
const char *path = "/__mkfs__mnt__";
|
||||
bool unmt = false;
|
||||
FRESULT res;
|
||||
|
||||
if (MP_OBJ_IS_STR_OR_BYTES(device)) {
|
||||
path = mp_obj_str_get_str(device);
|
||||
// otherwise the relative path check will pass...
|
||||
if (path[0] != '/') {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
} else {
|
||||
// mount it and unmount it briefly
|
||||
unmt = true;
|
||||
mount(device, path, strlen(path), false);
|
||||
}
|
||||
|
||||
byte sfd = 0;
|
||||
if (!memcmp(path, "/flash", strlen("/flash"))) {
|
||||
sfd = 1;
|
||||
} else {
|
||||
os_fs_mount_t *mount_obj;
|
||||
if ((mount_obj = osmount_find_by_path(path))) {
|
||||
if (mount_obj->device != (mp_obj_t)&pybsd_obj &&
|
||||
mp_obj_get_int(mp_call_method_n_kw(0, 0, mount_obj->count)) < 2048) {
|
||||
sfd = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// now format the device
|
||||
res = f_mkfs(path, sfd, 0);
|
||||
|
||||
if (unmt) {
|
||||
unmount (path);
|
||||
}
|
||||
|
||||
if (res != FR_OK) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
return mp_const_none;
|
||||
|
@ -381,13 +546,13 @@ STATIC const mp_map_elem_t os_module_globals_table[] = {
|
|||
{ MP_OBJ_NEW_QSTR(MP_QSTR_mkdir), (mp_obj_t)&os_mkdir_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_rename), (mp_obj_t)&os_rename_obj},
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_remove), (mp_obj_t)&os_remove_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_rmdir), (mp_obj_t)&os_remove_obj }, // rmdir aliases to remove
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_rmdir), (mp_obj_t)&os_remove_obj }, // rmdir aliases to remove
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_stat), (mp_obj_t)&os_stat_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_unlink), (mp_obj_t)&os_remove_obj }, // unlink aliases to remove
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_unlink), (mp_obj_t)&os_remove_obj }, // unlink aliases to remove
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_sync), (mp_obj_t)&os_sync_obj },
|
||||
#if MICROPY_HW_ENABLE_RNG
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_urandom), (mp_obj_t)&os_urandom_obj },
|
||||
#endif
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_mount), (mp_obj_t)&os_mount_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_unmount), (mp_obj_t)&os_unmount_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_mkfs), (mp_obj_t)&os_mkfs_obj },
|
||||
|
||||
/// \constant sep - separation character used in paths
|
||||
|
|
|
@ -28,5 +28,20 @@
|
|||
#ifndef MODUOS_H_
|
||||
#define MODUOS_H_
|
||||
|
||||
typedef struct _os_fs_mount_t {
|
||||
mp_obj_t device;
|
||||
const char *path;
|
||||
mp_uint_t pathlen;
|
||||
mp_obj_t readblocks[4];
|
||||
mp_obj_t writeblocks[4];
|
||||
mp_obj_t sync[2];
|
||||
mp_obj_t count[2];
|
||||
FATFS fatfs;
|
||||
uint8_t vol;
|
||||
} os_fs_mount_t;
|
||||
|
||||
void moduos_init0 (void);
|
||||
os_fs_mount_t *osmount_find_by_path (const char *path);
|
||||
os_fs_mount_t *osmount_find_by_volume (uint8_t vol);
|
||||
|
||||
#endif // MODUOS_H_
|
||||
|
|
|
@ -74,12 +74,12 @@ STATIC const mp_obj_type_t ssl_socket_type = {
|
|||
|
||||
STATIC mp_obj_t mod_ssl_wrap_socket(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
STATIC const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_sock, MP_ARG_REQUIRED | MP_ARG_OBJ, },
|
||||
{ MP_QSTR_keyfile, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
|
||||
{ MP_QSTR_certfile, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
|
||||
{ MP_QSTR_server_side, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_false} },
|
||||
{ MP_QSTR_cert_reqs, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = SSL_CERT_NONE} },
|
||||
{ MP_QSTR_ca_certs, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
|
||||
{ MP_QSTR_sock, MP_ARG_REQUIRED | MP_ARG_OBJ, },
|
||||
{ MP_QSTR_keyfile, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
|
||||
{ MP_QSTR_certfile, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
|
||||
{ MP_QSTR_server_side, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
|
||||
{ MP_QSTR_cert_reqs, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = SSL_CERT_NONE} },
|
||||
{ MP_QSTR_ca_certs, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
|
||||
};
|
||||
|
||||
// parse arguments
|
||||
|
@ -98,7 +98,7 @@ STATIC mp_obj_t mod_ssl_wrap_socket(mp_uint_t n_args, const mp_obj_t *pos_args,
|
|||
NULL : &(mp_obj_str_get_str(args[5].u_obj)[6]);
|
||||
|
||||
// server side requires both certfile and keyfile
|
||||
if (mp_obj_is_true(args[3].u_obj) && (!keyfile || !certfile)) {
|
||||
if (args[3].u_bool && (!keyfile || !certfile)) {
|
||||
goto arg_error;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,14 +38,20 @@
|
|||
#include "inc/hw_memmap.h"
|
||||
#include "rom_map.h"
|
||||
#include "prcm.h"
|
||||
#include "systick.h"
|
||||
#include "pybrtc.h"
|
||||
#include "mpsystick.h"
|
||||
#include "mpexception.h"
|
||||
#include "utils.h"
|
||||
|
||||
/// \module time - time related functions
|
||||
///
|
||||
/// The `time` module provides functions for getting the current time and date,
|
||||
/// and for sleeping.
|
||||
|
||||
/******************************************************************************/
|
||||
// Micro Python bindings
|
||||
|
||||
/// \function localtime([secs])
|
||||
/// Convert a time expressed in seconds since Jan 1, 2000 into an 8-tuple which
|
||||
/// contains: (year, month, mday, hour, minute, second, weekday, yearday)
|
||||
|
@ -99,11 +105,6 @@ STATIC mp_obj_t time_localtime(mp_uint_t n_args, const mp_obj_t *args) {
|
|||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(time_localtime_obj, 0, 1, time_localtime);
|
||||
|
||||
|
||||
/// \function mktime()
|
||||
/// This is inverse function of localtime. It's argument is a full 8-tuple
|
||||
/// which expresses a time as per localtime. It returns an integer which is
|
||||
/// the number of seconds since Jan 1, 2000.
|
||||
STATIC mp_obj_t time_mktime(mp_obj_t tuple) {
|
||||
mp_uint_t len;
|
||||
mp_obj_t *elem;
|
||||
|
@ -115,15 +116,16 @@ STATIC mp_obj_t time_mktime(mp_obj_t tuple) {
|
|||
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, mpexception_num_type_invalid_arguments));
|
||||
}
|
||||
|
||||
return mp_obj_new_int_from_uint(timeutils_mktime(mp_obj_get_int(elem[0]),
|
||||
mp_obj_get_int(elem[1]), mp_obj_get_int(elem[2]), mp_obj_get_int(elem[3]),
|
||||
mp_obj_get_int(elem[4]), mp_obj_get_int(elem[5])));
|
||||
return mp_obj_new_int_from_uint(timeutils_mktime(mp_obj_get_int(elem[0]), mp_obj_get_int(elem[1]), mp_obj_get_int(elem[2]),
|
||||
mp_obj_get_int(elem[3]), mp_obj_get_int(elem[4]), mp_obj_get_int(elem[5])));
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(time_mktime_obj, time_mktime);
|
||||
|
||||
STATIC mp_obj_t time_time(void) {
|
||||
return mp_obj_new_int(pyb_rtc_get_seconds());
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_0(time_time_obj, time_time);
|
||||
|
||||
/// \function sleep(seconds)
|
||||
/// Sleep for the given number of seconds.
|
||||
STATIC mp_obj_t time_sleep(mp_obj_t seconds_o) {
|
||||
int32_t sleep_s = mp_obj_get_int(seconds_o);
|
||||
if (sleep_s > 0) {
|
||||
|
@ -133,20 +135,71 @@ STATIC mp_obj_t time_sleep(mp_obj_t seconds_o) {
|
|||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(time_sleep_obj, time_sleep);
|
||||
|
||||
/// \function time()
|
||||
/// Returns the number of seconds, as an integer, since 1/1/2000.
|
||||
STATIC mp_obj_t time_time(void) {
|
||||
return mp_obj_new_int(pybrtc_get_seconds());
|
||||
STATIC mp_obj_t time_sleep_ms (mp_obj_t ms_in) {
|
||||
mp_int_t ms = mp_obj_get_int(ms_in);
|
||||
if (ms > 0) {
|
||||
HAL_Delay(ms);
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_0(time_time_obj, time_time);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(time_sleep_ms_obj, time_sleep_ms);
|
||||
|
||||
STATIC mp_obj_t time_sleep_us (mp_obj_t usec_in) {
|
||||
mp_int_t usec = mp_obj_get_int(usec_in);
|
||||
if (usec > 0) {
|
||||
UtilsDelay(UTILS_DELAY_US_TO_COUNT(usec));
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(time_sleep_us_obj, time_sleep_us);
|
||||
|
||||
STATIC mp_obj_t time_ticks_ms(void) {
|
||||
// We want to "cast" the 32 bit unsigned into a small-int. This means
|
||||
// copying the MSB down 1 bit (extending the sign down), which is
|
||||
// equivalent to just using the MP_OBJ_NEW_SMALL_INT macro.
|
||||
return MP_OBJ_NEW_SMALL_INT(HAL_GetTick());
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(time_ticks_ms_obj, time_ticks_ms);
|
||||
|
||||
STATIC mp_obj_t time_ticks_us(void) {
|
||||
// We want to "cast" the 32 bit unsigned into a small-int. This means
|
||||
// copying the MSB down 1 bit (extending the sign down), which is
|
||||
// equivalent to just using the MP_OBJ_NEW_SMALL_INT macro.
|
||||
return MP_OBJ_NEW_SMALL_INT(sys_tick_get_microseconds());
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(time_ticks_us_obj, time_ticks_us);
|
||||
|
||||
STATIC mp_obj_t time_ticks_cpu(void) {
|
||||
// We want to "cast" the 32 bit unsigned into a small-int. This means
|
||||
// copying the MSB down 1 bit (extending the sign down), which is
|
||||
// equivalent to just using the MP_OBJ_NEW_SMALL_INT macro.
|
||||
return MP_OBJ_NEW_SMALL_INT(SysTickValueGet());
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(time_ticks_cpu_obj, time_ticks_cpu);
|
||||
|
||||
STATIC mp_obj_t time_ticks_diff(mp_obj_t t0, mp_obj_t t1) {
|
||||
// We want to "cast" the 32 bit unsigned into a small-int. This means
|
||||
// copying the MSB down 1 bit (extending the sign down), which is
|
||||
// equivalent to just using the MP_OBJ_NEW_SMALL_INT macro.
|
||||
uint32_t start = mp_obj_get_int(t0);
|
||||
uint32_t end = mp_obj_get_int(t1);
|
||||
return MP_OBJ_NEW_SMALL_INT((end > start) ? (end - start) : (start - end));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(time_ticks_diff_obj, time_ticks_diff);
|
||||
|
||||
STATIC const mp_map_elem_t time_module_globals_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_utime) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_utime) },
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_localtime), (mp_obj_t)&time_localtime_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_mktime), (mp_obj_t)&time_mktime_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_sleep), (mp_obj_t)&time_sleep_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&time_time_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_localtime), (mp_obj_t)&time_localtime_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_mktime), (mp_obj_t)&time_mktime_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&time_time_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_sleep), (mp_obj_t)&time_sleep_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_sleep_ms), (mp_obj_t)&time_sleep_ms_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_sleep_us), (mp_obj_t)&time_sleep_us_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ticks_ms), (mp_obj_t)&time_ticks_ms_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ticks_us), (mp_obj_t)&time_ticks_us_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ticks_cpu), (mp_obj_t)&time_ticks_cpu_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ticks_diff), (mp_obj_t)&time_ticks_diff_obj },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(time_module_globals, time_module_globals_table);
|
||||
|
|
|
@ -533,7 +533,7 @@ void wlan_sl_enable (int8_t mode, const char *ssid, uint8_t ssid_len, uint8_t se
|
|||
}
|
||||
|
||||
// set current time and date (needed to validate certificates)
|
||||
wlan_set_current_time (pybrtc_get_seconds());
|
||||
wlan_set_current_time (pyb_rtc_get_seconds());
|
||||
|
||||
// start the servers before returning
|
||||
wlan_servers_start();
|
||||
|
@ -993,7 +993,7 @@ STATIC mp_obj_t wlan_ifconfig (mp_uint_t n_args, const mp_obj_t *args) {
|
|||
}
|
||||
}
|
||||
// set current time and date (needed to validate certificates)
|
||||
wlan_set_current_time (pybrtc_get_seconds());
|
||||
wlan_set_current_time (pyb_rtc_get_seconds());
|
||||
return mp_const_none;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -279,7 +279,7 @@ STATIC void pyb_i2c_print(const mp_print_t *print, mp_obj_t self_in, mp_print_ki
|
|||
}
|
||||
}
|
||||
|
||||
STATIC mp_obj_t pyb_i2c_init_helper(pyb_i2c_obj_t *self, mp_arg_val_t *args) {
|
||||
STATIC mp_obj_t pyb_i2c_init_helper(pyb_i2c_obj_t *self, const mp_arg_val_t *args) {
|
||||
// verify that mode is master
|
||||
if (args[0].u_int != PYBI2C_MASTER) {
|
||||
goto invalid_args;
|
||||
|
|
|
@ -43,70 +43,86 @@
|
|||
#include "simplelink.h"
|
||||
#include "modnetwork.h"
|
||||
#include "modwlan.h"
|
||||
#include "mpexception.h"
|
||||
|
||||
/// \moduleref pyb
|
||||
/// \class RTC - real time clock
|
||||
///
|
||||
/// The RTC is and independent clock that keeps track of the date
|
||||
/// and time.
|
||||
///
|
||||
/// Example usage:
|
||||
///
|
||||
/// rtc = pyb.RTC()
|
||||
/// rtc.datetime((2014, 5, 1, 4, 13, 0, 0, 0))
|
||||
/// print(rtc.datetime())
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE CONSTANTS
|
||||
******************************************************************************/
|
||||
#define PYBRTC_CLOCK_FREQUENCY_HZ 32768
|
||||
#define PYBRTC_MIN_INTERVAL_VALUE 25
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE TYPES
|
||||
******************************************************************************/
|
||||
typedef struct {
|
||||
typedef struct _pyb_rtc_obj_t {
|
||||
mp_obj_base_t base;
|
||||
byte prwmode;
|
||||
} pybrtc_data_t;
|
||||
bool alarmset;
|
||||
bool repeat;
|
||||
} pyb_rtc_obj_t;
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE DATA
|
||||
******************************************************************************/
|
||||
STATIC pybrtc_data_t pybrtc_data;
|
||||
STATIC const mp_cb_methods_t pybrtc_cb_methods;
|
||||
STATIC const mp_obj_base_t pyb_rtc_obj = {&pyb_rtc_type};
|
||||
STATIC pyb_rtc_obj_t pyb_rtc_obj = {.prwmode = 0, .alarmset = false, .repeat = false};
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE FUNCTIONS
|
||||
******************************************************************************/
|
||||
STATIC uint32_t pyb_rtc_reset (mp_obj_t self_in);
|
||||
STATIC void pyb_rtc_callback_enable (mp_obj_t self_in);
|
||||
STATIC void pyb_rtc_callback_disable (mp_obj_t self_in);
|
||||
STATIC mp_obj_t pyb_rtc_datetime(mp_obj_t self, const mp_obj_t datetime);
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PUBLIC FUNCTIONS
|
||||
******************************************************************************/
|
||||
__attribute__ ((section (".boot")))
|
||||
void pybrtc_pre_init(void) {
|
||||
void pyb_rtc_pre_init(void) {
|
||||
// if the RTC was previously set, leave it alone
|
||||
if (MAP_PRCMSysResetCauseGet() == PRCM_POWER_ON) {
|
||||
// fresh reset; configure the RTC Calendar
|
||||
// set the date to 1st Jan 2015
|
||||
// set the time to 00:00:00
|
||||
uint32_t seconds = timeutils_seconds_since_2000(2015, 1, 1, 0, 0, 0);
|
||||
|
||||
// Mark the RTC in use first
|
||||
MAP_PRCMRTCInUseSet();
|
||||
|
||||
// Now set the RTC calendar seconds
|
||||
MAP_PRCMRTCSet(seconds, 0);
|
||||
// reset the time and date
|
||||
pyb_rtc_reset((mp_obj_t)&pyb_rtc_obj);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t pybrtc_get_seconds (void) {
|
||||
uint32_t pyb_rtc_get_seconds (void) {
|
||||
uint32_t seconds;
|
||||
uint16_t mseconds;
|
||||
|
||||
MAP_PRCMRTCGet(&seconds, &mseconds);
|
||||
return seconds;
|
||||
}
|
||||
|
||||
void pyb_rtc_callback_disable (mp_obj_t self_in) {
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE FUNCTIONS
|
||||
******************************************************************************/
|
||||
STATIC uint32_t pyb_rtc_reset (mp_obj_t self_in) {
|
||||
// fresh reset; configure the RTC Calendar
|
||||
// set the date to 1st Jan 2015
|
||||
// set the time to 00:00:00
|
||||
uint32_t seconds = timeutils_seconds_since_2000(2015, 1, 1, 0, 0, 0);
|
||||
// Now set the RTC calendar seconds
|
||||
MAP_PRCMRTCSet(seconds, 0);
|
||||
return seconds;
|
||||
}
|
||||
|
||||
STATIC void pyb_rtc_callback_enable (mp_obj_t self_in) {
|
||||
pyb_rtc_obj_t *self = self_in;
|
||||
// check the wake from param
|
||||
if (pybrtc_data.prwmode & PYB_PWR_MODE_ACTIVE) {
|
||||
if (self->prwmode & PYB_PWR_MODE_ACTIVE) {
|
||||
// enable the slow clock interrupt
|
||||
MAP_PRCMIntEnable(PRCM_INT_SLOW_CLK_CTR);
|
||||
} else {
|
||||
// just in case it was already enabled before
|
||||
MAP_PRCMIntDisable(PRCM_INT_SLOW_CLK_CTR);
|
||||
}
|
||||
pybsleep_configure_timer_wakeup (self->prwmode);
|
||||
}
|
||||
|
||||
STATIC void pyb_rtc_callback_disable (mp_obj_t self_in) {
|
||||
pyb_rtc_obj_t *self = self_in;
|
||||
// check the wake from param
|
||||
if (self->prwmode & PYB_PWR_MODE_ACTIVE) {
|
||||
// disable the slow clock interrupt
|
||||
MAP_PRCMIntDisable(PRCM_INT_SLOW_CLK_CTR);
|
||||
}
|
||||
|
@ -116,102 +132,219 @@ void pyb_rtc_callback_disable (mp_obj_t self_in) {
|
|||
(void)MAP_PRCMIntStatus();
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE FUNCTIONS
|
||||
******************************************************************************/
|
||||
STATIC void pyb_rtc_callback_enable (mp_obj_t self_in) {
|
||||
// check the wake from param
|
||||
if (pybrtc_data.prwmode & PYB_PWR_MODE_ACTIVE) {
|
||||
// enable the slow clock interrupt
|
||||
MAP_PRCMIntEnable(PRCM_INT_SLOW_CLK_CTR);
|
||||
STATIC uint pyb_rtc_datetime_s_us(const mp_obj_t datetime, uint32_t *seconds) {
|
||||
timeutils_struct_time_t tm;
|
||||
uint32_t useconds;
|
||||
|
||||
// set date and time
|
||||
mp_obj_t *items;
|
||||
uint len;
|
||||
mp_obj_get_array(datetime, &len, &items);
|
||||
|
||||
// verify the tuple
|
||||
if (len < 3 || len > 8) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
else {
|
||||
// just in case it was already enabled before
|
||||
MAP_PRCMIntDisable(PRCM_INT_SLOW_CLK_CTR);
|
||||
|
||||
tm.tm_year = mp_obj_get_int(items[0]);
|
||||
tm.tm_mon = mp_obj_get_int(items[1]);
|
||||
tm.tm_mday = mp_obj_get_int(items[2]);
|
||||
if (len < 7) {
|
||||
useconds = 0;
|
||||
} else {
|
||||
useconds = mp_obj_get_int(items[6]);
|
||||
}
|
||||
pybsleep_configure_timer_wakeup (pybrtc_data.prwmode);
|
||||
if (len < 6) {
|
||||
tm.tm_sec = 0;
|
||||
} else {
|
||||
tm.tm_sec = mp_obj_get_int(items[5]);
|
||||
}
|
||||
if (len < 5) {
|
||||
tm.tm_min = 0;
|
||||
} else {
|
||||
tm.tm_min = mp_obj_get_int(items[4]);
|
||||
}
|
||||
if (len < 4) {
|
||||
tm.tm_hour = 0;
|
||||
} else {
|
||||
tm.tm_hour = mp_obj_get_int(items[3]);
|
||||
}
|
||||
*seconds = timeutils_seconds_since_2000(tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
|
||||
return useconds;
|
||||
}
|
||||
|
||||
/// The 8-tuple has the same format as CPython's datetime object:
|
||||
///
|
||||
/// (year, month, day, hours, minutes, seconds, milliseconds, tzinfo=None)
|
||||
///
|
||||
STATIC mp_obj_t pyb_rtc_datetime(mp_obj_t self, const mp_obj_t datetime) {
|
||||
uint32_t seconds;
|
||||
uint32_t useconds;
|
||||
|
||||
if (datetime != MP_OBJ_NULL) {
|
||||
useconds = pyb_rtc_datetime_s_us(datetime, &seconds);
|
||||
MAP_PRCMRTCSet(seconds, RTC_U16MS_CYCLES(useconds / 1000));
|
||||
} else {
|
||||
seconds = pyb_rtc_reset(self);
|
||||
}
|
||||
|
||||
// set WLAN time and date, this is needed to verify certificates
|
||||
wlan_set_current_time(seconds);
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
// Micro Python bindings
|
||||
|
||||
/// \classmethod \constructor()
|
||||
/// Create an RTC object.
|
||||
STATIC mp_obj_t pyb_rtc_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
|
||||
// check arguments
|
||||
mp_arg_check_num(n_args, n_kw, 0, 0, false);
|
||||
STATIC const mp_arg_t pyb_rtc_init_args[] = {
|
||||
{ MP_QSTR_id, MP_ARG_INT, {.u_int = 0} },
|
||||
{ MP_QSTR_datetime, MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
||||
};
|
||||
STATIC mp_obj_t pyb_rtc_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *all_args) {
|
||||
// parse args
|
||||
mp_map_t kw_args;
|
||||
mp_map_init_fixed_table(&kw_args, n_kw, all_args + n_args);
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(pyb_rtc_init_args)];
|
||||
mp_arg_parse_all(n_args, all_args, &kw_args, MP_ARRAY_SIZE(args), pyb_rtc_init_args, args);
|
||||
|
||||
// check the peripheral id
|
||||
if (args[0].u_int != 0) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable));
|
||||
}
|
||||
|
||||
// setup the object
|
||||
pyb_rtc_obj_t *self = &pyb_rtc_obj;
|
||||
self->base.type = &pyb_rtc_type;
|
||||
|
||||
// set the time and date
|
||||
pyb_rtc_datetime((mp_obj_t)&pyb_rtc_obj, args[1].u_obj);
|
||||
|
||||
// return constant object
|
||||
return (mp_obj_t)&pyb_rtc_obj;
|
||||
}
|
||||
|
||||
/// \method datetime([datetimetuple])
|
||||
/// Get or set the date and time of the RTC.
|
||||
///
|
||||
/// With no arguments, this method returns an 8-tuple with the current
|
||||
/// date and time. With 1 argument (being an 8-tuple) it sets the date
|
||||
/// and time.
|
||||
///
|
||||
/// The 8-tuple has the following format:
|
||||
///
|
||||
/// (year, month, day, weekday, hours, minutes, seconds, milliseconds)
|
||||
///
|
||||
/// `weekday` is 0-6 for Monday through Sunday.
|
||||
///
|
||||
mp_obj_t pyb_rtc_datetime(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
STATIC mp_obj_t pyb_rtc_init (mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
// parse args
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(pyb_rtc_init_args) - 1];
|
||||
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(args), &pyb_rtc_init_args[1], args);
|
||||
return pyb_rtc_datetime(pos_args[0], args[0].u_obj);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_rtc_init_obj, 1, pyb_rtc_init);
|
||||
|
||||
STATIC mp_obj_t pyb_rtc_now (mp_obj_t self_in) {
|
||||
timeutils_struct_time_t tm;
|
||||
uint32_t seconds;
|
||||
uint16_t mseconds;
|
||||
|
||||
if (n_args == 1) {
|
||||
// get the seconds and the milliseconds from the RTC
|
||||
MAP_PRCMRTCGet(&seconds, &mseconds);
|
||||
mseconds = RTC_CYCLES_U16MS(mseconds);
|
||||
timeutils_seconds_since_2000_to_struct_time(seconds, &tm);
|
||||
// get the seconds and the milliseconds from the RTC
|
||||
MAP_PRCMRTCGet(&seconds, &mseconds);
|
||||
mseconds = RTC_CYCLES_U16MS(mseconds);
|
||||
timeutils_seconds_since_2000_to_struct_time(seconds, &tm);
|
||||
|
||||
mp_obj_t tuple[8] = {
|
||||
mp_obj_new_int(tm.tm_year),
|
||||
mp_obj_new_int(tm.tm_mon),
|
||||
mp_obj_new_int(tm.tm_mday),
|
||||
mp_obj_new_int(tm.tm_wday),
|
||||
mp_obj_new_int(tm.tm_hour),
|
||||
mp_obj_new_int(tm.tm_min),
|
||||
mp_obj_new_int(tm.tm_sec),
|
||||
mp_obj_new_int(mseconds)
|
||||
};
|
||||
return mp_obj_new_tuple(8, tuple);
|
||||
} else {
|
||||
// set date and time
|
||||
mp_obj_t *items;
|
||||
mp_obj_get_array_fixed_n(args[1], 8, &items);
|
||||
|
||||
tm.tm_year = mp_obj_get_int(items[0]);
|
||||
tm.tm_mon = mp_obj_get_int(items[1]);
|
||||
tm.tm_mday = mp_obj_get_int(items[2]);
|
||||
// skip the weekday
|
||||
tm.tm_hour = mp_obj_get_int(items[4]);
|
||||
tm.tm_min = mp_obj_get_int(items[5]);
|
||||
tm.tm_sec = mp_obj_get_int(items[6]);
|
||||
mseconds = mp_obj_get_int(items[7]);
|
||||
|
||||
seconds = timeutils_seconds_since_2000(tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
|
||||
mseconds = RTC_U16MS_CYCLES(mseconds);
|
||||
MAP_PRCMRTCSet(seconds, mseconds);
|
||||
|
||||
// set WLAN time and date, this is needed to verify certificates
|
||||
wlan_set_current_time(seconds);
|
||||
return mp_const_none;
|
||||
}
|
||||
mp_obj_t tuple[8] = {
|
||||
mp_obj_new_int(tm.tm_year),
|
||||
mp_obj_new_int(tm.tm_mon),
|
||||
mp_obj_new_int(tm.tm_mday),
|
||||
mp_obj_new_int(tm.tm_hour),
|
||||
mp_obj_new_int(tm.tm_min),
|
||||
mp_obj_new_int(tm.tm_sec),
|
||||
mp_obj_new_int(mseconds * 1000),
|
||||
mp_const_none
|
||||
};
|
||||
return mp_obj_new_tuple(8, tuple);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_rtc_datetime_obj, 1, 2, pyb_rtc_datetime);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_rtc_now_obj, pyb_rtc_now);
|
||||
|
||||
STATIC mp_obj_t pyb_rtc_deinit (mp_obj_t self_in) {
|
||||
pyb_rtc_reset (self_in);
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_rtc_deinit_obj, pyb_rtc_deinit);
|
||||
|
||||
STATIC mp_obj_t pyb_rtc_alarm (mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
STATIC const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_id, MP_ARG_INT, {.u_int = 0} },
|
||||
{ MP_QSTR_time, MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
||||
{ MP_QSTR_repeat, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
|
||||
};
|
||||
|
||||
// parse args
|
||||
pyb_rtc_obj_t *self = pos_args[0];
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(args), allowed_args, args);
|
||||
|
||||
// check the alarm id
|
||||
if (args[0].u_int != 0) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable));
|
||||
}
|
||||
|
||||
uint32_t a_seconds;
|
||||
uint16_t a_mseconds;
|
||||
if (MP_OBJ_IS_TYPE(args[1].u_obj, &mp_type_tuple)) { // datetime tuple given
|
||||
a_mseconds = pyb_rtc_datetime_s_us (args[1].u_obj, &a_seconds) / 1000;
|
||||
} else { // then it must be an integer or MP_OBJ_NULL
|
||||
uint32_t c_seconds;
|
||||
uint16_t c_mseconds;
|
||||
if (MP_OBJ_IS_INT(args[1].u_obj)) {
|
||||
a_seconds = 0, a_mseconds = mp_obj_get_int(args[1].u_obj);
|
||||
} else {
|
||||
a_seconds = 1, a_mseconds = 0;
|
||||
}
|
||||
// get the seconds and the milliseconds from the RTC
|
||||
MAP_PRCMRTCGet(&c_seconds, &c_mseconds);
|
||||
a_mseconds += RTC_CYCLES_U16MS(c_mseconds);
|
||||
// calculate the future time
|
||||
a_seconds += c_seconds + (a_mseconds / 1000);
|
||||
a_mseconds -= ((a_mseconds / 1000) * 1000);
|
||||
}
|
||||
|
||||
// disable the interrupt before updating anything
|
||||
pyb_rtc_callback_disable((mp_obj_t)self);
|
||||
|
||||
// set the match value
|
||||
MAP_PRCMRTCMatchSet(a_seconds, a_mseconds);
|
||||
|
||||
// enabled it again (according to the power mode)
|
||||
pyb_rtc_callback_enable((mp_obj_t)self);
|
||||
|
||||
// set the alarmset flag and store the repeat one
|
||||
self->alarmset = true;
|
||||
self->repeat = args[2].u_bool;
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_rtc_alarm_obj, 1, pyb_rtc_alarm);
|
||||
|
||||
STATIC mp_obj_t pyb_rtc_alarm_left (mp_obj_t self_in) {
|
||||
pyb_rtc_obj_t *self = self_in;
|
||||
uint32_t a_seconds, c_seconds;
|
||||
uint16_t a_mseconds, c_mseconds;
|
||||
int32_t ms_left;
|
||||
|
||||
// get the alarm time
|
||||
MAP_PRCMRTCMatchGet(&a_seconds, &a_mseconds);
|
||||
a_mseconds = RTC_CYCLES_U16MS(a_mseconds);
|
||||
// get the current time
|
||||
MAP_PRCMRTCGet(&c_seconds, &c_mseconds);
|
||||
c_mseconds = RTC_CYCLES_U16MS(c_mseconds);
|
||||
// calculate the ms left
|
||||
ms_left = ((a_seconds * 1000) + a_mseconds) - ((c_seconds * 1000) + c_mseconds);
|
||||
if (!self->alarmset || ms_left < 0) {
|
||||
ms_left = 0;
|
||||
}
|
||||
return mp_obj_new_int(ms_left);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_rtc_alarm_left_obj, pyb_rtc_alarm_left);
|
||||
|
||||
/// \method callback(handler, value, pwrmode)
|
||||
/// Creates a callback object associated with the real time clock
|
||||
/// min num of arguments is 1 (value). The value is the alarm time
|
||||
/// in the future, in msec
|
||||
/// FIXME
|
||||
STATIC mp_obj_t pyb_rtc_callback (mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
mp_arg_val_t args[mpcallback_INIT_NUM_ARGS];
|
||||
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, mpcallback_INIT_NUM_ARGS, mpcallback_init_args, args);
|
||||
pyb_rtc_obj_t *self = pos_args[0];
|
||||
|
||||
// check if any parameters were passed
|
||||
mp_obj_t _callback = mpcallback_find((mp_obj_t)&pyb_rtc_obj);
|
||||
|
@ -228,14 +361,13 @@ STATIC mp_obj_t pyb_rtc_callback (mp_uint_t n_args, const mp_obj_t *pos_args, mp
|
|||
mseconds += f_mseconds - ((f_mseconds / 1000) * 1000);
|
||||
|
||||
// disable the interrupt before updating anything
|
||||
// (the object is not relevant here, the function already knows it)
|
||||
pyb_rtc_callback_disable(NULL);
|
||||
pyb_rtc_callback_disable((mp_obj_t)&pyb_rtc_obj);
|
||||
|
||||
// set the match value
|
||||
MAP_PRCMRTCMatchSet(seconds, mseconds);
|
||||
|
||||
// save the power mode data for later
|
||||
pybrtc_data.prwmode = args[4].u_int;
|
||||
self->prwmode = args[4].u_int;
|
||||
|
||||
// create the callback
|
||||
_callback = mpcallback_new ((mp_obj_t)&pyb_rtc_obj, args[1].u_obj, &pybrtc_cb_methods, true);
|
||||
|
@ -246,8 +378,8 @@ STATIC mp_obj_t pyb_rtc_callback (mp_uint_t n_args, const mp_obj_t *pos_args, mp
|
|||
// the interrupt priority is ignored since it's already set to to highest level by the sleep module
|
||||
// to make sure that the wakeup callbacks are always called first when resuming from sleep
|
||||
|
||||
// enable the interrupt (the object is not relevant here, the function already knows it)
|
||||
pyb_rtc_callback_enable(NULL);
|
||||
// enable the interrupt
|
||||
pyb_rtc_callback_enable((mp_obj_t)&pyb_rtc_obj);
|
||||
} else if (!_callback) {
|
||||
_callback = mpcallback_new ((mp_obj_t)&pyb_rtc_obj, mp_const_none, &pybrtc_cb_methods, false);
|
||||
}
|
||||
|
@ -256,8 +388,12 @@ STATIC mp_obj_t pyb_rtc_callback (mp_uint_t n_args, const mp_obj_t *pos_args, mp
|
|||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_rtc_callback_obj, 1, pyb_rtc_callback);
|
||||
|
||||
STATIC const mp_map_elem_t pyb_rtc_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_datetime), (mp_obj_t)&pyb_rtc_datetime_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_callback), (mp_obj_t)&pyb_rtc_callback_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&pyb_rtc_init_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_deinit), (mp_obj_t)&pyb_rtc_deinit_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_now), (mp_obj_t)&pyb_rtc_now_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_alarm), (mp_obj_t)&pyb_rtc_alarm_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_alarm_left), (mp_obj_t)&pyb_rtc_alarm_left_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_callback), (mp_obj_t)&pyb_rtc_callback_obj },
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(pyb_rtc_locals_dict, pyb_rtc_locals_dict_table);
|
||||
|
||||
|
|
|
@ -33,8 +33,7 @@
|
|||
|
||||
extern const mp_obj_type_t pyb_rtc_type;
|
||||
|
||||
extern void pybrtc_pre_init(void);
|
||||
extern void pyb_rtc_callback_disable (mp_obj_t self_in);
|
||||
extern uint32_t pybrtc_get_seconds (void);
|
||||
extern void pyb_rtc_pre_init(void);
|
||||
extern uint32_t pyb_rtc_get_seconds (void);
|
||||
|
||||
#endif // PYBRTC_H_
|
||||
|
|
|
@ -37,69 +37,46 @@
|
|||
#include "prcm.h"
|
||||
#include "gpio.h"
|
||||
#include "sdhost.h"
|
||||
#include "pybpin.h"
|
||||
#include "pybsd.h"
|
||||
#include "ff.h"
|
||||
#include "diskio.h"
|
||||
#include "sd_diskio.h"
|
||||
#include "simplelink.h"
|
||||
#include "debug.h"
|
||||
#include "pybsd.h"
|
||||
#include "mpexception.h"
|
||||
#include "pybsleep.h"
|
||||
#include "pybpin.h"
|
||||
#include "pins.h"
|
||||
|
||||
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PRIVATE CONSTANTS
|
||||
******************************************************************************/
|
||||
#define PYBSD_FREQUENCY_HZ 15000000 // 15MHz
|
||||
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
FATFS *fatfs;
|
||||
pin_obj_t *pin_clk;
|
||||
bool pinsset;
|
||||
bool enabled;
|
||||
bool mounted;
|
||||
} pybsd_obj_t;
|
||||
/******************************************************************************
|
||||
DECLARE PUBLIC DATA
|
||||
******************************************************************************/
|
||||
pybsd_obj_t pybsd_obj = {.pin_clk = MP_OBJ_NULL, .enabled = false};
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE DATA
|
||||
******************************************************************************/
|
||||
STATIC pybsd_obj_t pybsd_obj = {.pinsset = false, .enabled = false, .mounted = false};
|
||||
STATIC const mp_obj_t pyb_sd_def_pin[3] = {&pin_GP10, &pin_GP11, &pin_GP15};
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE FUNCTIONS
|
||||
******************************************************************************/
|
||||
STATIC void pybsd_hw_init (pybsd_obj_t *self);
|
||||
STATIC mp_obj_t pybsd_make_new (mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args);
|
||||
STATIC mp_obj_t pybsd_init (uint n_args, const mp_obj_t *args);
|
||||
STATIC mp_obj_t pybsd_deinit (mp_obj_t self_in);
|
||||
STATIC mp_obj_t pybsd_mount (mp_obj_t self_in);
|
||||
STATIC mp_obj_t pybsd_unmount (mp_obj_t self_in);
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PUBLIC FUNCTIONS
|
||||
******************************************************************************/
|
||||
__attribute__ ((section (".boot")))
|
||||
void pybsd_pre_init (void) {
|
||||
// allocate memory for the sd file system
|
||||
ASSERT ((pybsd_obj.fatfs = mem_Malloc(sizeof(FATFS))) != NULL);
|
||||
}
|
||||
|
||||
void pybsd_disable (void) {
|
||||
pybsd_deinit ((mp_obj_t)&pybsd_obj);
|
||||
}
|
||||
|
||||
bool pybsd_is_mounted (void) {
|
||||
return pybsd_obj.mounted;
|
||||
}
|
||||
STATIC void pyb_sd_hw_init (pybsd_obj_t *self);
|
||||
STATIC mp_obj_t pyb_sd_make_new (mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args);
|
||||
STATIC mp_obj_t pyb_sd_deinit (mp_obj_t self_in);
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PRIVATE FUNCTIONS
|
||||
******************************************************************************/
|
||||
/// Initalizes the sd card hardware driver
|
||||
STATIC void pybsd_hw_init (pybsd_obj_t *self) {
|
||||
// Configure the clock pin as output only
|
||||
MAP_PinDirModeSet(self->pin_clk->pin_num, PIN_DIR_MODE_OUT);
|
||||
STATIC void pyb_sd_hw_init (pybsd_obj_t *self) {
|
||||
if (self->pin_clk) {
|
||||
// Configure the clock pin as output only
|
||||
MAP_PinDirModeSet(((pin_obj_t *)(self->pin_clk))->pin_num, PIN_DIR_MODE_OUT);
|
||||
}
|
||||
// Enable SD peripheral clock
|
||||
MAP_PRCMPeripheralClkEnable(PRCM_SDHOST, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
|
||||
// Reset MMCHS
|
||||
|
@ -110,38 +87,36 @@ STATIC void pybsd_hw_init (pybsd_obj_t *self) {
|
|||
MAP_SDHostSetExpClk(SDHOST_BASE, MAP_PRCMPeripheralClockGet(PRCM_SDHOST), PYBSD_FREQUENCY_HZ);
|
||||
// Set card rd/wr block len
|
||||
MAP_SDHostBlockSizeSet(SDHOST_BASE, SD_SECTOR_SIZE);
|
||||
self->enabled = true;
|
||||
}
|
||||
|
||||
STATIC mp_obj_t pybsd_init_helper (pybsd_obj_t *self, uint n_args, const mp_obj_t *args) {
|
||||
if (n_args > 0) {
|
||||
if (mp_obj_get_type(args[0]) == &mp_type_tuple) {
|
||||
mp_obj_t *items;
|
||||
mp_obj_get_array_fixed_n(args[0], 6, &items);
|
||||
|
||||
// save the clock pin for later use
|
||||
self->pin_clk = (pin_obj_t *)pin_find(items[2]);
|
||||
|
||||
// configure the data pin with pull-up enabled
|
||||
pin_config ((pin_obj_t *)pin_find(items[0]), mp_obj_get_int(items[1]), 0, PIN_TYPE_STD_PU, -1, PIN_STRENGTH_4MA);
|
||||
// configure the clock pin
|
||||
pin_config (self->pin_clk, mp_obj_get_int(items[3]), 0, PIN_TYPE_STD, -1, PIN_STRENGTH_4MA);
|
||||
// configure the command pin with pull-up enabled
|
||||
pin_config ((pin_obj_t *)pin_find(items[4]), mp_obj_get_int(items[5]), 0, PIN_TYPE_STD_PU, -1, PIN_STRENGTH_4MA);
|
||||
self->pinsset = true;
|
||||
STATIC mp_obj_t pyb_sd_init_helper (pybsd_obj_t *self, const mp_arg_val_t *args) {
|
||||
// assign the pins
|
||||
mp_obj_t pins_o = args[0].u_obj;
|
||||
if (pins_o != mp_const_none) {
|
||||
mp_obj_t *pins;
|
||||
mp_uint_t n_pins = MP_ARRAY_SIZE(pyb_sd_def_pin);
|
||||
if (pins_o == MP_OBJ_NULL) {
|
||||
// use the default pins
|
||||
pins = (mp_obj_t *)pyb_sd_def_pin;
|
||||
} else {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, mpexception_num_type_invalid_arguments));
|
||||
mp_obj_get_array(pins_o, &n_pins, &pins);
|
||||
if (n_pins != MP_ARRAY_SIZE(pyb_sd_def_pin)) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
}
|
||||
pin_assign_pins_af (pins, n_pins, PIN_TYPE_STD_PU, PIN_FN_SD, 0);
|
||||
// save the pins clock
|
||||
self->pin_clk = pin_find(pins[0]);
|
||||
}
|
||||
|
||||
if (!self->enabled) {
|
||||
if (!self->pinsset) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
|
||||
}
|
||||
pybsd_hw_init (self);
|
||||
// mark as enabled and register it with the sleep module
|
||||
self->enabled = true;
|
||||
pybsleep_add ((const mp_obj_t)self, (WakeUpCB_t)pybsd_hw_init);
|
||||
pyb_sd_hw_init (self);
|
||||
if (sd_disk_init() != 0) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
|
||||
// register it with the sleep module
|
||||
pybsleep_add ((const mp_obj_t)self, (WakeUpCB_t)pyb_sd_hw_init);
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
|
@ -149,107 +124,60 @@ STATIC mp_obj_t pybsd_init_helper (pybsd_obj_t *self, uint n_args, const mp_obj_
|
|||
// Micro Python bindings
|
||||
//
|
||||
|
||||
/// \classmethod \constructor()
|
||||
/// Creates an SD card object.
|
||||
/// Accepts a tuple of pins an alternate functions to configure the SD card interface.
|
||||
/// When called with no arguments it returns the previoulsy created SD card object.
|
||||
///
|
||||
/// Usage:
|
||||
/// sd = pyb.SD()
|
||||
/// Or:
|
||||
/// sd = pyb.SD((d0_pin, d0_af, clk_pin, clk_af, cmd_pin, cmd_af))
|
||||
///
|
||||
STATIC mp_obj_t pybsd_make_new (mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
|
||||
mp_arg_check_num(n_args, n_kw, 0, 1, false);
|
||||
STATIC const mp_arg_t pyb_sd_init_args[] = {
|
||||
{ MP_QSTR_id, MP_ARG_INT, {.u_int = 0} },
|
||||
{ MP_QSTR_pins, MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
||||
};
|
||||
STATIC mp_obj_t pyb_sd_make_new (mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *all_args) {
|
||||
// parse args
|
||||
mp_map_t kw_args;
|
||||
mp_map_init_fixed_table(&kw_args, n_kw, all_args + n_args);
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(pyb_sd_init_args)];
|
||||
mp_arg_parse_all(n_args, all_args, &kw_args, MP_ARRAY_SIZE(args), pyb_sd_init_args, args);
|
||||
|
||||
// check the peripheral id
|
||||
if (args[0].u_int != 0) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable));
|
||||
}
|
||||
|
||||
// setup and initialize the object
|
||||
mp_obj_t self = &pybsd_obj;
|
||||
pybsd_obj.base.type = &pyb_sd_type;
|
||||
|
||||
if (n_args > 0) {
|
||||
pybsd_init_helper (self, n_args, args);
|
||||
}
|
||||
pyb_sd_init_helper (self, &args[1]);
|
||||
return self;
|
||||
}
|
||||
|
||||
/// \method init()
|
||||
/// Enables the sd card
|
||||
STATIC mp_obj_t pybsd_init (uint n_args, const mp_obj_t *args) {
|
||||
return pybsd_init_helper(args[0], n_args - 1, args + 1);
|
||||
STATIC mp_obj_t pyb_sd_init (mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
// parse args
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(pyb_sd_init_args) - 1];
|
||||
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(args), &pyb_sd_init_args[1], args);
|
||||
return pyb_sd_init_helper(pos_args[0], args);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pybsd_init_obj, 1, 2, pybsd_init);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_sd_init_obj, 1, pyb_sd_init);
|
||||
|
||||
/// \method deinit()
|
||||
/// Disables the sd card
|
||||
STATIC mp_obj_t pybsd_deinit (mp_obj_t self_in) {
|
||||
STATIC mp_obj_t pyb_sd_deinit (mp_obj_t self_in) {
|
||||
pybsd_obj_t *self = self_in;
|
||||
if (self->enabled) {
|
||||
// unmounted in case not done yet
|
||||
pybsd_unmount (self);
|
||||
self->enabled = false;
|
||||
// disable the peripheral
|
||||
MAP_PRCMPeripheralClkDisable(PRCM_SDHOST, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
|
||||
// de-initialze the sd card at diskio level
|
||||
sd_disk_deinit();
|
||||
// unregister it with the sleep module
|
||||
pybsleep_remove (self);
|
||||
}
|
||||
// disable the peripheral
|
||||
self->enabled = false;
|
||||
MAP_PRCMPeripheralClkDisable(PRCM_SDHOST, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
|
||||
// de-initialze the sd card at diskio level
|
||||
sd_disk_deinit();
|
||||
// unregister it from the sleep module
|
||||
pybsleep_remove (self);
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pybsd_deinit_obj, pybsd_deinit);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_sd_deinit_obj, pyb_sd_deinit);
|
||||
|
||||
/// \method mount()
|
||||
/// Mount the sd card on /sd
|
||||
STATIC mp_obj_t pybsd_mount (mp_obj_t self_in) {
|
||||
pybsd_obj_t *self = self_in;
|
||||
if (!self->mounted) {
|
||||
if (!self->enabled) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
|
||||
}
|
||||
// try to mount the sd card on /sd
|
||||
if (FR_OK != f_mount(self->fatfs, "/sd", 1)) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_sd));
|
||||
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_sd_slash_lib));
|
||||
self->mounted = true;
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pybsd_mount_obj, pybsd_mount);
|
||||
|
||||
/// \method unmount()
|
||||
/// Unmount the sd card
|
||||
STATIC mp_obj_t pybsd_unmount (mp_obj_t self_in) {
|
||||
pybsd_obj_t *self = self_in;
|
||||
if (self->mounted) {
|
||||
if (!self->enabled) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
|
||||
}
|
||||
// unmount the sd card
|
||||
f_mount (NULL, "/sd", 1);
|
||||
// remove sd paths from mp_sys_path
|
||||
mp_obj_list_remove(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_sd));
|
||||
mp_obj_list_remove(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_sd_slash_lib));
|
||||
self->mounted = false;
|
||||
// change the drive in case it was /sd
|
||||
f_chdrive("/flash");
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pybsd_unmount_obj, pybsd_unmount);
|
||||
|
||||
STATIC const mp_map_elem_t pybsd_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&pybsd_init_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_deinit), (mp_obj_t)&pybsd_deinit_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_mount), (mp_obj_t)&pybsd_mount_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_unmount), (mp_obj_t)&pybsd_unmount_obj },
|
||||
STATIC const mp_map_elem_t pyb_sd_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&pyb_sd_init_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_deinit), (mp_obj_t)&pyb_sd_deinit_obj },
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(pybsd_locals_dict, pybsd_locals_dict_table);
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(pyb_sd_locals_dict, pyb_sd_locals_dict_table);
|
||||
|
||||
const mp_obj_type_t pyb_sd_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_SD,
|
||||
.make_new = pybsd_make_new,
|
||||
.locals_dict = (mp_obj_t)&pybsd_locals_dict,
|
||||
.make_new = pyb_sd_make_new,
|
||||
.locals_dict = (mp_obj_t)&pyb_sd_locals_dict,
|
||||
};
|
||||
|
||||
#endif // MICROPY_HW_HAS_SDCARD
|
||||
|
|
|
@ -26,12 +26,19 @@
|
|||
#ifndef PYBSD_H_
|
||||
#define PYBSD_H_
|
||||
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
/******************************************************************************
|
||||
DEFINE PUBLIC TYPES
|
||||
******************************************************************************/
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
mp_obj_t pin_clk;
|
||||
bool enabled;
|
||||
} pybsd_obj_t;
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE EXPORTED DATA
|
||||
******************************************************************************/
|
||||
extern pybsd_obj_t pybsd_obj;
|
||||
extern const mp_obj_type_t pyb_sd_type;
|
||||
|
||||
void pybsd_pre_init (void);
|
||||
void pybsd_disable (void);
|
||||
bool pybsd_is_mounted (void);
|
||||
#endif
|
||||
|
||||
#endif // PYBSD_H_
|
||||
|
|
|
@ -156,7 +156,7 @@ STATIC void pyb_spi_print(const mp_print_t *print, mp_obj_t self_in, mp_print_ki
|
|||
}
|
||||
}
|
||||
|
||||
STATIC mp_obj_t pyb_spi_init_helper(pyb_spi_obj_t *self, mp_arg_val_t *args) {
|
||||
STATIC mp_obj_t pyb_spi_init_helper(pyb_spi_obj_t *self, const mp_arg_val_t *args) {
|
||||
// verify that mode is master
|
||||
if (args[0].u_int != SPI_MODE_MASTER) {
|
||||
goto invalid_args;
|
||||
|
|
|
@ -352,7 +352,7 @@ STATIC void pyb_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_print_k
|
|||
}
|
||||
}
|
||||
|
||||
STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, mp_arg_val_t *args) {
|
||||
STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, const mp_arg_val_t *args) {
|
||||
// get the baudrate
|
||||
if (args[0].u_int <= 0) {
|
||||
goto error;
|
||||
|
|
|
@ -53,17 +53,17 @@
|
|||
DECLARE TYPES
|
||||
******************************************************************************/
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
bool servers;
|
||||
bool servers_sleeping;
|
||||
bool simplelink;
|
||||
bool running;
|
||||
} pybwdt_data_t;
|
||||
} pyb_wdt_obj_t;
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE DATA
|
||||
******************************************************************************/
|
||||
STATIC pybwdt_data_t pybwdt_data = {.servers = false, .servers_sleeping = false, .simplelink = false, .running = false};
|
||||
STATIC const mp_obj_base_t pyb_wdt_obj = {&pyb_wdt_type};
|
||||
STATIC pyb_wdt_obj_t pyb_wdt_obj = {.servers = false, .servers_sleeping = false, .simplelink = false, .running = false};
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PUBLIC FUNCTIONS
|
||||
|
@ -74,15 +74,15 @@ void pybwdt_init0 (void) {
|
|||
}
|
||||
|
||||
void pybwdt_srv_alive (void) {
|
||||
pybwdt_data.servers = true;
|
||||
pyb_wdt_obj.servers = true;
|
||||
}
|
||||
|
||||
void pybwdt_srv_sleeping (bool state) {
|
||||
pybwdt_data.servers_sleeping = state;
|
||||
pyb_wdt_obj.servers_sleeping = state;
|
||||
}
|
||||
|
||||
void pybwdt_sl_alive (void) {
|
||||
pybwdt_data.simplelink = true;
|
||||
pyb_wdt_obj.simplelink = true;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -106,7 +106,7 @@ STATIC mp_obj_t pyb_wdt_make_new (mp_obj_t type_in, mp_uint_t n_args, mp_uint_t
|
|||
if (timeout_ms < PYBWDT_MIN_TIMEOUT_MS) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
if (pybwdt_data.running) {
|
||||
if (pyb_wdt_obj.running) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
|
||||
}
|
||||
|
||||
|
@ -128,15 +128,17 @@ STATIC mp_obj_t pyb_wdt_make_new (mp_obj_t type_in, mp_uint_t n_args, mp_uint_t
|
|||
|
||||
// start the timer. Once it's started, it cannot be disabled.
|
||||
MAP_WatchdogEnable(WDT_BASE);
|
||||
pybwdt_data.running = true;
|
||||
pyb_wdt_obj.base.type = &pyb_wdt_type;
|
||||
pyb_wdt_obj.running = true;
|
||||
|
||||
return (mp_obj_t)&pyb_wdt_obj;
|
||||
}
|
||||
|
||||
STATIC mp_obj_t pyb_wdt_feed(mp_obj_t self) {
|
||||
if ((pybwdt_data.servers || pybwdt_data.servers_sleeping) && pybwdt_data.simplelink && pybwdt_data.running) {
|
||||
pybwdt_data.servers = false;
|
||||
pybwdt_data.simplelink = false;
|
||||
STATIC mp_obj_t pyb_wdt_feed(mp_obj_t self_in) {
|
||||
pyb_wdt_obj_t *self = self_in;
|
||||
if ((self->servers || self->servers_sleeping) && self->simplelink && self->running) {
|
||||
self->servers = false;
|
||||
self->simplelink = false;
|
||||
MAP_WatchdogIntClear(WDT_BASE);
|
||||
}
|
||||
return mp_const_none;
|
||||
|
|
|
@ -162,6 +162,7 @@ extern const struct _mp_obj_module_t mp_module_ussl;
|
|||
mp_obj_list_t pybsleep_obj_list; \
|
||||
mp_obj_list_t mpcallback_obj_list; \
|
||||
mp_obj_list_t pyb_timer_channel_obj_list; \
|
||||
mp_obj_list_t mount_obj_list; \
|
||||
struct _pyb_uart_obj_t *pyb_uart_objs[2]; \
|
||||
|
||||
|
||||
|
|
|
@ -61,13 +61,13 @@
|
|||
#include "mpexception.h"
|
||||
#include "random.h"
|
||||
#include "pybi2c.h"
|
||||
#include "pybsd.h"
|
||||
#include "pins.h"
|
||||
#include "pybsleep.h"
|
||||
#include "pybtimer.h"
|
||||
#include "mpcallback.h"
|
||||
#include "cryptohash.h"
|
||||
#include "updater.h"
|
||||
#include "moduos.h"
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE CONSTANTS
|
||||
|
@ -134,9 +134,8 @@ soft_reset:
|
|||
timer_init0();
|
||||
readline_init0();
|
||||
mod_network_init0();
|
||||
#if MICROPY_HW_ENABLE_RNG
|
||||
moduos_init0();
|
||||
rng_init0();
|
||||
#endif
|
||||
|
||||
#ifdef LAUNCHXL
|
||||
// instantiate the stdio uart on the default pins
|
||||
|
@ -243,10 +242,6 @@ soft_reset_exit:
|
|||
// clean-up the user socket space
|
||||
modusocket_close_all_user_sockets();
|
||||
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
pybsd_disable();
|
||||
#endif
|
||||
|
||||
// wait for pending transactions to complete
|
||||
HAL_Delay(20);
|
||||
|
||||
|
@ -258,9 +253,8 @@ soft_reset_exit:
|
|||
******************************************************************************/
|
||||
__attribute__ ((section (".boot")))
|
||||
STATIC void mptask_pre_init (void) {
|
||||
#if MICROPY_HW_ENABLE_RTC
|
||||
pybrtc_pre_init();
|
||||
#endif
|
||||
// this one only makes sense after a poweron reset
|
||||
pyb_rtc_pre_init();
|
||||
|
||||
// Create the simple link spawn task
|
||||
ASSERT (OSI_OK == VStartSimpleLinkSpawnTask(SIMPLELINK_SPAWN_TASK_PRIORITY));
|
||||
|
@ -280,11 +274,6 @@ STATIC void mptask_pre_init (void) {
|
|||
// this one allocates memory for the socket semaphore
|
||||
modusocket_pre_init();
|
||||
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
// this one allocates memory for the SD file system
|
||||
pybsd_pre_init();
|
||||
#endif
|
||||
|
||||
CRYPTOHASH_Init();
|
||||
|
||||
#ifdef DEBUG
|
||||
|
|
|
@ -35,40 +35,18 @@ Q(main)
|
|||
Q(sync)
|
||||
Q(gc)
|
||||
Q(rng)
|
||||
Q(delay)
|
||||
Q(time)
|
||||
Q(open)
|
||||
Q(on)
|
||||
Q(off)
|
||||
Q(toggle)
|
||||
Q(write)
|
||||
Q(read)
|
||||
Q(readall)
|
||||
Q(readline)
|
||||
Q(input)
|
||||
Q(os)
|
||||
Q(freq)
|
||||
Q(unique_id)
|
||||
Q(repl_info)
|
||||
Q(disable_irq)
|
||||
Q(enable_irq)
|
||||
Q(millis)
|
||||
Q(micros)
|
||||
Q(elapsed_millis)
|
||||
Q(elapsed_micros)
|
||||
Q(udelay)
|
||||
Q(flush)
|
||||
Q(FileIO)
|
||||
Q(enable)
|
||||
Q(disable)
|
||||
Q(repl_uart)
|
||||
// Entries for sys.path
|
||||
// entries for sys.path
|
||||
Q(/flash)
|
||||
Q(/flash/lib)
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
Q(/sd)
|
||||
Q(/sd/lib)
|
||||
#endif
|
||||
|
||||
// for module weak links
|
||||
Q(struct)
|
||||
|
@ -79,8 +57,8 @@ Q(heapq)
|
|||
Q(hashlib)
|
||||
|
||||
// for os module
|
||||
Q(uos)
|
||||
Q(os)
|
||||
Q(uos)
|
||||
Q(sysname)
|
||||
Q(nodename)
|
||||
Q(release)
|
||||
|
@ -89,9 +67,6 @@ Q(machine)
|
|||
Q(uname)
|
||||
Q(/)
|
||||
Q(flash)
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
Q(sd)
|
||||
#endif
|
||||
Q(chdir)
|
||||
Q(getcwd)
|
||||
Q(listdir)
|
||||
|
@ -104,6 +79,13 @@ Q(sep)
|
|||
Q(stat)
|
||||
Q(urandom)
|
||||
Q(mkfs)
|
||||
Q(mount)
|
||||
Q(unmount)
|
||||
Q(readonly)
|
||||
Q(readblocks)
|
||||
Q(writeblocks)
|
||||
Q(sync)
|
||||
Q(count)
|
||||
|
||||
// for file class
|
||||
Q(seek)
|
||||
|
@ -185,25 +167,35 @@ Q(channel)
|
|||
Q(id)
|
||||
Q(pin)
|
||||
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
// for SD class
|
||||
Q(SD)
|
||||
Q(init)
|
||||
Q(deinit)
|
||||
Q(mount)
|
||||
Q(unmount)
|
||||
#endif
|
||||
Q(id)
|
||||
Q(pins)
|
||||
|
||||
// for RTC class
|
||||
Q(RTC)
|
||||
Q(init)
|
||||
Q(alarm)
|
||||
Q(alarm_left)
|
||||
Q(now)
|
||||
Q(deinit)
|
||||
Q(datetime)
|
||||
Q(repeat)
|
||||
|
||||
// for time class
|
||||
Q(time)
|
||||
Q(utime)
|
||||
Q(localtime)
|
||||
Q(mktime)
|
||||
Q(sleep)
|
||||
Q(time)
|
||||
Q(sleep_ms)
|
||||
Q(sleep_us)
|
||||
Q(ticks_ms)
|
||||
Q(ticks_us)
|
||||
Q(ticks_cpu)
|
||||
Q(ticks_diff)
|
||||
|
||||
// for select class
|
||||
Q(select)
|
||||
|
|
|
@ -63,12 +63,12 @@ print(ls)
|
|||
|
||||
# test the real time clock
|
||||
rtc = pyb.RTC()
|
||||
while rtc.datetime()[7] > 800:
|
||||
while rtc.now()[6] > 800:
|
||||
pass
|
||||
|
||||
time1 = rtc.datetime()
|
||||
time1 = rtc.now()
|
||||
pyb.delay(1000)
|
||||
time2 = rtc.datetime()
|
||||
print(time2[6] - time1[6] == 1)
|
||||
print(time2[7] - time1[7] < 50)
|
||||
time2 = rtc.now()
|
||||
print(time2[5] - time1[5] == 1)
|
||||
print(time2[6] - time1[6] < 5000) # microseconds
|
||||
|
||||
|
|
|
@ -43,11 +43,11 @@
|
|||
/******************************************************************************
|
||||
* LOCAL TYPES
|
||||
******************************************************************************/
|
||||
typedef union Id_t {
|
||||
typedef union _rng_id_t {
|
||||
uint32_t id32;
|
||||
uint16_t id16[3];
|
||||
uint8_t id8[6];
|
||||
} Id_t;
|
||||
} rng_id_t;
|
||||
|
||||
/******************************************************************************
|
||||
* LOCAL VARIABLES
|
||||
|
@ -64,29 +64,19 @@ static uint32_t lfsr (uint32_t input);
|
|||
******************************************************************************/
|
||||
static uint32_t lfsr (uint32_t input) {
|
||||
assert( input != 0 );
|
||||
|
||||
/*lint -save -e501*/
|
||||
return (input >> 1) ^ (-(input & 0x01) & 0x00E10000);
|
||||
/*lint -restore*/
|
||||
}
|
||||
|
||||
#if MICROPY_HW_ENABLE_RNG
|
||||
/// \moduleref rng
|
||||
|
||||
/// \function rng()
|
||||
/// Return a 24-bit hardware generated random number.
|
||||
STATIC mp_obj_t pyb_rng_get(void) {
|
||||
return mp_obj_new_int(rng_get());
|
||||
}
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_0(pyb_rng_get_obj, pyb_rng_get);
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
* PUBLIC FUNCTIONS
|
||||
******************************************************************************/
|
||||
void rng_init0 (void) {
|
||||
Id_t juggler;
|
||||
rng_id_t juggler;
|
||||
uint32_t seconds;
|
||||
uint16_t mseconds;
|
||||
|
||||
|
@ -95,7 +85,7 @@ void rng_init0 (void) {
|
|||
|
||||
wlan_get_mac (juggler.id8);
|
||||
|
||||
// Flatten the 48-bit board identification to 24 bits
|
||||
// flatten the 48-bit board identification to 24 bits
|
||||
juggler.id16[0] ^= juggler.id16[2];
|
||||
|
||||
juggler.id8[0] ^= juggler.id8[3];
|
||||
|
@ -104,7 +94,8 @@ void rng_init0 (void) {
|
|||
|
||||
s_seed = juggler.id32 & 0x00FFFFFF;
|
||||
s_seed += (seconds & 0x000FFFFF) + mseconds;
|
||||
// The seed must not be zero
|
||||
|
||||
// the seed must not be zero
|
||||
if (s_seed == 0) {
|
||||
s_seed = 1;
|
||||
}
|
||||
|
|
|
@ -30,8 +30,6 @@
|
|||
void rng_init0 (void);
|
||||
uint32_t rng_get (void);
|
||||
|
||||
#if MICROPY_HW_ENABLE_RNG
|
||||
MP_DECLARE_CONST_FUN_OBJ(pyb_rng_get_obj);
|
||||
#endif
|
||||
MP_DECLARE_CONST_FUN_OBJ(pyb_rng_get_obj);
|
||||
|
||||
#endif // __RANDOM_H
|
||||
|
|
|
@ -158,11 +158,12 @@ SD card
|
|||
See :ref:`pyb.SD <pyb.SD>`. ::
|
||||
|
||||
from pyb import SD
|
||||
import os
|
||||
|
||||
# SD card pins need special configuration so we pass them to the constructor
|
||||
# data pin, data af, clock pin, clock af, cmd pin, cmd af
|
||||
sd = pyb.SD(('GP15', 8, 'GP10', 6, 'GP11', 6))
|
||||
sd.mount()
|
||||
# clock pin, cmd pin, data0 pin
|
||||
sd = SD(pins=('GP10', 'GP11', 'GP15'))
|
||||
os.mount(sd, '/sd')
|
||||
|
||||
WLAN (WiFi)
|
||||
-----------
|
||||
|
|
|
@ -5,7 +5,7 @@ A MPU-9150 sensor must be connected to the I2C bus.
|
|||
|
||||
from pyb import I2C
|
||||
import os
|
||||
import pyb
|
||||
import time
|
||||
|
||||
machine = os.uname().machine
|
||||
if 'LaunchPad' in machine:
|
||||
|
@ -39,7 +39,7 @@ reg2_r = bytearray(2)
|
|||
# reset the sensor
|
||||
reg[0] |= 0x80
|
||||
print(1 == i2c.writeto_mem(addr, 107, reg))
|
||||
pyb.delay(100) # wait for the sensor to reset...
|
||||
time.sleep_ms(100) # wait for the sensor to reset...
|
||||
|
||||
print(1 == i2c.readfrom_mem_into(addr, 107, reg)) # read the power management register 1
|
||||
print(0x40 == reg[0])
|
||||
|
@ -79,7 +79,7 @@ print(0x40 == reg[0])
|
|||
# reset the sensor
|
||||
reg[0] |= 0x80
|
||||
print(1 == i2c.writeto_mem(addr, 107, reg))
|
||||
pyb.delay(100) # wait for the sensor to reset...
|
||||
time.sleep_ms(100) # wait for the sensor to reset...
|
||||
|
||||
# now read and write two register at a time
|
||||
print(2 == i2c.readfrom_mem_into(addr, 107, reg2))
|
||||
|
@ -97,7 +97,7 @@ print(reg2 == reg2_r)
|
|||
# reset the sensor
|
||||
reg[0] = 0x80
|
||||
print(1 == i2c.writeto_mem(addr, 107, reg))
|
||||
pyb.delay(100) # wait for the sensor to reset...
|
||||
time.sleep_ms(100) # wait for the sensor to reset...
|
||||
|
||||
# try some raw read and writes
|
||||
reg[0] = 117 # register address
|
||||
|
|
|
@ -0,0 +1,155 @@
|
|||
'''
|
||||
os module test for the CC3200 based boards
|
||||
'''
|
||||
|
||||
from pyb import SD
|
||||
import pyb
|
||||
import os
|
||||
|
||||
machine = os.uname().machine
|
||||
if 'LaunchPad' in machine:
|
||||
sd_pins = ('GP16', 'GP17', 'GP15')
|
||||
elif 'WiPy' in machine:
|
||||
sd_pins = ('GP10', 'GP11', 'GP15')
|
||||
else:
|
||||
raise Exception('Board not supported!')
|
||||
|
||||
sd = SD(pins=sd_pins)
|
||||
|
||||
os.mount(sd, '/sd')
|
||||
os.mkfs('/sd')
|
||||
os.chdir('/flash')
|
||||
print(os.listdir())
|
||||
|
||||
os.chdir('/sd')
|
||||
print(os.listdir())
|
||||
|
||||
# create a test directory in flash
|
||||
os.mkdir('/flash/test')
|
||||
os.chdir('/flash/test')
|
||||
print(os.getcwd())
|
||||
os.chdir('..')
|
||||
print(os.getcwd())
|
||||
os.chdir('test')
|
||||
print(os.getcwd())
|
||||
# create a new file
|
||||
f = open('test.txt', 'w')
|
||||
test_bytes = os.urandom(1024)
|
||||
n_w = f.write(test_bytes)
|
||||
print(n_w == len(test_bytes))
|
||||
f.close()
|
||||
f = open('test.txt', 'r')
|
||||
r = bytes(f.readall(), 'ascii')
|
||||
# check that we can write and read it correctly
|
||||
print(r == test_bytes)
|
||||
f.close()
|
||||
os.rename('test.txt', 'newtest.txt')
|
||||
print(os.listdir())
|
||||
os.rename('/flash/test', '/flash/newtest')
|
||||
print(os.listdir('/flash'))
|
||||
os.remove('newtest.txt')
|
||||
os.chdir('..')
|
||||
os.rmdir('newtest')
|
||||
|
||||
# create a test directory in the sd card
|
||||
os.mkdir('/sd/test')
|
||||
os.chdir('/sd/test')
|
||||
print(os.getcwd())
|
||||
os.chdir('..')
|
||||
print(os.getcwd())
|
||||
os.chdir('test')
|
||||
print(os.getcwd())
|
||||
# create a new file
|
||||
f = open('test.txt', 'w')
|
||||
test_bytes = os.urandom(1024)
|
||||
n_w = f.write(test_bytes)
|
||||
print(n_w == len(test_bytes))
|
||||
f.close()
|
||||
f = open('test.txt', 'r')
|
||||
r = bytes(f.readall(), 'ascii')
|
||||
# check that we can write and read it correctly
|
||||
print(r == test_bytes)
|
||||
f.close()
|
||||
|
||||
print('CC3200' in os.uname().machine)
|
||||
print('WiPy' == os.uname().sysname)
|
||||
|
||||
os.sync()
|
||||
os.stat('/flash')
|
||||
os.stat('/flash/sys')
|
||||
os.stat('/flash/boot.py')
|
||||
os.stat('/sd')
|
||||
os.stat('/')
|
||||
os.chdir('/sd/test')
|
||||
os.remove('test.txt')
|
||||
os.chdir('/sd')
|
||||
os.rmdir('test')
|
||||
os.listdir('/sd')
|
||||
print(os.listdir('/'))
|
||||
os.unmount('/sd')
|
||||
print(os.listdir('/'))
|
||||
os.mkfs(sd)
|
||||
os.mount(sd, '/sd')
|
||||
print(os.listdir('/'))
|
||||
os.chdir('/flash')
|
||||
|
||||
# next ones must raise
|
||||
sd.deinit()
|
||||
try:
|
||||
os.listdir('/sd')
|
||||
except:
|
||||
print('Exception')
|
||||
|
||||
#re-initialization must work
|
||||
sd.init()
|
||||
print(os.listdir('/sd'))
|
||||
|
||||
try:
|
||||
os.mount(sd, '/sd')
|
||||
except:
|
||||
print('Exception')
|
||||
|
||||
try:
|
||||
os.mount(sd, '/sd2')
|
||||
except:
|
||||
print('Exception')
|
||||
|
||||
os.unmount('/sd')
|
||||
try:
|
||||
os.listdir('/sd')
|
||||
except:
|
||||
print('Exception')
|
||||
|
||||
try:
|
||||
os.unmount('/flash')
|
||||
except:
|
||||
print('Exception')
|
||||
|
||||
try:
|
||||
os.mkfs('flash') # incorrect path format
|
||||
except:
|
||||
print('Exception')
|
||||
|
||||
try:
|
||||
os.remove('/flash/nofile.txt')
|
||||
except:
|
||||
print('Exception')
|
||||
|
||||
try:
|
||||
os.rename('/flash/nofile.txt', '/flash/nofile2.txt')
|
||||
except:
|
||||
print('Exception')
|
||||
|
||||
try:
|
||||
os.chdir('/flash/nodir')
|
||||
except:
|
||||
print('Exception')
|
||||
|
||||
try:
|
||||
os.listdir('/flash/nodir')
|
||||
except:
|
||||
print('Exception')
|
||||
|
||||
os.mount(sd, '/sd')
|
||||
print(os.listdir('/'))
|
||||
os.unmount('/sd')
|
|
@ -0,0 +1,30 @@
|
|||
['main.py', 'sys', 'lib', 'cert', 'boot.py']
|
||||
[]
|
||||
/flash/test
|
||||
/flash
|
||||
/flash/test
|
||||
True
|
||||
True
|
||||
['newtest.txt']
|
||||
['main.py', 'sys', 'lib', 'cert', 'boot.py', 'newtest']
|
||||
/sd/test
|
||||
/sd
|
||||
/sd/test
|
||||
True
|
||||
True
|
||||
True
|
||||
True
|
||||
['flash', 'sd']
|
||||
['flash']
|
||||
['flash', 'sd']
|
||||
[]
|
||||
Exception
|
||||
Exception
|
||||
Exception
|
||||
Exception
|
||||
Exception
|
||||
Exception
|
||||
Exception
|
||||
Exception
|
||||
Exception
|
||||
['flash', 'sd']
|
|
@ -0,0 +1,100 @@
|
|||
'''
|
||||
RTC test for the CC3200 based boards.
|
||||
'''
|
||||
|
||||
from pyb import RTC
|
||||
import os
|
||||
import time
|
||||
|
||||
machine = os.uname().machine
|
||||
if not 'LaunchPad' in machine and not 'WiPy' in machine:
|
||||
raise Exception('Board not supported!')
|
||||
|
||||
rtc = RTC()
|
||||
print(rtc)
|
||||
print(rtc.now()[:6])
|
||||
|
||||
rtc = RTC(datetime=(2015, 8, 29, 9, 0, 0, 0, None))
|
||||
print(rtc.now()[:6])
|
||||
|
||||
rtc.deinit()
|
||||
print(rtc.now()[:6])
|
||||
|
||||
rtc.init((2015, 8, 29, 9, 0, 0, 0, None))
|
||||
print(rtc.now()[:6])
|
||||
seconds = rtc.now()[5]
|
||||
time.sleep_ms(1000)
|
||||
print(rtc.now()[5] - seconds == 1)
|
||||
seconds = rtc.now()[5]
|
||||
time.sleep_ms(2000)
|
||||
print(rtc.now()[5] - seconds == 2)
|
||||
|
||||
# initialization with shorter tuples
|
||||
rtc.init((2015, 9, 19, 8, 0, 0, 0))
|
||||
print(rtc.now()[5])
|
||||
rtc.init((2015, 9, 19, 8, 0, 0))
|
||||
print(rtc.now()[5])
|
||||
rtc.init((2015, 9, 19, 8, 0))
|
||||
print(rtc.now()[5])
|
||||
rtc.init((2015, 9, 19, 8))
|
||||
print(rtc.now()[4])
|
||||
rtc.init((2015, 9, 19))
|
||||
print(rtc.now()[3])
|
||||
|
||||
def set_and_print(datetime):
|
||||
rtc.init(datetime)
|
||||
print(rtc.now()[:6])
|
||||
|
||||
# make sure that setting works correctly
|
||||
set_and_print((2000, 1, 1, 0, 0, 0, 0, None))
|
||||
set_and_print((2000, 1, 31, 0, 0, 0, 0, None))
|
||||
set_and_print((2000, 12, 31, 0, 0, 0, 0, None))
|
||||
set_and_print((2016, 12, 31, 0, 0, 0, 0, None))
|
||||
set_and_print((2016, 12, 31, 0, 0, 0, 0, None))
|
||||
set_and_print((2016, 12, 31, 1, 0, 0, 0, None))
|
||||
set_and_print((2016, 12, 31, 12, 0, 0, 0, None))
|
||||
set_and_print((2016, 12, 31, 13, 0, 0, 0, None))
|
||||
set_and_print((2016, 12, 31, 23, 0, 0, 0, None))
|
||||
set_and_print((2016, 12, 31, 23, 1, 0, 0, None))
|
||||
set_and_print((2016, 12, 31, 23, 59, 0, 50, None))
|
||||
set_and_print((2016, 12, 31, 23, 59, 1, 900, None))
|
||||
set_and_print((2016, 12, 31, 23, 59, 59, 100, None))
|
||||
set_and_print((2048, 12, 31, 23, 59, 59, 99999, None))
|
||||
|
||||
rtc.init((2015, 8, 29, 9, 0, 0, 0, None))
|
||||
rtc.alarm(0, 5000)
|
||||
rtc.alarm(time=2000)
|
||||
time.sleep_ms(1000)
|
||||
left = rtc.alarm_left()
|
||||
print(abs(left-1000) < 20)
|
||||
time.sleep_ms(1000)
|
||||
print(rtc.alarm_left() == 0)
|
||||
time.sleep_ms(100)
|
||||
print(rtc.alarm_left() == 0)
|
||||
|
||||
rtc.init((2015, 8, 29, 9, 0, 0, 0, None))
|
||||
rtc.alarm(time=(2015, 8, 29, 9, 0, 45))
|
||||
time.sleep_ms(1000)
|
||||
left = rtc.alarm_left()
|
||||
print(abs(left-44000) < 100)
|
||||
|
||||
# next ones must raise
|
||||
try:
|
||||
rtc.alarm(5000)
|
||||
except:
|
||||
print('Exception')
|
||||
|
||||
try:
|
||||
rtc.alarm(5000)
|
||||
except:
|
||||
print('Exception')
|
||||
|
||||
try:
|
||||
rtc = RTC(200000000)
|
||||
except:
|
||||
print('Exception')
|
||||
|
||||
try:
|
||||
rtc = RTC((2015, 8, 29, 9, 0, 0, 0, None))
|
||||
except:
|
||||
print('Exception')
|
|
@ -0,0 +1,34 @@
|
|||
<RTC>
|
||||
(2015, 1, 1, 0, 0, 0)
|
||||
(2015, 8, 29, 9, 0, 0)
|
||||
(2015, 1, 1, 0, 0, 0)
|
||||
(2015, 8, 29, 9, 0, 0)
|
||||
True
|
||||
True
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
(2000, 1, 1, 0, 0, 0)
|
||||
(2000, 1, 31, 0, 0, 0)
|
||||
(2000, 12, 31, 0, 0, 0)
|
||||
(2016, 12, 31, 0, 0, 0)
|
||||
(2016, 12, 31, 0, 0, 0)
|
||||
(2016, 12, 31, 1, 0, 0)
|
||||
(2016, 12, 31, 12, 0, 0)
|
||||
(2016, 12, 31, 13, 0, 0)
|
||||
(2016, 12, 31, 23, 0, 0)
|
||||
(2016, 12, 31, 23, 1, 0)
|
||||
(2016, 12, 31, 23, 59, 0)
|
||||
(2016, 12, 31, 23, 59, 1)
|
||||
(2016, 12, 31, 23, 59, 59)
|
||||
(2048, 12, 31, 23, 59, 59)
|
||||
True
|
||||
True
|
||||
True
|
||||
True
|
||||
Exception
|
||||
Exception
|
||||
Exception
|
||||
Exception
|
|
@ -0,0 +1,46 @@
|
|||
'''
|
||||
SD card test for the CC3200 based boards.
|
||||
'''
|
||||
|
||||
from pyb import SD
|
||||
import os
|
||||
|
||||
machine = os.uname().machine
|
||||
if 'LaunchPad' in machine:
|
||||
sd_pins = ('GP16', 'GP17', 'GP15')
|
||||
elif 'WiPy' in machine:
|
||||
sd_pins = ('GP10', 'GP11', 'GP15')
|
||||
else:
|
||||
raise Exception('Board not supported!')
|
||||
|
||||
sd = SD(pins=sd_pins)
|
||||
print(sd)
|
||||
sd.deinit()
|
||||
print(sd)
|
||||
sd.init(sd_pins)
|
||||
print(sd)
|
||||
|
||||
sd = SD(0, pins=sd_pins)
|
||||
sd = SD(id=0, pins=sd_pins)
|
||||
sd = SD(0, sd_pins)
|
||||
|
||||
# check for memory leaks
|
||||
for i in range(0, 1000):
|
||||
sd = sd = SD(0, pins=sd_pins)
|
||||
|
||||
# next ones should raise
|
||||
try:
|
||||
sd = SD(pins=())
|
||||
except Exception:
|
||||
print("Exception")
|
||||
|
||||
try:
|
||||
sd = SD(pins=('GP10', 'GP11', 'GP8'))
|
||||
except Exception:
|
||||
print("Exception")
|
||||
|
||||
try:
|
||||
sd = SD(pins=('GP10', 'GP11'))
|
||||
except Exception:
|
||||
print("Exception")
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
<SD>
|
||||
<SD>
|
||||
<SD>
|
||||
Exception
|
||||
Exception
|
||||
Exception
|
|
@ -0,0 +1,78 @@
|
|||
import time
|
||||
|
||||
DAYS_PER_MONTH = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
|
||||
|
||||
def is_leap(year):
|
||||
return (year % 4) == 0
|
||||
|
||||
def test():
|
||||
seconds = 0
|
||||
wday = 5 # Jan 1, 2000 was a Saturday
|
||||
for year in range(2000, 2049):
|
||||
print("Testing %d" % year)
|
||||
yday = 1
|
||||
for month in range(1, 13):
|
||||
if month == 2 and is_leap(year):
|
||||
DAYS_PER_MONTH[2] = 29
|
||||
else:
|
||||
DAYS_PER_MONTH[2] = 28
|
||||
for day in range(1, DAYS_PER_MONTH[month] + 1):
|
||||
secs = time.mktime((year, month, day, 0, 0, 0, 0, 0))
|
||||
if secs != seconds:
|
||||
print("mktime failed for %d-%02d-%02d got %d expected %d" % (year, month, day, secs, seconds))
|
||||
tuple = time.localtime(seconds)
|
||||
secs = time.mktime(tuple)
|
||||
if secs != seconds:
|
||||
print("localtime failed for %d-%02d-%02d got %d expected %d" % (year, month, day, secs, seconds))
|
||||
return
|
||||
seconds += 86400
|
||||
if yday != tuple[7]:
|
||||
print("locatime for %d-%02d-%02d got yday %d, expecting %d" % (year, month, day, tuple[7], yday))
|
||||
return
|
||||
if wday != tuple[6]:
|
||||
print("locatime for %d-%02d-%02d got wday %d, expecting %d" % (year, month, day, tuple[6], wday))
|
||||
return
|
||||
yday += 1
|
||||
wday = (wday + 1) % 7
|
||||
|
||||
def spot_test(seconds, expected_time):
|
||||
actual_time = time.localtime(seconds)
|
||||
for i in range(len(actual_time)):
|
||||
if actual_time[i] != expected_time[i]:
|
||||
print("time.localtime(", seconds, ") returned", actual_time, "expecting", expected_time)
|
||||
return
|
||||
print("time.localtime(", seconds, ") returned", actual_time, "(pass)")
|
||||
|
||||
|
||||
test()
|
||||
spot_test( 0, (2000, 1, 1, 0, 0, 0, 5, 1))
|
||||
spot_test( 1, (2000, 1, 1, 0, 0, 1, 5, 1))
|
||||
spot_test( 59, (2000, 1, 1, 0, 0, 59, 5, 1))
|
||||
spot_test( 60, (2000, 1, 1, 0, 1, 0, 5, 1))
|
||||
spot_test( 3599, (2000, 1, 1, 0, 59, 59, 5, 1))
|
||||
spot_test( 3600, (2000, 1, 1, 1, 0, 0, 5, 1))
|
||||
spot_test( -1, (1999, 12, 31, 23, 59, 59, 4, 365))
|
||||
spot_test( 447549467, (2014, 3, 7, 23, 17, 47, 4, 66))
|
||||
spot_test( -940984933, (1970, 3, 7, 23, 17, 47, 5, 66))
|
||||
spot_test(-1072915199, (1966, 1, 1, 0, 0, 1, 5, 1))
|
||||
spot_test(-1072915200, (1966, 1, 1, 0, 0, 0, 5, 1))
|
||||
spot_test(-1072915201, (1965, 12, 31, 23, 59, 59, 4, 365))
|
||||
|
||||
t1 = time.time()
|
||||
time.sleep(2)
|
||||
t2 = time.time()
|
||||
print(time.ticks_diff(t1, t2) == 2)
|
||||
|
||||
t1 = time.ticks_ms()
|
||||
time.sleep_ms(50)
|
||||
t2 = time.ticks_ms()
|
||||
print(time.ticks_diff(t1, t2) == 50)
|
||||
|
||||
t1 = time.ticks_us()
|
||||
time.sleep_us(1000)
|
||||
t2 = time.ticks_us()
|
||||
print(time.ticks_diff(t1, t2) < 2000)
|
||||
|
||||
t1 = time.ticks_cpu()
|
||||
t2 = time.ticks_cpu()
|
||||
print(time.ticks_diff(t1, t2) < 16384)
|
|
@ -0,0 +1,65 @@
|
|||
Testing 2000
|
||||
Testing 2001
|
||||
Testing 2002
|
||||
Testing 2003
|
||||
Testing 2004
|
||||
Testing 2005
|
||||
Testing 2006
|
||||
Testing 2007
|
||||
Testing 2008
|
||||
Testing 2009
|
||||
Testing 2010
|
||||
Testing 2011
|
||||
Testing 2012
|
||||
Testing 2013
|
||||
Testing 2014
|
||||
Testing 2015
|
||||
Testing 2016
|
||||
Testing 2017
|
||||
Testing 2018
|
||||
Testing 2019
|
||||
Testing 2020
|
||||
Testing 2021
|
||||
Testing 2022
|
||||
Testing 2023
|
||||
Testing 2024
|
||||
Testing 2025
|
||||
Testing 2026
|
||||
Testing 2027
|
||||
Testing 2028
|
||||
Testing 2029
|
||||
Testing 2030
|
||||
Testing 2031
|
||||
Testing 2032
|
||||
Testing 2033
|
||||
Testing 2034
|
||||
Testing 2035
|
||||
Testing 2036
|
||||
Testing 2037
|
||||
Testing 2038
|
||||
Testing 2039
|
||||
Testing 2040
|
||||
Testing 2041
|
||||
Testing 2042
|
||||
Testing 2043
|
||||
Testing 2044
|
||||
Testing 2045
|
||||
Testing 2046
|
||||
Testing 2047
|
||||
Testing 2048
|
||||
time.localtime( 0 ) returned (2000, 1, 1, 0, 0, 0, 5, 1) (pass)
|
||||
time.localtime( 1 ) returned (2000, 1, 1, 0, 0, 1, 5, 1) (pass)
|
||||
time.localtime( 59 ) returned (2000, 1, 1, 0, 0, 59, 5, 1) (pass)
|
||||
time.localtime( 60 ) returned (2000, 1, 1, 0, 1, 0, 5, 1) (pass)
|
||||
time.localtime( 3599 ) returned (2000, 1, 1, 0, 59, 59, 5, 1) (pass)
|
||||
time.localtime( 3600 ) returned (2000, 1, 1, 1, 0, 0, 5, 1) (pass)
|
||||
time.localtime( -1 ) returned (1999, 12, 31, 23, 59, 59, 4, 365) (pass)
|
||||
time.localtime( 447549467 ) returned (2014, 3, 7, 23, 17, 47, 4, 66) (pass)
|
||||
time.localtime( -940984933 ) returned (1970, 3, 7, 23, 17, 47, 5, 66) (pass)
|
||||
time.localtime( -1072915199 ) returned (1966, 1, 1, 0, 0, 1, 5, 1) (pass)
|
||||
time.localtime( -1072915200 ) returned (1966, 1, 1, 0, 0, 0, 5, 1) (pass)
|
||||
time.localtime( -1072915201 ) returned (1965, 12, 31, 23, 59, 59, 4, 365) (pass)
|
||||
True
|
||||
True
|
||||
True
|
||||
True
|
|
@ -7,6 +7,7 @@ from pyb import UART
|
|||
from pyb import Pin
|
||||
import os
|
||||
import pyb
|
||||
import time
|
||||
|
||||
machine = os.uname().machine
|
||||
if 'LaunchPad' in machine:
|
||||
|
@ -66,7 +67,7 @@ print(buf)
|
|||
# try initializing without the id
|
||||
uart0 = UART(baudrate=1000000, pins=uart_pins[0][0])
|
||||
uart0.write(b'1234567890')
|
||||
pyb.delay(2) # because of the fifo interrupt levels
|
||||
time.sleep_ms(2) # because of the fifo interrupt levels
|
||||
print(uart1.any() == 10)
|
||||
print(uart1.readline() == b'1234567890')
|
||||
print(uart1.any() == 0)
|
||||
|
|
|
@ -3,6 +3,7 @@ WDT test for the CC3200 based boards
|
|||
'''
|
||||
|
||||
from pyb import WDT
|
||||
import time
|
||||
|
||||
# test the invalid cases first
|
||||
try:
|
||||
|
@ -28,10 +29,10 @@ try:
|
|||
except Exception:
|
||||
print("Exception")
|
||||
|
||||
pyb.delay(500)
|
||||
time.sleep_ms(500)
|
||||
wdt.feed()
|
||||
print(wdt)
|
||||
pyb.delay(900)
|
||||
time.sleep_ms(900)
|
||||
wdt.feed()
|
||||
print(wdt)
|
||||
pyb.delay(950)
|
||||
time.sleep_ms(950)
|
||||
|
|
Loading…
Reference in New Issue