From eb660ef2184565c6bb69f1f67f7af8918d15688f Mon Sep 17 00:00:00 2001 From: Nick Choi Date: Mon, 15 May 2017 01:52:45 -0400 Subject: emoji support but --- keyboards/frosty_flake/keymaps/nikchi/Makefile | 2 +- keyboards/frosty_flake/keymaps/nikchi/keymap.c | 99 +++++++++++++++++++------- keyboards/frosty_flake/rules.mk | 5 +- quantum/process_keycode/process_unicodemap.c | 2 +- 4 files changed, 78 insertions(+), 30 deletions(-) diff --git a/keyboards/frosty_flake/keymaps/nikchi/Makefile b/keyboards/frosty_flake/keymaps/nikchi/Makefile index 377a25c28..ad86e82d2 100644 --- a/keyboards/frosty_flake/keymaps/nikchi/Makefile +++ b/keyboards/frosty_flake/keymaps/nikchi/Makefile @@ -12,7 +12,7 @@ BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality MIDI_ENABLE = no # MIDI controls AUDIO_ENABLE = no # Audio output on port C6 UNICODE_ENABLE = no # Unicode -UNICODEMAP_ENABLE = no # unicodemap +UNICODEMAP_ENABLE = yes # unicodemap BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time. SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend diff --git a/keyboards/frosty_flake/keymaps/nikchi/keymap.c b/keyboards/frosty_flake/keymaps/nikchi/keymap.c index 955891eb2..58964d1e3 100644 --- a/keyboards/frosty_flake/keymaps/nikchi/keymap.c +++ b/keyboards/frosty_flake/keymaps/nikchi/keymap.c @@ -1,4 +1,9 @@ #include "frosty_flake.h" +#include "action_layer.h" +#include "eeconfig.h" +#include "process_unicode.h" +#include "quantum.h" + #define _______ KC_TRNS //Tap Dance Declarations @@ -13,25 +18,32 @@ qk_tap_dance_action_t tap_dance_actions[] = { // Other declarations would go here, separated by commas, if you have them }; +enum my_macros { + NEWDESK = 0, + LEFTDESK, + RIGHTDESK, + CLOSEDESK +}; + const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) // this is the function signature -- just copy/paste it into your keymap file as it is. { switch(id) { - case 0: // this would trigger when you hit a key mapped as M(0) + case NEWDESK: // this would trigger when you hit a key mapped as M(0) if (record->event.pressed) { return MACRO( I(1), D(LGUI), D(LCTL), D(D), U(LGUI), U(LCTL), U(D), END ); // NEW DESKTOP } break; - case 1: // this would trigger when you hit a key mapped as M(0) + case LEFTDESK: // this would trigger when you hit a key mapped as M(0) if (record->event.pressed) { return MACRO( I(1), D(LGUI), D(LCTL), D(LEFT), U(LGUI), U(LCTL), U(LEFT), END ); // LEFT DESKTOP } break; - case 2: // this would trigger when you hit a key mapped as M(0) + case RIGHTDESK: // this would trigger when you hit a key mapped as M(0) if (record->event.pressed) { return MACRO( I(1), D(LGUI), D(LCTL), D(RGHT), U(LGUI), U(LCTL), U(RGHT), END ); // RIGHT DESKTOP } break; - case 3: // this would trigger when you hit a key mapped as M(0) + case CLOSEDESK: // this would trigger when you hit a key mapped as M(0) if (record->event.pressed) { return MACRO( I(1), D(LGUI), D(LCTL), D(F4), U(LGUI), U(LCTL), U(F4), END ); // CLOSE DESKTOP } @@ -40,25 +52,36 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) // return MACRO_NONE; }; -LEADER_EXTERNS(); - -void matrix_scan_user(void) { - LEADER_DICTIONARY() { - leading = false; - leader_end(); - - SEQ_TWO_KEYS(KC_A, KC_A) { - register_code(KC_LCTL); - register_code(KC_A); - unregister_code(KC_A); - register_code(KC_C); - unregister_code(KC_C); - unregister_code(KC_LCTL); - } - } -} +enum unicode_name { + THINK, // thinking face 🤔 + GRIN, // grinning face 😊 + BBB, // dat B 🅱 + POO, // poop 💩 + HUNDR, // 100 💯 + SMRK, // smirk 😏 + WEARY, // good shit 😩 + EGGPL, // EGGPLANT 🍆 + WATER, // wet 💦 + LIT, // fire 🔥 + UNAMU, // unamused 😒 + SNEK // snke 🐍 +}; +const uint32_t PROGMEM unicode_map[] = { + [THINK] = 0x1F914, + [GRIN] = 0x1F600, + [BBB] = 0x1F171, + [POO] = 0x1F4A9, + [HUNDR] = 0x1F4AF, + [SMRK] = 0x1F60F, + [WEARY] = 0x1F629, + [EGGPL] = 0x1F346, + [WATER] = 0x1F4A6, + [LIT] = 0x1F525, + [UNAMU] = 0x1F612, + [SNEK] = 0x1F40D + }; const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [0] = KEYMAP(\ @@ -70,10 +93,10 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { TD(TD_CTCPS),KC_LGUI,KC_LALT, KC_SPC, KC_LEAD,KC_RGUI, KC_APP,MO(1) , KC_LEFT,KC_DOWN,KC_RGHT, KC_P0,KC_PDOT), [1] = KEYMAP(\ KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_PSCR,KC_SLCK,KC_PAUS, \ - KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0,KC_MINS, KC_EQL,KC_BSPC, KC_MPRV,KC_MPLY,KC_MNXT, KC_NLCK,KC_PSLS,KC_PAST,KC_PMNS, \ - KC_TAB, KC_Q, M(0), KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P,KC_LBRC,KC_RBRC,KC_BSLS, KC_MUTE,KC_VOLD,KC_VOLU, KC_P7, KC_P8, KC_P9,KC_PPLS, \ - KC_LCTL, M(1), M(3), M(2), KC_F, KC_G, KC_H, KC_J, KC_K, KC_L,KC_SCLN,KC_QUOT, KC_ENT, KC_P4, KC_P5, KC_P6, \ - KC_LSFT,KC_NUBS, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M,KC_COMM, KC_DOT,KC_SLSH, KC_RSFT, KC_MS_U, KC_P1, KC_P2, KC_P3,KC_PENT, \ + KC_GRV, X(GRIN),X(THINK),X(SMRK),X(WEARY),X(UNAMU), KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL,KC_BSPC, KC_MPRV,KC_MPLY,KC_MNXT, KC_NLCK,KC_PSLS,KC_PAST,KC_PMNS, \ + KC_TAB, KC_Q, M(0), KC_E, KC_R,X(EGGPL),X(WATER), KC_U, KC_I, KC_O, KC_P, KC_UP ,KC_RBRC,KC_BSLS, KC_MUTE,KC_VOLD,KC_VOLU, KC_P7, KC_P8, KC_P9,KC_PPLS, \ + KC_LCTL, M(1), M(3), M(2), KC_F, X(LIT), X(SNEK), KC_J, KC_K, KC_L,KC_LEFT,KC_RGHT, KC_ENT, KC_P4, KC_P5, KC_P6, \ + KC_LSFT,KC_NUBS, KC_Z, KC_X, KC_C, X(HUNDR), X(BBB), X(POO), KC_M,KC_COMM, KC_DOT,KC_DOWN, KC_RSFT, KC_MS_U, KC_P1, KC_P2, KC_P3,KC_PENT, \ KC_BTN1,KC_BTN3,KC_BTN2, KC_SPC, KC_RALT,KC_RGUI, TG(2),_______ , KC_MS_L,KC_MS_D,KC_MS_R, KC_P0,KC_PDOT), [2] = KEYMAP(\ KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_PSCR,KC_SLCK,KC_PAUS, \ @@ -81,5 +104,29 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P,KC_LBRC,KC_RBRC,KC_BSLS, KC_MUTE,KC_VOLD,KC_VOLU, KC_P7, KC_P8, KC_P9,KC_PPLS, \ KC_LCTL, KC_D, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L,KC_SCLN,KC_QUOT, KC_ENT, KC_P4, KC_P5, KC_P6, \ KC_LSFT,KC_NUBS, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M,KC_COMM, KC_DOT,KC_SLSH, KC_RSFT, KC_MS_U, KC_P1, KC_P2, KC_P3,KC_PENT, \ - KC_BTN1,KC_BTN3,KC_BTN2, KC_SPC, KC_RALT,KC_RGUI, _______,_______ , KC_MS_L,KC_MS_D,KC_MS_R, KC_P0,KC_PDOT), + KC_BTN1,KC_BTN3,KC_BTN2, KC_SPC, KC_RALT,KC_RGUI, _______, _______, KC_MS_L,KC_MS_D,KC_MS_R, KC_P0,KC_PDOT), +}; + +LEADER_EXTERNS(); + +void matrix_scan_user(void) { + LEADER_DICTIONARY() { + leading = false; + leader_end(); + + SEQ_TWO_KEYS(KC_A, KC_A) { + register_code(KC_LCTL); + register_code(KC_A); + unregister_code(KC_A); + register_code(KC_C); + unregister_code(KC_C); + unregister_code(KC_LCTL); + } + + } +} + +void matrix_init_user(void) { + _delay_ms(500); + set_unicode_input_mode(UC_WINC); }; diff --git a/keyboards/frosty_flake/rules.mk b/keyboards/frosty_flake/rules.mk index dd2f4b6ee..8c59241d4 100644 --- a/keyboards/frosty_flake/rules.mk +++ b/keyboards/frosty_flake/rules.mk @@ -54,8 +54,8 @@ OPT_DEFS += -DBOOTLOADER_SIZE=4096 BOOTMAGIC_ENABLE ?= no # Virtual DIP switch configuration(+1000) MOUSEKEY_ENABLE ?= yes # Mouse keys(+4700) EXTRAKEY_ENABLE ?= yes # Audio control and System control(+450) -CONSOLE_ENABLE ?= yes # Console for debug(+400) -COMMAND_ENABLE ?= yes # Commands for debug and configuration +CONSOLE_ENABLE ?= no # Console for debug(+400) +COMMAND_ENABLE ?= no # Commands for debug and configuration # Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE SLEEP_LED_ENABLE ?= no # Breathing sleep LED during USB suspend # if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work @@ -63,6 +63,7 @@ NKRO_ENABLE ?= no # USB Nkey Rollover BACKLIGHT_ENABLE ?= no # Enable keyboard backlight functionality on B7 by default MIDI_ENABLE ?= no # MIDI controls UNICODE_ENABLE ?= no # Unicode +UNICODEMAP_ENABLE ?= yes BLUETOOTH_ENABLE ?= no # Enable Bluetooth with the Adafruit EZ-Key HID AUDIO_ENABLE ?= no # Audio output on port C6 FAUXCLICKY_ENABLE ?= no # Use buzzer to emulate clicky switches diff --git a/quantum/process_keycode/process_unicodemap.c b/quantum/process_keycode/process_unicodemap.c index 0227fbdd7..75f35112b 100644 --- a/quantum/process_keycode/process_unicodemap.c +++ b/quantum/process_keycode/process_unicodemap.c @@ -49,7 +49,7 @@ bool process_unicode_map(uint16_t keycode, keyrecord_t *record) { if ((keycode & QK_UNICODE_MAP) == QK_UNICODE_MAP && record->event.pressed) { const uint32_t* map = unicode_map; uint16_t index = keycode - QK_UNICODE_MAP; - uint32_t code = pgm_read_dword_far(&map[index]); + uint32_t code = pgm_read_dword(&map[index]); if (code > 0xFFFF && code <= 0x10ffff && input_mode == UC_OSX) { // Convert to UTF-16 surrogate pair code -= 0x10000; -- cgit v1.2.3 '>210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385
/*
    ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
                 2011,2012 Giovanni Di Sirio.

    This file is part of ChibiOS/RT.

    ChibiOS/RT 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.

    ChibiOS/RT 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/>.
*/

