Forked repo of Platform Drivers- Analog Devices
uart.cpp@20:26b1a4570f4b, 2021-11-22 (annotated)
- Committer:
- Janani Sunil
- Date:
- Mon Nov 22 22:26:51 2021 +0530
- Revision:
- 20:26b1a4570f4b
- Parent:
- 17:af1f2416dd26
The following changes were made:
1.) Modified udelay() function for generating more accurate smaller usec delays
2.) Implemented the irq_enable and irq_disable functions
3.) Removed the confusion b/w application created peripheral object and interrupt specific object
4.) Created PWM extra init structure and added PWM pin as it's member for multiplatform project compatibility
5.) Added a module for timer and its related header file
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
mahphalke |
17:af1f2416dd26 | 1 | /***************************************************************************//** |
mahphalke |
17:af1f2416dd26 | 2 | * @file uart.cpp |
mahphalke |
17:af1f2416dd26 | 3 | * @brief Implementation of UART Mbed platform driver interfaces |
mahphalke |
17:af1f2416dd26 | 4 | ******************************************************************************** |
mahphalke |
17:af1f2416dd26 | 5 | * Copyright (c) 2021 Analog Devices, Inc. |
mahphalke |
17:af1f2416dd26 | 6 | * All rights reserved. |
mahphalke |
17:af1f2416dd26 | 7 | * |
mahphalke |
17:af1f2416dd26 | 8 | * This software is proprietary to Analog Devices, Inc. and its licensors. |
mahphalke |
17:af1f2416dd26 | 9 | * By using this software you agree to the terms of the associated |
mahphalke |
17:af1f2416dd26 | 10 | * Analog Devices Software License Agreement. |
mahphalke |
17:af1f2416dd26 | 11 | *******************************************************************************/ |
mahphalke |
17:af1f2416dd26 | 12 | |
mahphalke |
17:af1f2416dd26 | 13 | /******************************************************************************/ |
mahphalke |
17:af1f2416dd26 | 14 | /***************************** Include Files **********************************/ |
mahphalke |
17:af1f2416dd26 | 15 | /******************************************************************************/ |
mahphalke |
17:af1f2416dd26 | 16 | #include <stdio.h> |
mahphalke |
17:af1f2416dd26 | 17 | #include <mbed.h> |
mahphalke |
17:af1f2416dd26 | 18 | #include <USBCDC.h> |
mahphalke |
17:af1f2416dd26 | 19 | |
mahphalke |
17:af1f2416dd26 | 20 | // Platform drivers needs to be C-compatible to work with other drivers |
mahphalke |
17:af1f2416dd26 | 21 | #ifdef __cplusplus |
mahphalke |
17:af1f2416dd26 | 22 | extern "C" |
mahphalke |
17:af1f2416dd26 | 23 | { |
mahphalke |
17:af1f2416dd26 | 24 | #endif // _cplusplus |
mahphalke |
17:af1f2416dd26 | 25 | |
mahphalke |
17:af1f2416dd26 | 26 | #include "error.h" |
mahphalke |
17:af1f2416dd26 | 27 | #include "delay.h" |
mahphalke |
17:af1f2416dd26 | 28 | #include "uart.h" |
mahphalke |
17:af1f2416dd26 | 29 | #include "uart_extra.h" |
mahphalke |
17:af1f2416dd26 | 30 | |
mahphalke |
17:af1f2416dd26 | 31 | /******************************************************************************/ |
mahphalke |
17:af1f2416dd26 | 32 | /************************ Macros/Constants ************************************/ |
mahphalke |
17:af1f2416dd26 | 33 | /******************************************************************************/ |
mahphalke |
17:af1f2416dd26 | 34 | |
mahphalke |
17:af1f2416dd26 | 35 | /* Max size for USB CDC packet during transmit/receive */ |
mahphalke |
17:af1f2416dd26 | 36 | #define USB_CDC_MAX_PACKET_SIZE (64) |
mahphalke |
17:af1f2416dd26 | 37 | |
mahphalke |
17:af1f2416dd26 | 38 | /* Max allowed length of USB serial number in characters */ |
mahphalke |
17:af1f2416dd26 | 39 | #define USB_SERIAL_NUM_MAX_LENGTH (100) |
mahphalke |
17:af1f2416dd26 | 40 | |
mahphalke |
17:af1f2416dd26 | 41 | /******************************************************************************/ |
mahphalke |
17:af1f2416dd26 | 42 | /*************************** Types Declarations *******************************/ |
mahphalke |
17:af1f2416dd26 | 43 | /******************************************************************************/ |
mahphalke |
17:af1f2416dd26 | 44 | |
mahphalke |
17:af1f2416dd26 | 45 | /* Derived USBCDC class to access protected members of USBCDC class */ |
mahphalke |
17:af1f2416dd26 | 46 | class platform_usbcdc :public USBCDC |
mahphalke |
17:af1f2416dd26 | 47 | { |
mahphalke |
17:af1f2416dd26 | 48 | private: |
mahphalke |
17:af1f2416dd26 | 49 | uint8_t usb_iserial_descriptor[(USB_SERIAL_NUM_MAX_LENGTH * 2) + 2]; |
mahphalke |
17:af1f2416dd26 | 50 | |
mahphalke |
17:af1f2416dd26 | 51 | public : |
mahphalke |
17:af1f2416dd26 | 52 | /* Call parent class (USBCDC) constructor explicitly */ |
mahphalke |
17:af1f2416dd26 | 53 | platform_usbcdc(bool connect_blocking, uint16_t vendor_id, uint16_t product_id, |
mahphalke |
17:af1f2416dd26 | 54 | const char *serial_number) |
mahphalke |
17:af1f2416dd26 | 55 | : USBCDC(connect_blocking, vendor_id, product_id) |
mahphalke |
17:af1f2416dd26 | 56 | { |
mahphalke |
17:af1f2416dd26 | 57 | uint8_t usb_iserial_len; // USB serial number length |
mahphalke |
17:af1f2416dd26 | 58 | uint8_t i, j = 0; |
mahphalke |
17:af1f2416dd26 | 59 | |
mahphalke |
17:af1f2416dd26 | 60 | usb_iserial_len = strlen(serial_number); |
mahphalke |
17:af1f2416dd26 | 61 | if (usb_iserial_len > USB_SERIAL_NUM_MAX_LENGTH) { |
mahphalke |
17:af1f2416dd26 | 62 | usb_iserial_len = USB_SERIAL_NUM_MAX_LENGTH; |
mahphalke |
17:af1f2416dd26 | 63 | } |
mahphalke |
17:af1f2416dd26 | 64 | |
mahphalke |
17:af1f2416dd26 | 65 | this->usb_iserial_descriptor[j++] = (usb_iserial_len * 2) + 2; /* bLength */ |
mahphalke |
17:af1f2416dd26 | 66 | this->usb_iserial_descriptor[j++] = STRING_DESCRIPTOR; /* bDescriptorType */ |
mahphalke |
17:af1f2416dd26 | 67 | |
mahphalke |
17:af1f2416dd26 | 68 | /* bString iSerial */ |
mahphalke |
17:af1f2416dd26 | 69 | for (i = 0; i < usb_iserial_len; i++) { |
mahphalke |
17:af1f2416dd26 | 70 | this->usb_iserial_descriptor[j++] = serial_number[i]; |
mahphalke |
17:af1f2416dd26 | 71 | this->usb_iserial_descriptor[j++] = 0; |
mahphalke |
17:af1f2416dd26 | 72 | } |
mahphalke |
17:af1f2416dd26 | 73 | } |
mahphalke |
17:af1f2416dd26 | 74 | |
mahphalke |
17:af1f2416dd26 | 75 | /* Override the virtual function that sets the USB serial number |
mahphalke |
17:af1f2416dd26 | 76 | * The custom (user provided) USB serial number is passed through this function */ |
mahphalke |
17:af1f2416dd26 | 77 | virtual const uint8_t *string_iserial_desc() |
mahphalke |
17:af1f2416dd26 | 78 | { |
mahphalke |
17:af1f2416dd26 | 79 | return this->usb_iserial_descriptor; |
mahphalke |
17:af1f2416dd26 | 80 | } |
mahphalke |
17:af1f2416dd26 | 81 | |
mahphalke |
17:af1f2416dd26 | 82 | void change_terminal_connection(bool connect_status); |
mahphalke |
17:af1f2416dd26 | 83 | bool data_received(uint32_t rx_size); |
mahphalke |
17:af1f2416dd26 | 84 | bool data_transmited(void); |
mahphalke |
17:af1f2416dd26 | 85 | }; |
mahphalke |
17:af1f2416dd26 | 86 | |
mahphalke |
17:af1f2416dd26 | 87 | /******************************************************************************/ |
mahphalke |
17:af1f2416dd26 | 88 | /************************ Functions Definitions *******************************/ |
mahphalke |
17:af1f2416dd26 | 89 | /******************************************************************************/ |
mahphalke |
17:af1f2416dd26 | 90 | |
mahphalke |
17:af1f2416dd26 | 91 | /** |
mahphalke |
17:af1f2416dd26 | 92 | * @brief Change the terminal connection status (for non-terminal) based USB interface |
mahphalke |
17:af1f2416dd26 | 93 | * @param connect_status- new connection status |
mahphalke |
17:af1f2416dd26 | 94 | * @note This functions is used to change the terminal connection status of USB client |
mahphalke |
17:af1f2416dd26 | 95 | * interface which is different than the 'console terminal'. The console terminals acknowledge |
mahphalke |
17:af1f2416dd26 | 96 | * back to USB host when USB connection is opened on the console terminal and Mbed USBCDC |
mahphalke |
17:af1f2416dd26 | 97 | * class automatically changes the '_terminal_connected' status accordingly. However, for |
mahphalke |
17:af1f2416dd26 | 98 | * custom PC applications (non terminal), the terminal connection status needs to be changed |
mahphalke |
17:af1f2416dd26 | 99 | * manually. The '_terminal_connected' is protected member of USBCDC parent class and thus can |
mahphalke |
17:af1f2416dd26 | 100 | * be accessed through 'platform_usbcdc' derived class using below function. |
mahphalke |
17:af1f2416dd26 | 101 | */ |
mahphalke |
17:af1f2416dd26 | 102 | void platform_usbcdc::change_terminal_connection(bool connect_status) |
mahphalke |
17:af1f2416dd26 | 103 | { |
mahphalke |
17:af1f2416dd26 | 104 | _terminal_connected = connect_status; |
mahphalke |
17:af1f2416dd26 | 105 | } |
mahphalke |
17:af1f2416dd26 | 106 | |
mahphalke |
17:af1f2416dd26 | 107 | |
mahphalke |
17:af1f2416dd26 | 108 | /** |
mahphalke |
17:af1f2416dd26 | 109 | * @brief Check if new USB data is received/available |
mahphalke |
17:af1f2416dd26 | 110 | * @param bytes[in] - Number of expected bytes to be received |
mahphalke |
17:af1f2416dd26 | 111 | * @return true if expected number of bytes received, else false |
mahphalke |
17:af1f2416dd26 | 112 | */ |
mahphalke |
17:af1f2416dd26 | 113 | bool platform_usbcdc::data_received(uint32_t bytes) |
mahphalke |
17:af1f2416dd26 | 114 | { |
mahphalke |
17:af1f2416dd26 | 115 | volatile static uint32_t *rx_size = &_rx_size; |
mahphalke |
17:af1f2416dd26 | 116 | |
mahphalke |
17:af1f2416dd26 | 117 | if (*rx_size >= bytes) { |
mahphalke |
17:af1f2416dd26 | 118 | return true; |
mahphalke |
17:af1f2416dd26 | 119 | } else { |
mahphalke |
17:af1f2416dd26 | 120 | return false; |
mahphalke |
17:af1f2416dd26 | 121 | } |
mahphalke |
17:af1f2416dd26 | 122 | } |
mahphalke |
17:af1f2416dd26 | 123 | |
mahphalke |
17:af1f2416dd26 | 124 | |
mahphalke |
17:af1f2416dd26 | 125 | /** |
mahphalke |
17:af1f2416dd26 | 126 | * @brief Check if old USB data was transmitted |
mahphalke |
17:af1f2416dd26 | 127 | * @return true if transmit not in progress, else false |
mahphalke |
17:af1f2416dd26 | 128 | */ |
mahphalke |
17:af1f2416dd26 | 129 | bool platform_usbcdc::data_transmited(void) |
mahphalke |
17:af1f2416dd26 | 130 | { |
mahphalke |
17:af1f2416dd26 | 131 | volatile static bool *tx_in_progress = &_tx_in_progress; |
mahphalke |
17:af1f2416dd26 | 132 | |
mahphalke |
17:af1f2416dd26 | 133 | if (*tx_in_progress) { |
mahphalke |
17:af1f2416dd26 | 134 | return false; |
mahphalke |
17:af1f2416dd26 | 135 | } else { |
mahphalke |
17:af1f2416dd26 | 136 | return true; |
mahphalke |
17:af1f2416dd26 | 137 | } |
mahphalke |
17:af1f2416dd26 | 138 | } |
mahphalke |
17:af1f2416dd26 | 139 | |
mahphalke |
17:af1f2416dd26 | 140 | |
mahphalke |
17:af1f2416dd26 | 141 | /** |
mahphalke |
17:af1f2416dd26 | 142 | * @brief Read data from UART device. |
mahphalke |
17:af1f2416dd26 | 143 | * @param desc - Instance of UART. |
mahphalke |
17:af1f2416dd26 | 144 | * @param data - Pointer to buffer containing data. |
mahphalke |
17:af1f2416dd26 | 145 | * @param bytes_number - Number of bytes to read. |
mahphalke |
17:af1f2416dd26 | 146 | * @return SUCCESS in case of success, FAILURE otherwise. |
mahphalke |
17:af1f2416dd26 | 147 | */ |
mahphalke |
17:af1f2416dd26 | 148 | int32_t uart_read(struct uart_desc *desc, uint8_t *data, uint32_t bytes_number) |
mahphalke |
17:af1f2416dd26 | 149 | { |
mahphalke |
17:af1f2416dd26 | 150 | uint8_t cnt; |
mahphalke |
17:af1f2416dd26 | 151 | mbed::UnbufferedSerial *uart; // pointer to UnbufferedSerial/UART instance |
mahphalke |
17:af1f2416dd26 | 152 | platform_usbcdc *usb_cdc_dev; // Pointer to usb cdc device class instance |
mahphalke |
17:af1f2416dd26 | 153 | uint32_t size_rd; |
mahphalke |
17:af1f2416dd26 | 154 | |
mahphalke |
17:af1f2416dd26 | 155 | if (desc && data) { |
mahphalke |
17:af1f2416dd26 | 156 | if (((mbed_uart_desc *)(desc->extra))->uart_port) { |
mahphalke |
17:af1f2416dd26 | 157 | if (((mbed_uart_desc *)desc->extra)->virtual_com_enable) { |
mahphalke |
17:af1f2416dd26 | 158 | usb_cdc_dev = (platform_usbcdc *)((mbed_uart_desc *)( |
mahphalke |
17:af1f2416dd26 | 159 | desc->extra))->uart_port; |
mahphalke |
17:af1f2416dd26 | 160 | |
mahphalke |
17:af1f2416dd26 | 161 | while (!usb_cdc_dev->data_received(bytes_number)) { |
mahphalke |
17:af1f2416dd26 | 162 | /* Wait until new data is available */ |
mahphalke |
17:af1f2416dd26 | 163 | } |
mahphalke |
17:af1f2416dd26 | 164 | |
mahphalke |
17:af1f2416dd26 | 165 | /* Change terminal connection status manually */ |
mahphalke |
17:af1f2416dd26 | 166 | usb_cdc_dev->change_terminal_connection(true); |
mahphalke |
17:af1f2416dd26 | 167 | |
mahphalke |
17:af1f2416dd26 | 168 | usb_cdc_dev->receive_nb(data, bytes_number, &size_rd); |
mahphalke |
17:af1f2416dd26 | 169 | } else { |
mahphalke |
17:af1f2416dd26 | 170 | uart = (UnbufferedSerial *)(((mbed_uart_desc *)(desc->extra))->uart_port); |
mahphalke |
17:af1f2416dd26 | 171 | |
mahphalke |
17:af1f2416dd26 | 172 | for (cnt = 0; cnt < bytes_number; cnt++) { |
mahphalke |
17:af1f2416dd26 | 173 | uart->read(data + cnt, 1); |
mahphalke |
17:af1f2416dd26 | 174 | } |
mahphalke |
17:af1f2416dd26 | 175 | } |
mahphalke |
17:af1f2416dd26 | 176 | |
mahphalke |
17:af1f2416dd26 | 177 | return bytes_number; |
mahphalke |
17:af1f2416dd26 | 178 | } |
mahphalke |
17:af1f2416dd26 | 179 | } |
mahphalke |
17:af1f2416dd26 | 180 | |
mahphalke |
17:af1f2416dd26 | 181 | return FAILURE; |
mahphalke |
17:af1f2416dd26 | 182 | } |
mahphalke |
17:af1f2416dd26 | 183 | |
mahphalke |
17:af1f2416dd26 | 184 | |
mahphalke |
17:af1f2416dd26 | 185 | /** |
mahphalke |
17:af1f2416dd26 | 186 | * @brief Write data to UART device. |
mahphalke |
17:af1f2416dd26 | 187 | * @param desc - Instance of UART. |
mahphalke |
17:af1f2416dd26 | 188 | * @param data - Pointer to buffer containing data. |
mahphalke |
17:af1f2416dd26 | 189 | * @param bytes_number - Number of bytes to read. |
mahphalke |
17:af1f2416dd26 | 190 | * @return SUCCESS in case of success, FAILURE otherwise. |
mahphalke |
17:af1f2416dd26 | 191 | */ |
mahphalke |
17:af1f2416dd26 | 192 | int32_t uart_write(struct uart_desc *desc, const uint8_t *data, |
mahphalke |
17:af1f2416dd26 | 193 | uint32_t bytes_number) |
mahphalke |
17:af1f2416dd26 | 194 | { |
mahphalke |
17:af1f2416dd26 | 195 | mbed::UnbufferedSerial *uart; // pointer to UnbufferedSerial/UART instance |
mahphalke |
17:af1f2416dd26 | 196 | platform_usbcdc *usb_cdc_dev; // Pointer to usb cdc device class instance |
mahphalke |
17:af1f2416dd26 | 197 | uint32_t d_sz; |
mahphalke |
17:af1f2416dd26 | 198 | uint32_t indx = 0; |
mahphalke |
17:af1f2416dd26 | 199 | |
mahphalke |
17:af1f2416dd26 | 200 | if (desc && data) { |
mahphalke |
17:af1f2416dd26 | 201 | if (((mbed_uart_desc *)(desc->extra))->uart_port) { |
mahphalke |
17:af1f2416dd26 | 202 | if (((mbed_uart_desc *)desc->extra)->virtual_com_enable) { |
mahphalke |
17:af1f2416dd26 | 203 | usb_cdc_dev = (platform_usbcdc *)((mbed_uart_desc *)( |
mahphalke |
17:af1f2416dd26 | 204 | desc->extra))->uart_port; |
mahphalke |
17:af1f2416dd26 | 205 | |
mahphalke |
17:af1f2416dd26 | 206 | while (bytes_number) { |
mahphalke |
17:af1f2416dd26 | 207 | while (!usb_cdc_dev->data_transmited()) { |
mahphalke |
17:af1f2416dd26 | 208 | /* Wait until old data is transmitted */ |
mahphalke |
17:af1f2416dd26 | 209 | } |
mahphalke |
17:af1f2416dd26 | 210 | |
mahphalke |
17:af1f2416dd26 | 211 | /* Make sure packet size is less than max CDC packet size during data transmit */ |
mahphalke |
17:af1f2416dd26 | 212 | d_sz = (bytes_number > (USB_CDC_MAX_PACKET_SIZE - 1)) ? |
mahphalke |
17:af1f2416dd26 | 213 | (USB_CDC_MAX_PACKET_SIZE - 1) : |
mahphalke |
17:af1f2416dd26 | 214 | bytes_number; |
mahphalke |
17:af1f2416dd26 | 215 | |
mahphalke |
17:af1f2416dd26 | 216 | /* Change terminal connection status manually */ |
mahphalke |
17:af1f2416dd26 | 217 | usb_cdc_dev->change_terminal_connection(true); |
mahphalke |
17:af1f2416dd26 | 218 | |
mahphalke |
17:af1f2416dd26 | 219 | usb_cdc_dev->send_nb((uint8_t *)&data[indx], d_sz, &d_sz); |
mahphalke |
17:af1f2416dd26 | 220 | |
mahphalke |
17:af1f2416dd26 | 221 | bytes_number -= d_sz; |
mahphalke |
17:af1f2416dd26 | 222 | indx += d_sz; |
mahphalke |
17:af1f2416dd26 | 223 | } |
mahphalke |
17:af1f2416dd26 | 224 | |
mahphalke |
17:af1f2416dd26 | 225 | return bytes_number; |
mahphalke |
17:af1f2416dd26 | 226 | } else { |
mahphalke |
17:af1f2416dd26 | 227 | uart = (UnbufferedSerial *)(((mbed_uart_desc *)(desc->extra))->uart_port); |
mahphalke |
17:af1f2416dd26 | 228 | return uart->write(data, bytes_number); |
mahphalke |
17:af1f2416dd26 | 229 | } |
mahphalke |
17:af1f2416dd26 | 230 | } |
mahphalke |
17:af1f2416dd26 | 231 | } |
mahphalke |
17:af1f2416dd26 | 232 | |
mahphalke |
17:af1f2416dd26 | 233 | return FAILURE; |
mahphalke |
17:af1f2416dd26 | 234 | } |
mahphalke |
17:af1f2416dd26 | 235 | |
mahphalke |
17:af1f2416dd26 | 236 | |
mahphalke |
17:af1f2416dd26 | 237 | /** |
mahphalke |
17:af1f2416dd26 | 238 | * @brief Submit reading buffer to the UART driver. |
mahphalke |
17:af1f2416dd26 | 239 | * |
mahphalke |
17:af1f2416dd26 | 240 | * Buffer is used until bytes_number bytes are read. |
mahphalke |
17:af1f2416dd26 | 241 | * @param desc: Descriptor of the UART device |
mahphalke |
17:af1f2416dd26 | 242 | * @param data: Buffer where data will be read |
mahphalke |
17:af1f2416dd26 | 243 | * @param bytes_number: Number of bytes to be read. |
mahphalke |
17:af1f2416dd26 | 244 | * @return \ref SUCCESS in case of success, \ref FAILURE otherwise. |
mahphalke |
17:af1f2416dd26 | 245 | */ |
mahphalke |
17:af1f2416dd26 | 246 | int32_t uart_read_nonblocking(struct uart_desc *desc, |
mahphalke |
17:af1f2416dd26 | 247 | uint8_t *data, |
mahphalke |
17:af1f2416dd26 | 248 | uint32_t bytes_number) |
mahphalke |
17:af1f2416dd26 | 249 | { |
mahphalke |
17:af1f2416dd26 | 250 | mbed::UnbufferedSerial *uart; // pointer to UnbufferedSerial/UART instance |
mahphalke |
17:af1f2416dd26 | 251 | |
mahphalke |
17:af1f2416dd26 | 252 | if (desc) { |
mahphalke |
17:af1f2416dd26 | 253 | if (((mbed_uart_desc *)(desc->extra))->uart_port) { |
mahphalke |
17:af1f2416dd26 | 254 | uart = (UnbufferedSerial *)(((mbed_uart_desc *)(desc->extra))->uart_port); |
mahphalke |
17:af1f2416dd26 | 255 | |
mahphalke |
17:af1f2416dd26 | 256 | if (data) { |
mahphalke |
17:af1f2416dd26 | 257 | for (size_t i = 0; i < bytes_number; i++) { |
mahphalke |
17:af1f2416dd26 | 258 | if (uart->readable() > 0) { |
mahphalke |
17:af1f2416dd26 | 259 | uart->read(&data[i], 1); |
mahphalke |
17:af1f2416dd26 | 260 | } |
mahphalke |
17:af1f2416dd26 | 261 | } |
mahphalke |
17:af1f2416dd26 | 262 | |
mahphalke |
17:af1f2416dd26 | 263 | return bytes_number; |
mahphalke |
17:af1f2416dd26 | 264 | } |
mahphalke |
17:af1f2416dd26 | 265 | } |
mahphalke |
17:af1f2416dd26 | 266 | } |
mahphalke |
17:af1f2416dd26 | 267 | |
mahphalke |
17:af1f2416dd26 | 268 | return FAILURE; |
mahphalke |
17:af1f2416dd26 | 269 | } |
mahphalke |
17:af1f2416dd26 | 270 | |
mahphalke |
17:af1f2416dd26 | 271 | |
mahphalke |
17:af1f2416dd26 | 272 | /** |
mahphalke |
17:af1f2416dd26 | 273 | * @brief Submit writting buffer to the UART driver. |
mahphalke |
17:af1f2416dd26 | 274 | * |
mahphalke |
17:af1f2416dd26 | 275 | * Data from the buffer is sent over the UART, the function returns imediatly. |
mahphalke |
17:af1f2416dd26 | 276 | * @param desc: Descriptor of the UART device |
mahphalke |
17:af1f2416dd26 | 277 | * @param data: Buffer where data will be written |
mahphalke |
17:af1f2416dd26 | 278 | * @param bytes_number: Number of bytes to be written. |
mahphalke |
17:af1f2416dd26 | 279 | * @return \ref SUCCESS in case of success, \ref FAILURE otherwise. |
mahphalke |
17:af1f2416dd26 | 280 | */ |
mahphalke |
17:af1f2416dd26 | 281 | int32_t uart_write_nonblocking(struct uart_desc *desc, |
mahphalke |
17:af1f2416dd26 | 282 | const uint8_t *data, |
mahphalke |
17:af1f2416dd26 | 283 | uint32_t bytes_number) |
mahphalke |
17:af1f2416dd26 | 284 | { |
mahphalke |
17:af1f2416dd26 | 285 | mbed::UnbufferedSerial *uart; // pointer to UnbufferedSerial/UART instance |
mahphalke |
17:af1f2416dd26 | 286 | |
mahphalke |
17:af1f2416dd26 | 287 | if (desc) { |
mahphalke |
17:af1f2416dd26 | 288 | if (((mbed_uart_desc *)(desc->extra))->uart_port) { |
mahphalke |
17:af1f2416dd26 | 289 | uart = (UnbufferedSerial *)(((mbed_uart_desc *)(desc->extra))->uart_port); |
mahphalke |
17:af1f2416dd26 | 290 | |
mahphalke |
17:af1f2416dd26 | 291 | if (data) { |
mahphalke |
17:af1f2416dd26 | 292 | for (size_t i = 0; i < bytes_number; i++) { |
mahphalke |
17:af1f2416dd26 | 293 | uart->write(&data[i], 1); |
mahphalke |
17:af1f2416dd26 | 294 | } |
mahphalke |
17:af1f2416dd26 | 295 | |
mahphalke |
17:af1f2416dd26 | 296 | return bytes_number; |
mahphalke |
17:af1f2416dd26 | 297 | } |
mahphalke |
17:af1f2416dd26 | 298 | } |
mahphalke |
17:af1f2416dd26 | 299 | } |
mahphalke |
17:af1f2416dd26 | 300 | |
mahphalke |
17:af1f2416dd26 | 301 | return FAILURE; |
mahphalke |
17:af1f2416dd26 | 302 | } |
mahphalke |
17:af1f2416dd26 | 303 | |
mahphalke |
17:af1f2416dd26 | 304 | |
mahphalke |
17:af1f2416dd26 | 305 | /** |
mahphalke |
17:af1f2416dd26 | 306 | * @brief Initialize the UART communication peripheral. |
mahphalke |
17:af1f2416dd26 | 307 | * @param desc - The UART descriptor. |
mahphalke |
17:af1f2416dd26 | 308 | * @param param - The structure that contains the UART parameters. |
mahphalke |
17:af1f2416dd26 | 309 | * @return SUCCESS in case of success, FAILURE otherwise. |
mahphalke |
17:af1f2416dd26 | 310 | */ |
mahphalke |
17:af1f2416dd26 | 311 | int32_t uart_init(struct uart_desc **desc, struct uart_init_param *param) |
mahphalke |
17:af1f2416dd26 | 312 | { |
mahphalke |
17:af1f2416dd26 | 313 | mbed::UnbufferedSerial *uart; // Pointer to new UnbufferedSerial/UART instance |
mahphalke |
17:af1f2416dd26 | 314 | platform_usbcdc *usb_cdc_dev; // Pointer to usb cdc device class instance |
mahphalke |
17:af1f2416dd26 | 315 | mbed_uart_desc *mbed_desc; // Pointer to mbed uart descriptor |
mahphalke |
17:af1f2416dd26 | 316 | uart_desc *new_desc; // UART new descriptor |
mahphalke |
17:af1f2416dd26 | 317 | |
mahphalke |
17:af1f2416dd26 | 318 | if (desc && param && param->extra) { |
mahphalke |
17:af1f2416dd26 | 319 | // Create the UART description object for the device |
mahphalke |
17:af1f2416dd26 | 320 | new_desc = (uart_desc *)malloc(sizeof(uart_desc)); |
mahphalke |
17:af1f2416dd26 | 321 | if (!new_desc) { |
mahphalke |
17:af1f2416dd26 | 322 | goto err_new_desc; |
mahphalke |
17:af1f2416dd26 | 323 | } |
mahphalke |
17:af1f2416dd26 | 324 | |
mahphalke |
17:af1f2416dd26 | 325 | new_desc->baud_rate = param->baud_rate; |
mahphalke |
17:af1f2416dd26 | 326 | |
mahphalke |
17:af1f2416dd26 | 327 | if (((mbed_uart_init_param *)param->extra)->virtual_com_enable) { |
mahphalke |
17:af1f2416dd26 | 328 | // Create a new instance of platform_usbcdc class |
mahphalke |
17:af1f2416dd26 | 329 | usb_cdc_dev = new platform_usbcdc(false, |
mahphalke |
17:af1f2416dd26 | 330 | ((mbed_uart_init_param *)param->extra)->vendor_id, |
mahphalke |
17:af1f2416dd26 | 331 | ((mbed_uart_init_param *)param->extra)->product_id, |
mahphalke |
17:af1f2416dd26 | 332 | ((mbed_uart_init_param *)param->extra)->serial_number); |
mahphalke |
17:af1f2416dd26 | 333 | if (!usb_cdc_dev) { |
mahphalke |
17:af1f2416dd26 | 334 | goto err_usb_cdc_dev; |
mahphalke |
17:af1f2416dd26 | 335 | } |
mahphalke |
17:af1f2416dd26 | 336 | } else { |
mahphalke |
17:af1f2416dd26 | 337 | // Create and configure a new instance of UnbufferedSerial/UART port |
mahphalke |
17:af1f2416dd26 | 338 | uart = new UnbufferedSerial( |
mahphalke |
17:af1f2416dd26 | 339 | (PinName)(((mbed_uart_init_param *)param->extra)->uart_tx_pin), |
mahphalke |
17:af1f2416dd26 | 340 | (PinName)(((mbed_uart_init_param *)param->extra)->uart_rx_pin), |
mahphalke |
17:af1f2416dd26 | 341 | (int)param->baud_rate); |
mahphalke |
17:af1f2416dd26 | 342 | |
mahphalke |
17:af1f2416dd26 | 343 | if (!uart) { |
mahphalke |
17:af1f2416dd26 | 344 | goto err_uart; |
mahphalke |
17:af1f2416dd26 | 345 | } |
mahphalke |
17:af1f2416dd26 | 346 | } |
mahphalke |
17:af1f2416dd26 | 347 | |
mahphalke |
17:af1f2416dd26 | 348 | // Create a new mbed descriptor to store new UART instances |
mahphalke |
17:af1f2416dd26 | 349 | mbed_desc = (mbed_uart_desc *)malloc(sizeof(mbed_uart_desc)); |
mahphalke |
17:af1f2416dd26 | 350 | if (!mbed_desc) { |
mahphalke |
17:af1f2416dd26 | 351 | goto err_mbed_desc; |
mahphalke |
17:af1f2416dd26 | 352 | } |
mahphalke |
17:af1f2416dd26 | 353 | |
mahphalke |
17:af1f2416dd26 | 354 | if (((mbed_uart_init_param *)param->extra)->virtual_com_enable) { |
mahphalke |
17:af1f2416dd26 | 355 | mbed_desc->uart_port = (platform_usbcdc *)usb_cdc_dev; |
mahphalke |
17:af1f2416dd26 | 356 | |
mahphalke |
17:af1f2416dd26 | 357 | /* Establish connection with the USB CDC communication port */ |
mahphalke |
17:af1f2416dd26 | 358 | usb_cdc_dev->connect(); |
mahphalke |
17:af1f2416dd26 | 359 | mdelay(2000); |
mahphalke |
17:af1f2416dd26 | 360 | } else { |
mahphalke |
17:af1f2416dd26 | 361 | mbed_desc->uart_port = (UnbufferedSerial *)uart; |
mahphalke |
17:af1f2416dd26 | 362 | } |
mahphalke |
17:af1f2416dd26 | 363 | |
mahphalke |
17:af1f2416dd26 | 364 | mbed_desc->virtual_com_enable = ((mbed_uart_init_param *) |
mahphalke |
17:af1f2416dd26 | 365 | param->extra)->virtual_com_enable; |
mahphalke |
17:af1f2416dd26 | 366 | new_desc->extra = (mbed_uart_desc *)mbed_desc; |
mahphalke |
17:af1f2416dd26 | 367 | *desc = new_desc; |
mahphalke |
17:af1f2416dd26 | 368 | |
mahphalke |
17:af1f2416dd26 | 369 | return SUCCESS; |
mahphalke |
17:af1f2416dd26 | 370 | } |
mahphalke |
17:af1f2416dd26 | 371 | |
mahphalke |
17:af1f2416dd26 | 372 | err_mbed_desc: |
mahphalke |
17:af1f2416dd26 | 373 | if (uart) { |
mahphalke |
17:af1f2416dd26 | 374 | free(uart); |
mahphalke |
17:af1f2416dd26 | 375 | } |
mahphalke |
17:af1f2416dd26 | 376 | if (usb_cdc_dev) { |
mahphalke |
17:af1f2416dd26 | 377 | free(usb_cdc_dev); |
mahphalke |
17:af1f2416dd26 | 378 | } |
mahphalke |
17:af1f2416dd26 | 379 | err_uart: |
mahphalke |
17:af1f2416dd26 | 380 | err_usb_cdc_dev: |
mahphalke |
17:af1f2416dd26 | 381 | free(new_desc); |
mahphalke |
17:af1f2416dd26 | 382 | err_new_desc: |
mahphalke |
17:af1f2416dd26 | 383 | // Nothing to free |
mahphalke |
17:af1f2416dd26 | 384 | |
mahphalke |
17:af1f2416dd26 | 385 | return FAILURE; |
mahphalke |
17:af1f2416dd26 | 386 | } |
mahphalke |
17:af1f2416dd26 | 387 | |
mahphalke |
17:af1f2416dd26 | 388 | |
mahphalke |
17:af1f2416dd26 | 389 | /** |
mahphalke |
17:af1f2416dd26 | 390 | * @brief Free the resources allocated by uart_init(). |
mahphalke |
17:af1f2416dd26 | 391 | * @param desc - The UART descriptor. |
mahphalke |
17:af1f2416dd26 | 392 | * @return SUCCESS in case of success, FAILURE otherwise. |
mahphalke |
17:af1f2416dd26 | 393 | */ |
mahphalke |
17:af1f2416dd26 | 394 | int32_t uart_remove(struct uart_desc *desc) |
mahphalke |
17:af1f2416dd26 | 395 | { |
mahphalke |
17:af1f2416dd26 | 396 | if (desc) { |
mahphalke |
17:af1f2416dd26 | 397 | // Free the UART port object |
mahphalke |
17:af1f2416dd26 | 398 | if (((mbed_uart_desc *)desc->extra)->virtual_com_enable) { |
mahphalke |
17:af1f2416dd26 | 399 | if ((platform_usbcdc *)((mbed_uart_desc *)desc->extra)->uart_port) |
mahphalke |
17:af1f2416dd26 | 400 | delete((platform_usbcdc *)(platform_usbcdc *)((mbed_uart_desc *) |
mahphalke |
17:af1f2416dd26 | 401 | desc->extra)->uart_port); |
mahphalke |
17:af1f2416dd26 | 402 | } else { |
mahphalke |
17:af1f2416dd26 | 403 | if ((UnbufferedSerial *)(((mbed_uart_desc *)(desc->extra))->uart_port)) { |
mahphalke |
17:af1f2416dd26 | 404 | delete((UnbufferedSerial *)(((mbed_uart_desc *)(desc->extra))->uart_port)); |
mahphalke |
17:af1f2416dd26 | 405 | } |
mahphalke |
17:af1f2416dd26 | 406 | } |
mahphalke |
17:af1f2416dd26 | 407 | |
mahphalke |
17:af1f2416dd26 | 408 | // Free the UART extra descriptor object |
mahphalke |
17:af1f2416dd26 | 409 | if ((mbed_uart_desc *)(desc->extra)) { |
mahphalke |
17:af1f2416dd26 | 410 | free((mbed_uart_desc *)(desc->extra)); |
mahphalke |
17:af1f2416dd26 | 411 | } |
mahphalke |
17:af1f2416dd26 | 412 | |
mahphalke |
17:af1f2416dd26 | 413 | // Free the UART descriptor object |
mahphalke |
17:af1f2416dd26 | 414 | free(desc); |
mahphalke |
17:af1f2416dd26 | 415 | |
mahphalke |
17:af1f2416dd26 | 416 | return SUCCESS; |
mahphalke |
17:af1f2416dd26 | 417 | } |
mahphalke |
17:af1f2416dd26 | 418 | |
mahphalke |
17:af1f2416dd26 | 419 | return FAILURE; |
mahphalke |
17:af1f2416dd26 | 420 | } |
mahphalke |
17:af1f2416dd26 | 421 | |
mahphalke |
17:af1f2416dd26 | 422 | |
mahphalke |
17:af1f2416dd26 | 423 | /** |
mahphalke |
17:af1f2416dd26 | 424 | * @brief Get number of UART errors. |
mahphalke |
17:af1f2416dd26 | 425 | * @param desc - The UART descriptor. |
mahphalke |
17:af1f2416dd26 | 426 | * @return number of errors. |
mahphalke |
17:af1f2416dd26 | 427 | */ |
mahphalke |
17:af1f2416dd26 | 428 | uint32_t uart_get_errors(struct uart_desc *desc) |
mahphalke |
17:af1f2416dd26 | 429 | { |
mahphalke |
17:af1f2416dd26 | 430 | if (desc) { |
mahphalke |
17:af1f2416dd26 | 431 | // Unused variable - fix compiler warning |
mahphalke |
17:af1f2416dd26 | 432 | } |
mahphalke |
17:af1f2416dd26 | 433 | |
mahphalke |
17:af1f2416dd26 | 434 | return SUCCESS; |
mahphalke |
17:af1f2416dd26 | 435 | } |
mahphalke |
17:af1f2416dd26 | 436 | |
mahphalke |
17:af1f2416dd26 | 437 | #ifdef __cplusplus // Closing extern c |
mahphalke |
17:af1f2416dd26 | 438 | } |
mahphalke |
17:af1f2416dd26 | 439 | #endif // _cplusplus |