Sunday, October 10, 2010

Lattice XP2 Brevia Diamond Starter Project

Its a royal PITA to specify the pinout of a 144 pin part! So there is no point to doing this more than once -- across the entire internet.

Its unfortunate that Lattice does not provide one, but their Demo project does not specify the IOs since they are not used.

In my code repository is a Diamond project that specifies all XP2 IOs as used by the Brevia board. And it sets the XP2 part up with 3 clocks, 400mhz, 50mhz, and 25mhz. Of course you can change these clock values by editing the "pll" module.

You checkout the entire project (recommended), or browse and pull down the key files to add into your own project:

top.v: the "main" verilog file

starter1.lpf: the file that places the verilog symbols onto particular pins

pll.v: autogenerated pll module that sets up the 3 clocks.

Tuesday, October 5, 2010

Lattice Diamond on Ubuntu 10.04 64 bit

For some reason, Lattice provides its new Diamond GUI for the second most popular Linux distribution instead of Ubuntu, the most popular distribution.

Here is how to fix their mistake :-). Additionally, they only provide 32 bit binaries but I have a 64 bit system. So this how-to solves that problem as well.

Installing the IDE

Step 1: Download Diamond's .rpm located here, and apply for a license.

Step 2: Install "alien", the .rpm to .deb package converter.
sudo apt-get install alien

Step 3: install "getlibs"
This handy script will install the 32-bit version of libraries even if you are running 64-bit Ubuntu. Since Diamond is 32 bit you will have to install some 32 bit stuff.

click here for info (http://ubuntuforums.org/showthread.php?t=474790)

Step 4: Install 32 bit libraries (if on 64 bit Ubuntu)
apt-get install ia-32libs
sudo getlibs -p libmotif3

I am doing this from memory...if you run diamond (later step) and get a missing .so, please run "getlibs -l " to install that library and post a comment so I can update this HOW-TO!

Step 5: Run alien on the diamond RPM.
When the diamond RPM is downloaded, run alien on it:
alien -d diamond_1_0-base-135-i386-linux.rpm

Wait for a very long time. This will ultimately have an error and drop you back to the Linux prompt. It will not hang (be patient). However you will find that it created a subdirectory called "diamond_1_0-base-1.0" off your current directory. Everything we need is in there. I'll copy it to /usr/local so it is accessible:

sudo cp -r diamond_1_0-base-1.0/usr/local /usr/local

Step 6: Copy the license
You should have gotten a license file in your email stream from step 1.
Save that file into the diamond subdirectory: /usr/local/diamond/1.0/license/license.txt

Step 7: Run it!
/usr/local/diamond/1.0/bin/lin/diamond

if you get any missing libraries, please attempt to "getlibs" (see step 4) and post a comment here so others can benefit from your pain :-).


Installing the Lattice USB Programmer

Before you actually program your board, you'll have to install drivers for the programmer dongle.

The Lattice USB programmer uses libusb so that is convenient as no kernel module needs to be built. I think there is another programmer that uses the FTDI 2232 chip that does require drivers to be installed. This how-to won't cover that one, or the parallel port programmer (which I was unable to get working).

Step 1: install libusb
sudo apt-get install libusb-1.0-0

Step 2: Add the USB device to "udev"

sudo emacs /etc/udev/rules.d/10-local.rules

Append this line:
#lattice
BUS=="usb",ACTION=="add",SYSFS{idVendor}=="1134",SYSFS{idProduct}=="8001",MODE=="0660",OWNER=="root",SYMLINK+="lattice-%n"

Step 3: Plug in the USB device programmer

You should see a device in /dev named "lattice":

~$ ls /dev/lat*
/dev/lattice-6


Step 4: Fix permissions.
Shown here is an impermanent fix. Every time you turn off your computer or remove the programmer you'll have to re-run this, since the device is removed and recreated during these events. I'm sure that some of you Ubuntu/Linux wizards can tell me how to make it permanent...

sudo chmod a+rw /dev/lat*

That's it! The ispVM programming tool should auto-detect the cable now.

