Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion lib/mcal/sil/README

This file was deleted.

45 changes: 0 additions & 45 deletions lib/mcal/sil/adc.hpp

This file was deleted.

17 changes: 17 additions & 0 deletions lib/mcal/sil/analog_input.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#pragma once

#include "periph/analog_input.hpp"

namespace mcal::sil {

class AnalogInput : public macfe::periph::AnalogInput {
private:
float* input_;

public:
AnalogInput(float* input) : input_(input) {}
float ReadVoltage() {
return *input_;
}
};
} // namespace mcal::sil
17 changes: 17 additions & 0 deletions lib/mcal/sil/analog_output.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#pragma once

#include "periph/analog_output.hpp"

namespace mcal::sil {

class AnalogOutput : public macfe::periph::AnalogOutput {
private:
float* output_;

public:
AnalogOutput(float* output) : output_(output) {}
void SetVoltage(float voltage) override {
*output_ = voltage;
}
};
} // namespace mcal::sil
125 changes: 12 additions & 113 deletions lib/mcal/sil/can.hpp
Original file line number Diff line number Diff line change
@@ -1,139 +1,38 @@
/// @author Samuel Parent
/// @date 2023-01-12

#pragma once

#include <linux/can.h>
#include <linux/can/raw.h>
#include <net/if.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <unistd.h>

#include <chrono>
#include <cstdint>
#include <cstring>
#include <format>
#include <iostream>
#include <queue>
#include <thread>

#include "can/raw_can_msg.hpp"
#include "can/msg.hpp"
#include "periph/can.hpp"
#include "third-party/etl/include/etl/queue.h"

namespace mcal::raspi {
namespace mcal::sil {

class CanBase : public macfe::periph::CanBase {
public:
CanBase(std::string can_iface) : iface_(can_iface) {
program_start_ = std::chrono::steady_clock::now();
};
CanBase(std::string can_iface) : iface_(can_iface) {};

void Setup() {
// Create a socket
sock_ = socket(PF_CAN, SOCK_RAW, CAN_RAW);
if (sock_ < 0) {
perror("Error creating socket");
return;
}

// Specify the can interface
strncpy(ifreq_.ifr_name, iface_.c_str(), sizeof(ifreq_.ifr_name) - 1);

std::cout << std::format("can interface: {}", iface_) << std::endl;

ioctl(sock_, SIOCGIFINDEX, &ifreq_);

// Bind the socket to the can interface
sock_addr_.can_family = AF_CAN;
sock_addr_.can_ifindex = ifreq_.ifr_ifindex;

int bind_status =
bind(sock_, (struct sockaddr*)&sock_addr_, sizeof(sock_addr_));
if (bind_status < 0) {
perror("Error binding socket");
close(sock_);
}

reader_thread_ = std::thread(&CanBase::StartReading, this);
}

void Send(const macfe::can::RawCanMsg& can_tx_msg) {
frame_.can_id = can_tx_msg.header.id;
frame_.can_dlc = can_tx_msg.header.data_len;
memcpy((uint8_t*)frame_.data, can_tx_msg.data, 8);

ssize_t bytes_written = write(sock_, &frame_, sizeof(struct can_frame));
if (bytes_written != sizeof(struct can_frame)) {
perror("Error writing to socket");
close(sock_);
}
}

void ReadQueue(macfe::can::RawCanMsg can_rx_msgs[], size_t len) {
uint16_t msg_idx = 0;
{
std::lock_guard<std::mutex> lock(queue_mtx_);
while (!can_queue_.empty() && (msg_idx < len)) {
can_rx_msgs[msg_idx] = can_queue_.front();
can_queue_.pop();
msg_idx++;
}
}
void Send(const macfe::can::RawMessage& msg) override {
// std::cout << std::format("CanBase {}: Sending\n| {}", iface_, msg)
// << std::endl;
}

private:
static constexpr uint8_t kMaxMsgBytes = 8;

struct sockaddr_can sock_addr_;
struct ifreq ifreq_;
struct can_frame frame_;
std::string iface_;
int sock_;

std::queue<macfe::can::RawCanMsg> can_queue_;
std::mutex queue_mtx_;
std::thread reader_thread_;

std::chrono::steady_clock::time_point program_start_;

inline uint32_t get_tick() {
std::chrono::milliseconds elapsed_ms =
std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::steady_clock::now() - program_start_);
return static_cast<uint32_t>(elapsed_ms.count());
}

void StartReading() {
struct can_frame frame;

while (true) {
ssize_t bytesRead =
recv(sock_, &frame, sizeof(struct can_frame), 0);
if (bytesRead == -1) {
perror("Error reading from CAN socket");
continue;
}

macfe::can::RawCanMsg rawMsg;
rawMsg.header.id = frame.can_id;
rawMsg.header.data_len = frame.can_dlc;
rawMsg.header.is_extended_frame = frame.can_id & CAN_EFF_FLAG;
rawMsg.tick_timestamp = get_tick();

std::copy(frame.data, frame.data + kMaxMsgBytes, rawMsg.data);

// Add to the queue
{
std::lock_guard<std::mutex> lock(queue_mtx_);
can_queue_.push(rawMsg);
}
}
uint32_t GetTimestamp() const override {
using namespace std::chrono;
// auto t = system_clock::now().time_since_epoch();
// auto ms = duration_cast<milliseconds>(4).count();
return 4;
}
};

} // namespace mcal::raspi
} // namespace mcal::sil
Loading