Compare commits

..

24 Commits

Author SHA1 Message Date
314e1d20ab Updated compiler settings 2020-02-01 22:44:01 +01:00
b8ea05597f Changed toolchain to gcc v9 2020-02-01 22:38:15 +01:00
52d964d8e7 Updated submodule 2020-02-01 22:29:05 +01:00
820a2813d1 Updated example to show virtual port usage 2020-02-01 22:15:49 +01:00
afbb1d0423 Updated submodule and added MIT license file 2020-02-01 15:28:41 +01:00
f7753a0cf9 Updated project and submodule 2019-08-15 17:38:49 +02:00
f6613f662a Updated submodule 2019-08-10 13:59:00 +02:00
ac7a909c20 Fixed submodule url 2019-08-02 19:35:59 +02:00
69bca8c08f Updated submodule 2019-07-28 14:01:48 +02:00
5c0f29e452 Updated project file 2019-07-26 18:57:56 +02:00
d1da327558 Fixed outdated submodule path 2019-07-26 18:54:22 +02:00
04c1401a9c Finished example implementation using new library 2019-07-26 18:50:26 +02:00
e95f936321 Added clock config 2019-07-26 14:07:20 +02:00
9519f3a444 Included new library 2019-07-26 14:02:12 +02:00
b3c111dc89 Added io submodule 2019-07-26 13:56:52 +02:00
171aa72b2e Removed old example 2019-07-26 13:55:35 +02:00
a5761ab5db Added clang-format and removed submodule 2019-07-26 13:48:54 +02:00
fb6003eaa3 Adapted example to new shortened function names 2018-04-26 16:03:45 +02:00
08b69f70d7 Adapted example to new interface 2018-04-26 15:24:10 +02:00
b438aac91d Exported library to submodule branch and adapted example 2018-04-26 13:45:23 +02:00
79741c300b Merged changes from submodule branch 2016-10-29 16:47:56 +02:00
103e8698bf Changed Atmel Studio project files 2016-05-24 20:38:32 +02:00
9e1a0d8a2e Removed trailing newlines 2016-05-24 20:13:39 +02:00
065f21440c Renamed project to lowercase 2016-05-24 19:40:08 +02:00
8 changed files with 472 additions and 430 deletions

3
.gitmodules vendored Normal file
View File

@@ -0,0 +1,3 @@
[submodule "io/io"]
path = io/io
url = git@git.blackmark.me:avr/io.git

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2019 BlackMark
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

22
io.atsln Normal file
View File

@@ -0,0 +1,22 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Atmel Studio Solution File, Format Version 11.00
VisualStudioVersion = 14.0.23107.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{E66E83B9-2572-4076-B26E-6BE79FF3018A}") = "io", "io\io.cppproj", "{DCE6C7E3-EE26-4D79-826B-08594B9AD897}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|AVR = Debug|AVR
Release|AVR = Release|AVR
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{DCE6C7E3-EE26-4D79-826B-08594B9AD897}.Debug|AVR.ActiveCfg = Debug|AVR
{DCE6C7E3-EE26-4D79-826B-08594B9AD897}.Debug|AVR.Build.0 = Debug|AVR
{DCE6C7E3-EE26-4D79-826B-08594B9AD897}.Release|AVR.ActiveCfg = Release|AVR
{DCE6C7E3-EE26-4D79-826B-08594B9AD897}.Release|AVR.Build.0 = Release|AVR
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

430
io.hpp
View File

