aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal/src
diff options
context:
space:
mode:
authorbarthess <barthess@35acf78f-673a-0410-8e92-d51de3d6d3f4>2011-06-07 14:34:59 +0000
committerbarthess <barthess@35acf78f-673a-0410-8e92-d51de3d6d3f4>2011-06-07 14:34:59 +0000
commit5cad241306f64d0a3c0f7829421e4bf8f4b18fbe (patch)
treeebbcad6d0cdb19fa5ef0bf5f6dc5cf80dfbdc4d1 /os/hal/src
parent152f34a80c6ffe5fd17809732272823091b854e8 (diff)
parentaec912f13f9aa85cd677353fa556f679c3832970 (diff)
downloadChibiOS-5cad241306f64d0a3c0f7829421e4bf8f4b18fbe.tar.gz
ChibiOS-5cad241306f64d0a3c0f7829421e4bf8f4b18fbe.tar.bz2
ChibiOS-5cad241306f64d0a3c0f7829421e4bf8f4b18fbe.zip
I2C. Merged code from trunk.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/i2c_dev@3036 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os/hal/src')
-rw-r--r--os/hal/src/adc.c81
-rw-r--r--os/hal/src/can.c83
-rw-r--r--os/hal/src/gpt.c229
-rw-r--r--os/hal/src/hal.c12
-rw-r--r--os/hal/src/i2c.c3
-rw-r--r--os/hal/src/icu.c151
-rw-r--r--os/hal/src/mac.c17
-rw-r--r--os/hal/src/mmc_spi.c202
-rw-r--r--os/hal/src/pal.c15
-rw-r--r--os/hal/src/pwm.c62
-rw-r--r--os/hal/src/sdc.c392
-rw-r--r--os/hal/src/serial.c3
-rw-r--r--os/hal/src/serial_usb.c107
-rw-r--r--os/hal/src/spi.c80
-rw-r--r--os/hal/src/uart.c100
-rw-r--r--os/hal/src/usb.c547
16 files changed, 1521 insertions, 563 deletions
diff --git a/os/hal/src/adc.c b/os/hal/src/adc.c
index 25cbfe750..4843ca90b 100644
--- a/os/hal/src/adc.c
+++ b/os/hal/src/adc.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -67,19 +68,19 @@ void adcInit(void) {
*/
void adcObjectInit(ADCDriver *adcp) {
- adcp->ad_state = ADC_STOP;
- adcp->ad_config = NULL;
- adcp->ad_samples = NULL;
- adcp->ad_depth = 0;
- adcp->ad_grpp = NULL;
+ adcp->state = ADC_STOP;
+ adcp->config = NULL;
+ adcp->samples = NULL;
+ adcp->depth = 0;
+ adcp->grpp = NULL;
#if ADC_USE_WAIT
- adcp->ad_thread = NULL;
+ adcp->thread = NULL;
#endif /* ADC_USE_WAIT */
#if ADC_USE_MUTUAL_EXCLUSION
#if CH_USE_MUTEXES
- chMtxInit(&adcp->ad_mutex);
+ chMtxInit(&adcp->mutex);
#else
- chSemInit(&adcp->ad_semaphore, 1);
+ chSemInit(&adcp->semaphore, 1);
#endif
#endif /* ADC_USE_MUTUAL_EXCLUSION */
#if defined(ADC_DRIVER_EXT_INIT_HOOK)
@@ -101,11 +102,11 @@ void adcStart(ADCDriver *adcp, const ADCConfig *config) {
chDbgCheck(adcp != NULL, "adcStart");
chSysLock();
- chDbgAssert((adcp->ad_state == ADC_STOP) || (adcp->ad_state == ADC_READY),
+ chDbgAssert((adcp->state == ADC_STOP) || (adcp->state == ADC_READY),
"adcStart(), #1", "invalid state");
- adcp->ad_config = config;
+ adcp->config = config;
adc_lld_start(adcp);
- adcp->ad_state = ADC_READY;
+ adcp->state = ADC_READY;
chSysUnlock();
}
@@ -121,10 +122,10 @@ void adcStop(ADCDriver *adcp) {
chDbgCheck(adcp != NULL, "adcStop");
chSysLock();
- chDbgAssert((adcp->ad_state == ADC_STOP) || (adcp->ad_state == ADC_READY),
+ chDbgAssert((adcp->state == ADC_STOP) || (adcp->state == ADC_READY),
"adcStop(), #1", "invalid state");
adc_lld_stop(adcp);
- adcp->ad_state = ADC_STOP;
+ adcp->state = ADC_STOP;
chSysUnlock();
}
@@ -179,13 +180,13 @@ void adcStartConversionI(ADCDriver *adcp,
((depth == 1) || ((depth & 1) == 0)),
"adcStartConversionI");
- chDbgAssert((adcp->ad_state == ADC_READY) ||
- (adcp->ad_state == ADC_COMPLETE),
+ chDbgAssert((adcp->state == ADC_READY) ||
+ (adcp->state == ADC_COMPLETE),
"adcStartConversionI(), #1", "not ready");
- adcp->ad_samples = samples;
- adcp->ad_depth = depth;
- adcp->ad_grpp = grpp;
- adcp->ad_state = ADC_ACTIVE;
+ adcp->samples = samples;
+ adcp->depth = depth;
+ adcp->grpp = grpp;
+ adcp->state = ADC_ACTIVE;
adc_lld_start_conversion(adcp);
}
@@ -204,13 +205,13 @@ void adcStopConversion(ADCDriver *adcp) {
chDbgCheck(adcp != NULL, "adcStopConversion");
chSysLock();
- chDbgAssert((adcp->ad_state == ADC_READY) ||
- (adcp->ad_state == ADC_ACTIVE),
+ chDbgAssert((adcp->state == ADC_READY) ||
+ (adcp->state == ADC_ACTIVE),
"adcStopConversion(), #1", "invalid state");
- if (adcp->ad_state != ADC_READY) {
+ if (adcp->state != ADC_READY) {
adc_lld_stop_conversion(adcp);
- adcp->ad_grpp = NULL;
- adcp->ad_state = ADC_READY;
+ adcp->grpp = NULL;
+ adcp->state = ADC_READY;
_adc_reset_s(adcp);
}
chSysUnlock();
@@ -230,14 +231,14 @@ void adcStopConversionI(ADCDriver *adcp) {
chDbgCheck(adcp != NULL, "adcStopConversionI");
- chDbgAssert((adcp->ad_state == ADC_READY) ||
- (adcp->ad_state == ADC_ACTIVE) ||
- (adcp->ad_state == ADC_COMPLETE),
+ chDbgAssert((adcp->state == ADC_READY) ||
+ (adcp->state == ADC_ACTIVE) ||
+ (adcp->state == ADC_COMPLETE),
"adcStopConversionI(), #1", "invalid state");
- if (adcp->ad_state != ADC_READY) {
+ if (adcp->state != ADC_READY) {
adc_lld_stop_conversion(adcp);
- adcp->ad_grpp = NULL;
- adcp->ad_state = ADC_READY;
+ adcp->grpp = NULL;
+ adcp->state = ADC_READY;
_adc_reset_i(adcp);
}
}
@@ -271,9 +272,9 @@ msg_t adcConvert(ADCDriver *adcp,
msg_t msg;
chSysLock();
- chDbgAssert(grpp->acg_endcb == NULL, "adcConvert(), #1", "has callback");
+ chDbgAssert(adcp->thread == NULL, "adcConvert(), #1", "already waiting");
adcStartConversionI(adcp, grpp, samples, depth);
- (adcp)->ad_thread = chThdSelf();
+ (adcp)->thread = chThdSelf();
chSchGoSleepS(THD_STATE_SUSPENDED);
msg = chThdSelf()->p_u.rdymsg;
chSysUnlock();
@@ -286,8 +287,8 @@ msg_t adcConvert(ADCDriver *adcp,
* @brief Gains exclusive access to the ADC peripheral.
* @details This function tries to gain ownership to the ADC bus, if the bus
* is already being used then the invoking thread is queued.
- * @pre In order to use this function the option @p ADC_USE_MUTUAL_EXCLUSION
- * must be enabled.
+ * @pre In order to use this function the option
+ * @p ADC_USE_MUTUAL_EXCLUSION must be enabled.
*
* @param[in] adcp pointer to the @p ADCDriver object
*
@@ -298,16 +299,16 @@ void adcAcquireBus(ADCDriver *adcp) {
chDbgCheck(adcp != NULL, "adcAcquireBus");
#if CH_USE_MUTEXES
- chMtxLock(&adcp->ad_mutex);
+ chMtxLock(&adcp->mutex);
#elif CH_USE_SEMAPHORES
- chSemWait(&adcp->ad_semaphore);
+ chSemWait(&adcp->semaphore);
#endif
}
/**
* @brief Releases exclusive access to the ADC peripheral.
- * @pre In order to use this function the option @p ADC_USE_MUTUAL_EXCLUSION
- * must be enabled.
+ * @pre In order to use this function the option
+ * @p ADC_USE_MUTUAL_EXCLUSION must be enabled.
*
* @param[in] adcp pointer to the @p ADCDriver object
*
@@ -321,7 +322,7 @@ void adcReleaseBus(ADCDriver *adcp) {
(void)adcp;
chMtxUnlock();
#elif CH_USE_SEMAPHORES
- chSemSignal(&adcp->ad_semaphore);
+ chSemSignal(&adcp->semaphore);
#endif
}
#endif /* ADC_USE_MUTUAL_EXCLUSION */
diff --git a/os/hal/src/can.c b/os/hal/src/can.c
index d63cbfd8a..f9a827c4e 100644
--- a/os/hal/src/can.c
+++ b/os/hal/src/can.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -67,17 +68,17 @@ void canInit(void) {
*/
void canObjectInit(CANDriver *canp) {
- canp->cd_state = CAN_STOP;
- canp->cd_config = NULL;
- chSemInit(&canp->cd_txsem, 0);
- chSemInit(&canp->cd_rxsem, 0);
- chEvtInit(&canp->cd_rxfull_event);
- chEvtInit(&canp->cd_txempty_event);
- chEvtInit(&canp->cd_error_event);
- canp->cd_status = 0;
+ canp->state = CAN_STOP;
+ canp->config = NULL;
+ chSemInit(&canp->txsem, 0);
+ chSemInit(&canp->rxsem, 0);
+ chEvtInit(&canp->rxfull_event);
+ chEvtInit(&canp->txempty_event);
+ chEvtInit(&canp->error_event);
+ canp->status = 0;
#if CAN_USE_SLEEP_MODE
- chEvtInit(&canp->cd_sleep_event);
- chEvtInit(&canp->cd_wakeup_event);
+ chEvtInit(&canp->sleep_event);
+ chEvtInit(&canp->wakeup_event);
#endif /* CAN_USE_SLEEP_MODE */
}
@@ -98,16 +99,16 @@ void canStart(CANDriver *canp, const CANConfig *config) {
chDbgCheck(canp != NULL, "canStart");
chSysLock();
- chDbgAssert((canp->cd_state == CAN_STOP) ||
- (canp->cd_state == CAN_STARTING) ||
- (canp->cd_state == CAN_READY),
+ chDbgAssert((canp->state == CAN_STOP) ||
+ (canp->state == CAN_STARTING) ||
+ (canp->state == CAN_READY),
"canStart(), #1", "invalid state");
- while (canp->cd_state == CAN_STARTING)
+ while (canp->state == CAN_STARTING)
chThdSleepS(1);
- if (canp->cd_state == CAN_STOP) {
- canp->cd_config = config;
+ if (canp->state == CAN_STOP) {
+ canp->config = config;
can_lld_start(canp);
- canp->cd_state = CAN_READY;
+ canp->state = CAN_READY;
}
chSysUnlock();
}
@@ -124,14 +125,14 @@ void canStop(CANDriver *canp) {
chDbgCheck(canp != NULL, "canStop");
chSysLock();
- chDbgAssert((canp->cd_state == CAN_STOP) || (canp->cd_state == CAN_READY),
+ chDbgAssert((canp->state == CAN_STOP) || (canp->state == CAN_READY),
"canStop(), #1", "invalid state");
can_lld_stop(canp);
- chSemResetI(&canp->cd_rxsem, 0);
- chSemResetI(&canp->cd_txsem, 0);
+ chSemResetI(&canp->rxsem, 0);
+ chSemResetI(&canp->txsem, 0);
chSchRescheduleS();
- canp->cd_state = CAN_STOP;
- canp->cd_status = 0;
+ canp->state = CAN_STOP;
+ canp->status = 0;
chSysUnlock();
}
@@ -142,7 +143,7 @@ void canStop(CANDriver *canp) {
* @note Trying to transmit while in sleep mode simply enqueues the thread.
*
* @param[in] canp pointer to the @p CANDriver object
- * @param[in] ctfp pointer to the CAN frame to be transmitted
+ * @param[in] ctfp pointer to the CAN frame to be transmitted
* @param[in] timeout the number of ticks before the operation timeouts,
* the following special values are allowed:
* - @a TIME_IMMEDIATE immediate timeout.
@@ -160,10 +161,10 @@ msg_t canTransmit(CANDriver *canp, const CANTxFrame *ctfp, systime_t timeout) {
chDbgCheck((canp != NULL) && (ctfp != NULL), "canTransmit");
chSysLock();
- chDbgAssert((canp->cd_state == CAN_READY) || (canp->cd_state == CAN_SLEEP),
+ chDbgAssert((canp->state == CAN_READY) || (canp->state == CAN_SLEEP),
"canTransmit(), #1", "invalid state");
- while ((canp->cd_state == CAN_SLEEP) || !can_lld_can_transmit(canp)) {
- msg_t msg = chSemWaitTimeoutS(&canp->cd_txsem, timeout);
+ while ((canp->state == CAN_SLEEP) || !can_lld_can_transmit(canp)) {
+ msg_t msg = chSemWaitTimeoutS(&canp->txsem, timeout);
if (msg != RDY_OK) {
chSysUnlock();
return msg;
@@ -200,10 +201,10 @@ msg_t canReceive(CANDriver *canp, CANRxFrame *crfp, systime_t timeout) {
chDbgCheck((canp != NULL) && (crfp != NULL), "canReceive");
chSysLock();
- chDbgAssert((canp->cd_state == CAN_READY) || (canp->cd_state == CAN_SLEEP),
+ chDbgAssert((canp->state == CAN_READY) || (canp->state == CAN_SLEEP),
"canReceive(), #1", "invalid state");
- while ((canp->cd_state == CAN_SLEEP) || !can_lld_can_receive(canp)) {
- msg_t msg = chSemWaitTimeoutS(&canp->cd_rxsem, timeout);
+ while ((canp->state == CAN_SLEEP) || !can_lld_can_receive(canp)) {
+ msg_t msg = chSemWaitTimeoutS(&canp->rxsem, timeout);
if (msg != RDY_OK) {
chSysUnlock();
return msg;
@@ -226,8 +227,8 @@ canstatus_t canGetAndClearFlags(CANDriver *canp) {
canstatus_t status;
chSysLock();
- status = canp->cd_status;
- canp->cd_status = 0;
+ status = canp->status;
+ canp->status = 0;
chSysUnlock();
return status;
}
@@ -236,7 +237,7 @@ canstatus_t canGetAndClearFlags(CANDriver *canp) {
/**
* @brief Enters the sleep mode.
* @details This function puts the CAN driver in sleep mode and broadcasts
- * the @p cd_sleep_event event source.
+ * the @p sleep_event event source.
* @pre In order to use this function the option @p CAN_USE_SLEEP_MODE must
* be enabled and the @p CAN_SUPPORTS_SLEEP mode must be supported
* by the low level driver.
@@ -250,12 +251,12 @@ void canSleep(CANDriver *canp) {
chDbgCheck(canp != NULL, "canSleep");
chSysLock();
- chDbgAssert((canp->cd_state == CAN_READY) || (canp->cd_state == CAN_SLEEP),
+ chDbgAssert((canp->state == CAN_READY) || (canp->state == CAN_SLEEP),
"canSleep(), #1", "invalid state");
- if (canp->cd_state == CAN_READY) {
+ if (canp->state == CAN_READY) {
can_lld_sleep(canp);
- canp->cd_state = CAN_SLEEP;
- chEvtBroadcastI(&canp->cd_sleep_event);
+ canp->state = CAN_SLEEP;
+ chEvtBroadcastI(&canp->sleep_event);
chSchRescheduleS();
}
chSysUnlock();
@@ -273,12 +274,12 @@ void canWakeup(CANDriver *canp) {
chDbgCheck(canp != NULL, "canWakeup");
chSysLock();
- chDbgAssert((canp->cd_state == CAN_READY) || (canp->cd_state == CAN_SLEEP),
+ chDbgAssert((canp->state == CAN_READY) || (canp->state == CAN_SLEEP),
"canWakeup(), #1", "invalid state");
- if (canp->cd_state == CAN_SLEEP) {
+ if (canp->state == CAN_SLEEP) {
can_lld_wakeup(canp);
- canp->cd_state = CAN_READY;
- chEvtBroadcastI(&canp->cd_wakeup_event);
+ canp->state = CAN_READY;
+ chEvtBroadcastI(&canp->wakeup_event);
chSchRescheduleS();
}
chSysUnlock();
diff --git a/os/hal/src/gpt.c b/os/hal/src/gpt.c
new file mode 100644
index 000000000..e90a8911a
--- /dev/null
+++ b/os/hal/src/gpt.c
@@ -0,0 +1,229 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 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 gpt.c
+ * @brief GPT Driver code.
+ *
+ * @addtogroup GPT
+ * @{
+ */
+
+#include "ch.h"
+#include "hal.h"
+
+#if HAL_USE_GPT || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief GPT Driver initialization.
+ * @note This function is implicitly invoked by @p halInit(), there is
+ * no need to explicitly initialize the driver.
+ *
+ * @init
+ */
+void gptInit(void) {
+
+ gpt_lld_init();
+}
+
+/**
+ * @brief Initializes the standard part of a @p GPTDriver structure.
+ *
+ * @param[out] gptp pointer to the @p GPTDriver object
+ *
+ * @init
+ */
+void gptObjectInit(GPTDriver *gptp) {
+
+ gptp->state = GPT_STOP;
+ gptp->config = NULL;
+}
+
+/**
+ * @brief Configures and activates the GPT peripheral.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ * @param[in] config pointer to the @p GPTConfig object
+ *
+ * @api
+ */
+void gptStart(GPTDriver *gptp, const GPTConfig *config) {
+
+ chDbgCheck((gptp != NULL) && (config != NULL), "ptStart");
+
+ chSysLock();
+ chDbgAssert((gptp->state == GPT_STOP) || (gptp->state == GPT_READY),
+ "gptStart(), #1", "invalid state");
+ gptp->config = config;
+ gpt_lld_start(gptp);
+ gptp->state = GPT_READY;
+ chSysUnlock();
+}
+
+/**
+ * @brief Deactivates the GPT peripheral.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ *
+ * @api
+ */
+void gptStop(GPTDriver *gptp) {
+
+ chDbgCheck(gptp != NULL, "gptStop");
+
+ chSysLock();
+ chDbgAssert((gptp->state == GPT_STOP) || (gptp->state == GPT_READY),
+ "gptStop(), #1", "invalid state");
+ gpt_lld_stop(gptp);
+ gptp->state = GPT_STOP;
+ chSysUnlock();
+}
+
+/**
+ * @brief Starts the timer in continuous mode.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ * @param[in] interval period in ticks
+ *
+ * @api
+ */
+void gptStartContinuous(GPTDriver *gptp, gptcnt_t interval) {
+
+ chSysLock();
+ gptStartContinuousI(gptp, interval);
+ chSysUnlock();
+}
+
+/**
+ * @brief Starts the timer in continuous mode.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ * @param[in] interval period in ticks
+ *
+ * @iclass
+ */
+void gptStartContinuousI(GPTDriver *gptp, gptcnt_t interval) {
+
+ chDbgAssert(gptp->state == GPT_READY,
+ "gptStartContinuousI(), #1", "invalid state");
+ gptp->state = GPT_CONTINUOUS;
+ gpt_lld_start_timer(gptp, interval);
+}
+
+/**
+ * @brief Starts the timer in one shot mode.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ * @param[in] interval time interval in ticks
+ *
+ * @api
+ */
+void gptStartOneShot(GPTDriver *gptp, gptcnt_t interval) {
+
+ chSysLock();
+ gptStartOneShotI(gptp, interval);
+ chSysUnlock();
+}
+
+/**
+ * @brief Starts the timer in one shot mode.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ * @param[in] interval time interval in ticks
+ *
+ * @api
+ */
+void gptStartOneShotI(GPTDriver *gptp, gptcnt_t interval) {
+
+ chDbgAssert(gptp->state == GPT_READY,
+ "gptStartOneShotI(), #1", "invalid state");
+ gptp->state = GPT_ONESHOT;
+ gpt_lld_start_timer(gptp, interval);
+}
+
+/**
+ * @brief Stops the timer.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ *
+ * @api
+ */
+void gptStopTimer(GPTDriver *gptp) {
+
+ chSysLock();
+ gptStopTimerI(gptp);
+ chSysUnlock();
+}
+
+/**
+ * @brief Stops the timer.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ *
+ * @api
+ */
+void gptStopTimerI(GPTDriver *gptp) {
+
+ chDbgAssert((gptp->state == GPT_READY) || (gptp->state == GPT_CONTINUOUS) ||
+ (gptp->state == GPT_ONESHOT),
+ "gptStopTimerI(), #1", "invalid state");
+ gptp->state = GPT_READY;
+ gpt_lld_stop_timer(gptp);
+}
+
+/**
+ * @brief Starts the timer in one shot mode and waits for completion.
+ * @details This function specifically polls the timer waiting for completion
+ * in order to not have extra delays caused by interrupt servicing,
+ * this function is only recommended for short delays.
+ * @note The configured callback is not invoked when using this function.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ * @param[in] interval time interval in ticks
+ *
+ * @api
+ */
+void gptPolledDelay(GPTDriver *gptp, gptcnt_t interval) {
+
+ chDbgAssert(gptp->state == GPT_READY,
+ "gptPolledDelay(), #1", "invalid state");
+ gptp->state = GPT_ONESHOT;
+ gpt_lld_polled_delay(gptp, interval);
+}
+
+#endif /* HAL_USE_GPT */
+
+/** @} */
diff --git a/os/hal/src/hal.c b/os/hal/src/hal.c
index bfbaa3e84..1a15988f5 100644
--- a/os/hal/src/hal.c
+++ b/os/hal/src/hal.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -66,9 +67,15 @@ void halInit(void) {
#if HAL_USE_CAN || defined(__DOXYGEN__)
canInit();
#endif
+#if HAL_USE_GPT || defined(__DOXYGEN__)
+ gptInit();
+#endif
#if HAL_USE_I2C || defined(__DOXYGEN__)
i2cInit();
#endif
+#if HAL_USE_ICU || defined(__DOXYGEN__)
+ icuInit();
+#endif
#if HAL_USE_MAC || defined(__DOXYGEN__)
macInit();
#endif
@@ -78,6 +85,9 @@ void halInit(void) {
#if HAL_USE_SERIAL || defined(__DOXYGEN__)
sdInit();
#endif
+#if HAL_USE_SDC || defined(__DOXYGEN__)
+ sdcInit();
+#endif
#if HAL_USE_SPI || defined(__DOXYGEN__)
spiInit();
#endif
diff --git a/os/hal/src/i2c.c b/os/hal/src/i2c.c
index 84dfcf958..6f99a1afb 100644
--- a/os/hal/src/i2c.c
+++ b/os/hal/src/i2c.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/src/icu.c b/os/hal/src/icu.c
new file mode 100644
index 000000000..3be67448e
--- /dev/null
+++ b/os/hal/src/icu.c
@@ -0,0 +1,151 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 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 icu.c
+ * @brief ICU Driver code.
+ *
+ * @addtogroup ICU
+ * @{
+ */
+
+#include "ch.h"
+#include "hal.h"
+
+#if HAL_USE_ICU || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief ICU Driver initialization.
+ * @note This function is implicitly invoked by @p halInit(), there is
+ * no need to explicitly initialize the driver.
+ *
+ * @init
+ */
+void icuInit(void) {
+
+ icu_lld_init();
+}
+
+/**
+ * @brief Initializes the standard part of a @p ICUDriver structure.
+ *
+ * @param[out] icup pointer to the @p ICUDriver object
+ *
+ * @init
+ */
+void icuObjectInit(ICUDriver *icup) {
+
+ icup->state = ICU_STOP;
+ icup->config = NULL;
+}
+
+/**
+ * @brief Configures and activates the ICU peripheral.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ * @param[in] config pointer to the @p ICUConfig object
+ *
+ * @api
+ */
+void icuStart(ICUDriver *icup, const ICUConfig *config) {
+
+ chDbgCheck((icup != NULL) && (config != NULL), "icuStart");
+
+ chSysLock();
+ chDbgAssert((icup->state == ICU_STOP) || (icup->state == ICU_READY),
+ "icuStart(), #1", "invalid state");
+ icup->config = config;
+ icu_lld_start(icup);
+ icup->state = ICU_READY;
+ chSysUnlock();
+}
+
+/**
+ * @brief Deactivates the ICU peripheral.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ *
+ * @api
+ */
+void icuStop(ICUDriver *icup) {
+
+ chDbgCheck(icup != NULL, "icuStop");
+
+ chSysLock();
+ chDbgAssert((icup->state == ICU_STOP) || (icup->state == ICU_READY),
+ "icuStop(), #1", "invalid state");
+ icu_lld_stop(icup);
+ icup->state = ICU_STOP;
+ chSysUnlock();
+}
+
+/**
+ * @brief Enables the input capture.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ *
+ * @api
+ */
+void icuEnable(ICUDriver *icup) {
+
+ chSysLock();
+ chDbgAssert(icup->state == ICU_READY, "icuEnable(), #1", "invalid state");
+ icu_lld_enable(icup);
+ icup->state = ICU_WAITING;
+ chSysUnlock();
+}
+
+/**
+ * @brief Disables the input capture.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ *
+ * @api
+ */
+void icuDisable(ICUDriver *icup) {
+
+ chSysLock();
+ chDbgAssert((icup->state == ICU_READY) || (icup->state == ICU_WAITING) ||
+ (icup->state == ICU_ACTIVE) || (icup->state == ICU_IDLE),
+ "icuDisable(), #1", "invalid state");
+ icu_lld_disable(icup);
+ icup->state = ICU_READY;
+ chSysUnlock();
+}
+
+#endif /* HAL_USE_ICU */
+
+/** @} */
diff --git a/os/hal/src/mac.c b/os/hal/src/mac.c
index 48656a8a3..4d6a9b2cd 100644
--- a/os/hal/src/mac.c
+++ b/os/hal/src/mac.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -71,10 +72,10 @@ void macInit(void) {
*/
void macObjectInit(MACDriver *macp) {
- chSemInit(&macp->md_tdsem, 0);
- chSemInit(&macp->md_rdsem, 0);
+ chSemInit(&macp->tdsem, 0);
+ chSemInit(&macp->rdsem, 0);
#if CH_USE_EVENTS
- chEvtInit(&macp->md_rdevent);
+ chEvtInit(&macp->rdevent);
#endif
}
@@ -123,8 +124,10 @@ msg_t macWaitTransmitDescriptor(MACDriver *macp,
(time > 0)) {
chSysLock();
systime_t now = chTimeNow();
- if ((msg = chSemWaitTimeoutS(&macp->md_tdsem, time)) == RDY_TIMEOUT)
+ if ((msg = chSemWaitTimeoutS(&macp->tdsem, time)) == RDY_TIMEOUT) {
+ chSysUnlock();
break;
+ }
if (time != TIME_INFINITE)
time -= (chTimeNow() - now);
chSysUnlock();
@@ -173,8 +176,10 @@ msg_t macWaitReceiveDescriptor(MACDriver *macp,
(time > 0)) {
chSysLock();
systime_t now = chTimeNow();
- if ((msg = chSemWaitTimeoutS(&macp->md_rdsem, time)) == RDY_TIMEOUT)
+ if ((msg = chSemWaitTimeoutS(&macp->rdsem, time)) == RDY_TIMEOUT) {
+ chSysUnlock();
break;
+ }
if (time != TIME_INFINITE)
time -= (chTimeNow() - now);
chSysUnlock();
diff --git a/os/hal/src/mmc_spi.c b/os/hal/src/mmc_spi.c
index 1b2d930c5..e6dcf9287 100644
--- a/os/hal/src/mmc_spi.c
+++ b/os/hal/src/mmc_spi.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -18,7 +19,7 @@
*/
/**
- * @file mmc_spi.c
+ * @file spi.c
* @brief MMC over SPI driver code.
*
* @addtogroup MMC_SPI
@@ -52,24 +53,24 @@
static void tmrfunc(void *p) {
MMCDriver *mmcp = p;
- if (mmcp->mmc_cnt > 0) {
- if (mmcp->mmc_is_inserted()) {
- if (--mmcp->mmc_cnt == 0) {
- mmcp->mmc_state = MMC_INSERTED;
- chEvtBroadcastI(&mmcp->mmc_inserted_event);
+ if (mmcp->cnt > 0) {
+ if (mmcp->is_inserted()) {
+ if (--mmcp->cnt == 0) {
+ mmcp->state = MMC_INSERTED;
+ chEvtBroadcastI(&mmcp->inserted_event);
}
}
else
- mmcp->mmc_cnt = MMC_POLLING_INTERVAL;
+ mmcp->cnt = MMC_POLLING_INTERVAL;
}
else {
- if (!mmcp->mmc_is_inserted()) {
- mmcp->mmc_state = MMC_WAIT;
- mmcp->mmc_cnt = MMC_POLLING_INTERVAL;
- chEvtBroadcastI(&mmcp->mmc_removed_event);
+ if (!mmcp->is_inserted()) {
+ mmcp->state = MMC_WAIT;
+ mmcp->cnt = MMC_POLLING_INTERVAL;
+ chEvtBroadcastI(&mmcp->removed_event);
}
}
- chVTSetI(&mmcp->mmc_vt, MS2ST(MMC_POLLING_DELAY), tmrfunc, mmcp);
+ chVTSetI(&mmcp->vt, MS2ST(MMC_POLLING_DELAY), tmrfunc, mmcp);
}
/**
@@ -84,13 +85,13 @@ static void wait(MMCDriver *mmcp) {
uint8_t buf[4];
for (i = 0; i < 16; i++) {
- spiReceive(mmcp->mmc_spip, 1, buf);
+ spiReceive(mmcp->spip, 1, buf);
if (buf[0] == 0xFF)
break;
}
/* Looks like it is a long wait.*/
while (TRUE) {
- spiReceive(mmcp->mmc_spip, 1, buf);
+ spiReceive(mmcp->spip, 1, buf);
if (buf[0] == 0xFF)
break;
#ifdef MMC_NICE_WAITING
@@ -121,7 +122,7 @@ static void send_hdr(MMCDriver *mmcp, uint8_t cmd, uint32_t arg) {
buf[3] = arg >> 8;
buf[4] = arg;
buf[5] = 0x95; /* Valid for CMD0 ignored by other commands. */
- spiSend(mmcp->mmc_spip, 6, buf);
+ spiSend(mmcp->spip, 6, buf);
}
/**
@@ -138,7 +139,7 @@ static uint8_t recvr1(MMCDriver *mmcp) {
uint8_t r1[1];
for (i = 0; i < 9; i++) {
- spiReceive(mmcp->mmc_spip, 1, r1);
+ spiReceive(mmcp->spip, 1, r1);
if (r1[0] != 0xFF)
return r1[0];
}
@@ -159,10 +160,10 @@ static uint8_t recvr1(MMCDriver *mmcp) {
static uint8_t send_command(MMCDriver *mmcp, uint8_t cmd, uint32_t arg) {
uint8_t r1;
- spiSelect(mmcp->mmc_spip);
+ spiSelect(mmcp->spip);
send_hdr(mmcp, cmd, arg);
r1 = recvr1(mmcp);
- spiUnselect(mmcp->mmc_spip);
+ spiUnselect(mmcp->spip);
return r1;
}
@@ -176,16 +177,16 @@ static uint8_t send_command(MMCDriver *mmcp, uint8_t cmd, uint32_t arg) {
static void sync(MMCDriver *mmcp) {
uint8_t buf[1];
- spiSelect(mmcp->mmc_spip);
+ spiSelect(mmcp->spip);
while (TRUE) {
- spiReceive(mmcp->mmc_spip, 1, buf);
+ spiReceive(mmcp->spip, 1, buf);
if (buf[0] == 0xFF)
break;
#ifdef MMC_NICE_WAITING
chThdSleep(1); /* Trying to be nice with the other threads.*/
#endif
}
- spiUnselect(mmcp->mmc_spip);
+ spiUnselect(mmcp->spip);
}
/*===========================================================================*/
@@ -221,15 +222,15 @@ void mmcObjectInit(MMCDriver *mmcp, SPIDriver *spip,
const SPIConfig *lscfg, const SPIConfig *hscfg,
mmcquery_t is_protected, mmcquery_t is_inserted) {
- mmcp->mmc_state = MMC_STOP;
- mmcp->mmc_config = NULL;
- mmcp->mmc_spip = spip;
- mmcp->mmc_lscfg = lscfg;
- mmcp->mmc_hscfg = hscfg;
- mmcp->mmc_is_protected = is_protected;
- mmcp->mmc_is_inserted = is_inserted;
- chEvtInit(&mmcp->mmc_inserted_event);
- chEvtInit(&mmcp->mmc_removed_event);
+ mmcp->state = MMC_STOP;
+ mmcp->config = NULL;
+ mmcp->spip = spip;
+ mmcp->lscfg = lscfg;
+ mmcp->hscfg = hscfg;
+ mmcp->is_protected = is_protected;
+ mmcp->is_inserted = is_inserted;
+ chEvtInit(&mmcp->inserted_event);
+ chEvtInit(&mmcp->removed_event);
}
/**
@@ -245,11 +246,11 @@ void mmcStart(MMCDriver *mmcp, const MMCConfig *config) {
chDbgCheck((mmcp != NULL) && (config == NULL), "mmcStart");
chSysLock();
- chDbgAssert(mmcp->mmc_state == MMC_STOP, "mmcStart(), #1", "invalid state");
- mmcp->mmc_config = config;
- mmcp->mmc_state = MMC_WAIT;
- mmcp->mmc_cnt = MMC_POLLING_INTERVAL;
- chVTSetI(&mmcp->mmc_vt, MS2ST(MMC_POLLING_DELAY), tmrfunc, mmcp);
+ chDbgAssert(mmcp->state == MMC_STOP, "mmcStart(), #1", "invalid state");
+ mmcp->config = config;
+ mmcp->state = MMC_WAIT;
+ mmcp->cnt = MMC_POLLING_INTERVAL;
+ chVTSetI(&mmcp->vt, MS2ST(MMC_POLLING_DELAY), tmrfunc, mmcp);
chSysUnlock();
}
@@ -265,17 +266,16 @@ void mmcStop(MMCDriver *mmcp) {
chDbgCheck(mmcp != NULL, "mmcStop");
chSysLock();
- chDbgAssert((mmcp->mmc_state != MMC_UNINIT) &&
- (mmcp->mmc_state != MMC_READING) &&
- (mmcp->mmc_state != MMC_WRITING),
- "mmcStop(), #1",
- "invalid state");
- if (mmcp->mmc_state != MMC_STOP) {
- mmcp->mmc_state = MMC_STOP;
- chVTResetI(&mmcp->mmc_vt);
+ chDbgAssert((mmcp->state != MMC_UNINIT) &&
+ (mmcp->state != MMC_READING) &&
+ (mmcp->state != MMC_WRITING),
+ "mmcStop(), #1", "invalid state");
+ if (mmcp->state != MMC_STOP) {
+ mmcp->state = MMC_STOP;
+ chVTResetI(&mmcp->vt);
}
chSysUnlock();
- spiStop(mmcp->mmc_spip);
+ spiStop(mmcp->spip);
}
/**
@@ -300,15 +300,13 @@ bool_t mmcConnect(MMCDriver *mmcp) {
chDbgCheck(mmcp != NULL, "mmcConnect");
- chDbgAssert((mmcp->mmc_state != MMC_UNINIT) &&
- (mmcp->mmc_state != MMC_STOP),
- "mmcConnect(), #1",
- "invalid state");
+ chDbgAssert((mmcp->state != MMC_UNINIT) && (mmcp->state != MMC_STOP),
+ "mmcConnect(), #1", "invalid state");
- if (mmcp->mmc_state == MMC_INSERTED) {
+ if (mmcp->state == MMC_INSERTED) {
/* Slow clock mode and 128 clock pulses.*/
- spiStart(mmcp->mmc_spip, mmcp->mmc_lscfg);
- spiIgnore(mmcp->mmc_spip, 16);
+ spiStart(mmcp->spip, mmcp->lscfg);
+ spiIgnore(mmcp->spip, 16);
/* SPI mode selection.*/
i = 0;
@@ -334,7 +332,7 @@ bool_t mmcConnect(MMCDriver *mmcp) {
}
/* Initialization complete, full speed. */
- spiStart(mmcp->mmc_spip, mmcp->mmc_hscfg);
+ spiStart(mmcp->spip, mmcp->hscfg);
/* Setting block size.*/
if (send_command(mmcp, MMC_CMDSETBLOCKLEN, MMC_SECTOR_SIZE) != 0x00)
@@ -342,8 +340,8 @@ bool_t mmcConnect(MMCDriver *mmcp) {
/* Transition to MMC_READY state (if not extracted).*/
chSysLock();
- if (mmcp->mmc_state == MMC_INSERTED) {
- mmcp->mmc_state = MMC_READY;
+ if (mmcp->state == MMC_INSERTED) {
+ mmcp->state = MMC_READY;
result = FALSE;
}
else
@@ -351,7 +349,7 @@ bool_t mmcConnect(MMCDriver *mmcp) {
chSysUnlock();
return result;
}
- if (mmcp->mmc_state == MMC_READY)
+ if (mmcp->state == MMC_READY)
return FALSE;
/* Any other state is invalid.*/
return TRUE;
@@ -373,24 +371,22 @@ bool_t mmcDisconnect(MMCDriver *mmcp) {
chDbgCheck(mmcp != NULL, "mmcDisconnect");
- chDbgAssert((mmcp->mmc_state != MMC_UNINIT) &&
- (mmcp->mmc_state != MMC_STOP),
- "mmcDisconnect(), #1",
- "invalid state");
- switch (mmcp->mmc_state) {
+ chDbgAssert((mmcp->state != MMC_UNINIT) && (mmcp->state != MMC_STOP),
+ "mmcDisconnect(), #1", "invalid state");
+ switch (mmcp->state) {
case MMC_READY:
/* Wait for the pending write operations to complete.*/
sync(mmcp);
chSysLock();
- if (mmcp->mmc_state == MMC_READY)
- mmcp->mmc_state = MMC_INSERTED;
+ if (mmcp->state == MMC_READY)
+ mmcp->state = MMC_INSERTED;
chSysUnlock();
case MMC_INSERTED:
status = FALSE;
default:
status = TRUE;
}
- spiStop(mmcp->mmc_spip);
+ spiStop(mmcp->spip);
return status;
}
@@ -410,21 +406,21 @@ bool_t mmcStartSequentialRead(MMCDriver *mmcp, uint32_t startblk) {
chDbgCheck(mmcp != NULL, "mmcStartSequentialRead");
chSysLock();
- if (mmcp->mmc_state != MMC_READY) {
+ if (mmcp->state != MMC_READY) {
chSysUnlock();
return TRUE;
}
- mmcp->mmc_state = MMC_READING;
+ mmcp->state = MMC_READING;
chSysUnlock();
- spiStart(mmcp->mmc_spip, mmcp->mmc_hscfg);
- spiSelect(mmcp->mmc_spip);
+ spiStart(mmcp->spip, mmcp->hscfg);
+ spiSelect(mmcp->spip);
send_hdr(mmcp, MMC_CMDREADMULTIPLE, startblk * MMC_SECTOR_SIZE);
if (recvr1(mmcp) != 0x00) {
- spiUnselect(mmcp->mmc_spip);
+ spiUnselect(mmcp->spip);
chSysLock();
- if (mmcp->mmc_state == MMC_READING)
- mmcp->mmc_state = MMC_READY;
+ if (mmcp->state == MMC_READING)
+ mmcp->state = MMC_READY;
chSysUnlock();
return TRUE;
}
@@ -448,26 +444,26 @@ bool_t mmcSequentialRead(MMCDriver *mmcp, uint8_t *buffer) {
chDbgCheck((mmcp != NULL) && (buffer != NULL), "mmcSequentialRead");
chSysLock();
- if (mmcp->mmc_state != MMC_READING) {
+ if (mmcp->state != MMC_READING) {
chSysUnlock();
return TRUE;
}
chSysUnlock();
for (i = 0; i < MMC_WAIT_DATA; i++) {
- spiReceive(mmcp->mmc_spip, 1, buffer);
+ spiReceive(mmcp->spip, 1, buffer);
if (buffer[0] == 0xFE) {
- spiReceive(mmcp->mmc_spip, MMC_SECTOR_SIZE, buffer);
+ spiReceive(mmcp->spip, MMC_SECTOR_SIZE, buffer);
/* CRC ignored. */
- spiIgnore(mmcp->mmc_spip, 2);
+ spiIgnore(mmcp->spip, 2);
return FALSE;
}
}
/* Timeout.*/
- spiUnselect(mmcp->mmc_spip);
+ spiUnselect(mmcp->spip);
chSysLock();
- if (mmcp->mmc_state == MMC_READING)
- mmcp->mmc_state = MMC_READY;
+ if (mmcp->state == MMC_READING)
+ mmcp->state = MMC_READY;
chSysUnlock();
return TRUE;
}
@@ -489,22 +485,22 @@ bool_t mmcStopSequentialRead(MMCDriver *mmcp) {
chDbgCheck(mmcp != NULL, "mmcStopSequentialRead");
chSysLock();
- if (mmcp->mmc_state != MMC_READING) {
+ if (mmcp->state != MMC_READING) {
chSysUnlock();
return TRUE;
}
chSysUnlock();
- spiSend(mmcp->mmc_spip, sizeof(stopcmd), stopcmd);
+ spiSend(mmcp->spip, sizeof(stopcmd), stopcmd);
/* result = recvr1(mmcp) != 0x00;*/
/* Note, ignored r1 response, it can be not zero, unknown issue.*/
recvr1(mmcp);
result = FALSE;
- spiUnselect(mmcp->mmc_spip);
+ spiUnselect(mmcp->spip);
chSysLock();
- if (mmcp->mmc_state == MMC_READING)
- mmcp->mmc_state = MMC_READY;
+ if (mmcp->state == MMC_READING)
+ mmcp->state = MMC_READY;
chSysUnlock();
return result;
}
@@ -525,21 +521,21 @@ bool_t mmcStartSequentialWrite(MMCDriver *mmcp, uint32_t startblk) {
chDbgCheck(mmcp != NULL, "mmcStartSequentialWrite");
chSysLock();
- if (mmcp->mmc_state != MMC_READY) {
+ if (mmcp->state != MMC_READY) {
chSysUnlock();
return TRUE;
}
- mmcp->mmc_state = MMC_WRITING;
+ mmcp->state = MMC_WRITING;
chSysUnlock();
- spiStart(mmcp->mmc_spip, mmcp->mmc_hscfg);
- spiSelect(mmcp->mmc_spip);
+ spiStart(mmcp->spip, mmcp->hscfg);
+ spiSelect(mmcp->spip);
send_hdr(mmcp, MMC_CMDWRITEMULTIPLE, startblk * MMC_SECTOR_SIZE);
if (recvr1(mmcp) != 0x00) {
- spiUnselect(mmcp->mmc_spip);
+ spiUnselect(mmcp->spip);
chSysLock();
- if (mmcp->mmc_state == MMC_WRITING)
- mmcp->mmc_state = MMC_READY;
+ if (mmcp->state == MMC_WRITING)
+ mmcp->state = MMC_READY;
chSysUnlock();
return TRUE;
}
@@ -564,26 +560,26 @@ bool_t mmcSequentialWrite(MMCDriver *mmcp, const uint8_t *buffer) {
chDbgCheck((mmcp != NULL) && (buffer != NULL), "mmcSequentialWrite");
chSysLock();
- if (mmcp->mmc_state != MMC_WRITING) {
+ if (mmcp->state != MMC_WRITING) {
chSysUnlock();
return TRUE;
}
chSysUnlock();
- spiSend(mmcp->mmc_spip, sizeof(start), start); /* Data prologue. */
- spiSend(mmcp->mmc_spip, MMC_SECTOR_SIZE, buffer); /* Data. */
- spiIgnore(mmcp->mmc_spip, 2); /* CRC ignored. */
- spiReceive(mmcp->mmc_spip, 1, b);
+ spiSend(mmcp->spip, sizeof(start), start); /* Data prologue. */
+ spiSend(mmcp->spip, MMC_SECTOR_SIZE, buffer); /* Data. */
+ spiIgnore(mmcp->spip, 2); /* CRC ignored. */
+ spiReceive(mmcp->spip, 1, b);
if ((b[0] & 0x1F) == 0x05) {
wait(mmcp);
return FALSE;
}
/* Error.*/
- spiUnselect(mmcp->mmc_spip);
+ spiUnselect(mmcp->spip);
chSysLock();
- if (mmcp->mmc_state == MMC_WRITING)
- mmcp->mmc_state = MMC_READY;
+ if (mmcp->state == MMC_WRITING)
+ mmcp->state = MMC_READY;
chSysUnlock();
return TRUE;
}
@@ -604,18 +600,18 @@ bool_t mmcStopSequentialWrite(MMCDriver *mmcp) {
chDbgCheck(mmcp != NULL, "mmcStopSequentialWrite");
chSysLock();
- if (mmcp->mmc_state != MMC_WRITING) {
+ if (mmcp->state != MMC_WRITING) {
chSysUnlock();
return TRUE;
}
chSysUnlock();
- spiSend(mmcp->mmc_spip, sizeof(stop), stop);
- spiUnselect(mmcp->mmc_spip);
+ spiSend(mmcp->spip, sizeof(stop), stop);
+ spiUnselect(mmcp->spip);
chSysLock();
- if (mmcp->mmc_state == MMC_WRITING) {
- mmcp->mmc_state = MMC_READY;
+ if (mmcp->state == MMC_WRITING) {
+ mmcp->state = MMC_READY;
chSysUnlock();
return FALSE;
}
diff --git a/os/hal/src/pal.c b/os/hal/src/pal.c
index ce7c226e9..534935a55 100644
--- a/os/hal/src/pal.c
+++ b/os/hal/src/pal.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -64,9 +65,9 @@
ioportmask_t palReadBus(IOBus *bus) {
chDbgCheck((bus != NULL) &&
- (bus->bus_offset > PAL_IOPORTS_WIDTH), "palReadBus");
+ (bus->offset < PAL_IOPORTS_WIDTH), "palReadBus");
- return palReadGroup(bus->bus_portid, bus->bus_mask, bus->bus_offset);
+ return palReadGroup(bus->portid, bus->mask, bus->offset);
}
/**
@@ -89,9 +90,9 @@ ioportmask_t palReadBus(IOBus *bus) {
void palWriteBus(IOBus *bus, ioportmask_t bits) {
chDbgCheck((bus != NULL) &&
- (bus->bus_offset > PAL_IOPORTS_WIDTH), "palWriteBus");
+ (bus->offset < PAL_IOPORTS_WIDTH), "palWriteBus");
- palWriteGroup(bus->bus_portid, bus->bus_mask, bus->bus_offset, bits);
+ palWriteGroup(bus->portid, bus->mask, bus->offset, bits);
}
/**
@@ -112,9 +113,9 @@ void palWriteBus(IOBus *bus, ioportmask_t bits) {
void palSetBusMode(IOBus *bus, uint_fast8_t mode) {
chDbgCheck((bus != NULL) &&
- (bus->bus_offset > PAL_IOPORTS_WIDTH), "palSetBusMode");
+ (bus->offset < PAL_IOPORTS_WIDTH), "palSetBusMode");
- palSetGroupMode(bus->bus_portid, bus->bus_mask, mode);
+ palSetGroupMode(bus->portid, bus->mask, mode);
}
#endif /* HAL_USE_PAL */
diff --git a/os/hal/src/pwm.c b/os/hal/src/pwm.c
index cf619e508..e7dd6b64c 100644
--- a/os/hal/src/pwm.c
+++ b/os/hal/src/pwm.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -67,8 +68,8 @@ void pwmInit(void) {
*/
void pwmObjectInit(PWMDriver *pwmp) {
- pwmp->pd_state = PWM_STOP;
- pwmp->pd_config = NULL;
+ pwmp->state = PWM_STOP;
+ pwmp->config = NULL;
#if defined(PWM_DRIVER_EXT_INIT_HOOK)
PWM_DRIVER_EXT_INIT_HOOK(pwmp);
#endif
@@ -76,6 +77,8 @@ void pwmObjectInit(PWMDriver *pwmp) {
/**
* @brief Configures and activates the PWM peripheral.
+ * @note Starting a driver that is already in the @p PWM_READY state
+ * disables all the active channels.
*
* @param[in] pwmp pointer to a @p PWMDriver object
* @param[in] config pointer to a @p PWMConfig object
@@ -87,11 +90,12 @@ void pwmStart(PWMDriver *pwmp, const PWMConfig *config) {
chDbgCheck((pwmp != NULL) && (config != NULL), "pwmStart");
chSysLock();
- chDbgAssert((pwmp->pd_state == PWM_STOP) || (pwmp->pd_state == PWM_READY),
+ chDbgAssert((pwmp->state == PWM_STOP) || (pwmp->state == PWM_READY),
"pwmStart(), #1", "invalid state");
- pwmp->pd_config = config;
+ pwmp->config = config;
+ pwmp->period = config->period;
pwm_lld_start(pwmp);
- pwmp->pd_state = PWM_READY;
+ pwmp->state = PWM_READY;
chSysUnlock();
}
@@ -107,16 +111,46 @@ void pwmStop(PWMDriver *pwmp) {
chDbgCheck(pwmp != NULL, "pwmStop");
chSysLock();
- chDbgAssert((pwmp->pd_state == PWM_STOP) || (pwmp->pd_state == PWM_READY),
+ chDbgAssert((pwmp->state == PWM_STOP) || (pwmp->state == PWM_READY),
"pwmStop(), #1", "invalid state");
pwm_lld_stop(pwmp);
- pwmp->pd_state = PWM_STOP;
+ pwmp->state = PWM_STOP;
+ chSysUnlock();
+}
+
+/**
+ * @brief Changes the period the PWM peripheral.
+ * @details This function changes the period of a PWM unit that has already
+ * been activated using @p pwmStart().
+ * @pre The PWM unit must have been activated using @p pwmStart().
+ * @post The PWM unit period is changed to the new value.
+ * @note If a period is specified that is shorter than the pulse width
+ * programmed in one of the channels then the behavior is not
+ * guaranteed.
+ *
+ * @param[in] pwmp pointer to a @p PWMDriver object
+ * @param[in] period new cycle time in ticks
+ *
+ * @api
+ */
+void pwmChangePeriod(PWMDriver *pwmp, pwmcnt_t period) {
+
+ chDbgCheck(pwmp != NULL, "pwmChangePeriod");
+
+ chSysLock();
+ chDbgAssert(pwmp->state == PWM_READY,
+ "pwmChangePeriod(), #1", "invalid state");
+ pwmChangePeriodI(pwmp, period);
chSysUnlock();
}
/**
* @brief Enables a PWM channel.
- * @details Programs (or reprograms) a PWM channel.
+ * @pre The PWM unit must have been activated using @p pwmStart().
+ * @post The channel is active using the specified configuration.
+ * @note Depending on the hardware implementation this function has
+ * effect starting on the next cycle (recommended implementation)
+ * or immediately (fallback implementation).
*
* @param[in] pwmp pointer to a @p PWMDriver object
* @param[in] channel PWM channel identifier (0...PWM_CHANNELS-1)
@@ -132,7 +166,7 @@ void pwmEnableChannel(PWMDriver *pwmp,
"pwmEnableChannel");
chSysLock();
- chDbgAssert(pwmp->pd_state == PWM_READY,
+ chDbgAssert(pwmp->state == PWM_READY,
"pwmEnableChannel(), #1", "not ready");
pwm_lld_enable_channel(pwmp, channel, width);
chSysUnlock();
@@ -140,8 +174,12 @@ void pwmEnableChannel(PWMDriver *pwmp,
/**
* @brief Disables a PWM channel.
- * @details The channel is disabled and its output line returned to the
+ * @pre The PWM unit must have been activated using @p pwmStart().
+ * @post The channel is disabled and its output line returned to the
* idle state.
+ * @note Depending on the hardware implementation this function has
+ * effect starting on the next cycle (recommended implementation)
+ * or immediately (fallback implementation).
*
* @param[in] pwmp pointer to a @p PWMDriver object
* @param[in] channel PWM channel identifier (0...PWM_CHANNELS-1)
@@ -154,7 +192,7 @@ void pwmDisableChannel(PWMDriver *pwmp, pwmchannel_t channel) {
"pwmEnableChannel");
chSysLock();
- chDbgAssert(pwmp->pd_state == PWM_READY,
+ chDbgAssert(pwmp->state == PWM_READY,
"pwmDisableChannel(), #1", "not ready");
pwm_lld_disable_channel(pwmp, channel);
chSysUnlock();
diff --git a/os/hal/src/sdc.c b/os/hal/src/sdc.c
new file mode 100644
index 000000000..283a0ee75
--- /dev/null
+++ b/os/hal/src/sdc.c
@@ -0,0 +1,392 @@
+/*
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 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 sdc.c
+ * @brief SDC Driver code.
+ *
+ * @addtogroup SDC
+ * @{
+ */
+
+#include "ch.h"
+#include "hal.h"
+
+#if HAL_USE_SDC || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Wait for the card to complete pending operations.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @return The operation status.
+ * @retval FALSE the card is now in transfer state.
+ * @retval TRUE an error occurred while waiting or the card is in an
+ * unexpected state.
+ *
+ * @notapi
+ */
+bool_t sdc_wait_for_transfer_state(SDCDriver *sdcp) {
+ uint32_t resp[1];
+
+ while (TRUE) {
+ if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_SEND_STATUS,
+ sdcp->rca, resp) ||
+ SDC_R1_ERROR(resp[0]))
+ return TRUE;
+ switch (SDC_R1_STS(resp[0])) {
+ case SDC_STS_TRAN:
+ return FALSE;
+ case SDC_STS_DATA:
+ case SDC_STS_RCV:
+ case SDC_STS_PRG:
+#if SDC_NICE_WAITING
+ chThdSleepMilliseconds(1);
+#endif
+ continue;
+ default:
+ /* The card should have been initialized so any other state is not
+ valid and is reported as an error.*/
+ return TRUE;
+ }
+ }
+}
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief SDC Driver initialization.
+ * @note This function is implicitly invoked by @p halInit(), there is
+ * no need to explicitly initialize the driver.
+ *
+ * @init
+ */
+void sdcInit(void) {
+
+ sdc_lld_init();
+}
+
+/**
+ * @brief Initializes the standard part of a @p SDCDriver structure.
+ *
+ * @param[out] sdcp pointer to the @p SDCDriver object
+ *
+ * @init
+ */
+void sdcObjectInit(SDCDriver *sdcp) {
+
+ sdcp->state = SDC_STOP;
+ sdcp->config = NULL;
+}
+
+/**
+ * @brief Configures and activates the SDC peripheral.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] config pointer to the @p SDCConfig object, can be @p NULL if
+ * the driver supports a default configuration or
+ * requires no configuration
+ *
+ * @api
+ */
+void sdcStart(SDCDriver *sdcp, const SDCConfig *config) {
+
+ chDbgCheck(sdcp != NULL, "sdcStart");
+
+ chSysLock();
+ chDbgAssert((sdcp->state == SDC_STOP) || (sdcp->state == SDC_READY),
+ "sdcStart(), #1", "invalid state");
+ sdcp->config = config;
+ sdc_lld_start(sdcp);
+ sdcp->state = SDC_READY;
+ chSysUnlock();
+}
+
+/**
+ * @brief Deactivates the SDC peripheral.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ *
+ * @api
+ */
+void sdcStop(SDCDriver *sdcp) {
+
+ chDbgCheck(sdcp != NULL, "sdcStop");
+
+ chSysLock();
+ chDbgAssert((sdcp->state == SDC_STOP) || (sdcp->state == SDC_READY),
+ "sdcStop(), #1", "invalid state");
+ sdc_lld_stop(sdcp);
+ sdcp->state = SDC_STOP;
+ chSysUnlock();
+}
+
+/**
+ * @brief Performs the initialization procedure on the inserted card.
+ * @details This function should be invoked when a card is inserted and
+ * brings the driver in the @p SDC_ACTIVE state where it is possible
+ * to perform read and write operations.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @return The operation status.
+ * @retval FALSE operation succeeded, the driver is now
+ * in the @p SDC_ACTIVE state.
+ * @retval TRUE operation failed.
+ *
+ * @api
+ */
+bool_t sdcConnect(SDCDriver *sdcp) {
+ uint32_t resp[1];
+
+ chDbgCheck(sdcp != NULL, "sdcConnect");
+
+ chSysLock();
+ chDbgAssert((sdcp->state == SDC_READY) || (sdcp->state == SDC_ACTIVE),
+ "mmcConnect(), #1", "invalid state");
+ sdcp->state = SDC_CONNECTING;
+ chSysUnlock();
+
+ /* Card clock initialization.*/
+ sdc_lld_start_clk(sdcp);
+
+ /* Enforces the initial card state.*/
+ sdc_lld_send_cmd_none(sdcp, SDC_CMD_GO_IDLE_STATE, 0);
+
+ /* V2.0 cards detection.*/
+ if (!sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_SEND_IF_COND,
+ SDC_CMD8_PATTERN, resp))
+ sdcp->cardmode = SDC_MODE_CARDTYPE_SDV20;
+ /* Voltage verification.*/
+ if (((resp[0] >> 8) & 0xF) != 1)
+ goto failed;
+ if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_APP_CMD, 0, resp) ||
+ SDC_R1_ERROR(resp[0]))
+ goto failed;
+ else {
+#if SDC_MMC_SUPPORT
+ /* MMC or SD V1.1 detection.*/
+ if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_APP_CMD, 0, resp) ||
+ SDC_R1_ERROR(resp[0]))
+ sdcp->cardmode = SDC_MODE_CARDTYPE_MMC;
+ else
+#endif /* SDC_MMC_SUPPORT */
+ sdcp->cardmode = SDC_MODE_CARDTYPE_SDV11;
+ }
+
+#if SDC_MMC_SUPPORT
+ if ((sdcp->cardmode & SDC_MODE_CARDTYPE_MASK) == SDC_MODE_CARDTYPE_MMC) {
+ /* TODO: MMC initialization.*/
+ return TRUE;
+ }
+ else
+#endif /* SDC_MMC_SUPPORT */
+ {
+ unsigned i;
+ uint32_t ocr;
+
+ /* SD initialization.*/
+ if ((sdcp->cardmode & SDC_MODE_CARDTYPE_MASK) == SDC_MODE_CARDTYPE_SDV20)
+ ocr = 0xC0100000;
+ else
+ ocr = 0x80100000;
+
+ /* SD-type initialization. */
+ i = 0;
+ while (TRUE) {
+ if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_APP_CMD, 0, resp) ||
+ SDC_R1_ERROR(resp[0]))
+ goto failed;
+ if (sdc_lld_send_cmd_short(sdcp, SDC_CMD_APP_OP_COND, ocr, resp))
+ goto failed;
+ if ((resp[0] & 0x80000000) != 0) {
+ if (resp[0] & 0x40000000)
+ sdcp->cardmode |= SDC_MODE_HIGH_CAPACITY;
+ break;
+ }
+ if (++i >= SDC_INIT_RETRY)
+ goto failed;
+ chThdSleepMilliseconds(10);
+ }
+ }
+
+ /* Reads CID.*/
+ if (sdc_lld_send_cmd_long_crc(sdcp, SDC_CMD_ALL_SEND_CID, 0, sdcp->cid))
+ goto failed;
+
+ /* Asks for the RCA.*/
+ if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_SEND_RELATIVE_ADDR,
+ 0, &sdcp->rca))
+ goto failed;
+
+ /* Reads CSD.*/
+ if (sdc_lld_send_cmd_long_crc(sdcp, SDC_CMD_SEND_CSD, sdcp->rca, sdcp->csd))
+ goto failed;
+
+ /* Switches to high speed.*/
+ sdc_lld_set_data_clk(sdcp);
+
+ /* Selects the card for operations.*/
+ if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_SEL_DESEL_CARD,
+ sdcp->rca, resp))
+ goto failed;
+
+ /* Block length fixed at 512 bytes.*/
+ if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_SET_BLOCKLEN,
+ SDC_BLOCK_SIZE, resp) ||
+ SDC_R1_ERROR(resp[0]))
+ goto failed;
+
+ /* Switches to wide bus mode.*/
+ switch (sdcp->cardmode & SDC_MODE_CARDTYPE_MASK) {
+ case SDC_MODE_CARDTYPE_SDV11:
+ case SDC_MODE_CARDTYPE_SDV20:
+ sdc_lld_set_bus_mode(sdcp, SDC_MODE_4BIT);
+ if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_APP_CMD, sdcp->rca, resp) ||
+ SDC_R1_ERROR(resp[0]))
+ goto failed;
+ if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_SET_BUS_WIDTH, 2, resp) ||
+ SDC_R1_ERROR(resp[0]))
+ goto failed;
+ }
+
+ sdcp->state = SDC_ACTIVE;
+ return FALSE;
+failed:
+ sdc_lld_stop_clk(sdcp);
+ sdcp->state = SDC_READY;
+ return TRUE;
+}
+
+/**
+ * @brief Brings the driver in a state safe for card removal.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @return The operation status.
+ * @retval FALSE the operation succeeded and the driver is now
+ * in the @p SDC_READY state.
+ * @retval TRUE the operation failed.
+ *
+ * @api
+ */
+bool_t sdcDisconnect(SDCDriver *sdcp) {
+
+ chDbgCheck(sdcp != NULL, "sdcDisconnect");
+
+ chSysLock();
+ chDbgAssert(sdcp->state == SDC_ACTIVE,
+ "sdcDisconnect(), #1", "invalid state");
+ if (sdcp->state == SDC_READY) {
+ chSysUnlock();
+ return FALSE;
+ }
+ sdcp->state = SDC_DISCONNECTING;
+ chSysUnlock();
+
+ /* Waits for eventual pending operations completion.*/
+ if (sdc_wait_for_transfer_state(sdcp))
+ return TRUE;
+
+ /* Card clock stopped.*/
+ sdc_lld_stop_clk(sdcp);
+
+ sdcp->state = SDC_READY;
+ return FALSE;
+}
+
+/**
+ * @brief Reads one or more blocks.
+ * @pre The driver must be in the @p SDC_ACTIVE state after a successful
+ * sdcConnect() invocation.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] startblk first block to read
+ * @param[out] buf pointer to the read buffer
+ * @param[in] n number of blocks to read
+ * @return The operation status.
+ * @retval FALSE operation succeeded, the requested blocks have been
+ * read.
+ * @retval TRUE operation failed, the state of the buffer is uncertain.
+ *
+ * @api
+ */
+bool_t sdcRead(SDCDriver *sdcp, uint32_t startblk,
+ uint8_t *buf, uint32_t n) {
+ bool_t err;
+
+ chDbgCheck((sdcp != NULL) && (buf != NULL) && (n > 0), "sdcRead");
+
+ chSysLock();
+ chDbgAssert(sdcp->state == SDC_ACTIVE, "sdcRead(), #1", "invalid state");
+ sdcp->state = SDC_READING;
+ chSysUnlock();
+
+ err = sdc_lld_read(sdcp, startblk, buf, n);
+ sdcp->state = SDC_ACTIVE;
+ return err;
+}
+
+/**
+ * @brief Writes one or more blocks.
+ * @pre The driver must be in the @p SDC_ACTIVE state after a successful
+ * sdcConnect() invocation.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] startblk first block to write
+ * @param[out] buf pointer to the write buffer
+ * @param[in] n number of blocks to write
+ * @return The operation status.
+ * @retval FALSE operation succeeded, the requested blocks have been
+ * written.
+ * @retval TRUE operation failed.
+ *
+ * @api
+ */
+bool_t sdcWrite(SDCDriver *sdcp, uint32_t startblk,
+ const uint8_t *buf, uint32_t n) {
+ bool_t err;
+
+ chDbgCheck((sdcp != NULL) && (buf != NULL) && (n > 0), "sdcWrite");
+
+ chSysLock();
+ chDbgAssert(sdcp->state == SDC_ACTIVE, "sdcWrite(), #1", "invalid state");
+ sdcp->state = SDC_WRITING;
+ chSysUnlock();
+
+ err = sdc_lld_write(sdcp, startblk, buf, n);
+ sdcp->state = SDC_ACTIVE;
+ return err;
+}
+
+#endif /* HAL_USE_SDC */
+
+/** @} */
diff --git a/os/hal/src/serial.c b/os/hal/src/serial.c
index aafedcc6b..414689aac 100644
--- a/os/hal/src/serial.c
+++ b/os/hal/src/serial.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
diff --git a/os/hal/src/serial_usb.c b/os/hal/src/serial_usb.c
index 62a901162..3f53d7df0 100644
--- a/os/hal/src/serial_usb.c
+++ b/os/hal/src/serial_usb.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -58,44 +59,44 @@ static cdc_linecoding_t linecoding = {
static size_t writes(void *ip, const uint8_t *bp, size_t n) {
- return chOQWriteTimeout(&((SerialDriver *)ip)->oqueue, bp,
+ return chOQWriteTimeout(&((SerialUSBDriver *)ip)->oqueue, bp,
n, TIME_INFINITE);
}
static size_t reads(void *ip, uint8_t *bp, size_t n) {
- return chIQReadTimeout(&((SerialDriver *)ip)->iqueue, bp,
+ return chIQReadTimeout(&((SerialUSBDriver *)ip)->iqueue, bp,
n, TIME_INFINITE);
}
static bool_t putwouldblock(void *ip) {
- return chOQIsFullI(&((SerialDriver *)ip)->oqueue);
+ return chOQIsFullI(&((SerialUSBDriver *)ip)->oqueue);
}
static bool_t getwouldblock(void *ip) {
- return chIQIsEmptyI(&((SerialDriver *)ip)->iqueue);
+ return chIQIsEmptyI(&((SerialUSBDriver *)ip)->iqueue);
}
static msg_t putt(void *ip, uint8_t b, systime_t timeout) {
- return chOQPutTimeout(&((SerialDriver *)ip)->oqueue, b, timeout);
+ return chOQPutTimeout(&((SerialUSBDriver *)ip)->oqueue, b, timeout);
}
static msg_t gett(void *ip, systime_t timeout) {
- return chIQGetTimeout(&((SerialDriver *)ip)->iqueue, timeout);
+ return chIQGetTimeout(&((SerialUSBDriver *)ip)->iqueue, timeout);
}
static size_t writet(void *ip, const uint8_t *bp, size_t n, systime_t time) {
- return chOQWriteTimeout(&((SerialDriver *)ip)->oqueue, bp, n, time);
+ return chOQWriteTimeout(&((SerialUSBDriver *)ip)->oqueue, bp, n, time);
}
static size_t readt(void *ip, uint8_t *bp, size_t n, systime_t time) {
- return chIQReadTimeout(&((SerialDriver *)ip)->iqueue, bp, n, time);
+ return chIQReadTimeout(&((SerialUSBDriver *)ip)->iqueue, bp, n, time);
}
static ioflags_t getflags(void *ip) {
@@ -119,11 +120,14 @@ static void inotify(GenericQueue *qp) {
emptied, then a whole packet is loaded in the queue.*/
if (chIQIsEmptyI(&sdup->iqueue)) {
- n = usbReadI(sdup->config->usbp, sdup->config->data_available_ep,
- sdup->iqueue.q_buffer, SERIAL_USB_BUFFERS_SIZE);
- if (n > 0) {
+ n = usbReadPacketI(sdup->config->usbp, DATA_AVAILABLE_EP,
+ sdup->iqueue.q_buffer, SERIAL_USB_BUFFERS_SIZE);
+ if (n != USB_ENDPOINT_BUSY) {
+ chIOAddFlagsI(sdup, IO_INPUT_AVAILABLE);
sdup->iqueue.q_rdptr = sdup->iqueue.q_buffer;
- chSemSetCounterI(&sdup->iqueue.q_sem, n);
+ sdup->iqueue.q_counter = n;
+ while (notempty(&sdup->iqueue.q_waiting))
+ chSchReadyI(fifo_remove(&sdup->iqueue.q_waiting))->p_u.rdymsg = Q_OK;
}
}
}
@@ -133,15 +137,19 @@ static void inotify(GenericQueue *qp) {
*/
static void onotify(GenericQueue *qp) {
SerialUSBDriver *sdup = (SerialUSBDriver *)qp->q_rdptr;
- size_t n;
+ size_t w, n;
/* If there is any data in the output queue then it is sent within a
single packet and the queue is emptied.*/
- n = usbWriteI(sdup->config->usbp, sdup->config->data_request_ep,
- sdup->oqueue.q_buffer, chOQGetFullI(&sdup->oqueue));
- if (n > 0) {
+ n = chOQGetFullI(&sdup->oqueue);
+ w = usbWritePacketI(sdup->config->usbp, DATA_REQUEST_EP,
+ sdup->oqueue.q_buffer, n);
+ if (w != USB_ENDPOINT_BUSY) {
+ chIOAddFlagsI(sdup, IO_OUTPUT_EMPTY);
sdup->oqueue.q_wrptr = sdup->oqueue.q_buffer;
- chSemSetCounterI(&sdup->oqueue.q_sem, SERIAL_USB_BUFFERS_SIZE);
+ sdup->oqueue.q_counter = chQSizeI(&sdup->oqueue);
+ while (notempty(&sdup->oqueue.q_waiting))
+ chSchReadyI(fifo_remove(&sdup->oqueue.q_waiting))->p_u.rdymsg = Q_OK;
}
}
@@ -165,12 +173,6 @@ void sduInit(void) {
* outside, usually in the hardware initialization code.
*
* @param[out] sdup pointer to a @p SerialUSBDriver structure
- * @param[in] inotify pointer to a callback function that is invoked when
- * some data is read from the Queue. The value can be
- * @p NULL.
- * @param[in] onotify pointer to a callback function that is invoked when
- * some data is written in the Queue. The value can be
- * @p NULL.
*
* @init
*/
@@ -206,7 +208,7 @@ void sduStart(SerialUSBDriver *sdup, const SerialUSBConfig *config) {
"invalid state");
sdup->config = config;
usbStart(config->usbp, &config->usb_config);
- config->usbp->usb_param = sdup;
+ config->usbp->param = sdup;
sdup->state = SDU_READY;
chSysUnlock();
}
@@ -242,11 +244,16 @@ void sduStop(SerialUSBDriver *sdup) {
* - CDC_SET_LINE_CODING.
* - CDC_SET_CONTROL_LINE_STATE.
* .
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @return The hook status.
+ * @retval TRUE Message handled internally.
+ * @retval FALSE Message not handled.
*/
bool_t sduRequestsHook(USBDriver *usbp) {
- if ((usbp->usb_setup[0] & USB_RTYPE_TYPE_MASK) == USB_RTYPE_TYPE_CLASS) {
- switch (usbp->usb_setup[1]) {
+ if ((usbp->setup[0] & USB_RTYPE_TYPE_MASK) == USB_RTYPE_TYPE_CLASS) {
+ switch (usbp->setup[1]) {
case CDC_GET_LINE_CODING:
usbSetupTransfer(usbp, (uint8_t *)&linecoding, sizeof(linecoding), NULL);
return TRUE;
@@ -265,36 +272,44 @@ bool_t sduRequestsHook(USBDriver *usbp) {
}
/**
- * @brief Default data request callback.
+ * @brief Default data transmitted callback.
* @details The application must use this function as callback for the IN
* data endpoint.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
*/
-void sduDataRequest(USBDriver *usbp, usbep_t ep) {
- SerialUSBDriver *sdup = usbp->usb_param;
- size_t n;
+void sduDataTransmitted(USBDriver *usbp, usbep_t ep) {
+ SerialUSBDriver *sdup = usbp->param;
+ size_t n, w;
chSysLockFromIsr();
/* If there is any data in the output queue then it is sent within a
single packet and the queue is emptied.*/
n = chOQGetFullI(&sdup->oqueue);
if (n > 0) {
- n = usbWriteI(usbp, ep, sdup->oqueue.q_buffer, n);
- if (n > 0) {
- sdup->oqueue.q_wrptr = sdup->oqueue.q_buffer;
- chSemSetCounterI(&sdup->oqueue.q_sem, SERIAL_USB_BUFFERS_SIZE);
+ w = usbWritePacketI(usbp, ep, sdup->oqueue.q_buffer, n);
+ if (w != USB_ENDPOINT_BUSY) {
chIOAddFlagsI(sdup, IO_OUTPUT_EMPTY);
+ sdup->oqueue.q_wrptr = sdup->oqueue.q_buffer;
+ sdup->oqueue.q_counter = chQSizeI(&sdup->oqueue);
+ while (notempty(&sdup->oqueue.q_waiting))
+ chSchReadyI(fifo_remove(&sdup->oqueue.q_waiting))->p_u.rdymsg = Q_OK;
}
}
chSysUnlockFromIsr();
}
/**
- * @brief Default data available callback.
+ * @brief Default data received callback.
* @details The application must use this function as callback for the OUT
* data endpoint.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
*/
-void sduDataAvailable(USBDriver *usbp, usbep_t ep) {
- SerialUSBDriver *sdup = usbp->usb_param;
+void sduDataReceived(USBDriver *usbp, usbep_t ep) {
+ SerialUSBDriver *sdup = usbp->param;
chSysLockFromIsr();
/* Writes to the input queue can only happen when the queue has been
@@ -302,11 +317,14 @@ void sduDataAvailable(USBDriver *usbp, usbep_t ep) {
if (chIQIsEmptyI(&sdup->iqueue)) {
size_t n;
- n = usbReadI(usbp, ep, sdup->iqueue.q_buffer, SERIAL_USB_BUFFERS_SIZE);
- if (n > 0) {
- sdup->iqueue.q_rdptr = sdup->iqueue.q_buffer;
- chSemSetCounterI(&sdup->iqueue.q_sem, n);
+ n = usbReadPacketI(usbp, ep, sdup->iqueue.q_buffer,
+ SERIAL_USB_BUFFERS_SIZE);
+ if (n != USB_ENDPOINT_BUSY) {
chIOAddFlagsI(sdup, IO_INPUT_AVAILABLE);
+ sdup->iqueue.q_rdptr = sdup->iqueue.q_buffer;
+ sdup->iqueue.q_counter = n;
+ while (notempty(&sdup->iqueue.q_waiting))
+ chSchReadyI(fifo_remove(&sdup->iqueue.q_waiting))->p_u.rdymsg = Q_OK;
}
}
chSysUnlockFromIsr();
@@ -316,8 +334,11 @@ void sduDataAvailable(USBDriver *usbp, usbep_t ep) {
* @brief Default data received callback.
* @details The application must use this function as callback for the IN
* interrupt endpoint.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
*/
-void sduInterruptRequest(USBDriver *usbp, usbep_t ep) {
+void sduInterruptTransmitted(USBDriver *usbp, usbep_t ep) {
(void)usbp;
(void)ep;
diff --git a/os/hal/src/spi.c b/os/hal/src/spi.c
index e99126b9e..aaf0115eb 100644
--- a/os/hal/src/spi.c
+++ b/os/hal/src/spi.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -67,16 +68,16 @@ void spiInit(void) {
*/
void spiObjectInit(SPIDriver *spip) {
- spip->spd_state = SPI_STOP;
- spip->spd_config = NULL;
+ spip->state = SPI_STOP;
+ spip->config = NULL;
#if SPI_USE_WAIT
- spip->spd_thread = NULL;
+ spip->thread = NULL;
#endif /* SPI_USE_WAIT */
#if SPI_USE_MUTUAL_EXCLUSION
#if CH_USE_MUTEXES
- chMtxInit(&spip->spd_mutex);
+ chMtxInit(&spip->mutex);
#else
- chSemInit(&spip->spd_semaphore, 1);
+ chSemInit(&spip->semaphore, 1);
#endif
#endif /* SPI_USE_MUTUAL_EXCLUSION */
#if defined(SPI_DRIVER_EXT_INIT_HOOK)
@@ -97,11 +98,11 @@ void spiStart(SPIDriver *spip, const SPIConfig *config) {
chDbgCheck((spip != NULL) && (config != NULL), "spiStart");
chSysLock();
- chDbgAssert((spip->spd_state == SPI_STOP) || (spip->spd_state == SPI_READY),
+ chDbgAssert((spip->state == SPI_STOP) || (spip->state == SPI_READY),
"spiStart(), #1", "invalid state");
- spip->spd_config = config;
+ spip->config = config;
spi_lld_start(spip);
- spip->spd_state = SPI_READY;
+ spip->state = SPI_READY;
chSysUnlock();
}
@@ -119,11 +120,11 @@ void spiStop(SPIDriver *spip) {
chDbgCheck(spip != NULL, "spiStop");
chSysLock();
- chDbgAssert((spip->spd_state == SPI_STOP) || (spip->spd_state == SPI_READY),
+ chDbgAssert((spip->state == SPI_STOP) || (spip->state == SPI_READY),
"spiStop(), #1", "invalid state");
spi_lld_unselect(spip);
spi_lld_stop(spip);
- spip->spd_state = SPI_STOP;
+ spip->state = SPI_STOP;
chSysUnlock();
}
@@ -139,8 +140,7 @@ void spiSelect(SPIDriver *spip) {
chDbgCheck(spip != NULL, "spiSelect");
chSysLock();
- chDbgAssert(spip->spd_state == SPI_READY,
- "spiSelect(), #1", "not ready");
+ chDbgAssert(spip->state == SPI_READY, "spiSelect(), #1", "not ready");
spiSelectI(spip);
chSysUnlock();
}
@@ -158,8 +158,7 @@ void spiUnselect(SPIDriver *spip) {
chDbgCheck(spip != NULL, "spiUnselect");
chSysLock();
- chDbgAssert(spip->spd_state == SPI_READY,
- "spiUnselect(), #1", "not ready");
+ chDbgAssert(spip->state == SPI_READY, "spiUnselect(), #1", "not ready");
spiUnselectI(spip);
chSysUnlock();
}
@@ -182,8 +181,7 @@ void spiStartIgnore(SPIDriver *spip, size_t n) {
chDbgCheck((spip != NULL) && (n > 0), "spiStartIgnore");
chSysLock();
- chDbgAssert(spip->spd_state == SPI_READY,
- "spiStartIgnore(), #1", "not ready");
+ chDbgAssert(spip->state == SPI_READY, "spiStartIgnore(), #1", "not ready");
spiStartIgnoreI(spip, n);
chSysUnlock();
}
@@ -212,8 +210,7 @@ void spiStartExchange(SPIDriver *spip, size_t n,
"spiStartExchange");
chSysLock();
- chDbgAssert(spip->spd_state == SPI_READY,
- "spiStartExchange(), #1", "not ready");
+ chDbgAssert(spip->state == SPI_READY, "spiStartExchange(), #1", "not ready");
spiStartExchangeI(spip, n, txbuf, rxbuf);
chSysUnlock();
}
@@ -239,8 +236,7 @@ void spiStartSend(SPIDriver *spip, size_t n, const void *txbuf) {
"spiStartSend");
chSysLock();
- chDbgAssert(spip->spd_state == SPI_READY,
- "spiStartSend(), #1", "not ready");
+ chDbgAssert(spip->state == SPI_READY, "spiStartSend(), #1", "not ready");
spiStartSendI(spip, n, txbuf);
chSysUnlock();
}
@@ -266,8 +262,7 @@ void spiStartReceive(SPIDriver *spip, size_t n, void *rxbuf) {
"spiStartReceive");
chSysLock();
- chDbgAssert(spip->spd_state == SPI_READY,
- "spiStartReceive(), #1", "not ready");
+ chDbgAssert(spip->state == SPI_READY, "spiStartReceive(), #1", "not ready");
spiStartReceiveI(spip, n, rxbuf);
chSysUnlock();
}
@@ -280,7 +275,7 @@ void spiStartReceive(SPIDriver *spip, size_t n, void *rxbuf) {
* @pre In order to use this function the option @p SPI_USE_WAIT must be
* enabled.
* @pre In order to use this function the driver must have been configured
- * without callbacks (@p spc_endcb = @p NULL).
+ * without callbacks (@p end_cb = @p NULL).
*
* @param[in] spip pointer to the @p SPIDriver object
* @param[in] n number of words to be ignored
@@ -292,10 +287,8 @@ void spiIgnore(SPIDriver *spip, size_t n) {
chDbgCheck((spip != NULL) && (n > 0), "spiIgnoreWait");
chSysLock();
- chDbgAssert(spip->spd_state == SPI_READY,
- "spiIgnore(), #1", "not ready");
- chDbgAssert(spip->spd_config->spc_endcb == NULL,
- "spiIgnore(), #2", "has callback");
+ chDbgAssert(spip->state == SPI_READY, "spiIgnore(), #1", "not ready");
+ chDbgAssert(spip->config->end_cb == NULL, "spiIgnore(), #2", "has callback");
spiStartIgnoreI(spip, n);
_spi_wait_s(spip);
chSysUnlock();
@@ -308,7 +301,7 @@ void spiIgnore(SPIDriver *spip, size_t n) {
* @pre In order to use this function the option @p SPI_USE_WAIT must be
* enabled.
* @pre In order to use this function the driver must have been configured
- * without callbacks (@p spc_endcb = @p NULL).
+ * without callbacks (@p end_cb = @p NULL).
* @note The buffers are organized as uint8_t arrays for data sizes below
* or equal to 8 bits else it is organized as uint16_t arrays.
*
@@ -326,9 +319,8 @@ void spiExchange(SPIDriver *spip, size_t n,
"spiExchange");
chSysLock();
- chDbgAssert(spip->spd_state == SPI_READY,
- "spiExchange(), #1", "not ready");
- chDbgAssert(spip->spd_config->spc_endcb == NULL,
+ chDbgAssert(spip->state == SPI_READY, "spiExchange(), #1", "not ready");
+ chDbgAssert(spip->config->end_cb == NULL,
"spiExchange(), #2", "has callback");
spiStartExchangeI(spip, n, txbuf, rxbuf);
_spi_wait_s(spip);
@@ -341,7 +333,7 @@ void spiExchange(SPIDriver *spip, size_t n,
* @pre In order to use this function the option @p SPI_USE_WAIT must be
* enabled.
* @pre In order to use this function the driver must have been configured
- * without callbacks (@p spc_endcb = @p NULL).
+ * without callbacks (@p end_cb = @p NULL).
* @note The buffers are organized as uint8_t arrays for data sizes below
* or equal to 8 bits else it is organized as uint16_t arrays.
*
@@ -353,14 +345,11 @@ void spiExchange(SPIDriver *spip, size_t n,
*/
void spiSend(SPIDriver *spip, size_t n, const void *txbuf) {
- chDbgCheck((spip != NULL) && (n > 0) && (txbuf != NULL),
- "spiSend");
+ chDbgCheck((spip != NULL) && (n > 0) && (txbuf != NULL), "spiSend");
chSysLock();
- chDbgAssert(spip->spd_state == SPI_READY,
- "spiSend(), #1", "not ready");
- chDbgAssert(spip->spd_config->spc_endcb == NULL,
- "spiSend(), #2", "has callback");
+ chDbgAssert(spip->state == SPI_READY, "spiSend(), #1", "not ready");
+ chDbgAssert(spip->config->end_cb == NULL, "spiSend(), #2", "has callback");
spiStartSendI(spip, n, txbuf);
_spi_wait_s(spip);
chSysUnlock();
@@ -372,7 +361,7 @@ void spiSend(SPIDriver *spip, size_t n, const void *txbuf) {
* @pre In order to use this function the option @p SPI_USE_WAIT must be
* enabled.
* @pre In order to use this function the driver must have been configured
- * without callbacks (@p spc_endcb = @p NULL).
+ * without callbacks (@p end_cb = @p NULL).
* @note The buffers are organized as uint8_t arrays for data sizes below
* or equal to 8 bits else it is organized as uint16_t arrays.
*
@@ -388,9 +377,8 @@ void spiReceive(SPIDriver *spip, size_t n, void *rxbuf) {
"spiReceive");
chSysLock();
- chDbgAssert(spip->spd_state == SPI_READY,
- "spiReceive(), #1", "not ready");
- chDbgAssert(spip->spd_config->spc_endcb == NULL,
+ chDbgAssert(spip->state == SPI_READY, "spiReceive(), #1", "not ready");
+ chDbgAssert(spip->config->end_cb == NULL,
"spiReceive(), #2", "has callback");
spiStartReceiveI(spip, n, rxbuf);
_spi_wait_s(spip);
@@ -415,9 +403,9 @@ void spiAcquireBus(SPIDriver *spip) {
chDbgCheck(spip != NULL, "spiAcquireBus");
#if CH_USE_MUTEXES
- chMtxLock(&spip->spd_mutex);
+ chMtxLock(&spip->mutex);
#elif CH_USE_SEMAPHORES
- chSemWait(&spip->spd_semaphore);
+ chSemWait(&spip->semaphore);
#endif
}
@@ -438,7 +426,7 @@ void spiReleaseBus(SPIDriver *spip) {
(void)spip;
chMtxUnlock();
#elif CH_USE_SEMAPHORES
- chSemSignal(&spip->spd_semaphore);
+ chSemSignal(&spip->semaphore);
#endif
}
#endif /* SPI_USE_MUTUAL_EXCLUSION */
diff --git a/os/hal/src/uart.c b/os/hal/src/uart.c
index 4a21e907f..05fdbb168 100644
--- a/os/hal/src/uart.c
+++ b/os/hal/src/uart.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -67,10 +68,10 @@ void uartInit(void) {
*/
void uartObjectInit(UARTDriver *uartp) {
- uartp->ud_state = UART_STOP;
- uartp->ud_txstate = UART_TX_IDLE;
- uartp->ud_rxstate = UART_RX_IDLE;
- uartp->ud_config = NULL;
+ uartp->state = UART_STOP;
+ uartp->txstate = UART_TX_IDLE;
+ uartp->rxstate = UART_RX_IDLE;
+ uartp->config = NULL;
/* Optional, user-defined initializer.*/
#if defined(UART_DRIVER_EXT_INIT_HOOK)
UART_DRIVER_EXT_INIT_HOOK(uartp);
@@ -90,14 +91,12 @@ void uartStart(UARTDriver *uartp, const UARTConfig *config) {
chDbgCheck((uartp != NULL) && (config != NULL), "uartStart");
chSysLock();
- chDbgAssert((uartp->ud_state == UART_STOP) ||
- (uartp->ud_state == UART_READY),
- "uartStart(), #1",
- "invalid state");
+ chDbgAssert((uartp->state == UART_STOP) || (uartp->state == UART_READY),
+ "uartStart(), #1", "invalid state");
- uartp->ud_config = config;
+ uartp->config = config;
uart_lld_start(uartp);
- uartp->ud_state = UART_READY;
+ uartp->state = UART_READY;
chSysUnlock();
}
@@ -113,15 +112,13 @@ void uartStop(UARTDriver *uartp) {
chDbgCheck(uartp != NULL, "uartStop");
chSysLock();
- chDbgAssert((uartp->ud_state == UART_STOP) ||
- (uartp->ud_state == UART_READY),
- "uartStop(), #1",
- "invalid state");
+ chDbgAssert((uartp->state == UART_STOP) || (uartp->state == UART_READY),
+ "uartStop(), #1", "invalid state");
uart_lld_stop(uartp);
- uartp->ud_state = UART_STOP;
- uartp->ud_txstate = UART_TX_IDLE;
- uartp->ud_rxstate = UART_RX_IDLE;
+ uartp->state = UART_STOP;
+ uartp->txstate = UART_TX_IDLE;
+ uartp->rxstate = UART_RX_IDLE;
chSysUnlock();
}
@@ -142,13 +139,11 @@ void uartStartSend(UARTDriver *uartp, size_t n, const void *txbuf) {
"uartStartSend");
chSysLock();
- chDbgAssert((uartp->ud_state == UART_READY) &&
- (uartp->ud_txstate == UART_TX_IDLE),
- "uartStartSend(), #1",
- "not active");
+ chDbgAssert((uartp->state == UART_READY) && (uartp->txstate == UART_TX_IDLE),
+ "uartStartSend(), #1", "not active");
uart_lld_start_send(uartp, n, txbuf);
- uartp->ud_txstate = UART_TX_ACTIVE;
+ uartp->txstate = UART_TX_ACTIVE;
chSysUnlock();
}
@@ -169,12 +164,11 @@ void uartStartSendI(UARTDriver *uartp, size_t n, const void *txbuf) {
chDbgCheck((uartp != NULL) && (n > 0) && (txbuf != NULL),
"uartStartSendI");
- chDbgAssert((uartp->ud_state == UART_READY) &&
- (uartp->ud_txstate != UART_TX_ACTIVE),
- "uartStartSendI(), #1",
- "not active");
+ chDbgAssert((uartp->state == UART_READY) &&
+ (uartp->txstate != UART_TX_ACTIVE),
+ "uartStartSendI(), #1", "not active");
uart_lld_start_send(uartp, n, txbuf);
- uartp->ud_txstate = UART_TX_ACTIVE;
+ uartp->txstate = UART_TX_ACTIVE;
}
/**
@@ -195,13 +189,11 @@ size_t uartStopSend(UARTDriver *uartp) {
chDbgCheck(uartp != NULL, "uartStopSend");
chSysLock();
- chDbgAssert(uartp->ud_state == UART_READY,
- "uartStopSend(), #1",
- "not active");
+ chDbgAssert(uartp->state == UART_READY, "uartStopSend(), #1", "not active");
- if (uartp->ud_txstate == UART_TX_ACTIVE) {
+ if (uartp->txstate == UART_TX_ACTIVE) {
n = uart_lld_stop_send(uartp);
- uartp->ud_txstate = UART_TX_IDLE;
+ uartp->txstate = UART_TX_IDLE;
}
else
n = 0;
@@ -226,13 +218,11 @@ size_t uartStopSendI(UARTDriver *uartp) {
chDbgCheck(uartp != NULL, "uartStopSendI");
- chDbgAssert(uartp->ud_state == UART_READY,
- "uartStopSendI(), #1",
- "not active");
+ chDbgAssert(uartp->state == UART_READY, "uartStopSendI(), #1", "not active");
- if (uartp->ud_txstate == UART_TX_ACTIVE) {
+ if (uartp->txstate == UART_TX_ACTIVE) {
size_t n = uart_lld_stop_send(uartp);
- uartp->ud_txstate = UART_TX_IDLE;
+ uartp->txstate = UART_TX_IDLE;
return n;
}
return 0;
@@ -255,13 +245,11 @@ void uartStartReceive(UARTDriver *uartp, size_t n, void *rxbuf) {
"uartStartReceive");
chSysLock();
- chDbgAssert((uartp->ud_state == UART_READY) &&
- (uartp->ud_rxstate == UART_RX_IDLE),
- "uartStartReceive(), #1",
- "not active");
+ chDbgAssert((uartp->state == UART_READY) && (uartp->rxstate == UART_RX_IDLE),
+ "uartStartReceive(), #1", "not active");
uart_lld_start_receive(uartp, n, rxbuf);
- uartp->ud_rxstate = UART_RX_ACTIVE;
+ uartp->rxstate = UART_RX_ACTIVE;
chSysUnlock();
}
@@ -282,13 +270,11 @@ void uartStartReceiveI(UARTDriver *uartp, size_t n, void *rxbuf) {
chDbgCheck((uartp != NULL) && (n > 0) && (rxbuf != NULL),
"uartStartReceiveI");
- chDbgAssert((uartp->ud_state == UART_READY) &&
- (uartp->ud_rxstate == UART_RX_IDLE),
- "uartStartReceiveI(), #1",
- "not active");
+ chDbgAssert((uartp->state == UART_READY) && (uartp->rxstate == UART_RX_IDLE),
+ "uartStartReceiveI(), #1", "not active");
uart_lld_start_receive(uartp, n, rxbuf);
- uartp->ud_rxstate = UART_RX_ACTIVE;
+ uartp->rxstate = UART_RX_ACTIVE;
}
/**
@@ -309,13 +295,12 @@ size_t uartStopReceive(UARTDriver *uartp) {
chDbgCheck(uartp != NULL, "uartStopReceive");
chSysLock();
- chDbgAssert(uartp->ud_state == UART_READY,
- "uartStopReceive(), #1",
- "not active");
+ chDbgAssert(uartp->state == UART_READY,
+ "uartStopReceive(), #1", "not active");
- if (uartp->ud_rxstate == UART_RX_ACTIVE) {
+ if (uartp->rxstate == UART_RX_ACTIVE) {
n = uart_lld_stop_receive(uartp);
- uartp->ud_rxstate = UART_RX_IDLE;
+ uartp->rxstate = UART_RX_IDLE;
}
else
n = 0;
@@ -339,13 +324,12 @@ size_t uartStopReceive(UARTDriver *uartp) {
size_t uartStopReceiveI(UARTDriver *uartp) {
chDbgCheck(uartp != NULL, "uartStopReceiveI");
- chDbgAssert(uartp->ud_state == UART_READY,
- "uartStopReceiveI(), #1",
- "not active");
+ chDbgAssert(uartp->state == UART_READY,
+ "uartStopReceiveI(), #1", "not active");
- if (uartp->ud_rxstate == UART_RX_ACTIVE) {
+ if (uartp->rxstate == UART_RX_ACTIVE) {
size_t n = uart_lld_stop_receive(uartp);
- uartp->ud_rxstate = UART_RX_IDLE;
+ uartp->rxstate = UART_RX_IDLE;
return n;
}
return 0;
diff --git a/os/hal/src/usb.c b/os/hal/src/usb.c
index 3cc076443..484590f3b 100644
--- a/os/hal/src/usb.c
+++ b/os/hal/src/usb.c
@@ -1,5 +1,6 @@
/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
+ ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
+ 2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@@ -54,74 +55,19 @@ static const uint8_t halted_status[] = {0x01, 0x00};
*
* @param[in] usbp pointer to the @p USBDriver object
*/
-void set_address(USBDriver *usbp) {
+static void set_address(USBDriver *usbp) {
- usbp->usb_address = usbp->usb_setup[2];
- usb_lld_set_address(usbp, usbp->usb_address);
- if (usbp->usb_config->uc_event_cb)
- usbp->usb_config->uc_event_cb(usbp, USB_EVENT_ADDRESS);
- usbp->usb_state = USB_SELECTED;
-}
-
-/**
- * @brief Starts a receive phase on the endpoint zero.
- *
- * @param[in] usbp pointer to the @p USBDriver object
- */
-static void start_rx_ep0(USBDriver *usbp) {
-
- if (usbp->usb_ep0n > 0) {
- /* The received data cannot exceed the available amount.*/
- if (usbp->usb_ep0n > usbp->usb_ep0max)
- usbp->usb_ep0n = usbp->usb_ep0max;
-
- /* Determines the maximum amount that can be received using a
- single packet.*/
- if (usbp->usb_ep0n > usbp->usb_ep[0]->uep_config->uepc_out_maxsize)
- usbp->usb_ep0lastsize = usbp->usb_ep[0]->uep_config->uepc_out_maxsize;
- else
- usbp->usb_ep0lastsize = usbp->usb_ep0n;
- usbp->usb_ep0state = USB_EP0_RX;
- }
- else {
- /* Sending zero sized status packet.*/
- usb_lld_write(usbp, 0, NULL, 0);
- usbp->usb_ep0state = USB_EP0_SENDING_STS;
- }
-}
-
-/**
- * @brief Starts a transmission phase on the endpoint zero.
- *
- * @param[in] usbp pointer to the @p USBDriver object
- */
-static void start_tx_ep0(USBDriver *usbp) {
-
- if (usbp->usb_ep0n > 0) {
- /* The transmitted data cannot exceed the requested amount.*/
- if (usbp->usb_ep0n > usbp->usb_ep0max)
- usbp->usb_ep0n = usbp->usb_ep0max;
-
- /* Determines the maximum amount that can be transmitted using a
- single packet.*/
- if (usbp->usb_ep0n > usbp->usb_ep[0]->uep_config->uepc_in_maxsize)
- usbp->usb_ep0lastsize = usbp->usb_ep[0]->uep_config->uepc_in_maxsize;
- else
- usbp->usb_ep0lastsize = usbp->usb_ep0n;
-
- /* Starts transmission.*/
- usb_lld_write(usbp, 0, usbp->usb_ep0next, usbp->usb_ep0lastsize);
- usbp->usb_ep0state = USB_EP0_TX;
- }
- else
- usbp->usb_ep0state = USB_EP0_WAITING_STS;
+ usbp->address = usbp->setup[2];
+ usb_lld_set_address(usbp);
+ _usb_isr_invoke_event_cb(usbp, USB_EVENT_ADDRESS);
+ usbp->state = USB_SELECTED;
}
/**
* @brief Standard requests handler.
* @details This is the standard requests default handler, most standard
* requests are handled here, the user can override the standard
- * handling using the @p uc_requests_hook_cb hook in the
+ * handling using the @p requests_hook_cb hook in the
* @p USBConfig structure.
*
* @param[in] usbp pointer to the @p USBDriver object
@@ -133,18 +79,18 @@ static bool_t default_handler(USBDriver *usbp) {
const USBDescriptor *dp;
/* Decoding the request.*/
- switch (((usbp->usb_setup[0] & (USB_RTYPE_RECIPIENT_MASK |
- USB_RTYPE_TYPE_MASK)) |
- (usbp->usb_setup[1] << 8))) {
+ switch (((usbp->setup[0] & (USB_RTYPE_RECIPIENT_MASK |
+ USB_RTYPE_TYPE_MASK)) |
+ (usbp->setup[1] << 8))) {
case USB_RTYPE_RECIPIENT_DEVICE | (USB_REQ_GET_STATUS << 8):
/* Just returns the current status word.*/
- usbSetupTransfer(usbp, (uint8_t *)&usbp->usb_status, 2, NULL);
+ usbSetupTransfer(usbp, (uint8_t *)&usbp->status, 2, NULL);
return TRUE;
case USB_RTYPE_RECIPIENT_DEVICE | (USB_REQ_CLEAR_FEATURE << 8):
/* Only the DEVICE_REMOTE_WAKEUP is handled here, any other feature
number is handled as an error.*/
- if (usbp->usb_setup[2] == USB_FEATURE_DEVICE_REMOTE_WAKEUP) {
- usbp->usb_status &= ~2;
+ if (usbp->setup[2] == USB_FEATURE_DEVICE_REMOTE_WAKEUP) {
+ usbp->status &= ~2;
usbSetupTransfer(usbp, NULL, 0, NULL);
return TRUE;
}
@@ -152,39 +98,46 @@ static bool_t default_handler(USBDriver *usbp) {
case USB_RTYPE_RECIPIENT_DEVICE | (USB_REQ_SET_FEATURE << 8):
/* Only the DEVICE_REMOTE_WAKEUP is handled here, any other feature
number is handled as an error.*/
- if (usbp->usb_setup[2] == USB_FEATURE_DEVICE_REMOTE_WAKEUP) {
- usbp->usb_status |= 2;
+ if (usbp->setup[2] == USB_FEATURE_DEVICE_REMOTE_WAKEUP) {
+ usbp->status |= 2;
usbSetupTransfer(usbp, NULL, 0, NULL);
return TRUE;
}
return FALSE;
case USB_RTYPE_RECIPIENT_DEVICE | (USB_REQ_SET_ADDRESS << 8):
- /* The handling is posponed to after the status phase in order to allow
- the proper completion of the transaction.*/
+ /* The SET_ADDRESS handling can be performed here or postponed after
+ the status packed depending on the USB_SET_ADDRESS_MODE low
+ driver setting.*/
+#if USB_SET_ADDRESS_MODE == USB_EARLY_SET_ADDRESS
+ if ((usbp->setup[0] == USB_RTYPE_RECIPIENT_DEVICE) &&
+ (usbp->setup[1] == USB_REQ_SET_ADDRESS))
+ set_address(usbp);
+ usbSetupTransfer(usbp, NULL, 0, NULL);
+#else
usbSetupTransfer(usbp, NULL, 0, set_address);
+#endif
return TRUE;
case USB_RTYPE_RECIPIENT_DEVICE | (USB_REQ_GET_DESCRIPTOR << 8):
/* Handling descriptor requests from the host.*/
- dp = usbp->usb_config->uc_get_descriptor_cb(
- usbp, usbp->usb_setup[3], usbp->usb_setup[2],
- usb_lld_fetch_word(&usbp->usb_setup[4]));
+ dp = usbp->config->get_descriptor_cb(
+ usbp, usbp->setup[3], usbp->setup[2],
+ usb_lld_fetch_word(&usbp->setup[4]));
if (dp == NULL)
return FALSE;
usbSetupTransfer(usbp, (uint8_t *)dp->ud_string, dp->ud_size, NULL);
return TRUE;
case USB_RTYPE_RECIPIENT_DEVICE | (USB_REQ_GET_CONFIGURATION << 8):
/* Returning the last selected configuration.*/
- usbSetupTransfer(usbp, &usbp->usb_configuration, 1, NULL);
+ usbSetupTransfer(usbp, &usbp->configuration, 1, NULL);
return TRUE;
case USB_RTYPE_RECIPIENT_DEVICE | (USB_REQ_SET_CONFIGURATION << 8):
/* Handling configuration selection from the host.*/
- usbp->usb_configuration = usbp->usb_setup[2];
- if (usbp->usb_configuration == 0)
- usbp->usb_state = USB_SELECTED;
+ usbp->configuration = usbp->setup[2];
+ if (usbp->configuration == 0)
+ usbp->state = USB_SELECTED;
else
- usbp->usb_state = USB_ACTIVE;
- if (usbp->usb_config->uc_event_cb)
- usbp->usb_config->uc_event_cb(usbp, USB_EVENT_CONFIGURED);
+ usbp->state = USB_ACTIVE;
+ _usb_isr_invoke_event_cb(usbp, USB_EVENT_CONFIGURED);
usbSetupTransfer(usbp, NULL, 0, NULL);
return TRUE;
case USB_RTYPE_RECIPIENT_INTERFACE | (USB_REQ_GET_STATUS << 8):
@@ -195,8 +148,8 @@ static bool_t default_handler(USBDriver *usbp) {
return TRUE;
case USB_RTYPE_RECIPIENT_ENDPOINT | (USB_REQ_GET_STATUS << 8):
/* Sending the EP status.*/
- if (usbp->usb_setup[4] & 0x80) {
- switch (usb_lld_get_status_in(usbp, usbp->usb_setup[4] & 0x0F)) {
+ if (usbp->setup[4] & 0x80) {
+ switch (usb_lld_get_status_in(usbp, usbp->setup[4] & 0x0F)) {
case EP_STATUS_STALLED:
usbSetupTransfer(usbp, (uint8_t *)halted_status, 2, NULL);
return TRUE;
@@ -208,7 +161,7 @@ static bool_t default_handler(USBDriver *usbp) {
}
}
else {
- switch (usb_lld_get_status_out(usbp, usbp->usb_setup[4] & 0x0F)) {
+ switch (usb_lld_get_status_out(usbp, usbp->setup[4] & 0x0F)) {
case EP_STATUS_STALLED:
usbSetupTransfer(usbp, (uint8_t *)halted_status, 2, NULL);
return TRUE;
@@ -221,27 +174,27 @@ static bool_t default_handler(USBDriver *usbp) {
}
case USB_RTYPE_RECIPIENT_ENDPOINT | (USB_REQ_CLEAR_FEATURE << 8):
/* Only ENDPOINT_HALT is handled as feature.*/
- if (usbp->usb_setup[2] != USB_FEATURE_ENDPOINT_HALT)
+ if (usbp->setup[2] != USB_FEATURE_ENDPOINT_HALT)
return FALSE;
/* Clearing the EP status, not valid for EP0, it is ignored in that case.*/
- if ((usbp->usb_setup[4] & 0x0F) > 0) {
- if (usbp->usb_setup[4] & 0x80)
- usb_lld_clear_in(usbp, usbp->usb_setup[4] & 0x0F);
+ if ((usbp->setup[4] & 0x0F) > 0) {
+ if (usbp->setup[4] & 0x80)
+ usb_lld_clear_in(usbp, usbp->setup[4] & 0x0F);
else
- usb_lld_clear_out(usbp, usbp->usb_setup[4] & 0x0F);
+ usb_lld_clear_out(usbp, usbp->setup[4] & 0x0F);
}
usbSetupTransfer(usbp, NULL, 0, NULL);
return TRUE;
case USB_RTYPE_RECIPIENT_ENDPOINT | (USB_REQ_SET_FEATURE << 8):
/* Only ENDPOINT_HALT is handled as feature.*/
- if (usbp->usb_setup[2] != USB_FEATURE_ENDPOINT_HALT)
+ if (usbp->setup[2] != USB_FEATURE_ENDPOINT_HALT)
return FALSE;
/* Stalling the EP, not valid for EP0, it is ignored in that case.*/
- if ((usbp->usb_setup[4] & 0x0F) > 0) {
- if (usbp->usb_setup[4] & 0x80)
- usb_lld_stall_in(usbp, usbp->usb_setup[4] & 0x0F);
+ if ((usbp->setup[4] & 0x0F) > 0) {
+ if (usbp->setup[4] & 0x80)
+ usb_lld_stall_in(usbp, usbp->setup[4] & 0x0F);
else
- usb_lld_stall_out(usbp, usbp->usb_setup[4] & 0x0F);
+ usb_lld_stall_out(usbp, usbp->setup[4] & 0x0F);
}
usbSetupTransfer(usbp, NULL, 0, NULL);
return TRUE;
@@ -282,9 +235,11 @@ void usbInit(void) {
*/
void usbObjectInit(USBDriver *usbp) {
- usbp->usb_state = USB_STOP;
- usbp->usb_config = NULL;
- usbp->usb_param = NULL;
+ usbp->state = USB_STOP;
+ usbp->config = NULL;
+ usbp->param = NULL;
+ usbp->transmitting = 0;
+ usbp->receiving = 0;
}
/**
@@ -301,13 +256,13 @@ void usbStart(USBDriver *usbp, const USBConfig *config) {
chDbgCheck((usbp != NULL) && (config != NULL), "usbStart");
chSysLock();
- chDbgAssert((usbp->usb_state == USB_STOP) || (usbp->usb_state == USB_READY),
+ chDbgAssert((usbp->state == USB_STOP) || (usbp->state == USB_READY),
"usbStart(), #1", "invalid state");
- usbp->usb_config = config;
+ usbp->config = config;
for (i = 0; i <= USB_MAX_ENDPOINTS; i++)
- usbp->usb_ep[i] = NULL;
+ usbp->epc[i] = NULL;
usb_lld_start(usbp);
- usbp->usb_state = USB_READY;
+ usbp->state = USB_READY;
chSysUnlock();
}
@@ -323,11 +278,10 @@ void usbStop(USBDriver *usbp) {
chDbgCheck(usbp != NULL, "usbStop");
chSysLock();
- chDbgAssert((usbp->usb_state == USB_STOP) || (usbp->usb_state == USB_READY),
- "usbStop(), #1",
- "invalid state");
+ chDbgAssert((usbp->state == USB_STOP) || (usbp->state == USB_READY),
+ "usbStop(), #1", "invalid state");
usb_lld_stop(usbp);
- usbp->usb_state = USB_STOP;
+ usbp->state = USB_STOP;
chSysUnlock();
}
@@ -340,23 +294,24 @@ void usbStop(USBDriver *usbp) {
*
* @param[in] usbp pointer to the @p USBDriver object
* @param[in] ep endpoint number
- * @param[out] epp pointer to an endpoint state descriptor structure
* @param[in] epcp the endpoint configuration
*
* @iclass
*/
-void usbInitEndpointI(USBDriver *usbp, usbep_t ep, USBEndpointState *epp,
+void usbInitEndpointI(USBDriver *usbp, usbep_t ep,
const USBEndpointConfig *epcp) {
- chDbgAssert(usbp->usb_state == USB_ACTIVE,
+ chDbgAssert(usbp->state == USB_ACTIVE,
"usbEnableEndpointI(), #1", "invalid state");
- chDbgAssert(usbp->usb_ep[ep] != NULL,
+ chDbgAssert(usbp->epc[ep] != NULL,
"usbEnableEndpointI(), #2", "already initialized");
/* Logically enabling the endpoint in the USBDriver structure.*/
- memset(epp, 0, sizeof(USBEndpointState));
- epp->uep_config = epcp;
- usbp->usb_ep[ep] = epp;
+ if (!(epcp->ep_mode & USB_EP_MODE_PACKET)) {
+ memset(epcp->in_state, 0, sizeof(USBInEndpointState));
+ memset(epcp->out_state, 0, sizeof(USBOutEndpointState));
+ }
+ usbp->epc[ep] = epcp;
/* Low level endpoint activation.*/
usb_lld_init_endpoint(usbp, ep);
@@ -376,18 +331,174 @@ void usbInitEndpointI(USBDriver *usbp, usbep_t ep, USBEndpointState *epp,
void usbDisableEndpointsI(USBDriver *usbp) {
unsigned i;
- chDbgAssert(usbp->usb_state == USB_SELECTED,
+ chDbgAssert(usbp->state == USB_SELECTED,
"usbDisableEndpointsI(), #1", "invalid state");
+ usbp->transmitting &= ~1;
+ usbp->receiving &= ~1;
for (i = 1; i <= USB_MAX_ENDPOINTS; i++)
- usbp->usb_ep[i] = NULL;
+ usbp->epc[i] = NULL;
/* Low level endpoints deactivation.*/
usb_lld_disable_endpoints(usbp);
}
/**
+ * @brief Reads a packet from the dedicated packet buffer.
+ * @pre In order to use this function he endpoint must have been
+ * initialized in packet mode.
+ * @post The endpoint is ready to accept another packet.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ * @param[out] buf buffer where to copy the packet data
+ * @param[in] n maximum number of bytes to copy. This value must
+ * not exceed the maximum packet size for this endpoint.
+ * @return The received packet size regardless the specified
+ * @p n parameter.
+ * @retval USB_ENDPOINT_BUSY Endpoint busy receiving.
+ * @retval 0 Zero size packet received.
+ *
+ * @iclass
+ */
+size_t usbReadPacketI(USBDriver *usbp, usbep_t ep,
+ uint8_t *buf, size_t n) {
+
+ if (usbGetReceiveStatusI(usbp, ep))
+ return USB_ENDPOINT_BUSY;
+
+ usbp->receiving |= (1 << ep);
+ return usb_lld_read_packet(usbp, ep, buf, n);;
+}
+
+/**
+ * @brief Writes a packet to the dedicated packet buffer.
+ * @pre In order to use this function he endpoint must have been
+ * initialized in packet mode.
+ * @post The endpoint is ready to transmit the packet.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ * @param[in] buf buffer where to fetch the packet data
+ * @param[in] n maximum number of bytes to copy. This value must
+ * not exceed the maximum packet size for this endpoint.
+ * @return The operation status.
+ * @retval USB_ENDPOINT_BUSY Endpoint busy transmitting.
+ * @retval 0 Operation complete.
+ *
+ * @iclass
+ */
+size_t usbWritePacketI(USBDriver *usbp, usbep_t ep,
+ const uint8_t *buf, size_t n) {
+
+ if (usbGetTransmitStatusI(usbp, ep))
+ return USB_ENDPOINT_BUSY;
+
+ usbp->transmitting |= (1 << ep);
+ usb_lld_write_packet(usbp, ep, buf, n);
+ return 0;
+}
+
+/**
+ * @brief Starts a receive transaction on an OUT endpoint.
+ * @pre In order to use this function he endpoint must have been
+ * initialized in transaction mode.
+ * @post The endpoint callback is invoked when the transfer has been
+ * completed.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ * @param[out] buf buffer where to copy the received data
+ * @param[in] n maximum number of bytes to copy
+ * @return The operation status.
+ * @retval FALSE Operation started successfully.
+ * @retval TRUE Endpoint busy, operation not started.
+ *
+ * @iclass
+ */
+bool_t usbStartReceiveI(USBDriver *usbp, usbep_t ep,
+ uint8_t *buf, size_t n) {
+
+ if (usbGetReceiveStatusI(usbp, ep))
+ return TRUE;
+
+ usbp->receiving |= (1 << ep);
+ usb_lld_start_out(usbp, ep, buf, n);
+ return FALSE;
+}
+
+/**
+ * @brief Starts a transmit transaction on an IN endpoint.
+ * @pre In order to use this function he endpoint must have been
+ * initialized in transaction mode.
+ * @post The endpoint callback is invoked when the transfer has been
+ * completed.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ * @param[in] buf buffer where to fetch the data to be transmitted
+ * @param[in] n maximum number of bytes to copy
+ * @return The operation status.
+ * @retval FALSE Operation started successfully.
+ * @retval TRUE Endpoint busy, operation not started.
+ *
+ * @iclass
+ */
+bool_t usbStartTransmitI(USBDriver *usbp, usbep_t ep,
+ const uint8_t *buf, size_t n) {
+
+ if (usbGetTransmitStatusI(usbp, ep))
+ return TRUE;
+
+ usbp->transmitting |= (1 << ep);
+ usb_lld_start_in(usbp, ep, buf, n);
+ return FALSE;
+}
+
+/**
+ * @brief Stalls an OUT endpoint.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ * @return The operation status.
+ * @retval FALSE Endpoint stalled.
+ * @retval TRUE Endpoint busy, not stalled.
+ *
+ * @iclass
+ */
+bool_t usbStallReceiveI(USBDriver *usbp, usbep_t ep) {
+
+ if (usbGetReceiveStatusI(usbp, ep))
+ return TRUE;
+
+ usb_lld_stall_out(usbp, ep);
+ return FALSE;
+}
+
+/**
+ * @brief Stalls an IN endpoint.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ * @return The operation status.
+ * @retval FALSE Endpoint stalled.
+ * @retval TRUE Endpoint busy, not stalled.
+ *
+ * @iclass
+ */
+bool_t usbStallTransmitI(USBDriver *usbp, usbep_t ep) {
+
+ if (usbGetTransmitStatusI(usbp, ep))
+ return TRUE;
+
+ usb_lld_stall_in(usbp, ep);
+ return FALSE;
+}
+
+/**
* @brief USB reset routine.
+ * @details This function must be invoked when an USB bus reset condition is
+ * detected.
*
* @param[in] usbp pointer to the @p USBDriver object
*
@@ -396,24 +507,93 @@ void usbDisableEndpointsI(USBDriver *usbp) {
void _usb_reset(USBDriver *usbp) {
unsigned i;
- usbp->usb_state = USB_READY;
- usbp->usb_status = 0;
- usbp->usb_address = 0;
- usbp->usb_configuration = 0;
+ usbp->state = USB_READY;
+ usbp->status = 0;
+ usbp->address = 0;
+ usbp->configuration = 0;
+ usbp->transmitting = 0;
+ usbp->receiving = 0;
/* Invalidates all endpoints into the USBDriver structure.*/
for (i = 0; i <= USB_MAX_ENDPOINTS; i++)
- usbp->usb_ep[i] = NULL;
+ usbp->epc[i] = NULL;
/* EP0 state machine initialization.*/
- usbp->usb_ep0state = USB_EP0_WAITING_SETUP;
+ usbp->ep0state = USB_EP0_WAITING_SETUP;
/* Low level reset.*/
usb_lld_reset(usbp);
+}
- /* Endpoint zero initialization.*/
-/* usbp->usb_ep[0].uep_config = &usb_lld_ep0config;
- usb_lld_init_endpoint(usbp, 0, &usb_lld_ep0config);*/
+/**
+ * @brief Default EP0 SETUP callback.
+ * @details This function is used by the low level driver as default handler
+ * for EP0 SETUP events.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number, always zero
+ *
+ * @notapi
+ */
+void _usb_ep0setup(USBDriver *usbp, usbep_t ep) {
+ size_t max;
+
+ usbp->ep0state = USB_EP0_WAITING_SETUP;
+ usbReadSetup(usbp, ep, usbp->setup);
+
+ /* First verify if the application has an handler installed for this
+ request.*/
+ if (!(usbp->config->requests_hook_cb) ||
+ !(usbp->config->requests_hook_cb(usbp))) {
+ /* Invoking the default handler, if this fails then stalls the
+ endpoint zero as error.*/
+ if (((usbp->setup[0] & USB_RTYPE_TYPE_MASK) != USB_RTYPE_TYPE_STD) ||
+ !default_handler(usbp)) {
+ /* Error response, the state machine goes into an error state, the low
+ level layer will have to reset it to USB_EP0_WAITING_SETUP after
+ receiving a SETUP packet.*/
+ usb_lld_stall_in(usbp, 0);
+ usb_lld_stall_out(usbp, 0);
+ _usb_isr_invoke_event_cb(usbp, USB_EVENT_STALLED);
+ usbp->ep0state = USB_EP0_ERROR;
+ }
+ }
+
+ /* Transfer preparation. The request handler must have populated
+ correctly the fields ep0next, ep0n and ep0endcb using the macro
+ usbSetupTransfer().*/
+ max = usb_lld_fetch_word(&usbp->setup[6]);
+ /* The transfer size cannot exceed the specified amount.*/
+ if (usbp->ep0n > max)
+ usbp->ep0n = max;
+ if ((usbp->setup[0] & USB_RTYPE_DIR_MASK) == USB_RTYPE_DIR_DEV2HOST) {
+ /* IN phase.*/
+ if (usbp->ep0n > 0) {
+ /* Starts the transmit phase.*/
+ usbp->ep0state = USB_EP0_TX;
+ usb_lld_start_in(usbp, 0, usbp->ep0next, usbp->ep0n);
+ }
+ else {
+ /* No transmission phase, directly receiving the zero sized status
+ packet.*/
+ usbp->ep0state = USB_EP0_WAITING_STS;
+ usb_lld_start_out(usbp, 0, NULL, 0);
+ }
+ }
+ else {
+ /* OUT phase.*/
+ if (usbp->ep0n > 0) {
+ /* Starts the receive phase.*/
+ usbp->ep0state = USB_EP0_RX;
+ usb_lld_start_out(usbp, 0, usbp->ep0next, usbp->ep0n);
+ }
+ else {
+ /* No receive phase, directly sending the zero sized status
+ packet.*/
+ usbp->ep0state = USB_EP0_SENDING_STS;
+ usb_lld_start_in(usbp, 0, NULL, 0);
+ }
+ }
}
/**
@@ -427,43 +607,41 @@ void _usb_reset(USBDriver *usbp) {
* @notapi
*/
void _usb_ep0in(USBDriver *usbp, usbep_t ep) {
+ size_t max;
(void)ep;
- switch (usbp->usb_ep0state) {
+ switch (usbp->ep0state) {
case USB_EP0_TX:
- usbp->usb_ep0next += usbp->usb_ep0lastsize;
- usbp->usb_ep0max -= usbp->usb_ep0lastsize;
- usbp->usb_ep0n -= usbp->usb_ep0lastsize;
-
- /* The final condition is when the requested size has been transmitted or
- when a packet has been sent with size less than the maximum packet
- size.*/
- if ((usbp->usb_ep0max == 0) ||
- (usbp->usb_ep0lastsize < usbp->usb_ep[0]->uep_config->uepc_in_maxsize))
- usbp->usb_ep0state = USB_EP0_WAITING_STS;
- else {
- usbp->usb_ep0lastsize =
- usbp->usb_ep0n > usbp->usb_ep[0]->uep_config->uepc_in_maxsize ?
- usbp->usb_ep[0]->uep_config->uepc_in_maxsize :
- usbp->usb_ep0n;
- usb_lld_write(usbp, 0, usbp->usb_ep0next, usbp->usb_ep0lastsize);
- }
+ max = usb_lld_fetch_word(&usbp->setup[6]);
+ /* If the transmitted size is less than the requested size and it is a
+ multiple of the maximum packet size then a zero size packet must be
+ transmitted.*/
+ if ((usbp->ep0n < max) &&
+ ((usbp->ep0n % usbp->epc[0]->in_maxsize) == 0)) {
+ usb_lld_start_in(usbp, 0, NULL, 0);
+ return;
+ }
+
+ /* Transmit phase over, receiving the zero sized status packet.*/
+ usbp->ep0state = USB_EP0_WAITING_STS;
+ usb_lld_start_out(usbp, 0, NULL, 0);
return;
case USB_EP0_SENDING_STS:
- if (usbp->usb_ep0endcb)
- usbp->usb_ep0endcb(usbp);
-
- usbp->usb_ep0state = USB_EP0_WAITING_SETUP;
+ /* Status packet sent, invoking the callback if defined.*/
+ if (usbp->ep0endcb != NULL)
+ usbp->ep0endcb(usbp);
+ usbp->ep0state = USB_EP0_WAITING_SETUP;
return;
default:
;
}
- /* Error response.*/
+ /* Error response, the state machine goes into an error state, the low
+ level layer will have to reset it to USB_EP0_WAITING_SETUP after
+ receiving a SETUP packet.*/
usb_lld_stall_in(usbp, 0);
usb_lld_stall_out(usbp, 0);
- if (usbp->usb_config->uc_event_cb)
- usbp->usb_config->uc_event_cb(usbp, USB_EVENT_STALLED);
- usbp->usb_ep0state = USB_EP0_WAITING_SETUP;
+ _usb_isr_invoke_event_cb(usbp, USB_EVENT_STALLED);
+ usbp->ep0state = USB_EP0_ERROR;
}
/**
@@ -477,72 +655,33 @@ void _usb_ep0in(USBDriver *usbp, usbep_t ep) {
* @notapi
*/
void _usb_ep0out(USBDriver *usbp, usbep_t ep) {
- size_t n, size;
- uint8_t buf[1];
(void)ep;
- switch (usbp->usb_ep0state) {
- case USB_EP0_WAITING_SETUP:
- /* SETUP packet handling.*/
- n = usb_lld_read(usbp, 0, usbp->usb_setup, 8);
- if (n != 8)
- break;
-
- /* First verify if the application has an handler installed for this
- request.*/
- if (!(usbp->usb_config->uc_requests_hook_cb) ||
- !(usbp->usb_config->uc_requests_hook_cb(usbp))) {
- /* Invoking the default handler, if this fails then stalls the
- endpoint zero as error.*/
- if (((usbp->usb_setup[0] & USB_RTYPE_TYPE_MASK) != USB_RTYPE_TYPE_STD) ||
- !default_handler(usbp))
- break;
- }
-
- /* Transfer preparation. The request handler must have populated
- correctly the fields usb_ep0next, usb_ep0n and usb_ep0endcb using
- the macro usbSetupTransfer().*/
- usbp->usb_ep0max = usb_lld_fetch_word(&usbp->usb_setup[6]);
- if ((usbp->usb_setup[0] & USB_RTYPE_DIR_MASK) == USB_RTYPE_DIR_DEV2HOST)
- start_tx_ep0(usbp);
- else
- start_rx_ep0(usbp);
- return;
+ switch (usbp->ep0state) {
case USB_EP0_RX:
- /* Check for buffer overflow.*/
- n = size = usb_lld_get_readable(usbp, 0);
- if (n > usbp->usb_ep0n)
- n = usbp->usb_ep0n;
- /* Fetching received data packet.*/
- n = usb_lld_read(usbp, 0, usbp->usb_ep0next, n);
- if (n > usbp->usb_ep0max)
- break;
- usbp->usb_ep0max -= size;
- usbp->usb_ep0n -= n;
- usbp->usb_ep0next += n;
- if (usbp->usb_ep0max == 0) {
- usb_lld_write(usbp, 0, NULL, 0);
- usbp->usb_ep0state = USB_EP0_SENDING_STS;
- }
+ /* Receive phase over, sending the zero sized status packet.*/
+ usbp->ep0state = USB_EP0_SENDING_STS;
+ usb_lld_start_in(usbp, 0, NULL, 0);
return;
case USB_EP0_WAITING_STS:
- /* STATUS received packet handling, it must be zero sized.*/
- n = usb_lld_read(usbp, 0, buf, 1);
- if (n != 0)
+ /* Status packet received, it must be zero sized, invoking the callback
+ if defined.*/
+ if (usbGetReceiveTransactionSizeI(usbp, 0) != 0)
break;
- if (usbp->usb_ep0endcb)
- usbp->usb_ep0endcb(usbp);
- usbp->usb_ep0state = USB_EP0_WAITING_SETUP;
+ if (usbp->ep0endcb != NULL)
+ usbp->ep0endcb(usbp);
+ usbp->ep0state = USB_EP0_WAITING_SETUP;
return;
default:
;
}
- /* Error response.*/
+ /* Error response, the state machine goes into an error state, the low
+ level layer will have to reset it to USB_EP0_WAITING_SETUP after
+ receiving a SETUP packet.*/
usb_lld_stall_in(usbp, 0);
usb_lld_stall_out(usbp, 0);
- if (usbp->usb_config->uc_event_cb)
- usbp->usb_config->uc_event_cb(usbp, USB_EVENT_STALLED);
- usbp->usb_ep0state = USB_EP0_WAITING_SETUP;
+ _usb_isr_invoke_event_cb(usbp, USB_EVENT_STALLED);
+ usbp->ep0state = USB_EP0_ERROR;
}
#endif /* HAL_USE_USB */