Example #1
0
uint32_t can_tx(CanTxMsgTypeDef *tx_msg, uint32_t timeout) {
    uint32_t status;

    // transmit can frame
    hcan.pTxMsg = tx_msg;
    status = HAL_CAN_Transmit(&hcan, timeout);

    return status;
}
Example #2
0
// Send a message on the CAN bus (blocking)
uint32_t can_tx(CanTxMsgTypeDef *tx_msg)
{
    uint32_t status;

    // Transmit can frame
    can_handle.pTxMsg = tx_msg;
    status = HAL_CAN_Transmit(&can_handle, 10);
    led_green_on();

    return status;
}
Example #3
0
File: main.c Project: thiemar/mucan
int __start(void) {
    const volatile uint32_t *src;
    volatile uint32_t *dest;

    /* Set up BSS and copy data from flash */
    for (src = &_eronly, dest = &_sdata; dest < &_edata;) {
        *dest++ = *src++;
    }

    for (dest = &_sbss; dest < &_ebss;) {
        *dest++ = 0;
    }

    SystemInit();
    HAL_Init();

    /* Configure the system clock */
    SystemClock_Config();

    /*
    Make sure the flash option bytes are set such that we don't re-enter
    bootloader mode
    */
    set_dfu_option_bytes(0u);

    MX_USB_DEVICE_Init();

    /* Configure GPIO for the CAN_SILENT signal */
    GPIO_InitTypeDef GPIO_InitStruct;

    /* GPIO Ports Clock Enable */
    __GPIOA_CLK_ENABLE();
    __GPIOB_CLK_ENABLE();
    __CRS_CLK_ENABLE();

    /*Configure GPIO pin : PB7 */
    GPIO_InitStruct.Pin = GPIO_PIN_7;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_PULLDOWN;
    GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    /**CAN GPIO Configuration
    PB8     ------> CAN_RX
    PB9     ------> CAN_TX
    */
    GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF4_CAN;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    /* Configure the bxCAN transceiver */
    CAN_HandleTypeDef hcan;

    __CAN_CLK_ENABLE();

    hcan.Instance = CAN;
    hcan.Init.Mode = CAN_MODE_SILENT;
    hcan.Init.TTCM = DISABLE;
    hcan.Init.ABOM = ENABLE;
    hcan.Init.AWUM = ENABLE;
    hcan.Init.NART = DISABLE;
    hcan.Init.RFLM = DISABLE;
    hcan.Init.TXFP = DISABLE;

    /* Set the bitrate and init */
    set_can_bitrate(&hcan, 1000000u);

    CanRxMsgTypeDef rx_msg;
    hcan.pRxMsg = &rx_msg;

    CanTxMsgTypeDef tx_msg;
    hcan.pTxMsg = &tx_msg;

    CAN_FilterConfTypeDef filter;
    filter.FilterNumber = 0;
    filter.FilterMode = CAN_FILTERMODE_IDMASK;
    filter.FilterScale = CAN_FILTERSCALE_32BIT;
    filter.FilterFIFOAssignment = CAN_FILTER_FIFO0;
    filter.FilterActivation = ENABLE;
    filter.BankNumber = 0;
    filter.FilterMaskIdLow = filter.FilterIdLow = filter.FilterMaskIdHigh =
        filter.FilterIdHigh = 0;
    HAL_CAN_ConfigFilter(&hcan, &filter);

    __HAL_UNLOCK(&hcan);

    /*
    Now that USB is active, we need to sync with the 1 kHz SOF packets to
    tune the HSI48 so it's accurate enough not to disrupt the CAN bus.
    */
    RCC_CRSInitTypeDef crs_config;
    crs_config.Prescaler = RCC_CRS_SYNC_DIV1;
    crs_config.Source = RCC_CRS_SYNC_SOURCE_USB;
    crs_config.Polarity = RCC_CRS_SYNC_POLARITY_RISING;
    crs_config.ReloadValue = RCC_CRS_RELOADVALUE_DEFAULT;
    crs_config.ErrorLimitValue = RCC_CRS_ERRORLIMIT_DEFAULT;
    crs_config.HSI48CalibrationValue = RCC_CRS_HSI48CALIBRATION_DEFAULT;

    HAL_RCCEx_CRSConfig(&crs_config);

    /* Don't continue unless we're synced */
    while (!(HAL_RCCEx_CRSWaitSynchronization(1000000u) & RCC_CRS_SYNCOK));

    while (1) {
        /* Set up the command record */
        size_t i;
        uint8_t current_cmd;
        uint8_t current_cmd_data[32];
        uint8_t current_cmd_data_length;
        uint8_t channel_open;

        current_cmd = current_cmd_data_length = i = 0;
        channel_open = 0;
        rx_buffer_length = 0;

        while (hUsbDevice_0 && hUsbDevice_0->pClassData) {
            /*
            If the RX buffer is non-empty, process any commands/messages in it
            and then acknowledge the transfer to the USB stack
            */
            if (rx_buffer_length) {
                /*
                Exit if we've read the entire buffer, or if transmit mailboxes
                are full and the current command is a transmit.
                */
                for (; i < rx_buffer_length &&
                        ((current_cmd != 't' && current_cmd != 'T') ||
                         __HAL_CAN_GET_FLAG(&hcan, CAN_FLAG_TME0)); i++) {
                    if (rx_buffer[i] == '\r') {
                        uint8_t *buf = active_buffer ? tx_buffer_1 :
                                                       tx_buffer_0;

                        /* End of command -- process and reset state */
                        switch (current_cmd) {
                            case 'S':
                                /*
                                Setup bitrate -- data should be a number from
                                0 to 8.
                                */
                                if (current_cmd_data[0] < '0' ||
                                        current_cmd_data[0] > '8') {
                                    buf[active_buffer_length++] = '\a';
                                } else if (set_can_bitrate(
                                        &hcan,
                                        bitrate_lookup[current_cmd_data[0] - '0'])) {
                                    buf[active_buffer_length++] = '\r';
                                } else {
                                    buf[active_buffer_length++] = '\a';
                                }
                                break;
                            case 'O':
                                /*
                                Open channel -- take CAN out of silent mode
                                and start receiving.
                                */
                                if (!channel_open) {
                                    channel_open = 1;
                                    set_can_silent(&hcan, 0);
                                    buf[active_buffer_length++] = '\r';
                                } else {
                                    buf[active_buffer_length++] = '\a';
                                }
                                break;
                            case 'L':
                                /*
                                Open in listen-only -- CAN should already be
                                in silent mode but just make sure.
                                */
                                if (!channel_open) {
                                    channel_open = 1;
                                    set_can_silent(&hcan, 1);
                                    buf[active_buffer_length++] = '\r';
                                } else {
                                    buf[active_buffer_length++] = '\a';
                                }
                                break;
                            case 'C':
                                /*
                                Close channel -- put CAN back in silent mode.
                                */
                                if (channel_open) {
                                    channel_open = 0;
                                    set_can_silent(&hcan, 1);
                                    buf[active_buffer_length++] = '\r';
                                } else {
                                    buf[active_buffer_length++] = '\a';
                                }
                                break;
                            case 'V':
                                /* Hardware version */
                                buf[active_buffer_length++] = 'V';
                                buf[active_buffer_length++] = '0';
                                buf[active_buffer_length++] = '0';
                                buf[active_buffer_length++] = '0';
                                buf[active_buffer_length++] = '1';
                                buf[active_buffer_length++] = '\r';
                                break;
                            case 'v':
                                /* Major/minor version */
                                buf[active_buffer_length++] = 'v';
                                buf[active_buffer_length++] = '0';
                                buf[active_buffer_length++] = '0';
                                buf[active_buffer_length++] = '0';
                                buf[active_buffer_length++] = '1';
                                buf[active_buffer_length++] = '\r';
                                break;
                            case 'N':
                                /* Serial number */
                                buf[active_buffer_length++] = 'N';
                                buf[active_buffer_length++] = 'F';
                                buf[active_buffer_length++] = 'F';
                                buf[active_buffer_length++] = 'F';
                                buf[active_buffer_length++] = 'F';
                                buf[active_buffer_length++] = '\r';
                                break;
                            case 'T':
                                /* Extended message */
                                if (read_ext_message(&tx_msg, current_cmd_data,
                                                     current_cmd_data_length) &&
                                        HAL_CAN_Transmit(&hcan, 0) == HAL_OK) {
                                    buf[active_buffer_length++] = '\r';
                                } else {
                                    buf[active_buffer_length++] = '\a';
                                }
                                break;
                            case 't':
                                /* Standard message */
                                if (read_std_message(&tx_msg, current_cmd_data,
                                                     current_cmd_data_length) &&
                                        HAL_CAN_Transmit(&hcan, 0) == HAL_OK) {
                                    buf[active_buffer_length++] = '\r';
                                } else {
                                    buf[active_buffer_length++] = '\a';
                                }
                                break;
                            case 'R':
                                /* Extended RTR */
                                if (read_ext_rtr(&tx_msg, current_cmd_data,
                                                 current_cmd_data_length) &&
                                        HAL_CAN_Transmit(&hcan, 0) == HAL_OK) {
                                    buf[active_buffer_length++] = '\r';
                                } else {
                                    buf[active_buffer_length++] = '\a';
                                }
                                break;
                            case 'r':
                                /* Standard RTR */
                                if (read_std_rtr(&tx_msg, current_cmd_data,
                                                 current_cmd_data_length) &&
                                        HAL_CAN_Transmit(&hcan, 0) == HAL_OK) {
                                    buf[active_buffer_length++] = '\r';
                                } else {
                                    buf[active_buffer_length++] = '\a';
                                }
                                break;
                            case '_':
                                /* Bootloader request */
                                if (current_cmd_data[0] == '_' &&
                                        current_cmd_data[1] == 'd' &&
                                        current_cmd_data[2] == 'f' &&
                                        current_cmd_data[3] == 'u') {
                                    /*
                                    Set option bytes to force bootloader entry
                                    */
                                    set_dfu_option_bytes(1u);

                                    NVIC_SystemReset();
                                } else {
                                    buf[active_buffer_length++] = '\a';
                                }
                                break;
                            case 'F':
                                /* Read status flags -- return 4 hex digits */
                            case 'Z':
                                /* Timestamp on/off -- 0=off, 1=on */
                            case 'M':
                                /* Acceptance mask -- 8 hex digits */
                            case 'm':
                                /* Acceptance value -- 8 hex digits */
                            case 's':
                                /* Set bitrate register -- 6 hex digits */
                            default:
                                /* NACK */
                                buf[active_buffer_length++] = '\a';
                                break;
                        }

                        current_cmd = current_cmd_data_length = 0;
                    } else if (current_cmd) {
                        /* Command data -- save it */
                        current_cmd_data[current_cmd_data_length++] =
                            rx_buffer[i];

                        /* Reset command state if the data is too long */
                        if (current_cmd_data_length == 32u) {
                            current_cmd = current_cmd_data_length = 0;
                        }
                    } else {
                        /*
                        The first letter of a line is the command type --
                        don't bother validating as we can't NACK until the
                        data has been received.
                        */
                        current_cmd = rx_buffer[i];
                    }
                }

                if (i == rx_buffer_length) {
                    /* Mark last packet as received */
                    rx_buffer_length = i = 0;
                    USBD_CDC_ReceivePacket(hUsbDevice_0);
                }
            }

            /*
            Check the CAN controller for messages and process them if the
            channel is open
            */
            if (HAL_CAN_Receive(&hcan, CAN_FIFO0, 0) == HAL_OK && hUsbDevice_0 &&
                    channel_open) {
                /*
                Format the message and send it to the host.

                The data format for a standard ID message is:
                tiiildddddddddddddddd\r

                The data format for a standard ID RTR is:
                riii\r

                The data format for an extended ID message is:
                Tiiiiiiiildddddddddddddddd\r

                The data format for an extended ID RTR is:
                Riiiiiiii\r
                */
                uint8_t *write_location;

                if (active_buffer_length + EXT_MESSAGE_LEN > TX_BUFFER_SIZE) {
                    /*
                    Reset buffer if we're too far behind -- use worst-case
                    message length for calculation
                    */
                    active_buffer_length = 0;
                }

                write_location = &((active_buffer ? tx_buffer_1 : tx_buffer_0)[active_buffer_length]);

                if (rx_msg.IDE == CAN_ID_EXT && rx_msg.RTR) {
                    active_buffer_length += write_ext_rtr(
                        write_location, &rx_msg);
                } else if (rx_msg.IDE == CAN_ID_EXT && !rx_msg.RTR) {
                    active_buffer_length += write_ext_message(
                        write_location, &rx_msg);
                } else if (rx_msg.IDE == CAN_ID_STD && rx_msg.RTR) {
                    active_buffer_length += write_std_rtr(
                        write_location, &rx_msg);
                } else if (rx_msg.IDE == CAN_ID_STD && !rx_msg.RTR) {
                    active_buffer_length += write_std_message(
                        write_location, &rx_msg);
                }
            }

            if (!hUsbDevice_0 || !hUsbDevice_0->pClassData) {
                /* Reset TX buffer if USB is not connected */
                active_buffer_length = 0;
            } else if (active_buffer_length &&
                        ((USBD_CDC_HandleTypeDef*)hUsbDevice_0->pClassData)->TxState == 0) {
                /* Transmit the next buffer if one is available */
                CDC_Transmit_FS(active_buffer ? tx_buffer_1 : tx_buffer_0,
                                active_buffer_length);
                active_buffer_length = 0;
                active_buffer = active_buffer ? 0 : 1;
            }
        }
    }
}
Example #4
0
/**
  * @brief  Configures the CAN, transmit and receive by polling
  * @param  None
  * @retval PASSED if the reception is well done, FAILED in other case
  */
