From 68dabd22a63dcfdf3815be9a61937f564f193d5b Mon Sep 17 00:00:00 2001
From: Oliver Ford <oliford@NervousEnergy.(none)>
Date: Fri, 6 Jun 2008 00:00:55 +0100
Subject: [PATCH] Hacked in stuff to turn bluetooth chip on and watch when/where it works
- Turns out to be pointless, nvm.
---
 include/irq.h    |    6 ++
 src/irq.cpp      |  255 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/l1trace.cpp  |    4 +
 src/pxatrace.cpp |    4 +
 4 files changed, 269 insertions(+), 0 deletions(-)

diff --git a/include/irq.h b/include/irq.h
index 6a00ff9..630d36f 100644
--- a/include/irq.h
+++ b/include/irq.h
@@ -112,6 +112,12 @@ struct irqData {
     uint32 mergeTableStart;
     uint32 l1Copy[4096];
     uint32 l1Changed[4096];
+
+	// iPAQ 214 Bluetooth test
+	uint32 *vGPIOs;
+	uint32 *vMFPs;
+	uint32 *vTimers;
+	int btTestDone;
 };
 
 // Add an item to the trace buffer.
diff --git a/src/irq.cpp b/src/irq.cpp
index 7764c2b..7214753 100644
--- a/src/irq.cpp
+++ b/src/irq.cpp
@@ -56,6 +56,8 @@ static uint32 resumeHandlerOvr = 0xffffffff;
 REG_VAR_INT(testWirqAvail,"resumeHandlerOvr",resumeHandlerOvr,
             "Force this resume handler physical address during WIRQ (for internal use)")
 