/**
 * @file    STM32/spi_lld.h
 * @brief   STM32 SPI subsystem low level driver header.
 *
 * @addtogroup SPI
 * @{
 */

#ifndef _SPI_LLD_H_
#define _SPI_LLD_H_

#if HAL_USE_SPI || defined(__DOXYGEN__)

/*===========================================================================*/
/* Driver constants.                                                         */
/*===========================================================================*/

/*===========================================================================*/
/* Driver pre-compile time settings.                                         */
/*===========================================================================*/

/**
 * @name    Configuration options
 * @{
 */
/**
 * @brief   SPI1 driver enable switch.
 * @details If set to @p TRUE the support for SPI1 is included.
 * @note    The default is @p TRUE.
 */
#if !defined(STM32_SPI_USE_SPI1) || defined(__DOXYGEN__)
#define STM32_SPI_USE_SPI1                  TRUE
#endif

/**
 * @brief   SPI2 driver enable switch.
 * @details If set to @p TRUE the support for SPI2 is included.
 * @note    The default is @p TRUE.
 */
#if !defined(STM32_SPI_USE_SPI2) || defined(__DOXYGEN__)
#define STM32_SPI_USE_SPI2                  TRUE
#endif

/**
 * @brief   SPI3 driver enable switch.
 * @details If set to @p TRUE the support for SPI3 is included.
 * @note    The default is @p TRUE.
 */