HAL_StatusTypeDef CAN_Polling(void)
{
  CAN_FilterConfTypeDef  sFilterConfig;
  static CanTxMsgTypeDef        TxMessage;
  static CanRxMsgTypeDef        RxMessage;

  /*##-1- Configure the CAN peripheral #######################################*/
  CanHandle.Instance = CANx;
  CanHandle.pTxMsg = &TxMessage;
  CanHandle.pRxMsg = &RxMessage;

  CanHandle.Init.TTCM = DISABLE;
  CanHandle.Init.ABOM = DISABLE;
  CanHandle.Init.AWUM = DISABLE;
  CanHandle.Init.NART = DISABLE;
  CanHandle.Init.RFLM = DISABLE;
  CanHandle.Init.TXFP = DISABLE;
  CanHandle.Init.Mode = CAN_MODE_LOOPBACK;
  CanHandle.Init.SJW = CAN_SJW_1TQ;
  CanHandle.Init.BS1 = CAN_BS1_6TQ;
  CanHandle.Init.BS2 = CAN_BS2_8TQ;
  CanHandle.Init.Prescaler = 2;

  if(HAL_CAN_Init(&CanHandle) != HAL_OK)
  {
    /* Initialization Error */
    Error_Handler();
  }

  /*##-2- Configure the CAN Filter ###########################################*/
  sFilterConfig.FilterNumber = 0;
  sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
  sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
  sFilterConfig.FilterIdHigh = 0x0000;
  sFilterConfig.FilterIdLow = 0x0000;
  sFilterConfig.FilterMaskIdHigh = 0x0000;
  sFilterConfig.FilterMaskIdLow = 0x0000;
  sFilterConfig.FilterFIFOAssignment = 0;
  sFilterConfig.FilterActivation = ENABLE;
  sFilterConfig.BankNumber = 14;

  if(HAL_CAN_ConfigFilter(&CanHandle, &sFilterConfig) != HAL_OK)
  {
    /* Filter configuration Error */
    Error_Handler();
  }

  /*##-3- Start the Transmission process #####################################*/
  CanHandle.pTxMsg->StdId = 0x11;
  CanHandle.pTxMsg->RTR = CAN_RTR_DATA;
  CanHandle.pTxMsg->IDE = CAN_ID_STD;
  CanHandle.pTxMsg->DLC = 2;
  CanHandle.pTxMsg->Data[0] = 0xCA;
  CanHandle.pTxMsg->Data[1] = 0xFE;

  if(HAL_CAN_Transmit(&CanHandle, 10) != HAL_OK)
  {
    /* Transmition Error */
    Error_Handler();
  }

  if(HAL_CAN_GetState(&CanHandle) != HAL_CAN_STATE_READY)
  {
    return HAL_ERROR;
  }

  /*##-4- Start the Reception process ########################################*/
  if(HAL_CAN_Receive(&CanHandle, CAN_FIFO0,10) != HAL_OK)
  {
    /* Reception Error */
    Error_Handler();
  }

  if(HAL_CAN_GetState(&CanHandle) != HAL_CAN_STATE_READY)
  {
    return HAL_ERROR;
  }

  if(CanHandle.pRxMsg->StdId != 0x11)
  {
    return HAL_ERROR;
  }

  if(CanHandle.pRxMsg->IDE != CAN_ID_STD)
  {
    return HAL_ERROR;
  }

  if(CanHandle.pRxMsg->DLC != 2)
  {
    return HAL_ERROR;
  }

  if((CanHandle.pRxMsg->Data[0]<<8|RxMessage.Data[1]) != 0xCAFE)
  {
    return HAL_ERROR;
  }

  return HAL_OK; /* Test Passed */
}
Example #5
0
/**
  * @brief  Main program.
  * @param  None
  * @retval None
  */
