From a884e58e2cea877f804cb643d4d1e0909bd1fa49 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 30 Oct 2010 11:18:28 +0000 Subject: Added a polled exchange function to the SPI driver model, implemented on LPCxxxx SPI drivers. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2302 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- demos/ARM7-LPC214x-FATFS-GCC/main.c | 2 -- demos/ARMCM0-LPC1114-GCC/main.c | 29 ++++++++++++++--------------- demos/ARMCM3-LPC1343-GCC/main.c | 27 +++++++++++++-------------- docs/reports/LPC1114-48.txt | 34 ++++++++++++++++++++-------------- docs/reports/LPC1343-72.txt | 34 ++++++++++++++++++++-------------- docs/reports/LPC2148-48-ARM.txt | 31 +++++++++++++++++-------------- docs/reports/LPC2148-48-THUMB.txt | 25 ++++++++++++++----------- os/hal/include/spi.h | 15 +++++++++++++++ os/hal/platforms/LPC11xx/spi_lld.c | 28 +++++++++++++++++++++++----- os/hal/platforms/LPC11xx/spi_lld.h | 1 + os/hal/platforms/LPC13xx/spi_lld.c | 27 +++++++++++++++++++++++---- os/hal/platforms/LPC13xx/spi_lld.h | 1 + os/hal/platforms/LPC214x/spi_lld.c | 31 +++++++++++++++++++++++++------ os/hal/platforms/LPC214x/spi_lld.h | 5 +---- os/hal/templates/halconf.h | 11 +++++++++++ os/hal/templates/spi_lld.c | 16 ++++++++++++++++ os/hal/templates/spi_lld.h | 1 + readme.txt | 7 +++++-- todo.txt | 4 +--- 19 files changed, 221 insertions(+), 108 deletions(-) diff --git a/demos/ARM7-LPC214x-FATFS-GCC/main.c b/demos/ARM7-LPC214x-FATFS-GCC/main.c index 92c4563e0..ffe50af6a 100644 --- a/demos/ARM7-LPC214x-FATFS-GCC/main.c +++ b/demos/ARM7-LPC214x-FATFS-GCC/main.c @@ -47,7 +47,6 @@ static SPIConfig hs_spicfg = { IOPORT1, PA_SSEL1, CR0_DSS8BIT | CR0_FRFSPI | CR0_CLOCKRATE(0), - 0, 2 }; @@ -57,7 +56,6 @@ static SPIConfig ls_spicfg = { IOPORT1, PA_SSEL1, CR0_DSS8BIT | CR0_FRFSPI | CR0_CLOCKRATE(0), - 0, 254 }; diff --git a/demos/ARMCM0-LPC1114-GCC/main.c b/demos/ARMCM0-LPC1114-GCC/main.c index 046ac6fe6..61d48003f 100644 --- a/demos/ARMCM0-LPC1114-GCC/main.c +++ b/demos/ARMCM0-LPC1114-GCC/main.c @@ -24,7 +24,7 @@ /* * Conversion table from hex digit to 7 segments encoding, bit 5 controls the * dot. - * 8 = LU, 4 = RL, 2 = D, 1 = RU, 8 = U, 4 = M, 2 = LL, 1 = L. + * 8 = LU, 4 = RL, 2 = D, 1 = RU, 8 = U, 4 = M, 2 = LL, 1 = L. */ static uint8_t digits[32] = { 0x24, 0xAF, 0xE0, 0xA2, 0x2B, 0x32, 0x30, 0xA7, @@ -33,14 +33,9 @@ static uint8_t digits[32] = { 0x00, 0x02, 0x01, 0x18, 0x54, 0x88, 0x50, 0x51 }; -static void endsend(SPIDriver *spip) { - - spiUnselect(spip); -} - /* Maximum speed SPI configuration (1MHz, CPHA=0, CPOL=0).*/ static SPIConfig spicfg = { - endsend, + NULL, GPIO1, GPIO1_SPI0SEL, CR0_DSS8BIT | CR0_FRFSPI | CR0_CLOCKRATE(0), @@ -52,19 +47,13 @@ static SPIConfig spicfg = { */ static WORKING_AREA(waThread1, 128); static msg_t Thread1(void *arg) { - uint8_t i = 0; (void)arg; while (TRUE) { - spiSelect(&SPID1); - spiStartSend(&SPID1, 1, &digits[i]); palClearPad(GPIO0, GPIO0_LED2); chThdSleepMilliseconds(500); - spiSelect(&SPID1); - spiStartSend(&SPID1, 1, &digits[i | 0x10]); palSetPad(GPIO0, GPIO0_LED2); chThdSleepMilliseconds(500); - i = (i + 1) & 15; } return 0; } @@ -105,6 +94,7 @@ static msg_t Thread2(void *arg) { * on entry. */ int main(int argc, char **argv) { + uint8_t i; (void)argc; (void)argv; @@ -122,13 +112,22 @@ int main(int argc, char **argv) { chThdCreateStatic(waThread2, sizeof(waThread2), NORMALPRIO, Thread2, NULL); /* - * Normal main() thread activity, in this demo it does nothing except - * sleeping in a loop and check the button state. + * Normal main() thread activity, in this demo it updates the 7-segments + * display on the LPCXpresso main board using the SPI driver. */ + i = 0; while (TRUE) { if (!palReadPad(GPIO0, GPIO0_SW3)) TestThread(&SD1); + spiSelect(&SPID1); + spiSend(&SPID1, 1, &digits[i]); /* Non polled method. */ + spiUnselect(&SPID1); chThdSleepMilliseconds(500); + spiSelect(&SPID1); + spiPolledExchange(&SPID1, digits[i | 0x10]); /* Polled method. */ + spiUnselect(&SPID1); + chThdSleepMilliseconds(500); + i = (i + 1) & 15; } return 0; } diff --git a/demos/ARMCM3-LPC1343-GCC/main.c b/demos/ARMCM3-LPC1343-GCC/main.c index 092cecdbb..a645bf3d2 100644 --- a/demos/ARMCM3-LPC1343-GCC/main.c +++ b/demos/ARMCM3-LPC1343-GCC/main.c @@ -33,14 +33,9 @@ static uint8_t digits[32] = { 0x00, 0x02, 0x01, 0x18, 0x54, 0x88, 0x50, 0x51 }; -static void endsend(SPIDriver *spip) { - - spiUnselect(spip); -} - /* Maximum speed SPI configuration (1MHz, CPHA=0, CPOL=0).*/ static SPIConfig spicfg = { - endsend, + NULL, GPIO1, GPIO1_SPI0SEL, CR0_DSS8BIT | CR0_FRFSPI | CR0_CLOCKRATE(0), @@ -52,19 +47,13 @@ static SPIConfig spicfg = { */ static WORKING_AREA(waThread1, 128); static msg_t Thread1(void *arg) { - uint8_t i = 0; (void)arg; while (TRUE) { - spiSelect(&SPID1); - spiStartSend(&SPID1, 1, &digits[i]); palClearPad(GPIO0, GPIO0_LED2); chThdSleepMilliseconds(500); - spiSelect(&SPID1); - spiStartSend(&SPID1, 1, &digits[i | 0x10]); palSetPad(GPIO0, GPIO0_LED2); chThdSleepMilliseconds(500); - i = (i + 1) & 15; } return 0; } @@ -105,6 +94,7 @@ static msg_t Thread2(void *arg) { * on entry. */ int main(int argc, char **argv) { + uint8_t i; (void)argc; (void)argv; @@ -122,13 +112,22 @@ int main(int argc, char **argv) { chThdCreateStatic(waThread2, sizeof(waThread2), NORMALPRIO, Thread2, NULL); /* - * Normal main() thread activity, in this demo it does nothing except - * sleeping in a loop and check the button state. + * Normal main() thread activity, in this demo it updates the 7-segments + * display on the LPCXpresso main board using the SPI driver. */ + i = 0; while (TRUE) { if (!palReadPad(GPIO0, GPIO0_SW3)) TestThread(&SD1); + spiSelect(&SPID1); + spiSend(&SPID1, 1, &digits[i]); /* Non polled method. */ + spiUnselect(&SPID1); chThdSleepMilliseconds(500); + spiSelect(&SPID1); + spiPolledExchange(&SPID1, digits[i | 0x10]); /* Polled method. */ + spiUnselect(&SPID1); + chThdSleepMilliseconds(500); + i = (i + 1) & 15; } return 0; } diff --git a/docs/reports/LPC1114-48.txt b/docs/reports/LPC1114-48.txt index 33c853f5d..ec518e4f6 100644 --- a/docs/reports/LPC1114-48.txt +++ b/docs/reports/LPC1114-48.txt @@ -5,7 +5,7 @@ Settings: CLK=48, (3 wait states) *** ChibiOS/RT test suite *** -*** Kernel: 1.5.5unstable +*** Kernel: 2.1.2unstable *** GCC Version: 4.3.3 *** Architecture: ARMv6-M *** Core Variant: Cortex-M0 @@ -34,6 +34,9 @@ Settings: CLK=48, (3 wait states) --- Test Case 2.3 (Semaphores, atomic signal-wait) --- Result: SUCCESS ---------------------------------------------------------------------------- +--- Test Case 2.4 (Binary Semaphores, functionality) +--- Result: SUCCESS +---------------------------------------------------------------------------- --- Test Case 3.1 (Mutexes, priority enqueuing test) --- Result: SUCCESS ---------------------------------------------------------------------------- @@ -85,6 +88,9 @@ Settings: CLK=48, (3 wait states) --- Test Case 9.2 (Dynamic APIs, threads creation from memory pool) --- Result: SUCCESS ---------------------------------------------------------------------------- +--- Test Case 9.3 (Dynamic APIs, registry and references) +--- Result: SUCCESS +---------------------------------------------------------------------------- --- Test Case 10.1 (Queues, input queues) --- Result: SUCCESS ---------------------------------------------------------------------------- @@ -92,55 +98,55 @@ Settings: CLK=48, (3 wait states) --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.1 (Benchmark, messages #1) ---- Score : 125437 msgs/S, 250874 ctxswc/S +--- Score : 124135 msgs/S, 248270 ctxswc/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.2 (Benchmark, messages #2) ---- Score : 102120 msgs/S, 204240 ctxswc/S +--- Score : 99992 msgs/S, 199984 ctxswc/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.3 (Benchmark, messages #3) ---- Score : 102120 msgs/S, 204240 ctxswc/S +--- Score : 99992 msgs/S, 199984 ctxswc/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.4 (Benchmark, context switch) ---- Score : 384256 ctxswc/S +--- Score : 380432 ctxswc/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.5 (Benchmark, threads, full cycle) ---- Score : 78221 threads/S +--- Score : 80188 threads/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.6 (Benchmark, threads, create only) ---- Score : 105737 threads/S +--- Score : 111404 threads/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.7 (Benchmark, mass reschedule, 5 threads) ---- Score : 31756 reschedules/S, 190536 ctxswc/S +--- Score : 31034 reschedules/S, 186204 ctxswc/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.8 (Benchmark, round robin context switching) ---- Score : 238060 ctxswc/S +--- Score : 253200 ctxswc/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.9 (Benchmark, I/O Queues throughput) ---- Score : 316568 bytes/S +--- Score : 298992 bytes/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.10 (Benchmark, virtual timers set/reset) ---- Score : 355402 timers/S +--- Score : 350196 timers/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.11 (Benchmark, semaphores wait/signal) ---- Score : 607004 wait+signal/S +--- Score : 591948 wait+signal/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.12 (Benchmark, mutexes lock/unlock) ---- Score : 371272 lock+unlock/S +--- Score : 334860 lock+unlock/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.13 (Benchmark, RAM footprint) ---- System: 340 bytes +--- System: 360 bytes --- Thread: 68 bytes --- Timer : 20 bytes --- Semaph: 12 bytes diff --git a/docs/reports/LPC1343-72.txt b/docs/reports/LPC1343-72.txt index be0807c5c..277879671 100644 --- a/docs/reports/LPC1343-72.txt +++ b/docs/reports/LPC1343-72.txt @@ -5,7 +5,7 @@ Settings: CLK=72, (3 wait states) *** ChibiOS/RT test suite *** -*** Kernel: 1.5.5unstable +*** Kernel: 2.1.2unstable *** GCC Version: 4.3.3 *** Architecture: ARMv7-M *** Core Variant: Cortex-M3 @@ -34,6 +34,9 @@ Settings: CLK=72, (3 wait states) --- Test Case 2.3 (Semaphores, atomic signal-wait) --- Result: SUCCESS ---------------------------------------------------------------------------- +--- Test Case 2.4 (Binary Semaphores, functionality) +--- Result: SUCCESS +---------------------------------------------------------------------------- --- Test Case 3.1 (Mutexes, priority enqueuing test) --- Result: SUCCESS ---------------------------------------------------------------------------- @@ -85,6 +88,9 @@ Settings: CLK=72, (3 wait states) --- Test Case 9.2 (Dynamic APIs, threads creation from memory pool) --- Result: SUCCESS ---------------------------------------------------------------------------- +--- Test Case 9.3 (Dynamic APIs, registry and references) +--- Result: SUCCESS +---------------------------------------------------------------------------- --- Test Case 10.1 (Queues, input queues) --- Result: SUCCESS ---------------------------------------------------------------------------- @@ -92,55 +98,55 @@ Settings: CLK=72, (3 wait states) --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.1 (Benchmark, messages #1) ---- Score : 246902 msgs/S, 493804 ctxswc/S +--- Score : 241881 msgs/S, 483762 ctxswc/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.2 (Benchmark, messages #2) ---- Score : 199024 msgs/S, 398048 ctxswc/S +--- Score : 196281 msgs/S, 392562 ctxswc/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.3 (Benchmark, messages #3) ---- Score : 199024 msgs/S, 398048 ctxswc/S +--- Score : 196281 msgs/S, 392562 ctxswc/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.4 (Benchmark, context switch) ---- Score : 797224 ctxswc/S +--- Score : 806072 ctxswc/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.5 (Benchmark, threads, full cycle) ---- Score : 154518 threads/S +--- Score : 155163 threads/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.6 (Benchmark, threads, create only) ---- Score : 212574 threads/S +--- Score : 219028 threads/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.7 (Benchmark, mass reschedule, 5 threads) ---- Score : 65262 reschedules/S, 391572 ctxswc/S +--- Score : 63239 reschedules/S, 379434 ctxswc/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.8 (Benchmark, round robin context switching) ---- Score : 476648 ctxswc/S +--- Score : 473392 ctxswc/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.9 (Benchmark, I/O Queues throughput) ---- Score : 521644 bytes/S +--- Score : 482836 bytes/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.10 (Benchmark, virtual timers set/reset) ---- Score : 674724 timers/S +--- Score : 707908 timers/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.11 (Benchmark, semaphores wait/signal) ---- Score : 977676 wait+signal/S +--- Score : 909504 wait+signal/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.12 (Benchmark, mutexes lock/unlock) ---- Score : 662296 lock+unlock/S +--- Score : 588968 lock+unlock/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.13 (Benchmark, RAM footprint) ---- System: 324 bytes +--- System: 360 bytes --- Thread: 68 bytes --- Timer : 20 bytes --- Semaph: 12 bytes diff --git a/docs/reports/LPC2148-48-ARM.txt b/docs/reports/LPC2148-48-ARM.txt index 9cae2a078..e5c3669fb 100644 --- a/docs/reports/LPC2148-48-ARM.txt +++ b/docs/reports/LPC2148-48-ARM.txt @@ -5,8 +5,8 @@ Settings: CCLK=48, MAMCR=2, MAMTIM=3 (3 wait states) *** ChibiOS/RT test suite *** -*** Kernel: 1.5.7unstable -*** GCC Version: 4.5.0 +*** Kernel: 2.1.2unstable +*** GCC Version: 4.5.1 *** Architecture: ARM *** Core Variant: ARM7TDMI *** Platform: LPC214x @@ -34,6 +34,9 @@ Settings: CCLK=48, MAMCR=2, MAMTIM=3 (3 wait states) --- Test Case 2.3 (Semaphores, atomic signal-wait) --- Result: SUCCESS ---------------------------------------------------------------------------- +--- Test Case 2.4 (Binary Semaphores, functionality) +--- Result: SUCCESS +---------------------------------------------------------------------------- --- Test Case 3.1 (Mutexes, priority enqueuing test) --- Result: SUCCESS ---------------------------------------------------------------------------- @@ -95,51 +98,51 @@ Settings: CCLK=48, MAMCR=2, MAMTIM=3 (3 wait states) --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.1 (Benchmark, messages #1) ---- Score : 138220 msgs/S, 276440 ctxswc/S +--- Score : 145385 msgs/S, 290770 ctxswc/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.2 (Benchmark, messages #2) ---- Score : 104419 msgs/S, 208838 ctxswc/S +--- Score : 113890 msgs/S, 227780 ctxswc/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.3 (Benchmark, messages #3) ---- Score : 104419 msgs/S, 208838 ctxswc/S +--- Score : 113890 msgs/S, 227780 ctxswc/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.4 (Benchmark, context switch) ---- Score : 460416 ctxswc/S +--- Score : 493760 ctxswc/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.5 (Benchmark, threads, full cycle) ---- Score : 85707 threads/S +--- Score : 89746 threads/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.6 (Benchmark, threads, create only) ---- Score : 124543 threads/S +--- Score : 128237 threads/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.7 (Benchmark, mass reschedule, 5 threads) ---- Score : 33282 reschedules/S, 199692 ctxswc/S +--- Score : 35380 reschedules/S, 212280 ctxswc/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.8 (Benchmark, round robin context switching) ---- Score : 265316 ctxswc/S +--- Score : 276084 ctxswc/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.9 (Benchmark, I/O Queues throughput) ---- Score : 316988 bytes/S +--- Score : 341980 bytes/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.10 (Benchmark, virtual timers set/reset) ---- Score : 335642 timers/S +--- Score : 333360 timers/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.11 (Benchmark, semaphores wait/signal) ---- Score : 585024 wait+signal/S +--- Score : 607412 wait+signal/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.12 (Benchmark, mutexes lock/unlock) ---- Score : 368620 lock+unlock/S +--- Score : 380408 lock+unlock/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.13 (Benchmark, RAM footprint) diff --git a/docs/reports/LPC2148-48-THUMB.txt b/docs/reports/LPC2148-48-THUMB.txt index aeaae4845..a45dc45b5 100644 --- a/docs/reports/LPC2148-48-THUMB.txt +++ b/docs/reports/LPC2148-48-THUMB.txt @@ -5,8 +5,8 @@ Settings: CCLK=48, MAMCR=2, MAMTIM=3 (3 wait states) *** ChibiOS/RT test suite *** -*** Kernel: 1.5.7unstable -*** GCC Version: 4.5.0 +*** Kernel: 2.1.2unstable +*** GCC Version: 4.5.1 *** Architecture: ARM *** Core Variant: ARM7TDMI *** Platform: LPC214x @@ -34,6 +34,9 @@ Settings: CCLK=48, MAMCR=2, MAMTIM=3 (3 wait states) --- Test Case 2.3 (Semaphores, atomic signal-wait) --- Result: SUCCESS ---------------------------------------------------------------------------- +--- Test Case 2.4 (Binary Semaphores, functionality) +--- Result: SUCCESS +---------------------------------------------------------------------------- --- Test Case 3.1 (Mutexes, priority enqueuing test) --- Result: SUCCESS ---------------------------------------------------------------------------- @@ -95,15 +98,15 @@ Settings: CCLK=48, MAMCR=2, MAMTIM=3 (3 wait states) --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.1 (Benchmark, messages #1) ---- Score : 106460 msgs/S, 212920 ctxswc/S +--- Score : 106223 msgs/S, 212446 ctxswc/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.2 (Benchmark, messages #2) ---- Score : 88195 msgs/S, 176390 ctxswc/S +--- Score : 88032 msgs/S, 176064 ctxswc/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.3 (Benchmark, messages #3) ---- Score : 88195 msgs/S, 176390 ctxswc/S +--- Score : 88032 msgs/S, 176064 ctxswc/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.4 (Benchmark, context switch) @@ -111,23 +114,23 @@ Settings: CCLK=48, MAMCR=2, MAMTIM=3 (3 wait states) --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.5 (Benchmark, threads, full cycle) ---- Score : 69580 threads/S +--- Score : 71990 threads/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.6 (Benchmark, threads, create only) ---- Score : 104828 threads/S +--- Score : 110394 threads/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.7 (Benchmark, mass reschedule, 5 threads) ---- Score : 29580 reschedules/S, 177480 ctxswc/S +--- Score : 29290 reschedules/S, 175740 ctxswc/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.8 (Benchmark, round robin context switching) ---- Score : 221556 ctxswc/S +--- Score : 221560 ctxswc/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.9 (Benchmark, I/O Queues throughput) ---- Score : 261124 bytes/S +--- Score : 261396 bytes/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.10 (Benchmark, virtual timers set/reset) @@ -139,7 +142,7 @@ Settings: CCLK=48, MAMCR=2, MAMTIM=3 (3 wait states) --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.12 (Benchmark, mutexes lock/unlock) ---- Score : 260148 lock+unlock/S +--- Score : 244200 lock+unlock/S --- Result: SUCCESS ---------------------------------------------------------------------------- --- Test Case 11.13 (Benchmark, RAM footprint) diff --git a/os/hal/include/spi.h b/os/hal/include/spi.h index ed8ba8de0..92fccec61 100644 --- a/os/hal/include/spi.h +++ b/os/hal/include/spi.h @@ -186,6 +186,21 @@ typedef enum { spi_lld_receive(spip, n, rxbuf); \ } +/** + * @brief Exchanges one frame using a polled wait. + * @details This synchronous function exchanges one frame using a polled + * synchronization method. This function is useful when exchanging + * small amount of data on high speed channels, usually in this + * situation is much more efficient just wait for completion using + * polling than suspending the thread waiting for an interrupt. + * @note This API is implemented as a macro in order to minimize latency. + * + * @param[in] spip pointer to the @p SPIDriver object + * @param[in] frame the data frame to send over the SPI bus + * @return The received data frame from the SPI bus. + */ +#define spiPolledExchange(spip, frame) spi_lld_polled_exchange(spip, frame) + #if SPI_USE_WAIT || defined(__DOXYGEN__) /** * @brief Waits for operation completion. diff --git a/os/hal/platforms/LPC11xx/spi_lld.c b/os/hal/platforms/LPC11xx/spi_lld.c index becf691a3..8b0081b5e 100644 --- a/os/hal/platforms/LPC11xx/spi_lld.c +++ b/os/hal/platforms/LPC11xx/spi_lld.c @@ -234,13 +234,15 @@ void spi_lld_start(SPIDriver *spip) { void spi_lld_stop(SPIDriver *spip) { if (spip->spd_state != SPI_STOP) { + spip->spd_ssp->CR1 = 0; + spip->spd_ssp->CR0 = 0; + spip->spd_ssp->CPSR = 0; #if LPC11xx_SPI_USE_SSP0 if (&SPID1 == spip) { LPC_SYSCON->PRESETCTRL &= ~1; LPC_SYSCON->SYSAHBCLKCTRL &= ~(1 << 11); LPC_SYSCON->SSP0CLKDIV = 0; NVICDisableVector(SSP0_IRQn); - return; } #endif #if LPC11xx_SPI_USE_SSP1 @@ -249,12 +251,8 @@ void spi_lld_stop(SPIDriver *spip) { LPC_SYSCON->SYSAHBCLKCTRL &= ~(1 << 18); LPC_SYSCON->SSP1CLKDIV = 0; NVICDisableVector(SSP1_IRQn); - return; } #endif - spip->spd_ssp->CR1 = 0; - spip->spd_ssp->CR0 = 0; - spip->spd_ssp->CPSR = 0; } } @@ -372,6 +370,26 @@ void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) { spip->spd_ssp->IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX; } +/** + * @brief Exchanges one frame using a polled wait. + * @details This synchronous function exchanges one frame using a polled + * synchronization method. This function is useful when exchanging + * small amount of data on high speed channels, usually in this + * situation is much more efficient just wait for completion using + * polling than suspending the thread waiting for an interrupt. + * + * @param[in] spip pointer to the @p SPIDriver object + * @param[in] frame the data frame to send over the SPI bus + * @return The received data frame from the SPI bus. + */ +uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame) { + + spip->spd_ssp->DR = (uint32_t)frame; + while ((spip->spd_ssp->SR & SR_RNE) == 0) + ; + return (uint16_t)spip->spd_ssp->DR; +} + #endif /* CH_HAL_USE_SPI */ /** @} */ diff --git a/os/hal/platforms/LPC11xx/spi_lld.h b/os/hal/platforms/LPC11xx/spi_lld.h index 021099097..b3f38056f 100644 --- a/os/hal/platforms/LPC11xx/spi_lld.h +++ b/os/hal/platforms/LPC11xx/spi_lld.h @@ -334,6 +334,7 @@ extern "C" { const void *txbuf, void *rxbuf); void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf); void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf); + uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame); #ifdef __cplusplus } #endif diff --git a/os/hal/platforms/LPC13xx/spi_lld.c b/os/hal/platforms/LPC13xx/spi_lld.c index d9b8ef06f..ee6a71c8f 100644 --- a/os/hal/platforms/LPC13xx/spi_lld.c +++ b/os/hal/platforms/LPC13xx/spi_lld.c @@ -196,18 +196,17 @@ void spi_lld_start(SPIDriver *spip) { void spi_lld_stop(SPIDriver *spip) { if (spip->spd_state != SPI_STOP) { + spip->spd_ssp->CR1 = 0; + spip->spd_ssp->CR0 = 0; + spip->spd_ssp->CPSR = 0; #if LPC13xx_SPI_USE_SSP0 if (&SPID1 == spip) { LPC_SYSCON->PRESETCTRL &= ~1; LPC_SYSCON->SYSAHBCLKCTRL &= ~(1 << 11); LPC_SYSCON->SSPCLKDIV = 0; NVICDisableVector(SSP_IRQn); - return; } #endif - spip->spd_ssp->CR1 = 0; - spip->spd_ssp->CR0 = 0; - spip->spd_ssp->CPSR = 0; } } @@ -325,6 +324,26 @@ void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) { spip->spd_ssp->IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX; } +/** + * @brief Exchanges one frame using a polled wait. + * @details This synchronous function exchanges one frame using a polled + * synchronization method. This function is useful when exchanging + * small amount of data on high speed channels, usually in this + * situation is much more efficient just wait for completion using + * polling than suspending the thread waiting for an interrupt. + * + * @param[in] spip pointer to the @p SPIDriver object + * @param[in] frame the data frame to send over the SPI bus + * @return The received data frame from the SPI bus. + */ +uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame) { + + spip->spd_ssp->DR = (uint32_t)frame; + while ((spip->spd_ssp->SR & SR_RNE) == 0) + ; + return (uint16_t)spip->spd_ssp->DR; +} + #endif /* CH_HAL_USE_SPI */ /** @} */ diff --git a/os/hal/platforms/LPC13xx/spi_lld.h b/os/hal/platforms/LPC13xx/spi_lld.h index c85f358b8..add7c3323 100644 --- a/os/hal/platforms/LPC13xx/spi_lld.h +++ b/os/hal/platforms/LPC13xx/spi_lld.h @@ -334,6 +334,7 @@ extern "C" { const void *txbuf, void *rxbuf); void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf); void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf); + uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame); #ifdef __cplusplus } #endif diff --git a/os/hal/platforms/LPC214x/spi_lld.c b/os/hal/platforms/LPC214x/spi_lld.c index 7c3287298..6df0106b2 100644 --- a/os/hal/platforms/LPC214x/spi_lld.c +++ b/os/hal/platforms/LPC214x/spi_lld.c @@ -99,7 +99,7 @@ static void serve_interrupt(SPIDriver *spip) { (void)ssp->SSP_DR; if (--spip->spd_rxcnt == 0) { chDbgAssert(spip->spd_txcnt == 0, - "chSemResetI(), #1", "counter out of synch"); + "spi_serve_interrupt(), #1", "counter out of synch"); /* Stops the IRQ sources.*/ ssp->SSP_IMSC = 0; /* Portable SPI ISR code defined in the high level driver, note, it is @@ -178,7 +178,7 @@ void spi_lld_start(SPIDriver *spip) { spip->spd_ssp->SSP_ICR = ICR_RT | ICR_ROR; spip->spd_ssp->SSP_CR0 = spip->spd_config->spc_cr0; spip->spd_ssp->SSP_CPSR = spip->spd_config->spc_cpsr; - spip->spd_ssp->SSP_CR1 = spip->spd_config->spc_cr1 | CR1_SSE; + spip->spd_ssp->SSP_CR1 = CR1_SSE; } /** @@ -191,16 +191,15 @@ void spi_lld_start(SPIDriver *spip) { void spi_lld_stop(SPIDriver *spip) { if (spip->spd_state != SPI_STOP) { + spip->spd_ssp->SSP_CR1 = 0; + spip->spd_ssp->SSP_CR0 = 0; + spip->spd_ssp->SSP_CPSR = 0; #if LPC214x_SPI_USE_SSP if (&SPID1 == spip) { PCONP = (PCONP & PCALL) & ~PCSPI1; VICIntEnClear = INTMASK(SOURCE_SPI1); } #endif - spip->spd_ssp->SSP_CR1 = 0; - spip->spd_ssp->SSP_CR0 = 0; - spip->spd_ssp->SSP_CPSR = 0; - PCONP &= ~PCSPI1; } } @@ -318,6 +317,26 @@ void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) { spip->spd_ssp->SSP_IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX; } +/** + * @brief Exchanges one frame using a polled wait. + * @details This synchronous function exchanges one frame using a polled + * synchronization method. This function is useful when exchanging + * small amount of data on high speed channels, usually in this + * situation is much more efficient just wait for completion using + * polling than suspending the thread waiting for an interrupt. + * + * @param[in] spip pointer to the @p SPIDriver object + * @param[in] frame the data frame to send over the SPI bus + * @return The received data frame from the SPI bus. + */ +uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame) { + + spip->spd_ssp->SSP_DR = (uint32_t)frame; + while ((spip->spd_ssp->SSP_SR & SR_RNE) == 0) + ; + return (uint16_t)spip->spd_ssp->SSP_DR; +} + #endif /* CH_HAL_USE_SPI */ /** @} */ diff --git a/os/hal/platforms/LPC214x/spi_lld.h b/os/hal/platforms/LPC214x/spi_lld.h index eafa23f88..a4b16f76a 100644 --- a/os/hal/platforms/LPC214x/spi_lld.h +++ b/os/hal/platforms/LPC214x/spi_lld.h @@ -116,10 +116,6 @@ typedef struct { * @brief SSP CR0 initialization data. */ uint16_t spc_cr0; - /** - * @brief SSP CR1 initialization data. - */ - uint16_t spc_cr1; /** * @brief SSP CPSR initialization data. */ @@ -205,6 +201,7 @@ extern "C" { const void *txbuf, void *rxbuf); void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf); void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf); + uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame); #ifdef __cplusplus } #endif diff --git a/os/hal/templates/halconf.h b/os/hal/templates/halconf.h index 20cd4c54e..d5cd47cb5 100644 --- a/os/hal/templates/halconf.h +++ b/os/hal/templates/halconf.h @@ -173,6 +173,17 @@ #define MMC_POLLING_DELAY 10 #endif +/** + * @brief Uses the SPI polled API for small data transfers. + * @details Polled transfers usually improve performance because it + * saves two context switches and interrupt servicing. Note + * that this option has no effect on large transfers which + * are always performed using DMAs/IRQs. + */ +#if !defined(MMC_USE_SPI_POLLING) || defined(__DOXYGEN__) +#define MMC_USE_SPI_POLLING TRUE +#endif + /*===========================================================================*/ /* PAL driver related settings. */ /*===========================================================================*/ diff --git a/os/hal/templates/spi_lld.c b/os/hal/templates/spi_lld.c index 1fca51d41..f3053f725 100644 --- a/os/hal/templates/spi_lld.c +++ b/os/hal/templates/spi_lld.c @@ -177,6 +177,22 @@ void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) { } +/** + * @brief Exchanges one frame using a polled wait. + * @details This synchronous function exchanges one frame using a polled + * synchronization method. This function is useful when exchanging + * small amount of data on high speed channels, usually in this + * situation is much more efficient just wait for completion using + * polling than suspending the thread waiting for an interrupt. + * + * @param[in] spip pointer to the @p SPIDriver object + * @param[in] frame the data frame to send over the SPI bus + * @return The received data frame from the SPI bus. + */ +uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame) { + +} + #endif /* CH_HAL_USE_SPI */ /** @} */ diff --git a/os/hal/templates/spi_lld.h b/os/hal/templates/spi_lld.h index 7fff799d1..acc6a699f 100644 --- a/os/hal/templates/spi_lld.h +++ b/os/hal/templates/spi_lld.h @@ -132,6 +132,7 @@ extern "C" { const void *txbuf, void *rxbuf); void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf); void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf); + uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame); #ifdef __cplusplus } #endif diff --git a/readme.txt b/readme.txt index 838f5eb2c..44a9c0405 100644 --- a/readme.txt +++ b/readme.txt @@ -100,10 +100,13 @@ - NEW: New I2C driver model (not complete and no implementations yet). - NEW: New SPI driver model, the new model supports both synchronous and asynchronous operations and, in general, simplifies the implementation of the - low level driver. The state diagram changed slightly changed so be careful. + low level driver. The new driver also specifies a simplified polled exchange + API, useful for efficiently sending small amount of data over high speed + connections. The driver state diagram changed slightly changed so be careful. - NEW: New ADC driver model, the new model supports both synchronous and asynchronous operations and, in general, simplifies the implementation of the - low level driver. The state diagram changed slightly changed so be careful. + low level driver. The driver state diagram changed slightly changed so be + careful. - NEW: Improved PWM driver model, added several macros that helps to setup configuration structures and to specify pulse widths also as percentages or degrees using a fixed point notation. Added new pwmEnableChannelI() and diff --git a/todo.txt b/todo.txt index 6c07249b1..a1ec0f505 100644 --- a/todo.txt +++ b/todo.txt @@ -43,10 +43,8 @@ X PDF generation from the documentation system (only separate documents, not a very similar DMA (waiting for the new STM8L-Discovery kit). - Add the STM32VL to the official STM32 HAL support (waiting for the new STM32-Discovery kit). -- Add a spiPolledExchange() API to the SPI driver model. +* Add an optional spiPolledExchange() API to the SPI driver model. - New STM8S/A SPI driver. -X Evaluate a new API for the SPI driver enabling quick transfers of few bytes - in polled mode. X Except for the above, bug fixing only until the 2.2.0 release. Within 2.3.x (hopefully) -- cgit v1.2.3