Browse Source

Merge remote-tracking branch 'upstream/master'

teensy4-core
Tilo Nitzsche 7 years ago
parent
commit
0cebe6328b
14 changed files with 199 additions and 49 deletions
  1. +6
    -0
      teensy3/HardwareSerial.h
  2. +20
    -0
      teensy3/kinetis.h
  3. +7
    -0
      teensy3/memcpy-armv7m.S
  4. +25
    -3
      teensy3/mk20dx128.c
  5. +50
    -6
      teensy3/nonstd.c
  6. +8
    -1
      teensy3/pins_teensy.c
  7. +29
    -4
      teensy3/serial1.c
  8. +5
    -2
      teensy3/serial2.c
  9. +11
    -0
      teensy3/serial3.c
  10. +0
    -2
      teensy3/serial4.c
  11. +26
    -1
      teensy3/usb_audio.cpp
  12. +4
    -28
      teensy3/usb_audio.h
  13. +1
    -1
      teensy3/usb_desc.c
  14. +7
    -1
      teensy3/usb_serial.h

+ 6
- 0
teensy3/HardwareSerial.h View File

@@ -255,6 +255,7 @@ public:
virtual void flush(void) { serial_flush(); }
virtual void clear(void) { serial_clear(); }
virtual int availableForWrite(void) { return serial_write_buffer_free(); }
using Print::write;
virtual size_t write(uint8_t c) { serial_putchar(c); return 1; }
virtual size_t write(unsigned long n) { return write((uint8_t)n); }
virtual size_t write(long n) { return write((uint8_t)n); }
@@ -290,6 +291,7 @@ public:
virtual void flush(void) { serial2_flush(); }
virtual void clear(void) { serial2_clear(); }
virtual int availableForWrite(void) { return serial2_write_buffer_free(); }
using Print::write;
virtual size_t write(uint8_t c) { serial2_putchar(c); return 1; }
virtual size_t write(unsigned long n) { return write((uint8_t)n); }
virtual size_t write(long n) { return write((uint8_t)n); }
@@ -325,6 +327,7 @@ public:
virtual void flush(void) { serial3_flush(); }
virtual void clear(void) { serial3_clear(); }
virtual int availableForWrite(void) { return serial3_write_buffer_free(); }
using Print::write;
virtual size_t write(uint8_t c) { serial3_putchar(c); return 1; }
virtual size_t write(unsigned long n) { return write((uint8_t)n); }
virtual size_t write(long n) { return write((uint8_t)n); }
@@ -360,6 +363,7 @@ public:
virtual void flush(void) { serial4_flush(); }
virtual void clear(void) { serial4_clear(); }
virtual int availableForWrite(void) { return serial4_write_buffer_free(); }
using Print::write;
virtual size_t write(uint8_t c) { serial4_putchar(c); return 1; }
virtual size_t write(unsigned long n) { return write((uint8_t)n); }
virtual size_t write(long n) { return write((uint8_t)n); }
@@ -395,6 +399,7 @@ public:
virtual void flush(void) { serial5_flush(); }
virtual void clear(void) { serial5_clear(); }
virtual int availableForWrite(void) { return serial5_write_buffer_free(); }
using Print::write;
virtual size_t write(uint8_t c) { serial5_putchar(c); return 1; }
virtual size_t write(unsigned long n) { return write((uint8_t)n); }
virtual size_t write(long n) { return write((uint8_t)n); }
@@ -437,6 +442,7 @@ public:
virtual void flush(void) { serial6_flush(); }
virtual void clear(void) { serial6_clear(); }
virtual int availableForWrite(void) { return serial6_write_buffer_free(); }
using Print::write;
virtual size_t write(uint8_t c) { serial6_putchar(c); return 1; }
virtual size_t write(unsigned long n) { return write((uint8_t)n); }
virtual size_t write(long n) { return write((uint8_t)n); }

+ 20
- 0
teensy3/kinetis.h View File