Have fun and post some OSS designs!

Monday, October 4, 2010

Lattice FPGA -- They are beginning to get OSS

After a quite a bit of comparative evaluation I chose the Lattice XP2 FPGA and the Brevia demo board for a bit of hardware hacking. (In short, I wanted a non-volatile FPGA or large CPLD, and found that the XP2 and MachXO seemed better than the Altera and Xilinx offerings).

And I'm happy to say that unlike my prior complaints about Cypress, I do think that Lattice "gets it" around open source hardware.

Al is not perfect, but they seem to be moving rapidly in the right direction.

First off, they recently obsoleted their old GUI and released their "Diamond" GUI for both Windows and Linux. Its a little crunchy still on Linux. However, this is a major, probably very expensive, initiative and Lattice should be commended for letting Linux be part of it! While they officially only support Red Hat, check out this output coming from the "compiler":

Warning: You are running on an unsupported platform
'synplify_pro' only supports Red Hat Enterprise Linux 4.0 and above
current platform: Ubuntu 10.04.1 LTS


That's right! I managed to get it up on Ubuntu 64 bit (I'll provide a little HOW TO in my next post).

Secondly, they priced the board extremely well at $29.

Third, they provide a lot of free libraries (called "designs" or "IP" in the hardware world) so long as you only use them on Lattice parts. Personally, I can live with that. After all Lattice is in the business of selling chips. And you know if I decide to switch chips, I can implement the underlying library myself and still have benefited from using Lattice's library to get me prototyping my application code faster...

Fourth, the GUI/compiler is free (well, its a 1 year free license so I guess someday they could take that away) and command line accessible.

Fifth, the USB programmer uses libusb, so you don't even need to install a special driver. This makes it a lot easier to run on different linux distros.

This is a great first step!!! Its perfect for OSS hackers and students.

... but there is stuff Lattice needs to work on.

First, my biggest gripe is that the Brevia board ships with a parallel port programmer. But who has parallel ports anymore? And by the way, purchasing a USB->parallel converter WILL NOT work. Those converters do not translate all parallel signals. Lattice FAEs claim some converters work, but will not endorse a particular one so we are left guessing.

In fact I was unable to get the parallel port programmer to work.

Second, the USB programmer purchased separately costs $150!!! This is an evil bait-and-switch. Honestly I haven't priced components out, but in this market I'd bet that USB components are cheaper than parallel because its all about volume. So what is going on here!!?

However its standard JTAG so other programmers should also work...

Third, the ispVM device programming tool was poorly ported to Linux. In particular, you actually specify the old 8088 parallel port number 0x378 (or whatever) to identify the parallel port, not the device name (and again I never got it to work with the parallel programmer).

Fourth, they only offer RPMs. Lattice, even if you don't want to support every distro, its traditional to just jam your program in a big gzipped tarball archive so we can pull it down and install it by hand by coping it to /usr/local or something along those lines.

