Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

BitBanger Driver


  • Please log in to reply
39 replies to this topic

#1 sweetlilmre

sweetlilmre

    Advanced Member

  • Members
  • PipPipPip
  • 62 posts

Posted 05 September 2010 - 05:07 PM

Hi,


UPDATE: this post has been updated with a newer version and firmware: 11/29/2010. This newer version provides SoftSPI like capabilities.

In my quest to make my HT1632 display useable I have developed a generic bit banger driver.

The attached archive unzips into the "MicroFrameworkPK_v4_1\Solutions\Netduino" dir.
If you want to build this yourselves you will have to build the managed solution and generate the client assemblies and then build the firmware as usual.

The speed increase in amazing when driving the HT1632 and I know that variable SPI is around the corner, but I thought this might be useful in a more generic context (the code should be device neutral).

The bit banger is constructed with a configuration class that describes two pins, one clock and one data.
Ownership of the pins then belongs to the BitBanger class.

public class Config
{
public Config( Cpu.Pin clockPin,
             		bool clockEdgeRising,
             		Cpu.Pin dataPin,
             		Cpu.Pin latchPin,
             		bool latchActiveState )
}

BitBang.Config config = new BitBang.Config( clkPin, true, dataPin );
// set data & clock pin modes
BitBang bb = new BitBang( config );


Additionally the latchPin and latchActiveState Config members allow for additional flexible latching behaviour.

public enum LatchBehaviour
{
	PerTransfer,
	Per8Bits,
	Per16Bits,
	Per32Bits,
	Never
}

LatchBehaviour is passed to the block blitting function and will toggle a latch line (or CS possibly) in a certain manner.
This is very useful for writing to shift registers in a continuous mode.


The BitBang class interface has some basic functionality:

These two methods bang out a stream of bytes, with each byte written from the MSb (bigEndian) or LSb and with optional latch behaviour.

public void Write( byte[] writeBuffer, int writeOffset, int writeCount, bool bigEndian)
public void Write( byte[] writeBuffer, int writeOffset, int writeCount, bool bigEndian, LatchBehaviour latchBehaviour )


And these two methods bang out up to 32 bits with the same endian functionality as above.

public void Write32( UInt32 data, byte numBits, bool bigEndian )
public void Write32AndLatch( UInt32 data, byte numBits, bool bigEndian )


I have attached 2 files containing the compiled firmare (tinyclr.hex.zip) and the source code (bitbang.zip).
Included in the source code is the compiled client assembly which you will find under the MicroFrameworkPK_v4_1\Solutions\Netduino\ManagedCode\SecretLabs_NETMF_Hardware\bin\Release dir.
You will need to reference this assembly or replace the one provided with the NetDuino SDK in order to use the BitBang class.

:D :D :D

Hope this is interesting / useful
-(e)

Attached Files



#2 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 05 September 2010 - 08:24 PM

Oh hey, that is really cool. If a few community members have feedback on uses for this, maybe we could integrate something like this into the stock firmware in a future update? Chris

#3 sweetlilmre

sweetlilmre

    Advanced Member

  • Members
  • PipPipPip
  • 62 posts

Posted 06 September 2010 - 05:03 AM

Oh hey, that is really cool. If a few community members have feedback on uses for this, maybe we could integrate something like this into the stock firmware in a future update?

Chris


Thanks! Maybe this could be built into a namespace with CW2's OneWire stuff? A kind of bitbanger toolkit?

Is there anyway to ship a driver without including it in a matching kernel i.e. have the native and managed portions separate and loadable or is built-in the only possibility?

Also I can trim down the code more, and put it in a better more generic namespace. Do you have a namespace suggestion?

edit: any news on a GIT source share or something similar for the firmware? It would make community generated patches so much nicer and easier :)

-(e)

#4 dragonfly

dragonfly

    Member

  • Members
  • PipPip
  • 12 posts
  • LocationSouth Africa

Posted 06 September 2010 - 09:21 AM

Awesome stuff dude :D A repository is not a bad idea. Using git, sourceforge or even google code. I was wondering if there's a way to combine patches such as this one to create a custom firmware image with only the features you need. It might help to keep down the code size while still allowing for cool features such as this to be integrated when needed.

#5 CW2

CW2

    Advanced Member

  • Members
  • PipPipPip
  • 1592 posts
  • LocationCzech Republic

