freemyipod r304 - Code Review

Jump to: navigation, search
Repository:freemyipod
Revision:r303‎ | r304 | r305 >
Date:21:36, 1 December 2010
Author:theseven
Status:new
Tags:
Comment:
Fix red: Oops, /me should actually add the new files.
Modified paths:
  • /embios/trunk/target/ipodnano3g/clickwheel.c (added) (history)
  • /embios/trunk/target/ipodnano3g/targetinit.c (added) (history)

Diff [purge]

Index: embios/trunk/target/ipodnano3g/targetinit.c
@@ -0,0 +1,127 @@
 2+//
 3+//
 4+// Copyright 2010 TheSeven
 5+//
 6+//
 7+// This file is part of emBIOS.
 8+//
 9+// emBIOS is free software: you can redistribute it and/or
 10+// modify it under the terms of the GNU General Public License as
 11+// published by the Free Software Foundation, either version 2 of the
 12+// License, or (at your option) any later version.
 13+//
 14+// emBIOS is distributed in the hope that it will be useful,
 15+// but WITHOUT ANY WARRANTY; without even the implied warranty of
 16+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 17+// See the GNU General Public License for more details.
 18+//
 19+// You should have received a copy of the GNU General Public License along
 20+// with emBIOS. If not, see <http://www.gnu.org/licenses/>.
 21+//
 22+//
 23+
 24+
 25+#include "global.h"
 26+#include "clickwheel.h"
 27+
 28+
 29+#define sysi ((uint8_t*)0x2203fdf0)
 30+#define sysiword ((uint32_t*)0x2203fdf0)
 31+
 32+
 33+void targetinit_late()
 34+{
 35+ int i;
 36+
 37+ clickwheel_init();
 38+
 39+/* uint32_t scfg_size = norword[0x401];
 40+ uint32_t scfg_entrycount = norword[0x405];
 41+ if (norword[0x400] == 0x53436667 && scfg_size <= 0x1000
 42+ && scfg_entrycount * 0x14 + 0x18 == scfg_size)
 43+ {
 44+ memset(sysi, 0, 0x104);
 45+ sysiword[0] = 0x53797349;
 46+ sysiword[1] = 0x104;
 47+ sysiword[0x21] = 0x100000;
 48+ for (i = 0; i < scfg_entrycount; i++)
 49+ switch (norword[0x406 + i * 5])
 50+ {
 51+ case 0x48774e6d: // HwNm
 52+ memcpy(&sysi[0x08], &norword[0x406 + i * 5 + 1], 16);
 53+ break;
 54+ case 0x48775672: // HwVr
 55+ if (norword[0x406 + i * 5 + 1] == 0)
 56+ sysiword[0x21] = norword[0x406 + i * 5 + 2];
 57+ break;
 58+ case 0x53724e6d: // SrNm
 59+ memcpy(&sysi[0x18], &norword[0x406 + i * 5 + 1], 16);
 60+ break;
 61+ case 0x46774964: // FwId
 62+ if (nor[0x1018 + i * 0x14 + 7] == 0)
 63+ {
 64+ memcpy(&sysi[0x38], &norword[0x406 + i * 5 + 2], 3);
 65+ sysi[0x3b] = 2;
 66+ sysiword[0xf] = 0xa2700;
 67+ }
 68+ else memcpy(&sysi[0x38], &norword[0x406 + i * 5 + 2], 8);
 69+ memset(&sysi[0x40], 10, 0);
 70+ break;
 71+ case 0x556e7443: // UntC
 72+ memcpy(&sysi[0xbc], &norword[0x406 + i * 5 + 1], 16);
 73+ break;
 74+ case 0x52746341: // RtcA
 75+ if (norword[0x406 + i * 5 + 1] == 1)
 76+ sysiword[0x80] = norword[0x406 + i * 5 + 2];
 77+ break;
 78+ case 0x42747279: // Btry
 79+ if (norword[0x406 + i * 5 + 1] == 1)
 80+ memcpy(&sysi[0x5c], &norword[0x406 + i * 5 + 2], 12);
 81+ break;
 82+ case 0x5265676e: // Regn
 83+ if (nor[0x1018 + i * 0x14 + 4] == 1 && nor[0x1018 + i * 0x14 + 5] == 0)
 84+ memcpy(&sysi[0x92], &norword[0x406 + i * 5 + 2], 4);
 85+ break;
 86+ case 0x4d6f6423: // Mod#
 87+ memcpy(&sysi[0x98], &norword[0x406 + i * 5 + 1], 16);
 88+ break;
 89+ case 0x48774f31: // Hw01
 90+ memcpy(&sysi[0xa8], &norword[0x406 + i * 5 + 1], 16);
 91+ break;
 92+ case 0x436f6e74: // Cont
 93+ if (nor[0x1018 + i * 0x14 + 4] == 0 && nor[0x1018 + i * 0x14 + 5] == 0)
 94+ {
 95+ sysi[0xb8] = nor[0x1018 + i * 0x14 + 6];
 96+ sysi[0xb9] = nor[0x1018 + i * 0x14 + 8];
 97+ }
 98+ break;
 99+ case 0x426b4c74: // BkLt
 100+ if (nor[0x1018 + i * 0x14 + 4] == 0xaa && nor[0x1018 + i * 0x14 + 5] == 0x55)
 101+ {
 102+ sysi[0xba] = nor[0x1018 + i * 0x14 + 6];
 103+ sysi[0xbb] = nor[0x1018 + i * 0x14 + 8];
 104+ }
 105+ break;
 106+ case 0x44726d56: // DrmV
 107+ memcpy(&sysi[0xce], &norword[0x406 + i * 5 + 1], 16);
 108+ break;
 109+ }
 110+ sysiword[2] = 0x646f5069;
 111+ sysiword[3] = 0x36334e20;
 112+ sysi[0x88] = 0x4e;
 113+ sysi[0x89] = 0x41;
 114+#ifdef TARGET_ipodclassic
 115+ sysiword[0x38] = 0x4000000;
 116+#else
 117+ sysiword[0x38] = 0x2000000;
 118+#endif
 119+ sysiword[0x39] = 0x8000000;
 120+ sysiword[0x3a] = 0x40000;
 121+ sysiword[0x3b] = 0x22000000;
 122+ sysiword[0x3c] = 0x100000;
 123+ sysiword[0x3d] = 0x24000000;
 124+ sysiword[0x4a] = 0x53797349;
 125+ sysiword[0x4b] = 0x2203fdf0;
 126+ }
 127+*/
 128+}