And finally, Diamond is still a little rough around the edges. For example, sometimes the editor stops working and I have to close and reopen my project. Even worse, I managed to get my project into an inconsistent state where some generated files thought that certain clock resources existed but I had removed them. The easiest way out of that was to create a new project :-(, and copy my source code over.

However Diamond is very new. I expect very good things.

All in all its a great start! Thanks Lattice!

Disclosure: I am in no way affiliated with Lattice, other than having bought their $29 Brevia board...

Saturday, August 7, 2010

Arduino/AVR vs Cypress/PSOC

I've recently been working on a simple PSOC (www.cypress.com/psoc) project using the CY8C64315 USB chip and can't help but compare it to the popular Arduino platform since it is pretty similar to the AVR 328P. These are my observations:

Feature Comparison

Cypress/PSOC 9, Arduino/AVR 5

Initially I chose PSOC because it has some great features packed into a tiny 16 pin QFN part at a cheap price. In particular it provides a full-speed USB device with very few external components -- not even a crystal! It runs at 24Mhz instead of the AVR's 20mhz and contains SPI, I2C, a bunch of IOs and so forth.

One issue is that it does not contain a serial UART (but other, bigger PSOC parts do), but I'm hoping to do a soft-serial implementation.

Perhaps its kind of silly but I didn't want my USB controller to be larger, more expensive, and have more pins than an embedded CPU itself (but when you get right down to it, it is in fact on par or more powerful than the 328p)! So the tiny part size combined with good features was the clincher for me.


Documentation


Cypress/PSOC 3, Arduino/AVR 10

The Cypress Application Note search tool is totally impossible to use. And their community site www.psocdeveloper.com is better but not "alive" like the Arduino or even avrfreaks. Its too tightly coupled with Cypress I think.

And none of this stuff comes up in google searches.

Note to Cypress -- you are NOT a SEARCH company! Just post all your App Notes in HTML form on a public site and let Google do the job. It will do it much better and you'll save some money.

One wild/good thing; I posted an issue bringing the chip up and actually got an essentially unsolicited telephone call from a real human being engineer the next day to help me (but had already figured it out). So that can make up for a lot of doc issues, but of course its pretty expensive for Cypress...


Hardware Design


Cypress 2, AVR 10

2. Application Schematic? It seems that Cypress didn't bother to put one in the datasheet. In fact I had to glean portions of the full "typical application schematic" from a bunch of "Application Notes" -- USB from here, ISSP from there. And of course those schematics were not necessarily for the chip variant I chose so there was lots of uncertainty in this process.

In contrast the Arduino project and all its variants are open hardware, so there are lots of circuit examples to choose from.


PSOC Designer vs Arduino IDE

Cypress 5, Arduno 5

PSOC is supposed to be some reconfigurable hardware "magic" that requires a fancy windows-only IDE. Not in my chip. Everything is just registers AFAIK. But still you can use a GUI to configure things and then it generates the code to write these registers for you. Now, this might seem cool, but actually it just gets in the way. It gives Cypress and excuse to not supply an API like the Arduino's "pinMode" and not to supply good docs. So what if you want to CHANGE the behavior of a pin while your program runs -- you've got to delve into the registers...

The rest of the IDE is everything you'd expect from a programmer's IDE. Good job Cypress! You are just as good as the free Eclipse :-).

However I do have one or 2 beefs. It:
1. Only runs on windows *sigh*
2. Pops up an irritiating "Programming" dialog box. This should be done in a small side-docked pane so the programmer can continue to WORK while the chip gets programmed...


Build Toolchain

Cypress/PSOC 5, Arduino/AVR 5

G++, GCC???

For some reason, instead of adding a gcc backend for the PSOC CPU, Cypress decided to go with some commercial C compiler. So no C++.

The result is a bit more like "Kiel" C then gcc and in particular has irritatingly difficult tranlation between a string stored in "flash" vs one in "ram". In fact, you have to define 2 functions one to handle "__flash" strings and one to handle normal "char *". *sigh*

But of course Arduino has this strange thing called "processing" with is actually C++ with some "try to help me but actually get in the way" thrown in so really average marks on both.


How to "Blink" (Basic programs/sketches)


Cypress/PSOC 7, Arduino/AVR 10

Its pretty INSANELY hard to figure out how to do simple things like configure a digital input (you use the GUI to graphically set the pin as CPU open-drain, then in code write the bit HIGH). Also standard C functions like "printf" are there but don't work... better that they not be there if they don't work.

Yet at the same time, it can be very EASY to do an entire USB HID device. So it just depends on how many Cypress libraries you can use.


Software Layers


Cypress/PSOC 9, Arduino/AVR 9

Ok, I've got to give cred to Cypress for being the 1st hardware company (AFAIK) to realise that we don't want to program at the register level. Yes, the GUI has "user modules" and you just pull them into your project to get massive functionality like a USB endpoint.

