Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: cpputest mbed-dev_tmp
Diff: spi_master_asynch.cpp
- Revision:
- 0:829da9075ffa
diff -r 000000000000 -r 829da9075ffa spi_master_asynch.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/spi_master_asynch.cpp Tue Apr 26 02:12:17 2016 +0000
@@ -0,0 +1,332 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <stdio.h>
+#include "TestHarness.h"
+#include "mbed.h"
+
+#if !DEVICE_SPI || !DEVICE_SPI_ASYNCH
+#error spi_master_asynch requires asynch SPI
+#endif
+
+
+#define SHORT_XFR 3
+#define LONG_XFR 16
+#define TEST_BYTE0 0x00
+#define TEST_BYTE1 0x11
+#define TEST_BYTE2 0xFF
+#define TEST_BYTE3 0xAA
+#define TEST_BYTE4 0x55
+#define TEST_BYTE5 0x50
+
+#define TEST_BYTE_RX TEST_BYTE3
+#define TEST_BYTE_TX_BASE TEST_BYTE5
+
+#if defined(TARGET_K64F)
+#define TEST_MOSI_PIN PTD2
+#define TEST_MISO_PIN PTD3
+#define TEST_SCLK_PIN PTD1
+#define TEST_CS_PIN PTD0
+
+#elif defined(TARGET_EFM32LG_STK3600) || defined(TARGET_EFM32GG_STK3700) || defined(TARGET_EFM32WG_STK3800)
+#define TEST_MOSI_PIN PD0
+#define TEST_MISO_PIN PD1
+#define TEST_SCLK_PIN PD2
+#define TEST_CS_PIN PD3
+
+#elif defined(TARGET_EFM32ZG_STK3200)
+#define TEST_MOSI_PIN PD7
+#define TEST_MISO_PIN PD6
+#define TEST_SCLK_PIN PC15
+#define TEST_CS_PIN PC14
+
+#elif defined(TARGET_EFM32HG_STK3400)
+#define TEST_MOSI_PIN PE10
+#define TEST_MISO_PIN PE11
+#define TEST_SCLK_PIN PE12
+#define TEST_CS_PIN PE13
+
+#elif defined(TARGET_RZ_A1H)
+#define TEST_MOSI_PIN P10_14
+#define TEST_MISO_PIN P10_15
+#define TEST_SCLK_PIN P10_12
+#define TEST_CS_PIN P10_13
+
+#else
+#error Target not supported
+#endif
+
+volatile int why;
+volatile bool complete;
+void cbdone(int event) {
+ complete = true;
+ why = event;
+}
+
+
+TEST_GROUP(SPI_Master_Asynchronous)
+{
+ uint8_t tx_buf[LONG_XFR];
+ uint8_t rx_buf[LONG_XFR];
+ SPI *obj;
+ DigitalOut *cs;
+ event_callback_t callback;
+
+ void setup() {
+ obj = new SPI(TEST_MOSI_PIN, TEST_MISO_PIN, TEST_SCLK_PIN);
+ cs = new DigitalOut(TEST_CS_PIN);
+ complete = false;
+ why = 0;
+ callback.attach(cbdone);
+
+ // Set the default value of tx_buf
+ for (uint32_t i = 0; i < sizeof(tx_buf); i++) {
+ tx_buf[i] = i + TEST_BYTE_TX_BASE;
+ }
+ memset(rx_buf,TEST_BYTE_RX,sizeof(rx_buf));
+ }
+ void teardown() {
+ delete obj;
+ obj = NULL;
+ delete cs;
+ cs = NULL;
+ }
+ uint32_t cmpnbuf(uint8_t *expect, uint8_t *actual, uint32_t offset, uint32_t end, const char *file, uint32_t line)
+ {
+ uint32_t i;
+ for (i = offset; i < end; i++){
+ if (expect[i] != actual[i]) {
+ break;
+ }
+ }
+ if (i < end) {
+ CHECK_EQUAL_LOCATION((int)expect[i], (int)actual[i], file, line);
+ }
+ CHECK_EQUAL_LOCATION(end, i, file, line);
+ return i;
+ }
+ uint32_t cmpnbufc(uint8_t expect, uint8_t *actual, uint32_t offset, uint32_t end, const char *file, uint32_t line)
+ {
+ uint32_t i;
+ for (i = offset; i < end; i++){
+ if (expect != actual[i]) {
+ break;
+ }
+ }
+ if (i < end) {
+ CHECK_EQUAL_LOCATION((int)expect, (int)actual[i], file, line);
+ }
+ CHECK_EQUAL_LOCATION(end, i, file, line);
+ return i;
+ }
+ void dumpRXbuf() {
+ uint32_t i;
+ printf("\r\n");
+ printf("RX Buffer Contents: [");
+ //flushf(stdout);
+ for (i = 0; i < sizeof(rx_buf); i++){
+ printf("%02x",rx_buf[i]);
+ if (i+1 < sizeof(rx_buf)){
+ printf(",");
+ }
+ }
+ printf("]\r\n");
+ }
+};
+
+// SPI write tx length: FIFO-1, read length: 0
+// Checks: Null pointer exceptions, completion event
+TEST(SPI_Master_Asynchronous, short_tx_0_rx)
+{
+ int rc;
+ // Write a buffer of Short Transfer length.
+// rc = obj->transfer( tx_buf,SHORT_XFR,NULL,0, callback, -1);
+ rc = obj->transfer( tx_buf,SHORT_XFR,(uint8_t *)NULL,0, callback, -1);
+ CHECK_EQUAL(0, rc);
+
+ while (!complete);
+
+ // Make sure that the callback fires.
+ CHECK_EQUAL(why, SPI_EVENT_COMPLETE);
+
+ // TODO: Check for a null pointer exception
+}
+
+
+//
+// SPI write tx length: FIFO-1, read length: 0, non-null read pointer
+// Checks: Null pointer exceptions, completion event, canary values in read buffer
+TEST(SPI_Master_Asynchronous, short_tx_0_rx_nn)
+{
+ int rc;
+ // Write a buffer of Short Transfer length.
+ rc = obj->transfer( tx_buf,SHORT_XFR,rx_buf,0,callback, -1);
+ CHECK_EQUAL(0, rc);
+
+ while (!complete);
+
+ // Make sure that the callback fires.
+ CHECK_EQUAL(SPI_EVENT_COMPLETE, why);
+
+ // Check that the rx buffer is untouched
+ cmpnbufc(TEST_BYTE_RX,rx_buf,0,sizeof(rx_buf),__FILE__,__LINE__);
+}
+
+// SPI write tx length: 0, read length: FIFO-1
+// Checks: Receive value==fill character, completion event
+TEST(SPI_Master_Asynchronous, 0_tx_short_rx)
+{
+ int rc;
+ // Read a buffer of Short Transfer length.
+// rc = obj->transfer( NULL,0,rx_buf,SHORT_XFR,callback, -1);
+ rc = obj->transfer( (uint8_t *)NULL,0,rx_buf,SHORT_XFR,callback, -1);
+ CHECK_EQUAL(0, rc);
+
+ while (!complete);
+
+ // Make sure that the callback fires.
+ CHECK_EQUAL(SPI_EVENT_COMPLETE, why);
+
+ // TODO: Check for null pointer exception
+ // Check that the receive buffer contains the fill byte.
+ cmpnbufc(SPI_FILL_WORD,rx_buf,0,SHORT_XFR,__FILE__,__LINE__);
+ // Check that remaining portion of the receive buffer contains the rx test byte
+ cmpnbufc(TEST_BYTE_RX,rx_buf,SHORT_XFR,sizeof(rx_buf),__FILE__,__LINE__);
+}
+
+// SPI write tx length: 0, read length: FIFO-1
+// Checks: Receive value==fill character, completion event
+TEST(SPI_Master_Asynchronous, 0_tx_nn_short_rx)
+{
+ int rc;
+ // Read a buffer of Short Transfer length.
+ rc = obj->transfer(tx_buf,0,rx_buf,SHORT_XFR,callback, -1);
+ CHECK_EQUAL(0, rc);
+
+ while (!complete);
+
+ // Make sure that the callback fires.
+ CHECK_EQUAL(SPI_EVENT_COMPLETE, why);
+
+ // Check that the receive buffer contains the fill byte.
+ cmpnbufc(SPI_FILL_WORD,rx_buf,0,SHORT_XFR,__FILE__,__LINE__);
+ // Check that remaining portion of the receive buffer contains the rx test byte
+ cmpnbufc(TEST_BYTE_RX,rx_buf,SHORT_XFR,sizeof(rx_buf),__FILE__,__LINE__);
+}
+
+// SPI write tx length: FIFO-1 ascending values, read length: FIFO-1
+// Checks: Receive buffer == tx buffer, completion event
+TEST(SPI_Master_Asynchronous, short_tx_short_rx)
+{
+ int rc;
+ // Write/Read a buffer of Long Transfer length.
+ rc = obj->transfer( tx_buf,SHORT_XFR,rx_buf,SHORT_XFR,callback, -1);
+ CHECK_EQUAL(0, rc);
+
+ while (!complete);
+
+ // Make sure that the callback fires.
+ CHECK_EQUAL(SPI_EVENT_COMPLETE, why);
+
+ // Check that the rx buffer contains the tx bytes
+ cmpnbuf(tx_buf,rx_buf,0,SHORT_XFR,__FILE__,__LINE__);
+ // Check that remaining portion of the receive buffer contains the rx test byte
+ cmpnbufc(TEST_BYTE_RX,rx_buf,SHORT_XFR,sizeof(rx_buf),__FILE__,__LINE__);
+}
+// SPI write tx length: 2xFIFO ascending values, read length: 2xFIFO
+// Checks: Receive buffer == tx buffer, completion event
+TEST(SPI_Master_Asynchronous, long_tx_long_rx)
+{
+ int rc;
+ // Write/Read a buffer of Long Transfer length.
+ rc = obj->transfer(tx_buf,LONG_XFR,rx_buf,LONG_XFR,callback, -1);
+ CHECK_EQUAL(0, rc);
+
+ while (!complete);
+
+ // Make sure that the callback fires.
+ CHECK_EQUAL(SPI_EVENT_COMPLETE, why);
+
+ //dumpRXbuf();
+ // Check that the rx buffer contains the tx bytes
+ cmpnbuf(tx_buf,rx_buf,0,LONG_XFR,__FILE__,__LINE__);
+ // Check that remaining portion of the receive buffer contains the rx test byte
+ cmpnbufc(TEST_BYTE_RX,rx_buf,LONG_XFR,sizeof(rx_buf),__FILE__,__LINE__);
+}
+
+// SPI write tx length: 2xFIFO, ascending, read length: FIFO-1
+// Checks: Receive buffer == tx buffer, completion event, read buffer overflow
+TEST(SPI_Master_Asynchronous, long_tx_short_rx)
+{
+ int rc;
+ // Write a buffer of Short Transfer length.
+ rc = obj->transfer(tx_buf,LONG_XFR,rx_buf,SHORT_XFR,callback, -1);
+ CHECK_EQUAL(0, rc);
+
+ while (!complete);
+
+ // Make sure that the callback fires.
+ CHECK_EQUAL(SPI_EVENT_COMPLETE, why);
+
+ // Check that the rx buffer contains the tx bytes
+ cmpnbuf(tx_buf,rx_buf,0,SHORT_XFR,__FILE__,__LINE__);
+ // Check that remaining portion of the receive buffer contains the rx test byte
+ cmpnbufc(TEST_BYTE_RX,rx_buf,SHORT_XFR,sizeof(rx_buf),__FILE__,__LINE__);
+}
+
+// SPI write tx length: FIFO-1, ascending, read length: 2xFIFO
+// Checks: Receive buffer == tx buffer, then fill, completion event
+TEST(SPI_Master_Asynchronous, short_tx_long_rx)
+{
+ int rc;
+ // Write a buffer of Short Transfer length.
+ rc = obj->transfer(tx_buf,SHORT_XFR,rx_buf,LONG_XFR,callback, -1);
+ CHECK_EQUAL(0, rc);
+
+ while (!complete);
+
+ // Make sure that the callback fires.
+ CHECK_EQUAL(SPI_EVENT_COMPLETE, why);
+
+ //dumpRXbuf();
+ // Check that the rx buffer contains the tx bytes
+ cmpnbuf(tx_buf,rx_buf,0,SHORT_XFR,__FILE__,__LINE__);
+ // Check that the rx buffer contains the tx fill bytes
+ cmpnbufc(SPI_FILL_WORD,rx_buf,SHORT_XFR,LONG_XFR,__FILE__,__LINE__);
+ // Check that remaining portion of the receive buffer contains the rx test byte
+ cmpnbufc(TEST_BYTE_RX,rx_buf,LONG_XFR,sizeof(rx_buf),__FILE__,__LINE__);
+}
+
+TEST(SPI_Master_Asynchronous, queue_test)
+{
+ int rc;
+ // Write/Read a buffer of Long Transfer length.
+ rc = obj->transfer( tx_buf,4,rx_buf,4,callback, 0);
+ CHECK_EQUAL(0, rc);
+ rc = obj->transfer( &tx_buf[4],4, &rx_buf[4],4,callback, 0);
+ CHECK_EQUAL(0, rc);
+ rc = obj->transfer( &tx_buf[8],4, &rx_buf[8],4,callback, -1);
+ CHECK_EQUAL(0, rc);
+
+ while (!complete);
+
+ // Make sure that the callback fires.
+ CHECK_EQUAL(SPI_EVENT_COMPLETE, why);
+
+ // Check that the rx buffer contains the tx bytes
+ cmpnbuf(tx_buf,rx_buf,0,12,__FILE__,__LINE__);
+ // Check that remaining portion of the receive buffer contains the rx test byte
+ cmpnbufc(TEST_BYTE_RX,rx_buf,12,sizeof(rx_buf),__FILE__,__LINE__);
+}