Index: embios/trunk/target/ipodnano3g/clickwheel.c
@@ -0,0 +1,175 @@
 2+//
 3+//
 4+// Copyright 2010 TheSeven
 5+//
 6+//
 7+// This file is part of emBIOS.
 8+//
 9+// emBIOS is free software: you can redistribute it and/or
 10+// modify it under the terms of the GNU General Public License as
 11+// published by the Free Software Foundation, either version 2 of the
 12+// License, or (at your option) any later version.
 13+//
 14+// emBIOS is distributed in the hope that it will be useful,
 15+// but WITHOUT ANY WARRANTY; without even the implied warranty of
 16+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 17+// See the GNU General Public License for more details.
 18+//
 19+// You should have received a copy of the GNU General Public License along
 20+// with emBIOS. If not, see <http://www.gnu.org/licenses/>.
 21+//
 22+//
 23+
 24+
 25+#include "global.h"
 26+#include "clickwheel.h"
 27+#include "button.h"
 28+#include "thread.h"
 29+#include "timer.h"
 30+#include "s5l8702.h"
 31+#include "contextswitch.h"
 32+
 33+
 34+static struct wakeup clickwheel_wakeup IBSS_ATTR;
 35+static volatile uint32_t clickwheel_packet IBSS_ATTR;
 36+static uint32_t clickwheel_stack[0x100];
 37+static bool oldtouched IBSS_ATTR;
 38+static int oldpos IBSS_ATTR;
 39+static int oldbuttons IBSS_ATTR;
 40+static uint32_t lastpacket IBSS_ATTR;
 41+static int packets IBSS_ATTR;
 42+static int collect IBSS_ATTR;
 43+static int lastdiff IBSS_ATTR;
 44+
 45+
 46+void clickwheel_thread(void) ICODE_ATTR;
 47+void clickwheel_thread()
 48+{
 49+ int i;
 50+ while (true)
 51+ {
 52+ wakeup_wait(&clickwheel_wakeup, TIMEOUT_BLOCK);
 53+ DEBUGF("Got clickwheel packet");
 54+ uint32_t mode = enter_critical_section();
 55+ uint32_t data = clickwheel_packet;
 56+ leave_critical_section(mode);
 57+ DEBUGF("Acquired clickwheel packet: %08X", data);
 58+ if ((data & 0x800000FF) == 0x8000001A)
 59+ {
 60+ int newbuttons = (data >> 8) & 0x1f;
 61+ int newpos = (data >> 16) & 0xff;
 62+ bool newtouched = (data & 0x40000000) ? true : false;
 63+
 64+ DEBUGF("This is a change packet, button state: %02X, position: %02d, touched: %d",
 65+ newbuttons, newpos, newtouched);
 66+ int buttonschanged = oldbuttons ^ newbuttons;
 67+ DEBUGF("Changed buttons: %02X", buttonschanged);
 68+ for (i = 0; i < 5; i++)
 69+ if ((buttonschanged >> i) & 1)
 70+ {
 71+ if ((oldbuttons >> i) & 1) button_send_event(BUTTON_RELEASE, i, 0);
 72+ else button_send_event(BUTTON_PRESS, i, 0);
 73+ }
 74+
 75+ if (newtouched)
 76+ {
 77+ if (!oldtouched) button_send_event(WHEEL_TOUCH, 0, newpos);
 78+ button_send_event(WHEEL_POSITION, 0, newpos);
 79+ int distance = newpos - oldpos;
 80+ DEBUGF("Time since last packet: %d microseconds", USEC_TIMER - lastpacket);
 81+ if (TIMEOUT_EXPIRED(lastpacket, 200000))
 82+ {
 83+ DEBUGF("Resetting accel due to timeout");
 84+ packets = 10;
 85+ }
 86+ else if (lastdiff * distance < 0)
 87+ {
 88+ DEBUGF("Resetting accel due to direction change");
 89+ packets = 10;
 90+ }
 91+ else packets++;
 92+ lastdiff = distance;
 93+ if (packets > 200) packets = 200;
 94+ if (distance < -48) distance += 96;
 95+ else if (distance > 48) distance -= 96;
 96+ DEBUGF("Wheel moved %d units without accel", distance);
 97+ DEBUGF("Wheel moved %d units with accel", distance * packets);
 98+ button_send_event(WHEEL_MOVED, 0, distance);
 99+ collect += distance * packets;
 100+ enum button_event e = collect > 0 ? WHEEL_FORWARD : WHEEL_BACKWARD;
 101+ int data = (collect > 0 ? collect : -collect) / 128;
 102+ if (data) button_send_event(e, 0, data);
 103+ collect %= 128;
 104+ DEBUGF("Wheel moved %d steps (%d left)", data, collect);
 105+ }
 106+ else if (oldtouched)
 107+ {
 108+ DEBUGF("Wheel was untouched");
 109+ button_send_event(WHEEL_POSITION, 0, newpos);
 110+ button_send_event(WHEEL_UNTOUCH, 0, newpos);
 111+ collect = 0;
 112+ packets = 0;
 113+ lastdiff = 0;
 114+ }
 115+
 116+ oldbuttons = newbuttons;
 117+ oldpos = newpos;
 118+ oldtouched = newtouched;
 119+ lastpacket = USEC_TIMER;
 120+ }
 121+ else if ((data & 0x8000FFFF) == 0x8000023A)
 122+ {
 123+ if (data & 0x1F0000) oldbuttons = (data >> 16) & 0x1F;
 124+ DEBUGF("This is an init packet, button state: %02X", oldbuttons);
 125+ }
 126+ }
 127+}
 128+
 129+
 130+void clickwheel_init()
 131+{
 132+ wakeup_init(&clickwheel_wakeup);
 133+ oldtouched = false;
 134+ oldbuttons = 0;
 135+ lastpacket = 0;
 136+ collect = 0;
 137+ lastdiff = 0;
 138+ PWRCON(0) = 0;
 139+ PWRCON(1) = 0;
 140+ interrupt_enable(IRQ_WHEEL, true);
 141+ PUNA(2) &= ~2;
 142+ PCON(14) = (PCON(14) & ~0xffff0000) | 0x22220000;
 143+ WHEELINT = 7;
 144+ WHEEL10 = 7;
 145+ WHEEL00 = 0x380000;
 146+ WHEEL08 = 0x20000;
 147+ do
 148+ {
 149+ WHEELTX = 0x8001052A;
 150+ while (WHEEL0C & 4) yield();
 151+ WHEEL04 = 1;
 152+ sleep(20000);
 153+ }
 154+ while (WHEEL0C & 4);
 155+ thread_create("Clickwheel dispatcher", clickwheel_thread, clickwheel_stack,
 156+ sizeof(clickwheel_stack), OS_THREAD, 200, true);
 157+}
 158+
 159+void INT_WHEEL(void) ICODE_ATTR;
 160+void INT_WHEEL()
 161+{
 162+ uint32_t events = WHEELINT;
 163+ if (events & 4) WHEELINT = 4;
 164+ if (events & 2) WHEELINT = 2;
 165+ if (events & 1)
 166+ {
 167+ clickwheel_packet = WHEELRX;
 168+ wakeup_signal(&clickwheel_wakeup);
 169+ WHEELINT = 1;
 170+ }
 171+}
 172+
 173+uint32_t clickwheel_get_state()
 174+{
 175+ return (oldtouched << 15) | (oldpos << 8) | oldbuttons;
 176+}