Compare commits

...

43 Commits

Author SHA1 Message Date
d1452b6dc0 Update uart example to use latest library version 2020-10-18 12:19:19 +02:00
e760cf541c Update submodule 2020-04-13 17:17:38 +02:00
6b90c1779f Adapt to new interrupt handling interface and change example back to atmega1284p 2020-04-13 16:43:48 +02:00
8bb1bd7397 Update uart submodule 2020-04-13 13:06:31 +02:00
24d17688c0 Add double speed test and change to atmega328p 2020-04-12 23:59:18 +02:00
414ebbebff Refactor uart utils to separate submodule 2020-04-07 03:54:40 +02:00
717a69c231 Updated uart submodule 2020-04-05 03:37:41 +02:00
f0abf335e5 Updated flash submodule 2020-04-05 00:02:33 +02:00
991a67bd86 Updated submodule 2020-02-21 17:50:02 +01:00
4d31f20714 Updated submodules and added MIT license file 2020-02-01 15:43:38 +01:00
85e6510cd5 Adapted to library change 2019-08-15 19:01:56 +02:00
2eefa7fd7f Changed toolchain to 9.1.0 and updated submodules 2019-08-15 18:49:53 +02:00
dd3e69daa3 Disabled unused interrupt vectors 2019-08-15 18:13:12 +02:00
cc5b375b44 Updated project settings 2019-08-15 17:43:11 +02:00
fcdce7cc1d Adapted example slightly and updated submodules 2019-08-14 20:00:40 +02:00
0354bc3020 Adapted interface to move more often used template parameters to the front 2019-08-05 20:06:42 +02:00
c74f1afcac Adapted to c++ clock header 2019-08-05 19:43:00 +02:00
823921dcd8 Added flushing test 2019-08-03 18:46:23 +02:00
2ba032c103 Added test for number conversion 2019-08-03 17:33:05 +02:00
dafb7ee059 Added test for stream operator overloading 2019-08-03 16:53:29 +02:00
9b4b0cac67 Adapted to new interface 2019-08-03 16:26:32 +02:00
2d54e4ea45 Updated submodule 2019-08-02 19:45:02 +02:00
d32e2a13e6 Fixed submodule url 2019-08-02 19:31:08 +02:00
5047b661af Changed example to use peeking 2019-08-02 18:22:38 +02:00
408ab83afb Changed example to use rx as well 2019-08-02 17:42:12 +02:00
e891e1019f Switched to only Uart1 for testing 2019-08-02 09:22:27 +02:00
4a25398c1e Added Uart1 example 2019-07-30 21:51:47 +02:00
48e312d076 Implemented test using Peter Fleury's c uart library 2019-07-30 18:32:32 +02:00
59a83a304b Used defaultet constructor for uart 2019-07-28 19:20:36 +02:00
011776a709 Removed test implementation 2019-07-28 18:11:23 +02:00
d952794c55 Refactored code to use capital letters for classes and added using namespace inside functions 2019-07-28 18:00:15 +02:00
9809b34bca Implemented optimal example to compare implementations 2019-07-28 17:33:42 +02:00
e71d103602 Added explicit selection of interrupt driven uart 2019-07-28 14:09:52 +02:00
d8aee7498d Removed unnecessary const qualifiers in template 2019-07-28 14:01:05 +02:00
5cd2b963fa Added proof of concept for using hardware0 in SPI mode 2019-07-28 12:16:09 +02:00
ab1d55ee6f Updated submodule 2019-07-28 10:35:32 +02:00
b66c33506c Implemented proof of concept for new library interface and added basic outline of new interface 2019-07-27 18:56:31 +02:00
2cb62d4fac Added flash submodule for flash strings 2019-07-27 13:38:45 +02:00
98bd0e1238 Added clock and io/uart submodules 2019-07-27 11:01:56 +02:00
f1de6c3701 Renamed library from usart to uart and wiped example to implement new library 2019-07-27 10:53:23 +02:00
0ec71af448 Used submodule branch as library source 2018-08-11 13:37:15 +02:00
8fa18f8e88 Merged changes from submodule branch 2016-10-29 17:22:34 +02:00
5ba8cc4ec3 Fixed submodule 2016-10-29 17:12:11 +02:00
17 changed files with 490 additions and 868 deletions

13
.clang-format Normal file
View File

@ -0,0 +1,13 @@
---
BasedOnStyle: LLVM
ColumnLimit: 120
IndentWidth: 4
TabWidth: 4
UseTab: ForIndentation
AlignEscapedNewlines: DontAlign
AllowShortFunctionsOnASingleLine: Empty
AlwaysBreakTemplateDeclarations: true
BreakBeforeBraces: Custom
BraceWrapping:
AfterFunction: true
...

8
.gitignore vendored
View File

@ -2,4 +2,10 @@
Release
Debug
*.componentinfo.xml
avrdude.bat
*.elf
*.o
*.hex
*.srec
*.eeprom
*.lss
*.map

15
.gitmodules vendored
View File

@ -1,3 +1,12 @@
[submodule "usart/array"]
path = usart/array
url = git@blackmark.me:array.git
[submodule "uart/io"]
path = uart/io
url = git@git.blackmark.me:avr/io.git
[submodule "uart/uart"]
path = uart/uart
url = git@git.blackmark.me:avr/uart.git
[submodule "uart/flash"]
path = uart/flash
url = git@git.blackmark.me:avr/flash.git
[submodule "uart/util"]
path = uart/util
url = git@git.blackmark.me:avr/util.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.

View File

@ -3,7 +3,7 @@ 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}") = "usart", "usart\usart.cppproj", "{DCE6C7E3-EE26-4D79-826B-08594B9AD897}"
Project("{E66E83B9-2572-4076-B26E-6BE79FF3018A}") = "uart", "uart\uart.cppproj", "{DCE6C7E3-EE26-4D79-826B-08594B9AD897}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution

4
uart/clock.hpp Normal file
View File

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

1
uart/flash Submodule

