--- /dev/null
+/*
+ * buttons.c - button api
+ *
+ * author: hackbard@hackdaworld.org
+ *
+ */
+
+#include "buttons.h"
+
+void button_init(void) {
+
+ /*
+ * select as input the following pins
+ * - p0.30 : interrupt, wtf is the 'vw 3 p9'?
+ * - p0.28, p0.27, p3.21, p3.20, p0.22, p0.13 : column select
+ *
+ * select as output
+ * - p2.18-p2.24 : the rows
+ */
+
+ // gpio, as is: p3.20, p3.21
+ PINSEL1&=~((1<<29)|(1<<28)); // p0.30
+ PINSEL1&=~((1<<25)|(1<<24)); // p0.28
+ PINSEL1&=~((1<<23)|(1<<22)); // p0.27
+ PINSEL1&=~((1<<13)|(1<<12)); // p0.22
+ PINSEL0&=~((1<<27)|(1<<26)); // p0.13
+ // ctrl databus for p2.18 - p2.24
+ PINSEL2&=(PINSEL2&(~((1<<5)|(1<<4))))|(1<<4);
+ // input
+ IODIR0&=~((1<<30)|(1<<28)|(1<<27)|(1<<22)|(1<<13));
+ IODIR3&=~((1<<21)|(1<<20));
+ // output + pull them high
+ IODIR2|=((1<<18)|(1<<19)|(1<<20)|(1<<21)|(1<<22)|(1<<23)|(1<<24));
+ IOSET2=((1<<18)|(1<<19)|(1<<20)|(1<<21)|(1<<22)|(1<<23)|(1<<24));
+}
+
+void button_select_row(u8 row) {
+
+ IOSET2=((1<<18)|(1<<19)|(1<<20)|(1<<21)|(1<<22)|(1<<23)|(1<<24));
+ if(row>6)
+ return;
+ IOCLR2=(1<<(18+row));
+}
+
+u8 button_get_event(u64 *keys,int retries) {
+
+ u8 row;
+ u8 offset;
+ u8 cnt;
+ u32 port0,port3;
+
+ *keys=0;
+ cnt=0;
+
+ while(retries--) {
+ /* rest counter */
+ offset=0;
+ /* rows */
+ for(row=0;row<7;row++) {
+ /* select the row */
+ button_select_row(row);
+ /* scan the columns 6 */
+ port0=IOPIN0;
+ port3=IOPIN2;
+ if(!(port0&(1<<28))) {
+ *keys|=(1<<(offset+0));
+ cnt+=1;
+ }
+ if(!(port0&(1<<27))) {
+ *keys|=(1<<(offset+1));
+ cnt+=1;
+ }
+ if(!(port0&(1<<22))) {
+ *keys|=(1<<(offset+2));
+ cnt+=1;
+ }
+ if(!(port0&(1<<13))) {
+ *keys|=(1<<(offset+3));
+ cnt+=1;
+ }
+ if(!(port3&(1<<21))) {
+ *keys|=(1<<(offset+4));
+ cnt+=1;
+ }
+ if(!(port3&(1<<20))) {
+ *keys|=(1<<(offset+5));
+ cnt+=1;
+ }
+ offset+=6;
+ }
+ if(*keys)
+ break;
+ }
+
+ return cnt;
+}
+