@@ -1,430 +0,0 @@
#pragma once
#include <stdint.h>
#include <avr/io.h>
#include <avr/sfr_defs.h>
//////////////////////////////////////////////////////////////////////////
// Preprocessor defines
#if defined(__AVR_ATmega32__) || defined(__AVR_ATmega32A__) || defined(__AVR_ATmega644P__) || \
defined(__AVR_ATmega1284P__)
#define GPIO_32
#endif
#if defined(__AVR_ATmega8__) || defined(__AVR_ATmega8A__) || defined(__AVR_ATmega168A__) || defined(__AVR_ATmega328P__)
#define GPIO_23
#endif
#if defined(__AVR_ATtiny13A__) || defined(__AVR_ATtiny85__)
#define GPIO_6
#endif
#if defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega168A__) || \
defined(__AVR_ATmega328P__) || defined(__AVR_ATtiny13A__) || defined(__AVR_ATtiny85__)
#define HARDWARE_TOGGLE
#endif
#ifdef GPIO_32
#define PORT_A_AVAILABLE
#endif
#if defined(GPIO_32) || defined(GPIO_23) || defined(GPIO_6)
#define PORT_B_AVAILABLE
#endif
#if defined(GPIO_32) || defined(GPIO_23)
#define PORT_C_AVAILABLE
#define PORT_D_AVAILABLE
#define PIN_B6_AVAILABLE
#define PIN_B7_AVAILABLE
#endif
#if defined(GPIO_32)
#define PIN_C7_AVAILABLE
#endif
#define FORCE_INLINE __attribute__((always_inline))
//////////////////////////////////////////////////////////////////////////
// Library implementation
namespace io {
enum class Dir { IN, OUT };
enum class P {
#ifdef PORT_A_AVAILABLE
A0 = 0x00,
A1 = 0x01,
A2 = 0x02,
A3 = 0x03,
A4 = 0x04,
A5 = 0x05,
A6 = 0x06,
A7 = 0x07,
#endif
#ifdef PORT_B_AVAILABLE
B0 = 0x10,
B1 = 0x11,
B2 = 0x12,
B3 = 0x13,
B4 = 0x14,
B5 = 0x15,
#ifdef PIN_B6_AVAILABLE
B6 = 0x16,
#endif
#ifdef PIN_B7_AVAILABLE
B7 = 0x17,
#endif
#endif
#ifdef PORT_C_AVAILABLE
C0 = 0x20,
C1 = 0x21,
C2 = 0x22,
C3 = 0x23,
C4 = 0x24,
C5 = 0x25,
C6 = 0x26,
#ifdef PIN_C7_AVAILABLE
C7 = 0x27,
#endif
#endif
#ifdef PORT_D_AVAILABLE
D0 = 0x30,
D1 = 0x31,
D2 = 0x32,
D3 = 0x33,
D4 = 0x34,
D5 = 0x35,
D6 = 0x36,
D7 = 0x37,
#endif
};
enum class Bus {
#ifdef PORT_A_AVAILABLE
A = 0x00,
#endif
#ifdef PORT_B_AVAILABLE
B = 0x01,
#endif
#ifdef PORT_C_AVAILABLE
C = 0x02,
#endif
#ifdef PORT_D_AVAILABLE
D = 0x03,
#endif
};
//////////////////////////////////////////////////////////////////////////
// Implementation details
namespace detail {
/*
The following works in avr-gcc 5.4.0, but is not legal C++, because ptr's are not legal constexpr's
constexpr auto *foo = ptr;
Workaround is to store the the address of the ptr in a uintptr_t and reinterpret_cast it at call site
For this to work we need to temporarily disable the _SFR_IO8 macro so that the register macro just gives the address
*/
#undef _SFR_IO8
#define _SFR_IO8
#ifdef PORT_A_AVAILABLE
static constexpr uintptr_t PORT_A_DIR_REG_ADDR = DDRA + __SFR_OFFSET;
static constexpr uintptr_t PORT_A_OUTPUT_REG_ADDR = PORTA + __SFR_OFFSET;
static constexpr uintptr_t PORT_A_INPUT_REG_ADDR = PINA + __SFR_OFFSET;
#else
static constexpr uintptr_t PORT_A_DIR_REG_ADDR = 0;
static constexpr uintptr_t PORT_A_OUTPUT_REG_ADDR = 0;
static constexpr uintptr_t PORT_A_INPUT_REG_ADDR = 0;
#endif
#ifdef PORT_B_AVAILABLE
static constexpr uintptr_t PORT_B_DIR_REG_ADDR = DDRB + __SFR_OFFSET;
static constexpr uintptr_t PORT_B_OUTPUT_REG_ADDR = PORTB + __SFR_OFFSET;
static constexpr uintptr_t PORT_B_INPUT_REG_ADDR = PINB + __SFR_OFFSET;
#else
static constexpr uintptr_t PORT_B_DIR_REG_ADDR = 0;
static constexpr uintptr_t PORT_B_OUTPUT_REG_ADDR = 0;
static constexpr uintptr_t PORT_B_INPUT_REG_ADDR = 0;
#endif
#ifdef PORT_C_AVAILABLE
static constexpr uintptr_t PORT_C_DIR_REG_ADDR = DDRC + __SFR_OFFSET;
static constexpr uintptr_t PORT_C_OUTPUT_REG_ADDR = PORTC + __SFR_OFFSET;
static constexpr uintptr_t PORT_C_INPUT_REG_ADDR = PINC + __SFR_OFFSET;
#else
static constexpr uintptr_t PORT_C_DIR_REG_ADDR = 0;
static constexpr uintptr_t PORT_C_OUTPUT_REG_ADDR = 0;
static constexpr uintptr_t PORT_C_INPUT_REG_ADDR = 0;
#endif
#ifdef PORT_D_AVAILABLE
static constexpr uintptr_t PORT_D_DIR_REG_ADDR = DDRD + __SFR_OFFSET;
static constexpr uintptr_t PORT_D_OUTPUT_REG_ADDR = PORTD + __SFR_OFFSET;
static constexpr uintptr_t PORT_D_INPUT_REG_ADDR = PIND + __SFR_OFFSET;
#else
static constexpr uintptr_t PORT_D_DIR_REG_ADDR = 0;
static constexpr uintptr_t PORT_D_OUTPUT_REG_ADDR = 0;
static constexpr uintptr_t PORT_D_INPUT_REG_ADDR = 0;
#endif
#undef _SFR_IO8
#define _SFR_IO8(io_addr) _MMIO_BYTE((io_addr) + __SFR_OFFSET)
static constexpr auto getBus(const P pin)
{
// Upper 4 bits of pin encode which port this pin is on
uint8_t port = static_cast<uint8_t>(pin) >> 4 & 0x0F;
return static_cast<Bus>(port);
}
static constexpr auto getPinBit(const P pin)
{
// Lower 4 bits of pin encode which pin bit it is
uint8_t pinBit = static_cast<uint8_t>(pin) & 0x0F;
return pinBit;
}
static constexpr auto getDDR(const Bus bus)
{
switch (static_cast<uint8_t>(bus)) {
case 0: // Bus::A
return PORT_A_DIR_REG_ADDR;
case 1: // Bus::B
return PORT_B_DIR_REG_ADDR;
case 2: // Bus::C
return PORT_C_DIR_REG_ADDR;
case 3: // Bus::D
return PORT_D_DIR_REG_ADDR;
}
}
static constexpr auto getPORT(const Bus bus)
{
switch (static_cast<uint8_t>(bus)) {
case 0: // Bus::A
return PORT_A_OUTPUT_REG_ADDR;
case 1: // Bus::B
return PORT_B_OUTPUT_REG_ADDR;
case 2: // Bus::C
return PORT_C_OUTPUT_REG_ADDR;
case 3: // Bus::D
return PORT_D_OUTPUT_REG_ADDR;
}
}
static constexpr auto getPIN(const Bus bus)
{
switch (static_cast<uint8_t>(bus)) {
case 0: // Bus::A
return PORT_A_INPUT_REG_ADDR;
case 1: // Bus::B
return PORT_B_INPUT_REG_ADDR;
case 2: // Bus::C
return PORT_C_INPUT_REG_ADDR;
case 3: // Bus::D
return PORT_D_INPUT_REG_ADDR;
}
}
using reg_ptr_t = volatile uint8_t *;
template <uintptr_t Address>
static inline reg_ptr_t getRegPtr()
{
return reinterpret_cast<reg_ptr_t>(Address);
}
} // namespace detail
//////////////////////////////////////////////////////////////////////////
// Zero overhead Pin object for pretty code without losing performance
template <P pin>
class Pin {
public:
// Pin objects cannot be moved or copied
Pin(const Pin &) = delete;
Pin(Pin &&) = delete;
Pin &operator=(const Pin &) = delete;
Pin &operator=(Pin &&) = delete;
// The only valid way to create a Pin object is with the default constructor
Pin() = default;
static inline void dir(const Dir dir) FORCE_INLINE
{
constexpr auto bus = detail::getBus(pin);
constexpr auto pinBit = detail::getPinBit(pin);
detail::reg_ptr_t dirRegPtr = detail::getRegPtr<detail::getDDR(bus)>();
if (dir == Dir::IN)
*dirRegPtr &= ~(1 << pinBit);
else if (dir == Dir::OUT)
*dirRegPtr |= (1 << pinBit);
}
static inline void pullup(const bool enable) FORCE_INLINE
{
constexpr auto bus = detail::getBus(pin);
constexpr auto pinBit = detail::getPinBit(pin);
detail::reg_ptr_t portRegPtr = detail::getRegPtr<detail::getPORT(bus)>();
if (enable)
*portRegPtr |= (1 << pinBit);
else
*portRegPtr &= ~(1 << pinBit);
}
static inline void write(const bool value) FORCE_INLINE
{
constexpr auto bus = detail::getBus(pin);
constexpr auto pinBit = detail::getPinBit(pin);
detail::reg_ptr_t portRegPtr = detail::getRegPtr<detail::getPORT(bus)>();
if (value)
*portRegPtr |= (1 << pinBit);
else
*portRegPtr &= ~(1 << pinBit);
}
static inline void toggle() FORCE_INLINE
{
constexpr auto bus = detail::getBus(pin);
constexpr auto pinBit = detail::getPinBit(pin);
#ifdef HARDWARE_TOGGLE
detail::reg_ptr_t pinRegPtr = detail::getRegPtr<detail::getPIN(bus)>();
*pinRegPtr |= (1 << pinBit);
#else
detail::reg_ptr_t portRegPtr = detail::getRegPtr<detail::getPORT(bus)>();
*portRegPtr ^= (1 << pinBit);
#endif
}
static inline bool read() FORCE_INLINE
{
constexpr auto bus = detail::getBus(pin);
constexpr auto pinBit = detail::getPinBit(pin);
detail::reg_ptr_t pinRegPtr = detail::getRegPtr<detail::getPIN(bus)>();
if (*pinRegPtr >> pinBit & 1)
return true;
return false;
}
Pin &operator=(const bool value) FORCE_INLINE
{
write(value);
return *this;
}
operator bool() const FORCE_INLINE
{
return read();
}
};
//////////////////////////////////////////////////////////////////////////
// Zero overhead Port object for pretty code without losing performance
template <Bus port>
class Port {
public:
// Port objects cannot be moved or copied
Port(const Port &) = delete;
Port(Port &&) = delete;
Port &operator=(const Port &) = delete;
Port &operator=(Port &&) = delete;
// The only valid way to create a Port object is with the default constructor
Port() = default;
static inline void dir(const Dir dir) FORCE_INLINE
{
detail::reg_ptr_t dirRegPtr = detail::getRegPtr<detail::getDDR(port)>();
if (dir == Dir::IN)
*dirRegPtr = 0x00;
else if (dir == Dir::OUT)
*dirRegPtr = 0xFF;
}
static inline void pullup(const bool enable) FORCE_INLINE
{
detail::reg_ptr_t portRegPtr = detail::getRegPtr<detail::getPORT(port)>();
if (enable)
*portRegPtr = 0xFF;
else
*portRegPtr = 0x00;
}
static inline void write(const uint8_t value) FORCE_INLINE
{
detail::reg_ptr_t portRegPtr = detail::getRegPtr<detail::getPORT(port)>();
*portRegPtr = value;
}
static inline void invert() FORCE_INLINE
{
#ifdef HARDWARE_TOGGLE
detail::reg_ptr_t pinRegPtr = detail::getRegPtr<detail::getPIN(port)>();
*pinRegPtr = 0xFF;
#else
detail::reg_ptr_t portRegPtr = detail::getRegPtr<detail::getPORT(port)>();
*portRegPtr = ~(*portRegPtr);
#endif
}
static inline uint8_t read() FORCE_INLINE
{
detail::reg_ptr_t pinRegPtr = detail::getRegPtr<detail::getPIN(port)>();
return *pinRegPtr;
}
inline Port &operator=(const uint8_t value) FORCE_INLINE
{
write(value);
return *this;
}
inline operator uint8_t() const FORCE_INLINE
{
return read();
}
};
} // namespace io
//////////////////////////////////////////////////////////////////////////
#undef GPIO_32
#undef GPIO_23
#undef GPIO_6
#undef PORT_A_AVAILABLE
#undef PORT_B_AVAILABLE
#undef PORT_C_AVAILABLE
#undef PORT_D_AVAILABLE
#undef PIN_B6_AVAILABLE
#undef PIN_B7_AVAILABLE
#undef PIN_C7_AVAILABLE
#undef FORCE_INLINE