@ -0,0 +1 @@
Subproject commit 6edb2e5a21e0ce58ff2df936caee8b84e240a46b

1
uart/io Submodule

@ -0,0 +1 @@
Subproject commit 80de36ee7ee3e6b0842d5eaee81d54062cb496b2

283
uart/main.cpp Normal file
View File

@ -0,0 +1,283 @@
#include "clock.hpp"
#include <avr/interrupt.h>
#include <stdint.h>
#include "flash/flash.hpp"
#include "io/io.hpp"
#include "uart/uart.hpp"
using uart0_interface_t =
uart::Uart<uart::Hardware0<uart::Config<115200>, uart::Driven::INTERRUPT, uart::Mode::ASYNCHRONOUS>>;
using uart1_interface_t = uart::Uart1<>;
REGISTER_UART0_INT_VECTORS(uart0_interface_t);
REGISTER_UART1_INT_VECTORS(uart1_interface_t);
void doubleSpeedTest()
{
uart0_interface_t serial;
serial.init();
uint8_t counter = 100;
uint8_t data;
while (counter) {
if (serial.rxByte(data)) {
serial.txByte(data);
--counter;
}
}
serial << F("\r\n");
serial.flushTx();
}
void newUartUsage()
{
using namespace uart;
Uart<Hardware0<Config<115200>, Driven::BLOCKING, Mode::ASYNCHRONOUS>> serial;
serial.init();
serial << "New uart hi from RAM. " << F("New uart hi from flash\r\n");
while (false) {
uint8_t received = 0;
while (!serial.peek())
;
{
serial << F("Peeked: ");
serial.txByte(received);
serial << F("\r\n");
}
if (serial.rxByte(received)) {
serial << F("Received: ");
serial.txByte(received);
serial << F("\r\n");
}
}
serial.flushTx();
}
void newUartUsage2()
{
uart1_interface_t serial1;
auto ramString = "Hello World from RAM. ";
auto flashString = F("Hello World from flash\r\n");
serial1.init();
serial1 << ramString;
serial1 << flashString;
serial1.flushTx();
}
void newUartStreamOverloads()
{
using namespace uart;
Uart<Hardware0<Config<115200>, Driven::BLOCKING, Mode::ASYNCHRONOUS>> serial;
serial.init();
bool bVal = true;
char chVal = 'c';
signed char schVal = 's';
unsigned char uchVal = 'u';
short shVal = -12345;
unsigned short ushVal = 64123;
int iVal = -14321;
unsigned int uiVal = 32146;
long lVal = -571474496;
unsigned long ulVal = 2718958144;
long long llVal = -45197516864960;
unsigned long long ullVal = 4611685969606738496;
serial << F("Stream overload test:") << F("\r\n");
serial << F("bool : ") << bVal << F("\r\n");
serial << F("char : ") << chVal << F("\r\n");
serial << F("signed char : ") << schVal << F("\r\n");
serial << F("unsigned char : ") << uchVal << F("\r\n");
serial << F("short : ") << shVal << F("\r\n");
serial << F("unsigned short : ") << ushVal << F("\r\n");
serial << F("int : ") << iVal << F("\r\n");
serial << F("unsigned int : ") << uiVal << F("\r\n");
serial << F("long : ") << lVal << F("\r\n");
serial << F("unsigned long : ") << ulVal << F("\r\n");
serial << F("long long : ") << llVal << F("\r\n");
serial << F("unsigned long long : ") << ullVal << F("\r\n");
serial << F("const void : ") << &bVal << F("\r\n");
auto number = 0xBADF00D;
serial << F("Binary : 0b");
serial.txNumber<decltype(number), 2>(number);
serial << F("\r\n");
serial << F("Octal : 0");
serial.txNumber<decltype(number), 8>(number);
serial << F("\r\n");
serial << F("Decimal : ");
serial.txNumber<decltype(number), 10>(number);
serial << F("\r\n");
serial << F("Hex : 0x");
serial.txNumber<decltype(number), 16>(number);
serial << F("\r\n");
serial.flushTx();
}
namespace spi {
enum class Cpol {
MODE_0,
MODE_1,
};
enum class Cpha {
MODE_0,
MODE_1,
};
enum class DataOrder {
MSB,
LSB,
};
template <Cpol cpol, Cpha cpha, DataOrder dataOrder>
struct Config {
static constexpr auto CPOL_MODE = cpol;
static constexpr auto CPHA_MODE = cpha;
static constexpr auto DATA_ORDER = dataOrder;
};
template <class Driver>
struct spi {
spi()
{
Driver::init();
}
};
} // namespace spi
namespace uart {
template <class Config>
class Hardware0<Config, Driven::INTERRUPT, Mode::SPI> {
public:
static void init()
{
UCSR0C |= (1 << UMSEL01) | (1 << UMSEL00);
if (DATA_ORDER == spi::DataOrder::MSB)
UCSR0C &= ~(1 << UCSZ01);
else
UCSR0C |= (1 << UCSZ01);
if (CPOL_MODE == spi::Cpol::MODE_0)
UCSR0C &= ~(1 << UCPOL0);
else
UCSR0C |= (1 << UCPOL0);
if (CPHA_MODE == spi::Cpha::MODE_0)
UCSR0C &= ~(1 << UCSZ00);
else
UCSR0C |= (1 << UCSZ00);
}
private:
static constexpr auto CPOL_MODE = Config::CPOL_MODE;
static constexpr auto CPHA_MODE = Config::CPHA_MODE;
static constexpr auto DATA_ORDER = Config::DATA_ORDER;
};
} // namespace uart
void spiTest()
{
using config = spi::Config<spi::Cpol::MODE_0, spi::Cpha::MODE_0, spi::DataOrder::MSB>;
using uartspi = uart::Hardware0<config, uart::Driven::INTERRUPT, uart::Mode::SPI>;
spi::spi<uartspi> uartSpi;
}
static inline void initUart(const uint32_t baudRate)
{
UBRR0 = static_cast<uint16_t>((F_CPU + 8 * baudRate) / (16 * baudRate) - 1);
UCSR0A = 0;
UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);
UCSR0B = (1 << RXEN0) | (1 << TXEN0);
}
static inline void txUart(uint8_t byte)
{
while (!(UCSR0A & (1 << UDRE0)))
;
UDR0 = byte;
}
static inline void txString(const char *str)
{
while (char ch = *str++)
txUart(ch);
}
static inline void txString(const detail::FlashString *str)
{
const char *strIt = reinterpret_cast<const char *>(str);
while (char ch = pgm_read_byte(strIt++))
txUart(ch);
}
static inline void flushTx()
{
while (!(UCSR0A & (1 << UDRE0)))
;
while (!(UCSR0A & (1 << TXC0)))
;
UCSR0A |= (1 << TXC0);
}
void optimalUartTest()
{
auto ramString = "Hello World from RAM. ";
auto flashString = F("Hello World from flash\r\n");
initUart(115200);
txString(ramString);
txString(flashString);
flushTx();
}
int main()
{
sei();
doubleSpeedTest();
newUartUsage2();
optimalUartTest();
newUartStreamOverloads();
txString(F("\r\n"));
flushTx();
spiTest();
return 0;
}

