Git Product home page Git Product logo

kvasir's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

kvasir's Issues

We should refactor kvasir to use an external metaprogramming library

Back in the beginning of 2013 when I started working on Kvasir I was not able to find a good MPL which did not rely on the STL but did make use of variadic templates, so I wrote my own. Now almost 3 years later metaprogramming has greatly advanced especially in terms of finding ungodly performance tricks.
Couppled with the fact that I did not document my MPL well/at all it is high time it get swapped out with a new/faster/documented one.

many chip headers not compiling

The example header Chip/MKL27Z4.hpp compiles OK. But most of the others I tried do not, producing many errors. This was using gcc-arm-none-eabi-5_3-2016q1 from the GCC ARM Embedded project.

The errors vary with the chip but for example
main.cpp:

include "Chip/STM32F30x.hpp"

...

arm-none-eabi-g++ -o build/example-main.o -c -Og -mcpu=cortex-m4 -mthumb -std=gnu++11 -Ibuild/.:./lib -I.:./lib -I/home/jd/output/Kvasir/Lib main.cpp
In file included from /home/jd/output/Kvasir/Lib/Chip/STM32F30x.hpp:2:0,
from main.cpp:2:
/home/jd/output/Kvasir/Lib/Chip/Unknown/STMicro/STM32F30x/GPIOA.hpp:8:15: error: too many decimal points in number
0..15)
^
/home/jd/output/Kvasir/Lib/Chip/Unknown/STMicro/STM32F30x/GPIOA.hpp:11:15: error: too many decimal points in number
0..15)
^
(continues for many screenfuls)

TMP refactoring in Kvasir

There are still a good number of things in Kvasir which are not in line with modern TMP style. Especially offending are the uppercase nested Types (rather than lowercase) and the idiom of returning by inheritance. This is actually starting to infect things outside of core like MakeAction in Io and should be refactored soon.

Things could also run much faster if we made many more type empty inside and relied on pattern matching to work on them (instantiating is less costly for the compiler if the struct is truly empty).

wrong apply in seam with sets in list-constexpr

if saving list in constexpr & using more than one set() than seamwrite is only showing one set();

testcases:

fails with

0x400@0x48000014
constexpr auto s = set(Kvasir::GpiobOdr::odr8),set(Kvasir::GpioaOdr::odr8),set(Kvasir::GpioaOdr::odr10));
apply(s);

works with

0x100@48000414
0x500@48000014

constexpr auto s = (set(Kvasir::GpiobOdr::odr8, Kvasir::GpioaOdr::odr8, Kvasir::GpioaOdr::odr10));
apply(s);

apply(set(Kvasir::GpiobOdr::odr8,Kvasir::GpioaOdr::odr8, Kvasir::GpioaOdr::odr10));

apply(set(Kvasir::GpiobOdr::odr8),set(Kvasir::GpioaOdr::odr8),set(Kvasir::GpioaOdr::odr10));

Should we change our read abstractions to reguard bit banding?

So far we have left bit banding out. In the case where a register action only effects one bit and is not merged with anything a write using bit banding would surely be better than a read-mask-or-write like we are doing now. Implementing that optimization can be done after the fact with the same interface.

With regard to single bit reads however there is an interface decision to be made. If the user reads a register and is interested in only a single bit then bit banding is surely more efficient. However if the user reads a register using a pod conversion policy the returned POD value is not marked volatile, thus the optimizer has much more room to operate especially when the user tests multiple bits.

Our objective is clear, optimize for the common case, however I can't say definitively what the common case is. It probably depends on the register in question, however a piecemeal solution would be less logical to the end user.

Implement clock initialization in KVASIR_STARTUP

We need to implement a clock initialization step before we initialize other modules. should be realized by treating the first parameter passed to the KVASIR_STARTUP macro as a functor and executing it first. We can build a factory allowing the user to create such a functor from desired parameters.

Compilation error in Register/Utility.hpp

