Saturday, March 7, 2009

Friday, March 6, 2009

avr-gcc read I/O on single port with AT90USB162

I want to repeatedly read from and write to a single port on a AT90USB162. This is to implement a key matrix scanner and pins will be repeated reconfigured as input or output. I ran in to trouble, reads seems to overlap as if they were being cached.



For example, I have pins 1 and 2 shorted.

pin 1 is set as an output. pin 2 an input.

pin 2 is set to pullup.

I output logic 0 on pin 1.

I read the value from pin 2 and store the result in a variable VAL1.



Now I set pin 1 as a input (and pullup).

I set another pin, say pin 3 to logic 0 (not shorted to anything).

I output logic 0 on pin 3.

I read the value from pin 2 in to a variable VAL2.





Now logically VAL1 should be 0 and VAL2 1. However that doesn't seem to be the case. If I do this I often read 1 for both VAL1 and VAL2. Removing the second read however makes VAL1 revert to it's correct value, EVEN THOUGH BOTH READS SHOULD BE INDEPENDENT!! I've not seen this with the AT90USBKey so it's a bit odd.


The solution I've found is to place a delay loop after the port configuration but before the read, in my code:

inline unsigned char get_scan(unsigned char pin) {

unsigned char p = 1 << pin;

DDR = 0x00 ^ p;
PORTD = 0xFF ^ p;

for(volatile int i=0;i<100;i++);

return ~p & PIND;
}


The volatile is important, if you omit that it doesn't work. I guess the compiler optimizes it out. (volatile tells the compiler some other external code could change this variable so explicitly check it where ever it's referenced).

Wednesday, March 4, 2009

jvterm: text based cut and based


I've been trying to rid myself of the mouse. The final thing holding me back is cut and paste for terminal applications. Turns out that most Linux terminal programs don't have any support for keyboard based cut and paste. And in fact the only mainstream terminal app I've seen it in the The OS X Tiger Terminal.app (it seems to have been removed from later versions).



Anyway, after some hunting I found a Linux terminal program that does text based cut and paste. It's called jvterm. The downside is that though it's an X11 application it's not really designed to run in concert with X. It only works full screen and you can't alt-tab between it and X applications. Anyway, I couldn't find the documentation for text based selection so here's typically how you might use it:


Press Shift twice to enter selection mode

Use the cursor keys to move to the start of the selection region

Press Shift again

Move to the end of the selection region (text will be highlighted)

Press space


The text will now be on the clipboard. To paste it press Shift Twice and then Enter.


This is a really neat feature, and I hope it finds its way in to other terminal applications.



(protip: Read the man page. I found this out from guessing, but it's actually in the man page).





AHHH! You can do something similar with screen but how do I get it to share the X clipboard?!?




There's a urxvt (rxvt-unicode) perl script for this!

I found it in google cache and have copied it here:

HERE

To use it press alt-y to activate. Move using vi style keystrokes (hjkl) then press space to start selection and space to end. The text appears on you x buffer via xclip! Neato!

To install the script copy it to ~/.urxvt The copy the following in to you ~/.Xdefaults:

URxvt.keysym.M-y: perl:mark-and-yank:activate_mark_mode
URxvt.keysym.M-u: perl:mark-and-yank:activate_mark_url_mode
URxvt.perl-lib: /home/new/.urxvt/
URxvt.perl-ext-common: tabbed,mark-and-yank
URxvt.urlLauncher: firefox



Sunday, March 1, 2009

Gaussian and Binomial distributions

I'm most probably being entirely stupid here...

I've been trying to understand the Gaussian distribution and it's relation to the Binomial distribution. I've kind of decided that the Gaussian distribution is a continuous representation of the Binomial distribution. Is this correct?

Anyway, here is some C++ which creates a binomial distribution by adding n random values (-1,0 or 1) to a fixed initial value. I think for this as a kind of 2D random walk. Here's the code:

#include <vector>
#include <iostream>
#include <math.h>

using namespace std;

int main(void) {

vector<size_t> space(100,0);

size_t tries=1000000;
size_t offset=50;
for(size_t n=0;n<tries;n++) {

size_t moves=1000;

int final=50;
for(size_t t=0;t<moves;t++) {
int val = rand()%3;
val -= 1;

final +=val;
}
space[final]++;
}

for(int n=0;n<space.size();n++) {
cout << n << " " << space[n] << endl;
}

return 0;
}



Here's the gnuplot generated from the output:



If you have any pointer on the link between Binomial and Gaussian distributions explained in a way a computer scientist can understand please add them below.