Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: DM_HttpServer DM_USBHost
Dependents: lpc4088_displaymodule_emwin lpc4088_displaymodule_demo_sphere sampleGUI sampleEmptyGUI ... more
Fork of DMSupport by
Revision 42:bbfe299d4a0c, committed 2019-11-04
- Comitter:
- embeddedartists
- Date:
- Mon Nov 04 14:32:50 2019 +0000
- Parent:
- 41:e06e764ff4fd
- Commit message:
- More updates related to mbed OS 5
Changed in this revision
--- a/Bios/BiosLoader.cpp Wed Oct 23 06:59:29 2019 +0000
+++ b/Bios/BiosLoader.cpp Mon Nov 04 14:32:50 2019 +0000
@@ -222,12 +222,7 @@
DMBoard::BoardError err = DMBoard::Ok;
if (!_initialized) {
do {
-
- // With mbed OS 5 the MPU has been enabled and by default execution from
- // RAM is not allowed. Calling this function to allow execution since
- // the BIOS code will be executed from RAM.
- mbed_mpu_manager_lock_ram_execution();
-
+
// Get the display bios from the DMBoard. DMBoard will have verified it
// and will keep it in RAM so there is no need to copy it.
uint8_t* p = NULL;
--- a/DMBoard.cpp Wed Oct 23 06:59:29 2019 +0000
+++ b/DMBoard.cpp Mon Nov 04 14:32:50 2019 +0000
@@ -26,7 +26,9 @@
#if defined(DM_BOARD_ENABLE_MEASSURING_PINS)
#include "meas.h"
-#endif
+#endif
+
+#include "dm_rtc.h"
/******************************************************************************
* Configuration Compatibility Control
@@ -74,7 +76,8 @@
DMBoard::DMBoard() :
_initialized(false),
#if defined(DM_BOARD_USE_MCI_FS)
- _mcifs("mci", P4_16),
+ _mcifs(P4_16),
+ _mciFatFs("mci"),
#endif
#if defined(DM_BOARD_USE_QSPI_FS)
_qspifs("qspi"),
@@ -101,6 +104,17 @@
BoardError err = Ok;
if (!_initialized) {
do {
+
+ /*
+ * By default mbed OS 5 comes with the MPU enabled and prevents execution
+ * from RAM and writes to ROM. We need to be able to execute from EAM
+ * (e.g. the BIOS functionality) and also write to ROM area (we are e.g.
+ * using the EEPROM peripheral in the LPC4088 which has an address space
+ * within the ROM area).
+ */
+ mbed_mpu_manager_lock_ram_execution();
+ mbed_mpu_manager_lock_rom_write();
+
// Turn off the buzzer
_buzzer.period_ms(1);
_buzzer = 0;
@@ -129,6 +143,10 @@
freopen("/null", "w", stdout);
#endif
+#if defined(DM_BOARD_USE_MCI_FS)
+ _mciFatFs.mount(&_mcifs);
+#endif
+
#if defined(DM_BOARD_USE_QSPI) || defined(DM_BOARD_USE_QSPI_FS)
if (SPIFI::instance().init() != SPIFI::Ok) {
err = SpifiError;
@@ -156,6 +174,12 @@
break;
}
#endif
+ /*
+ * With mbed OS 5 the rtc driver in target/hal has been disabled
+ * Adding an external rtc driver instead.
+ */
+ attach_rtc(&dm_read_rtc, &dm_write_rtc, &dm_init_rtc, &dm_isenabled_rtc);
+
_initialized = true;
} while(0);
}
--- a/DMBoard.h Wed Oct 23 06:59:29 2019 +0000
+++ b/DMBoard.h Mon Nov 04 14:32:50 2019 +0000
@@ -36,6 +36,18 @@
#include "Registry.h"
#endif
+#if defined(DM_BOARD_USE_USB_HOST) && defined(DM_BOARD_USE_ETHERNET)
+/*
+ * It is not possible to use USB Host and Ethernet at the same time due to a
+ * conflict in memory areas.
+ *
+ * In OS 5 memory area AHBSRAM0 is used by the EMAC driver (lpc17_emac.cpp) and
+ * AHBSRAM1 is used by LWIP as heap (lwip_sys_arch.c). The USB host
+ * implementation is using AHBSRAM1 (USBHALHost.cpp).
+ */
+#error "Cannot have both USB Host and Ethernet enabled at the same time. See DMBoard.h"
+#endif
+
/**
* Example of using the Board class:
@@ -181,6 +193,7 @@
#if defined(DM_BOARD_USE_MCI_FS)
MCIFileSystem _mcifs;
+ FATFileSystem _mciFatFs;
#endif
#if defined(DM_BOARD_USE_QSPI_FS)
QSPIFileSystem _qspifs;
--- a/DM_HttpServer.lib Wed Oct 23 06:59:29 2019 +0000 +++ b/DM_HttpServer.lib Mon Nov 04 14:32:50 2019 +0000 @@ -1,1 +1,1 @@ -http://developer.mbed.org/teams/Embedded-Artists/code/DM_HttpServer/#c1c8276af541 +http://developer.mbed.org/teams/Embedded-Artists/code/DM_HttpServer/#9dcff8cf906a
--- a/DM_USBHost.lib Wed Oct 23 06:59:29 2019 +0000 +++ b/DM_USBHost.lib Mon Nov 04 14:32:50 2019 +0000 @@ -1,1 +1,1 @@ -http://developer.mbed.org/teams/Embedded-Artists/code/DM_USBHost/#f2d129436056 +http://developer.mbed.org/teams/Embedded-Artists/code/DM_USBHost/#819bbf04163b
--- a/FileSystems/MCIFileSystem.cpp Wed Oct 23 06:59:29 2019 +0000
+++ b/FileSystems/MCIFileSystem.cpp Mon Nov 04 14:32:50 2019 +0000
@@ -581,12 +581,11 @@
* Public Functions
*****************************************************************************/
-MCIFileSystem::MCIFileSystem(const char* name, PinName cd) :
- FATFileSystem(name)
+MCIFileSystem::MCIFileSystem(PinName cd) :
+ _init_ref_count(0), _is_initialized(false)
{
pUglyForIRQ = this;
- _Stat = STA_NOINIT;
memset(&_sdCardInfo, 0, sizeof(SDMMC_CARD_T));
_eventReceived = false;
_eventSuccess = false;
@@ -670,90 +669,131 @@
_eventDmaChannel = GPDMA::instance().acquireChannel(mydmairq);
}
-int MCIFileSystem::disk_initialize() {
+int MCIFileSystem::init() {
+ uint32_t val = core_util_atomic_incr_u32(&_init_ref_count, 1);
+
+ if (val != 1) {
+ return BD_ERROR_OK;
+ }
- debug_if(MCI_DBG, "mcifs:disk_initialize(), _Stat = %#x\n", _Stat);
+ debug_if(MCI_DBG, "mcifs:disk_initialize()\n");
if (!cardInserted()) {
- /* No card in the socket */
- _Stat = STA_NODISK | STA_NOINIT;
+ debug("No card detected\r\n");
+ return BD_ERROR_DEVICE_ERROR;
}
- if (_Stat != STA_NOINIT) {
- return _Stat; /* card is already enumerated */
- }
-
- //rtc_init();
-
/* Initialize the Card Data Strucutre */
memset(&_sdCardInfo, 0, sizeof(SDMMC_CARD_T));
- /* Reset */
- _Stat = STA_NOINIT;
-
/* Enumerate the card once detected. Note this function may block for a little while. */
int ret = mci_Acquire();
if (ret != 1) {
debug("Card Acquire failed... got %d, but expected 1\r\n", ret);
- return 1;//Stat;
+ return BD_ERROR_DEVICE_ERROR;
}
- _Stat &= ~STA_NOINIT;
- return _Stat;
+ _is_initialized = true;
+ return BD_ERROR_OK;
}
-int MCIFileSystem::disk_write(const uint8_t *buffer, uint64_t block_number, uint8_t count) {
- debug_if(MCI_DBG, "mcifs:disk_write(%#x, %llu, %u), _Stat = %#x\n", (uint32_t)buffer, block_number, count, _Stat);
- if (_Stat & STA_NOINIT) {
- // not ready
- return 1;
- }
- if (mci_WriteBlocks((void*)buffer, block_number, count) == SDC_RET_OK) {
- return 0;
+int MCIFileSystem::deinit() {
+
+ if (!_is_initialized) {
+ return BD_ERROR_OK;
+ }
+
+ uint32_t val = core_util_atomic_decr_u32(&_init_ref_count, 1);
+
+ if (val) {
+ return BD_ERROR_OK;
}
- return 1;
+ _is_initialized = false;
+ return BD_ERROR_OK;
}
-int MCIFileSystem::disk_read(uint8_t *buffer, uint64_t block_number, uint8_t count) {
- debug_if(MCI_DBG, "mcifs:disk_read(%#x, %llu, %u), _Stat = %#x\n", (uint32_t)buffer, block_number, count, _Stat);
- if (_Stat & STA_NOINIT) {
- // not ready
- return _Stat;
+int MCIFileSystem::program(const void *buffer, bd_addr_t addr, bd_size_t size) {
+ ReturnCode status;
+
+ debug_if(MCI_DBG, "mcifs:disk_write(%#x, %llu, %llu)\n", (uint32_t)buffer, addr, size);
+
+ if (!_is_initialized) {
+ return BD_ERROR_DEVICE_ERROR;
}
- if (mci_ReadBlocks(buffer, block_number, count) == SDC_RET_OK) {
- return 0;
+
+ /* need to convert from number of bytes to blocks */
+ addr = addr / MMC_SECTOR_SIZE;
+ size = size / MMC_SECTOR_SIZE;
+
+ status = mci_WriteBlocks((void*)buffer, addr, size);
+ if (status != SDC_RET_OK) {
+ return status;
}
- return 1;
+ return BD_ERROR_OK;
}
-int MCIFileSystem::disk_status()
-{
- debug_if(MCI_DBG, "mcifs:disk_status(), _Stat = %#x\n", _Stat);
- return _Stat;
+int MCIFileSystem::read(void *buffer, bd_addr_t addr, bd_size_t size) {
+ ReturnCode status;
+ debug_if(MCI_DBG, "mcifs:disk_read(%#x, %llu, %llu)\n", (uint32_t)buffer, addr, size);
+
+ if (!_is_initialized) {
+ return BD_ERROR_DEVICE_ERROR;
+ }
+
+ /* need to convert from number of bytes to blocks */
+ addr = addr / MMC_SECTOR_SIZE;
+ size = size / MMC_SECTOR_SIZE;
+
+ status = mci_ReadBlocks(buffer, addr, size);
+ if (status != SDC_RET_OK) {
+ return status;
+ }
+
+ return BD_ERROR_OK;
}
-int MCIFileSystem::disk_sync()
+int MCIFileSystem::sync()
{
- debug_if(MCI_DBG, "mcifs:disk_sync(), _Stat = %#x\n", _Stat);
- uint32_t end = us_ticker_read() + 50*1000; // 50ms
- while (us_ticker_read() < end)
- {
- if (mci_GetCardStatus() & R1_READY_FOR_DATA)
+ debug_if(MCI_DBG, "mcifs:disk_sync()\n");
+
+ if (!_is_initialized) {
+ return BD_ERROR_OK;
+ }
+
+ uint32_t end = us_ticker_read() + 50*1000; // 50ms
+ while (us_ticker_read() < end)
{
- // card is ready
- return 0;
+ if (mci_GetCardStatus() & R1_READY_FOR_DATA)
+ {
+ // card is ready
+ return BD_ERROR_OK;
+ }
}
- }
- // timeout while waiting for card to get ready
- return 1;
+
+ // timeout while waiting for card to get ready
+ return SDC_RET_TIMEOUT;
}
-uint64_t MCIFileSystem::disk_sectors()
+bd_size_t MCIFileSystem::get_read_size() const
+{
+ return MMC_SECTOR_SIZE;
+}
+
+bd_size_t MCIFileSystem::get_program_size() const
{
- debug_if(MCI_DBG, "mcifs:disk_sectors(), _Stat = %#x, returning %u\n", _Stat, _sdCardInfo.blocknr);
- return _sdCardInfo.blocknr;
+ return MMC_SECTOR_SIZE;
+}
+
+bd_size_t MCIFileSystem::size() const
+{
+ return _sdCardInfo.block_len * MMC_SECTOR_SIZE;
+}
+
+const char *MCIFileSystem::get_type() const
+{
+ return "MCI";
}
void MCIFileSystem::mci_MCIIRQHandler()
@@ -1386,7 +1426,6 @@
/* compute block length based on CSD response */
_sdCardInfo.block_len = 1 << mci_GetBits(80, 83, _sdCardInfo.csd);
-
if ((_sdCardInfo.card_type & CARD_TYPE_HC) && (_sdCardInfo.card_type & CARD_TYPE_SD)) {
/* See section 5.3.3 CSD Register (CSD Version 2.0) of SD2.0 spec an explanation for the calculation of these values */
CSize = mci_GetBits(48, 63, (uint32_t *) _sdCardInfo.csd) + 1;
@@ -1778,6 +1817,7 @@
// If the driver is having problems reading the card, adding a delay here
// might help.
//wait(0.01);
+ ThisThread::sleep_for(10);
}
if (_eventReceived && _eventSuccess) {
--- a/FileSystems/MCIFileSystem.h Wed Oct 23 06:59:29 2019 +0000
+++ b/FileSystems/MCIFileSystem.h Mon Nov 04 14:32:50 2019 +0000
@@ -48,24 +48,27 @@
* }
* @endcode
*/
-class MCIFileSystem : public FATFileSystem {
+class MCIFileSystem : public BlockDevice {
public:
/** Create the File System for accessing an SD/MMC Card using MCI
*
- * @param name The name used to access the virtual filesystem
* @param cd The pin connected to the CardDetect line
*/
- MCIFileSystem(const char* name, PinName cd = P4_16);
+ MCIFileSystem(PinName cd = P4_16);
virtual ~MCIFileSystem();
- virtual int disk_initialize();
- virtual int disk_status();
- virtual int disk_read(uint8_t * buffer, uint64_t block_number, uint8_t count);
- virtual int disk_write(const uint8_t * buffer, uint64_t block_number, uint8_t count);
- virtual int disk_sync();
- virtual uint64_t disk_sectors();
+ virtual int init();
+ virtual int deinit();
+
+ virtual int sync();
+ virtual int read(void * buffer, bd_addr_t addr, bd_size_t size);
+ virtual int program(const void * buffer, bd_addr_t addr, bd_size_t size);
+ virtual bd_size_t get_read_size() const;
+ virtual bd_size_t get_program_size() const;
+ virtual bd_size_t size() const;
+ virtual const char *get_type() const;
void mci_MCIIRQHandler();
void mci_DMAIRQHandler();
@@ -130,20 +133,20 @@
uint16_t rca; /*!< Relative address assigned to card */
uint32_t speed; /*!< Speed */
uint32_t block_len; /*!< Card sector size */
- uint32_t device_size; /*!< Device Size */
+ bd_size_t device_size; /*!< Device Size */
uint32_t blocknr; /*!< Block Number */
uint32_t clk_rate; /*!< Clock rate */
} SDMMC_CARD_T;
typedef enum {
SDC_RET_OK = 0,
- SDC_RET_CMD_FAILED = -1,
- SDC_RET_BAD_PARAMETERS = -2,
- SDC_RET_BUS_NOT_IDLE = -3,
- SDC_RET_TIMEOUT = -4,
- SDC_RET_ERR_STATE = -5,
- SDC_RET_NOT_READY = -6,
- SDC_RET_FAILED = -7,
+ SDC_RET_CMD_FAILED = -5001,
+ SDC_RET_BAD_PARAMETERS = -5002,
+ SDC_RET_BUS_NOT_IDLE = -5003,
+ SDC_RET_TIMEOUT = -5004,
+ SDC_RET_ERR_STATE = -5005,
+ SDC_RET_NOT_READY = -5006,
+ SDC_RET_FAILED = -5007,
} ReturnCode;
void initMCI();
@@ -192,8 +195,6 @@
ReturnCode _readBlocks(uint32_t card_type, uint32_t startBlock, uint32_t blockNum) const;
ReturnCode _writeBlocks(uint32_t card_type, uint32_t startBlock, uint32_t blockNum) const;
-
- uint32_t _Stat;
SDMMC_CARD_T _sdCardInfo;
DigitalIn* _cardDetect;
@@ -201,6 +202,9 @@
GPDMA::DMAChannels _eventDmaChannel; /*!< DMA Channel used for transfer data */
volatile bool _eventReceived;
volatile bool _eventSuccess;
+
+ uint32_t _init_ref_count;
+ bool _is_initialized;
};
#endif
--- a/FileSystems/QSPIFileSystem.cpp Wed Oct 23 06:59:29 2019 +0000
+++ b/FileSystems/QSPIFileSystem.cpp Mon Nov 04 14:32:50 2019 +0000
@@ -1238,8 +1238,9 @@
// file is not in any sub folder so it is truly in the wanted dir
nextTocIdx = possible + 1;
strcpy(cur_entry.d_name, filename);
- //return &cur_entry;
- *ent = cur_entry;
+
+ memcpy(ent->d_name, cur_entry.d_name, sizeof(cur_entry.d_name));
+ return 1;
}
// this is a file in a subfolder and should not be reported,
@@ -1262,13 +1263,14 @@
char* pSlash = strchr(cur_entry.d_name, '/');
// pSlash++; //with ++ the returned dir name is "mydir/" without ++ "mydir" is returned
*pSlash = '\0';
- //return &cur_entry;
- *ent = cur_entry;
+
+ memcpy(ent->d_name, cur_entry.d_name, sizeof(cur_entry.d_name));
+ return 1;
}
}
}
}
- return NULL;
+ return 0;
}
void QSPIDirHandle::rewind() {
@@ -1293,7 +1295,7 @@
// ReadWrite - dictates where to read from, writes ignore it but
// sets the position to the end afterwards
//
-FileHandle *QSPIFileSystem::open(const char *filename, int flags)
+int QSPIFileSystem::open(FileHandle **file, const char *filename, int flags)
{
fresult res = qspifs_init();
// if (res == FS_OK) {
@@ -1308,6 +1310,7 @@
// res = FS_ERR_INVALID_PARAM;
// }
// }
+
if (res == FS_OK) {
if (strlen(filename) > HEADER_FNAME_STRLEN) {
// Filename is too long
@@ -1331,11 +1334,14 @@
res = qspifs_saveTOC();
}
if (res == FS_OK) {
- return new QSPIFileHandle(&fh, flags);
+ *file = new QSPIFileHandle(&fh, flags);
}
}
- debug_if(QSPI_DBG, "QSPIFS: Failed to open: %d\n", res);
- return NULL;
+ if (res != FS_OK) {
+ debug_if(QSPI_DBG, "QSPIFS: Failed to open: %d\n", res);
+ return -res;
+ }
+ return 0;
}
int QSPIFileSystem::remove(const char *filename)
@@ -1399,27 +1405,29 @@
return 0;
}
-DirHandle *QSPIFileSystem::opendir(const char *name)
+int QSPIFileSystem::open(DirHandle **dir, const char *path)
{
if (isformatted()) {
- if (*name == '\0') {
- // opendir("/qspi/") will result in a call to this function with name=""
- return QSPIDirHandle::openDir(name);
+ if (*path == '\0') {
+ // opendir("/qspi/") will result in a call to this function with path=""
+ *dir = QSPIDirHandle::openDir(path);
+ return 0;
}
- FileHandle* fh = open(name, O_RDONLY);
- if (fh != NULL) {
+ FileHandle* fh;
+ if (open(&fh, path, O_RDONLY) == 0) {
// Attempting to open a file as a dir
delete fh;
- return NULL;
+ return -1;
}
-// printf("opendir: name '%s'\n", name);
- if (strlen(name) <= HEADER_DNAME_MAXLEN) {
- return QSPIDirHandle::openDir(name);
+// printf("opendir: path '%s'\n", path);
+ if (strlen(path) <= HEADER_DNAME_MAXLEN) {
+ *dir = QSPIDirHandle::openDir(path);
+ return 0;
}
}
- return NULL;
+ return -1;
}
int QSPIFileSystem::mkdir(const char *name, mode_t mode)
--- a/FileSystems/QSPIFileSystem.h Wed Oct 23 06:59:29 2019 +0000
+++ b/FileSystems/QSPIFileSystem.h Mon Nov 04 14:32:50 2019 +0000
@@ -118,10 +118,12 @@
*/
QSPIFileSystem(const char* name);
- virtual FileHandle *open(const char *filename, int flags);
+ virtual int open(FileHandle **file, const char *filename, int flags);
+ virtual int open(DirHandle **dir, const char *path);
+
virtual int remove(const char *filename);
virtual int rename(const char *oldname, const char *newname);
- virtual DirHandle *opendir(const char *name);
+
virtual int mkdir(const char *name, mode_t mode);
/** Creates a new file system on the QSPI flash.
--- a/Memory/InternalEEPROM.cpp Wed Oct 23 06:59:29 2019 +0000
+++ b/Memory/InternalEEPROM.cpp Mon Nov 04 14:32:50 2019 +0000
@@ -123,11 +123,7 @@
void InternalEEPROM::init()
{
if (!_initialized) {
-
- // The EEPROM peripheral is in ROM address space. Must allow
- // writes to this address space.
- mbed_mpu_manager_lock_rom_write();
-
+
// Bring EEPROM device out of power down mode
powerUp();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dm_rtc.cpp Mon Nov 04 14:32:50 2019 +0000
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2019 Embedded Artists AB
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+/******************************************************************************
+ * Includes
+ *****************************************************************************/
+
+#include "mbed.h"
+#include "dm_rtc.h"
+#include "mbed_mktime.h"
+
+/******************************************************************************
+ * Defines and typedefs
+ *****************************************************************************/
+
+/******************************************************************************
+ * External global variables
+ *****************************************************************************/
+
+/******************************************************************************
+ * Local variables
+ *****************************************************************************/
+
+/******************************************************************************
+ * Local Functions
+ *****************************************************************************/
+
+
+/******************************************************************************
+ * Public Functions
+ *****************************************************************************/
+
+void dm_init_rtc(void)
+{
+ LPC_SC->PCONP |= 0x200; // Ensure power is on
+ LPC_RTC->CCR = 0x00;
+
+ LPC_RTC->CCR |= 1 << 0; // Ensure the RTC is enabled
+}
+
+time_t dm_read_rtc(void)
+{
+ // Setup a tm structure based on the RTC
+ struct tm timeinfo;
+ timeinfo.tm_sec = LPC_RTC->SEC;
+ timeinfo.tm_min = LPC_RTC->MIN;
+ timeinfo.tm_hour = LPC_RTC->HOUR;
+ timeinfo.tm_mday = LPC_RTC->DOM;
+ timeinfo.tm_mon = LPC_RTC->MONTH - 1;
+ timeinfo.tm_year = LPC_RTC->YEAR - 1900;
+
+ // Convert to timestamp
+ time_t t;
+ if (_rtc_maketime(&timeinfo, &t, RTC_4_YEAR_LEAP_YEAR_SUPPORT) == false) {
+ return 0;
+ }
+
+ return t;
+}
+
+void dm_write_rtc(time_t t)
+{
+ // Convert the time in to a tm
+ struct tm timeinfo;
+ if (_rtc_localtime(t, &timeinfo, RTC_4_YEAR_LEAP_YEAR_SUPPORT) == false) {
+ return;
+ }
+
+ // Pause clock, and clear counter register (clears us count)
+ LPC_RTC->CCR |= 2;
+
+ // Set the RTC
+ LPC_RTC->SEC = timeinfo.tm_sec;
+ LPC_RTC->MIN = timeinfo.tm_min;
+ LPC_RTC->HOUR = timeinfo.tm_hour;
+ LPC_RTC->DOM = timeinfo.tm_mday;
+ LPC_RTC->MONTH = timeinfo.tm_mon + 1;
+ LPC_RTC->YEAR = timeinfo.tm_year + 1900;
+
+ // Restart clock
+ LPC_RTC->CCR &= ~((uint32_t)2);
+}
+
+int dm_isenabled_rtc(void)
+{
+ return(((LPC_RTC->CCR) & 0x01) != 0);
+}
+
+
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dm_rtc.h Mon Nov 04 14:32:50 2019 +0000 @@ -0,0 +1,25 @@ +/* + * Copyright 2014 Embedded Artists AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DM_RTC_H +#define DM_RTC_H + +void dm_init_rtc(void); +time_t dm_read_rtc(void); +void dm_write_rtc(time_t t); +int dm_isenabled_rtc(void); + +#endif \ No newline at end of file
