pub

Fork of CANnucleo by Zoltan Hudak

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers stm32f0xx_hal_msp.c Source File

stm32f0xx_hal_msp.c

Go to the documentation of this file.
00001  /**
00002   ******************************************************************************
00003   * @file    stm32f0xx_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_F072RB) || \
00042     defined(TARGET_NUCLEO_F091RC)
00043 
00044 #include "cannucleo_api.h"
00045 #include "pinmap.h"
00046 
00047 CAN_HandleTypeDef   _canHandle;
00048 CanRxMsgTypeDef     _canRxMsg;
00049 CanTxMsgTypeDef     _canTxMsg;
00050 PinName             _rxPin;
00051 PinName             _txPin;
00052 
00053 void (*rxCompleteCallback)(void);
00054 
00055 /**
00056   * @brief  CAN initialization.
00057   * @param  obj: can_t object
00058   * @param  rxPin: RX pin name
00059   * @param  txPin: TX pin name
00060   * @param  abom: Automatic recovery from bus-off state
00061   * @retval None
00062   */
00063 void initCAN(PinName rxPin, PinName txPin, FunctionalState abom) {
00064     _rxPin = rxPin;
00065     _txPin = txPin;
00066 
00067     _canHandle.Instance = ((CAN_TypeDef*)CAN_BASE);
00068     _canHandle.pTxMsg = &_canTxMsg;
00069     _canHandle.pRxMsg = &_canRxMsg;
00070 
00071     _canHandle.Init.TTCM = DISABLE;
00072     _canHandle.Init.ABOM = abom;
00073     _canHandle.Init.AWUM = DISABLE;
00074     _canHandle.Init.NART = DISABLE;
00075     _canHandle.Init.RFLM = DISABLE;
00076     _canHandle.Init.TXFP = DISABLE;
00077     _canHandle.Init.Mode = CAN_MODE_NORMAL;
00078 
00079     // 125kbps bit rate (default)
00080     // APB1 peripheral clock = 48000000Hz
00081     _canHandle.Init.Prescaler = 24;     // number of time quanta = 48000000/24/125000 = 16
00082     _canHandle.Init.SJW = CAN_SJW_1TQ;
00083     _canHandle.Init.BS1 = CAN_BS1_11TQ; // sample point at: (1 + 11) / 16 * 100 = 75%
00084     _canHandle.Init.BS2 = CAN_BS2_4TQ;
00085 
00086     HAL_CAN_Init(&_canHandle);
00087 }
00088 
00089 /**
00090   * @brief  CAN MSP Initialization
00091   * @param  hcan: CAN handle pointer
00092   * @retval None
00093   */
00094 void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan) {
00095     GPIO_InitTypeDef    GPIO_InitStruct;
00096 
00097     if((_rxPin == PA_11) && (_txPin == PA_12)) {
00098 
00099         /* CAN1 Periph clock enable */
00100         __CAN_CLK_ENABLE();
00101 
00102         /* Enable GPIO clock */
00103         __GPIOA_CLK_ENABLE();
00104 
00105         /* CAN1 RX GPIO pin configuration */
00106         GPIO_InitStruct.Pin = GPIO_PIN_11;
00107         GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
00108         GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
00109         GPIO_InitStruct.Pull = GPIO_NOPULL;
00110         GPIO_InitStruct.Alternate =  GPIO_AF4_CAN;
00111         HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
00112         
00113         /* CAN1 TX GPIO pin configuration */
00114         GPIO_InitStruct.Pin = GPIO_PIN_12;
00115         GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
00116         GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
00117         GPIO_InitStruct.Pull = GPIO_NOPULL;
00118         GPIO_InitStruct.Alternate =  GPIO_AF4_CAN;
00119         HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
00120     }
00121     else
00122     if((_rxPin == PB_8) && (_txPin == PB_9)) {
00123         /* CAN1 Periph clock enable */
00124         __CAN_CLK_ENABLE();
00125 
00126         /* Enable GPIO clock */
00127         __GPIOB_CLK_ENABLE();
00128 
00129         /* CAN1 RX GPIO pin configuration */
00130         GPIO_InitStruct.Pin = GPIO_PIN_8;
00131         GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
00132         GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
00133         GPIO_InitStruct.Pull = GPIO_NOPULL;
00134         GPIO_InitStruct.Alternate =  GPIO_AF4_CAN;
00135         HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
00136         
00137         /* CAN1 TX GPIO pin configuration */
00138         GPIO_InitStruct.Pin = GPIO_PIN_9;
00139         GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
00140         GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
00141         GPIO_InitStruct.Pull = GPIO_NOPULL;
00142         GPIO_InitStruct.Alternate =  GPIO_AF4_CAN;
00143         HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
00144     }
00145     else
00146         return;
00147     /* NVIC configuration for CAN1 Reception complete interrupt */
00148     HAL_NVIC_SetPriority(CAN_IRQ, 1, 0);
00149     HAL_NVIC_EnableIRQ(CAN_IRQ);
00150 }
00151 
00152 /**
00153   * @brief CAN MSP De-Initialization
00154   *        This function frees the hardware resources used:
00155   *          - Disable the Peripheral's clock
00156   *          - Revert GPIO to their default state
00157   * @param hcan: CAN handle pointer
00158   * @retval None
00159   */
00160 void HAL_CAN_MspDeInit(CAN_HandleTypeDef* hcan) {
00161 
00162     /* Reset peripherals */
00163 
00164     __CAN_FORCE_RESET();
00165     __CAN_RELEASE_RESET();
00166 
00167     /* Disable peripherals and GPIO Clocks */
00168     if((_rxPin == PA_11) && (_txPin == PA_12)) {
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 RX 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 
00185     /* Disable the NVIC for CAN reception */
00186     HAL_NVIC_DisableIRQ(CAN_IRQ);
00187 }
00188 
00189 /**
00190 * @brief  Handles CAN RX interrupt request.
00191 * @param  None
00192 * @retval None
00193 */
00194 void CEC_CAN_IRQHandler(void) {
00195     HAL_CAN_IRQHandler(&_canHandle);
00196 }
00197 
00198 /**
00199   * @brief  Reception  complete callback in non blocking mode
00200   * @param  _canHandle: pointer to a CAN_HandleTypeDef structure that contains
00201   *         the configuration information for the specified CAN.
00202   * @retval None
00203   */
00204 void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* _canHandle) {
00205     // if(HAL_CAN_Receive_IT(_canHandle, CAN_FIFO0) == HAL_OK) {
00206     //     if(rxCompleteCallback != NULL)
00207     //         rxCompleteCallback();
00208     // }
00209     // else {
00210     //     error_handler(error);
00211     // }
00212 
00213     // BUG: CAN race condition if HAL_CAN_Receive_IT() is used.
00214     // 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
00215     //
00216     // Fixed by Mark Burton:
00217     // ideally, we should be able to call HAL_CAN_Receive_IT() here to set up for another
00218     // receive but the API is flawed because that function will fail if HAL_CAN_Transmit()
00219     // had already locked the handle when the receive interrupt occurred - so we do what
00220     // HAL_CAN_Receive_IT() would do
00221 
00222     if (rxCompleteCallback != 0)
00223         rxCompleteCallback();
00224 
00225     if (_canHandle->State == HAL_CAN_STATE_BUSY_TX)
00226         _canHandle->State = HAL_CAN_STATE_BUSY_TX_RX;
00227     else {
00228         _canHandle->State = HAL_CAN_STATE_BUSY_RX;
00229 
00230         /* Set CAN error code to none */
00231         _canHandle->ErrorCode = HAL_CAN_ERROR_NONE;
00232 
00233         /* Enable Error warning Interrupt */
00234         __HAL_CAN_ENABLE_IT(_canHandle, CAN_IT_EWG);
00235 
00236         /* Enable Error passive Interrupt */
00237         __HAL_CAN_ENABLE_IT(_canHandle, CAN_IT_EPV);
00238 
00239         /* Enable Bus-off Interrupt */
00240         __HAL_CAN_ENABLE_IT(_canHandle, CAN_IT_BOF);
00241 
00242         /* Enable Last error code Interrupt */
00243         __HAL_CAN_ENABLE_IT(_canHandle, CAN_IT_LEC);
00244 
00245         /* Enable Error Interrupt */
00246         __HAL_CAN_ENABLE_IT(_canHandle, CAN_IT_ERR);
00247     }
00248 
00249     // Enable FIFO 0 message pending Interrupt
00250     __HAL_CAN_ENABLE_IT(_canHandle, CAN_IT_FMP0);
00251 }
00252 #endif
00253 
00254 
00255