4
io/clock.hpp Normal file
View File

@@ -0,0 +1,4 @@
#pragma once
#define F_CPU 16000000
#include <util/delay.h>

1
io/io Submodule

Submodule io/io added at 80de36ee7e

220
io/io.cppproj Normal file
View File

@@ -0,0 +1,220 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="14.0">
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
<ProjectVersion>7.0</ProjectVersion>
<ToolchainName>com.Atmel.AVRGCC8.CPP</ToolchainName>
<ProjectGuid>dce6c7e3-ee26-4d79-826b-08594b9ad897</ProjectGuid>
<avrdevice>ATmega328P</avrdevice>
<avrdeviceseries>none</avrdeviceseries>
<OutputType>Executable</OutputType>
<Language>CPP</Language>
<OutputFileName>$(MSBuildProjectName)</OutputFileName>
<OutputFileExtension>.elf</OutputFileExtension>
<OutputDirectory>$(MSBuildProjectDirectory)\$(Configuration)</OutputDirectory>
<AssemblyName>io</AssemblyName>
<Name>io</Name>
<RootNamespace>io</RootNamespace>
<ToolchainFlavour>avr-g++-9.1.0</ToolchainFlavour>
<KeepTimersRunning>true</KeepTimersRunning>
<OverrideVtor>false</OverrideVtor>
<CacheFlash>true</CacheFlash>
<ProgFlashFromRam>true</ProgFlashFromRam>
<RamSnippetAddress>0x20000000</RamSnippetAddress>
<UncachedRange />
<preserveEEPROM>true</preserveEEPROM>
<OverrideVtorValue>exception_table</OverrideVtorValue>
<BootSegment>2</BootSegment>
<ResetRule>0</ResetRule>
<eraseonlaunchrule>0</eraseonlaunchrule>
<EraseKey />
<avrtool>com.atmel.avrdbg.tool.stk500</avrtool>
<avrtoolserialnumber>
</avrtoolserialnumber>
<avrdeviceexpectedsignature>0x1E950F</avrdeviceexpectedsignature>
<com_atmel_avrdbg_tool_jtagicemkii>
<ToolOptions>
<InterfaceProperties>
<IspClock>0</IspClock>
</InterfaceProperties>
<InterfaceName>ISP</InterfaceName>
</ToolOptions>
<ToolType>com.atmel.avrdbg.tool.jtagicemkii</ToolType>
<ToolNumber>070000004699</ToolNumber>
<ToolName>JTAGICE mkII</ToolName>
</com_atmel_avrdbg_tool_jtagicemkii>
<avrtoolinterface>ISP</avrtoolinterface>
<avrtoolinterfaceclock>125000</avrtoolinterfaceclock>
<AAFDebugger>
<AAFDebugFiles>
<DebugFile>
<path>\Debug\io.lss</path>
<AAFSetting>
<Label>Lss Files</Label>
<Extention>.lss</Extention>
<Regex>^\s*(?&lt;address&gt;[a-f0-9]*):\s*.*$</Regex>
<DebugEnabled>true</DebugEnabled>
<RegexGroups>address</RegexGroups>
<DebuggerExpression>$pc</DebuggerExpression>
</AAFSetting>
</DebugFile>
</AAFDebugFiles>
</AAFDebugger>
<AsfFrameworkConfig>
<framework-data xmlns="">
<options />
<configurations />
<files />
<documentation help="" />
<offline-documentation help="" />
<dependencies>
<content-extension eid="atmel.asf" uuidref="Atmel.ASF" version="3.46.0" />
</dependencies>
</framework-data>
</AsfFrameworkConfig>
<com_atmel_avrdbg_tool_stk500>
<ToolOptions>
<InterfaceProperties>
<IspClock>125000</IspClock>
</InterfaceProperties>
<InterfaceName>ISP</InterfaceName>
</ToolOptions>
<ToolType>com.atmel.avrdbg.tool.stk500</ToolType>
<ToolNumber>
</ToolNumber>
<ToolName>STK500</ToolName>
</com_atmel_avrdbg_tool_stk500>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<ToolchainSettings>
<AvrGccCpp>
<avrgcc.common.Device>-mmcu=atmega328p -B "%24(PackRepoDir)\Atmel\ATmega_DFP\1.3.300\gcc\dev\atmega328p"</avrgcc.common.Device>
<avrgcc.common.outputfiles.hex>True</avrgcc.common.outputfiles.hex>
<avrgcc.common.outputfiles.lss>True</avrgcc.common.outputfiles.lss>
<avrgcc.common.outputfiles.eep>True</avrgcc.common.outputfiles.eep>
<avrgcc.common.outputfiles.srec>True</avrgcc.common.outputfiles.srec>
<avrgcc.common.outputfiles.usersignatures>False</avrgcc.common.outputfiles.usersignatures>
<avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>
<avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>
<avrgcc.compiler.symbols.DefSymbols>
<ListValues>
<Value>NDEBUG</Value>
</ListValues>
</avrgcc.compiler.symbols.DefSymbols>
<avrgcc.compiler.directories.IncludePaths>
<ListValues>
<Value>%24(PackRepoDir)\Atmel\ATmega_DFP\1.3.300\include</Value>
</ListValues>
</avrgcc.compiler.directories.IncludePaths>
<avrgcc.compiler.optimization.level>Optimize for size (-Os)</avrgcc.compiler.optimization.level>
<avrgcc.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcc.compiler.optimization.AllocateBytesNeededForEnum>
<avrgcc.compiler.warnings.AllWarnings>True</avrgcc.compiler.warnings.AllWarnings>
<avrgcc.compiler.warnings.ExtraWarnings>True</avrgcc.compiler.warnings.ExtraWarnings>
<avrgcc.compiler.warnings.Pedantic>True</avrgcc.compiler.warnings.Pedantic>
<avrgcc.compiler.miscellaneous.OtherFlags>-fno-threadsafe-statics -std=c11</avrgcc.compiler.miscellaneous.OtherFlags>
<avrgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned>
<avrgcccpp.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcccpp.compiler.general.ChangeDefaultBitFieldUnsigned>
<avrgcccpp.compiler.symbols.DefSymbols>
<ListValues>
<Value>NDEBUG</Value>
</ListValues>
</avrgcccpp.compiler.symbols.DefSymbols>
<avrgcccpp.compiler.directories.IncludePaths>
<ListValues>
<Value>%24(PackRepoDir)\Atmel\ATmega_DFP\1.3.300\include</Value>
</ListValues>
</avrgcccpp.compiler.directories.IncludePaths>
<avrgcccpp.compiler.optimization.level>Optimize for size (-Os)</avrgcccpp.compiler.optimization.level>
<avrgcccpp.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcccpp.compiler.optimization.AllocateBytesNeededForEnum>
<avrgcccpp.compiler.warnings.AllWarnings>True</avrgcccpp.compiler.warnings.AllWarnings>
<avrgcccpp.compiler.warnings.Pedantic>True</avrgcccpp.compiler.warnings.Pedantic>
<avrgcccpp.compiler.miscellaneous.OtherFlags>-fno-threadsafe-statics -Wextra -std=c++17</avrgcccpp.compiler.miscellaneous.OtherFlags>
<avrgcccpp.linker.libraries.Libraries>
<ListValues>
<Value>libm</Value>
</ListValues>
</avrgcccpp.linker.libraries.Libraries>
<avrgcccpp.assembler.general.IncludePaths>
<ListValues>
<Value>%24(PackRepoDir)\Atmel\ATmega_DFP\1.3.300\include</Value>
</ListValues>
</avrgcccpp.assembler.general.IncludePaths>
</AvrGccCpp>
</ToolchainSettings>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<ToolchainSettings>
<AvrGccCpp>
<avrgcc.common.Device>-mmcu=atmega328p -B "%24(PackRepoDir)\Atmel\ATmega_DFP\1.3.300\gcc\dev\atmega328p"</avrgcc.common.Device>
<avrgcc.common.outputfiles.hex>True</avrgcc.common.outputfiles.hex>
<avrgcc.common.outputfiles.lss>True</avrgcc.common.outputfiles.lss>
<avrgcc.common.outputfiles.eep>True</avrgcc.common.outputfiles.eep>
<avrgcc.common.outputfiles.srec>True</avrgcc.common.outputfiles.srec>
<avrgcc.common.outputfiles.usersignatures>False</avrgcc.common.outputfiles.usersignatures>
<avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>
<avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>
<avrgcc.compiler.symbols.DefSymbols>
<ListValues>
<Value>DEBUG</Value>
</ListValues>
</avrgcc.compiler.symbols.DefSymbols>
<avrgcc.compiler.directories.IncludePaths>
<ListValues>
<Value>%24(PackRepoDir)\Atmel\ATmega_DFP\1.3.300\include</Value>
</ListValues>
</avrgcc.compiler.directories.IncludePaths>
<avrgcc.compiler.optimization.level>Optimize (-O1)</avrgcc.compiler.optimization.level>
<avrgcc.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcc.compiler.optimization.AllocateBytesNeededForEnum>
<avrgcc.compiler.optimization.DebugLevel>Maximum (-g3)</avrgcc.compiler.optimization.DebugLevel>
<avrgcc.compiler.warnings.AllWarnings>True</avrgcc.compiler.warnings.AllWarnings>
<avrgcc.compiler.warnings.ExtraWarnings>True</avrgcc.compiler.warnings.ExtraWarnings>
<avrgcc.compiler.warnings.Pedantic>True</avrgcc.compiler.warnings.Pedantic>
<avrgcc.compiler.miscellaneous.OtherFlags>-fno-threadsafe-statics -std=c11</avrgcc.compiler.miscellaneous.OtherFlags>
<avrgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned>
<avrgcccpp.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcccpp.compiler.general.ChangeDefaultBitFieldUnsigned>
<avrgcccpp.compiler.symbols.DefSymbols>
<ListValues>
<Value>DEBUG</Value>
</ListValues>
</avrgcccpp.compiler.symbols.DefSymbols>
<avrgcccpp.compiler.directories.IncludePaths>
<ListValues>
<Value>%24(PackRepoDir)\Atmel\ATmega_DFP\1.3.300\include</Value>
</ListValues>
</avrgcccpp.compiler.directories.IncludePaths>
<avrgcccpp.compiler.optimization.level>Optimize (-O1)</avrgcccpp.compiler.optimization.level>
<avrgcccpp.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcccpp.compiler.optimization.AllocateBytesNeededForEnum>
<avrgcccpp.compiler.optimization.DebugLevel>Maximum (-g3)</avrgcccpp.compiler.optimization.DebugLevel>
<avrgcccpp.compiler.warnings.AllWarnings>True</avrgcccpp.compiler.warnings.AllWarnings>
<avrgcccpp.compiler.warnings.Pedantic>True</avrgcccpp.compiler.warnings.Pedantic>
<avrgcccpp.compiler.miscellaneous.OtherFlags>-fno-threadsafe-statics -Wextra -std=c++17</avrgcccpp.compiler.miscellaneous.OtherFlags>
<avrgcccpp.linker.libraries.Libraries>
<ListValues>
<Value>libm</Value>
</ListValues>
</avrgcccpp.linker.libraries.Libraries>
<avrgcccpp.assembler.general.IncludePaths>
<ListValues>
<Value>%24(PackRepoDir)\Atmel\ATmega_DFP\1.3.300\include</Value>
</ListValues>
</avrgcccpp.assembler.general.IncludePaths>
<avrgcccpp.assembler.debugging.DebugLevel>Default (-Wa,-g)</avrgcccpp.assembler.debugging.DebugLevel>
</AvrGccCpp>
</ToolchainSettings>
</PropertyGroup>
<ItemGroup>
<Compile Include="clock.hpp">
<SubType>compile</SubType>
</Compile>
<Compile Include="io\io.hpp">
<SubType>compile</SubType>
</Compile>
<Compile Include="main.cpp">
<SubType>compile</SubType>
</Compile>
</ItemGroup>
<ItemGroup>
<Folder Include="io" />
</ItemGroup>
<Import Project="$(AVRSTUDIO_EXE_PATH)\\Vs\\Compiler.targets" />
</Project>

