git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2615 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
parent
7dc2098ccd
commit
eb665ad240
|
@ -57,7 +57,6 @@ static msg_t Thread1(void *arg) {
|
|||
palSetPad(GPIO0, GPIO0_LED2);
|
||||
chThdSleepMilliseconds(500);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -88,7 +87,6 @@ static msg_t Thread2(void *arg) {
|
|||
palSetPort(GPIO1, PAL_PORT_BIT(GPIO1_LED3G));
|
||||
chThdSleepMilliseconds(250);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -137,5 +135,4 @@ int main(void) {
|
|||
chThdSleepMilliseconds(500);
|
||||
i = (i + 1) & 15;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -523,8 +523,8 @@
|
|||
</option>
|
||||
<option>
|
||||
<name>AUserIncludes</name>
|
||||
<state>$PROJ_DIR$\..\..\..\os\ports\IAR\ARMCMx\STM32</state>
|
||||
<state>$PROJ_DIR$\..\..\..\boards\OLIMEX_STM32_P103</state>
|
||||
<state>$PROJ_DIR$\..\..\..\os\ports\IAR\ARMCMx\LPC13xx</state>
|
||||
<state>$PROJ_DIR$\..\..\..\boards\EA_LPCXPRESSO_BB_1343</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>AExtraOptionsCheckV2</name>
|
||||
|
@ -1387,8 +1387,8 @@
|
|||
</option>
|
||||
<option>
|
||||
<name>AUserIncludes</name>
|
||||
<state>$PROJ_DIR$\..\..\..\os\ports\IAR\ARMCMx\STM32</state>
|
||||
<state>$PROJ_DIR$\..\..\..\boards\OLIMEX_STM32_P103</state>
|
||||
<state>$PROJ_DIR$\..\..\..\os\ports\IAR\ARMCMx\LPC13xx</state>
|
||||
<state>$PROJ_DIR$\..\..\..\boards\EA_LPCXPRESSO_BB_1343</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>AExtraOptionsCheckV2</name>
|
||||
|
|
|
@ -64,10 +64,16 @@ static void ssp_fifo_preload(SPIDriver *spip) {
|
|||
|
||||
while(((ssp->SR & SR_TNF) != 0) && (n > 0)) {
|
||||
if (spip->spd_txptr != NULL) {
|
||||
if ((ssp->CR0 & CR0_DSSMASK) > CR0_DSS8BIT)
|
||||
ssp->DR = *(uint16_t *)spip->spd_txptr++;
|
||||
else
|
||||
ssp->DR = *(uint8_t *)spip->spd_txptr++;
|
||||
if ((ssp->CR0 & CR0_DSSMASK) > CR0_DSS8BIT) {
|
||||
const uint16_t *p = spip->spd_txptr;
|
||||
ssp->DR = *p++;
|
||||
spip->spd_txptr = p;
|
||||
}
|
||||
else {
|
||||
const uint8_t *p = spip->spd_txptr;
|
||||
ssp->DR = *p++;
|
||||
spip->spd_txptr = p;
|
||||
}
|
||||
}
|
||||
else
|
||||
ssp->DR = 0xFFFFFFFF;
|
||||
|
@ -92,10 +98,16 @@ static void spi_serve_interrupt(SPIDriver *spip) {
|
|||
ssp->ICR = ICR_RT | ICR_ROR;
|
||||
while ((ssp->SR & SR_RNE) != 0) {
|
||||
if (spip->spd_rxptr != NULL) {
|
||||
if ((ssp->CR0 & CR0_DSSMASK) > CR0_DSS8BIT)
|
||||
*(uint16_t *)spip->spd_rxptr++ = ssp->DR;
|
||||
else
|
||||
*(uint8_t *)spip->spd_rxptr++ = ssp->DR;
|
||||
if ((ssp->CR0 & CR0_DSSMASK) > CR0_DSS8BIT) {
|
||||
uint16_t *p = spip->spd_rxptr;
|
||||
*p++ = ssp->DR;
|
||||
spip->spd_rxptr = p;
|
||||
}
|
||||
else {
|
||||
uint8_t *p = spip->spd_rxptr;
|
||||
*p++ = ssp->DR;
|
||||
spip->spd_rxptr = p;
|
||||
}
|
||||
}
|
||||
else
|
||||
(void)ssp->DR;
|
||||
|
|
|
@ -53,94 +53,4 @@ CH_IRQ_HANDLER(SysTickVector) {
|
|||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Post-IRQ switch code.
|
||||
* @details On entry the stack and the registers are restored by the exception
|
||||
* return, the PC value is stored in @p _port_saved_pc, the interrupts
|
||||
* are disabled.
|
||||
*/
|
||||
void _port_switch_from_irq(void) {
|
||||
/* Note, saves r4 to make space for the PC.*/
|
||||
asm ("push {r0, r1, r2, r3, r4} \n\t"
|
||||
"mrs r0, APSR \n\t"
|
||||
"mov r1, r12 \n\t"
|
||||
"push {r0, r1, lr} \n\t"
|
||||
"ldr r0, =_port_saved_pc \n\t"
|
||||
"ldr r0, [r0] \n\t"
|
||||
"add r0, r0, #1 \n\t"
|
||||
"str r0, [sp, #28]");
|
||||
|
||||
chSchDoRescheduleI();
|
||||
|
||||
/* Note, the last registers are restored alone after re-enabling the
|
||||
interrupts in order to minimize the (very remote and unlikely)
|
||||
possibility that the stack is filled by continuous and saturating
|
||||
interrupts that would not allow that last words to be pulled out of
|
||||
the stack.*/
|
||||
asm ("pop {r0, r1, r2} \n\t"
|
||||
"mov r12, r1 \n\t"
|
||||
"msr APSR, r0 \n\t"
|
||||
"mov lr, r2 \n\t"
|
||||
"cpsie i \n\t"
|
||||
"pop {r0, r1, r2, r3, pc}");
|
||||
}
|
||||
|
||||
#define PUSH_CONTEXT(sp) { \
|
||||
asm ("push {r4, r5, r6, r7, lr} \n\t" \
|
||||
"mov r4, r8 \n\t" \
|
||||
"mov r5, r9 \n\t" \
|
||||
"mov r6, r10 \n\t" \
|
||||
"mov r7, r11 \n\t" \
|
||||
"push {r4, r5, r6, r7}"); \
|
||||
}
|
||||
|
||||
#define POP_CONTEXT(sp) { \
|
||||
asm ("pop {r4, r5, r6, r7} \n\t" \
|
||||
"mov r8, r4 \n\t" \
|
||||
"mov r9, r5 \n\t" \
|
||||
"mov r10, r6 \n\t" \
|
||||
"mov r11, r7 \n\t" \
|
||||
"pop {r4, r5, r6, r7, pc}"); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Performs a context switch between two threads.
|
||||
* @details This is the most critical code in any port, this function
|
||||
* is responsible for the context switch between 2 threads.
|
||||
* @note The implementation of this code affects <b>directly</b> the context
|
||||
* switch performance so optimize here as much as you can.
|
||||
*
|
||||
* @param[in] ntp the thread to be switched in
|
||||
* @param[in] otp the thread to be switched out
|
||||
*/
|
||||
void port_switch(Thread *ntp, Thread *otp) {
|
||||
|
||||
/* Stack overflow check, if enabled.*/
|
||||
#if CH_DBG_ENABLE_STACK_CHECK
|
||||
if ((void *)(r13 - 1) < (void *)(otp + 1))
|
||||
asm volatile ("movs r0, #0 \n\t"
|
||||
"b chDbgPanic");
|
||||
#endif /* CH_DBG_ENABLE_STACK_CHECK */
|
||||
|
||||
PUSH_CONTEXT(r13);
|
||||
|
||||
asm ("str sp, [r1, #12] \n\t"
|
||||
"ldr sp, [r0, #12]");
|
||||
|
||||
POP_CONTEXT(r13);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Start a thread by invoking its work function.
|
||||
* @details If the work function returns @p chThdExit() is automatically
|
||||
* invoked.
|
||||
*/
|
||||
void _port_thread_start(void) {
|
||||
|
||||
port_unlock();
|
||||
asm ("mov r0, r5 \n\t"
|
||||
"blx r4 \n\t"
|
||||
"bl chThdExit");
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
|
|
@ -216,6 +216,18 @@ struct intctx {
|
|||
#define port_wait_for_interrupt()
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Performs a context switch between two threads.
|
||||
* @details This is the most critical code in any port, this function
|
||||
* is responsible for the context switch between 2 threads.
|
||||
* @note The implementation of this code affects <b>directly</b> the context
|
||||
* switch performance so optimize here as much as you can.
|
||||
*
|
||||
* @param[in] ntp the thread to be switched in
|
||||
* @param[in] otp the thread to be switched out
|
||||
*/
|
||||
#define port_switch(ntp, otp) _port_switch(ntp, otp)
|
||||
|
||||
#if !defined(__DOXYGEN__)
|
||||
extern regarm_t _port_saved_pc;
|
||||
extern unsigned _port_irq_nesting;
|
||||
|
@ -225,8 +237,9 @@ extern unsigned _port_irq_nesting;
|
|||
extern "C" {
|
||||
#endif
|
||||
void port_halt(void);
|
||||
void port_switch(Thread *ntp, Thread *otp);
|
||||
void _port_switch_from_irq(void);
|
||||
void _port_switch(Thread *ntp, Thread *otp);
|
||||
void _port_irq_epilogue(void);
|
||||
void _port_switch_from_isr(void);
|
||||
void _port_thread_start(void);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -225,7 +225,7 @@ struct intctx {
|
|||
* @param[in] ntp the thread to be switched in
|
||||
* @param[in] otp the thread to be switched out
|
||||
*/
|
||||
#define port_switch(ntp, otp) _port_switch(ntp, otp)
|
||||
#define port_switch(ntp, otp) _port_switch(ntp, otp)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 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/>.
|
||||
*/
|
||||
|
||||
MODULE ?chcoreasm_v6m
|
||||
|
||||
AAPCS INTERWORK, VFP_COMPATIBLE
|
||||
PRESERVE8
|
||||
|
||||
/*
|
||||
* Imports the Cortex-Mx parameters header and performs the same calculations
|
||||
* done in chcore.h.
|
||||
*/
|
||||
#include "cmparams.h"
|
||||
|
||||
#define CORTEX_PRIORITY_MASK(n) ((n) << (8 - CORTEX_PRIORITY_BITS))
|
||||
|
||||
#ifndef CORTEX_PRIORITY_SVCALL
|
||||
#define CORTEX_PRIORITY_SVCALL 1
|
||||
#endif
|
||||
|
||||
EXTCTX_SIZE SET 32
|
||||
CONTEXT_OFFSET SET 12
|
||||
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
|
||||
EXTERN chThdExit
|
||||
EXTERN chSchIsRescRequiredExI
|
||||
EXTERN chSchDoRescheduleI
|
||||
EXTERN _port_saved_pc
|
||||
EXTERN _port_irq_nesting
|
||||
|
||||
THUMB
|
||||
|
||||
/*
|
||||
* Performs a context switch between two threads.
|
||||
*/
|
||||
PUBLIC _port_switch
|
||||
_port_switch:
|
||||
push {r4, r5, r6, r7, lr}
|
||||
mov r4, r8
|
||||
mov r5, r9
|
||||
mov r6, r10
|
||||
mov r7, r11
|
||||
push {r4, r5, r6, r7}
|
||||
mov r3, sp
|
||||
str r3, [r1, #CONTEXT_OFFSET]
|
||||
ldr r3, [r0, #CONTEXT_OFFSET]
|
||||
mov sp, r3
|
||||
pop {r4, r5, r6, r7}
|
||||
mov r8, r4
|
||||
mov r9, r5
|
||||
mov r10, r6
|
||||
mov r11, r7
|
||||
pop {r4, r5, r6, r7, pc}
|
||||
|
||||
/*
|
||||
* Start a thread by invoking its work function.
|
||||
* If the work function returns @p chThdExit() is automatically invoked.
|
||||
*/
|
||||
PUBLIC _port_thread_start
|
||||
_port_thread_start:
|
||||
cpsie i
|
||||
mov r0, r5
|
||||
blx r4
|
||||
bl chThdExit
|
||||
|
||||
/*
|
||||
* Post-IRQ switch code.
|
||||
* Exception handlers return here for context switching.
|
||||
*/
|
||||
PUBLIC _port_switch_from_isr
|
||||
_port_switch_from_isr:
|
||||
/* Note, saves r4 to make space for the PC.*/
|
||||
push {r0, r1, r2, r3, r4}
|
||||
mrs r0, APSR
|
||||
mov r1, r12
|
||||
push {r0, r1, lr}
|
||||
ldr r0, =_port_saved_pc
|
||||
ldr r0, [r0]
|
||||
adds r0, r0, #1
|
||||
str r0, [sp, #28]
|
||||
bl chSchDoRescheduleI
|
||||
pop {r0, r1, r2}
|
||||
mov r12, r1
|
||||
msr APSR, r0
|
||||
mov lr, r2
|
||||
cpsie i
|
||||
pop {r0, r1, r2, r3, pc}
|
||||
|
||||
/*
|
||||
* Reschedule verification and setup after an IRQ.
|
||||
*/
|
||||
PUBLIC _port_irq_epilogue
|
||||
_port_irq_epilogue:
|
||||
push {r4, lr}
|
||||
cpsid i
|
||||
ldr r2, =_port_irq_nesting
|
||||
ldr r3, [r2]
|
||||
subs r3, r3, #1
|
||||
str r3, [r2]
|
||||
cmp r3, #0
|
||||
beq .L34
|
||||
cpsie i
|
||||
pop {r4, pc}
|
||||
.L34:
|
||||
bl chSchIsRescRequiredExI
|
||||
cmp r0, #0
|
||||
beq .L31
|
||||
mrs r1, PSP
|
||||
ldr r2, =_port_saved_pc
|
||||
ldr r3, [r1, #24]
|
||||
str r3, [r2]
|
||||
ldr r3, =_port_switch_from_isr
|
||||
str r3, [r1, #24]
|
||||
.L31:
|
||||
pop {r4, pc}
|
||||
|
||||
END
|
Loading…
Reference in New Issue