Working fork to test F0 application

Dependents:   ppCANOpen_Example

Fork of CANnucleo by Zoltan Hudak

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers stm32f3xx_hal_msp.c Source File

stm32f3xx_hal_msp.c

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