Various KType updates
- Updated port switching pins (split USB and UART switching) - Added basic support for 2nd i2c bus - Updated key matrix - Fixed udev rules - Added missing register defines
This commit is contained in:
parent
fbc8c873ec
commit
d1e969ce8f
@ -4,7 +4,7 @@ ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789]?", ENV{MTP_NO_PROBE}="1"
|
|||||||
SUBSYSTEMS=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789]?", MODE:="0666"
|
SUBSYSTEMS=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789]?", MODE:="0666"
|
||||||
|
|
||||||
# Kiibohd Serial Interface
|
# Kiibohd Serial Interface
|
||||||
KERNEL=="ttyACM*", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789]?", SYMLINK+="kiibohd", MODE:="0666",
|
KERNEL=="ttyACM*", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789]?", SYMLINK+="kiibohd", MODE:="0666"
|
||||||
KERNEL=="ttyACM*", ATTRS{idVendor}=="1c11", ATTRS{idProduct}=="b04d", SYMLINK+="kiibohd", MODE:="0666"
|
KERNEL=="ttyACM*", ATTRS{idVendor}=="1c11", ATTRS{idProduct}=="b04d", SYMLINK+="kiibohd", MODE:="0666"
|
||||||
KERNEL=="ttyACM*", ATTRS{idVendor}=="1c11", ATTRS{idProduct}=="f05c", SYMLINK+="kiibohd", MODE:="0666"
|
KERNEL=="ttyACM*", ATTRS{idVendor}=="1c11", ATTRS{idProduct}=="f05c", SYMLINK+="kiibohd", MODE:="0666"
|
||||||
|
|
||||||
|
16
Lib/mk20dx.h
16
Lib/mk20dx.h
@ -1,7 +1,7 @@
|
|||||||
/* Teensyduino Core Library
|
/* Teensyduino Core Library
|
||||||
* http://www.pjrc.com/teensy/
|
* http://www.pjrc.com/teensy/
|
||||||
* Copyright (c) 2013 PJRC.COM, LLC.
|
* Copyright (c) 2013 PJRC.COM, LLC.
|
||||||
* Modified by Jacob Alexander 2014-2015
|
* Modified by Jacob Alexander 2014-2016
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
* a copy of this software and associated documentation files (the
|
* a copy of this software and associated documentation files (the
|
||||||
@ -1457,6 +1457,20 @@ typedef struct {
|
|||||||
#define I2C0_SLTH *(volatile uint8_t *)0x4006600A // I2C SCL Low Timeout Register High
|
#define I2C0_SLTH *(volatile uint8_t *)0x4006600A // I2C SCL Low Timeout Register High
|
||||||
#define I2C0_SLTL *(volatile uint8_t *)0x4006600B // I2C SCL Low Timeout Register Low
|
#define I2C0_SLTL *(volatile uint8_t *)0x4006600B // I2C SCL Low Timeout Register Low
|
||||||
|
|
||||||
|
#define I2C1_A1 *(volatile uint8_t *)0x40067000 // I2C Address Register 1
|
||||||
|
#define I2C1_F *(volatile uint8_t *)0x40067001 // I2C Frequency Divider register
|
||||||
|
#define I2C1_C1 *(volatile uint8_t *)0x40067002 // I2C Control Register 1
|
||||||
|
#define I2C1_S *(volatile uint8_t *)0x40067003 // I2C Status register
|
||||||
|
#define I2C1_D *(volatile uint8_t *)0x40067004 // I2C Data I/O register
|
||||||
|
#define I2C1_C2 *(volatile uint8_t *)0x40067005 // I2C Control Register 2
|
||||||
|
#define I2C1_FLT *(volatile uint8_t *)0x40067006 // I2C Programmable Input Glitch Filter register
|
||||||
|
#define I2C1_RA *(volatile uint8_t *)0x40067007 // I2C Range Address register
|
||||||
|
#define I2C1_SMB *(volatile uint8_t *)0x40067008 // I2C SMBus Control and Status register
|
||||||
|
#define I2C1_A2 *(volatile uint8_t *)0x40067009 // I2C Address Register 2
|
||||||
|
#define I2C1_SLTH *(volatile uint8_t *)0x4006700A // I2C SCL Low Timeout Register High
|
||||||
|
#define I2C1_SLTL *(volatile uint8_t *)0x4006700B // I2C SCL Low Timeout Register Low
|
||||||
|
|
||||||
|
|
||||||
// Chapter 45: Universal Asynchronous Receiver/Transmitter (UART)
|
// Chapter 45: Universal Asynchronous Receiver/Transmitter (UART)
|
||||||
#define UART0_BDH *(volatile uint8_t *)0x4006A000 // UART Baud Rate Registers: High
|
#define UART0_BDH *(volatile uint8_t *)0x4006A000 // UART Baud Rate Registers: High
|
||||||
#define UART0_BDL *(volatile uint8_t *)0x4006A001 // UART Baud Rate Registers: Low
|
#define UART0_BDL *(volatile uint8_t *)0x4006A001 // UART Baud Rate Registers: Low
|
||||||
|
@ -111,7 +111,7 @@ PixelBuf Pixel_Buffers[] = {
|
|||||||
|
|
||||||
|
|
||||||
// Pixel Mapping
|
// Pixel Mapping
|
||||||
#define Pixel_TotalPixels 128 // TODO Generate
|
#define Pixel_TotalPixels 127 // TODO Generate
|
||||||
PixelElement Pixel_Mapping[] = {
|
PixelElement Pixel_Mapping[] = {
|
||||||
// Function Row (1-16)
|
// Function Row (1-16)
|
||||||
Pixel_RGBChannel(0,33,49), // 1
|
Pixel_RGBChannel(0,33,49), // 1
|
||||||
@ -2593,7 +2593,8 @@ inline void Pixel_process()
|
|||||||
uint16_t ch;
|
uint16_t ch;
|
||||||
|
|
||||||
// Only update 50 positions at a time
|
// Only update 50 positions at a time
|
||||||
for ( ch = Pixel_testPos; ch < Pixel_testPos + 50 && ch < Pixel_TotalChannels; ch++ )
|
for ( ch = Pixel_testPos; ch < Pixel_TotalChannels; ch++ )
|
||||||
|
//for ( ch = Pixel_testPos; ch < Pixel_testPos + 50 && ch < Pixel_TotalChannels; ch++ )
|
||||||
{
|
{
|
||||||
// Toggle channel
|
// Toggle channel
|
||||||
Pixel_channelToggle( ch );
|
Pixel_channelToggle( ch );
|
||||||
|
@ -39,6 +39,9 @@
|
|||||||
#include <arm/usb_serial.h>
|
#include <arm/usb_serial.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// KLL
|
||||||
|
#include <kll_defs.h>
|
||||||
|
|
||||||
// Local Includes
|
// Local Includes
|
||||||
#include "output_com.h"
|
#include "output_com.h"
|
||||||
|
|
||||||
@ -117,15 +120,25 @@ uint8_t USBKeys_SentCLI = 0;
|
|||||||
// 1=num lock, 2=caps lock, 4=scroll lock, 8=compose, 16=kana
|
// 1=num lock, 2=caps lock, 4=scroll lock, 8=compose, 16=kana
|
||||||
volatile uint8_t USBKeys_LEDs = 0;
|
volatile uint8_t USBKeys_LEDs = 0;
|
||||||
|
|
||||||
|
// Currently pressed mouse buttons, bitmask, 0 represents no buttons pressed
|
||||||
|
volatile uint16_t USBMouse_Buttons = 0;
|
||||||
|
|
||||||
|
// Relative mouse axis movement, stores pending movement
|
||||||
|
volatile uint16_t USBMouse_Relative_x = 0;
|
||||||
|
volatile uint16_t USBMouse_Relative_y = 0;
|
||||||
|
|
||||||
// Protocol setting from the host.
|
// Protocol setting from the host.
|
||||||
// 0 - Boot Mode
|
// 0 - Boot Mode
|
||||||
// 1 - NKRO Mode (Default, unless set by a BIOS or boot interface)
|
// 1 - NKRO Mode (Default, unless set by a BIOS or boot interface)
|
||||||
volatile uint8_t USBKeys_Protocol = 1;
|
volatile uint8_t USBKeys_Protocol = USBProtocol_define;
|
||||||
|
|
||||||
// Indicate if USB should send update
|
// Indicate if USB should send update
|
||||||
// OS only needs update if there has been a change in state
|
// OS only needs update if there has been a change in state
|
||||||
USBKeyChangeState USBKeys_Changed = USBKeyChangeState_None;
|
USBKeyChangeState USBKeys_Changed = USBKeyChangeState_None;
|
||||||
|
|
||||||
|
// Indicate if USB should send update
|
||||||
|
USBMouseChangeState USBMouse_Changed = 0;
|
||||||
|
|
||||||
// the idle configuration, how often we send the report to the
|
// the idle configuration, how often we send the report to the
|
||||||
// host (ms * 4) even when it hasn't changed
|
// host (ms * 4) even when it hasn't changed
|
||||||
uint8_t USBKeys_Idle_Config = 125;
|
uint8_t USBKeys_Idle_Config = 125;
|
||||||
@ -511,6 +524,63 @@ void Output_flashMode_capability( uint8_t state, uint8_t stateType, uint8_t *arg
|
|||||||
Output_firmwareReload();
|
Output_firmwareReload();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sends a mouse command over the USB Output buffer
|
||||||
|
// XXX This function *will* be changing in the future
|
||||||
|
// If you use it, be prepared that your .kll files will break in the future (post KLL 0.5)
|
||||||
|
// Argument #1: USB Mouse Button (16 bit)
|
||||||
|
// Argument #2: USB X Axis (16 bit) relative
|
||||||
|
// Argument #3: USB Y Axis (16 bit) relative
|
||||||
|
void Output_usbMouse_capability( uint8_t state, uint8_t stateType, uint8_t *args )
|
||||||
|
{
|
||||||
|
// Display capability name
|
||||||
|
if ( stateType == 0xFF && state == 0xFF )
|
||||||
|
{
|
||||||
|
print("Output_usbMouse(mouseButton,relX,relY)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine which mouse button was sent
|
||||||
|
// The USB spec defines up to a max of 0xFFFF buttons
|
||||||
|
// The usual are:
|
||||||
|
// 1 - Button 1 - (Primary)
|
||||||
|
// 2 - Button 2 - (Secondary)
|
||||||
|
// 3 - Button 3 - (Tertiary)
|
||||||
|
uint16_t mouse_button = *(uint16_t*)(&args[0]);
|
||||||
|
|
||||||
|
// X/Y Relative Axis
|
||||||
|
uint16_t mouse_x = *(uint16_t*)(&args[2]);
|
||||||
|
uint16_t mouse_y = *(uint16_t*)(&args[4]);
|
||||||
|
|
||||||
|
// Adjust for bit shift
|
||||||
|
uint16_t mouse_button_shift = mouse_button - 1;
|
||||||
|
|
||||||
|
// Only send mouse button if in press or hold state
|
||||||
|
if ( stateType == 0x00 && state == 0x03 ) // Release state
|
||||||
|
{
|
||||||
|
// Release
|
||||||
|
if ( mouse_button )
|
||||||
|
USBMouse_Buttons &= ~(1 << mouse_button_shift);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Press or hold
|
||||||
|
if ( mouse_button )
|
||||||
|
USBMouse_Buttons |= (1 << mouse_button_shift);
|
||||||
|
|
||||||
|
if ( mouse_x )
|
||||||
|
USBMouse_Relative_x = mouse_x;
|
||||||
|
if ( mouse_y )
|
||||||
|
USBMouse_Relative_y = mouse_y;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trigger updates
|
||||||
|
if ( mouse_button )
|
||||||
|
USBMouse_Changed |= USBMouseChangeState_Buttons;
|
||||||
|
|
||||||
|
if ( mouse_x || mouse_y )
|
||||||
|
USBMouse_Changed |= USBMouseChangeState_Relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ----- Functions -----
|
// ----- Functions -----
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
Name = ISSILedCapabilities;
|
Name = ISSILedCapabilities;
|
||||||
Version = 0.2;
|
Version = 0.2;
|
||||||
Author = "HaaTa (Jacob Alexander) 2015";
|
Author = "HaaTa (Jacob Alexander) 2015-2016";
|
||||||
KLL = 0.3d;
|
KLL = 0.3d;
|
||||||
|
|
||||||
# Modified Date
|
# Modified Date
|
||||||
@ -22,12 +22,35 @@ Date = 2015-10-09;
|
|||||||
# i.e. 23 then 144
|
# i.e. 23 then 144
|
||||||
ledControl => LED_control_capability( mode : 1, amount : 1, index : 2 );
|
ledControl => LED_control_capability( mode : 1, amount : 1, index : 2 );
|
||||||
|
|
||||||
|
|
||||||
# Defines available to the ISSILed sub-module
|
# Defines available to the ISSILed sub-module
|
||||||
|
|
||||||
|
# Driver Chip
|
||||||
|
# Selects which driver chip being used
|
||||||
|
# Set to 1 to enable
|
||||||
|
# Valid Chips
|
||||||
|
# 31FL3731 - http://www.issi.com/WW/pdf/31FL3731.pdf (31FL3731C has the same datasheet)
|
||||||
|
# 31FL3732 - http://www.issi.com/WW/pdf/31FL3732.pdf
|
||||||
|
ISSI_Chip_31FL3731 => ISSI_Chip_31FL3731_define;
|
||||||
|
ISSI_Chip_31FL3732 => ISSI_Chip_31FL3732_define;
|
||||||
|
ISSI_Chip_31FL3731 = 0;
|
||||||
|
ISSI_Chip_31FL3732 = 0;
|
||||||
|
|
||||||
|
# Global Brightness
|
||||||
|
# 31FL3732 only
|
||||||
|
# 0 to 0xFF (255)
|
||||||
|
# See datasheet for current calculation, depends on Rext
|
||||||
|
ISSI_Global_Brightness => ISSI_Global_Brightness_define;
|
||||||
|
ISSI_Global_Brightness = 0xFF;
|
||||||
|
|
||||||
# Available ISSI Chips
|
# Available ISSI Chips
|
||||||
ISSI_Chips => ISSI_Chips_define;
|
ISSI_Chips => ISSI_Chips_define;
|
||||||
ISSI_Chips = 1; # 1 by default
|
ISSI_Chips = 1; # 1 by default
|
||||||
|
|
||||||
|
# I2C Buses
|
||||||
|
ISSI_I2C_Buses => ISSI_I2C_Buses_define;
|
||||||
|
ISSI_I2C_Buses = 1; # 1 by default
|
||||||
|
|
||||||
# Default animation speed
|
# Default animation speed
|
||||||
# Can be set from 0 to 63 (A)
|
# Can be set from 0 to 63 (A)
|
||||||
# Formula is TxA (T is approx 11ms)
|
# Formula is TxA (T is approx 11ms)
|
||||||
@ -40,9 +63,9 @@ ISSI_Chips = 1; # 1 by default
|
|||||||
# For a 400 kHz I2C, with a single chip, updating all 144 channels, generally 30 fps is the max for continuous animations
|
# For a 400 kHz I2C, with a single chip, updating all 144 channels, generally 30 fps is the max for continuous animations
|
||||||
# Each additional chip consumes more bandwidth
|
# Each additional chip consumes more bandwidth
|
||||||
# 20 - 4.5 fps - Slow, but should always work without glitches
|
# 20 - 4.5 fps - Slow, but should always work without glitches
|
||||||
# See (http://www.issi.com/WW/pdf/31FL3731C.pdf) for details
|
# See chip datasheet (above) for details
|
||||||
ISSI_AnimationSpeed => ISSI_AnimationSpeed_define;
|
ISSI_AnimationSpeed => ISSI_AnimationSpeed_define;
|
||||||
ISSI_AnimationSpeed = 20; # 20 by default
|
ISSI_AnimationSpeed = 4; # 20 by default
|
||||||
|
|
||||||
# LED Default Enable Mask
|
# LED Default Enable Mask
|
||||||
#
|
#
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright ( C ) 2014 Jan Rychter
|
* Copyright (C) 2014 Jan Rychter
|
||||||
* Modifications ( C ) 2015 Jacob Alexander
|
* Modifications (C) 2015-2016 Jacob Alexander
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files ( the "Software" ), to deal
|
* of this software and associated documentation files ( the "Software" ), to deal
|
||||||
@ -28,6 +28,7 @@
|
|||||||
|
|
||||||
// Project Includes
|
// Project Includes
|
||||||
#include <print.h>
|
#include <print.h>
|
||||||
|
#include <kll_defs.h>
|
||||||
|
|
||||||
// Local Includes
|
// Local Includes
|
||||||
#include "i2c.h"
|
#include "i2c.h"
|
||||||
@ -36,38 +37,78 @@
|
|||||||
|
|
||||||
// ----- Variables -----
|
// ----- Variables -----
|
||||||
|
|
||||||
volatile I2C_Channel i2c_channels[1];
|
volatile I2C_Channel i2c_channels[ISSI_I2C_Buses_define];
|
||||||
|
|
||||||
|
uint32_t i2c_offset[] = {
|
||||||
|
0x0, // Bus 0
|
||||||
|
0x1000, // Bus 1
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ----- Functions -----
|
// ----- Functions -----
|
||||||
|
|
||||||
inline void i2c_setup( )
|
inline void i2c_setup()
|
||||||
{
|
{
|
||||||
// Enable I2C internal clock
|
for ( uint8_t ch = 0; ch < ISSI_I2C_Buses_define; ch++ )
|
||||||
SIM_SCGC4 |= SIM_SCGC4_I2C0; // Bus 0
|
{
|
||||||
|
volatile uint8_t *I2C_F = (uint8_t*)(&I2C0_F) + i2c_offset[ch];
|
||||||
|
volatile uint8_t *I2C_FLT = (uint8_t*)(&I2C0_FLT) + i2c_offset[ch];
|
||||||
|
volatile uint8_t *I2C_C1 = (uint8_t*)(&I2C0_C1) + i2c_offset[ch];
|
||||||
|
volatile uint8_t *I2C_C2 = (uint8_t*)(&I2C0_C2) + i2c_offset[ch];
|
||||||
|
|
||||||
// External pull-up resistor
|
switch ( ch )
|
||||||
PORTB_PCR0 = PORT_PCR_ODE | PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(2);
|
{
|
||||||
PORTB_PCR1 = PORT_PCR_ODE | PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(2);
|
case 0:
|
||||||
|
// Enable I2C internal clock
|
||||||
|
SIM_SCGC4 |= SIM_SCGC4_I2C0; // Bus 0
|
||||||
|
|
||||||
// SCL Frequency Divider
|
// External pull-up resistor
|
||||||
// 1.8 MBaud ( likely higher than spec )
|
PORTB_PCR0 = PORT_PCR_ODE | PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(2);
|
||||||
// 0x82 -> 36 MHz / (4 * 3) = 2.25 MBaud
|
PORTB_PCR1 = PORT_PCR_ODE | PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(2);
|
||||||
// 0x80 => mul(4)
|
|
||||||
// 0x05 => ICL(5)
|
|
||||||
I2C0_F = 0x84;
|
|
||||||
I2C0_FLT = 4;
|
|
||||||
I2C0_C1 = I2C_C1_IICEN;
|
|
||||||
I2C0_C2 = I2C_C2_HDRS; // High drive select
|
|
||||||
|
|
||||||
// Enable I2C Interrupt
|
break;
|
||||||
NVIC_ENABLE_IRQ( IRQ_I2C0 );
|
|
||||||
|
case 1:
|
||||||
|
// Enable I2C internal clock
|
||||||
|
SIM_SCGC4 |= SIM_SCGC4_I2C1; // Bus 1
|
||||||
|
|
||||||
|
// External pull-up resistor
|
||||||
|
PORTC_PCR10 = PORT_PCR_ODE | PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(2);
|
||||||
|
PORTC_PCR11 = PORT_PCR_ODE | PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(2);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// SCL Frequency Divider
|
||||||
|
// 1.8 MBaud ( likely higher than spec )
|
||||||
|
// 0x82 -> 36 MHz / (4 * 3) = 2.25 MBaud
|
||||||
|
// 0x80 => mul(4)
|
||||||
|
// 0x05 => ICL(5)
|
||||||
|
*I2C_F = 0x84;
|
||||||
|
*I2C_FLT = 4;
|
||||||
|
*I2C_C1 = I2C_C1_IICEN;
|
||||||
|
*I2C_C2 = I2C_C2_HDRS; // High drive select
|
||||||
|
|
||||||
|
switch ( ch )
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
// Enable I2C Interrupt
|
||||||
|
NVIC_ENABLE_IRQ( IRQ_I2C0 );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
|
||||||
|
// Enable I2C Interrupt
|
||||||
|
NVIC_ENABLE_IRQ( IRQ_I2C1 );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t i2c_busy()
|
uint8_t i2c_busy( uint8_t ch )
|
||||||
{
|
{
|
||||||
volatile I2C_Channel *channel = &( i2c_channels[0] );
|
volatile I2C_Channel *channel = &( i2c_channels[ch] );
|
||||||
if ( channel->status == I2C_BUSY )
|
if ( channel->status == I2C_BUSY )
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
@ -76,19 +117,35 @@ uint8_t i2c_busy()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t i2c_any_busy()
|
||||||
|
{
|
||||||
|
for ( uint8_t ch = 0; ch < ISSI_I2C_Buses_define; ch++ )
|
||||||
|
{
|
||||||
|
if ( i2c_busy( ch ) )
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// These are here for readability and correspond to bit 0 of the address byte.
|
// These are here for readability and correspond to bit 0 of the address byte.
|
||||||
#define I2C_WRITING 0
|
#define I2C_WRITING 0
|
||||||
#define I2C_READING 1
|
#define I2C_READING 1
|
||||||
|
|
||||||
int32_t i2c_send_sequence(
|
int32_t i2c_send_sequence(
|
||||||
|
uint8_t ch,
|
||||||
uint16_t *sequence,
|
uint16_t *sequence,
|
||||||
uint32_t sequence_length,
|
uint32_t sequence_length,
|
||||||
uint8_t *received_data,
|
uint8_t *received_data,
|
||||||
void ( *callback_fn )( void* ),
|
void ( *callback_fn )( void* ),
|
||||||
void *user_data
|
void *user_data
|
||||||
) {
|
) {
|
||||||
volatile I2C_Channel *channel = &( i2c_channels[0] );
|
volatile I2C_Channel *channel = &( i2c_channels[ch] );
|
||||||
|
|
||||||
|
volatile uint8_t *I2C_C1 = (uint8_t*)(&I2C0_C1) + i2c_offset[ch];
|
||||||
|
volatile uint8_t *I2C_S = (uint8_t*)(&I2C0_S) + i2c_offset[ch];
|
||||||
|
volatile uint8_t *I2C_D = (uint8_t*)(&I2C0_D) + i2c_offset[ch];
|
||||||
|
|
||||||
int32_t result = 0;
|
int32_t result = 0;
|
||||||
uint8_t status;
|
uint8_t status;
|
||||||
|
|
||||||
@ -118,13 +175,13 @@ int32_t i2c_send_sequence(
|
|||||||
// reads_ahead does not need to be initialized
|
// reads_ahead does not need to be initialized
|
||||||
|
|
||||||
// Acknowledge the interrupt request, just in case
|
// Acknowledge the interrupt request, just in case
|
||||||
I2C0_S |= I2C_S_IICIF;
|
*I2C_S |= I2C_S_IICIF;
|
||||||
I2C0_C1 = ( I2C_C1_IICEN | I2C_C1_IICIE );
|
*I2C_C1 = ( I2C_C1_IICEN | I2C_C1_IICIE );
|
||||||
|
|
||||||
// Generate a start condition and prepare for transmitting.
|
// Generate a start condition and prepare for transmitting.
|
||||||
I2C0_C1 |= ( I2C_C1_MST | I2C_C1_TX );
|
*I2C_C1 |= ( I2C_C1_MST | I2C_C1_TX );
|
||||||
|
|
||||||
status = I2C0_S;
|
status = *I2C_S;
|
||||||
if ( status & I2C_S_ARBL )
|
if ( status & I2C_S_ARBL )
|
||||||
{
|
{
|
||||||
warn_print("Arbitration lost");
|
warn_print("Arbitration lost");
|
||||||
@ -133,34 +190,42 @@ int32_t i2c_send_sequence(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Write the first (address) byte.
|
// Write the first (address) byte.
|
||||||
I2C0_D = *channel->sequence++;
|
*I2C_D = *channel->sequence++;
|
||||||
|
|
||||||
// Everything is OK.
|
// Everything is OK.
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
i2c_send_sequence_cleanup:
|
i2c_send_sequence_cleanup:
|
||||||
I2C0_C1 &= ~( I2C_C1_IICIE | I2C_C1_MST | I2C_C1_TX );
|
*I2C_C1 &= ~( I2C_C1_IICIE | I2C_C1_MST | I2C_C1_TX );
|
||||||
channel->status = I2C_ERROR;
|
channel->status = I2C_ERROR;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void i2c0_isr()
|
void i2c_isr( uint8_t ch )
|
||||||
{
|
{
|
||||||
volatile I2C_Channel* channel = &i2c_channels[0];
|
volatile I2C_Channel* channel = &i2c_channels[ch];
|
||||||
|
|
||||||
|
volatile uint8_t *I2C_C1 = (uint8_t*)(&I2C0_C1) + i2c_offset[ch];
|
||||||
|
volatile uint8_t *I2C_S = (uint8_t*)(&I2C0_S) + i2c_offset[ch];
|
||||||
|
volatile uint8_t *I2C_D = (uint8_t*)(&I2C0_D) + i2c_offset[ch];
|
||||||
|
|
||||||
uint8_t element;
|
uint8_t element;
|
||||||
uint8_t status;
|
uint8_t status;
|
||||||
|
|
||||||
status = I2C0_S;
|
status = *I2C_S;
|
||||||
|
|
||||||
// Acknowledge the interrupt request
|
// Acknowledge the interrupt request
|
||||||
I2C0_S |= I2C_S_IICIF;
|
*I2C_S |= I2C_S_IICIF;
|
||||||
|
|
||||||
// Arbitration problem
|
// Arbitration problem
|
||||||
if ( status & I2C_S_ARBL )
|
if ( status & I2C_S_ARBL )
|
||||||
{
|
{
|
||||||
warn_print("Arbitration error");
|
warn_msg("Arbitration error. Bus: ");
|
||||||
I2C0_S |= I2C_S_ARBL;
|
printHex( ch );
|
||||||
|
print(NL);
|
||||||
|
|
||||||
|
*I2C_S |= I2C_S_ARBL;
|
||||||
goto i2c_isr_error;
|
goto i2c_isr_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,17 +239,17 @@ void i2c0_isr()
|
|||||||
// switch to TX mode, either to generate a repeated start condition, or to avoid triggering another I2C read
|
// switch to TX mode, either to generate a repeated start condition, or to avoid triggering another I2C read
|
||||||
// when reading the contents of the data register.
|
// when reading the contents of the data register.
|
||||||
case 0:
|
case 0:
|
||||||
I2C0_C1 |= I2C_C1_TX;
|
*I2C_C1 |= I2C_C1_TX;
|
||||||
|
|
||||||
// Perform the final data register read now that it's safe to do so.
|
// Perform the final data register read now that it's safe to do so.
|
||||||
*channel->received_data++ = I2C0_D;
|
*channel->received_data++ = *I2C_D;
|
||||||
|
|
||||||
// Do we have a repeated start?
|
// Do we have a repeated start?
|
||||||
if ( ( channel->sequence < channel->sequence_end ) && ( *channel->sequence == I2C_RESTART ) )
|
if ( ( channel->sequence < channel->sequence_end ) && ( *channel->sequence == I2C_RESTART ) )
|
||||||
{
|
{
|
||||||
|
|
||||||
// Generate a repeated start condition.
|
// Generate a repeated start condition.
|
||||||
I2C0_C1 |= I2C_C1_RSTA;
|
*I2C_C1 |= I2C_C1_RSTA;
|
||||||
|
|
||||||
// A restart is processed immediately, so we need to get a new element from our sequence. This is safe, because
|
// A restart is processed immediately, so we need to get a new element from our sequence. This is safe, because
|
||||||
// a sequence cannot end with a RESTART: there has to be something after it. Note that the only thing that can
|
// a sequence cannot end with a RESTART: there has to be something after it. Note that the only thing that can
|
||||||
@ -192,7 +257,7 @@ void i2c0_isr()
|
|||||||
channel->txrx = I2C_WRITING;
|
channel->txrx = I2C_WRITING;
|
||||||
channel->sequence++;
|
channel->sequence++;
|
||||||
element = *channel->sequence;
|
element = *channel->sequence;
|
||||||
I2C0_D = element;
|
*I2C_D = element;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -202,12 +267,12 @@ void i2c0_isr()
|
|||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
// do not ACK the final read
|
// do not ACK the final read
|
||||||
I2C0_C1 |= I2C_C1_TXAK;
|
*I2C_C1 |= I2C_C1_TXAK;
|
||||||
*channel->received_data++ = I2C0_D;
|
*channel->received_data++ = *I2C_D;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
*channel->received_data++ = I2C0_D;
|
*channel->received_data++ = *I2C_D;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -234,7 +299,7 @@ void i2c0_isr()
|
|||||||
// Do we have a restart? If so, generate repeated start and make sure TX is on.
|
// Do we have a restart? If so, generate repeated start and make sure TX is on.
|
||||||
if ( element == I2C_RESTART )
|
if ( element == I2C_RESTART )
|
||||||
{
|
{
|
||||||
I2C0_C1 |= I2C_C1_RSTA | I2C_C1_TX;
|
*I2C_C1 |= I2C_C1_RSTA | I2C_C1_TX;
|
||||||
|
|
||||||
// A restart is processed immediately, so we need to get a new element from our sequence.
|
// A restart is processed immediately, so we need to get a new element from our sequence.
|
||||||
// This is safe, because a sequence cannot end with a RESTART: there has to be something after it.
|
// This is safe, because a sequence cannot end with a RESTART: there has to be something after it.
|
||||||
@ -242,7 +307,7 @@ void i2c0_isr()
|
|||||||
element = *channel->sequence;
|
element = *channel->sequence;
|
||||||
|
|
||||||
// Note that the only thing that can come after a restart is a write.
|
// Note that the only thing that can come after a restart is a write.
|
||||||
I2C0_D = element;
|
*I2C_D = element;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -260,29 +325,29 @@ void i2c0_isr()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Switch to RX mode.
|
// Switch to RX mode.
|
||||||
I2C0_C1 &= ~I2C_C1_TX;
|
*I2C_C1 &= ~I2C_C1_TX;
|
||||||
|
|
||||||
// do not ACK the final read
|
// do not ACK the final read
|
||||||
if ( channel->reads_ahead == 1 )
|
if ( channel->reads_ahead == 1 )
|
||||||
{
|
{
|
||||||
I2C0_C1 |= I2C_C1_TXAK;
|
*I2C_C1 |= I2C_C1_TXAK;
|
||||||
}
|
}
|
||||||
// ACK all but the final read
|
// ACK all but the final read
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
I2C0_C1 &= ~( I2C_C1_TXAK );
|
*I2C_C1 &= ~( I2C_C1_TXAK );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dummy read comes first, note that this is not valid data!
|
// Dummy read comes first, note that this is not valid data!
|
||||||
// This only triggers a read, actual data will come in the next interrupt call and overwrite this.
|
// This only triggers a read, actual data will come in the next interrupt call and overwrite this.
|
||||||
// This is why we do not increment the received_data pointer.
|
// This is why we do not increment the received_data pointer.
|
||||||
*channel->received_data = I2C0_D;
|
*channel->received_data = *I2C_D;
|
||||||
channel->reads_ahead--;
|
channel->reads_ahead--;
|
||||||
}
|
}
|
||||||
// Not a restart, not a read, must be a write.
|
// Not a restart, not a read, must be a write.
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
I2C0_D = element;
|
*I2C_D = element;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -292,13 +357,14 @@ void i2c0_isr()
|
|||||||
|
|
||||||
i2c_isr_stop:
|
i2c_isr_stop:
|
||||||
// Generate STOP ( set MST=0 ), switch to RX mode, and disable further interrupts.
|
// Generate STOP ( set MST=0 ), switch to RX mode, and disable further interrupts.
|
||||||
I2C0_C1 &= ~( I2C_C1_MST | I2C_C1_IICIE | I2C_C1_TXAK );
|
*I2C_C1 &= ~( I2C_C1_MST | I2C_C1_IICIE | I2C_C1_TXAK );
|
||||||
channel->status = I2C_AVAILABLE;
|
channel->status = I2C_AVAILABLE;
|
||||||
|
|
||||||
// Call the user-supplied callback function upon successful completion (if it exists).
|
// Call the user-supplied callback function upon successful completion (if it exists).
|
||||||
if ( channel->callback_fn )
|
if ( channel->callback_fn )
|
||||||
{
|
{
|
||||||
// Delay 10 microseconds before starting linked function
|
// Delay 10 microseconds before starting linked function
|
||||||
|
// TODO, is this chip dependent? -HaaTa
|
||||||
delayMicroseconds(10);
|
delayMicroseconds(10);
|
||||||
( *channel->callback_fn )( channel->user_data );
|
( *channel->callback_fn )( channel->user_data );
|
||||||
}
|
}
|
||||||
@ -306,8 +372,18 @@ i2c_isr_stop:
|
|||||||
|
|
||||||
i2c_isr_error:
|
i2c_isr_error:
|
||||||
// Generate STOP and disable further interrupts.
|
// Generate STOP and disable further interrupts.
|
||||||
I2C0_C1 &= ~( I2C_C1_MST | I2C_C1_IICIE );
|
*I2C_C1 &= ~( I2C_C1_MST | I2C_C1_IICIE );
|
||||||
channel->status = I2C_ERROR;
|
channel->status = I2C_ERROR;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void i2c0_isr()
|
||||||
|
{
|
||||||
|
i2c_isr( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
void i2c1_isr()
|
||||||
|
{
|
||||||
|
i2c_isr( 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2014 Jan Rychter
|
* Copyright (C) 2014 Jan Rychter
|
||||||
* Modifications (C) 2015 Jacob Alexander
|
* Modifications (C) 2015-2016 Jacob Alexander
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@ -58,16 +58,10 @@ typedef struct {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ----- Variables -----
|
|
||||||
|
|
||||||
extern volatile I2C_Channel i2c_channels[1];
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ----- Functions -----
|
// ----- Functions -----
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* I2C Module Setup - Channel 0 only
|
* I2C Module Setup
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void i2c_setup();
|
void i2c_setup();
|
||||||
@ -95,6 +89,7 @@ void i2c_setup();
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
int32_t i2c_send_sequence(
|
int32_t i2c_send_sequence(
|
||||||
|
uint8_t ch,
|
||||||
uint16_t *sequence,
|
uint16_t *sequence,
|
||||||
uint32_t sequence_length,
|
uint32_t sequence_length,
|
||||||
uint8_t *received_data,
|
uint8_t *received_data,
|
||||||
@ -105,11 +100,12 @@ int32_t i2c_send_sequence(
|
|||||||
/*
|
/*
|
||||||
* Convenience macros
|
* Convenience macros
|
||||||
*/
|
*/
|
||||||
#define i2c_send(seq, seq_len) i2c_send_sequence( seq, seq_len, 0, 0, 0 )
|
#define i2c_send(ch, seq, seq_len) i2c_send_sequence( ch, seq, seq_len, 0, 0, 0 )
|
||||||
#define i2c_read(seq, seq_len, rec) i2c_send_sequence( seq, seq_len, rec, 0, 0 )
|
#define i2c_read(ch, seq, seq_len, rec) i2c_send_sequence( ch, seq, seq_len, rec, 0, 0 )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check if busy
|
* Check if busy
|
||||||
*/
|
*/
|
||||||
uint8_t i2c_busy();
|
uint8_t i2c_busy( uint8_t ch );
|
||||||
|
uint8_t i2c_any_busy();
|
||||||
|
|
||||||
|
@ -52,34 +52,65 @@
|
|||||||
|
|
||||||
// ISSI Addresses
|
// ISSI Addresses
|
||||||
// IS31FL3731 (max 4 channels per bus)
|
// IS31FL3731 (max 4 channels per bus)
|
||||||
#if 1
|
#if ISSI_Chip_31FL3731_define == 1
|
||||||
#define ISSI_Ch1 0xE8
|
#define ISSI_Ch1 0xE8
|
||||||
#define ISSI_Ch2 0xEA
|
#define ISSI_Ch2 0xEA
|
||||||
#define ISSI_Ch3 0xEC
|
#define ISSI_Ch3 0xEC
|
||||||
#define ISSI_Ch4 0xEE
|
#define ISSI_Ch4 0xEE
|
||||||
|
|
||||||
// IS31FL3732 (max 16 channels per bus)
|
// IS31FL3732 (max 16 channels per bus)
|
||||||
|
#elif ISSI_Chip_31FL3732_define == 1
|
||||||
|
#define ISSI_Ch1 0xA0
|
||||||
|
#define ISSI_Ch2 0xA2
|
||||||
|
#define ISSI_Ch3 0xA4
|
||||||
|
#define ISSI_Ch4 0xA6
|
||||||
|
#define ISSI_Ch5 0xA8
|
||||||
|
#define ISSI_Ch6 0xAA
|
||||||
|
#define ISSI_Ch7 0xAC
|
||||||
|
#define ISSI_Ch8 0xAE
|
||||||
|
#define ISSI_Ch9 0xB0
|
||||||
|
#define ISSI_Ch10 0xB2
|
||||||
|
#define ISSI_Ch11 0xB4
|
||||||
|
#define ISSI_Ch12 0xB6
|
||||||
|
#define ISSI_Ch13 0xB8
|
||||||
|
#define ISSI_Ch14 0xBA
|
||||||
|
#define ISSI_Ch15 0xBC
|
||||||
|
#define ISSI_Ch16 0xBE
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#define ISSI_Ch1 0xB0
|
#error "ISSI Driver Chip not defined in Scan defaultMap.kll..."
|
||||||
#define ISSI_Ch2 0xB2
|
|
||||||
#define ISSI_Ch3 0xB4
|
|
||||||
#define ISSI_Ch4 0xB6
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// TODO Generate in KLL
|
||||||
|
#define LED_MapCh1_Bus_define 0x0
|
||||||
|
#define LED_MapCh1_Addr_define ISSI_Ch1
|
||||||
|
#define LED_MapCh2_Bus_define 0x0
|
||||||
|
#define LED_MapCh2_Addr_define ISSI_Ch2
|
||||||
|
#define LED_MapCh3_Bus_define 0x1
|
||||||
|
#define LED_MapCh3_Addr_define ISSI_Ch1
|
||||||
|
#define LED_MapCh4_Bus_define 0x1
|
||||||
|
#define LED_MapCh4_Addr_define ISSI_Ch2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ----- Macros -----
|
// ----- Macros -----
|
||||||
|
|
||||||
|
#define LED_ChannelMapDefine(ch) \
|
||||||
|
{ \
|
||||||
|
LED_MapCh##ch##_Bus_define, /* I2C bus number */ \
|
||||||
|
LED_MapCh##ch##_Addr_define, /* I2C address */ \
|
||||||
|
}
|
||||||
|
|
||||||
#define LED_MaskDefine(ch) \
|
#define LED_MaskDefine(ch) \
|
||||||
{ \
|
{ \
|
||||||
ISSI_Ch##ch, /* I2C address */ \
|
LED_MapCh##ch##_Addr_define, /* I2C address */ \
|
||||||
0x00, /* Starting register address */ \
|
0x00, /* Starting register address */ \
|
||||||
{ ISSILedMask##ch##_define }, \
|
{ ISSILedMask##ch##_define }, \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define LED_BrightnessDefine(ch) \
|
#define LED_BrightnessDefine(ch) \
|
||||||
{ \
|
{ \
|
||||||
ISSI_Ch##ch, /* I2C address */ \
|
LED_MapCh##ch##_Addr_define, /* I2C address */ \
|
||||||
0x24, /* Starting register address */ \
|
0x24, /* Starting register address */ \
|
||||||
{ ISSILedBrightness##ch##_define }, \
|
{ ISSILedBrightness##ch##_define }, \
|
||||||
}
|
}
|
||||||
@ -100,6 +131,11 @@ typedef struct LED_EnableBuffer {
|
|||||||
uint16_t buffer[LED_EnableBufferLength];
|
uint16_t buffer[LED_EnableBufferLength];
|
||||||
} LED_EnableBuffer;
|
} LED_EnableBuffer;
|
||||||
|
|
||||||
|
typedef struct LED_ChannelMap {
|
||||||
|
uint8_t bus;
|
||||||
|
uint8_t addr;
|
||||||
|
} LED_ChannelMap;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ----- Function Declarations -----
|
// ----- Function Declarations -----
|
||||||
@ -129,7 +165,7 @@ CLIDict_Def( ledCLIDict, "ISSI LED Module Commands" ) = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
volatile 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
|
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
|
volatile uint8_t LED_FrameBufferReset; // INTB interrupt received, reset available buffer count when ready
|
||||||
@ -138,6 +174,21 @@ volatile uint8_t LED_FrameBufferReset; // INTB interrupt received, reset availa
|
|||||||
|
|
||||||
uint8_t LED_displayFPS; // Display fps to cli
|
uint8_t LED_displayFPS; // Display fps to cli
|
||||||
|
|
||||||
|
// TODO - Autogenerate for each keyboard
|
||||||
|
// ISSI Driver Channel to Bus:Address mapping
|
||||||
|
const LED_ChannelMap LED_ChannelMapping[ISSI_Chips_define] = {
|
||||||
|
LED_ChannelMapDefine( 1 ),
|
||||||
|
#if ISSI_Chips_define >= 2
|
||||||
|
LED_ChannelMapDefine( 2 ),
|
||||||
|
#endif
|
||||||
|
#if ISSI_Chips_define >= 3
|
||||||
|
LED_ChannelMapDefine( 3 ),
|
||||||
|
#endif
|
||||||
|
#if ISSI_Chips_define >= 4
|
||||||
|
LED_ChannelMapDefine( 4 ),
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
// Enable mask and default brightness for ISSI chip channel
|
// Enable mask and default brightness for ISSI chip channel
|
||||||
const LED_EnableBuffer LED_ledEnableMask[ISSI_Chips_define] = {
|
const LED_EnableBuffer LED_ledEnableMask[ISSI_Chips_define] = {
|
||||||
LED_MaskDefine( 1 ),
|
LED_MaskDefine( 1 ),
|
||||||
@ -192,7 +243,7 @@ void portb_isr()
|
|||||||
|
|
||||||
// ----- Functions -----
|
// ----- Functions -----
|
||||||
|
|
||||||
void LED_zeroPages( uint8_t addr, uint8_t startPage, uint8_t numPages, uint8_t startReg, uint8_t endReg )
|
void LED_zeroPages( uint8_t bus, uint8_t addr, uint8_t startPage, uint8_t numPages, uint8_t startReg, uint8_t endReg )
|
||||||
{
|
{
|
||||||
// Clear Page
|
// Clear Page
|
||||||
// Max length of a page + chip id + reg start
|
// Max length of a page + chip id + reg start
|
||||||
@ -207,20 +258,20 @@ void LED_zeroPages( uint8_t addr, uint8_t startPage, uint8_t numPages, uint8_t s
|
|||||||
uint16_t pageSetup[] = { addr, 0xFD, page };
|
uint16_t pageSetup[] = { addr, 0xFD, page };
|
||||||
|
|
||||||
// Setup page
|
// Setup page
|
||||||
while ( i2c_send( pageSetup, sizeof( pageSetup ) / 2 ) == -1 )
|
while ( i2c_send( bus, pageSetup, sizeof( pageSetup ) / 2 ) == -1 )
|
||||||
delay(1);
|
delay(1);
|
||||||
|
|
||||||
// Zero out page
|
// Zero out page
|
||||||
while ( i2c_send( clearPage, 2 + endReg - startReg ) == -1 )
|
while ( i2c_send( bus, clearPage, 2 + endReg - startReg ) == -1 )
|
||||||
delay(1);
|
delay(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait until finished zero'ing
|
// Wait until finished zero'ing
|
||||||
while ( i2c_busy() )
|
while ( i2c_busy( bus ) )
|
||||||
delay(1);
|
delay(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LED_sendPage( uint8_t addr, uint16_t *buffer, uint32_t len, uint8_t page )
|
void LED_sendPage( uint8_t bus, uint8_t addr, uint16_t *buffer, uint32_t len, uint8_t page )
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
info_msg("I2C Send Page Addr: ");
|
info_msg("I2C Send Page Addr: ");
|
||||||
@ -236,11 +287,11 @@ void LED_sendPage( uint8_t addr, uint16_t *buffer, uint32_t len, uint8_t page )
|
|||||||
uint16_t pageSetup[] = { addr, 0xFD, page };
|
uint16_t pageSetup[] = { addr, 0xFD, page };
|
||||||
|
|
||||||
// Setup page
|
// Setup page
|
||||||
while ( i2c_send( pageSetup, sizeof( pageSetup ) / 2 ) == -1 )
|
while ( i2c_send( bus, pageSetup, sizeof( pageSetup ) / 2 ) == -1 )
|
||||||
delay(1);
|
delay(1);
|
||||||
|
|
||||||
// Write page to I2C Tx Buffer
|
// Write page to I2C Tx Buffer
|
||||||
while ( i2c_send( buffer, len ) == -1 )
|
while ( i2c_send( bus, buffer, len ) == -1 )
|
||||||
delay(1);
|
delay(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -253,9 +304,10 @@ void LED_syncReg( uint8_t reg, uint8_t val, uint8_t page )
|
|||||||
// Setup each of the pages
|
// Setup each of the pages
|
||||||
for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ )
|
for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ )
|
||||||
{
|
{
|
||||||
pageSetup[0] = LED_pageBuffer[ ch ].i2c_addr;
|
pageSetup[0] = LED_ChannelMapping[ ch ].addr;
|
||||||
|
uint8_t bus = LED_ChannelMapping[ ch ].bus;
|
||||||
|
|
||||||
while ( i2c_send( pageSetup, sizeof( pageSetup ) / 2 ) == -1 )
|
while ( i2c_send( bus, pageSetup, sizeof( pageSetup ) / 2 ) == -1 )
|
||||||
delay(1);
|
delay(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,20 +317,21 @@ void LED_syncReg( uint8_t reg, uint8_t val, uint8_t page )
|
|||||||
// Write to all the registers
|
// Write to all the registers
|
||||||
for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ )
|
for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ )
|
||||||
{
|
{
|
||||||
writeData[0] = LED_pageBuffer[ ch ].i2c_addr;
|
writeData[0] = LED_ChannelMapping[ ch ].addr;
|
||||||
|
uint8_t bus = LED_ChannelMapping[ ch ].bus;
|
||||||
|
|
||||||
// Delay very little to help with synchronization
|
// Delay very little to help with synchronization
|
||||||
while ( i2c_send( writeData, sizeof( writeData ) / 2 ) == -1 )
|
while ( i2c_send( bus, writeData, sizeof( writeData ) / 2 ) == -1 )
|
||||||
delayMicroseconds(10);
|
delayMicroseconds(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delay until written
|
// Delay until written
|
||||||
while ( i2c_busy() )
|
while ( i2c_any_busy() )
|
||||||
delay(1);
|
delay(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write address
|
// Write address
|
||||||
void LED_writeReg( uint8_t addr, uint8_t reg, uint8_t val, uint8_t page )
|
void LED_writeReg( uint8_t bus, uint8_t addr, uint8_t reg, uint8_t val, uint8_t page )
|
||||||
{
|
{
|
||||||
// Page Setup
|
// Page Setup
|
||||||
uint16_t pageSetup[] = { addr, 0xFD, page };
|
uint16_t pageSetup[] = { addr, 0xFD, page };
|
||||||
@ -287,37 +340,37 @@ void LED_writeReg( uint8_t addr, uint8_t reg, uint8_t val, uint8_t page )
|
|||||||
uint16_t writeData[] = { addr, reg, val };
|
uint16_t writeData[] = { addr, reg, val };
|
||||||
|
|
||||||
// Setup page
|
// Setup page
|
||||||
while ( i2c_send( pageSetup, sizeof( pageSetup ) / 2 ) == -1 )
|
while ( i2c_send( bus, pageSetup, sizeof( pageSetup ) / 2 ) == -1 )
|
||||||
delay(1);
|
delay(1);
|
||||||
|
|
||||||
// Write register
|
// Write register
|
||||||
while ( i2c_send( writeData, sizeof( writeData ) / 2 ) == -1 )
|
while ( i2c_send( bus, writeData, sizeof( writeData ) / 2 ) == -1 )
|
||||||
delay(1);
|
delay(1);
|
||||||
|
|
||||||
// Delay until written
|
// Delay until written
|
||||||
while ( i2c_busy() )
|
while ( i2c_busy( bus ) )
|
||||||
delay(1);
|
delay(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read address
|
// Read address
|
||||||
// TODO Not working?
|
// TODO Not working?
|
||||||
uint8_t LED_readReg( uint8_t addr, uint8_t reg, uint8_t page )
|
uint8_t LED_readReg( uint8_t bus, uint8_t addr, uint8_t reg, uint8_t page )
|
||||||
{
|
{
|
||||||
// Software shutdown must be enabled to read registers
|
// Software shutdown must be enabled to read registers
|
||||||
LED_writeReg( addr, 0x0A, 0x00, 0x0B );
|
LED_writeReg( bus, addr, 0x0A, 0x00, 0x0B );
|
||||||
|
|
||||||
// Page Setup
|
// Page Setup
|
||||||
uint16_t pageSetup[] = { addr, 0xFD, page };
|
uint16_t pageSetup[] = { addr, 0xFD, page };
|
||||||
|
|
||||||
// Setup page
|
// Setup page
|
||||||
while ( i2c_send( pageSetup, sizeof( pageSetup ) / 2 ) == -1 )
|
while ( i2c_send( bus, pageSetup, sizeof( pageSetup ) / 2 ) == -1 )
|
||||||
delay(1);
|
delay(1);
|
||||||
|
|
||||||
// Register Setup
|
// Register Setup
|
||||||
uint16_t regSetup[] = { addr, reg };
|
uint16_t regSetup[] = { addr, reg };
|
||||||
|
|
||||||
// Configure register
|
// Configure register
|
||||||
while ( i2c_send( regSetup, sizeof( regSetup ) / 2 ) == -1 )
|
while ( i2c_send( bus, regSetup, sizeof( regSetup ) / 2 ) == -1 )
|
||||||
delay(1);
|
delay(1);
|
||||||
|
|
||||||
// Register Read Command
|
// Register Read Command
|
||||||
@ -325,11 +378,11 @@ uint8_t LED_readReg( uint8_t addr, uint8_t reg, uint8_t page )
|
|||||||
uint8_t recv_data;
|
uint8_t recv_data;
|
||||||
|
|
||||||
// Request single register byte
|
// Request single register byte
|
||||||
while ( i2c_read( regReadCmd, sizeof( regReadCmd ) / 2, &recv_data ) == -1 )
|
while ( i2c_read( bus, regReadCmd, sizeof( regReadCmd ) / 2, &recv_data ) == -1 )
|
||||||
delay(1);
|
delay(1);
|
||||||
|
|
||||||
// Disable software shutdown
|
// Disable software shutdown
|
||||||
LED_writeReg( addr, 0x0A, 0x01, 0x0B );
|
LED_writeReg( bus, addr, 0x0A, 0x01, 0x0B );
|
||||||
|
|
||||||
return recv_data;
|
return recv_data;
|
||||||
}
|
}
|
||||||
@ -352,13 +405,15 @@ void LED_reset()
|
|||||||
// Enable LEDs based upon mask
|
// Enable LEDs based upon 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;
|
uint8_t addr = LED_ChannelMapping[ ch ].addr;
|
||||||
LED_zeroPages( addr, 0x00, 8, 0x00, 0xB4 ); // LED Registers
|
uint8_t bus = LED_ChannelMapping[ ch ].bus;
|
||||||
|
LED_zeroPages( bus, addr, 0x00, 8, 0x00, 0xB4 ); // LED Registers
|
||||||
|
|
||||||
// For each page
|
// For each page
|
||||||
for ( uint8_t pg = 0; pg < LED_FrameBuffersMax * 2; pg++ )
|
for ( uint8_t pg = 0; pg < LED_FrameBuffersMax * 2; pg++ )
|
||||||
{
|
{
|
||||||
LED_sendPage(
|
LED_sendPage(
|
||||||
|
bus,
|
||||||
addr,
|
addr,
|
||||||
(uint16_t*)&LED_ledEnableMask[ ch ],
|
(uint16_t*)&LED_ledEnableMask[ ch ],
|
||||||
sizeof( LED_EnableBuffer ) / 2,
|
sizeof( LED_EnableBuffer ) / 2,
|
||||||
@ -367,20 +422,33 @@ void LED_reset()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set global brightness control
|
||||||
|
#if ISSI_Chip_31FL3732_define == 1
|
||||||
|
for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ )
|
||||||
|
{
|
||||||
|
uint8_t addr = LED_ChannelMapping[ ch ].addr;
|
||||||
|
uint8_t bus = LED_ChannelMapping[ ch ].bus;
|
||||||
|
// See, 31FL3732 datasheet for details on calculation
|
||||||
|
// Depends on Rext
|
||||||
|
LED_writeReg( bus, addr, 0x04, ISSI_Global_Brightness_define, 0x0B );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Setup ISSI auto frame play, but do not start yet
|
// Setup ISSI auto frame play, but do not start yet
|
||||||
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;
|
uint8_t addr = LED_ChannelMapping[ ch ].addr;
|
||||||
|
uint8_t bus = LED_ChannelMapping[ ch ].bus;
|
||||||
// CNS 1 loop, FNS 4 frames - 0x14
|
// CNS 1 loop, FNS 4 frames - 0x14
|
||||||
LED_writeReg( addr, 0x02, 0x14, 0x0B );
|
LED_writeReg( bus, addr, 0x02, 0x14, 0x0B );
|
||||||
|
|
||||||
// Default refresh speed - TxA
|
// Default refresh speed - TxA
|
||||||
// T is typically 11ms
|
// T is typically 11ms
|
||||||
// A is 1 to 64 (where 0 is 64)
|
// A is 1 to 64 (where 0 is 64)
|
||||||
LED_writeReg( addr, 0x03, ISSI_AnimationSpeed_define, 0x0B );
|
LED_writeReg( bus, addr, 0x03, ISSI_AnimationSpeed_define, 0x0B );
|
||||||
|
|
||||||
// Set MODE to Auto Frame Play
|
// Set MODE to Auto Frame Play
|
||||||
LED_writeReg( addr, 0x00, 0x08, 0x0B );
|
LED_writeReg( bus, addr, 0x00, 0x08, 0x0B );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do not disable software shutdown of ISSI chip unless current is high enough
|
// Do not disable software shutdown of ISSI chip unless current is high enough
|
||||||
@ -391,8 +459,9 @@ void LED_reset()
|
|||||||
// Disable Software shutdown of ISSI chip
|
// Disable Software shutdown of ISSI chip
|
||||||
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;
|
uint8_t addr = LED_ChannelMapping[ ch ].addr;
|
||||||
LED_writeReg( addr, 0x0A, 0x01, 0x0B );
|
uint8_t bus = LED_ChannelMapping[ ch ].bus;
|
||||||
|
LED_writeReg( bus, addr, 0x0A, 0x01, 0x0B );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -407,18 +476,18 @@ inline void LED_setup()
|
|||||||
i2c_setup();
|
i2c_setup();
|
||||||
|
|
||||||
// Setup LED_pageBuffer addresses and brightness section
|
// Setup LED_pageBuffer addresses and brightness section
|
||||||
LED_pageBuffer[0].i2c_addr = ISSI_Ch1;
|
LED_pageBuffer[0].i2c_addr = LED_MapCh1_Addr_define;
|
||||||
LED_pageBuffer[0].reg_addr = 0x24;
|
LED_pageBuffer[0].reg_addr = 0x24;
|
||||||
#if ISSI_Chips_define >= 2
|
#if ISSI_Chips_define >= 2
|
||||||
LED_pageBuffer[1].i2c_addr = ISSI_Ch2;
|
LED_pageBuffer[1].i2c_addr = LED_MapCh2_Addr_define;
|
||||||
LED_pageBuffer[1].reg_addr = 0x24;
|
LED_pageBuffer[1].reg_addr = 0x24;
|
||||||
#endif
|
#endif
|
||||||
#if ISSI_Chips_define >= 3
|
#if ISSI_Chips_define >= 3
|
||||||
LED_pageBuffer[2].i2c_addr = ISSI_Ch3;
|
LED_pageBuffer[2].i2c_addr = LED_MapCh3_Addr_define;
|
||||||
LED_pageBuffer[2].reg_addr = 0x24;
|
LED_pageBuffer[2].reg_addr = 0x24;
|
||||||
#endif
|
#endif
|
||||||
#if ISSI_Chips_define >= 4
|
#if ISSI_Chips_define >= 4
|
||||||
LED_pageBuffer[3].i2c_addr = ISSI_Ch4;
|
LED_pageBuffer[3].i2c_addr = LED_MapCh4_Addr_define;
|
||||||
LED_pageBuffer[3].reg_addr = 0x24;
|
LED_pageBuffer[3].reg_addr = 0x24;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -431,8 +500,9 @@ inline void LED_setup()
|
|||||||
// This needs to be done before disabling the hardware shutdown (or the leds will do undefined things)
|
// This needs to be done before disabling the hardware shutdown (or the leds will do undefined things)
|
||||||
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;
|
uint8_t addr = LED_ChannelMapping[ ch ].addr;
|
||||||
LED_zeroPages( addr, 0x0B, 1, 0x00, 0x0C ); // Control Registers
|
uint8_t bus = LED_ChannelMapping[ ch ].bus;
|
||||||
|
LED_zeroPages( bus, addr, 0x0B, 1, 0x00, 0x0C ); // Control Registers
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disable Hardware shutdown of ISSI chip (pull high)
|
// Disable Hardware shutdown of ISSI chip (pull high)
|
||||||
@ -455,6 +525,7 @@ inline void LED_setup()
|
|||||||
|
|
||||||
// LED Linked Send
|
// LED Linked Send
|
||||||
// Call-back for i2c write when updating led display
|
// Call-back for i2c write when updating led display
|
||||||
|
// TODO Optimize linked send for multiple i2c buses
|
||||||
uint8_t LED_chipSend;
|
uint8_t LED_chipSend;
|
||||||
void LED_linkedSend()
|
void LED_linkedSend()
|
||||||
{
|
{
|
||||||
@ -476,6 +547,9 @@ void LED_linkedSend()
|
|||||||
// Update ISSI Frame State
|
// Update ISSI Frame State
|
||||||
Pixel_FrameState = FrameState_Sending;
|
Pixel_FrameState = FrameState_Sending;
|
||||||
|
|
||||||
|
// Lookup bus number
|
||||||
|
uint8_t bus = LED_ChannelMapping[ LED_chipSend ].bus;
|
||||||
|
|
||||||
// Debug
|
// Debug
|
||||||
/*
|
/*
|
||||||
dbug_msg("Linked Send: chip(");
|
dbug_msg("Linked Send: chip(");
|
||||||
@ -500,6 +574,7 @@ void LED_linkedSend()
|
|||||||
|
|
||||||
// Send, and recursively call this function when finished
|
// Send, and recursively call this function when finished
|
||||||
while ( i2c_send_sequence(
|
while ( i2c_send_sequence(
|
||||||
|
bus,
|
||||||
(uint16_t*)&LED_pageBuffer[ LED_chipSend ],
|
(uint16_t*)&LED_pageBuffer[ LED_chipSend ],
|
||||||
sizeof( LED_Buffer ) / 2,
|
sizeof( LED_Buffer ) / 2,
|
||||||
0,
|
0,
|
||||||
@ -527,8 +602,9 @@ inline void LED_scan()
|
|||||||
// Enable Software shutdown of ISSI chip
|
// Enable Software shutdown of ISSI chip
|
||||||
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;
|
uint8_t addr = LED_ChannelMapping[ ch ].addr;
|
||||||
LED_writeReg( addr, 0x0A, 0x00, 0x0B );
|
uint8_t bus = LED_ChannelMapping[ ch ].bus;
|
||||||
|
LED_writeReg( bus, addr, 0x0A, 0x00, 0x0B );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -536,8 +612,9 @@ inline void LED_scan()
|
|||||||
// Disable Software shutdown of ISSI chip
|
// Disable Software shutdown of ISSI chip
|
||||||
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;
|
uint8_t addr = LED_ChannelMapping[ ch ].addr;
|
||||||
LED_writeReg( addr, 0x0A, 0x01, 0x0B );
|
uint8_t bus = LED_ChannelMapping[ ch ].bus;
|
||||||
|
LED_writeReg( bus, addr, 0x0A, 0x01, 0x0B );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -602,11 +679,12 @@ inline void LED_scan()
|
|||||||
for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ )
|
for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ )
|
||||||
{
|
{
|
||||||
// Page Setup
|
// Page Setup
|
||||||
uint8_t addr = LED_pageBuffer[ ch ].i2c_addr;
|
uint8_t addr = LED_ChannelMapping[ ch ].addr;
|
||||||
|
uint8_t bus = LED_ChannelMapping[ ch ].bus;
|
||||||
uint16_t pageSetup[] = { addr, 0xFD, LED_FrameBufferPage };
|
uint16_t pageSetup[] = { addr, 0xFD, LED_FrameBufferPage };
|
||||||
|
|
||||||
// Send each update
|
// Send each update
|
||||||
while ( i2c_send( pageSetup, sizeof( pageSetup ) / 2 ) == -1 )
|
while ( i2c_send( bus, pageSetup, sizeof( pageSetup ) / 2 ) == -1 )
|
||||||
delay(1);
|
delay(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -699,7 +777,12 @@ void LED_control( LedControl *control )
|
|||||||
// TODO Support multiple frames
|
// TODO Support multiple frames
|
||||||
for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ )
|
for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ )
|
||||||
{
|
{
|
||||||
LED_sendPage( LED_pageBuffer[ ch ].i2c_addr, (uint16_t*)&LED_pageBuffer[ ch ], sizeof( LED_Buffer ) / 2, 0 );
|
LED_sendPage(
|
||||||
|
LED_ChannelMapping[ ch ].bus,
|
||||||
|
LED_ChannelMapping[ ch ].addr,
|
||||||
|
(uint16_t*)&LED_pageBuffer[ ch ],
|
||||||
|
sizeof( LED_Buffer ) / 2, 0
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -806,6 +889,7 @@ void LED_control_capability( uint8_t state, uint8_t stateType, uint8_t *args )
|
|||||||
// TODO Currently not working correctly
|
// TODO Currently not working correctly
|
||||||
void cliFunc_i2cSend( char* args )
|
void cliFunc_i2cSend( char* args )
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
char* curArgs;
|
char* curArgs;
|
||||||
char* arg1Ptr;
|
char* arg1Ptr;
|
||||||
char* arg2Ptr = args;
|
char* arg2Ptr = args;
|
||||||
@ -850,6 +934,7 @@ void cliFunc_i2cSend( char* args )
|
|||||||
print( NL );
|
print( NL );
|
||||||
|
|
||||||
i2c_send( buffer, bufferLen );
|
i2c_send( buffer, bufferLen );
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -917,8 +1002,11 @@ void cliFunc_ledReset( char* args )
|
|||||||
|
|
||||||
for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ )
|
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(
|
||||||
|
LED_ChannelMapping[ ch ].bus,
|
||||||
|
LED_ChannelMapping[ ch ].addr,
|
||||||
|
0x0B, 1, 0x00, 0x0C
|
||||||
|
); // Control Registers
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear buffers
|
// Clear buffers
|
||||||
@ -928,6 +1016,18 @@ void cliFunc_ledReset( char* args )
|
|||||||
}
|
}
|
||||||
|
|
||||||
LED_reset();
|
LED_reset();
|
||||||
|
|
||||||
|
// TODO Remove me
|
||||||
|
/*
|
||||||
|
for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ )
|
||||||
|
{
|
||||||
|
LED_sendPage(
|
||||||
|
LED_ChannelMapping[ ch ].bus,
|
||||||
|
LED_ChannelMapping[ ch ].addr,
|
||||||
|
0x0B, 1, 0x00, 0x0C
|
||||||
|
); // Control Registers
|
||||||
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void cliFunc_ledSpeed( char* args )
|
void cliFunc_ledSpeed( char* args )
|
||||||
@ -969,12 +1069,13 @@ void cliFunc_ledSpeed( char* args )
|
|||||||
// Set refresh speed per ISSI chip
|
// Set refresh speed per ISSI chip
|
||||||
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;
|
uint8_t addr = LED_ChannelMapping[ ch ].addr;
|
||||||
|
uint8_t bus = LED_ChannelMapping[ ch ].bus;
|
||||||
|
|
||||||
// Default refresh speed - TxA
|
// Default refresh speed - TxA
|
||||||
// T is typically 11ms
|
// T is typically 11ms
|
||||||
// A is 1 to 64 (where 0 is 64)
|
// A is 1 to 64 (where 0 is 64)
|
||||||
LED_writeReg( addr, 0x03, speed, 0x0B );
|
LED_writeReg( bus, addr, 0x03, speed, 0x0B );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1039,8 +1140,10 @@ void cliFunc_ledNFrame( char* args )
|
|||||||
// XXX It is more efficient to only send positions that are used
|
// XXX It is more efficient to only send positions that are used
|
||||||
// However, this may actually have more addressing overhead
|
// However, this may actually have more addressing overhead
|
||||||
// For simplicity, just sending the full 144 positions per ISSI chip
|
// For simplicity, just sending the full 144 positions per ISSI chip
|
||||||
uint8_t addr = LED_pageBuffer[ ch ].i2c_addr;
|
uint8_t addr = LED_ChannelMapping[ ch ].addr;
|
||||||
|
uint8_t bus = LED_ChannelMapping[ ch ].bus;
|
||||||
LED_sendPage(
|
LED_sendPage(
|
||||||
|
bus,
|
||||||
addr,
|
addr,
|
||||||
(uint16_t*)&LED_pageBuffer[ ch ],
|
(uint16_t*)&LED_pageBuffer[ ch ],
|
||||||
sizeof( LED_Buffer ) / 2,
|
sizeof( LED_Buffer ) / 2,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
Name = KType;
|
Name = KType;
|
||||||
Version = 0.1;
|
Version = 0.2;
|
||||||
Author = "HaaTa (Jacob Alexander) 2015";
|
Author = "HaaTa (Jacob Alexander) 2015-2016";
|
||||||
KLL = 0.3c;
|
KLL = 0.3c;
|
||||||
|
|
||||||
# Modified Date
|
# Modified Date
|
||||||
@ -115,11 +115,20 @@ S0x5D : U"Down";
|
|||||||
S0x5E : U"Right";
|
S0x5E : U"Right";
|
||||||
|
|
||||||
|
|
||||||
|
# Driver Chip
|
||||||
|
ISSI_Chip_31FL3732 = 1;
|
||||||
|
|
||||||
|
# Global Brightness
|
||||||
|
ISSI_Global_Brightness = 0xFF; # 0xFF by default (max)
|
||||||
|
|
||||||
# Available ISSI Chips
|
# Available ISSI Chips
|
||||||
ISSI_Chips = 4; # 1 by default
|
ISSI_Chips = 4; # 2 by default
|
||||||
|
|
||||||
|
# I2C Buses
|
||||||
|
ISSI_I2C_Buses = 2; # 1 by default
|
||||||
|
|
||||||
# Default animation speed
|
# Default animation speed
|
||||||
ISSI_AnimationSpeed = 14; # 20 by default
|
ISSI_AnimationSpeed = 6; # 20 by default
|
||||||
|
|
||||||
# LED Default Enable Mask
|
# LED Default Enable Mask
|
||||||
#
|
#
|
||||||
@ -175,19 +184,6 @@ ISSILedMask4 = "
|
|||||||
0xFF, 0xFF, /* C9-1 -> C9-16 */
|
0xFF, 0xFF, /* C9-1 -> C9-16 */
|
||||||
";
|
";
|
||||||
|
|
||||||
# Disabled for now
|
|
||||||
#ISSILedMask4 = "
|
|
||||||
# 0x00, 0x00, /* C1-1 -> C1-16 */
|
|
||||||
# 0x00, 0x00, /* C2-1 -> C2-16 */
|
|
||||||
# 0x00, 0x00, /* C3-1 -> C3-16 */
|
|
||||||
# 0x00, 0x00, /* C4-1 -> C4-16 */
|
|
||||||
# 0x00, 0x00, /* C5-1 -> C5-16 */
|
|
||||||
# 0x00, 0x00, /* C6-1 -> C6-16 */
|
|
||||||
# 0x00, 0x00, /* C7-1 -> C7-16 */
|
|
||||||
# 0x00, 0x00, /* C8-1 -> C8-16 */
|
|
||||||
# 0x00, 0x00, /* C9-1 -> C9-16 */
|
|
||||||
#";
|
|
||||||
|
|
||||||
ISSILedBrightness1 = "
|
ISSILedBrightness1 = "
|
||||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, /* C1-1 -> C1-16 */
|
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, /* C1-1 -> C1-16 */
|
||||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, /* C2-1 -> C2-16 */
|
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, /* C2-1 -> C2-16 */
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (C) 2014-2015 by Jacob Alexander
|
/* Copyright (C) 2014-2016 by Jacob Alexander
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@ -49,8 +49,8 @@
|
|||||||
// PTC1..5
|
// PTC1..5
|
||||||
|
|
||||||
// Define Rows (Sense) and Columns (Strobes)
|
// Define Rows (Sense) and Columns (Strobes)
|
||||||
GPIO_Pin Matrix_cols[] = { gpio(B,2), gpio(B,3), gpio(B,18), gpio(B,19), gpio(C,0), gpio(C,8), gpio(C,9), gpio(C,10), gpio(C,11), gpio(D,0) };
|
GPIO_Pin Matrix_cols[] = { gpio(B,2), gpio(B,3), gpio(B,18), gpio(B,19), gpio(C,0), gpio(C,8), gpio(C,9), gpio(D,0), gpio(D,1), gpio(D,4) };
|
||||||
GPIO_Pin Matrix_rows[] = { gpio(D,1), gpio(D,4), gpio(D,5), gpio(D,6), gpio(D,7), gpio(C,1), gpio(C,2), gpio(C,3), gpio(C,4), gpio(C,5) };
|
GPIO_Pin Matrix_rows[] = { gpio(D,5), gpio(D,6), gpio(D,7), gpio(C,1), gpio(C,2), gpio(C,3), gpio(C,4), gpio(C,5), gpio(C,6), gpio(C,7) };
|
||||||
|
|
||||||
// Define type of scan matrix
|
// Define type of scan matrix
|
||||||
Config Matrix_type = Config_Pulldown;
|
Config Matrix_type = Config_Pulldown;
|
||||||
|
@ -82,7 +82,7 @@ inline uint8_t Scan_loop()
|
|||||||
Port_scan();
|
Port_scan();
|
||||||
|
|
||||||
// Scan Matrix
|
// Scan Matrix
|
||||||
Matrix_scan( Scan_scanCount++ );
|
//Matrix_scan( Scan_scanCount++ );
|
||||||
|
|
||||||
// Process any interconnect commands
|
// Process any interconnect commands
|
||||||
Connect_scan();
|
Connect_scan();
|
||||||
|
@ -409,7 +409,15 @@ void Matrix_scan( uint16_t scanNum )
|
|||||||
|
|
||||||
case KeyState_Invalid:
|
case KeyState_Invalid:
|
||||||
default:
|
default:
|
||||||
erro_print("Matrix scan bug!! Report me!");
|
erro_msg("Matrix scan bug!! Report me! - ");
|
||||||
|
printHex( state->prevState );
|
||||||
|
print(" Col: ");
|
||||||
|
printHex( strobe );
|
||||||
|
print(" Row: ");
|
||||||
|
printHex( sense );
|
||||||
|
print(" Key: ");
|
||||||
|
printHex( key );
|
||||||
|
print( NL );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,5 +10,8 @@ Date = 2015-10-23;
|
|||||||
portCross => Port_cross_capability();
|
portCross => Port_cross_capability();
|
||||||
|
|
||||||
# Capability to swap the USB port mapping
|
# Capability to swap the USB port mapping
|
||||||
portSwap => Port_swap_capability();
|
portSwapUSB => Port_usb_capability();
|
||||||
|
|
||||||
|
# Capability to swap the interconnect port mapping
|
||||||
|
portSwapInter => Port_uart_capability();
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (C) 2015 by Jacob Alexander
|
/* Copyright (C) 2015-2016 by Jacob Alexander
|
||||||
*
|
*
|
||||||
* This file is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -52,7 +52,8 @@
|
|||||||
|
|
||||||
// CLI Functions
|
// CLI Functions
|
||||||
void cliFunc_portCross( char* args );
|
void cliFunc_portCross( char* args );
|
||||||
void cliFunc_portSwap ( char* args );
|
void cliFunc_portUART ( char* args );
|
||||||
|
void cliFunc_portUSB ( char* args );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -62,11 +63,13 @@ uint32_t Port_lastcheck_ms;
|
|||||||
|
|
||||||
// Scan Module command dictionary
|
// Scan Module command dictionary
|
||||||
CLIDict_Entry( portCross, "Cross interconnect pins." );
|
CLIDict_Entry( portCross, "Cross interconnect pins." );
|
||||||
CLIDict_Entry( portSwap, "Swap USB ports manually, forces usb and interconnect to re-negotiate if necessary." );
|
CLIDict_Entry( portUSB, "Swap USB ports manually, forces usb and interconnect to re-negotiate if necessary." );
|
||||||
|
CLIDict_Entry( portUART, "Swap interconnect ports." );
|
||||||
|
|
||||||
CLIDict_Def( portCLIDict, "Port Swap Module Commands" ) = {
|
CLIDict_Def( portCLIDict, "Port Swap Module Commands" ) = {
|
||||||
CLIDict_Item( portCross ),
|
CLIDict_Item( portCross ),
|
||||||
CLIDict_Item( portSwap ),
|
CLIDict_Item( portUART ),
|
||||||
|
CLIDict_Item( portUSB ),
|
||||||
{ 0, 0, 0 } // Null entry for dictionary end
|
{ 0, 0, 0 } // Null entry for dictionary end
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -74,18 +77,26 @@ CLIDict_Def( portCLIDict, "Port Swap Module Commands" ) = {
|
|||||||
|
|
||||||
// ----- Functions -----
|
// ----- Functions -----
|
||||||
|
|
||||||
void Port_swap()
|
void Port_usb_swap()
|
||||||
{
|
{
|
||||||
info_print("USB Port Swap");
|
info_print("USB Port Swap");
|
||||||
|
|
||||||
// PTA13 - USB Swap
|
// PTA4 - USB Swap
|
||||||
GPIOA_PTOR |= (1<<13);
|
GPIOA_PTOR |= (1<<4);
|
||||||
|
|
||||||
// Re-initialize usb
|
// Re-initialize usb
|
||||||
// Call usb_configured() to check if usb is ready
|
// Call usb_configured() to check if usb is ready
|
||||||
usb_init();
|
usb_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Port_uart_swap()
|
||||||
|
{
|
||||||
|
info_print("Interconnect Line Swap");
|
||||||
|
|
||||||
|
// PTA13 - UART Swap
|
||||||
|
GPIOA_PTOR |= (1<<13);
|
||||||
|
}
|
||||||
|
|
||||||
void Port_cross()
|
void Port_cross()
|
||||||
{
|
{
|
||||||
info_print("Interconnect Line Cross");
|
info_print("Interconnect Line Cross");
|
||||||
@ -103,13 +114,19 @@ inline void Port_setup()
|
|||||||
// Register Scan CLI dictionary
|
// Register Scan CLI dictionary
|
||||||
CLI_registerDictionary( portCLIDict, portCLIDictName );
|
CLI_registerDictionary( portCLIDict, portCLIDictName );
|
||||||
|
|
||||||
|
// PTA4 - USB Swap
|
||||||
|
// Start, disabled
|
||||||
|
GPIOA_PDDR |= (1<<4);
|
||||||
|
PORTA_PCR4 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
|
||||||
|
GPIOA_PCOR |= (1<<4);
|
||||||
|
|
||||||
// PTA12 - UART Tx/Rx cross-over
|
// PTA12 - UART Tx/Rx cross-over
|
||||||
// Start, disabled
|
// Start, disabled
|
||||||
GPIOA_PDDR |= (1<<12);
|
GPIOA_PDDR |= (1<<12);
|
||||||
PORTA_PCR12 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
|
PORTA_PCR12 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
|
||||||
GPIOA_PCOR |= (1<<12);
|
GPIOA_PCOR |= (1<<12);
|
||||||
|
|
||||||
// PTA13 - USB Swap
|
// PTA13 - UART Swap
|
||||||
// Start, disabled
|
// Start, disabled
|
||||||
GPIOA_PDDR |= (1<<13);
|
GPIOA_PDDR |= (1<<13);
|
||||||
PORTA_PCR13 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
|
PORTA_PCR13 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
|
||||||
@ -136,7 +153,7 @@ inline uint8_t Port_scan()
|
|||||||
// USB not initialized, attempt to swap
|
// USB not initialized, attempt to swap
|
||||||
if ( !usb_configured() )
|
if ( !usb_configured() )
|
||||||
{
|
{
|
||||||
Port_swap();
|
Port_usb_swap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,12 +172,12 @@ void Port_currentChange( unsigned int current )
|
|||||||
|
|
||||||
// ----- Capabilities -----
|
// ----- Capabilities -----
|
||||||
|
|
||||||
void Port_swap_capability( uint8_t state, uint8_t stateType, uint8_t *args )
|
void Port_uart_capability( uint8_t state, uint8_t stateType, uint8_t *args )
|
||||||
{
|
{
|
||||||
// Display capability name
|
// Display capability name
|
||||||
if ( stateType == 0xFF && state == 0xFF )
|
if ( stateType == 0xFF && state == 0xFF )
|
||||||
{
|
{
|
||||||
print("Port_swap_capability()");
|
print("Port_uart_capability()");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,7 +186,24 @@ void Port_swap_capability( uint8_t state, uint8_t stateType, uint8_t *args )
|
|||||||
if ( state != 0x03 )
|
if ( state != 0x03 )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Port_swap();
|
Port_uart_swap();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Port_usb_capability( uint8_t state, uint8_t stateType, uint8_t *args )
|
||||||
|
{
|
||||||
|
// Display capability name
|
||||||
|
if ( stateType == 0xFF && state == 0xFF )
|
||||||
|
{
|
||||||
|
print("Port_usb_capability()");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only only release
|
||||||
|
// TODO Analog
|
||||||
|
if ( state != 0x03 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
Port_usb_swap();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Port_cross_capability( uint8_t state, uint8_t stateType, uint8_t *args )
|
void Port_cross_capability( uint8_t state, uint8_t stateType, uint8_t *args )
|
||||||
@ -193,10 +227,16 @@ void Port_cross_capability( uint8_t state, uint8_t stateType, uint8_t *args )
|
|||||||
|
|
||||||
// ----- CLI Command Functions -----
|
// ----- CLI Command Functions -----
|
||||||
|
|
||||||
void cliFunc_portSwap( char* args )
|
void cliFunc_portUART( char* args )
|
||||||
{
|
{
|
||||||
print( NL );
|
print( NL );
|
||||||
Port_swap();
|
Port_uart_swap();
|
||||||
|
}
|
||||||
|
|
||||||
|
void cliFunc_portUSB( char* args )
|
||||||
|
{
|
||||||
|
print( NL );
|
||||||
|
Port_usb_swap();
|
||||||
}
|
}
|
||||||
|
|
||||||
void cliFunc_portCross( char* args )
|
void cliFunc_portCross( char* args )
|
||||||
|
@ -1161,7 +1161,7 @@ void Connect_scan()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Limit how often we do cable checks
|
// Limit how often we do cable checks
|
||||||
//uint32_t time_compare = 0x007; // Used for debugging cables -HaaTa
|
//uint32_t time_compare = 0x007; // XXX Used for debugging cables -HaaTa
|
||||||
uint32_t time_compare = 0x7FF; // Must be all 1's, 0x3FF is valid, 0x4FF is not
|
uint32_t time_compare = 0x7FF; // Must be all 1's, 0x3FF is valid, 0x4FF is not
|
||||||
uint32_t current_time = systick_millis_count;
|
uint32_t current_time = systick_millis_count;
|
||||||
if ( Connect_lastCheck != current_time
|
if ( Connect_lastCheck != current_time
|
||||||
|
Reference in New Issue
Block a user