aboutsummaryrefslogtreecommitdiffstats
path: root/os/various
diff options
context:
space:
mode:
Diffstat (limited to 'os/various')
-rw-r--r--os/various/chprintf.c56
-rw-r--r--os/various/chprintf.h7
-rw-r--r--[-rwxr-xr-x]os/various/chrtclib.c0
-rw-r--r--[-rwxr-xr-x]os/various/chrtclib.h0
-rwxr-xr-xos/various/diskio.c244
-rw-r--r--os/various/evtimer.h8
-rw-r--r--os/various/mail.c96
-rw-r--r--os/various/mail.h59
8 files changed, 465 insertions, 5 deletions
diff --git a/os/various/chprintf.c b/os/various/chprintf.c
index 3936226c1..1b2c3329c 100644
--- a/os/various/chprintf.c
+++ b/os/various/chprintf.c
@@ -17,25 +17,42 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+/*
+ Concepts and parts of this file have been contributed by Fabio Utzig.
+ */
#include <stdarg.h>
#include "ch.h"
+#include "chprintf.h"
#define MAX_FILLER 11
+#define FLOAT_PRECISION 100000
-static char *ltoa(char *p, long num, unsigned radix) {
+static char *long_to_string_with_divisor(char *p,
+ long num,
+ unsigned radix,
+ long divisor) {
int i;
char *q;
+ long l, ll;
+
+ l = num;
+ if (divisor == 0) {
+ ll = num;
+ } else {
+ ll = divisor;
+ }
q = p + MAX_FILLER;
do {
- i = (int)(num % radix);
+ i = (int)(l % radix);
i += '0';
if (i > '9')
i += 'A' - '0' - 10;
*--q = i;
- } while ((num /= radix) != 0);
+ l /= radix;
+ } while ((ll /= radix) != 0);
i = (int)(p + MAX_FILLER - q);
do
@@ -45,6 +62,24 @@ static char *ltoa(char *p, long num, unsigned radix) {
return p;
}
+static char *ltoa(char *p, long num, unsigned radix) {
+
+ return long_to_string_with_divisor(p, num, radix, 0);
+}
+
+#if CHPRINTF_USE_FLOAT
+static char *ftoa(char *p, double num) {
+ long l;
+ unsigned long precision = FLOAT_PRECISION;
+
+ l = num;
+ p = long_to_string_with_divisor(p, l, 10, 0);
+ *p++ = '.';
+ l = (num - l) * precision;
+ return long_to_string_with_divisor(p, l, 10, precision / 10);
+}
+#endif
+
/**
* @brief System formatted output function.
* @details This function implements a minimal @p printf() like functionality
@@ -62,8 +97,6 @@ static char *ltoa(char *p, long num, unsigned radix) {
* - <b>c</b> character.
* - <b>s</b> string.
* .
- * @note Floating point types are not implemented, this function is meant
- * as a system utility and not a full implementation.
*
* @param[in] chp pointer to a @p BaseChannel implementing object
* @param[in] fmt formatting string
@@ -75,6 +108,9 @@ void chprintf(BaseChannel *chp, const char *fmt, ...) {
int i, precision, width;
bool_t is_long, left_align;
long l;
+#if CHPRINTF_USE_FLOAT
+ float f;
+#endif
va_start(ap, fmt);
while (TRUE) {
@@ -160,6 +196,16 @@ void chprintf(BaseChannel *chp, const char *fmt, ...) {
}
p = ltoa(p, l, 10);
break;
+#if CHPRINTF_USE_FLOAT
+ case 'f':
+ f = (float) va_arg(ap, double);
+ if (f < 0) {
+ *p++ = '-';
+ f = -f;
+ }
+ p = ftoa(p, f);
+ break;
+#endif
case 'X':
case 'x':
c = 16;
diff --git a/os/various/chprintf.h b/os/various/chprintf.h
index 929da639e..866dfa067 100644
--- a/os/various/chprintf.h
+++ b/os/various/chprintf.h
@@ -29,6 +29,13 @@
#ifndef _CHPRINTF_H_
#define _CHPRINTF_H_
+/**
+ * @brief Float type support.
+ */
+#if !defined(CHPRINTF_USE_FLOAT) || defined(__DOXYGEN__)
+#define CHPRINTF_USE_FLOAT FALSE
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/os/various/chrtclib.c b/os/various/chrtclib.c
index 38f5a3627..38f5a3627 100755..100644
--- a/os/various/chrtclib.c
+++ b/os/various/chrtclib.c
diff --git a/os/various/chrtclib.h b/os/various/chrtclib.h
index 7831be83d..7831be83d 100755..100644
--- a/os/various/chrtclib.h
+++ b/os/various/chrtclib.h
diff --git a/os/various/diskio.c b/os/various/diskio.c
new file mode 100755
index 000000000..07d44db49
--- /dev/null
+++ b/os/various/diskio.c
@@ -0,0 +1,244 @@
+/*-----------------------------------------------------------------------*/
+/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2007 */
+/*-----------------------------------------------------------------------*/
+/* This is a stub disk I/O module that acts as front end of the existing */
+/* disk I/O modules and attach it to FatFs module with common interface. */
+/*-----------------------------------------------------------------------*/
+
+#include "ch.h"
+#include "hal.h"
+
+#include "diskio.h"
+
+#if HAL_USE_MMC_SPI && HAL_USE_SDC
+#error "cannot specify both MMC_SPI and SDC drivers"
+#endif
+
+#if HAL_USE_MMC_SPI
+extern MMCDriver MMCD1;
+#elif HAL_USE_SDC
+extern SDCDriver SDCD1;
+#else
+#error "MMC_SPI or SDC driver must be specified"
+#endif
+
+#if HAL_USE_RTC
+#include "chrtclib.h"
+extern RTCDriver RTCD1;
+#endif
+
+/*-----------------------------------------------------------------------*/
+/* Correspondence between physical drive number and physical drive. */
+
+#define MMC 0
+#define SDC 0
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Inidialize a Drive */
+
+DSTATUS disk_initialize (
+ BYTE drv /* Physical drive nmuber (0..) */
+)
+{
+ DSTATUS stat;
+
+ switch (drv) {
+#if HAL_USE_MMC_SPI
+ case MMC:
+ stat = 0;
+ /* It is initialized externally, just reads the status.*/
+ if (mmcGetDriverState(&MMCD1) != MMC_READY)
+ stat |= STA_NOINIT;
+ if (mmcIsWriteProtected(&MMCD1))
+ stat |= STA_PROTECT;
+ return stat;
+#else
+ case SDC:
+ stat = 0;
+ /* It is initialized externally, just reads the status.*/
+ if (sdcGetDriverState(&SDCD1) != SDC_ACTIVE)
+ stat |= STA_NOINIT;
+ if (sdcIsWriteProtected(&SDCD1))
+ stat |= STA_PROTECT;
+ return stat;
+#endif
+ }
+ return STA_NODISK;
+}
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Return Disk Status */
+
+DSTATUS disk_status (
+ BYTE drv /* Physical drive nmuber (0..) */
+)
+{
+ DSTATUS stat;
+
+ switch (drv) {
+#if HAL_USE_MMC_SPI
+ case MMC:
+ stat = 0;
+ /* It is initialized externally, just reads the status.*/
+ if (mmcGetDriverState(&MMCD1) != MMC_READY)
+ stat |= STA_NOINIT;
+ if (mmcIsWriteProtected(&MMCD1))
+ stat |= STA_PROTECT;
+ return stat;
+#else
+ case SDC:
+ stat = 0;
+ /* It is initialized externally, just reads the status.*/
+ if (sdcGetDriverState(&SDCD1) != SDC_ACTIVE)
+ stat |= STA_NOINIT;
+ if (sdcIsWriteProtected(&SDCD1))
+ stat |= STA_PROTECT;
+ return stat;
+#endif
+ }
+ return STA_NODISK;
+}
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Read Sector(s) */
+
+DRESULT disk_read (
+ BYTE drv, /* Physical drive nmuber (0..) */
+ BYTE *buff, /* Data buffer to store read data */
+ DWORD sector, /* Sector address (LBA) */
+ BYTE count /* Number of sectors to read (1..255) */
+)
+{
+ switch (drv) {
+#if HAL_USE_MMC_SPI
+ case MMC:
+ if (mmcGetDriverState(&MMCD1) != MMC_READY)
+ return RES_NOTRDY;
+ if (mmcStartSequentialRead(&MMCD1, sector))
+ return RES_ERROR;
+ while (count > 0) {
+ if (mmcSequentialRead(&MMCD1, buff))
+ return RES_ERROR;
+ buff += MMC_SECTOR_SIZE;
+ count--;
+ }
+ if (mmcStopSequentialRead(&MMCD1))
+ return RES_ERROR;
+ return RES_OK;
+#else
+ case SDC:
+ if (sdcGetDriverState(&SDCD1) != SDC_ACTIVE)
+ return RES_NOTRDY;
+ if (sdcRead(&SDCD1, sector, buff, count))
+ return RES_ERROR;
+ return RES_OK;
+#endif
+ }
+ return RES_PARERR;
+}
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Write Sector(s) */
+
+#if _READONLY == 0
+DRESULT disk_write (
+ BYTE drv, /* Physical drive nmuber (0..) */
+ const BYTE *buff, /* Data to be written */
+ DWORD sector, /* Sector address (LBA) */
+ BYTE count /* Number of sectors to write (1..255) */
+)
+{
+ switch (drv) {
+#if HAL_USE_MMC_SPI
+ case MMC:
+ if (mmcGetDriverState(&MMCD1) != MMC_READY)
+ return RES_NOTRDY;
+ if (mmcIsWriteProtected(&MMCD1))
+ return RES_WRPRT;
+ if (mmcStartSequentialWrite(&MMCD1, sector))
+ return RES_ERROR;
+ while (count > 0) {
+ if (mmcSequentialWrite(&MMCD1, buff))
+ return RES_ERROR;
+ buff += MMC_SECTOR_SIZE;
+ count--;
+ }
+ if (mmcStopSequentialWrite(&MMCD1))
+ return RES_ERROR;
+ return RES_OK;
+#else
+ case SDC:
+ if (sdcGetDriverState(&SDCD1) != SDC_ACTIVE)
+ return RES_NOTRDY;
+ if (sdcWrite(&SDCD1, sector, buff, count))
+ return RES_ERROR;
+ return RES_OK;
+#endif
+ }
+ return RES_PARERR;
+}
+#endif /* _READONLY */
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Miscellaneous Functions */
+
+DRESULT disk_ioctl (
+ BYTE drv, /* Physical drive nmuber (0..) */
+ BYTE ctrl, /* Control code */
+ void *buff /* Buffer to send/receive control data */
+)
+{
+ switch (drv) {
+#if HAL_USE_MMC_SPI
+ case MMC:
+ switch (ctrl) {
+ case CTRL_SYNC:
+ return RES_OK;
+ case GET_SECTOR_SIZE:
+ *((WORD *)buff) = MMC_SECTOR_SIZE;
+ return RES_OK;
+ default:
+ return RES_PARERR;
+ }
+#else
+ case SDC:
+ switch (ctrl) {
+ case CTRL_SYNC:
+ return RES_OK;
+ case GET_SECTOR_COUNT:
+ *((DWORD *)buff) = sdcGetCardCapacity(&SDCD1);
+ return RES_OK;
+ case GET_SECTOR_SIZE:
+ *((WORD *)buff) = SDC_BLOCK_SIZE;
+ return RES_OK;
+ case GET_BLOCK_SIZE:
+ *((DWORD *)buff) = 256; /* 512b blocks in one erase block */
+ return RES_OK;
+ default:
+ return RES_PARERR;
+ }
+#endif
+ }
+ return RES_PARERR;
+}
+
+DWORD get_fattime(void) {
+#if HAL_USE_RTC
+ return rtcGetTimeFat(&RTCD1);
+#else
+ return ((uint32_t)0 | (1 << 16)) | (1 << 21); /* wrong but valid time */
+#endif
+}
+
+
+
diff --git a/os/various/evtimer.h b/os/various/evtimer.h
index 7d54d446b..695a3851e 100644
--- a/os/various/evtimer.h
+++ b/os/various/evtimer.h
@@ -29,6 +29,14 @@
#ifndef _EVTIMER_H_
#define _EVTIMER_H_
+
+/*
+ * Module dependencies check.
+ */
+#if !CH_USE_EVENTS
+#error "Event Timers require CH_USE_EVENTS"
+#endif
+
/**
* @brief Event timer structure.
*/
diff --git a/os/various/mail.c b/os/various/mail.c
new file mode 100644
index 000000000..cebd44457
--- /dev/null
+++ b/os/various/mail.c
@@ -0,0 +1,96 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file mail.c
+ * @brief Threads mail code.
+ *
+ * @addtogroup mail
+ * @{
+ */
+
+#include "ch.h"
+#include "mail.h"
+
+/**
+ * @brief Initializes a Mail Pool.
+ * @note The number of the mail objects in the mail pool should be at
+ * least <b>2+size(mailbox)<b>, this considering one writer and
+ * one reader, add one element for each extra reader or writer in
+ * order to avoid waiting on the mail pool. A smaller number of
+ * elements can be specified if waiting on the pool is acceptable.
+ *
+ * @param[out] mlp pointer to a @p MailPool structure
+ * @param[in] size the size of the mail objects to be placed in the pool
+ * @param[in] p pointer to the mail objects array first element
+ * @param[in] n number of elements in the mail objects array
+ *
+ * @init
+ */
+void mailInit(MailPool *mlp, size_t size, void *p, size_t n) {
+
+ chPoolInit(&mlp->pool, size, NULL);
+ chPoolLoadArray(&mlp->pool, p, n);
+ chSemInit(&mlp->sem, (cnt_t)n);
+}
+
+/**
+ * @brief Allocates a mail object from a mail pool.
+ * @pre The mail pool must be already been initialized.
+ *
+ * @param[in] mlp pointer to a @p MailPool structure
+ * @param[in] time the number of ticks before the operation timeouts,
+ * the following special values are allowed:
+ * - @a TIME_IMMEDIATE immediate timeout.
+ * - @a TIME_INFINITE no timeout.
+ * .
+ * @return The mail object.
+ * @retval NULL timeout expired.
+ *
+ * @api
+ */
+void *mailCreate(MailPool *mlp, systime_t time) {
+ msg_t msg;
+ void *mailp;
+
+ msg = chSemWaitTimeout(&mlp->sem, time);
+ if (msg != RDY_OK)
+ return NULL;
+ mailp = chPoolAlloc(&mlp->pool);
+ chDbgAssert(mailp != NULL, "mailCreate(), #1", "empty pool");
+ return mailp;
+}
+
+/**
+ * @brief Releases a mail object into a mail pool.
+ * @pre The mail pool must be already been initialized.
+ *
+ * @param[in] mlp pointer to a @p MailPool structure
+ * @param[in] mailp the pointer to the mail object to be released
+ *
+ * @api
+ */
+void mailDelete(MailPool *mlp, void *mailp) {
+
+ chPoolFree(&mlp->pool, mailp);
+ chSemSignal(&mlp->sem);
+}
+
+/** @} */
diff --git a/os/various/mail.h b/os/various/mail.h
new file mode 100644
index 000000000..1786494e6
--- /dev/null
+++ b/os/various/mail.h
@@ -0,0 +1,59 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011,2012 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file mail.h
+ * @brief Threads mail macros and structures.
+ *
+ * @addtogroup mail
+ * @{
+ */
+
+#ifndef _MAIL_H_
+#define _MAIL_H_
+
+/*
+ * Module dependencies check.
+ */
+#if !CH_USE_SEMAPHORES || !CH_USE_MEMPOOLS
+#error "Mail Pools require CH_USE_SEMAPHORES and CH_USE_MEMPOOLS"
+#endif
+
+/**
+ * @brief Mail Pool descriptor.
+ */
+typedef struct {
+ MemoryPool pool; /**< @brief Available mail objects. */
+ Semaphore sem; /**< @brief Semaphore guard. */
+} MailPool;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void mailInit(MailPool *mlp, size_t size, void *p, size_t n);
+ void *mailCreate(MailPool *mlp, systime_t time);
+ void mailDelete(MailPool *mlp, void *mailp);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _MAIL_H_ */
+
+/** @} */