int main(void)
{
  /* Enable the CPU Cache */
  CPU_CACHE_Enable();

  /* STM32F7xx HAL library initialization:
       - Configure the Flash ART accelerator on ITCM interface
       - Systick timer is configured by default as source of time base, but user 
         can eventually implement his proper time base source (a general purpose 
         timer for example or other time source), keeping in mind that Time base 
         duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and 
         handled in milliseconds basis.
       - Set NVIC Group Priority to 4
       - Low Level Initialization
     */
  HAL_Init();


  /* Configure the system clock to 216 MHz */
  SystemClock_Config();

  /* Since MFX is used, LED init is done after clock config */
  /* Configure LED1, LED2, LED3 and LED4 */
  BSP_LED_Init(LED1);
  BSP_LED_Init(LED2);
  BSP_LED_Init(LED3);
  BSP_LED_Init(LED4);
  
  /* Configure Tamper push-button */
  BSP_PB_Init(BUTTON_TAMPER, BUTTON_MODE_GPIO);

  /*##-1- Configure the CAN peripheral #######################################*/
  CAN_Config();

  /*##-2- Start the Reception process and enable reception interrupt #########*/
  if (HAL_CAN_Receive_IT(&CanHandle, CAN_FIFO0) != HAL_OK)
  {
    /* Reception Error */
    Error_Handler();
  }

  /* Infinite loop */
  while (1)
  {
    while (BSP_PB_GetState(BUTTON_TAMPER) == KEY_PRESSED)
    {
      if (ubKeyNumber == 0x4)
      {
        ubKeyNumber = 0x00;
      }
      else
      {
        LED_Display(++ubKeyNumber);
        
        /* Set the data to be transmitted */
        CanHandle.pTxMsg->Data[0] = ubKeyNumber;
        CanHandle.pTxMsg->Data[1] = 0xAD;
        
        /*##-3- Start the Transmission process ###############################*/
        if (HAL_CAN_Transmit(&CanHandle, 10) != HAL_OK)
        {
          /* Transmission Error */
          Error_Handler();
        }
        HAL_Delay(10);
        
        while (BSP_PB_GetState(BUTTON_TAMPER) != KEY_NOT_PRESSED)
        {
        }
      }
    }
  }
}
Example #6
0
/**
  * @brief  Main program
  * @param  None
  * @retval None
  */
