Teensy 4.1 core updated for C++20
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

502 lines
13KB

  1. /* Teensyduino Core Library
  2. * http://www.pjrc.com/teensy/
  3. * Copyright (c) 2017 PJRC.COM, LLC.
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining
  6. * a copy of this software and associated documentation files (the
  7. * "Software"), to deal in the Software without restriction, including
  8. * without limitation the rights to use, copy, modify, merge, publish,
  9. * distribute, sublicense, and/or sell copies of the Software, and to
  10. * permit persons to whom the Software is furnished to do so, subject to
  11. * the following conditions:
  12. *
  13. * 1. The above copyright notice and this permission notice shall be
  14. * included in all copies or substantial portions of the Software.
  15. *
  16. * 2. If the Software is incorporated into a build system that allows
  17. * selection among a list of target devices, then similar target
  18. * devices manufactured by PJRC.COM must be included in the list of
  19. * target devices and selectable in the same manner.
  20. *
  21. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  22. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  23. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  24. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  25. * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  26. * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  27. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  28. * SOFTWARE.
  29. */
  30. #include <Arduino.h>
  31. #include "usb_dev.h"
  32. #include "debug/printf.h"
  33. #ifdef AUDIO_INTERFACE
  34. // Uncomment this to work around a limitation in Macintosh adaptive rates
  35. // This is not a perfect solution. Details here:
  36. // https://forum.pjrc.com/threads/34855-Distorted-audio-when-using-USB-input-on-Teensy-3-1
  37. //#define MACOSX_ADAPTIVE_LIMIT
  38. bool AudioInputUSB::update_responsibility;
  39. audio_block_t * AudioInputUSB::incoming_left;
  40. audio_block_t * AudioInputUSB::incoming_right;
  41. audio_block_t * AudioInputUSB::ready_left;
  42. audio_block_t * AudioInputUSB::ready_right;
  43. uint16_t AudioInputUSB::incoming_count;
  44. uint8_t AudioInputUSB::receive_flag;
  45. struct usb_audio_features_struct AudioInputUSB::features = {0,0,FEATURE_MAX_VOLUME/2};
  46. extern volatile uint8_t usb_high_speed;
  47. static void rx_event(transfer_t *t);
  48. static transfer_t rx_transfer __attribute__ ((used, aligned(32)));
  49. /*DMAMEM*/ static uint8_t rx_buffer[AUDIO_RX_SIZE_12] __attribute__ ((aligned(32)));
  50. static uint16_t rx_max_size;
  51. //#define DMABUFATTR __attribute__ ((section(".dmabuffers"), aligned (4)))
  52. //uint16_t usb_audio_receive_buffer[AUDIO_RX_SIZE/2] DMABUFATTR;
  53. //uint32_t usb_audio_sync_feedback DMABUFATTR;
  54. uint8_t usb_audio_receive_setting=0;
  55. uint8_t usb_audio_transmit_setting=0;
  56. static uint32_t feedback_accumulator = 185042824;
  57. static void rx_queue_transfer(void)
  58. {
  59. usb_prepare_transfer(&rx_transfer, rx_buffer, rx_max_size, 0);
  60. arm_dcache_delete(&rx_transfer, rx_max_size);
  61. usb_receive(AUDIO_RX_ENDPOINT, &rx_transfer);
  62. }
  63. void usb_audio_configure(void)
  64. {
  65. printf("usb_audio_configure\n");
  66. memset(&rx_transfer, 0, sizeof(rx_transfer));
  67. rx_max_size = usb_high_speed ? AUDIO_RX_SIZE_480 : AUDIO_RX_SIZE_12;
  68. usb_config_rx(AUDIO_RX_ENDPOINT, rx_max_size, 0, rx_event);
  69. rx_queue_transfer();
  70. }
  71. void AudioInputUSB::begin(void)
  72. {
  73. incoming_count = 0;
  74. incoming_left = NULL;
  75. incoming_right = NULL;
  76. ready_left = NULL;
  77. ready_right = NULL;
  78. receive_flag = 0;
  79. // update_responsibility = update_setup();
  80. // TODO: update responsibility is tough, partly because the USB
  81. // interrupts aren't sychronous to the audio library block size,
  82. // but also because the PC may stop transmitting data, which
  83. // means we no longer get receive callbacks from usb.c
  84. update_responsibility = false;
  85. //usb_audio_sync_feedback = feedback_accumulator >> 8;
  86. }
  87. static void copy_to_buffers(const uint32_t *src, int16_t *left, int16_t *right, unsigned int len)
  88. {
  89. uint32_t *target = (uint32_t*) src + len;
  90. while ((src < target) && (((uintptr_t) left & 0x02) != 0)) {
  91. uint32_t n = *src++;
  92. *left++ = n & 0xFFFF;
  93. *right++ = n >> 16;
  94. }
  95. while ((src < target - 2)) {
  96. uint32_t n1 = *src++;
  97. uint32_t n = *src++;
  98. *(uint32_t *)left = (n1 & 0xFFFF) | ((n & 0xFFFF) << 16);
  99. left+=2;
  100. *(uint32_t *)right = (n1 >> 16) | ((n & 0xFFFF0000)) ;
  101. right+=2;
  102. }
  103. while ((src < target)) {
  104. uint32_t n = *src++;
  105. *left++ = n & 0xFFFF;
  106. *right++ = n >> 16;
  107. }
  108. }
  109. static void rx_event(transfer_t *t)
  110. {
  111. int len = rx_max_size - ((t->status >> 16) & 0x7FFF);
  112. printf("rx event, len=%d\n", len);
  113. // TODO: actually move the data from USB to audio lib
  114. rx_queue_transfer();
  115. }
  116. // Called from the USB interrupt when an isochronous packet arrives
  117. // we must completely remove it from the receive buffer before returning
  118. //
  119. #if 0
  120. void usb_audio_receive_callback(unsigned int len)
  121. {
  122. unsigned int count, avail;
  123. audio_block_t *left, *right;
  124. const uint32_t *data;
  125. AudioInputUSB::receive_flag = 1;
  126. len >>= 2; // 1 sample = 4 bytes: 2 left, 2 right
  127. data = (const uint32_t *)usb_audio_receive_buffer;
  128. count = AudioInputUSB::incoming_count;
  129. left = AudioInputUSB::incoming_left;
  130. right = AudioInputUSB::incoming_right;
  131. if (left == NULL) {
  132. left = AudioStream::allocate();
  133. if (left == NULL) return;
  134. AudioInputUSB::incoming_left = left;
  135. }
  136. if (right == NULL) {
  137. right = AudioStream::allocate();
  138. if (right == NULL) return;
  139. AudioInputUSB::incoming_right = right;
  140. }
  141. while (len > 0) {
  142. avail = AUDIO_BLOCK_SAMPLES - count;
  143. if (len < avail) {
  144. copy_to_buffers(data, left->data + count, right->data + count, len);
  145. AudioInputUSB::incoming_count = count + len;
  146. return;
  147. } else if (avail > 0) {
  148. copy_to_buffers(data, left->data + count, right->data + count, avail);
  149. data += avail;
  150. len -= avail;
  151. if (AudioInputUSB::ready_left || AudioInputUSB::ready_right) {
  152. // buffer overrun, PC sending too fast
  153. AudioInputUSB::incoming_count = count + avail;
  154. //if (len > 0) {
  155. //serial_print("!");
  156. //serial_phex(len);
  157. //}
  158. return;
  159. }
  160. send:
  161. AudioInputUSB::ready_left = left;
  162. AudioInputUSB::ready_right = right;
  163. //if (AudioInputUSB::update_responsibility) AudioStream::update_all();
  164. left = AudioStream::allocate();
  165. if (left == NULL) {
  166. AudioInputUSB::incoming_left = NULL;
  167. AudioInputUSB::incoming_right = NULL;
  168. AudioInputUSB::incoming_count = 0;
  169. return;
  170. }
  171. right = AudioStream::allocate();
  172. if (right == NULL) {
  173. AudioStream::release(left);
  174. AudioInputUSB::incoming_left = NULL;
  175. AudioInputUSB::incoming_right = NULL;
  176. AudioInputUSB::incoming_count = 0;
  177. return;
  178. }
  179. AudioInputUSB::incoming_left = left;
  180. AudioInputUSB::incoming_right = right;
  181. count = 0;
  182. } else {
  183. if (AudioInputUSB::ready_left || AudioInputUSB::ready_right) return;
  184. goto send; // recover from buffer overrun
  185. }
  186. }
  187. AudioInputUSB::incoming_count = count;
  188. }
  189. #endif
  190. void AudioInputUSB::update(void)
  191. {
  192. audio_block_t *left, *right;
  193. __disable_irq();
  194. left = ready_left;
  195. ready_left = NULL;
  196. right = ready_right;
  197. ready_right = NULL;
  198. uint16_t c = incoming_count;
  199. uint8_t f = receive_flag;
  200. receive_flag = 0;
  201. __enable_irq();
  202. if (f) {
  203. int diff = AUDIO_BLOCK_SAMPLES/2 - (int)c;
  204. feedback_accumulator += diff / 3;
  205. uint32_t feedback = (feedback_accumulator >> 8) + diff * 100;
  206. #ifdef MACOSX_ADAPTIVE_LIMIT
  207. if (feedback > 722698) feedback = 722698;
  208. #endif
  209. //usb_audio_sync_feedback = feedback;
  210. //if (diff > 0) {
  211. //serial_print(".");
  212. //} else if (diff < 0) {
  213. //serial_print("^");
  214. //}
  215. }
  216. //serial_phex(c);
  217. //serial_print(".");
  218. if (!left || !right) {
  219. //serial_print("#"); // buffer underrun - PC sending too slow
  220. //if (f) feedback_accumulator += 10 << 8;
  221. }
  222. if (left) {
  223. transmit(left, 0);
  224. release(left);
  225. }
  226. if (right) {
  227. transmit(right, 1);
  228. release(right);
  229. }
  230. }
  231. #if 0
  232. bool AudioOutputUSB::update_responsibility;
  233. audio_block_t * AudioOutputUSB::left_1st;
  234. audio_block_t * AudioOutputUSB::left_2nd;
  235. audio_block_t * AudioOutputUSB::right_1st;
  236. audio_block_t * AudioOutputUSB::right_2nd;
  237. uint16_t AudioOutputUSB::offset_1st;
  238. uint16_t usb_audio_transmit_buffer[AUDIO_TX_SIZE/2] DMABUFATTR;
  239. void AudioOutputUSB::begin(void)
  240. {
  241. update_responsibility = false;
  242. left_1st = NULL;
  243. right_1st = NULL;
  244. }
  245. static void copy_from_buffers(uint32_t *dst, int16_t *left, int16_t *right, unsigned int len)
  246. {
  247. // TODO: optimize...
  248. while (len > 0) {
  249. *dst++ = (*right++ << 16) | (*left++ & 0xFFFF);
  250. len--;
  251. }
  252. }
  253. void AudioOutputUSB::update(void)
  254. {
  255. audio_block_t *left, *right;
  256. // TODO: we shouldn't be writing to these......
  257. //left = receiveReadOnly(0); // input 0 = left channel
  258. //right = receiveReadOnly(1); // input 1 = right channel
  259. left = receiveWritable(0); // input 0 = left channel
  260. right = receiveWritable(1); // input 1 = right channel
  261. if (usb_audio_transmit_setting == 0) {
  262. if (left) release(left);
  263. if (right) release(right);
  264. if (left_1st) { release(left_1st); left_1st = NULL; }
  265. if (left_2nd) { release(left_2nd); left_2nd = NULL; }
  266. if (right_1st) { release(right_1st); right_1st = NULL; }
  267. if (right_2nd) { release(right_2nd); right_2nd = NULL; }
  268. offset_1st = 0;
  269. return;
  270. }
  271. if (left == NULL) {
  272. left = allocate();
  273. if (left == NULL) {
  274. if (right) release(right);
  275. return;
  276. }
  277. memset(left->data, 0, sizeof(left->data));
  278. }
  279. if (right == NULL) {
  280. right = allocate();
  281. if (right == NULL) {
  282. release(left);
  283. return;
  284. }
  285. memset(right->data, 0, sizeof(right->data));
  286. }
  287. __disable_irq();
  288. if (left_1st == NULL) {
  289. left_1st = left;
  290. right_1st = right;
  291. offset_1st = 0;
  292. } else if (left_2nd == NULL) {
  293. left_2nd = left;
  294. right_2nd = right;
  295. } else {
  296. // buffer overrun - PC is consuming too slowly
  297. audio_block_t *discard1 = left_1st;
  298. left_1st = left_2nd;
  299. left_2nd = left;
  300. audio_block_t *discard2 = right_1st;
  301. right_1st = right_2nd;
  302. right_2nd = right;
  303. offset_1st = 0; // TODO: discard part of this data?
  304. //serial_print("*");
  305. release(discard1);
  306. release(discard2);
  307. }
  308. __enable_irq();
  309. }
  310. // Called from the USB interrupt when ready to transmit another
  311. // isochronous packet. If we place data into the transmit buffer,
  312. // the return is the number of bytes. Otherwise, return 0 means
  313. // no data to transmit
  314. unsigned int usb_audio_transmit_callback(void)
  315. {
  316. static uint32_t count=5;
  317. uint32_t avail, num, target, offset, len=0;
  318. audio_block_t *left, *right;
  319. if (++count < 9) { // TODO: dynamic adjust to match USB rate
  320. target = 44;
  321. } else {
  322. count = 0;
  323. target = 45;
  324. }
  325. while (len < target) {
  326. num = target - len;
  327. left = AudioOutputUSB::left_1st;
  328. if (left == NULL) {
  329. // buffer underrun - PC is consuming too quickly
  330. memset(usb_audio_transmit_buffer + len, 0, num * 4);
  331. //serial_print("%");
  332. break;
  333. }
  334. right = AudioOutputUSB::right_1st;
  335. offset = AudioOutputUSB::offset_1st;
  336. avail = AUDIO_BLOCK_SAMPLES - offset;
  337. if (num > avail) num = avail;
  338. copy_from_buffers((uint32_t *)usb_audio_transmit_buffer + len,
  339. left->data + offset, right->data + offset, num);
  340. len += num;
  341. offset += num;
  342. if (offset >= AUDIO_BLOCK_SAMPLES) {
  343. AudioStream::release(left);
  344. AudioStream::release(right);
  345. AudioOutputUSB::left_1st = AudioOutputUSB::left_2nd;
  346. AudioOutputUSB::left_2nd = NULL;
  347. AudioOutputUSB::right_1st = AudioOutputUSB::right_2nd;
  348. AudioOutputUSB::right_2nd = NULL;
  349. AudioOutputUSB::offset_1st = 0;
  350. } else {
  351. AudioOutputUSB::offset_1st = offset;
  352. }
  353. }
  354. return target * 4;
  355. }
  356. #endif
  357. struct setup_struct {
  358. union {
  359. struct {
  360. uint8_t bmRequestType;
  361. uint8_t bRequest;
  362. union {
  363. struct {
  364. uint8_t bChannel; // 0=main, 1=left, 2=right
  365. uint8_t bCS; // Control Selector
  366. };
  367. uint16_t wValue;
  368. };
  369. union {
  370. struct {
  371. uint8_t bIfEp; // type of entity
  372. uint8_t bEntityId; // UnitID, TerminalID, etc.
  373. };
  374. uint16_t wIndex;
  375. };
  376. uint16_t wLength;
  377. };
  378. };
  379. };
  380. int usb_audio_get_feature(void *stp, uint8_t *data, uint32_t *datalen)
  381. {
  382. struct setup_struct setup = *((struct setup_struct *)stp);
  383. if (setup.bmRequestType==0xA1) { // should check bRequest, bChannel, and UnitID
  384. if (setup.bCS==0x01) { // mute
  385. data[0] = AudioInputUSB::features.mute; // 1=mute, 0=unmute
  386. *datalen = 1;
  387. return 1;
  388. }
  389. else if (setup.bCS==0x02) { // volume
  390. if (setup.bRequest==0x81) { // GET_CURR
  391. data[0] = AudioInputUSB::features.volume & 0xFF;
  392. data[1] = (AudioInputUSB::features.volume>>8) & 0xFF;
  393. }
  394. else if (setup.bRequest==0x82) { // GET_MIN
  395. //serial_print("vol get_min\n");
  396. data[0] = 0; // min level is 0
  397. data[1] = 0;
  398. }
  399. else if (setup.bRequest==0x83) { // GET_MAX
  400. data[0] = FEATURE_MAX_VOLUME & 0xFF; // max level, for range of 0 to MAX
  401. data[1] = (FEATURE_MAX_VOLUME>>8) & 0x0F;
  402. }
  403. else if (setup.bRequest==0x84) { // GET_RES
  404. data[0] = 1; // increment vol by by 1
  405. data[1] = 0;
  406. }
  407. else { // pass over SET_MEM, etc.
  408. return 0;
  409. }
  410. *datalen = 2;
  411. return 1;
  412. }
  413. }
  414. return 0;
  415. }
  416. int usb_audio_set_feature(void *stp, uint8_t *buf)
  417. {
  418. struct setup_struct setup = *((struct setup_struct *)stp);
  419. if (setup.bmRequestType==0x21) { // should check bRequest, bChannel and UnitID
  420. if (setup.bCS==0x01) { // mute
  421. if (setup.bRequest==0x01) { // SET_CUR
  422. AudioInputUSB::features.mute = buf[0]; // 1=mute,0=unmute
  423. AudioInputUSB::features.change = 1;
  424. return 1;
  425. }
  426. }
  427. else if (setup.bCS==0x02) { // volume
  428. if (setup.bRequest==0x01) { // SET_CUR
  429. AudioInputUSB::features.volume = buf[0] + (buf[1]<<8);
  430. AudioInputUSB::features.change = 1;
  431. return 1;
  432. }
  433. }
  434. }
  435. return 0;
  436. }
  437. #endif // AUDIO_INTERFACE