@@ -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); } |
@@ -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 |
@@ -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. |
@@ -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); |
@@ -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; |
@@ -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++) { |
@@ -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) { |
@@ -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) { |
@@ -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(); |
@@ -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; |
@@ -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); |
@@ -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; |
@@ -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 |
@@ -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(); } |