Keyboard firmwares for Atmel AVR and Cortex-M
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

rn42.c 4.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. #include <avr/io.h>
  2. #include "host.h"
  3. #include "host_driver.h"
  4. #include "serial.h"
  5. #include "rn42.h"
  6. #include "print.h"
  7. #include "wait.h"
  8. /* Host driver */
  9. static uint8_t keyboard_leds(void);
  10. static void send_keyboard(report_keyboard_t *report);
  11. static void send_mouse(report_mouse_t *report);
  12. static void send_system(uint16_t data);
  13. static void send_consumer(uint16_t data);
  14. host_driver_t rn42_driver = {
  15. keyboard_leds,
  16. send_keyboard,
  17. send_mouse,
  18. send_system,
  19. send_consumer
  20. };
  21. void rn42_init(void)
  22. {
  23. // PF7: BT connection control(HiZ: connect, low: disconnect)
  24. // JTAG disable for PORT F. write JTD bit twice within four cycles.
  25. MCUCR |= (1<<JTD);
  26. MCUCR |= (1<<JTD);
  27. rn42_autoconnect();
  28. // PF1: RTS(low: allowed to send, high: not allowed)
  29. DDRF &= ~(1<<1);
  30. PORTF &= ~(1<<1);
  31. // PD5: CTS(low: allow to send, high:not allow)
  32. DDRD |= (1<<5);
  33. PORTD &= ~(1<<5);
  34. serial_init();
  35. }
  36. void rn42_putc(uint8_t c)
  37. {
  38. serial_send(c);
  39. }
  40. bool rn42_autoconnecting(void)
  41. {
  42. // GPIO6 for control connection(high: auto connect, low: disconnect)
  43. // Note that this needs config: SM,4(Auto-Connect DTR Mode)
  44. return (PORTF & (1<<7) ? true : false);
  45. }
  46. void rn42_autoconnect(void)
  47. {
  48. // hi to auto connect
  49. DDRF |= (1<<7);
  50. PORTF |= (1<<7);
  51. }
  52. void rn42_disconnect(void)
  53. {
  54. // low to disconnect
  55. DDRF |= (1<<7);
  56. PORTF &= ~(1<<7);
  57. }
  58. bool rn42_rts(void)
  59. {
  60. // low when RN-42 is powered and ready to receive
  61. return PINF&(1<<1);
  62. }
  63. void rn42_cts_hi(void)
  64. {
  65. // not allow to send
  66. PORTD |= (1<<5);
  67. }
  68. void rn42_cts_lo(void)
  69. {
  70. // allow to send
  71. PORTD &= ~(1<<5);
  72. }
  73. static uint8_t keyboard_leds(void) { return 0; }
  74. static void send_keyboard(report_keyboard_t *report)
  75. {
  76. // wake from deep sleep
  77. /*
  78. PORTD |= (1<<5); // high
  79. wait_ms(5);
  80. PORTD &= ~(1<<5); // low
  81. */
  82. serial_send(0xFD); // Raw report mode
  83. serial_send(9); // length
  84. serial_send(1); // descriptor type
  85. serial_send(report->mods);
  86. serial_send(0x00);
  87. serial_send(report->keys[0]);
  88. serial_send(report->keys[1]);
  89. serial_send(report->keys[2]);
  90. serial_send(report->keys[3]);
  91. serial_send(report->keys[4]);
  92. serial_send(report->keys[5]);
  93. }
  94. static void send_mouse(report_mouse_t *report)
  95. {
  96. // wake from deep sleep
  97. /*
  98. PORTD |= (1<<5); // high
  99. wait_ms(5);
  100. PORTD &= ~(1<<5); // low
  101. */
  102. serial_send(0xFD); // Raw report mode
  103. serial_send(5); // length
  104. serial_send(2); // descriptor type
  105. serial_send(report->buttons);
  106. serial_send(report->x);
  107. serial_send(report->y);
  108. serial_send(report->v);
  109. }
  110. static void send_system(uint16_t data)
  111. {
  112. // Table 5-6 of RN-BT-DATA-UB
  113. // 81,82,83 scan codes can be used?
  114. }
  115. static uint16_t usage2bits(uint16_t usage)
  116. {
  117. switch (usage) {
  118. case AC_HOME: return 0x01;
  119. case AL_EMAIL: return 0x02;
  120. case AC_SEARCH: return 0x04;
  121. //case AL_KBD_LAYOUT: return 0x08; // Apple virtual keybaord toggle
  122. case AUDIO_VOL_UP: return 0x10;
  123. case AUDIO_VOL_DOWN: return 0x20;
  124. case AUDIO_MUTE: return 0x40;
  125. case TRANSPORT_PLAY_PAUSE: return 0x80;
  126. case TRANSPORT_NEXT_TRACK: return 0x100;
  127. case TRANSPORT_PREV_TRACK: return 0x200;
  128. case TRANSPORT_STOP: return 0x400;
  129. case TRANSPORT_STOP_EJECT: return 0x800;
  130. //case return 0x1000; // Fast forward
  131. //case return 0x2000; // Rewind
  132. //case return 0x4000; // Stop/eject
  133. //case return 0x8000; // Internet browser
  134. };
  135. return 0;
  136. }
  137. static void send_consumer(uint16_t data)
  138. {
  139. uint16_t bits = usage2bits(data);
  140. serial_send(0xFD); // Raw report mode
  141. serial_send(3); // length
  142. serial_send(3); // descriptor type
  143. serial_send(bits&0xFF);
  144. serial_send((bits>>8)&0xFF);
  145. }
  146. /* Null driver for config_mode */
  147. static uint8_t config_keyboard_leds(void);
  148. static void config_send_keyboard(report_keyboard_t *report);
  149. static void config_send_mouse(report_mouse_t *report);
  150. static void config_send_system(uint16_t data);
  151. static void config_send_consumer(uint16_t data);
  152. host_driver_t rn42_config_driver = {
  153. config_keyboard_leds,
  154. config_send_keyboard,
  155. config_send_mouse,
  156. config_send_system,
  157. config_send_consumer
  158. };
  159. static uint8_t config_keyboard_leds(void) { return 0; }
  160. static void config_send_keyboard(report_keyboard_t *report) {}
  161. static void config_send_mouse(report_mouse_t *report) {}
  162. static void config_send_system(uint16_t data) {}
  163. static void config_send_consumer(uint16_t data) {}