aboutsummaryrefslogtreecommitdiff
path: root/tmk_core/protocol
diff options
context:
space:
mode:
authorpatrickmt <40182064+patrickmt@users.noreply.github.com>2018-11-02 15:30:51 -0400
committerDrashna Jaelre <drashna@live.com>2018-11-02 14:33:07 -0700
commitcec203ea80c8e9365bb5f43418fba5971dd4091f (patch)
tree6ea7d621f7f14bf6ea2b5019867cac8c71a0e8e8 /tmk_core/protocol
parent563fe23e53fb747f509b8558bb29bde0baf2d6a8 (diff)
downloadqmk_firmware-cec203ea80c8e9365bb5f43418fba5971dd4091f.tar.gz
qmk_firmware-cec203ea80c8e9365bb5f43418fba5971dd4091f.zip
USB Suspend for arm_atsam protocol
Rewrote USB state tracking for implementation of suspend state. Updated suspend.c in entirety. Main subtasks (generally hardware related) are now run prior to keyboard task.
Diffstat (limited to 'tmk_core/protocol')
-rw-r--r--tmk_core/protocol/arm_atsam/i2c_master.c5
-rw-r--r--tmk_core/protocol/arm_atsam/main_arm_atsam.c80
-rw-r--r--tmk_core/protocol/arm_atsam/usb/ui.c8
-rw-r--r--tmk_core/protocol/arm_atsam/usb/ui.h6
4 files changed, 57 insertions, 42 deletions
diff --git a/tmk_core/protocol/arm_atsam/i2c_master.c b/tmk_core/protocol/arm_atsam/i2c_master.c
index 4f5a79e89..ece9ee5db 100644
--- a/tmk_core/protocol/arm_atsam/i2c_master.c
+++ b/tmk_core/protocol/arm_atsam/i2c_master.c
@@ -261,8 +261,9 @@ uint8_t I2C3733_Init_Control(void)
261{ 261{
262 DBGC(DC_I2C3733_INIT_CONTROL_BEGIN); 262 DBGC(DC_I2C3733_INIT_CONTROL_BEGIN);
263 263
264 srdata.bit.SDB_N = 1; 264 //Hardware state shutdown on boot
265 SPI_WriteSRData(); 265 //USB state machine will enable driver when communication is ready
266 I2C3733_Control_Set(0);
266 267
267 CLK_delay_ms(1); 268 CLK_delay_ms(1);
268 269
diff --git a/tmk_core/protocol/arm_atsam/main_arm_atsam.c b/tmk_core/protocol/arm_atsam/main_arm_atsam.c
index d3dc272ee..13034a05d 100644
--- a/tmk_core/protocol/arm_atsam/main_arm_atsam.c
+++ b/tmk_core/protocol/arm_atsam/main_arm_atsam.c
@@ -31,6 +31,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
31//From keyboard's directory 31//From keyboard's directory
32#include "config_led.h" 32#include "config_led.h"
33 33
34uint8_t g_usb_state = USB_FSMSTATUS_FSMSTATE_OFF_Val; //Saved USB state from hardware value to detect changes
35
34void main_subtasks(void); 36void main_subtasks(void);
35uint8_t keyboard_leds(void); 37uint8_t keyboard_leds(void);
36void send_keyboard(report_keyboard_t *report); 38void send_keyboard(report_keyboard_t *report);
@@ -62,12 +64,6 @@ void send_keyboard(report_keyboard_t *report)
62{ 64{
63 uint32_t irqflags; 65 uint32_t irqflags;
64 66
65 if (usb_state == USB_STATE_POWERDOWN)
66 {
67 udc_remotewakeup();
68 return;
69 }
70
71#ifdef NKRO_ENABLE 67#ifdef NKRO_ENABLE
72 if (!keymap_config.nkro) 68 if (!keymap_config.nkro)
73 { 69 {
@@ -161,41 +157,56 @@ void send_consumer(uint16_t data)
161#endif //EXTRAKEY_ENABLE 157#endif //EXTRAKEY_ENABLE
162} 158}
163 159
164uint8_t g_drvid;
165uint8_t g_usb_sleeping = 0;
166
167void main_subtask_usb_state(void) 160void main_subtask_usb_state(void)
168{ 161{
169 if (usb_state == USB_STATE_POWERDOWN) 162 static uint32_t fsmstate_on_delay = 0; //Delay timer to be sure USB is actually operating before bringing up hardware
163 uint8_t fsmstate_now = USB->DEVICE.FSMSTATUS.reg; //Current state from hardware register
164
165 if (fsmstate_now == USB_FSMSTATUS_FSMSTATE_SUSPEND_Val) //If USB SUSPENDED
170 { 166 {
171 if (!g_usb_sleeping) 167 fsmstate_on_delay = 0; //Clear ON delay timer
168
169 if (g_usb_state != USB_FSMSTATUS_FSMSTATE_SUSPEND_Val) //If previously not SUSPENDED
172 { 170 {
173 g_usb_sleeping = 1; 171 suspend_power_down(); //Run suspend routine
174 if (led_enabled) 172 g_usb_state = fsmstate_now; //Save current USB state
175 {
176 for (g_drvid = 0; g_drvid < ISSI3733_DRIVER_COUNT; g_drvid++)
177 {
178 I2C3733_Control_Set(0);
179 }
180 }
181 } 173 }
182 } 174 }
183 else if (g_usb_sleeping) 175 else if (fsmstate_now == USB_FSMSTATUS_FSMSTATE_SLEEP_Val) //Else if USB SLEEPING
184 { 176 {
185 g_usb_sleeping = 0; 177 fsmstate_on_delay = 0; //Clear ON delay timer
186 if (led_enabled) 178
179 if (g_usb_state != USB_FSMSTATUS_FSMSTATE_SLEEP_Val) //If previously not SLEEPING
187 { 180 {
188 for (g_drvid = 0; g_drvid < ISSI3733_DRIVER_COUNT; g_drvid++) 181 suspend_power_down(); //Run suspend routine
182 g_usb_state = fsmstate_now; //Save current USB state
183 }
184 }
185 else if (fsmstate_now == USB_FSMSTATUS_FSMSTATE_ON_Val) //Else if USB ON
186 {
187 if (g_usb_state != USB_FSMSTATUS_FSMSTATE_ON_Val) //If previously not ON
188 {
189 if (fsmstate_on_delay == 0) //If ON delay timer is cleared
189 { 190 {
190 I2C3733_Control_Set(1); 191 fsmstate_on_delay = CLK_get_ms() + 250; //Set ON delay timer
192 }
193 else if (CLK_get_ms() > fsmstate_on_delay) //Else if ON delay timer is active and timed out
194 {
195 suspend_wakeup_init(); //Run wakeup routine
196 g_usb_state = fsmstate_now; //Save current USB state
191 } 197 }
192 } 198 }
193 } 199 }
200 else //Else if USB is in a state not being tracked
201 {
202 fsmstate_on_delay = 0; //Clear ON delay timer
203 }
194} 204}
195 205
196void main_subtask_led(void) 206void main_subtask_led(void)
197{ 207{
198 if (g_usb_sleeping) return; 208 if (g_usb_state != USB_FSMSTATUS_FSMSTATE_ON_Val) return; //Only run LED tasks if USB is operating
209
199 led_matrix_task(); 210 led_matrix_task();
200} 211}
201 212
@@ -275,8 +286,8 @@ int main(void)
275 286
276 i2c_led_q_init(); 287 i2c_led_q_init();
277 288
278 for (g_drvid = 0; g_drvid < ISSI3733_DRIVER_COUNT; g_drvid++) 289 for (uint8_t drvid = 0; drvid < ISSI3733_DRIVER_COUNT; drvid++)
279 I2C_LED_Q_ONOFF(g_drvid); //Queue data 290 I2C_LED_Q_ONOFF(drvid); //Queue data
280 291
281 keyboard_setup(); 292 keyboard_setup();
282 293
@@ -294,10 +305,21 @@ int main(void)
294 305
295 while (1) 306 while (1)
296 { 307 {
297 keyboard_task();
298
299 main_subtasks(); //Note these tasks will also be run while waiting for USB keyboard polling intervals 308 main_subtasks(); //Note these tasks will also be run while waiting for USB keyboard polling intervals
300 309
310 if (g_usb_state == USB_FSMSTATUS_FSMSTATE_SUSPEND_Val || g_usb_state == USB_FSMSTATUS_FSMSTATE_SLEEP_Val)
311 {
312 if (suspend_wakeup_condition())
313 {
314 udc_remotewakeup(); //Send remote wakeup signal
315 wait_ms(50);
316 }
317
318 continue;
319 }
320
321 keyboard_task();
322
301#ifdef CONSOLE_ENABLE 323#ifdef CONSOLE_ENABLE
302 if (CLK_get_ms() > next_print) 324 if (CLK_get_ms() > next_print)
303 { 325 {
diff --git a/tmk_core/protocol/arm_atsam/usb/ui.c b/tmk_core/protocol/arm_atsam/usb/ui.c
index 031678b64..70a619109 100644
--- a/tmk_core/protocol/arm_atsam/usb/ui.c
+++ b/tmk_core/protocol/arm_atsam/usb/ui.c
@@ -52,8 +52,6 @@
52#include "samd51j18a.h" 52#include "samd51j18a.h"
53#include "ui.h" 53#include "ui.h"
54 54
55volatile uint8_t usb_state;
56
57//! Sequence process running each \c SEQUENCE_PERIOD ms 55//! Sequence process running each \c SEQUENCE_PERIOD ms
58#define SEQUENCE_PERIOD 150 56#define SEQUENCE_PERIOD 150
59 57
@@ -72,12 +70,12 @@ static void ui_wakeup_handler(void)
72 70
73void ui_init(void) 71void ui_init(void)
74{ 72{
75 usb_state = USB_STATE_POWERUP; 73
76} 74}
77 75
78void ui_powerdown(void) 76void ui_powerdown(void)
79{ 77{
80 usb_state = USB_STATE_POWERDOWN; 78
81} 79}
82 80
83void ui_wakeup_enable(void) 81void ui_wakeup_enable(void)
@@ -92,7 +90,7 @@ void ui_wakeup_disable(void)
92 90
93void ui_wakeup(void) 91void ui_wakeup(void)
94{ 92{
95 usb_state = USB_STATE_POWERUP; 93
96} 94}
97 95
98void ui_process(uint16_t framenumber) 96void ui_process(uint16_t framenumber)
diff --git a/tmk_core/protocol/arm_atsam/usb/ui.h b/tmk_core/protocol/arm_atsam/usb/ui.h
index 3d899e669..d1c767d45 100644
--- a/tmk_core/protocol/arm_atsam/usb/ui.h
+++ b/tmk_core/protocol/arm_atsam/usb/ui.h
@@ -47,12 +47,6 @@
47#ifndef _UI_H_ 47#ifndef _UI_H_
48#define _UI_H_ 48#define _UI_H_
49 49
50extern volatile uint8_t usb_state;
51
52#define USB_STATE_UNKNOWN 0
53#define USB_STATE_POWERDOWN 1
54#define USB_STATE_POWERUP 2
55
56//! \brief Initializes the user interface 50//! \brief Initializes the user interface
57void ui_init(void); 51void ui_init(void);
58 52