Browse Source

[Keyboard] Pearl Refactors (#5907)

* use pragma once

* remove custom matrix

* remove custom i2c code in favor of QMK's i2c_master

* rename to all lower case readme

* update readme

* turn off bootmagic as it doesn't work anyway

* Update keyboards/pearl/readme.md

Co-Authored-By: noroadsleft <18669334+noroadsleft@users.noreply.github.com>
pull/5923/head
MechMerlin 5 years ago
committed by Drashna Jaelre
parent
commit
d67eb20aed
10 changed files with 102 additions and 356 deletions
  1. +0
    -85
      keyboards/pearl/README.md
  2. +2
    -2
      keyboards/pearl/config.h
  3. +0
    -106
      keyboards/pearl/i2c.c
  4. +0
    -27
      keyboards/pearl/i2c.h
  5. +0
    -106
      keyboards/pearl/matrix.c
  6. +49
    -18
      keyboards/pearl/pearl.c
  7. +1
    -5
      keyboards/pearl/pearl.h
  8. +47
    -0
      keyboards/pearl/readme.md
  9. +2
    -3
      keyboards/pearl/rules.mk
  10. +1
    -4
      keyboards/pearl/usbconfig.h

+ 0
- 85
keyboards/pearl/README.md View File

@ -1,85 +0,0 @@
# Pearl 40%
Pearl 40% is a keyboard designed by Koobaczech. It uses an Atmel
ATMEGA32A MCU.
## Compiling and flashing
These instructions are for building and flashing your Pearl 40% without
Bootmapper Client.
### Requirements
#### Windows
(to be written, help needed)
#### Mac
Apart from regular QMK and AVR dependencies you need to install
`bootloadHID`. You can install it with `homebrew` as follows:
$ brew install --HEAD https://raw.githubusercontent.com/robertgzr/homebrew-tap/master/bootloadhid.rb
If you don't use `homebrew` you can try following the compiling
instructions defined below in the Linux section.
#### Linux
For Linux you require all regular QMK dependencies, but make sure you're
using `gcc-avr` version 4.9 or higher. 4.8 and lower do not contain the
proper definitions for ATMEGA32A MCUs and QMK will fail while attempting
to compile a HEX for Pearl 40%.
E.g. you cannot compile Pearl 40% HEX on a regular Ubuntu 14.04 as
`gcc-avr` version is maxed to 4.8 on it.
Additionally you need an operational `bootloadHID` binary.
You can install `bootloadHID` by taking the following steps:
$ git clone https://github.com/robertgzr/bootloadHID ~/tmp/bootloadHIDsrc
$ cd ~/tmp/bootloadHIDsrc/commandline
$ make VENDORID=0x16c0 PRODUCTID=0x05DF # vid and pid for atmega32a
$ chmod +x bootloadHID && cp bootloadHID /usr/bin/bootloadHID
Running `which bootloadHID` should return `/usr/bin/bootloadHID`.
### Compiling
Enter the QMK root directory and compile a keymap with the following
command:
$ make pearl:<keymap>
where `<keymap>` is a layout directory under the `pearl` directory.
QMK should compile a HEX (called `pearl_<keymap>.hex`) for you, which
you can flash using `bootloadHID`.
### Flashing
To enable Pearl 40% bootloading mode, unplug the keyboard, then plug it
in while holding `Esc` at the same time (the top-leftmost switch on the
PCB, next to the USB connector). Once the board is in bootload mode,
issue the following command (you might require `sudo` to perform the
command):
# assuming we're still in the QMK root dir where you compiled a HEX into
$ bootloadHID -r ./pearl_<keymap>.hex
You should see something similar to
> Page size = <value>
> Device size = <value>; <value> remaining
> Uploading <value> bytes starting at 0 (0x0)
> <value> ... <current value>
where `<current value>` should be slowly increasing as the HEX is being
flashed to the board. If there is some warning about `resource busy` it
should still work OK.
Once done the board underglow should turn red and the new firmware has
been flashed. If you can't type on the board try plugging it in again
(without holding any keys to prevent accidentally setting it into
bootload mode again).

+ 2
- 2
keyboards/pearl/config.h View File

@ -35,8 +35,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define MATRIX_ROWS 4
#define MATRIX_COLS 13
#define MATRIX_ROW_PINS { B0, B1, B2, B3, B4, B5, B6, B7 }
#define MATRIX_COL_PINS { A0, A1, A2, A3, A4, A5, A6, A7, C7, C6}
#define MATRIX_ROW_PINS { B0, B1, B2, B3 }
#define MATRIX_COL_PINS { A0, A1, A2, A3, A4, A5, A6, A7, C7, C6, C5, C4, C3}
#define UNUSED_PINS
#define DIODE_DIRECTION COL2ROW


+ 0
- 106
keyboards/pearl/i2c.c View File

@ -1,106 +0,0 @@
/*
Copyright 2016 Luiz Ribeiro <luizribeiro@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// Please do not modify this file
#include <avr/io.h>
#include <util/twi.h>
#include "i2c.h"
void i2c_set_bitrate(uint16_t bitrate_khz) {
uint8_t bitrate_div = ((F_CPU / 1000l) / bitrate_khz);
if (bitrate_div >= 16) {
bitrate_div = (bitrate_div - 16) / 2;
}
TWBR = bitrate_div;
}
void i2c_init(void) {
// set pull-up resistors on I2C bus pins
PORTC |= 0b11;
i2c_set_bitrate(400);
// enable TWI (two-wire interface)
TWCR |= (1 << TWEN);
// enable TWI interrupt and slave address ACK
TWCR |= (1 << TWIE);
TWCR |= (1 << TWEA);
}
uint8_t i2c_start(uint8_t address) {
// reset TWI control register
TWCR = 0;
// begin transmission and wait for it to end
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
while (!(TWCR & (1<<TWINT)));
// check if the start condition was successfully transmitted
if ((TWSR & 0xF8) != TW_START) {
return 1;
}
// transmit address and wait
TWDR = address;
TWCR = (1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT)));
// check if the device has acknowledged the READ / WRITE mode
uint8_t twst = TW_STATUS & 0xF8;
if ((twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK)) {
return 1;
}
return 0;
}
void i2c_stop(void) {
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
}
uint8_t i2c_write(uint8_t data) {
TWDR = data;
// transmit data and wait
TWCR = (1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT)));
if ((TWSR & 0xF8) != TW_MT_DATA_ACK) {
return 1;
}
return 0;
}
uint8_t i2c_send(uint8_t address, uint8_t *data, uint16_t length) {
if (i2c_start(address)) {
return 1;
}
for (uint16_t i = 0; i < length; i++) {
if (i2c_write(data[i])) {
return 1;
}
}
i2c_stop();
return 0;
}

+ 0
- 27
keyboards/pearl/i2c.h View File

@ -1,27 +0,0 @@
/*
Copyright 2016 Luiz Ribeiro <luizribeiro@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// Please do not modify this file
#ifndef __I2C_H__
#define __I2C_H__
void i2c_init(void);
void i2c_set_bitrate(uint16_t bitrate_khz);
uint8_t i2c_send(uint8_t address, uint8_t *data, uint16_t length);
#endif

+ 0
- 106
keyboards/pearl/matrix.c View File

@ -1,106 +0,0 @@
/*
Copyright 2017 Luiz Ribeiro <luizribeiro@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <avr/io.h>
#include <util/delay.h>
#include "matrix.h"
#ifndef DEBOUNCE
#define DEBOUNCE 5
#endif
static uint8_t debouncing = DEBOUNCE;
static matrix_row_t matrix[MATRIX_ROWS];
static matrix_row_t matrix_debouncing[MATRIX_ROWS];
void matrix_init(void) {
// all outputs for rows high
DDRB = 0xFF;
PORTB = 0xFF;
// all inputs for columns
DDRA = 0x00;
DDRC &= ~(0x111111<<2);
DDRD &= ~(1<<PIND7);
// all columns are pulled-up
PORTA = 0xFF;
PORTC |= (0b111111<<2);
PORTD |= (1<<PIND7);
// initialize matrix state: all keys off
for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
matrix[row] = 0x00;
matrix_debouncing[row] = 0x00;
}
}
void matrix_set_row_status(uint8_t row) {
DDRB = (1 << row);
PORTB = ~(1 << row);
}
uint8_t bit_reverse(uint8_t x) {
x = ((x >> 1) & 0x55) | ((x << 1) & 0xaa);
x = ((x >> 2) & 0x33) | ((x << 2) & 0xcc);
x = ((x >> 4) & 0x0f) | ((x << 4) & 0xf0);
return x;
}
uint8_t matrix_scan(void) {
for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
matrix_set_row_status(row);
_delay_us(5);
matrix_row_t cols = (
// cols 0..7, PORTA 0 -> 7
(~PINA) & 0xFF
) | (
// cols 8..13, PORTC 7 -> 0
bit_reverse((~PINC) & 0xFF) << 8
) | (
// col 14, PORTD 7
((~PIND) & (1 << PIND7)) << 7
);
if (matrix_debouncing[row] != cols) {
matrix_debouncing[row] = cols;
debouncing = DEBOUNCE;
}
}
if (debouncing) {
if (--debouncing) {
_delay_ms(1);
} else {
for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
matrix[i] = matrix_debouncing[i];
}
}
}
matrix_scan_user();
return 1;
}
inline matrix_row_t matrix_get_row(uint8_t row) {
return matrix[row];
}
void matrix_print(void) {
}

+ 49
- 18
keyboards/pearl/pearl.c View File

@ -15,16 +15,11 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "pearl.h"
#include "rgblight.h"
#include "backlight.h"
#include <avr/pgmspace.h>
#include "action_layer.h"
#include "i2c.h"
#include "i2c_master.h"
#include "quantum.h"
#ifdef RGBLIGHT_ENABLE
extern rgblight_config_t rgblight_config;
void rgblight_set(void) {
@ -37,23 +32,59 @@ void rgblight_set(void) {
}
i2c_init();
i2c_send(0xb0, (uint8_t*)led, 3 * RGBLED_NUM);
i2c_transmit(0xb0, (uint8_t*)led, 3 * RGBLED_NUM, 100);
}
#endif
void backlight_init_ports(void) {
DDRD |= (1<<4);
PORTD &= ~(1<<4);
void matrix_init_kb(void) {
#ifdef RGBLIGHT_ENABLE
if (rgblight_config.enable) {
i2c_init();
i2c_transmit(0xb0, (uint8_t*)led, 3 * RGBLED_NUM, 100);
}
#endif
// call user level keymaps, if any
matrix_init_user();
}
void backlight_set(uint8_t level) {
if (level > 0) {
PORTD |= (1<<4);
} else {
PORTD &= ~(1<<4);
}
void matrix_scan_kb(void) {
#ifdef RGBLIGHT_ENABLE
rgblight_task();
#endif
matrix_scan_user();
/* Nothing else for now. */
}
__attribute__ ((weak))
void matrix_scan_user(void) {
rgblight_task();
}
void backlight_init_ports(void) {
// initialize pins D0, D1, D4 and D6 as output
setPinOutput(D0);
setPinOutput(D1);
setPinOutput(D4);
setPinOutput(D6);
// turn backlight LEDs on
writePinHigh(D0);
writePinHigh(D1);
writePinHigh(D4);
writePinHigh(D6);
}
void backlight_set(uint8_t level) {
if (level == 0) {
// turn backlight LEDs off
writePinLow(D0);
writePinLow(D1);
writePinLow(D4);
writePinLow(D6);
} else {
// turn backlight LEDs on
writePinHigh(D0);
writePinHigh(D1);
writePinHigh(D4);
writePinHigh(D6);
}
}

