core: LUFA_DEBUG_SUART for serial debug
authortmk <hasu@tmk-kbd.com>
Wed, 28 Sep 2016 07:39:41 +0000 (16:39 +0900)
committertmk <hasu@tmk-kbd.com>
Mon, 3 Oct 2016 04:10:53 +0000 (13:10 +0900)
tmk_core/common/avr/suart.S [new file with mode: 0644]
tmk_core/common/avr/suart.h [new file with mode: 0644]
tmk_core/protocol/lufa.mk
tmk_core/protocol/lufa/lufa.c

diff --git a/tmk_core/common/avr/suart.S b/tmk_core/common/avr/suart.S
new file mode 100644 (file)
index 0000000..9fa5452
--- /dev/null
@@ -0,0 +1,156 @@
+;---------------------------------------------------------------------------;\r
+; Software implemented UART module                                          ;\r
+; (C)ChaN, 2005 (http://elm-chan.org/)                                      ;\r
+;---------------------------------------------------------------------------;\r
+; Bit rate settings:\r
+;\r
+;            1MHz  2MHz  4MHz  6MHz  8MHz  10MHz  12MHz  16MHz  20MHz\r
+;   2.4kbps   138     -     -     -     -      -      -      -      -\r
+;   4.8kbps    68   138     -     -     -      -      -      -      -\r
+;   9.6kbps    33    68   138   208     -      -      -      -      -\r
+;  19.2kbps     -    33    68   102   138    173    208      -      -\r
+;  38.4kbps     -     -    33    50    68     85    102    138    172\r
+;  57.6kbps     -     -    21    33    44     56     68     91    114\r
+; 115.2kbps     -     -     -     -    21     27     33     44     56\r
+\r
+.nolist\r
+#include <avr/io.h>\r
+.list\r
+\r
+#define        BPS     44      /* Bit delay. (see above table) */\r
+#define        BIDIR   0       /* 0:Separated Tx/Rx, 1:Shared Tx/Rx */\r
+\r
+#define        OUT_1           sbi _SFR_IO_ADDR(SUART_OUT_PORT), SUART_OUT_BIT /* Output 1 */\r
+#define        OUT_0           cbi _SFR_IO_ADDR(SUART_OUT_PORT), SUART_OUT_BIT /* Output 0 */\r
+#define        SKIP_IN_1       sbis _SFR_IO_ADDR(SUART_IN_PIN), SUART_IN_BIT   /* Skip if 1 */\r
+#define        SKIP_IN_0       sbic _SFR_IO_ADDR(SUART_IN_PIN), SUART_IN_BIT   /* Skip if 0 */\r
+\r
+\r
+\r
+#ifdef SPM_PAGESIZE\r
+.macro _LPMI   reg\r
+       lpm     \reg, Z+\r
+.endm\r
+.macro _MOVW   dh,dl, sh,sl\r
+       movw    \dl, \sl\r
+.endm\r
+#else\r
+.macro _LPMI   reg\r
+       lpm\r
+       mov     \reg, r0\r
+       adiw    ZL, 1\r
+.endm\r
+.macro _MOVW   dh,dl, sh,sl\r
+       mov     \dl, \sl\r
+       mov     \dh, \sh\r
+.endm\r
+#endif\r
+\r
+\r
+\r
+;---------------------------------------------------------------------------;\r
+; Transmit a byte in serial format of N81\r
+;\r
+;Prototype: void xmit (uint8_t data);\r
+;Size: 16 words\r
+\r
+.global xmit\r
+.func xmit\r
+xmit:\r
+#if BIDIR\r
+       ldi     r23, BPS-1      ;Pre-idle time for bidirectional data line\r
+5:     dec     r23             ;\r
+       brne    5b              ;/\r
+#endif\r
+       in      r0, _SFR_IO_ADDR(SREG)  ;Save flags\r
+\r
+       com     r24             ;C = start bit\r
+       ldi     r25, 10         ;Bit counter\r
+       cli                     ;Start critical section\r
+\r
+1:     ldi     r23, BPS-1      ;----- Bit transferring loop \r
+2:     dec     r23             ;Wait for a bit time\r
+       brne    2b              ;/\r
+       brcs    3f              ;MISO = bit to be sent\r
+       OUT_1                   ;\r
+3:     brcc    4f              ;\r
+       OUT_0                   ;/\r
+4:     lsr     r24             ;Get next bit into C\r
+       dec     r25             ;All bits sent?\r
+       brne    1b              ;  no, coutinue\r
+\r
+       out     _SFR_IO_ADDR(SREG), r0  ;End of critical section\r
+       ret\r
+.endfunc\r
+\r
+\r
+\r
+;---------------------------------------------------------------------------;\r
+; Receive a byte\r
+;\r
+;Prototype: uint8_t rcvr (void);\r
+;Size: 19 words\r
+\r
+.global rcvr\r
+.func rcvr\r
+rcvr:\r
+       in      r0, _SFR_IO_ADDR(SREG)  ;Save flags\r
+\r
+       ldi     r24, 0x80       ;Receiving shift reg\r
+       cli                     ;Start critical section\r
+\r
+1:     SKIP_IN_1               ;Wait for idle\r
+       rjmp    1b\r
+2:     SKIP_IN_0               ;Wait for start bit\r
+       rjmp    2b\r
+       ldi     r25, BPS/2      ;Wait for half bit time\r
+3:     dec     r25\r
+       brne    3b\r
+\r
+4:     ldi     r25, BPS        ;----- Bit receiving loop\r
+5:     dec     r25             ;Wait for a bit time\r
+       brne    5b              ;/\r
+       lsr     r24             ;Next bit\r
+       SKIP_IN_0               ;Get a data bit into r24.7\r
+       ori     r24, 0x80\r
+       brcc    4b              ;All bits received?  no, continue\r
+\r
+       out     _SFR_IO_ADDR(SREG), r0  ;End of critical section\r
+       ret\r
+.endfunc\r
+\r
+\r
+; Not wait for start bit. This should be called after detecting start bit.\r
+.global recv\r
+.func recv\r
+recv:\r
+       in      r0, _SFR_IO_ADDR(SREG)  ;Save flags\r
+\r
+       ldi     r24, 0x80       ;Receiving shift reg\r
+       cli                     ;Start critical section\r
+\r
+;1:    SKIP_IN_1               ;Wait for idle\r
+;      rjmp    1b\r
+;2:    SKIP_IN_0               ;Wait for start bit\r
+;      rjmp    2b\r
+       ldi     r25, BPS/2      ;Wait for half bit time\r
+3:     dec     r25\r
+       brne    3b\r
+\r
+4:     ldi     r25, BPS        ;----- Bit receiving loop\r
+5:     dec     r25             ;Wait for a bit time\r
+       brne    5b              ;/\r
+       lsr     r24             ;Next bit\r
+       SKIP_IN_0               ;Get a data bit into r24.7\r
+       ori     r24, 0x80\r
+       brcc    4b              ;All bits received?  no, continue\r
+\r
+       ldi     r25, BPS/2      ;Wait for half bit time\r
+6:     dec     r25\r
+       brne    6b\r
+7:     SKIP_IN_1               ;Wait for stop bit\r
+       rjmp    7b\r
+\r
+       out     _SFR_IO_ADDR(SREG), r0  ;End of critical section\r
+       ret\r
+.endfunc\r
diff --git a/tmk_core/common/avr/suart.h b/tmk_core/common/avr/suart.h
new file mode 100644 (file)
index 0000000..72725b9
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef SUART\r
+#define SUART\r
+\r
+void xmit(uint8_t);\r
+uint8_t rcvr(void);\r
+uint8_t recv(void);\r
+\r
+#endif /* SUART */\r
index d239585ba9af251b2223ba5d5c1241f661733934..1b529bde61e15dc6575150545b1de1f8cefdc0e3 100644 (file)
@@ -48,3 +48,8 @@ OPT_DEFS += $(LUFA_OPTS)
 
 # This indicates using LUFA stack
 OPT_DEFS += -DPROTOCOL_LUFA
+
+ifeq (yes,$(strip $(LUFA_DEBUG_SUART)))
+    SRC += common/avr/suart.S
+    LUFA_OPTS += -DLUFA_DEBUG_SUART
+endif
index beec6b2be31d3f30d926f0fbcc652f4bce839473..c16fd1775b83cc1c85066da8a53c1a97fc69b8c0 100644 (file)
 #include "suspend.h"
 #include "hook.h"
 
+#ifdef LUFA_DEBUG_SUART
+#include "avr/suart.h"
+#endif
+
 #include "descriptor.h"
 #include "lufa.h"
 
@@ -217,6 +221,7 @@ void EVENT_USB_Device_StartOfFrame(void)
  */
 void EVENT_USB_Device_ConfigurationChanged(void)
 {
+    print("[c]");
     bool ConfigSuccess = true;
 
     /* Setup Keyboard HID Report Endpoints */
@@ -270,6 +275,7 @@ Other Device    Required    Optional    Optional    Optional    Optional    Opti
  */
 void EVENT_USB_Device_ControlRequest(void)
 {
+    print("[r]");
     uint8_t* ReportData = NULL;
     uint8_t  ReportSize = 0;
 
@@ -494,6 +500,9 @@ static void send_consumer(uint16_t data)
 #define SEND_TIMEOUT 5
 int8_t sendchar(uint8_t c)
 {
+#ifdef LUFA_DEBUG_SUART
+    xmit(c);
+#endif
     // Not wait once timeouted.
     // Because sendchar() is called so many times, waiting each call causes big lag.
     static bool timeouted = false;
@@ -551,6 +560,9 @@ ERROR_EXIT:
 #else
 int8_t sendchar(uint8_t c)
 {
+#ifdef LUFA_DEBUG_SUART
+    xmit(c);
+#endif
     return 0;
 }
 #endif
@@ -578,12 +590,15 @@ static void setup_usb(void)
 
     // for Console_Task
     USB_Device_EnableSOFEvents();
-    print_set_sendchar(sendchar);
 }
 
 int main(void)  __attribute__ ((weak));
 int main(void)
 {
+#ifdef LUFA_DEBUG_SUART
+    DDRD |= (1<<SUART_OUT_BIT);
+#endif
+    print_set_sendchar(sendchar);
     setup_mcu();
     hook_early_init();
     keyboard_setup();
Imprint / Impressum