Posted 06 September 2010 - 01:46 PM

I was wondering if there's a way to combine patches such as this one to create a custom firmware image with only the features you need. It might help to keep down the code size while still allowing for cool features such as this to be integrated when needed.

IMHO combining patches is easy as long as they are firmware 'features': just un/check appropriate checkbox in the Solution Wizard, save and rebuild. What I don't know exactly at this time is how to deal with possible large number of managed libraries (one for each feature?). I am thinking about merging them (ilmerge), but this may not work at all due to method checksums, and can lead into hard-to-troubleshoot problems with unresolved references and mismatches among managed wrappers and their native implementations.

The Idea: A web interface to the firmware build process - select the features, hit 'build' button, wait a moment, download .zipped hex and dll files (in case you are not happy with any pre-built one). May be easier to realize than I thought initially... Posted Image

#6 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 06 September 2010 - 11:12 PM

Is there anyway to ship a driver without including it in a matching kernel i.e. have the native and managed portions separate and loadable or is built-in the only possibility?


In theory, we could make it so you could just load native code into RAM and then move the execution pointer to the beginning of the native code--and we could write an instruction to RAM at the end of your dynamic native code to move the execution pointer back to the .NET MF runtime.

But that's a big 'ol can of worms :)

We're looking at different ways we can accomplish this while giving guidance on best methods for implementation, etc. My personal dream scenario would be inline C code in Visual Studio :)

Chris

#7 CW2

CW2

    Advanced Member

  • Members
  • PipPipPip
  • 1592 posts
  • LocationCzech Republic

Posted 07 September 2010 - 06:04 AM

My personal dream scenario would be inline C code in Visual Studio :)

The Ultimate Solution: C++/CLI for ARM Posted Image

#8 Roceh

Roceh

    Member

  • Members
  • PipPip
  • 11 posts

Posted 17 September 2010 - 07:57 PM

Just a tip for anymore else putting this into their own custom firmware, i had to enable the "Generate native stubs for internal methods" option in the project properties, with a root name of "BitBanger" and a folder called "stubs". If you dont do that the firmware download complains about a missing checksum in the assembly.

#9 hookedup

hookedup

    Member

  • Members
  • PipPip
  • 20 posts
  • LocationFlorida - USA

Posted 06 October 2010 - 08:25 PM

Oh hey, that is really cool. If a few community members have feedback on uses for this, maybe we could integrate something like this into the stock firmware in a future update?

Chris


+1 to include bit banging in stock firmware. The standard output pins are so slow I can see the shift registers update LEDs before my very eyes (when normally this is done many times per second).

I downloaded the porting kit and was able to move the files around as described but now I am a total loss as to what to do next to update my firmware. There is a netduino firmware .. how does this update integrate with the netduino firmware? I have tried to read through documentation, but it goes in 100 directions .. a bit much for a newbie like me.

Any tips on what docs to read that with help me understand how to use bit banger in a project would be much appreciated.

#10 CW2

CW2

    Advanced Member

  • Members
  • PipPipPip
  • 1592 posts
  • LocationCzech Republic

Posted 06 October 2010 - 08:54 PM

The standard output pins are so slow I can see the shift registers update LEDs before my very eyes (when normally this is done many times per second).

What kind of shift registers do you have? Usually, it is possible to drive them via SPI...

#11 hookedup

hookedup

    Member

  • Members
  • PipPip
  • 20 posts
  • LocationFlorida - USA

Posted 06 October 2010 - 09:21 PM

What kind of shift registers do you have? Usually, it is possible to drive them via SPI...


The LEDs from bliptronics.com uses LPD-6803 chips which are like shift registers but they work using just clock and data pins.

The code from their site was pretty easy to port to netduino but is slow. I updated to use direct port manipulation in arduino and got up to 200 LEDs before hitting memory limits. I am hoping that getting port manipulation pin speeds at the native level will help that trend scale up to the netduino to run 1000 or two :).

I have tried in arduino to get this working via SPI with no luck and understand netduino less, but still may give that route another shot.

I would however like to learn how to write / use native code in firmware .. so any pointers on how to get bit banger working would be helpful as well.

Thanks for your reply and idea for SPI.

#12 CW2

CW2

    Advanced Member

  • Members
  • PipPipPip
  • 1592 posts
  • LocationCzech Republic

Posted 07 October 2010 - 06:12 AM

