diff --git a/Keyboards/Pipfile b/Keyboards/Pipfile index ddb746ad5..871719254 100644 --- a/Keyboards/Pipfile +++ b/Keyboards/Pipfile @@ -4,7 +4,7 @@ verify_ssl = true name = "pypi" [packages] -kll = "==0.5.7.5" +kll = "==0.5.7.6" [dev-packages] diff --git a/Lib/CMake/kll.cmake b/Lib/CMake/kll.cmake index 14f5b3a34..e27c01e2e 100644 --- a/Lib/CMake/kll.cmake +++ b/Lib/CMake/kll.cmake @@ -43,7 +43,7 @@ endif () message ( STATUS "Checking for kll" ) ### XXX XXX XXX - Remember to update Pipfile as well when you change the version! ### -set ( KLL_MIN_VERSION "0.5.7.5" ) +set ( KLL_MIN_VERSION "0.5.7.6" ) # 1) Check for environment variable if ( NOT DEFINED KLL_EXECUTABLE ) diff --git a/Lib/storage.c b/Lib/storage.c index 5fbf04e4b..7b2a3bbe2 100644 --- a/Lib/storage.c +++ b/Lib/storage.c @@ -1,6 +1,6 @@ /** * Copyright (c) 2012 Atmel Corporation. All rights reserved. - * Modified by Jacob Alexander 2018 + * Modified by Jacob Alexander 2018-2019 * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -266,6 +266,12 @@ void storage_init() storage_buffer[i] = page_buffer[i + 449]; #endif } + + // If this is the first page, then set the cleared flag as no flash has been written + if ( page_walker == 0 ) + { + cleared_block = 1; + } } // If the block is within a page, go to previous block and fetch the data else @@ -350,6 +356,13 @@ uint8_t storage_write(uint8_t* data, uint16_t address, uint16_t size, uint8_t cl return 0; } + // Make sure this isn't the same data already set in flash + // If so, just exit, no need to wear the flash any further + if ( memcmp( storage_buffer, data, size ) == 0 ) + { + return 1; + } + // Set internal buffer to all 0xffs // This way it's possible to do partial writes to the page for ( int i = 0; i < STORAGE_FLASH_PAGE_SIZE; i++ ) @@ -482,16 +495,10 @@ int8_t storage_block_position() } // Returns 1 if storage has been cleared and will not have conflicts when changing the block size -// Or if there is no useful data in the non-volatile storage +// Or if there is no useful data in the non-volatile storage (i.e. completely empty, fresh erase) // storage_init() must be called first uint8_t storage_is_storage_cleared() { - // Check to see if this page is empty - if ( !find_cleared_block(storage_buffer) ) - { - return 1; - } - return cleared_block; } diff --git a/Macro/PixelMap/pixel.c b/Macro/PixelMap/pixel.c index 732892f22..45704b932 100644 --- a/Macro/PixelMap/pixel.c +++ b/Macro/PixelMap/pixel.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2018 by Jacob Alexander +/* Copyright (C) 2015-2019 by Jacob Alexander * * This file is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -82,21 +82,25 @@ typedef enum PixelTest { PixelTest_XY_Roll = 33, } PixelTest; + + // ----- Variables ----- -#if Storage_Enable_define == 1 typedef struct { - uint8_t animation_indices[Pixel_AnimationStackSize]; + uint8_t index; + uint8_t pos; +} PixelConfigElem; + +typedef struct { + PixelConfigElem animations[Pixel_AnimationStackSize]; PixelPeriodConfig fade_periods[4][4]; } PixelConfig; -static PixelConfig defaults = { - .animation_indices = {[0 ... Pixel_AnimationStackSize-1] = 255}, //Todo, use some kll define - // .fade_periods initialized later -}; - static PixelConfig settings; +#if Storage_Enable_define == 1 +static PixelConfig defaults; + static StorageModule PixelStorage = { .name = "Pixel Map", .settings = &settings, @@ -758,6 +762,49 @@ uint8_t Pixel_addAnimation( AnimationStackElement *element, CapabilityState csta Pixel_clearAnimations(); break; + // Clear all current animations from stack before adding new animation + // Unless it's paused, and if it's paused do a replace if necessary + case AnimationReplaceType_ClearActive: + found = Pixel_lookupAnimation( element->index, 0 ); + // If found, modify stack element + if ( found ) + { + found->pos = element->pos; + found->subpos = element->subpos; + found->loops = element->loops; + found->pfunc = element->pfunc; + found->ffunc = element->ffunc; + found->framedelay = element->framedelay; + found->frameoption = element->frameoption; + found->replace = element->replace; + found->state = element->state; + return 0; + } + + // Iterate through stack, stopping animations that are not paused + // and ignoring the found animation + for ( uint16_t pos = 0; pos < Pixel_AnimationStack.size; pos++ ) + { + // Ignore found animation + if ( Pixel_AnimationStack.stack[pos] == found ) + { + continue; + } + + // Ignore paused animations (single will be paused on the next frame) + if ( + Pixel_AnimationStack.stack[pos]->state == AnimationPlayState_Pause || + Pixel_AnimationStack.stack[pos]->state == AnimationPlayState_Single + ) + { + continue; + } + + // Otherwise stop + Pixel_AnimationStack.stack[pos]->state = AnimationPlayState_Stop; + } + break; + default: break; } @@ -2016,13 +2063,9 @@ void Pixel_SecondaryProcessing_setup() // Each of the periods for ( uint8_t pr = 0; pr < 4; pr++ ) { - // Lookup period using index - uint8_t period_index = Pixel_LED_FadePeriod_Defaults[pf][pr]; - PixelPeriodConfig conf = Pixel_LED_FadePeriods[period_index]; - // Set period to profile - Pixel_pixel_fade_profile_entries[pf].conf[pr].start = conf.start; - Pixel_pixel_fade_profile_entries[pf].conf[pr].end = conf.end; + PixelPeriodConfig conf = settings.fade_periods[pf][pr]; + Pixel_pixel_fade_profile_entries[pf].conf[pr] = conf; } // Reset state @@ -2245,23 +2288,21 @@ void Pixel_setAnimationControl( AnimationControl control ) // Starting Animation setup void Pixel_initializeStartAnimations() { - // Iterate over starting animations - for ( uint32_t index = 0; index < Pixel_AnimationSettingsNum_KLL; index++ ) + // Animations + for ( uint8_t pos = 0; pos < Pixel_AnimationStackSize; pos++ ) { - // Check if a starting animation - if ( Pixel_AnimationSettings[ index ].state == AnimationPlayState_Start ) - { - // Default animations are noted by the TriggerMacro *trigger pointer being set to 1 - if ( (uintptr_t)(Pixel_AnimationSettings[ index ].trigger) == 1 ) + uint8_t index = settings.animations[pos].index; + if (index != 255) { + AnimationStackElement element = Pixel_AnimationSettings[ index ]; + + // Only update state if not already defined + if ( element.state == AnimationPlayState_Pause ) { - // Start animation - if ( Pixel_addDefaultAnimation( index ) == 0 ) - { - warn_msg("Failed to start starting animation index: "); - printInt32( index ); - print( NL ); - } + element.state = AnimationPlayState_Start; } + + element.pos = settings.animations[pos].pos; + Pixel_addAnimation( &element, CapabilityState_None ); } } } @@ -2649,14 +2690,58 @@ inline void Pixel_setup() // Register Pixel CLI dictionary CLI_registerDictionary( pixelCLIDict, pixelCLIDictName ); - // Register storage module + // Iterate over starting animations + uint8_t add_animations = 0; + for ( uint32_t index = 0; index < Pixel_AnimationSettingsNum_KLL; index++ ) + { + // Check if a starting animation + if ( Pixel_AnimationSettings[ index ].state == AnimationPlayState_Start ) + { + // Default animations are noted by the TriggerMacro *trigger pointer being set to 1 + if ( (uintptr_t)(Pixel_AnimationSettings[ index ].trigger) == 1 ) + { + // Add animation to the defaults stack +#if Storage_Enable_define == 1 + defaults.animations[add_animations].index = index; + defaults.animations[add_animations].pos = Pixel_AnimationSettings[index].pos; +#else + settings.animations[add_animations].index = index; + settings.animations[add_animations].pos = Pixel_AnimationSettings[index].pos; +#endif + add_animations++; + } + } + } + + // Fill in rest of stack + for ( uint8_t animation = add_animations; animation < Pixel_AnimationStackSize; animation++ ) + { +#if Storage_Enable_define == 1 + defaults.animations[animation].index = 255; + defaults.animations[animation].pos = 0; +#else + settings.animations[animation].index = 255; + settings.animations[animation].pos = 0; +#endif + } + + // Setup fade defaults + for ( uint8_t profile = 0; profile < 4; profile++ ) + { + for ( uint8_t config = 0; config < 4; config++ ) + { #if Storage_Enable_define == 1 - for (uint8_t profile=0; profile<4; profile++) { - for (uint8_t config=0; config<4; config++) { defaults.fade_periods[profile][config] = Pixel_LED_FadePeriods[Pixel_LED_FadePeriod_Defaults[profile][config]]; +#else + settings.fade_periods[profile][config] = + Pixel_LED_FadePeriods[Pixel_LED_FadePeriod_Defaults[profile][config]]; +#endif } } + + // Register storage module +#if Storage_Enable_define == 1 Storage_registerModule(&PixelStorage); #endif @@ -3201,27 +3286,13 @@ void cliFunc_rectDisp( char* args ) #if Storage_Enable_define == 1 -void Pixel_loadConfig() { - // Animations - for ( uint8_t pos = 0; pos < Pixel_AnimationStackSize; pos++ ) - { - uint8_t index = settings.animation_indices[pos]; - if (index != 255) { - AnimationStackElement element = Pixel_AnimationSettings[ index ]; - element.state = AnimationPlayState_Start; - Pixel_addAnimation( &element, CapabilityState_None ); - } - } +void Pixel_loadConfig() +{ + // Animation setup + Pixel_initializeStartAnimations(); // Fade periods - for (uint8_t profile=0; profile<4; profile++) - { - for (uint8_t config=0; config<4; config++) - { - PixelPeriodConfig period_config = settings.fade_periods[profile][config]; - Pixel_pixel_fade_profile_entries[profile].conf[config] = period_config; - } - } + Pixel_SecondaryProcessing_setup(); } void Pixel_saveConfig() { @@ -3230,9 +3301,20 @@ void Pixel_saveConfig() { { if (pos < Pixel_AnimationStack.size) { AnimationStackElement *elem = Pixel_AnimationStack.stack[pos]; - settings.animation_indices[pos] = elem->index; + settings.animations[pos].index = elem->index; + + // Save position, only if paused + if ( elem->state == AnimationPlayState_Pause ) + { + settings.animations[pos].pos = elem->pos - 1; + } + else + { + settings.animations[pos].pos = 0; + } } else { - settings.animation_indices[pos] = 255; + settings.animations[pos].index = 255; + settings.animations[pos].pos = 0; } } @@ -3253,12 +3335,15 @@ void Pixel_printConfig() { print(" \033[35mAnimations\033[0m" NL); for ( uint8_t pos = 0; pos < Pixel_AnimationStackSize; pos++ ) { - uint8_t index = settings.animation_indices[pos]; + uint8_t index = settings.animations[pos].index; + uint8_t fpos = settings.animations[pos].pos; if (index != 255) { print("AnimationStack.stack["); printInt8(pos); print("]->index = "); printInt8(index); + print("; pos = "); + printInt8(fpos); print(NL); } } @@ -3278,6 +3363,7 @@ void Pixel_printConfig() { printInt8(period.start); print(", "); printInt8(period.end); + print("}"); print(NL); } } diff --git a/Macro/PixelMap/pixel.h b/Macro/PixelMap/pixel.h index 829d22108..ac46ee874 100644 --- a/Macro/PixelMap/pixel.h +++ b/Macro/PixelMap/pixel.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2015-2018 by Jacob Alexander +/* Copyright (C) 2015-2019 by Jacob Alexander * * This file is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -104,11 +104,12 @@ typedef enum PixelAddressType { // Animation Replace Type typedef enum AnimationReplaceType { - AnimationReplaceType_None = 0, // Don't replace (add new animation to stack if not full) - AnimationReplaceType_Basic = 1, // Replace only if the same trigger initiated - AnimationReplaceType_All = 2, // Replace no matter what trigger initiated - AnimationReplaceType_State = 3, // Using same trigger, start on Activate/Press, stop on Deactivate/Release - AnimationReplaceType_Clear = 4, // Clear all other animations before addi + AnimationReplaceType_None = 0, // Don't replace (add new animation to stack if not full) + AnimationReplaceType_Basic = 1, // Replace only if the same trigger initiated + AnimationReplaceType_All = 2, // Replace no matter what trigger initiated + AnimationReplaceType_State = 3, // Using same trigger, start on Activate/Press, stop on Deactivate/Release + AnimationReplaceType_Clear = 4, // Clear all other animations before adding + AnimationReplaceType_ClearActive = 5, // Clear all other animations before adding, except paused (replace those) } AnimationReplaceType; // Animation Play State diff --git a/Scan/Devices/ISSILed/led_scan.c b/Scan/Devices/ISSILed/led_scan.c index dfe8881fa..499f38eb9 100644 --- a/Scan/Devices/ISSILed/led_scan.c +++ b/Scan/Devices/ISSILed/led_scan.c @@ -213,18 +213,18 @@ CLIDict_Def( ledCLIDict, "ISSI LED Module Commands" ) = { { 0, 0, 0 } // Null entry for dictionary end }; -#if Storage_Enable_define == 1 // Storage Module typedef struct { uint8_t brightness; } LedConfig; +static LedConfig settings; + +#if Storage_Enable_define == 1 static LedConfig defaults = { .brightness = ISSI_Global_Brightness_define }; -static LedConfig settings; - static StorageModule LedStorage = { .name = "LED Scan", .settings = &settings, @@ -550,7 +550,7 @@ void LED_reset() } // Reset global brightness - LED_brightness = ISSI_Global_Brightness_define; + LED_brightness = settings.brightness; #if ISSI_Chip_31FL3733_define == 1 // Enable pull-up and pull-down anti-ghosting resistors @@ -1279,7 +1279,7 @@ void cliFunc_ledSet( char* args ) // Reset brightness if ( *arg1Ptr == '\0' ) { - LED_setBrightness( ISSI_Global_Brightness_define ); + LED_setBrightness( settings.brightness ); } else {