Working fork to test F0 application
Fork of CANnucleo by
Embed:
(wiki syntax)
Show/hide line numbers
can_api.c
00001 /* 00002 ****************************************************************************** 00003 * @file can_api.c 00004 * @author Zoltan Hudak 00005 * @version 00006 * @date 04-August-2015 00007 * @brief CAN api for NUCLEO-F103RB platform 00008 ****************************************************************************** 00009 * @attention 00010 * 00011 * <h2><center>© COPYRIGHT(c) 2015 Zoltan Hudak <hudakz@inbox.com> 00012 * 00013 * All rights reserved. 00014 00015 This program is free software: you can redistribute it and/or modify 00016 it under the terms of the GNU General Public License as published by 00017 the Free Software Foundation, either version 3 of the License, or 00018 (at your option) any later version. 00019 00020 This program is distributed in the hope that it will be useful, 00021 but WITHOUT ANY WARRANTY; without even the implied warranty of 00022 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00023 GNU General Public License for more details. 00024 00025 You should have received a copy of the GNU General Public License 00026 along with this program. If not, see <http://www.gnu.org/licenses/>. 00027 */ 00028 #include "can_api.h" 00029 #include "can_helper.h" 00030 #include "pinmap.h" 00031 00032 extern void (*rxCompleteCallback) (void); 00033 extern CAN_HandleTypeDef _canHandle; 00034 00035 /** 00036 * @brief 00037 * @note 00038 * @param 00039 * @retval 00040 */ 00041 void can_init(can_t* obj, PinName rd, PinName td, FunctionalState abom) { 00042 initCAN(obj, rd, td, abom); 00043 can_filter(obj, 0, 0, CANAny, 0); 00044 } 00045 00046 /** 00047 * @brief 00048 * @note 00049 * @param 00050 * @retval 00051 */ 00052 void can_free(can_t* obj) { 00053 HAL_CAN_MspDeInit(&_canHandle); 00054 } 00055 00056 /** 00057 * @brief 00058 * @note 00059 * @param 00060 * @retval 00061 */ 00062 int can_frequency(can_t* obj, int hz) { 00063 HAL_NVIC_DisableIRQ(CAN_IRQ); 00064 00065 #if defined(TARGET_NUCLEO_F072RB) || \ 00066 defined(TARGET_NUCLEO_F091RC) 00067 00068 // APB1 peripheral clock = 48000000Hz 00069 00070 switch(hz) { 00071 case 1000000: 00072 // 1000kbps bit rate 00073 _canHandle.Init.Prescaler = 4; // number of time quanta = 48000000/4/1000000 = 12 00074 _canHandle.Init.SJW = CAN_SJW_1TQ; 00075 _canHandle.Init.BS1 = CAN_BS1_8TQ; // sample point at: (1 + 8) / 12 * 100 = 75% 00076 _canHandle.Init.BS2 = CAN_BS2_3TQ; 00077 break; 00078 00079 case 500000: 00080 // 500kbps bit rate 00081 _canHandle.Init.Prescaler = 8; // number of time quanta = 48000000/8/500000 = 12 00082 _canHandle.Init.SJW = CAN_SJW_1TQ; 00083 _canHandle.Init.BS1 = CAN_BS1_8TQ; // sample point at: (1 + 8) / 12 * 100 = 75% 00084 _canHandle.Init.BS2 = CAN_BS2_3TQ; 00085 break; 00086 00087 case 250000: 00088 // 250kbps 00089 _canHandle.Init.Prescaler = 12; // number of time quanta = 48000000/12/250000 = 16 00090 _canHandle.Init.SJW = CAN_SJW_1TQ; 00091 _canHandle.Init.BS1 = CAN_BS1_11TQ; // sample point at: (1 + 11) / 16 * 100 = 75% 00092 _canHandle.Init.BS2 = CAN_BS2_4TQ; 00093 break; 00094 00095 case 125000: 00096 // 125kbps 00097 _canHandle.Init.Prescaler = 24; // number of time quanta = 48000000/24/125000 = 16 00098 _canHandle.Init.SJW = CAN_SJW_1TQ; 00099 _canHandle.Init.BS1 = CAN_BS1_11TQ; // sample point at: (1 + 11) / 16 * 100 = 75% 00100 _canHandle.Init.BS2 = CAN_BS2_4TQ; 00101 break; 00102 00103 default: 00104 // 125kbps (default) 00105 _canHandle.Init.Prescaler = 24; // number of time quanta = 48000000/24/125000 = 16 00106 _canHandle.Init.SJW = CAN_SJW_1TQ; 00107 _canHandle.Init.BS1 = CAN_BS1_11TQ; // sample point at: (1 + 11) / 16 * 100 = 75% 00108 _canHandle.Init.BS2 = CAN_BS2_4TQ; 00109 } 00110 00111 #elif defined(TARGET_NUCLEO_F103RB) || \ 00112 defined(TARGET_NUCLEO_F303RE) || \ 00113 defined(TARGET_NUCLEO_F303K8) || \ 00114 defined(TARGET_NUCLEO_F334R8) || \ 00115 defined(TARGET_DISCO_F334C8) 00116 00117 // APB1 peripheral clock = 36000000Hz 00118 00119 switch(hz) { 00120 case 1000000: 00121 // 1000kbps bit rate 00122 _canHandle.Init.Prescaler = 3; // number of time quanta = 36000000/3/1000000 = 12 00123 _canHandle.Init.SJW = CAN_SJW_1TQ; 00124 _canHandle.Init.BS1 = CAN_BS1_8TQ; // sample point at: (1 + 8) / 12 * 100 = 75% 00125 _canHandle.Init.BS2 = CAN_BS2_3TQ; 00126 break; 00127 00128 case 500000: 00129 // 500kbps bit rate 00130 _canHandle.Init.Prescaler = 6; // number of time quanta = 36000000/6/500000 = 12 00131 _canHandle.Init.SJW = CAN_SJW_1TQ; 00132 _canHandle.Init.BS1 = CAN_BS1_8TQ; // sample point at: (1 + 8) / 12 * 100 = 75% 00133 _canHandle.Init.BS2 = CAN_BS2_3TQ; 00134 break; 00135 00136 case 250000: 00137 // 250kbps 00138 _canHandle.Init.Prescaler = 9; // number of time quanta = 36000000/9/250000 = 16 00139 _canHandle.Init.SJW = CAN_SJW_1TQ; 00140 _canHandle.Init.BS1 = CAN_BS1_11TQ; // sample point at: (1 + 11) / 16 * 100 = 75% 00141 _canHandle.Init.BS2 = CAN_BS2_4TQ; 00142 break; 00143 00144 case 125000: 00145 // 125kbps 00146 _canHandle.Init.Prescaler = 18; // number of time quanta = 36000000/18/125000 = 16 00147 _canHandle.Init.SJW = CAN_SJW_1TQ; 00148 _canHandle.Init.BS1 = CAN_BS1_11TQ; // sample point at: (1 + 11) / 16 * 100 = 75% 00149 _canHandle.Init.BS2 = CAN_BS2_4TQ; 00150 break; 00151 00152 default: 00153 // 125kbps (default) 00154 #if DEBUG 00155 printf("Unknown frequency specified!\r\n"); 00156 printf("Using default 125kbps\r\n"); 00157 #endif 00158 _canHandle.Init.Prescaler = 18; // number of time quanta = 36000000/18/125000 = 16 00159 _canHandle.Init.SJW = CAN_SJW_1TQ; 00160 _canHandle.Init.BS1 = CAN_BS1_11TQ; // sample point at: (1 + 11) / 16 * 100 = 75% 00161 _canHandle.Init.BS2 = CAN_BS2_4TQ; 00162 } 00163 00164 #elif defined(TARGET_NUCLEO_F446RE) 00165 00166 // APB1 peripheral clock = 45000000Hz 00167 00168 switch(hz) { 00169 case 1000000: 00170 // 1000kbps bit rate 00171 _canHandle.Init.Prescaler = 5; // number of time quanta = 45000000/5/1000000 = 9 00172 _canHandle.Init.SJW = CAN_SJW_1TQ; 00173 _canHandle.Init.BS1 = CAN_BS1_6TQ; // sample point at: (1 + 6) / 9 * 100 = 77.78% 00174 _canHandle.Init.BS2 = CAN_BS2_2TQ; 00175 break; 00176 00177 case 500000: 00178 // 500kbps bit rate 00179 _canHandle.Init.Prescaler = 10; // number of time quanta = 45000000/10/500000 = 9 00180 _canHandle.Init.SJW = CAN_SJW_1TQ; 00181 _canHandle.Init.BS1 = CAN_BS1_6TQ; // sample point at: (1 + 6) / 9 * 100 = 77.78% 00182 _canHandle.Init.BS2 = CAN_BS2_2TQ; 00183 break; 00184 00185 case 250000: 00186 // 250kbps 00187 _canHandle.Init.Prescaler = 15; // number of time quanta = 45000000/15/250000 = 12 00188 _canHandle.Init.SJW = CAN_SJW_1TQ; 00189 _canHandle.Init.BS1 = CAN_BS1_8TQ; // sample point at: (1 + 8) / 12 * 100 = 75% 00190 _canHandle.Init.BS2 = CAN_BS2_3TQ; 00191 break; 00192 00193 case 125000: 00194 // 125kbps 00195 _canHandle.Init.Prescaler = 30; // number of time quanta = 45000000/30/125000 = 12 00196 _canHandle.Init.SJW = CAN_SJW_1TQ; 00197 _canHandle.Init.BS1 = CAN_BS1_8TQ; // sample point at: (1 + 8) / 12 * 100 = 75% 00198 _canHandle.Init.BS2 = CAN_BS2_3TQ; 00199 break; 00200 00201 default: 00202 // 125kbps (default) 00203 #if DEBUG 00204 printf("Unknown frequency specified!\r\n"); 00205 printf("Using default 125kbps\r\n"); 00206 #endif 00207 _canHandle.Init.Prescaler = 30; // number of time quanta = 45000000/30/125000 = 12 00208 _canHandle.Init.SJW = CAN_SJW_1TQ; 00209 _canHandle.Init.BS1 = CAN_BS1_8TQ; // sample point at: (1 + 8) / 12 * 100 = 75% 00210 _canHandle.Init.BS2 = CAN_BS2_3TQ; 00211 } 00212 00213 #endif 00214 00215 HAL_CAN_Init(&_canHandle); 00216 HAL_NVIC_EnableIRQ(CAN_IRQ); 00217 00218 return 1; 00219 } 00220 00221 /** 00222 * @brief 00223 * @note 00224 * @param 00225 * @retval 00226 */ 00227 void can_irq_init(can_t* obj, can_irq_handler handler, uint32_t id) { 00228 if(HAL_CAN_Receive_IT(&_canHandle, CAN_FIFO0) != HAL_OK) { 00229 #ifdef DEBUG 00230 printf("CAN reception initialization error\r\n"); 00231 #endif 00232 } 00233 } 00234 00235 /** 00236 * @brief 00237 * @note 00238 * @param 00239 * @retval 00240 */ 00241 void can_irq_free(can_t* obj) { 00242 rxCompleteCallback = 0; 00243 } 00244 00245 /** 00246 * @brief 00247 * @note 00248 * @param 00249 * @retval 00250 */ 00251 void can_irq_set(void (*fptr) (void)) { 00252 rxCompleteCallback = fptr; 00253 } 00254 00255 /** 00256 * @brief 00257 * @note 00258 * @param 00259 * @retval 00260 */ 00261 int can_write(can_t* obj, CAN_Message msg, int cc) { 00262 int i = 0; 00263 00264 if(msg.format == CANStandard) { 00265 _canHandle.pTxMsg->StdId = msg.id; 00266 _canHandle.pTxMsg->ExtId = 0x00; 00267 } 00268 else { 00269 _canHandle.pTxMsg->StdId = 0x00; 00270 _canHandle.pTxMsg->ExtId = msg.id; 00271 } 00272 00273 _canHandle.pTxMsg->RTR = msg.type == CANData ? CAN_RTR_DATA : CAN_RTR_REMOTE; 00274 _canHandle.pTxMsg->IDE = msg.format == CANStandard ? CAN_ID_STD : CAN_ID_EXT; 00275 _canHandle.pTxMsg->DLC = msg.len; 00276 00277 for(i = 0; i < msg.len; i++) 00278 _canHandle.pTxMsg->Data[i] = msg.data[i]; 00279 00280 if(HAL_CAN_Transmit(&_canHandle, 10) != HAL_OK) { 00281 #ifdef DEBUG 00282 printf("Transmission error\r\n"); 00283 #endif 00284 return 0; 00285 } 00286 else 00287 return 1; 00288 } 00289 00290 /** 00291 * @brief 00292 * @note 00293 * @param 00294 * @retval 00295 */ 00296 int can_read(can_t* obj, CAN_Message* msg, int handle) { 00297 int i; 00298 msg->id = _canHandle.pRxMsg->IDE == CAN_ID_STD ? _canHandle.pRxMsg->StdId : _canHandle.pRxMsg->ExtId; 00299 msg->type = _canHandle.pRxMsg->RTR == CAN_RTR_DATA ? CANData : CANRemote; 00300 msg->format = _canHandle.pRxMsg->IDE == CAN_ID_STD ? CANStandard : CANExtended; 00301 msg->len = _canHandle.pRxMsg->DLC; 00302 for(i = 0; i < msg->len; i++) 00303 msg->data[i] = _canHandle.pRxMsg->Data[i]; 00304 00305 return msg->len; 00306 } 00307 00308 /** 00309 * @brief 00310 * @note 00311 * @param 00312 * @retval 00313 */ 00314 int can_mode(can_t* obj, CanMode mode) { 00315 switch(mode) { 00316 case MODE_RESET: 00317 return HAL_ERROR; 00318 00319 case MODE_NORMAL: 00320 _canHandle.Init.Mode = CAN_MODE_NORMAL; 00321 break; 00322 00323 case MODE_SILENT: 00324 _canHandle.Init.Mode = CAN_MODE_SILENT; 00325 break; 00326 00327 case MODE_TEST_GLOBAL: 00328 _canHandle.Init.Mode = CAN_MODE_LOOPBACK; 00329 break; 00330 00331 case MODE_TEST_LOCAL: 00332 _canHandle.Init.Mode = CAN_MODE_LOOPBACK; 00333 break; 00334 00335 case MODE_TEST_SILENT: 00336 _canHandle.Init.Mode = CAN_MODE_SILENT_LOOPBACK; 00337 break; 00338 } 00339 00340 return HAL_CAN_Init(&_canHandle); 00341 } 00342 00343 /** 00344 * @brief 00345 * @note 00346 * @param 00347 * @retval 00348 */ 00349 int can_filter(can_t* obj, uint32_t id, uint32_t mask, CANFormat format /*=CANAny*/, int32_t handle /*=0*/ ) { 00350 CAN_FilterConfTypeDef sFilterConfig; 00351 00352 sFilterConfig.FilterNumber = handle; // Specifies the filter number (must be a number between 0 and 13 at 32-bit filter scale) 00353 sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; 00354 sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; 00355 sFilterConfig.FilterIdHigh = (((id) >> 16) & 0xFFFF); 00356 sFilterConfig.FilterIdLow = ((id) & 0xFFFF); 00357 sFilterConfig.FilterMaskIdHigh = (((mask) >> 16) & 0xFFFF); 00358 sFilterConfig.FilterMaskIdLow = ((mask) & 0xFFFF); 00359 sFilterConfig.FilterFIFOAssignment = 0; 00360 sFilterConfig.FilterActivation = ENABLE; 00361 sFilterConfig.BankNumber = 0; // Selects the start bank filter 00362 return HAL_CAN_ConfigFilter(&_canHandle, &sFilterConfig); 00363 } 00364 00365 /** 00366 * @brief 00367 * @note 00368 * @param 00369 * @retval 00370 */ 00371 void can_reset(can_t* obj) { 00372 __HAL_CAN_RESET_HANDLE_STATE(&_canHandle); 00373 } 00374 00375 /** 00376 * @brief 00377 * @note 00378 * @param 00379 * @retval 00380 */ 00381 unsigned char can_rderror(can_t* obj) { 00382 return HAL_CAN_GetError(&_canHandle); 00383 } 00384 00385 /** 00386 * @brief 00387 * @note 00388 * @param 00389 * @retval 00390 */ 00391 unsigned char can_tderror(can_t* obj) { 00392 return HAL_CAN_GetError(&_canHandle); 00393 } 00394 00395 /** 00396 * @brief 00397 * @note 00398 * @param 00399 * @retval 00400 */ 00401 void can_monitor(can_t* obj, int silent) { 00402 00403 // not implemented 00404 } 00405 00406 00407 00408 00409
Generated on Tue Jul 12 2022 20:03:31 by 1.7.2