My compiler (gcc 5.1) reports the following error:

Lib/Register/Utility.hpp:28:23:  in constexpr expansion of 'Kvasir::Register::maskFromRange(high, low)'
Lib/Register/Utility.hpp:24:22:  error: right operand of shift expression '(4294967295u >> 32)' is >= than the precision of the left operand
   return (0xFFFFFFFF >> (32-(high-low)))<<low;
                      ^

This then causes a cascade of error messages. I fixed this by changing the constant to 0xFFFFFFFFLLU

Cleanup in ChipFromSvdGenerator

I'm not the most Pythonic Pythonista who ever Pythoned but I have a few ideas for cleaning up the chip file generator.

It may make sense to use EmPy templates instead of concatenating formatted strings representing C++ code. It may make the process a bit more readable, since you could have a template file that looks a bit more like the resulting C++ code with placeholders that get filled in from the parsed xml. I have some experience with EmPy, so I could do this if others think it would be useful.

I couldn't find tests in place for results of the generator; if the chip generator gets rewritten it would be good to have those in place beforehand, to make sure the rewrite preserves functionality. Are there IP issues with adding example CMSIS SVD files to this repo for testing?

EDIT: just realized that the SVD files are in https://github.com/posborne/cmsis-svd/tree/master/data, cool. For now I can test any refactoring I do on my own by diffing against the state of the header files in master.

Indexing in multiple read apply does not work.

If i try to compile the following code the ADL fails.

#include <Chip/nrf52.hpp>
#include <Io/Io.hpp>

constexpr auto button1 = Kvasir::Io::makePinLocation(Kvasir::Io::port0, Kvasir::Io::pin13);
constexpr auto button2 = Kvasir::Io::makePinLocation(Kvasir::Io::port0, Kvasir::Io::pin14);

int main()
{


                        if (get<0>(apply(read(button1), (read(button2))))  ) {}
}

Kvasir::Register types should be refactored to be empty

In order to have lightning speed we need to refactor types like address to have an empty body. Things like nested type and values are not needed as they can be found through pattern matching. Plus this would mitigate my original sin of naming the nested types uppercase Type.

Usb documentation needed

Design goals for the USB abstraction were

  • complete static binding
  • fully configurable (to the point of micromanaging memory strategy)
  • unit tested for everything upwards from the HAL

Although I think these can be/have been met the interfaces between the HAL and the USB::Device as well as the interface between the USB::Device and the device classes could not be implemented as cleanly as I had hoped.
We need to do a good job of documenting the contracts between the Usb::Device and the Hal as well as the contracts between the Usb::Device and the interface class(es).

Should we rename namespaces to lowercase?

In the interest of breaking things now rather than later it seems people don't like my style ;) basically types being UpperCamelCase and values and functions being lowerCamelCase is ok by most people but that fact that namespaces are also upper camel case bugs a lot of people. So we should probably change it.

The one breach in this style is the nested type in Metafunction::type. The problem is that TMP convention is to use lower case type but it is a type so according to this style guide it should be upper case. I think we can get away with this breach in our style guide and use lower case though because the user should never see this, its just library internals.

RegisterAction should be renamed FieldAction

looking at the continuity of our naming conventions a Register is essentially a Tuple of (bit)Fields. Since a RegisterAction acts on a Field rather than on the whole register (usually reads and writes the whole register but only because of hardware constraints and not in the case of of BME ore bit banding) it should be named FieldAction.

apply, write etc missing on STM32F072x

apply, write set etc don't work.
works on MKL27Z4 trough generated "Chip/MKL27Z4.hpp" thats include generated "Io.hpp" in that includes "Register/Register.hpp". Io.hpp is missing on STM32F072x and therefore Registers.hpp.

helperscript must be modified for this.

Should ChipFromSvdGenerator get his own repo.

Because of the fact that the CFSG is a tool and not part of the kvasir registery abstraction I think it should have its own repo. In this way we could also version it as a standalone tool. Would also enable other users to use it for different purposes.

