Marcin Bukat | 28d54c6 | 2010-04-26 21:40:16 +0000 | [diff] [blame] | 1 | /*************************************************************************** |
| 2 | * __________ __ ___. |
| 3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ |
| 4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / |
| 5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < |
| 6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ |
| 7 | * \/ \/ \/ \/ \/ |
Marcin Bukat | 082c7d3 | 2010-10-22 12:28:43 +0000 | [diff] [blame^] | 8 | * $Id$ |
Marcin Bukat | 28d54c6 | 2010-04-26 21:40:16 +0000 | [diff] [blame] | 9 | * |
| 10 | * Copyright (C) 2010 Marcin Bukat |
| 11 | * |
| 12 | * This program is free software; you can redistribute it and/or |
| 13 | * modify it under the terms of the GNU General Public License |
| 14 | * as published by the Free Software Foundation; either version 2 |
| 15 | * of the License, or (at your option) any later version. |
| 16 | * |
| 17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY |
| 18 | * KIND, either express or implied. |
| 19 | * |
| 20 | ****************************************************************************/ |
| 21 | |
| 22 | #include "config.h" |
| 23 | #include "cpu.h" |
| 24 | #include "system.h" |
| 25 | #include "button.h" |
| 26 | #include "backlight.h" |
| 27 | #include "adc.h" |
| 28 | |
Marcin Bukat | 7c908bb | 2010-07-06 14:43:58 +0000 | [diff] [blame] | 29 | static bool remote_detect(void) |
| 30 | { |
| 31 | /* When there is no remote adc readout |
| 32 | * is exactly 0. We add some margin |
| 33 | * for ADC readout instability |
| 34 | */ |
| 35 | return adc_scan(ADC_REMOTE)>10?true:false; |
| 36 | } |
| 37 | |
Marcin Bukat | 28d54c6 | 2010-04-26 21:40:16 +0000 | [diff] [blame] | 38 | void button_init_device(void) |
| 39 | { |
Marcin Bukat | 3cdee0f | 2010-07-06 14:44:41 +0000 | [diff] [blame] | 40 | /* GPIO56 (main PLAY) general input |
| 41 | * GPIO41 (remote PLAY) is shared with Audio Serial Data |
Marcin Bukat | 8d3591a | 2010-07-03 20:20:42 +0000 | [diff] [blame] | 42 | */ |
Marcin Bukat | 3cdee0f | 2010-07-06 14:44:41 +0000 | [diff] [blame] | 43 | or_l((1<<24),&GPIO1_FUNCTION); |
| 44 | and_l(~(1<<24),&GPIO1_ENABLE); |
Marcin Bukat | 28d54c6 | 2010-04-26 21:40:16 +0000 | [diff] [blame] | 45 | } |
| 46 | |
| 47 | bool button_hold(void) |
| 48 | { |
| 49 | /* GPIO36 active high */ |
| 50 | return (GPIO1_READ & (1<<4))?true:false; |
| 51 | } |
| 52 | |
Marcin Bukat | 8d3591a | 2010-07-03 20:20:42 +0000 | [diff] [blame] | 53 | bool remote_button_hold(void) |
| 54 | { |
Marcin Bukat | 7c908bb | 2010-07-06 14:43:58 +0000 | [diff] [blame] | 55 | /* On my remote hold gives readout of 44 */ |
| 56 | if (remote_detect()) |
| 57 | return adc_scan(ADC_REMOTE)<50?true:false; |
| 58 | else |
| 59 | return false; |
Marcin Bukat | 8d3591a | 2010-07-03 20:20:42 +0000 | [diff] [blame] | 60 | } |
Marcin Bukat | 28d54c6 | 2010-04-26 21:40:16 +0000 | [diff] [blame] | 61 | |
| 62 | /* |
| 63 | * Get button pressed from hardware |
| 64 | */ |
| 65 | int button_read_device(void) |
| 66 | { |
| 67 | int btn = BUTTON_NONE; |
| 68 | int data = 0; |
| 69 | static bool hold_button = false; |
Marcin Bukat | 7c908bb | 2010-07-06 14:43:58 +0000 | [diff] [blame] | 70 | bool remote_hold_button = false; |
Marcin Bukat | 28d54c6 | 2010-04-26 21:40:16 +0000 | [diff] [blame] | 71 | |
Marcin Bukat | 28d54c6 | 2010-04-26 21:40:16 +0000 | [diff] [blame] | 72 | bool hold_button_old; |
Marcin Bukat | 7c908bb | 2010-07-06 14:43:58 +0000 | [diff] [blame] | 73 | bool remote_present; |
| 74 | |
| 75 | /* check if we have remote connected */ |
| 76 | remote_present = remote_detect(); |
Marcin Bukat | 28d54c6 | 2010-04-26 21:40:16 +0000 | [diff] [blame] | 77 | |
Marcin Bukat | 8d3591a | 2010-07-03 20:20:42 +0000 | [diff] [blame] | 78 | /* read hold buttons status */ |
Marcin Bukat | 28d54c6 | 2010-04-26 21:40:16 +0000 | [diff] [blame] | 79 | hold_button_old = hold_button; |
| 80 | hold_button = button_hold(); |
Marcin Bukat | 8d3591a | 2010-07-03 20:20:42 +0000 | [diff] [blame] | 81 | remote_hold_button = remote_button_hold(); |
Marcin Bukat | 28d54c6 | 2010-04-26 21:40:16 +0000 | [diff] [blame] | 82 | |
| 83 | #ifndef BOOTLOADER |
Marcin Bukat | 8d3591a | 2010-07-03 20:20:42 +0000 | [diff] [blame] | 84 | /* Only main hold affects backlight */ |
Marcin Bukat | 28d54c6 | 2010-04-26 21:40:16 +0000 | [diff] [blame] | 85 | if (hold_button != hold_button_old) |
| 86 | backlight_hold_changed(hold_button); |
| 87 | #endif |
| 88 | |
Marcin Bukat | 7c908bb | 2010-07-06 14:43:58 +0000 | [diff] [blame] | 89 | /* Skip if main hold is active */ |
Marcin Bukat | 28d54c6 | 2010-04-26 21:40:16 +0000 | [diff] [blame] | 90 | if (!hold_button) |
| 91 | { |
Marcin Bukat | 2a50270 | 2010-04-30 12:42:51 +0000 | [diff] [blame] | 92 | data = adc_scan(ADC_BUTTONS); |
Marcin Bukat | 28d54c6 | 2010-04-26 21:40:16 +0000 | [diff] [blame] | 93 | |
Marcin Bukat | 3cdee0f | 2010-07-06 14:44:41 +0000 | [diff] [blame] | 94 | if (data < 2300) /* valid button */ |
Marcin Bukat | 28d54c6 | 2010-04-26 21:40:16 +0000 | [diff] [blame] | 95 | { |
| 96 | if (data < 900) /* middle */ |
| 97 | { |
| 98 | if (data < 500) |
| 99 | { |
| 100 | if (data > 200) |
| 101 | /* 200 - 500 */ |
| 102 | btn = BUTTON_REC; |
| 103 | } |
| 104 | else /* 900 - 500 */ |
| 105 | btn = BUTTON_VOL_DOWN; |
| 106 | } |
| 107 | else /* 2250 - 900 */ |
| 108 | { |
| 109 | if (data < 1600) |
| 110 | { |
| 111 | /* 1600 - 900 */ |
| 112 | if (data < 1200) |
| 113 | /* 1200 - 900 */ |
| 114 | btn = BUTTON_VOL_UP; |
| 115 | else /* 1600 - 1200 */ |
| 116 | btn = BUTTON_NEXT; |
| 117 | } |
| 118 | else /* 1600 - 2250 */ |
| 119 | { |
| 120 | if (data < 1900) |
| 121 | /* 1900 - 1600 */ |
| 122 | btn = BUTTON_PREV; |
Marcin Bukat | 3cdee0f | 2010-07-06 14:44:41 +0000 | [diff] [blame] | 123 | else /* 1900 - 2300 */ |
Marcin Bukat | 28d54c6 | 2010-04-26 21:40:16 +0000 | [diff] [blame] | 124 | btn = BUTTON_SELECT; |
| 125 | } |
| 126 | } |
| 127 | } |
| 128 | } |
| 129 | |
Marcin Bukat | 7c908bb | 2010-07-06 14:43:58 +0000 | [diff] [blame] | 130 | /* Skip if remote is not present or remote_hold is active */ |
| 131 | if (remote_present && !remote_hold_button) |
Marcin Bukat | 8d3591a | 2010-07-03 20:20:42 +0000 | [diff] [blame] | 132 | { |
| 133 | data = adc_scan(ADC_REMOTE); |
| 134 | |
| 135 | if (data < 2050) /* valid button */ |
| 136 | { |
| 137 | if (data < 950) /* middle */ |
| 138 | { |
| 139 | if (data < 650) |
| 140 | { |
| 141 | if (data < 400) |
| 142 | { |
| 143 | if (data > 250) |
| 144 | /* 250 - 400 */ |
| 145 | btn = BUTTON_RC_VOL_DOWN; |
| 146 | } |
| 147 | else /* 650 - 400 */ |
| 148 | btn = BUTTON_RC_VOL_UP; |
| 149 | } |
| 150 | else /* 950 - 650 */ |
| 151 | btn = BUTTON_RC_NEXT; |
| 152 | } |
| 153 | else /* 2050 - 950 */ |
| 154 | { |
| 155 | if (data < 1900) |
| 156 | { |
| 157 | if (data < 1350) |
| 158 | /* 1350 - 900 */ |
| 159 | btn = BUTTON_RC_PREV; |
| 160 | } |
| 161 | else /* 2050 - 1900 */ |
| 162 | btn = BUTTON_RC_SELECT; |
| 163 | } |
| 164 | } |
| 165 | } |
Marcin Bukat | 28d54c6 | 2010-04-26 21:40:16 +0000 | [diff] [blame] | 166 | |
Marcin Bukat | 7c908bb | 2010-07-06 14:43:58 +0000 | [diff] [blame] | 167 | /* PLAY buttons (both remote and main) are |
| 168 | * GPIOs not ADC |
| 169 | */ |
Marcin Bukat | 28d54c6 | 2010-04-26 21:40:16 +0000 | [diff] [blame] | 170 | data = GPIO1_READ; |
| 171 | |
| 172 | /* GPIO56 active high main PLAY/PAUSE/ON */ |
| 173 | if (!hold_button && ((data & (1<<24)))) |
| 174 | btn |= BUTTON_PLAY; |
Marcin Bukat | 8d3591a | 2010-07-03 20:20:42 +0000 | [diff] [blame] | 175 | |
| 176 | /* GPIO41 active high remote PLAY/PAUSE/ON */ |
Marcin Bukat | 7c908bb | 2010-07-06 14:43:58 +0000 | [diff] [blame] | 177 | if (remote_present && !remote_hold_button && ((data & (1<<9)))) |
Marcin Bukat | 8d3591a | 2010-07-03 20:20:42 +0000 | [diff] [blame] | 178 | btn |= BUTTON_RC_PLAY; |
Marcin Bukat | 28d54c6 | 2010-04-26 21:40:16 +0000 | [diff] [blame] | 179 | |
| 180 | return btn; |
| 181 | } |