diff options
Diffstat (limited to 'platforms')
102 files changed, 1864 insertions, 1341 deletions
diff --git a/platforms/arm_atsam/bootloader.c b/platforms/arm_atsam/bootloader.c deleted file mode 100644 index 9015b00aab..0000000000 --- a/platforms/arm_atsam/bootloader.c +++ /dev/null @@ -1,57 +0,0 @@ -/* Copyright 2017 Fred Sundvik - * - * 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 "bootloader.h" -#include "samd51j18a.h" -#include "md_bootloader.h" - -// Set watchdog timer to reset. Directs the bootloader to stay in programming mode. -void bootloader_jump(void) { -#ifdef KEYBOARD_massdrop_ctrl - // CTRL keyboards released with bootloader version below must use RAM method. Otherwise use WDT method. - uint8_t ver_ram_method[] = "v2.18Jun 22 2018 17:28:08"; // The version to match (NULL terminated by compiler) - uint8_t *ver_check = ver_ram_method; // Pointer to version match string for traversal - uint8_t *ver_rom = (uint8_t *)0x21A0; // Pointer to address in ROM where this specific bootloader version would exist - - while (*ver_check && *ver_rom == *ver_check) { // While there are check version characters to match and bootloader's version matches check's version - ver_check++; // Move check version pointer to next character - ver_rom++; // Move ROM version pointer to next character - } - - if (!*ver_check) { // If check version pointer is NULL, all characters have matched - *MAGIC_ADDR = BOOTLOADER_MAGIC; // Set magic number into RAM - NVIC_SystemReset(); // Perform system reset - while (1) { - } // Won't get here - } -#endif - - WDT->CTRLA.bit.ENABLE = 0; - while (WDT->SYNCBUSY.bit.ENABLE) { - } - while (WDT->CTRLA.bit.ENABLE) { - } - WDT->CONFIG.bit.WINDOW = 0; - WDT->CONFIG.bit.PER = 0; - WDT->EWCTRL.bit.EWOFFSET = 0; - WDT->CTRLA.bit.ENABLE = 1; - while (WDT->SYNCBUSY.bit.ENABLE) { - } - while (!WDT->CTRLA.bit.ENABLE) { - } - while (1) { - } // Wait on timeout -} diff --git a/platforms/arm_atsam/bootloaders/md_boot.c b/platforms/arm_atsam/bootloaders/md_boot.c new file mode 100644 index 0000000000..32cf850448 --- /dev/null +++ b/platforms/arm_atsam/bootloaders/md_boot.c @@ -0,0 +1,65 @@ +/* Copyright 2017 Fred Sundvik + * + * 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 "bootloader.h" + +#include "samd51j18a.h" + +// WARNING: These are only for CTRL bootloader release "v2.18Jun 22 2018 17:28:08" for bootloader_jump support +extern uint32_t _eram; +#define BOOTLOADER_MAGIC 0x3B9ACA00 +#define MAGIC_ADDR (uint32_t *)((intptr_t)(&_eram) - 4) + +// CTRL keyboards released with bootloader version below must use RAM method. Otherwise use WDT method. +void bootloader_jump(void) { +#ifdef KEYBOARD_massdrop_ctrl + uint8_t ver_ram_method[] = "v2.18Jun 22 2018 17:28:08"; // The version to match (NULL terminated by compiler) + uint8_t *ver_check = ver_ram_method; // Pointer to version match string for traversal + uint8_t *ver_rom = (uint8_t *)0x21A0; // Pointer to address in ROM where this specific bootloader version would exist + + while (*ver_check && *ver_rom == *ver_check) { // While there are check version characters to match and bootloader's version matches check's version + ver_check++; // Move check version pointer to next character + ver_rom++; // Move ROM version pointer to next character + } + + if (!*ver_check) { // If check version pointer is NULL, all characters have matched + *MAGIC_ADDR = BOOTLOADER_MAGIC; // Set magic number into RAM + NVIC_SystemReset(); // Perform system reset + while (1) + ; // Won't get here + } +#endif + + // Set watchdog timer to reset. Directs the bootloader to stay in programming mode. + WDT->CTRLA.bit.ENABLE = 0; + + while (WDT->SYNCBUSY.bit.ENABLE) + ; + while (WDT->CTRLA.bit.ENABLE) + ; + + WDT->CONFIG.bit.WINDOW = 0; + WDT->CONFIG.bit.PER = 0; + WDT->EWCTRL.bit.EWOFFSET = 0; + WDT->CTRLA.bit.ENABLE = 1; + + while (WDT->SYNCBUSY.bit.ENABLE) + ; + while (!WDT->CTRLA.bit.ENABLE) + ; + while (1) + ; // Wait on timeout +} diff --git a/platforms/arm_atsam/eeprom.c b/platforms/arm_atsam/eeprom_samd.c index ff1a692623..1c1e031e5d 100644 --- a/platforms/arm_atsam/eeprom.c +++ b/platforms/arm_atsam/eeprom_samd.c @@ -18,11 +18,7 @@ #include "samd51j18a.h" #include "core_cm4.h" #include "component/nvmctrl.h" - -#ifndef EEPROM_SIZE -# include "eeconfig.h" -# define EEPROM_SIZE (((EECONFIG_SIZE + 3) / 4) * 4) // based off eeconfig's current usage, aligned to 4-byte sizes, to deal with LTO -#endif +#include "eeprom_samd.h" #ifndef MAX # define MAX(X, Y) ((X) > (Y) ? (X) : (Y)) @@ -159,7 +155,9 @@ void eeprom_write_block(const void *buf, void *addr, size_t len) { } } -void eeprom_update_byte(uint8_t *addr, uint8_t value) { eeprom_write_byte(addr, value); } +void eeprom_update_byte(uint8_t *addr, uint8_t value) { + eeprom_write_byte(addr, value); +} void eeprom_update_word(uint16_t *addr, uint16_t value) { uint8_t *p = (uint8_t *)addr; diff --git a/platforms/arm_atsam/eeprom_samd.h b/platforms/arm_atsam/eeprom_samd.h new file mode 100644 index 0000000000..878e72865c --- /dev/null +++ b/platforms/arm_atsam/eeprom_samd.h @@ -0,0 +1,8 @@ +// Copyright 2022 Nick Brassel (@tzarc) +// SPDX-License-Identifier: GPL-2.0-or-later +#pragma once + +#ifndef EEPROM_SIZE +# include "eeconfig.h" +# define EEPROM_SIZE (((EECONFIG_SIZE + 3) / 4) * 4) // based off eeconfig's current usage, aligned to 4-byte sizes, to deal with LTO +#endif diff --git a/platforms/arm_atsam/gpio.h b/platforms/arm_atsam/gpio.h index 915ed0ef4f..a42aaff54d 100644 --- a/platforms/arm_atsam/gpio.h +++ b/platforms/arm_atsam/gpio.h @@ -22,9 +22,9 @@ typedef uint8_t pin_t; -#define SAMD_PORT(pin) ((pin & 0x20) >> 5) -#define SAMD_PIN(pin) (pin & 0x1f) -#define SAMD_PIN_MASK(pin) (1 << (pin & 0x1f)) +#define SAMD_PORT(pin) (((pin)&0x20) >> 5) +#define SAMD_PIN(pin) ((pin)&0x1f) +#define SAMD_PIN_MASK(pin) (1 << ((pin)&0x1f)) #define setPinInput(pin) \ do { \ @@ -48,12 +48,16 @@ typedef uint8_t pin_t; PORT->Group[SAMD_PORT(pin)].PINCFG[SAMD_PIN(pin)].bit.PULLEN = 1; \ } while (0) -#define setPinOutput(pin) \ +#define setPinOutputPushPull(pin) \ do { \ PORT->Group[SAMD_PORT(pin)].DIRSET.reg = SAMD_PIN_MASK(pin); \ PORT->Group[SAMD_PORT(pin)].OUTCLR.reg = SAMD_PIN_MASK(pin); \ } while (0) +#define setPinOutputOpenDrain(pin) _Static_assert(0, "arm_atsam platform does not implement an open-drain output") + +#define setPinOutput(pin) setPinOutputPushPull(pin) + #define writePinHigh(pin) \ do { \ PORT->Group[SAMD_PORT(pin)].OUTSET.reg = SAMD_PIN_MASK(pin); \ diff --git a/platforms/arm_atsam/suspend.c b/platforms/arm_atsam/suspend.c index e51426128d..242e9c91a2 100644 --- a/platforms/arm_atsam/suspend.c +++ b/platforms/arm_atsam/suspend.c @@ -3,61 +3,18 @@ #include "md_rgb_matrix.h" #include "suspend.h" -/** \brief Suspend idle - * - * FIXME: needs doc - */ -void suspend_idle(uint8_t time) { /* Note: Not used anywhere currently */ -} - -/** \brief Run user level Power down - * - * FIXME: needs doc - */ -__attribute__((weak)) void suspend_power_down_user(void) {} - -/** \brief Run keyboard level Power down - * - * FIXME: needs doc - */ -__attribute__((weak)) void suspend_power_down_kb(void) { suspend_power_down_user(); } - /** \brief Suspend power down * * FIXME: needs doc */ void suspend_power_down(void) { #ifdef RGB_MATRIX_ENABLE - I2C3733_Control_Set(0); // Disable LED driver + I2C3733_Control_Set(0); // Disable LED driver #endif suspend_power_down_kb(); } -__attribute__((weak)) void matrix_power_up(void) {} -__attribute__((weak)) void matrix_power_down(void) {} -bool suspend_wakeup_condition(void) { - matrix_power_up(); - matrix_scan(); - matrix_power_down(); - for (uint8_t r = 0; r < MATRIX_ROWS; r++) { - if (matrix_get_row(r)) return true; - } - return false; -} - -/** \brief run user level code immediately after wakeup - * - * FIXME: needs doc - */ -__attribute__((weak)) void suspend_wakeup_init_user(void) {} - -/** \brief run keyboard level code immediately after wakeup - * - * FIXME: needs doc - */ -__attribute__((weak)) void suspend_wakeup_init_kb(void) { suspend_wakeup_init_user(); } - /** \brief run immediately after wakeup * * FIXME: needs doc diff --git a/platforms/arm_atsam/timer.c b/platforms/arm_atsam/timer.c index b835dd5e75..cf01e3625e 100644 --- a/platforms/arm_atsam/timer.c +++ b/platforms/arm_atsam/timer.c @@ -2,18 +2,34 @@ #include "timer.h" #include "tmk_core/protocol/arm_atsam/clks.h" -void set_time(uint64_t tset) { ms_clk = tset; } +void set_time(uint64_t tset) { + ms_clk = tset; +} -void timer_init(void) { timer_clear(); } +void timer_init(void) { + timer_clear(); +} -uint16_t timer_read(void) { return (uint16_t)ms_clk; } +uint16_t timer_read(void) { + return (uint16_t)ms_clk; +} -uint32_t timer_read32(void) { return (uint32_t)ms_clk; } +uint32_t timer_read32(void) { + return (uint32_t)ms_clk; +} -uint64_t timer_read64(void) { return ms_clk; } +uint64_t timer_read64(void) { + return ms_clk; +} -uint16_t timer_elapsed(uint16_t tlast) { return TIMER_DIFF_16(timer_read(), tlast); } +uint16_t timer_elapsed(uint16_t tlast) { + return TIMER_DIFF_16(timer_read(), tlast); +} -uint32_t timer_elapsed32(uint32_t tlast) { return TIMER_DIFF_32(timer_read32(), tlast); } +uint32_t timer_elapsed32(uint32_t tlast) { + return TIMER_DIFF_32(timer_read32(), tlast); +} -void timer_clear(void) { set_time(0); } +void timer_clear(void) { + set_time(0); +} diff --git a/platforms/avr/bootloader.c b/platforms/avr/bootloader.c deleted file mode 100644 index c0272903b8..0000000000 --- a/platforms/avr/bootloader.c +++ /dev/null @@ -1,293 +0,0 @@ -#include <stdint.h> -#include <stdbool.h> -#include <avr/io.h> -#include <avr/eeprom.h> -#include <avr/interrupt.h> -#include <avr/wdt.h> -#include <util/delay.h> -#include "bootloader.h" -#include <avr/boot.h> - -#ifdef PROTOCOL_LUFA -# include <LUFA/Drivers/USB/USB.h> -#endif - -/** \brief Bootloader Size in *bytes* - * - * AVR Boot section size are defined by setting BOOTSZ fuse in fact. Consult with your MCU datasheet. - * Note that 'Word'(2 bytes) size and address are used in datasheet while TMK uses 'Byte'. - * - * Size of Bootloaders in bytes: - * Atmel DFU loader(ATmega32U4) 4096 - * Atmel DFU loader(AT90USB128) 8192 - * LUFA bootloader(ATmega32U4) 4096 - * Arduino Caterina(ATmega32U4) 4096 - * USBaspLoader(ATmega***) 2048 - * Teensy halfKay(ATmega32U4) 512 - * Teensy++ halfKay(AT90USB128) 1024 - * - * AVR Boot section is located at the end of Flash memory like the followings. - * - * byte Atmel/LUFA(ATMega32u4) byte Atmel(AT90SUB128) - * 0x0000 +---------------+ 0x00000 +---------------+ - * | | | | - * | | | | - * | Application | | Application | - * | | | | - * = = = = - * | | 32KB-4KB | | 128KB-8KB - * 0x7000 +---------------+ 0x1E000 +---------------+ - * | Bootloader | 4KB | Bootloader | 8KB - * 0x7FFF +---------------+ 0x1FFFF +---------------+ - * - * - * byte Teensy(ATMega32u4) byte Teensy++(AT90SUB128) - * 0x0000 +---------------+ 0x00000 +---------------+ - * | | | | - * | | | | - * | Application | | Application | - * | | | | - * = = = = - * | | 32KB-512B | | 128KB-1KB - * 0x7E00 +---------------+ 0x1FC00 +---------------+ - * | Bootloader | 512B | Bootloader | 1KB - * 0x7FFF +---------------+ 0x1FFFF +---------------+ - */ -#define FLASH_SIZE (FLASHEND + 1L) - -#if !defined(BOOTLOADER_SIZE) -uint16_t bootloader_start; -#endif - -// compatibility between ATMega8 and ATMega88 -#if !defined(MCUCSR) -# if defined(MCUSR) -# define MCUCSR MCUSR -# endif -#endif - -/** \brief Entering the Bootloader via Software - * - * http://www.fourwalledcubicle.com/files/LUFA/Doc/120730/html/_page__software_bootloader_start.html - */ -#define BOOTLOADER_RESET_KEY 0xB007B007 -uint32_t reset_key __attribute__((section(".noinit,\"aw\",@nobits;"))); - -/** \brief initialize MCU status by watchdog reset - * - * FIXME: needs doc - */ -__attribute__((weak)) void bootloader_jump(void) { -#if !defined(BOOTLOADER_SIZE) - uint8_t high_fuse = boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS); - - if (high_fuse & ~(FUSE_BOOTSZ0 & FUSE_BOOTSZ1)) { - bootloader_start = (FLASH_SIZE - 512) >> 1; - } else if (high_fuse & ~(FUSE_BOOTSZ1)) { - bootloader_start = (FLASH_SIZE - 1024) >> 1; - } else if (high_fuse & ~(FUSE_BOOTSZ0)) { - bootloader_start = (FLASH_SIZE - 2048) >> 1; - } else { - bootloader_start = (FLASH_SIZE - 4096) >> 1; - } -#endif - - // Something like this might work, but it compiled larger than the block above - // bootloader_start = FLASH_SIZE - (256 << (~high_fuse & 0b110 >> 1)); - -#if defined(BOOTLOADER_HALFKAY) - // http://www.pjrc.com/teensy/jump_to_bootloader.html - cli(); - // disable watchdog, if enabled (it's not) - // disable all peripherals - // a shutdown call might make sense here - UDCON = 1; - USBCON = (1 << FRZCLK); // disable USB - UCSR1B = 0; - _delay_ms(5); -# if defined(__AVR_AT90USB162__) // Teensy 1.0 - EIMSK = 0; - PCICR = 0; - SPCR = 0; - ACSR = 0; - EECR = 0; - TIMSK0 = 0; - TIMSK1 = 0; - UCSR1B = 0; - DDRB = 0; - DDRC = 0; - DDRD = 0; - PORTB = 0; - PORTC = 0; - PORTD = 0; - asm volatile("jmp 0x3E00"); -# elif defined(__AVR_ATmega32U4__) // Teensy 2.0 - EIMSK = 0; - PCICR = 0; - SPCR = 0; - ACSR = 0; - EECR = 0; - ADCSRA = 0; - TIMSK0 = 0; - TIMSK1 = 0; - TIMSK3 = 0; - TIMSK4 = 0; - UCSR1B = 0; - TWCR = 0; - DDRB = 0; - DDRC = 0; - DDRD = 0; - DDRE = 0; - DDRF = 0; - TWCR = 0; - PORTB = 0; - PORTC = 0; - PORTD = 0; - PORTE = 0; - PORTF = 0; - asm volatile("jmp 0x7E00"); -# elif defined(__AVR_AT90USB646__) // Teensy++ 1.0 - EIMSK = 0; - PCICR = 0; - SPCR = 0; - ACSR = 0; - EECR = 0; - ADCSRA = 0; - TIMSK0 = 0; - TIMSK1 = 0; - TIMSK2 = 0; - TIMSK3 = 0; - UCSR1B = 0; - TWCR = 0; - DDRA = 0; - DDRB = 0; - DDRC = 0; - DDRD = 0; - DDRE = 0; - DDRF = 0; - PORTA = 0; - PORTB = 0; - PORTC = 0; - PORTD = 0; - PORTE = 0; - PORTF = 0; - asm volatile("jmp 0xFC00"); -# elif defined(__AVR_AT90USB1286__) // Teensy++ 2.0 - EIMSK = 0; - PCICR = 0; - SPCR = 0; - ACSR = 0; - EECR = 0; - ADCSRA = 0; - TIMSK0 = 0; - TIMSK1 = 0; - TIMSK2 = 0; - TIMSK3 = 0; - UCSR1B = 0; - TWCR = 0; - DDRA = 0; - DDRB = 0; - DDRC = 0; - DDRD = 0; - DDRE = 0; - DDRF = 0; - PORTA = 0; - PORTB = 0; - PORTC = 0; - PORTD = 0; - PORTE = 0; - PORTF = 0; - asm volatile("jmp 0x1FC00"); -# endif - -#elif defined(BOOTLOADER_CATERINA) - // this block may be optional - // TODO: figure it out - - uint16_t *const bootKeyPtr = (uint16_t *)0x0800; - - // Value used by Caterina bootloader use to determine whether to run the - // sketch or the bootloader programmer. - uint16_t bootKey = 0x7777; - - *bootKeyPtr = bootKey; - - // setup watchdog timeout - wdt_enable(WDTO_60MS); - - while (1) { - } // wait for watchdog timer to trigger - -#elif defined(BOOTLOADER_USBASP) - // Taken with permission of Stephan Baerwolf from https://github.com/tinyusbboard/API/blob/master/apipage.c - wdt_enable(WDTO_15MS); - wdt_reset(); - asm volatile("cli \n\t" - "ldi r29 , %[ramendhi] \n\t" - "ldi r28 , %[ramendlo] \n\t" -# if (FLASHEND > 131071) - "ldi r18 , %[bootaddrhi] \n\t" - "st Y+, r18 \n\t" -# endif - "ldi r18 , %[bootaddrme] \n\t" - "st Y+, r18 \n\t" - "ldi r18 , %[bootaddrlo] \n\t" - "st Y+, r18 \n\t" - "out %[mcucsrio], __zero_reg__ \n\t" - "bootloader_startup_loop%=: \n\t" - "rjmp bootloader_startup_loop%= \n\t" - : - : [mcucsrio] "I"(_SFR_IO_ADDR(MCUCSR)), -# if (FLASHEND > 131071) - [ramendhi] "M"(((RAMEND - 2) >> 8) & 0xff), [ramendlo] "M"(((RAMEND - 2) >> 0) & 0xff), [bootaddrhi] "M"((((FLASH_SIZE - BOOTLOADER_SIZE) >> 1) >> 16) & 0xff), -# else - [ramendhi] "M"(((RAMEND - 1) >> 8) & 0xff), [ramendlo] "M"(((RAMEND - 1) >> 0) & 0xff), -# endif - [bootaddrme] "M"((((FLASH_SIZE - BOOTLOADER_SIZE) >> 1) >> 8) & 0xff), [bootaddrlo] "M"((((FLASH_SIZE - BOOTLOADER_SIZE) >> 1) >> 0) & 0xff)); - -#else // Assume remaining boards are DFU, even if the flag isn't set - -# if !(defined(__AVR_ATmega32A__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328__) || defined(__AVR_ATtiny85__)) // no USB - maybe BOOTLOADER_BOOTLOADHID instead though? - UDCON = 1; - USBCON = (1 << FRZCLK); // disable USB - UCSR1B = 0; - _delay_ms(5); // 5 seems to work fine -# endif - -# ifdef BOOTLOADER_BOOTLOADHID - // force bootloadHID to stay in bootloader mode, so that it waits - // for a new firmware to be flashed - eeprom_write_byte((uint8_t *)1, 0x00); -# endif - - // watchdog reset - reset_key = BOOTLOADER_RESET_KEY; - wdt_enable(WDTO_250MS); - for (;;) - ; -#endif -} - -/* this runs before main() */ -void bootloader_jump_after_watchdog_reset(void) __attribute__((used, naked, section(".init3"))); -void bootloader_jump_after_watchdog_reset(void) { -#ifndef BOOTLOADER_HALFKAY - if ((MCUCSR & (1 << WDRF)) && reset_key == BOOTLOADER_RESET_KEY) { - reset_key = 0; - - // My custom USBasploader requires this to come up. - MCUCSR = 0; - - // Seems like Teensy halfkay loader requires clearing WDRF and disabling watchdog. - MCUCSR &= ~(1 << WDRF); - wdt_disable(); - -// This is compled into 'icall', address should be in word unit, not byte. -# ifdef BOOTLOADER_SIZE - ((void (*)(void))((FLASH_SIZE - BOOTLOADER_SIZE) >> 1))(); -# else - asm("ijmp" ::"z"(bootloader_start)); -# endif - } -#endif -} diff --git a/platforms/avr/bootloaders/bootloadhid.c b/platforms/avr/bootloaders/bootloadhid.c new file mode 100644 index 0000000000..ae58760d7d --- /dev/null +++ b/platforms/avr/bootloaders/bootloadhid.c @@ -0,0 +1,33 @@ +/* Copyright 2021 QMK + * + * 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 3 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 "bootloader.h" + +#include <avr/eeprom.h> +#include <avr/wdt.h> + +__attribute__((weak)) void bootloader_jump(void) { + // force bootloadHID to stay in bootloader mode, so that it waits + // for a new firmware to be flashed + // NOTE: this byte is part of QMK's "magic number" - changing it causes the EEPROM to be re-initialized + // thus every time the device is flashed the EEPROM will be wiped + eeprom_write_byte((uint8_t *)1, 0x00); + + // watchdog reset + wdt_enable(WDTO_250MS); + for (;;) + ; +} diff --git a/platforms/avr/bootloaders/caterina.c b/platforms/avr/bootloaders/caterina.c new file mode 100644 index 0000000000..82a16a3765 --- /dev/null +++ b/platforms/avr/bootloaders/caterina.c @@ -0,0 +1,39 @@ +/* Copyright 2021 QMK + * + * 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 3 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 "bootloader.h" + +#include <avr/wdt.h> + +__attribute__((weak)) void bootloader_jump(void) { + // this block may be optional + // TODO: figure it out + + uint16_t *const bootKeyPtr = (uint16_t *)0x0800; + + // Value used by Caterina bootloader use to determine whether to run the + // sketch or the bootloader programmer. + uint16_t bootKey = 0x7777; + + *bootKeyPtr = bootKey; + + // setup watchdog timeout + wdt_enable(WDTO_60MS); + + // wait for watchdog timer to trigger + while (1) { + } +} diff --git a/platforms/chibios/boards/GENERIC_STM32_G431XB/configs/config.h b/platforms/avr/bootloaders/custom.c index 39ce627e77..624fbe242a 100644 --- a/platforms/chibios/boards/GENERIC_STM32_G431XB/configs/config.h +++ b/platforms/avr/bootloaders/custom.c @@ -1,8 +1,8 @@ -/* Copyright 2018-2020 Nick Brassel (@tzarc) +/* Copyright 2021 QMK * * 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 + * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, @@ -14,10 +14,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* Address for jumping to bootloader on STM32 chips. */ -/* It is chip dependent, the correct number can be looked up here (page 175): - * http://www.st.com/web/en/resource/technical/document/application_note/CD00167594.pdf - * This also requires a patch to chibios: - * <tmk_dir>/tmk_core/tool/chibios/ch-bootloader-jump.patch - */ -#define STM32_BOOTLOADER_ADDRESS 0x1FFF0000 +#include "bootloader.h" + +__attribute__((weak)) void bootloader_jump(void) {} diff --git a/platforms/avr/bootloaders/dfu.c b/platforms/avr/bootloaders/dfu.c new file mode 100644 index 0000000000..06b2c8963a --- /dev/null +++ b/platforms/avr/bootloaders/dfu.c @@ -0,0 +1,52 @@ +/* Copyright 2021 QMK + * + * 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 3 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 "bootloader.h" + +#include <avr/wdt.h> +#include <util/delay.h> + +#define FLASH_SIZE (FLASHEND + 1L) + +/** \brief Entering the Bootloader via Software + * + * http://www.fourwalledcubicle.com/files/LUFA/Doc/120730/html/_page__software_bootloader_start.html + */ +#define BOOTLOADER_RESET_KEY 0xB007B007 +uint32_t reset_key __attribute__((section(".noinit,\"aw\",@nobits;"))); + +__attribute__((weak)) void bootloader_jump(void) { + UDCON = 1; + USBCON = (1 << FRZCLK); // disable USB + UCSR1B = 0; + _delay_ms(5); // 5 seems to work fine + + // watchdog reset + reset_key = BOOTLOADER_RESET_KEY; + wdt_enable(WDTO_250MS); + for (;;) + ; +} + +/* this runs before main() */ +void bootloader_jump_after_watchdog_reset(void) __attribute__((used, naked, section(".init3"))); +void bootloader_jump_after_watchdog_reset(void) { + if ((MCUSR & (1 << WDRF)) && reset_key == BOOTLOADER_RESET_KEY) { + reset_key = 0; + + ((void (*)(void))((FLASH_SIZE - BOOTLOADER_SIZE) >> 1))(); + } +} diff --git a/platforms/avr/bootloaders/halfkay.c b/platforms/avr/bootloaders/halfkay.c new file mode 100644 index 0000000000..651696f988 --- /dev/null +++ b/platforms/avr/bootloaders/halfkay.c @@ -0,0 +1,128 @@ +/* Copyright 2021 QMK + * + * 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 3 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 "bootloader.h" + +#include <avr/interrupt.h> +#include <util/delay.h> + +__attribute__((weak)) void bootloader_jump(void) { + // http://www.pjrc.com/teensy/jump_to_bootloader.html + + cli(); + // disable watchdog, if enabled (it's not) + // disable all peripherals + // a shutdown call might make sense here + UDCON = 1; + USBCON = (1 << FRZCLK); // disable USB + UCSR1B = 0; + _delay_ms(5); + +#if defined(__AVR_AT90USB162__) // Teensy 1.0 + EIMSK = 0; + PCICR = 0; + SPCR = 0; + ACSR = 0; + EECR = 0; + TIMSK0 = 0; + TIMSK1 = 0; + UCSR1B = 0; + DDRB = 0; + DDRC = 0; + DDRD = 0; + PORTB = 0; + PORTC = 0; + PORTD = 0; + asm volatile("jmp 0x3E00"); +#elif defined(__AVR_ATmega32U4__) // Teensy 2.0 + EIMSK = 0; + PCICR = 0; + SPCR = 0; + ACSR = 0; + EECR = 0; + ADCSRA = 0; + TIMSK0 = 0; + TIMSK1 = 0; + TIMSK3 = 0; + TIMSK4 = 0; + UCSR1B = 0; + TWCR = 0; + DDRB = 0; + DDRC = 0; + DDRD = 0; + DDRE = 0; + DDRF = 0; + TWCR = 0; + PORTB = 0; + PORTC = 0; + PORTD = 0; + PORTE = 0; + PORTF = 0; + asm volatile("jmp 0x7E00"); +#elif defined(__AVR_AT90USB646__) // Teensy++ 1.0 + EIMSK = 0; + PCICR = 0; + SPCR = 0; + ACSR = 0; + EECR = 0; + ADCSRA = 0; + TIMSK0 = 0; + TIMSK1 = 0; + TIMSK2 = 0; + TIMSK3 = 0; + UCSR1B = 0; + TWCR = 0; + DDRA = 0; + DDRB = 0; + DDRC = 0; + DDRD = 0; + DDRE = 0; + DDRF = 0; + PORTA = 0; + PORTB = 0; + PORTC = 0; + PORTD = 0; + PORTE = 0; + PORTF = 0; + asm volatile("jmp 0xFC00"); +#elif defined(__AVR_AT90USB1286__) // Teensy++ 2.0 + EIMSK = 0; + PCICR = 0; + SPCR = 0; + ACSR = 0; + EECR = 0; + ADCSRA = 0; + TIMSK0 = 0; + TIMSK1 = 0; + TIMSK2 = 0; + TIMSK3 = 0; + UCSR1B = 0; + TWCR = 0; + DDRA = 0; + DDRB = 0; + DDRC = 0; + DDRD = 0; + DDRE = 0; + DDRF = 0; + PORTA = 0; + PORTB = 0; + PORTC = 0; + PORTD = 0; + PORTE = 0; + PORTF = 0; + asm volatile("jmp 0x1FC00"); +#endif +} diff --git a/platforms/avr/bootloaders/usbasploader.c b/platforms/avr/bootloaders/usbasploader.c new file mode 100644 index 0000000000..008bd16069 --- /dev/null +++ b/platforms/avr/bootloaders/usbasploader.c @@ -0,0 +1,56 @@ +/* Copyright 2021 QMK + * + * 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 3 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 "bootloader.h" + +#include <avr/wdt.h> + +#define FLASH_SIZE (FLASHEND + 1L) + +#if !defined(MCUCSR) +# if defined(MCUSR) +# define MCUCSR MCUSR +# endif +#endif + +__attribute__((weak)) void bootloader_jump(void) { + // Taken with permission of Stephan Baerwolf from https://github.com/tinyusbboard/API/blob/master/apipage.c + + wdt_enable(WDTO_15MS); + wdt_reset(); + asm volatile("cli \n\t" + "ldi r29 , %[ramendhi] \n\t" + "ldi r28 , %[ramendlo] \n\t" +#if (FLASHEND > 131071) + "ldi r18 , %[bootaddrhi] \n\t" + "st Y+, r18 \n\t" +#endif + "ldi r18 , %[bootaddrme] \n\t" + "st Y+, r18 \n\t" + "ldi r18 , %[bootaddrlo] \n\t" + "st Y+, r18 \n\t" + "out %[mcucsrio], __zero_reg__ \n\t" + "bootloader_startup_loop%=: \n\t" + "rjmp bootloader_startup_loop%= \n\t" + : + : [mcucsrio] "I"(_SFR_IO_ADDR(MCUCSR)), +#if (FLASHEND > 131071) + [ramendhi] "M"(((RAMEND - 2) >> 8) & 0xff), [ramendlo] "M"(((RAMEND - 2) >> 0) & 0xff), [bootaddrhi] "M"((((FLASH_SIZE - BOOTLOADER_SIZE) >> 1) >> 16) & 0xff), +#else + [ramendhi] "M"(((RAMEND - 1) >> 8) & 0xff), [ramendlo] "M"(((RAMEND - 1) >> 0) & 0xff), +#endif + [bootaddrme] "M"((((FLASH_SIZE - BOOTLOADER_SIZE) >> 1) >> 8) & 0xff), [bootaddrlo] "M"((((FLASH_SIZE - BOOTLOADER_SIZE) >> 1) >> 0) & 0xff)); +} diff --git a/platforms/avr/drivers/analog.c b/platforms/avr/drivers/analog.c index 628835ccef..ed4d563609 100644 --- a/platforms/avr/drivers/analog.c +++ b/platforms/avr/drivers/analog.c @@ -21,9 +21,13 @@ static uint8_t aref = ADC_REF_POWER; -void analogReference(uint8_t mode) { aref = mode & (_BV(REFS1) | _BV(REFS0)); } +void analogReference(uint8_t mode) { + aref = mode & (_BV(REFS1) | _BV(REFS0)); +} -int16_t analogReadPin(pin_t pin) { return adc_read(pinToMux(pin)); } +int16_t analogReadPin(pin_t pin) { + return adc_read(pinToMux(pin)); +} uint8_t pinToMux(pin_t pin) { switch (pin) { diff --git a/platforms/avr/drivers/analog.h b/platforms/avr/drivers/analog.h index fa2fb0d89b..fb13e106ff 100644 --- a/platforms/avr/drivers/analog.h +++ b/platforms/avr/drivers/analog.h @@ -32,21 +32,21 @@ int16_t adc_read(uint8_t mux); } #endif -#define ADC_REF_EXTERNAL 0 // AREF, Internal Vref turned off -#define ADC_REF_POWER _BV(REFS0) // AVCC with external capacitor on AREF pin -#define ADC_REF_INTERNAL (_BV(REFS1) | _BV(REFS0)) // Internal 2.56V Voltage Reference with external capacitor on AREF pin (1.1V for 328P) +#define ADC_REF_EXTERNAL 0 // AREF, Internal Vref turned off +#define ADC_REF_POWER _BV(REFS0) // AVCC with external capacitor on AREF pin +#define ADC_REF_INTERNAL (_BV(REFS1) | _BV(REFS0)) // Internal 2.56V Voltage Reference with external capacitor on AREF pin (1.1V for 328P) // These prescaler values are for high speed mode, ADHSM = 1 #if F_CPU == 16000000L || F_CPU == 12000000L -# define ADC_PRESCALER (_BV(ADPS2) | _BV(ADPS1)) // /64 +# define ADC_PRESCALER (_BV(ADPS2) | _BV(ADPS1)) // /64 #elif F_CPU == 8000000L -# define ADC_PRESCALER (_BV(ADPS2) | _BV(ADPS0)) // /32 +# define ADC_PRESCALER (_BV(ADPS2) | _BV(ADPS0)) // /32 #elif F_CPU == 4000000L -# define ADC_PRESCALER (_BV(ADPS2)) // /16 +# define ADC_PRESCALER (_BV(ADPS2)) // /16 #elif F_CPU == 2000000L -# define ADC_PRESCALER (_BV(ADPS1) | _BV(ADPS0)) // /8 +# define ADC_PRESCALER (_BV(ADPS1) | _BV(ADPS0)) // /8 #elif F_CPU == 1000000L -# define ADC_PRESCALER _BV(ADPS1) // /4 +# define ADC_PRESCALER _BV(ADPS1) // /4 #else -# define ADC_PRESCALER _BV(ADPS0) // /2 +# define ADC_PRESCALER _BV(ADPS0) // /2 #endif diff --git a/platforms/avr/drivers/audio_pwm_hardware.c b/platforms/avr/drivers/audio_pwm_hardware.c index df03a4558c..78776ee48a 100644 --- a/platforms/avr/drivers/audio_pwm_hardware.c +++ b/platforms/avr/drivers/audio_pwm_hardware.c @@ -152,7 +152,7 @@ extern uint8_t note_timbre; #ifdef AUDIO1_PIN_SET static float channel_1_frequency = 0.0f; void channel_1_set_frequency(float freq) { - if (freq == 0.0f) // a pause/rest is a valid "note" with freq=0 + if (freq == 0.0f) // a pause/rest is a valid "note" with freq=0 { // disable the output, but keep the pwm-ISR going (with the previous // frequency) so the audio-state keeps getting updated @@ -160,7 +160,7 @@ void channel_1_set_frequency(float freq) { AUDIO1_TCCRxA &= ~(_BV(AUDIO1_COMxy1) | _BV(AUDIO1_COMxy0)); return; } else { - AUDIO1_TCCRxA |= _BV(AUDIO1_COMxy1); // enable output, PWM mode + AUDIO1_TCCRxA |= _BV(AUDIO1_COMxy1); // enable output, PWM mode } channel_1_frequency = freq; @@ -202,7 +202,9 @@ void channel_2_set_frequency(float freq) { AUDIO2_OCRxy = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre / 100); } -float channel_2_get_frequency(void) { return channel_2_frequency; } +float channel_2_get_frequency(void) { + return channel_2_frequency; +} void channel_2_start(void) { AUDIO2_TIMSKx |= _BV(AUDIO2_OCIExy); diff --git a/platforms/avr/drivers/glcdfont.c b/platforms/avr/drivers/glcdfont.c index 5e763b054f..57a21965de 100644 --- a/platforms/avr/drivers/glcdfont.c +++ b/platforms/avr/drivers/glcdfont.c @@ -10,14 +10,14 @@ static const unsigned char font[] PROGMEM = { 0x30, 0x38, 0x3E, 0x38, 0x30, 0x06, 0x0E, 0x3E, 0x0E, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x00, 0x07, 0x00, 0x07, 0x00, 0x14, 0x7F, 0x14, 0x7F, 0x14, 0x24, 0x2A, 0x7F, 0x2A, 0x12, 0x23, 0x13, 0x08, 0x64, 0x62, 0x36, 0x49, 0x56, 0x20, 0x50, 0x00, 0x08, 0x07, 0x03, 0x00, 0x00, 0x1C, 0x22, 0x41, 0x00, 0x00, 0x41, 0x22, 0x1C, 0x00, 0x2A, 0x1C, 0x7F, 0x1C, 0x2A, 0x08, 0x08, 0x3E, 0x08, 0x08, 0x00, 0x80, 0x70, 0x30, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x60, 0x60, 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, 0x3E, 0x51, 0x49, 0x45, 0x3E, 0x00, 0x42, 0x7F, 0x40, 0x00, 0x72, 0x49, 0x49, 0x49, 0x46, 0x21, 0x41, 0x49, 0x4D, 0x33, 0x18, 0x14, 0x12, 0x7F, 0x10, 0x27, 0x45, 0x45, 0x45, 0x39, 0x3C, 0x4A, 0x49, 0x49, 0x31, 0x41, 0x21, 0x11, 0x09, 0x07, 0x36, 0x49, 0x49, 0x49, 0x36, 0x46, 0x49, 0x49, 0x29, 0x1E, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x40, 0x34, 0x00, 0x00, 0x00, 0x08, 0x14, 0x22, 0x41, 0x14, 0x14, 0x14, 0x14, 0x14, 0x00, 0x41, 0x22, 0x14, 0x08, 0x02, 0x01, 0x59, 0x09, 0x06, 0x3E, 0x41, 0x5D, 0x59, 0x4E, 0x7C, 0x12, 0x11, 0x12, 0x7C, 0x7F, 0x49, 0x49, 0x49, 0x36, 0x3E, 0x41, 0x41, 0x41, 0x22, 0x7F, 0x41, 0x41, 0x41, 0x3E, 0x7F, 0x49, 0x49, 0x49, 0x41, 0x7F, 0x09, 0x09, 0x09, 0x01, 0x3E, 0x41, 0x41, 0x51, 0x73, 0x7F, 0x08, 0x08, 0x08, 0x7F, 0x00, 0x41, 0x7F, 0x41, 0x00, 0x20, 0x40, 0x41, 0x3F, 0x01, 0x7F, 0x08, 0x14, 0x22, 0x41, 0x7F, 0x40, 0x40, 0x40, 0x40, 0x7F, 0x02, 0x1C, 0x02, 0x7F, 0x7F, 0x04, 0x08, 0x10, 0x7F, 0x3E, 0x41, 0x41, 0x41, 0x3E, 0x7F, 0x09, 0x09, 0x09, 0x06, 0x3E, 0x41, 0x51, 0x21, 0x5E, 0x7F, 0x09, 0x19, 0x29, 0x46, 0x26, 0x49, 0x49, 0x49, 0x32, 0x03, 0x01, 0x7F, 0x01, 0x03, 0x3F, 0x40, 0x40, 0x40, 0x3F, 0x1F, 0x20, 0x40, 0x20, 0x1F, 0x3F, 0x40, 0x38, 0x40, 0x3F, 0x63, 0x14, 0x08, 0x14, 0x63, 0x03, 0x04, 0x78, 0x04, 0x03, 0x61, 0x59, 0x49, 0x4D, 0x43, 0x00, 0x7F, 0x41, 0x41, 0x41, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, 0x41, 0x41, 0x41, 0x7F, 0x04, 0x02, 0x01, 0x02, 0x04, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x03, 0x07, 0x08, 0x00, 0x20, 0x54, 0x54, 0x78, 0x40, 0x7F, 0x28, 0x44, 0x44, 0x38, 0x38, 0x44, 0x44, 0x44, 0x28, 0x38, 0x44, 0x44, 0x28, 0x7F, 0x38, 0x54, 0x54, 0x54, 0x18, 0x00, 0x08, 0x7E, 0x09, 0x02, 0x18, 0xA4, 0xA4, 0x9C, 0x78, 0x7F, 0x08, 0x04, 0x04, 0x78, 0x00, 0x44, 0x7D, 0x40, 0x00, 0x20, 0x40, 0x40, 0x3D, 0x00, 0x7F, 0x10, 0x28, 0x44, 0x00, 0x00, 0x41, 0x7F, 0x40, 0x00, 0x7C, 0x04, 0x78, 0x04, 0x78, 0x7C, 0x08, 0x04, 0x04, 0x78, 0x38, 0x44, 0x44, 0x44, 0x38, 0xFC, 0x18, 0x24, 0x24, 0x18, 0x18, 0x24, 0x24, 0x18, 0xFC, 0x7C, 0x08, 0x04, 0x04, 0x08, 0x48, 0x54, 0x54, 0x54, 0x24, 0x04, 0x04, 0x3F, 0x44, 0x24, 0x3C, 0x40, 0x40, 0x20, 0x7C, 0x1C, 0x20, 0x40, 0x20, 0x1C, 0x3C, 0x40, 0x30, 0x40, 0x3C, - 0x44, 0x28, 0x10, 0x28, 0x44, 0x4C, 0x90, 0x90, 0x90, 0x7C, 0x44, 0x64, 0x54, 0x4C, 0x44, 0x00, 0x08, 0x36, 0x41, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x41, 0x36, 0x08, 0x00, 0x02, 0x01, 0x02, 0x04, 0x02, 0x3C, 0x26, 0x23, 0x26, 0x3C, 0x1E, 0xA1, 0xA1, 0x61, 0x12, 0x3A, 0x40, 0x40, 0x20, 0x7A, 0x38, 0x54, 0x54, 0x55, 0x59, 0x21, 0x55, 0x55, 0x79, 0x41, 0x22, 0x54, 0x54, 0x78, 0x42, // a-umlaut - 0x21, 0x55, 0x54, 0x78, 0x40, 0x20, 0x54, 0x55, 0x79, 0x40, 0x0C, 0x1E, 0x52, 0x72, 0x12, 0x39, 0x55, 0x55, 0x55, 0x59, 0x39, 0x54, 0x54, 0x54, 0x59, 0x39, 0x55, 0x54, 0x54, 0x58, 0x00, 0x00, 0x45, 0x7C, 0x41, 0x00, 0x02, 0x45, 0x7D, 0x42, 0x00, 0x01, 0x45, 0x7C, 0x40, 0x7D, 0x12, 0x11, 0x12, 0x7D, // A-umlaut - 0xF0, 0x28, 0x25, 0x28, 0xF0, 0x7C, 0x54, 0x55, 0x45, 0x00, 0x20, 0x54, 0x54, 0x7C, 0x54, 0x7C, 0x0A, 0x09, 0x7F, 0x49, 0x32, 0x49, 0x49, 0x49, 0x32, 0x3A, 0x44, 0x44, 0x44, 0x3A, // o-umlaut - 0x32, 0x4A, 0x48, 0x48, 0x30, 0x3A, 0x41, 0x41, 0x21, 0x7A, 0x3A, 0x42, 0x40, 0x20, 0x78, 0x00, 0x9D, 0xA0, 0xA0, 0x7D, 0x3D, 0x42, 0x42, 0x42, 0x3D, // O-umlaut - 0x3D, 0x40, 0x40, 0x40, 0x3D, 0x3C, 0x24, 0xFF, 0x24, 0x24, 0x48, 0x7E, 0x49, 0x43, 0x66, 0x2B, 0x2F, 0xFC, 0x2F, 0x2B, 0xFF, 0x09, 0x29, 0xF6, 0x20, 0xC0, 0x88, 0x7E, 0x09, 0x03, 0x20, 0x54, 0x54, 0x79, 0x41, 0x00, 0x00, 0x44, 0x7D, 0x41, 0x30, 0x48, 0x48, 0x4A, 0x32, 0x38, 0x40, 0x40, 0x22, 0x7A, 0x00, 0x7A, 0x0A, 0x0A, 0x72, 0x7D, 0x0D, 0x19, 0x31, 0x7D, 0x26, 0x29, 0x29, 0x2F, 0x28, 0x26, 0x29, 0x29, 0x29, 0x26, 0x30, 0x48, 0x4D, 0x40, 0x20, 0x38, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x38, 0x2F, 0x10, 0xC8, 0xAC, 0xBA, 0x2F, 0x10, 0x28, 0x34, 0xFA, 0x00, 0x00, 0x7B, 0x00, 0x00, 0x08, 0x14, 0x2A, 0x14, 0x22, 0x22, 0x14, 0x2A, 0x14, 0x08, 0x55, 0x00, 0x55, 0x00, 0x55, // #176 (25% block) missing in old code - 0xAA, 0x55, 0xAA, 0x55, 0xAA, // 50% block - 0xFF, 0x55, 0xFF, 0x55, 0xFF, // 75% block + 0x44, 0x28, 0x10, 0x28, 0x44, 0x4C, 0x90, 0x90, 0x90, 0x7C, 0x44, 0x64, 0x54, 0x4C, 0x44, 0x00, 0x08, 0x36, 0x41, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x41, 0x36, 0x08, 0x00, 0x02, 0x01, 0x02, 0x04, 0x02, 0x3C, 0x26, 0x23, 0x26, 0x3C, 0x1E, 0xA1, 0xA1, 0x61, 0x12, 0x3A, 0x40, 0x40, 0x20, 0x7A, 0x38, 0x54, 0x54, 0x55, 0x59, 0x21, 0x55, 0x55, 0x79, 0x41, 0x22, 0x54, 0x54, 0x78, 0x42, // a-umlaut + 0x21, 0x55, 0x54, 0x78, 0x40, 0x20, 0x54, 0x55, 0x79, 0x40, 0x0C, 0x1E, 0x52, 0x72, 0x12, 0x39, 0x55, 0x55, 0x55, 0x59, 0x39, 0x54, 0x54, 0x54, 0x59, 0x39, 0x55, 0x54, 0x54, 0x58, 0x00, 0x00, 0x45, 0x7C, 0x41, 0x00, 0x02, 0x45, 0x7D, 0x42, 0x00, 0x01, 0x45, 0x7C, 0x40, 0x7D, 0x12, 0x11, 0x12, 0x7D, // A-umlaut + 0xF0, 0x28, 0x25, 0x28, 0xF0, 0x7C, 0x54, 0x55, 0x45, 0x00, 0x20, 0x54, 0x54, 0x7C, 0x54, 0x7C, 0x0A, 0x09, 0x7F, 0x49, 0x32, 0x49, 0x49, 0x49, 0x32, 0x3A, 0x44, 0x44, 0x44, 0x3A, // o-umlaut + 0x32, 0x4A, 0x48, 0x48, 0x30, 0x3A, 0x41, 0x41, 0x21, 0x7A, 0x3A, 0x42, 0x40, 0x20, 0x78, 0x00, 0x9D, 0xA0, 0xA0, 0x7D, 0x3D, 0x42, 0x42, 0x42, 0x3D, // O-umlaut + 0x3D, 0x40, 0x40, 0x40, 0x3D, 0x3C, 0x24, 0xFF, 0x24, 0x24, 0x48, 0x7E, 0x49, 0x43, 0x66, 0x2B, 0x2F, 0xFC, 0x2F, 0x2B, 0xFF, 0x09, 0x29, 0xF6, 0x20, 0xC0, 0x88, 0x7E, 0x09, 0x03, 0x20, 0x54, 0x54, 0x79, 0x41, 0x00, 0x00, 0x44, 0x7D, 0x41, 0x30, 0x48, 0x48, 0x4A, 0x32, 0x38, 0x40, 0x40, 0x22, 0x7A, 0x00, 0x7A, 0x0A, 0x0A, 0x72, 0x7D, 0x0D, 0x19, 0x31, 0x7D, 0x26, 0x29, 0x29, 0x2F, 0x28, 0x26, 0x29, 0x29, 0x29, 0x26, 0x30, 0x48, 0x4D, 0x40, 0x20, 0x38, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x38, 0x2F, 0x10, 0xC8, 0xAC, 0xBA, 0x2F, 0x10, 0x28, 0x34, 0xFA, 0x00, 0x00, 0x7B, 0x00, 0x00, 0x08, 0x14, 0x2A, 0x14, 0x22, 0x22, 0x14, 0x2A, 0x14, 0x08, 0x55, 0x00, 0x55, 0x00, 0x55, // #176 (25% block) missing in old code + 0xAA, 0x55, 0xAA, 0x55, 0xAA, // 50% block + 0xFF, 0x55, 0xFF, 0x55, 0xFF, // 75% block 0x00, 0x00, 0x00, 0xFF, 0x00, 0x10, 0x10, 0x10, 0xFF, 0x00, 0x14, 0x14, 0x14, 0xFF, 0x00, 0x10, 0x10, 0xFF, 0x00, 0xFF, 0x10, 0x10, 0xF0, 0x10, 0xF0, 0x14, 0x14, 0x14, 0xFC, 0x00, 0x14, 0x14, 0xF7, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x14, 0x14, 0xF4, 0x04, 0xFC, 0x14, 0x14, 0x17, 0x10, 0x1F, 0x10, 0x10, 0x1F, 0x10, 0x1F, 0x14, 0x14, 0x14, 0x1F, 0x00, 0x10, 0x10, 0x10, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x10, 0x10, 0x10, 0x10, 0x1F, 0x10, 0x10, 0x10, 0x10, 0xF0, 0x10, 0x00, 0x00, 0x00, 0xFF, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xFF, 0x10, 0x00, 0x00, 0x00, 0xFF, 0x14, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x1F, 0x10, 0x17, 0x00, 0x00, 0xFC, 0x04, 0xF4, 0x14, 0x14, 0x17, 0x10, 0x17, 0x14, 0x14, 0xF4, 0x04, 0xF4, 0x00, 0x00, 0xFF, 0x00, 0xF7, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0xF7, 0x00, 0xF7, 0x14, 0x14, 0x14, 0x17, 0x14, 0x10, 0x10, 0x1F, 0x10, 0x1F, - 0x14, 0x14, 0x14, 0xF4, 0x14, 0x10, 0x10, 0xF0, 0x10, 0xF0, 0x00, 0x00, 0x1F, 0x10, 0x1F, 0x00, 0x00, 0x00, 0x1F, 0x14, 0x00, 0x00, 0x00, 0xFC, 0x14, 0x00, 0x00, 0xF0, 0x10, 0xF0, 0x10, 0x10, 0xFF, 0x10, 0xFF, 0x14, 0x14, 0x14, 0xFF, 0x14, 0x10, 0x10, 0x10, 0x1F, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x38, 0x44, 0x44, 0x38, 0x44, 0xFC, 0x4A, 0x4A, 0x4A, 0x34, // sharp-s or beta - 0x7E, 0x02, 0x02, 0x06, 0x06, 0x02, 0x7E, 0x02, 0x7E, 0x02, 0x63, 0x55, 0x49, 0x41, 0x63, 0x38, 0x44, 0x44, 0x3C, 0x04, 0x40, 0x7E, 0x20, 0x1E, 0x20, 0x06, 0x02, 0x7E, 0x02, 0x02, 0x99, 0xA5, 0xE7, 0xA5, 0x99, 0x1C, 0x2A, 0x49, 0x2A, 0x1C, 0x4C, 0x72, 0x01, 0x72, 0x4C, 0x30, 0x4A, 0x4D, 0x4D, 0x30, 0x30, 0x48, 0x78, 0x48, 0x30, 0xBC, 0x62, 0x5A, 0x46, 0x3D, 0x3E, 0x49, 0x49, 0x49, 0x00, 0x7E, 0x01, 0x01, 0x01, 0x7E, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x44, 0x44, 0x5F, 0x44, 0x44, 0x40, 0x51, 0x4A, 0x44, 0x40, 0x40, 0x44, 0x4A, 0x51, 0x40, 0x00, 0x00, 0xFF, 0x01, 0x03, 0xE0, 0x80, 0xFF, 0x00, 0x00, 0x08, 0x08, 0x6B, 0x6B, 0x08, 0x36, 0x12, 0x36, 0x24, 0x36, 0x06, 0x0F, 0x09, 0x0F, 0x06, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x30, 0x40, 0xFF, 0x01, 0x01, 0x00, 0x1F, 0x01, 0x01, 0x1E, 0x00, 0x19, 0x1D, 0x17, 0x12, 0x00, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00 // #255 NBSP + 0x14, 0x14, 0x14, 0xF4, 0x14, 0x10, 0x10, 0xF0, 0x10, 0xF0, 0x00, 0x00, 0x1F, 0x10, 0x1F, 0x00, 0x00, 0x00, 0x1F, 0x14, 0x00, 0x00, 0x00, 0xFC, 0x14, 0x00, 0x00, 0xF0, 0x10, 0xF0, 0x10, 0x10, 0xFF, 0x10, 0xFF, 0x14, 0x14, 0x14, 0xFF, 0x14, 0x10, 0x10, 0x10, 0x1F, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x38, 0x44, 0x44, 0x38, 0x44, 0xFC, 0x4A, 0x4A, 0x4A, 0x34, // sharp-s or beta + 0x7E, 0x02, 0x02, 0x06, 0x06, 0x02, 0x7E, 0x02, 0x7E, 0x02, 0x63, 0x55, 0x49, 0x41, 0x63, 0x38, 0x44, 0x44, 0x3C, 0x04, 0x40, 0x7E, 0x20, 0x1E, 0x20, 0x06, 0x02, 0x7E, 0x02, 0x02, 0x99, 0xA5, 0xE7, 0xA5, 0x99, 0x1C, 0x2A, 0x49, 0x2A, 0x1C, 0x4C, 0x72, 0x01, 0x72, 0x4C, 0x30, 0x4A, 0x4D, 0x4D, 0x30, 0x30, 0x48, 0x78, 0x48, 0x30, 0xBC, 0x62, 0x5A, 0x46, 0x3D, 0x3E, 0x49, 0x49, 0x49, 0x00, 0x7E, 0x01, 0x01, 0x01, 0x7E, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x44, 0x44, 0x5F, 0x44, 0x44, 0x40, 0x51, 0x4A, 0x44, 0x40, 0x40, 0x44, 0x4A, 0x51, 0x40, 0x00, 0x00, 0xFF, 0x01, 0x03, 0xE0, 0x80, 0xFF, 0x00, 0x00, 0x08, 0x08, 0x6B, 0x6B, 0x08, 0x36, 0x12, 0x36, 0x24, 0x36, 0x06, 0x0F, 0x09, 0x0F, 0x06, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x30, 0x40, 0xFF, 0x01, 0x01, 0x00, 0x1F, 0x01, 0x01, 0x1E, 0x00, 0x19, 0x1D, 0x17, 0x12, 0x00, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00 // #255 NBSP }; diff --git a/platforms/avr/drivers/hd44780.c b/platforms/avr/drivers/hd44780.c index f71069dece..f15d7d0da8 100644 --- a/platforms/avr/drivers/hd44780.c +++ b/platforms/avr/drivers/hd44780.c @@ -262,7 +262,7 @@ static uint8_t lcd_waitbusy(void) delay(LCD_DELAY_BUSY_FLAG); /* now read the address counter */ - return (lcd_read(0)); // return address counter + return (lcd_read(0)); // return address counter } /* lcd_waitbusy */ @@ -362,17 +362,23 @@ void lcd_gotoxy(uint8_t x, uint8_t y) { /************************************************************************* *************************************************************************/ -int lcd_getxy(void) { return lcd_waitbusy(); } +int lcd_getxy(void) { + return lcd_waitbusy(); +} /************************************************************************* Clear display and set cursor to home position *************************************************************************/ -void lcd_clrscr(void) { lcd_command(1 << LCD_CLR); } +void lcd_clrscr(void) { + lcd_command(1 << LCD_CLR); +} /************************************************************************* Set cursor to home position *************************************************************************/ -void lcd_home(void) { lcd_command(1 << LCD_HOME); } +void lcd_home(void) { + lcd_command(1 << LCD_HOME); +} /************************************************************************* Display character at current cursor position @@ -382,7 +388,7 @@ Returns: none void lcd_putc(char c) { uint8_t pos; - pos = lcd_waitbusy(); // read busy-flag and address counter + pos = lcd_waitbusy(); // read busy-flag and address counter if (c == '\n') { lcd_newline(pos); } else { @@ -483,8 +489,8 @@ void lcd_init(uint8_t dispAttr) { delay(LCD_DELAY_BOOTUP); /* wait 16ms or more after power-on */ /* initial write to lcd is 8bit */ - LCD_DATA1_PORT |= _BV(LCD_DATA1_PIN); // LCD_FUNCTION>>4; - LCD_DATA0_PORT |= _BV(LCD_DATA0_PIN); // LCD_FUNCTION_8BIT>>4; + LCD_DATA1_PORT |= _BV(LCD_DATA1_PIN); // LCD_FUNCTION>>4; + LCD_DATA0_PORT |= _BV(LCD_DATA0_PIN); // LCD_FUNCTION_8BIT>>4; lcd_e_toggle(); delay(LCD_DELAY_INIT); /* delay, busy flag can't be checked here */ @@ -497,7 +503,7 @@ void lcd_init(uint8_t dispAttr) { delay(LCD_DELAY_INIT_REP); /* delay, busy flag can't be checked here */ /* now configure for 4bit mode */ - LCD_DATA0_PORT &= ~_BV(LCD_DATA0_PIN); // LCD_FUNCTION_4BIT_1LINE>>4 + LCD_DATA0_PORT &= ~_BV(LCD_DATA0_PIN); // LCD_FUNCTION_4BIT_1LINE>>4 lcd_e_toggle(); delay(LCD_DELAY_INIT_4BIT); /* some displays need this additional delay */ diff --git a/platforms/avr/drivers/i2c_master.c b/platforms/avr/drivers/i2c_master.c index 111b55d6b0..c1a7b5f72d 100644 --- a/platforms/avr/drivers/i2c_master.c +++ b/platforms/avr/drivers/i2c_master.c @@ -25,12 +25,15 @@ #include "wait.h" #ifndef F_SCL -# define F_SCL 400000UL // SCL frequency +# define F_SCL 400000UL // SCL frequency #endif #ifndef I2C_START_RETRY_COUNT # define I2C_START_RETRY_COUNT 20 -#endif // I2C_START_RETRY_COUNT +#endif // I2C_START_RETRY_COUNT + +#define I2C_ACTION_READ 0x01 +#define I2C_ACTION_WRITE 0x00 #define TWBR_val (((F_CPU / F_SCL) - 16) / 2) @@ -95,7 +98,7 @@ static i2c_status_t i2c_start_impl(uint8_t address, uint16_t timeout) { i2c_status_t i2c_start(uint8_t address, uint16_t timeout) { // Retry i2c_start_impl a bunch times in case the remote side has interrupts disabled. uint16_t timeout_timer = timer_read(); - uint16_t time_slice = MAX(1, (timeout == (I2C_TIMEOUT_INFINITE)) ? 5 : (timeout / (I2C_START_RETRY_COUNT))); // if it's infinite, wait 1ms between attempts, otherwise split up the entire timeout into the number of retries + uint16_t time_slice = MAX(1, (timeout == (I2C_TIMEOUT_INFINITE)) ? 5 : (timeout / (I2C_START_RETRY_COUNT))); // if it's infinite, wait 1ms between attempts, otherwise split up the entire timeout into the number of retries i2c_status_t status; do { status = i2c_start_impl(address, time_slice); @@ -154,7 +157,7 @@ int16_t i2c_read_nack(uint16_t timeout) { } i2c_status_t i2c_transmit(uint8_t address, const uint8_t* data, uint16_t length, uint16_t timeout) { - i2c_status_t status = i2c_start(address | I2C_WRITE, timeout); + i2c_status_t status = i2c_start(address | I2C_ACTION_WRITE, timeout); for (uint16_t i = 0; i < length && status >= 0; i++) { status = i2c_write(data[i], timeout); @@ -166,7 +169,7 @@ i2c_status_t i2c_transmit(uint8_t address, const uint8_t* data, uint16_t length, } i2c_status_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout) { - i2c_status_t status = i2c_start(address | I2C_READ, timeout); + i2c_status_t status = i2c_start(address | I2C_ACTION_READ, timeout); for (uint16_t i = 0; i < (length - 1) && status >= 0; i++) { status = i2c_read_ack(timeout); diff --git a/platforms/avr/drivers/i2c_slave.c b/platforms/avr/drivers/i2c_slave.c index 2907f164c0..660d271be2 100644 --- a/platforms/avr/drivers/i2c_slave.c +++ b/platforms/avr/drivers/i2c_slave.c @@ -29,7 +29,7 @@ # include "transactions.h" static volatile bool is_callback_executor = false; -#endif // defined(USE_I2C) && defined(SPLIT_COMMON_TRANSACTIONS) +#endif // defined(USE_I2C) && defined(SPLIT_COMMON_TRANSACTIONS) volatile uint8_t i2c_slave_reg[I2C_SLAVE_REG_COUNT]; @@ -57,7 +57,7 @@ ISR(TWI_vect) { slave_has_register_set = false; #if defined(USE_I2C) && defined(SPLIT_COMMON_TRANSACTIONS) is_callback_executor = false; -#endif // defined(USE_I2C) && defined(SPLIT_COMMON_TRANSACTIONS) +#endif // defined(USE_I2C) && defined(SPLIT_COMMON_TRANSACTIONS) break; case TW_SR_DATA_ACK: @@ -66,16 +66,16 @@ ISR(TWI_vect) { if (!slave_has_register_set) { buffer_address = TWDR; - if (buffer_address >= I2C_SLAVE_REG_COUNT) { // address out of bounds dont ack + if (buffer_address >= I2C_SLAVE_REG_COUNT) { // address out of bounds dont ack ack = 0; buffer_address = 0; } - slave_has_register_set = true; // address has been received now fill in buffer + slave_has_register_set = true; // address has been received now fill in buffer #if defined(USE_I2C) && defined(SPLIT_COMMON_TRANSACTIONS) // Work out if we're attempting to execute a callback is_callback_executor = buffer_address == split_transaction_table[I2C_EXECUTE_CALLBACK].initiator2target_offset; -#endif // defined(USE_I2C) && defined(SPLIT_COMMON_TRANSACTIONS) +#endif // defined(USE_I2C) && defined(SPLIT_COMMON_TRANSACTIONS) } else { i2c_slave_reg[buffer_address] = TWDR; buffer_address++; @@ -88,7 +88,7 @@ ISR(TWI_vect) { trans->slave_callback(trans->initiator2target_buffer_size, split_trans_initiator2target_buffer(trans), trans->target2initiator_buffer_size, split_trans_target2initiator_buffer(trans)); } } -#endif // defined(USE_I2C) && defined(SPLIT_COMMON_TRANSACTIONS) +#endif // defined(USE_I2C) && defined(SPLIT_COMMON_TRANSACTIONS) } break; diff --git a/platforms/avr/drivers/i2c_slave.h b/platforms/avr/drivers/i2c_slave.h index a8647c9da3..178b6a29df 100644 --- a/platforms/avr/drivers/i2c_slave.h +++ b/platforms/avr/drivers/i2c_slave.h @@ -27,11 +27,11 @@ # if defined(USE_I2C) && defined(SPLIT_COMMON_TRANSACTIONS) # include "transport.h" # define I2C_SLAVE_REG_COUNT sizeof(split_shared_memory_t) -# else // defined(USE_I2C) && defined(SPLIT_COMMON_TRANSACTIONS) +# else // defined(USE_I2C) && defined(SPLIT_COMMON_TRANSACTIONS) # define I2C_SLAVE_REG_COUNT 30 -# endif // defined(USE_I2C) && defined(SPLIT_COMMON_TRANSACTIONS) +# endif // defined(USE_I2C) && defined(SPLIT_COMMON_TRANSACTIONS) -#endif // I2C_SLAVE_REG_COUNT +#endif // I2C_SLAVE_REG_COUNT _Static_assert(I2C_SLAVE_REG_COUNT < 256, "I2C target registers must be single byte"); diff --git a/platforms/avr/drivers/ps2/ps2_io.c b/platforms/avr/drivers/ps2/ps2_io.c index 7c826fbf1a..b75a1ab0be 100644 --- a/platforms/avr/drivers/ps2/ps2_io.c +++ b/platforms/avr/drivers/ps2/ps2_io.c @@ -23,7 +23,9 @@ void clock_lo(void) { setPinOutput(PS2_CLOCK_PIN); } -void clock_hi(void) { setPinInputHigh(PS2_CLOCK_PIN); } +void clock_hi(void) { + setPinInputHigh(PS2_CLOCK_PIN); +} bool clock_in(void) { setPinInputHigh(PS2_CLOCK_PIN); @@ -42,7 +44,9 @@ void data_lo(void) { setPinOutput(PS2_DATA_PIN); } -void data_hi(void) { setPinInputHigh(PS2_DATA_PIN); } +void data_hi(void) { + setPinInputHigh(PS2_DATA_PIN); +} bool data_in(void) { setPinInputHigh(PS2_DATA_PIN); diff --git a/platforms/avr/drivers/ps2/ps2_usart.c b/platforms/avr/drivers/ps2/ps2_usart.c index 151cfcd68f..39ec930d4a 100644 --- a/platforms/avr/drivers/ps2/ps2_usart.c +++ b/platforms/avr/drivers/ps2/ps2_usart.c @@ -76,7 +76,7 @@ static inline bool pbuf_has_data(void); static inline void pbuf_clear(void); void ps2_host_init(void) { - idle(); // without this many USART errors occur when cable is disconnected + idle(); // without this many USART errors occur when cable is disconnected PS2_USART_INIT(); PS2_USART_RX_INT_ON(); // POR(150-2000ms) plus BAT(300-500ms) may take 2.5sec([3]p.20) @@ -91,12 +91,12 @@ uint8_t ps2_host_send(uint8_t data) { /* terminate a transmission if we have */ inhibit(); - _delay_us(100); // [4]p.13 + _delay_us(100); // [4]p.13 /* 'Request to Send' and Start bit */ data_lo(); clock_hi(); - WAIT(clock_lo, 10000, 10); // 10ms [5]p.50 + WAIT(clock_lo, 10000, 10); // 10ms [5]p.50 /* Data bit[2-9] */ for (uint8_t i = 0; i < 8; i++) { @@ -165,7 +165,7 @@ uint8_t ps2_host_recv(void) { ISR(PS2_USART_RX_VECT) { // TODO: request RESEND when error occurs? - uint8_t error = PS2_USART_ERROR; // USART error should be read before data + uint8_t error = PS2_USART_ERROR; // USART error should be read before data uint8_t data = PS2_USART_RX_DATA; if (!error) { pbuf_enqueue(data); diff --git a/platforms/avr/drivers/serial.c b/platforms/avr/drivers/serial.c index 9a7345a53d..6a36aa5f7f 100644 --- a/platforms/avr/drivers/serial.c +++ b/platforms/avr/drivers/serial.c @@ -16,6 +16,7 @@ #include <util/delay.h> #include <stddef.h> #include <stdbool.h> +#include "gpio.h" #include "serial.h" #ifdef SOFT_SERIAL_PIN @@ -119,12 +120,6 @@ # error invalid SOFT_SERIAL_PIN value # endif -# define setPinInputHigh(pin) (DDRx_ADDRESS(pin) &= ~_BV((pin)&0xF), PORTx_ADDRESS(pin) |= _BV((pin)&0xF)) -# define setPinOutput(pin) (DDRx_ADDRESS(pin) |= _BV((pin)&0xF)) -# define writePinHigh(pin) (PORTx_ADDRESS(pin) |= _BV((pin)&0xF)) -# define writePinLow(pin) (PORTx_ADDRESS(pin) &= ~_BV((pin)&0xF)) -# define readPin(pin) ((bool)(PINx_ADDRESS(pin) & _BV((pin)&0xF))) - # define ALWAYS_INLINE __attribute__((always_inline)) # define NO_INLINE __attribute__((noinline)) # define _delay_sub_us(x) __builtin_avr_delay_cycles(x) @@ -161,59 +156,59 @@ # if SELECT_SOFT_SERIAL_SPEED == 0 // Very High speed -# define SERIAL_DELAY 4 // micro sec +# define SERIAL_DELAY 4 // micro sec # if __GNUC__ < 6 -# define READ_WRITE_START_ADJUST 33 // cycles -# define READ_WRITE_WIDTH_ADJUST 3 // cycles +# define READ_WRITE_START_ADJUST 33 // cycles +# define READ_WRITE_WIDTH_ADJUST 3 // cycles # else -# define READ_WRITE_START_ADJUST 34 // cycles -# define READ_WRITE_WIDTH_ADJUST 7 // cycles +# define READ_WRITE_START_ADJUST 34 // cycles +# define READ_WRITE_WIDTH_ADJUST 7 // cycles # endif # elif SELECT_SOFT_SERIAL_SPEED == 1 // High speed -# define SERIAL_DELAY 6 // micro sec +# define SERIAL_DELAY 6 // micro sec # if __GNUC__ < 6 -# define READ_WRITE_START_ADJUST 30 // cycles -# define READ_WRITE_WIDTH_ADJUST 3 // cycles +# define READ_WRITE_START_ADJUST 30 // cycles +# define READ_WRITE_WIDTH_ADJUST 3 // cycles # else -# define READ_WRITE_START_ADJUST 33 // cycles -# define READ_WRITE_WIDTH_ADJUST 7 // cycles +# define READ_WRITE_START_ADJUST 33 // cycles +# define READ_WRITE_WIDTH_ADJUST 7 // cycles # endif # elif SELECT_SOFT_SERIAL_SPEED == 2 // Middle speed -# define SERIAL_DELAY 12 // micro sec -# define READ_WRITE_START_ADJUST 30 // cycles +# define SERIAL_DELAY 12 // micro sec +# define READ_WRITE_START_ADJUST 30 // cycles # if __GNUC__ < 6 -# define READ_WRITE_WIDTH_ADJUST 3 // cycles +# define READ_WRITE_WIDTH_ADJUST 3 // cycles # else -# define READ_WRITE_WIDTH_ADJUST 7 // cycles +# define READ_WRITE_WIDTH_ADJUST 7 // cycles # endif # elif SELECT_SOFT_SERIAL_SPEED == 3 // Low speed -# define SERIAL_DELAY 24 // micro sec -# define READ_WRITE_START_ADJUST 30 // cycles +# define SERIAL_DELAY 24 // micro sec +# define READ_WRITE_START_ADJUST 30 // cycles # if __GNUC__ < 6 -# define READ_WRITE_WIDTH_ADJUST 3 // cycles +# define READ_WRITE_WIDTH_ADJUST 3 // cycles # else -# define READ_WRITE_WIDTH_ADJUST 7 // cycles +# define READ_WRITE_WIDTH_ADJUST 7 // cycles # endif # elif SELECT_SOFT_SERIAL_SPEED == 4 // Very Low speed -# define SERIAL_DELAY 36 // micro sec -# define READ_WRITE_START_ADJUST 30 // cycles +# define SERIAL_DELAY 36 // micro sec +# define READ_WRITE_START_ADJUST 30 // cycles # if __GNUC__ < 6 -# define READ_WRITE_WIDTH_ADJUST 3 // cycles +# define READ_WRITE_WIDTH_ADJUST 3 // cycles # else -# define READ_WRITE_WIDTH_ADJUST 7 // cycles +# define READ_WRITE_WIDTH_ADJUST 7 // cycles # endif # elif SELECT_SOFT_SERIAL_SPEED == 5 // Ultra Low speed -# define SERIAL_DELAY 48 // micro sec -# define READ_WRITE_START_ADJUST 30 // cycles +# define SERIAL_DELAY 48 // micro sec +# define READ_WRITE_START_ADJUST 30 // cycles # if __GNUC__ < 6 -# define READ_WRITE_WIDTH_ADJUST 3 // cycles +# define READ_WRITE_WIDTH_ADJUST 3 // cycles # else -# define READ_WRITE_WIDTH_ADJUST 7 // cycles +# define READ_WRITE_WIDTH_ADJUST 7 // cycles # endif # else # error invalid SELECT_SOFT_SERIAL_SPEED value @@ -228,29 +223,45 @@ # define SLAVE_INT_ACK_WIDTH 4 inline static void serial_delay(void) ALWAYS_INLINE; -inline static void serial_delay(void) { _delay_us(SERIAL_DELAY); } +inline static void serial_delay(void) { + _delay_us(SERIAL_DELAY); +} inline static void serial_delay_half1(void) ALWAYS_INLINE; -inline static void serial_delay_half1(void) { _delay_us(SERIAL_DELAY_HALF1); } +inline static void serial_delay_half1(void) { + _delay_us(SERIAL_DELAY_HALF1); +} inline static void serial_delay_half2(void) ALWAYS_INLINE; -inline static void serial_delay_half2(void) { _delay_us(SERIAL_DELAY_HALF2); } +inline static void serial_delay_half2(void) { + _delay_us(SERIAL_DELAY_HALF2); +} inline static void serial_output(void) ALWAYS_INLINE; -inline static void serial_output(void) { setPinOutput(SOFT_SERIAL_PIN); } +inline static void serial_output(void) { + setPinOutput(SOFT_SERIAL_PIN); +} // make the serial pin an input with pull-up resistor inline static void serial_input_with_pullup(void) ALWAYS_INLINE; -inline static void serial_input_with_pullup(void) { setPinInputHigh(SOFT_SERIAL_PIN); } +inline static void serial_input_with_pullup(void) { + setPinInputHigh(SOFT_SERIAL_PIN); +} inline static uint8_t serial_read_pin(void) ALWAYS_INLINE; -inline static uint8_t serial_read_pin(void) { return !!readPin(SOFT_SERIAL_PIN); } +inline static uint8_t serial_read_pin(void) { + return !!readPin(SOFT_SERIAL_PIN); +} inline static void serial_low(void) ALWAYS_INLINE; -inline static void serial_low(void) { writePinLow(SOFT_SERIAL_PIN); } +inline static void serial_low(void) { + writePinLow(SOFT_SERIAL_PIN); +} inline static void serial_high(void) ALWAYS_INLINE; -inline static void serial_high(void) { writePinHigh(SOFT_SERIAL_PIN); } +inline static void serial_high(void) { + writePinHigh(SOFT_SERIAL_PIN); +} void soft_serial_initiator_init(void) { serial_output(); @@ -291,7 +302,7 @@ static uint8_t serial_read_chunk(uint8_t *pterrcount, uint8_t bit) { _delay_sub_us(READ_WRITE_START_ADJUST); for (i = 0, byte = 0, p = PARITY; i < bit; i++) { - serial_delay_half1(); // read the middle of pulses + serial_delay_half1(); // read the middle of pulses if (serial_read_pin()) { byte = (byte << 1) | 1; p ^= 1; @@ -303,7 +314,7 @@ static uint8_t serial_read_chunk(uint8_t *pterrcount, uint8_t bit) { serial_delay_half2(); } /* recive parity bit */ - serial_delay_half1(); // read the middle of pulses + serial_delay_half1(); // read the middle of pulses pb = serial_read_pin(); _delay_sub_us(READ_WRITE_WIDTH_ADJUST); serial_delay_half2(); @@ -335,7 +346,7 @@ void serial_write_chunk(uint8_t data, uint8_t bit) { } serial_delay(); - serial_low(); // sync_send() / senc_recv() need raise edge + serial_low(); // sync_send() / senc_recv() need raise edge } static void serial_send_packet(uint8_t *buffer, uint8_t size) NO_INLINE; @@ -361,19 +372,19 @@ static uint8_t serial_recive_packet(uint8_t *buffer, uint8_t size) { } inline static void change_sender2reciver(void) { - sync_send(); // 0 - serial_delay_half1(); // 1 - serial_low(); // 2 - serial_input_with_pullup(); // 2 - serial_delay_half1(); // 3 + sync_send(); // 0 + serial_delay_half1(); // 1 + serial_low(); // 2 + serial_input_with_pullup(); // 2 + serial_delay_half1(); // 3 } inline static void change_reciver2sender(void) { - sync_recv(); // 0 - serial_delay(); // 1 - serial_low(); // 3 - serial_output(); // 3 - serial_delay_half1(); // 4 + sync_recv(); // 0 + serial_delay(); // 1 + serial_low(); // 3 + serial_output(); // 3 + serial_delay_half1(); // 4 } static inline uint8_t nibble_bits_count(uint8_t bits) { @@ -396,11 +407,11 @@ ISR(SERIAL_PIN_INTERRUPT) { } serial_delay_half1(); - serial_high(); // response step1 low->high + serial_high(); // response step1 low->high serial_output(); _delay_sub_us(SLAVE_INT_ACK_WIDTH_UNIT * SLAVE_INT_ACK_WIDTH); split_transaction_desc_t *trans = &split_transaction_table[tid]; - serial_low(); // response step2 ack high->low + serial_low(); // response step2 ack high->low // If the transaction has a callback, we can execute it now if (trans->slave_callback) { @@ -414,34 +425,22 @@ ISR(SERIAL_PIN_INTERRUPT) { // target recive phase if (trans->initiator2target_buffer_size > 0) { - if (serial_recive_packet((uint8_t *)split_trans_initiator2target_buffer(trans), trans->initiator2target_buffer_size)) { - *trans->status = TRANSACTION_ACCEPTED; - } else { - *trans->status = TRANSACTION_DATA_ERROR; - } - } else { - *trans->status = TRANSACTION_ACCEPTED; + serial_recive_packet((uint8_t *)split_trans_initiator2target_buffer(trans), trans->initiator2target_buffer_size); } - sync_recv(); // weit initiator output to high + sync_recv(); // weit initiator output to high } ///////// // start transaction by initiator // -// int soft_serial_transaction(int sstd_index) +// bool soft_serial_transaction(int sstd_index) // -// Returns: -// TRANSACTION_END -// TRANSACTION_NO_RESPONSE -// TRANSACTION_DATA_ERROR // this code is very time dependent, so we need to disable interrupts -int soft_serial_transaction(int sstd_index) { - if (sstd_index > NUM_TOTAL_TRANSACTIONS) return TRANSACTION_TYPE_ERROR; +bool soft_serial_transaction(int sstd_index) { + if (sstd_index > NUM_TOTAL_TRANSACTIONS) return false; split_transaction_desc_t *trans = &split_transaction_table[sstd_index]; - if (!trans->status) return TRANSACTION_TYPE_ERROR; // not registered - cli(); // signal to the target that we want to start a transaction @@ -468,9 +467,8 @@ int soft_serial_transaction(int sstd_index) { // slave failed to pull the line low, assume not present serial_output(); serial_high(); - *trans->status = TRANSACTION_NO_RESPONSE; sei(); - return TRANSACTION_NO_RESPONSE; + return false; } _delay_sub_us(SLAVE_INT_ACK_WIDTH_UNIT); } @@ -481,9 +479,8 @@ int soft_serial_transaction(int sstd_index) { if (!serial_recive_packet((uint8_t *)split_trans_target2initiator_buffer(trans), trans->target2initiator_buffer_size)) { serial_output(); serial_high(); - *trans->status = TRANSACTION_DATA_ERROR; sei(); - return TRANSACTION_DATA_ERROR; + return false; } } @@ -498,19 +495,8 @@ int soft_serial_transaction(int sstd_index) { // always, release the line when not in use sync_send(); - *trans->status = TRANSACTION_END; - sei(); - return TRANSACTION_END; -} - -int soft_serial_get_and_clean_status(int sstd_index) { - split_transaction_desc_t *trans = &split_transaction_table[sstd_index]; - cli(); - int retval = *trans->status; - *trans->status = 0; - ; sei(); - return retval; + return true; } #endif diff --git a/platforms/avr/drivers/spi_master.c b/platforms/avr/drivers/spi_master.c index 4e8fd3bcdf..ae9df03c02 100644 --- a/platforms/avr/drivers/spi_master.c +++ b/platforms/avr/drivers/spi_master.c @@ -125,7 +125,7 @@ spi_status_t spi_write(uint8_t data) { } spi_status_t spi_read() { - SPDR = 0x00; // Dummy + SPDR = 0x00; // Dummy uint16_t timeout_timer = timer_read(); while (!(SPSR & _BV(SPIF))) { diff --git a/platforms/avr/drivers/ssd1306.c b/platforms/avr/drivers/ssd1306.c index 1a09a2bcb7..7afbc09f00 100644 --- a/platforms/avr/drivers/ssd1306.c +++ b/platforms/avr/drivers/ssd1306.c @@ -161,7 +161,7 @@ bool iota_gfx_init(void) { send_cmd1(DeActivateScroll); send_cmd1(DisplayOn); - send_cmd2(SetContrast, 0); // Dim + send_cmd2(SetContrast, 0); // Dim clear_display(); @@ -226,7 +226,9 @@ void matrix_write_char(struct CharacterMatrix *matrix, uint8_t c) { matrix_write_char_inner(matrix, c); } -void iota_gfx_write_char(uint8_t c) { matrix_write_char(&display, c); } +void iota_gfx_write_char(uint8_t c) { + matrix_write_char(&display, c); +} void matrix_write(struct CharacterMatrix *matrix, const char *data) { const char *end = data + strlen(data); @@ -236,7 +238,9 @@ void matrix_write(struct CharacterMatrix *matrix, const char *data) { } } -void iota_gfx_write(const char *data) { matrix_write(&display, data); } +void iota_gfx_write(const char *data) { + matrix_write(&display, data); +} void matrix_write_P(struct CharacterMatrix *matrix, const char *data) { while (true) { @@ -249,7 +253,9 @@ void matrix_write_P(struct CharacterMatrix *matrix, const char *data) { } } -void iota_gfx_write_P(const char *data) { matrix_write_P(&display, data); } +void iota_gfx_write_P(const char *data) { + matrix_write_P(&display, data); +} void matrix_clear(struct CharacterMatrix *matrix) { memset(matrix->display, ' ', sizeof(matrix->display)); @@ -257,7 +263,9 @@ void matrix_clear(struct CharacterMatrix *matrix) { matrix->dirty = true; } -void iota_gfx_clear_screen(void) { matrix_clear(&display); } +void iota_gfx_clear_screen(void) { + matrix_clear(&display); +} void matrix_render(struct CharacterMatrix *matrix) { last_flush = timer_read(); @@ -301,7 +309,9 @@ done: # endif } -void iota_gfx_flush(void) { matrix_render(&display); } +void iota_gfx_flush(void) { + matrix_render(&display); +} __attribute__((weak)) void iota_gfx_task_user(void) {} diff --git a/platforms/avr/drivers/uart.c b/platforms/avr/drivers/uart.c index 01cf6b1fb8..fd5caf9a78 100644 --- a/platforms/avr/drivers/uart.c +++ b/platforms/avr/drivers/uart.c @@ -108,7 +108,7 @@ void uart_write(uint8_t data) { // return immediately to avoid deadlock when interrupt is disabled(called from ISR) if (tx_buffer_tail == i && (SREG & (1 << SREG_I)) == 0) return; while (tx_buffer_tail == i) - ; // wait until space in buffer + ; // wait until space in buffer // cli(); tx_buffer[i] = data; tx_buffer_head = i; @@ -121,7 +121,7 @@ uint8_t uart_read(void) { uint8_t data, i; while (rx_buffer_head == rx_buffer_tail) - ; // wait for character + ; // wait for character i = rx_buffer_tail + 1; if (i >= RX_BUFFER_SIZE) i = 0; data = rx_buffer[i]; diff --git a/platforms/avr/drivers/ws2812.c b/platforms/avr/drivers/ws2812.c index 9150b3c520..c461ab3ba7 100644 --- a/platforms/avr/drivers/ws2812.c +++ b/platforms/avr/drivers/ws2812.c @@ -110,7 +110,7 @@ static inline void ws2812_sendarray_mask(uint8_t *data, uint16_t datlen, uint8_t asm volatile(" ldi %0,8 \n\t" "loop%=: \n\t" - " out %2,%3 \n\t" // '1' [01] '0' [01] - re + " out %2,%3 \n\t" // '1' [01] '0' [01] - re #if (w1_nops & 1) w_nop1 #endif @@ -126,9 +126,9 @@ static inline void ws2812_sendarray_mask(uint8_t *data, uint16_t datlen, uint8_t #if (w1_nops & 16) w_nop16 #endif - " sbrs %1,7 \n\t" // '1' [03] '0' [02] - " out %2,%4 \n\t" // '1' [--] '0' [03] - fe-low - " lsl %1 \n\t" // '1' [04] '0' [04] + " sbrs %1,7 \n\t" // '1' [03] '0' [02] + " out %2,%4 \n\t" // '1' [--] '0' [03] - fe-low + " lsl %1 \n\t" // '1' [04] '0' [04] #if (w2_nops & 1) w_nop1 #endif @@ -144,7 +144,7 @@ static inline void ws2812_sendarray_mask(uint8_t *data, uint16_t datlen, uint8_t #if (w2_nops & 16) w_nop16 #endif - " out %2,%4 \n\t" // '1' [+1] '0' [+1] - fe-high + " out %2,%4 \n\t" // '1' [+1] '0' [+1] - fe-high #if (w3_nops & 1) w_nop1 #endif @@ -161,8 +161,8 @@ static inline void ws2812_sendarray_mask(uint8_t *data, uint16_t datlen, uint8_t w_nop16 #endif - " dec %0 \n\t" // '1' [+2] '0' [+2] - " brne loop%=\n\t" // '1' [+3] '0' [+4] + " dec %0 \n\t" // '1' [+2] '0' [+2] + " brne loop%=\n\t" // '1' [+3] '0' [+4] : "=&d"(ctr) : "r"(curbyte), "I"(_SFR_IO_ADDR(PORTx_ADDRESS(RGB_DI_PIN))), "r"(maskhi), "r"(masklo)); } diff --git a/platforms/avr/drivers/ws2812_i2c.c b/platforms/avr/drivers/ws2812_i2c.c index 1c332e24b6..709f382254 100644 --- a/platforms/avr/drivers/ws2812_i2c.c +++ b/platforms/avr/drivers/ws2812_i2c.c @@ -13,7 +13,9 @@ # define WS2812_TIMEOUT 100 #endif -void ws2812_init(void) { i2c_init(); } +void ws2812_init(void) { + i2c_init(); +} // Setleds for standard RGB void ws2812_setleds(LED_TYPE *ledarray, uint16_t leds) { diff --git a/platforms/avr/gpio.h b/platforms/avr/gpio.h index e9be68491d..95f15c28dc 100644 --- a/platforms/avr/gpio.h +++ b/platforms/avr/gpio.h @@ -25,7 +25,9 @@ typedef uint8_t pin_t; #define setPinInput(pin) (DDRx_ADDRESS(pin) &= ~_BV((pin)&0xF), PORTx_ADDRESS(pin) &= ~_BV((pin)&0xF)) #define setPinInputHigh(pin) (DDRx_ADDRESS(pin) &= ~_BV((pin)&0xF), PORTx_ADDRESS(pin) |= _BV((pin)&0xF)) #define setPinInputLow(pin) _Static_assert(0, "AVR processors cannot implement an input as pull low") -#define setPinOutput(pin) (DDRx_ADDRESS(pin) |= _BV((pin)&0xF)) +#define setPinOutputPushPull(pin) (DDRx_ADDRESS(pin) |= _BV((pin)&0xF)) +#define setPinOutputOpenDrain(pin) _Static_assert(0, "AVR platform does not implement an open-drain output") +#define setPinOutput(pin) setPinOutputPushPull(pin) #define writePinHigh(pin) (PORTx_ADDRESS(pin) |= _BV((pin)&0xF)) #define writePinLow(pin) (PORTx_ADDRESS(pin) &= ~_BV((pin)&0xF)) @@ -34,16 +36,3 @@ typedef uint8_t pin_t; #define readPin(pin) ((bool)(PINx_ADDRESS(pin) & _BV((pin)&0xF))) #define togglePin(pin) (PORTx_ADDRESS(pin) ^= _BV((pin)&0xF)) - -/* Operation of GPIO by port. */ - -typedef uint8_t port_data_t; - -#define readPort(port) PINx_ADDRESS(port) - -#define setPortBitInput(port, bit) (DDRx_ADDRESS(port) &= ~_BV((bit)&0xF), PORTx_ADDRESS(port) &= ~_BV((bit)&0xF)) -#define setPortBitInputHigh(port, bit) (DDRx_ADDRESS(port) &= ~_BV((bit)&0xF), PORTx_ADDRESS(port) |= _BV((bit)&0xF)) -#define setPortBitOutput(port, bit) (DDRx_ADDRESS(port) |= _BV((bit)&0xF)) - -#define writePortBitLow(port, bit) (PORTx_ADDRESS(port) &= ~_BV((bit)&0xF)) -#define writePortBitHigh(port, bit) (PORTx_ADDRESS(port) |= _BV((bit)&0xF)) diff --git a/platforms/avr/pin_defs.h b/platforms/avr/pin_defs.h index 23d948041d..3889704a87 100644 --- a/platforms/avr/pin_defs.h +++ b/platforms/avr/pin_defs.h @@ -17,7 +17,7 @@ #include <avr/io.h> -#define PORT_SHIFTER 4 // this may be 4 for all AVR chips +#define PORT_SHIFTER 4 // this may be 4 for all AVR chips // If you want to add more to this list, reference the PINx definitions in these header // files: https://github.com/vancegroup-mirrors/avr-libc/tree/master/avr-libc/include/avr diff --git a/platforms/avr/platform.mk b/platforms/avr/platform.mk index b45108736f..4d9cafaeef 100644 --- a/platforms/avr/platform.mk +++ b/platforms/avr/platform.mk @@ -159,7 +159,7 @@ endif bootloader: ifeq ($(strip $(QMK_BOOTLOADER_TYPE)),) - $(error Please set BOOTLOADER to "qmk-dfu" or "qmk-hid" first!) + $(call CATASTROPHIC_ERROR,Invalid BOOTLOADER,Please set BOOTLOADER to "qmk-dfu" or "qmk-hid" first!) else make -C lib/lufa/Bootloaders/$(QMK_BOOTLOADER_TYPE)/ clean $(QMK_BIN) generate-dfu-header --quiet --keyboard $(KEYBOARD) --output lib/lufa/Bootloaders/$(QMK_BOOTLOADER_TYPE)/Keyboard.h diff --git a/platforms/avr/printf.c b/platforms/avr/printf.c index 9ad7a38693..062f70fa0b 100644 --- a/platforms/avr/printf.c +++ b/platforms/avr/printf.c @@ -17,4 +17,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #include "xprintf.h" #include "sendchar.h" -void print_set_sendchar(sendchar_func_t func) { xdev_out(func); } +void print_set_sendchar(sendchar_func_t func) { + xdev_out(func); +} diff --git a/platforms/avr/sleep_led.c b/platforms/avr/sleep_led.c index 9a3b52abe5..b05431633b 100644 --- a/platforms/avr/sleep_led.c +++ b/platforms/avr/sleep_led.c @@ -12,7 +12,7 @@ #if SLEEP_LED_TIMER == 1 # define TCCRxB TCCR1B # define TIMERx_COMPA_vect TIMER1_COMPA_vect -# if defined(__AVR_ATmega32A__) // This MCU has only one TIMSK register +# if defined(__AVR_ATmega32A__) // This MCU has only one TIMSK register # define TIMSKx TIMSK # else # define TIMSKx TIMSK1 diff --git a/platforms/avr/suspend.c b/platforms/avr/suspend.c index b614746e6c..1a7cd3b4ab 100644 --- a/platforms/avr/suspend.c +++ b/platforms/avr/suspend.c @@ -2,12 +2,9 @@ #include <avr/sleep.h> #include <avr/wdt.h> #include <avr/interrupt.h> -#include "matrix.h" -#include "action.h" #include "suspend.h" +#include "action.h" #include "timer.h" -#include "led.h" -#include "host.h" #ifdef PROTOCOL_LUFA # include "lufa.h" @@ -16,19 +13,6 @@ # include "vusb.h" #endif -/** \brief Suspend idle - * - * FIXME: needs doc - */ -void suspend_idle(uint8_t time) { - cli(); - set_sleep_mode(SLEEP_MODE_IDLE); - sleep_enable(); - sei(); - sleep_cpu(); - sleep_disable(); -} - // TODO: This needs some cleanup #if !defined(NO_SUSPEND_POWER_DOWN) && defined(WDT_vect) @@ -91,6 +75,18 @@ static void power_down(uint8_t wdto) { // Disable watchdog after sleep wdt_disable(); } + +/* watchdog timeout */ +ISR(WDT_vect) { + // compensate timer for sleep + switch (wdt_timeout) { + case WDTO_15MS: + timer_count += 15 + 2; // WDTO_15MS + 2(from observation) + break; + default:; + } +} + #endif /** \brief Suspend power down @@ -115,18 +111,6 @@ void suspend_power_down(void) { #endif } -__attribute__((weak)) void matrix_power_up(void) {} -__attribute__((weak)) void matrix_power_down(void) {} -bool suspend_wakeup_condition(void) { - matrix_power_up(); - matrix_scan(); - matrix_power_down(); - for (uint8_t r = 0; r < MATRIX_ROWS; r++) { - if (matrix_get_row(r)) return true; - } - return false; -} - /** \brief run immediately after wakeup * * FIXME: needs doc @@ -137,16 +121,3 @@ void suspend_wakeup_init(void) { suspend_wakeup_init_quantum(); } - -#if !defined(NO_SUSPEND_POWER_DOWN) && defined(WDT_vect) -/* watchdog timeout */ -ISR(WDT_vect) { - // compensate timer for sleep - switch (wdt_timeout) { - case WDTO_15MS: - timer_count += 15 + 2; // WDTO_15MS + 2(from observation) - break; - default:; - } -} -#endif diff --git a/platforms/avr/timer.c b/platforms/avr/timer.c index c2e6c6e081..9fb671ae8d 100644 --- a/platforms/avr/timer.c +++ b/platforms/avr/timer.c @@ -73,7 +73,9 @@ void timer_init(void) { * FIXME: needs doc */ inline void timer_clear(void) { - ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { timer_count = 0; } + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { + timer_count = 0; + } } /** \brief timer read @@ -83,7 +85,9 @@ inline void timer_clear(void) { inline uint16_t timer_read(void) { uint32_t t; - ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { t = timer_count; } + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { + t = timer_count; + } return (t & 0xFFFF); } @@ -95,7 +99,9 @@ inline uint16_t timer_read(void) { inline uint32_t timer_read32(void) { uint32_t t; - ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { t = timer_count; } + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { + t = timer_count; + } return t; } @@ -107,7 +113,9 @@ inline uint32_t timer_read32(void) { inline uint16_t timer_elapsed(uint16_t last) { uint32_t t; - ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { t = timer_count; } + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { + t = timer_count; + } return TIMER_DIFF_16((t & 0xFFFF), last); } @@ -119,7 +127,9 @@ inline uint16_t timer_elapsed(uint16_t last) { inline uint32_t timer_elapsed32(uint32_t last) { uint32_t t; - ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { t = timer_count; } + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { + t = timer_count; + } return TIMER_DIFF_32(t, last); } @@ -130,4 +140,6 @@ inline uint32_t timer_elapsed32(uint32_t last) { #else # define TIMER_INTERRUPT_VECTOR TIMER0_COMP_vect #endif -ISR(TIMER_INTERRUPT_VECTOR, ISR_NOBLOCK) { timer_count++; } +ISR(TIMER_INTERRUPT_VECTOR, ISR_NOBLOCK) { + timer_count++; +} diff --git a/platforms/chibios/boards/BLACKPILL_STM32_F401/configs/bootloader_defs.h b/platforms/chibios/boards/BLACKPILL_STM32_F401/configs/bootloader_defs.h deleted file mode 100644 index 4da3d39a32..0000000000 --- a/platforms/chibios/boards/BLACKPILL_STM32_F401/configs/bootloader_defs.h +++ /dev/null @@ -1,5 +0,0 @@ -/* Address for jumping to bootloader on STM32 chips. */ -/* It is chip dependent, the correct number can be looked up here: - * http://www.st.com/web/en/resource/technical/document/application_note/CD00167594.pdf - */ -#define STM32_BOOTLOADER_ADDRESS 0x1FFF0000 diff --git a/platforms/chibios/boards/BLACKPILL_STM32_F411/configs/bootloader_defs.h b/platforms/chibios/boards/BLACKPILL_STM32_F411/configs/bootloader_defs.h deleted file mode 100644 index 4da3d39a32..0000000000 --- a/platforms/chibios/boards/BLACKPILL_STM32_F411/configs/bootloader_defs.h +++ /dev/null @@ -1,5 +0,0 @@ -/* Address for jumping to bootloader on STM32 chips. */ -/* It is chip dependent, the correct number can be looked up here: - * http://www.st.com/web/en/resource/technical/document/application_note/CD00167594.pdf - */ -#define STM32_BOOTLOADER_ADDRESS 0x1FFF0000 diff --git a/platforms/chibios/boards/GENERIC_STM32_F042X6/configs/bootloader_defs.h b/platforms/chibios/boards/GENERIC_STM32_F042X6/configs/bootloader_defs.h deleted file mode 100644 index 25113425a6..0000000000 --- a/platforms/chibios/boards/GENERIC_STM32_F042X6/configs/bootloader_defs.h +++ /dev/null @@ -1,5 +0,0 @@ -/* Address for jumping to bootloader on STM32 chips. */ -/* It is chip dependent, the correct number can be looked up here: - * http://www.st.com/web/en/resource/technical/document/application_note/CD00167594.pdf - */ -#define STM32_BOOTLOADER_ADDRESS 0x1FFFC400 diff --git a/platforms/chibios/boards/GENERIC_STM32_F072XB/configs/bootloader_defs.h b/platforms/chibios/boards/GENERIC_STM32_F072XB/configs/bootloader_defs.h deleted file mode 100644 index dccd0fa5d1..0000000000 --- a/platforms/chibios/boards/GENERIC_STM32_F072XB/configs/bootloader_defs.h +++ /dev/null @@ -1,5 +0,0 @@ -/* Address for jumping to bootloader on STM32 chips. */ -/* It is chip dependent, the correct number can be looked up here (page 175): - * http://www.st.com/web/en/resource/technical/document/application_note/CD00167594.pdf - */ -#define STM32_BOOTLOADER_ADDRESS 0x1FFFC800 diff --git a/platforms/chibios/boards/GENERIC_STM32_F303XC/configs/bootloader_defs.h b/platforms/chibios/boards/GENERIC_STM32_F303XC/configs/bootloader_defs.h deleted file mode 100644 index 87ac7b10dc..0000000000 --- a/platforms/chibios/boards/GENERIC_STM32_F303XC/configs/bootloader_defs.h +++ /dev/null @@ -1,5 +0,0 @@ -/* Address for jumping to bootloader on STM32 chips. */ -/* It is chip dependent, the correct number can be looked up here: - * http://www.st.com/web/en/resource/technical/document/application_note/CD00167594.pdf - */ -#define STM32_BOOTLOADER_ADDRESS 0x1FFFD800 diff --git a/platforms/chibios/boards/GENERIC_STM32_F405XG/configs/config.h b/platforms/chibios/boards/GENERIC_STM32_F405XG/configs/config.h index cc52a953ed..90a41326a1 100644 --- a/platforms/chibios/boards/GENERIC_STM32_F405XG/configs/config.h +++ b/platforms/chibios/boards/GENERIC_STM32_F405XG/configs/config.h @@ -17,7 +17,7 @@ /* Address for jumping to bootloader on STM32 chips. */ /* It is chip dependent, the correct number can be looked up by checking against ST's application note AN2606. */ -#define STM32_BOOTLOADER_ADDRESS 0x1FFF0000 + #ifndef EARLY_INIT_PERFORM_BOOTLOADER_JUMP # define EARLY_INIT_PERFORM_BOOTLOADER_JUMP TRUE #endif diff --git a/platforms/chibios/boards/GENERIC_STM32_F407XE/configs/config.h b/platforms/chibios/boards/GENERIC_STM32_F407XE/configs/config.h index cc52a953ed..90a41326a1 100644 --- a/platforms/chibios/boards/GENERIC_STM32_F407XE/configs/config.h +++ b/platforms/chibios/boards/GENERIC_STM32_F407XE/configs/config.h @@ -17,7 +17,7 @@ /* Address for jumping to bootloader on STM32 chips. */ /* It is chip dependent, the correct number can be looked up by checking against ST's application note AN2606. */ -#define STM32_BOOTLOADER_ADDRESS 0x1FFF0000 + #ifndef EARLY_INIT_PERFORM_BOOTLOADER_JUMP # define EARLY_INIT_PERFORM_BOOTLOADER_JUMP TRUE #endif diff --git a/platforms/chibios/boards/GENERIC_STM32_F446XE/configs/config.h b/platforms/chibios/boards/GENERIC_STM32_F446XE/configs/config.h index cc52a953ed..90a41326a1 100644 --- a/platforms/chibios/boards/GENERIC_STM32_F446XE/configs/config.h +++ b/platforms/chibios/boards/GENERIC_STM32_F446XE/configs/config.h @@ -17,7 +17,7 @@ /* Address for jumping to bootloader on STM32 chips. */ /* It is chip dependent, the correct number can be looked up by checking against ST's application note AN2606. */ -#define STM32_BOOTLOADER_ADDRESS 0x1FFF0000 + #ifndef EARLY_INIT_PERFORM_BOOTLOADER_JUMP # define EARLY_INIT_PERFORM_BOOTLOADER_JUMP TRUE #endif diff --git a/platforms/chibios/boards/GENERIC_STM32_L412XB/configs/config.h b/platforms/chibios/boards/GENERIC_STM32_L412XB/configs/config.h index c27c61b19a..fc9055ccfb 100644 --- a/platforms/chibios/boards/GENERIC_STM32_L412XB/configs/config.h +++ b/platforms/chibios/boards/GENERIC_STM32_L412XB/configs/config.h @@ -17,7 +17,6 @@ /* Address for jumping to bootloader on STM32 chips. */ /* It is chip dependent, the correct number can be looked up by checking against ST's application note AN2606. */ -#define STM32_BOOTLOADER_ADDRESS 0x1FFF0000 #define PAL_STM32_OSPEED_HIGHEST PAL_STM32_OSPEED_HIGH diff --git a/platforms/chibios/boards/GENERIC_STM32_L432XC/board/board.mk b/platforms/chibios/boards/GENERIC_STM32_L432XC/board/board.mk new file mode 100644 index 0000000000..1250385eb8 --- /dev/null +++ b/platforms/chibios/boards/GENERIC_STM32_L432XC/board/board.mk @@ -0,0 +1,9 @@ +# List of all the board related files. +BOARDSRC = $(CHIBIOS)/os/hal/boards/ST_NUCLEO32_L432KC/board.c + +# Required include directories +BOARDINC = $(CHIBIOS)/os/hal/boards/ST_NUCLEO32_L432KC + +# Shared variables +ALLCSRC += $(BOARDSRC) +ALLINC += $(BOARDINC) diff --git a/platforms/chibios/boards/GENERIC_STM32_L432XC/configs/config.h b/platforms/chibios/boards/GENERIC_STM32_L432XC/configs/config.h new file mode 100644 index 0000000000..b1838b30a8 --- /dev/null +++ b/platforms/chibios/boards/GENERIC_STM32_L432XC/configs/config.h @@ -0,0 +1,10 @@ +// Copyright 2021 Nick Brassel (@tzarc) +// SPDX-License-Identifier: GPL-2.0-or-later +#pragma once + +// Fixup equivalent usages within QMK as the base board definitions only go up to high +#define PAL_STM32_OSPEED_HIGHEST PAL_STM32_OSPEED_HIGH + +#ifndef EARLY_INIT_PERFORM_BOOTLOADER_JUMP +# define EARLY_INIT_PERFORM_BOOTLOADER_JUMP TRUE +#endif diff --git a/platforms/chibios/boards/GENERIC_STM32_L432XC/configs/mcuconf.h b/platforms/chibios/boards/GENERIC_STM32_L432XC/configs/mcuconf.h new file mode 100644 index 0000000000..707134d49e --- /dev/null +++ b/platforms/chibios/boards/GENERIC_STM32_L432XC/configs/mcuconf.h @@ -0,0 +1,267 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/* + * STM32L4xx drivers configuration. + * The following settings override the default settings present in + * the various device driver implementation headers. + * Note that the settings for each driver only have effect if the whole + * driver is enabled in halconf.h. + * + * IRQ priorities: + * 15...0 Lowest...Highest. + * + * DMA priorities: + * 0...3 Lowest...Highest. + */ + +#ifndef MCUCONF_H +#define MCUCONF_H + +#define STM32L4xx_MCUCONF +#define STM32L432_MCUCONF +#define STM32L433_MCUCONF + +/* + * HAL driver system settings. + */ +#define STM32_NO_INIT FALSE +#define STM32_VOS STM32_VOS_RANGE1 +#define STM32_PVD_ENABLE FALSE +#define STM32_PLS STM32_PLS_LEV0 +#define STM32_HSI16_ENABLED TRUE +#define STM32_HSI48_ENABLED TRUE +#define STM32_LSI_ENABLED TRUE +#define STM32_HSE_ENABLED FALSE +#define STM32_LSE_ENABLED FALSE +#define STM32_MSIPLL_ENABLED FALSE +#define STM32_MSIRANGE STM32_MSIRANGE_4M +#define STM32_MSISRANGE STM32_MSISRANGE_4M +#define STM32_SW STM32_SW_PLL +#define STM32_PLLSRC STM32_PLLSRC_HSI16 +#define STM32_PLLM_VALUE 1 +#define STM32_PLLN_VALUE 10 +#define STM32_PLLPDIV_VALUE 0 +#define STM32_PLLP_VALUE 7 +#define STM32_PLLQ_VALUE 2 +#define STM32_PLLR_VALUE 2 +#define STM32_HPRE STM32_HPRE_DIV1 +#define STM32_PPRE1 STM32_PPRE1_DIV1 +#define STM32_PPRE2 STM32_PPRE2_DIV1 +#define STM32_STOPWUCK STM32_STOPWUCK_MSI +#define STM32_MCOSEL STM32_MCOSEL_NOCLOCK +#define STM32_MCOPRE STM32_MCOPRE_DIV1 +#define STM32_LSCOSEL STM32_LSCOSEL_NOCLOCK +#define STM32_PLLSAI1N_VALUE 24 +#define STM32_PLLSAI1PDIV_VALUE 0 +#define STM32_PLLSAI1P_VALUE 7 +#define STM32_PLLSAI1Q_VALUE 2 +#define STM32_PLLSAI1R_VALUE 2 + +/* + * Peripherals clock sources. + */ +#define STM32_USART1SEL STM32_USART1SEL_SYSCLK +#define STM32_USART2SEL STM32_USART2SEL_SYSCLK +#define STM32_LPUART1SEL STM32_LPUART1SEL_SYSCLK +#define STM32_I2C1SEL STM32_I2C1SEL_SYSCLK +#define STM32_I2C3SEL STM32_I2C3SEL_SYSCLK +#define STM32_LPTIM1SEL STM32_LPTIM1SEL_PCLK1 +#define STM32_LPTIM2SEL STM32_LPTIM2SEL_PCLK1 +#define STM32_SAI1SEL STM32_SAI1SEL_OFF +#define STM32_CLK48SEL STM32_CLK48SEL_HSI48 +#define STM32_ADCSEL STM32_ADCSEL_SYSCLK +#define STM32_SWPMI1SEL STM32_SWPMI1SEL_PCLK1 +#define STM32_RTCSEL STM32_RTCSEL_LSI + +/* + * IRQ system settings. + */ +#define STM32_IRQ_EXTI0_PRIORITY 6 +#define STM32_IRQ_EXTI1_PRIORITY 6 +#define STM32_IRQ_EXTI2_PRIORITY 6 +#define STM32_IRQ_EXTI3_PRIORITY 6 +#define STM32_IRQ_EXTI4_PRIORITY 6 +#define STM32_IRQ_EXTI5_9_PRIORITY 6 +#define STM32_IRQ_EXTI10_15_PRIORITY 6 +#define STM32_IRQ_EXTI1635_38_PRIORITY 6 +#define STM32_IRQ_EXTI18_PRIORITY 6 +#define STM32_IRQ_EXTI19_PRIORITY 6 +#define STM32_IRQ_EXTI20_PRIORITY 6 +#define STM32_IRQ_EXTI21_22_PRIORITY 15 + +#define STM32_IRQ_TIM1_BRK_TIM15_PRIORITY 7 +#define STM32_IRQ_TIM1_UP_TIM16_PRIORITY 7 +#define STM32_IRQ_TIM1_TRGCO_TIM17_PRIORITY 7 +#define STM32_IRQ_TIM1_CC_PRIORITY 7 +#define STM32_IRQ_TIM2_PRIORITY 7 +#define STM32_IRQ_TIM6_PRIORITY 7 +#define STM32_IRQ_TIM7_PRIORITY 7 + +#define STM32_IRQ_USART1_PRIORITY 12 +#define STM32_IRQ_USART2_PRIORITY 12 +#define STM32_IRQ_LPUART1_PRIORITY 12 + +/* + * ADC driver system settings. + */ +#define STM32_ADC_COMPACT_SAMPLES FALSE +#define STM32_ADC_USE_ADC1 FALSE +#define STM32_ADC_ADC1_DMA_STREAM STM32_DMA_STREAM_ID(1, 1) +#define STM32_ADC_ADC1_DMA_PRIORITY 2 +#define STM32_ADC_ADC12_IRQ_PRIORITY 5 +#define STM32_ADC_ADC1_DMA_IRQ_PRIORITY 5 +#define STM32_ADC_ADC123_CLOCK_MODE ADC_CCR_CKMODE_AHB_DIV1 +#define STM32_ADC_ADC123_PRESC ADC_CCR_PRESC_DIV2 + +/* + * CAN driver system settings. + */ +#define STM32_CAN_USE_CAN1 FALSE +#define STM32_CAN_CAN1_IRQ_PRIORITY 11 + +/* + * DAC driver system settings. + */ +#define STM32_DAC_DUAL_MODE FALSE +#define STM32_DAC_USE_DAC1_CH1 FALSE +#define STM32_DAC_USE_DAC1_CH2 FALSE +#define STM32_DAC_DAC1_CH1_IRQ_PRIORITY 10 +#define STM32_DAC_DAC1_CH2_IRQ_PRIORITY 10 +#define STM32_DAC_DAC1_CH1_DMA_PRIORITY 2 +#define STM32_DAC_DAC1_CH2_DMA_PRIORITY 2 +#define STM32_DAC_DAC1_CH1_DMA_STREAM STM32_DMA_STREAM_ID(2, 4) +#define STM32_DAC_DAC1_CH2_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) + +/* + * GPT driver system settings. + */ +#define STM32_GPT_USE_TIM1 FALSE +#define STM32_GPT_USE_TIM2 FALSE +#define STM32_GPT_USE_TIM6 FALSE +#define STM32_GPT_USE_TIM7 FALSE +#define STM32_GPT_USE_TIM15 FALSE +#define STM32_GPT_USE_TIM16 FALSE + +/* + * I2C driver system settings. + */ +#define STM32_I2C_USE_I2C1 FALSE +#define STM32_I2C_USE_I2C3 FALSE +#define STM32_I2C_BUSY_TIMEOUT 50 +#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7) +#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6) +#define STM32_I2C_I2C3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) +#define STM32_I2C_I2C3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) +#define STM32_I2C_I2C1_IRQ_PRIORITY 5 +#define STM32_I2C_I2C3_IRQ_PRIORITY 5 +#define STM32_I2C_I2C1_DMA_PRIORITY 3 +#define STM32_I2C_I2C3_DMA_PRIORITY 3 +#define STM32_I2C_DMA_ERROR_HOOK(i2cp) osalSysHalt("DMA failure") + +/* + * ICU driver system settings. + */ +#define STM32_ICU_USE_TIM1 FALSE +#define STM32_ICU_USE_TIM2 FALSE +#define STM32_ICU_USE_TIM15 FALSE +#define STM32_ICU_USE_TIM16 FALSE + +/* + * PWM driver system settings. + */ +#define STM32_PWM_USE_ADVANCED FALSE +#define STM32_PWM_USE_TIM1 FALSE +#define STM32_PWM_USE_TIM2 FALSE +#define STM32_PWM_USE_TIM15 FALSE +#define STM32_PWM_USE_TIM16 FALSE + +/* + * RTC driver system settings. + */ +#define STM32_RTC_PRESA_VALUE 32 +#define STM32_RTC_PRESS_VALUE 1024 +#define STM32_RTC_CR_INIT 0 +#define STM32_RTC_TAMPCR_INIT 0 + +/* + * SERIAL driver system settings. + */ +#define STM32_SERIAL_USE_USART1 FALSE +#define STM32_SERIAL_USE_USART2 FALSE +#define STM32_SERIAL_USE_LPUART1 FALSE +#define STM32_SERIAL_USART1_PRIORITY 12 +#define STM32_SERIAL_USART2_PRIORITY 12 +#define STM32_SERIAL_LPUART1_PRIORITY 12 + +/* + * SPI driver system settings. + */ +#define STM32_SPI_USE_SPI1 FALSE +#define STM32_SPI_USE_SPI3 FALSE +#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 3) +#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 4) +#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1) +#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2) +#define STM32_SPI_SPI1_DMA_PRIORITY 1 +#define STM32_SPI_SPI3_DMA_PRIORITY 1 +#define STM32_SPI_SPI1_IRQ_PRIORITY 10 +#define STM32_SPI_SPI3_IRQ_PRIORITY 10 +#define STM32_SPI_DMA_ERROR_HOOK(spip) osalSysHalt("DMA failure") + +/* + * ST driver system settings. + */ +#define STM32_ST_IRQ_PRIORITY 8 +#define STM32_ST_USE_TIMER 2 + +/* + * TRNG driver system settings. + */ +#define STM32_TRNG_USE_RNG1 FALSE + +/* + * UART driver system settings. + */ +#define STM32_UART_USE_USART1 FALSE +#define STM32_UART_USE_USART2 FALSE +#define STM32_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 7) +#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 6) +#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6) +#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7) +#define STM32_UART_DMA_ERROR_HOOK(uartp) osalSysHalt("DMA failure") + +/* + * USB driver system settings. + */ +#define STM32_USB_USE_USB1 TRUE +#define STM32_USB_LOW_POWER_ON_SUSPEND FALSE +#define STM32_USB_USB1_HP_IRQ_PRIORITY 13 +#define STM32_USB_USB1_LP_IRQ_PRIORITY 14 + +/* + * WDG driver system settings. + */ +#define STM32_WDG_USE_IWDG FALSE + +/* + * WSPI driver system settings. + */ +#define STM32_WSPI_USE_QUADSPI1 FALSE +#define STM32_WSPI_QUADSPI1_DMA_STREAM STM32_DMA_STREAM_ID(2, 7) +#define STM32_WSPI_QUADSPI1_PRESCALER_VALUE 1 + +#endif /* MCUCONF_H */ diff --git a/platforms/chibios/boards/GENERIC_STM32_L433XC/configs/config.h b/platforms/chibios/boards/GENERIC_STM32_L433XC/configs/config.h index c27c61b19a..fc9055ccfb 100644 --- a/platforms/chibios/boards/GENERIC_STM32_L433XC/configs/config.h +++ b/platforms/chibios/boards/GENERIC_STM32_L433XC/configs/config.h @@ -17,7 +17,6 @@ /* Address for jumping to bootloader on STM32 chips. */ /* It is chip dependent, the correct number can be looked up by checking against ST's application note AN2606. */ -#define STM32_BOOTLOADER_ADDRESS 0x1FFF0000 #define PAL_STM32_OSPEED_HIGHEST PAL_STM32_OSPEED_HIGH diff --git a/platforms/chibios/boards/GENERIC_WB32_F3G71XX/configs/bootloader_defs.h b/platforms/chibios/boards/GENERIC_WB32_F3G71XX/configs/bootloader_defs.h deleted file mode 100644 index c929d2ad03..0000000000 --- a/platforms/chibios/boards/GENERIC_WB32_F3G71XX/configs/bootloader_defs.h +++ /dev/null @@ -1,12 +0,0 @@ -/* Address for jumping to bootloader on WB32 chips. */ -/* It is chip dependent, the correct number can be looked up here: - * http://www.westberrytech.com/down/mcu/data/WB32F3G71xx_rm.pdf - */ -#ifndef WB32_BOOTLOADER_ADDRESS -# undef STM32_BOOTLOADER_ADDRESS -# define WB32_BOOTLOADER_ADDRESS 0x1FFFE000 -# define STM32_BOOTLOADER_ADDRESS WB32_BOOTLOADER_ADDRESS -#else -# undef STM32_BOOTLOADER_ADDRESS -# define STM32_BOOTLOADER_ADDRESS WB32_BOOTLOADER_ADDRESS -#endif diff --git a/platforms/chibios/boards/QMK_PROTON_C/configs/bootloader_defs.h b/platforms/chibios/boards/QMK_PROTON_C/configs/bootloader_defs.h deleted file mode 100644 index 3b0e9d20a6..0000000000 --- a/platforms/chibios/boards/QMK_PROTON_C/configs/bootloader_defs.h +++ /dev/null @@ -1,7 +0,0 @@ -/* Address for jumping to bootloader on STM32 chips. */ -/* It is chip dependent, the correct number can be looked up here: - * http://www.st.com/web/en/resource/technical/document/application_note/CD00167594.pdf - * This also requires a patch to chibios: - * <tmk_dir>/tmk_core/tool/chibios/ch-bootloader-jump.patch - */ -#define STM32_BOOTLOADER_ADDRESS 0x1FFFD800 diff --git a/platforms/chibios/bootloader.c b/platforms/chibios/bootloader.c deleted file mode 100644 index 58212948b0..0000000000 --- a/platforms/chibios/bootloader.c +++ /dev/null @@ -1,145 +0,0 @@ -#include "bootloader.h" - -#include <ch.h> -#include <hal.h> -#include "wait.h" - -/* This code should be checked whether it runs correctly on platforms */ -#define SYMVAL(sym) (uint32_t)(((uint8_t *)&(sym)) - ((uint8_t *)0)) -#define BOOTLOADER_MAGIC 0xDEADBEEF -#define MAGIC_ADDR (unsigned long *)(SYMVAL(__ram0_end__) - 4) - -#ifndef STM32_BOOTLOADER_DUAL_BANK -# define STM32_BOOTLOADER_DUAL_BANK FALSE -#endif - -#ifdef BOOTLOADER_TINYUF2 - -# define DBL_TAP_MAGIC 0xf01669ef // From tinyuf2's board_api.h - -// defined by linker script -extern uint32_t _board_dfu_dbl_tap[]; -# define DBL_TAP_REG _board_dfu_dbl_tap[0] - -void bootloader_jump(void) { - DBL_TAP_REG = DBL_TAP_MAGIC; - NVIC_SystemReset(); -} - -void enter_bootloader_mode_if_requested(void) { /* not needed, no two-stage reset */ -} - -#elif STM32_BOOTLOADER_DUAL_BANK - -// Need pin definitions -# include "config_common.h" - -# ifndef STM32_BOOTLOADER_DUAL_BANK_GPIO -# error "No STM32_BOOTLOADER_DUAL_BANK_GPIO defined, don't know which pin to toggle" -# endif - -# ifndef STM32_BOOTLOADER_DUAL_BANK_POLARITY -# define STM32_BOOTLOADER_DUAL_BANK_POLARITY 0 -# endif - -# ifndef STM32_BOOTLOADER_DUAL_BANK_DELAY -# define STM32_BOOTLOADER_DUAL_BANK_DELAY 100000 -# endif - -extern uint32_t __ram0_end__; - -__attribute__((weak)) void bootloader_jump(void) { - // For STM32 MCUs with dual-bank flash, and we're incapable of jumping to the bootloader. The first valid flash - // bank is executed unconditionally after a reset, so it doesn't enter DFU unless BOOT0 is high. Instead, we do - // it with hardware...in this case, we pull a GPIO high/low depending on the configuration, connects 3.3V to - // BOOT0's RC charging circuit, lets it charge the capacitor, and issue a system reset. See the QMK discord - // #hardware channel pins for an example circuit. - palSetPadMode(PAL_PORT(STM32_BOOTLOADER_DUAL_BANK_GPIO), PAL_PAD(STM32_BOOTLOADER_DUAL_BANK_GPIO), PAL_MODE_OUTPUT_PUSHPULL); -# if STM32_BOOTLOADER_DUAL_BANK_POLARITY - palSetPad(PAL_PORT(STM32_BOOTLOADER_DUAL_BANK_GPIO), PAL_PAD(STM32_BOOTLOADER_DUAL_BANK_GPIO)); -# else - palClearPad(PAL_PORT(STM32_BOOTLOADER_DUAL_BANK_GPIO), PAL_PAD(STM32_BOOTLOADER_DUAL_BANK_GPIO)); -# endif - - // Wait for a while for the capacitor to charge - wait_ms(100); - - // Issue a system reset to get the ROM bootloader to execute, with BOOT0 high - NVIC_SystemReset(); -} - -void enter_bootloader_mode_if_requested(void) {} // not needed at all, but if anybody attempts to invoke it.... - -#elif defined(STM32_BOOTLOADER_ADDRESS) // STM32_BOOTLOADER_DUAL_BANK - -extern uint32_t __ram0_end__; - -__attribute__((weak)) void bootloader_jump(void) { - *MAGIC_ADDR = BOOTLOADER_MAGIC; // set magic flag => reset handler will jump into boot loader - NVIC_SystemReset(); -} - -void enter_bootloader_mode_if_requested(void) { - unsigned long *check = MAGIC_ADDR; - if (*check == BOOTLOADER_MAGIC) { - *check = 0; - __set_CONTROL(0); - __set_MSP(*(__IO uint32_t *)STM32_BOOTLOADER_ADDRESS); - __enable_irq(); - - typedef void (*BootJump_t)(void); - BootJump_t boot_jump = *(BootJump_t *)(STM32_BOOTLOADER_ADDRESS + 4); - boot_jump(); - while (1) - ; - } -} - -#elif defined(GD32VF103) - -# define DBGMCU_KEY_UNLOCK 0x4B5A6978 -# define DBGMCU_CMD_RESET 0x1 - -__IO uint32_t *DBGMCU_KEY = (uint32_t *)DBGMCU_BASE + 0x0CU; -__IO uint32_t *DBGMCU_CMD = (uint32_t *)DBGMCU_BASE + 0x08U; - -__attribute__((weak)) void bootloader_jump(void) { - /* The MTIMER unit of the GD32VF103 doesn't have the MSFRST - * register to generate a software reset request. - * BUT instead two undocumented registers in the debug peripheral - * that allow issueing a software reset. WHO would need the MSFRST - * register anyway? Source: - * https://github.com/esmil/gd32vf103inator/blob/master/include/gd32vf103/dbg.h */ - *DBGMCU_KEY = DBGMCU_KEY_UNLOCK; - *DBGMCU_CMD = DBGMCU_CMD_RESET; -} - -void enter_bootloader_mode_if_requested(void) { /* Jumping to bootloader is not possible from user code. */ -} - -#elif defined(KL2x) || defined(K20x) || defined(MK66F18) || defined(MIMXRT1062) // STM32_BOOTLOADER_DUAL_BANK // STM32_BOOTLOADER_ADDRESS -/* Kinetis */ - -# if defined(BOOTLOADER_KIIBOHD) -/* Kiibohd Bootloader (MCHCK and Infinity KB) */ -# define SCB_AIRCR_VECTKEY_WRITEMAGIC 0x05FA0000 -const uint8_t sys_reset_to_loader_magic[] = "\xff\x00\x7fRESET TO LOADER\x7f\x00\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; -__attribute__((weak)) void bootloader_jump(void) { - void *volatile vbat = (void *)VBAT; - __builtin_memcpy(vbat, (const void *)sys_reset_to_loader_magic, sizeof(sys_reset_to_loader_magic)); - // request reset - SCB->AIRCR = SCB_AIRCR_VECTKEY_WRITEMAGIC | SCB_AIRCR_SYSRESETREQ_Msk; -} - -# else /* defined(BOOTLOADER_KIIBOHD) */ -/* Default for Kinetis - expecting an ARM Teensy */ -# include "wait.h" -__attribute__((weak)) void bootloader_jump(void) { - wait_ms(100); - __BKPT(0); -} -# endif /* defined(BOOTLOADER_KIIBOHD) */ - -#else /* neither STM32 nor KINETIS */ -__attribute__((weak)) void bootloader_jump(void) {} -#endif diff --git a/platforms/chibios/bootloaders/custom.c b/platforms/chibios/bootloaders/custom.c new file mode 100644 index 0000000000..bba9fc4637 --- /dev/null +++ b/platforms/chibios/bootloaders/custom.c @@ -0,0 +1,21 @@ +/* Copyright 2021 QMK + * + * 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 3 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 "bootloader.h" + +__attribute__((weak)) void bootloader_jump(void) {} + +__attribute__((weak)) void enter_bootloader_mode_if_requested(void) {} diff --git a/platforms/chibios/bootloaders/gd32v_dfu.c b/platforms/chibios/bootloaders/gd32v_dfu.c new file mode 100644 index 0000000000..baa7d1f882 --- /dev/null +++ b/platforms/chibios/bootloaders/gd32v_dfu.c @@ -0,0 +1,40 @@ +/* Copyright 2021 QMK + * + * 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 3 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 "bootloader.h" + +#include <ch.h> +#include <hal.h> + +#define DBGMCU_KEY_UNLOCK 0x4B5A6978 +#define DBGMCU_CMD_RESET 0x1 + +__IO uint32_t *DBGMCU_KEY = (uint32_t *)DBGMCU_BASE + 0x0CU; +__IO uint32_t *DBGMCU_CMD = (uint32_t *)DBGMCU_BASE + 0x08U; + +__attribute__((weak)) void bootloader_jump(void) { + /* The MTIMER unit of the GD32VF103 doesn't have the MSFRST + * register to generate a software reset request. + * BUT instead two undocumented registers in the debug peripheral + * that allow issueing a software reset. WHO would need the MSFRST + * register anyway? Source: + * https://github.com/esmil/gd32vf103inator/blob/master/include/gd32vf103/dbg.h */ + *DBGMCU_KEY = DBGMCU_KEY_UNLOCK; + *DBGMCU_CMD = DBGMCU_CMD_RESET; +} + +/* Jumping to bootloader is not possible from user code. */ +void enter_bootloader_mode_if_requested(void) {} diff --git a/platforms/chibios/bootloaders/halfkay.c b/platforms/chibios/bootloaders/halfkay.c new file mode 100644 index 0000000000..168c2abc23 --- /dev/null +++ b/platforms/chibios/bootloaders/halfkay.c @@ -0,0 +1,25 @@ +/* Copyright 2021 QMK + * + * 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 3 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 "bootloader.h" + +#include <ch.h> +#include "wait.h" + +__attribute__((weak)) void bootloader_jump(void) { + wait_ms(100); + __BKPT(0); +} diff --git a/platforms/chibios/bootloaders/kiibohd.c b/platforms/chibios/bootloaders/kiibohd.c new file mode 100644 index 0000000000..911e807092 --- /dev/null +++ b/platforms/chibios/bootloaders/kiibohd.c @@ -0,0 +1,32 @@ +/* Copyright 2021 QMK + * + * 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 3 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 "bootloader.h" + +#include <ch.h> + +/* Kiibohd Bootloader (MCHCK and Infinity KB) */ +#define SCB_AIRCR_VECTKEY_WRITEMAGIC 0x05FA0000 + +const uint8_t sys_reset_to_loader_magic[] = "\xff\x00\x7fRESET TO LOADER\x7f\x00\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; + +__attribute__((weak)) void bootloader_jump(void) { + void *volatile vbat = (void *)VBAT; + __builtin_memcpy(vbat, (const void *)sys_reset_to_loader_magic, sizeof(sys_reset_to_loader_magic)); + + // request reset + SCB->AIRCR = SCB_AIRCR_VECTKEY_WRITEMAGIC | SCB_AIRCR_SYSRESETREQ_Msk; +} diff --git a/platforms/chibios/bootloaders/stm32_dfu.c b/platforms/chibios/bootloaders/stm32_dfu.c new file mode 100644 index 0000000000..0e74111367 --- /dev/null +++ b/platforms/chibios/bootloaders/stm32_dfu.c @@ -0,0 +1,94 @@ +/* Copyright 2021 QMK + * + * 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 3 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 "bootloader.h" + +#include <ch.h> +#include <hal.h> +#include "wait.h" + +extern uint32_t __ram0_end__; + +#ifndef STM32_BOOTLOADER_DUAL_BANK +# define STM32_BOOTLOADER_DUAL_BANK FALSE +#endif + +#if STM32_BOOTLOADER_DUAL_BANK +# include "config_common.h" + +# ifndef STM32_BOOTLOADER_DUAL_BANK_GPIO +# error "No STM32_BOOTLOADER_DUAL_BANK_GPIO defined, don't know which pin to toggle" +# endif + +# ifndef STM32_BOOTLOADER_DUAL_BANK_POLARITY +# define STM32_BOOTLOADER_DUAL_BANK_POLARITY 0 +# endif + +# ifndef STM32_BOOTLOADER_DUAL_BANK_DELAY +# define STM32_BOOTLOADER_DUAL_BANK_DELAY 100000 +# endif + +__attribute__((weak)) void bootloader_jump(void) { + // For STM32 MCUs with dual-bank flash, and we're incapable of jumping to the bootloader. The first valid flash + // bank is executed unconditionally after a reset, so it doesn't enter DFU unless BOOT0 is high. Instead, we do + // it with hardware...in this case, we pull a GPIO high/low depending on the configuration, connects 3.3V to + // BOOT0's RC charging circuit, lets it charge the capacitor, and issue a system reset. See the QMK discord + // #hardware channel pins for an example circuit. + palSetPadMode(PAL_PORT(STM32_BOOTLOADER_DUAL_BANK_GPIO), PAL_PAD(STM32_BOOTLOADER_DUAL_BANK_GPIO), PAL_MODE_OUTPUT_PUSHPULL); +# if STM32_BOOTLOADER_DUAL_BANK_POLARITY + palSetPad(PAL_PORT(STM32_BOOTLOADER_DUAL_BANK_GPIO), PAL_PAD(STM32_BOOTLOADER_DUAL_BANK_GPIO)); +# else + palClearPad(PAL_PORT(STM32_BOOTLOADER_DUAL_BANK_GPIO), PAL_PAD(STM32_BOOTLOADER_DUAL_BANK_GPIO)); +# endif + + // Wait for a while for the capacitor to charge + wait_ms(100); + + // Issue a system reset to get the ROM bootloader to execute, with BOOT0 high + NVIC_SystemReset(); +} + +// not needed at all, but if anybody attempts to invoke it.... +void enter_bootloader_mode_if_requested(void) {} + +#else + +/* This code should be checked whether it runs correctly on platforms */ +# define SYMVAL(sym) (uint32_t)(((uint8_t *)&(sym)) - ((uint8_t *)0)) +# define BOOTLOADER_MAGIC 0xDEADBEEF +# define MAGIC_ADDR (unsigned long *)(SYMVAL(__ram0_end__) - 4) + +__attribute__((weak)) void bootloader_jump(void) { + *MAGIC_ADDR = BOOTLOADER_MAGIC; // set magic flag => reset handler will jump into boot loader + NVIC_SystemReset(); +} + +void enter_bootloader_mode_if_requested(void) { + unsigned long *check = MAGIC_ADDR; + if (*check == BOOTLOADER_MAGIC) { + *check = 0; + __set_CONTROL(0); + __set_MSP(*(__IO uint32_t *)STM32_BOOTLOADER_ADDRESS); + __enable_irq(); + + typedef void (*BootJump_t)(void); + BootJump_t boot_jump = *(BootJump_t *)(STM32_BOOTLOADER_ADDRESS + 4); + boot_jump(); + while (1) + ; + } +} +#endif diff --git a/platforms/chibios/bootloaders/stm32duino.c b/platforms/chibios/bootloaders/stm32duino.c new file mode 100644 index 0000000000..53d3ba0adb --- /dev/null +++ b/platforms/chibios/bootloaders/stm32duino.c @@ -0,0 +1,23 @@ +/* Copyright 2021 QMK + * + * 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 3 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 "bootloader.h" + +#include <ch.h> + +__attribute__((weak)) void bootloader_jump(void) { + NVIC_SystemReset(); +} diff --git a/platforms/chibios/bootloaders/tinyuf2.c b/platforms/chibios/bootloaders/tinyuf2.c new file mode 100644 index 0000000000..9ffca5dec8 --- /dev/null +++ b/platforms/chibios/bootloaders/tinyuf2.c @@ -0,0 +1,34 @@ +/* Copyright 2021 QMK + * + * 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 3 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 "bootloader.h" + +#include <ch.h> + +// From tinyuf2's board_api.h +#define DBL_TAP_MAGIC 0xF01669EF + +// defined by linker script +extern uint32_t _board_dfu_dbl_tap[]; +#define DBL_TAP_REG _board_dfu_dbl_tap[0] + +__attribute__((weak)) void bootloader_jump(void) { + DBL_TAP_REG = DBL_TAP_MAGIC; + NVIC_SystemReset(); +} + +/* not needed, no two-stage reset */ +void enter_bootloader_mode_if_requested(void) {} diff --git a/platforms/chibios/chibios_config.h b/platforms/chibios/chibios_config.h index 4e35736606..67d7541ba2 100644 --- a/platforms/chibios/chibios_config.h +++ b/platforms/chibios/chibios_config.h @@ -16,7 +16,7 @@ #pragma once #ifndef USB_VBUS_PIN -# define SPLIT_USB_DETECT // Force this on when dedicated pin is not used +# define SPLIT_USB_DETECT // Force this on when dedicated pin is not used #endif // STM32 compatibility @@ -76,7 +76,7 @@ # if defined(K20x) || defined(KL2x) # define USE_I2CV1 -# define USE_I2CV1_CONTRIB // for some reason a bunch of ChibiOS-Contrib boards only have clock_speed +# define USE_I2CV1_CONTRIB // for some reason a bunch of ChibiOS-Contrib boards only have clock_speed # define USE_GPIOV1 # endif #endif diff --git a/platforms/chibios/drivers/analog.c b/platforms/chibios/drivers/analog.c index eb437665f1..48a59fd290 100644 --- a/platforms/chibios/drivers/analog.c +++ b/platforms/chibios/drivers/analog.c @@ -101,9 +101,9 @@ // Options are 12, 10, 8, and 6 bit. #ifndef ADC_RESOLUTION -# ifdef ADC_CFGR_RES_10BITS // ADCv3, ADCv4 +# ifdef ADC_CFGR_RES_10BITS // ADCv3, ADCv4 # define ADC_RESOLUTION ADC_CFGR_RES_10BITS -# else // ADCv1, ADCv5, or the bodge for ADCv2 above +# else // ADCv1, ADCv5, or the bodge for ADCv2 above # define ADC_RESOLUTION ADC_CFGR1_RES_10BIT # endif #endif @@ -123,7 +123,7 @@ static ADCConversionGroup adcConversionGroup = { .smpr = ADC_SAMPLING_RATE, #elif defined(USE_ADCV2) # if !defined(STM32F1XX) && !defined(GD32VF103) - .cr2 = ADC_CR2_SWSTART, // F103 seem very unhappy with, F401 seems very unhappy without... + .cr2 = ADC_CR2_SWSTART, // F103 seem very unhappy with, F401 seems very unhappy without... # endif .smpr2 = ADC_SMPR2_SMP_AN0(ADC_SAMPLING_RATE) | ADC_SMPR2_SMP_AN1(ADC_SAMPLING_RATE) | ADC_SMPR2_SMP_AN2(ADC_SAMPLING_RATE) | ADC_SMPR2_SMP_AN3(ADC_SAMPLING_RATE) | ADC_SMPR2_SMP_AN4(ADC_SAMPLING_RATE) | ADC_SMPR2_SMP_AN5(ADC_SAMPLING_RATE) | ADC_SMPR2_SMP_AN6(ADC_SAMPLING_RATE) | ADC_SMPR2_SMP_AN7(ADC_SAMPLING_RATE) | ADC_SMPR2_SMP_AN8(ADC_SAMPLING_RATE) | ADC_SMPR2_SMP_AN9(ADC_SAMPLING_RATE), .smpr1 = ADC_SMPR1_SMP_AN10(ADC_SAMPLING_RATE) | ADC_SMPR1_SMP_AN11(ADC_SAMPLING_RATE) | ADC_SMPR1_SMP_AN12(ADC_SAMPLING_RATE) | ADC_SMPR1_SMP_AN13(ADC_SAMPLING_RATE) | ADC_SMPR1_SMP_AN14(ADC_SAMPLING_RATE) | ADC_SMPR1_SMP_AN15(ADC_SAMPLING_RATE), diff --git a/platforms/chibios/drivers/analog.h b/platforms/chibios/drivers/analog.h index e61c394265..8a821719e3 100644 --- a/platforms/chibios/drivers/analog.h +++ b/platforms/chibios/drivers/analog.h @@ -28,7 +28,9 @@ typedef struct { uint8_t adc; } adc_mux; #define TO_MUX(i, a) \ - (adc_mux) { i, a } + (adc_mux) { \ + i, a \ + } int16_t analogReadPin(pin_t pin); int16_t analogReadPinAdc(pin_t pin, uint8_t adc); diff --git a/platforms/chibios/drivers/audio_dac_additive.c b/platforms/chibios/drivers/audio_dac_additive.c index db304adb87..db07c4b393 100644 --- a/platforms/chibios/drivers/audio_dac_additive.c +++ b/platforms/chibios/drivers/audio_dac_additive.c @@ -52,19 +52,19 @@ static const dacsample_t dac_buffer_sine[AUDIO_DAC_BUFFER_SIZE] = { // 256 values, max 4095 0x0, 0x1, 0x2, 0x6, 0xa, 0xf, 0x16, 0x1e, 0x27, 0x32, 0x3d, 0x4a, 0x58, 0x67, 0x78, 0x89, 0x9c, 0xb0, 0xc5, 0xdb, 0xf2, 0x10a, 0x123, 0x13e, 0x159, 0x175, 0x193, 0x1b1, 0x1d1, 0x1f1, 0x212, 0x235, 0x258, 0x27c, 0x2a0, 0x2c6, 0x2ed, 0x314, 0x33c, 0x365, 0x38e, 0x3b8, 0x3e3, 0x40e, 0x43a, 0x467, 0x494, 0x4c2, 0x4f0, 0x51f, 0x54e, 0x57d, 0x5ad, 0x5dd, 0x60e, 0x63f, 0x670, 0x6a1, 0x6d3, 0x705, 0x737, 0x769, 0x79b, 0x7cd, 0x800, 0x832, 0x864, 0x896, 0x8c8, 0x8fa, 0x92c, 0x95e, 0x98f, 0x9c0, 0x9f1, 0xa22, 0xa52, 0xa82, 0xab1, 0xae0, 0xb0f, 0xb3d, 0xb6b, 0xb98, 0xbc5, 0xbf1, 0xc1c, 0xc47, 0xc71, 0xc9a, 0xcc3, 0xceb, 0xd12, 0xd39, 0xd5f, 0xd83, 0xda7, 0xdca, 0xded, 0xe0e, 0xe2e, 0xe4e, 0xe6c, 0xe8a, 0xea6, 0xec1, 0xedc, 0xef5, 0xf0d, 0xf24, 0xf3a, 0xf4f, 0xf63, 0xf76, 0xf87, 0xf98, 0xfa7, 0xfb5, 0xfc2, 0xfcd, 0xfd8, 0xfe1, 0xfe9, 0xff0, 0xff5, 0xff9, 0xffd, 0xffe, 0xfff, 0xffe, 0xffd, 0xff9, 0xff5, 0xff0, 0xfe9, 0xfe1, 0xfd8, 0xfcd, 0xfc2, 0xfb5, 0xfa7, 0xf98, 0xf87, 0xf76, 0xf63, 0xf4f, 0xf3a, 0xf24, 0xf0d, 0xef5, 0xedc, 0xec1, 0xea6, 0xe8a, 0xe6c, 0xe4e, 0xe2e, 0xe0e, 0xded, 0xdca, 0xda7, 0xd83, 0xd5f, 0xd39, 0xd12, 0xceb, 0xcc3, 0xc9a, 0xc71, 0xc47, 0xc1c, 0xbf1, 0xbc5, 0xb98, 0xb6b, 0xb3d, 0xb0f, 0xae0, 0xab1, 0xa82, 0xa52, 0xa22, 0x9f1, 0x9c0, 0x98f, 0x95e, 0x92c, 0x8fa, 0x8c8, 0x896, 0x864, 0x832, 0x800, 0x7cd, 0x79b, 0x769, 0x737, 0x705, 0x6d3, 0x6a1, 0x670, 0x63f, 0x60e, 0x5dd, 0x5ad, 0x57d, 0x54e, 0x51f, 0x4f0, 0x4c2, 0x494, 0x467, 0x43a, 0x40e, 0x3e3, 0x3b8, 0x38e, 0x365, 0x33c, 0x314, 0x2ed, 0x2c6, 0x2a0, 0x27c, 0x258, 0x235, 0x212, 0x1f1, 0x1d1, 0x1b1, 0x193, 0x175, 0x159, 0x13e, 0x123, 0x10a, 0xf2, 0xdb, 0xc5, 0xb0, 0x9c, 0x89, 0x78, 0x67, 0x58, 0x4a, 0x3d, 0x32, 0x27, 0x1e, 0x16, 0xf, 0xa, 0x6, 0x2, 0x1}; -#endif // AUDIO_DAC_SAMPLE_WAVEFORM_SINE +#endif // AUDIO_DAC_SAMPLE_WAVEFORM_SINE #ifdef AUDIO_DAC_SAMPLE_WAVEFORM_TRIANGLE static const dacsample_t dac_buffer_triangle[AUDIO_DAC_BUFFER_SIZE] = { // 256 values, max 4095 0x0, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0, 0x100, 0x120, 0x140, 0x160, 0x180, 0x1a0, 0x1c0, 0x1e0, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0x300, 0x320, 0x340, 0x360, 0x380, 0x3a0, 0x3c0, 0x3e0, 0x400, 0x420, 0x440, 0x460, 0x480, 0x4a0, 0x4c0, 0x4e0, 0x500, 0x520, 0x540, 0x560, 0x580, 0x5a0, 0x5c0, 0x5e0, 0x600, 0x620, 0x640, 0x660, 0x680, 0x6a0, 0x6c0, 0x6e0, 0x700, 0x720, 0x740, 0x760, 0x780, 0x7a0, 0x7c0, 0x7e0, 0x800, 0x81f, 0x83f, 0x85f, 0x87f, 0x89f, 0x8bf, 0x8df, 0x8ff, 0x91f, 0x93f, 0x95f, 0x97f, 0x99f, 0x9bf, 0x9df, 0x9ff, 0xa1f, 0xa3f, 0xa5f, 0xa7f, 0xa9f, 0xabf, 0xadf, 0xaff, 0xb1f, 0xb3f, 0xb5f, 0xb7f, 0xb9f, 0xbbf, 0xbdf, 0xbff, 0xc1f, 0xc3f, 0xc5f, 0xc7f, 0xc9f, 0xcbf, 0xcdf, 0xcff, 0xd1f, 0xd3f, 0xd5f, 0xd7f, 0xd9f, 0xdbf, 0xddf, 0xdff, 0xe1f, 0xe3f, 0xe5f, 0xe7f, 0xe9f, 0xebf, 0xedf, 0xeff, 0xf1f, 0xf3f, 0xf5f, 0xf7f, 0xf9f, 0xfbf, 0xfdf, 0xfff, 0xfdf, 0xfbf, 0xf9f, 0xf7f, 0xf5f, 0xf3f, 0xf1f, 0xeff, 0xedf, 0xebf, 0xe9f, 0xe7f, 0xe5f, 0xe3f, 0xe1f, 0xdff, 0xddf, 0xdbf, 0xd9f, 0xd7f, 0xd5f, 0xd3f, 0xd1f, 0xcff, 0xcdf, 0xcbf, 0xc9f, 0xc7f, 0xc5f, 0xc3f, 0xc1f, 0xbff, 0xbdf, 0xbbf, 0xb9f, 0xb7f, 0xb5f, 0xb3f, 0xb1f, 0xaff, 0xadf, 0xabf, 0xa9f, 0xa7f, 0xa5f, 0xa3f, 0xa1f, 0x9ff, 0x9df, 0x9bf, 0x99f, 0x97f, 0x95f, 0x93f, 0x91f, 0x8ff, 0x8df, 0x8bf, 0x89f, 0x87f, 0x85f, 0x83f, 0x81f, 0x800, 0x7e0, 0x7c0, 0x7a0, 0x780, 0x760, 0x740, 0x720, 0x700, 0x6e0, 0x6c0, 0x6a0, 0x680, 0x660, 0x640, 0x620, 0x600, 0x5e0, 0x5c0, 0x5a0, 0x580, 0x560, 0x540, 0x520, 0x500, 0x4e0, 0x4c0, 0x4a0, 0x480, 0x460, 0x440, 0x420, 0x400, 0x3e0, 0x3c0, 0x3a0, 0x380, 0x360, 0x340, 0x320, 0x300, 0x2e0, 0x2c0, 0x2a0, 0x280, 0x260, 0x240, 0x220, 0x200, 0x1e0, 0x1c0, 0x1a0, 0x180, 0x160, 0x140, 0x120, 0x100, 0xe0, 0xc0, 0xa0, 0x80, 0x60, 0x40, 0x20}; -#endif // AUDIO_DAC_SAMPLE_WAVEFORM_TRIANGLE +#endif // AUDIO_DAC_SAMPLE_WAVEFORM_TRIANGLE #ifdef AUDIO_DAC_SAMPLE_WAVEFORM_SQUARE static const dacsample_t dac_buffer_square[AUDIO_DAC_BUFFER_SIZE] = { - [0 ... AUDIO_DAC_BUFFER_SIZE / 2 - 1] = 0, // first and - [AUDIO_DAC_BUFFER_SIZE / 2 ... AUDIO_DAC_BUFFER_SIZE - 1] = AUDIO_DAC_SAMPLE_MAX, // second half + [0 ... AUDIO_DAC_BUFFER_SIZE / 2 - 1] = 0, // first and + [AUDIO_DAC_BUFFER_SIZE / 2 ... AUDIO_DAC_BUFFER_SIZE - 1] = AUDIO_DAC_SAMPLE_MAX, // second half }; -#endif // AUDIO_DAC_SAMPLE_WAVEFORM_SQUARE +#endif // AUDIO_DAC_SAMPLE_WAVEFORM_SQUARE /* // four steps: 0, 1/3, 2/3 and 1 static const dacsample_t dac_buffer_staircase[AUDIO_DAC_BUFFER_SIZE] = { @@ -77,7 +77,7 @@ static const dacsample_t dac_buffer_staircase[AUDIO_DAC_BUFFER_SIZE] = { #ifdef AUDIO_DAC_SAMPLE_WAVEFORM_TRAPEZOID static const dacsample_t dac_buffer_trapezoid[AUDIO_DAC_BUFFER_SIZE] = {0x0, 0x1f, 0x7f, 0xdf, 0x13f, 0x19f, 0x1ff, 0x25f, 0x2bf, 0x31f, 0x37f, 0x3df, 0x43f, 0x49f, 0x4ff, 0x55f, 0x5bf, 0x61f, 0x67f, 0x6df, 0x73f, 0x79f, 0x7ff, 0x85f, 0x8bf, 0x91f, 0x97f, 0x9df, 0xa3f, 0xa9f, 0xaff, 0xb5f, 0xbbf, 0xc1f, 0xc7f, 0xcdf, 0xd3f, 0xd9f, 0xdff, 0xe5f, 0xebf, 0xf1f, 0xf7f, 0xfdf, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfdf, 0xf7f, 0xf1f, 0xebf, 0xe5f, 0xdff, 0xd9f, 0xd3f, 0xcdf, 0xc7f, 0xc1f, 0xbbf, 0xb5f, 0xaff, 0xa9f, 0xa3f, 0x9df, 0x97f, 0x91f, 0x8bf, 0x85f, 0x7ff, 0x79f, 0x73f, 0x6df, 0x67f, 0x61f, 0x5bf, 0x55f, 0x4ff, 0x49f, 0x43f, 0x3df, 0x37f, 0x31f, 0x2bf, 0x25f, 0x1ff, 0x19f, 0x13f, 0xdf, 0x7f, 0x1f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; -#endif // AUDIO_DAC_SAMPLE_WAVEFORM_TRAPEZOID +#endif // AUDIO_DAC_SAMPLE_WAVEFORM_TRAPEZOID static dacsample_t dac_buffer_empty[AUDIO_DAC_BUFFER_SIZE] = {AUDIO_DAC_OFF_VALUE}; @@ -98,7 +98,7 @@ typedef enum { OUTPUT_REACHED_ZERO_BEFORE_OFF, OUTPUT_OFF, OUTPUT_OFF_1, - OUTPUT_OFF_2, // trailing off: giving the DAC two more conversion cycles until the AUDIO_DAC_OFF_VALUE reaches the output, then turn the timer off, which leaves the output at that level + OUTPUT_OFF_2, // trailing off: giving the DAC two more conversion cycles until the AUDIO_DAC_OFF_VALUE reaches the output, then turn the timer off, which leaves the output at that level number_of_output_states } output_states_t; output_states_t state = OUTPUT_OFF_2; @@ -171,7 +171,7 @@ static void dac_end(DACDriver *dacp) { // work on the other half of the buffer if (dacIsBufferComplete(dacp)) { - sample_p += AUDIO_DAC_BUFFER_SIZE / 2; // 'half_index' + sample_p += AUDIO_DAC_BUFFER_SIZE / 2; // 'half_index' } for (uint8_t s = 0; s < AUDIO_DAC_BUFFER_SIZE / 2; s++) { @@ -196,8 +196,8 @@ static void dac_end(DACDriver *dacp) { * * * * =====*=*================================================= 0x0 */ - if (((sample_p[s] + (AUDIO_DAC_SAMPLE_MAX / 100)) > AUDIO_DAC_OFF_VALUE) && // value approaches from below - (sample_p[s] < (AUDIO_DAC_OFF_VALUE + (AUDIO_DAC_SAMPLE_MAX / 100))) // or above + if (((sample_p[s] + (AUDIO_DAC_SAMPLE_MAX / 100)) > AUDIO_DAC_OFF_VALUE) && // value approaches from below + (sample_p[s] < (AUDIO_DAC_OFF_VALUE + (AUDIO_DAC_SAMPLE_MAX / 100))) // or above ) { if ((OUTPUT_SHOULD_START == state) && (active_tones_snapshot_length > 0)) { state = OUTPUT_RUN_NORMALLY; @@ -220,7 +220,7 @@ static void dac_end(DACDriver *dacp) { // -> saves cpu cycles (?) for (uint8_t i = 0; i < active_tones; i++) { float freq = audio_get_processed_frequency(i); - if (freq > 0) { // disregard 'rest' notes, with valid frequency 0.0f; which would only lower the resulting waveform volume during the additive synthesis step + if (freq > 0) { // disregard 'rest' notes, with valid frequency 0.0f; which would only lower the resulting waveform volume during the additive synthesis step active_tones_snapshot[active_tones_snapshot_length++] = freq; } } @@ -321,7 +321,9 @@ void audio_driver_initialize() { gptStart(&GPTD6, &gpt6cfg1); } -void audio_driver_stop(void) { state = OUTPUT_SHOULD_STOP; } +void audio_driver_stop(void) { + state = OUTPUT_SHOULD_STOP; +} void audio_driver_start(void) { gptStartContinuous(&GPTD6, 2U); diff --git a/platforms/chibios/drivers/audio_dac_basic.c b/platforms/chibios/drivers/audio_dac_basic.c index fac6513506..64439a1e3c 100644 --- a/platforms/chibios/drivers/audio_dac_basic.c +++ b/platforms/chibios/drivers/audio_dac_basic.c @@ -115,13 +115,15 @@ void channel_1_set_frequency(float freq) { channel_1_frequency = freq; channel_1_stop(); - if (freq <= 0.0) // a pause/rest has freq=0 + if (freq <= 0.0) // a pause/rest has freq=0 return; gpt6cfg1.frequency = 2 * freq * AUDIO_DAC_BUFFER_SIZE; channel_1_start(); } -float channel_1_get_frequency(void) { return channel_1_frequency; } +float channel_1_get_frequency(void) { + return channel_1_frequency; +} void channel_2_start(void) { gptStart(&GPTD7, &gpt7cfg1); @@ -140,13 +142,15 @@ void channel_2_set_frequency(float freq) { channel_2_frequency = freq; channel_2_stop(); - if (freq <= 0.0) // a pause/rest has freq=0 + if (freq <= 0.0) // a pause/rest has freq=0 return; gpt7cfg1.frequency = 2 * freq * AUDIO_DAC_BUFFER_SIZE; channel_2_start(); } -float channel_2_get_frequency(void) { return channel_2_frequency; } +float channel_2_get_frequency(void) { + return channel_2_frequency; +} static void gpt_audio_state_cb(GPTDriver *gptp) { if (audio_update_state()) { @@ -155,8 +159,8 @@ static void gpt_audio_state_cb(GPTDriver *gptp) { channel_1_set_frequency(audio_get_processed_frequency(0)); channel_2_set_frequency(audio_get_processed_frequency(0)); -#else // two separate audio outputs/speakers - // primary speaker on A4, optional secondary on A5 +#else // two separate audio outputs/speakers + // primary speaker on A4, optional secondary on A5 if (AUDIO_PIN == A4) { channel_1_set_frequency(audio_get_processed_frequency(0)); if (AUDIO_PIN_ALT == A5) { diff --git a/platforms/chibios/drivers/audio_pwm_hardware.c b/platforms/chibios/drivers/audio_pwm_hardware.c index cd40019ee7..710f397609 100644 --- a/platforms/chibios/drivers/audio_pwm_hardware.c +++ b/platforms/chibios/drivers/audio_pwm_hardware.c @@ -72,7 +72,7 @@ static float channel_1_frequency = 0.0f; void channel_1_set_frequency(float freq) { channel_1_frequency = freq; - if (freq <= 0.0) // a pause/rest has freq=0 + if (freq <= 0.0) // a pause/rest has freq=0 return; pwmcnt_t period = (pwmCFG.frequency / freq); @@ -82,14 +82,18 @@ void channel_1_set_frequency(float freq) { PWM_PERCENTAGE_TO_WIDTH(&AUDIO_PWM_DRIVER, (100 - note_timbre) * 100)); } -float channel_1_get_frequency(void) { return channel_1_frequency; } +float channel_1_get_frequency(void) { + return channel_1_frequency; +} void channel_1_start(void) { pwmStop(&AUDIO_PWM_DRIVER); pwmStart(&AUDIO_PWM_DRIVER, &pwmCFG); } -void channel_1_stop(void) { pwmStop(&AUDIO_PWM_DRIVER); } +void channel_1_stop(void) { + pwmStop(&AUDIO_PWM_DRIVER); +} static void gpt_callback(GPTDriver *gptp); GPTConfig gptCFG = { @@ -108,9 +112,9 @@ void audio_driver_initialize(void) { pwmStart(&AUDIO_PWM_DRIVER, &pwmCFG); // connect the AUDIO_PIN to the PWM hardware -#if defined(USE_GPIOV1) // STM32F103C8 +#if defined(USE_GPIOV1) // STM32F103C8 palSetLineMode(AUDIO_PIN, PAL_MODE_ALTERNATE_PUSHPULL); -#else // GPIOv2 (or GPIOv3 for f4xx, which is the same/compatible at this command) +#else // GPIOv2 (or GPIOv3 for f4xx, which is the same/compatible at this command) palSetLineMode(AUDIO_PIN, PAL_MODE_ALTERNATE(AUDIO_PWM_PAL_MODE)); #endif @@ -135,10 +139,10 @@ void audio_driver_stop(void) { * and updates the pwm to output that frequency */ static void gpt_callback(GPTDriver *gptp) { - float freq; // TODO: freq_alt + float freq; // TODO: freq_alt if (audio_update_state()) { - freq = audio_get_processed_frequency(0); // freq_alt would be index=1 + freq = audio_get_processed_frequency(0); // freq_alt would be index=1 channel_1_set_frequency(freq); } } diff --git a/platforms/chibios/drivers/audio_pwm_software.c b/platforms/chibios/drivers/audio_pwm_software.c index 15c3e98b6a..e01f86ea52 100644 --- a/platforms/chibios/drivers/audio_pwm_software.c +++ b/platforms/chibios/drivers/audio_pwm_software.c @@ -57,7 +57,7 @@ static float channel_1_frequency = 0.0f; void channel_1_set_frequency(float freq) { channel_1_frequency = freq; - if (freq <= 0.0) // a pause/rest has freq=0 + if (freq <= 0.0) // a pause/rest has freq=0 return; pwmcnt_t period = (pwmCFG.frequency / freq); @@ -68,7 +68,9 @@ void channel_1_set_frequency(float freq) { PWM_PERCENTAGE_TO_WIDTH(&AUDIO_PWM_DRIVER, (100 - note_timbre) * 100)); } -float channel_1_get_frequency(void) { return channel_1_frequency; } +float channel_1_get_frequency(void) { + return channel_1_frequency; +} void channel_1_start(void) { pwmStop(&AUDIO_PWM_DRIVER); @@ -81,10 +83,10 @@ void channel_1_start(void) { void channel_1_stop(void) { pwmStop(&AUDIO_PWM_DRIVER); - palClearLine(AUDIO_PIN); // leave the line low, after last note was played + palClearLine(AUDIO_PIN); // leave the line low, after last note was played #if defined(AUDIO_PIN_ALT) && defined(AUDIO_PIN_ALT_AS_NEGATIVE) - palClearLine(AUDIO_PIN_ALT); // leave the line low, after last note was played + palClearLine(AUDIO_PIN_ALT); // leave the line low, after last note was played #endif } @@ -100,7 +102,7 @@ static void pwm_audio_period_callback(PWMDriver *pwmp) { static void pwm_audio_channel_interrupt_callback(PWMDriver *pwmp) { (void)pwmp; if (channel_1_frequency > 0) { - palSetLine(AUDIO_PIN); // generate a PWM signal on any pin, not necessarily the one connected to the timer + palSetLine(AUDIO_PIN); // generate a PWM signal on any pin, not necessarily the one connected to the timer #if defined(AUDIO_PIN_ALT) && defined(AUDIO_PIN_ALT_AS_NEGATIVE) palClearLine(AUDIO_PIN_ALT); #endif @@ -131,7 +133,7 @@ void audio_driver_initialize(void) { palClearLine(AUDIO_PIN_ALT); #endif - pwmEnablePeriodicNotification(&AUDIO_PWM_DRIVER); // enable pwm callbacks + pwmEnablePeriodicNotification(&AUDIO_PWM_DRIVER); // enable pwm callbacks pwmEnableChannelNotification(&AUDIO_PWM_DRIVER, AUDIO_PWM_CHANNEL - 1); gptStart(&AUDIO_STATE_TIMER, &gptCFG); @@ -155,10 +157,10 @@ void audio_driver_stop(void) { * and updates the pwm to output that frequency */ static void gpt_callback(GPTDriver *gptp) { - float freq; // TODO: freq_alt + float freq; // TODO: freq_alt if (audio_update_state()) { - freq = audio_get_processed_frequency(0); // freq_alt would be index=1 + freq = audio_get_processed_frequency(0); // freq_alt would be index=1 channel_1_set_frequency(freq); } } diff --git a/platforms/chibios/drivers/eeprom/eeprom_stm32_L0_L1.h b/platforms/chibios/drivers/eeprom/eeprom_stm32_L0_L1.h index a35defca8b..616d7ccbee 100644 --- a/platforms/chibios/drivers/eeprom/eeprom_stm32_L0_L1.h +++ b/platforms/chibios/drivers/eeprom/eeprom_stm32_L0_L1.h @@ -24,7 +24,7 @@ # define STM32_ONBOARD_EEPROM_SIZE 1024 # else # include "eeconfig.h" -# define STM32_ONBOARD_EEPROM_SIZE (((EECONFIG_SIZE + 3) / 4) * 4) // based off eeconfig's current usage, aligned to 4-byte sizes, to deal with LTO and EEPROM page sizing +# define STM32_ONBOARD_EEPROM_SIZE (((EECONFIG_SIZE + 3) / 4) * 4) // based off eeconfig's current usage, aligned to 4-byte sizes, to deal with LTO and EEPROM page sizing # endif #endif diff --git a/platforms/chibios/drivers/i2c_master.c b/platforms/chibios/drivers/i2c_master.c index 43591d56f8..d10bdbabc1 100644 --- a/platforms/chibios/drivers/i2c_master.c +++ b/platforms/chibios/drivers/i2c_master.c @@ -27,8 +27,67 @@ #include "quantum.h" #include "i2c_master.h" #include <string.h> +#include <ch.h> #include <hal.h> +#ifndef I2C1_SCL_PIN +# define I2C1_SCL_PIN B6 +#endif +#ifndef I2C1_SDA_PIN +# define I2C1_SDA_PIN B7 +#endif + +#ifdef USE_I2CV1 +# ifndef I2C1_OPMODE +# define I2C1_OPMODE OPMODE_I2C +# endif +# ifndef I2C1_CLOCK_SPEED +# define I2C1_CLOCK_SPEED 100000 /* 400000 */ +# endif +# ifndef I2C1_DUTY_CYCLE +# define I2C1_DUTY_CYCLE STD_DUTY_CYCLE /* FAST_DUTY_CYCLE_2 */ +# endif +#else +// The default timing values below configures the I2C clock to 400khz assuming a 72Mhz clock +// For more info : https://www.st.com/en/embedded-software/stsw-stm32126.html +# ifndef I2C1_TIMINGR_PRESC +# define I2C1_TIMINGR_PRESC 0U +# endif +# ifndef I2C1_TIMINGR_SCLDEL +# define I2C1_TIMINGR_SCLDEL 7U +# endif +# ifndef I2C1_TIMINGR_SDADEL +# define I2C1_TIMINGR_SDADEL 0U +# endif +# ifndef I2C1_TIMINGR_SCLH +# define I2C1_TIMINGR_SCLH 38U +# endif +# ifndef I2C1_TIMINGR_SCLL +# define I2C1_TIMINGR_SCLL 129U +# endif +#endif + +#ifndef I2C_DRIVER +# define I2C_DRIVER I2CD1 +#endif + +#ifdef USE_GPIOV1 +# ifndef I2C1_SCL_PAL_MODE +# define I2C1_SCL_PAL_MODE PAL_MODE_ALTERNATE_OPENDRAIN +# endif +# ifndef I2C1_SDA_PAL_MODE +# define I2C1_SDA_PAL_MODE PAL_MODE_ALTERNATE_OPENDRAIN +# endif +#else +// The default PAL alternate modes are used to signal that the pins are used for I2C +# ifndef I2C1_SCL_PAL_MODE +# define I2C1_SCL_PAL_MODE 4 +# endif +# ifndef I2C1_SDA_PAL_MODE +# define I2C1_SDA_PAL_MODE 4 +# endif +#endif + static uint8_t i2c_address; static const I2CConfig i2cconfig = { @@ -144,4 +203,6 @@ i2c_status_t i2c_readReg16(uint8_t devaddr, uint16_t regaddr, uint8_t* data, uin return chibios_to_qmk(&status); } -void i2c_stop(void) { i2cStop(&I2C_DRIVER); } +void i2c_stop(void) { + i2cStop(&I2C_DRIVER); +} diff --git a/platforms/chibios/drivers/i2c_master.h b/platforms/chibios/drivers/i2c_master.h index 5f082e9d1e..deee7ecc08 100644 --- a/platforms/chibios/drivers/i2c_master.h +++ b/platforms/chibios/drivers/i2c_master.h @@ -24,66 +24,7 @@ */ #pragma once -#include <ch.h> -#include <hal.h> - -#ifndef I2C1_SCL_PIN -# define I2C1_SCL_PIN B6 -#endif -#ifndef I2C1_SDA_PIN -# define I2C1_SDA_PIN B7 -#endif - -#ifdef USE_I2CV1 -# ifndef I2C1_OPMODE -# define I2C1_OPMODE OPMODE_I2C -# endif -# ifndef I2C1_CLOCK_SPEED -# define I2C1_CLOCK_SPEED 100000 /* 400000 */ -# endif -# ifndef I2C1_DUTY_CYCLE -# define I2C1_DUTY_CYCLE STD_DUTY_CYCLE /* FAST_DUTY_CYCLE_2 */ -# endif -#else -// The default timing values below configures the I2C clock to 400khz assuming a 72Mhz clock -// For more info : https://www.st.com/en/embedded-software/stsw-stm32126.html -# ifndef I2C1_TIMINGR_PRESC -# define I2C1_TIMINGR_PRESC 0U -# endif -# ifndef I2C1_TIMINGR_SCLDEL -# define I2C1_TIMINGR_SCLDEL 7U -# endif -# ifndef I2C1_TIMINGR_SDADEL -# define I2C1_TIMINGR_SDADEL 0U -# endif -# ifndef I2C1_TIMINGR_SCLH -# define I2C1_TIMINGR_SCLH 38U -# endif -# ifndef I2C1_TIMINGR_SCLL -# define I2C1_TIMINGR_SCLL 129U -# endif -#endif - -#ifndef I2C_DRIVER -# define I2C_DRIVER I2CD1 -#endif - -#ifdef USE_GPIOV1 -# ifndef I2C1_SCL_PAL_MODE -# define I2C1_SCL_PAL_MODE PAL_MODE_ALTERNATE_OPENDRAIN -# endif -# ifndef I2C1_SDA_PAL_MODE -# define I2C1_SDA_PAL_MODE PAL_MODE_ALTERNATE_OPENDRAIN -# endif -#else -// The default PAL alternate modes are used to signal that the pins are used for I2C -# ifndef I2C1_SCL_PAL_MODE -# define I2C1_SCL_PAL_MODE 4 -# endif -# ifndef I2C1_SDA_PAL_MODE -# define I2C1_SDA_PAL_MODE 4 -# endif -#endif +#include <stdint.h> typedef int16_t i2c_status_t; diff --git a/platforms/chibios/drivers/serial.c b/platforms/chibios/drivers/serial.c index ef6f0aa8d5..6db5d85250 100644 --- a/platforms/chibios/drivers/serial.c +++ b/platforms/chibios/drivers/serial.c @@ -50,14 +50,30 @@ # error invalid SELECT_SOFT_SERIAL_SPEED value #endif -inline static void serial_delay(void) { wait_us(SERIAL_DELAY); } -inline static void serial_delay_half(void) { wait_us(SERIAL_DELAY / 2); } -inline static void serial_delay_blip(void) { wait_us(1); } -inline static void serial_output(void) { setPinOutput(SOFT_SERIAL_PIN); } -inline static void serial_input(void) { setPinInputHigh(SOFT_SERIAL_PIN); } -inline static bool serial_read_pin(void) { return !!readPin(SOFT_SERIAL_PIN); } -inline static void serial_low(void) { writePinLow(SOFT_SERIAL_PIN); } -inline static void serial_high(void) { writePinHigh(SOFT_SERIAL_PIN); } +inline static void serial_delay(void) { + wait_us(SERIAL_DELAY); +} +inline static void serial_delay_half(void) { + wait_us(SERIAL_DELAY / 2); +} +inline static void serial_delay_blip(void) { + wait_us(1); +} +inline static void serial_output(void) { + setPinOutput(SOFT_SERIAL_PIN); +} +inline static void serial_input(void) { + setPinInputHigh(SOFT_SERIAL_PIN); +} +inline static bool serial_read_pin(void) { + return !!readPin(SOFT_SERIAL_PIN); +} +inline static void serial_low(void) { + writePinLow(SOFT_SERIAL_PIN); +} +inline static void serial_high(void) { + writePinHigh(SOFT_SERIAL_PIN); +} void interrupt_handler(void *arg); @@ -179,8 +195,6 @@ void interrupt_handler(void *arg) { // wait for the sync to finish sending serial_delay(); - *trans->status = (checksum_computed == checksum_received) ? TRANSACTION_ACCEPTED : TRANSACTION_DATA_ERROR; - // end transaction serial_input(); @@ -193,17 +207,12 @@ void interrupt_handler(void *arg) { ///////// // start transaction by initiator // -// int soft_serial_transaction(int sstd_index) +// bool soft_serial_transaction(int sstd_index) // -// Returns: -// TRANSACTION_END -// TRANSACTION_NO_RESPONSE -// TRANSACTION_DATA_ERROR // this code is very time dependent, so we need to disable interrupts -int soft_serial_transaction(int sstd_index) { - if (sstd_index > NUM_TOTAL_TRANSACTIONS) return TRANSACTION_TYPE_ERROR; +bool soft_serial_transaction(int sstd_index) { + if (sstd_index > NUM_TOTAL_TRANSACTIONS) return false; split_transaction_desc_t *trans = &split_transaction_table[sstd_index]; - if (!trans->status) return TRANSACTION_TYPE_ERROR; // not registered // TODO: remove extra delay between transactions serial_delay(); @@ -226,14 +235,14 @@ int soft_serial_transaction(int sstd_index) { // slave failed to pull the line low, assume not present dprintf("serial::NO_RESPONSE\n"); chSysUnlock(); - return TRANSACTION_NO_RESPONSE; + return false; } // if the slave is present syncronize with it uint8_t checksum = 0; // send data to the slave - serial_write_byte(sstd_index); // first chunk is transaction id + serial_write_byte(sstd_index); // first chunk is transaction id sync_recv(); for (int i = 0; i < trans->initiator2target_buffer_size; ++i) { @@ -245,7 +254,7 @@ int soft_serial_transaction(int sstd_index) { sync_recv(); serial_delay(); - serial_delay(); // read mid pulses + serial_delay(); // read mid pulses // receive data from the slave uint8_t checksum_computed = 0; @@ -266,7 +275,7 @@ int soft_serial_transaction(int sstd_index) { serial_high(); chSysUnlock(); - return TRANSACTION_DATA_ERROR; + return false; } // always, release the line when not in use @@ -274,5 +283,5 @@ int soft_serial_transaction(int sstd_index) { serial_output(); chSysUnlock(); - return TRANSACTION_END; + return true; } diff --git a/platforms/chibios/drivers/serial_usart.c b/platforms/chibios/drivers/serial_usart.c index 124e4be685..85c64214d1 100644 --- a/platforms/chibios/drivers/serial_usart.c +++ b/platforms/chibios/drivers/serial_usart.c @@ -36,7 +36,7 @@ static SerialDriver* serial_driver = &SERIAL_USART_DRIVER; static inline bool react_to_transactions(void); static inline bool __attribute__((nonnull)) receive(uint8_t* destination, const size_t size); static inline bool __attribute__((nonnull)) send(const uint8_t* source, const size_t size); -static inline int initiate_transaction(uint8_t sstd_index); +static inline bool initiate_transaction(uint8_t sstd_index); static inline void usart_clear(void); /** @@ -206,14 +206,12 @@ static inline bool react_to_transactions(void) { to signal that the slave is ready to receive possible transaction buffers */ sstd_index ^= HANDSHAKE_MAGIC; if (!send(&sstd_index, sizeof(sstd_index))) { - *trans->status = TRANSACTION_DATA_ERROR; return false; } /* Receive transaction buffer from the master. If this transaction requires it.*/ if (trans->initiator2target_buffer_size) { if (!receive(split_trans_initiator2target_buffer(trans), trans->initiator2target_buffer_size)) { - *trans->status = TRANSACTION_DATA_ERROR; return false; } } @@ -226,12 +224,10 @@ static inline bool react_to_transactions(void) { /* Send transaction buffer to the master. If this transaction requires it. */ if (trans->target2initiator_buffer_size) { if (!send(split_trans_target2initiator_buffer(trans), trans->target2initiator_buffer_size)) { - *trans->status = TRANSACTION_DATA_ERROR; return false; } } - *trans->status = TRANSACTION_ACCEPTED; return true; } @@ -242,7 +238,7 @@ void soft_serial_initiator_init(void) { usart_master_init(&serial_driver); #if defined(MCU_STM32) && defined(SERIAL_USART_PIN_SWAP) - serial_config.cr2 |= USART_CR2_SWAP; // master has swapped TX/RX pins + serial_config.cr2 |= USART_CR2_SWAP; // master has swapped TX/RX pins #endif sdStart(serial_driver, &serial_config); @@ -252,11 +248,9 @@ void soft_serial_initiator_init(void) { * @brief Start transaction from the master half to the slave half. * * @param index Transaction Table index of the transaction to start. - * @return int TRANSACTION_NO_RESPONSE in case of Timeout. - * TRANSACTION_TYPE_ERROR in case of invalid transaction index. - * TRANSACTION_END in case of success. + * @return bool Indicates success of transaction. */ -int soft_serial_transaction(int index) { +bool soft_serial_transaction(int index) { /* Clear the receive queue, to start with a clean slate. * Parts of failed transactions or spurious bytes could still be in it. */ usart_clear(); @@ -266,25 +260,19 @@ int soft_serial_transaction(int index) { /** * @brief Initiate transaction to slave half. */ -static inline int initiate_transaction(uint8_t sstd_index) { +static inline bool initiate_transaction(uint8_t sstd_index) { /* Sanity check that we are actually starting a valid transaction. */ if (sstd_index >= NUM_TOTAL_TRANSACTIONS) { dprintln("USART: Illegal transaction Id."); - return TRANSACTION_TYPE_ERROR; + return false; } split_transaction_desc_t* trans = &split_transaction_table[sstd_index]; - /* Transaction is not registered. Abort. */ - if (!trans->status) { - dprintln("USART: Transaction not registered."); - return TRANSACTION_TYPE_ERROR; - } - /* Send transaction table index to the slave, which doubles as basic handshake token. */ if (!send(&sstd_index, sizeof(sstd_index))) { dprintln("USART: Send Handshake failed."); - return TRANSACTION_TYPE_ERROR; + return false; } uint8_t sstd_index_shake = 0xFF; @@ -295,14 +283,14 @@ static inline int initiate_transaction(uint8_t sstd_index) { */ if (!receive(&sstd_index_shake, sizeof(sstd_index_shake)) || (sstd_index_shake != (sstd_index ^ HANDSHAKE_MAGIC))) { dprintln("USART: Handshake failed."); - return TRANSACTION_NO_RESPONSE; + return false; } /* Send transaction buffer to the slave. If this transaction requires it. */ if (trans->initiator2target_buffer_size) { if (!send(split_trans_initiator2target_buffer(trans), trans->initiator2target_buffer_size)) { dprintln("USART: Send failed."); - return TRANSACTION_NO_RESPONSE; + return false; } } @@ -310,9 +298,9 @@ static inline int initiate_transaction(uint8_t sstd_index) { if (trans->target2initiator_buffer_size) { if (!receive(split_trans_target2initiator_buffer(trans), trans->target2initiator_buffer_size)) { dprintln("USART: Receive failed."); - return TRANSACTION_NO_RESPONSE; + return false; } } - return TRANSACTION_END; + return true; } diff --git a/platforms/chibios/drivers/serial_usart.h b/platforms/chibios/drivers/serial_usart.h index 7b135b31e0..81fe9e0113 100644 --- a/platforms/chibios/drivers/serial_usart.h +++ b/platforms/chibios/drivers/serial_usart.h @@ -50,15 +50,15 @@ #endif #if !defined(USART_CR1_M0) -# define USART_CR1_M0 USART_CR1_M // some platforms (f1xx) dont have this so +# define USART_CR1_M0 USART_CR1_M // some platforms (f1xx) dont have this so #endif #if !defined(SERIAL_USART_CR1) -# define SERIAL_USART_CR1 (USART_CR1_PCE | USART_CR1_PS | USART_CR1_M0) // parity enable, odd parity, 9 bit length +# define SERIAL_USART_CR1 (USART_CR1_PCE | USART_CR1_PS | USART_CR1_M0) // parity enable, odd parity, 9 bit length #endif #if !defined(SERIAL_USART_CR2) -# define SERIAL_USART_CR2 (USART_CR2_STOP_1) // 2 stop bits +# define SERIAL_USART_CR2 (USART_CR2_STOP_1) // 2 stop bits #endif #if !defined(SERIAL_USART_CR3) diff --git a/platforms/chibios/drivers/spi_master.c b/platforms/chibios/drivers/spi_master.c index dde0bb0597..998bace550 100644 --- a/platforms/chibios/drivers/spi_master.c +++ b/platforms/chibios/drivers/spi_master.c @@ -115,7 +115,7 @@ bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor) { #elif defined(HT32) spiConfig.cr0 = SPI_CR0_SELOEN; - spiConfig.cr1 = SPI_CR1_MODE | 8; // 8 bits and in master mode + spiConfig.cr1 = SPI_CR1_MODE | 8; // 8 bits and in master mode if (lsbFirst) { spiConfig.cr1 |= SPI_CR1_FIRSTBIT; diff --git a/platforms/chibios/drivers/uart.c b/platforms/chibios/drivers/uart.c index d2ea5d6415..4884d7024f 100644 --- a/platforms/chibios/drivers/uart.c +++ b/platforms/chibios/drivers/uart.c @@ -43,7 +43,9 @@ void uart_init(uint32_t baud) { } } -void uart_write(uint8_t data) { sdPut(&SERIAL_DRIVER, c); } +void uart_write(uint8_t data) { + sdPut(&SERIAL_DRIVER, data); +} uint8_t uart_read(void) { msg_t res = sdGet(&SERIAL_DRIVER); @@ -51,8 +53,14 @@ uint8_t uart_read(void) { return (uint8_t)res; } -void uart_transmit(const uint8_t *data, uint16_t length) { sdWrite(&SERIAL_DRIVER, data, length); } +void uart_transmit(const uint8_t *data, uint16_t length) { + sdWrite(&SERIAL_DRIVER, data, length); +} -void uart_receive(uint8_t *data, uint16_t length) { sdRead(&SERIAL_DRIVER, data, length); } +void uart_receive(uint8_t *data, uint16_t length) { + sdRead(&SERIAL_DRIVER, data, length); +} -bool uart_available(void) { return !sdGetWouldBlock(&SERIAL_DRIVER); } +bool uart_available(void) { + return !sdGetWouldBlock(&SERIAL_DRIVER); +} diff --git a/platforms/chibios/drivers/usbpd_stm32g4.c b/platforms/chibios/drivers/usbpd_stm32g4.c index f16ca8aeae..0096f22f07 100644 --- a/platforms/chibios/drivers/usbpd_stm32g4.c +++ b/platforms/chibios/drivers/usbpd_stm32g4.c @@ -18,7 +18,7 @@ #ifndef USBPD_UCPD1_CFG1 # define USBPD_UCPD1_CFG1 (UCPD_CFG1_PSC_UCPDCLK_0 | UCPD_CFG1_TRANSWIN_3 | UCPD_CFG1_IFRGAP_4 | UCPD_CFG1_HBITCLKDIV_4) -#endif // USBPD_UCPD1_CFG1 +#endif // USBPD_UCPD1_CFG1 // Initialises the USBPD subsystem __attribute__((weak)) void usbpd_init(void) { @@ -64,7 +64,7 @@ __attribute__((weak)) usbpd_allowance_t usbpd_get_allowance(void) { switch (vstate_max) { case 0: case 1: - return USBPD_500MA; // Note that this is 500mA (i.e. max USB 2.0), not 900mA, as we're not using USB 3.1 as a sink device. + return USBPD_500MA; // Note that this is 500mA (i.e. max USB 2.0), not 900mA, as we're not using USB 3.1 as a sink device. case 2: return USBPD_1500MA; case 3: diff --git a/platforms/chibios/drivers/ws2812.c b/platforms/chibios/drivers/ws2812.c index 7e870661de..1b3bb59842 100644 --- a/platforms/chibios/drivers/ws2812.c +++ b/platforms/chibios/drivers/ws2812.c @@ -10,7 +10,7 @@ # define NOP_FUDGE 0.4 # else # error("NOP_FUDGE configuration required") -# define NOP_FUDGE 1 // this just pleases the compile so the above error is easier to spot +# define NOP_FUDGE 1 // this just pleases the compile so the above error is easier to spot # endif #endif @@ -25,12 +25,12 @@ // The reset gap can be 6000 ns, but depending on the LED strip it may have to be increased // to values like 600000 ns. If it is too small, the pixels will show nothing most of the time. #ifndef WS2812_RES -# define WS2812_RES (1000 * WS2812_TRST_US) // Width of the low gap between bits to cause a frame to latch +# define WS2812_RES (1000 * WS2812_TRST_US) // Width of the low gap between bits to cause a frame to latch #endif #define NUMBER_NOPS 6 #define CYCLES_PER_SEC (CPU_CLOCK / NUMBER_NOPS * NOP_FUDGE) -#define NS_PER_SEC (1000000000L) // Note that this has to be SIGNED since we want to be able to check for negative values of derivatives +#define NS_PER_SEC (1000000000L) // Note that this has to be SIGNED since we want to be able to check for negative values of derivatives #define NS_PER_CYCLE (NS_PER_SEC / CYCLES_PER_SEC) #define NS_TO_CYCLES(n) ((n) / NS_PER_CYCLE) @@ -67,7 +67,9 @@ void sendByte(uint8_t byte) { } } -void ws2812_init(void) { palSetLineMode(RGB_DI_PIN, WS2812_OUTPUT_MODE); } +void ws2812_init(void) { + palSetLineMode(RGB_DI_PIN, WS2812_OUTPUT_MODE); +} // Setleds for standard RGB void ws2812_setleds(LED_TYPE *ledarray, uint16_t leds) { diff --git a/platforms/chibios/drivers/ws2812_pwm.c b/platforms/chibios/drivers/ws2812_pwm.c index 19ea3cfe8a..57187676d7 100644 --- a/platforms/chibios/drivers/ws2812_pwm.c +++ b/platforms/chibios/drivers/ws2812_pwm.c @@ -11,19 +11,19 @@ #endif #ifndef WS2812_PWM_DRIVER -# define WS2812_PWM_DRIVER PWMD2 // TIMx +# define WS2812_PWM_DRIVER PWMD2 // TIMx #endif #ifndef WS2812_PWM_CHANNEL -# define WS2812_PWM_CHANNEL 2 // Channel +# define WS2812_PWM_CHANNEL 2 // Channel #endif #ifndef WS2812_PWM_PAL_MODE -# define WS2812_PWM_PAL_MODE 2 // DI Pin's alternate function value +# define WS2812_PWM_PAL_MODE 2 // DI Pin's alternate function value #endif #ifndef WS2812_DMA_STREAM -# define WS2812_DMA_STREAM STM32_DMA1_STREAM2 // DMA Stream for TIMx_UP +# define WS2812_DMA_STREAM STM32_DMA1_STREAM2 // DMA Stream for TIMx_UP #endif #ifndef WS2812_DMA_CHANNEL -# define WS2812_DMA_CHANNEL 2 // DMA Channel for TIMx_UP +# define WS2812_DMA_CHANNEL 2 // DMA Channel for TIMx_UP #endif #if (STM32_DMA_SUPPORTS_DMAMUX == TRUE) && !defined(WS2812_DMAMUX_ID) # error "please consult your MCU's datasheet and specify in your config.h: #define WS2812_DMAMUX_ID STM32_DMAMUX1_TIM?_UP" @@ -56,7 +56,7 @@ #ifndef WS2812_PWM_TARGET_PERIOD //# define WS2812_PWM_TARGET_PERIOD 800000 // Original code is 800k...? -# define WS2812_PWM_TARGET_PERIOD 80000 // TODO: work out why 10x less on f303/f4x1 +# define WS2812_PWM_TARGET_PERIOD 80000 // TODO: work out why 10x less on f303/f4x1 #endif /* --- PRIVATE CONSTANTS ---------------------------------------------------- */ @@ -259,8 +259,10 @@ write/read to/from the other buffer). void ws2812_init(void) { // Initialize led frame buffer uint32_t i; - for (i = 0; i < WS2812_COLOR_BIT_N; i++) ws2812_frame_buffer[i] = WS2812_DUTYCYCLE_0; // All color bits are zero duty cycle - for (i = 0; i < WS2812_RESET_BIT_N; i++) ws2812_frame_buffer[i + WS2812_COLOR_BIT_N] = 0; // All reset bits are zero + for (i = 0; i < WS2812_COLOR_BIT_N; i++) + ws2812_frame_buffer[i] = WS2812_DUTYCYCLE_0; // All color bits are zero duty cycle + for (i = 0; i < WS2812_RESET_BIT_N; i++) + ws2812_frame_buffer[i + WS2812_COLOR_BIT_N] = 0; // All reset bits are zero palSetLineMode(RGB_DI_PIN, WS2812_OUTPUT_MODE); @@ -268,22 +270,22 @@ void ws2812_init(void) { //#pragma GCC diagnostic ignored "-Woverride-init" // Turn off override-init warning for this struct. We use the overriding ability to set a "default" channel config static const PWMConfig ws2812_pwm_config = { .frequency = WS2812_PWM_FREQUENCY, - .period = WS2812_PWM_PERIOD, // Mit dieser Periode wird UDE-Event erzeugt und ein neuer Wert (Länge WS2812_BIT_N) vom DMA ins CCR geschrieben + .period = WS2812_PWM_PERIOD, // Mit dieser Periode wird UDE-Event erzeugt und ein neuer Wert (Länge WS2812_BIT_N) vom DMA ins CCR geschrieben .callback = NULL, .channels = { - [0 ... 3] = {.mode = PWM_OUTPUT_DISABLED, .callback = NULL}, // Channels default to disabled - [WS2812_PWM_CHANNEL - 1] = {.mode = WS2812_PWM_OUTPUT_MODE, .callback = NULL}, // Turn on the channel we care about + [0 ... 3] = {.mode = PWM_OUTPUT_DISABLED, .callback = NULL}, // Channels default to disabled + [WS2812_PWM_CHANNEL - 1] = {.mode = WS2812_PWM_OUTPUT_MODE, .callback = NULL}, // Turn on the channel we care about }, .cr2 = 0, - .dier = TIM_DIER_UDE, // DMA on update event for next period + .dier = TIM_DIER_UDE, // DMA on update event for next period }; //#pragma GCC diagnostic pop // Restore command-line warning options // Configure DMA // dmaInit(); // Joe added this dmaStreamAlloc(WS2812_DMA_STREAM - STM32_DMA_STREAM(0), 10, NULL, NULL); - dmaStreamSetPeripheral(WS2812_DMA_STREAM, &(WS2812_PWM_DRIVER.tim->CCR[WS2812_PWM_CHANNEL - 1])); // Ziel ist der An-Zeit im Cap-Comp-Register + dmaStreamSetPeripheral(WS2812_DMA_STREAM, &(WS2812_PWM_DRIVER.tim->CCR[WS2812_PWM_CHANNEL - 1])); // Ziel ist der An-Zeit im Cap-Comp-Register dmaStreamSetMemory0(WS2812_DMA_STREAM, ws2812_frame_buffer); dmaStreamSetTransactionSize(WS2812_DMA_STREAM, WS2812_BIT_N); dmaStreamSetMode(WS2812_DMA_STREAM, STM32_DMA_CR_CHSEL(WS2812_DMA_CHANNEL) | STM32_DMA_CR_DIR_M2P | STM32_DMA_CR_PSIZE_WORD | STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_MINC | STM32_DMA_CR_CIRC | STM32_DMA_CR_PL(3)); @@ -302,7 +304,7 @@ void ws2812_init(void) { // ChibiOS driver code, so we don't have to do anything special to the timer. If we did, we'd have to start the timer, // disable counting, enable the channel, and then make whatever configuration changes we need. pwmStart(&WS2812_PWM_DRIVER, &ws2812_pwm_config); - pwmEnableChannel(&WS2812_PWM_DRIVER, WS2812_PWM_CHANNEL - 1, 0); // Initial period is 0; output will be low until first duty cycle is DMA'd in + pwmEnableChannel(&WS2812_PWM_DRIVER, WS2812_PWM_CHANNEL - 1, 0); // Initial period is 0; output will be low until first duty cycle is DMA'd in } void ws2812_write_led(uint16_t led_number, uint8_t r, uint8_t g, uint8_t b) { diff --git a/platforms/chibios/drivers/ws2812_spi.c b/platforms/chibios/drivers/ws2812_spi.c index ba471e0b8e..76191db165 100644 --- a/platforms/chibios/drivers/ws2812_spi.c +++ b/platforms/chibios/drivers/ws2812_spi.c @@ -42,7 +42,7 @@ # define WS2812_SPI_DIVISOR_CR1_BR_X (SPI_CR1_BR_0) #elif WS2812_SPI_DIVISOR == 8 # define WS2812_SPI_DIVISOR_CR1_BR_X (SPI_CR1_BR_1) -#elif WS2812_SPI_DIVISOR == 16 // same as default +#elif WS2812_SPI_DIVISOR == 16 // same as default # define WS2812_SPI_DIVISOR_CR1_BR_X (SPI_CR1_BR_1 | SPI_CR1_BR_0) #elif WS2812_SPI_DIVISOR == 32 # define WS2812_SPI_DIVISOR_CR1_BR_X (SPI_CR1_BR_2) @@ -53,14 +53,14 @@ #elif WS2812_SPI_DIVISOR == 256 # define WS2812_SPI_DIVISOR_CR1_BR_X (SPI_CR1_BR_2 | SPI_CR1_BR_1 | SPI_CR1_BR_0) #else -# define WS2812_SPI_DIVISOR_CR1_BR_X (SPI_CR1_BR_1 | SPI_CR1_BR_0) // default +# define WS2812_SPI_DIVISOR_CR1_BR_X (SPI_CR1_BR_1 | SPI_CR1_BR_0) // default #endif // Use SPI circular buffer #ifdef WS2812_SPI_USE_CIRCULAR_BUFFER -# define WS2812_SPI_BUFFER_MODE 1 // circular buffer +# define WS2812_SPI_BUFFER_MODE 1 // circular buffer #else -# define WS2812_SPI_BUFFER_MODE 0 // normal buffer +# define WS2812_SPI_BUFFER_MODE 0 // normal buffer #endif #if defined(USE_GPIOV1) @@ -104,20 +104,30 @@ static void set_led_color_rgb(LED_TYPE color, int pos) { uint8_t* tx_start = &txbuf[PREAMBLE_SIZE]; #if (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_GRB) - for (int j = 0; j < 4; j++) tx_start[BYTES_FOR_LED * pos + j] = get_protocol_eq(color.g, j); - for (int j = 0; j < 4; j++) tx_start[BYTES_FOR_LED * pos + BYTES_FOR_LED_BYTE + j] = get_protocol_eq(color.r, j); - for (int j = 0; j < 4; j++) tx_start[BYTES_FOR_LED * pos + BYTES_FOR_LED_BYTE * 2 + j] = get_protocol_eq(color.b, j); + for (int j = 0; j < 4; j++) + tx_start[BYTES_FOR_LED * pos + j] = get_protocol_eq(color.g, j); + for (int j = 0; j < 4; j++) + tx_start[BYTES_FOR_LED * pos + BYTES_FOR_LED_BYTE + j] = get_protocol_eq(color.r, j); + for (int j = 0; j < 4; j++) + tx_start[BYTES_FOR_LED * pos + BYTES_FOR_LED_BYTE * 2 + j] = get_protocol_eq(color.b, j); #elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_RGB) - for (int j = 0; j < 4; j++) tx_start[BYTES_FOR_LED * pos + j] = get_protocol_eq(color.r, j); - for (int j = 0; j < 4; j++) tx_start[BYTES_FOR_LED * pos + BYTES_FOR_LED_BYTE + j] = get_protocol_eq(color.g, j); - for (int j = 0; j < 4; j++) tx_start[BYTES_FOR_LED * pos + BYTES_FOR_LED_BYTE * 2 + j] = get_protocol_eq(color.b, j); + for (int j = 0; j < 4; j++) + tx_start[BYTES_FOR_LED * pos + j] = get_protocol_eq(color.r, j); + for (int j = 0; j < 4; j++) + tx_start[BYTES_FOR_LED * pos + BYTES_FOR_LED_BYTE + j] = get_protocol_eq(color.g, j); + for (int j = 0; j < 4; j++) + tx_start[BYTES_FOR_LED * pos + BYTES_FOR_LED_BYTE * 2 + j] = get_protocol_eq(color.b, j); #elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_BGR) - for (int j = 0; j < 4; j++) tx_start[BYTES_FOR_LED * pos + j] = get_protocol_eq(color.b, j); - for (int j = 0; j < 4; j++) tx_start[BYTES_FOR_LED * pos + BYTES_FOR_LED_BYTE + j] = get_protocol_eq(color.g, j); - for (int j = 0; j < 4; j++) tx_start[BYTES_FOR_LED * pos + BYTES_FOR_LED_BYTE * 2 + j] = get_protocol_eq(color.r, j); + for (int j = 0; j < 4; j++) + tx_start[BYTES_FOR_LED * pos + j] = get_protocol_eq(color.b, j); + for (int j = 0; j < 4; j++) + tx_start[BYTES_FOR_LED * pos + BYTES_FOR_LED_BYTE + j] = get_protocol_eq(color.g, j); + for (int j = 0; j < 4; j++) + tx_start[BYTES_FOR_LED * pos + BYTES_FOR_LED_BYTE * 2 + j] = get_protocol_eq(color.r, j); #endif #ifdef RGBW - for (int j = 0; j < 4; j++) tx_start[BYTES_FOR_LED * pos + BYTES_FOR_LED_BYTE * 4 + j] = get_protocol_eq(color.w, j); + for (int j = 0; j < 4; j++) + tx_start[BYTES_FOR_LED * pos + BYTES_FOR_LED_BYTE * 4 + j] = get_protocol_eq(color.w, j); #endif } @@ -126,7 +136,7 @@ void ws2812_init(void) { #ifdef WS2812_SPI_SCK_PIN palSetLineMode(WS2812_SPI_SCK_PIN, WS2812_SCK_OUTPUT_MODE); -#endif // WS2812_SPI_SCK_PIN +#endif // WS2812_SPI_SCK_PIN // TODO: more dynamic baudrate static const SPIConfig spicfg = {WS2812_SPI_BUFFER_MODE, NULL, PAL_PORT(RGB_DI_PIN), PAL_PAD(RGB_DI_PIN), WS2812_SPI_DIVISOR_CR1_BR_X}; diff --git a/platforms/chibios/eeprom_stm32.c b/platforms/chibios/eeprom_stm32.c index acc6a48516..a15bfe09ed 100644 --- a/platforms/chibios/eeprom_stm32.c +++ b/platforms/chibios/eeprom_stm32.c @@ -133,10 +133,6 @@ */ #include "eeprom_stm32_defs.h" -#if !defined(FEE_PAGE_SIZE) || !defined(FEE_PAGE_COUNT) || !defined(FEE_MCU_FLASH_SIZE) || !defined(FEE_PAGE_BASE_ADDRESS) -# error "not implemented." -#endif - /* These bits are used for optimizing encoding of bytes, 0 and 1 */ #define FEE_WORD_ENCODING 0x8000 #define FEE_VALUE_NEXT 0x6000 @@ -144,69 +140,11 @@ #define FEE_VALUE_ENCODED 0x2000 #define FEE_BYTE_RANGE 0x80 -/* Addressable range 16KByte: 0 <-> (0x1FFF << 1) */ -#define FEE_ADDRESS_MAX_SIZE 0x4000 - /* Flash word value after erase */ #define FEE_EMPTY_WORD ((uint16_t)0xFFFF) -/* Size of combined compacted eeprom and write log pages */ -#define FEE_DENSITY_MAX_SIZE (FEE_PAGE_COUNT * FEE_PAGE_SIZE) - -#ifndef FEE_MCU_FLASH_SIZE_IGNORE_CHECK /* *TODO: Get rid of this check */ -# if FEE_DENSITY_MAX_SIZE > (FEE_MCU_FLASH_SIZE * 1024) -# pragma message STR(FEE_DENSITY_MAX_SIZE) " > " STR(FEE_MCU_FLASH_SIZE * 1024) -# error emulated eeprom: FEE_DENSITY_MAX_SIZE is greater than available flash size -# endif -#endif - -/* Size of emulated eeprom */ -#ifdef FEE_DENSITY_BYTES -# if (FEE_DENSITY_BYTES > FEE_DENSITY_MAX_SIZE) -# pragma message STR(FEE_DENSITY_BYTES) " > " STR(FEE_DENSITY_MAX_SIZE) -# error emulated eeprom: FEE_DENSITY_BYTES exceeds FEE_DENSITY_MAX_SIZE -# endif -# if (FEE_DENSITY_BYTES == FEE_DENSITY_MAX_SIZE) -# pragma message STR(FEE_DENSITY_BYTES) " == " STR(FEE_DENSITY_MAX_SIZE) -# warning emulated eeprom: FEE_DENSITY_BYTES leaves no room for a write log. This will greatly increase the flash wear rate! -# endif -# if FEE_DENSITY_BYTES > FEE_ADDRESS_MAX_SIZE -# pragma message STR(FEE_DENSITY_BYTES) " > " STR(FEE_ADDRESS_MAX_SIZE) -# error emulated eeprom: FEE_DENSITY_BYTES is greater than FEE_ADDRESS_MAX_SIZE allows -# endif -# if ((FEE_DENSITY_BYTES) % 2) == 1 -# error emulated eeprom: FEE_DENSITY_BYTES must be even -# endif -#else -/* Default to half of allocated space used for emulated eeprom, half for write log */ -# define FEE_DENSITY_BYTES (FEE_PAGE_COUNT * FEE_PAGE_SIZE / 2) -#endif - -/* Size of write log */ -#ifdef FEE_WRITE_LOG_BYTES -# if ((FEE_DENSITY_BYTES + FEE_WRITE_LOG_BYTES) > FEE_DENSITY_MAX_SIZE) -# pragma message STR(FEE_DENSITY_BYTES) " + " STR(FEE_WRITE_LOG_BYTES) " > " STR(FEE_DENSITY_MAX_SIZE) -# error emulated eeprom: FEE_WRITE_LOG_BYTES exceeds remaining FEE_DENSITY_MAX_SIZE -# endif -# if ((FEE_WRITE_LOG_BYTES) % 2) == 1 -# error emulated eeprom: FEE_WRITE_LOG_BYTES must be even -# endif -#else -/* Default to use all remaining space */ -# define FEE_WRITE_LOG_BYTES (FEE_PAGE_COUNT * FEE_PAGE_SIZE - FEE_DENSITY_BYTES) -#endif - -/* Start of the emulated eeprom compacted flash area */ -#define FEE_COMPACTED_BASE_ADDRESS FEE_PAGE_BASE_ADDRESS -/* End of the emulated eeprom compacted flash area */ -#define FEE_COMPACTED_LAST_ADDRESS (FEE_COMPACTED_BASE_ADDRESS + FEE_DENSITY_BYTES) -/* Start of the emulated eeprom write log */ -#define FEE_WRITE_LOG_BASE_ADDRESS FEE_COMPACTED_LAST_ADDRESS -/* End of the emulated eeprom write log */ -#define FEE_WRITE_LOG_LAST_ADDRESS (FEE_WRITE_LOG_BASE_ADDRESS + FEE_WRITE_LOG_BYTES) - -#if defined(DYNAMIC_KEYMAP_EEPROM_MAX_ADDR) && (DYNAMIC_KEYMAP_EEPROM_MAX_ADDR >= FEE_DENSITY_BYTES) -# error emulated eeprom: DYNAMIC_KEYMAP_EEPROM_MAX_ADDR is greater than the FEE_DENSITY_BYTES available +#if !defined(FEE_PAGE_SIZE) || !defined(FEE_PAGE_COUNT) || !defined(FEE_MCU_FLASH_SIZE) || !defined(FEE_PAGE_BASE_ADDRESS) +# error "not implemented." #endif /* In-memory contents of emulated eeprom for faster access */ @@ -622,9 +560,13 @@ uint16_t EEPROM_ReadDataWord(uint16_t Address) { /***************************************************************************** * Bind to eeprom_driver.c *******************************************************************************/ -void eeprom_driver_init(void) { EEPROM_Init(); } +void eeprom_driver_init(void) { + EEPROM_Init(); +} -void eeprom_driver_erase(void) { EEPROM_Erase(); } +void eeprom_driver_erase(void) { + EEPROM_Erase(); +} void eeprom_read_block(void *buf, const void *addr, size_t len) { const uint8_t *src = (const uint8_t *)addr; diff --git a/platforms/chibios/eeprom_stm32_defs.h b/platforms/chibios/eeprom_stm32_defs.h index 66904f247f..a6ceb41355 100644 --- a/platforms/chibios/eeprom_stm32_defs.h +++ b/platforms/chibios/eeprom_stm32_defs.h @@ -20,41 +20,41 @@ #if !defined(FEE_PAGE_SIZE) || !defined(FEE_PAGE_COUNT) # if defined(STM32F103xB) || defined(STM32F042x6) || defined(GD32VF103C8) || defined(GD32VF103CB) # ifndef FEE_PAGE_SIZE -# define FEE_PAGE_SIZE 0x400 // Page size = 1KByte +# define FEE_PAGE_SIZE 0x400 // Page size = 1KByte # endif # ifndef FEE_PAGE_COUNT -# define FEE_PAGE_COUNT 2 // How many pages are used +# define FEE_PAGE_COUNT 2 // How many pages are used # endif # elif defined(STM32F103xE) || defined(STM32F303xC) || defined(STM32F072xB) || defined(STM32F070xB) # ifndef FEE_PAGE_SIZE -# define FEE_PAGE_SIZE 0x800 // Page size = 2KByte +# define FEE_PAGE_SIZE 0x800 // Page size = 2KByte # endif # ifndef FEE_PAGE_COUNT -# define FEE_PAGE_COUNT 4 // How many pages are used +# define FEE_PAGE_COUNT 4 // How many pages are used # endif # elif defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F405xG) || defined(STM32F411xE) # ifndef FEE_PAGE_SIZE -# define FEE_PAGE_SIZE 0x4000 // Page size = 16KByte +# define FEE_PAGE_SIZE 0x4000 // Page size = 16KByte # endif # ifndef FEE_PAGE_COUNT -# define FEE_PAGE_COUNT 1 // How many pages are used +# define FEE_PAGE_COUNT 1 // How many pages are used # endif # endif #endif #if !defined(FEE_MCU_FLASH_SIZE) # if defined(STM32F042x6) -# define FEE_MCU_FLASH_SIZE 32 // Size in Kb +# define FEE_MCU_FLASH_SIZE 32 // Size in Kb # elif defined(GD32VF103C8) -# define FEE_MCU_FLASH_SIZE 64 // Size in Kb +# define FEE_MCU_FLASH_SIZE 64 // Size in Kb # elif defined(STM32F103xB) || defined(STM32F072xB) || defined(STM32F070xB) || defined(GD32VF103CB) -# define FEE_MCU_FLASH_SIZE 128 // Size in Kb +# define FEE_MCU_FLASH_SIZE 128 // Size in Kb # elif defined(STM32F303xC) || defined(STM32F401xC) -# define FEE_MCU_FLASH_SIZE 256 // Size in Kb +# define FEE_MCU_FLASH_SIZE 256 // Size in Kb # elif defined(STM32F103xE) || defined(STM32F401xE) || defined(STM32F411xE) -# define FEE_MCU_FLASH_SIZE 512 // Size in Kb +# define FEE_MCU_FLASH_SIZE 512 // Size in Kb # elif defined(STM32F405xG) -# define FEE_MCU_FLASH_SIZE 1024 // Size in Kb +# define FEE_MCU_FLASH_SIZE 1024 // Size in Kb # endif #endif @@ -62,7 +62,7 @@ #if !defined(FEE_PAGE_BASE_ADDRESS) # if defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F405xG) || defined(STM32F411xE) # ifndef FEE_PAGE_BASE_ADDRESS -# define FEE_PAGE_BASE_ADDRESS 0x08004000 // bodge to force 2nd 16k page +# define FEE_PAGE_BASE_ADDRESS 0x08004000 // bodge to force 2nd 16k page # endif # else # ifndef FEE_FLASH_BASE @@ -72,3 +72,65 @@ # define FEE_PAGE_BASE_ADDRESS ((uintptr_t)(FEE_FLASH_BASE) + FEE_MCU_FLASH_SIZE * 1024 - (FEE_PAGE_COUNT * FEE_PAGE_SIZE)) # endif #endif + +/* Addressable range 16KByte: 0 <-> (0x1FFF << 1) */ +#define FEE_ADDRESS_MAX_SIZE 0x4000 + +/* Size of combined compacted eeprom and write log pages */ +#define FEE_DENSITY_MAX_SIZE (FEE_PAGE_COUNT * FEE_PAGE_SIZE) + +#ifndef FEE_MCU_FLASH_SIZE_IGNORE_CHECK /* *TODO: Get rid of this check */ +# if FEE_DENSITY_MAX_SIZE > (FEE_MCU_FLASH_SIZE * 1024) +# pragma message STR(FEE_DENSITY_MAX_SIZE) " > " STR(FEE_MCU_FLASH_SIZE * 1024) +# error emulated eeprom: FEE_DENSITY_MAX_SIZE is greater than available flash size +# endif +#endif + +/* Size of emulated eeprom */ +#ifdef FEE_DENSITY_BYTES +# if (FEE_DENSITY_BYTES > FEE_DENSITY_MAX_SIZE) +# pragma message STR(FEE_DENSITY_BYTES) " > " STR(FEE_DENSITY_MAX_SIZE) +# error emulated eeprom: FEE_DENSITY_BYTES exceeds FEE_DENSITY_MAX_SIZE +# endif +# if (FEE_DENSITY_BYTES == FEE_DENSITY_MAX_SIZE) +# pragma message STR(FEE_DENSITY_BYTES) " == " STR(FEE_DENSITY_MAX_SIZE) +# warning emulated eeprom: FEE_DENSITY_BYTES leaves no room for a write log. This will greatly increase the flash wear rate! +# endif +# if FEE_DENSITY_BYTES > FEE_ADDRESS_MAX_SIZE +# pragma message STR(FEE_DENSITY_BYTES) " > " STR(FEE_ADDRESS_MAX_SIZE) +# error emulated eeprom: FEE_DENSITY_BYTES is greater than FEE_ADDRESS_MAX_SIZE allows +# endif +# if ((FEE_DENSITY_BYTES) % 2) == 1 +# error emulated eeprom: FEE_DENSITY_BYTES must be even +# endif +#else +/* Default to half of allocated space used for emulated eeprom, half for write log */ +# define FEE_DENSITY_BYTES (FEE_PAGE_COUNT * FEE_PAGE_SIZE / 2) +#endif + +/* Size of write log */ +#ifdef FEE_WRITE_LOG_BYTES +# if ((FEE_DENSITY_BYTES + FEE_WRITE_LOG_BYTES) > FEE_DENSITY_MAX_SIZE) +# pragma message STR(FEE_DENSITY_BYTES) " + " STR(FEE_WRITE_LOG_BYTES) " > " STR(FEE_DENSITY_MAX_SIZE) +# error emulated eeprom: FEE_WRITE_LOG_BYTES exceeds remaining FEE_DENSITY_MAX_SIZE +# endif +# if ((FEE_WRITE_LOG_BYTES) % 2) == 1 +# error emulated eeprom: FEE_WRITE_LOG_BYTES must be even +# endif +#else +/* Default to use all remaining space */ +# define FEE_WRITE_LOG_BYTES (FEE_PAGE_COUNT * FEE_PAGE_SIZE - FEE_DENSITY_BYTES) +#endif + +/* Start of the emulated eeprom compacted flash area */ +#define FEE_COMPACTED_BASE_ADDRESS FEE_PAGE_BASE_ADDRESS +/* End of the emulated eeprom compacted flash area */ +#define FEE_COMPACTED_LAST_ADDRESS (FEE_COMPACTED_BASE_ADDRESS + FEE_DENSITY_BYTES) +/* Start of the emulated eeprom write log */ +#define FEE_WRITE_LOG_BASE_ADDRESS FEE_COMPACTED_LAST_ADDRESS +/* End of the emulated eeprom write log */ +#define FEE_WRITE_LOG_LAST_ADDRESS (FEE_WRITE_LOG_BASE_ADDRESS + FEE_WRITE_LOG_BYTES) + +#if defined(DYNAMIC_KEYMAP_EEPROM_MAX_ADDR) && (DYNAMIC_KEYMAP_EEPROM_MAX_ADDR >= FEE_DENSITY_BYTES) +# error emulated eeprom: DYNAMIC_KEYMAP_EEPROM_MAX_ADDR is greater than the FEE_DENSITY_BYTES available +#endif diff --git a/platforms/chibios/eeprom_teensy.c b/platforms/chibios/eeprom_teensy.c index 4aaf665269..c8777febde 100644 --- a/platforms/chibios/eeprom_teensy.c +++ b/platforms/chibios/eeprom_teensy.c @@ -1,6 +1,7 @@ #include <ch.h> #include <hal.h> +#include "eeprom_teensy.h" #include "eeconfig.h" /*************************************/ @@ -42,18 +43,6 @@ #if defined(K20x) /* chip selection */ /* Teensy 3.0, 3.1, 3.2; mchck; infinity keyboard */ -// The EEPROM is really RAM with a hardware-based backup system to -// flash memory. Selecting a smaller size EEPROM allows more wear -// leveling, for higher write endurance. If you edit this file, -// set this to the smallest size your application can use. Also, -// due to Freescale's implementation, writing 16 or 32 bit words -// (aligned to 2 or 4 byte boundaries) has twice the endurance -// compared to writing 8 bit bytes. -// -# ifndef EEPROM_SIZE -# define EEPROM_SIZE 32 -# endif - /* ^^^ Here be dragons: NXP AppNote AN4282 section 3.1 states that partitioning must only be done once. @@ -71,19 +60,19 @@ // Minimum EEPROM Endurance // ------------------------ -# if (EEPROM_SIZE == 2048) // 35000 writes/byte or 70000 writes/word +# if (EEPROM_SIZE == 2048) // 35000 writes/byte or 70000 writes/word # define EEESIZE 0x33 -# elif (EEPROM_SIZE == 1024) // 75000 writes/byte or 150000 writes/word +# elif (EEPROM_SIZE == 1024) // 75000 writes/byte or 150000 writes/word # define EEESIZE 0x34 -# elif (EEPROM_SIZE == 512) // 155000 writes/byte or 310000 writes/word +# elif (EEPROM_SIZE == 512) // 155000 writes/byte or 310000 writes/word # define EEESIZE 0x35 -# elif (EEPROM_SIZE == 256) // 315000 writes/byte or 630000 writes/word +# elif (EEPROM_SIZE == 256) // 315000 writes/byte or 630000 writes/word # define EEESIZE 0x36 -# elif (EEPROM_SIZE == 128) // 635000 writes/byte or 1270000 writes/word +# elif (EEPROM_SIZE == 128) // 635000 writes/byte or 1270000 writes/word # define EEESIZE 0x37 -# elif (EEPROM_SIZE == 64) // 1275000 writes/byte or 2550000 writes/word +# elif (EEPROM_SIZE == 64) // 1275000 writes/byte or 2550000 writes/word # define EEESIZE 0x38 -# elif (EEPROM_SIZE == 32) // 2555000 writes/byte or 5110000 writes/word +# elif (EEPROM_SIZE == 32) // 2555000 writes/byte or 5110000 writes/word # define EEESIZE 0x39 # endif @@ -99,9 +88,9 @@ void eeprom_initialize(void) { if (FTFL->FCNFG & FTFL_FCNFG_RAMRDY) { // FlexRAM is configured as traditional RAM // We need to reconfigure for EEPROM usage - FTFL->FCCOB0 = 0x80; // PGMPART = Program Partition Command - FTFL->FCCOB4 = EEESIZE; // EEPROM Size - FTFL->FCCOB5 = 0x03; // 0K for Dataflash, 32K for EEPROM backup + FTFL->FCCOB0 = 0x80; // PGMPART = Program Partition Command + FTFL->FCCOB4 = EEESIZE; // EEPROM Size + FTFL->FCCOB5 = 0x03; // 0K for Dataflash, 32K for EEPROM backup __disable_irq(); // do_flash_cmd() must execute from RAM. Luckily the C syntax is simple... (*((void (*)(volatile uint8_t *))((uint32_t)do_flash_cmd | 1)))(&(FTFL->FSTAT)); @@ -109,7 +98,7 @@ void eeprom_initialize(void) { status = FTFL->FSTAT; if (status & (FTFL_FSTAT_RDCOLERR | FTFL_FSTAT_ACCERR | FTFL_FSTAT_FPVIOL)) { FTFL->FSTAT = (status & (FTFL_FSTAT_RDCOLERR | FTFL_FSTAT_ACCERR | FTFL_FSTAT_FPVIOL)); - return; // error + return; // error } } // wait for eeprom to become ready (is this really necessary?) @@ -173,7 +162,9 @@ void eeprom_read_block(void *buf, const void *addr, uint32_t len) { * * FIXME: needs doc */ -int eeprom_is_ready(void) { return (FTFL->FCNFG & FTFL_FCNFG_EEERDY) ? 1 : 0; } +int eeprom_is_ready(void) { + return (FTFL->FCNFG & FTFL_FCNFG_EEERDY) ? 1 : 0; +} /** \brief flexram wait * @@ -350,8 +341,6 @@ void do_flash_cmd(volatile uint8_t *fstat) extern uint32_t __eeprom_workarea_start__; extern uint32_t __eeprom_workarea_end__; -# define EEPROM_SIZE 128 - static uint32_t flashend = 0; void eeprom_initialize(void) { @@ -499,7 +488,9 @@ void eeprom_read_block(void *buf, const void *addr, uint32_t len) { } } -int eeprom_is_ready(void) { return 1; } +int eeprom_is_ready(void) { + return 1; +} void eeprom_write_word(uint16_t *addr, uint16_t value) { uint8_t *p = (uint8_t *)addr; @@ -524,68 +515,13 @@ void eeprom_write_block(const void *buf, void *addr, uint32_t len) { } #else -// No EEPROM supported, so emulate it - -# ifndef EEPROM_SIZE -# include "eeconfig.h" -# define EEPROM_SIZE (((EECONFIG_SIZE + 3) / 4) * 4) // based off eeconfig's current usage, aligned to 4-byte sizes, to deal with LTO -# endif -__attribute__((aligned(4))) static uint8_t buffer[EEPROM_SIZE]; - -uint8_t eeprom_read_byte(const uint8_t *addr) { - uint32_t offset = (uint32_t)addr; - return buffer[offset]; -} - -void eeprom_write_byte(uint8_t *addr, uint8_t value) { - uint32_t offset = (uint32_t)addr; - buffer[offset] = value; -} - -uint16_t eeprom_read_word(const uint16_t *addr) { - const uint8_t *p = (const uint8_t *)addr; - return eeprom_read_byte(p) | (eeprom_read_byte(p + 1) << 8); -} - -uint32_t eeprom_read_dword(const uint32_t *addr) { - const uint8_t *p = (const uint8_t *)addr; - return eeprom_read_byte(p) | (eeprom_read_byte(p + 1) << 8) | (eeprom_read_byte(p + 2) << 16) | (eeprom_read_byte(p + 3) << 24); -} - -void eeprom_read_block(void *buf, const void *addr, size_t len) { - const uint8_t *p = (const uint8_t *)addr; - uint8_t * dest = (uint8_t *)buf; - while (len--) { - *dest++ = eeprom_read_byte(p++); - } -} - -void eeprom_write_word(uint16_t *addr, uint16_t value) { - uint8_t *p = (uint8_t *)addr; - eeprom_write_byte(p++, value); - eeprom_write_byte(p, value >> 8); -} - -void eeprom_write_dword(uint32_t *addr, uint32_t value) { - uint8_t *p = (uint8_t *)addr; - eeprom_write_byte(p++, value); - eeprom_write_byte(p++, value >> 8); - eeprom_write_byte(p++, value >> 16); - eeprom_write_byte(p, value >> 24); -} - -void eeprom_write_block(const void *buf, void *addr, size_t len) { - uint8_t * p = (uint8_t *)addr; - const uint8_t *src = (const uint8_t *)buf; - while (len--) { - eeprom_write_byte(p++, *src++); - } -} - +# error Unsupported Teensy EEPROM. #endif /* chip selection */ // The update functions just calls write for now, but could probably be optimized -void eeprom_update_byte(uint8_t *addr, uint8_t value) { eeprom_write_byte(addr, value); } +void eeprom_update_byte(uint8_t *addr, uint8_t value) { + eeprom_write_byte(addr, value); +} void eeprom_update_word(uint16_t *addr, uint16_t value) { uint8_t *p = (uint8_t *)addr; diff --git a/platforms/chibios/eeprom_teensy.h b/platforms/chibios/eeprom_teensy.h new file mode 100755 index 0000000000..9a14a1fa79 --- /dev/null +++ b/platforms/chibios/eeprom_teensy.h @@ -0,0 +1,25 @@ +// Copyright 2022 Nick Brassel (@tzarc) +// SPDX-License-Identifier: GPL-2.0-or-later +#pragma once + +#include <ch.h> +#include <hal.h> + +#if defined(K20x) +/* Teensy 3.0, 3.1, 3.2; mchck; infinity keyboard */ +// The EEPROM is really RAM with a hardware-based backup system to +// flash memory. Selecting a smaller size EEPROM allows more wear +// leveling, for higher write endurance. If you edit this file, +// set this to the smallest size your application can use. Also, +// due to Freescale's implementation, writing 16 or 32 bit words +// (aligned to 2 or 4 byte boundaries) has twice the endurance +// compared to writing 8 bit bytes. +// +# ifndef EEPROM_SIZE +# define EEPROM_SIZE 32 +# endif +#elif defined(KL2x) /* Teensy LC (emulated) */ +# define EEPROM_SIZE 128 +#else +# error Unsupported Teensy EEPROM. +#endif diff --git a/platforms/chibios/gd32v_compatibility.h b/platforms/chibios/gd32v_compatibility.h index f4dcfd8c55..a3148fb6d2 100644 --- a/platforms/chibios/gd32v_compatibility.h +++ b/platforms/chibios/gd32v_compatibility.h @@ -97,10 +97,10 @@ /* Serial USART redefines. */ #if HAL_USE_SERIAL # if !defined(SERIAL_USART_CR1) -# define SERIAL_USART_CR1 (USART_CTL0_PCEN | USART_CTL0_PM | USART_CTL0_WL) // parity enable, odd parity, 9 bit length +# define SERIAL_USART_CR1 (USART_CTL0_PCEN | USART_CTL0_PM | USART_CTL0_WL) // parity enable, odd parity, 9 bit length # endif # if !defined(SERIAL_USART_CR2) -# define SERIAL_USART_CR2 (USART_CTL1_STB_1) // 2 stop bits +# define SERIAL_USART_CR2 (USART_CTL1_STB_1) // 2 stop bits # endif # if !defined(SERIAL_USART_CR3) # define SERIAL_USART_CR3 0x0 diff --git a/platforms/chibios/gpio.h b/platforms/chibios/gpio.h index 4d057f1cab..eb44a18f9c 100644 --- a/platforms/chibios/gpio.h +++ b/platforms/chibios/gpio.h @@ -22,10 +22,12 @@ typedef ioline_t pin_t; /* Operation of GPIO by pin. */ -#define setPinInput(pin) palSetLineMode(pin, PAL_MODE_INPUT) -#define setPinInputHigh(pin) palSetLineMode(pin, PAL_MODE_INPUT_PULLUP) -#define setPinInputLow(pin) palSetLineMode(pin, PAL_MODE_INPUT_PULLDOWN) -#define setPinOutput(pin) palSetLineMode(pin, PAL_MODE_OUTPUT_PUSHPULL) +#define setPinInput(pin) palSetLineMode((pin), PAL_MODE_INPUT) +#define setPinInputHigh(pin) palSetLineMode((pin), PAL_MODE_INPUT_PULLUP) +#define setPinInputLow(pin) palSetLineMode((pin), PAL_MODE_INPUT_PULLDOWN) +#define setPinOutputPushPull(pin) palSetLineMode((pin), PAL_MODE_OUTPUT_PUSHPULL) +#define setPinOutputOpenDrain(pin) palSetLineMode((pin), PAL_MODE_OUTPUT_OPENDRAIN) +#define setPinOutput(pin) setPinOutputPushPull(pin) #define writePinHigh(pin) palSetLine(pin) #define writePinLow(pin) palClearLine(pin) @@ -34,17 +36,3 @@ typedef ioline_t pin_t; #define readPin(pin) palReadLine(pin) #define togglePin(pin) palToggleLine(pin) - -/* Operation of GPIO by port. */ - -typedef uint16_t port_data_t; - -#define readPort(pin) palReadPort(PAL_PORT(pin)) - -#define setPortBitInput(pin, bit) palSetPadMode(PAL_PORT(pin), bit, PAL_MODE_INPUT) -#define setPortBitInputHigh(pin, bit) palSetPadMode(PAL_PORT(pin), bit, PAL_MODE_INPUT_PULLUP) -#define setPortBitInputLow(pin, bit) palSetPadMode(PAL_PORT(pin), bit, PAL_MODE_INPUT_PULLDOWN) -#define setPortBitOutput(pin, bit) palSetPadMode(PAL_PORT(pin), bit, PAL_MODE_OUTPUT_PUSHPULL) - -#define writePortBitLow(pin, bit) palClearLine(PAL_LINE(PAL_PORT(pin), bit)) -#define writePortBitHigh(pin, bit) palSetLine(PAL_LINE(PAL_PORT(pin), bit)) diff --git a/platforms/chibios/platform.mk b/platforms/chibios/platform.mk index 45e3377882..6fd1fd83f5 100644 --- a/platforms/chibios/platform.mk +++ b/platforms/chibios/platform.mk @@ -344,7 +344,7 @@ ifeq ($(strip $(MCU)), risc-v) ifneq ($(shell which riscv64-unknown-elf-gcc 2>/dev/null),) TOOLCHAIN = riscv64-unknown-elf- else - $(error "No RISC-V toolchain found. Can't find riscv32-unknown-elf-gcc or riscv64-unknown-elf-gcc found in your systems PATH variable. Please install a valid toolchain and make it accessible!") + $(call CATASTROPHIC_ERROR,Missing toolchain,No RISC-V toolchain found. Can't find riscv32-unknown-elf-gcc or riscv64-unknown-elf-gcc found in your systems PATH variable. Please install a valid toolchain and make it accessible!) endif endif endif diff --git a/platforms/chibios/sleep_led.c b/platforms/chibios/sleep_led.c index 477056a454..a777d60468 100644 --- a/platforms/chibios/sleep_led.c +++ b/platforms/chibios/sleep_led.c @@ -93,7 +93,7 @@ void sleep_led_init(void) { /* Reset LPTMR settings */ LPTMR0->CSR = 0; /* Set the compare value */ - LPTMR0->CMR = 0; // trigger on counter value (i.e. every time) + LPTMR0->CMR = 0; // trigger on counter value (i.e. every time) /* Set up clock source and prescaler */ /* Software PWM @@ -118,11 +118,11 @@ void sleep_led_init(void) { /* === OPTION 2 === */ # if 1 // nMHz IRC (n=4 on KL25Z, KL26Z and K20x; n=2 or 8 on KL27Z) - MCG->C2 |= MCG_C2_IRCS; // fast (4MHz) internal ref clock -# if defined(KL27) // divide the 8MHz IRC by 2, to have the same MCGIRCLK speed as others + MCG->C2 |= MCG_C2_IRCS; // fast (4MHz) internal ref clock +# if defined(KL27) // divide the 8MHz IRC by 2, to have the same MCGIRCLK speed as others MCG->MC |= MCG_MC_LIRC_DIV2_DIV2; -# endif /* KL27 */ - MCG->C1 |= MCG_C1_IRCLKEN; // enable internal ref clock +# endif /* KL27 */ + MCG->C1 |= MCG_C1_IRCLKEN; // enable internal ref clock // to work in stop mode, also MCG_C1_IREFSTEN // Divide 4MHz by 2^N (N=6) => 62500 irqs/sec => // => approx F=61, R=256, duration = 4 @@ -140,7 +140,7 @@ void sleep_led_init(void) { /* === END OPTIONS === */ /* Interrupt on TCF set (compare flag) */ - nvicEnableVector(LPTMR0_IRQn, 2); // vector, priority + nvicEnableVector(LPTMR0_IRQn, 2); // vector, priority LPTMR0->CSR |= LPTMRx_CSR_TIE; } @@ -169,21 +169,33 @@ static void gptTimerCallback(GPTDriver *gptp) { static const GPTConfig gptcfg = {1000000, gptTimerCallback, 0, 0}; /* Initialise the timer */ -void sleep_led_init(void) { gptStart(&SLEEP_LED_GPT_DRIVER, &gptcfg); } +void sleep_led_init(void) { + gptStart(&SLEEP_LED_GPT_DRIVER, &gptcfg); +} -void sleep_led_enable(void) { gptStartContinuous(&SLEEP_LED_GPT_DRIVER, gptcfg.frequency / 0xFFFF); } +void sleep_led_enable(void) { + gptStartContinuous(&SLEEP_LED_GPT_DRIVER, gptcfg.frequency / 0xFFFF); +} -void sleep_led_disable(void) { gptStopTimer(&SLEEP_LED_GPT_DRIVER); } +void sleep_led_disable(void) { + gptStopTimer(&SLEEP_LED_GPT_DRIVER); +} -void sleep_led_toggle(void) { (SLEEP_LED_GPT_DRIVER.state == GPT_READY) ? sleep_led_enable() : sleep_led_disable(); } +void sleep_led_toggle(void) { + (SLEEP_LED_GPT_DRIVER.state == GPT_READY) ? sleep_led_enable() : sleep_led_disable(); +} #else /* platform selection: not on familiar chips */ void sleep_led_init(void) {} -void sleep_led_enable(void) { led_set(1 << USB_LED_CAPS_LOCK); } +void sleep_led_enable(void) { + led_set(1 << USB_LED_CAPS_LOCK); +} -void sleep_led_disable(void) { led_set(0); } +void sleep_led_disable(void) { + led_set(0); +} void sleep_led_toggle(void) { // not implemented diff --git a/platforms/chibios/suspend.c b/platforms/chibios/suspend.c index 9310a99920..ce03433e3a 100644 --- a/platforms/chibios/suspend.c +++ b/platforms/chibios/suspend.c @@ -13,15 +13,6 @@ #include "led.h" #include "wait.h" -/** \brief suspend idle - * - * FIXME: needs doc - */ -void suspend_idle(uint8_t time) { - // TODO: this is not used anywhere - what units is 'time' in? - wait_ms(time); -} - /** \brief suspend power down * * FIXME: needs doc @@ -36,34 +27,6 @@ void suspend_power_down(void) { /** \brief suspend wakeup condition * - * FIXME: needs doc - */ -__attribute__((weak)) void matrix_power_up(void) {} -__attribute__((weak)) void matrix_power_down(void) {} -bool suspend_wakeup_condition(void) { - matrix_power_up(); - matrix_scan(); - matrix_power_down(); - for (uint8_t r = 0; r < MATRIX_ROWS; r++) { - if (matrix_get_row(r)) return true; - } - return false; -} - -/** \brief run user level code immediately after wakeup - * - * FIXME: needs doc - */ -__attribute__((weak)) void suspend_wakeup_init_user(void) {} - -/** \brief run keyboard level code immediately after wakeup - * - * FIXME: needs doc - */ -__attribute__((weak)) void suspend_wakeup_init_kb(void) { suspend_wakeup_init_user(); } - -/** \brief suspend wakeup condition - * * run immediately after wakeup * FIXME: needs doc */ diff --git a/platforms/chibios/syscall-fallbacks.c b/platforms/chibios/syscall-fallbacks.c index 7150a46326..86f7907bfc 100644 --- a/platforms/chibios/syscall-fallbacks.c +++ b/platforms/chibios/syscall-fallbacks.c @@ -87,9 +87,13 @@ __attribute__((weak, used)) int _kill(int pid, int sig) { return -1; } -__attribute__((weak, used)) pid_t _getpid(void) { return 1; } +__attribute__((weak, used)) pid_t _getpid(void) { + return 1; +} -__attribute__((weak, used)) void _fini(void) { return; } +__attribute__((weak, used)) void _fini(void) { + return; +} __attribute__((weak, used, noreturn)) void _exit(int i) { while (1) diff --git a/platforms/chibios/timer.c b/platforms/chibios/timer.c index 9f664e1f79..e3bdfdcc37 100644 --- a/platforms/chibios/timer.c +++ b/platforms/chibios/timer.c @@ -2,46 +2,106 @@ #include "timer.h" -static uint32_t reset_point = 0; +static uint32_t ticks_offset = 0; +static uint32_t last_ticks = 0; +static uint32_t ms_offset = 0; #if CH_CFG_ST_RESOLUTION < 32 static uint32_t last_systime = 0; static uint32_t overflow = 0; #endif -void timer_init(void) { timer_clear(); } +// Get the current system time in ticks as a 32-bit number. +// This function must be called from within a system lock zone (so that it can safely use and update the static data). +static inline uint32_t get_system_time_ticks(void) { + uint32_t systime = (uint32_t)chVTGetSystemTimeX(); -void timer_clear(void) { - reset_point = (uint32_t)chVTGetSystemTime(); #if CH_CFG_ST_RESOLUTION < 32 - last_systime = reset_point; - overflow = 0; -#endif -} - -uint16_t timer_read(void) { return (uint16_t)timer_read32(); } - -uint32_t timer_read32(void) { - uint32_t systime = (uint32_t)chVTGetSystemTime(); - -#if CH_CFG_ST_RESOLUTION < 32 - // If/when we need to support 64-bit chips, this may need to be modified to match the native bit-ness of the MCU. - // At this point, the only SysTick resolution allowed other than 32 is 16 bit. - // In the 16-bit case, at: + // If the real system timer resolution is less than 32 bits, provide the missing bits by checking for the counter + // overflow. For this to work, this function must be called at least once for every overflow of the system timer. + // In the 16-bit case, the corresponding times are: // - CH_CFG_ST_FREQUENCY = 100000, overflow will occur every ~0.65 seconds // - CH_CFG_ST_FREQUENCY = 10000, overflow will occur every ~6.5 seconds // - CH_CFG_ST_FREQUENCY = 1000, overflow will occur every ~65 seconds - // With this implementation, as long as we ensure a timer read happens at least once during the overflow period, timing should be accurate. if (systime < last_systime) { overflow += ((uint32_t)1) << CH_CFG_ST_RESOLUTION; } - last_systime = systime; - return (uint32_t)TIME_I2MS(systime - reset_point + overflow); -#else - return (uint32_t)TIME_I2MS(systime - reset_point); + systime += overflow; +#endif + + return systime; +} + +#if CH_CFG_ST_RESOLUTION < 32 +static virtual_timer_t update_timer; + +// Update the system tick counter every half of the timer overflow period; this should keep the tick counter correct +// even if something blocks timer interrupts for 1/2 of the timer overflow period. +# define UPDATE_INTERVAL (((sysinterval_t)1) << (CH_CFG_ST_RESOLUTION - 1)) + +// VT callback function to keep the overflow bits of the system tick counter updated. +static void update_fn(void *arg) { + (void)arg; + chSysLockFromISR(); + get_system_time_ticks(); + chVTSetI(&update_timer, UPDATE_INTERVAL, update_fn, NULL); + chSysUnlockFromISR(); +} +#endif + +// The highest multiple of CH_CFG_ST_FREQUENCY that fits into uint32_t. This number of ticks will necessarily +// correspond to some integer number of seconds. +#define OVERFLOW_ADJUST_TICKS ((uint32_t)((UINT32_MAX / CH_CFG_ST_FREQUENCY) * CH_CFG_ST_FREQUENCY)) + +// The time in milliseconds which corresponds to OVERFLOW_ADJUST_TICKS ticks (this is a precise conversion, because +// OVERFLOW_ADJUST_TICKS corresponds to an integer number of seconds). +#define OVERFLOW_ADJUST_MS (TIME_I2MS(OVERFLOW_ADJUST_TICKS)) + +void timer_init(void) { + timer_clear(); +#if CH_CFG_ST_RESOLUTION < 32 + chVTObjectInit(&update_timer); + chVTSet(&update_timer, UPDATE_INTERVAL, update_fn, NULL); #endif } -uint16_t timer_elapsed(uint16_t last) { return TIMER_DIFF_16(timer_read(), last); } +void timer_clear(void) { + chSysLock(); + ticks_offset = get_system_time_ticks(); + last_ticks = 0; + ms_offset = 0; + chSysUnlock(); +} + +uint16_t timer_read(void) { + return (uint16_t)timer_read32(); +} -uint32_t timer_elapsed32(uint32_t last) { return TIMER_DIFF_32(timer_read32(), last); } +uint32_t timer_read32(void) { + chSysLock(); + uint32_t ticks = get_system_time_ticks() - ticks_offset; + if (ticks < last_ticks) { + // The 32-bit tick counter overflowed and wrapped around. We cannot just extend the counter to 64 bits here, + // because TIME_I2MS() may encounter overflows when handling a 64-bit argument; therefore the solution here is + // to subtract a reasonably large number of ticks from the tick counter to bring its value below the 32-bit + // limit again, and then add the equivalent number of milliseconds to the converted value. (Adjusting just the + // converted value to account for 2**32 ticks is not possible in general, because 2**32 ticks may not correspond + // to an integer number of milliseconds). + ticks -= OVERFLOW_ADJUST_TICKS; + ticks_offset += OVERFLOW_ADJUST_TICKS; + ms_offset += OVERFLOW_ADJUST_MS; + } + last_ticks = ticks; + uint32_t ms_offset_copy = ms_offset; // read while still holding the lock to ensure a consistent value + chSysUnlock(); + + return (uint32_t)TIME_I2MS(ticks) + ms_offset_copy; +} + +uint16_t timer_elapsed(uint16_t last) { + return TIMER_DIFF_16(timer_read(), last); +} + +uint32_t timer_elapsed32(uint32_t last) { + return TIMER_DIFF_32(timer_read32(), last); +} diff --git a/platforms/common.mk b/platforms/common.mk index f7a0fc7028..2a1fc8d377 100644 --- a/platforms/common.mk +++ b/platforms/common.mk @@ -1,10 +1,11 @@ PLATFORM_COMMON_DIR = $(PLATFORM_PATH)/$(PLATFORM_KEY) TMK_COMMON_SRC += \ + $(PLATFORM_PATH)/suspend.c \ $(PLATFORM_COMMON_DIR)/platform.c \ $(PLATFORM_COMMON_DIR)/suspend.c \ $(PLATFORM_COMMON_DIR)/timer.c \ - $(PLATFORM_COMMON_DIR)/bootloader.c \ + $(PLATFORM_COMMON_DIR)/bootloaders/$(BOOTLOADER_TYPE).c # Search Path VPATH += $(PLATFORM_PATH) diff --git a/platforms/eeprom.h b/platforms/eeprom.h index f5b3f0ad53..091e6e4400 100644 --- a/platforms/eeprom.h +++ b/platforms/eeprom.h @@ -1,3 +1,5 @@ +// Copyright 2018-2022 QMK +// SPDX-License-Identifier: GPL-2.0-or-later #pragma once #if defined(__AVR__) && !defined(EEPROM_DRIVER) @@ -19,3 +21,50 @@ void eeprom_update_word(uint16_t *__p, uint16_t __value); void eeprom_update_dword(uint32_t *__p, uint32_t __value); void eeprom_update_block(const void *__src, void *__dst, size_t __n); #endif + +#if defined(EEPROM_CUSTOM) +# ifndef EEPROM_SIZE +# error EEPROM_SIZE has not been defined for custom driver. +# endif +# define TOTAL_EEPROM_BYTE_COUNT (EEPROM_SIZE) +#elif defined(EEPROM_TRANSIENT) +# include "eeprom_transient.h" +# define TOTAL_EEPROM_BYTE_COUNT (TRANSIENT_EEPROM_SIZE) +#elif defined(EEPROM_I2C) +# include "eeprom_i2c.h" +# define TOTAL_EEPROM_BYTE_COUNT (EXTERNAL_EEPROM_BYTE_COUNT) +#elif defined(EEPROM_SPI) +# include "eeprom_spi.h" +# define TOTAL_EEPROM_BYTE_COUNT (EXTERNAL_EEPROM_BYTE_COUNT) +#elif defined(EEPROM_STM32_L0_L1) +# include "eeprom_stm32_L0_L1.h" +# define TOTAL_EEPROM_BYTE_COUNT (STM32_ONBOARD_EEPROM_SIZE) +#elif defined(EEPROM_TEENSY) +# include "eeprom_teensy.h" +# define TOTAL_EEPROM_BYTE_COUNT (EEPROM_SIZE) +#elif defined(EEPROM_STM32_FLASH_EMULATED) +# include "eeprom_stm32_defs.h" +# define TOTAL_EEPROM_BYTE_COUNT (FEE_DENSITY_BYTES) +#elif defined(EEPROM_SAMD) +# include "eeprom_samd.h" +# define TOTAL_EEPROM_BYTE_COUNT (EEPROM_SIZE) +#elif defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega16U4__) || defined(__AVR_AT90USB162__) || defined(__AVR_ATtiny85__) +# define TOTAL_EEPROM_BYTE_COUNT 512 +#elif defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega32A__) +# define TOTAL_EEPROM_BYTE_COUNT 1024 +#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) +# define TOTAL_EEPROM_BYTE_COUNT 2048 +#elif defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) +# define TOTAL_EEPROM_BYTE_COUNT 4096 +#elif defined(EEPROM_TEST_HARNESS) +# ifndef FLASH_STM32_MOCKED +// Normal tests +# define TOTAL_EEPROM_BYTE_COUNT 32 +# else +// Flash wear-leveling testing +# include "eeprom_stm32_tests.h" +# define TOTAL_EEPROM_BYTE_COUNT (EEPROM_SIZE) +# endif +#else +# error Unknown EEPROM driver. +#endif diff --git a/platforms/suspend.c b/platforms/suspend.c new file mode 100644 index 0000000000..fea23cbd02 --- /dev/null +++ b/platforms/suspend.c @@ -0,0 +1,51 @@ +// Copyright 2022 QMK +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "suspend.h" +#include "matrix.h" + +// TODO: Move to more correct location +__attribute__((weak)) void matrix_power_up(void) {} +__attribute__((weak)) void matrix_power_down(void) {} + +/** \brief Run user level Power down + * + * FIXME: needs doc + */ +__attribute__((weak)) void suspend_power_down_user(void) {} + +/** \brief Run keyboard level Power down + * + * FIXME: needs doc + */ +__attribute__((weak)) void suspend_power_down_kb(void) { + suspend_power_down_user(); +} + +/** \brief run user level code immediately after wakeup + * + * FIXME: needs doc + */ +__attribute__((weak)) void suspend_wakeup_init_user(void) {} + +/** \brief run keyboard level code immediately after wakeup + * + * FIXME: needs doc + */ +__attribute__((weak)) void suspend_wakeup_init_kb(void) { + suspend_wakeup_init_user(); +} + +/** \brief suspend wakeup condition + * + * FIXME: needs doc + */ +bool suspend_wakeup_condition(void) { + matrix_power_up(); + matrix_scan(); + matrix_power_down(); + for (uint8_t r = 0; r < MATRIX_ROWS; r++) { + if (matrix_get_row(r)) return true; + } + return false; +} diff --git a/platforms/suspend.h b/platforms/suspend.h index 081735f90e..e4f7f39ddb 100644 --- a/platforms/suspend.h +++ b/platforms/suspend.h @@ -3,7 +3,6 @@ #include <stdint.h> #include <stdbool.h> -void suspend_idle(uint8_t timeout); void suspend_power_down(void); bool suspend_wakeup_condition(void); void suspend_wakeup_init(void); diff --git a/platforms/test/bootloader.c b/platforms/test/bootloaders/none.c index 5155d9ff04..5155d9ff04 100644 --- a/platforms/test/bootloader.c +++ b/platforms/test/bootloaders/none.c diff --git a/platforms/test/eeprom.c b/platforms/test/eeprom.c index 5c8e69dae3..d501745e55 100644 --- a/platforms/test/eeprom.c +++ b/platforms/test/eeprom.c @@ -16,9 +16,7 @@ #include "eeprom.h" -#define EEPROM_SIZE 32 - -static uint8_t buffer[EEPROM_SIZE]; +static uint8_t buffer[TOTAL_EEPROM_BYTE_COUNT]; uint8_t eeprom_read_byte(const uint8_t *addr) { uintptr_t offset = (uintptr_t)addr; @@ -70,7 +68,9 @@ void eeprom_write_block(const void *buf, void *addr, size_t len) { } } -void eeprom_update_byte(uint8_t *addr, uint8_t value) { eeprom_write_byte(addr, value); } +void eeprom_update_byte(uint8_t *addr, uint8_t value) { + eeprom_write_byte(addr, value); +} void eeprom_update_word(uint16_t *addr, uint16_t value) { uint8_t *p = (uint8_t *)addr; diff --git a/platforms/test/eeprom_stm32_tests.cpp b/platforms/test/eeprom_stm32_tests.cpp index 5bc8d87900..d2c41fb77d 100644 --- a/platforms/test/eeprom_stm32_tests.cpp +++ b/platforms/test/eeprom_stm32_tests.cpp @@ -17,8 +17,6 @@ #include "gtest/gtest.h" extern "C" { -#include "flash_stm32.h" -#include "eeprom_stm32.h" #include "eeprom.h" } @@ -46,7 +44,6 @@ extern "C" { * */ -#define EEPROM_SIZE (FEE_PAGE_SIZE * FEE_PAGE_COUNT / 2) #define LOG_SIZE EEPROM_SIZE #define LOG_BASE (MOCK_FLASH_SIZE - LOG_SIZE) #define EEPROM_BASE (LOG_BASE - EEPROM_SIZE) @@ -63,7 +60,9 @@ class EepromStm32Test : public testing::Test { ~EepromStm32Test() {} protected: - void SetUp() override { EEPROM_Erase(); } + void SetUp() override { + EEPROM_Erase(); + } void TearDown() override { #ifdef EEPROM_DEBUG @@ -86,7 +85,7 @@ TEST_F(EepromStm32Test, TestReadGarbage) { garbage += i; FlashBuf[i] = garbage; } - EEPROM_Init(); // Just verify we don't crash + EEPROM_Init(); // Just verify we don't crash } TEST_F(EepromStm32Test, TestWriteBadAddress) { @@ -209,11 +208,11 @@ TEST_F(EepromStm32Test, TestReadWord) { TEST_F(EepromStm32Test, TestWriteWord) { /* Direct compacted-area: Address < 0x80 */ - EEPROM_WriteDataWord(0, 0xdead); // Aligned - EEPROM_WriteDataWord(3, 0xbeef); // Unaligned + EEPROM_WriteDataWord(0, 0xdead); // Aligned + EEPROM_WriteDataWord(3, 0xbeef); // Unaligned /* Direct compacted-area: Address >= 0x80 */ - EEPROM_WriteDataWord(200, 0xabcd); // Aligned - EEPROM_WriteDataWord(203, 0x9876); // Unaligned + EEPROM_WriteDataWord(200, 0xabcd); // Aligned + EEPROM_WriteDataWord(203, 0x9876); // Unaligned EEPROM_WriteDataWord(EEPROM_SIZE - 4, 0x1234); EEPROM_WriteDataWord(EEPROM_SIZE - 2, 0x5678); /* Write Log word zero-encoded */ @@ -221,10 +220,10 @@ TEST_F(EepromStm32Test, TestWriteWord) { /* Write Log word one-encoded */ EEPROM_WriteDataWord(EEPROM_SIZE - 2, 1); /* Write Log word value aligned */ - EEPROM_WriteDataWord(200, 0x4321); // Aligned + EEPROM_WriteDataWord(200, 0x4321); // Aligned /* Write Log word value unaligned */ - EEPROM_WriteDataByte(202, 0x3c); // Set neighboring byte - EEPROM_WriteDataWord(203, 0xcdef); // Unaligned + EEPROM_WriteDataByte(202, 0x3c); // Set neighboring byte + EEPROM_WriteDataWord(203, 0xcdef); // Unaligned /* Check values */ /* Direct compacted-area */ EXPECT_EQ(*(uint16_t*)&FlashBuf[EEPROM_BASE], (uint16_t)~0xdead); @@ -252,11 +251,11 @@ TEST_F(EepromStm32Test, TestWriteWord) { TEST_F(EepromStm32Test, TestWordRoundTrip) { /* Direct compacted-area: Address < 0x80 */ - EEPROM_WriteDataWord(0, 0xdead); // Aligned - EEPROM_WriteDataWord(3, 0xbeef); // Unaligned + EEPROM_WriteDataWord(0, 0xdead); // Aligned + EEPROM_WriteDataWord(3, 0xbeef); // Unaligned /* Direct compacted-area: Address >= 0x80 */ - EEPROM_WriteDataWord(200, 0xabcd); // Aligned - EEPROM_WriteDataWord(203, 0x9876); // Unaligned + EEPROM_WriteDataWord(200, 0xabcd); // Aligned + EEPROM_WriteDataWord(203, 0x9876); // Unaligned EEPROM_WriteDataWord(EEPROM_SIZE - 4, 0x1234); EEPROM_WriteDataWord(EEPROM_SIZE - 2, 0x5678); /* Check values */ @@ -273,10 +272,10 @@ TEST_F(EepromStm32Test, TestWordRoundTrip) { /* Write Log word one-encoded */ EEPROM_WriteDataWord(EEPROM_SIZE - 2, 1); /* Write Log word value aligned */ - EEPROM_WriteDataWord(200, 0x4321); // Aligned + EEPROM_WriteDataWord(200, 0x4321); // Aligned /* Write Log word value unaligned */ - EEPROM_WriteDataByte(202, 0x3c); // Set neighboring byte - EEPROM_WriteDataWord(203, 0xcdef); // Unaligned + EEPROM_WriteDataByte(202, 0x3c); // Set neighboring byte + EEPROM_WriteDataWord(203, 0xcdef); // Unaligned /* Check values */ EEPROM_Init(); EXPECT_EQ(EEPROM_ReadDataWord(200), 0x4321); @@ -327,34 +326,34 @@ TEST_F(EepromStm32Test, TestByteWordBoundary) { TEST_F(EepromStm32Test, TestDWordRoundTrip) { /* Direct compacted-area: Address < 0x80 */ - eeprom_write_dword((uint32_t*)0, 0xdeadbeef); // Aligned - eeprom_write_dword((uint32_t*)9, 0x12345678); // Unaligned + eeprom_write_dword((uint32_t*)0, 0xdeadbeef); // Aligned + eeprom_write_dword((uint32_t*)9, 0x12345678); // Unaligned /* Direct compacted-area: Address >= 0x80 */ eeprom_write_dword((uint32_t*)200, 0xfacef00d); - eeprom_write_dword((uint32_t*)(EEPROM_SIZE - 4), 0xba5eba11); // Aligned - eeprom_write_dword((uint32_t*)(EEPROM_SIZE - 9), 0xcafed00d); // Unaligned + eeprom_write_dword((uint32_t*)(EEPROM_SIZE - 4), 0xba5eba11); // Aligned + eeprom_write_dword((uint32_t*)(EEPROM_SIZE - 9), 0xcafed00d); // Unaligned /* Check direct values */ EEPROM_Init(); EXPECT_EQ(eeprom_read_dword((uint32_t*)0), 0xdeadbeef); EXPECT_EQ(eeprom_read_dword((uint32_t*)9), 0x12345678); EXPECT_EQ(eeprom_read_dword((uint32_t*)200), 0xfacef00d); - EXPECT_EQ(eeprom_read_dword((uint32_t*)(EEPROM_SIZE - 4)), 0xba5eba11); // Aligned - EXPECT_EQ(eeprom_read_dword((uint32_t*)(EEPROM_SIZE - 9)), 0xcafed00d); // Unaligned + EXPECT_EQ(eeprom_read_dword((uint32_t*)(EEPROM_SIZE - 4)), 0xba5eba11); // Aligned + EXPECT_EQ(eeprom_read_dword((uint32_t*)(EEPROM_SIZE - 9)), 0xcafed00d); // Unaligned /* Write Log byte encoded */ eeprom_write_dword((uint32_t*)0, 0xdecafbad); eeprom_write_dword((uint32_t*)9, 0x87654321); /* Write Log word encoded */ eeprom_write_dword((uint32_t*)200, 1); /* Write Log word value aligned */ - eeprom_write_dword((uint32_t*)(EEPROM_SIZE - 4), 0xdeadc0de); // Aligned - eeprom_write_dword((uint32_t*)(EEPROM_SIZE - 9), 0x6789abcd); // Unaligned + eeprom_write_dword((uint32_t*)(EEPROM_SIZE - 4), 0xdeadc0de); // Aligned + eeprom_write_dword((uint32_t*)(EEPROM_SIZE - 9), 0x6789abcd); // Unaligned /* Check log values */ EEPROM_Init(); EXPECT_EQ(eeprom_read_dword((uint32_t*)0), 0xdecafbad); EXPECT_EQ(eeprom_read_dword((uint32_t*)9), 0x87654321); EXPECT_EQ(eeprom_read_dword((uint32_t*)200), 1); - EXPECT_EQ(eeprom_read_dword((uint32_t*)(EEPROM_SIZE - 4)), 0xdeadc0de); // Aligned - EXPECT_EQ(eeprom_read_dword((uint32_t*)(EEPROM_SIZE - 9)), 0x6789abcd); // Unaligned + EXPECT_EQ(eeprom_read_dword((uint32_t*)(EEPROM_SIZE - 4)), 0xdeadc0de); // Aligned + EXPECT_EQ(eeprom_read_dword((uint32_t*)(EEPROM_SIZE - 9)), 0x6789abcd); // Unaligned } TEST_F(EepromStm32Test, TestBlockRoundTrip) { diff --git a/platforms/test/eeprom_stm32_tests.h b/platforms/test/eeprom_stm32_tests.h new file mode 100644 index 0000000000..35ed885e52 --- /dev/null +++ b/platforms/test/eeprom_stm32_tests.h @@ -0,0 +1,8 @@ +// Copyright 2018-2022 Nick Brassel (@tzarc) +// SPDX-License-Identifier: GPL-2.0-or-later +#pragma once + +#include "flash_stm32.h" +#include "eeprom_stm32.h" + +#define EEPROM_SIZE (FEE_PAGE_SIZE * FEE_PAGE_COUNT / 2) diff --git a/platforms/test/flash_stm32_mock.c b/platforms/test/flash_stm32_mock.c index 222a004bc7..b6ab170f95 100644 --- a/platforms/test/flash_stm32_mock.c +++ b/platforms/test/flash_stm32_mock.c @@ -44,6 +44,12 @@ FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data) { } } -FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout) { return FLASH_COMPLETE; } -void FLASH_Unlock(void) { flash_locked = false; } -void FLASH_Lock(void) { flash_locked = true; } +FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout) { + return FLASH_COMPLETE; +} +void FLASH_Unlock(void) { + flash_locked = false; +} +void FLASH_Lock(void) { + flash_locked = true; +} diff --git a/platforms/test/rules.mk b/platforms/test/rules.mk index 66b853d8ee..55512c7392 100644 --- a/platforms/test/rules.mk +++ b/platforms/test/rules.mk @@ -1,4 +1,4 @@ -eeprom_stm32_DEFS := -DFLASH_STM32_MOCKED -DNO_PRINT -DFEE_FLASH_BASE=FlashBuf +eeprom_stm32_DEFS := -DEEPROM_TEST_HARNESS -DFLASH_STM32_MOCKED -DNO_PRINT -DFEE_FLASH_BASE=FlashBuf eeprom_stm32_tiny_DEFS := $(eeprom_stm32_DEFS) \ -DFEE_MCU_FLASH_SIZE=1 \ -DMOCK_FLASH_SIZE=1024 \ diff --git a/platforms/test/timer.c b/platforms/test/timer.c index 61c3a00201..e0acd1b16d 100644 --- a/platforms/test/timer.c +++ b/platforms/test/timer.c @@ -18,16 +18,34 @@ static uint32_t current_time = 0; -void timer_init(void) { current_time = 0; } +void timer_init(void) { + current_time = 0; +} -void timer_clear(void) { current_time = 0; } +void timer_clear(void) { + current_time = 0; +} -uint16_t timer_read(void) { return current_time & 0xFFFF; } -uint32_t timer_read32(void) { return current_time; } -uint16_t timer_elapsed(uint16_t last) { return TIMER_DIFF_16(timer_read(), last); } -uint32_t timer_elapsed32(uint32_t last) { return TIMER_DIFF_32(timer_read32(), last); } +uint16_t timer_read(void) { + return current_time & 0xFFFF; +} +uint32_t timer_read32(void) { + return current_time; +} +uint16_t timer_elapsed(uint16_t last) { + return TIMER_DIFF_16(timer_read(), last); +} +uint32_t timer_elapsed32(uint32_t last) { + return TIMER_DIFF_32(timer_read32(), last); +} -void set_time(uint32_t t) { current_time = t; } -void advance_time(uint32_t ms) { current_time += ms; } +void set_time(uint32_t t) { + current_time = t; +} +void advance_time(uint32_t ms) { + current_time += ms; +} -void wait_ms(uint32_t ms) { advance_time(ms); } +void wait_ms(uint32_t ms) { + advance_time(ms); +} diff --git a/platforms/timer.h b/platforms/timer.h index 02e39e79e7..d55f40f0b0 100644 --- a/platforms/timer.h +++ b/platforms/timer.h @@ -52,14 +52,22 @@ uint32_t timer_elapsed32(uint32_t last); # define TIMER_DIFF_FAST(a, b) TIMER_DIFF_16(a, b) # define timer_expired_fast(current, future) timer_expired(current, future) typedef uint16_t fast_timer_t; -fast_timer_t inline timer_read_fast(void) { return timer_read(); } -fast_timer_t inline timer_elapsed_fast(fast_timer_t last) { return timer_elapsed(last); } +fast_timer_t inline timer_read_fast(void) { + return timer_read(); +} +fast_timer_t inline timer_elapsed_fast(fast_timer_t last) { + return timer_elapsed(last); +} #else # define TIMER_DIFF_FAST(a, b) TIMER_DIFF_32(a, b) # define timer_expired_fast(current, future) timer_expired32(current, future) typedef uint32_t fast_timer_t; -fast_timer_t inline timer_read_fast(void) { return timer_read32(); } -fast_timer_t inline timer_elapsed_fast(fast_timer_t last) { return timer_elapsed32(last); } +fast_timer_t inline timer_read_fast(void) { + return timer_read32(); +} +fast_timer_t inline timer_elapsed_fast(fast_timer_t last) { + return timer_elapsed32(last); +} #endif #ifdef __cplusplus |