Platform drivers for Mbed.
Dependents: EVAL-CN0535-FMCZ EVAL-CN0535-FMCZ EVAL-AD568x-AD569x EVAL-AD7606 ... more
irq.cpp
00001 /***************************************************************************//** 00002 * @file irq.cpp 00003 * @brief Implementation of Interrupt Mbed platform driver interfaces 00004 ******************************************************************************** 00005 * Copyright (c) 2020-2021 Analog Devices, Inc. 00006 * All rights reserved. 00007 * 00008 * This software is proprietary to Analog Devices, Inc. and its licensors. 00009 * By using this software you agree to the terms of the associated 00010 * Analog Devices Software License Agreement. 00011 *******************************************************************************/ 00012 00013 /******************************************************************************/ 00014 /***************************** Include Files **********************************/ 00015 /******************************************************************************/ 00016 00017 #include <stdio.h> 00018 #include <mbed.h> 00019 00020 // Platform support needs to be C-compatible to work with other drivers 00021 #ifdef __cplusplus 00022 extern "C" 00023 { 00024 #endif 00025 00026 #include "error.h" 00027 #include "irq.h" 00028 #include "irq_extra.h" 00029 #include "uart_extra.h" 00030 00031 /******************************************************************************/ 00032 /*************************** Types Declarations *******************************/ 00033 /******************************************************************************/ 00034 00035 using namespace std::chrono; 00036 00037 /** 00038 * @struct mbed_irq_callback_desc 00039 * @brief Structure holding the callback functions for mbed irqs 00040 * @note The callback functions are mapped with 'irq_id' structure 00041 */ 00042 typedef struct { 00043 struct callback_desc callback_ext_int_id1; 00044 struct callback_desc callback_ext_int_id2; 00045 struct callback_desc callback_ext_int_id3; 00046 struct callback_desc callback_ext_int_id4; 00047 struct callback_desc callback_ext_int_id5; 00048 struct callback_desc callback_uart_rx_id1; 00049 struct callback_desc callback_ticker_id; 00050 } mbed_irq_callback_desc; 00051 00052 /* Mbed callback function pointer typedef */ 00053 typedef void(*mbed_callback_func)(void); 00054 00055 /* Mbed irq callback structure variable */ 00056 static mbed_irq_callback_desc mbed_irq_callbacks; 00057 00058 /******************************************************************************/ 00059 /************************ Functions Declarations ******************************/ 00060 /******************************************************************************/ 00061 00062 /******************************************************************************/ 00063 /************************ Functions Definitions *******************************/ 00064 /******************************************************************************/ 00065 00066 /** 00067 * @brief Mbed callback function for external interrupt ID1 event 00068 * @return none 00069 */ 00070 static void mbed_ext_int_id1_callback(void) 00071 { 00072 if (mbed_irq_callbacks.callback_ext_int_id1.callback) { 00073 mbed_irq_callbacks.callback_ext_int_id1.callback( 00074 mbed_irq_callbacks.callback_ext_int_id1.ctx, EXTERNAL_INT_ID1, NULL); 00075 } 00076 } 00077 00078 00079 /** 00080 * @brief Mbed callback function for external interrupt ID2 event 00081 * @return none 00082 */ 00083 static void mbed_ext_int_id2_callback(void) 00084 { 00085 if (mbed_irq_callbacks.callback_ext_int_id2.callback) { 00086 mbed_irq_callbacks.callback_ext_int_id2.callback( 00087 mbed_irq_callbacks.callback_ext_int_id2.ctx, EXTERNAL_INT_ID2, NULL); 00088 } 00089 } 00090 00091 00092 /** 00093 * @brief Mbed callback function for external interrupt ID3 event 00094 * @return none 00095 */ 00096 static void mbed_ext_int_id3_callback(void) 00097 { 00098 if (mbed_irq_callbacks.callback_ext_int_id3.callback) { 00099 mbed_irq_callbacks.callback_ext_int_id3.callback( 00100 mbed_irq_callbacks.callback_ext_int_id3.ctx, EXTERNAL_INT_ID3, NULL); 00101 } 00102 } 00103 00104 00105 /** 00106 * @brief Mbed callback function for external interrupt ID4 event 00107 * @return none 00108 */ 00109 static void mbed_ext_int_id4_callback(void) 00110 { 00111 if (mbed_irq_callbacks.callback_ext_int_id4.callback) { 00112 mbed_irq_callbacks.callback_ext_int_id4.callback( 00113 mbed_irq_callbacks.callback_ext_int_id4.ctx, EXTERNAL_INT_ID4, NULL); 00114 } 00115 } 00116 00117 00118 /** 00119 * @brief Mbed callback function for external interrupt ID5 event 00120 * @return none 00121 */ 00122 static void mbed_ext_int_id5_callback(void) 00123 { 00124 if (mbed_irq_callbacks.callback_ext_int_id5.callback) { 00125 mbed_irq_callbacks.callback_ext_int_id5.callback( 00126 mbed_irq_callbacks.callback_ext_int_id5.ctx, EXTERNAL_INT_ID5, NULL); 00127 } 00128 } 00129 00130 00131 /** 00132 * @brief Mbed callback function for UART Rx ID1 event 00133 * @return none 00134 */ 00135 static void mbed_uart_rx_id1_callback(void) 00136 { 00137 if (mbed_irq_callbacks.callback_uart_rx_id1.callback) { 00138 mbed_irq_callbacks.callback_uart_rx_id1.callback( 00139 mbed_irq_callbacks.callback_uart_rx_id1.ctx, UART_RX_INT_ID1, NULL); 00140 } 00141 } 00142 00143 00144 /** 00145 * @brief Mbed callback function for ticker ID event 00146 * @return none 00147 */ 00148 static void mbed_ticker_id_callback(void) 00149 { 00150 if (mbed_irq_callbacks.callback_ticker_id.callback) { 00151 mbed_irq_callbacks.callback_ticker_id.callback( 00152 mbed_irq_callbacks.callback_ticker_id.ctx, TICKER_INT_ID, NULL); 00153 } 00154 } 00155 00156 00157 /** 00158 * @brief Initialized the controller for the peripheral interrupts 00159 * @param desc[in, out] - Pointer where the configured instance is stored 00160 * @param param[in] - Configuration information for the instance 00161 * @return SUCCESS in case of success, FAILURE otherwise. 00162 */ 00163 int32_t irq_ctrl_init(struct irq_ctrl_desc **desc, 00164 const struct irq_init_param *param) 00165 { 00166 mbed::Ticker *ticker; 00167 InterruptIn *ext_interrupt; 00168 mbed_irq_desc *new_mbed_desc; 00169 00170 if (!desc || !param) { 00171 return FAILURE; 00172 } 00173 00174 irq_ctrl_desc *new_desc = (irq_ctrl_desc *)malloc(sizeof(irq_ctrl_desc)); 00175 if (!new_desc) { 00176 goto err_new_desc; 00177 } 00178 00179 new_mbed_desc = (mbed_irq_desc *)malloc(sizeof(mbed_irq_desc)); 00180 if (!new_mbed_desc) { 00181 goto err_new_mbed_desc; 00182 } 00183 00184 new_desc->irq_ctrl_id = param->irq_ctrl_id; 00185 new_mbed_desc->int_mode = ((mbed_irq_init_param *)param->extra)->int_mode; 00186 new_mbed_desc->ext_int_pin = ((mbed_irq_init_param *) 00187 param->extra)->ext_int_pin; 00188 00189 switch (param->irq_ctrl_id) { 00190 case EXTERNAL_INT_ID1: 00191 case EXTERNAL_INT_ID2: 00192 case EXTERNAL_INT_ID3: 00193 case EXTERNAL_INT_ID4: 00194 case EXTERNAL_INT_ID5: 00195 /* Create a new external interrupt object */ 00196 ext_interrupt = new InterruptIn((PinName)(new_mbed_desc->ext_int_pin)); 00197 if (!ext_interrupt) { 00198 goto err_interrupt; 00199 } 00200 00201 new_mbed_desc->int_obj = (mbed::InterruptIn *)ext_interrupt; 00202 break; 00203 00204 case TICKER_INT_ID: 00205 /* Ticker is a special mbed class used for generating recurring interrupt. 00206 * The object of this class is created during interrupt initialization as: 00207 * 1) To avoid having seperate module for it. 00208 * 2) To avoid having multiple instances of Ticker class 00209 * */ 00210 ticker = new Ticker(); 00211 if (!ticker) { 00212 goto err_interrupt; 00213 } 00214 00215 new_mbed_desc->int_obj = (mbed::Ticker *)ticker; 00216 new_mbed_desc->ticker_period_usec = ((mbed_irq_init_param *) 00217 param->extra)->ticker_period_usec; 00218 break; 00219 00220 case UART_RX_INT_ID1: 00221 /* UART object must be created from uart.cpp module by an application */ 00222 new_mbed_desc->int_obj = ((mbed_irq_init_param *) 00223 param->extra)->int_obj_type; 00224 break; 00225 00226 default: 00227 goto err_interrupt; 00228 } 00229 00230 new_desc->extra = (irq_ctrl_desc *)new_mbed_desc; 00231 00232 *desc = new_desc; 00233 00234 return SUCCESS; 00235 00236 err_interrupt: 00237 free(new_mbed_desc); 00238 err_new_mbed_desc: 00239 free(new_desc); 00240 err_new_desc: 00241 // Nothing to free 00242 00243 return FAILURE; 00244 } 00245 00246 00247 /** 00248 * @brief Free the resources allocated by irq_ctrl_init() 00249 * @param desc[in, out] - Interrupt controller descriptor. 00250 * @return SUCCESS in case of success, FAILURE otherwise. 00251 */ 00252 int32_t irq_ctrl_remove(struct irq_ctrl_desc *desc) 00253 { 00254 uint8_t irq_id; 00255 00256 if (!desc) { 00257 return FAILURE; 00258 } 00259 00260 if (((mbed_irq_desc *)desc->extra)->int_obj) { 00261 free(((mbed_irq_desc *)desc->extra)->int_obj); 00262 } 00263 00264 /* Unregister all callbacks */ 00265 for (irq_id = 0; irq_id < (uint8_t)NB_INTERRUPTS; irq_id++) { 00266 if (irq_unregister(desc, irq_id) != SUCCESS) 00267 return FAILURE; 00268 } 00269 00270 if ((irq_ctrl_desc *)desc->extra) { 00271 free((irq_ctrl_desc *)desc->extra); 00272 } 00273 00274 free(desc); 00275 00276 return SUCCESS; 00277 } 00278 00279 00280 /** 00281 * @brief Registers a IRQ callback function to irq controller. 00282 * @param desc[in] - The IRQ controller descriptor. 00283 * @param irq_id[in] - Interrupt identifier. 00284 * @param callback_desc - Descriptor of the callback. If it is NULL, the 00285 * callback will be unregistered 00286 * @return SUCCESS in case of success, FAILURE otherwise. 00287 */ 00288 int32_t irq_register_callback(struct irq_ctrl_desc *desc, 00289 uint32_t irq_id, 00290 struct callback_desc *callback_desc) 00291 { 00292 InterruptIn *ext_interrupt; 00293 mbed_callback_func mbed_callback; 00294 00295 if (!desc || !callback_desc) { 00296 return FAILURE; 00297 } 00298 00299 switch (irq_id) { 00300 case EXTERNAL_INT_ID1: 00301 case EXTERNAL_INT_ID2: 00302 case EXTERNAL_INT_ID3: 00303 case EXTERNAL_INT_ID4: 00304 case EXTERNAL_INT_ID5: 00305 switch (irq_id) { 00306 case EXTERNAL_INT_ID1: 00307 mbed_irq_callbacks.callback_ext_int_id1.callback = callback_desc->callback; 00308 mbed_irq_callbacks.callback_ext_int_id1.ctx = callback_desc->ctx; 00309 mbed_callback = mbed_ext_int_id1_callback; 00310 break; 00311 00312 case EXTERNAL_INT_ID2: 00313 mbed_irq_callbacks.callback_ext_int_id2.callback = callback_desc->callback; 00314 mbed_irq_callbacks.callback_ext_int_id2.ctx = callback_desc->ctx; 00315 mbed_callback = mbed_ext_int_id2_callback; 00316 break; 00317 00318 case EXTERNAL_INT_ID3: 00319 mbed_irq_callbacks.callback_ext_int_id3.callback = callback_desc->callback; 00320 mbed_irq_callbacks.callback_ext_int_id3.ctx = callback_desc->ctx; 00321 mbed_callback = mbed_ext_int_id3_callback; 00322 break; 00323 00324 case EXTERNAL_INT_ID4: 00325 mbed_irq_callbacks.callback_ext_int_id4.callback = callback_desc->callback; 00326 mbed_irq_callbacks.callback_ext_int_id4.ctx = callback_desc->ctx; 00327 mbed_callback = mbed_ext_int_id4_callback; 00328 break; 00329 00330 case EXTERNAL_INT_ID5: 00331 mbed_irq_callbacks.callback_ext_int_id5.callback = callback_desc->callback; 00332 mbed_irq_callbacks.callback_ext_int_id5.ctx = callback_desc->ctx; 00333 mbed_callback = mbed_ext_int_id5_callback; 00334 break; 00335 00336 default: 00337 return FAILURE; 00338 } 00339 00340 ext_interrupt = (InterruptIn *)(((mbed_irq_desc *)(desc->extra))->int_obj); 00341 00342 /* Select interrupt mode */ 00343 if (((mbed_irq_desc *)(desc->extra))->int_mode == EXT_IRQ_FALL) { 00344 ext_interrupt->fall(mbed_callback); 00345 } else if (((mbed_irq_desc *)(desc->extra))->int_mode == EXT_IRQ_RISE) { 00346 ext_interrupt->rise(mbed_callback); 00347 } else { 00348 return FAILURE; 00349 } 00350 00351 break; 00352 00353 case UART_RX_INT_ID1: 00354 mbed_irq_callbacks.callback_uart_rx_id1.callback = callback_desc->callback; 00355 mbed_irq_callbacks.callback_uart_rx_id1.ctx = callback_desc->ctx; 00356 break; 00357 00358 case TICKER_INT_ID: 00359 mbed_irq_callbacks.callback_ticker_id.callback = callback_desc->callback; 00360 mbed_irq_callbacks.callback_ticker_id.ctx = callback_desc->ctx; 00361 break; 00362 00363 default: 00364 return FAILURE; 00365 } 00366 00367 return SUCCESS; 00368 } 00369 00370 00371 /** 00372 * @brief Unregister a IRQ callback function. 00373 * @param desc[in] - The IRQ controller descriptor. 00374 * @param irq_id[in] - Interrupt identifier. 00375 * @return SUCCESS in case of success, FAILURE otherwise. 00376 */ 00377 int32_t irq_unregister(struct irq_ctrl_desc *desc, uint32_t irq_id) 00378 { 00379 if (!desc) { 00380 return FAILURE; 00381 } 00382 00383 switch (irq_id) { 00384 case EXTERNAL_INT_ID1: 00385 mbed_irq_callbacks.callback_ext_int_id1.callback = NULL; 00386 break; 00387 00388 case EXTERNAL_INT_ID2: 00389 mbed_irq_callbacks.callback_ext_int_id2.callback = NULL; 00390 break; 00391 00392 case EXTERNAL_INT_ID3: 00393 mbed_irq_callbacks.callback_ext_int_id3.callback = NULL; 00394 break; 00395 00396 case EXTERNAL_INT_ID4: 00397 mbed_irq_callbacks.callback_ext_int_id4.callback = NULL; 00398 break; 00399 00400 case EXTERNAL_INT_ID5: 00401 mbed_irq_callbacks.callback_ext_int_id5.callback = NULL; 00402 break; 00403 00404 case UART_RX_INT_ID1: 00405 mbed_irq_callbacks.callback_uart_rx_id1.callback = NULL; 00406 break; 00407 00408 case TICKER_INT_ID: 00409 mbed_irq_callbacks.callback_ticker_id.callback = NULL; 00410 break; 00411 00412 default: 00413 return FAILURE; 00414 } 00415 00416 return SUCCESS; 00417 } 00418 00419 /** 00420 * @brief Enable specific interrupt 00421 * @param desc[in] - The IRQ controller descriptor. 00422 * @param irq_id[in] - Interrupt identifier. 00423 * @return SUCCESS in case of success, FAILURE otherwise. 00424 */ 00425 int32_t irq_enable(struct irq_ctrl_desc *desc, uint32_t irq_id) 00426 { 00427 InterruptIn *ext_interrupt; 00428 mbed::UnbufferedSerial *uart_rx_port; 00429 mbed::Ticker *ticker; 00430 00431 if (!desc || !desc->extra) { 00432 return FAILURE; 00433 } 00434 00435 switch (irq_id) { 00436 case EXTERNAL_INT_ID1: 00437 case EXTERNAL_INT_ID2: 00438 case EXTERNAL_INT_ID3: 00439 case EXTERNAL_INT_ID4: 00440 case EXTERNAL_INT_ID5: 00441 ext_interrupt = (InterruptIn *)(((mbed_irq_desc *)(desc->extra))->int_obj); 00442 ext_interrupt->enable_irq(); 00443 break; 00444 00445 case UART_RX_INT_ID1: 00446 uart_rx_port = (mbed::UnbufferedSerial *)(((mbed_irq_desc *)( 00447 desc->extra))->int_obj); 00448 uart_rx_port->attach(mbed_uart_rx_id1_callback, UnbufferedSerial::RxIrq); 00449 break; 00450 00451 case TICKER_INT_ID: 00452 ticker = (mbed::Ticker *)(((mbed_irq_desc *)(desc->extra))->int_obj); 00453 ticker->attach(mbed_ticker_id_callback, 00454 microseconds(((mbed_irq_desc *)(desc->extra))->ticker_period_usec)); 00455 break; 00456 00457 default: 00458 return FAILURE; 00459 } 00460 00461 return SUCCESS; 00462 } 00463 00464 /** 00465 * @brief Disable specific interrupt 00466 * @param desc[in] - The IRQ controller descriptor. 00467 * @param irq_id[in] - Interrupt identifier. 00468 * @return SUCCESS in case of success, FAILURE otherwise. 00469 */ 00470 int32_t irq_disable(struct irq_ctrl_desc *desc, uint32_t irq_id) 00471 { 00472 InterruptIn *ext_interrupt; 00473 mbed::UnbufferedSerial *uart_rx_port; 00474 mbed::Ticker *ticker; 00475 00476 if (!desc || !desc->extra) { 00477 return FAILURE; 00478 } 00479 00480 switch (irq_id) { 00481 case EXTERNAL_INT_ID1: 00482 case EXTERNAL_INT_ID2: 00483 case EXTERNAL_INT_ID3: 00484 case EXTERNAL_INT_ID4: 00485 case EXTERNAL_INT_ID5: 00486 ext_interrupt = (InterruptIn *)(((mbed_irq_desc *)(desc->extra))->int_obj); 00487 ext_interrupt->disable_irq(); 00488 break; 00489 00490 case UART_RX_INT_ID1: 00491 uart_rx_port = (mbed::UnbufferedSerial *)(((mbed_irq_desc *)( 00492 desc->extra))->int_obj); 00493 uart_rx_port->attach(NULL, UnbufferedSerial::RxIrq); 00494 break; 00495 00496 case TICKER_INT_ID: 00497 ticker = (mbed::Ticker *)(((mbed_irq_desc *)(desc->extra))->int_obj); 00498 ticker->detach(); 00499 break; 00500 00501 default: 00502 return FAILURE; 00503 } 00504 00505 return SUCCESS; 00506 } 00507 00508 #ifdef __cplusplus // Closing extern c 00509 } 00510 #endif
Generated on Wed Jul 13 2022 14:37:51 by 1.7.2