Skip to content

Commit

Permalink
[amnb] WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
salkinium committed Jun 7, 2020
1 parent 5f5d726 commit 16ce934
Show file tree
Hide file tree
Showing 42 changed files with 3,198 additions and 1,908 deletions.
132 changes: 132 additions & 0 deletions examples/nucleo_g071rb/amnb/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
/*
* Copyright (c) 2019, Niklas Hauser
*
* This file is part of the modm project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

#include <modm/board.hpp>
#include <modm/communication/amnb.hpp>

using namespace Board;
using namespace std::chrono_literals;
using namespace modm::amnb;
// ----------------------------------------------------------------------------

const Listener listeners[] =
{
{1, +[](uint8_t sender, const uint32_t& data)
{
MODM_LOG_INFO << "Node2 and Node3 received Broadcast 1 from '" << sender;
MODM_LOG_INFO << "': " << data << modm::endl;
}
},
{2, [](uint8_t sender)
{
MODM_LOG_INFO << "Node2 and Node3 received Broadcast 2 from '" << sender << "'" << modm::endl;
}
},
};
const Action actions[] =
{
{1, +[]() -> Response
{
static uint8_t counter{0};
MODM_LOG_INFO << "Node1 and Node3 received Action 1" << modm::endl;
return counter++;
}
},
{2, +[](const uint32_t& data) -> Response
{
static uint8_t counter{0};
MODM_LOG_INFO << "Node1 and Node3 received Action 2 with argument: " << data << modm::endl;
return ErrorResponse(counter++);
}
},
};

// Two nodes on the same device on different UARTs of course!
DeviceWrapper<Usart1> device1;
DeviceWrapper<Usart3> device2;
DeviceWrapper<Usart4> device3;
Node node1(device1, 1, actions);
Node node2(device2, 2, listeners);
Node node3(device3, 3, actions, listeners);

// You need to connect D1 with D15 and with A0
using PinNode1 = GpioC4; // D1
using PinNode2 = GpioB8; // D15
using PinNode3 = GpioA0; // A0

// ----------------------------------------------------------------------------
int
main()
{
Board::initialize();
LedD13::setOutput();

Usart1::connect<PinNode1::Tx>();
Usart1::initialize<SystemClock, 115200>();
// Use Single-Wire Half-Duplex Mode
PinNode1::configure(Gpio::OutputType::OpenDrain);
PinNode1::configure(Gpio::InputType::PullUp);
USART1->CR1 &= ~USART_CR1_UE;
USART1->CR3 = USART_CR3_HDSEL;
USART1->CR1 |= USART_CR1_UE;

Usart3::connect<PinNode2::Tx>();
Usart3::initialize<SystemClock, 115200>();
// Use Single-Wire Half-Duplex Mode
PinNode2::configure(Gpio::OutputType::OpenDrain);
PinNode2::configure(Gpio::InputType::PullUp);
USART3->CR1 &= ~USART_CR1_UE;
USART3->CR3 = USART_CR3_HDSEL;
USART3->CR1 |= USART_CR1_UE;

Usart4::connect<PinNode3::Tx>();
Usart4::initialize<SystemClock, 115200>();
// Use Single-Wire Half-Duplex Mode
PinNode3::configure(Gpio::OutputType::OpenDrain);
PinNode3::configure(Gpio::InputType::PullUp);
USART4->CR1 &= ~USART_CR1_UE;
USART4->CR3 = USART_CR3_HDSEL;
USART4->CR1 |= USART_CR1_UE;


modm::ShortPeriodicTimer tmr{1s};
uint32_t counter{0};

while (true)
{
node1.update();
node2.update();
node3.update();

if (tmr.execute())
{
LedD13::toggle();
node1.broadcast(1, counter++);
node3.broadcast(2);

{
modm::ResumableResult< Result<uint8_t> > res{0};
while((res = node2.request<uint8_t>(1, 1)).getState() == modm::rf::Running)
{ node1.update(); node2.update(); node3.update(); }
MODM_LOG_INFO << "Node1 responded with: " << res.getResult().error();
MODM_LOG_INFO << " " << *res.getResult().result() << modm::endl;
}
{
modm::ResumableResult< Result<uint8_t, uint8_t> > res{0};
while((res = node1.request<uint8_t, uint8_t>(3, 2, counter)).getState() == modm::rf::Running)
{ node1.update(); node2.update(); node3.update(); }
MODM_LOG_INFO << "Node3 responded with: " << res.getResult().error();
MODM_LOG_INFO << " " << *res.getResult().resultError() << modm::endl;
}
}
}

return 0;
}
19 changes: 19 additions & 0 deletions examples/nucleo_g071rb/amnb/project.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<library>
<extends>modm:nucleo-g071rb</extends>
<options>
<option name="modm:build:build.path">../../../build/nucleo_g071rb/amnb</option>
<option name="modm:platform:uart:1:buffer.tx">1</option>
<option name="modm:platform:uart:1:buffer.rx">32</option>
<option name="modm:platform:uart:3:buffer.tx">1</option>
<option name="modm:platform:uart:3:buffer.rx">32</option>
<option name="modm:communication:amnb:with_heap">False</option>
</options>
<modules>
<module>modm:platform:gpio</module>
<module>modm:communication:amnb</module>
<module>modm:platform:uart:1</module>
<module>modm:platform:uart:3</module>
<module>modm:platform:uart:4</module>
<module>modm:build:scons</module>
</modules>
</library>
130 changes: 130 additions & 0 deletions examples/nucleo_g071rb/flash/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
/*
* Copyright (c) 2019, Niklas Hauser
*
* This file is part of the modm project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

#include <modm/board.hpp>
#include <modm/processing.hpp>

#undef MODM_LOG_LEVEL
#define MODM_LOG_LEVEL modm::log::INFO

using namespace Board;
using namespace std::chrono_literals;
// ----------------------------------------------------------------------------
const uint32_t FLASH_SR_ERR = FLASH_SR_OPTVERR | FLASH_SR_RDERR |
FLASH_SR_FASTERR | FLASH_SR_MISERR | FLASH_SR_PGSERR | FLASH_SR_SIZERR |
FLASH_SR_PGAERR | FLASH_SR_WRPERR | FLASH_SR_PROGERR | FLASH_SR_OPERR;

void
unlock()
{
Rcc::enable<Peripheral::Flash>();
if (FLASH->CR & FLASH_CR_LOCK)
{
MODM_LOG_INFO << "Unlocking Flash" << modm::endl;
FLASH->KEYR = 0x45670123;
FLASH->KEYR = 0xCDEF89AB;
}
if (FLASH->CR & FLASH_CR_LOCK) {
MODM_LOG_ERROR << "Failed to unlock Flash" << modm::endl;
}
}

uint32_t
erase(uint8_t page)
{
MODM_LOG_DEBUG << "Erasing Page " << page << modm::endl;
while(FLASH->SR & FLASH_SR_BSY1) ;

FLASH->ECCR |= FLASH_ECCR_ECCC | FLASH_ECCR_ECCD;
FLASH->SR = FLASH_SR_ERR;
while(FLASH->SR & FLASH_SR_CFGBSY) ;

FLASH->CR = FLASH_CR_PER | ((page << FLASH_CR_PNB_Pos) & FLASH_CR_PNB);
FLASH->CR |= FLASH_CR_STRT;

while(FLASH->SR & FLASH_SR_BSY1) ;
FLASH->CR = 0;

const uint32_t err = FLASH->SR & FLASH_SR_ERR;
if (err) {
MODM_LOG_ERROR << "Erasing failed 0x" << modm::hex << err << modm::endl;
}
return err;
}

uint32_t
program_dword(uint32_t addr, uint64_t data)
{
MODM_LOG_DEBUG << "Programming Addr " << addr << modm::endl;

while(FLASH->SR & FLASH_SR_BSY1) ;

FLASH->ECCR |= FLASH_ECCR_ECCC | FLASH_ECCR_ECCD;
FLASH->SR = FLASH_SR_ERR;
FLASH->CR = FLASH_CR_PG;

while(FLASH->SR & FLASH_SR_CFGBSY) ;

*(uint32_t*)addr = (uint32_t)data;
__ISB();
*(uint32_t*)(addr+4) = (uint32_t)(data >> 32);

while(FLASH->SR & FLASH_SR_BSY1) ;
FLASH->CR = 0;

const uint32_t err = FLASH->SR & FLASH_SR_ERR;
if (err) {
MODM_LOG_ERROR << "Programming failed 0x" << modm::hex << err << modm::endl;
}

if (*(uint64_t*)addr != data) {
MODM_LOG_ERROR << "Programming data mismatch 0x" << modm::hex << *(uint64_t*)addr <<
modm::ascii << " vs 0x" << modm::hex << data << modm::endl;
}

return err;
}

uint32_t
memcpy_flash(uint8_t *dst, const uint8_t *src, size_t count)
{
uint32_t err{0};
for (uint32_t dst_addr = uint32_t(dst), src_addr = uint32_t(src);
src_addr < uint32_t(src + count);
src_addr += 8, dst_addr += 8)
{
err |= program_dword(dst_addr, *(uint64_t*)src_addr);
}
return err;
}


// ----------------------------------------------------------------------------
int
main()
{
Board::initialize();
LedD13::setOutput();

unlock();

uint32_t err{0};
const modm::PreciseTimestamp start = modm::PreciseClock::now();

for (uint8_t page{31}; page < 64u; page++)
err |= erase(page);
err |= memcpy_flash((uint8_t*)0x0801'0000ul, (uint8_t*)0x0800'0000ul, 0x1'0000ul);

MODM_LOG_INFO << "Programming done in " << (modm::PreciseClock::now() - start) <<
" with errors: " << err << modm::endl;

while(1) ;
return 0;
}
11 changes: 11 additions & 0 deletions examples/nucleo_g071rb/flash/project.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<library>
<extends>modm:nucleo-g071rb</extends>
<options>
<option name="modm:build:build.path">../../../build/nucleo_g071rb/flash</option>
</options>
<modules>
<module>modm:platform:gpio</module>
<module>modm:processing:timer</module>
<module>modm:build:scons</module>
</modules>
</library>
3 changes: 3 additions & 0 deletions src/modm/architecture/driver/atomic/queue.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ namespace modm
modm_always_inline Size
getMaxSize() const;

Size
getSize() const;

const T&
get() const;

Expand Down
38 changes: 16 additions & 22 deletions src/modm/architecture/driver/atomic/queue_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,19 +42,7 @@ bool
modm::atomic::Queue<T, N>::isNearlyFull() const
{
static_assert(N > 3, "Not possible the check for 'nearly full' of such a small queue.");

Index tmphead = this->head;
Index tmptail = this->tail;

Index free;
if (tmphead >= tmptail) {
free = (N + 1) - tmphead + tmptail;
}
else {
free = tmptail - tmphead;
}

return (free < 3);
return (((N + 1) - getSize()) < 3);
}

template<typename T, std::size_t N>
Expand All @@ -69,7 +57,21 @@ bool
modm::atomic::Queue<T, N>::isNearlyEmpty() const
{
static_assert(N > 3, "Not possible the check for 'nearly empty' of such a small queue. ");
return (getSize() < 3);
}


template<typename T, std::size_t N>
modm_always_inline typename modm::atomic::Queue<T, N>::Size
modm::atomic::Queue<T, N>::getMaxSize() const
{
return N;
}

template<typename T, std::size_t N>
typename modm::atomic::Queue<T, N>::Size
modm::atomic::Queue<T, N>::getSize() const
{
Index tmphead = this->head;
Index tmptail = this->tail;

Expand All @@ -81,15 +83,7 @@ modm::atomic::Queue<T, N>::isNearlyEmpty() const
stored = (N + 1) - tmptail + tmphead;
}

return (stored < 3);
}


template<typename T, std::size_t N>
modm_always_inline typename modm::atomic::Queue<T, N>::Size
modm::atomic::Queue<T, N>::getMaxSize() const
{
return N;
return stored;
}

template<typename T, std::size_t N>
Expand Down
Loading

0 comments on commit 16ce934

Please sign in to comment.