1
uart/uart Submodule

@ -0,0 +1 @@
Subproject commit 119de3244588b19b4afb06f33f66f22bb80a89b5

View File

@ -5,17 +5,17 @@
<ProjectVersion>7.0</ProjectVersion>
<ToolchainName>com.Atmel.AVRGCC8.CPP</ToolchainName>
<ProjectGuid>dce6c7e3-ee26-4d79-826b-08594b9ad897</ProjectGuid>
<avrdevice>ATmega328P</avrdevice>
<avrdevice>ATmega1284P</avrdevice>
<avrdeviceseries>none</avrdeviceseries>
<OutputType>Executable</OutputType>
<Language>CPP</Language>
<OutputFileName>$(MSBuildProjectName)</OutputFileName>
<OutputFileExtension>.elf</OutputFileExtension>
<OutputDirectory>$(MSBuildProjectDirectory)\$(Configuration)</OutputDirectory>
<AssemblyName>usart</AssemblyName>
<Name>usart</Name>
<RootNamespace>usart</RootNamespace>
<ToolchainFlavour>Native</ToolchainFlavour>
<AssemblyName>uart</AssemblyName>
<Name>uart</Name>
<RootNamespace>uart</RootNamespace>
<ToolchainFlavour>avr-g++-9.1.0</ToolchainFlavour>
<KeepTimersRunning>true</KeepTimersRunning>
<OverrideVtor>false</OverrideVtor>
<CacheFlash>true</CacheFlash>
@ -25,7 +25,41 @@
<preserveEEPROM>true</preserveEEPROM>
<OverrideVtorValue>exception_table</OverrideVtorValue>
<BootSegment>2</BootSegment>
<ResetRule>0</ResetRule>
<eraseonlaunchrule>0</eraseonlaunchrule>
<EraseKey />
<avrtool>
</avrtool>
<avrtoolserialnumber>J41800099437</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\uart.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 />
@ -34,44 +68,27 @@
<documentation help="" />
<offline-documentation help="" />
<dependencies>
<content-extension eid="atmel.asf" uuidref="Atmel.ASF" version="3.31.0" />
<content-extension eid="atmel.asf" uuidref="Atmel.ASF" version="3.46.0" />
</dependencies>
</framework-data>
</AsfFrameworkConfig>
<avrtool>com.atmel.avrdbg.tool.stk500</avrtool>
<avrtoolserialnumber />
<avrdeviceexpectedsignature>0x1E950F</avrdeviceexpectedsignature>
<com_atmel_avrdbg_tool_stk500>
<com_atmel_avrdbg_tool_atmelice>
<ToolOptions>
<InterfaceProperties>
<IspClock>1843200</IspClock>
<IspClock>125000</IspClock>
<JtagDbgClock>5000000</JtagDbgClock>
</InterfaceProperties>
<InterfaceName>ISP</InterfaceName>
</ToolOptions>
<ToolType>com.atmel.avrdbg.tool.stk500</ToolType>
<ToolNumber>
</ToolNumber>
<ToolName>STK500</ToolName>
</com_atmel_avrdbg_tool_stk500>
<avrtoolinterface>ISP</avrtoolinterface>
<avrtoolinterfaceclock>1843200</avrtoolinterfaceclock>
<com_atmel_avrdbg_tool_simulator>
<ToolOptions xmlns="">
<InterfaceProperties>
</InterfaceProperties>
<InterfaceName>
</InterfaceName>
</ToolOptions>
<ToolType xmlns="">com.atmel.avrdbg.tool.simulator</ToolType>
<ToolNumber xmlns="">
</ToolNumber>
<ToolName xmlns="">Simulator</ToolName>
</com_atmel_avrdbg_tool_simulator>
<ToolType>com.atmel.avrdbg.tool.atmelice</ToolType>
<ToolNumber>J41800099437</ToolNumber>
<ToolName>Atmel-ICE</ToolName>
</com_atmel_avrdbg_tool_atmelice>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<ToolchainSettings>
<AvrGccCpp>
<avrgcc.common.Device>-mmcu=atmega328p -B "%24(PackRepoDir)\atmel\ATmega_DFP\1.0.106\gcc\dev\atmega328p"</avrgcc.common.Device>
<avrgcc.common.Device>-mmcu=atmega1284p</avrgcc.common.Device>
<avrgcc.common.optimization.RelaxBranches>True</avrgcc.common.optimization.RelaxBranches>
<avrgcc.common.outputfiles.hex>True</avrgcc.common.outputfiles.hex>
<avrgcc.common.outputfiles.lss>True</avrgcc.common.outputfiles.lss>
@ -80,58 +97,56 @@
<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.directories.IncludePaths>
<ListValues>
<Value>%24(PackRepoDir)\atmel\ATmega_DFP\1.0.106\include</Value>
</ListValues>
</avrgcc.compiler.directories.IncludePaths>
<avrgcc.compiler.optimization.PackStructureMembers>True</avrgcc.compiler.optimization.PackStructureMembers>
<avrgcc.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcc.compiler.optimization.AllocateBytesNeededForEnum>
<avrgcc.compiler.warnings.AllWarnings>True</avrgcc.compiler.warnings.AllWarnings>
<avrgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned>
<avrgcccpp.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcccpp.compiler.general.ChangeDefaultBitFieldUnsigned>
<avrgcccpp.compiler.directories.IncludePaths>
<ListValues>
<Value>%24(PackRepoDir)\atmel\ATmega_DFP\1.0.106\include</Value>
</ListValues>
</avrgcccpp.compiler.directories.IncludePaths>
<avrgcccpp.compiler.optimization.PackStructureMembers>True</avrgcccpp.compiler.optimization.PackStructureMembers>
<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>-Wextra -std=c++11</avrgcccpp.compiler.miscellaneous.OtherFlags>
<avrgcccpp.linker.general.UseVprintfLibrary>True</avrgcccpp.linker.general.UseVprintfLibrary>
<avrgcccpp.linker.libraries.Libraries>
<ListValues>
<Value>libm</Value>
<Value>libprintf_flt</Value>
</ListValues>
</avrgcccpp.linker.libraries.Libraries>
<avrgcccpp.assembler.general.IncludePaths>
<ListValues>
<Value>%24(PackRepoDir)\atmel\ATmega_DFP\1.0.106\include</Value>
</ListValues>
</avrgcccpp.assembler.general.IncludePaths>
<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>
<PreBuildEvent>echo "C:\avrdude-6.2\avrdude.exe" -v -p$(avrdevice) %%* -Uflash:w:"$(OutputDirectory)\$(Name).hex":i &gt; "$(MSBuildProjectDirectory)\avrdude.bat"</PreBuildEvent>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<ToolchainSettings>
<AvrGccCpp>
<avrgcc.common.Device>-mmcu=atmega328p -B "%24(PackRepoDir)\atmel\ATmega_DFP\1.0.106\gcc\dev\atmega328p"</avrgcc.common.Device>
<avrgcc.common.Device>-mmcu=atmega1284p</avrgcc.common.Device>
<avrgcc.common.optimization.RelaxBranches>True</avrgcc.common.optimization.RelaxBranches>
<avrgcc.common.outputfiles.hex>True</avrgcc.common.outputfiles.hex>
<avrgcc.common.outputfiles.lss>True</avrgcc.common.outputfiles.lss>
@ -140,76 +155,100 @@
<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.directories.IncludePaths>
<ListValues>
<Value>%24(PackRepoDir)\atmel\ATmega_DFP\1.0.106\include</Value>
</ListValues>
</avrgcc.compiler.directories.IncludePaths>
<avrgcc.compiler.optimization.PackStructureMembers>True</avrgcc.compiler.optimization.PackStructureMembers>
<avrgcc.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcc.compiler.optimization.AllocateBytesNeededForEnum>
<avrgcc.compiler.warnings.AllWarnings>True</avrgcc.compiler.warnings.AllWarnings>
<avrgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned>
<avrgcccpp.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcccpp.compiler.general.ChangeDefaultBitFieldUnsigned>
<avrgcccpp.compiler.directories.IncludePaths>
<ListValues>
<Value>%24(PackRepoDir)\atmel\ATmega_DFP\1.0.106\include</Value>
</ListValues>
</avrgcccpp.compiler.directories.IncludePaths>
<avrgcccpp.compiler.optimization.PackStructureMembers>True</avrgcccpp.compiler.optimization.PackStructureMembers>
<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>-Wextra -std=c++11</avrgcccpp.compiler.miscellaneous.OtherFlags>
<avrgcccpp.linker.general.UseVprintfLibrary>True</avrgcccpp.linker.general.UseVprintfLibrary>
<avrgcccpp.linker.libraries.Libraries>
<ListValues>
<Value>libm</Value>
<Value>libprintf_flt</Value>
</ListValues>
</avrgcccpp.linker.libraries.Libraries>
<avrgcccpp.assembler.general.IncludePaths>
<ListValues>
<Value>%24(PackRepoDir)\atmel\ATmega_DFP\1.0.106\include</Value>
</ListValues>
</avrgcccpp.assembler.general.IncludePaths>
<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.DebugLevel>Default (-g2)</avrgcc.compiler.optimization.DebugLevel>
<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.optimization.level>Optimize (-O1)</avrgcccpp.compiler.optimization.level>
<avrgcccpp.compiler.optimization.DebugLevel>Default (-g2)</avrgcccpp.compiler.optimization.DebugLevel>
<avrgcccpp.compiler.directories.IncludePaths>
<ListValues>
<Value>%24(PackRepoDir)\Atmel\ATmega_DFP\1.3.300\include</Value>
</ListValues>
</avrgcccpp.compiler.directories.IncludePaths>
<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>
<PreBuildEvent>echo "C:\avrdude-6.2\avrdude.exe" -v -p$(avrdevice) %%* -Uflash:w:"$(OutputDirectory)\$(Name).hex":i &gt; "$(MSBuildProjectDirectory)\avrdude.bat"</PreBuildEvent>
</PropertyGroup>
<ItemGroup>
<Compile Include="array\array.h">
<Compile Include="clock.hpp">
<SubType>compile</SubType>
</Compile>
<Compile Include="clock.h">
<Compile Include="flash\flash.hpp">
<SubType>compile</SubType>
</Compile>
<Compile Include="io\io.hpp">
<SubType>compile</SubType>
</Compile>
<Compile Include="main.cpp">
<SubType>compile</SubType>
</Compile>
<Compile Include="usart.cpp">
<Compile Include="uart\config.hpp">
<SubType>compile</SubType>
</Compile>
<Compile Include="usart.h">
<Compile Include="uart\hardware.hpp">
<SubType>compile</SubType>
</Compile>
<Compile Include="uart\hardware0.hpp">
<SubType>compile</SubType>
</Compile>
<Compile Include="uart\hardware1.hpp">
<SubType>compile</SubType>
</Compile>
<Compile Include="uart\software.hpp">
<SubType>compile</SubType>
</Compile>
<Compile Include="uart\uart.hpp">
<SubType>compile</SubType>
</Compile>
<Compile Include="util\func.hpp">
<SubType>compile</SubType>
</Compile>
<Compile Include="util\type.hpp">
<SubType>compile</SubType>
</Compile>
<Compile Include="util\util.hpp">
<SubType>compile</SubType>
</Compile>
</ItemGroup>
<ItemGroup>
<Folder Include="array" />
<Folder Include="io" />
<Folder Include="flash" />
<Folder Include="util" />
<Folder Include="uart" />
</ItemGroup>
<Import Project="$(AVRSTUDIO_EXE_PATH)\\Vs\\Compiler.targets" />
</Project>