#if !defined(STM32_SPI_USE_SPI3) || defined(__DOXYGEN__)
#define STM32_SPI_USE_SPI3                  FALSE
#endif

/**
 * @brief   SPI1 interrupt priority level setting.
 */
#if !defined(STM32_SPI_SPI1_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_SPI_SPI1_IRQ_PRIORITY         10
#endif

/**
 * @brief   SPI2 interrupt priority level setting.
 */
#if !defined(STM32_SPI_SPI2_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_SPI_SPI2_IRQ_PRIORITY         10
#endif

/**
 * @brief   SPI3 interrupt priority level setting.
 */
#if !defined(STM32_SPI_SPI3_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_SPI_SPI3_IRQ_PRIORITY         10
#endif

/**
 * @brief   SPI1 DMA priority (0..3|lowest..highest).
 * @note    The priority level is used for both the TX and RX DMA streams but
 *          because of the streams ordering the RX stream has always priority
 *          over the TX stream.
 */
#if !defined(STM32_SPI_SPI1_DMA_PRIORITY) || defined(__DOXYGEN__)
#define STM32_SPI_SPI1_DMA_PRIORITY         1
#endif

/**
 * @brief   SPI2 DMA priority (0..3|lowest..highest).
 * @note    The priority level is used for both the TX and RX DMA streams but
 *          because of the streams ordering the RX stream has always priority
 *          over the TX stream.
 */
