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.

193 lines
5.3KB

  1. #include "Audio.h"
  2. #include "arm_math.h"
  3. DMAMEM static uint16_t analog_rx_buffer[AUDIO_BLOCK_SAMPLES];
  4. audio_block_t * AudioInputAnalog::block_left = NULL;
  5. uint16_t AudioInputAnalog::block_offset = 0;
  6. bool AudioInputAnalog::update_responsibility = false;
  7. // #define PDB_CONFIG (PDB_SC_TRGSEL(15) | PDB_SC_PDBEN | PDB_SC_CONT)
  8. // #define PDB_PERIOD 1087 // 48e6 / 44100
  9. void AudioInputAnalog::begin(unsigned int pin)
  10. {
  11. uint32_t i, sum=0;
  12. // pin must be 0 to 13 (for A0 to A13)
  13. // or 14 to 23 for digital pin numbers A0-A9
  14. // or 34 to 37 corresponding to A10-A13
  15. if (pin > 23 && !(pin >= 34 && pin <= 37)) return;
  16. //pinMode(2, OUTPUT);
  17. //pinMode(3, OUTPUT);
  18. //digitalWriteFast(3, HIGH);
  19. //delayMicroseconds(500);
  20. //digitalWriteFast(3, LOW);
  21. // Configure the ADC and run at least one software-triggered
  22. // conversion. This completes the self calibration stuff and
  23. // leaves the ADC in a state that's mostly ready to use
  24. analogReadRes(16);
  25. analogReference(INTERNAL); // range 0 to 1.2 volts
  26. //analogReference(DEFAULT); // range 0 to 3.3 volts
  27. analogReadAveraging(8);
  28. // Actually, do many normal reads, to start with a nice DC level
  29. for (i=0; i < 1024; i++) {
  30. sum += analogRead(pin);
  31. }
  32. dc_average = sum >> 10;
  33. // testing only, enable adc interrupt
  34. //ADC0_SC1A |= ADC_SC1_AIEN;
  35. //while ((ADC0_SC1A & ADC_SC1_COCO) == 0) ; // wait
  36. //NVIC_ENABLE_IRQ(IRQ_ADC0);
  37. // set the programmable delay block to trigger the ADC at 44.1 kHz
  38. SIM_SCGC6 |= SIM_SCGC6_PDB;
  39. PDB0_MOD = PDB_PERIOD;
  40. PDB0_SC = PDB_CONFIG | PDB_SC_LDOK;
  41. PDB0_SC = PDB_CONFIG | PDB_SC_SWTRIG;
  42. PDB0_CH0C1 = 0x0101;
  43. // enable the ADC for hardware trigger and DMA
  44. ADC0_SC2 |= ADC_SC2_ADTRG | ADC_SC2_DMAEN;
  45. // set up a DMA channel to store the ADC data
  46. SIM_SCGC7 |= SIM_SCGC7_DMA;
  47. SIM_SCGC6 |= SIM_SCGC6_DMAMUX;
  48. DMA_CR = 0;
  49. DMA_TCD2_SADDR = &ADC0_RA;
  50. DMA_TCD2_SOFF = 0;
  51. DMA_TCD2_ATTR = DMA_TCD_ATTR_SSIZE(1) | DMA_TCD_ATTR_DSIZE(1);
  52. DMA_TCD2_NBYTES_MLNO = 2;
  53. DMA_TCD2_SLAST = 0;
  54. DMA_TCD2_DADDR = analog_rx_buffer;
  55. DMA_TCD2_DOFF = 2;
  56. DMA_TCD2_CITER_ELINKNO = sizeof(analog_rx_buffer) / 2;
  57. DMA_TCD2_DLASTSGA = -sizeof(analog_rx_buffer);
  58. DMA_TCD2_BITER_ELINKNO = sizeof(analog_rx_buffer) / 2;
  59. DMA_TCD2_CSR = DMA_TCD_CSR_INTHALF | DMA_TCD_CSR_INTMAJOR;
  60. DMAMUX0_CHCFG2 = DMAMUX_DISABLE;
  61. DMAMUX0_CHCFG2 = DMAMUX_SOURCE_ADC0 | DMAMUX_ENABLE;
  62. update_responsibility = update_setup();
  63. DMA_SERQ = 2;
  64. NVIC_ENABLE_IRQ(IRQ_DMA_CH2);
  65. }
  66. void dma_ch2_isr(void)
  67. {
  68. uint32_t daddr, offset;
  69. const uint16_t *src, *end;
  70. uint16_t *dest_left;
  71. audio_block_t *left;
  72. //digitalWriteFast(3, HIGH);
  73. daddr = (uint32_t)DMA_TCD2_DADDR;
  74. DMA_CINT = 2;
  75. if (daddr < (uint32_t)analog_rx_buffer + sizeof(analog_rx_buffer) / 2) {
  76. // DMA is receiving to the first half of the buffer
  77. // need to remove data from the second half
  78. src = (uint16_t *)&analog_rx_buffer[AUDIO_BLOCK_SAMPLES/2];
  79. end = (uint16_t *)&analog_rx_buffer[AUDIO_BLOCK_SAMPLES];
  80. if (AudioInputAnalog::update_responsibility) AudioStream::update_all();
  81. } else {
  82. // DMA is receiving to the second half of the buffer
  83. // need to remove data from the first half
  84. src = (uint16_t *)&analog_rx_buffer[0];
  85. end = (uint16_t *)&analog_rx_buffer[AUDIO_BLOCK_SAMPLES/2];
  86. }
  87. left = AudioInputAnalog::block_left;
  88. if (left != NULL) {
  89. offset = AudioInputAnalog::block_offset;
  90. if (offset > AUDIO_BLOCK_SAMPLES/2) offset = AUDIO_BLOCK_SAMPLES/2;
  91. //if (offset <= AUDIO_BLOCK_SAMPLES/2) {
  92. dest_left = (uint16_t *)&(left->data[offset]);
  93. AudioInputAnalog::block_offset = offset + AUDIO_BLOCK_SAMPLES/2;
  94. do {
  95. *dest_left++ = *src++;
  96. } while (src < end);
  97. //}
  98. }
  99. //digitalWriteFast(3, LOW);
  100. }
  101. #if 0
  102. void adc0_isr(void)
  103. {
  104. uint32_t tmp = ADC0_RA; // read ADC result to clear interrupt
  105. digitalWriteFast(3, HIGH);
  106. delayMicroseconds(1);
  107. digitalWriteFast(3, LOW);
  108. }
  109. #endif
  110. void AudioInputAnalog::update(void)
  111. {
  112. audio_block_t *new_left=NULL, *out_left=NULL;
  113. unsigned int dc, offset;
  114. int16_t s, *p, *end;
  115. // allocate new block (ok if NULL)
  116. new_left = allocate();
  117. __disable_irq();
  118. offset = block_offset;
  119. if (offset < AUDIO_BLOCK_SAMPLES) {
  120. // the DMA didn't fill a block
  121. if (new_left != NULL) {
  122. // but we allocated a block
  123. if (block_left == NULL) {
  124. // the DMA doesn't have any blocks to fill, so
  125. // give it the one we just allocated
  126. block_left = new_left;
  127. block_offset = 0;
  128. __enable_irq();
  129. //Serial.println("fail1");
  130. } else {
  131. // the DMA already has blocks, doesn't need this
  132. __enable_irq();
  133. release(new_left);
  134. //Serial.print("fail2, offset=");
  135. //Serial.println(offset);
  136. }
  137. } else {
  138. // The DMA didn't fill a block, and we could not allocate
  139. // memory... the system is likely starving for memory!
  140. // Sadly, there's nothing we can do.
  141. __enable_irq();
  142. //Serial.println("fail3");
  143. }
  144. return;
  145. }
  146. // the DMA filled a block, so grab it and get the
  147. // new block to the DMA, as quickly as possible
  148. out_left = block_left;
  149. block_left = new_left;
  150. block_offset = 0;
  151. __enable_irq();
  152. // find and subtract DC offset....
  153. // TODO: this may not be correct, needs testing with more types of signals
  154. dc = dc_average;
  155. p = out_left->data;
  156. end = p + AUDIO_BLOCK_SAMPLES;
  157. do {
  158. s = (uint16_t)(*p) - dc; // TODO: should be saturating subtract
  159. *p++ = s;
  160. dc += s >> 13; // approx 5.38 Hz high pass filter
  161. } while (p < end);
  162. dc_average = dc;
  163. // then transmit the AC data
  164. transmit(out_left);
  165. release(out_left);
  166. }