Merge branch 'normaldotcom-master'
This commit is contained in:
commit
fdfd6d1848
|
@ -22,6 +22,9 @@ void can_init(void);
|
|||
void can_enable(void);
|
||||
void can_disable(void);
|
||||
void can_set_bitrate(enum can_bitrate bitrate);
|
||||
void can_set_silent(uint8_t silent);
|
||||
uint32_t can_tx(CanTxMsgTypeDef *tx_msg, uint32_t timeout);
|
||||
uint32_t can_rx(CanRxMsgTypeDef *rx_msg, uint32_t timeout);
|
||||
uint8_t is_can_msg_pending(uint8_t fifo);
|
||||
|
||||
#endif // _CAN_H
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef _LED_H
|
||||
#define _LED_H
|
||||
|
||||
|
||||
#define LED_DURATION 50
|
||||
|
||||
void led_on(void);
|
||||
void led_process(void);
|
||||
|
||||
#endif
|
|
@ -1,8 +1,8 @@
|
|||
#ifndef _SLCAN_H
|
||||
#define _SLCAN_H
|
||||
|
||||
int8_t slcan_parse_frame(char *buf, CanRxMsgTypeDef *frame);
|
||||
int8_t slcan_parse_str(char *buf, uint8_t len);
|
||||
int8_t slcan_parse_frame(uint8_t *buf, CanRxMsgTypeDef *frame);
|
||||
int8_t slcan_parse_str(uint8_t *buf, uint8_t len);
|
||||
|
||||
/* maximum rx buffer len: extended CAN frame with timestamp */
|
||||
#define SLCAN_MTU 30// (sizeof("T1111222281122334455667788EA5F\r")+1)
|
||||
|
|
3
Makefile
3
Makefile
|
@ -11,7 +11,7 @@
|
|||
BUILD_NUMBER ?= 0
|
||||
|
||||
# SOURCES: list of sources in the user application
|
||||
SOURCES = main.c usbd_conf.c usbd_cdc_if.c usb_device.c usbd_desc.c stm32f0xx_hal_msp.c stm32f0xx_it.c system_stm32f0xx.c can.c slcan.c
|
||||
SOURCES = main.c usbd_conf.c usbd_cdc_if.c usb_device.c usbd_desc.c stm32f0xx_hal_msp.c stm32f0xx_it.c system_stm32f0xx.c can.c slcan.c led.c
|
||||
|
||||
# TARGET: name of the user application
|
||||
TARGET = CANtact-b$(BUILD_NUMBER)
|
||||
|
@ -176,5 +176,6 @@ clean:
|
|||
-rm $(BUILD_DIR)/*.elf
|
||||
-rm $(BUILD_DIR)/*.hex
|
||||
-rm $(BUILD_DIR)/*.map
|
||||
-rm $(BUILD_DIR)/*.bin
|
||||
|
||||
.PHONY: clean all cubelib
|
||||
|
|
13
Src/can.c
13
Src/can.c
|
@ -1,5 +1,6 @@
|
|||
#include "stm32f0xx_hal.h"
|
||||
#include "can.h"
|
||||
#include "led.h"
|
||||
|
||||
CAN_HandleTypeDef hcan;
|
||||
CAN_FilterConfTypeDef filter;
|
||||
|
@ -7,8 +8,6 @@ uint32_t prescaler;
|
|||
enum can_bus_state bus_state;
|
||||
|
||||
void can_init(void) {
|
||||
uint32_t status;
|
||||
|
||||
filter.FilterIdHigh = 0;
|
||||
filter.FilterIdLow = 0;
|
||||
filter.FilterMaskIdHigh = 0;
|
||||
|
@ -27,7 +26,6 @@ void can_init(void) {
|
|||
}
|
||||
|
||||
void can_enable(void) {
|
||||
uint32_t status;
|
||||
if (bus_state == OFF_BUS) {
|
||||
hcan.Init.Prescaler = prescaler;
|
||||
hcan.Init.Mode = CAN_MODE_NORMAL;
|
||||
|
@ -41,14 +39,13 @@ void can_enable(void) {
|
|||
hcan.Init.RFLM = DISABLE;
|
||||
hcan.Init.TXFP = DISABLE;
|
||||
hcan.pTxMsg = NULL;
|
||||
status = HAL_CAN_Init(&hcan);
|
||||
status = HAL_CAN_ConfigFilter(&hcan, &filter);
|
||||
HAL_CAN_Init(&hcan);
|
||||
HAL_CAN_ConfigFilter(&hcan, &filter);
|
||||
bus_state = ON_BUS;
|
||||
}
|
||||
}
|
||||
|
||||
void can_disable(void) {
|
||||
uint32_t status;
|
||||
if (bus_state == ON_BUS) {
|
||||
// do a bxCAN reset (set RESET bit to 1)
|
||||
hcan.Instance->MCR |= CAN_MCR_RESET;
|
||||
|
@ -113,7 +110,7 @@ uint32_t can_tx(CanTxMsgTypeDef *tx_msg, uint32_t timeout) {
|
|||
hcan.pTxMsg = tx_msg;
|
||||
status = HAL_CAN_Transmit(&hcan, timeout);
|
||||
|
||||
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_1);
|
||||
led_on();
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -124,7 +121,7 @@ uint32_t can_rx(CanRxMsgTypeDef *rx_msg, uint32_t timeout) {
|
|||
|
||||
status = HAL_CAN_Receive(&hcan, CAN_FIFO0, timeout);
|
||||
|
||||
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_1);
|
||||
led_on();
|
||||
return status;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
//
|
||||
// LED: Handles blinking of status light
|
||||
//
|
||||
|
||||
#include "stm32f0xx_hal.h"
|
||||
#include "led.h"
|
||||
|
||||
static uint32_t led_laston = 0;
|
||||
static uint32_t led_lastoff = 0;
|
||||
|
||||
// Attempt to turn on status LED
|
||||
void led_on(void)
|
||||
{
|
||||
// Make sure the LED has been off for at least LED_DURATION before turning on again
|
||||
// This prevents a solid status LED on a busy canbus
|
||||
if(led_laston == 0 && HAL_GetTick() - led_lastoff > LED_DURATION)
|
||||
{
|
||||
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, 1);
|
||||
led_laston = HAL_GetTick();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Process time-based LED events
|
||||
void led_process(void)
|
||||
{
|
||||
// If LED has been on for long enough, turn it off
|
||||
if(led_laston > 0 && HAL_GetTick() - led_laston > LED_DURATION)
|
||||
{
|
||||
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, 0);
|
||||
led_laston = 0;
|
||||
led_lastoff = HAL_GetTick();
|
||||
}
|
||||
}
|
||||
|
61
Src/main.c
61
Src/main.c
|
@ -40,6 +40,10 @@
|
|||
#include "usbd_cdc_if.h"
|
||||
#include "can.h"
|
||||
#include "slcan.h"
|
||||
#include "led.h"
|
||||
|
||||
//#define INTERNAL_OSCILLATOR
|
||||
#define EXTERNAL_OSCILLATOR
|
||||
|
||||
/* USER CODE END Includes */
|
||||
|
||||
|
@ -62,6 +66,7 @@ static void led_init(void);
|
|||
|
||||
/* USER CODE END 0 */
|
||||
|
||||
|
||||
volatile int i=0;
|
||||
int main(void)
|
||||
{
|
||||
|
@ -93,9 +98,12 @@ int main(void)
|
|||
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET);
|
||||
|
||||
// blink red LED for test
|
||||
uint32_t count;
|
||||
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_SET);
|
||||
for (count=0; count < 200000; count++) { __asm("nop");}
|
||||
HAL_Delay(100);
|
||||
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);
|
||||
HAL_Delay(100);
|
||||
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_SET);
|
||||
HAL_Delay(100);
|
||||
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);
|
||||
|
||||
// loop forever
|
||||
|
@ -103,13 +111,16 @@ int main(void)
|
|||
uint32_t status;
|
||||
uint8_t msg_buf[SLCAN_MTU];
|
||||
|
||||
|
||||
for (;;) {
|
||||
while (!is_can_msg_pending());
|
||||
status = can_rx(&rx_msg, 3);
|
||||
if (status == HAL_OK) {
|
||||
status = slcan_parse_frame(&msg_buf, &rx_msg);
|
||||
CDC_Transmit_FS(msg_buf, status);
|
||||
}
|
||||
while (!is_can_msg_pending(CAN_FIFO0))
|
||||
led_process();
|
||||
status = can_rx(&rx_msg, 3);
|
||||
if (status == HAL_OK) {
|
||||
status = slcan_parse_frame((uint8_t *)&msg_buf, &rx_msg);
|
||||
CDC_Transmit_FS(msg_buf, status);
|
||||
}
|
||||
led_process();
|
||||
}
|
||||
|
||||
/* USER CODE END 3 */
|
||||
|
@ -125,6 +136,26 @@ void SystemClock_Config(void)
|
|||
RCC_ClkInitTypeDef RCC_ClkInitStruct;
|
||||
RCC_PeriphCLKInitTypeDef PeriphClkInit;
|
||||
|
||||
#ifdef INTERNAL_OSCILLATOR
|
||||
// set up the oscillators
|
||||
// use internal HSI48 (48 MHz), no PLL
|
||||
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48;
|
||||
RCC_OscInitStruct.HSI48State = RCC_HSI48_ON;
|
||||
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
|
||||
|
||||
// set sysclk, hclk, and pclk1 source to HSI48 (48 MHz)
|
||||
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK |
|
||||
RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1);
|
||||
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI48;
|
||||
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
|
||||
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
|
||||
|
||||
// set USB clock source to HSI48 (48 MHz)
|
||||
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB;
|
||||
PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_HSI48;
|
||||
|
||||
|
||||
#elif defined EXTERNAL_OSCILLATOR
|
||||
// set up the oscillators
|
||||
// use external oscillator (16 MHz), enable 3x PLL (48 MHz)
|
||||
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
|
||||
|
@ -133,7 +164,6 @@ void SystemClock_Config(void)
|
|||
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
|
||||
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL3;
|
||||
RCC_OscInitStruct.PLL.PREDIV = RCC_PREDIV_DIV1;
|
||||
HAL_RCC_OscConfig(&RCC_OscInitStruct);
|
||||
|
||||
// set sysclk, hclk, and pclk1 source to PLL (48 MHz)
|
||||
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK |
|
||||
|
@ -141,15 +171,24 @@ void SystemClock_Config(void)
|
|||
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
|
||||
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
|
||||
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
|
||||
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0);
|
||||
|
||||
// set USB clock source to PLL (48 MHz)
|
||||
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB;
|
||||
PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLLCLK;
|
||||
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
|
||||
|
||||
#else
|
||||
#error "Please define whether to use an internal or external oscillator"
|
||||
#endif
|
||||
|
||||
HAL_RCC_OscConfig(&RCC_OscInitStruct);
|
||||
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0);
|
||||
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
|
||||
__SYSCFG_CLK_ENABLE();
|
||||
|
||||
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
|
||||
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
|
||||
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
|
||||
|
||||
}
|
||||
|
||||
/** Configure pins as
|
||||
|
|
18
Src/slcan.c
18
Src/slcan.c
|
@ -2,7 +2,7 @@
|
|||
#include "can.h"
|
||||
#include "slcan.h"
|
||||
|
||||
int8_t slcan_parse_frame(char *buf, CanRxMsgTypeDef *frame) {
|
||||
int8_t slcan_parse_frame(uint8_t *buf, CanRxMsgTypeDef *frame) {
|
||||
uint8_t i = 0;
|
||||
uint8_t id_len, j;
|
||||
uint32_t tmp;
|
||||
|
@ -63,17 +63,21 @@ int8_t slcan_parse_frame(char *buf, CanRxMsgTypeDef *frame) {
|
|||
return i;
|
||||
}
|
||||
|
||||
int8_t slcan_parse_str(char *buf, uint8_t len) {
|
||||
int8_t slcan_parse_str(uint8_t *buf, uint8_t len) {
|
||||
CanTxMsgTypeDef frame;
|
||||
uint8_t i;
|
||||
|
||||
// convert from ASCII (2nd character to end)
|
||||
for (i = 1; i < len; i++) {
|
||||
if (buf[i] < 'A') {
|
||||
buf[i] -= 0x30;
|
||||
} else {
|
||||
buf[i] -= 0x37;
|
||||
}
|
||||
// lowercase letters
|
||||
if(buf[i] >= 'a')
|
||||
buf[i] = buf[i] - 'a' + 10;
|
||||
// uppercase letters
|
||||
else if(buf[i] >= 'A')
|
||||
buf[i] = buf[i] - 'A' + 10;
|
||||
// numbers
|
||||
else
|
||||
buf[i] = buf[i] - '0';
|
||||
}
|
||||
|
||||
if (buf[0] == 'O') {
|
||||
|
|
|
@ -250,17 +250,11 @@ uint8_t slcan_str_index = 0;
|
|||
static int8_t CDC_Receive_FS (uint8_t* Buf, uint32_t *Len)
|
||||
{
|
||||
/* USER CODE BEGIN 7 */
|
||||
uint32_t status;
|
||||
CanTxMsgTypeDef TxMsg;
|
||||
|
||||
/*uint8_t test_str[] = "t71181122334455667788";
|
||||
slcan_parse_str(&TxMsg, test_str, sizeof(test_str));*/
|
||||
|
||||
uint8_t n = *Len;
|
||||
uint8_t i;
|
||||
for (i = 0; i < n; i++) {
|
||||
if (Buf[i] == '\r') {
|
||||
status = slcan_parse_str(slcan_str, slcan_str_index);
|
||||
slcan_parse_str(slcan_str, slcan_str_index);
|
||||
slcan_str_index = 0;
|
||||
} else {
|
||||
slcan_str[slcan_str_index++] = Buf[i];
|
||||
|
|
Loading…
Reference in New Issue