Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
3f45eb5
define sercom transaction structure for enqueueing async transactions.
crabel99 Jan 28, 2026
de24356
provide unified structure for maintaining and accessing sercom protoc…
crabel99 Jan 28, 2026
2c9e540
add support for mux pin deconfliction during development.
crabel99 Jan 28, 2026
86ee1c4
integrate needed dma sercom structure into the SERCOM class
crabel99 Jan 28, 2026
82b1d3a
refactored initMaster/SlaveWIRE() to support rapid swapping of roles …
crabel99 Jan 29, 2026
b0d39fd
generalize RingBuffer to support any type not just uint8_t while pres…
crabel99 Jan 29, 2026
3586cf6
refactored stopTransmissionWIRE to support DMA and async operations, …
crabel99 Jan 29, 2026
7a353b0
add 10-bit address support for client operations
crabel99 Jan 29, 2026
b0fbebc
finish implementing wire async and dma callback structure and inlinin…
crabel99 Jan 30, 2026
a956137
add async and automatic dma support for client mode operations.
crabel99 Jan 31, 2026
6c58fd5
refactor SPI to use SERCOM dma implementation
crabel99 Feb 1, 2026
10b86e3
stage more UART DMA structure
crabel99 Feb 15, 2026
6e6d303
unify structure between different sercoms to mirror each other more c…
crabel99 Feb 15, 2026
18a3924
get sercom's wire protocol working in master mode
crabel99 Feb 15, 2026
66c1ff7
clean up SPI
crabel99 Feb 15, 2026
430e8bf
finish refactor of Wire to fully use async SERCOM
crabel99 Feb 15, 2026
51e0dd5
master wire fully tested sync/async
crabel99 Feb 17, 2026
d5d0430
test SPI sync and async operations
crabel99 Feb 17, 2026
6bb67bc
high level testing no hardware testing done on UART
crabel99 Feb 17, 2026
9370d6a
refactor to use async sercom api's
crabel99 Feb 17, 2026
c4bc1bd
samd datasheet multiplexing tables as csv
crabel99 Feb 17, 2026
f4fc47a
script to generate wire sercom specific pin assignments can be used …
crabel99 Feb 17, 2026
c10a922
Merge upstream master - version bump and submodule updates
crabel99 Feb 17, 2026
12f886b
Fix CI build errors
crabel99 Feb 17, 2026
694b1d2
Make SPI interrupt handlers weak and fix example ambiguity
crabel99 Feb 17, 2026
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
91 changes: 63 additions & 28 deletions cores/arduino/RingBuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#define _RING_BUFFER_

#include <stdint.h>
#include <type_traits>

// Define constants and variables for buffering incoming serial data. We're
// using a ring buffer (I think), in which head is the index of the location
Expand All @@ -32,16 +33,19 @@
#define SERIAL_BUFFER_SIZE 350
#endif

template <int N>
template <int N, typename T = uint8_t>
class RingBufferN
{
public:
uint8_t _aucBuffer[N] ;
T _aucBuffer[N] ;
volatile int _iHead ;
volatile int _iTail ;

public:
RingBufferN( void ) ;
bool store( const T& c ) ;
bool read( T& out ) ;
bool peek( T& out ) const ;
void store_char( uint8_t c ) ;
void clear();
int read_char();
Expand All @@ -57,15 +61,16 @@ class RingBufferN
typedef RingBufferN<SERIAL_BUFFER_SIZE> RingBuffer;


template <int N>
RingBufferN<N>::RingBufferN( void )
template <int N, typename T>
RingBufferN<N, T>::RingBufferN( void )
{
memset( _aucBuffer, 0, N ) ;
for (int i = 0; i < N; ++i)
_aucBuffer[i] = T{};
clear();
}

template <int N>
void RingBufferN<N>::store_char( uint8_t c )
template <int N, typename T>
bool RingBufferN<N, T>::store( const T& c )
{
int i = nextIndex(_iHead);

Expand All @@ -77,30 +82,58 @@ void RingBufferN<N>::store_char( uint8_t c )
{
_aucBuffer[_iHead] = c ;
_iHead = i ;
return true;
}
return false;
}

template <int N>
void RingBufferN<N>::clear()
template <int N, typename T>
bool RingBufferN<N, T>::read( T& out )
{
_iHead = 0;
_iTail = 0;
if(_iTail == _iHead)
return false;

out = _aucBuffer[_iTail];
_iTail = nextIndex(_iTail);
return true;
}

template <int N>
int RingBufferN<N>::read_char()
template <int N, typename T>
bool RingBufferN<N, T>::peek( T& out ) const
{
if(_iTail == _iHead)
return -1;
return false;

uint8_t value = _aucBuffer[_iTail];
_iTail = nextIndex(_iTail);
out = _aucBuffer[_iTail];
return true;
}

template <int N, typename T>
void RingBufferN<N, T>::store_char( uint8_t c )
{
static_assert(std::is_same<T, uint8_t>::value, "store_char only valid for uint8_t buffers");
(void)store(static_cast<T>(c));
}

template <int N, typename T>
void RingBufferN<N, T>::clear()
{
_iHead = 0;
_iTail = 0;
}

template <int N, typename T>
int RingBufferN<N, T>::read_char()
{
static_assert(std::is_same<T, uint8_t>::value, "read_char only valid for uint8_t buffers");
uint8_t value;
if (!read(value))
return -1;
return value;
}

template <int N>
int RingBufferN<N>::available()
template <int N, typename T>
int RingBufferN<N, T>::available()
{
int delta = _iHead - _iTail;

Expand All @@ -110,32 +143,34 @@ int RingBufferN<N>::available()
return delta;
}

template <int N>
int RingBufferN<N>::availableForStore()
template <int N, typename T>
int RingBufferN<N, T>::availableForStore()
{
if (_iHead >= _iTail)
return N - 1 - _iHead + _iTail;
else
return _iTail - _iHead - 1;
}

template <int N>
int RingBufferN<N>::peek()
template <int N, typename T>
int RingBufferN<N, T>::peek()
{
if(_iTail == _iHead)
static_assert(std::is_same<T, uint8_t>::value, "peek() only valid for uint8_t buffers");
uint8_t value;
if (!peek(value))
return -1;

return _aucBuffer[_iTail];
return value;
}

template <int N>
int RingBufferN<N>::nextIndex(int index)
template <int N, typename T>
int RingBufferN<N, T>::nextIndex(int index)
{
return (uint32_t)(index + 1) % N;
}

template <int N>
bool RingBufferN<N>::isFull()
template <int N, typename T>
bool RingBufferN<N, T>::isFull()
{
return (nextIndex(_iHead) == _iTail);
}
Expand Down
Loading