Skip to content

Commit

Permalink
feat: add Immediate and Dispatched interrupt handling to DmaStm's Str…
Browse files Browse the repository at this point in the history
…eamInterruptHandler via tag dispatching (#336)
  • Loading branch information
daantimmer authored Jun 12, 2024
1 parent bca8097 commit 736df80
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 15 deletions.
47 changes: 38 additions & 9 deletions hal_st/stm32fxxx/DmaStm.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "hal_st/stm32fxxx/DmaStm.hpp"
#include "hal_st/cortex/InterruptCortex.hpp"
#include "infra/util/ByteRange.hpp"
#include "infra/util/Optional.hpp"

#if !defined(STM32F0) && !defined(STM32F1) && !defined(STM32F3)

Expand Down Expand Up @@ -785,12 +787,26 @@ namespace hal
return (data.size() - BytesToTransfer()) / DataSize();
}

DmaStm::StreamInterruptHandler::StreamInterruptHandler(Stream& stream, const infra::Function<void()>& transferFullComplete)
DmaStm::StreamInterruptHandler::StreamInterruptHandler(Stream& stream, const infra::Function<void()>& transferFullComplete, Dispatched)
: stream{ stream }
, dispatchedInterruptHandler{ dmaIrq[stream.dmaIndex][stream.streamIndex], [this]
, interruptHandler{ infra::InPlaceType<DispatchedInterruptHandler>{}, dmaIrq[stream.dmaIndex][stream.streamIndex], [this]
{
OnInterrupt();
} }
, interruptHandlerHandle{ &interruptHandler.Get<DispatchedInterruptHandler>() }
, transferFullComplete{ transferFullComplete }
{
stream.DisableCircularMode();
stream.EnableTransferCompleteInterrupt();
}

DmaStm::StreamInterruptHandler::StreamInterruptHandler(Stream& stream, const infra::Function<void()>& transferFullComplete, Immediate)
: stream{ stream }
, interruptHandler{ infra::InPlaceType<ImmediateInterruptHandler>{}, dmaIrq[stream.dmaIndex][stream.streamIndex], [this]
{
OnInterrupt();
} }
, interruptHandlerHandle{ &interruptHandler.Get<ImmediateInterruptHandler>() }
, transferFullComplete{ transferFullComplete }
{
stream.DisableCircularMode();
Expand All @@ -807,7 +823,7 @@ namespace hal

__DMB();

dispatchedInterruptHandler.ClearPending();
interruptHandlerHandle->ClearPending();
transferFullComplete();
}
}
Expand Down Expand Up @@ -918,17 +934,30 @@ namespace hal
peripheralStream.StartReceiveDummy(size, dataSize);
}

TransceiverDmaChannel::TransceiverDmaChannel(DmaStm::TransceiveStream& stream, volatile void* peripheralAddress, uint8_t peripheralTransferSize, const infra::Function<void()>& transferFullComplete)
TransceiverDmaChannel::TransceiverDmaChannel(DmaStm::TransceiveStream& stream, volatile void* peripheralAddress, uint8_t peripheralTransferSize, const infra::Function<void()>& transferFullComplete, const DmaStm::StreamInterruptHandler::Dispatched& irqHandlerType)
: TransceiverDmaChannelBase{ stream, peripheralAddress, peripheralTransferSize }
, streamInterruptHandler{ stream, transferFullComplete, irqHandlerType }
{}

TransceiverDmaChannel::TransceiverDmaChannel(DmaStm::TransceiveStream& stream, volatile void* peripheralAddress, uint8_t peripheralTransferSize, const infra::Function<void()>& transferFullComplete, const DmaStm::StreamInterruptHandler::Immediate& irqHandlerType)
: TransceiverDmaChannelBase{ stream, peripheralAddress, peripheralTransferSize }
, streamInterruptHandler{ stream, transferFullComplete }
, streamInterruptHandler{ stream, transferFullComplete, irqHandlerType }
{}

TransmitDmaChannel::TransmitDmaChannel(DmaStm::TransmitStream& stream, volatile void* peripheralAddress, uint8_t peripheralTransferSize, const infra::Function<void()>& transferFullComplete, const DmaStm::StreamInterruptHandler::Dispatched& irqHandlerType)
: TransceiverDmaChannel{ stream, peripheralAddress, peripheralTransferSize, transferFullComplete, irqHandlerType }
{}

TransmitDmaChannel::TransmitDmaChannel(DmaStm::TransmitStream& stream, volatile void* peripheralAddress, uint8_t peripheralTransferSize, const infra::Function<void()>& transferFullComplete, const DmaStm::StreamInterruptHandler::Immediate& irqHandlerType)
: TransceiverDmaChannel{ stream, peripheralAddress, peripheralTransferSize, transferFullComplete, irqHandlerType }
{}

TransmitDmaChannel::TransmitDmaChannel(DmaStm::TransmitStream& stream, volatile void* peripheralAddress, uint8_t peripheralTransferSize, const infra::Function<void()>& transferFullComplete)
: TransceiverDmaChannel{ stream, peripheralAddress, peripheralTransferSize, transferFullComplete }
ReceiveDmaChannel::ReceiveDmaChannel(DmaStm::ReceiveStream& stream, volatile void* peripheralAddress, uint8_t peripheralTransferSize, const infra::Function<void()>& transferFullComplete, const DmaStm::StreamInterruptHandler::Dispatched& irqHandlerType)
: TransceiverDmaChannel{ stream, peripheralAddress, peripheralTransferSize, transferFullComplete, irqHandlerType }
{}

