Example #1
0
uint32_t can_rx(CanRxMsgTypeDef *rx_msg, uint32_t timeout) {
    uint32_t status;

    hcan.pRxMsg = rx_msg;

    status = HAL_CAN_Receive(&hcan, CAN_FIFO0, timeout);

    return status;
}
Example #2
0
// Receive message from the CAN bus (blocking)
uint32_t can_rx(CanRxMsgTypeDef *rx_msg, uint32_t timeout) 
{
    uint32_t status;

    can_handle.pRxMsg = rx_msg;

    status = HAL_CAN_Receive(&can_handle, CAN_FIFO0, timeout);

	led_blue_on();
    return status;
}
Example #3
0
int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration----------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

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

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_CAN_Init();
  MX_USART1_UART_Init();

  /* USER CODE BEGIN 2 */
  setup_can_filter();

  for (int i = 0; i < 10; ++i)
  {
	  led_blink();
	  HAL_Delay(100);
  }

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  CanRxMsgTypeDef rx_msg;
  uint8_t prebuf[12];
  uint8_t uart_msg[18];

  while (1)
  {
	  //

	  while (__HAL_CAN_MSG_PENDING(&hcan, CAN_FIFO0) <= 0) ;

	  hcan.pRxMsg = &rx_msg;
	  if (HAL_OK != HAL_CAN_Receive(&hcan, CAN_FIFO0, 3))
		  continue;

	  //

	  uint8_t flags = rx_msg.DLC & 0xf;

	  if (rx_msg.RTR == CAN_RTR_REMOTE)
		  flags |= 0x10;

	  if (rx_msg.IDE == CAN_ID_EXT)
		  flags |= 0x20;

	  uint32_t id = (rx_msg.IDE == CAN_ID_EXT ? rx_msg.ExtId : rx_msg.StdId);

	  for (int i = 3; i >= 0; --i)
	  {
		  prebuf[i] = (id & 0xff);
		  id >>= 8;
	  }

	  for (int i = 4; i < 12; ++i)
		  prebuf[i] = 0;

	  for (int i = 0; i < 8 && i < rx_msg.DLC; ++i)
		  prebuf[4+i] = rx_msg.Data[i];

	  //

	  int j = 0;
	  for (int i = 0; i < 12; i += 3, j += 4)
	  {
		  uint32_t triple = 0;
		  for (int k = 0; k < 3; ++k)
		  {
			  triple <<= 8;
			  triple += prebuf[i+k];
		  }

		  for (int k = 0; k < 4; ++k)
		  {
			  uart_msg[j+3-k] = basis_64[triple & 63];
			  triple >>= 6;
		  }

	  }

	  uart_msg[16] = basis_64[flags];
	  uart_msg[17] = '\n';

	  //

	  HAL_UART_Transmit(&huart1, uart_msg, 18, 1000);

	  //

	  led_blink();

  /* USER CODE END WHILE */

  /* USER CODE BEGIN 3 */

  }
  /* USER CODE END 3 */

}
Example #4
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 #5
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 */
}