#if !defined(STM32_SPI_SPI2_DMA_PRIORITY) || defined(__DOXYGEN__)
#define STM32_SPI_SPI2_DMA_PRIORITY         1
#endif

/**
 * @brief   SPI3 DMA priority (0..3|lowest..highest).
 * @note    The priority level is used for both the TX and RX DMA streams but
 *          because of the streams ordering the RX stream has always priority
 *          over the TX stream.
 */
#if !defined(STM32_SPI_SPI3_DMA_PRIORITY) || defined(__DOXYGEN__)
#define STM32_SPI_SPI3_DMA_PRIORITY         1
#endif

/**
 * @brief   SPI DMA error hook.
 */
#if !defined(STM32_SPI_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
#define STM32_SPI_DMA_ERROR_HOOK(spip)      chSysHalt()
#endif

#if STM32_ADVANCED_DMA || defined(__DOXYGEN__)

/**
 * @brief   DMA stream used for SPI1 RX operations.
 * @note    This option is only available on platforms with enhanced DMA.
 */
#if !defined(STM32_SPI_SPI1_RX_DMA_STREAM) || defined(__DOXYGEN__)
#define STM32_SPI_SPI1_RX_DMA_STREAM        STM32_DMA_STREAM_ID(2, 0)
#endif

/**
 * @brief   DMA stream used for SPI1 TX operations.
 * @note    This option is only available on platforms with enhanced DMA.
 */