+void prepBT(struct irqData *data );
+void __irq testBT(struct irqData *data, uint32 *vGPIOs, uint32 *vMFPs, uint32 *vTimers);
 
 /****************************************************************
  * PXA wrappers
@@ -224,6 +226,10 @@ resume_handler(struct irqData *data, struct irqregs *regs)
     if (isPXA)
         PXA_resume_handler(data, regs);
 
+    testBT(data,(uint32 *)0x40e00000,
+		(uint32 *)0x40e10000,
+		(uint32 *)0x40a00000 );
+
     add_trace(data, report_resume);
     checkPolls(data, &data->resumepoll, 0);
 }
@@ -467,6 +473,8 @@ cmd_wirq(const char *cmd, const char *args)
 
     preLoop(data);
 
+	prepBT(data);
+
     ret = prepPXAtraps(data);
     if (ret)
         goto abort;
@@ -643,3 +651,250 @@ static void __irq checkMMUMerge(struct irqData *data )
 		}
 	}
 }
+
+
+
+
+
+static void
+report_btattempt(irqData *data, const char *header, traceitem *item)
+{
+	int gp79=item->d0;
+	int gp81=item->d1;
+	int gp84=item->d2;
+	int gp114=item->d3;
+	int gp124=item->d4;
+	Output("%s BT wakeup status: 79=%i 81=%i 84=%i 114=%i 124=%i",header,gp79,gp81,gp84,gp114,gp124);
+}
+
+static void __irq  setGPIOdir(uint32 *vGPIOs, int gpio, int output){
+	int bit;
+	uint32 *dir = vGPIOs + 3;
+	
+	if(gpio < 32)		bit = gpio;
+	else if(gpio < 64){	bit = gpio-32;	dir += 1;	}
+	else if(gpio < 96){	bit = gpio-64;	dir += 2;	}
+	else if(gpio < 127){	bit = gpio-96;	dir += 64;	}
+	else return;
+
+	if(output){
+		*dir |= (1 << bit);
+// 		Output("setGPIOdir: set %p bit %i",dir,bit);
+	}else{
+		*dir &= ~(1 << bit);
+// 		Output("setGPIOdir: clear %p bit %i",dir,bit);
+	}
+}
+
+static void __irq  setGPIO(uint32 *vGPIOs, int gpio, int on ){
+	int bit;
+	uint32 *set = vGPIOs + 6;
+	uint32 *clr = vGPIOs + 9;
+	
+	if(gpio < 32)		bit = gpio;
+	else if(gpio < 64){	bit = gpio-32;	set += 1; clr += 1;}
+	else if(gpio < 96){	bit = gpio-64;	set += 2; clr += 2; }
+	else if(gpio < 127){	bit = gpio-96;	set += 64; clr += 64; }
+	else return;
+
+	if(on){
+		*set |= (1 << bit);
+// 		Output("setGPIO: set %p bit %i",set,bit);
+	}else{
+		*clr |= (1 << bit);
+// 		Output("setGPIO: set %p bit %i",clr,bit);
+	}
+}
+
+static int __irq  getGPIO(uint32 *vGPIOs, int gpio ){
+	int bit;
+	uint32 *level = vGPIOs + 0;
+	
+	if(gpio < 32)		bit = gpio;
+	else if(gpio < 64){	bit = gpio-32;	level += 1;}
+	else if(gpio < 96){	bit = gpio-64;	level += 2;}
+	else if(gpio < 127){	bit = gpio-96;	level += 64; }
+	else return -1;
+
+// 	Output("getGPIO: read %p and shift right by %i",level,bit);
+	return (*level >> bit) & 0x01;
+	//return 0;
+}
+
+static void __irq  mdelay(uint32 *vTimers, uint32 msecs){
+	volatile uint32 *counter0 = vTimers + 4; //3.25Mhz clock
+	uint32 start,end,now;
+	
+	start = *counter0;
+	end = start + (msecs * 3250);
+	//Output("mdelay: counter is %08x, waiting till %08x",start,end);
+
+	do{
+		now = *counter0;		
+	}while( now < end );
+
+	
+}
+
+void prepBT(struct irqData *data ){
+	data->vGPIOs = (uint32*)memPhysMap(0x40e00000);
+	data->vMFPs = (uint32*)memPhysMap(0x40e10000);
+	data->vTimers = (uint32*)memPhysMap(0x40a00000);
+	data->btTestDone = 0;
+
+	Output("gpio vbase = %p",data->vGPIOs);
+	Output("mfp vbase = %p",data->vMFPs);
+	Output("timers vbase = %p",data->vTimers);
+}
+
+
+void __irq testBT(struct irqData *data, uint32 *vGPIOs, uint32 *vMFPs, uint32 *vTimers)
+{
+	volatile uint32 *mfp3 = vMFPs + (0x27c/4);
+	volatile uint32 *mfp3_2 = vMFPs + (0x2e0/4);
+	volatile uint32 *mfp53 = vMFPs + (0x474/4);
+	volatile uint32 *mfp71 = vMFPs + (0x4bc/4);
+	volatile uint32 *mfp79 = vMFPs + (0x4dc/4);	//CTS
+	volatile uint32 *mfp81 = vMFPs + (0x4e4/4);
+	volatile uint32 *mfp84 = vMFPs + (0x4f0/4);	//RTS
+	volatile uint32 *mfp114 = vMFPs + (0x63c/4);
+	volatile uint32 *mfp124 = vMFPs + (0x664/4);
+
+	//if(data->btTestDone)
+	//	return;
+	//data->btTestDone = 1;
+
+	setGPIO(vGPIOs, 3, 1);
+
+	add_trace(data, report_btattempt,getGPIO(vGPIOs, 79),getGPIO(vGPIOs, 81),getGPIO(vGPIOs, 84),getGPIO(vGPIOs, 114),getGPIO(vGPIOs, 124));
+
+// 	Output("set %p",mfp53);
+// 	Output("set %p",mfp71);
+// 	Output("set %p",mfp79);
+// 	Output("set %p",mfp81);
+// 	Output("set %p",mfp84);
+// 	Output("set %p",mfp114);
+// 	Output("set %p",mfp124);
+
+ 	*mfp3 = 0x0844;
+ 	*mfp3_2 = 0x8C40;
+ 	*mfp53 = 0x8840;
+ 	*mfp71 = 0x8840;
+ 	*mfp79 = 0x0840; // af0 = gpio
+ 	*mfp81 = 0x0840;
+ 	*mfp84 = 0x0840; // af0 = gpio
+ 	*mfp114 = 0x8040;
+ 	*mfp124 = 0x8840;
+	mdelay(vTimers, 1);	
+
+	add_trace(data, report_btattempt,getGPIO(vGPIOs, 79),getGPIO(vGPIOs, 81),getGPIO(vGPIOs, 84),getGPIO(vGPIOs, 114),getGPIO(vGPIOs, 124));
+
+	setGPIOdir(vGPIOs, 53, 1);
+	setGPIOdir(vGPIOs, 71, 1);
+	setGPIOdir(vGPIOs, 79, 0);	// CTS
+	setGPIOdir(vGPIOs, 81, 1);
+	setGPIOdir(vGPIOs, 84, 1);	// RTS
+	setGPIOdir(vGPIOs, 114, 1);
+	setGPIOdir(vGPIOs, 124, 1);
+	mdelay(vTimers, 1);
+
+	add_trace(data, report_btattempt,getGPIO(vGPIOs, 79),getGPIO(vGPIOs, 81),getGPIO(vGPIOs, 84),getGPIO(vGPIOs, 114),getGPIO(vGPIOs, 124));
+
+	//everything off
+	setGPIO(vGPIOs, 53, 0);
+	setGPIO(vGPIOs, 71, 0);	
+	setGPIO(vGPIOs, 81, 0);
+	setGPIO(vGPIOs, 84, 0);	// RTS
+	setGPIO(vGPIOs, 114, 0);
+	setGPIO(vGPIOs, 124, 0);
+	mdelay(vTimers, 100);			//wait for it to settle
+
+	add_trace(data, report_btattempt,getGPIO(vGPIOs, 79),getGPIO(vGPIOs, 81),getGPIO(vGPIOs, 84),getGPIO(vGPIOs, 114),getGPIO(vGPIOs, 124));
+	
+	setGPIO(vGPIOs, 53, 1);
+	setGPIO(vGPIOs, 71, 1);
+	setGPIO(vGPIOs, 124, 1);
+	mdelay(vTimers, 6);
+
+	add_trace(data, report_btattempt,getGPIO(vGPIOs, 79),getGPIO(vGPIOs, 81),getGPIO(vGPIOs, 84),getGPIO(vGPIOs, 114),getGPIO(vGPIOs, 124));
+		
+	setGPIO(vGPIOs, 81, 0);
+	setGPIO(vGPIOs, 84, 1);		// RTS			
+	setGPIO(vGPIOs, 114, 1);
+	mdelay(vTimers, 2);	// delay(2)
+
+	add_trace(data, report_btattempt,getGPIO(vGPIOs, 79),getGPIO(vGPIOs, 81),getGPIO(vGPIOs, 84),getGPIO(vGPIOs, 114),getGPIO(vGPIOs, 124));
+
+	setGPIO(vGPIOs, 114, 0);
+	mdelay(vTimers, 2);	// delay(2)
+
+	add_trace(data, report_btattempt,getGPIO(vGPIOs, 79),getGPIO(vGPIOs, 81),getGPIO(vGPIOs, 84),getGPIO(vGPIOs, 114),getGPIO(vGPIOs, 124));
+
+	setGPIO(vGPIOs, 114, 1);
+	setGPIO(vGPIOs, 81, 1);
+	mdelay(vTimers, 500);	// delay(500)
+
+	add_trace(data, report_btattempt,getGPIO(vGPIOs, 79),getGPIO(vGPIOs, 81),getGPIO(vGPIOs, 84),getGPIO(vGPIOs, 114),getGPIO(vGPIOs, 124));
+
+	setGPIO(vGPIOs, 84, 0);	// 84(RTS)	--> off
+	mdelay(vTimers, 5);
+
+	//int cts = getGPIO(vGPIOs, 79);
+	add_trace(data, report_btattempt,
+		getGPIO(vGPIOs, 79),
+		getGPIO(vGPIOs, 81),
+		getGPIO(vGPIOs, 84),
+		getGPIO(vGPIOs, 114),
+		getGPIO(vGPIOs, 124) );
+	
+	//everything off again
+	setGPIO(vGPIOs, 53, 0);
+	setGPIO(vGPIOs, 71, 0);	
+	setGPIO(vGPIOs, 81, 0);
+	setGPIO(vGPIOs, 84, 0);	// RTS
+	setGPIO(vGPIOs, 114, 0);
+	setGPIO(vGPIOs, 124, 0);
+	mdelay(vTimers, 1);
+
+	add_trace(data, report_btattempt,getGPIO(vGPIOs, 79),getGPIO(vGPIOs, 81),getGPIO(vGPIOs, 84),getGPIO(vGPIOs, 114),getGPIO(vGPIOs, 124));
+	setGPIO(vGPIOs, 3, 0);
+}
+
+/*
+
+
+Set GPIOs 53,71,124,114 low
+Wait a few seconds for everything to die
+
+Raise 53,71,124 
+6ms pause
+Raise 114
+3ms pause
+lower 114
+3ms pause
+raise 81 and 114
+500ms pause
+
+
+------
+More accurate version of all the twiddling from bt_pwrmgr.dll:
+
+81	--> AF0
+81	--> output
+81	--> off
+84	--> AF0
+84(RTS)	--> output
+84(RTS)	--> on
+114	--> on
+114	???
+delay(2)
+114	--> off
+delay(2)
+114	--> on
+81	--> on
+delay(500)
+84(RTS)	--> off
+delay(5)
+84(RTS)	--> AF1 (RTS)
+check 	79(CTS) ok if on
+*/
diff --git a/src/l1trace.cpp b/src/l1trace.cpp
index 8bf7d67..809f86f 100644
--- a/src/l1trace.cpp
+++ b/src/l1trace.cpp
@@ -17,6 +17,8 @@
 #define TOPBITS 0xFFF00000
 #define BOTBITS 0x000FFFFF
 
