aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2007-10-30 16:32:55 +0000
committergdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2007-10-30 16:32:55 +0000
commit61319fc705563c68e8f40ca9857b1521b8d47ba9 (patch)
tree4834345e184dc3f687fd7cc22f32670c54d6bd67
parent35dea10cc76722976bfbf368dd50f7617ca86a45 (diff)
downloadChibiOS-61319fc705563c68e8f40ca9857b1521b8d47ba9.tar.gz
ChibiOS-61319fc705563c68e8f40ca9857b1521b8d47ba9.tar.bz2
ChibiOS-61319fc705563c68e8f40ca9857b1521b8d47ba9.zip
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@70 35acf78f-673a-0410-8e92-d51de3d6d3f4
-rw-r--r--ports/ARM7-LPC214x/GCC/lpc214x_ssp.c85
-rw-r--r--ports/ARM7-LPC214x/GCC/lpc214x_ssp.h5
-rw-r--r--readme.txt3
-rw-r--r--src/include/threads.h3
4 files changed, 91 insertions, 5 deletions
diff --git a/ports/ARM7-LPC214x/GCC/lpc214x_ssp.c b/ports/ARM7-LPC214x/GCC/lpc214x_ssp.c
index 4168b6157..473ca169a 100644
--- a/ports/ARM7-LPC214x/GCC/lpc214x_ssp.c
+++ b/ports/ARM7-LPC214x/GCC/lpc214x_ssp.c
@@ -23,10 +23,49 @@
#include "lpc214x_ssp.h"
static BYTE8 *ip, *op;
-static t_size icnt, ocnt;
+static int icnt, ocnt;
static t_sspnotify callback;
+static void *cbpar;
void SSPIrq(void) {
+ SSP *ssp = SSPBase;
+ BYTE8 b;
+
+ while (ssp->SSP_MIS & (MIS_ROR | MIS_RT | MIS_RX | MIS_TX)) {
+
+ if (ssp->SSP_MIS & MIS_ROR)
+ chSysHalt();
+
+ if (ssp->SSP_MIS & (MIS_RX | MIS_RT)) {
+ ssp->SSP_ICR = ICR_RT;
+ while (ssp->SSP_SR & SR_RNE) {
+ b = ssp->SSP_DR;
+ if (ip)
+ *ip++ = b;
+ icnt--;
+ }
+ if (icnt <= 0) { /* It should never become less than zero */
+ t_sspnotify fn = callback;
+ callback = NULL;
+ ssp->SSP_IMSC = 0;
+ VICVectAddr = 0;
+ fn(cbpar);
+ return;
+ }
+ continue;
+ }
+ /* It is MIS_TX, no need to test it again. */
+ while (ocnt && (ssp->SSP_SR & SR_TNF)) {
+ if (op)
+ ssp->SSP_DR = *op++;
+ else
+ ssp->SSP_DR = 0xFF;
+ ocnt--;
+ }
+ if (!ocnt)
+ ssp->SSP_IMSC = IMSC_ROR | IMSC_RT | IMSC_RX;
+ }
+ VICVectAddr = 0;
}
/*
@@ -37,19 +76,57 @@ void SSPIrq(void) {
* \p NULL then 0xFF bytes will be output.
* @param n the number of bytes to be transferred
* @param fn callback function invoked when the operation is done
- * @return \p SSP_OK if the trasfer is started else \p SSP_RUNNING if a
+ * @param par parameter to be passed to the callback function
+ * @return \p SSP_OK if the trasfer was started else \p SSP_RUNNING if a
* an operation was already started
*/
-t_msg sspRWI(BYTE8 *in, BYTE8 *out, t_size n, t_sspnotify fn) {
+t_msg sspRWI(BYTE8 *in, BYTE8 *out, t_size n, t_sspnotify fn, void *par) {
if (callback)
return SSP_RUNNING;
- callback = fn, ip = in, op = out, icnt = ocnt = n;
+ callback = fn, cbpar = par, ip = in, op = out, icnt = ocnt = n;
SSPIMSC = IMSC_ROR | IMSC_RT | IMSC_RX | IMSC_TX;
return SSP_OK;
}
+
+static void done(void *tp) {
+
+ chThdResumeI(tp);
+}
+
+/*
+ * Synchronous SSP transfer.
+ * @param in pointer to the incoming data buffer, if this parameter is set to
+ * \p NULL then the incoming data is discarded.
+ * @param out pointer to the outgoing data buffer, if this parameter is set to
+ * \p NULL then 0xFF bytes will be output.
+ * @param n the number of bytes to be transferred
+ * @return \p SSP_OK if the trasfer was performed else \p SSP_RUNNING if a
+ * an operation was already started
+ */
+t_msg sspRW(BYTE8 *in, BYTE8 *out, t_size n) {
+
+ chSysLock();
+
+ t_msg sts = sspRWI(in, out, n, done, chThdSelf());
+ if (sts == SSP_OK)
+ chSchGoSleepS(PRSUSPENDED);
+
+ chSysUnlock();
+ return sts;
+}
+
+/*
+ * Checks if a SSP operation is running.
+ * @return \p TRUE if an asynchronous operation is already running.
+ */
+BOOL sspIsRunningI(void) {
+
+ return callback != NULL;
+}
+
/*
* SSP setup, must be invoked with interrupts disabled.
* Do not invoke while an operation is in progress.
diff --git a/ports/ARM7-LPC214x/GCC/lpc214x_ssp.h b/ports/ARM7-LPC214x/GCC/lpc214x_ssp.h
index 655a6b1e0..093edc952 100644
--- a/ports/ARM7-LPC214x/GCC/lpc214x_ssp.h
+++ b/ports/ARM7-LPC214x/GCC/lpc214x_ssp.h
@@ -23,10 +23,13 @@
#define SSP_OK RDY_OK
#define SSP_RUNNING -3
-typedef void (*t_sspnotify)(void);
+typedef void (*t_sspnotify)(void *par);
void InitSSP(void);
void SetSSPI(int cpsr, int cr0, int cr1);
void SSPIrqHandler(void);
+t_msg sspRWI(BYTE8 *in, BYTE8 *out, t_size n, t_sspnotify fn, void *par);
+BOOL sspIsRunningI(void);
+
#endif /* _LPC214x_SSP_H_*/
diff --git a/readme.txt b/readme.txt
index 3336c8789..d6a7dda55 100644
--- a/readme.txt
+++ b/readme.txt
@@ -40,6 +40,9 @@ AVR-AT90CANx-GCC - Port on AVR AT90CAN128, not complete yet.
*** 0.3.6 ***
- Added SSP (SPI1) definitions to the lpc214x.h file.
+- Added SSP driver for the LPC2148. It allows both asynchronous and
+ synchronous operations.
+- Added missing chThdSuspend() declararion in threads.h.
*** 0.3.5 ***
- Space optimization in events code.
diff --git a/src/include/threads.h b/src/include/threads.h
index f97148087..effad525c 100644
--- a/src/include/threads.h
+++ b/src/include/threads.h
@@ -158,6 +158,9 @@ extern "C" {
#ifdef CH_USE_RESUME
void chThdResume(Thread *tp);
#endif
+#ifdef CH_USE_SUSPEND
+ void chThdSuspend(Thread **tpp);
+#endif
#ifdef CH_USE_TERMINATE
void chThdTerminate(Thread *tp);
#endif