#if !defined(STM32_SPI_SPI1_TX_DMA_STREAM) || defined(__DOXYGEN__)
#define STM32_SPI_SPI1_TX_DMA_STREAM        STM32_DMA_STREAM_ID(2, 3)
#endif

/**
 * @brief   DMA stream used for SPI2 RX operations.
 * @note    This option is only available on platforms with enhanced DMA.
 */
#if !defined(STM32_SPI_SPI2_RX_DMA_STREAM) || defined(__DOXYGEN__)
#define STM32_SPI_SPI2_RX_DMA_STREAM        STM32_DMA_STREAM_ID(1, 3)
#endif

/**
 * @brief   DMA stream used for SPI2 TX operations.
 * @note    This option is only available on platforms with enhanced DMA.
 */
#if !defined(STM32_SPI_SPI2_TX_DMA_STREAM) || defined(__DOXYGEN__)
#define STM32_SPI_SPI2_TX_DMA_STREAM        STM32_DMA_STREAM_ID(1, 4)
#endif

/**
 * @brief   DMA stream used for SPI3 RX operations.
 * @note    This option is only available on platforms with enhanced DMA.
 */
#if !defined(STM32_SPI_SPI3_RX_DMA_STREAM) || defined(__DOXYGEN__)
#define STM32_SPI_SPI3_RX_DMA_STREAM        STM32_DMA_STREAM_ID(1, 0)
#endif

/**
 * @brief   DMA stream used for SPI3 TX operations.
 * @note    This option is only available on platforms with enhanced DMA.
 */
#if !defined(STM32_SPI_SPI3_TX_DMA_STREAM) || defined(__DOXYGEN__)
#define STM32_SPI_SPI3_TX_DMA_STREAM        STM32_DMA_STREAM_ID(1, 7)
#endif

#else /* !STM32_ADVANCED_DMA */

/* Fixed streams for platforms using the old DMA peripheral, the values are
   valid for both STM32F1xx and STM32L1xx.*/
#define STM32_SPI_SPI1_RX_DMA_STREAM        STM32_DMA_STREAM_ID(1, 2)
#define STM32_SPI_SPI1_TX_DMA_STREAM        STM32_DMA_STREAM_ID(1, 3)
#define STM32_SPI_SPI2_RX_DMA_STREAM        STM32_DMA_STREAM_ID(1, 4)
#define STM32_SPI_SPI2_TX_DMA_STREAM        STM32_DMA_STREAM_ID(1, 5)
#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)

#endif /* !STM32_ADVANCED_DMA*/
/** @} */

/*===========================================================================*/
/* Derived constants and error checks.                                       */
/*===========================================================================*/

#if STM32_SPI_USE_SPI1 && !STM32_HAS_SPI1
#error "SPI1 not present in the selected device"
#endif

#if STM32_SPI_USE_SPI2 && !STM32_HAS_SPI2
#error "SPI2 not present in the selected device"
#endif

#if STM32_SPI_USE_SPI3 && !STM32_HAS_SPI3
#error "SPI3 not present in the selected device"
#endif

#if !STM32_SPI_USE_SPI1 && !STM32_SPI_USE_SPI2 && !STM32_SPI_USE_SPI3
#error "SPI driver activated but no SPI peripheral assigned"
#endif

#if STM32_SPI_USE_SPI1 &&                                                   \
    !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI1_RX_DMA_STREAM, STM32_SPI1_RX_DMA_MSK)
#error "invalid DMA stream associated to SPI1 RX"
#endif

#if STM32_SPI_USE_SPI1 &&                                                   \
    !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI1_TX_DMA_STREAM, STM32_SPI1_TX_DMA_MSK)
#error "invalid DMA stream associated to SPI1 TX"
#endif

#if STM32_SPI_USE_SPI2 &&                                                   \
    !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI2_RX_DMA_STREAM, STM32_SPI2_RX_DMA_MSK)
#error "invalid DMA stream associated to SPI2 RX"
#endif

#if STM32_SPI_USE_SPI2 &&                                                   \
    !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI2_TX_DMA_STREAM, STM32_SPI2_TX_DMA_MSK)
#error "invalid DMA stream associated to SPI2 TX"
#endif

