Rtos API example

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers spi_master_asynch.cpp Source File

spi_master_asynch.cpp

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2015 ARM Limited
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 #include <stdio.h>
00017 #include "TestHarness.h"
00018 #include "mbed.h"
00019 
00020 #if !DEVICE_SPI || !DEVICE_SPI_ASYNCH
00021 #error spi_master_asynch requires asynch SPI
00022 #endif
00023 
00024 
00025 #define SHORT_XFR 3
00026 #define LONG_XFR 16
00027 #define TEST_BYTE0 0x00
00028 #define TEST_BYTE1 0x11
00029 #define TEST_BYTE2 0xFF
00030 #define TEST_BYTE3 0xAA
00031 #define TEST_BYTE4 0x55
00032 #define TEST_BYTE5 0x50
00033 
00034 #define TEST_BYTE_RX TEST_BYTE3
00035 #define TEST_BYTE_TX_BASE TEST_BYTE5
00036 
00037 #if defined(TARGET_K64F) || defined(TARGET_K66F)
00038 #define TEST_MOSI_PIN PTD2
00039 #define TEST_MISO_PIN PTD3
00040 #define TEST_SCLK_PIN PTD1
00041 #define TEST_CS_PIN   PTD0
00042 
00043 #elif defined(TARGET_EFM32LG_STK3600) || defined(TARGET_EFM32GG_STK3700) || defined(TARGET_EFM32WG_STK3800)
00044 #define TEST_MOSI_PIN PD0
00045 #define TEST_MISO_PIN PD1
00046 #define TEST_SCLK_PIN PD2
00047 #define TEST_CS_PIN   PD3
00048 
00049 #elif defined(TARGET_EFM32ZG_STK3200)
00050 #define TEST_MOSI_PIN PD7
00051 #define TEST_MISO_PIN PD6
00052 #define TEST_SCLK_PIN PC15
00053 #define TEST_CS_PIN   PC14
00054 
00055 #elif defined(TARGET_EFM32HG_STK3400)
00056 #define TEST_MOSI_PIN PE10
00057 #define TEST_MISO_PIN PE11
00058 #define TEST_SCLK_PIN PE12
00059 #define TEST_CS_PIN   PE13
00060 
00061 #elif defined(TARGET_RZ_A1H)
00062 #define TEST_MOSI_PIN P10_14
00063 #define TEST_MISO_PIN P10_15
00064 #define TEST_SCLK_PIN P10_12
00065 #define TEST_CS_PIN   P10_13
00066 
00067 #elif defined(TARGET_FF_ARDUINO)
00068 #define TEST_MOSI_PIN D11
00069 #define TEST_MISO_PIN D12
00070 #define TEST_SCLK_PIN D13
00071 #define TEST_CS_PIN   D10
00072 
00073 #elif defined(TARGET_DISCO_F429ZI)
00074 #define TEST_MOSI_PIN PC_12
00075 #define TEST_MISO_PIN PC_11
00076 #define TEST_SCLK_PIN PC_10
00077 #define TEST_CS_PIN   PA_15
00078 
00079 #else
00080 #error Target not supported
00081 #endif
00082 
00083 volatile int why;
00084 volatile bool complete;
00085 void cbdone(int event) {
00086     complete = true;
00087     why = event;
00088 }
00089 
00090 
00091 TEST_GROUP(SPI_Master_Asynchronous)
00092 {
00093     uint8_t tx_buf[LONG_XFR];
00094     uint8_t rx_buf[LONG_XFR];
00095     SPI *obj;
00096     DigitalOut *cs;
00097     event_callback_t callback;
00098 
00099     void setup() {
00100         obj = new SPI(TEST_MOSI_PIN, TEST_MISO_PIN, TEST_SCLK_PIN);
00101         cs = new DigitalOut(TEST_CS_PIN);
00102         complete = false;
00103         why = 0;
00104         callback.attach(cbdone);
00105 
00106         // Set the default value of tx_buf
00107         for (uint32_t i = 0; i < sizeof(tx_buf); i++) {
00108             tx_buf[i] = i + TEST_BYTE_TX_BASE;
00109         }
00110         memset(rx_buf,TEST_BYTE_RX,sizeof(rx_buf));
00111     }
00112     void teardown() {
00113         delete obj;
00114         obj = NULL;
00115         delete cs;
00116         cs = NULL;
00117     }
00118     uint32_t cmpnbuf(uint8_t *expect, uint8_t *actual, uint32_t offset, uint32_t end, const char *file, uint32_t line)
00119     {
00120         uint32_t i;
00121         for (i = offset; i < end; i++){
00122             if (expect[i] != actual[i]) {
00123                 break;
00124             }
00125         }
00126         if (i < end) {
00127             CHECK_EQUAL_LOCATION((int)expect[i], (int)actual[i], file, line);
00128         }
00129         CHECK_EQUAL_LOCATION(end, i, file, line);
00130         return i;
00131     }
00132     uint32_t cmpnbufc(uint8_t expect, uint8_t *actual, uint32_t offset, uint32_t end, const char *file, uint32_t line)
00133     {
00134         uint32_t i;
00135         for (i = offset; i < end; i++){
00136             if (expect != actual[i]) {
00137                 break;
00138             }
00139         }
00140         if (i < end) {
00141             CHECK_EQUAL_LOCATION((int)expect, (int)actual[i], file, line);
00142         }
00143         CHECK_EQUAL_LOCATION(end, i, file, line);
00144         return i;
00145     }
00146     void dumpRXbuf() {
00147         uint32_t i;
00148         printf("\r\n");
00149         printf("RX Buffer Contents: [");
00150         //flushf(stdout);
00151         for (i = 0; i < sizeof(rx_buf); i++){
00152             printf("%02x",rx_buf[i]);
00153             if (i+1 < sizeof(rx_buf)){
00154                 printf(",");
00155             }
00156         }
00157         printf("]\r\n");
00158     }
00159 };
00160 
00161 // SPI write tx length: FIFO-1, read length: 0
00162 //   Checks: Null pointer exceptions, completion event
00163 TEST(SPI_Master_Asynchronous, short_tx_0_rx)
00164 {
00165     int rc;
00166     // Write a buffer of Short Transfer length.
00167     rc = obj->transfer( (const uint8_t *) tx_buf, SHORT_XFR,  (uint8_t *) NULL, 0, callback, SPI_EVENT_ALL);
00168     CHECK_EQUAL(0, rc);
00169 
00170     while (!complete);
00171 
00172     // Make sure that the callback fires.
00173     CHECK_EQUAL(why, SPI_EVENT_COMPLETE);
00174 
00175     // TODO: Check for a null pointer exception
00176 }
00177 
00178 
00179 //
00180 // SPI write tx length: FIFO-1, read length: 0, non-null read pointer
00181 //   Checks: Null pointer exceptions, completion event, canary values in read buffer
00182 TEST(SPI_Master_Asynchronous, short_tx_0_rx_nn)
00183 {
00184     int rc;
00185     // Write a buffer of Short Transfer length.
00186     rc = obj->transfer( (const uint8_t *)tx_buf,SHORT_XFR,(uint8_t *) rx_buf, 0,callback, SPI_EVENT_ALL);
00187     CHECK_EQUAL(0, rc);
00188 
00189     while (!complete);
00190 
00191     // Make sure that the callback fires.
00192     CHECK_EQUAL(SPI_EVENT_COMPLETE, why);
00193 
00194     // Check that the rx buffer is untouched
00195     cmpnbufc(TEST_BYTE_RX,rx_buf,0,sizeof(rx_buf),__FILE__,__LINE__);
00196 }
00197 
00198 // SPI write tx length: 0, read length: FIFO-1
00199 //   Checks: Receive value==fill character, completion event
00200 TEST(SPI_Master_Asynchronous, 0_tx_short_rx)
00201 {
00202     int rc;
00203     // Read a buffer of Short Transfer length.
00204     rc = obj->transfer( (const uint8_t *)NULL,0,(uint8_t *) rx_buf,SHORT_XFR,callback, SPI_EVENT_ALL);
00205     CHECK_EQUAL(0, rc);
00206 
00207     while (!complete);
00208 
00209     // Make sure that the callback fires.
00210     CHECK_EQUAL(SPI_EVENT_COMPLETE, why);
00211 
00212     // TODO: Check for null pointer exception
00213     // Check that the receive buffer contains the fill byte.
00214     cmpnbufc(SPI_FILL_WORD,rx_buf,0,SHORT_XFR,__FILE__,__LINE__);
00215     // Check that remaining portion of the receive buffer contains the rx test byte
00216     cmpnbufc(TEST_BYTE_RX,rx_buf,SHORT_XFR,sizeof(rx_buf),__FILE__,__LINE__);
00217 }
00218 
00219 // SPI write tx length: 0, read length: FIFO-1
00220 //   Checks: Receive value==fill character, completion event
00221 TEST(SPI_Master_Asynchronous, 0_tx_nn_short_rx)
00222 {
00223     int rc;
00224     // Read a buffer of Short Transfer length.
00225     rc = obj->transfer(tx_buf,0,rx_buf,SHORT_XFR,callback, SPI_EVENT_ALL);
00226     CHECK_EQUAL(0, rc);
00227 
00228     while (!complete);
00229 
00230     // Make sure that the callback fires.
00231     CHECK_EQUAL(SPI_EVENT_COMPLETE, why);
00232 
00233     // Check that the receive buffer contains the fill byte.
00234     cmpnbufc(SPI_FILL_WORD,rx_buf,0,SHORT_XFR,__FILE__,__LINE__);
00235     // Check that remaining portion of the receive buffer contains the rx test byte
00236     cmpnbufc(TEST_BYTE_RX,rx_buf,SHORT_XFR,sizeof(rx_buf),__FILE__,__LINE__);
00237 }
00238 
00239 // SPI write tx length: FIFO-1 ascending values, read length: FIFO-1
00240 //   Checks: Receive buffer == tx buffer, completion event
00241 TEST(SPI_Master_Asynchronous, short_tx_short_rx)
00242 {
00243     int rc;
00244     // Write/Read a buffer of Long Transfer length.
00245     rc = obj->transfer( tx_buf,SHORT_XFR,rx_buf,SHORT_XFR,callback, SPI_EVENT_ALL);
00246     CHECK_EQUAL(0, rc);
00247 
00248     while (!complete);
00249 
00250     // Make sure that the callback fires.
00251     CHECK_EQUAL(SPI_EVENT_COMPLETE, why);
00252 
00253     // Check that the rx buffer contains the tx bytes
00254     cmpnbuf(tx_buf,rx_buf,0,SHORT_XFR,__FILE__,__LINE__);
00255     // Check that remaining portion of the receive buffer contains the rx test byte
00256     cmpnbufc(TEST_BYTE_RX,rx_buf,SHORT_XFR,sizeof(rx_buf),__FILE__,__LINE__);
00257 }
00258 // SPI write tx length: 2xFIFO ascending values, read length: 2xFIFO
00259 //   Checks: Receive buffer == tx buffer, completion event
00260 TEST(SPI_Master_Asynchronous, long_tx_long_rx)
00261 {
00262     int rc;
00263     // Write/Read a buffer of Long Transfer length.
00264     rc = obj->transfer(tx_buf,LONG_XFR,rx_buf,LONG_XFR,callback, SPI_EVENT_ALL);
00265     CHECK_EQUAL(0, rc);
00266 
00267     while (!complete);
00268 
00269     // Make sure that the callback fires.
00270     CHECK_EQUAL(SPI_EVENT_COMPLETE, why);
00271 
00272     //dumpRXbuf();
00273     // Check that the rx buffer contains the tx bytes
00274     cmpnbuf(tx_buf,rx_buf,0,LONG_XFR,__FILE__,__LINE__);
00275     // Check that remaining portion of the receive buffer contains the rx test byte
00276     cmpnbufc(TEST_BYTE_RX,rx_buf,LONG_XFR,sizeof(rx_buf),__FILE__,__LINE__);
00277 }
00278 
00279 // SPI write tx length: 2xFIFO, ascending, read length: FIFO-1
00280 //   Checks: Receive buffer == tx buffer, completion event, read buffer overflow
00281 TEST(SPI_Master_Asynchronous, long_tx_short_rx)
00282 {
00283     int rc;
00284     // Write a buffer of Short Transfer length.
00285     rc = obj->transfer(tx_buf,LONG_XFR,rx_buf,SHORT_XFR,callback, SPI_EVENT_ALL);
00286     CHECK_EQUAL(0, rc);
00287 
00288     while (!complete);
00289 
00290     // Make sure that the callback fires.
00291     CHECK_EQUAL(SPI_EVENT_COMPLETE, why);
00292 
00293     // Check that the rx buffer contains the tx bytes
00294     cmpnbuf(tx_buf,rx_buf,0,SHORT_XFR,__FILE__,__LINE__);
00295     // Check that remaining portion of the receive buffer contains the rx test byte
00296     cmpnbufc(TEST_BYTE_RX,rx_buf,SHORT_XFR,sizeof(rx_buf),__FILE__,__LINE__);
00297 }
00298 
00299 // SPI write tx length: FIFO-1, ascending, read length: 2xFIFO
00300 //   Checks: Receive buffer == tx buffer, then fill, completion event
00301 TEST(SPI_Master_Asynchronous, short_tx_long_rx)
00302 {
00303     int rc;
00304     // Write a buffer of Short Transfer length.
00305     rc = obj->transfer(tx_buf,SHORT_XFR,rx_buf,LONG_XFR,callback, SPI_EVENT_ALL);
00306     CHECK_EQUAL(0, rc);
00307 
00308     while (!complete);
00309 
00310     // Make sure that the callback fires.
00311     CHECK_EQUAL(SPI_EVENT_COMPLETE, why);
00312 
00313     //dumpRXbuf();
00314     // Check that the rx buffer contains the tx bytes
00315     cmpnbuf(tx_buf,rx_buf,0,SHORT_XFR,__FILE__,__LINE__);
00316     // Check that the rx buffer contains the tx fill bytes
00317     cmpnbufc(SPI_FILL_WORD,rx_buf,SHORT_XFR,LONG_XFR,__FILE__,__LINE__);
00318     // Check that remaining portion of the receive buffer contains the rx test byte
00319     cmpnbufc(TEST_BYTE_RX,rx_buf,LONG_XFR,sizeof(rx_buf),__FILE__,__LINE__);
00320 }
00321 
00322 TEST(SPI_Master_Asynchronous, queue_test)
00323 {
00324     int rc;
00325     // Write/Read a buffer of Long Transfer length.
00326     rc = obj->transfer( tx_buf,4,rx_buf,4,callback, 0);
00327     CHECK_EQUAL(0, rc);
00328     rc = obj->transfer( &tx_buf[4],4, &rx_buf[4],4,callback, 0);
00329     CHECK_EQUAL(0, rc);
00330     rc = obj->transfer( &tx_buf[8],4, &rx_buf[8],4,callback, SPI_EVENT_ALL);
00331     CHECK_EQUAL(0, rc);
00332 
00333     while (!complete);
00334 
00335     // Make sure that the callback fires.
00336     CHECK_EQUAL(SPI_EVENT_COMPLETE, why);
00337 
00338     // Check that the rx buffer contains the tx bytes
00339     cmpnbuf(tx_buf,rx_buf,0,12,__FILE__,__LINE__);
00340     // Check that remaining portion of the receive buffer contains the rx test byte
00341     cmpnbufc(TEST_BYTE_RX,rx_buf,12,sizeof(rx_buf),__FILE__,__LINE__);
00342 }