@@ -909,6 +909,9 @@ enum IRQ_NUMBER_t {
#define PORTA_GPCLR (*(volatile uint32_t *)0x40049080) // Global Pin Control Low Register
#define PORTA_GPCHR (*(volatile uint32_t *)0x40049084) // Global Pin Control High Register
#define PORTA_ISFR (*(volatile uint32_t *)0x400490A0) // Interrupt Status Flag Register
#define PORTA_DFER (*(volatile uint32_t *)0x400490C0) // Digital Filter Enable
#define PORTA_DFCR (*(volatile uint32_t *)0x400490C4) // Digital Filter Clock
#define PORTA_DFWR (*(volatile uint32_t *)0x400490C8) // Digital Filter Width
#define PORTB_PCR0 (*(volatile uint32_t *)0x4004A000) // Pin Control Register n
#define PORTB_PCR1 (*(volatile uint32_t *)0x4004A004) // Pin Control Register n
#define PORTB_PCR2 (*(volatile uint32_t *)0x4004A008) // Pin Control Register n
@@ -944,6 +947,9 @@ enum IRQ_NUMBER_t {
#define PORTB_GPCLR (*(volatile uint32_t *)0x4004A080) // Global Pin Control Low Register
#define PORTB_GPCHR (*(volatile uint32_t *)0x4004A084) // Global Pin Control High Register
#define PORTB_ISFR (*(volatile uint32_t *)0x4004A0A0) // Interrupt Status Flag Register
#define PORTB_DFER (*(volatile uint32_t *)0x4004A0C0) // Digital Filter Enable
#define PORTB_DFCR (*(volatile uint32_t *)0x4004A0C4) // Digital Filter Clock
#define PORTB_DFWR (*(volatile uint32_t *)0x4004A0C8) // Digital Filter Width
#define PORTC_PCR0 (*(volatile uint32_t *)0x4004B000) // Pin Control Register n
#define PORTC_PCR1 (*(volatile uint32_t *)0x4004B004) // Pin Control Register n
#define PORTC_PCR2 (*(volatile uint32_t *)0x4004B008) // Pin Control Register n
@@ -979,6 +985,9 @@ enum IRQ_NUMBER_t {
#define PORTC_GPCLR (*(volatile uint32_t *)0x4004B080) // Global Pin Control Low Register
#define PORTC_GPCHR (*(volatile uint32_t *)0x4004B084) // Global Pin Control High Register
#define PORTC_ISFR (*(volatile uint32_t *)0x4004B0A0) // Interrupt Status Flag Register
#define PORTC_DFER (*(volatile uint32_t *)0x4004B0C0) // Digital Filter Enable
#define PORTC_DFCR (*(volatile uint32_t *)0x4004B0C4) // Digital Filter Clock
#define PORTC_DFWR (*(volatile uint32_t *)0x4004B0C8) // Digital Filter Width
#define PORTD_PCR0 (*(volatile uint32_t *)0x4004C000) // Pin Control Register n
#define PORTD_PCR1 (*(volatile uint32_t *)0x4004C004) // Pin Control Register n
#define PORTD_PCR2 (*(volatile uint32_t *)0x4004C008) // Pin Control Register n
@@ -1014,6 +1023,9 @@ enum IRQ_NUMBER_t {
#define PORTD_GPCLR (*(volatile uint32_t *)0x4004C080) // Global Pin Control Low Register
#define PORTD_GPCHR (*(volatile uint32_t *)0x4004C084) // Global Pin Control High Register
#define PORTD_ISFR (*(volatile uint32_t *)0x4004C0A0) // Interrupt Status Flag Register
#define PORTD_DFER (*(volatile uint32_t *)0x4004C0C0) // Digital Filter Enable
#define PORTD_DFCR (*(volatile uint32_t *)0x4004C0C4) // Digital Filter Clock
#define PORTD_DFWR (*(volatile uint32_t *)0x4004C0C8) // Digital Filter Width
#define PORTE_PCR0 (*(volatile uint32_t *)0x4004D000) // Pin Control Register n
#define PORTE_PCR1 (*(volatile uint32_t *)0x4004D004) // Pin Control Register n
#define PORTE_PCR2 (*(volatile uint32_t *)0x4004D008) // Pin Control Register n
@@ -1049,6 +1061,9 @@ enum IRQ_NUMBER_t {
#define PORTE_GPCLR (*(volatile uint32_t *)0x4004D080) // Global Pin Control Low Register
#define PORTE_GPCHR (*(volatile uint32_t *)0x4004D084) // Global Pin Control High Register
#define PORTE_ISFR (*(volatile uint32_t *)0x4004D0A0) // Interrupt Status Flag Register
#define PORTE_DFER (*(volatile uint32_t *)0x4004D0C0) // Digital Filter Enable
#define PORTE_DFCR (*(volatile uint32_t *)0x4004D0C4) // Digital Filter Clock
#define PORTE_DFWR (*(volatile uint32_t *)0x4004D0C8) // Digital Filter Width

// System Integration Module (SIM)

@@ -2878,6 +2893,9 @@ typedef struct {
#define DAC0_DAT14L (*(volatile uint8_t *)0x400CC01C) // DAC Data Low Register
#define DAC0_DAT15L (*(volatile uint8_t *)0x400CC01E) // DAC Data Low Register
#define DAC0_SR (*(volatile uint8_t *)0x400CC020) // DAC Status Register
#define DAC_SR_DACBFWMF 0x04 // Buffer Watermark Flag
#define DAC_SR_DACBFRTF 0x02 // Pointer Top Position Flag
#define DAC_SR_DACBFRBF 0x01 // Pointer Bottom Position Flag
#define DAC0_C0 (*(volatile uint8_t *)0x400CC021) // DAC Control Register
#define DAC_C0_DACEN 0x80 // DAC Enable
#define DAC_C0_DACRFS 0x40 // DAC Reference Select
@@ -3031,6 +3049,8 @@ typedef struct {
#define PDB0_CH1DLY0 (*(volatile uint32_t *)0x40036040) // Channel 1 Delay 0 Register
#define PDB0_CH1DLY1 (*(volatile uint32_t *)0x40036044) // Channel 1 Delay 1 Register
#define PDB0_DACINTC0 (*(volatile uint32_t *)0x40036150) // DAC Interval Trigger n Control Register
#define PDB_DACINTC_EXT 0x02 // External Trigger Input Enable
#define PDB_DACINTC_TOE 0x01 // Interval Trigger Enable
#define PDB0_DACINT0 (*(volatile uint32_t *)0x40036154) // DAC Interval n Register
#define PDB0_DACINTC1 (*(volatile uint32_t *)0x40036158) // DAC Interval Trigger n Control register
#define PDB0_DACINT1 (*(volatile uint32_t *)0x4003615C) // DAC Interval n register

+ 7
- 0
teensy3/memcpy-armv7m.S View File

@@ -28,7 +28,14 @@

#if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)
#if defined (__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__)
/*
* Let __ARM_FEATURE_UNALIGNED be set by the achitechture and the compiler flags:
* -munaligned-access
* -mno-unaligned-access
* instead of always setting it here.
*
#define __ARM_FEATURE_UNALIGNED 1
*/
/* This memcpy routine is optimised for Cortex-M3/M4 cores with/without
unaligned access.

+ 25
- 3
teensy3/mk20dx128.c View File

@@ -31,6 +31,7 @@
#include "kinetis.h"
#include "core_pins.h" // testing only
#include "ser_print.h" // testing only
#include <errno.h>


// Flash Security Setting. On Teensy 3.2, you can lock the MK20 chip to prevent
@@ -1137,10 +1138,31 @@ void ResetHandler(void)

char *__brkval = (char *)&_ebss;

#ifndef STACK_MARGIN
#if defined(__MKL26Z64__)
#define STACK_MARGIN 512
#elif defined(__MK20DX128__)
#define STACK_MARGIN 1024
#elif defined(__MK20DX256__)
#define STACK_MARGIN 4096
#elif defined(__MK64FX512__) || defined(__MK66FX1M0__)
#define STACK_MARGIN 8192
#endif
#endif

void * _sbrk(int incr)
{
char *prev = __brkval;
__brkval += incr;
char *prev, *stack;

prev = __brkval;
if (incr != 0) {
__asm__ volatile("mov %0, sp" : "=r" (stack) ::);
if (prev + incr >= stack - STACK_MARGIN) {
errno = ENOMEM;
return (void *)-1;
}
__brkval = prev + incr;
}
return prev;
}

@@ -1275,7 +1297,7 @@ int kinetis_hsrun_enable(void)
if (SMC_PMSTAT == SMC_PMSTAT_RUN) {
// Turn HSRUN mode on
SMC_PMCTRL = SMC_PMCTRL_RUNM(3);
while (SMC_PMSTAT != SMC_PMSTAT_HSRUN) ; // wait
while (SMC_PMSTAT != SMC_PMSTAT_HSRUN) {;} // wait
// Then configure clock for full speed
#if F_CPU == 240000000 && F_BUS == 60000000
SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(0, 3, 0, 7);

+ 50
- 6
teensy3/nonstd.c View File

@@ -126,15 +126,58 @@ char * dtostrf(float val, int width, unsigned int precision, char *buf)
}

s = fcvtf(val, precision, &decpt, &sign);

// if only 1 digit in output
if (precision == 0 && decpt == 0) {
// round and move decimal point
s = (*s < '5') ? "0" : "1";
reqd = 1;
} else {
reqd = strlen(s);
if (reqd > decpt) reqd++;
if (decpt == 0) reqd++;
decpt++;
}

// if all zeros, limit to precision
if (-decpt > (int)precision) {
s = "0";
decpt = -precision;
}

reqd = strlen(s);

// add 1 for decimal point
if (reqd > decpt) reqd++;

// add 1 for zero in front of decimal point
if (decpt == 0) reqd++;

// if leading zeros after decimal point
if (decpt < 0 && precision > 0) {
// ensure enough trailing zeros, add 2 for '0.'
reqd = precision + 2;

if (strlen(s) > precision + decpt) {
// bug in fcvtf. e.g. 0.012, precision 2 should return 1 instead of 12.
// However, 1.2, precision 0 returns correct value. So shift values so
// that decimal point is after the first digit, then convert again

int newPrecision = precision;
int newDecimalPoint;

// shift decimal point
while (newPrecision > 0) {
val *= 10.0;
newPrecision--;
}

// round after accounting for leading 0's
s = fcvtf(val, newPrecision, &newDecimalPoint, &sign);

// if rounded up to new digit (e.g. 0.09 to 0.1), move decimal point
if (newDecimalPoint - decpt == precision + 1) decpt++;
}
}

// add 1 for sign if negative
if (sign) reqd++;

p = buf;
e = p + reqd;
pad = width - reqd;
@@ -150,12 +193,13 @@ char * dtostrf(float val, int width, unsigned int precision, char *buf)
else if (decpt < 0 && precision > 0) {
*p++ = '0';
*p++ = '.';
e++;
// print leading zeros
while ( decpt < 0 ) {
decpt++;
*p++ = '0';
}
}
// print digits
while (p < e) {
*p++ = *s++;
if (p == e) break;

+ 8
- 1
teensy3/pins_teensy.c View File

@@ -583,8 +583,9 @@ void _init_Teensyduino_internal_(void)
// for background about this startup delay, please see these conversations
// https://forum.pjrc.com/threads/36606-startup-time-(400ms)?p=113980&viewfull=1#post113980
// https://forum.pjrc.com/threads/31290-Teensey-3-2-Teensey-Loader-1-24-Issues?p=87273&viewfull=1#post87273
delay(400);
delay(50);
usb_init();
delay(350);
}


@@ -926,6 +927,11 @@ void analogWriteFrequency(uint8_t pin, float frequency)
ftmClock = 16000000;
} else
#endif
#if defined(__MKL26Z64__)
// Teensy LC does not support slow clock source (ftmClockSource = 2)
ftmClockSource = 1; // Use default F_TIMER clock source
ftmClock = F_TIMER; // Set variable for the actual timer clock frequency
#else
if (frequency < (float)(F_TIMER >> 7) / 65536.0f) {
// frequency is too low for working with F_TIMER:
ftmClockSource = 2; // Use alternative 31250Hz clock source
@@ -934,6 +940,7 @@ void analogWriteFrequency(uint8_t pin, float frequency)
ftmClockSource = 1; // Use default F_TIMER clock source
ftmClock = F_TIMER; // Set variable for the actual timer clock frequency
}
#endif

for (prescale = 0; prescale < 7; prescale++) {

+ 29
- 4
teensy3/serial1.c View File

@@ -121,6 +121,7 @@ void serial_begin(uint32_t divisor)
case 21: CORE_PIN21_CONFIG = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_PFE | PORT_PCR_MUX(3); break;
#if defined(KINETISL)
case 3: CORE_PIN3_CONFIG = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_PFE | PORT_PCR_MUX(2); break;
case 25: CORE_PIN25_CONFIG = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_PFE | PORT_PCR_MUX(4); break;
#endif
#if defined(__MK64FX512__) || defined(__MK66FX1M0__)
case 27: CORE_PIN27_CONFIG = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_PFE | PORT_PCR_MUX(3); break;
@@ -131,6 +132,7 @@ void serial_begin(uint32_t divisor)
case 5: CORE_PIN5_CONFIG = PORT_PCR_DSE | PORT_PCR_SRE | PORT_PCR_MUX(3); break;
#if defined(KINETISL)
case 4: CORE_PIN4_CONFIG = PORT_PCR_DSE | PORT_PCR_SRE | PORT_PCR_MUX(2); break;
case 24: CORE_PIN24_CONFIG = PORT_PCR_DSE | PORT_PCR_SRE | PORT_PCR_MUX(4); break;
#endif
#if defined(__MK64FX512__) || defined(__MK66FX1M0__)
case 26: CORE_PIN26_CONFIG = PORT_PCR_DSE | PORT_PCR_SRE | PORT_PCR_MUX(3); break;
@@ -196,8 +198,28 @@ void serial_end(void)
while (transmitting) yield(); // wait for buffered data to send
NVIC_DISABLE_IRQ(IRQ_UART0_STATUS);
UART0_C2 = 0;
CORE_PIN0_CONFIG = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_MUX(1);
CORE_PIN1_CONFIG = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_MUX(1);
switch (rx_pin_num) {
case 0: CORE_PIN0_CONFIG = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_MUX(1); break;
case 21: CORE_PIN21_CONFIG = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_MUX(1); break;
#if defined(KINETISL)
case 3: CORE_PIN3_CONFIG = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_MUX(1); break;
case 25: CORE_PIN25_CONFIG = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_MUX(1); break;
#endif
#if defined(__MK64FX512__) || defined(__MK66FX1M0__)
case 27: CORE_PIN27_CONFIG = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_MUX(1); break;
#endif
}
switch (tx_pin_num & 127) {
case 1: CORE_PIN1_CONFIG = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_MUX(1); break;
case 5: CORE_PIN5_CONFIG = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_MUX(1); break;
#if defined(KINETISL)
case 4: CORE_PIN4_CONFIG = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_MUX(1); break;
case 24: CORE_PIN24_CONFIG = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_MUX(1); break;
#endif
#if defined(__MK64FX512__) || defined(__MK66FX1M0__)
case 26: CORE_PIN26_CONFIG = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_MUX(1); break;
#endif
}
rx_buffer_head = 0;
rx_buffer_tail = 0;
if (rts_pin) rts_deassert();
@@ -553,8 +575,11 @@ void uart0_status_isr(void)
}
#else
if (UART0_S1 & UART_S1_RDRF) {
n = UART0_D;
if (use9Bits && (UART0_C3 & 0x80)) n |= 0x100;
if (use9Bits && (UART0_C3 & 0x80)) {
n = UART0_D | 0x100;
} else {
n = UART0_D;
}
head = rx_buffer_head + 1;
if (head >= SERIAL1_RX_BUFFER_SIZE) head = 0;
if (head != rx_buffer_tail) {

+ 5
- 2
teensy3/serial2.c View File

@@ -565,8 +565,11 @@ void uart1_status_isr(void)
}
#else
if (UART1_S1 & UART_S1_RDRF) {
n = UART1_D;
if (use9Bits && (UART1_C3 & 0x80)) n |= 0x100;
if (use9Bits && (UART1_C3 & 0x80)) {
n = UART1_D | 0x100;
} else {
n = UART1_D;
}
head = rx_buffer_head + 1;
if (head >= SERIAL2_RX_BUFFER_SIZE) head = 0;
if (head != rx_buffer_tail) {

+ 11
- 0
teensy3/serial3.c View File

@@ -181,8 +181,19 @@ void serial3_end(void)
while (transmitting) yield(); // wait for buffered data to send
NVIC_DISABLE_IRQ(IRQ_UART2_STATUS);
UART2_C2 = 0;
#if defined(KINETISK)
CORE_PIN7_CONFIG = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_MUX(1);
CORE_PIN8_CONFIG = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_MUX(1);
#elif defined(KINETISL)
switch (rx_pin_num) {
case 7: CORE_PIN7_CONFIG = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_MUX(1); break;
case 6: CORE_PIN6_CONFIG = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_MUX(1); break;
}
switch (tx_pin_num & 127) {
case 8: CORE_PIN8_CONFIG = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_MUX(1); break;
case 20: CORE_PIN20_CONFIG = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_MUX(1); break;
}
#endif
rx_buffer_head = 0;
rx_buffer_tail = 0;
if (rts_pin) rts_deassert();

+ 0
- 2
teensy3/serial4.c View File

@@ -159,8 +159,6 @@ void serial4_end(void)
while (transmitting) yield(); // wait for buffered data to send
NVIC_DISABLE_IRQ(IRQ_UART3_STATUS);
UART3_C2 = 0;
CORE_PIN31_CONFIG = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_MUX(1);
CORE_PIN32_CONFIG = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_MUX(1);
switch (rx_pin_num) {
case 31: CORE_PIN31_CONFIG = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_MUX(1); break; // PTC3
case 63: CORE_PIN63_CONFIG = 0; break;

+ 26
- 1
teensy3/usb_audio.cpp View File

@@ -49,7 +49,7 @@ audio_block_t * AudioInputUSB::ready_right;
uint16_t AudioInputUSB::incoming_count;
uint8_t AudioInputUSB::receive_flag;

struct usb_audio_features_struct AudioInputUSB::features = {0,0,FEATURE_MAX_VOLUME};
struct usb_audio_features_struct AudioInputUSB::features = {0,0,FEATURE_MAX_VOLUME/2};

#define DMABUFATTR __attribute__ ((section(".dmabuffers"), aligned (4)))
uint16_t usb_audio_receive_buffer[AUDIO_RX_SIZE/2] DMABUFATTR;
@@ -350,6 +350,31 @@ unsigned int usb_audio_transmit_callback(void)
return target * 4;
}


struct setup_struct {
union {
struct {
uint8_t bmRequestType;
uint8_t bRequest;
union {
struct {
uint8_t bChannel; // 0=main, 1=left, 2=right
uint8_t bCS; // Control Selector
};
uint16_t wValue;
};
union {
struct {
uint8_t bIfEp; // type of entity
uint8_t bEntityId; // UnitID, TerminalID, etc.
};
uint16_t wIndex;
};
uint16_t wLength;
};
};
};

int usb_audio_get_feature(void *stp, uint8_t *data, uint32_t *datalen)
{
struct setup_struct setup = *((struct setup_struct *)stp);

+ 4
- 28
teensy3/usb_audio.h View File

@@ -22,32 +22,6 @@ extern uint8_t usb_audio_transmit_setting;
#ifdef __cplusplus
}

// setup struct definition could be moved from usb_dev.c to usb_dev.h so we can reuse
// it instead of redefining it here
struct setup_struct {
union {
struct {
uint8_t bmRequestType;
uint8_t bRequest;
union {
struct {
uint8_t bChannel; // 0=main, 1=left, 2=right
uint8_t bCS; // Control Selector
};
uint16_t wValue;
};
union {
struct {
uint8_t bIfEp; // type of entity
uint8_t bEntityId; // UnitID, TerminalID, etc.
};
uint16_t wIndex;
};
uint16_t wLength;
};
};
};

// audio features supported
struct usb_audio_features_struct {
int change; // set to 1 when any value is changed
@@ -66,9 +40,11 @@ public:
friend void usb_audio_receive_callback(unsigned int len);
friend int usb_audio_set_feature(void *stp, uint8_t *buf);
friend int usb_audio_get_feature(void *stp, uint8_t *data, uint32_t *datalen);

static struct usb_audio_features_struct features;

float volume(void) {
if (features.mute) return 0.0;
return (float)(features.volume) * (1.0 / (float)FEATURE_MAX_VOLUME);
}
private:
static bool update_responsibility;
static audio_block_t *incoming_left;

+ 1
- 1
teensy3/usb_desc.c View File

@@ -1131,7 +1131,7 @@ static uint8_t config_descriptor[CONFIG_DESC_SIZE] = {
9, // bLength
5, // bDescriptorType, 5 = ENDPOINT_DESCRIPTOR
AUDIO_TX_ENDPOINT | 0x80, // bEndpointAddress
0x05, // bmAttributes = isochronous, asynchronous
0x09, // bmAttributes = isochronous, adaptive
LSB(AUDIO_TX_SIZE), MSB(AUDIO_TX_SIZE), // wMaxPacketSize
1, // bInterval, 1 = every frame
0, // bRefresh

+ 7
- 1
teensy3/usb_serial.h View File

@@ -71,7 +71,13 @@ extern volatile uint8_t usb_configuration;
class usb_serial_class : public Stream
{
public:
void begin(long) { /* TODO: call a function that tries to wait for enumeration */ };
void begin(long) {
uint32_t millis_begin = systick_millis_count;
while (!(*this)) {
// wait up to 1 second for Arduino Serial Monitor
if ((uint32_t)(systick_millis_count - millis_begin) > 1000) break;
}
}
void end() { /* TODO: flush output and shut down USB port */ };
virtual int available() { return usb_serial_available(); }
virtual int read() { return usb_serial_getchar(); }

Loading…
Cancel
Save