add hhkb bluetooth functionality (rn42) (#2693)
* add hhkb bluetooth functionality (rn42)
pretty much straight from tmk
some minor changes to make things work
* hhkb jp personal keymap
* Revert "hhkb jp personal keymap"
This reverts commit 886713d8bb
.
This commit is contained in:
@ -54,6 +54,47 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
|
||||
)
|
||||
|
||||
#ifdef HHKB_RN42_ENABLE
|
||||
// rn42 support -- acquired from the tmk repo. This is almost certainly not
|
||||
// integrated with qmk in the correct way.
|
||||
|
||||
#define SUART_OUT_PORT PORTD
|
||||
#define SUART_OUT_BIT 0
|
||||
#define SUART_IN_PIN PIND
|
||||
#define SUART_IN_BIT 1
|
||||
|
||||
#ifdef __AVR_ATmega32U4__
|
||||
/* iom32u4.h has no definition of UCSR1D. copy from iom32u2.h */
|
||||
#define UCSR1D _SFR_MEM8(0xCB)
|
||||
#define RTSEN 0
|
||||
#define CTSEN 1
|
||||
|
||||
#define SERIAL_UART_BAUD 115200
|
||||
#define SERIAL_UART_DATA UDR1
|
||||
#define SERIAL_UART_UBRR ((F_CPU/(16.0*SERIAL_UART_BAUD)-1+0.5))
|
||||
#define SERIAL_UART_RXD_VECT USART1_RX_vect
|
||||
#define SERIAL_UART_TXD_READY (UCSR1A&(1<<UDRE1))
|
||||
#define SERIAL_UART_INIT() do { \
|
||||
UBRR1L = (uint8_t) SERIAL_UART_UBRR; /* baud rate */ \
|
||||
UBRR1H = ((uint16_t)SERIAL_UART_UBRR>>8); /* baud rate */ \
|
||||
UCSR1B |= (1<<RXCIE1) | (1<<RXEN1); /* RX interrupt, RX: enable */ \
|
||||
UCSR1B |= (0<<TXCIE1) | (1<<TXEN1); /* TX interrupt, TX: enable */ \
|
||||
UCSR1C |= (0<<UPM11) | (0<<UPM10); /* parity: none(00), even(01), odd(11) */ \
|
||||
UCSR1D |= (0<<RTSEN) | (0<<CTSEN); /* RTS, CTS(no flow control by hardware) */ \
|
||||
DDRD |= (1<<5); PORTD &= ~(1<<5); /* RTS for flow control by firmware */ \
|
||||
sei(); \
|
||||
} while(0)
|
||||
#define SERIAL_UART_RTS_LO() do { PORTD &= ~(1<<5); } while (0)
|
||||
#define SERIAL_UART_RTS_HI() do { PORTD |= (1<<5); } while (0)
|
||||
#else
|
||||
#error "USART configuration is needed."
|
||||
#endif
|
||||
|
||||
/* power control of key switch board */
|
||||
#define HHKB_POWER_SAVING
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Feature disable options
|
||||
* These options are also useful to firmware size reduction.
|
||||
|
262
keyboards/hhkb/rn42/MEMO.txt
Normal file
262
keyboards/hhkb/rn42/MEMO.txt
Normal file
@ -0,0 +1,262 @@
|
||||
Memo of deveopment
|
||||
==================
|
||||
just memo, NOT WORTH READING
|
||||
|
||||
2015/11/24
|
||||
JP Bluetooth:
|
||||
RN-42 cannot send Japanese keys like; henkan, mu-henkan and kana, JPY and RO.
|
||||
It seems HID usage more than 0x65 cannot be send with the module.
|
||||
http://shiki.esrille.com/2014/07/bluetoothnisse.html
|
||||
|
||||
|
||||
Bug:
|
||||
- Factory Reset PIO4 doesn't work
|
||||
- the reason is unclear - 12/08 NOT LOOK INTO ANY MORE
|
||||
- WORKAROUND: use serial pins(3.3V, GND, RX and TX)
|
||||
- SF,1 and R,1 to set factory defalult
|
||||
|
||||
|
||||
Todo:
|
||||
- LED cover and switch knob and new Slide Switch
|
||||
- RN42 auto configuration
|
||||
- configure the module as HID device every time powering up
|
||||
- this'll reduce work load of assembly
|
||||
|
||||
- move rn42 to protocol directory when it becomes reusable stack
|
||||
|
||||
- sendchar() in lufa.c no buffer
|
||||
- no buffering. character lost can be caused.
|
||||
- LUFA sendchar should be buffered and serial_uart.c buffur size is too large(256).
|
||||
|
||||
- BT operations
|
||||
- disconnect
|
||||
- new connection
|
||||
- remove connection
|
||||
|
||||
- sendchar() in lufa.c block loop - DONE 11/29
|
||||
- block loop when powered with AC adapter
|
||||
- FrameNumber is not updated when adapter powered
|
||||
|
||||
Improving:
|
||||
- ADC resolution
|
||||
AVR120
|
||||
AVR32138
|
||||
- Enhancing ADC resolution by oversampling
|
||||
AVR121 http://www.atmel.com/images/doc8003.pdf
|
||||
- disable digital input buffer DIDR(7.8.6)
|
||||
|
||||
Design:
|
||||
- suspend.h - DONE 11/26
|
||||
- remove argument from suspend_power_down() for backward compatitibility
|
||||
- remove MCU dependent power saving code from core/keyboard - DONE 11/23
|
||||
- it should be located in project matrix.c
|
||||
- HHKB matrix.c needs matrix_prev?
|
||||
- is_modified() is obsolete now. really needs?
|
||||
- ADC: removing AREF capacitor C10
|
||||
- seems to be better while usb powered
|
||||
- still bad while battery powered
|
||||
http://electronics.stackexchange.com/questions/105849/avcc-and-capacitor-using-adc
|
||||
- ADC: smaller resistors for voltage dividor
|
||||
- 1K + 1K: not improved. - 11/27
|
||||
|
||||
|
||||
LUFA:
|
||||
USB connection check: state of USB deivce
|
||||
- USB_DeviceState:
|
||||
USB_Deivce_State_t { Unattached, Powered, Default, Addressed, Configured*, Suspended* }
|
||||
Unattached: unpluged
|
||||
Powered: pluged with power adapter
|
||||
Default: enumerate process bigin
|
||||
Addressed: addressed
|
||||
Configured: enumerated
|
||||
Suspended: suspended
|
||||
|
||||
- USB_IsInitialized: state of LUFA core setup
|
||||
becomes true in USB_Init() USBController_AVR8.c
|
||||
becomes false in USB_Disable() USBController_AVR8.c
|
||||
- USB_VBUS_GetStatus(): state of VBUS(power/connection)
|
||||
- USB_Disable() detaches, disables all interrupts, controller, PLL, regulater.
|
||||
|
||||
- When connect to power adapter
|
||||
- event happened: CW or CSW or C or DDC
|
||||
- USB state: not configured
|
||||
|
||||
- USB evnets
|
||||
- USB connect: CSWRWRW
|
||||
- USB connect but fail to enumeration: CWRWRWRWS
|
||||
- USB disconnect: D
|
||||
- Power adapter connect: CW, CSW, C
|
||||
- Power adapter disconnect: D
|
||||
|
||||
|
||||
Power saving:
|
||||
- Pro2 current consumption
|
||||
- active: 138.2mA(no device on Hub)
|
||||
- suspended: 30.9mA(WakeUp enabled DIPSW6)
|
||||
- suspended: 0mA->46.0mA(WakeUp disabled DIPSW6)
|
||||
- Pro current consumption
|
||||
- active: 54.0mA
|
||||
- suspended: 40.5mA(WakeUp enabled DIPSW6)
|
||||
- suspended: 0.3mA(WakeUp disabled DIPSW6)
|
||||
|
||||
- RN42 3.3V
|
||||
- disconnected(Idle): 5mA (config mode)
|
||||
- connected(Active):
|
||||
SW,0000: 23-26mA
|
||||
SW,0010: 27-29mA worse than 0000 for unknown reason
|
||||
SW,0020: 17-19mA mouse NG
|
||||
SW,0030: 13-16mA laggy mouse NG
|
||||
SW,0050: 10-13mA laggy mouse NG
|
||||
|
||||
- matrix power saving
|
||||
- power saving while externally powered and not while unpluged
|
||||
- confirm suspend mode lufa.c: matrix_power_*, suspend_wakeup_condition
|
||||
- 8MHz clock
|
||||
- When not connected in a few minutes get into deep sleep to save battery life
|
||||
- CTS is needed for waking up from deep sleep? How deep sleep is activated?
|
||||
- firmware controlled 3.3V DC converter to switch on/off BT module
|
||||
- sleep MCU and BT module(keyboard is not used)
|
||||
- deep sleep MCU and BT module(keyboard is not used for long time)
|
||||
- deep sleep MCU and turn off BT module(keyboard is not used and not connected)
|
||||
- Battery ADC; switching, high resistance
|
||||
- switching gnd end of divider with PF4
|
||||
- high resistor 100K/1M?
|
||||
capacitor 10nF
|
||||
http://www.eevblog.com/forum/beginners/measuring-battery-voltage-without-consuming-current/
|
||||
- During USB suspend change clock source to internal RC from external Xtal(6.8)
|
||||
- FRZCLK: you can freeze clock for power saving. still WAKEUPI and VBUSTI interrupts are available while freezing.(21.7.3)
|
||||
- Suspend: Clear Suspend Bit, Freeze clock, disable PLL, MCU sleep(21.13)
|
||||
- Voltage reference(8.1.1)
|
||||
- to reduce power consumption while power down mode
|
||||
- unset ADEN before sleep(24.7)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Lipo
|
||||
----
|
||||
850mA lasts around 9 hours(07/28)
|
||||
|
||||
Sparkfun Polymer Lithium Ion Battery 850mAh:
|
||||
https://www.sparkfun.com/products/341
|
||||
Lipo Cell spec:
|
||||
https://www.sparkfun.com/datasheets/Batteries/063048%20Li-polymer.pdf
|
||||
Protection spec:
|
||||
http://dlnmh9ip6v2uc.cloudfront.net/datasheets/Prototyping/BatteryProtection.pdf
|
||||
min typical max
|
||||
over-charge 4.255 4.280 4.305
|
||||
over-charge discover? 4.030 4.080 4.130
|
||||
over-discharge 2.827 2.900 2.973
|
||||
over-discharge discover 3.022 3.100 3.178
|
||||
|
||||
ADC voltage monitor: voltage divider 10K+10K(0.5)
|
||||
ADC=V*0.5/2.56*1024
|
||||
|
||||
V ADC
|
||||
------------------
|
||||
4.20 0x347(839)
|
||||
3.10 0x26b(619)
|
||||
|
||||
|
||||
|
||||
|
||||
TROUBLE SHOOT
|
||||
-------------
|
||||
07/16 After fix of voltage dividor on GPIO6, had a trouble that it could not send a char to BT module, though could receive.
|
||||
Found R8 had wrong 1K resistor and changed to 10K, after that it can send to the module again. Not sure how it had sent with the wrong 1K before.
|
||||
|
||||
07/18 On Linux, had an USB related trouble; keyboard or console didn't work for some reason. Changing PID cured this problem. Very annoying, took very long time before resolved it.
|
||||
|
||||
12/07 rn42_rts() read 1 every time. R12 broke in open mode(no coductive), idk why, too much heat with soldering? and PF1 pin was not soldered.
|
||||
It resolved with resoldering PF1 and new resistor on R12.
|
||||
|
||||
|
||||
|
||||
|
||||
Done:
|
||||
- low battery alert(solid light) 09/04
|
||||
- *** Rev.E BT test *** - DONE
|
||||
- with MCP73832, new Schottky, tantalum caps - DONE 12/07
|
||||
* MCP73832 doesn't leak from Vcc pin when unpluged and battery powered
|
||||
34mV vs 2.07V(MCP73831) at Vcc pin
|
||||
MCP73832 doesn't need revese protection diode D5
|
||||
* PMEG2010ER is very low VF while reverse current/voltage is high
|
||||
VF=0.96 vs 1.98(RB160M-30TR)with Fluke 175
|
||||
Anode of D11 is 680mV vs 20mV(RB160M-30TR)
|
||||
780mV is still low < 1.4V VBUS plugin detection(21.11)
|
||||
this doesn't cause false VBUS detect
|
||||
and 780mV on MCP73832 Vcc pin is also no problem.
|
||||
D5 can be removed.
|
||||
- ADC divider switching - DONE 12/07
|
||||
* Drain and Source of Q4 Pch was reversed wrongly on Rev.E.
|
||||
|
||||
- reverse current from Lipo charger - DONE 12/07
|
||||
* MCP73832 has no recverse current from Vcc pin unlike MCP73831
|
||||
|
||||
|
||||
- Rev.F design - DONE
|
||||
- current measure point - DONE 12/08
|
||||
- change value of cap 68->47 - DONE 12/08
|
||||
- PPTC land pattern: no solder jumper, use 0Ohm resistor instead - CANCEL 12/08
|
||||
- Q4 Pch FET: wrong Drain and Source - DONE 12/08
|
||||
- D5 can be removed. - DONE 12/08
|
||||
|
||||
|
||||
|
||||
- BT_INDICATOR LED turns on wrongly when touching line or pin. -- pull-up enabled on PF6/GPIO2 08/30
|
||||
- Lipo charger configuration: fast charge time: USB charger spec? -- used 2kohm
|
||||
- use LED of charger to alarm low battery. LED should be powered directly from Lipo? - cancel; powered from VUSB
|
||||
- Use RTS in serial_uart.c to resolve missing chars from help message of RN-42 - done
|
||||
- CTS/RTS lines are needed? just connect in loop back if no flow control is needed. - done
|
||||
- add IO pin to charger status CHRG; LED control(low) and detect charge status(input HiZ) 07.24
|
||||
- LINKED: add trace on PIO2 to PF6 07.24
|
||||
- Lipo voltage ADC sensing
|
||||
- Lipo charger MCP73831: needs capacitor 4.7uF *2
|
||||
- USB connection check - 07.01
|
||||
- BT on/off check: whether RX line is pulled up? - checking RTS 07.01
|
||||
- USB/BT switching BT is on -> BT, BT is off -> USB - 07.01
|
||||
- Under voltage lock out UVLO for protection of Lipo - Lipo has discharge protection at 3.100V 07.01
|
||||
- Power saving: HHKB scan, BT radio control - 9h with 850mAh, this is enough 07.01
|
||||
- Power selector doesn't work; Q4 MOSFET leaks from Lipo to USB power line. -- use Schottky instead 07/04
|
||||
|
||||
- wrongly suspended when powered from adapter without USB connection - DONE
|
||||
- suspend event may occur when plug into adapter
|
||||
- and never wake until conected to real USB line
|
||||
- without debug print via USB no problem; CSW(wake just after suspend as real USB line)
|
||||
- seems like USB print causes this problem after suspended
|
||||
|
||||
- lose USB connection during power-down mode - DONE
|
||||
- USB initialize code in main() causes this - WRONG
|
||||
- Do not power-down during USB connection is active - DONE 11/11
|
||||
(USB_DeviceState == USB_DEVICE_Configured) is used to check USB connection
|
||||
matrix_power_down() matrix.c - 11/23
|
||||
|
||||
- with Nexus5 keyboard and mouse are very laggy.
|
||||
Not confirmed. 01/15
|
||||
|
||||
- switch BT host connections - CANCEL 01/15
|
||||
- switch next connection
|
||||
cannot switch connection with version 6.15 at least
|
||||
|
||||
- When given power only from wall wart adapter - DONE? not confirmed 01/15
|
||||
- it sleeps. it should not sleep
|
||||
- Configured state without USB connection?
|
||||
|
||||
- timer is slow while power down - DONE 11/26
|
||||
- time out interrupt is lost while power down?
|
||||
- interrupt of watchdog timer compensates timer counter(avr/suspend.c)
|
||||
|
||||
- repeated CHARGING/FULL_CHARGED - No longer problem 01/15
|
||||
- In LTC sharp pulses are observed.
|
||||
- MCP has no pulse but still has a problem.
|
||||
- needs more wait before read pin state? - NO
|
||||
|
||||
- USB plug-in fails while BT - No longer problem 01/15
|
||||
- it ends in suspend state
|
||||
- maybe, not responsive to host enumeration process due to power-down.
|
||||
- matrix_power_down() only when state is unattached - 11/26
|
||||
- need to observe a while
|
||||
|
88
keyboards/hhkb/rn42/PowerSave.txt
Normal file
88
keyboards/hhkb/rn42/PowerSave.txt
Normal file
@ -0,0 +1,88 @@
|
||||
Power Saving
|
||||
============
|
||||
|
||||
|
||||
MCU+HHKB Power Comsumption
|
||||
--------------------------
|
||||
Battery drive:
|
||||
idle 18.9mA
|
||||
active 35.8mA
|
||||
|
||||
USB powered:
|
||||
40.0mA
|
||||
52mA 01/17
|
||||
|
||||
Other keyboards:
|
||||
HHKB Pro 55mA
|
||||
HHKB Pro2 140mA
|
||||
HHKB Pro 42mA(Alt)
|
||||
HHKB Pro2 52mA(Alt BT controller USB mode)
|
||||
HHKB Pro2 88mA(Alt BT controller BT mode connected)
|
||||
HHKB Pro2 68mA(Alt BT controller BT mode config mode)
|
||||
Poker X 6mA
|
||||
Infinity 24mA(TMK)
|
||||
65mA(kiibohd)
|
||||
|
||||
|
||||
HHKB key switch power control
|
||||
-----------------------------
|
||||
MOS FET Nch: BSS138 or IRLML6344T, either works and no apparent difference.
|
||||
Normally on(pull-up) or off(pull-down)? interms of power saving it prefers pull-down?
|
||||
|
||||
Pull-down will be better for power saving, normally off.
|
||||
|
||||
|
||||
|
||||
Used Timer
|
||||
----------
|
||||
|
||||
8MHz clock
|
||||
----------
|
||||
1) 16MHz xtal with system prescaler div2: F_CPU=8MHz, F_USB=16MHz
|
||||
2) 8MHz xtal with div1: F_CPU=8MHz, F_USB=8MHz
|
||||
Hardware USART doesn't work at 115200bps with 8MHz(F_CPU).
|
||||
|
||||
workaround:
|
||||
a) use Sotwre serial for communcation with RN-42
|
||||
b) reduce baud of RN-42 to lower rate;(factory default is 115200bps)
|
||||
10/03
|
||||
|
||||
|
||||
|
||||
Slave mode
|
||||
----------
|
||||
Discovery/Inquire
|
||||
Connect/Page
|
||||
|
||||
SI,0012
|
||||
SJ,0012
|
||||
InqWindw=0100
|
||||
PagWindw=0100
|
||||
|
||||
|
||||
Sniff mode
|
||||
----------
|
||||
0.625ms * <hex>
|
||||
SW,0320 Very sluggish. Type is not lost but very slow to register.
|
||||
SW,0160 Still sluggish. may transposed? can type but ...
|
||||
Mouse point move intermittently
|
||||
SW,0020 feel a bit late like stumble(20ms)
|
||||
SW,0010 feel no latency(10ms)
|
||||
|
||||
|
||||
Deep sleep
|
||||
----------
|
||||
SW,8010
|
||||
|
||||
|
||||
TX power
|
||||
--------
|
||||
SY,fff4
|
||||
|
||||
|
||||
IO pins
|
||||
-------
|
||||
S%,1000 status led and connection control don't work
|
||||
GPIO5: status LED
|
||||
GPIO6: Connection control
|
||||
GPIO2: linked status
|
408
keyboards/hhkb/rn42/RN42.txt
Normal file
408
keyboards/hhkb/rn42/RN42.txt
Normal file
File diff suppressed because it is too large
Load Diff
130
keyboards/hhkb/rn42/battery.c
Normal file
130
keyboards/hhkb/rn42/battery.c
Normal file
@ -0,0 +1,130 @@
|
||||
#include <avr/io.h>
|
||||
#include <util/delay.h>
|
||||
#include "battery.h"
|
||||
|
||||
|
||||
/*
|
||||
* Battery
|
||||
*/
|
||||
void battery_init(void)
|
||||
{
|
||||
// blink
|
||||
battery_led(LED_ON); _delay_ms(100);
|
||||
battery_led(LED_OFF); _delay_ms(100);
|
||||
battery_led(LED_ON); _delay_ms(100);
|
||||
battery_led(LED_OFF); _delay_ms(100);
|
||||
// LED indicates charger status
|
||||
battery_led(LED_CHARGER);
|
||||
|
||||
// ADC setting for voltage monitor
|
||||
// Ref:2.56V band-gap, Input:ADC0(PF0), Prescale:128(16MHz/128=125KHz)
|
||||
ADMUX = (1<<REFS1) | (1<<REFS0);
|
||||
ADCSRA = (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);
|
||||
// digital input buffer disable(24.9.5)
|
||||
DIDR0 = (1<<ADC0D) | (1<<ADC4D) | (1<<ADC7D);
|
||||
DIDR1 = (1<<AIN0D);
|
||||
DIDR2 = (1<<ADC8D) | (1<<ADC9D) | (1<<ADC11D) | (1<<ADC12D) | (1<<ADC13D);
|
||||
|
||||
// ADC disable voltate divider(PF4)
|
||||
DDRF |= (1<<4);
|
||||
PORTF &= ~(1<<4);
|
||||
}
|
||||
|
||||
// Indicator for battery
|
||||
void battery_led(battery_led_t val)
|
||||
{
|
||||
if (val == LED_TOGGLE) {
|
||||
// Toggle LED
|
||||
DDRF |= (1<<5);
|
||||
PINF |= (1<<5);
|
||||
} else if (val == LED_ON) {
|
||||
// On overriding charger status
|
||||
DDRF |= (1<<5);
|
||||
PORTF &= ~(1<<5);
|
||||
} else if (val == LED_OFF) {
|
||||
// Off overriding charger status
|
||||
DDRF |= (1<<5);
|
||||
PORTF |= (1<<5);
|
||||
} else {
|
||||
// Display charger status
|
||||
DDRF &= ~(1<<5);
|
||||
PORTF &= ~(1<<5);
|
||||
}
|
||||
}
|
||||
|
||||
bool battery_charging(void)
|
||||
{
|
||||
if (!(USBSTA&(1<<VBUS))) return false;
|
||||
|
||||
// Charger Status:
|
||||
// MCP73831 MCP73832 LTC4054 Status
|
||||
// Hi-Z Hi-Z Hi-Z Shutdown/No Battery
|
||||
// Low Low Low Charging
|
||||
// Hi Hi-Z Hi-Z Charged
|
||||
|
||||
// preserve last register status
|
||||
uint8_t ddrf_prev = DDRF;
|
||||
uint8_t portf_prev = PORTF;
|
||||
|
||||
// Input with pullup
|
||||
DDRF &= ~(1<<5);
|
||||
PORTF |= (1<<5);
|
||||
_delay_ms(1);
|
||||
bool charging = PINF&(1<<5) ? false : true;
|
||||
|
||||
// restore last register status
|
||||
DDRF = (DDRF&~(1<<5)) | (ddrf_prev&(1<<5));
|
||||
PORTF = (PORTF&~(1<<5)) | (portf_prev&(1<<5));
|
||||
|
||||
// TODO: With MCP73831 this can not get stable status when charging.
|
||||
// LED is powered from PSEL line(USB or Lipo)
|
||||
// due to weak low output of STAT pin?
|
||||
// due to pull-up'd via resitor and LED?
|
||||
return charging;
|
||||
}
|
||||
|
||||
// Returns voltage in mV
|
||||
uint16_t battery_voltage(void)
|
||||
{
|
||||
// ADC disable voltate divider(PF4)
|
||||
DDRF |= (1<<4);
|
||||
PORTF |= (1<<4);
|
||||
|
||||
volatile uint16_t bat;
|
||||
ADCSRA |= (1<<ADEN);
|
||||
_delay_ms(1); // wait for charging S/H capacitance
|
||||
|
||||
ADCSRA |= (1<<ADSC);
|
||||
while (ADCSRA & (1<<ADSC)) ;
|
||||
bat = ADC;
|
||||
|
||||
ADCSRA &= ~(1<<ADEN);
|
||||
|
||||
// ADC disable voltate divider(PF4)
|
||||
DDRF |= (1<<4);
|
||||
PORTF &= ~(1<<4);
|
||||
|
||||
return (bat - BATTERY_ADC_OFFSET) * BATTERY_ADC_RESOLUTION;
|
||||
}
|
||||
|
||||
static bool low_voltage(void) {
|
||||
static bool low = false;
|
||||
uint16_t v = battery_voltage();
|
||||
if (v < BATTERY_VOLTAGE_LOW_LIMIT) {
|
||||
low = true;
|
||||
} else if (v > BATTERY_VOLTAGE_LOW_RECOVERY) {
|
||||
low = false;
|
||||
}
|
||||
return low;
|
||||
}
|
||||
|
||||
battery_status_t battery_status(void)
|
||||
{
|
||||
if (USBSTA&(1<<VBUS)) {
|
||||
/* powered */
|
||||
return battery_charging() ? CHARGING : FULL_CHARGED;
|
||||
} else {
|
||||
/* not powered */
|
||||
return low_voltage() ? LOW_VOLTAGE : DISCHARGING;
|
||||
}
|
||||
}
|
35
keyboards/hhkb/rn42/battery.h
Normal file
35
keyboards/hhkb/rn42/battery.h
Normal file
@ -0,0 +1,35 @@
|
||||
#ifndef POWER_H
|
||||
#define POWER_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef enum {
|
||||
FULL_CHARGED,
|
||||
CHARGING,
|
||||
DISCHARGING,
|
||||
LOW_VOLTAGE,
|
||||
UNKNOWN,
|
||||
} battery_status_t;
|
||||
|
||||
typedef enum {
|
||||
LED_CHARGER = 0,
|
||||
LED_ON,
|
||||
LED_OFF,
|
||||
LED_TOGGLE,
|
||||
} battery_led_t;
|
||||
|
||||
/* Battery API */
|
||||
void battery_init(void);
|
||||
void battery_led(battery_led_t val);
|
||||
bool battery_charging(void);
|
||||
uint16_t battery_voltage(void);
|
||||
battery_status_t battery_status(void);
|
||||
|
||||
#define BATTERY_VOLTAGE_LOW_LIMIT 3500
|
||||
#define BATTERY_VOLTAGE_LOW_RECOVERY 3700
|
||||
// ADC offset:16, resolution:5mV
|
||||
#define BATTERY_ADC_OFFSET 16
|
||||
#define BATTERY_ADC_RESOLUTION 5
|
||||
|
||||
#endif
|
106
keyboards/hhkb/rn42/main.c
Normal file
106
keyboards/hhkb/rn42/main.c
Normal file
@ -0,0 +1,106 @@
|
||||
#include <avr/io.h>
|
||||
#include <avr/power.h>
|
||||
#include <avr/wdt.h>
|
||||
#include "lufa.h"
|
||||
#include "print.h"
|
||||
#include "sendchar.h"
|
||||
#include "rn42.h"
|
||||
#include "rn42_task.h"
|
||||
#include "serial.h"
|
||||
#include "keyboard.h"
|
||||
#include "keycode.h"
|
||||
#include "action.h"
|
||||
#include "action_util.h"
|
||||
#include "wait.h"
|
||||
#include "suart.h"
|
||||
#include "suspend.h"
|
||||
#include "matrix.h"
|
||||
|
||||
static int8_t sendchar_func(uint8_t c)
|
||||
{
|
||||
xmit(c); // SUART
|
||||
sendchar(c); // LUFA
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void SetupHardware(void)
|
||||
{
|
||||
/* Disable watchdog if enabled by bootloader/fuses */
|
||||
MCUSR &= ~(1 << WDRF);
|
||||
wdt_disable();
|
||||
|
||||
/* Disable clock division */
|
||||
clock_prescale_set(clock_div_1);
|
||||
|
||||
// Leonardo needs. Without this USB device is not recognized.
|
||||
USB_Disable();
|
||||
|
||||
USB_Init();
|
||||
|
||||
// for Console_Task
|
||||
USB_Device_EnableSOFEvents();
|
||||
print_set_sendchar(sendchar_func);
|
||||
|
||||
// SUART PD0:output, PD1:input
|
||||
DDRD |= (1<<0);
|
||||
PORTD |= (1<<0);
|
||||
DDRD &= ~(1<<1);
|
||||
PORTD |= (1<<1);
|
||||
}
|
||||
|
||||
int main(void) __attribute__ ((weak));
|
||||
int main(void)
|
||||
{
|
||||
SetupHardware();
|
||||
sei();
|
||||
|
||||
/* wait for USB startup to get ready for debug output */
|
||||
uint8_t timeout = 255; // timeout when USB is not available(Bluetooth)
|
||||
while (timeout-- && USB_DeviceState != DEVICE_STATE_Configured) {
|
||||
wait_ms(4);
|
||||
#if defined(INTERRUPT_CONTROL_ENDPOINT)
|
||||
;
|
||||
#else
|
||||
USB_USBTask();
|
||||
#endif
|
||||
}
|
||||
print("\nUSB init\n");
|
||||
|
||||
rn42_init();
|
||||
rn42_task_init();
|
||||
print("RN-42 init\n");
|
||||
|
||||
/* init modules */
|
||||
keyboard_init();
|
||||
|
||||
#ifdef SLEEP_LED_ENABLE
|
||||
sleep_led_init();
|
||||
#endif
|
||||
|
||||
print("Keyboard start\n");
|
||||
while (1) {
|
||||
while (rn42_rts() && // RN42 is off
|
||||
USB_DeviceState == DEVICE_STATE_Suspended) {
|
||||
print("[s]");
|
||||
matrix_power_down();
|
||||
suspend_power_down();
|
||||
suspend_power_down();
|
||||
suspend_power_down();
|
||||
suspend_power_down();
|
||||
suspend_power_down();
|
||||
suspend_power_down();
|
||||
suspend_power_down();
|
||||
if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) {
|
||||
USB_Device_SendRemoteWakeup();
|
||||
}
|
||||
}
|
||||
|
||||
keyboard_task();
|
||||
|
||||
#if !defined(INTERRUPT_CONTROL_ENDPOINT)
|
||||
USB_USBTask();
|
||||
#endif
|
||||
|
||||
rn42_task();
|
||||
}
|
||||
}
|
265
keyboards/hhkb/rn42/rn42.c
Normal file
265
keyboards/hhkb/rn42/rn42.c
Normal file
@ -0,0 +1,265 @@
|
||||
#include <avr/io.h>
|
||||
#include "host.h"
|
||||
#include "host_driver.h"
|
||||
#include "serial.h"
|
||||
#include "rn42.h"
|
||||
#include "print.h"
|
||||
#include "timer.h"
|
||||
#include "wait.h"
|
||||
|
||||
|
||||
/* Host driver */
|
||||
static uint8_t keyboard_leds(void);
|
||||
static void send_keyboard(report_keyboard_t *report);
|
||||
static void send_mouse(report_mouse_t *report);
|
||||
static void send_system(uint16_t data);
|
||||
static void send_consumer(uint16_t data);
|
||||
|
||||
host_driver_t rn42_driver = {
|
||||
keyboard_leds,
|
||||
send_keyboard,
|
||||
send_mouse,
|
||||
send_system,
|
||||
send_consumer
|
||||
};
|
||||
|
||||
|
||||
void rn42_init(void)
|
||||
{
|
||||
// JTAG disable for PORT F. write JTD bit twice within four cycles.
|
||||
MCUCR |= (1<<JTD);
|
||||
MCUCR |= (1<<JTD);
|
||||
|
||||
// PF7: BT connection control(high: connect, low: disconnect)
|
||||
rn42_autoconnect();
|
||||
|
||||
// PF6: linked(input without pull-up)
|
||||
DDRF &= ~(1<<6);
|
||||
PORTF |= (1<<6);
|
||||
|
||||
// PF1: RTS(low: allowed to send, high: not allowed)
|
||||
DDRF &= ~(1<<1);
|
||||
PORTF &= ~(1<<1);
|
||||
|
||||
// PD5: CTS(low: allow to send, high:not allow)
|
||||
DDRD |= (1<<5);
|
||||
PORTD &= ~(1<<5);
|
||||
|
||||
serial_init();
|
||||
}
|
||||
|
||||
int16_t rn42_getc(void)
|
||||
{
|
||||
return serial_recv2();
|
||||
}
|
||||
|
||||
const char *rn42_gets(uint16_t timeout)
|
||||
{
|
||||
static char s[24];
|
||||
uint16_t t = timer_read();
|
||||
uint8_t i = 0;
|
||||
int16_t c;
|
||||
while (i < 23 && timer_elapsed(t) < timeout) {
|
||||
if ((c = rn42_getc()) != -1) {
|
||||
if ((char)c == '\r') continue;
|
||||
if ((char)c == '\n') break;
|
||||
s[i++] = c;
|
||||
}
|
||||
}
|
||||
s[i] = '\0';
|
||||
return s;
|
||||
}
|
||||
|
||||
void rn42_putc(uint8_t c)
|
||||
{
|
||||
serial_send(c);
|
||||
}
|
||||
|
||||
void rn42_puts(char *s)
|
||||
{
|
||||
while (*s)
|
||||
serial_send(*s++);
|
||||
}
|
||||
|
||||
bool rn42_autoconnecting(void)
|
||||
{
|
||||
// GPIO6 for control connection(high: auto connect, low: disconnect)
|
||||
// Note that this needs config: SM,4(Auto-Connect DTR Mode)
|
||||
return (PORTF & (1<<7) ? true : false);
|
||||
}
|
||||
|
||||
void rn42_autoconnect(void)
|
||||
{
|
||||
// hi to auto connect
|
||||
DDRF |= (1<<7);
|
||||
PORTF |= (1<<7);
|
||||
}
|
||||
|
||||
void rn42_disconnect(void)
|
||||
{
|
||||
// low to disconnect
|
||||
DDRF |= (1<<7);
|
||||
PORTF &= ~(1<<7);
|
||||
}
|
||||
|
||||
bool rn42_rts(void)
|
||||
{
|
||||
// low when RN-42 is powered and ready to receive
|
||||
return PINF&(1<<1);
|
||||
}
|
||||
|
||||
void rn42_cts_hi(void)
|
||||
{
|
||||
// not allow to send
|
||||
PORTD |= (1<<5);
|
||||
}
|
||||
|
||||
void rn42_cts_lo(void)
|
||||
{
|
||||
// allow to send
|
||||
PORTD &= ~(1<<5);
|
||||
}
|
||||
|
||||
bool rn42_linked(void)
|
||||
{
|
||||
// RN-42 GPIO2
|
||||
// Hi-Z: Not powered
|
||||
// High: Linked
|
||||
// Low: Connecting
|
||||
return PINF&(1<<6);
|
||||
}
|
||||
|
||||
|
||||
static uint8_t leds = 0;
|
||||
static uint8_t keyboard_leds(void) { return leds; }
|
||||
void rn42_set_leds(uint8_t l) { leds = l; }
|
||||
|
||||
|
||||
void rn42_send_str(const char *str)
|
||||
{
|
||||
uint8_t c;
|
||||
while ((c = pgm_read_byte(str++)))
|
||||
rn42_putc(c);
|
||||
}
|
||||
|
||||
const char *rn42_send_command(const char *cmd)
|
||||
{
|
||||
static const char *s;
|
||||
rn42_send_str(cmd);
|
||||
wait_ms(500);
|
||||
s = rn42_gets(100);
|
||||
xprintf("%s\r\n", s);
|
||||
rn42_print_response();
|
||||
return s;
|
||||
}
|
||||
|
||||
void rn42_print_response(void)
|
||||
{
|
||||
int16_t c;
|
||||
while ((c = rn42_getc()) != -1) {
|
||||
xprintf("%c", c);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void send_keyboard(report_keyboard_t *report)
|
||||
{
|
||||
// wake from deep sleep
|
||||
/*
|
||||
PORTD |= (1<<5); // high
|
||||
wait_ms(5);
|
||||
PORTD &= ~(1<<5); // low
|
||||
*/
|
||||
|
||||
serial_send(0xFD); // Raw report mode
|
||||
serial_send(9); // length
|
||||
serial_send(1); // descriptor type
|
||||
serial_send(report->mods);
|
||||
serial_send(0x00);
|
||||
serial_send(report->keys[0]);
|
||||
serial_send(report->keys[1]);
|
||||
serial_send(report->keys[2]);
|
||||
serial_send(report->keys[3]);
|
||||
serial_send(report->keys[4]);
|
||||
serial_send(report->keys[5]);
|
||||
}
|
||||
|
||||
static void send_mouse(report_mouse_t *report)
|
||||
{
|
||||
// wake from deep sleep
|
||||
/*
|
||||
PORTD |= (1<<5); // high
|
||||
wait_ms(5);
|
||||
PORTD &= ~(1<<5); // low
|
||||
*/
|
||||
|
||||
serial_send(0xFD); // Raw report mode
|
||||
serial_send(5); // length
|
||||
serial_send(2); // descriptor type
|
||||
serial_send(report->buttons);
|
||||
serial_send(report->x);
|
||||
serial_send(report->y);
|
||||
serial_send(report->v);
|
||||
}
|
||||
|
||||
static void send_system(uint16_t data)
|
||||
{
|
||||
// Table 5-6 of RN-BT-DATA-UB
|
||||
// 81,82,83 scan codes can be used?
|
||||
}
|
||||
|
||||
|
||||
static uint16_t usage2bits(uint16_t usage)
|
||||
{
|
||||
switch (usage) {
|
||||
case AC_HOME: return 0x01;
|
||||
case AL_EMAIL: return 0x02;
|
||||
case AC_SEARCH: return 0x04;
|
||||
//case AL_KBD_LAYOUT: return 0x08; // Apple virtual keybaord toggle
|
||||
case AUDIO_VOL_UP: return 0x10;
|
||||
case AUDIO_VOL_DOWN: return 0x20;
|
||||
case AUDIO_MUTE: return 0x40;
|
||||
case TRANSPORT_PLAY_PAUSE: return 0x80;
|
||||
case TRANSPORT_NEXT_TRACK: return 0x100;
|
||||
case TRANSPORT_PREV_TRACK: return 0x200;
|
||||
case TRANSPORT_STOP: return 0x400;
|
||||
case TRANSPORT_STOP_EJECT: return 0x800;
|
||||
case TRANSPORT_FAST_FORWARD: return 0x1000;
|
||||
case TRANSPORT_REWIND: return 0x2000;
|
||||
//case return 0x4000; // Stop/eject
|
||||
//case return 0x8000; // Internet browser
|
||||
};
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void send_consumer(uint16_t data)
|
||||
{
|
||||
uint16_t bits = usage2bits(data);
|
||||
serial_send(0xFD); // Raw report mode
|
||||
serial_send(3); // length
|
||||
serial_send(3); // descriptor type
|
||||
serial_send(bits&0xFF);
|
||||
serial_send((bits>>8)&0xFF);
|
||||
}
|
||||
|
||||
|
||||
/* Null driver for config_mode */
|
||||
static uint8_t config_keyboard_leds(void);
|
||||
static void config_send_keyboard(report_keyboard_t *report);
|
||||
static void config_send_mouse(report_mouse_t *report);
|
||||
static void config_send_system(uint16_t data);
|
||||
static void config_send_consumer(uint16_t data);
|
||||
|
||||
host_driver_t rn42_config_driver = {
|
||||
config_keyboard_leds,
|
||||
config_send_keyboard,
|
||||
config_send_mouse,
|
||||
config_send_system,
|
||||
config_send_consumer
|
||||
};
|
||||
|
||||
static uint8_t config_keyboard_leds(void) { return leds; }
|
||||
static void config_send_keyboard(report_keyboard_t *report) {}
|
||||
static void config_send_mouse(report_mouse_t *report) {}
|
||||
static void config_send_system(uint16_t data) {}
|
||||
static void config_send_consumer(uint16_t data) {}
|
30
keyboards/hhkb/rn42/rn42.h
Normal file
30
keyboards/hhkb/rn42/rn42.h
Normal file
@ -0,0 +1,30 @@
|
||||
#ifndef RN42_H
|
||||
#define RN42_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "host_driver.h"
|
||||
|
||||
host_driver_t rn42_driver;
|
||||
host_driver_t rn42_config_driver;
|
||||
|
||||
void rn42_init(void);
|
||||
int16_t rn42_getc(void);
|
||||
const char *rn42_gets(uint16_t timeout);
|
||||
void rn42_putc(uint8_t c);
|
||||
void rn42_puts(char *s);
|
||||
bool rn42_autoconnecting(void);
|
||||
void rn42_autoconnect(void);
|
||||
void rn42_disconnect(void);
|
||||
bool rn42_rts(void);
|
||||
void rn42_cts_hi(void);
|
||||
void rn42_cts_lo(void);
|
||||
bool rn42_linked(void);
|
||||
void rn42_set_leds(uint8_t l);
|
||||
|
||||
const char *rn42_send_command(const char *cmd);
|
||||
void rn42_send_str(const char *str);
|
||||
void rn42_print_response(void);
|
||||
#define SEND_STR(str) rn42_send_str(PSTR(str))
|
||||
#define SEND_COMMAND(cmd) rn42_send_command(PSTR(cmd))
|
||||
|
||||
#endif
|
467
keyboards/hhkb/rn42/rn42_task.c
Normal file
467
keyboards/hhkb/rn42/rn42_task.c
Normal file
File diff suppressed because it is too large
Load Diff
14
keyboards/hhkb/rn42/rn42_task.h
Normal file
14
keyboards/hhkb/rn42/rn42_task.h
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef RN42_TASK_H
|
||||
#define RN42_TASK_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "rn42.h"
|
||||
|
||||
#ifdef NKRO_ENABLE
|
||||
bool rn42_nkro_last;
|
||||
#endif
|
||||
|
||||
void rn42_task_init(void);
|
||||
void rn42_task(void);
|
||||
|
||||
#endif
|
156
keyboards/hhkb/rn42/suart.S
Normal file
156
keyboards/hhkb/rn42/suart.S
Normal file
@ -0,0 +1,156 @@
|
||||
;---------------------------------------------------------------------------;
|
||||
; Software implemented UART module ;
|
||||
; (C)ChaN, 2005 (http://elm-chan.org/) ;
|
||||
;---------------------------------------------------------------------------;
|
||||
; Bit rate settings:
|
||||
;
|
||||
; 1MHz 2MHz 4MHz 6MHz 8MHz 10MHz 12MHz 16MHz 20MHz
|
||||
; 2.4kbps 138 - - - - - - - -
|
||||
; 4.8kbps 68 138 - - - - - - -
|
||||
; 9.6kbps 33 68 138 208 - - - - -
|
||||
; 19.2kbps - 33 68 102 138 173 208 - -
|
||||
; 38.4kbps - - 33 50 68 85 102 138 172
|
||||
; 57.6kbps - - 21 33 44 56 68 91 114
|
||||
; 115.2kbps - - - - 21 27 33 44 56
|
||||
|
||||
.nolist
|
||||
#include <avr/io.h>
|
||||
.list
|
||||
|
||||
#define BPS 44 /* Bit delay. (see above table) */
|
||||
#define BIDIR 0 /* 0:Separated Tx/Rx, 1:Shared Tx/Rx */
|
||||
|
||||
#define OUT_1 sbi _SFR_IO_ADDR(SUART_OUT_PORT), SUART_OUT_BIT /* Output 1 */
|
||||
#define OUT_0 cbi _SFR_IO_ADDR(SUART_OUT_PORT), SUART_OUT_BIT /* Output 0 */
|
||||
#define SKIP_IN_1 sbis _SFR_IO_ADDR(SUART_IN_PIN), SUART_IN_BIT /* Skip if 1 */
|
||||
#define SKIP_IN_0 sbic _SFR_IO_ADDR(SUART_IN_PIN), SUART_IN_BIT /* Skip if 0 */
|
||||
|
||||
|
||||
|
||||
#ifdef SPM_PAGESIZE
|
||||
.macro _LPMI reg
|
||||
lpm \reg, Z+
|
||||
.endm
|
||||
.macro _MOVW dh,dl, sh,sl
|
||||
movw \dl, \sl
|
||||
.endm
|
||||
#else
|
||||
.macro _LPMI reg
|
||||
lpm
|
||||
mov \reg, r0
|
||||
adiw ZL, 1
|
||||
.endm
|
||||
.macro _MOVW dh,dl, sh,sl
|
||||
mov \dl, \sl
|
||||
mov \dh, \sh
|
||||
.endm
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
;---------------------------------------------------------------------------;
|
||||
; Transmit a byte in serial format of N81
|
||||
;
|
||||
;Prototype: void xmit (uint8_t data);
|
||||
;Size: 16 words
|
||||
|
||||
.global xmit
|
||||
.func xmit
|
||||
xmit:
|
||||
#if BIDIR
|
||||
ldi r23, BPS-1 ;Pre-idle time for bidirectional data line
|
||||
5: dec r23 ;
|
||||
brne 5b ;/
|
||||
#endif
|
||||
in r0, _SFR_IO_ADDR(SREG) ;Save flags
|
||||
|
||||
com r24 ;C = start bit
|
||||
ldi r25, 10 ;Bit counter
|
||||
cli ;Start critical section
|
||||
|
||||
1: ldi r23, BPS-1 ;----- Bit transferring loop
|
||||
2: dec r23 ;Wait for a bit time
|
||||
brne 2b ;/
|
||||
brcs 3f ;MISO = bit to be sent
|
||||
OUT_1 ;
|
||||
3: brcc 4f ;
|
||||
OUT_0 ;/
|
||||
4: lsr r24 ;Get next bit into C
|
||||
dec r25 ;All bits sent?
|
||||
brne 1b ; no, coutinue
|
||||
|
||||
out _SFR_IO_ADDR(SREG), r0 ;End of critical section
|
||||
ret
|
||||
.endfunc
|
||||
|
||||
|
||||
|
||||
;---------------------------------------------------------------------------;
|
||||
; Receive a byte
|
||||
;
|
||||
;Prototype: uint8_t rcvr (void);
|
||||
;Size: 19 words
|
||||
|
||||
.global rcvr
|
||||
.func rcvr
|
||||
rcvr:
|
||||
in r0, _SFR_IO_ADDR(SREG) ;Save flags
|
||||
|
||||
ldi r24, 0x80 ;Receiving shift reg
|
||||
cli ;Start critical section
|
||||
|
||||
1: SKIP_IN_1 ;Wait for idle
|
||||
rjmp 1b
|
||||
2: SKIP_IN_0 ;Wait for start bit
|
||||
rjmp 2b
|
||||
ldi r25, BPS/2 ;Wait for half bit time
|
||||
3: dec r25
|
||||
brne 3b
|
||||
|
||||
4: ldi r25, BPS ;----- Bit receiving loop
|
||||
5: dec r25 ;Wait for a bit time
|
||||
brne 5b ;/
|
||||
lsr r24 ;Next bit
|
||||
SKIP_IN_0 ;Get a data bit into r24.7
|
||||
ori r24, 0x80
|
||||
brcc 4b ;All bits received? no, continue
|
||||
|
||||
out _SFR_IO_ADDR(SREG), r0 ;End of critical section
|
||||
ret
|
||||
.endfunc
|
||||
|
||||
|
||||
; Not wait for start bit. This should be called after detecting start bit.
|
||||
.global recv
|
||||
.func recv
|
||||
recv:
|
||||
in r0, _SFR_IO_ADDR(SREG) ;Save flags
|
||||
|
||||
ldi r24, 0x80 ;Receiving shift reg
|
||||
cli ;Start critical section
|
||||
|
||||
;1: SKIP_IN_1 ;Wait for idle
|
||||
; rjmp 1b
|
||||
;2: SKIP_IN_0 ;Wait for start bit
|
||||
; rjmp 2b
|
||||
ldi r25, BPS/2 ;Wait for half bit time
|
||||
3: dec r25
|
||||
brne 3b
|
||||
|
||||
4: ldi r25, BPS ;----- Bit receiving loop
|
||||
5: dec r25 ;Wait for a bit time
|
||||
brne 5b ;/
|
||||
lsr r24 ;Next bit
|
||||
SKIP_IN_0 ;Get a data bit into r24.7
|
||||
ori r24, 0x80
|
||||
brcc 4b ;All bits received? no, continue
|
||||
|
||||
ldi r25, BPS/2 ;Wait for half bit time
|
||||
6: dec r25
|
||||
brne 6b
|
||||
7: SKIP_IN_1 ;Wait for stop bit
|
||||
rjmp 7b
|
||||
|
||||
out _SFR_IO_ADDR(SREG), r0 ;End of critical section
|
||||
ret
|
||||
.endfunc
|
8
keyboards/hhkb/rn42/suart.h
Normal file
8
keyboards/hhkb/rn42/suart.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef SUART
|
||||
#define SUART
|
||||
|
||||
void xmit(uint8_t);
|
||||
uint8_t rcvr(void);
|
||||
uint8_t recv(void);
|
||||
|
||||
#endif /* SUART */
|
@ -72,6 +72,36 @@ CUSTOM_MATRIX = yes # Custom matrix file for the HHKB
|
||||
# UNICODE_ENABLE = yes # Unicode
|
||||
# BLUETOOTH_ENABLE = yes # Enable Bluetooth with the Adafruit EZ-Key HID
|
||||
|
||||
|
||||
# HHKB_RN42_ENABLE = yes # Enable support for hasu's BT alt controller -- code borrowed from tmk source tree.
|
||||
|
||||
# Either uncomment the HHKB_RN42_ENABLE line above, or run make enabling the
|
||||
# feature. Be sure to clean any existing build before trying to enable rn42
|
||||
# support. For example:
|
||||
#
|
||||
# make hhkb-keymap-clean
|
||||
# make hhkb-keymap-dfu HHKB_RN42_ENABLE=yes
|
||||
|
||||
ifeq ($(strip $(HHKB_RN42_ENABLE)), yes)
|
||||
|
||||
OPT_DEFS += -DHHKB_RN42_ENABLE
|
||||
|
||||
# Support for the RN42 Bluetooth module. This is the BT module in Hasu's BT
|
||||
# HHKB Alt controller.
|
||||
RN42_DIR = rn42
|
||||
|
||||
SRC += serial_uart.c \
|
||||
rn42/suart.S \
|
||||
rn42/rn42.c \
|
||||
rn42/rn42_task.c \
|
||||
rn42/battery.c \
|
||||
rn42/main.c
|
||||
|
||||
VPATH += $(RN42_DIR)
|
||||
|
||||
endif
|
||||
|
||||
|
||||
# debug-on: EXTRAFLAGS += -DDEBUG -DDEBUG_ACTION
|
||||
# debug-on: all
|
||||
|
||||
|
Reference in New Issue
Block a user