#if STM32_SPI_USE_SPI3 &&                                                   \
    !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI3_RX_DMA_STREAM, STM32_SPI3_RX_DMA_MSK)
#error "invalid DMA stream associated to SPI3 RX"
#endif

#if STM32_SPI_USE_SPI3 &&                                                   \
    !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI3_TX_DMA_STREAM, STM32_SPI3_TX_DMA_MSK)
#error "invalid DMA stream associated to SPI3 TX"
#endif

#if !defined(STM32_DMA_REQUIRED)
#define STM32_DMA_REQUIRED
#endif

/*===========================================================================*/
/* Driver data structures and types.                                         */
/*===========================================================================*/

/**
 * @brief   Type of a structure representing an SPI driver.
 */
typedef struct SPIDriver SPIDriver;

/**
 * @brief   SPI notification callback type.
 *
 * @param[in] spip      pointer to the @p SPIDriver object triggering the
 *                      callback
 */
typedef void (*spicallback_t)(SPIDriver *spip);

/**
 * @brief   Driver configuration structure.
 */
typedef struct {
  /**
   * @brief Operation complete callback or @p NULL.
   */
  spicallback_t             end_cb;
  /* End of the mandatory fields.*/
  /**
   * @brief The chip select line port.
   */
  ioportid_t                ssport;
  /**
   * @brief The chip select line pad number.
   */
  uint16_t                  sspad;
  /**
   * @brief SPI initialization data.
   */
  uint16_t                  cr1;
} SPIConfig;

/**
 * @brief   Structure representing a SPI driver.
 */
struct SPIDriver{
  /**
   * @brief Driver state.
   */
  spistate_t                state;
  /**
   * @brief Current configuration data.
   */
  const SPIConfig           *config;
#if SPI_USE_WAIT || defined(__DOXYGEN__)
  /**
   * @brief Waiting thread.
   */
  Thread                    *thread;
#endif /* SPI_USE_WAIT */
#if SPI_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
  /**
   * @brief Mutex protecting the bus.
   */
  Mutex                     mutex;
#elif CH_USE_SEMAPHORES
  Semaphore                 semaphore;
#endif
#endif /* SPI_USE_MUTUAL_EXCLUSION */
#if defined(SPI_DRIVER_EXT_FIELDS)
  SPI_DRIVER_EXT_FIELDS
#endif
  /* End of the mandatory fields.*/
  /**
   * @brief Pointer to the SPIx registers block.
   */
  SPI_TypeDef               *spi;
  /**
   * @brief Receive DMA stream.
   */
  const stm32_dma_stream_t  *dmarx;
  /**
   * @brief Transmit DMA stream.
   */
  const stm32_dma_stream_t  *dmatx;
  /**
   * @brief RX DMA mode bit mask.
   */
  uint32_t                  rxdmamode;
  /**
   * @brief TX DMA mode bit mask.
   */
  uint32_t                  txdmamode;
};

/*===========================================================================*/
/* Driver macros.                                                            */
/*===========================================================================*/

/*===========================================================================*/
/* External declarations.                                                    */
/*===========================================================================*/

#if STM32_SPI_USE_SPI1 && !defined(__DOXYGEN__)
extern SPIDriver SPID1;
#endif

#if STM32_SPI_USE_SPI2 && !defined(__DOXYGEN__)
extern SPIDriver SPID2;
#endif

#if STM32_SPI_USE_SPI3 && !defined(__DOXYGEN__)
extern SPIDriver SPID3;
#endif

#ifdef __cplusplus
extern "C" {
#endif
  void spi_lld_init(void);
  void spi_lld_start(SPIDriver *spip);
  void spi_lld_stop(SPIDriver *spip);
  void spi_lld_select(SPIDriver *spip);
  void spi_lld_unselect(SPIDriver *spip);
  void spi_lld_ignore(SPIDriver *spip, size_t n);
  void spi_lld_exchange(SPIDriver *spip, size_t n,
                        const void *txbuf, void *rxbuf);
  void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf);
  void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf);
  uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame);
#ifdef __cplusplus
}
#endif

#endif /* HAL_USE_SPI */

#endif /* _SPI_LLD_H_ */

/** @} */