+void __irq testBT(struct irqData *data, uint32 *vGPIOs, uint32 *vMFPs, uint32 *vTimers);
+
 /*
  * Theory of operation:
  *
@@ -181,6 +183,8 @@ static void __irq reportAddr(struct irqData *data, uint32 addr, uint32 val,
                 continue;
         }
 
+	testBT(data,data->vGPIOs,data->vMFPs,data->vTimers);
+
         uint32 shift = 8 * (addr & 3);
         uint32 mask = ((1 << (8 * addrsize)) - 1) << shift;
         uint32 cmpval = ((val << shift) & mask) | (t->cmpVal & ~mask);
diff --git a/src/pxatrace.cpp b/src/pxatrace.cpp
index bd8fce0..c0d0122 100644
--- a/src/pxatrace.cpp
+++ b/src/pxatrace.cpp
@@ -11,6 +11,8 @@
 #include "arminsns.h" // getInsnName
 #include "irq.h"
 
+void __irq testBT(struct irqData *data, uint32 *vGPIOs, uint32 *vMFPs, uint32 *vTimers);
+
 // The DBCON software debug register
 DEF_GETIRQCPR(get_DBCON, p15, 0, c14, c4, 0)
 // Interrupt status register
@@ -139,6 +141,7 @@ PXA_prefetch_handler(struct irqData *data, struct irqregs *regs)
     } else if (idata->addr2 == old_pc) {
         // Called after single stepping - reset breakpoint.
         set_IBCR0(idata->addr1 | 0x01);
+	testBT(data,data->vGPIOs,data->vMFPs,data->vTimers);
     } else {
         idata = &data->insns[1];
         if (idata->addr1 == old_pc) {
@@ -159,6 +162,7 @@ PXA_prefetch_handler(struct irqData *data, struct irqregs *regs)
               , getReg(regs, idata->reg1)
               , getReg(regs, idata->reg2));
 
+
     return 1;
 }
 
-- 
1.5.2.5

