Rtos API example

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers serial_asynch.cpp Source File

serial_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 /* Serial asynch cross */
00021 
00022 #if !DEVICE_SERIAL || !DEVICE_SERIAL_ASYNCH
00023 #error serial_asynch requires asynch Serial
00024 #endif
00025 
00026 // Device config
00027 #if defined(TARGET_K64F)
00028 #define TEST_SERIAL_ONE_TX_PIN PTC17 // uart3
00029 #define TEST_SERIAL_TWO_RX_PIN PTD2  // uart2
00030 
00031 #elif defined(TARGET_K66F)
00032 #define TEST_SERIAL_ONE_TX_PIN PTD3 // uart2
00033 #define TEST_SERIAL_TWO_RX_PIN PTC16  // uart3
00034 
00035 #elif defined(TARGET_EFM32LG_STK3600) || defined(TARGET_EFM32GG_STK3700) || defined(TARGET_EFM32WG_STK3800)
00036 #define TEST_SERIAL_ONE_TX_PIN PD0   // usart1
00037 #define TEST_SERIAL_TWO_RX_PIN PC3   // usart2
00038 
00039 #elif defined(TARGET_EFM32ZG_STK3200)
00040 #error "Target not supported (only 2 serial ports available, need 3)"
00041 
00042 #elif defined(TARGET_EFM32HG_STK3400)
00043 #define TEST_SERIAL_ONE_TX_PIN PE10 // usart0
00044 #define TEST_SERIAL_TWO_RX_PIN PC1  // usart1
00045 
00046 #elif defined(TARGET_B96B_F446VE)
00047 #define TEST_SERIAL_ONE_TX_PIN D1   // UART2
00048 #define TEST_SERIAL_TWO_RX_PIN D4   // UART5
00049 
00050 #elif defined(TARGET_NUCLEO_L053R8)
00051 #define TEST_SERIAL_ONE_TX_PIN PB_10   // UART3
00052 #define TEST_SERIAL_TWO_RX_PIN PA_10   // UART1
00053 
00054 #elif defined(TARGET_NUCLEO_L073RZ)
00055 #define TEST_SERIAL_ONE_TX_PIN PB_10   // UART3
00056 #define TEST_SERIAL_TWO_RX_PIN PA_10   // UART1
00057 
00058 #elif defined(TARGET_NUCLEO_L152RE)
00059 #define TEST_SERIAL_ONE_TX_PIN PB_10   // UART3
00060 #define TEST_SERIAL_TWO_RX_PIN PA_10   // UART1
00061 
00062 #elif defined(TARGET_NUCLEO_F103RB)
00063 #define TEST_SERIAL_ONE_TX_PIN PB_10   // UART3
00064 #define TEST_SERIAL_TWO_RX_PIN PA_10   // UART1
00065 
00066 #elif defined(TARGET_NUCLEO_F070RB)
00067 #define TEST_SERIAL_ONE_TX_PIN PB_10  // UART3
00068 #define TEST_SERIAL_TWO_RX_PIN PA_10  // UART1
00069 
00070 #elif defined(TARGET_NUCLEO_F072RB)
00071 #define TEST_SERIAL_ONE_TX_PIN PB_10  // UART3
00072 #define TEST_SERIAL_TWO_RX_PIN PA_10  // UART1
00073 
00074 #elif defined(TARGET_NUCLEO_F091RC)
00075 #define TEST_SERIAL_ONE_TX_PIN PB_6   // UART1
00076 #define TEST_SERIAL_TWO_RX_PIN PC_7   // UART7
00077 
00078 #elif defined(TARGET_NUCLEO_F207ZG)
00079 #define TEST_SERIAL_ONE_TX_PIN PC_12   // UART5
00080 #define TEST_SERIAL_TWO_RX_PIN PC_11   // UART4
00081 
00082 #elif defined(TARGET_DISCO_F334C8)
00083 #define TEST_SERIAL_ONE_TX_PIN PB_10   // UART3
00084 #define TEST_SERIAL_TWO_RX_PIN PA_10   // UART1
00085 
00086 #elif defined(TARGET_NUCLEO_F302R8)
00087 #define TEST_SERIAL_ONE_TX_PIN PB_10   // UART3
00088 #define TEST_SERIAL_TWO_RX_PIN PA_10   // UART1
00089 
00090 #elif defined(TARGET_NUCLEO_F303RE)
00091 #define TEST_SERIAL_ONE_TX_PIN PB_10   // UART3
00092 #define TEST_SERIAL_TWO_RX_PIN PA_10   // UART1
00093 
00094 #elif defined(TARGET_NUCLEO_F334R8)
00095 #define TEST_SERIAL_ONE_TX_PIN PB_10   // UART3
00096 #define TEST_SERIAL_TWO_RX_PIN PA_10   // UART1
00097 
00098 #elif defined(TARGET_DISCO_F429ZI)
00099 #define TEST_SERIAL_ONE_TX_PIN PD_5   // UART2
00100 #define TEST_SERIAL_TWO_RX_PIN PG_9   // UART6
00101 
00102 #elif defined(TARGET_NUCLEO_F401RE)
00103 #define TEST_SERIAL_ONE_TX_PIN PB_6  // UART1
00104 #define TEST_SERIAL_TWO_RX_PIN PC_7  // UART6
00105 
00106 #elif defined(TARGET_NUCLEO_F411RE)
00107 #define TEST_SERIAL_ONE_TX_PIN PB_6  // UART1
00108 #define TEST_SERIAL_TWO_RX_PIN PC_7  // UART6
00109 
00110 #elif defined(TARGET_NUCLEO_F446RE)
00111 #define TEST_SERIAL_ONE_TX_PIN PB_6  // UART1
00112 #define TEST_SERIAL_TWO_RX_PIN PC_7  // UART6
00113 
00114 #elif defined(TARGET_NUCLEO_F410RB)
00115 #define TEST_SERIAL_ONE_TX_PIN PB_6  // UART1
00116 #define TEST_SERIAL_TWO_RX_PIN PC_7  // UART6
00117 
00118 #elif defined(TARGET_NUCLEO_F429ZI)
00119 #define TEST_SERIAL_ONE_TX_PIN PE_8  // UART7
00120 #define TEST_SERIAL_TWO_RX_PIN PG_9  // UART6
00121 
00122 #elif defined(TARGET_NUCLEO_F446ZE)
00123 #define TEST_SERIAL_ONE_TX_PIN PB_6  // UART1
00124 #define TEST_SERIAL_TWO_RX_PIN PG_9  // UART6
00125 
00126 #elif defined(TARGET_DISCO_F746NG)
00127 #define TEST_SERIAL_ONE_TX_PIN PC_6  // UART6
00128 #define TEST_SERIAL_TWO_RX_PIN PF_6  // UART7
00129 
00130 #elif defined(TARGET_NUCLEO_F746ZG)
00131 #define TEST_SERIAL_ONE_TX_PIN PC_12  // UART5
00132 #define TEST_SERIAL_TWO_RX_PIN PC_11  // UART4
00133 
00134 #elif defined(TARGET_NUCLEO_F767ZI)
00135 #define TEST_SERIAL_ONE_TX_PIN PC_12  // UART5
00136 #define TEST_SERIAL_TWO_RX_PIN PC_11  // UART4
00137 
00138 #elif defined(TARGET_NUCLEO_L476RG)
00139 #define TEST_SERIAL_ONE_TX_PIN PB_10   // UART3
00140 #define TEST_SERIAL_TWO_RX_PIN PA_10   // UART1
00141 
00142 #elif defined(TARGET_RZ_A1H)
00143 #define TEST_SERIAL_ONE_TX_PIN P8_14  // UART4
00144 #define TEST_SERIAL_TWO_RX_PIN P8_11  // UART5
00145 
00146 #else
00147 
00148 #error Target not supported
00149 #endif
00150 
00151 // Test config
00152 #define SHORT_XFR 3
00153 #define LONG_XFR 16
00154 #define TEST_BYTE_TX_BASE 0x5555
00155 #define TEST_BYTE_RX      0x5A5A
00156 
00157 volatile int tx_event_flag;
00158 volatile bool tx_complete;
00159 
00160 volatile int rx_event_flag;
00161 volatile bool rx_complete;
00162 
00163 void cb_tx_done(int event)
00164 {
00165     tx_complete = true;
00166     tx_event_flag = event;
00167 }
00168 
00169 void cb_rx_done(int event)
00170 {
00171     rx_complete = true;
00172     rx_event_flag = event;
00173 }
00174 
00175 TEST_GROUP(Serial_Asynchronous)
00176 {
00177     uint8_t tx_buf[LONG_XFR];
00178     uint8_t rx_buf[LONG_XFR];
00179 
00180     Serial *serial_tx;
00181     Serial *serial_rx;
00182     event_callback_t tx_callback;
00183     event_callback_t rx_callback;
00184 
00185     void setup()
00186     {
00187         serial_tx = new Serial(TEST_SERIAL_ONE_TX_PIN, NC);
00188         serial_rx = new Serial(NC, TEST_SERIAL_TWO_RX_PIN);
00189         tx_complete = false;
00190         tx_event_flag = 0;
00191         rx_complete = false;
00192         rx_event_flag = 0;
00193         tx_callback.attach(cb_tx_done);
00194         rx_callback.attach(cb_rx_done);
00195 
00196         // Set the default value of tx_buf
00197         for (uint32_t i = 0; i < sizeof(tx_buf); i++) {
00198             tx_buf[i] = i + TEST_BYTE_TX_BASE;
00199         }
00200         memset(rx_buf, TEST_BYTE_RX, sizeof(rx_buf));
00201     }
00202 
00203     void teardown()
00204     {
00205         delete serial_tx;
00206         serial_tx = NULL;
00207         delete serial_rx;
00208         serial_rx = NULL;
00209 
00210     }
00211 
00212     uint32_t cmpnbufc(uint8_t expect, uint8_t *actual, uint32_t offset, uint32_t end, const char *file, uint32_t line)
00213     {
00214         uint32_t i;
00215         for (i = offset; i < end; i++){
00216             if (expect != actual[i]) {
00217                 break;
00218             }
00219         }
00220         if (i < end) {
00221             CHECK_EQUAL_LOCATION((int)expect, (int)actual[i], file, line);
00222         }
00223         CHECK_EQUAL_LOCATION(end, i, file, line);
00224         return i;
00225     }
00226 
00227     uint32_t cmpnbuf(uint8_t *expect, uint8_t *actual, uint32_t offset, uint32_t end, const char *file, uint32_t line)
00228     {
00229         uint32_t i;
00230         for (i = offset; i < end; i++){
00231             if (expect[i] != actual[i]) {
00232                 break;
00233             }
00234         }
00235         if (i < end) {
00236             CHECK_EQUAL_LOCATION((int)expect[i], (int)actual[i], file, line);
00237         }
00238         CHECK_EQUAL_LOCATION(end, i, file, line);
00239         return i;
00240     }
00241 
00242 };
00243 
00244 TEST(Serial_Asynchronous, short_tx_0_rx)
00245 {
00246     int rc;
00247     rc = serial_tx->write(tx_buf, SHORT_XFR, tx_callback, -1);
00248     CHECK_EQUAL(0, rc);
00249 
00250     while (!tx_complete);
00251 
00252     CHECK_EQUAL(SERIAL_EVENT_TX_COMPLETE, tx_event_flag);
00253     // rx buffer unchanged
00254     cmpnbufc(TEST_BYTE_RX, rx_buf, 0, sizeof(rx_buf), __FILE__, __LINE__);
00255 }
00256 
00257 TEST(Serial_Asynchronous, short_tx_short_rx)
00258 {
00259     int rc;
00260     serial_rx->read(rx_buf, SHORT_XFR, rx_callback, -1);
00261     rc = serial_tx->write(tx_buf, SHORT_XFR, tx_callback, -1);
00262     CHECK_EQUAL(0, rc);
00263 
00264     while ((!tx_complete) || (!rx_complete));
00265 
00266     CHECK_EQUAL(SERIAL_EVENT_TX_COMPLETE, tx_event_flag);
00267     CHECK_EQUAL(SERIAL_EVENT_RX_COMPLETE, rx_event_flag);
00268 
00269     // Check that the receive buffer contains the fill byte.
00270     cmpnbuf(tx_buf, rx_buf, 0, SHORT_XFR, __FILE__, __LINE__);
00271     // Check that remaining portion of the receive buffer contains the rx test byte
00272     cmpnbufc(TEST_BYTE_RX, rx_buf, SHORT_XFR, sizeof(rx_buf), __FILE__, __LINE__);
00273 }
00274 
00275 TEST(Serial_Asynchronous, long_tx_long_rx)
00276 {
00277     int rc;
00278     serial_rx->read(rx_buf, LONG_XFR, rx_callback, -1);
00279     rc = serial_tx->write(tx_buf, LONG_XFR, tx_callback, -1);
00280     CHECK_EQUAL(0, rc);
00281 
00282     while ((!tx_complete) || (!rx_complete));
00283 
00284     CHECK_EQUAL(SERIAL_EVENT_TX_COMPLETE, tx_event_flag);
00285     CHECK_EQUAL(SERIAL_EVENT_RX_COMPLETE, rx_event_flag);
00286 
00287     // Check that the receive buffer contains the fill byte.
00288     cmpnbuf(tx_buf, rx_buf, 0, LONG_XFR, __FILE__, __LINE__);
00289     // Check that remaining portion of the receive buffer contains the rx test byte
00290     cmpnbufc(TEST_BYTE_RX, rx_buf, LONG_XFR, sizeof(rx_buf), __FILE__, __LINE__);
00291 }
00292 
00293 TEST(Serial_Asynchronous, rx_parity_error)
00294 {
00295     int rc;
00296     // Set different parity for RX and TX
00297     serial_rx->format(8, SerialBase::Even, 1);
00298     serial_tx->format(8, SerialBase::Odd, 1);
00299     serial_rx->read(rx_buf, LONG_XFR, rx_callback, -1);
00300     rc = serial_tx->write(tx_buf, LONG_XFR, tx_callback, -1);
00301     CHECK_EQUAL(0, rc);
00302 
00303     while ((!tx_complete) || (!rx_complete));
00304 
00305     CHECK_EQUAL(SERIAL_EVENT_TX_COMPLETE, tx_event_flag);
00306     CHECK_EQUAL(SERIAL_EVENT_RX_PARITY_ERROR, rx_event_flag);
00307 }
00308 
00309 TEST(Serial_Asynchronous, rx_framing_error)
00310 {
00311    int rc;
00312    serial_tx->baud(4800);
00313    serial_rx->read(rx_buf, LONG_XFR, rx_callback, -1);
00314    rc = serial_tx->write(tx_buf, LONG_XFR, tx_callback, -1);
00315    CHECK_EQUAL(0, rc);
00316 
00317    while ((!tx_complete) || (!rx_complete));
00318 
00319    CHECK_EQUAL(SERIAL_EVENT_TX_COMPLETE, tx_event_flag);
00320    CHECK_EQUAL(SERIAL_EVENT_RX_FRAMING_ERROR, rx_event_flag);
00321 }
00322 
00323 TEST(Serial_Asynchronous, char_matching_success)
00324 {
00325     // match found
00326     serial_rx->read(rx_buf, LONG_XFR, rx_callback, -1, (uint8_t)(TEST_BYTE_TX_BASE+5));
00327     serial_tx->write(tx_buf, LONG_XFR, tx_callback, -1);
00328 
00329     while ((!tx_complete) || (!rx_complete));
00330 
00331     CHECK_EQUAL(SERIAL_EVENT_TX_COMPLETE, tx_event_flag);
00332     CHECK_EQUAL(SERIAL_EVENT_RX_CHARACTER_MATCH, rx_event_flag);
00333     
00334     cmpnbufc(TEST_BYTE_RX, rx_buf, 5, sizeof(rx_buf), __FILE__, __LINE__);
00335 }
00336 
00337 TEST(Serial_Asynchronous, char_matching_failed)
00338 {
00339     // no match found (specified match char is not in tx buffer)
00340     serial_rx->read(rx_buf, LONG_XFR, rx_callback, -1, (uint8_t)(TEST_BYTE_TX_BASE  + sizeof(tx_buf)));
00341     serial_tx->write(tx_buf, LONG_XFR, tx_callback, -1);
00342 
00343     while ((!tx_complete) || (!rx_complete));
00344 
00345     CHECK_EQUAL(SERIAL_EVENT_TX_COMPLETE, tx_event_flag);
00346     CHECK_EQUAL(SERIAL_EVENT_RX_COMPLETE, rx_event_flag);
00347 
00348     cmpnbuf(tx_buf, rx_buf, 0, LONG_XFR, __FILE__, __LINE__);
00349 }
00350 
00351 TEST(Serial_Asynchronous, char_matching_with_complete)
00352 {
00353     serial_rx->read(rx_buf, LONG_XFR, rx_callback, -1, (uint8_t)(TEST_BYTE_TX_BASE  + sizeof(tx_buf) - 1));
00354     serial_tx->write(tx_buf, LONG_XFR, tx_callback, -1);
00355 
00356     while ((!tx_complete) || (!rx_complete));
00357 
00358     CHECK_EQUAL(SERIAL_EVENT_TX_COMPLETE, tx_event_flag);
00359     CHECK_EQUAL((SERIAL_EVENT_RX_COMPLETE | SERIAL_EVENT_RX_CHARACTER_MATCH), rx_event_flag);
00360 
00361     cmpnbuf(tx_buf, rx_buf, 0, LONG_XFR, __FILE__, __LINE__);
00362 }