+ 1
- 5
keyboards/pearl/pearl.h View File

@ -15,8 +15,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PEARL_H
#define PEARL_H
#pragma once
#include "quantum.h"
#include "pearl.h"
@ -56,6 +55,3 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
{ K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, KC_NO}, \
{ K30, K31, KC_NO, KC_NO, KC_NO, K35, KC_NO, KC_NO, KC_NO, K39, K3A, KC_NO, KC_NO}, \
}
#endif

+ 47
- 0
keyboards/pearl/readme.md View File

@ -0,0 +1,47 @@
# Pearl 40%
Pearl 40% is a keyboard designed by Koobaczech. It uses an Atmel
ATMEGA32A MCU.
Keyboard Maintainer: [Ethan Madden](https://github.com/jetpacktuxedo)
Hardware Supported: Pearl
Hardware Availability: [Geekhack Group Buy](https://geekhack.org/index.php?topic=92259.0)
Make example for this keyboard (after setting up your build environment):
make pearl:default
Flashing
ps2avr(GB) boards use an atmega32a microcontroller and a different bootloader. It is not flashable using the regular QMK methods.
**Reset Key:** Hold down the key located at `K00`.
Windows:
1. Download [HIDBootFlash](http://vusb.wikidot.com/project:hidbootflash).
2. Place your keyboard into reset.
3. Press the `Find Device` button and ensure that your keyboard is found.
4. Press the `Open .hex File` button and locate the `.hex` file you created.
5. Press the `Flash Device` button and wait for the process to complete.
macOS:
1. Install homebrew by typing the following:
```
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
```
2. Install `crosspack-avr`.
```
brew cask install crosspack-avr
```
3. Install the following packages:
```
brew install python3
pip3 install pyusb
brew install --HEAD https://raw.githubusercontent.com/robertgzr/homebrew-tap/master/bootloadhid.rb
```
4. Place your keyboard into reset.
5. Flash the board by typing `bootloadHID -r` followed by the path to your `.hex` file.
**Please Note:** You will need to use the `EEP_RST` keycode first, followed by unplugging/replugging the board to get RGB underglow effects to work.
See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).

+ 2
- 3
keyboards/pearl/rules.mk View File

@ -31,7 +31,7 @@ F_CPU = 12000000
BOOTLOADER = bootloadHID
# build options
BOOTMAGIC_ENABLE = full
BOOTMAGIC_ENABLE = no
MOUSEKEY_ENABLE = no
EXTRAKEY_ENABLE = yes
CONSOLE_ENABLE = yes
@ -43,8 +43,7 @@ RGBLIGHT_CUSTOM_DRIVER = yes
OPT_DEFS = -DDEBUG_LEVEL=0
# custom matrix setup
CUSTOM_MATRIX = yes
SRC = matrix.c i2c.c
SRC = i2c_master.c
# programming options
PROGRAM_CMD = ./util/atmega32a_program.py $(TARGET).hex

+ 1
- 4
keyboards/pearl/usbconfig.h View File

@ -8,8 +8,7 @@
* This Revision: $Id: usbconfig-prototype.h 785 2010-05-30 17:57:07Z cs $
*/
#ifndef __usbconfig_h_included__
#define __usbconfig_h_included__
#pragma once
#include "config.h"
@ -392,5 +391,3 @@ section at the end of this file).
/* #define USB_INTR_PENDING EIFR */
#define USB_INTR_PENDING_BIT INTF1
#define USB_INTR_VECTOR INT1_vect
#endif /* __usbconfig_h_included__ */

Loading…
Cancel
Save