ReceiveDmaChannel::ReceiveDmaChannel(DmaStm::ReceiveStream& stream, volatile void* peripheralAddress, uint8_t peripheralTransferSize, const infra::Function<void()>& transferFullComplete)
: TransceiverDmaChannel{ stream, peripheralAddress, peripheralTransferSize, transferFullComplete }
ReceiveDmaChannel::ReceiveDmaChannel(DmaStm::ReceiveStream& stream, volatile void* peripheralAddress, uint8_t peripheralTransferSize, const infra::Function<void()>& transferFullComplete, const DmaStm::StreamInterruptHandler::Immediate& irqHandlerType)
: TransceiverDmaChannel{ stream, peripheralAddress, peripheralTransferSize, transferFullComplete, irqHandlerType }
{}

CircularTransceiverDmaChannel::CircularTransceiverDmaChannel(DmaStm::TransceiveStream& stream, volatile void* peripheralAddress, uint8_t peripheralTransferSize, const infra::Function<void()>& transferHalfComplete, const infra::Function<void()>& transferFullComplete)
Expand Down
28 changes: 22 additions & 6 deletions hal_st/stm32fxxx/DmaStm.hpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
#ifndef HAL_DMA_STM_HPP
#define HAL_DMA_STM_HPP

#include DEVICE_HEADER
#include "hal_st/cortex/InterruptCortex.hpp"
#include "infra/util/ByteRange.hpp"
#include "infra/util/Function.hpp"
#include "infra/util/MemoryRange.hpp"
#include "infra/util/Variant.hpp"
#include <cstdint>

#include DEVICE_HEADER

namespace hal
{
#if defined(STM32G0) || defined(STM32G4) || defined(STM32WB) || defined(STM32WBA)
Expand Down Expand Up @@ -164,14 +166,25 @@ namespace hal
class StreamInterruptHandler
{
public:
StreamInterruptHandler(Stream& stream, const infra::Function<void()>& transferFullComplete);
struct Immediate
{};

struct Dispatched
{};

static inline constexpr Immediate immediate{};
static inline constexpr Dispatched dispatched{};

StreamInterruptHandler(Stream& stream, const infra::Function<void()>& transferFullComplete, Dispatched = {});
StreamInterruptHandler(Stream& stream, const infra::Function<void()>& transferFullComplete, Immediate);

private:
void OnInterrupt();

Stream& stream;

DispatchedInterruptHandler dispatchedInterruptHandler;
infra::Variant<DispatchedInterruptHandler, ImmediateInterruptHandler> interruptHandler;
InterruptHandler* interruptHandlerHandle;

infra::Function<void()> transferFullComplete;
};
Expand Down Expand Up @@ -282,7 +295,8 @@ namespace hal
: public TransceiverDmaChannelBase
{
public:
TransceiverDmaChannel(DmaStm::TransceiveStream& receiveStream, volatile void* peripheralAddress, uint8_t peripheralTransferSize, const infra::Function<void()>& transferFullComplete);
TransceiverDmaChannel(DmaStm::TransceiveStream& receiveStream, volatile void* peripheralAddress, uint8_t peripheralTransferSize, const infra::Function<void()>& transferFullComplete, const DmaStm::StreamInterruptHandler::Dispatched& irqHandlerType = {});
TransceiverDmaChannel(DmaStm::TransceiveStream& receiveStream, volatile void* peripheralAddress, uint8_t peripheralTransferSize, const infra::Function<void()>& transferFullComplete, const DmaStm::StreamInterruptHandler::Immediate& irqHandlerType);

private:
DmaStm::StreamInterruptHandler streamInterruptHandler;
Expand All @@ -292,7 +306,8 @@ namespace hal
: private TransceiverDmaChannel
{
public:
TransmitDmaChannel(DmaStm::TransmitStream& transmitStream, volatile void* peripheralAddress, uint8_t peripheralTransferSize, const infra::Function<void()>& transferFullComplete);
TransmitDmaChannel(DmaStm::TransmitStream& transmitStream, volatile void* peripheralAddress, uint8_t peripheralTransferSize, const infra::Function<void()>& transferFullComplete, const DmaStm::StreamInterruptHandler::Dispatched& irqHandlerType = {});
TransmitDmaChannel(DmaStm::TransmitStream& transmitStream, volatile void* peripheralAddress, uint8_t peripheralTransferSize, const infra::Function<void()>& transferFullComplete, const DmaStm::StreamInterruptHandler::Immediate& irqHandlerType);

using TransceiverDmaChannel::SetPeripheralTransferSize;
using TransceiverDmaChannel::StopTransfer;
Expand All @@ -310,7 +325,8 @@ namespace hal
: private TransceiverDmaChannel
{
public:
ReceiveDmaChannel(DmaStm::ReceiveStream& receiveStream, volatile void* peripheralAddress, uint8_t peripheralTransferSize, const infra::Function<void()>& transferFullComplete);
ReceiveDmaChannel(DmaStm::ReceiveStream& receiveStream, volatile void* peripheralAddress, uint8_t peripheralTransferSize, const infra::Function<void()>& transferFullComplete, const DmaStm::StreamInterruptHandler::Dispatched& irqHandlerType = {});
ReceiveDmaChannel(DmaStm::ReceiveStream& receiveStream, volatile void* peripheralAddress, uint8_t peripheralTransferSize, const infra::Function<void()>& transferFullComplete, const DmaStm::StreamInterruptHandler::Immediate& irqHandlerType);

using TransceiverDmaChannel::SetPeripheralTransferSize;
using TransceiverDmaChannel::StopTransfer;
Expand Down

0 comments on commit 736df80

Please sign in to comment.