One nasty issue the use of lots of assembly??!!? All the Cypress libraries AFAIK are written in assembly. This makes reading the code hard :-). And also you can't ignore it; installing things like interrupt handlers requires you to get down in there and call out to your C. And this is NOT easy; to make the C compiler correctly save state, you have to basically trick the CPU into calling your C routine as if it was an interrupt even though you are already IN an interrupt. There's an entire App Note about how to do it :-(.

The advantage is probably smaller code sizes. But the cost is essentially that if you need to modify the library or add a feature, you have to either rewrite the whole thing yourself in C, or learn PSOC assembly which of course ties you and your work inseparably to this processor.

Summary:

Its a neat little device with lots of potential. Great hardware, great software/support philosophy but not so good implementation. But its a pretty steep learning curve...

Now, Arduino/AVR generally relies on the community to provide great programming libraries, examples, tutorials and general help. And we do.

Cypress seems to be doing all/most of the work on its own. It seems to be caught attempting to implement a modern philosophy with a traditional unidirectional information-flow structure.

So while I give cred to Cypress for the tremendous effort I'm amazed at its total disregard for the open source movement -- in compilers, in IDE, in software libraries.

And I'm surprised at its inability to truly capitalize on internet resources and community.

Wednesday, June 9, 2010

Proposal for an "Open Device" License

There is an interesting read about an "open hardware" license here:
http://www.tapr.org/ohl.html

But I am interested in something that goes much further in several ways.

First off, my license would enforce the right and ability to modify a product and (especially) its firmware/software after it has been produced. This is what I mean by "open device" as opposed to simply "open hardware". In a world where the PC is increasingly pushed into a niche market, it is very important to protect the right to run software on other hardware, cell phones for example. I believe that the openness of the IBM PC is what created the personal computer revolution -- and why Apple lost out... as much as I love what Apple is doing on the physical side with the ipod, iphone, ipad, we need to ensure that Apple's restrictive policies do not prevail in devices or we will lose innovation in the personal device marketplace to the detriment of everyone who uses the devices.

This "modifiable device" restriction is also nice because it lets the original producer (and others) can use a high volume producer's hardware, so long as its functionality is accessible.. I believe that this would satisfy many open hardware developers since some are not motivated to make money; they are simply building a device that does not currently exist, and would be happy instead to buy it at Wallmart for significantly less cost. On the other hand, the greatest IP "theft" would be for a company to take a piece of open hardware and inaccessibly embed it within some consumer product, thereby reaping all the rewards of the open hardware communities' efforts and giving nothing back in return.

Secondly, I disagree with the TAPR's reliance on the GPL license to protect software, since (as I said above) it does not protect the ability to run that software on some device. It is very common for a company to comply with GPL by releasing the source of a Linux port onto a new CPU but in fact have no way for the end user to actually upload that release onto the CPU within the company's product! And generally other available hardware will not exist for the new CPU... Ironically, this effect is what drives some open hardware development, because the community then must produce (at great personal expense) custom hardware to utilize the Linux port...

There is one instance that I know of where in fact the software was released and the hardware fortuitously provided an update mechanism. This was the WRT-54G router. This device was a tremendous market success, and open source community's modifications to this router were so popular that some features were actually pushed back into the commerical release, AND even though the company eventually built a cheaper version on vxworks (a different operating system), they continued to sell the original under the product name WRT-54GL (more...). What if this phenomemon was the norm instead of the exception!?

Therefore, I believe that the hardware and software in embedded devices is intrinsically related -- one is almost worthless without the other. And finally, my experience as a software architect within the telecom industry and my experience as an open hardware developer is that in fact the software/firmware is 90% or more of the time effort. Since it is the major cost, it provides great leverage to pry off the lid of "closed" devices.

When you add these and a few other ideas together, you end up not with "open hardware", but something that looks a lot more like an "open device".

Wednesday, June 2, 2010

Success, Wall Street Style

I just finished reading "Den of Thieves" by James Stewart which is about the junk bond scandal that hit wall street in the '80s. What is fascinating about it is the similarities between it and the recent financial meltdown. Just swap "toxic asset" mortgages for corporate loans (AKA junk bonds) and hit the fast forward button.

Since this is a blog, I'm going to skip all explanations (read the book) and just hop to my observations:

First off, the financial system essentially and intrinsically encourages abuse. Capitalism trends towards perfect markets -- therefore there is an ever decreasing profit spread for financial guys to take advantage of. But wall street types are self-selected to not be happy with ever decreasing profits. They will find or create an edge.

Second, the junk-bond related crimes were totally unnecessary; they just added a buck or two per share to an already over-inflated, highly profitable transaction and sometimes "encouraged" a deal to go through if it was stalling. Judging by the lack of major arrests in the toxic asset meltdown, Wall street learned that crime in fact doesn't pay nearly as well as the long, legal con.

Third, never trust finance guys even as part of a reputable institution! [In fact, let me go on a limb and say, its your life, don't trust anyone! For major life issues like financial and medical, respect the expert opinions but learn their biases (for example, surgeons LIKE to do surgery, duhh!) and then spend the time to figure it out yourself!]

Around 2007-2008 a couple of my friends were buying a house and I was alarmed at the tendency for people to trust the bank's evaluation of how large a loan you could bear. Essentially they ceded responsibility for picking a reasonable load to the banking "experts", and did not bother to do even the most basic math. "If the bank is willing to offer me that much I must be good for it" is how the thinking goes. I think that this happened on a nationwide level. But I would tell my friends "yes but the bank's goal is for you to be in debt for the rest of your life, your goal should be to not be in debt. Because when you are in debt, you are paying 10% or more to your creditor. You are going into debt to buy more stuff, but ironically you'll end up with less".

Little did we know that many banks did not even care whether the loan could be repaid...


Recipe for Wall Street Mega-Success
(slashdot style)

1. Identify an information advantage. Look in unregulated areas of finance. For extra credit, artificially create an information advantage in your favor. For example, bundle financial instruments so the underlying entities are hidden. Write contracts that only finanical lawyers can understand (insurance is a great area of opportunity for this method). Transform an out-of-favor, high-risk financial instrument into one that is "in-favor". Take advantage of people's trust in "experts" -- i.e. yourself.

2. Market, market, sell, sell, sell. Get college professors to write papers about how low risk your market historically was (before you entered it).

3. Jam increasingly ludicrious and high risk underlying entities into your framework since that maximizes your profit by reducing the base cost.

4. Use recursion to keep the aura of good times going -- if an issue is about to fail, grab it up, twist it around, and jam it back into the system (AKA refinancing).

3. ??? (this is where the optional crimes are committed)

4. Profit!!!

5. You have 3-7 years; the fall will be from the summit, sudden and hard. be ready to bail.

Saturday, February 6, 2010

Arduino PWM on all pins.

What is PWM?
PWM (pulse width modulation) is the art of faking a particular voltage by rapidly moving between 2 other voltages. For example if you have a digital logic line that is 0 volts when LOW or 5 volts when HIGH, you can "trick" a multimeter into reading 1 volt by setting the line to low for 4/5s of the time and high for 1/5 of the time. The ratio of high to low is called the "duty cycle" and is specified in a percentage.

Why Use PWM?

You can trick a lot of other things too if you toggle the line tens to hundreds of times a second. For example if you connect a LED it will appear dimmer due to the same "persistence of vision" effect that makes movies appear smooth.

Another example is driving motors. Motors contain electromagnets which cause electrical inductance (in analogy "momentum"). If you put a diode across the motor's leads (backwards) then when the motor is turned off, the collapse of the magnetic field continues to drive current through the wire, and through the diode back to the other side of the motor. This current maintains the magnetic field! If there was no resistance this would go on forever (BTW this is how superconductors float above magnets). But since there is resistance, the circulating current slowly dies out.

But if you are doing PWM on the motor, a new influx of energy will re-energize the motor's coils resulting in a smoothly turning motor. But the speed of the motor will vary based on the duty cycle of the PWM. So you can use PWM to change the speed of a DC motor.

The Arduino has some hardware-based PWM. But only on certain pins. For things like motors, you do not need to PWM very fast so it can be done in software. So I have made a software PWM class for Arduino sketches that works on all pins.
The Four Line states in an AVR microcontroller

Another cool feature is that it will do PWM between any 2 line states. You may normally think of a digital line as having only 2 states (high or low) but the Arduino actually offers 4 states, high, low, high impedence, and pull up.

A lot of beginners think of the "low" state as "off" but really it means driven to 0 volts. So if you put a light between a "low" pin and 5v, the light will turn on!

On the other hand "high impedence" actually means "disconnected" or "floating" -- at least as close as you can get to that using solid state electronics. So in a high impedence state, the light described above would NOT turn on. But one issue with a line in the "high impedence" state is that its voltage is undefined and can be sensed as high or low and change between the 2 due to vagaries of electric fields on the board, etc.

"Pull up" refers to a connection to 5v through a large resistor. So it is "high impedence" in the sense that it cannot drive anything, and if driven by some external device it will follow that device. But if the line is otherwise floating, the connection to 5v thru the resistor will make the line show as high.

DOWNLOAD

The Code


#define PWM_NUM_PINS 16
#define PWM_MAX_DUTY 255
#define PWM_DEFAULT_FREQ (16000000.0/128.0) //2MHz for /8 prescale from 16MHz

//?? Software based PWM (Pulse width modulation) library for the ATMEGA168/328 (Arduino).
//
// This class implements PWM in software. PWM is a method whose purpose is to emulate an analog voltage by rapidly toggling a digital
// pin between the high and low states. By changing the duty cycle -- the percent of time the pin is "on" verses "off" the apparent voltage changes.
// This technique is only useful if the pin is controlling a device that averages voltages; for example:
// * Inductors (electromagnets, motors)
// * Capacitors
// * Human perception (via LEDs for example)
// This library does not work as efficiently as the hardware based PWM availabe in the ATMEGA, so that should be used if possible.
// However this library offers PWM on all pins, and also allows you to specify what the "on" and "off" pin states are. For example, you could choose the "off" state to be high impedence.
//
class SoftPWM
{
public:
typedef enum
{
DRIVEN_LOW = 2 | 0,
DRIVEN_HIGH = 2 | 1,
DRIVEN = 2,

FLOATING = 0,
PULL_UP = 1,
HIGH_IMPEDENCE = 0,

UNUSED = 4
} PinBehavior;
//?? Constructor
SoftPWM();

//?? Call this periodically to trigger a state change
void loop(void);

//?? Automatically call the loop() function periodically. Once you call this function YOU SHOULD NOT CALL LOOP()!
void startAutoLoop(int timer=2,int frequency=PWM_DEFAULT_FREQ);
//?? Stop automatic looping.
void stopAutoLoop(void);

//?? Duty Cycle. The fraction of time that the pin is HIGH is duty/255
uint8_t duty[PWM_NUM_PINS];

//?? Set what it means for a pin to be off or on.
// Typically you would want to PWM an output pin and toggle output voltage. This is what PWM normally means, and is the default.
// However, for other applications you may want to toggle the impedence and value simultaneously.
// For example, if the pin is sinking the base of a PNP transistor then you would switch from a high impedence (i.e. open circuit) state to a low output state (i.e. closed circuit, sinking current).
//
void enablePin(int pin, PinBehavior offMode=DRIVEN_LOW, PinBehavior onMode=DRIVEN_HIGH)
{
pinOnBehavior[pin] = onMode;
pinOffBehavior[pin] = offMode;
}
void disablePin(int pin) { pinOnBehavior[pin] = UNUSED; pinOffBehavior[pin] = UNUSED; }

//?? Set all duty cycles to 0
void zero(void)
{
for (int i=0;i != PWM_NUM_PINS;i++)
duty[i] = 0;
}

uint8_t pinOffBehavior[PWM_NUM_PINS];
uint8_t pinOnBehavior[PWM_NUM_PINS];
int bresenham[PWM_NUM_PINS];
};

SoftPWM::SoftPWM()
{
for (int c=0;c != PWM_NUM_PINS;c++)
{
bresenham[c] = 0;
pinOffBehavior[c] = UNUSED;
pinOnBehavior[c] = UNUSED;
}


}

void SoftPWM::loop(void)
{
boolean lvl;
unsigned char regLvlOut=0;
unsigned char regLvlIn;

unsigned char regDirOut=0;
unsigned char regDirIn;

for (int i=0;i != PWM_NUM_PINS;i++)
{
if (i==0) { regLvlIn = PORTD; regDirIn = DDRD; }
if (i==8) { regLvlIn = PORTB; regDirIn = DDRB; }

if (i==8)
{
DDRD = regDirOut;
PORTD = regLvlOut;
}

regLvlOut >>=1;
regDirOut >>=1;

if ((pinOnBehavior[i] & UNUSED) == UNUSED) // If its unused then keep the values the same
{
regDirOut |= (regDirIn&1);
regLvlOut |= (regLvlIn&1);
}
else
{
bresenham[i] += duty[i];
if (bresenham[i]>=PWM_MAX_DUTY)
{
bresenham[i] -= PWM_MAX_DUTY;
lvl = true;
}
else lvl = false;

if (lvl)
{
regLvlOut |= (pinOnBehavior[i]&1) ? 0x80:0;
regDirOut |= (pinOnBehavior[i]>>1) ? 0x80:0;
}
else
{
regLvlOut |= (pinOffBehavior[i]&1) ? 0x80:0;
regDirOut |= (pinOffBehavior[i]>>1) ? 0x80:0;
}

}

regLvlIn >>=1;
regDirIn >>=1;
}

if (1)
{
DDRB = regDirOut;
PORTB = regLvlOut;
}
}

typedef unsigned char byte;

int ledPin = 13;

void testSoftPWM()
{
SoftPWM pwm;
pwm.enablePin(ledPin, SoftPWM::DRIVEN_LOW, SoftPWM::DRIVEN_HIGH);
for (int i=0;i<25600;i++)
{
pwm.duty[ledPin] = i/100;
pwm.loop();
delay(1);
}
}

void setup() {}
void loop() { testSoftPWM(); }

Monday, January 25, 2010

Browser Hacking

Firefox has a cool extension called pyxpcomext that sticks a Python interpreter inside your browser!

But as is it is pretty hard to use unless you are already a browser geek. For example, it is hard to figure out how to access stuff like a page in the browser because all of the Firefox extension documentation is for either C or JavaScript. So you have to sort of read those APIs and translate them thru XPCOM into Python. This is tricky.

So I extended the pyxpcomext example "PyShell" into something a lot more user friendly (it wraps the most common XPCOM stuff into normal Python function calls) and useful. You can access and read details about it here: http://code.google.com/p/juicedpyshell/


Now, what's the point of this, you ask?

Well, what this means is that you can write a Python program that can interact with your browser as you are browsing and even modify the page (sort of like greasemonkey, but in Python) or even "click" the browser to another page for you!

But that's still technology, how about applications?

0. Automation of repetitive browser tasks.

1. Automated test of your live web site if you are a web developer.

2. Sophisticated ad elimination.

3. I'm thinking of a history database that remembers not only the link, i.e. "www.cnn.com" but also the contents of a page. Don't you hate it when you browse to an article only to find it gone!

4. Python XML/HTML development. If you are writing a Python back end server then your python is generating HTML. Its pretty cool to just be able to write hprt(" <> My Header < /h1 >") in the Juiced Python Shell, and actually SEE the rendered HTML appear. Its just like the Python standard "print" command but understands html! This really speeds up the dev/test cycle.


But why not...?

...just write an app that grabs pages as an http client? Well, because your app can't execute Javascript so it won't work on all of the new Web 2.0 sites.

...use greasemonkey? Because everyone hates Javascript :-)!! Seriously, because you can spawn multiple threads in your Python program (however, only the main thread can "touch" the browser). Because you have access to the incredibly rich set of Python libraries. Because Python has a real console and debugger. Greasemonkey is a toy to markup web pages. A very cool toy of course! But still your program will always be limited in complexity by inherent Javascript limitations.