From 9ed526deb669d793a2bd5a53d094f4cfbe17425c Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Sun, 3 Jan 2016 16:16:41 -0800 Subject: [PATCH] Adding PixelMap - Includes basic (led) channel testing tools - Currently hard-coded, needs kll integration before this can be used in general --- Macro/PixelMap/capabilities.kll | 9 + Macro/PixelMap/pixel.c | 358 ++++++++++++++++++++++++++++++++ Macro/PixelMap/pixel.h | 102 +++++++++ Macro/PixelMap/setup.cmake | 31 +++ Scan/ISSILed/led_scan.c | 334 +++++++++++++---------------- Scan/MatrixARM/matrix_scan.c | 1 + 6 files changed, 646 insertions(+), 189 deletions(-) create mode 100644 Macro/PixelMap/capabilities.kll create mode 100644 Macro/PixelMap/pixel.c create mode 100644 Macro/PixelMap/pixel.h create mode 100644 Macro/PixelMap/setup.cmake diff --git a/Macro/PixelMap/capabilities.kll b/Macro/PixelMap/capabilities.kll new file mode 100644 index 0000000..3d5202d --- /dev/null +++ b/Macro/PixelMap/capabilities.kll @@ -0,0 +1,9 @@ +Name = PartialMapCapabilities; +Version = 0.1; +Author = "HaaTa (Jacob Alexander) 2015"; +KLL = 0.5; + +# Modified Date +Date = 2015-12-19; + + diff --git a/Macro/PixelMap/pixel.c b/Macro/PixelMap/pixel.c new file mode 100644 index 0000000..4d188fa --- /dev/null +++ b/Macro/PixelMap/pixel.c @@ -0,0 +1,358 @@ +/* Copyright (C) 2015-2016 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 + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This file 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 file. If not, see . + */ + +// ----- Includes ----- + +// Compiler Includes +#include + +// Project Includes +#include +#include +#include +#include + +// Local Includes +#include "pixel.h" + + + +// ----- Function Declarations ----- + +void cliFunc_chanTest ( char* args ); +void cliFunc_pixelList ( char* args ); +void cliFunc_pixelTest ( char* args ); + + + +// ----- Enums ----- + +typedef enum PixelTest { + PixelTest_Off = 0, // Disabled + PixelTest_Chan_All, // Enable all positions + PixelTest_Chan_Roll, // Iterate over all positions + PixelTest_Pixel_All, // Enable all positions + PixelTest_Pixel_Roll, // Iterate over all positions +} PixelTest; + + + +// ----- Variables ----- + +// Macro Module command dictionary +CLIDict_Entry( chanTest, "Channel test. No arg - next pixel. # - pixel, r - roll-through. a - all, s - stop" ); +CLIDict_Entry( pixelList, "Prints out pixel:channel mappings." ); +CLIDict_Entry( pixelTest, "Pixel test. No arg - next pixel. # - pixel, r - roll-through. a - all, s - stop" ); + +CLIDict_Def( pixelCLIDict, "Pixel Module Commands" ) = { + CLIDict_Item( chanTest ), + CLIDict_Item( pixelList ), + CLIDict_Item( pixelTest ), + { 0, 0, 0 } // Null entry for dictionary end +}; + +// Debug states +PixelTest Pixel_testMode; +uint16_t Pixel_testPos; + +// Frame State +// Indicates to pixel and output modules current state of the buffer +FrameState Pixel_FrameState; + + + + +// ------------------------------- +// TODO This part is generated +// ------------------------------- + +// TODO Generate list of buffers and pointers from kll +#define LED_BufferLength 144 +typedef struct LED_Buffer { + uint16_t i2c_addr; + uint16_t reg_addr; + uint16_t buffer[LED_BufferLength]; +} LED_Buffer; +extern LED_Buffer LED_pageBuffer[ ISSI_Chips_define ]; + + +// Buffer list +#define Pixel_BuffersLen 3 +#define Pixel_TotalChannels 432 +PixelBuf Pixel_Buffers[] = { + PixelBufElem( LED_BufferLength, 16, 0, LED_pageBuffer[0].buffer ), + PixelBufElem( LED_BufferLength, 16, 144, LED_pageBuffer[1].buffer ), + PixelBufElem( LED_BufferLength, 16, 288, LED_pageBuffer[2].buffer ), +}; + + +// Pixel Mapping +uint8_t Pixel_Mapping[] = { + Pixel_RGBChannel(0,1,2), + // TODO +}; + +// Frame of led changes +// const uint8_t _frame[] = { PixelMod, ... } +#define Pixel_ModRGB(pixel,type,r,g,b) pixel, PixelChange_##type, 1, r, g, b +const uint8_t testani_frame0[] = { + Pixel_ModRGB(0, Set, 30, 70, 120), +}; +const uint8_t testani_frame1[] = { + Pixel_ModRGB(0, Set, 0, 0, 0), +}; +const uint8_t testani_frame2[] = { + Pixel_ModRGB(0, Set, 60, 90, 140), +}; + +// Index of frames for animations +// uint8_t *_frames[] = { _frame, ... } +const uint8_t *testani_frames[] = { + testani_frame0, + testani_frame1, + testani_frame2, +}; + +// Index of animations +// uint8_t *Pixel_Animations[] = { _frames, ... } +const uint8_t **Pixel_Animations[] = { + testani_frames, +}; + +// ------------------------------- +// TODO GENERATED END +// ------------------------------- + + + +// ----- Capabilities ----- + + + +// ----- Functions ----- + +PixelBuf Pixel_bufferMap( uint16_t channel ) +{ + // TODO Generate + if ( channel < 144 ) return Pixel_Buffers[0]; + else if ( channel < 288 ) return Pixel_Buffers[1]; + else if ( channel < 432 ) return Pixel_Buffers[2]; + + // Invalid channel, return first channel and display error + erro_msg("Invalid channel: "); + printHex( channel ); + print( NL ); + return Pixel_Buffers[0]; +} + +void Pixel_channelToggle( uint16_t channel ) +{ + // Determine which buffer we are in + PixelBuf pixbuf = Pixel_bufferMap( channel ); + + // Toggle channel accordingly + switch ( pixbuf.width ) + { + // Invalid width, default to 8 + default: + warn_msg("Unknown width, using 8: "); + printInt8( pixbuf.width ); + print(" Ch: "); + printHex( channel ); + print( NL ); + // Falls through on purpose + + // 8bit width + case 8: + PixelBuf8( pixbuf, channel ) ^= 128; + break; + + // 16bit width + case 16: + PixelBuf16( pixbuf, channel ) ^= 128; + break; + } +} + +// Pixel Procesing Loop +inline void Pixel_process() +{ + // Only update frame when ready + if ( Pixel_FrameState != FrameState_Update ) + return; + + // First check if we are in a test mode + switch ( Pixel_testMode ) + { + // Toggle current position, then increment + case PixelTest_Chan_Roll: + // Toggle channel + Pixel_channelToggle( Pixel_testPos ); + + // Increment channel + Pixel_testPos++; + if ( Pixel_testPos >= Pixel_TotalChannels ) + Pixel_testPos = 0; + + goto pixel_process_done; + + // Blink all channels + case PixelTest_Chan_All: + { + uint16_t ch; + + // Only update 50 positions at a time + for ( ch = Pixel_testPos; ch < Pixel_testPos + 50 && ch < Pixel_TotalChannels; ch++ ) + { + // Toggle channel + Pixel_channelToggle( ch ); + } + + Pixel_testPos = ch; + + // Only signal frame update after all pixels complete + if ( Pixel_testPos >= Pixel_TotalChannels ) + { + Pixel_testPos = 0; + goto pixel_process_done; + } + + return; + } + + default: + break; + } + + +pixel_process_done: + // Frame is now ready to send + Pixel_FrameState = FrameState_Ready; +} + + +inline void Pixel_setup() +{ + // Register Pixel CLI dictionary + CLI_registerDictionary( pixelCLIDict, pixelCLIDictName ); + + // Set frame state to update + Pixel_FrameState = FrameState_Update; + + // Disable test modes by default, start at position 0 + Pixel_testMode = PixelTest_Off; +} + + +// ----- CLI Command Functions ----- + +void cliFunc_pixelList( char* args ) +{ + print( NL ); // No \r\n by default after the command is entered + + char* curArgs; + char* arg1Ptr; + char* arg2Ptr = args; + + // Process speed argument if given + curArgs = arg2Ptr; + CLI_argumentIsolation( curArgs, &arg1Ptr, &arg2Ptr ); + + // Check for special args + switch ( *arg1Ptr ) + { + case 'b': + case 'B': + info_msg("Buffer List"); + + // List all buffers + for ( uint8_t buf = 0; buf < Pixel_BuffersLen; buf++ ) + { + print( NL "\t" ); + printInt8( buf ); + print(":"); + printHex32( (uint32_t)(Pixel_Buffers[ buf ].data) ); + print(":width("); + printInt8( Pixel_Buffers[ buf ].width ); + print("):size("); + printInt8( Pixel_Buffers[ buf ].size ); + print(")"); + } + break; + } +} + +void cliFunc_pixelTest( char* args ) +{ + print( NL ); +} + +void cliFunc_chanTest( char* args ) +{ + print( NL ); // No \r\n by default after the command is entered + + char* curArgs; + char* arg1Ptr; + char* arg2Ptr = args; + + // Process speed argument if given + curArgs = arg2Ptr; + CLI_argumentIsolation( curArgs, &arg1Ptr, &arg2Ptr ); + + // Check for special args + switch ( *arg1Ptr ) + { + case 'a': + case 'A': + info_msg("All channel test"); + Pixel_testPos = 0; + Pixel_testMode = PixelTest_Chan_All; + return; + + case 'r': + case 'R': + info_msg("Channel roll test"); + Pixel_testPos = 0; + Pixel_testMode = PixelTest_Chan_Roll; + return; + + case 's': + case 'S': + info_msg("Stopping channel test"); + Pixel_testMode = PixelTest_Off; + return; + } + + // Check for specific position + if ( *arg1Ptr != '\0' ) + { + Pixel_testPos = numToInt( arg1Ptr ); + } + else + { + info_msg("Channel: "); + printInt16( Pixel_testPos ); + } + + // Toggle channel + Pixel_channelToggle( Pixel_testPos ); + + // Increment channel + Pixel_testPos++; + if ( Pixel_testPos >= Pixel_TotalChannels ) + Pixel_testPos = 0; +} + diff --git a/Macro/PixelMap/pixel.h b/Macro/PixelMap/pixel.h new file mode 100644 index 0000000..c629782 --- /dev/null +++ b/Macro/PixelMap/pixel.h @@ -0,0 +1,102 @@ +/* Copyright (C) 2015 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 + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This file 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 file. If not, see . + */ + +#pragma once + +// ----- Includes ----- + +// Compiler Includes +#include + + + +// ----- Enums ----- + +typedef enum FrameState { + FrameState_Ready, // Buffers have been updated and are ready to send + FrameState_Sending, // Buffers are currently being sent, do not change + FrameState_Update, // Buffers need to be updated to latest frame +} FrameState; + +// Pixel Change Storage +// - Store only the change of the pixel +// - Change is a value (size of the pixel) +// - Contiguous sets of pixel changes can be stored for maximized packing (with the same width) +// - Each value has a corresponding operator +// * Add +// * Subtract +// * Left shift +// * Right shift +// * Set +// * Add no-rollover +// * Subtract no-rollover +typedef enum PixelChange { + PixelChange_Set = 0, // + PixelChange_Add, // + + PixelChange_Subtract, // - + PixelChange_NoRoll_Add, // +: + PixelChange_NoRoll_Subtract, // -: + PixelChange_LeftShift, // << + PixelChange_RightShift, // >> +} PixelChange; + + + +// ----- Structs ----- + +// Element of array of buffers pointers +typedef struct PixelBuf { + uint8_t size; // Number of elements + uint8_t width; // Width of each element + uint16_t offset; // Subtraction offset from absolute channel + void *data; // Pointer to start of buffer +} PixelBuf; +#define PixelBufElem(len,width,offset,ptr) { len, width, offset, (void*)ptr } +#define PixelBuf8(pixbuf, ch) ( ((uint8_t*) (pixbuf.data))[ ch - pixbuf.offset ] ) +#define PixelBuf16(pixbuf, ch) ( ((uint16_t*)(pixbuf.data))[ ch - pixbuf.offset ] ) + + +// Individual Pixel element +typedef struct PixelElement { + uint8_t width; // Number of bits in a channel + uint8_t channels; // Number of channels + uint16_t indices[0]; // Hardware indices for each channel +} PixelElement; +#define s2b(num) (num >> 8), (num & 0xFF) +#define Pixel_RGBChannel(r,g,b) 8, 3, s2b(r), s2b(g), s2b(b) +#define Pixel_8bitChannel(c) 8, 1, s2b(c) + + +typedef struct PixelMod { + uint16_t pixel; // Pixel index + PixelChange change; // Change to apply to pixel + uint8_t contiguousPixels; // # of contiguous pixels to apply same changes too + uint8_t data[0]; // Data size depends on PixelElement definition +} PixelMod; + + + +// ----- Variables ----- + +extern FrameState Pixel_FrameState; + + + +// ----- Functions ----- + +void Pixel_process(); +void Pixel_setup(); + diff --git a/Macro/PixelMap/setup.cmake b/Macro/PixelMap/setup.cmake new file mode 100644 index 0000000..158ffa5 --- /dev/null +++ b/Macro/PixelMap/setup.cmake @@ -0,0 +1,31 @@ +###| CMake Kiibohd Controller Macro Module |### +# +# Written by Jacob Alexander in 2015 for the Kiibohd Controller +# +# Released into the Public Domain +# +### + + +### +# Required Sub-modules +# +AddModule ( Macro PartialMap ) + + + +### +# Module C files +# +set ( Module_SRCS + pixel.c +) + + +### +# Compiler Family Compatibility +# +set ( ModuleCompatibility + arm +) + diff --git a/Scan/ISSILed/led_scan.c b/Scan/ISSILed/led_scan.c index e04067a..25ecc31 100644 --- a/Scan/ISSILed/led_scan.c +++ b/Scan/ISSILed/led_scan.c @@ -107,11 +107,8 @@ typedef struct LED_EnableBuffer { // CLI Functions void cliFunc_i2cSend ( char* args ); void cliFunc_ledCtrl ( char* args ); -void cliFunc_ledNFrame( char* args ); -void cliFunc_ledStart ( char* args ); -void cliFunc_ledTest ( char* args ); -void cliFunc_ledWPage ( char* args ); -void cliFunc_ledZero ( char* args ); +void cliFunc_ledReset ( char* args ); +void cliFunc_ledSpeed ( char* args ); @@ -120,31 +117,27 @@ void cliFunc_ledZero ( char* args ); // Scan Module command dictionary CLIDict_Entry( i2cSend, "Send I2C sequence of bytes. Use |'s to split sequences with a stop." ); CLIDict_Entry( ledCtrl, "Basic LED control. Args: []" ); -CLIDict_Entry( ledNFrame, "Increment led frame." ); -CLIDict_Entry( ledStart, "Disable software shutdown." ); -CLIDict_Entry( ledTest, "Test out the led pages." ); -CLIDict_Entry( ledWPage, "Write to given register page starting at address. i.e. 0xE8 0x2 0x24 0xF0 0x12" ); -CLIDict_Entry( ledZero, "Zero out LED register pages (non-configuration)." ); +CLIDict_Entry( ledReset, "Reset ISSI chips." ); +CLIDict_Entry( ledSpeed, "ISSI frame rate 0-63, 1 is fastest. f - display fps" ); CLIDict_Def( ledCLIDict, "ISSI LED Module Commands" ) = { CLIDict_Item( i2cSend ), CLIDict_Item( ledCtrl ), - CLIDict_Item( ledNFrame ), - CLIDict_Item( ledStart ), - CLIDict_Item( ledTest ), - CLIDict_Item( ledWPage ), - CLIDict_Item( ledZero ), + CLIDict_Item( ledReset ), + CLIDict_Item( ledSpeed ), { 0, 0, 0 } // Null entry for dictionary end }; -LED_Buffer LED_pageBuffer[ ISSI_Chips_define ]; +volatile LED_Buffer LED_pageBuffer[ ISSI_Chips_define ]; uint8_t LED_FrameBuffersReady; // Starts at maximum, reset on interrupt from ISSI volatile uint8_t LED_FrameBufferReset; // INTB interrupt received, reset available buffer count when ready uint8_t LED_FrameBufferPage; // Current page of the buffer uint8_t LED_FrameBufferStart; // Whether or not a start signal can be sent + uint8_t LED_displayFPS; // Display fps to cli + // Enable mask and default brightness for ISSI chip channel const LED_EnableBuffer LED_ledEnableMask[ISSI_Chips_define] = { LED_MaskDefine( 1 ), @@ -251,6 +244,39 @@ void LED_sendPage( uint8_t addr, uint16_t *buffer, uint32_t len, uint8_t page ) delay(1); } +// Write register on all ISSI chips +// Prepare pages first, then attempt write register with a minimal delay between chips +void LED_syncReg( uint8_t reg, uint8_t val, uint8_t page ) +{ + uint16_t pageSetup[] = { 0, 0xFD, page }; + + // Setup each of the pages + for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ ) + { + pageSetup[0] = LED_pageBuffer[ ch ].i2c_addr; + + while ( i2c_send( pageSetup, sizeof( pageSetup ) / 2 ) == -1 ) + delay(1); + } + + // Reg Write Setup + uint16_t writeData[] = { 0, reg, val }; + + // Write to all the registers + for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ ) + { + writeData[0] = LED_pageBuffer[ ch ].i2c_addr; + + // Delay very little to help with synchronization + while ( i2c_send( writeData, sizeof( writeData ) / 2 ) == -1 ) + delayMicroseconds(10); + } + + // Delay until written + while ( i2c_busy() ) + delay(1); +} + // Write address void LED_writeReg( uint8_t addr, uint8_t reg, uint8_t val, uint8_t page ) { @@ -308,6 +334,63 @@ uint8_t LED_readReg( uint8_t addr, uint8_t reg, uint8_t page ) return recv_data; } +void LED_reset() +{ + // Reset frame buffer used count + LED_FrameBuffersReady = LED_FrameBuffersMax; + + // Starting page for the buffers + LED_FrameBufferPage = 4; + + // Initially do not allow autoplay to restart + LED_FrameBufferStart = 0; + + // Disable FPS by default + LED_displayFPS = 0; + + // Clear LED Pages + // Enable LEDs based upon mask + for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ ) + { + uint8_t addr = LED_pageBuffer[ ch ].i2c_addr; + LED_zeroPages( addr, 0x00, 8, 0x00, 0xB4 ); // LED Registers + + // For each page + for ( uint8_t pg = 0; pg < LED_FrameBuffersMax * 2; pg++ ) + { + LED_sendPage( + addr, + (uint16_t*)&LED_ledEnableMask[ ch ], + sizeof( LED_EnableBuffer ) / 2, + pg + ); + } + } + + // Setup ISSI auto frame play, but do not start yet + for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ ) + { + uint8_t addr = LED_pageBuffer[ ch ].i2c_addr; + // CNS 1 loop, FNS 4 frames - 0x14 + LED_writeReg( addr, 0x02, 0x14, 0x0B ); + + // Default refresh speed - TxA + // T is typically 11ms + // A is 1 to 64 (where 0 is 64) + LED_writeReg( addr, 0x03, ISSI_AnimationSpeed_define, 0x0B ); + + // Set MODE to Auto Frame Play + LED_writeReg( addr, 0x00, 0x08, 0x0B ); + } + + // Disable Software shutdown of ISSI chip + for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ ) + { + uint8_t addr = LED_pageBuffer[ ch ].i2c_addr; + LED_writeReg( addr, 0x0A, 0x01, 0x0B ); + } +} + // Setup inline void LED_setup() { @@ -359,56 +442,8 @@ inline void LED_setup() // Enable PORTB interrupt NVIC_ENABLE_IRQ( IRQ_PORTB ); - // Reset frame buffer used count - LED_FrameBuffersReady = LED_FrameBuffersMax; - - // Starting page for the buffers - LED_FrameBufferPage = 4; - - // Initially do not allow autoplay to restart - LED_FrameBufferStart = 0; - - // Clear LED Pages - // Enable LEDs based upon mask - for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ ) - { - uint8_t addr = LED_pageBuffer[ ch ].i2c_addr; - LED_zeroPages( addr, 0x00, 8, 0x00, 0xB4 ); // LED Registers - - // For each page - for ( uint8_t pg = 0; pg < LED_FrameBuffersMax * 2; pg++ ) - { - LED_sendPage( - addr, - (uint16_t*)&LED_ledEnableMask[ ch ], - sizeof( LED_EnableBuffer ) / 2, - pg - ); - } - } - - // Setup ISSI auto frame play, but do not start yet - for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ ) - { - uint8_t addr = LED_pageBuffer[ ch ].i2c_addr; - // CNS 1 loop, FNS 4 frames - 0x14 - LED_writeReg( addr, 0x02, 0x14, 0x0B ); - - // Default refresh speed - TxA - // T is typically 11ms - // A is 1 to 64 (where 0 is 64) - LED_writeReg( addr, 0x03, ISSI_AnimationSpeed_define, 0x0B ); - - // Set MODE to Auto Frame Play - LED_writeReg( addr, 0x00, 0x08, 0x0B ); - } - - // Disable Software shutdown of ISSI chip - for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ ) - { - uint8_t addr = LED_pageBuffer[ ch ].i2c_addr; - LED_writeReg( addr, 0x0A, 0x01, 0x0B ); - } + // Reset LED sequencing + LED_reset(); } @@ -480,13 +515,17 @@ inline void LED_scan() if ( LED_FrameBufferReset ) { LED_FrameBufferReset = 0; + // Delay, in order to synchronize chips LED_FrameBufferStart = 1; - // Debug Status - dbug_msg("4frames/"); - printInt32( systick_millis_count - LED_timePrev ); - LED_timePrev = systick_millis_count; - print("ms" NL); + // FPS Display + if ( LED_displayFPS ) + { + dbug_msg("4frames/"); + printInt32( systick_millis_count - LED_timePrev ); + LED_timePrev = systick_millis_count; + print( "ms" NL ); + } } // Make sure there are buffers available @@ -497,15 +536,9 @@ inline void LED_scan() if ( !LED_FrameBufferStart || Pixel_FrameState == FrameState_Sending ) return; - // Buffers are now full, start signal can be sent - for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ ) - { - uint8_t addr = LED_pageBuffer[ ch ].i2c_addr; - - // Start Auto Frame Play on either frame 1 or 5 - uint8_t frame = LED_FrameBufferPage == 0 ? 4 : 0; - LED_writeReg( addr, 0x00, 0x08 | frame, 0x0B ); - } + // Start Auto Frame Play on either frame 1 or 5 + uint8_t frame = LED_FrameBufferPage == 0 ? 4 : 0; + LED_syncReg( 0x00, 0x08 | frame, 0x0B ); LED_FrameBufferStart = 0; LED_FrameBuffersReady = LED_FrameBuffersMax; @@ -777,9 +810,9 @@ void cliFunc_i2cSend( char* args ) i2c_send( buffer, bufferLen ); } +/* void cliFunc_ledWPage( char* args ) { - /* char* curArgs; char* arg1Ptr; char* arg2Ptr = args; @@ -833,23 +866,29 @@ void cliFunc_ledWPage( char* args ) // Increment address data[1]++; } - */ } +*/ -void cliFunc_ledStart( char* args ) +void cliFunc_ledReset( char* args ) { print( NL ); // No \r\n by default after the command is entered for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ ) { LED_zeroPages( LED_ledEnableMask[ ch ].i2c_addr, 0x0B, 1, 0x00, 0x0C ); // Control Registers - //LED_zeroPages( 0x00, 8, 0x00, 0xB4 ); // LED Registers - LED_writeReg( LED_ledEnableMask[ ch ].i2c_addr, 0x0A, 0x01, 0x0B ); - LED_sendPage( LED_ledEnableMask[ ch ].i2c_addr, (uint16_t*)&LED_ledEnableMask[ ch ], sizeof( LED_EnableBuffer ) / 2, 0 ); + } + + // Clear buffers + for ( uint8_t buf = 0; buf < ISSI_Chips_define; buf++ ) + { + memset( (void*)LED_pageBuffer[ buf ].buffer, 0, LED_BufferLength * 2 ); + } + + LED_reset(); } -void cliFunc_ledTest( char* args ) +void cliFunc_ledSpeed( char* args ) { print( NL ); // No \r\n by default after the command is entered @@ -862,121 +901,38 @@ void cliFunc_ledTest( char* args ) curArgs = arg2Ptr; CLI_argumentIsolation( curArgs, &arg1Ptr, &arg2Ptr ); + // Check if f argument was given + switch ( *arg1Ptr ) + { + case 'f': + case 'F': + info_msg("FPS Toggle"); + LED_displayFPS = !LED_displayFPS; + return; + } + // Stop processing args if no more are found if ( *arg1Ptr != '\0' ) + { speed = numToInt( arg1Ptr ); + } + // Default to default speed + else + { + info_msg("Setting default speed: "); + printInt8( speed ); + } - // TODO REMOVEME + // Set refresh speed per ISSI chip for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ ) { uint8_t addr = LED_pageBuffer[ ch ].i2c_addr; - // CNS 1 loop, FNS 4 frames - 0x14 - //LED_writeReg( addr, 0x02, 0x14, 0x0B ); // Default refresh speed - TxA // T is typically 11ms // A is 1 to 64 (where 0 is 64) LED_writeReg( addr, 0x03, speed, 0x0B ); - - // Set MODE to Auto Frame Play - // Set FS to 5, this is to train the IRQ on the ISSI for the processing loop - // The first 4 frames are blank, we fill the last 4 - // Clear the interrupt, and the movie display starts at frame 5 - //LED_writeReg( addr, 0x00, 0x0C, 0x0B ); - } - return; - - // Zero out Frame Registers - // This needs to be done before disabling the hardware shutdown (or the leds will do undefined things) - info_print("LED - Zeroing out all pages"); - for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ ) - { - uint8_t addr = LED_pageBuffer[ ch ].i2c_addr; - LED_zeroPages( addr, 0x0B, 1, 0x00, 0x0C ); // Control Registers - LED_zeroPages( addr, 0x00, 8, 0x00, 0xB4 ); // LED Registers - } - - // Clear LED Pages - // Enable LEDs based upon mask - info_print("LED - Setting LED enable mask"); - for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ ) - //for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ ) - { - uint8_t addr = LED_pageBuffer[ ch ].i2c_addr; - - // For each page - for ( uint8_t pg = 0; pg < LED_FrameBuffersMax * 2; pg++ ) - { - LED_sendPage( - addr, - (uint16_t*)&LED_ledEnableMask[ ch ], - sizeof( LED_EnableBuffer ) / 2, - pg - ); - } - } - - // Setup ISSI auto frame play, but do not start yet - /* - info_print("LED - Enabling 8 frame 3 loop auto play"); - for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ ) - { - uint8_t addr = LED_pageBuffer[ ch ].i2c_addr; - // CNS 3 loops, FNS all frames - 0x30 - LED_writeReg( addr, 0x02, 0x30, 0x0B ); - - // Default refresh speed - TxA - // T is typically 11ms - // A is 1 to 64 (where 0 is 64) - LED_writeReg( addr, 0x03, speed, 0x0B ); - - // Set MODE to Auto Frame Play - // Set FS to frame 1 - //LED_writeReg( addr, 0x00, 0x08, 0x0B ); - } - */ - - // Load frame data - for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ ) - { - uint8_t addr = LED_pageBuffer[ ch ].i2c_addr; - - // Load each page with a different led enabled - uint16_t data[] = { - addr, 0xFD, 0x00, - }; - while( i2c_send( data, sizeof( data ) / 2 ) == -1 ) - delay( 1 ); - data[1] = 0x24; - data[2] = 0xFF; - while( i2c_send( data, sizeof( data ) / 2 ) == -1 ) - delay( 1 ); - } - - // Disable Software shutdown of ISSI chip - for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ ) - { - uint8_t addr = LED_pageBuffer[ ch ].i2c_addr; - LED_writeReg( addr, 0x0A, 0x01, 0x0B ); - } - -/* - for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ ) - { - LED_sendPage( LED_defaultBrightness[ ch ].i2c_addr, (uint16_t*)&LED_defaultBrightness[ ch ], sizeof( LED_Buffer ), 0 ); - } -*/ -} - -void cliFunc_ledZero( char* args ) -{ - print( NL ); // No \r\n by default after the command is entered - - for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ ) - { - LED_zeroPages( LED_defaultBrightness[ ch ].i2c_addr, 0x0B, 1, 0x00, 0x0C ); // Control Registers - LED_zeroPages( LED_defaultBrightness[ ch ].i2c_addr, 0x00, 8, 0x24, 0xB4 ); // Only PWMs } } diff --git a/Scan/MatrixARM/matrix_scan.c b/Scan/MatrixARM/matrix_scan.c index 8463b26..a9018df 100644 --- a/Scan/MatrixARM/matrix_scan.c +++ b/Scan/MatrixARM/matrix_scan.c @@ -196,6 +196,7 @@ void Matrix_setup() print( NL ); info_msg("Max Keys: "); printHex( Matrix_maxKeys ); + print( NL ); // Clear out Debounce Array for ( uint8_t item = 0; item < Matrix_maxKeys; item++ )