h2_leaksensor_code/src/spi_manager.cpp
2026-07-24 16:39:26 +02:00

64 lines
1.7 KiB
C++

#include "spi_manager.h"
#include <Arduino.h>
#include <avr/io.h>
// =====================================================
// SPI MANAGER — SPI0 DEFAULT MUX
// PA1=MOSI (pin 20) PA2=MISO (pin 1)
// PA3=SCK (pin 2) PA4=CS (pin 5, software)
// No PORTMUX remapping required.
// =====================================================
void SPI_Init(void) {
pinMode(SPI_MOSI_PIN, OUTPUT);
pinMode(SPI_MISO_PIN, INPUT);
pinMode(SPI_SCK_PIN, OUTPUT);
pinMode(SPI_CS_CAN_PIN, OUTPUT);
digitalWrite(SPI_CS_CAN_PIN, HIGH); // CS inactive
// Default SPI0 MUX is already PA1/PA2/PA3.
PORTMUX.SPIROUTEA = PORTMUX_SPI0_DEFAULT_gc;
SPI0.CTRLA = SPI_MASTER_bm
| SPI_PRESC_DIV4_gc; // 20 MHz / 4 = 5 MHz
SPI0.CTRLB = SPI_MODE_0_gc
| SPI_SSD_bm; // Software SS
SPI0.CTRLA |= SPI_ENABLE_bm;
}
void SPI_CS_Assert(void) {
digitalWrite(SPI_CS_CAN_PIN, LOW);
}
void SPI_CS_Deassert(void) {
digitalWrite(SPI_CS_CAN_PIN, HIGH);
}
uint8_t SPI_TransferByte(uint8_t txByte) {
SPI0.DATA = txByte;
while (!(SPI0.INTFLAGS & SPI_IF_bm)) { /* wait */ }
return SPI0.DATA;
}
void SPI_TransferBuffer(const uint8_t *txBuf, uint8_t *rxBuf, uint16_t len) {
for (uint16_t i = 0; i < len; i++) {
uint8_t tx = (txBuf != nullptr) ? txBuf[i] : 0x00;
uint8_t rx = SPI_TransferByte(tx);
if (rxBuf != nullptr) rxBuf[i] = rx;
}
}
void SPI_Write(const uint8_t *data, uint16_t len) {
SPI_CS_Assert();
SPI_TransferBuffer(data, nullptr, len);
SPI_CS_Deassert();
}
void SPI_Read(uint8_t *buf, uint16_t len) {
SPI_CS_Assert();
SPI_TransferBuffer(nullptr, buf, len);
SPI_CS_Deassert();
}