Register::apply needs to be refactored to allow for locking policies

We need to expand the apply steps so we can support locking policies and decide if we need to lock at the largest granularity possible. I would expect the following steps in apply are needed:

  • index input
  • flatten input
  • determine return object type
  • determine atomic policy
  • split by sequence point
  • sort by address
  • path1 (taken if there are any atomics)
    • merge(each address will be merged unless atomic behavior is only possible with bit banding)
    • BME or bit banding as an optimization will be taken into account
    • check if atomic policy is possible
  • path 2 (taken if there are no atomics or if intrinsic atomics are not possible)
    • merge all addressed
    • make chip specific substitutions only if size or speed if positively affected
    • enable fall back locking policy
  • lock if needed
  • forward arguments to next helper (we need to expand our list of merged actions)
    • expand new action list
    • determine input parameters
    • forward input args to single actions
      • lock if needed
      • execute single action
      • compile returns
      • unlock if needed

Apply should take tuples of runtime write commands

in some cases we need to build up the contents of a register in a tree of ifs and then flush it all at the same time. This would be much easier and more efficient if we could make a tuple of writes, work on it and then flush it to the register.

documentation generation

I know there are automatic c++ documentation generators with github integration. We need to decide which one to use and start using it to generate documentation.

We may need a multi step action

In some cases we have multiple actions which need to be executed in a certain order with regard to each other but not with regard to other actions. Using a sequence point would be over kill here because we don't care about unrelated actions being moved across in order to merge or save address loads. A single action should be mergable with any action step with the same address, another multi step action should be mergable if all steps in the smaller list have common addresses with a sequence in the larger list.
Before writing I would like to compile a list of places that this would come in handy. Writing PowerClockInit routines for the LPC15xx is a good example, different modules need to access power clock and reset registers in a distinct order regarding other actions from the same peripheral, however with regard to other peripherals the order is not important. If one peripheral is power on by default but does need to enable clock or reset it self then we must remember to leave an extra sequence point in or generate less efficient code. Any other places this is needed?

We need to change timer match registers to use tags

Currently we handle the 4 match registers separately on the Lpc11u6x and LPC175x6x but the LPC15xx hat 16 match registers, this is too many to handle separately, we need a better way, the user should also be able to changes match registers dynamically from the hardware.h

Using tags should solve this eg. MatchRegister::makeSetValue<1000>(match0) or static void onMatch(Match0){ ... }; and we are already using this approach with ADC channels.

Should Register::Option become Register::Action with more functionality?

Right now we have a register option which consists of an address with a set and clear mask. In addition there is a bit of a hack which allows write only registers to be used like the bit toggle register in GPIO of the M0 core. It does not seem that this is powerful enough, we cannot easily detect clashes between writes for example and we need a better way of handling write only registers or registers where read and write are separate functions. We also need to allow the optimization of writing directly to a register if all the bits are changed by the option(s) after merging. Also we need to provide enough info for the init routine to load defaults to fill unused bits rather than reading, this should save a lot of code space.

Shared inteerrupts on M0 are not supported

The current code will work if one of the modules which shares the interrupt use it. However if both register the interrupt the compiler will issue an error. We need a work around eventually.

Should we start with a more release based workflow.

If we want to make kvasir usable for production code we should be more save. With more safe I mean using a git policy that allows us to indicate when a version is stable and ready for use.

We could implement this by using git flow. Als we should do code reviews before any master merge. Main work should be done off the master branch.

I think we have to discuss this and write a git and test plan for this repo and the whole kvasir idea. What do you think?

Make NVIC actions work like current IO actions

I am very happy with the current IO action factory structure, eg. apply(makeOutput(myPin)); I think we should use the same architecture for NVIC configuration except with Nvic::Index rather than Io::PinLocation eg. apply(makeEnable(Nvic::uart0));.