1
uart/util Submodule

@ -0,0 +1 @@
Subproject commit 81b3ae244c9773e7ea8ee08af43193275db48514

@ -1 +0,0 @@
Subproject commit 634564a7bb6f34305dbc6f68993a34a4419899a6

View File

@ -1,14 +0,0 @@
/*
* Copyright (c) by BlackMark 2015
* Date 24/11/2015
* Version 1.1
*/
#ifndef CLOCK_H
#define CLOCK_H
#define F_CPU 8000000
#include <util/delay.h>
#endif

View File

@ -1,92 +0,0 @@
/*
* Copyright (c) by BlackMark 2015-2016
* Date 21/05/2016
* Version 1.5
*/
#include <stdio.h>
#include "clock.h"
#include "usart.h"
#include "array/array.h"
int main()
{
sei();
USART0 &cUSART = USART0::inst();
cUSART.init();
uint32_t ui32Counter = 0;
array<char, 64> arrBuffer;
cUSART << "\r\nSizes: \r\n";
sprintf( arrBuffer.data(), "%d\r\n", sizeof( char ) );
cUSART << "sizeof( char ) = " << arrBuffer.data();
sprintf( arrBuffer.data(), "%d\r\n", sizeof( unsigned char ) );
cUSART << "sizeof( unsigned char ) = " << arrBuffer.data();
sprintf( arrBuffer.data(), "%d\r\n", sizeof( short int ) );
cUSART << "sizeof( short int ) = " << arrBuffer.data();
sprintf( arrBuffer.data(), "%d\r\n", sizeof( unsigned short int ) );
cUSART << "sizeof( unsigned short int ) = " << arrBuffer.data();
sprintf( arrBuffer.data(), "%d\r\n", sizeof( int ) );
cUSART << "sizeof( int ) = " << arrBuffer.data();
sprintf( arrBuffer.data(), "%d\r\n", sizeof( unsigned int ) );
cUSART << "sizeof( unsigned int ) = " << arrBuffer.data();
sprintf( arrBuffer.data(), "%d\r\n", sizeof( long int ) );
cUSART << "sizeof( long int ) = " << arrBuffer.data();
sprintf( arrBuffer.data(), "%d\r\n", sizeof( unsigned long int ) );
cUSART << "sizeof( unsigned long int ) = " << arrBuffer.data();
sprintf( arrBuffer.data(), "%d\r\n", sizeof( long long int ) );
cUSART << "sizeof( long long int ) = " << arrBuffer.data();
sprintf( arrBuffer.data(), "%d\r\n", sizeof( unsigned long long int ) );
cUSART << "sizeof( unsigned long long int ) = " << arrBuffer.data();
sprintf( arrBuffer.data(), "%d\r\n", sizeof( float ) );
cUSART << "sizeof( float ) = " << arrBuffer.data();
sprintf( arrBuffer.data(), "%d\r\n", sizeof( double ) );
cUSART << "sizeof( double ) = " << arrBuffer.data();
sprintf( arrBuffer.data(), "%d\r\n", sizeof( long double ) );
cUSART << "sizeof( long double ) = " << arrBuffer.data();
sprintf( arrBuffer.data(), "%d\r\n\r\n", sizeof( void* ) );
cUSART << "sizeof( void* ) = " << arrBuffer.data();
while( true )
{
sprintf( arrBuffer.data(), "%lu", ui32Counter++ );
cUSART << "This has been running for \"" << arrBuffer.data() << "\" seconds!\r\n";
if( !cUSART.receiveLine( arrBuffer.data(), arrBuffer.size(), "\r" ) )
{
cUSART << "Receive error: ";
}
else
{
cUSART << "Echo: ";
}
cUSART << arrBuffer.data() << "\r\n";
uint8_t ui8Byte;
if( cUSART.receiveByte( ui8Byte, 1000 ) )
{
cUSART.transmitByte( ui8Byte );
cUSART << "\r\n";
}
}
return 0;
}

