From 5675c4f485737997271932f9e3caca0e326d83bc Mon Sep 17 00:00:00 2001 From: Benjamin Vedder Date: Sun, 7 Dec 2014 04:30:25 +0100 Subject: [PATCH] First CAN implementation --- Makefile | 1 + comm_can.c | 164 +++++++++++++++++++++++++++++++++++++++++++++++ comm_can.h | 38 +++++++++++ datatypes.h | 8 +++ halconf.h | 2 +- main.c | 12 ++++ mcuconf.h | 2 +- stm32f4xx_conf.h | 2 +- 8 files changed, 226 insertions(+), 3 deletions(-) create mode 100644 comm_can.c create mode 100644 comm_can.h diff --git a/Makefile b/Makefile index dbf97c86..2e45afec 100644 --- a/Makefile +++ b/Makefile @@ -113,6 +113,7 @@ CSRC = $(PORTSRC) \ eeprom.c \ commands.c \ timeout.c \ + comm_can.c \ $(HWSRC) \ $(APPSRC) diff --git a/comm_can.c b/comm_can.c new file mode 100644 index 00000000..a0386997 --- /dev/null +++ b/comm_can.c @@ -0,0 +1,164 @@ +/* + Copyright 2012-2014 Benjamin Vedder benjamin@vedder.se + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + */ + +/* + * comm_can.c + * + * Created on: 7 dec 2014 + * Author: benjamin + */ + +#include "comm_can.h" +#include "ch.h" +#include "hal.h" +#include "datatypes.h" +#include "buffer.h" +#include "mcpwm.h" +#include "timeout.h" +#include "commands.h" + +// Settings +#define CANDx CAND1 + +// Threads +static WORKING_AREA(cancom_thread_wa, 2048); +static msg_t cancom_thread(void *arg); + +/* + * 500KBaud, automatic wakeup, automatic recover + * from abort mode. + * See section 22.7.7 on the STM32 reference manual. + */ +static const CANConfig cancfg = { + CAN_MCR_ABOM | CAN_MCR_AWUM | CAN_MCR_TXFP | CAN_MCR_NART, + CAN_BTR_SJW(0) | CAN_BTR_TS2(1) | + CAN_BTR_TS1(8) | CAN_BTR_BRP(6) +}; + +void comm_can_init(void) { + palSetPadMode(GPIOB, 8, + PAL_MODE_ALTERNATE(GPIO_AF_CAN1) | + PAL_STM32_OTYPE_PUSHPULL | + PAL_STM32_OSPEED_MID1); + palSetPadMode(GPIOB, 9, + PAL_MODE_ALTERNATE(GPIO_AF_CAN1) | + PAL_STM32_OTYPE_PUSHPULL | + PAL_STM32_OSPEED_MID1); + + canStart(&CANDx, &cancfg); + + chThdCreateStatic(cancom_thread_wa, sizeof(cancom_thread_wa), NORMALPRIO, + cancom_thread, NULL); +} + +static msg_t cancom_thread(void *arg) { + (void)arg; + chRegSetThreadName("CAN"); + + EventListener el; + CANRxFrame rxmsg; + int32_t ind = 0; + + chEvtRegister(&CANDx.rxfull_event, &el, 0); + + while(!chThdShouldTerminate()) { + if (chEvtWaitAnyTimeout(ALL_EVENTS, MS2ST(100)) == 0) { + continue; + } + + while (canReceive(&CANDx, CAN_ANY_MAILBOX, &rxmsg, TIME_IMMEDIATE) == RDY_OK) { + if (rxmsg.IDE == CAN_IDE_EXT) { + CAN_PACKET_ID cmd = rxmsg.EID >> 8; + + switch (cmd) { + case CAN_PACKET_SET_DUTY: + ind = 0; + mcpwm_set_duty((float)buffer_get_int32(rxmsg.data8, &ind) / 100000.0); + timeout_reset(); + break; + + case CAN_PACKET_SET_CURRENT: + ind = 0; + mcpwm_set_current((float)buffer_get_int32(rxmsg.data8, &ind) / 1000.0); + timeout_reset(); + break; + + case CAN_PACKET_SET_CURRENT_BRAKE: + ind = 0; + mcpwm_set_brake_current((float)buffer_get_int32(rxmsg.data8, &ind) / 1000.0); + timeout_reset(); + break; + + case CAN_PACKET_SET_RPM: + ind = 0; + mcpwm_set_pid_speed((float)buffer_get_int32(rxmsg.data8, &ind)); + timeout_reset(); + break; + + default: + break; + } + } + } + } + + chEvtUnregister(&CAND1.rxfull_event, &el); + return 0; +} + +void comm_can_transmit(uint32_t id, uint8_t *data, uint8_t len) { + CANTxFrame txmsg; + + txmsg.IDE = CAN_IDE_EXT; + txmsg.EID = id; + txmsg.RTR = CAN_RTR_DATA; + txmsg.DLC = len; + + for (int i = 0;i < len;i++) { + txmsg.data8[i] = data[i]; + } + + msg_t res = canTransmit(&CAND1, CAN_ANY_MAILBOX, &txmsg, TIME_IMMEDIATE); +} + +void comm_can_set_duty(uint8_t controller_id, float duty) { + int32_t send_index = 0; + uint8_t buffer[4]; + buffer_append_int32(buffer, (int32_t)(duty * 100000.0), &send_index); + comm_can_transmit(controller_id | ((uint32_t)CAN_PACKET_SET_DUTY << 8), buffer, send_index); +} + +void comm_can_set_current(uint8_t controller_id, float current) { + int32_t send_index = 0; + uint8_t buffer[4]; + buffer_append_int32(buffer, (int32_t)(current * 1000.0), &send_index); + comm_can_transmit(controller_id | ((uint32_t)CAN_PACKET_SET_CURRENT << 8), buffer, send_index); +} + +void comm_can_set_current_brake(uint8_t controller_id, float current) { + int32_t send_index = 0; + uint8_t buffer[4]; + buffer_append_int32(buffer, (int32_t)(current * 1000.0), &send_index); + comm_can_transmit(controller_id | ((uint32_t)CAN_PACKET_SET_CURRENT_BRAKE << 8), buffer, send_index); +} + +void comm_can_set_rpm(uint8_t controller_id, float rpm) { + int32_t send_index = 0; + uint8_t buffer[4]; + buffer_append_int32(buffer, (int32_t)rpm, &send_index); + comm_can_transmit(controller_id | ((uint32_t)CAN_PACKET_SET_RPM << 8), buffer, send_index); +} diff --git a/comm_can.h b/comm_can.h new file mode 100644 index 00000000..1fded776 --- /dev/null +++ b/comm_can.h @@ -0,0 +1,38 @@ +/* + Copyright 2012-2014 Benjamin Vedder benjamin@vedder.se + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + */ + +/* + * comm_can.h + * + * Created on: 7 dec 2014 + * Author: benjamin + */ + +#ifndef COMM_CAN_H_ +#define COMM_CAN_H_ + +#include "conf_general.h" + +// Functions +void comm_can_init(void); +void comm_can_transmit(uint32_t id, uint8_t *data, uint8_t len); +void comm_can_set_duty(uint8_t controller_id, float duty); +void comm_can_set_current(uint8_t controller_id, float current); +void comm_can_set_current_brake(uint8_t controller_id, float current); +void comm_can_set_rpm(uint8_t controller_id, float rpm); + +#endif /* COMM_CAN_H_ */ diff --git a/datatypes.h b/datatypes.h index 614da2c2..932b2ce0 100644 --- a/datatypes.h +++ b/datatypes.h @@ -205,6 +205,14 @@ typedef enum { COMM_GET_DECODED_CHUK } COMM_PACKET_ID; +// CAN commands +typedef enum { + CAN_PACKET_SET_DUTY = 0, + CAN_PACKET_SET_CURRENT, + CAN_PACKET_SET_CURRENT_BRAKE, + CAN_PACKET_SET_RPM +} CAN_PACKET_ID; + // Logged fault data typedef struct { mc_fault_code fault; diff --git a/halconf.h b/halconf.h index b19402d5..d862ce8f 100644 --- a/halconf.h +++ b/halconf.h @@ -66,7 +66,7 @@ * @brief Enables the CAN subsystem. */ #if !defined(HAL_USE_CAN) || defined(__DOXYGEN__) -#define HAL_USE_CAN FALSE +#define HAL_USE_CAN TRUE #endif /** diff --git a/main.c b/main.c index 286c5546..56c6dd4a 100644 --- a/main.c +++ b/main.c @@ -35,6 +35,7 @@ #include "packet.h" #include "commands.h" #include "timeout.h" +#include "comm_can.h" /* * Timers used: @@ -44,6 +45,16 @@ * TIM4: mcpwm * TIM8: mcpwm * TIM3: servo_dec + * + * DMA/stream Device Function + * 1, 2 I2C1 Nunchuk, temp on rev 4.5 + * 1, 7 I2C1 Nunchuk, temp on rev 4.5 + * 1, 1 UART3 HW_R2 + * 1, 3 UART3 HW_R2 + * 2, 2 UART6 Other HW + * 2, 7 UART6 Other HW + * 2, 4 ADC mcpwm + * */ /* @@ -282,6 +293,7 @@ int main(void) { commands_init(); comm_usb_init(); + comm_can_init(); app_configuration appconf; conf_general_read_app_configuration(&appconf); diff --git a/mcuconf.h b/mcuconf.h index 1be01cb2..16f6fa40 100644 --- a/mcuconf.h +++ b/mcuconf.h @@ -86,7 +86,7 @@ /* * CAN driver system settings. */ -#define STM32_CAN_USE_CAN1 FALSE +#define STM32_CAN_USE_CAN1 TRUE #define STM32_CAN_USE_CAN2 FALSE #define STM32_CAN_CAN1_IRQ_PRIORITY 11 #define STM32_CAN_CAN2_IRQ_PRIORITY 11 diff --git a/stm32f4xx_conf.h b/stm32f4xx_conf.h index 52b98afc..4931f352 100644 --- a/stm32f4xx_conf.h +++ b/stm32f4xx_conf.h @@ -32,7 +32,7 @@ /* Includes ------------------------------------------------------------------*/ /* Uncomment the line below to enable peripheral header file inclusion */ #include "stm32f4xx_adc.h" -#include "stm32f4xx_can.h" +//#include "stm32f4xx_can.h" #include "stm32f4xx_crc.h" #include "stm32f4xx_cryp.h" #include "stm32f4xx_dac.h"