I would however like to learn how to write / use native code in firmware .. so any pointers on how to get bit banger working would be helpful as well.

You may want to have a look at the following two articles Using Interop in the .NET Micro Framework V3.0 and Your first interop project walkthrough to get the overview and step-by-step instructions how to write native drivers for .NET Micro Framework. Also, the Porting Kit documentation contains detailed description (Adding Features to the .NET Micro Framework by Interoperating with Unmanaged Code) and introduction of the build system. There are also threads in this forum that discuss various firmware build issues and what is needed to use GCC 4.4 compiler.

#13 hookedup

hookedup

    Member

  • Members
  • PipPip
  • 20 posts
  • LocationFlorida - USA

Posted 07 October 2010 - 11:54 AM

You may want to have a look at the following two articles Using Interop in the .NET Micro Framework V3.0 and Your first interop project walkthrough to get the overview and step-by-step instructions how to write native drivers for .NET Micro Framework. Also, the Porting Kit documentation contains detailed description (Adding Features to the .NET Micro Framework by Interoperating with Unmanaged Code) and introduction of the build system. There are also threads in this forum that discuss various firmware build issues and what is needed to use GCC 4.4 compiler.


Thanks for the links.

#14 hookedup

hookedup

    Member

  • Members
  • PipPip
  • 20 posts
  • LocationFlorida - USA

Posted 09 October 2010 - 02:53 PM

Those links are pretty daunting for someone coming new into this technology. After reading those links am pretty sure I have no desire to go native for some time. That said, the current method of direct pin control is too slow. I tried FEZ Panda and it has the same slow pin speed, I guess it is the .NET layer. This seems very similar to standard pin control in the arduino being too slow, in which direct port access helps at the cost of portability. This bit banger driver seems to be a great solution for this problem. Is there is a way to put up a test firmware with big banger included? That would help see if bit banging will do the trick. I would think having bit banger built in would be best case. Is there a case to not include bit banger in the base outside firmware size? Thanks for building and posting bit banger, good to know there is a way to have fast pin access like direct port access in arduino.

#15 sweetlilmre

sweetlilmre

    Advanced Member

  • Members
  • PipPipPip
  • 62 posts

Posted 17 October 2010 - 01:29 PM

Those links are pretty daunting for someone coming new into this technology. After reading those links am pretty sure I have no desire to go native for some time. That said, the current method of direct pin control is too slow. I tried FEZ Panda and it has the same slow pin speed, I guess it is the .NET layer. This seems very similar to standard pin control in the arduino being too slow, in which direct port access helps at the cost of portability.

This bit banger driver seems to be a great solution for this problem.

Is there is a way to put up a test firmware with big banger included? That would help see if bit banging will do the trick.

I would think having bit banger built in would be best case. Is there a case to not include bit banger in the base outside firmware size?

Thanks for building and posting bit banger, good to know there is a way to have fast pin access like direct port access in arduino.


Hi,

Yep the interop is well scary the first time around. I had to bang my head hard to get it to work as there was some obscure bug in my code (a naming issue with a lib and an incorrect .proj file).

Its probably worth getting to know though. As far as posting a firmware image I can do that, but as I have had no luck in compiling with RVCS I can only give you a GCC based image which will require flashing your boot loader via SAM-BA as well. Are you comfortable with this?

I have been playing with the code and have managed to slim the size down significantly and keep the functionality. Perhaps I can convince Chris to add it to the main source tree.

-(e)

#16 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 17 October 2010 - 05:56 PM

I have been playing with the code and have managed to slim the size down significantly and keep the functionality. Perhaps I can convince Chris to add it to the main source tree.

Hi sweetlilmre,

We'd love to look at putting this (or something like it) into a firmware update.

Chris

#17 sweetlilmre

sweetlilmre

    Advanced Member

  • Members
  • PipPipPip
  • 62 posts

Posted 17 October 2010 - 07:29 PM

Hi sweetlilmre,

We'd love to look at putting this (or something like it) into a firmware update.

Chris


Awesome :)

The code is yours to do with what you will. I have made some improvements though so perhaps I should get you the new version.
I would appreciate your thoughts on this:

