Skip to content

Commit

Permalink
Implement 16-bit registers which use AtomicGuards to protect 16-bit r…
Browse files Browse the repository at this point in the history
…egister access
  • Loading branch information
cmnrd committed Jan 26, 2015
1 parent a619389 commit 0997bdf
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 8 deletions.
6 changes: 3 additions & 3 deletions include/yalla/avr/iomm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ namespace yalla
/**
* A static pointer that provides read and write access to the I/O Memory Space.
*
* When reading or writing types with size greater than 1 byte interrupts have
* to be disabled to guarantee atomic access.
*
* @tparam T type that is used for read and write access
* @tparam addr the address this pointer points to (absolute memory address)
*
* TODO for types larger than 1 byte interrupts need to be disabled on each
* write and read access.
*/
template<typename T, addr_t addr>
class IOMMPtr
Expand Down
86 changes: 81 additions & 5 deletions include/yalla/avr/register.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@

#include <avr/iomm.hpp>
#include <inline.hpp>
#include <inttypes.hpp>
#include <util/atomic.hpp>

namespace yalla
{
Expand All @@ -46,20 +48,94 @@ namespace yalla
* @tparam addr Address of the register.
*/
template<addr_t addr>
struct DataRegister : public IOMMPtr<uint8_t, addr>
{};
class DataRegister : public IOMMPtr<uint8_t, addr>
{
private:
/// Alias for the IOMMPtr
using Ptr = IOMMPtr<uint8_t, addr>;

public:
/**
* Write a 8-bit integer to the register.
*
* @param v value to be written
*/
static INLINE void write(uint8_t v) { Ptr::write(v); }

/**
* Read a 8-bit integer from the register.
*
* @return value read from register
*/
static INLINE uint8_t read() { return Ptr::read(); }
};

/**
* Simple wrapper for a IOMMPtr. Represents a 16-bit io data register.
*
* In contrast to a Register a DataRegister is represented only by a 16-bit value
* In contrast to a Register a DataRegister16 is represented only by a 16-bit value
* and is not a set of individual bits.
*
* @tparam addr Address of the register.
*/
template<addr_t addr>
struct DataRegister16 : public IOMMPtr<uint16_t, addr>
{};
class DataRegister16
{
private:
/// Alias for the IOMMPtr
using Ptr = IOMMPtr<uint16_t, addr>;

public:
/**
* Write a 16-bit integer to the register.
*
* This method always disables interrupts and restores status of the interrupt
* flag after the write operation is performed. If interrupts are always
* disabeled when this method is called, write_unsafe(uint8_t) can be used for
* more efficient write access.
*
* @param v value to be written
*/
static INLINE void write(uint8_t v)

This comment has been minimized.

Copy link
@salkinium

salkinium Mar 6, 2015

Shouldn't write and read have uint16_t as argument type?

This comment has been minimized.

Copy link
@cmnrd

cmnrd Mar 9, 2015

Author Owner

Yes, thanks for pointing it out!

{
auto guard = AtomicGuard<AtomicPolicy::RestoreState>();
Ptr::write(v);
}

/**
* Read a 16-bit integer from the register.
*
* This method always disables interrupts and restores status of the interrupt
* flag after the read operation is performed. If interrupts are always
* disabeled when this method is called, read_unsafe() can be used for
* more efficient read access.
*
* @return value read from register
*/
static INLINE uint8_t read()
{
auto guard = AtomicGuard<AtomicPolicy::RestoreState>();
return Ptr::read();
}

/**
* Directly write a 16-bit integer to the register.
*
* Interrupts must be disabled when this method is called!
*
* @param v value to be written
*/
static INLINE void write_unsafe(uint8_t v) { Ptr::write(v); }

/**
* Directly read a 16-bit integer from the register.
*
* Interrupts must be disabled when this method is called!
*
* @return value read from register
*/
static INLINE uint8_t read_unsafe() { return Ptr::read(); }
};

/**
* Represents a 8-bit io register that is assembled from 8 individual bits.
Expand Down
6 changes: 6 additions & 0 deletions include/yalla/device/atmega8/avr/io.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,12 @@ using PORTC2 = PORTC::Bit2;
using PORTC1 = PORTC::Bit1;
using PORTC0 = PORTC::Bit0;

// ... TODO

using ADCH = DataRegister<0x25>;
using ADCL = DataRegister<0x24>;
using ADC = DataRegister16<0x24>;

// ... TODO

} // namespace lunacy

0 comments on commit 0997bdf

Please sign in to comment.