Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • avn/swd/skyward-boardcore
  • emilio.corigliano/skyward-boardcore
  • nicolo.caruso/skyward-boardcore
  • ettore.pane/skyward-boardcore
  • giulia.facchi/skyward-boardcore
  • valerio.flamminii/skyward-boardcore
6 results
Show changes
Commits on Source (4)
Subproject commit c1bbe12c16099acb682dbf75136627ad309a0d35
Subproject commit 132a3522b41e20947f216c95c67909be54a1d6fe
Subproject commit 9268dbc2f3fd6b76ae3db68371be3473c0a8654e
Subproject commit 4f37d09806f9e63e94ca5ddc9c58ac9da29daddb
......@@ -96,14 +96,34 @@ CanbusDriver::CanbusDriver(CAN_TypeDef* can, CanbusConfig config,
// Enable interrupts
can->IER |= CAN_IER_FMPIE0 | CAN_IER_FMPIE1 | CAN_IER_TMEIE;
NVIC_EnableIRQ(CAN1_RX0_IRQn);
NVIC_SetPriority(CAN1_RX0_IRQn, 14);
// Enable the corresponding interrupts
if (can == CAN1)
{
NVIC_EnableIRQ(CAN1_RX0_IRQn);
NVIC_SetPriority(CAN1_RX0_IRQn, 14);
NVIC_EnableIRQ(CAN1_RX1_IRQn);
NVIC_SetPriority(CAN1_RX1_IRQn, 14);
NVIC_EnableIRQ(CAN1_RX1_IRQn);
NVIC_SetPriority(CAN1_RX1_IRQn, 14);
NVIC_EnableIRQ(CAN1_TX_IRQn);
NVIC_SetPriority(CAN1_TX_IRQn, 14);
NVIC_EnableIRQ(CAN1_TX_IRQn);
NVIC_SetPriority(CAN1_TX_IRQn, 14);
}
else if (can == CAN2)
{
NVIC_EnableIRQ(CAN2_RX0_IRQn);
NVIC_SetPriority(CAN2_RX0_IRQn, 14);
NVIC_EnableIRQ(CAN2_RX1_IRQn);
NVIC_SetPriority(CAN2_RX1_IRQn, 14);
NVIC_EnableIRQ(CAN2_TX_IRQn);
NVIC_SetPriority(CAN2_TX_IRQn, 14);
}
else
{
PrintLogger ls = l.getChild("constructor");
LOG_ERR(ls, "Not supported peripheral");
}
}
CanbusDriver::~CanbusDriver() { ClockUtils::disablePeripheralClock(can); }
......@@ -202,6 +222,13 @@ void CanbusDriver::init()
bool CanbusDriver::addFilter(FilterBank filter)
{
PrintLogger ls = l.getChild("addfilter");
uint8_t index = filterIndex;
// CAN2 filters start from the 15th position
if (can == CAN2)
{
index = index + 14;
}
if (isInit)
{
......@@ -209,21 +236,23 @@ bool CanbusDriver::addFilter(FilterBank filter)
return false;
}
if (filterIndex == NUM_FILTER_BANKS)
if (index >= NUM_FILTER_BANKS)
{
LOG_ERR(ls, "Cannot add filter: no more filter banks available");
return false;
}
can->sFilterRegister[filterIndex].FR1 = filter.FR1;
can->sFilterRegister[filterIndex].FR2 = filter.FR2;
// NOTE: the filters are set in CAN1 peripheral because the filter registers
// between the peripherals are in common.
CAN1->sFilterRegister[index].FR1 = filter.FR1;
CAN1->sFilterRegister[index].FR2 = filter.FR2;
can->FM1R |= (filter.mode == FilterMode::MASK ? 0 : 1) << filterIndex;
can->FS1R |= (filter.scale == FilterScale::DUAL16 ? 0 : 1) << filterIndex;
can->FFA1R |= (filter.fifo & 0x1) << filterIndex;
CAN1->FM1R |= (filter.mode == FilterMode::MASK ? 0 : 1) << index;
CAN1->FS1R |= (filter.scale == FilterScale::DUAL16 ? 0 : 1) << index;
CAN1->FFA1R |= (filter.fifo & 0x1) << index;
// Enable the filter
can->FA1R |= 1 << filterIndex;
CAN1->FA1R |= 1 << index;
++filterIndex;
......
......@@ -76,6 +76,21 @@ inline Canbus::CanMessage toCanMessage(const TemperatureData& data)
return message;
}
inline Canbus::CanMessage toCanMessage(const CurrentData& data)
{
Canbus::CanMessage message;
uint32_t current;
memcpy(&current, &(data.current), sizeof(current));
message.id = -1;
message.length = 1;
message.payload[0] = (data.currentTimestamp & ~0x3) << 30;
message.payload[0] |= current;
return message;
}
inline PitotData pitotDataFromCanMessage(const Canbus::CanMessage& msg)
{
PitotData data;
......@@ -115,4 +130,16 @@ inline TemperatureData temperatureDataFromCanMessage(
return data;
}
inline CurrentData currentDataFromCanMessage(const Canbus::CanMessage& msg)
{
CurrentData data;
uint32_t current = msg.payload[0];
memcpy(&(data.current), &current, sizeof(data.current));
data.currentTimestamp = (msg.payload[0] >> 30) & ~0x3;
return data;
}
} // namespace Boardcore
......@@ -104,8 +104,6 @@ public:
void set8BitFrameFormat();
void set16BitFrameFormat();
void enableSoftwareSlaveManagement();
void disableSoftwareSlaveManagement();
......@@ -331,26 +329,16 @@ inline void SPIBus::disable() { spi->CR1 &= ~SPI_CR1_SPE; }
inline void SPIBus::set8BitFrameFormat() { spi->CR1 &= ~SPI_CR1_DFF; }
inline void SPIBus::set16BitFrameFormat() { spi->CR1 |= SPI_CR1_DFF; }
#else
inline void SPIBus::set8bitRXNE() { spi->CR2 |= SPI_CR2_FRXTH; }
inline void SPIBus::set16bitRXNE() { spi->CR2 &= ~SPI_CR2_FRXTH; }
inline void SPIBus::set8BitFrameFormat()
{
spi->CR2 &= ~SPI_CR2_DS;
set8bitRXNE();
}
inline void SPIBus::set16BitFrameFormat()
{
spi->CR2 |= SPI_CR2_DS;
set16bitRXNE();
}
#endif
inline void SPIBus::enableSoftwareSlaveManagement() { spi->CR1 |= SPI_CR1_SSM; }
......@@ -443,11 +431,7 @@ inline void SPIBus::configure(SPIBusConfig newConfig)
enableInternalSlaveSelection();
setMasterConfiguration();
#ifdef _ARCH_CORTEXM7_STM32F7
// By default the driver uses 8 bit transactions. Therefore, for f7s,
// configure the FIFO threshold to 8 bit
set8bitRXNE();
#endif
set8BitFrameFormat();
// Enable the peripheral
enable();
......@@ -490,37 +474,20 @@ inline void SPIBus::read(uint8_t* data, size_t nBytes)
inline void SPIBus::read16(uint16_t* data, size_t nBytes)
{
// At the start of the transfer we assume that the RX FIFO is empty
assert((spi->SR & SPI_SR_RXNE) == 0);
// Set 16 bit frame format
set16BitFrameFormat();
// nBytes to be read must be a multiple of 2
assert(nBytes % 2 == 0);
uint16_t temp[2] = {0};
for (size_t i = 0; i < nBytes / 2; i++)
{
// Wait until the peripheral is ready to transmit
while ((spi->SR & SPI_SR_TXE) == 0)
;
// Write the data item to transmit
spi->DR = 0;
// Make sure transmission is complete
while ((spi->SR & SPI_SR_TXE) == 0)
;
while ((spi->SR & SPI_SR_BSY) > 0)
;
// Wait until data is received
while ((spi->SR & SPI_SR_RXNE) == 0)
;
// Receiving MSB
temp[0] = static_cast<uint16_t>(read());
// Receiving LSB
temp[1] = static_cast<uint16_t>(read());
// Read the received data item
data[i] = static_cast<uint16_t>(spi->DR);
// MSB | LSB
data[i] = temp[0] << 8 | temp[1];
}
// Go back to 8 bit frame format
set8BitFrameFormat();
}
inline void SPIBus::write(uint8_t data) { transfer(data); }
......@@ -539,37 +506,16 @@ inline void SPIBus::write(const uint8_t* data, size_t nBytes)
inline void SPIBus::write16(const uint16_t* data, size_t nBytes)
{
// At the start of the transfer we assume that the RX FIFO is empty
assert((spi->SR & SPI_SR_RXNE) == 0);
// Set 16 bit frame format
set16BitFrameFormat();
// nBytes to be read must be a multiple of 2
assert(nBytes % 2 == 0);
for (size_t i = 0; i < nBytes / 2; i++)
{
// Wait until the peripheral is ready to transmit
while ((spi->SR & SPI_SR_TXE) == 0)
;
// Write the data item to transmit
spi->DR = static_cast<uint16_t>(data[i]);
// Make sure transmission is complete
while ((spi->SR & SPI_SR_TXE) == 0)
;
while ((spi->SR & SPI_SR_BSY) > 0)
;
// Wait until data is received
while ((spi->SR & SPI_SR_RXNE) == 0)
;
// Read the received data item
(void)spi->DR;
// Sending MSB
write(static_cast<uint8_t>(data[i] >> 8));
// Sending LSB
write(static_cast<uint8_t>(data[i]));
}
// Go back to 8 bit frame format
set8BitFrameFormat();
}
inline uint8_t SPIBus::transfer(uint8_t data)
......@@ -600,52 +546,38 @@ inline uint8_t SPIBus::transfer(uint8_t data)
inline uint16_t SPIBus::transfer16(uint16_t data)
{
// At the start of the transfer we assume that the RX FIFO is empty
assert((spi->SR & SPI_SR_RXNE) == 0);
// Set 16 bit frame format
set16BitFrameFormat();
// Wait until the peripheral is ready to transmit
while ((spi->SR & SPI_SR_TXE) == 0)
;
// Write the data item to transmit
spi->DR = static_cast<uint16_t>(data);
// Make sure transmission is complete
while ((spi->SR & SPI_SR_TXE) == 0)
;
while ((spi->SR & SPI_SR_BSY) > 0)
;
// Wait until data is received
while ((spi->SR & SPI_SR_RXNE) == 0)
;
// Read the received data item
data = static_cast<uint16_t>(spi->DR);
// Go back to 8 bit frame format
set8BitFrameFormat();
return data;
uint16_t temp[2] = {0};
// Transferring MSB, putting the read value in the MSB of temp
temp[0] = static_cast<uint16_t>(transfer(static_cast<uint8_t>(data >> 8)));
// Transferring LSB, putting the read value in the LSB of temp
temp[1] = static_cast<uint16_t>(transfer(static_cast<uint8_t>(data)));
// MSB | LSB
return temp[0] << 8 | temp[1];
}
inline uint32_t SPIBus::transfer24(uint32_t data)
{
uint32_t res = static_cast<uint32_t>(transfer16(data >> 8)) << 8;
res |= transfer(data);
return res;
uint32_t temp[3] = {0};
// Transferring MSB, putting the read value in the MSB of temp
temp[0] = static_cast<uint32_t>(transfer(static_cast<uint8_t>(data >> 16)));
temp[1] = static_cast<uint32_t>(transfer(static_cast<uint8_t>(data >> 8)));
// Transferring LSB, putting the read value in the LSB of temp
temp[2] = static_cast<uint32_t>(transfer(static_cast<uint8_t>(data)));
return temp[0] << 16 | temp[1] << 8 | temp[2];
}
inline uint32_t SPIBus::transfer32(uint32_t data)
{
uint32_t res = static_cast<uint32_t>(transfer16(data >> 16)) << 16;
res |= transfer16(data);
return res;
uint32_t temp[4] = {0};
// Transferring MSB, putting the read value in the MSB of temp
temp[0] = static_cast<uint32_t>(transfer(static_cast<uint8_t>(data >> 24)));
temp[1] = static_cast<uint32_t>(transfer(static_cast<uint8_t>(data >> 16)));
temp[2] = static_cast<uint32_t>(transfer(static_cast<uint8_t>(data >> 8)));
// Transferring LSB, putting the read value in the LSB of temp
temp[3] = transfer(static_cast<uint8_t>(data));
return temp[0] << 24 | temp[1] << 16 | temp[2] << 8 | temp[3];
}
inline void SPIBus::transfer(uint8_t* data, size_t nBytes)
......@@ -656,37 +588,19 @@ inline void SPIBus::transfer(uint8_t* data, size_t nBytes)
inline void SPIBus::transfer16(uint16_t* data, size_t nBytes)
{
// At the start of the transfer we assume that the RX FIFO is empty
assert((spi->SR & SPI_SR_RXNE) == 0);
// nBytes to be read must be a multiple of 2
assert(nBytes % 2 == 0);
// Set 16 bit frame format
set16BitFrameFormat();
uint16_t temp[2] = {0};
for (size_t i = 0; i < nBytes / 2; i++)
{
// Wait until the peripheral is ready to transmit
while ((spi->SR & SPI_SR_TXE) == 0)
;
// Write the data item to transmit
spi->DR = static_cast<uint16_t>(data[i]);
// Make sure transmission is complete
while ((spi->SR & SPI_SR_TXE) == 0)
;
while ((spi->SR & SPI_SR_BSY) > 0)
;
// Wait until data is received
while ((spi->SR & SPI_SR_RXNE) == 0)
;
// Read the received data item
data[i] = static_cast<uint16_t>(spi->DR);
temp[0] =
static_cast<uint16_t>(transfer(static_cast<uint8_t>(data[i] >> 8)));
temp[1] =
static_cast<uint16_t>(transfer(static_cast<uint8_t>(data[i])));
data[i] = temp[0] << 8 | temp[1];
}
// Go back to 8 bit frame format
set8BitFrameFormat();
}
} // namespace Boardcore
......@@ -54,7 +54,6 @@
#include <sensors/VN100/VN100Data.h>
#include <sensors/analog/AnalogLoadCellData.h>
#include <sensors/analog/BatteryVoltageSensorData.h>
#include <sensors/analog/CurrentSensorData.h>
#include <sensors/analog/pressure/honeywell/HSCMAND015PAData.h>
#include <sensors/analog/pressure/honeywell/HSCMRNN030PAData.h>
#include <sensors/analog/pressure/honeywell/HSCMRNN160KAData.h>
......@@ -114,7 +113,7 @@ void registerTypes(Deserializer& ds)
ds.registerType<VN100Data>();
ds.registerType<AnalogLoadCellData>();
ds.registerType<BatteryVoltageSensorData>();
ds.registerType<CurrentSensorData>();
ds.registerType<CurrentData>();
ds.registerType<HSCMAND015PAData>();
ds.registerType<HSCMRNN030PAData>();
ds.registerType<HSCMRNN160KAData>();
......
......@@ -272,4 +272,20 @@ struct ADCData
float voltage = 0;
};
/**
* @brief Structure to handle current data.
*/
struct CurrentData
{
uint64_t currentTimestamp = 0;
float current = 0;
static std::string header() { return "timestamp,current\n"; }
void print(std::ostream& os) const
{
os << currentTimestamp << "," << current << "\n";
}
};
} // namespace Boardcore
......@@ -26,8 +26,6 @@
#include <functional>
#include "CurrentSensorData.h"
namespace Boardcore
{
......@@ -36,7 +34,7 @@ namespace Boardcore
*
* It needs a transfer function to convert the read voltage into current.
*/
class CurrentSensor : public Sensor<CurrentSensorData>
class CurrentSensor : public Sensor<CurrentData>
{
public:
static constexpr int MOVING_AVERAGE_N = 20;
......@@ -53,7 +51,7 @@ public:
bool selfTest() override { return true; };
///< Converts the voltage value to pressure
CurrentSensorData sampleImpl() override
CurrentData sampleImpl() override
{
ADCData adc_data = getVoltage();
......@@ -62,10 +60,8 @@ public:
lastSample.current = voltageToCurrent(adc_data.voltage);
}
CurrentSensorData current_data;
current_data.voltageTimestamp = adc_data.voltageTimestamp;
current_data.channelId = adc_data.channelId;
current_data.voltage = adc_data.voltage;
CurrentData current_data;
current_data.currentTimestamp = adc_data.voltageTimestamp;
// Moving average
current_data.current = lastSample.current * MOVING_AVERAGE_COMP_COEFF;
......
/* Copyright (c) 2021 Skyward Experimental Rocketry
* Author: Alberto Nidasio
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#pragma once
#include <sensors/SensorData.h>
namespace Boardcore
{
/**
* @brief Structure to handle current sense data.
*/
struct CurrentSensorData : public ADCData
{
float current = 0;
static std::string header()
{
return "voltageTimestamp,channelId,voltage,current\n";
}
void print(std::ostream& os) const
{
os << voltageTimestamp << "," << (int)channelId << "," << voltage << ","
<< current << "\n";
}
};
} // namespace Boardcore
......@@ -42,21 +42,43 @@ void print(const CanMessage& msg)
int main()
{
// Prepare the cab driver
GpioPin canA{GPIOB_BASE, 8};
GpioPin canB{GPIOB_BASE, 9};
canA.mode(Mode::ALTERNATE);
canB.mode(Mode::ALTERNATE);
canA.alternateFunction(9);
canB.alternateFunction(9);
GpioPin can2A{GPIOB_BASE, 12};
GpioPin can2B{GPIOB_BASE, 13};
can2A.mode(Mode::ALTERNATE);
can2B.mode(Mode::ALTERNATE);
can2A.alternateFunction(9);
can2B.alternateFunction(9);
printf("provolone fritto\n");
// // Prepare the cab driver
CanbusDriver::CanbusConfig config;
config.loopback = true;
CanbusDriver::AutoBitTiming bitTiming;
bitTiming.baudRate = 500 * 1000;
bitTiming.baudRate = 50 * 1000;
bitTiming.samplePoint = 87.5f / 100.0f;
CanbusDriver* driver = new CanbusDriver(CAN1, config, bitTiming);
// Prepare the can driver
CanProtocol protocol(driver, print);
// To make the CAN2 work the driver must be created also for CAN1
// TODO change this thing
CanbusDriver* driver1 = new CanbusDriver(CAN1, config, bitTiming);
CanbusDriver* driver2 = new CanbusDriver(CAN2, config, bitTiming);
// // Prepare the can driver
CanProtocol protocol(driver2, print);
// Add a filter to allow every message
Mask32FilterBank f2(0, 0, 1, 1, 0, 0, 0);
driver->addFilter(f2);
driver->init();
driver2->addFilter(f2);
driver2->init();
// Start the protocol
protocol.start();
......
......@@ -80,9 +80,8 @@ int main()
currentSensor.sample();
CurrentSensorData currentData = currentSensor.getLastSample();
printf("%llu %u %f %f \n", currentData.voltageTimestamp,
currentData.channelId, currentData.voltage,
CurrentData currentData = currentSensor.getLastSample();
printf("%llu %f \n", currentData.currentTimestamp,
currentData.current);
miosix::Thread::sleep(100);
......