int main(void)
{
  /* STM32F4xx HAL library initialization:
       - Configure the Flash prefetch, instruction and Data caches
       - Configure the Systick to generate an interrupt each 1 msec
       - Set NVIC Group Priority to 4
       - Global MSP (MCU Support Package) initialization
     */
  HAL_Init();
  
  /* Configure the system clock to 180 MHz */
  SystemClock_Config();
  
  /* Configure LED1, LED2, LED3 and LED4 */
  BSP_LED_Init(LED1);
  BSP_LED_Init(LED2);
  BSP_LED_Init(LED3);
  BSP_LED_Init(LED4);
  
  /* Configure Key Button */ 
  BSP_PB_Init(BUTTON_KEY, BUTTON_MODE_GPIO);
  
  /*##-1- Configure the CAN peripheral #######################################*/
  CAN_Config();
  
  /*##-2- Start the Reception process and enable reception interrupt #########*/
  if(HAL_CAN_Receive_IT(&CanHandle, CAN_FIFO0) != HAL_OK)
  {
    /* Reception Error */
    Error_Handler();
  }
  
  /* Infinite loop */
  while(1)
  {
    while(BSP_PB_GetState(BUTTON_KEY) == KEY_PRESSED)
    {
      if(ubKeyNumber == 0x4) 
      {
        ubKeyNumber = 0x00;
      }
      else
      {
        LED_Display(++ubKeyNumber);
        
        /* Set the data to be transmitted */
        CanHandle.pTxMsg->Data[0] = ubKeyNumber;
        CanHandle.pTxMsg->Data[1] = 0xAD;
        
        /*##-3- Start the Transmission process ###############################*/
        if(HAL_CAN_Transmit(&CanHandle, 10) != HAL_OK)
        {
          /* Transmition Error */
          Error_Handler();
        }
        HAL_Delay(10);
        
        while(BSP_PB_GetState(BUTTON_KEY) != KEY_NOT_PRESSED)
        {
        }
      }
    }
  } 
}