201
io/main.cpp Normal file
View File

@@ -0,0 +1,201 @@
#include "clock.hpp"
#include "io/io.hpp"
void pinUsage1()
{
using namespace io;
Pin<P::B0> pin1;
Pin<P::B5> pin2;
pin1.dir(Dir::IN);
pin1.pullup(false);
pin2.dir(Dir::OUT);
pin2.write(false);
pin2 = pin1;
if (pin1) {
pin1.dir(Dir::OUT);
pin1 = true;
} else {
pin1.dir(Dir::OUT);
pin2 = false;
}
pin2.toggle();
}
void pinUsage2()
{
using namespace io;
using pin1_t = Pin<P::B0>;
using pin2_t = Pin<P::B5>;
pin1_t::dir(Dir::IN);
pin1_t::pullup(false);
pin2_t::dir(Dir::OUT);
pin2_t::write(false);
pin2_t::write(pin1_t::read());
if (pin1_t::read()) {
pin1_t::dir(Dir::OUT);
pin1_t::write(true);
} else {
pin1_t::dir(Dir::OUT);
pin2_t::write(false);
}
pin2_t::toggle();
}
void portUsage1()
{
using namespace io;
Port<Bus::D> port1;
Port<Bus::B> port2;
port1.dir(Dir::IN);
port1.pullup(false);
port2.dir(Dir::OUT);
port2.write(0x00);
port2 = port1;
if (port1) {
port1.dir(Dir::OUT);
port1 = 0b10101010;
} else {
port1.dir(Dir::OUT);
port1 = 0b01010101;
}
port2.invert();
}
void portUsage2()
{
using namespace io;
using port1_t = Port<Bus::D>;
using port2_t = Port<Bus::B>;
port1_t::dir(Dir::IN);
port1_t::pullup(false);
port2_t::dir(Dir::OUT);
port2_t::write(0x00);
port2_t::write(port1_t::read());
if (port1_t::read()) {
port1_t::dir(Dir::OUT);
port1_t::write(0b10101010);
} else {
port1_t::dir(Dir::OUT);
port1_t::write(0b01010101);
}
port2_t::invert();
}
void virtualPortUsage1()
{
using namespace io;
VirtPort<P::B0, P::B1, P::B3, P::B4> port1;
VirtPort<P::C5, P::C4, P::C3, P::C2, P::C1, P::C0, P::D0, P::D1> port2;
port1.dir(Dir::IN);
port1.pullup(false);
port2.dir(Dir::OUT);
port2.write(0x00);
port2 = port1;
if (port1) {
port1.dir(Dir::OUT);
port1 = 0b10101010;
} else {
port1.dir(Dir::OUT);
port1 = 0b01010101;
}
port2.invert();
}
void virtualPortUsage2()
{
using namespace io;
using port1_t = VirtPort<P::B0, P::B1, P::B3, P::B4>;
using port2_t = VirtPort<P::C5, P::C4, P::C3, P::C2, P::C1, P::C0, P::D0, P::D1>;
port1_t::dir(Dir::IN);
port1_t::pullup(false);
port2_t::dir(Dir::OUT);
port2_t::write(0x00);
port2_t::write(port1_t::read());
if (port1_t::read()) {
port1_t::dir(Dir::OUT);
port1_t::write(0b10101010);
} else {
port1_t::dir(Dir::OUT);
port1_t::write(0b01010101);
}
port2_t::invert();
}
void outputByte(uint8_t value)
{
using namespace io;
Pin<P::B5> led;
led.dir(Dir::OUT);
for (uint16_t i = 0; i < value; ++i) {
led = true;
_delay_ms(250);
led = false;
_delay_ms(250);
}
}
int main()
{
pinUsage1();
pinUsage2();
portUsage1();
portUsage2();
virtualPortUsage1();
virtualPortUsage2();
using namespace io;
Pin<P::B5> led;
led.dir(Dir::OUT);
while (true) {
led = true;
_delay_ms(500);
led = false;
_delay_ms(500);
}
return 0;
}