stm32: Update can.c to use more consistent indentation

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor 2021-01-27 18:29:12 -05:00
parent 7d4df65920
commit 901ccfcb9d
1 changed files with 143 additions and 146 deletions

View File

@ -1,96 +1,90 @@
/*
* Serial over CAN emulation for STM32 boards.
*
* Copyright (C) 2019 Eug Krashtan <eug.krashtan@gmail.com>
* Copyright (C) 2020 Pontus Borg <glpontus@gmail.com>
* This file may be distributed under the terms of the GNU GPLv3 license.
*
*/
// Serial over CAN emulation for STM32 boards.
//
// Copyright (C) 2019 Eug Krashtan <eug.krashtan@gmail.com>
// Copyright (C) 2020 Pontus Borg <glpontus@gmail.com>
//
// This file may be distributed under the terms of the GNU GPLv3 license.
#include "autoconf.h" //
#include "board/armcm_boot.h" // armcm_enable_irq
#include "board/serial_irq.h" // serial_rx_byte
#include <string.h> // memcpy
#include "autoconf.h" // CONFIG_MACH_STM32F1
#include "can.h" // SHORT_UUID_LEN
#include "command.h" // DECL_CONSTANT_STR
#include "fasthash.h" // fasthash64
#include "generic/armcm_boot.h" // armcm_enable_irq
#include "generic/serial_irq.h" // serial_rx_byte
#include "internal.h" // enable_pclock
#include "sched.h" // DECL_INIT
#include <string.h>
#include "can.h"
#include <fasthash.h>
#if (CONFIG_CAN_PINS_PA11_PA12)
DECL_CONSTANT_STR("RESERVE_PINS_CAN", "PA11,PA12");
#define GPIO_Rx GPIO('A', 11)
#define GPIO_Tx GPIO('A', 12)
#if CONFIG_CAN_PINS_PA11_PA12
DECL_CONSTANT_STR("RESERVE_PINS_CAN", "PA11,PA12");
#define GPIO_Rx GPIO('A', 11)
#define GPIO_Tx GPIO('A', 12)
#endif
#if (CONFIG_CAN_PINS_PB8_PB9)
DECL_CONSTANT_STR("RESERVE_PINS_CAN", "PB8,PB9");
#define GPIO_Rx GPIO('B', 8)
#define GPIO_Tx GPIO('B', 9)
#if CONFIG_CAN_PINS_PB8_PB9
DECL_CONSTANT_STR("RESERVE_PINS_CAN", "PB8,PB9");
#define GPIO_Rx GPIO('B', 8)
#define GPIO_Tx GPIO('B', 9)
#endif
#if (CONFIG_CAN_PINS_PI8_PH13)
DECL_CONSTANT_STR("RESERVE_PINS_CAN", "PI8,PH13");
#define GPIO_Rx GPIO('I', 8)
#define GPIO_Tx GPIO('H', 13)
#if CONFIG_CAN_PINS_PI8_PH13
DECL_CONSTANT_STR("RESERVE_PINS_CAN", "PI8,PH13");
#define GPIO_Rx GPIO('I', 8)
#define GPIO_Tx GPIO('H', 13)
#endif
#if (CONFIG_CAN_PINS_PB5_PB6)
DECL_CONSTANT_STR("RESERVE_PINS_CAN", "PB5,PB6");
#define GPIO_Rx GPIO('B', 5)
#define GPIO_Tx GPIO('B', 6)
#if CONFIG_CAN_PINS_PB5_PB6
DECL_CONSTANT_STR("RESERVE_PINS_CAN", "PB5,PB6");
#define GPIO_Rx GPIO('B', 5)
#define GPIO_Tx GPIO('B', 6)
#endif
#if (CONFIG_CAN_PINS_PB12_PB13)
DECL_CONSTANT_STR("RESERVE_PINS_CAN", "PB12,PB13");
#define GPIO_Rx GPIO('B', 12)
#define GPIO_Tx GPIO('B', 13)
#if CONFIG_CAN_PINS_PB12_PB13
DECL_CONSTANT_STR("RESERVE_PINS_CAN", "PB12,PB13");
#define GPIO_Rx GPIO('B', 12)
#define GPIO_Tx GPIO('B', 13)
#endif
#if (CONFIG_MACH_STM32F0)
#define SOC_CAN CAN
#define CAN_RX0_IRQn CEC_CAN_IRQn
#define CAN_RX1_IRQn CEC_CAN_IRQn
#define CAN_TX_IRQn CEC_CAN_IRQn
#define CAN_SCE_IRQn CEC_CAN_IRQn
#define CAN_FUNCTION GPIO_FUNCTION(4) // Alternative function mapping number
#if CONFIG_MACH_STM32F0
#define SOC_CAN CAN
#define CAN_RX0_IRQn CEC_CAN_IRQn
#define CAN_RX1_IRQn CEC_CAN_IRQn
#define CAN_TX_IRQn CEC_CAN_IRQn
#define CAN_SCE_IRQn CEC_CAN_IRQn
#define CAN_FUNCTION GPIO_FUNCTION(4) // Alternative function mapping number
#endif
#if (CONFIG_MACH_STM32F1)
#define SOC_CAN CAN1
#define CAN_RX0_IRQn CAN1_RX0_IRQn
#define CAN_RX1_IRQn CAN1_RX1_IRQn
#define CAN_TX_IRQn CAN1_TX_IRQn
#define CAN_SCE_IRQn CAN1_SCE_IRQn
#define CAN_FUNCTION GPIO_FUNCTION(9) // Alternative function mapping number
#if CONFIG_MACH_STM32F1
#define SOC_CAN CAN1
#define CAN_RX0_IRQn CAN1_RX0_IRQn
#define CAN_RX1_IRQn CAN1_RX1_IRQn
#define CAN_TX_IRQn CAN1_TX_IRQn
#define CAN_SCE_IRQn CAN1_SCE_IRQn
#define CAN_FUNCTION GPIO_FUNCTION(9) // Alternative function mapping number
#endif
#if CONFIG_MACH_STM32F4
#warning CAN on STM32F4 is untested
#if (CONFIG_CAN_PINS_PA11_PA12 || CONFIG_CAN_PINS_PB8_PB9 \
|| CONFIG_CAN_PINS_PI8_PH13)
#define SOC_CAN CAN1
#define CAN_RX0_IRQn CAN1_RX0_IRQn
#define CAN_RX1_IRQn CAN1_RX1_IRQn
#define CAN_TX_IRQn CAN1_TX_IRQn
#define CAN_SCE_IRQn CAN1_SCE_IRQn
#elif CONFIG_CAN_PINS_PB5_PB6 || CONFIG_CAN_PINS_PB12_PB13
#define SOC_CAN CAN2
#define CAN_RX0_IRQn CAN2_RX0_IRQn
#define CAN_RX1_IRQn CAN2_RX1_IRQn
#define CAN_TX_IRQn CAN2_TX_IRQn
#define CAN_SCE_IRQn CAN2_SCE_IRQn
#else
#error Uknown pins for STMF32F4 CAN
#endif
#if (CONFIG_MACH_STM32F4)
#warning CAN on STM32F4 is untested
#if (CONFIG_CAN_PINS_PA11_PA12 || \
CONFIG_CAN_PINS_PB8_PB9 || \
CONFIG_CAN_PINS_PI8_PH13)
#define SOC_CAN CAN1
#define CAN_RX0_IRQn CAN1_RX0_IRQn
#define CAN_RX1_IRQn CAN1_RX1_IRQn
#define CAN_TX_IRQn CAN1_TX_IRQn
#define CAN_SCE_IRQn CAN1_SCE_IRQn
#elif ((CONFIG_CAN_PINS_PB5_PB6 || CONFIG_CAN_PINS_PB12_PB13)
#define SOC_CAN CAN2
#define CAN_RX0_IRQn CAN2_RX0_IRQn
#define CAN_RX1_IRQn CAN2_RX1_IRQn
#define CAN_TX_IRQn CAN2_TX_IRQn
#define CAN_SCE_IRQn CAN2_SCE_IRQn
#else
#error Uknown pins for STMF32F4 CAN
#define CAN_FUNCTION GPIO_FUNCTION(9) // Alternative function mapping number
#endif
#define CAN_FUNCTION GPIO_FUNCTION(9) // Alternative function mapping number
#endif
#ifndef SOC_CAN
#error No known CAN device for configured MCU
#error No known CAN device for configured MCU
#endif
// TXFP makes packets posted to the TX mboxes transmit in chronologcal order
// ABOM makes the hardware automatically leave bus-off state
#define MCR_FLAGS (CAN_MCR_TXFP | CAN_MCR_ABOM)
@ -99,17 +93,23 @@ DECL_CONSTANT_STR("RESERVE_PINS_CAN", "PB12,PB13");
static uint16_t MyCanId = 0;
static int can_find_empty_tx_mbox(void) {
static int
can_find_empty_tx_mbox(void)
{
uint32_t tsr = SOC_CAN->TSR;
if(tsr & CAN_TSR_TME0) return 0;
if(tsr & CAN_TSR_TME1) return 1;
if(tsr & CAN_TSR_TME2) return 2;
if (tsr & CAN_TSR_TME0)
return 0;
if (tsr & CAN_TSR_TME1)
return 1;
if (tsr & CAN_TSR_TME2)
return 2;
return -1;
}
static void can_transmit_mbox(uint32_t id, int mbox, uint32_t dlc, uint8_t *pkt)
static void
can_transmit_mbox(uint32_t id, int mbox, uint32_t dlc, uint8_t *pkt)
{
CAN_TxMailBox_TypeDef *mb = &SOC_CAN->sTxMailBox[mbox];
CAN_TxMailBox_TypeDef *mb = &SOC_CAN->sTxMailBox[mbox];
/* Set up the Id */
mb->TIR &= CAN_TI0R_TXRQ;
mb->TIR |= (id << CAN_TI0R_STID_Pos);
@ -119,51 +119,54 @@ static void can_transmit_mbox(uint32_t id, int mbox, uint32_t dlc, uint8_t *pkt)
mb->TDTR |= (dlc & 0xFU);
/* Set up the data field */
if(pkt) {
mb->TDLR = ((uint32_t)pkt[3] << 24) |
((uint32_t)pkt[2] << 16) |
((uint32_t)pkt[1] << 8) |
((uint32_t)pkt[0] << 0);
mb->TDHR = ((uint32_t)pkt[7] << 24) |
((uint32_t)pkt[6] << 16) |
((uint32_t)pkt[5] << 8) |
((uint32_t)pkt[4] << 0);
if (pkt) {
mb->TDLR = (((uint32_t)pkt[3] << 24)
| ((uint32_t)pkt[2] << 16)
| ((uint32_t)pkt[1] << 8)
| ((uint32_t)pkt[0] << 0));
mb->TDHR = (((uint32_t)pkt[7] << 24)
| ((uint32_t)pkt[6] << 16)
| ((uint32_t)pkt[5] << 8)
| ((uint32_t)pkt[4] << 0));
}
/* Request transmission */
/* Request transmission */
__sync_synchronize(); // disable write optimization
mb->TIR |= CAN_TI0R_TXRQ;
}
// Blocking transmit function, it can race with the IRQ driven TX handler.
// This should(tm) not happen
static void can_transmit(uint32_t id, uint32_t dlc, uint8_t *pkt)
static void
can_transmit(uint32_t id, uint32_t dlc, uint8_t *pkt)
{
int mbox = -1;
do {
mbox = can_find_empty_tx_mbox();
} while(mbox < 0);
mbox = can_find_empty_tx_mbox();
} while (mbox < 0);
can_transmit_mbox(id, mbox, dlc, pkt);
}
// Convert Unique 96-bit value into 48 bit representation
static void pack_uuid(uint8_t* u)
static void
pack_uuid(uint8_t *u)
{
uint64_t hash = fasthash64((uint8_t*)UID_BASE, 12, 0xA16231A7);
memcpy(u, &hash, SHORT_UUID_LEN);
}
static void can_uuid_resp(void)
static void
can_uuid_resp(void)
{
uint8_t short_uuid[SHORT_UUID_LEN];
pack_uuid(short_uuid);
can_transmit(PKT_ID_UUID_RESP, SHORT_UUID_LEN, short_uuid);
}
static void get_rx_data(uint8_t* buf, unsigned int mbox)
static void
get_rx_data(uint8_t *buf, unsigned int mbox)
{
uint32_t rdlr = SOC_CAN->sFIFOMailBox[mbox].RDLR;
buf[0] = (rdlr >> 0) & 0xff;
@ -178,42 +181,44 @@ static void get_rx_data(uint8_t* buf, unsigned int mbox)
}
// Return true if more data is available to send or mailboxes are full
int CAN_TxIrq(void) {
static int
CAN_TxIrq(void)
{
int txdata = 1;
// TODO: We need some kind of error handling?
while(txdata) {
while (txdata) {
int mbox = can_find_empty_tx_mbox();
if(mbox < 0) {
if (mbox < 0) {
// All mboxes full, wait for next IRQ
return 1;
}
int i=0;
int i;
uint8_t databuf[8];
for (;i<8;i++)
{
if(serial_get_tx_byte(&(databuf[i])) == -1) {
for (i=0; i<8; i++) {
if (serial_get_tx_byte(&(databuf[i])) == -1) {
txdata = 0;
break;
}
}
if (i>0) {
if (i > 0) {
can_transmit_mbox(MyCanId+1, mbox, i, databuf);
}
}
return txdata;
}
void CAN_RxCpltCallback(unsigned int mbox)
static void
CAN_RxCpltCallback(unsigned int mbox)
{
CAN_FIFOMailBox_TypeDef* mb = &SOC_CAN->sFIFOMailBox[mbox];
CAN_FIFOMailBox_TypeDef *mb = &SOC_CAN->sFIFOMailBox[mbox];
uint32_t id = (mb->RIR >> CAN_RI0R_STID_Pos) & 0x7FF;
uint8_t dlc = mb->RDTR & CAN_RDT0R_DLC;
uint8_t databuf[8];
if(!MyCanId) { // If serial not assigned yet
if(id==PKT_ID_UUID && dlc == 0) {
if (!MyCanId) { // If serial not assigned yet
if (id==PKT_ID_UUID && dlc == 0) {
// Just inform host about my UUID
can_uuid_resp();
} else if (id == PKT_ID_SET) {
@ -239,24 +244,21 @@ void CAN_RxCpltCallback(unsigned int mbox)
SOC_CAN->FMR &= ~(CAN_FMR_FINIT);
}
}
} else {
} else {
if (id == MyCanId) {
// compare my UUID with packet to check if this packet mine
if(dlc == 0) {
if (dlc == 0) {
// empty packet == ping request
can_transmit(MyCanId+1, 0, NULL);
} else {
get_rx_data(databuf, mbox);
for(int i=0; i < dlc; i++ ) {
for (int i=0; i < dlc; i++) {
serial_rx_byte(databuf[i]);
}
}
}
else if (id == PKT_ID_UUID && dlc > 0)
{
} else if (id == PKT_ID_UUID && dlc > 0) {
get_rx_data(databuf, mbox);
if (memcmp(databuf, &MyCanId, 2) == 0)
{
if (memcmp(databuf, &MyCanId, 2) == 0) {
// Reset from host
NVIC_SystemReset();
}
@ -264,45 +266,41 @@ void CAN_RxCpltCallback(unsigned int mbox)
}
}
/**
* @brief This function handles CAN global interrupts
*/
// This function handles CAN global interrupts
void
CAN_IRQHandler(void)
{
// RX
if (SOC_CAN->RF0R & CAN_RF0R_FMP0) {
// Mailbox 0
while(SOC_CAN->RF0R & CAN_RF0R_FMP0) {
while (SOC_CAN->RF0R & CAN_RF0R_FMP0) {
CAN_RxCpltCallback(0);
SOC_CAN->RF0R |= CAN_RF0R_RFOM0;
}
}
if (SOC_CAN->RF1R & CAN_RF1R_FMP1) {
// Mailbox 1
while(SOC_CAN->RF1R & CAN_RF1R_FMP1) {
while (SOC_CAN->RF1R & CAN_RF1R_FMP1) {
CAN_RxCpltCallback(1);
SOC_CAN->RF1R |= CAN_RF1R_RFOM1;
}
}
/* Check Overrun flag for FIFO0 */
if(SOC_CAN->RF0R & CAN_RF0R_FOVR0)
{
if (SOC_CAN->RF0R & CAN_RF0R_FOVR0) {
/* Clear FIFO0 Overrun Flag */
SOC_CAN->RF0R |= CAN_RF0R_FOVR0;
}
/* Check Overrun flag for FIFO1 */
if(SOC_CAN->RF1R & CAN_RF1R_FOVR1)
{
if (SOC_CAN->RF1R & CAN_RF1R_FOVR1) {
/* Clear FIFO1 Overrun Flag */
SOC_CAN->RF1R |= CAN_RF1R_FOVR1;
}
// TX
if(SOC_CAN->IER & CAN_IER_TMEIE) { // TX IRQ enabled
if(!CAN_TxIrq())
SOC_CAN->IER &= ~CAN_IER_TMEIE; // Disable TXIRQ
if (SOC_CAN->IER & CAN_IER_TMEIE) { // TX IRQ enabled
if (!CAN_TxIrq())
SOC_CAN->IER &= ~CAN_IER_TMEIE; // Disable TXIRQ
}
}
@ -312,17 +310,15 @@ make_btr(uint32_t sjw, // Sync jump width, ... hmm
uint32_t time_seg2, // time segment after sample point, 1 .. 8
uint32_t brp) // Baud rate prescaler, 1 .. 1024
{
return
((uint32_t)(sjw-1)) << CAN_BTR_SJW_Pos
| ((uint32_t)(time_seg1-1)) << CAN_BTR_TS1_Pos
| ((uint32_t)(time_seg2-1)) << CAN_BTR_TS2_Pos
| ((uint32_t)(brp - 1)) << CAN_BTR_BRP_Pos;
return (((uint32_t)(sjw-1)) << CAN_BTR_SJW_Pos
| ((uint32_t)(time_seg1-1)) << CAN_BTR_TS1_Pos
| ((uint32_t)(time_seg2-1)) << CAN_BTR_TS2_Pos
| ((uint32_t)(brp - 1)) << CAN_BTR_BRP_Pos);
}
static inline const uint32_t
compute_btr(uint32_t pclock, uint32_t bitrate) {
compute_btr(uint32_t pclock, uint32_t bitrate)
{
/*
Some equations:
Tpclock = 1 / pclock
@ -343,10 +339,10 @@ compute_btr(uint32_t pclock, uint32_t bitrate) {
uint32_t sjw = 2;
uint32_t qs;
// Find number of time quantas that gives us the exact wanted bit time
for(qs = 18; qs > 9; qs --) {
for (qs = 18; qs > 9; qs--) {
// check that bit_clocks / quantas is an integer
uint32_t brp_rem = bit_clocks % qs;
if(brp_rem == 0)
if (brp_rem == 0)
break;
}
uint32_t brp = bit_clocks / qs;
@ -375,7 +371,8 @@ can_init(void)
/* Request initialisation */
SOC_CAN->MCR |= CAN_MCR_INRQ;
/* Wait the acknowledge */
while( !(SOC_CAN->MSR & CAN_MSR_INAK) );
while (!(SOC_CAN->MSR & CAN_MSR_INAK))
;
SOC_CAN->MCR |= MCR_FLAGS;
SOC_CAN->BTR = btr;
@ -383,7 +380,8 @@ can_init(void)
/* Request leave initialisation */
SOC_CAN->MCR &= ~(CAN_MCR_INRQ);
/* Wait the acknowledge */
while( SOC_CAN->MSR & CAN_MSR_INAK );
while (SOC_CAN->MSR & CAN_MSR_INAK)
;
/*##-2- Configure the CAN Filter #######################################*/
uint32_t filternbrbitpos = (1U) << CAN_FILTER_NUMBER;
@ -398,7 +396,7 @@ can_init(void)
SOC_CAN->sFilterRegister[CAN_FILTER_NUMBER].FR2 =
((uint32_t)(PKT_ID_SET<<5) << 16U);
/*Identifier list mode for the filter*/
/* Identifier list mode for the filter */
SOC_CAN->FM1R |= filternbrbitpos;
/* 32-bit scale for the filter */
SOC_CAN->FS1R |= filternbrbitpos;
@ -416,13 +414,12 @@ can_init(void)
SOC_CAN->IER |= (CAN_IER_FMPIE0 | CAN_IER_FMPIE1); // RX mailbox IRQ
armcm_enable_irq(CAN_IRQHandler, CAN_RX0_IRQn, 0);
if(CAN_RX0_IRQn != CAN_RX1_IRQn)
armcm_enable_irq(CAN_IRQHandler, CAN_RX1_IRQn, 0);
if(CAN_RX0_IRQn != CAN_TX_IRQn)
armcm_enable_irq(CAN_IRQHandler, CAN_TX_IRQn, 0);
if (CAN_RX0_IRQn != CAN_RX1_IRQn)
armcm_enable_irq(CAN_IRQHandler, CAN_RX1_IRQn, 0);
if (CAN_RX0_IRQn != CAN_TX_IRQn)
armcm_enable_irq(CAN_IRQHandler, CAN_TX_IRQn, 0);
// TODO: CAN_SCE_IRQ?n
/*##-4- Say Hello #################################*/
can_uuid_resp();
}
@ -431,7 +428,7 @@ DECL_INIT(can_init);
void
serial_enable_tx_irq(void)
{
if(MyCanId == 0)
if (MyCanId == 0)
// Serial port not initialized
return;