Controller Area Network library for NUCLEO boards equipped with CAN peripheral.

Dependents:   Nucleo-Courtois CANBLE CANnucleo_Hello3 Nucleo_Serialprintf ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers stm32f1xx_hal_msp.c Source File

stm32f1xx_hal_msp.c

Go to the documentation of this file.
00001  /**
00002   ******************************************************************************
00003   * @file    stm32f1xx_hal_msp.c
00004   * @author  MCD Application Team
00005   * @version V1.0.0
00006   * @date    17-December-2014
00007   * @brief   HAL MSP module.
00008   ******************************************************************************
00009   * @attention
00010   *
00011   * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
00012   *
00013   * Redistribution and use in source and binary forms, with or without modification,
00014   * are permitted provided that the following conditions are met:
00015   *   1. Redistributions of source code must retain the above copyright notice,
00016   *      this list of conditions and the following disclaimer.
00017   *   2. Redistributions in binary form must reproduce the above copyright notice,
00018   *      this list of conditions and the following disclaimer in the documentation
00019   *      and/or other materials provided with the distribution.
00020   *   3. Neither the name of STMicroelectronics nor the names of its contributors
00021   *      may be used to endorse or promote products derived from this software
00022   *      without specific prior written permission.
00023   *
00024   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00025   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00026   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00027   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00028   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00029   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00030   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00031   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00032   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00033   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00034   *
00035   ******************************************************************************
00036   *
00037   * Modified by Zoltan Hudak    <hudakz@outlook.com>
00038   *
00039   ******************************************************************************
00040   */
00041 #if defined(TARGET_NUCLEO_F103RB)
00042 
00043 #include "cannucleo_api.h"
00044 #include "pinmap.h"
00045 
00046 CAN_HandleTypeDef   _canHandle;
00047 CanRxMsgTypeDef     _canRxMsg;
00048 CanTxMsgTypeDef     _canTxMsg;
00049 PinName             _rxPin;
00050 PinName             _txPin;
00051 
00052 void (*rxCompleteCallback)(void);
00053 
00054 /**
00055   * @brief  CAN initialization.
00056   * @param  obj: can_t object
00057   * @param  rxPin: RX pin name
00058   * @param  txPin: TX pin name
00059   * @param  abom: Automatic recovery from bus-off state
00060   * @retval None
00061   */
00062 void initCAN(PinName rxPin, PinName txPin, FunctionalState abom) {
00063     _rxPin = rxPin;
00064     _txPin = txPin;
00065 
00066     _canHandle.Instance = ((CAN_TypeDef*)CAN1_BASE);
00067     _canHandle.pTxMsg = &_canTxMsg;
00068     _canHandle.pRxMsg = &_canRxMsg;
00069 
00070     _canHandle.Init.TTCM = DISABLE;
00071     _canHandle.Init.ABOM = abom;
00072     _canHandle.Init.AWUM = DISABLE;
00073     _canHandle.Init.NART = DISABLE;
00074     _canHandle.Init.RFLM = DISABLE;
00075     _canHandle.Init.TXFP = DISABLE;
00076     _canHandle.Init.Mode = CAN_MODE_NORMAL;
00077 
00078     // 125kbps bit rate (default)
00079     // APB1 peripheral clock = 36000000Hz
00080     _canHandle.Init.Prescaler = 18;      // number of time quanta = 36000000/18/125000 = 16
00081     _canHandle.Init.SJW = CAN_SJW_1TQ;
00082     _canHandle.Init.BS1 = CAN_BS1_11TQ;  // sample point at (1 + 11) / 16 * 100 = 75%
00083     _canHandle.Init.BS2 = CAN_BS2_4TQ;
00084 
00085     HAL_CAN_Init(&_canHandle);
00086 }
00087 
00088 /**
00089   * @brief  CAN MSP Initialization
00090   * @param  hcan: CAN handle pointer
00091   * @retval None
00092   */
00093 void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan) {
00094     GPIO_InitTypeDef    GPIO_InitStruct;
00095 
00096     if((_rxPin == PA_11) && (_txPin == PA_12)) {
00097 
00098         /* CAN1 Periph clock enable */
00099         __HAL_RCC_CAN1_CLK_ENABLE();
00100 
00101         /* Enable GPIO clock */
00102         __HAL_RCC_GPIOA_CLK_ENABLE();
00103 
00104         /* Enable AFIO clock and remap CAN PINs to PA11 and PA12*/
00105         __HAL_RCC_AFIO_CLK_ENABLE();
00106         __HAL_AFIO_REMAP_CAN1_1();
00107 
00108         /* CAN1 RX GPIO pin configuration */
00109         GPIO_InitStruct.Pin = GPIO_PIN_11;
00110         GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
00111         GPIO_InitStruct.Pull = GPIO_NOPULL;
00112         HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
00113 
00114         GPIO_InitStruct.Pin = GPIO_PIN_12;
00115         GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
00116         GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
00117         HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
00118     }
00119     else
00120     if((_rxPin == PB_8) && (_txPin == PB_9)) {
00121 
00122         /* CAN1 Periph clock enable */
00123         __HAL_RCC_CAN1_CLK_ENABLE();
00124 
00125         /* Enable GPIO clock */
00126         __HAL_RCC_GPIOB_CLK_ENABLE();
00127 
00128         /* Enable AFIO clock and remap CAN PINs to PB_8 and PB_9*/
00129         __HAL_RCC_AFIO_CLK_ENABLE();
00130         __HAL_AFIO_REMAP_CAN1_2();
00131 
00132         /* CAN1 RX GPIO pin configuration */
00133         GPIO_InitStruct.Pin = GPIO_PIN_8;
00134         GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
00135         GPIO_InitStruct.Pull = GPIO_NOPULL;
00136         HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
00137 
00138         GPIO_InitStruct.Pin = GPIO_PIN_9;
00139         GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
00140         GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
00141         HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
00142     }
00143     else
00144         return;
00145 
00146     /* NVIC configuration for CAN1 Reception complete interrupt */
00147     HAL_NVIC_SetPriority(CAN_IRQ, 1, 0);
00148     HAL_NVIC_EnableIRQ(CAN_IRQ);
00149 }
00150 
00151 /**
00152   * @brief CAN MSP De-Initialization
00153   *        This function frees the hardware resources used:
00154   *          - Disable the Peripheral's clock
00155   *          - Revert GPIO to their default state
00156   * @param hcan: CAN handle pointer
00157   * @retval None
00158   */
00159 void HAL_CAN_MspDeInit(CAN_HandleTypeDef* hcan) {
00160 
00161     /* Reset peripherals */
00162 
00163     __HAL_RCC_CAN1_FORCE_RESET();
00164     __HAL_RCC_CAN1_RELEASE_RESET();
00165 
00166     /* Disable peripherals and GPIO Clocks */
00167     if((_rxPin == PA_11) && (_txPin == PA_12)) {
00168 
00169         /* De-initialize the CAN1 RX GPIO pin */
00170         HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11);
00171 
00172         /* De-initialize the CAN1 TX GPIO pin */
00173         HAL_GPIO_DeInit(GPIOA, GPIO_PIN_12);
00174     }
00175     else {
00176 
00177         /* De-initialize the CAN1 TX GPIO pin */
00178         HAL_GPIO_DeInit(GPIOB, GPIO_PIN_8);
00179 
00180         /* De-initialize the CAN1 TX GPIO pin */
00181         HAL_GPIO_DeInit(GPIOB, GPIO_PIN_9);
00182     }
00183 
00184     /* Disable the NVIC for CAN reception */
00185     HAL_NVIC_DisableIRQ(CAN_IRQ);
00186 }
00187 
00188 /**
00189 * @brief  Handles CAN1 RX0 interrupt request.
00190 * @param  None
00191 * @retval None
00192 */
00193 void USB_LP_CAN1_RX0_IRQHandler(void) {
00194     HAL_CAN_IRQHandler(&_canHandle);
00195 }
00196 
00197 /**
00198   * @brief  Reception  complete callback in non blocking mode
00199   * @param  _canHandle: pointer to a CAN_HandleTypeDef structure that contains
00200   *         the configuration information for the specified CAN.
00201   * @retval None
00202   */
00203 void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* _canHandle) {
00204     // if(HAL_CAN_Receive_IT(_canHandle, CAN_FIFO0) == HAL_OK) {
00205     //     if(rxCompleteCallback != NULL)
00206     //         rxCompleteCallback();
00207     // }
00208     // else {
00209     //     error_handler(error);
00210     // }
00211 
00212     // BUG: CAN race condition if HAL_CAN_Receive_IT() is used.
00213     // See https://my.st.com/public/STe2ecommunities/mcu/Lists/STM32Java/Flat.aspx?RootFolder=%2Fpublic%2FSTe2ecommunities%2Fmcu%2FLists%2FSTM32Java%2FBUG%20CAN%20race%20condition%20if%20HAL%5FCAN%5FReceive%5FIT%20is%20used
00214     //
00215     // Fixed by Mark Burton:
00216     // ideally, we should be able to call HAL_CAN_Receive_IT() here to set up for another
00217     // receive but the API is flawed because that function will fail if HAL_CAN_Transmit()
00218     // had already locked the handle when the receive interrupt occurred - so we do what
00219     // HAL_CAN_Receive_IT() would do
00220 
00221     if (rxCompleteCallback != NULL)
00222         rxCompleteCallback();
00223 
00224     if (_canHandle->State == HAL_CAN_STATE_BUSY_TX)
00225         _canHandle->State = HAL_CAN_STATE_BUSY_TX_RX0;
00226     else {
00227         _canHandle->State = HAL_CAN_STATE_BUSY_RX0;
00228 
00229         /* Set CAN error code to none */
00230         _canHandle->ErrorCode = HAL_CAN_ERROR_NONE;
00231 
00232         /* Enable Error warning Interrupt */
00233         __HAL_CAN_ENABLE_IT(_canHandle, CAN_IT_EWG);
00234 
00235         /* Enable Error passive Interrupt */
00236         __HAL_CAN_ENABLE_IT(_canHandle, CAN_IT_EPV);
00237 
00238         /* Enable Bus-off Interrupt */
00239         __HAL_CAN_ENABLE_IT(_canHandle, CAN_IT_BOF);
00240 
00241         /* Enable Last error code Interrupt */
00242         __HAL_CAN_ENABLE_IT(_canHandle, CAN_IT_LEC);
00243 
00244         /* Enable Error Interrupt */
00245         __HAL_CAN_ENABLE_IT(_canHandle, CAN_IT_ERR);
00246     }
00247 
00248     // Enable FIFO 0 message pending Interrupt
00249     __HAL_CAN_ENABLE_IT(_canHandle, CAN_IT_FMP0);
00250 }
00251 #endif
00252 
00253 
00254 
00255