Merge commit '6d0a62920410f50d7f6707960ca1ca0c8fd1d1fa' into firmware21
This commit is contained in:
@@ -27,9 +27,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#include "wait.h"
|
||||
#include "adc.h"
|
||||
#include "i2c_master.h"
|
||||
#include "spi.h"
|
||||
#include "shift_register.h"
|
||||
|
||||
#include "./usb/usb2422.h"
|
||||
#include "./usb/usb_hub.h"
|
||||
|
||||
#ifndef MD_BOOTLOADER
|
||||
|
||||
|
||||
@@ -564,4 +564,23 @@ uint8_t i2c_led_q_run(void) {
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
__attribute__((weak)) void i2c_init(void) {
|
||||
static bool is_initialised = false;
|
||||
if (!is_initialised) {
|
||||
is_initialised = true;
|
||||
|
||||
i2c0_init();
|
||||
}
|
||||
}
|
||||
|
||||
i2c_status_t i2c_transmit(uint8_t address, const uint8_t *data, uint16_t length, uint16_t timeout) {
|
||||
uint8_t ret = i2c0_transmit(address, (uint8_t *)data, length, timeout);
|
||||
SERCOM0->I2CM.CTRLB.bit.CMD = 0x03;
|
||||
while (SERCOM0->I2CM.SYNCBUSY.bit.SYSOP) {
|
||||
DBGC(DC_USB_WRITE2422_BLOCK_SYNC_SYSOP);
|
||||
}
|
||||
return ret ? I2C_STATUS_SUCCESS : I2C_STATUS_ERROR;
|
||||
}
|
||||
|
||||
#endif // !defined(MD_BOOTLOADER) && defined(RGB_MATRIX_ENABLE)
|
||||
|
||||
@@ -101,4 +101,13 @@ void i2c0_init(void);
|
||||
uint8_t i2c0_transmit(uint8_t address, uint8_t *data, uint16_t length, uint16_t timeout);
|
||||
void i2c0_stop(void);
|
||||
|
||||
// Terrible interface compatiblity...
|
||||
#define I2C_STATUS_SUCCESS (0)
|
||||
#define I2C_STATUS_ERROR (-1)
|
||||
|
||||
typedef int16_t i2c_status_t;
|
||||
|
||||
void i2c_init(void);
|
||||
i2c_status_t i2c_transmit(uint8_t address, const uint8_t *data, uint16_t length, uint16_t timeout);
|
||||
|
||||
#endif // _I2C_MASTER_H_
|
||||
|
||||
@@ -40,6 +40,10 @@ void send_mouse(report_mouse_t *report);
|
||||
void send_system(uint16_t data);
|
||||
void send_consumer(uint16_t data);
|
||||
|
||||
#ifdef DEFERRED_EXEC_ENABLE
|
||||
void deferred_exec_task(void);
|
||||
#endif // DEFERRED_EXEC_ENABLE
|
||||
|
||||
host_driver_t arm_atsam_driver = {keyboard_leds, send_keyboard, send_mouse, send_system, send_consumer};
|
||||
|
||||
uint8_t led_states;
|
||||
@@ -296,7 +300,7 @@ int main(void) {
|
||||
|
||||
matrix_init();
|
||||
|
||||
USB2422_init();
|
||||
USB_Hub_init();
|
||||
|
||||
DBGC(DC_MAIN_UDC_START_BEGIN);
|
||||
udc_start();
|
||||
@@ -306,7 +310,7 @@ int main(void) {
|
||||
CDC_init();
|
||||
DBGC(DC_MAIN_CDC_INIT_COMPLETE);
|
||||
|
||||
while (USB2422_Port_Detect_Init() == 0) {
|
||||
while (USB_Hub_Port_Detect_Init() == 0) {
|
||||
}
|
||||
|
||||
DBG_LED_OFF;
|
||||
@@ -360,6 +364,11 @@ int main(void) {
|
||||
}
|
||||
#endif // CONSOLE_ENABLE
|
||||
|
||||
#ifdef DEFERRED_EXEC_ENABLE
|
||||
// Run deferred executions
|
||||
deferred_exec_task();
|
||||
#endif // DEFERRED_EXEC_ENABLE
|
||||
|
||||
// Run housekeeping
|
||||
housekeeping_task();
|
||||
}
|
||||
|
||||
@@ -15,6 +15,10 @@ You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define FLUSH_TIMEOUT 5000
|
||||
#define EECONFIG_MD_LED ((uint8_t*)(EECONFIG_SIZE + 64))
|
||||
#define MD_LED_CONFIG_VERSION 1
|
||||
|
||||
#ifdef RGB_MATRIX_ENABLE
|
||||
# include "arm_atsam_protocol.h"
|
||||
# include "led.h"
|
||||
@@ -23,8 +27,41 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
# include <math.h>
|
||||
|
||||
# ifdef USE_MASSDROP_CONFIGURATOR
|
||||
// TODO?: wire these up to keymap.c
|
||||
md_led_config_t md_led_config = {0};
|
||||
|
||||
EECONFIG_DEBOUNCE_HELPER(md_led, EECONFIG_MD_LED, md_led_config);
|
||||
|
||||
void eeconfig_update_md_led_default(void) {
|
||||
md_led_config.ver = MD_LED_CONFIG_VERSION;
|
||||
|
||||
gcr_desired = LED_GCR_MAX;
|
||||
led_animation_orientation = 0;
|
||||
led_animation_direction = 0;
|
||||
led_animation_breathing = 0;
|
||||
led_animation_id = 0;
|
||||
led_animation_speed = 4.0f;
|
||||
led_lighting_mode = LED_MODE_NORMAL;
|
||||
led_enabled = 1;
|
||||
led_animation_breathe_cur = BREATHE_MIN_STEP;
|
||||
breathe_dir = 1;
|
||||
led_animation_circular = 0;
|
||||
led_edge_brightness = 1.0f;
|
||||
led_ratio_brightness = 1.0f;
|
||||
led_edge_mode = LED_EDGE_MODE_ALL;
|
||||
|
||||
eeconfig_flush_md_led(true);
|
||||
}
|
||||
|
||||
void md_led_changed(void) { eeconfig_flag_md_led(true); }
|
||||
|
||||
// todo: use real task rather than this bodge
|
||||
void housekeeping_task_kb(void) { eeconfig_flush_md_led_task(FLUSH_TIMEOUT); }
|
||||
|
||||
__attribute__((weak)) led_instruction_t led_instructions[] = {{.end = 1}};
|
||||
static void md_rgb_matrix_config_override(int i);
|
||||
# else
|
||||
uint8_t gcr_desired;
|
||||
# endif // USE_MASSDROP_CONFIGURATOR
|
||||
|
||||
void SERCOM1_0_Handler(void) {
|
||||
@@ -56,7 +93,6 @@ issi3733_driver_t issidrv[ISSI3733_DRIVER_COUNT];
|
||||
issi3733_led_t led_map[ISSI3733_LED_COUNT] = ISSI3733_LED_MAP;
|
||||
RGB led_buffer[ISSI3733_LED_COUNT];
|
||||
|
||||
uint8_t gcr_desired;
|
||||
uint8_t gcr_actual;
|
||||
uint8_t gcr_actual_last;
|
||||
# ifdef USE_MASSDROP_CONFIGURATOR
|
||||
@@ -218,6 +254,13 @@ static void led_set_all(uint8_t r, uint8_t g, uint8_t b) {
|
||||
static void init(void) {
|
||||
DBGC(DC_LED_MATRIX_INIT_BEGIN);
|
||||
|
||||
# ifdef USE_MASSDROP_CONFIGURATOR
|
||||
eeconfig_init_md_led();
|
||||
if (md_led_config.ver != MD_LED_CONFIG_VERSION) {
|
||||
eeconfig_update_md_led_default();
|
||||
}
|
||||
# endif
|
||||
|
||||
issi3733_prepare_arrays();
|
||||
|
||||
md_rgb_matrix_prepare();
|
||||
@@ -331,17 +374,6 @@ const rgb_matrix_driver_t rgb_matrix_driver = {.init = init, .flush = flush, .se
|
||||
# ifdef USE_MASSDROP_CONFIGURATOR
|
||||
// Ported from Massdrop QMK GitHub Repo
|
||||
|
||||
// TODO?: wire these up to keymap.c
|
||||
uint8_t led_animation_orientation = 0;
|
||||
uint8_t led_animation_direction = 0;
|
||||
uint8_t led_animation_breathing = 0;
|
||||
uint8_t led_animation_id = 0;
|
||||
float led_animation_speed = 4.0f;
|
||||
uint8_t led_lighting_mode = LED_MODE_NORMAL;
|
||||
uint8_t led_enabled = 1;
|
||||
uint8_t led_animation_breathe_cur = BREATHE_MIN_STEP;
|
||||
uint8_t breathe_dir = 1;
|
||||
|
||||
static void led_run_pattern(led_setup_t* f, float* ro, float* go, float* bo, float pos) {
|
||||
float po;
|
||||
|
||||
@@ -398,16 +430,32 @@ static void led_run_pattern(led_setup_t* f, float* ro, float* go, float* bo, flo
|
||||
}
|
||||
}
|
||||
|
||||
# define RGB_MAX_DISTANCE 232.9635f
|
||||
|
||||
static void md_rgb_matrix_config_override(int i) {
|
||||
float ro = 0;
|
||||
float go = 0;
|
||||
float bo = 0;
|
||||
|
||||
float po = (led_animation_orientation) ? (float)g_led_config.point[i].y / 64.f * 100 : (float)g_led_config.point[i].x / 224.f * 100;
|
||||
float po;
|
||||
|
||||
uint8_t highest_active_layer = biton32(layer_state);
|
||||
|
||||
if (led_lighting_mode == LED_MODE_KEYS_ONLY && HAS_FLAGS(g_led_config.flags[i], LED_FLAG_UNDERGLOW)) {
|
||||
if (led_animation_circular) {
|
||||
// TODO: should use min/max values from LED configuration instead of
|
||||
// hard-coded 224, 64
|
||||
// po = sqrtf((powf(fabsf((disp.width / 2) - (led_cur->x - disp.left)), 2) + powf(fabsf((disp.height / 2) - (led_cur->y - disp.bottom)), 2))) / disp.max_distance * 100;
|
||||
po = sqrtf((powf(fabsf((224 / 2) - (float)g_led_config.point[i].x), 2) + powf(fabsf((64 / 2) - (float)g_led_config.point[i].y), 2))) / RGB_MAX_DISTANCE * 100;
|
||||
} else {
|
||||
if (led_animation_orientation) {
|
||||
po = (float)g_led_config.point[i].y / 64.f * 100;
|
||||
} else {
|
||||
po = (float)g_led_config.point[i].x / 224.f * 100;
|
||||
}
|
||||
}
|
||||
|
||||
if (led_edge_mode == LED_EDGE_MODE_ALTERNATE && LED_IS_EDGE_ALT(led_map[i].scan)) {
|
||||
// Do not act on this LED (Edge alternate lighting mode)
|
||||
} else if (led_lighting_mode == LED_MODE_KEYS_ONLY && HAS_FLAGS(g_led_config.flags[i], LED_FLAG_UNDERGLOW)) {
|
||||
// Do not act on this LED
|
||||
} else if (led_lighting_mode == LED_MODE_NON_KEYS_ONLY && !HAS_FLAGS(g_led_config.flags[i], LED_FLAG_UNDERGLOW)) {
|
||||
// Do not act on this LED
|
||||
@@ -465,6 +513,26 @@ static void md_rgb_matrix_config_override(int i) {
|
||||
}
|
||||
}
|
||||
|
||||
// Adjust edge LED brightness
|
||||
if (led_edge_brightness != 1 && LED_IS_EDGE(led_map[i].scan)) {
|
||||
ro *= led_edge_brightness;
|
||||
go *= led_edge_brightness;
|
||||
bo *= led_edge_brightness;
|
||||
}
|
||||
|
||||
// Adjust ratio of key vs. underglow (edge) LED brightness
|
||||
if (LED_IS_EDGE(led_map[i].scan) && led_ratio_brightness > 1.0) {
|
||||
// Decrease edge (underglow) LEDs
|
||||
ro *= (2.0 - led_ratio_brightness);
|
||||
go *= (2.0 - led_ratio_brightness);
|
||||
bo *= (2.0 - led_ratio_brightness);
|
||||
} else if (LED_IS_KEY(led_map[i].scan) && led_ratio_brightness < 1.0) {
|
||||
// Decrease KEY LEDs
|
||||
ro *= led_ratio_brightness;
|
||||
go *= led_ratio_brightness;
|
||||
bo *= led_ratio_brightness;
|
||||
}
|
||||
|
||||
led_buffer[i].r = (uint8_t)ro;
|
||||
led_buffer[i].g = (uint8_t)go;
|
||||
led_buffer[i].b = (uint8_t)bo;
|
||||
|
||||
@@ -19,6 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#define _LED_MATRIX_H_
|
||||
|
||||
#include "quantum.h"
|
||||
#include "eeprom.h"
|
||||
|
||||
// From keyboard
|
||||
#include "config_led.h"
|
||||
@@ -79,7 +80,6 @@ typedef struct issi3733_led_s {
|
||||
|
||||
extern issi3733_driver_t issidrv[ISSI3733_DRIVER_COUNT];
|
||||
|
||||
extern uint8_t gcr_desired;
|
||||
extern uint8_t gcr_breathe;
|
||||
extern uint8_t gcr_actual;
|
||||
extern uint8_t gcr_actual_last;
|
||||
@@ -128,6 +128,8 @@ typedef struct led_instruction_s {
|
||||
uint32_t id1; // Bitwise id, IDs 32-63
|
||||
uint32_t id2; // Bitwise id, IDs 64-95
|
||||
uint32_t id3; // Bitwise id, IDs 96-127
|
||||
uint32_t id4; // Bitwise id, IDs 128-159
|
||||
uint32_t id5; // Bitwise id, IDs 160-191
|
||||
uint8_t layer;
|
||||
uint8_t r;
|
||||
uint8_t g;
|
||||
@@ -138,14 +140,43 @@ typedef struct led_instruction_s {
|
||||
|
||||
extern led_instruction_t led_instructions[];
|
||||
|
||||
extern uint8_t led_animation_breathing;
|
||||
extern uint8_t led_animation_id;
|
||||
extern float led_animation_speed;
|
||||
extern uint8_t led_lighting_mode;
|
||||
extern uint8_t led_enabled;
|
||||
extern uint8_t led_animation_breathe_cur;
|
||||
extern uint8_t led_animation_direction;
|
||||
extern uint8_t breathe_dir;
|
||||
typedef struct led_config_s {
|
||||
uint8_t ver; // assumed to be zero on eeprom reset
|
||||
|
||||
uint8_t desired_gcr;
|
||||
uint8_t animation_breathing;
|
||||
uint8_t animation_id;
|
||||
float animation_speed;
|
||||
uint8_t lighting_mode;
|
||||
uint8_t enabled;
|
||||
uint8_t animation_breathe_cur;
|
||||
uint8_t animation_direction;
|
||||
uint8_t animation_breathe_dir;
|
||||
uint8_t animation_orientation;
|
||||
uint8_t animation_circular;
|
||||
float edge_brightness;
|
||||
float ratio_brightness;
|
||||
uint8_t edge_mode;
|
||||
} md_led_config_t;
|
||||
|
||||
extern md_led_config_t md_led_config;
|
||||
|
||||
void md_led_changed(void);
|
||||
|
||||
# define gcr_desired md_led_config.desired_gcr
|
||||
# define led_animation_breathing md_led_config.animation_breathing
|
||||
# define led_animation_id md_led_config.animation_id
|
||||
# define led_animation_speed md_led_config.animation_speed
|
||||
# define led_lighting_mode md_led_config.lighting_mode
|
||||
# define led_enabled md_led_config.enabled
|
||||
# define led_animation_breathe_cur md_led_config.animation_breathe_cur
|
||||
# define led_animation_direction md_led_config.animation_direction
|
||||
# define breathe_dir md_led_config.animation_breathe_dir
|
||||
# define led_animation_orientation md_led_config.animation_orientation
|
||||
# define led_animation_circular md_led_config.animation_circular
|
||||
# define led_edge_brightness md_led_config.edge_brightness
|
||||
# define led_ratio_brightness md_led_config.ratio_brightness
|
||||
# define led_edge_mode md_led_config.edge_mode
|
||||
|
||||
# define LED_MODE_NORMAL 0 // Must be 0
|
||||
# define LED_MODE_KEYS_ONLY 1
|
||||
@@ -153,6 +184,21 @@ extern uint8_t breathe_dir;
|
||||
# define LED_MODE_INDICATORS_ONLY 3
|
||||
# define LED_MODE_MAX_INDEX LED_MODE_INDICATORS_ONLY // Must be highest value
|
||||
|
||||
# define LED_EDGE_MODE_ALL 0 // All edge LEDs are active (Must be 0)
|
||||
# define LED_EDGE_MODE_ALTERNATE 1 // Alternate mode of edge LEDs are active (Intention is for 'only every other edge LED' to be active)
|
||||
# define LED_EDGE_MODE_MAX LED_EDGE_MODE_ALTERNATE // Must be the highest valued LED edge mode
|
||||
|
||||
# define LED_EDGE_FULL_MODE 255 // LEDs configured with this scan code will always be on for edge lighting modes
|
||||
# define LED_EDGE_ALT_MODE 254 // LEDs configured with this scan code will turn off in edge alternating mode
|
||||
# define LED_EDGE_MIN_SCAN 254 // LEDs configured with scan code >= to this are assigned as edge LEDs
|
||||
# define LED_INDICATOR_SCAN 253 // LEDs configured as dedicated indicators
|
||||
|
||||
# define LED_IS_KEY(scan) (scan < LED_INDICATOR_SCAN) // Return true if an LED's scan value indicates it is a key LED
|
||||
# define LED_IS_EDGE(scan) (scan >= LED_EDGE_MIN_SCAN) // Return true if an LED's scan value indicates an edge LED
|
||||
# define LED_IS_EDGE_ALT(scan) (scan == LED_EDGE_ALT_MODE) // Return true if an LED's scan value indicates an alternate edge mode LED
|
||||
# define LED_IS_INDICATOR(scan) (scan == LED_INDICATOR_SCAN) // Return true if an LED's scan value indicates it is a dedicated Indicator
|
||||
#else
|
||||
extern uint8_t gcr_desired;
|
||||
#endif // USE_MASSDROP_CONFIGURATOR
|
||||
|
||||
#endif //_LED_MATRIX_H_
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
Copyright 2018 Massdrop Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "arm_atsam_protocol.h"
|
||||
|
||||
#include "spi_master.h"
|
||||
#include "wait.h"
|
||||
#include "gpio.h"
|
||||
|
||||
// #define SR_USE_BITBANG
|
||||
|
||||
// Bodge for when spi_master is not available
|
||||
#ifdef SR_USE_BITBANG
|
||||
# define CLOCK_DELAY 10
|
||||
|
||||
void shift_init_impl(void) {
|
||||
setPinOutput(SR_EXP_RCLK_PIN);
|
||||
setPinOutput(SPI_DATAOUT_PIN);
|
||||
setPinOutput(SPI_SCLK_PIN);
|
||||
}
|
||||
|
||||
void shift_out_impl(const uint8_t *data, uint16_t length) {
|
||||
writePinLow(SR_EXP_RCLK_PIN);
|
||||
for (uint16_t i = 0; i < length; i++) {
|
||||
uint8_t val = data[i];
|
||||
|
||||
// shift out lsb first
|
||||
for (uint8_t bit = 0; bit < 8; bit++) {
|
||||
writePin(SPI_DATAOUT_PIN, !!(val & (1 << bit)));
|
||||
writePin(SPI_SCLK_PIN, true);
|
||||
wait_us(CLOCK_DELAY);
|
||||
|
||||
writePin(SPI_SCLK_PIN, false);
|
||||
wait_us(CLOCK_DELAY);
|
||||
}
|
||||
}
|
||||
writePinHigh(SR_EXP_RCLK_PIN);
|
||||
return SPI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void shift_init_impl(void) { spi_init(); }
|
||||
|
||||
void shift_out_impl(const uint8_t *data, uint16_t length) {
|
||||
spi_start(SR_EXP_RCLK_PIN, true, 0, 0);
|
||||
|
||||
spi_transmit(data, length);
|
||||
|
||||
spi_stop();
|
||||
}
|
||||
#endif
|
||||
|
||||
// ***************************************************************
|
||||
|
||||
void shift_out(const uint8_t *data, uint16_t length) { shift_out_impl(data, length); }
|
||||
|
||||
void shift_enable(void) {
|
||||
setPinOutput(SR_EXP_OE_PIN);
|
||||
writePinLow(SR_EXP_OE_PIN);
|
||||
}
|
||||
|
||||
void shift_disable(void) {
|
||||
setPinOutput(SR_EXP_OE_PIN);
|
||||
writePinHigh(SR_EXP_OE_PIN);
|
||||
}
|
||||
|
||||
void shift_init(void) {
|
||||
shift_disable();
|
||||
shift_init_impl();
|
||||
}
|
||||
|
||||
// ***************************************************************
|
||||
|
||||
sr_exp_t sr_exp_data;
|
||||
|
||||
void SR_EXP_WriteData(void) {
|
||||
uint8_t data[2] = {
|
||||
sr_exp_data.reg & 0xFF, // Shift in bits 7-0
|
||||
(sr_exp_data.reg >> 8) & 0xFF, // Shift in bits 15-8
|
||||
};
|
||||
shift_out(data, 2);
|
||||
}
|
||||
|
||||
void SR_EXP_Init(void) {
|
||||
shift_init();
|
||||
|
||||
sr_exp_data.reg = 0;
|
||||
sr_exp_data.bit.HUB_CONNECT = 0;
|
||||
sr_exp_data.bit.HUB_RESET_N = 0;
|
||||
sr_exp_data.bit.S_UP = 0;
|
||||
sr_exp_data.bit.E_UP_N = 1;
|
||||
sr_exp_data.bit.S_DN1 = 1;
|
||||
sr_exp_data.bit.E_DN1_N = 1;
|
||||
sr_exp_data.bit.E_VBUS_1 = 0;
|
||||
sr_exp_data.bit.E_VBUS_2 = 0;
|
||||
sr_exp_data.bit.SRC_1 = 1;
|
||||
sr_exp_data.bit.SRC_2 = 1;
|
||||
sr_exp_data.bit.IRST = 1;
|
||||
sr_exp_data.bit.SDB_N = 0;
|
||||
SR_EXP_WriteData();
|
||||
|
||||
shift_enable();
|
||||
}
|
||||
@@ -15,28 +15,9 @@ You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _SPI_H_
|
||||
#define _SPI_H_
|
||||
#pragma once
|
||||
|
||||
/* Macros for Shift Register control */
|
||||
#define SR_EXP_RCLK_LO PORT->Group[SR_EXP_RCLK_PORT].OUTCLR.reg = (1 << SR_EXP_RCLK_PIN)
|
||||
#define SR_EXP_RCLK_HI PORT->Group[SR_EXP_RCLK_PORT].OUTSET.reg = (1 << SR_EXP_RCLK_PIN)
|
||||
#define SR_EXP_OE_N_ENA PORT->Group[SR_EXP_OE_N_PORT].OUTCLR.reg = (1 << SR_EXP_OE_N_PIN)
|
||||
#define SR_EXP_OE_N_DIS PORT->Group[SR_EXP_OE_N_PORT].OUTSET.reg = (1 << SR_EXP_OE_N_PIN)
|
||||
|
||||
/* Determine bits to set for mux selection */
|
||||
#if SR_EXP_DATAOUT_PIN % 2 == 0
|
||||
# define SR_EXP_DATAOUT_MUX_SEL PMUXE
|
||||
#else
|
||||
# define SR_EXP_DATAOUT_MUX_SEL PMUXO
|
||||
#endif
|
||||
|
||||
/* Determine bits to set for mux selection */
|
||||
#if SR_EXP_SCLK_PIN % 2 == 0
|
||||
# define SR_EXP_SCLK_MUX_SEL PMUXE
|
||||
#else
|
||||
# define SR_EXP_SCLK_MUX_SEL PMUXO
|
||||
#endif
|
||||
#include <stdint.h>
|
||||
|
||||
/* Data structure to define Shift Register output expander hardware */
|
||||
/* This structure gets shifted into registers LSB first */
|
||||
@@ -66,5 +47,3 @@ extern sr_exp_t sr_exp_data;
|
||||
|
||||
void SR_EXP_WriteData(void);
|
||||
void SR_EXP_Init(void);
|
||||
|
||||
#endif //_SPI_H_
|
||||
@@ -1,92 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 Massdrop Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "arm_atsam_protocol.h"
|
||||
|
||||
sr_exp_t sr_exp_data;
|
||||
|
||||
void SR_EXP_WriteData(void) {
|
||||
SR_EXP_RCLK_LO;
|
||||
|
||||
while (!(SR_EXP_SERCOM->SPI.INTFLAG.bit.DRE)) {
|
||||
DBGC(DC_SPI_WRITE_DRE);
|
||||
}
|
||||
|
||||
SR_EXP_SERCOM->SPI.DATA.bit.DATA = sr_exp_data.reg & 0xFF; // Shift in bits 7-0
|
||||
while (!(SR_EXP_SERCOM->SPI.INTFLAG.bit.TXC)) {
|
||||
DBGC(DC_SPI_WRITE_TXC_1);
|
||||
}
|
||||
|
||||
SR_EXP_SERCOM->SPI.DATA.bit.DATA = (sr_exp_data.reg >> 8) & 0xFF; // Shift in bits 15-8
|
||||
while (!(SR_EXP_SERCOM->SPI.INTFLAG.bit.TXC)) {
|
||||
DBGC(DC_SPI_WRITE_TXC_2);
|
||||
}
|
||||
|
||||
SR_EXP_RCLK_HI;
|
||||
}
|
||||
|
||||
void SR_EXP_Init(void) {
|
||||
DBGC(DC_SPI_INIT_BEGIN);
|
||||
|
||||
CLK_set_spi_freq(CHAN_SERCOM_SPI, FREQ_SPI_DEFAULT);
|
||||
|
||||
// Set up MCU Shift Register pins
|
||||
PORT->Group[SR_EXP_RCLK_PORT].DIRSET.reg = (1 << SR_EXP_RCLK_PIN);
|
||||
PORT->Group[SR_EXP_OE_N_PORT].DIRSET.reg = (1 << SR_EXP_OE_N_PIN);
|
||||
|
||||
// Set up MCU SPI pins
|
||||
PORT->Group[SR_EXP_DATAOUT_PORT].PMUX[SR_EXP_DATAOUT_PIN / 2].bit.SR_EXP_DATAOUT_MUX_SEL = SR_EXP_DATAOUT_MUX; // MUX select for sercom
|
||||
PORT->Group[SR_EXP_SCLK_PORT].PMUX[SR_EXP_SCLK_PIN / 2].bit.SR_EXP_SCLK_MUX_SEL = SR_EXP_SCLK_MUX; // MUX select for sercom
|
||||
PORT->Group[SR_EXP_DATAOUT_PORT].PINCFG[SR_EXP_DATAOUT_PIN].bit.PMUXEN = 1; // MUX Enable
|
||||
PORT->Group[SR_EXP_SCLK_PORT].PINCFG[SR_EXP_SCLK_PIN].bit.PMUXEN = 1; // MUX Enable
|
||||
|
||||
// Initialize Shift Register
|
||||
SR_EXP_OE_N_DIS;
|
||||
SR_EXP_RCLK_HI;
|
||||
|
||||
SR_EXP_SERCOM->SPI.CTRLA.bit.DORD = 1; // Data Order - LSB is transferred first
|
||||
SR_EXP_SERCOM->SPI.CTRLA.bit.CPOL = 1; // Clock Polarity - SCK high when idle. Leading edge of cycle is falling. Trailing rising.
|
||||
SR_EXP_SERCOM->SPI.CTRLA.bit.CPHA = 1; // Clock Phase - Leading Edge Falling, change, Trailing Edge - Rising, sample
|
||||
SR_EXP_SERCOM->SPI.CTRLA.bit.DIPO = 3; // Data In Pinout - SERCOM PAD[3] is used as data input (Configure away from DOPO. Not using input.)
|
||||
SR_EXP_SERCOM->SPI.CTRLA.bit.DOPO = 0; // Data Output PAD[0], Serial Clock PAD[1]
|
||||
SR_EXP_SERCOM->SPI.CTRLA.bit.MODE = 3; // Operating Mode - Master operation
|
||||
|
||||
SR_EXP_SERCOM->SPI.CTRLA.bit.ENABLE = 1; // Enable - Peripheral is enabled or being enabled
|
||||
while (SR_EXP_SERCOM->SPI.SYNCBUSY.bit.ENABLE) {
|
||||
DBGC(DC_SPI_SYNC_ENABLING);
|
||||
}
|
||||
|
||||
sr_exp_data.reg = 0;
|
||||
sr_exp_data.bit.HUB_CONNECT = 0;
|
||||
sr_exp_data.bit.HUB_RESET_N = 0;
|
||||
sr_exp_data.bit.S_UP = 0;
|
||||
sr_exp_data.bit.E_UP_N = 1;
|
||||
sr_exp_data.bit.S_DN1 = 1;
|
||||
sr_exp_data.bit.E_DN1_N = 1;
|
||||
sr_exp_data.bit.E_VBUS_1 = 0;
|
||||
sr_exp_data.bit.E_VBUS_2 = 0;
|
||||
sr_exp_data.bit.SRC_1 = 1;
|
||||
sr_exp_data.bit.SRC_2 = 1;
|
||||
sr_exp_data.bit.IRST = 1;
|
||||
sr_exp_data.bit.SDB_N = 0;
|
||||
SR_EXP_WriteData();
|
||||
|
||||
// Enable Shift Register output
|
||||
SR_EXP_OE_N_ENA;
|
||||
|
||||
DBGC(DC_SPI_INIT_COMPLETE);
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
Copyright 2018 Massdrop Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "arm_atsam_protocol.h"
|
||||
#include "spi_master.h"
|
||||
#include "gpio.h"
|
||||
|
||||
/* Determine bits to set for mux selection */
|
||||
#if SPI_DATAOUT_PIN % 2 == 0
|
||||
# define SPI_DATAOUT_MUX_SEL PMUXE
|
||||
#else
|
||||
# define SPI_DATAOUT_MUX_SEL PMUXO
|
||||
#endif
|
||||
|
||||
/* Determine bits to set for mux selection */
|
||||
#if SPI_SCLK_PIN % 2 == 0
|
||||
# define SPI_SCLK_MUX_SEL PMUXE
|
||||
#else
|
||||
# define SPI_SCLK_MUX_SEL PMUXO
|
||||
#endif
|
||||
|
||||
static pin_t currentSelectPin = NO_PIN;
|
||||
|
||||
__attribute__((weak)) void spi_init(void) {
|
||||
static bool is_initialised = false;
|
||||
if (!is_initialised) {
|
||||
is_initialised = true;
|
||||
|
||||
DBGC(DC_SPI_INIT_BEGIN);
|
||||
|
||||
CLK_set_spi_freq(CHAN_SERCOM_SPI, FREQ_SPI_DEFAULT);
|
||||
|
||||
// Set up MCU SPI pins
|
||||
PORT->Group[SAMD_PORT(SPI_DATAOUT_PIN)].PMUX[SAMD_PIN(SPI_DATAOUT_PIN) / 2].bit.SPI_DATAOUT_MUX_SEL = SPI_DATAOUT_MUX; // MUX select for sercom
|
||||
PORT->Group[SAMD_PORT(SPI_SCLK_PIN)].PMUX[SAMD_PIN(SPI_SCLK_PIN) / 2].bit.SPI_SCLK_MUX_SEL = SPI_SCLK_MUX; // MUX select for sercom
|
||||
PORT->Group[SAMD_PORT(SPI_DATAOUT_PIN)].PINCFG[SAMD_PIN(SPI_DATAOUT_PIN)].bit.PMUXEN = 1; // MUX Enable
|
||||
PORT->Group[SAMD_PORT(SPI_SCLK_PIN)].PINCFG[SAMD_PIN(SPI_SCLK_PIN)].bit.PMUXEN = 1; // MUX Enable
|
||||
|
||||
DBGC(DC_SPI_INIT_COMPLETE);
|
||||
}
|
||||
}
|
||||
|
||||
bool spi_start(pin_t csPin, bool lsbFirst, uint8_t mode, uint16_t divisor) {
|
||||
if (currentSelectPin != NO_PIN || csPin == NO_PIN) {
|
||||
return false;
|
||||
}
|
||||
|
||||
currentSelectPin = csPin;
|
||||
setPinOutput(currentSelectPin);
|
||||
writePinLow(currentSelectPin);
|
||||
|
||||
SPI_SERCOM->SPI.CTRLA.bit.DORD = lsbFirst; // Data Order - LSB is transferred first
|
||||
SPI_SERCOM->SPI.CTRLA.bit.CPOL = 1; // Clock Polarity - SCK high when idle. Leading edge of cycle is falling. Trailing rising.
|
||||
SPI_SERCOM->SPI.CTRLA.bit.CPHA = 1; // Clock Phase - Leading Edge Falling, change, Trailing Edge - Rising, sample
|
||||
SPI_SERCOM->SPI.CTRLA.bit.DIPO = 3; // Data In Pinout - SERCOM PAD[3] is used as data input (Configure away from DOPO. Not using input.)
|
||||
SPI_SERCOM->SPI.CTRLA.bit.DOPO = 0; // Data Output PAD[0], Serial Clock PAD[1]
|
||||
SPI_SERCOM->SPI.CTRLA.bit.MODE = 3; // Operating Mode - Master operation
|
||||
|
||||
SPI_SERCOM->SPI.CTRLA.bit.ENABLE = 1; // Enable - Peripheral is enabled or being enabled
|
||||
while (SPI_SERCOM->SPI.SYNCBUSY.bit.ENABLE) {
|
||||
DBGC(DC_SPI_SYNC_ENABLING);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
spi_status_t spi_transmit(const uint8_t *data, uint16_t length) {
|
||||
while (!(SPI_SERCOM->SPI.INTFLAG.bit.DRE)) {
|
||||
DBGC(DC_SPI_WRITE_DRE);
|
||||
}
|
||||
|
||||
for (uint16_t i = 0; i < length; i++) {
|
||||
SPI_SERCOM->SPI.DATA.bit.DATA = data[i];
|
||||
while (!(SPI_SERCOM->SPI.INTFLAG.bit.TXC)) {
|
||||
DBGC(DC_SPI_WRITE_TXC_1);
|
||||
}
|
||||
}
|
||||
|
||||
return SPI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
void spi_stop(void) {
|
||||
if (currentSelectPin != NO_PIN) {
|
||||
setPinOutput(currentSelectPin);
|
||||
writePinHigh(currentSelectPin);
|
||||
currentSelectPin = NO_PIN;
|
||||
}
|
||||
}
|
||||
|
||||
// Not implemented yet....
|
||||
|
||||
spi_status_t spi_write(uint8_t data);
|
||||
|
||||
spi_status_t spi_read(void);
|
||||
|
||||
spi_status_t spi_receive(uint8_t *data, uint16_t length);
|
||||
@@ -0,0 +1,48 @@
|
||||
/* Copyright 2021 QMK
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef int16_t spi_status_t;
|
||||
|
||||
#define SPI_STATUS_SUCCESS (0)
|
||||
#define SPI_STATUS_ERROR (-1)
|
||||
#define SPI_STATUS_TIMEOUT (-2)
|
||||
|
||||
#define SPI_TIMEOUT_IMMEDIATE (0)
|
||||
#define SPI_TIMEOUT_INFINITE (0xFFFF)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void spi_init(void);
|
||||
|
||||
bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor);
|
||||
|
||||
spi_status_t spi_write(uint8_t data);
|
||||
|
||||
spi_status_t spi_read(void);
|
||||
|
||||
spi_status_t spi_transmit(const uint8_t *data, uint16_t length);
|
||||
|
||||
spi_status_t spi_receive(uint8_t *data, uint16_t length);
|
||||
|
||||
void spi_stop(void);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -1,402 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 Massdrop Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _USB2422_H_
|
||||
#define _USB2422_H_
|
||||
|
||||
#define REV_USB2422 0x100
|
||||
|
||||
#define USB2422_ADDR 0x58 // I2C device address, one instance
|
||||
|
||||
#define USB2422_HUB_ACTIVE_GROUP 0 // PA
|
||||
#define USB2422_HUB_ACTIVE_PIN 18 // 18
|
||||
|
||||
/* -------- USB2422_VID : (USB2422L Offset: 0x00) (R/W 16) Vendor ID -------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef union {
|
||||
struct {
|
||||
uint16_t VID_LSB : 8;
|
||||
uint16_t VID_MSB : 8;
|
||||
} bit; /*!< Structure used for bit access */
|
||||
uint16_t reg; /*!< Type used for register access */
|
||||
} USB2422_VID_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/* -------- USB2422_PID : (USB2422L Offset: 0x02) (R/W 16) Product ID -------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef union {
|
||||
struct {
|
||||
uint16_t PID_LSB : 8;
|
||||
uint16_t PID_MSB : 8;
|
||||
} bit; /*!< Structure used for bit access */
|
||||
uint16_t reg; /*!< Type used for register access */
|
||||
} USB2422_PID_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/* -------- USB2422_DID : (USB2422L Offset: 0x04) (R/W 16) Device ID -------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef union {
|
||||
struct {
|
||||
uint16_t DID_LSB : 8;
|
||||
uint16_t DID_MSB : 8;
|
||||
} bit; /*!< Structure used for bit access */
|
||||
uint16_t reg; /*!< Type used for register access */
|
||||
} USB2422_DID_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/* -------- USB2422_CFG1 : (USB2422L Offset: 0x06) (R/W 8) Configuration Data Byte 1-------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t PORT_PWR : 1;
|
||||
uint8_t CURRENT_SNS : 2;
|
||||
uint8_t EOP_DISABLE : 1;
|
||||
uint8_t MTT_ENABLE : 1;
|
||||
uint8_t HS_DISABLE : 1;
|
||||
uint8_t : 1;
|
||||
uint8_t SELF_BUS_PWR : 1;
|
||||
} bit; /*!< Structure used for bit access */
|
||||
uint8_t reg; /*!< Type used for register access */
|
||||
} USB2422_CFG1_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/* -------- USB2422_CFG2 : (USB2422L Offset: 0x07) (R/W 8) Configuration Data Byte 2-------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t : 3;
|
||||
uint8_t COMPOUND : 1;
|
||||
uint8_t OC_TIMER : 2;
|
||||
uint8_t : 1;
|
||||
uint8_t DYNAMIC : 1;
|
||||
} bit; /*!< Structure used for bit access */
|
||||
uint8_t reg; /*!< Type used for register access */
|
||||
} USB2422_CFG2_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/* -------- USB2422_CFG3 : (USB2422L Offset: 0x08) (R/W 16) Configuration Data Byte 3-------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t STRING_EN : 1;
|
||||
uint8_t : 2;
|
||||
uint8_t PRTMAP_EN : 1;
|
||||
uint8_t : 4;
|
||||
} bit; /*!< Structure used for bit access */
|
||||
uint8_t reg; /*!< Type used for register access */
|
||||
} USB2422_CFG3_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/* -------- USB2422_NRD : (USB2422L Offset: 0x09) (R/W 8) Non Removable Device -------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t : 5;
|
||||
uint8_t PORT2_NR : 1;
|
||||
uint8_t PORT1_NR : 1;
|
||||
uint8_t : 1;
|
||||
} bit; /*!< Structure used for bit access */
|
||||
uint8_t reg; /*!< Type used for register access */
|
||||
} USB2422_NRD_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/* -------- USB2422_PDS : (USB2422L Offset: 0x0A) (R/W 8) Port Diable for Self-Powered Operation -------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t : 1;
|
||||
uint8_t PORT1_DIS : 1;
|
||||
uint8_t PORT2_DIS : 1;
|
||||
uint8_t : 5;
|
||||
} bit; /*!< Structure used for bit access */
|
||||
uint8_t reg; /*!< Type used for register access */
|
||||
} USB2422_PDS_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/* -------- USB2422_PDB : (USB2422L Offset: 0x0B) (R/W 8) Port Diable for Bus-Powered Operation -------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t : 1;
|
||||
uint8_t PORT1_DIS : 1;
|
||||
uint8_t PORT2_DIS : 1;
|
||||
uint8_t : 5;
|
||||
} bit; /*!< Structure used for bit access */
|
||||
uint8_t reg; /*!< Type used for register access */
|
||||
} USB2422_PDB_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/* -------- USB2422_MAXPS : (USB2422L Offset: 0x0C) (R/W 8) Max Power for Self-Powered Operation -------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t MAX_PWR_SP : 8;
|
||||
} bit; /*!< Structure used for bit access */
|
||||
uint8_t reg; /*!< Type used for register access */
|
||||
} USB2422_MAXPS_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/* -------- USB2422_MAXPB : (USB2422L Offset: 0x0D) (R/W 8) Max Power for Bus-Powered Operation -------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t MAX_PWR_BP : 8;
|
||||
} bit; /*!< Structure used for bit access */
|
||||
uint8_t reg; /*!< Type used for register access */
|
||||
} USB2422_MAXPB_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/* -------- USB2422_HCMCS : (USB2422L Offset: 0x0E) (R/W 8) Hub Controller Max Current for Self-Powered Operation -------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t HC_MAX_C_SP : 8;
|
||||
} bit; /*!< Structure used for bit access */
|
||||
uint8_t reg; /*!< Type used for register access */
|
||||
} USB2422_HCMCS_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/* -------- USB2422_HCMCB : (USB2422L Offset: 0x0F) (R/W 8) Hub Controller Max Current for Bus-Powered Operation -------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t HC_MAX_C_BP : 8;
|
||||
} bit; /*!< Structure used for bit access */
|
||||
uint8_t reg; /*!< Type used for register access */
|
||||
} USB2422_HCMCB_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/* -------- USB2422_PWRT : (USB2422L Offset: 0x10) (R/W 8) Power On Time -------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t POWER_ON_TIME : 8;
|
||||
} bit; /*!< Structure used for bit access */
|
||||
uint8_t reg; /*!< Type used for register access */
|
||||
} USB2422_PWRT_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/* -------- USB2422_LANGID LSB : (USB2422L Offset: 0x11) (R/W 16) Language ID -------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t LANGID_LSB : 8;
|
||||
} bit; /*!< Structure used for bit access */
|
||||
uint8_t reg; /*!< Type used for register access */
|
||||
} USB2422_LANGID_LSB_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/* -------- USB2422_LANGID MSB : (USB2422L Offset: 0x12) (R/W 16) Language ID -------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t LANGID_MSB : 8;
|
||||
} bit; /*!< Structure used for bit access */
|
||||
uint8_t reg; /*!< Type used for register access */
|
||||
} USB2422_LANGID_MSB_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/* -------- USB2422_MFRSL : (USB2422L Offset: 0x13) (R/W 8) Manufacturer String Length -------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t MFR_STR_LEN : 8;
|
||||
} bit; /*!< Structure used for bit access */
|
||||
uint8_t reg; /*!< Type used for register access */
|
||||
} USB2422_MFRSL_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/* -------- USB2422_PRDSL : (USB2422L Offset: 0x14) (R/W 8) Product String Length -------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t PRD_STR_LEN : 8;
|
||||
} bit; /*!< Structure used for bit access */
|
||||
uint8_t reg; /*!< Type used for register access */
|
||||
} USB2422_PRDSL_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/* -------- USB2422_SERSL : (USB2422L Offset: 0x15) (R/W 8) Serial String Length -------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t SER_STR_LEN : 8;
|
||||
} bit; /*!< Structure used for bit access */
|
||||
uint8_t reg; /*!< Type used for register access */
|
||||
} USB2422_SERSL_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/* -------- USB2422_MFRSTR : (USB2422L Offset: 0x16-53) (R/W 8) Maufacturer String -------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef uint16_t USB2422_MFRSTR_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/* -------- USB2422_PRDSTR : (USB2422L Offset: 0x54-91) (R/W 8) Product String -------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef uint16_t USB2422_PRDSTR_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/* -------- USB2422_SERSTR : (USB2422L Offset: 0x92-CF) (R/W 8) Serial String -------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef uint16_t USB2422_SERSTR_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/* -------- USB2422_BCEN : (USB2422L Offset: 0xD0) (R/W 8) Battery Charging Enable -------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t : 1;
|
||||
uint8_t PORT1_BCE : 1;
|
||||
uint8_t PORT2_BCE : 1;
|
||||
uint8_t : 5;
|
||||
} bit; /*!< Structure used for bit access */
|
||||
uint8_t reg; /*!< Type used for register access */
|
||||
} USB2422_BCEN_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/* -------- USB2422_BOOSTUP : (USB2422L Offset: 0xF6) (R/W 8) Boost Upstream -------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t BOOST : 2;
|
||||
uint8_t : 6;
|
||||
} bit; /*!< Structure used for bit access */
|
||||
uint8_t reg; /*!< Type used for register access */
|
||||
} USB2422_BOOSTUP_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/* -------- USB2422_BOOSTDOWN : (USB2422L Offset: 0xF8) (R/W 8) Boost Downstream -------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t BOOST1 : 2;
|
||||
uint8_t BOOST2 : 2;
|
||||
uint8_t : 4;
|
||||
} bit; /*!< Structure used for bit access */
|
||||
uint8_t reg; /*!< Type used for register access */
|
||||
} USB2422_BOOSTDOWN_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/* -------- USB2422_PRTSP : (USB2422L Offset: 0xFA) (R/W 8) Port Swap -------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t : 1;
|
||||
uint8_t PORT1_SP : 1;
|
||||
uint8_t PORT2_SP : 1;
|
||||
uint8_t : 5;
|
||||
} bit; /*!< Structure used for bit access */
|
||||
uint8_t reg; /*!< Type used for register access */
|
||||
} USB2422_PRTSP_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/* -------- USB2422_PRTR12 : (USB2422L Offset: 0xFB) (R/W 8) Port 1/2 Remap -------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t PORT1_REMAP : 4;
|
||||
uint8_t PORT2_REMAP : 4;
|
||||
} bit; /*!< Structure used for bit access */
|
||||
uint8_t reg; /*!< Type used for register access */
|
||||
} USB2422_PRTR12_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
#define USB2422_PRTR12_DISABLE 0
|
||||
#define USB2422_PRT12_P2TOL1 1
|
||||
#define USB2422_PRT12_P2XTOL2 2
|
||||
#define USB2422_PRT12_P1TOL1 1
|
||||
#define USB2422_PRT12_P1XTOL2 2
|
||||
|
||||
/* -------- USB2422_STCD : (USB2422L Offset: 0xFF) (R/W 8) Status Command -------- */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef union {
|
||||
struct {
|
||||
uint8_t USB_ATTACH : 1;
|
||||
uint8_t RESET : 1;
|
||||
uint8_t INTF_PWRDN : 1;
|
||||
uint8_t : 5;
|
||||
} bit; /*!< Structure used for bit access */
|
||||
uint8_t reg; /*!< Type used for register access */
|
||||
} USB2422_STCD_Type;
|
||||
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
|
||||
|
||||
/** \brief USB2422 device hardware registers */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
|
||||
typedef struct {
|
||||
USB2422_VID_Type VID; /**< \brief Offset: 0x00*/
|
||||
USB2422_PID_Type PID; /**< \brief Offset: 0x02*/
|
||||
USB2422_DID_Type DID; /**< \brief Offset: 0x04*/
|
||||
USB2422_CFG1_Type CFG1; /**< \brief Offset: 0x06*/
|
||||
USB2422_CFG2_Type CFG2; /**< \brief Offset: 0x07*/
|
||||
USB2422_CFG3_Type CFG3; /**< \brief Offset: 0x08*/
|
||||
USB2422_NRD_Type NRD; /**< \brief Offset: 0x09*/
|
||||
USB2422_PDS_Type PDS; /**< \brief Offset: 0x0A*/
|
||||
USB2422_PDB_Type PDB; /**< \brief Offset: 0x0B*/
|
||||
USB2422_MAXPS_Type MAXPS; /**< \brief Offset: 0x0C*/
|
||||
USB2422_MAXPB_Type MAXPB; /**< \brief Offset: 0x0D*/
|
||||
USB2422_HCMCS_Type HCMCS; /**< \brief Offset: 0x0E*/
|
||||
USB2422_HCMCB_Type HCMCB; /**< \brief Offset: 0x0F*/
|
||||
USB2422_PWRT_Type PWRT; /**< \brief Offset: 0x10*/
|
||||
USB2422_LANGID_LSB_Type LANGID_LSB; /**< \brief Offset: 0x11*/
|
||||
USB2422_LANGID_MSB_Type LANGID_MSB; /**< \brief Offset: 0x12*/
|
||||
USB2422_MFRSL_Type MFRSL; /**< \brief Offset: 0x13*/
|
||||
USB2422_PRDSL_Type PRDSL; /**< \brief Offset: 0x14*/
|
||||
USB2422_SERSL_Type SERSL; /**< \brief Offset: 0x15*/
|
||||
USB2422_MFRSTR_Type MFRSTR[31]; /**< \brief Offset: 0x16*/
|
||||
USB2422_PRDSTR_Type PRDSTR[31]; /**< \brief Offset: 0x54*/
|
||||
USB2422_SERSTR_Type SERSTR[31]; /**< \brief Offset: 0x92*/
|
||||
USB2422_BCEN_Type BCEN; /**< \brief Offset: 0xD0*/
|
||||
uint8_t Reserved1[0x25];
|
||||
USB2422_BOOSTUP_Type BOOSTUP; /**< \brief Offset: 0xF6*/
|
||||
uint8_t Reserved2[0x1];
|
||||
USB2422_BOOSTDOWN_Type BOOSTDOWN; /**< \brief Offset: 0xF8*/
|
||||
uint8_t Reserved3[0x1];
|
||||
USB2422_PRTSP_Type PRTSP; /**< \brief Offset: 0xFA*/
|
||||
USB2422_PRTR12_Type PRTR12; /**< \brief Offset: 0xFB*/
|
||||
uint8_t Reserved4[0x3];
|
||||
USB2422_STCD_Type STCD; /**< \brief Offset: 0xFF*/
|
||||
} Usb2422;
|
||||
#endif
|
||||
|
||||
#define PORT_DETECT_RETRY_INTERVAL 2000
|
||||
|
||||
#define USB_EXTRA_ADC_THRESHOLD 900
|
||||
|
||||
#define USB_EXTRA_STATE_DISABLED 0
|
||||
#define USB_EXTRA_STATE_ENABLED 1
|
||||
#define USB_EXTRA_STATE_UNKNOWN 2
|
||||
#define USB_EXTRA_STATE_DISABLED_UNTIL_REPLUG 3
|
||||
|
||||
#define USB_HOST_PORT_1 0
|
||||
#define USB_HOST_PORT_2 1
|
||||
#define USB_HOST_PORT_UNKNOWN 2
|
||||
|
||||
extern uint8_t usb_host_port;
|
||||
extern uint8_t usb_extra_state;
|
||||
extern uint8_t usb_extra_manual;
|
||||
extern uint8_t usb_gcr_auto;
|
||||
|
||||
void USB2422_init(void);
|
||||
void USB_reset(void);
|
||||
void USB_configure(void);
|
||||
uint16_t USB_active(void);
|
||||
void USB_set_host_by_voltage(void);
|
||||
uint16_t adc_get(uint8_t muxpos);
|
||||
uint8_t USB2422_Port_Detect_Init(void);
|
||||
void USB_HandleExtraDevice(void);
|
||||
void USB_ExtraSetState(uint8_t state);
|
||||
|
||||
#endif //_USB2422_H_
|
||||
+6
-92
@@ -16,25 +16,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "arm_atsam_protocol.h"
|
||||
#include "drivers/usb2422.h"
|
||||
#include <string.h>
|
||||
|
||||
Usb2422 USB2422_shadow;
|
||||
unsigned char i2c0_buf[34];
|
||||
|
||||
const uint16_t MFRNAME[] = {'M', 'a', 's', 's', 'd', 'r', 'o', 'p', ' ', 'I', 'n', 'c', '.'}; // Massdrop Inc.
|
||||
const uint16_t PRDNAME[] = {'M', 'a', 's', 's', 'd', 'r', 'o', 'p', ' ', 'H', 'u', 'b'}; // Massdrop Hub
|
||||
#ifndef MD_BOOTLOADER
|
||||
// Serial number reported stops before first found space character or at last found character
|
||||
const uint16_t SERNAME[] = {'U', 'n', 'a', 'v', 'a', 'i', 'l', 'a', 'b', 'l', 'e'}; // Unavailable
|
||||
#else
|
||||
// In production, this field is found, modified, and offset noted as the last 32-bit word in the bootloader space
|
||||
// The offset allows the application to use the factory programmed serial (which may differ from the physical serial label)
|
||||
// Serial number reported stops before first found space character or when max size is reached
|
||||
__attribute__((__aligned__(4))) const uint16_t SERNAME[BOOTLOADER_SERIAL_MAX_SIZE] = {'M', 'D', 'H', 'U', 'B', 'B', 'O', 'O', 'T', 'L', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0'};
|
||||
// NOTE: Serial replacer will not write a string longer than given here as a precaution, so give enough
|
||||
// space as needed and adjust BOOTLOADER_SERIAL_MAX_SIZE to match amount given
|
||||
#endif // MD_BOOTLOADER
|
||||
|
||||
uint8_t usb_host_port;
|
||||
|
||||
#ifndef MD_BOOTLOADER
|
||||
@@ -47,29 +31,7 @@ uint8_t usb_gcr_auto;
|
||||
|
||||
uint16_t adc_extra;
|
||||
|
||||
void USB_write2422_block(void) {
|
||||
unsigned char *dest = i2c0_buf;
|
||||
unsigned char *src;
|
||||
unsigned char *base = (unsigned char *)&USB2422_shadow;
|
||||
|
||||
DBGC(DC_USB_WRITE2422_BLOCK_BEGIN);
|
||||
|
||||
for (src = base; src < base + 256; src += 32) {
|
||||
dest[0] = src - base;
|
||||
dest[1] = 32;
|
||||
memcpy(&dest[2], src, 32);
|
||||
i2c0_transmit(USB2422_ADDR, dest, 34, 50000);
|
||||
SERCOM0->I2CM.CTRLB.bit.CMD = 0x03;
|
||||
while (SERCOM0->I2CM.SYNCBUSY.bit.SYSOP) {
|
||||
DBGC(DC_USB_WRITE2422_BLOCK_SYNC_SYSOP);
|
||||
}
|
||||
wait_us(100);
|
||||
}
|
||||
|
||||
DBGC(DC_USB_WRITE2422_BLOCK_COMPLETE);
|
||||
}
|
||||
|
||||
void USB2422_init(void) {
|
||||
void USB_Hub_init(void) {
|
||||
Gclk * pgclk = GCLK;
|
||||
Mclk * pmclk = MCLK;
|
||||
Port * pport = PORT;
|
||||
@@ -147,9 +109,7 @@ void USB2422_init(void) {
|
||||
pusb->DEVICE.QOSCTRL.bit.DQOS = 2;
|
||||
pusb->DEVICE.QOSCTRL.bit.CQOS = 2;
|
||||
|
||||
pport->Group[USB2422_HUB_ACTIVE_GROUP].PINCFG[USB2422_HUB_ACTIVE_PIN].bit.INEN = 1;
|
||||
|
||||
i2c0_init(); // IC2 clk must be high at USB2422 reset release time to signal SMB configuration
|
||||
USB2422_init();
|
||||
|
||||
sr_exp_data.bit.HUB_CONNECT = 1; // connect signal
|
||||
sr_exp_data.bit.HUB_RESET_N = 1; // reset high
|
||||
@@ -181,62 +141,16 @@ void USB_reset(void) {
|
||||
}
|
||||
|
||||
void USB_configure(void) {
|
||||
Usb2422 *pusb2422 = &USB2422_shadow;
|
||||
memset(pusb2422, 0, sizeof(Usb2422));
|
||||
|
||||
uint16_t *serial_use = (uint16_t *)SERNAME; // Default to use SERNAME from this file
|
||||
uint8_t serial_length = sizeof(SERNAME) / sizeof(uint16_t); // Default to use SERNAME from this file
|
||||
#ifndef MD_BOOTLOADER
|
||||
uint32_t serial_ptrloc = (uint32_t)&_srom - 4;
|
||||
#else // MD_BOOTLOADER
|
||||
uint32_t serial_ptrloc = (uint32_t)&_erom - 4;
|
||||
#endif // MD_BOOTLOADER
|
||||
uint32_t serial_address = *(uint32_t *)serial_ptrloc; // Address of bootloader's serial number if available
|
||||
|
||||
DBGC(DC_USB_CONFIGURE_BEGIN);
|
||||
|
||||
if (serial_address != 0xFFFFFFFF && serial_address < serial_ptrloc) // Check for factory programmed serial address
|
||||
{
|
||||
if ((serial_address & 0xFF) % 4 == 0) // Check alignment
|
||||
{
|
||||
serial_use = (uint16_t *)(serial_address);
|
||||
serial_length = 0;
|
||||
while ((*(serial_use + serial_length) > 32 && *(serial_use + serial_length) < 127) && serial_length < BOOTLOADER_SERIAL_MAX_SIZE) {
|
||||
serial_length++;
|
||||
DBGC(DC_USB_CONFIGURE_GET_SERIAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// configure Usb2422 registers
|
||||
pusb2422->VID.reg = 0x04D8; // from Microchip 4/19/2018
|
||||
pusb2422->PID.reg = 0xEEC5; // from Microchip 4/19/2018 = Massdrop, Inc. USB Hub
|
||||
pusb2422->DID.reg = 0x0101; // BCD 01.01
|
||||
pusb2422->CFG1.bit.SELF_BUS_PWR = 1; // self powered for now
|
||||
pusb2422->CFG1.bit.HS_DISABLE = 1; // full or high speed
|
||||
// pusb2422->CFG2.bit.COMPOUND = 0; // compound device
|
||||
pusb2422->CFG3.bit.STRING_EN = 1; // strings enabled
|
||||
// pusb2422->NRD.bit.PORT2_NR = 0; // MCU is non-removable
|
||||
pusb2422->MAXPB.reg = 20; // 0mA
|
||||
pusb2422->HCMCB.reg = 20; // 0mA
|
||||
pusb2422->MFRSL.reg = sizeof(MFRNAME) / sizeof(uint16_t);
|
||||
pusb2422->PRDSL.reg = sizeof(PRDNAME) / sizeof(uint16_t);
|
||||
pusb2422->SERSL.reg = serial_length;
|
||||
memcpy(pusb2422->MFRSTR, MFRNAME, sizeof(MFRNAME));
|
||||
memcpy(pusb2422->PRDSTR, PRDNAME, sizeof(PRDNAME));
|
||||
memcpy(pusb2422->SERSTR, serial_use, serial_length * sizeof(uint16_t));
|
||||
// pusb2422->BOOSTUP.bit.BOOST=3; //upstream port
|
||||
// pusb2422->BOOSTDOWN.bit.BOOST1=0; // extra port
|
||||
// pusb2422->BOOSTDOWN.bit.BOOST2=2; //MCU is close
|
||||
pusb2422->STCD.bit.USB_ATTACH = 1;
|
||||
USB_write2422_block();
|
||||
USB2422_configure();
|
||||
|
||||
adc_extra = 0;
|
||||
|
||||
DBGC(DC_USB_CONFIGURE_COMPLETE);
|
||||
}
|
||||
|
||||
uint16_t USB_active(void) { return (PORT->Group[USB2422_HUB_ACTIVE_GROUP].IN.reg & (1 << USB2422_HUB_ACTIVE_PIN)) != 0; }
|
||||
uint16_t USB_active(void) { return USB2422_active(); }
|
||||
|
||||
void USB_set_host_by_voltage(void) {
|
||||
// UP is upstream device (HOST)
|
||||
@@ -314,7 +228,7 @@ void USB_set_host_by_voltage(void) {
|
||||
DBGC(DC_USB_SET_HOST_BY_VOLTAGE_COMPLETE);
|
||||
}
|
||||
|
||||
uint8_t USB2422_Port_Detect_Init(void) {
|
||||
uint8_t USB_Hub_Port_Detect_Init(void) {
|
||||
uint32_t port_detect_retry_ms;
|
||||
uint32_t tmod;
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
Copyright 2018 Massdrop Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _USB2422_H_
|
||||
#define _USB2422_H_
|
||||
|
||||
#define REV_USB2422 0x100
|
||||
|
||||
#define PORT_DETECT_RETRY_INTERVAL 2000
|
||||
|
||||
#define USB_EXTRA_ADC_THRESHOLD 900
|
||||
|
||||
#define USB_EXTRA_STATE_DISABLED 0
|
||||
#define USB_EXTRA_STATE_ENABLED 1
|
||||
#define USB_EXTRA_STATE_UNKNOWN 2
|
||||
#define USB_EXTRA_STATE_DISABLED_UNTIL_REPLUG 3
|
||||
|
||||
#define USB_HOST_PORT_1 0
|
||||
#define USB_HOST_PORT_2 1
|
||||
#define USB_HOST_PORT_UNKNOWN 2
|
||||
|
||||
extern uint8_t usb_host_port;
|
||||
extern uint8_t usb_extra_state;
|
||||
extern uint8_t usb_extra_manual;
|
||||
extern uint8_t usb_gcr_auto;
|
||||
|
||||
void USB_Hub_init(void);
|
||||
uint8_t USB_Hub_Port_Detect_Init(void);
|
||||
void USB_reset(void);
|
||||
void USB_configure(void);
|
||||
uint16_t USB_active(void);
|
||||
void USB_set_host_by_voltage(void);
|
||||
uint16_t adc_get(uint8_t muxpos);
|
||||
void USB_HandleExtraDevice(void);
|
||||
void USB_ExtraSetState(uint8_t state);
|
||||
|
||||
#endif //_USB2422_H_
|
||||
Reference in New Issue
Block a user