main.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  1. // This file is part of parrocchetto.
  2. // parrocchetto is free software: you can redistribute it and/or modify
  3. // it under the terms of the GNU General Public License as published by
  4. // the Free Software Foundation, either version 3 of the License, or
  5. // (at your option) any later version.
  6. // parrocchetto is distributed in the hope that it will be useful,
  7. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. // GNU General Public License for more details.
  10. // You should have received a copy of the GNU General Public License
  11. // along with parrocchetto. If not, see <http://www.gnu.org/licenses/>.
  12. #include <xc.h>
  13. #include <dsp.h>
  14. #include <stdint.h>
  15. #include <p33Fxxxx.h>
  16. #include "G726A.h"
  17. #include "G726APack.h"
  18. #include "flash.h"
  19. // FICD
  20. #pragma config ICS = PGD1 // ICD Communication Channel Select bits->Communicate on PGEC1 and PGED1
  21. #pragma config JTAGEN = OFF // JTAG Enable bit->JTAG is disabled
  22. // FWDT
  23. #pragma config WDTPOST = PS32768 // Watchdog Timer Postscaler bits->1:32768
  24. #pragma config WDTPRE = PR128 // Watchdog Timer Prescaler bit->1:128
  25. #pragma config WINDIS = OFF // Watchdog Timer Window Enable bit->Watchdog Timer in Non-Window mode
  26. #pragma config FWDTEN = OFF // Watchdog Timer Enable bit->Watchdog timer enabled/disabled by user software
  27. // FOSC
  28. #pragma config POSCMD = NONE // Primary Oscillator Mode Select bits->Primary Oscillator disabled
  29. #pragma config OSCIOFNC = ON // OSC2 Pin Function bit->OSC2 is general purpose digital I/O pin
  30. #pragma config FCKSM = CSDCMD // Clock Switching Mode bits->Both Clock switching and Fail-safe Clock Monitor are disabled
  31. // FOSCSEL
  32. #pragma config FNOSC = FRCPLL // Oscillator Source Selection->Fast RC Oscillator with divide-by-N with PLL module (FRCPLL)
  33. // FGS
  34. #pragma config GWRP = OFF // General Segment Write-Protect bit->General Segment may be written
  35. // Sampling Control
  36. #define Fosc 79257600 // Hz
  37. #define Fcy (Fosc / 2) // Hz
  38. #define Fs 8042 // Hz
  39. #define SAMPPRD ((Fcy / Fs) - 1) // Hz
  40. #define PACKED_FRAME_SIZE (G726A_FRAME_SIZE >> 1)
  41. #define PACKED_FRAMES_NUM 0x20
  42. volatile int16_t samples_buf0[G726A_FRAME_SIZE] __attribute__((space(dma)));
  43. volatile int16_t samples_buf1[G726A_FRAME_SIZE] __attribute__((space(dma)));
  44. volatile uint16_t samples_buf_ready = 0, bufid = 0;
  45. volatile uint16_t playing = 0, recording = 0;
  46. volatile uint16_t page_samples_num = 0, page_samples_id = 0, packed_samples_num = 0;
  47. uint8_t samples_encoded[G726A_FRAME_SIZE];
  48. uint8_t samples_packed[PACKED_FRAME_SIZE * PACKED_FRAMES_NUM];
  49. uint8_t encoder[G726A_ENCODER_SIZE];
  50. uint8_t decoder[G726A_DECODER_SIZE];
  51. //adc1_init() is used to configure A/D to convert channel 4 on Timer event.
  52. //It generates event to DMA on every sample/convert sequence.
  53. void adc1_init(void)
  54. {
  55. AD1CON1bits.FORM = 3; // Data Output Format: Signed Fraction (Q15 format)
  56. AD1CON1bits.SSRC = 2; // Sample Clock Source: GP Timer starts conversion
  57. AD1CON1bits.ASAM = 1; // ADC Sample Control: Sampling begins immediately after conversion
  58. AD1CON1bits.AD12B = 1; // 12-bit ADC operation
  59. AD1CON2bits.CHPS = 0; // Converts CH0
  60. AD1CON3bits.ADRC = 0; // ADC Clock is derived from Systems Clock
  61. AD1CON3bits.ADCS = 3; // ADC Conversion Clock Tad=Tcy*(ADCS+1)= (1/40M)*4 = 100ns
  62. // ADC Conversion Time for 12-bit Tc=14*Tad = 1.4us
  63. AD1CON1bits.ADDMABM = 1; // DMA buffers are built in conversion order mode
  64. AD1CON2bits.SMPI = 0; // SMPI must be 0
  65. //AD1CHS0: A/D Input Select Register
  66. AD1CHS0bits.CH0SA = 4; // MUXA +ve input selection (AN4) for CH0
  67. AD1CHS0bits.CH0NA = 0; // MUXA -ve input selection (Vref-) for CH0
  68. //AD1PCFGH/AD1PCFGL: Port Configuration Register
  69. AD1PCFGL = 0xFFFF;
  70. AD1PCFGLbits.PCFG4 = 0; // AN4 as Analog Input
  71. IFS0bits.AD1IF = 0; // Clear the A/D interrupt flag bit
  72. IEC0bits.AD1IE = 0; // Do not Enable A/D interrupt
  73. AD1CON1bits.ADON = 0;
  74. // Timer 3 is setup to time-out every Ts secs. As a result, the module
  75. // will stop sampling and trigger a conversion on every Timer3 time-out Ts.
  76. // At that time, the conversion process starts and completes Tc=12*Tad periods later.
  77. // When the conversion completes, the module starts sampling again. However, since Timer3
  78. // is already on and counting, about (Ts-Tc)us later, Timer3 will expire again and trigger
  79. // next conversion.
  80. TMR3 = 0x0000; // Clear TMR3
  81. PR3 = SAMPPRD; // Load period value in PR3
  82. IFS0bits.T3IF = 0; // Clear Timer 3 Interrupt Flag
  83. IEC0bits.T3IE = 0; // Clear Timer 3 interrupt enable bit
  84. T3CONbits.TON = 0;
  85. }
  86. void dac1_init(void)
  87. {
  88. // Initiate DAC Clock
  89. ACLKCONbits.SELACLK = 0; // FRC w/ Pll as Clock Source
  90. ACLKCONbits.AOSCMD = 0; // Auxiliary Oscillator Disabled
  91. ACLKCONbits.ASRCSEL = 0; // Auxiliary Oscillator is the Clock Source
  92. ACLKCONbits.APSTSCLR = 7; // Fvco/1 = 158.5152 MHz/1 = 158.5152 MHz
  93. DAC1STATbits.RITYPE = 0; // Right Channel Interrupt if FIFO is not Full
  94. //DAC1STATbits.LITYPE = 0; // Left Channel Interrupt if FIFO is not Full
  95. DAC1STATbits.ROEN = 1; // Right Channel DAC Output Enabled
  96. DAC1STATbits.LOEN = 0; // Right Channel DAC Output Enabled
  97. DAC1DFLT = 0x000; // DAC Default value is the midpoint
  98. // Sampling Rate Fs = DACCLK / 256 = 16kHz
  99. DAC1CONbits.DACFDIV = 76; // DACCLK = ACLK/(DACFDIV + 1): 158.2 MHz/6 = 26.4 MHz
  100. DAC1CONbits.FORM = 1; // Data Format is signed integer
  101. DAC1CONbits.AMPON = 0; // Analog Output Amplifier is enabled during Sleep Mode/Stop-in Idle mode
  102. DAC1CONbits.DACEN = 0;
  103. IEC4bits.DAC1RIE = 0;
  104. IEC4bits.DAC1LIE = 0;
  105. }
  106. void dma_setadc(void)
  107. {
  108. DMA0CONbits.CHEN = 0; // Disable DMA channel
  109. IFS0bits.DMA0IF = 0; // Clear the DMA interrupt flag bit
  110. DMA0CONbits.AMODE = 0; // Register Indirect with Post Increment
  111. DMA0CONbits.MODE = 2; // Continuous Mode with Ping-Pong Enabled
  112. DMACS1bits.PPST0 = 0;
  113. DMA0CONbits.DIR = 0; // Peripheral-to-Ram Data Transfer
  114. DMA0PAD = (uint16_t)&ADC1BUF0; // Peripheral Address Register: ADC buffer
  115. DMA0CNT = G726A_FRAME_SIZE - 1; // DMA Transfer Count is (WB_SPEEX_ENCODER_INPUT_SIZE-1)
  116. DMA0REQ = 13; // ADC interrupt selected for DMA channel IRQ
  117. DMA0STA = __builtin_dmaoffset(samples_buf0); // DMA RAM Start Address A
  118. DMA0STB = __builtin_dmaoffset(samples_buf1); // DMA RAM Start Address B
  119. DSADR = 0;
  120. IEC0bits.DMA0IE = 1; // Set the DMA interrupt enable bit
  121. }
  122. void dma_setdac(void)
  123. {
  124. DMA0CONbits.CHEN = 0; // Disable DMA channel
  125. IFS0bits.DMA0IF = 0; // Clear the DMA interrupt flag bit
  126. DMA0CONbits.AMODE = 0; // Register Indirect with Post Increment
  127. DMA0CONbits.MODE = 2; // Continuous Mode with Ping-Pong Enabled
  128. DMACS1bits.PPST0 = 0;
  129. DMA0CONbits.DIR = 1; // Ram-to-Peripheral Data Transfer
  130. DMA0PAD = (uint16_t)&DAC1RDAT; // Point DMA to DAC1RDAT
  131. DMA0CNT = G726A_FRAME_SIZE - 1;
  132. DMA0REQ = 78; // Select DAC1RDAT as DMA Request Source
  133. DMA0STA = __builtin_dmaoffset(samples_buf0);
  134. DMA0STB = __builtin_dmaoffset(samples_buf1);
  135. DSADR = 0;
  136. IEC0bits.DMA0IE = 1; // Set the DMA interrupt enable bit
  137. }
  138. #define dma_start() (DMA0CONbits.CHEN = 1)
  139. #define dma_stop() (DMA0CONbits.CHEN = 0)
  140. #define dac_start() (DAC1CONbits.DACEN = 1)
  141. #define dac_stop() (DAC1CONbits.DACEN = 0)
  142. #define adc_start() do {AD1CON1bits.ADON = 1; T3CONbits.TON = 1; } while(0)
  143. #define adc_stop() do { AD1CON1bits.ADON = 0; T3CONbits.TON = 0; } while(0)
  144. void __attribute__((interrupt, no_auto_psv)) _DMA0Interrupt(void)
  145. {
  146. samples_buf_ready = 1;
  147. bufid ^= 1;
  148. IFS0bits.DMA0IF = 0;
  149. }
  150. void __attribute__((interrupt, no_auto_psv)) _T5Interrupt(void)
  151. {
  152. IFS1bits.T5IF = 0;
  153. if(!recording && !playing) {
  154. adc_stop();
  155. dma_setdac(); // No more carrier, playback
  156. dac_start();
  157. dma_start();
  158. playing = 1;
  159. page_samples_id = 0;
  160. packed_samples_num = 0;
  161. TRISB = 0x4c;
  162. }
  163. }
  164. void __attribute__((interrupt, no_auto_psv)) _CNInterrupt(void)
  165. {
  166. if(!recording && PORTBbits.RB3) {
  167. //if(!flag) {
  168. dac_stop();
  169. TRISB = 0x84c;
  170. dma_setadc(); // Carrier detected, listen
  171. adc_start();
  172. dma_start();
  173. page_samples_num = 0;
  174. packed_samples_num = 0;
  175. recording = 1;
  176. playing = 0;
  177. }
  178. else if(recording && !PORTBbits.RB3) {
  179. adc_stop();
  180. dma_stop();
  181. recording = 0;
  182. TMR5 = PR5 - 5;
  183. IFS1bits.T5IF = 0;
  184. playing = 0;
  185. }
  186. IFS1bits.CNIF = 0;
  187. }
  188. #include <stdlib.h>
  189. #include "data.h"
  190. int main(void)
  191. {
  192. //uint16_t i = 0, j;
  193. //uint8_t t, *p, *q;
  194. // Configure Oscillator to operate the device at ~39.6MIPS
  195. // Fosc= Fin * M / (N1*N2), Fcy = Fosc / 2
  196. // Fosc= 7.3728MHz * 43 / (2 * 2) = 79.2576Mhz
  197. PLLFBD = 41; // M = 43
  198. CLKDIVbits.PLLPOST = 0; // N1 = 2
  199. CLKDIVbits.PLLPRE = 0; // N2 = 2
  200. CLKDIVbits.FRCDIV = 0; // N2 = 2
  201. OSCTUN = 0; // Tune FRC oscillator
  202. // Disable Watch Dog Timer
  203. RCONbits.SWDTEN = 0;
  204. // Clock switching to incorporate PLL
  205. __builtin_write_OSCCONH(0x01); // Initiate Clock Switch to Primary
  206. // Oscillator with PLL (NOSC=0b011)
  207. __builtin_write_OSCCONL(0x01); // Start clock switching
  208. while(OSCCONbits.COSC != 0b001); // Wait for Clock switch to occur
  209. // Wait for PLL to lock
  210. while(OSCCONbits.LOCK != 1);
  211. G726AEncoderInit(encoder, G726A_32KBPS, G726A_FRAME_SIZE);
  212. G726ADecoderInit(decoder, G726A_32KBPS, G726A_FRAME_SIZE);
  213. //TRISA = 0;
  214. PORTBbits.RB11 = 0;
  215. TRISB = 0x84c;
  216. flash_init();
  217. // // OTP !!!!!!!!
  218. // // Power of 2 mode
  219. // spi1_begin();
  220. // spi1_write(0x3D);
  221. // spi1_write(0x2A);
  222. // spi1_write(0x80);
  223. // spi1_write(0xA6);
  224. // spi1_end();
  225. //
  226. // while(1);
  227. //PORTBbits.RB5 = flash_AT45DB041D_identify();
  228. adc1_init(); // Initialize the A/D converter to convert Channel 4
  229. dac1_init(); // Initialize the D/A converter
  230. //
  231. TMR4 = 0x0000;
  232. T4CONbits.TCKPS = 3;
  233. T4CONbits.TCS = 0;
  234. T4CONbits.T32 = 1;
  235. PR4 = 0;
  236. PR5 = 0x17;
  237. IFS1bits.T5IF = 0;
  238. IEC1bits.T5IE = 1;
  239. T4CONbits.TON = 1;
  240. //
  241. CNEN1bits.CN7IE = 1;
  242. IEC1bits.CNIE = 1;
  243. //page_samples_num = sizeof(test) >> 8;
  244. while(1) {
  245. while(!samples_buf_ready);
  246. samples_buf_ready = 0;
  247. if(recording) { // Encode the voice data
  248. if(!packed_samples_num)
  249. flash_sectorerase(page_samples_num);
  250. if(bufid)
  251. G726AEncode(encoder, (int*)samples_buf1, samples_encoded);
  252. else
  253. G726AEncode(encoder, (int*)samples_buf0, samples_encoded);
  254. G726APack(samples_encoded, samples_packed + (packed_samples_num << 7), G726A_FRAME_SIZE, G726A_32KBPS);
  255. // p = samples_encoded;
  256. // q = samples_packed + packed_samples_num * PACKED_FRAME_SIZE;
  257. // for(j = 0; j < PACKED_FRAME_SIZE; ++j) {
  258. // t = (*p++) & 0x3;
  259. // t |= ((*p++) << 2) & 0xc;
  260. // t |= ((*p++) << 4) & 0x30;
  261. // t |= ((*p++) << 6) & 0xc0;
  262. // *q++ = t;
  263. // }
  264. ++packed_samples_num;
  265. if(packed_samples_num & 0x20)
  266. packed_samples_num = 0;
  267. else if(packed_samples_num & 0x10)
  268. flash_pagewrite(page_samples_num++, samples_packed + ((packed_samples_num & 0xf) << 8));
  269. }
  270. else if(playing) { // Playback: decode the voice data
  271. if(!page_samples_num) {
  272. playing = 0;
  273. TRISB = 0x84c;
  274. continue;
  275. }
  276. flash_read(page_samples_id, (packed_samples_num << 7), samples_packed, 0x1 << 7);
  277. G726AUnpack(samples_packed, samples_encoded, G726A_FRAME_SIZE, G726A_32KBPS);
  278. // p = samples_encoded;
  279. // q = samples_packed + (i & 0x1) * PACKED_FRAME_SIZE;
  280. // for(j = 0; j < PACKED_FRAME_SIZE; ++j) {
  281. // t = *q++;
  282. // *p++ = t & 0x3;
  283. // *p++ = (t >> 2) & 0x3;
  284. // *p++ = (t >> 4) & 0x3;
  285. // *p++ = (t >> 6) & 0x3;
  286. // }
  287. //G726AUnpack(test + (page_samples_id << 7) + (packed_samples_num << 6), samples_encoded, G726A_FRAME_SIZE, G726A_32KBPS);
  288. if(bufid)
  289. G726ADecode(decoder, samples_encoded, (int*)samples_buf1);
  290. else
  291. G726ADecode(decoder, samples_encoded, (int*)samples_buf0);
  292. ++packed_samples_num;
  293. if(packed_samples_num & 0x2) {
  294. packed_samples_num = 0;
  295. if(++page_samples_id >= 0x4000)
  296. page_samples_id = 0;
  297. }
  298. if(page_samples_id == page_samples_num) {
  299. PR4 = 0;
  300. PR5 = 0x17;
  301. playing = 0;
  302. TRISB = 0x84c;
  303. dac_stop();
  304. dma_stop();
  305. }
  306. }
  307. }
  308. return 0;
  309. }