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.

520 lines
14KB

  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 "usb_audio.h"
  33. #include "debug/printf.h"
  34. #ifdef AUDIO_INTERFACE
  35. bool AudioInputUSB::update_responsibility;
  36. audio_block_t * AudioInputUSB::incoming_left;
  37. audio_block_t * AudioInputUSB::incoming_right;
  38. audio_block_t * AudioInputUSB::ready_left;
  39. audio_block_t * AudioInputUSB::ready_right;
  40. uint16_t AudioInputUSB::incoming_count;
  41. uint8_t AudioInputUSB::receive_flag;
  42. struct usb_audio_features_struct AudioInputUSB::features = {0,0,FEATURE_MAX_VOLUME/2};
  43. extern volatile uint8_t usb_high_speed;
  44. static void rx_event(transfer_t *t);
  45. static void rx_queue_transfer(void);
  46. /*static*/ transfer_t rx_transfer __attribute__ ((used, aligned(32)));
  47. /*static*/ transfer_t sync_transfer __attribute__ ((used, aligned(32)));
  48. DMAMEM static uint8_t rx_buffer[AUDIO_RX_SIZE] __attribute__ ((aligned(32)));
  49. DMAMEM uint32_t usb_audio_sync_feedback;
  50. uint8_t usb_audio_receive_setting=0;
  51. uint8_t usb_audio_transmit_setting=0;
  52. uint8_t usb_audio_sync_nbytes;
  53. uint8_t usb_audio_sync_rshift;
  54. uint32_t feedback_accumulator;
  55. volatile uint32_t usb_audio_underrun_count;
  56. volatile uint32_t usb_audio_overrun_count;
  57. static void rx_event(transfer_t *t)
  58. {
  59. if (t) {
  60. int len = AUDIO_RX_SIZE - ((rx_transfer.status >> 16) & 0x7FFF);
  61. //printf("rx %u\n", len);
  62. usb_audio_receive_callback(len);
  63. }
  64. usb_prepare_transfer(&rx_transfer, rx_buffer, AUDIO_RX_SIZE, 0);
  65. arm_dcache_delete(&rx_buffer, AUDIO_RX_SIZE);
  66. usb_receive(AUDIO_RX_ENDPOINT, &rx_transfer);
  67. }
  68. static void sync_event(transfer_t *t)
  69. {
  70. // USB 2.0 Specification, 5.12.4.2 Feedback, pages 73-75
  71. //printf("sync %x\n", sync_transfer.status); // too slow, can't print this much
  72. usb_audio_sync_feedback = feedback_accumulator >> usb_audio_sync_rshift;
  73. usb_prepare_transfer(&sync_transfer, &usb_audio_sync_feedback, usb_audio_sync_nbytes, 0);
  74. arm_dcache_delete(&usb_audio_sync_feedback, usb_audio_sync_nbytes);
  75. usb_transmit(AUDIO_SYNC_ENDPOINT, &sync_transfer);
  76. }
  77. void usb_audio_configure(void)
  78. {
  79. printf("usb_audio_configure\n");
  80. usb_audio_underrun_count = 0;
  81. usb_audio_overrun_count = 0;
  82. feedback_accumulator = 739875226; // 44.1 * 2^24
  83. if (usb_high_speed) {
  84. usb_audio_sync_nbytes = 4;
  85. usb_audio_sync_rshift = 8;
  86. } else {
  87. usb_audio_sync_nbytes = 3;
  88. usb_audio_sync_rshift = 10;
  89. }
  90. memset(&rx_transfer, 0, sizeof(rx_transfer));
  91. usb_config_rx_iso(AUDIO_RX_ENDPOINT, AUDIO_RX_SIZE, 1, rx_event);
  92. //rx_queue_transfer();
  93. rx_event(NULL);
  94. memset(&sync_transfer, 0, sizeof(sync_transfer));
  95. usb_config_tx_iso(AUDIO_SYNC_ENDPOINT, usb_audio_sync_nbytes, 1, sync_event);
  96. sync_event(NULL);
  97. }
  98. void AudioInputUSB::begin(void)
  99. {
  100. incoming_count = 0;
  101. incoming_left = NULL;
  102. incoming_right = NULL;
  103. ready_left = NULL;
  104. ready_right = NULL;
  105. receive_flag = 0;
  106. // update_responsibility = update_setup();
  107. // TODO: update responsibility is tough, partly because the USB
  108. // interrupts aren't sychronous to the audio library block size,
  109. // but also because the PC may stop transmitting data, which
  110. // means we no longer get receive callbacks from usb.c
  111. update_responsibility = false;
  112. }
  113. static void copy_to_buffers(const uint32_t *src, int16_t *left, int16_t *right, unsigned int len)
  114. {
  115. uint32_t *target = (uint32_t*) src + len;
  116. while ((src < target) && (((uintptr_t) left & 0x02) != 0)) {
  117. uint32_t n = *src++;
  118. *left++ = n & 0xFFFF;
  119. *right++ = n >> 16;
  120. }
  121. while ((src < target - 2)) {
  122. uint32_t n1 = *src++;
  123. uint32_t n = *src++;
  124. *(uint32_t *)left = (n1 & 0xFFFF) | ((n & 0xFFFF) << 16);
  125. left+=2;
  126. *(uint32_t *)right = (n1 >> 16) | ((n & 0xFFFF0000)) ;
  127. right+=2;
  128. }
  129. while ((src < target)) {
  130. uint32_t n = *src++;
  131. *left++ = n & 0xFFFF;
  132. *right++ = n >> 16;
  133. }
  134. }
  135. // Called from the USB interrupt when an isochronous packet arrives
  136. // we must completely remove it from the receive buffer before returning
  137. //
  138. #if 1
  139. void usb_audio_receive_callback(unsigned int len)
  140. {
  141. unsigned int count, avail;
  142. audio_block_t *left, *right;
  143. const uint32_t *data;
  144. AudioInputUSB::receive_flag = 1;
  145. len >>= 2; // 1 sample = 4 bytes: 2 left, 2 right
  146. data = (const uint32_t *)rx_buffer;
  147. count = AudioInputUSB::incoming_count;
  148. left = AudioInputUSB::incoming_left;
  149. right = AudioInputUSB::incoming_right;
  150. if (left == NULL) {
  151. left = AudioStream::allocate();
  152. if (left == NULL) return;
  153. AudioInputUSB::incoming_left = left;
  154. }
  155. if (right == NULL) {
  156. right = AudioStream::allocate();
  157. if (right == NULL) return;
  158. AudioInputUSB::incoming_right = right;
  159. }
  160. while (len > 0) {
  161. avail = AUDIO_BLOCK_SAMPLES - count;
  162. if (len < avail) {
  163. copy_to_buffers(data, left->data + count, right->data + count, len);
  164. AudioInputUSB::incoming_count = count + len;
  165. return;
  166. } else if (avail > 0) {
  167. copy_to_buffers(data, left->data + count, right->data + count, avail);
  168. data += avail;
  169. len -= avail;
  170. if (AudioInputUSB::ready_left || AudioInputUSB::ready_right) {
  171. // buffer overrun, PC sending too fast
  172. AudioInputUSB::incoming_count = count + avail;
  173. if (len > 0) {
  174. usb_audio_overrun_count++;
  175. printf("!");
  176. //serial_phex(len);
  177. }
  178. return;
  179. }
  180. send:
  181. AudioInputUSB::ready_left = left;
  182. AudioInputUSB::ready_right = right;
  183. //if (AudioInputUSB::update_responsibility) AudioStream::update_all();
  184. left = AudioStream::allocate();
  185. if (left == NULL) {
  186. AudioInputUSB::incoming_left = NULL;
  187. AudioInputUSB::incoming_right = NULL;
  188. AudioInputUSB::incoming_count = 0;
  189. return;
  190. }
  191. right = AudioStream::allocate();
  192. if (right == NULL) {
  193. AudioStream::release(left);
  194. AudioInputUSB::incoming_left = NULL;
  195. AudioInputUSB::incoming_right = NULL;
  196. AudioInputUSB::incoming_count = 0;
  197. return;
  198. }
  199. AudioInputUSB::incoming_left = left;
  200. AudioInputUSB::incoming_right = right;
  201. count = 0;
  202. } else {
  203. if (AudioInputUSB::ready_left || AudioInputUSB::ready_right) return;
  204. goto send; // recover from buffer overrun
  205. }
  206. }
  207. AudioInputUSB::incoming_count = count;
  208. }
  209. #endif
  210. void AudioInputUSB::update(void)
  211. {
  212. audio_block_t *left, *right;
  213. __disable_irq();
  214. left = ready_left;
  215. ready_left = NULL;
  216. right = ready_right;
  217. ready_right = NULL;
  218. uint16_t c = incoming_count;
  219. uint8_t f = receive_flag;
  220. receive_flag = 0;
  221. __enable_irq();
  222. if (f) {
  223. int diff = AUDIO_BLOCK_SAMPLES/2 - (int)c;
  224. feedback_accumulator += diff * 2;
  225. //__disable_irq();
  226. //printf("fb:%x\n", feedback_accumulator);
  227. //__enable_irq();
  228. //uint32_t feedback = (feedback_accumulator >> 8) + diff * 100;
  229. //usb_audio_sync_feedback = feedback;
  230. //if (diff > 0) {
  231. //serial_print(".");
  232. //} else if (diff < 0) {
  233. //serial_print("^");
  234. //}
  235. }
  236. //serial_phex(c);
  237. //serial_print(".");
  238. if (!left || !right) {
  239. usb_audio_underrun_count++;
  240. printf("#"); // buffer underrun - PC sending too slow
  241. //if (f) feedback_accumulator += 10 << 8;
  242. }
  243. if (left) {
  244. transmit(left, 0);
  245. release(left);
  246. }
  247. if (right) {
  248. transmit(right, 1);
  249. release(right);
  250. }
  251. }
  252. #if 0
  253. bool AudioOutputUSB::update_responsibility;
  254. audio_block_t * AudioOutputUSB::left_1st;
  255. audio_block_t * AudioOutputUSB::left_2nd;
  256. audio_block_t * AudioOutputUSB::right_1st;
  257. audio_block_t * AudioOutputUSB::right_2nd;
  258. uint16_t AudioOutputUSB::offset_1st;
  259. uint16_t usb_audio_transmit_buffer[AUDIO_TX_SIZE/2] DMABUFATTR;
  260. void AudioOutputUSB::begin(void)
  261. {
  262. update_responsibility = false;
  263. left_1st = NULL;
  264. right_1st = NULL;
  265. }
  266. static void copy_from_buffers(uint32_t *dst, int16_t *left, int16_t *right, unsigned int len)
  267. {
  268. // TODO: optimize...
  269. while (len > 0) {
  270. *dst++ = (*right++ << 16) | (*left++ & 0xFFFF);
  271. len--;
  272. }
  273. }
  274. void AudioOutputUSB::update(void)
  275. {
  276. audio_block_t *left, *right;
  277. // TODO: we shouldn't be writing to these......
  278. //left = receiveReadOnly(0); // input 0 = left channel
  279. //right = receiveReadOnly(1); // input 1 = right channel
  280. left = receiveWritable(0); // input 0 = left channel
  281. right = receiveWritable(1); // input 1 = right channel
  282. if (usb_audio_transmit_setting == 0) {
  283. if (left) release(left);
  284. if (right) release(right);
  285. if (left_1st) { release(left_1st); left_1st = NULL; }
  286. if (left_2nd) { release(left_2nd); left_2nd = NULL; }
  287. if (right_1st) { release(right_1st); right_1st = NULL; }
  288. if (right_2nd) { release(right_2nd); right_2nd = NULL; }
  289. offset_1st = 0;
  290. return;
  291. }
  292. if (left == NULL) {
  293. left = allocate();
  294. if (left == NULL) {
  295. if (right) release(right);
  296. return;
  297. }
  298. memset(left->data, 0, sizeof(left->data));
  299. }
  300. if (right == NULL) {
  301. right = allocate();
  302. if (right == NULL) {
  303. release(left);
  304. return;
  305. }
  306. memset(right->data, 0, sizeof(right->data));
  307. }
  308. __disable_irq();
  309. if (left_1st == NULL) {
  310. left_1st = left;
  311. right_1st = right;
  312. offset_1st = 0;
  313. } else if (left_2nd == NULL) {
  314. left_2nd = left;
  315. right_2nd = right;
  316. } else {
  317. // buffer overrun - PC is consuming too slowly
  318. audio_block_t *discard1 = left_1st;
  319. left_1st = left_2nd;
  320. left_2nd = left;
  321. audio_block_t *discard2 = right_1st;
  322. right_1st = right_2nd;
  323. right_2nd = right;
  324. offset_1st = 0; // TODO: discard part of this data?
  325. //serial_print("*");
  326. release(discard1);
  327. release(discard2);
  328. }
  329. __enable_irq();
  330. }
  331. // Called from the USB interrupt when ready to transmit another
  332. // isochronous packet. If we place data into the transmit buffer,
  333. // the return is the number of bytes. Otherwise, return 0 means
  334. // no data to transmit
  335. unsigned int usb_audio_transmit_callback(void)
  336. {
  337. static uint32_t count=5;
  338. uint32_t avail, num, target, offset, len=0;
  339. audio_block_t *left, *right;
  340. if (++count < 9) { // TODO: dynamic adjust to match USB rate
  341. target = 44;
  342. } else {
  343. count = 0;
  344. target = 45;
  345. }
  346. while (len < target) {
  347. num = target - len;
  348. left = AudioOutputUSB::left_1st;
  349. if (left == NULL) {
  350. // buffer underrun - PC is consuming too quickly
  351. memset(usb_audio_transmit_buffer + len, 0, num * 4);
  352. //serial_print("%");
  353. break;
  354. }
  355. right = AudioOutputUSB::right_1st;
  356. offset = AudioOutputUSB::offset_1st;
  357. avail = AUDIO_BLOCK_SAMPLES - offset;
  358. if (num > avail) num = avail;
  359. copy_from_buffers((uint32_t *)usb_audio_transmit_buffer + len,
  360. left->data + offset, right->data + offset, num);
  361. len += num;
  362. offset += num;
  363. if (offset >= AUDIO_BLOCK_SAMPLES) {
  364. AudioStream::release(left);
  365. AudioStream::release(right);
  366. AudioOutputUSB::left_1st = AudioOutputUSB::left_2nd;
  367. AudioOutputUSB::left_2nd = NULL;
  368. AudioOutputUSB::right_1st = AudioOutputUSB::right_2nd;
  369. AudioOutputUSB::right_2nd = NULL;
  370. AudioOutputUSB::offset_1st = 0;
  371. } else {
  372. AudioOutputUSB::offset_1st = offset;
  373. }
  374. }
  375. return target * 4;
  376. }
  377. #endif
  378. struct setup_struct {
  379. union {
  380. struct {
  381. uint8_t bmRequestType;
  382. uint8_t bRequest;
  383. union {
  384. struct {
  385. uint8_t bChannel; // 0=main, 1=left, 2=right
  386. uint8_t bCS; // Control Selector
  387. };
  388. uint16_t wValue;
  389. };
  390. union {
  391. struct {
  392. uint8_t bIfEp; // type of entity
  393. uint8_t bEntityId; // UnitID, TerminalID, etc.
  394. };
  395. uint16_t wIndex;
  396. };
  397. uint16_t wLength;
  398. };
  399. };
  400. };
  401. int usb_audio_get_feature(void *stp, uint8_t *data, uint32_t *datalen)
  402. {
  403. struct setup_struct setup = *((struct setup_struct *)stp);
  404. if (setup.bmRequestType==0xA1) { // should check bRequest, bChannel, and UnitID
  405. if (setup.bCS==0x01) { // mute
  406. data[0] = AudioInputUSB::features.mute; // 1=mute, 0=unmute
  407. *datalen = 1;
  408. return 1;
  409. }
  410. else if (setup.bCS==0x02) { // volume
  411. if (setup.bRequest==0x81) { // GET_CURR
  412. data[0] = AudioInputUSB::features.volume & 0xFF;
  413. data[1] = (AudioInputUSB::features.volume>>8) & 0xFF;
  414. }
  415. else if (setup.bRequest==0x82) { // GET_MIN
  416. //serial_print("vol get_min\n");
  417. data[0] = 0; // min level is 0
  418. data[1] = 0;
  419. }
  420. else if (setup.bRequest==0x83) { // GET_MAX
  421. data[0] = FEATURE_MAX_VOLUME & 0xFF; // max level, for range of 0 to MAX
  422. data[1] = (FEATURE_MAX_VOLUME>>8) & 0x0F;
  423. }
  424. else if (setup.bRequest==0x84) { // GET_RES
  425. data[0] = 1; // increment vol by by 1
  426. data[1] = 0;
  427. }
  428. else { // pass over SET_MEM, etc.
  429. return 0;
  430. }
  431. *datalen = 2;
  432. return 1;
  433. }
  434. }
  435. return 0;
  436. }
  437. int usb_audio_set_feature(void *stp, uint8_t *buf)
  438. {
  439. struct setup_struct setup = *((struct setup_struct *)stp);
  440. if (setup.bmRequestType==0x21) { // should check bRequest, bChannel and UnitID
  441. if (setup.bCS==0x01) { // mute
  442. if (setup.bRequest==0x01) { // SET_CUR
  443. AudioInputUSB::features.mute = buf[0]; // 1=mute,0=unmute
  444. AudioInputUSB::features.change = 1;
  445. return 1;
  446. }
  447. }
  448. else if (setup.bCS==0x02) { // volume
  449. if (setup.bRequest==0x01) { // SET_CUR
  450. AudioInputUSB::features.volume = buf[0] + (buf[1]<<8);
  451. AudioInputUSB::features.change = 1;
  452. return 1;
  453. }
  454. }
  455. }
  456. return 0;
  457. }
  458. #endif // AUDIO_INTERFACE