aboutsummaryrefslogtreecommitdiffstats
path: root/ports
diff options
context:
space:
mode:
authorgdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2009-01-09 11:05:26 +0000
committergdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2009-01-09 11:05:26 +0000
commit52ab7591c76c47228b41c23c45f943b7b0d43483 (patch)
treed76709419da73cab968434b6a2326dbe94fd8090 /ports
parenta07bd21d4427c9f254aae8f6da10dabdaedea43e (diff)
downloadChibiOS-52ab7591c76c47228b41c23c45f943b7b0d43483.tar.gz
ChibiOS-52ab7591c76c47228b41c23c45f943b7b0d43483.tar.bz2
ChibiOS-52ab7591c76c47228b41c23c45f943b7b0d43483.zip
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@595 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'ports')
-rw-r--r--ports/MSP430/chcore.c55
-rw-r--r--ports/MSP430/chcore.h11
-rw-r--r--ports/MSP430/msp430_serial.c36
3 files changed, 85 insertions, 17 deletions
diff --git a/ports/MSP430/chcore.c b/ports/MSP430/chcore.c
index e9a5dc574..e56f41120 100644
--- a/ports/MSP430/chcore.c
+++ b/ports/MSP430/chcore.c
@@ -31,12 +31,55 @@
* because performance concerns.
*/
+/**
+ * The default implementation of this function is void so no messages are
+ * actually printed.
+ * @note The function is declared as a weak symbol, it is possible to redefine
+ * it in your application code.
+ * @param msg pointer to the message string
+ */
+__attribute__((weak))
void sys_puts(char *msg) {
}
+/**
+ * Performs a context switch between two threads.
+ * @param otp the thread to be switched out
+ * @param ntp the thread to be switched in
+ * @note The function is declared as a weak symbol, it is possible to redefine
+ * it in your application code.
+ */
+__attribute__((naked, weak))
void sys_switch(Thread *otp, Thread *ntp) {
+ register struct intctx *sp asm("r1");
+
+ asm volatile ("push r11 \n\t" \
+ "push r10 \n\t" \
+ "push r9 \n\t" \
+ "push r8 \n\t" \
+ "push r7 \n\t" \
+ "push r6 \n\t" \
+ "push r6 \n\t" \
+ "push r4");
+ otp->p_ctx.sp = sp;
+ sp = ntp->p_ctx.sp;
+ asm volatile ("pop r4 \n\t" \
+ "pop r5 \n\t" \
+ "pop r6 \n\t" \
+ "pop r7 \n\t" \
+ "pop r8 \n\t" \
+ "pop r9 \n\t" \
+ "pop r10 \n\t" \
+ "pop r11 \n\t" \
+ "ret" : : "r" (sp));
}
+/**
+ * Disables the interrupts and halts the system.
+ * @note The function is declared as a weak symbol, it is possible to redefine
+ * it in your application code.
+ */
+__attribute__((weak))
void sys_halt(void) {
sys_disable();
@@ -44,4 +87,16 @@ void sys_halt(void) {
}
}
+/**
+ * Start a thread by invoking its work function.
+ * If the work function returns @p chThdExit() is automatically invoked.
+ */
+void threadstart(void) {
+
+ asm volatile ("eint \n\t" \
+ "mov r11, r15 \n\t" \
+ "call r10 \n\t" \
+ "call #chThdExit");
+}
+
/** @} */
diff --git a/ports/MSP430/chcore.h b/ports/MSP430/chcore.h
index db0d25f77..a4a866f11 100644
--- a/ports/MSP430/chcore.h
+++ b/ports/MSP430/chcore.h
@@ -151,6 +151,12 @@ if (chSchRescRequiredI()) \
}
/**
+ * IRQ handler function modifier. Note it just aliases the WinMSP "interrupt"
+ * macro.
+ */
+#define SYS_IRQ_HANDLER interrupt
+
+/**
* This port function is implemented as inlined code for performance reasons.
*/
#define sys_disable() asm volatile ("dint")
@@ -181,11 +187,6 @@ if (chSchRescRequiredI()) \
#define sys_wait_for_interrupt()
#endif
-/**
- * IRQ handler function modifier.
- */
-#define SYS_IRQ_HANDLER
-
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/ports/MSP430/msp430_serial.c b/ports/MSP430/msp430_serial.c
index 384cda0fc..27094edeb 100644
--- a/ports/MSP430/msp430_serial.c
+++ b/ports/MSP430/msp430_serial.c
@@ -34,7 +34,9 @@ static void SetError(uint8_t urctl, FullDuplexDriver *com) {
sts |= SD_FRAMING_ERROR;
if (urctl & BRK)
sts |= SD_BREAK_DETECTED;
+ chSysLockI();
chFDDAddFlagsI(com, sts);
+ chSysUnlockI();
}
#ifdef USE_MSP430_USART0
@@ -42,30 +44,34 @@ FullDuplexDriver COM1;
static uint8_t ib1[SERIAL_BUFFERS_SIZE];
static uint8_t ob1[SERIAL_BUFFERS_SIZE];
-interrupt(USART0TX_VECTOR) u0txirq(void) {
+SYS_IRQ_HANDLER(USART0TX_VECTOR) u0txirq(void) {
msg_t b;
- chSysIRQEnterI();
+ SYS_IRQ_PROLOGUE();
+ chSysLockI();
b = chFDDRequestDataI(&COM1);
+ chSysUnlockI();
if (b < Q_OK)
U0IE &= ~UTXIE0;
else
U0TXBUF = b;
- chSysIRQExitI();
+ SYS_IRQ_EPILOGUE();
}
-interrupt(USART0RX_VECTOR) u0rxirq(void) {
+SYS_IRQ_HANDLER(USART0RX_VECTOR) u0rxirq(void) {
uint8_t urctl;
- chSysIRQEnterI();
+ SYS_IRQ_PROLOGUE();
if ((urctl = U0RCTL) & RXERR)
SetError(urctl, &COM1);
+ chSysLockI();
chFDDIncomingDataI(&COM1, U0RXBUF);
+ chSysUnlockI();
- chSysIRQExitI();
+ SYS_IRQ_EPILOGUE();
}
/*
@@ -75,7 +81,9 @@ interrupt(USART0RX_VECTOR) u0rxirq(void) {
static void OutNotify1(void) {
if (!(U0IE & UTXIE0)) {
+ chSysLockI();
U0TXBUF = (uint8_t)chFDDRequestDataI(&COM1);
+ chSysUnlockI();
U0IE |= UTXIE0;
}
}
@@ -108,30 +116,34 @@ FullDuplexDriver COM2;
static uint8_t ib2[SERIAL_BUFFERS_SIZE];
static uint8_t ob2[SERIAL_BUFFERS_SIZE];
-interrupt(USART1TX_VECTOR) u1txirq(void) {
+SYS_IRQ_HANDLER(USART1TX_VECTOR) u1txirq(void) {
msg_t b;
- chSysIRQEnterI();
+ SYS_IRQ_PROLOGUE();
+ chSysLockI();
b = chFDDRequestDataI(&COM2);
+ chSysUnlockI();
if (b < Q_OK)
U1IE &= ~UTXIE1;
else
U1TXBUF = b;
- chSysIRQExitI();
+ SYS_IRQ_EPILOGUE();
}
-interrupt(USART1RX_VECTOR) u1rxirq(void) {
+SYS_IRQ_HANDLER(USART1RX_VECTOR) u1rxirq(void) {
uint8_t urctl;
- chSysIRQEnterI();
+ SYS_IRQ_PROLOGUE();
if ((urctl = U1RCTL) & RXERR)
SetError(urctl, &COM2);
+ chSysLockI();
chFDDIncomingDataI(&COM2, U1RXBUF);
+ chSysUnlockI();
- chSysIRQExitI();
+ SYS_IRQ_EPILOGUE();
}