The basic functionality is now wrapped into a class that provides two native methods:

  [MethodImpl( MethodImplOptions.InternalCall )]
  private extern void NativeWrite( Cpu.Pin clockPin, Cpu.Pin dataPin, byte[] data, int writeOffset, int writeCount,
 									bool risingClock, bool bigEndian );

  [MethodImpl( MethodImplOptions.InternalCall )]
  private extern void NativeWrite32( Cpu.Pin clockPin, Cpu.Pin dataPin, UInt32 data, byte numBits, bool risingClock,
   									bool bigEndian );

risingClock
allows for a rising edge clock signal (true) or falling edge (false)
bigEndian
indicates the bit order i.e. true = most significant bit first, false = least significant bit first. This applies on a per-byte basis for the Write() method and across the 32 bits for the Write32() method.
numBits
number of bits to process for Write32(). In bigEndian mode this indicates the start bit i.e. numBits = 9 would bitbang bits 8 to 0 in that order

Public methods wrap the internal methods to prevent passing a Cpu Pin that has not been assigned to an OutputPort (I could have passed the port to the native method but the marshalling is more complex and slower that way). Also resource management is handled by the containing class.

This seems to be the best compromise I could come up with in terms of speed and efficiency.
Unfortunately I left my NetDuino at work so I will only be able to test these changes tomorrow.

In terms of naming conventions / namespace, I would like to build this so that it is a drop in with the least amount of work for you. How would you like me to do this? Should I extend code inside the SecretLabs namespace? I am happy to assign all rights etc. over to you in this case?

-(e)

[edit: for numBits clarification]

Edited by sweetlilmre, 17 October 2010 - 07:39 PM.


#18 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 17 October 2010 - 08:17 PM

Hi sweetlilmre, Very cool. A few questions: 1. What do (or others) see as the typical use cases for this feature? By including it in the core firmware, we'd like to make sure that we communicate its use and value clearly to users. 2. What limits are you putting on length of data? My only concern would be that the code might send out enough bits that it would tie up the processor and not let other managed code run... In .NET MF, native code should use timers, continuations, or completions for long-running tasks. 3. Are you willing to include this in the core codebase (Apache 2.0 licensed)? Attribution to original authors (internal or external) doesn't appear in any of the source--but we'd like to find a way to give you credit. At minimum we can give you a big public "thank you" in the online release notes... Hmm, have to think about that... Chris

#19 sweetlilmre

sweetlilmre

    Advanced Member

  • Members
  • PipPipPip
  • 62 posts

Posted 17 October 2010 - 09:01 PM

Hi sweetlilmre,

Very cool.

A few questions:
1. What do (or others) see as the typical use cases for this feature? By including it in the core firmware, we'd like to make sure that we communicate its use and value clearly to users.

2. What limits are you putting on length of data? My only concern would be that the code might send out enough bits that it would tie up the processor and not let other managed code run... In .NET MF, native code should use timers, continuations, or completions for long-running tasks.

3. Are you willing to include this in the core codebase (Apache 2.0 licensed)? Attribution to original authors (internal or external) doesn't appear in any of the source--but we'd like to find a way to give you credit. At minimum we can give you a big public "thank you" in the online release notes... Hmm, have to think about that...

Chris


1. Typical use case is to handle hardware like the HT1632, shift registers etc. Of course you CAN do this in managed, its just slow. Basically any hardware that can be bitbanged can now be used 'speedily' from a NetDuino without custom drivers.

2. There is no limit on the length of data atm. typical usages look to be small arrays (16-32 bytes?) but I am willing to look into friendlier options to allow 'unlimited' data or even cap it at some reasonable value.

3. Sure no problem. Any license is pretty much fine with me. I am no GPL zealot :)

Something things to think about:
  • variable SPI might perform a similar function, although that obviously dictates the usage of the SPI pins. How is this going btw?
  • the 1-wire interface CW2 wrote also could use some firmware love :) It is different enough that it needs its own impl though.
-(e)

#20 sweetlilmre

sweetlilmre

    Advanced Member

  • Members
  • PipPipPip
  • 62 posts

Posted 19 October 2010 - 06:01 AM

Hi all, I've attached the latest code which I got a chance to test last night. It seems to perform well (and work!) :) Hookedup: if you want to flash this you will need to reflash your bootloader (tinybooterdecompressor.bin is included) and then flash the hex files included. Source is in the archive as well. Chris, now I just need to rename / whatever to make this an appropriate fit for the firmware. Thanks -(e)

Attached Files






0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.