We need a fieldEquals([FieldValue]) function

in code we find a common pattern:
if(apply(read([fieldValue])) == [fieldValue]){}

where [fieldValue] is usually long.

we could save a serious amount of typeing with a fieldEquals([fieldValue]) function.

Blinky demo does not compile

I use revision 729fa5c and the LPC1549 in the current lpcxpresso 8.0.
I get lots of compile errors (>80), e.g.
Kvasir/Lib/StartUp/StartUp.hpp:111:17: error: 'FlattenT' is not a member of 'Kvasir::MPL'

no type named 'DataType'

Hi,
while including "Chip/nrf52.hpp", I get following compiler message:

/Users/todi/Kvasir/Lib/Chip/CM4/Nordic/nrf52/RADIO.hpp:207:89: error: no type named 'DataType' in 'struct Kvasir::Register::FieldValue<Kvasir::Register::FieldLocation<Kvasir::Register::Address<1073746692u, 4294953728u, 0u, unsigned int>, 16u, Kvasir::Register::Access<(Kvasir::Register::AccessType)2>, Kvasir::RadioIntenset::DisabledVal>, (Kvasir::RadioIntenset::DataType)0>' constexpr Register::FieldValue<decltype(disabled)::Type,DisabledVal::enabled> enabled{};

Any idea, how to fix this?

TIA,
Torsten

Redesign of Device initialization needed in order to power on and provide clock to all peripheral devices used

the power on and clock configuration steps are the only unique thing in the initialization lists of most modules, it is also often the only reason one may need a sequence point. I think default behavior should be to turn on all Peripheral devices and configure them to use the fastest clock possible for every device mentioned in the KVASIR_START macro. If the user wants to save power they should have some way of overriding this and can surely reconfigure the initialization list if desired.
A work around could be to just turn everything on and then refine the process under the hood from there.

Ignore of Mask in Register::Action

Mask is ignored on writeactions. Means wrong bits could be set.
tested only with Register/Seam.hpp, not on real hardwarecompile

testcode:
apply(Kvasir::Register::Action<Kvasir::Register::FieldLocation<Kvasir::Register::Address<0x13371337,0x00000000>,(0b01<<30)>,Kvasir::Register::WriteLiteralAction<(0b11<<30)>>{});
apply(Kvasir::Register::Action<Kvasir::Register::FieldLocation<Kvasir::Register::Address<0x13381338,0x00000000>,(0b11<<30)>,Kvasir::Register::WriteLiteralAction<(0b11<<30)>>{});

Harmonize Nvic::Index with regard to pointer array offset

It seems most Cortex use ISR indexes which start at 0, the LPC175x6x however essentially starts at -16, we need to harmonize this so that less code needs to be chip specific, maybe just add 16 to the LPC17xx indexes and leave a comment? I'm not sure many users will actually look at the index numbers we are using if a plain text name is available.

How to deal with Dont-Touch Registers?

While writing Chipfile of UM10736 I found register 0x4007 4124
bits 11:0 and 31:14 have to be written back as read.
what does an action like this look like? should it be available at all to touch them? how can we secure that they are never touched?

->lpc15xx manual
->chapter 3.6.32
->syscon::flashcfg

havealookj

Kvasir::Register::apply should be refactored to allow for smaller debug builds

at least in the case where everythign is compile time known we should use recursion to walk the list of register actions rather than flat expansion. The advantage is we can force inline in debug builds and also give the user a better "step through experience". The release codegen should be identical according to my gut feeling.

Kvasir licencing and copyright

I'm writing the contribution file for Kvasir at the moment and I'm doubting how to handle copyright.

The whole Kvasir name space will be licenced under the apache. @odinthenerd and I were thinking on putting all the contributes in the readme for each repo in de the order of there first commit. This would work except for the copyright. Who is going to have copyright in the license of each file? Do we refer to the readme?

Would love your feedback!

@odinthenerd @Sickeroni @chieltbest

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.