View File

@ -1,474 +0,0 @@
#include "usart.h"
//////////////////////////////////////////////////////////////////////////
USART0 USART0::sm_cInstance;
//////////////////////////////////////////////////////////////////////////
USART0::USART0()
{
#ifdef USART_SHAREDIO
m_vui8pUCSRA = &UCSRA;
m_vui8pUCSRB = &UCSRB;
m_vui8pUCSRC = &UCSRC;
m_vui8pUBRRH = &UBRRH;
m_vui8pUBRRL = &UBRRL;
m_vui8pUDR = &UDR;
#endif
#ifndef USART_SHAREDIO
m_vui8pUCSRA = &UCSR0A;
m_vui8pUCSRB = &UCSR0B;
m_vui8pUCSRC = &UCSR0C;
m_vui8pUBRRH = &UBRR0H;
m_vui8pUBRRL = &UBRR0L;
m_vui8pUDR = &UDR0;
#endif
m_vsizeRXBufferHead = 0;
m_vsizeRXBufferTail = 0;
m_vsizeTXBufferHead = 0;
m_vsizeTXBufferTail = 0;
}
//////////////////////////////////////////////////////////////////////////
uint8_t USART0::readUCSRC()
{
uint8_t ui8UCSRC;
#ifdef USART_SHAREDIO
ui8UCSRC = UBRRH;
ui8UCSRC = UCSRC;
#else
ui8UCSRC = *m_vui8pUCSRC;
#endif
return ui8UCSRC;
}
//////////////////////////////////////////////////////////////////////////
void USART0::setUCSRC( uint8_t ui8UCSRC )
{
#ifdef USART_SHAREDIO
*m_vui8pUCSRC = ( 1 << URSEL ) | ui8UCSRC;
#else
*m_vui8pUCSRC = ui8UCSRC;
#endif
}
//////////////////////////////////////////////////////////////////////////
void USART0::setRXState( bool bEnable )
{
if( bEnable )
{
*m_vui8pUCSRB |= ( 1 << RXEN_D );
}
else
{
*m_vui8pUCSRB &= ~( 1 << RXEN_D );
}
}
//////////////////////////////////////////////////////////////////////////
void USART0::setTXState( bool bEnable )
{
if( bEnable )
{
*m_vui8pUCSRB |= ( 1 << TXEN_D );
}
else
{
*m_vui8pUCSRB &= ~( 1 << TXEN_D );
}
}
//////////////////////////////////////////////////////////////////////////
void USART0::setRXInterrupt( bool bEnable )
{
if( bEnable )
{
*m_vui8pUCSRB |= ( 1 << RXCIE_D );
}
else
{
*m_vui8pUCSRB &= ~( 1 << RXCIE_D );
}
}
//////////////////////////////////////////////////////////////////////////
void USART0::setUDREInterrupt( bool bEnable )
{
if( bEnable )
{
*m_vui8pUCSRB |= ( 1 << UDRIE_D );
}
else
{
*m_vui8pUCSRB &= ~( 1 << UDRIE_D );
}
}
//////////////////////////////////////////////////////////////////////////
void USART0::setBaudRate( uint32_t ui32BaudRate )
{
uint16_t ui16UBRR = ( ( F_CPU / ( 16 * ui32BaudRate ) ) - 1 );
*m_vui8pUBRRH = static_cast<uint8_t>( ui16UBRR >> 8 );
*m_vui8pUBRRL = static_cast<uint8_t>( ui16UBRR );
}
//////////////////////////////////////////////////////////////////////////
void USART0::setDataBits( uint8_t ui8DataBits )
{
uint8_t ui8UCSRC = readUCSRC();
if( ui8DataBits < 5 )
{
ui8DataBits = 5;
}
else if( ui8DataBits > 9 )
{
ui8DataBits = 9;
}
if( ui8DataBits <= 8 )
{
bool bZeroBit = ( ui8DataBits - 5 ) & 1;
bool bOneBit = ( ( ui8DataBits - 5 ) >> 1 ) & 1;
if( bZeroBit )
{
ui8UCSRC |= ( 1 << UCSZ0_D );
}
else
{
ui8UCSRC &= ~( 1 << UCSZ0_D );
}
if( bOneBit )
{
ui8UCSRC |= ( 1 << UCSZ1_D );
}
else
{
ui8UCSRC &= ~( 1 << UCSZ1_D );
}
*m_vui8pUCSRB &= ~( 1 << UCSZ2_D );
}
else
{
ui8UCSRC |= ( 1 << UCSZ1_D ) | ( 1 << UCSZ0_D );
*m_vui8pUCSRB |= ( 1 << UCSZ2_D );
}
setUCSRC( ui8UCSRC );
}
//////////////////////////////////////////////////////////////////////////
void USART0::setParity( Parity enmParity )
{
uint8_t ui8UCSRC = readUCSRC();
if( enmParity == Parity::DISABLED )
{
ui8UCSRC &= ~( ( 1 << UPM1_D ) | ( 1 << UPM0_D ) );
}
else if( enmParity == Parity::ODD )
{
ui8UCSRC |= ( ( 1 << UPM1_D ) | ( 1 << UPM0_D ) );
}
else if( enmParity == Parity::EVEN )
{
ui8UCSRC &= ~( ( 1 << UPM0_D ) );
ui8UCSRC |= ( ( 1 << UPM1_D ) );
}
setUCSRC( ui8UCSRC );
}
//////////////////////////////////////////////////////////////////////////
void USART0::setStopBits( StopBit enmStopBits )
{
uint8_t ui8UCSRC = readUCSRC();
if( enmStopBits == StopBit::ONE )
{
ui8UCSRC &= ~( 1 << USBS_D );
}
else if( enmStopBits == StopBit::TWO )
{
ui8UCSRC |= ( 1 << USBS_D );
}
setUCSRC( ui8UCSRC );
}
//////////////////////////////////////////////////////////////////////////
void USART0::setMode( Mode enmMode )
{
uint8_t ui8UCSRC = readUCSRC();
#ifdef USART_SPI
if( enmMode == Mode::ASYNCHRONOUS )
{
ui8UCSRC &= ~( ( 1 << UMSEL1_D ) | ( 1 << UMSEL0_D ) );
}
else if( enmMode == Mode::SYNCHRONOUS )
{
ui8UCSRC &= ~( 1 << UMSEL1_D );
ui8UCSRC |= ( 1 << UMSEL0_D );
}
else if( enmMode == Mode::MASTERSPI )
{
ui8UCSRC |= ( ( 1 << UMSEL1_D ) | ( 1 << UMSEL0_D ) );
}
#else
if( enmMode == Mode::ASYNCHRONOUS )
{
ui8UCSRC &= ~( 1 << UMSEL_D );
}
else if( enmMode == Mode::SYNCHRONOUS )
{
ui8UCSRC |= ( 1 << UMSEL_D );
}
#endif
setUCSRC( ui8UCSRC );
}
//////////////////////////////////////////////////////////////////////////
USART0::~USART0()
{
flushTransmit();
setBaudRate( 0 );
setRXState( false );
setTXState( false );
setRXInterrupt( false );
setUDREInterrupt( false );
}
//////////////////////////////////////////////////////////////////////////
USART0& USART0::inst()
{
return sm_cInstance;
}
//////////////////////////////////////////////////////////////////////////
void USART0::init( uint32_t ui32BaudRate /* = 9600 */, uint8_t ui8DataBits /* = 8 */, Parity enmParity /* = Parity::DISABLED */, StopBit enmStopBits /* = StopBit::ONE */, Mode enmMode /* = Mode::ASYNCHRONOUS */ )
{
setBaudRate( ui32BaudRate );
setDataBits( ui8DataBits );
setParity( enmParity );
setStopBits( enmStopBits );
setMode( enmMode );
setRXState( true );
setTXState( true );
setRXInterrupt( true );
setUDREInterrupt( false );
}
//////////////////////////////////////////////////////////////////////////
bool USART0::receiveByte( uint8_t &ui8Data )
{
if( m_vsizeRXBufferHead == m_vsizeRXBufferTail && !( SREG & ( 1 << SREG_I ) ) )
{
while( !( *m_vui8pUCSRA & ( 1 << RXC_D ) ) );
ui8Data = *m_vui8pUDR;
return true;
}
else if( m_vsizeRXBufferHead == m_vsizeRXBufferTail )
{
return false;
}
ui8Data = m_vui8aRXBuffer[m_vsizeRXBufferTail];
m_vsizeRXBufferTail = ( m_vsizeRXBufferTail + 1 ) % sm_sizeRXBUFFER_SIZE;
return true;
}
//////////////////////////////////////////////////////////////////////////
bool USART0::receiveByte( uint8_t &ui8Data, uint16_t ui16TimeoutMS )
{
uint16_t ui16DelayCounter = 0;
while( !receiveByte( ui8Data ) )
{
_delay_ms( 1 );
if( ui16DelayCounter++ >= ui16TimeoutMS )
{
return false;
}
}
return true;
}
//////////////////////////////////////////////////////////////////////////
bool USART0::receiveLine( char *szBuffer, size_t sizeBufferLength, const char *szLineTerminator /* = "\r\n" */ )
{
size_t sizeReceived = 0;
while( sizeReceived < sizeBufferLength - 1 )
{
uint8_t ui8ReceiveByte;
while( !receiveByte( ui8ReceiveByte ) );
szBuffer[sizeReceived++] = ui8ReceiveByte;
szBuffer[sizeReceived] = '\0';
if( strstr( szBuffer, szLineTerminator ) )
{
return true;
}
}
return false;
}
//////////////////////////////////////////////////////////////////////////
void USART0::flushReceive()
{
uint8_t ui8Received;
while( m_vsizeRXBufferHead != m_vsizeRXBufferTail )
{
receiveByte( ui8Received );
}
if( !( SREG & ( 1 << SREG_I ) ) && ( *m_vui8pUCSRA & ( 1 << RXC_D ) ) )
{
ui8Received = *m_vui8pUDR;
}
}
//////////////////////////////////////////////////////////////////////////
void USART0::transmitByte( uint8_t ui8Data )
{
if( m_vsizeTXBufferHead == m_vsizeTXBufferTail && *m_vui8pUCSRA & ( 1 << UDRE_D ) )
{
*m_vui8pUDR = ui8Data;
return;
}
size_t sizeIndex = ( m_vsizeTXBufferHead + 1 ) % sm_sizeTXBUFFER_SIZE;
while( sizeIndex == m_vsizeTXBufferTail )
{
if( !( SREG & ( 1 << SREG_I ) ) && *m_vui8pUCSRA & ( 1 << UDRE_D ) )
{
transmitInterruptHandler();
}
}
m_vui8aTXBuffer[m_vsizeTXBufferHead] = ui8Data;
m_vsizeTXBufferHead = sizeIndex;
if( !( SREG & ( 1 << SREG_I ) ) )
{
while( !( *m_vui8pUCSRA & ( 1 << UDRE_D ) ) );
transmitInterruptHandler();
}
else
{
setUDREInterrupt( true );
}
}
//////////////////////////////////////////////////////////////////////////
void USART0::transmitString( const char *szString )
{
while( *szString )
{
transmitByte( *szString++ );
}
}
//////////////////////////////////////////////////////////////////////////
void USART0::flushTransmit()
{
while( m_vsizeTXBufferHead != m_vsizeTXBufferTail && !( *m_vui8pUCSRA & ( 1 << UDRE_D ) ) );
}
//////////////////////////////////////////////////////////////////////////
void USART0::receiveInterruptHandler()
{
uint8_t ui8ReceivedByte = *m_vui8pUDR;
size_t sizeIndex = ( m_vsizeRXBufferHead + 1 ) % sm_sizeRXBUFFER_SIZE;
if( sizeIndex != m_vsizeRXBufferTail )
{
m_vui8aRXBuffer[m_vsizeRXBufferHead] = ui8ReceivedByte;
m_vsizeRXBufferHead = sizeIndex;
}
}
//////////////////////////////////////////////////////////////////////////
void USART0::transmitInterruptHandler()
{
uint8_t ui8TransmitByte = m_vui8aTXBuffer[m_vsizeTXBufferTail];
m_vsizeTXBufferTail = ( m_vsizeTXBufferTail + 1 ) % sm_sizeTXBUFFER_SIZE;
*m_vui8pUDR = ui8TransmitByte;
if( m_vsizeTXBufferHead == m_vsizeTXBufferTail )
{
setUDREInterrupt( false );
}
}
//////////////////////////////////////////////////////////////////////////
ISR( USART0_RX_vect_D )
{
USART0::inst().receiveInterruptHandler();
}
//////////////////////////////////////////////////////////////////////////
ISR( USART0_UDRE_vect_D )
{
USART0::inst().transmitInterruptHandler();
}
/************************************************************************/
/************************************************************************/
#ifdef SECOND_USART
//////////////////////////////////////////////////////////////////////////
USART1 USART1::sm_cInstance;
//////////////////////////////////////////////////////////////////////////
USART1& USART1::inst()
{
return sm_cInstance;
}
//////////////////////////////////////////////////////////////////////////
USART1::USART1()
{
m_vui8pUCSRA = &UCSR1A;
m_vui8pUCSRB = &UCSR1B;
m_vui8pUCSRC = &UCSR1C;
m_vui8pUBRRH = &UBRR1H;
m_vui8pUBRRL = &UBRR1L;
m_vui8pUDR = &UDR1;
}
//////////////////////////////////////////////////////////////////////////
ISR( USART1_RX_vect_D )
{
USART1::inst().receiveInterruptHandler();
}
//////////////////////////////////////////////////////////////////////////
ISR( USART1_UDRE_vect_D )
{
USART1::inst().transmitInterruptHandler();
}
#endif

View File

@ -1,176 +0,0 @@
/*
* Copyright (c) by BlackMark 2015-2016
* Date 24/05/2016
* Version 2.9
*/
#ifndef USART_H
#define USART_H
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdint.h>
#include <string.h>
#include "clock.h"
#if defined (__AVR_ATmega168A__) || defined (__AVR_ATmega328P__) || defined (__AVR_ATmega644P__) || defined (__AVR_ATmega1284P__)
#define USART_SPI
#define USART0_RX_vect_D USART_RX_vect
#define USART0_UDRE_vect_D USART_UDRE_vect
#endif
#if defined (__AVR_ATmega32A__) || (__AVR_ATmega8__)
#define USART_SHAREDIO
#define USART0_RX_vect_D USART_RXC_vect
#define USART0_UDRE_vect_D USART_UDRE_vect
#endif
#if defined (__AVR_ATmega1284P__)
#define SECOND_USART
#define USART0_RX_vect_D USART0_RX_vect
#define USART1_RX_vect_D USART1_RX_vect
#define USART0_UDRE_vect_D USART0_UDRE_vect
#define USART1_UDRE_vect_D USART1_UDRE_vect
#endif
#ifdef USART_SHAREDIO
#define RXEN_D RXEN
#define TXEN_D TXEN
#define RXCIE_D RXCIE
#define UDRIE_D UDRIE
#define UCSZ0_D UCSZ0
#define UCSZ1_D UCSZ1
#define UCSZ2_D UCSZ2
#define UPM0_D UPM0
#define UPM1_D UPM1
#define USBS_D USBS
#define RXC_D RXC
#define UDRE_D UDRE
#else
#define RXEN_D RXEN0
#define TXEN_D TXEN0
#define RXCIE_D RXCIE0
#define UDRIE_D UDRIE0
#define UCSZ0_D UCSZ00
#define UCSZ1_D UCSZ01
#define UCSZ2_D UCSZ02
#define UPM0_D UPM00
#define UPM1_D UPM01
#define USBS_D USBS0
#define RXC_D RXC0
#define UDRE_D UDRE0
#endif
#ifdef USART_SPI
#define UMSEL0_D UMSEL00
#define UMSEL1_D UMSEL01
#else
#define UMSEL_D UMSEL
#endif
class USART0
{
public:
enum class Mode
{
ASYNCHRONOUS = 0,
SYNCHRONOUS = 1,
#ifdef USART_SPI
MASTERSPI = 2
#endif
};
enum class Parity
{
DISABLED = 0,
ODD = 1,
EVEN = 2
};
enum class StopBit
{
ONE = 1,
TWO = 2
};
static constexpr size_t sm_sizeRXBUFFER_SIZE = 16;
static constexpr size_t sm_sizeTXBUFFER_SIZE = 16;
protected:
volatile uint8_t *m_vui8pUCSRA;
volatile uint8_t *m_vui8pUCSRB;
volatile uint8_t *m_vui8pUCSRC;
volatile uint8_t *m_vui8pUBRRH;
volatile uint8_t *m_vui8pUBRRL;
volatile uint8_t *m_vui8pUDR;
volatile size_t m_vsizeRXBufferHead;
volatile size_t m_vsizeRXBufferTail;
volatile size_t m_vsizeTXBufferHead;
volatile size_t m_vsizeTXBufferTail;
volatile uint8_t m_vui8aRXBuffer[sm_sizeRXBUFFER_SIZE];
volatile uint8_t m_vui8aTXBuffer[sm_sizeTXBUFFER_SIZE];
USART0();
private:
static USART0 sm_cInstance;
uint8_t readUCSRC();
void setUCSRC( uint8_t ui8UCSRC );
void setRXState( bool bEnable );
void setTXState( bool bEnable );
void setRXInterrupt( bool bEnable );
void setUDREInterrupt( bool bEnable );
void setBaudRate( uint32_t ui32BaudRate );
void setDataBits( uint8_t ui8DataBits );
void setParity( Parity enmParity );
void setStopBits( StopBit enmStopBits );
void setMode( Mode enmMode );
~USART0();
public:
static USART0& inst();
USART0( const USART0& ) = delete;
void operator=( const USART0& ) = delete;
void init( uint32_t ui32BaudRate = 9600, uint8_t ui8DataBits = 8, Parity enmParity = Parity::DISABLED, StopBit enmStopBits = StopBit::ONE, Mode enmMode = Mode::ASYNCHRONOUS );
bool receiveByte( uint8_t &ui8Data );
bool receiveByte( uint8_t &ui8Data, uint16_t ui16TimeoutMS );
bool receiveLine( char *szBuffer, size_t sizeBufferLength, const char *szLineTerminator = "\r\n" );
void flushReceive();
void transmitByte( uint8_t ui8Data );
void transmitString( const char *szString );
void flushTransmit();
void receiveInterruptHandler();
void transmitInterruptHandler();
inline USART0& operator<<( const char *szString )
{
transmitString( szString );
return *this;
}
};
#ifdef SECOND_USART
class USART1 : public USART0
{
public:
static USART1& inst();
USART1( const USART1& ) = delete;
void operator=( const USART1& ) = delete;
private:
static USART1 sm_cInstance;
USART1();
};
#endif
#endif