123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380 |
- // This file is part of parrocchetto.
- // parrocchetto is free software: you can redistribute it and/or modify
- // it under the terms of the GNU General Public License as published by
- // the Free Software Foundation, either version 3 of the License, or
- // (at your option) any later version.
- // parrocchetto is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU General Public License for more details.
- // You should have received a copy of the GNU General Public License
- // along with parrocchetto. If not, see <http://www.gnu.org/licenses/>.
- #include <xc.h>
- #include <dsp.h>
- #include <stdint.h>
- #include <p33Fxxxx.h>
- #include "G726A.h"
- #include "G726APack.h"
- #include "flash.h"
- // FICD
- #pragma config ICS = PGD1 // ICD Communication Channel Select bits->Communicate on PGEC1 and PGED1
- #pragma config JTAGEN = OFF // JTAG Enable bit->JTAG is disabled
- // FWDT
- #pragma config WDTPOST = PS32768 // Watchdog Timer Postscaler bits->1:32768
- #pragma config WDTPRE = PR128 // Watchdog Timer Prescaler bit->1:128
- #pragma config WINDIS = OFF // Watchdog Timer Window Enable bit->Watchdog Timer in Non-Window mode
- #pragma config FWDTEN = OFF // Watchdog Timer Enable bit->Watchdog timer enabled/disabled by user software
- // FOSC
- #pragma config POSCMD = NONE // Primary Oscillator Mode Select bits->Primary Oscillator disabled
- #pragma config OSCIOFNC = ON // OSC2 Pin Function bit->OSC2 is general purpose digital I/O pin
- #pragma config FCKSM = CSDCMD // Clock Switching Mode bits->Both Clock switching and Fail-safe Clock Monitor are disabled
- // FOSCSEL
- #pragma config FNOSC = FRCPLL // Oscillator Source Selection->Fast RC Oscillator with divide-by-N with PLL module (FRCPLL)
- // FGS
- #pragma config GWRP = OFF // General Segment Write-Protect bit->General Segment may be written
- // Sampling Control
- #define Fosc 79257600 // Hz
- #define Fcy (Fosc / 2) // Hz
- #define Fs 8042 // Hz
- #define SAMPPRD ((Fcy / Fs) - 1) // Hz
- #define PACKED_FRAME_SIZE (G726A_FRAME_SIZE >> 1)
- #define PACKED_FRAMES_NUM 0x20
- volatile int16_t samples_buf0[G726A_FRAME_SIZE] __attribute__((space(dma)));
- volatile int16_t samples_buf1[G726A_FRAME_SIZE] __attribute__((space(dma)));
- volatile uint16_t samples_buf_ready = 0, bufid = 0;
- volatile uint16_t playing = 0, recording = 0;
- volatile uint16_t page_samples_num = 0, page_samples_id = 0, packed_samples_num = 0;
- uint8_t samples_encoded[G726A_FRAME_SIZE];
- uint8_t samples_packed[PACKED_FRAME_SIZE * PACKED_FRAMES_NUM];
- uint8_t encoder[G726A_ENCODER_SIZE];
- uint8_t decoder[G726A_DECODER_SIZE];
- //adc1_init() is used to configure A/D to convert channel 4 on Timer event.
- //It generates event to DMA on every sample/convert sequence.
- void adc1_init(void)
- {
- AD1CON1bits.FORM = 3; // Data Output Format: Signed Fraction (Q15 format)
- AD1CON1bits.SSRC = 2; // Sample Clock Source: GP Timer starts conversion
- AD1CON1bits.ASAM = 1; // ADC Sample Control: Sampling begins immediately after conversion
- AD1CON1bits.AD12B = 1; // 12-bit ADC operation
- AD1CON2bits.CHPS = 0; // Converts CH0
- AD1CON3bits.ADRC = 0; // ADC Clock is derived from Systems Clock
- AD1CON3bits.ADCS = 3; // ADC Conversion Clock Tad=Tcy*(ADCS+1)= (1/40M)*4 = 100ns
- // ADC Conversion Time for 12-bit Tc=14*Tad = 1.4us
- AD1CON1bits.ADDMABM = 1; // DMA buffers are built in conversion order mode
- AD1CON2bits.SMPI = 0; // SMPI must be 0
- //AD1CHS0: A/D Input Select Register
- AD1CHS0bits.CH0SA = 4; // MUXA +ve input selection (AN4) for CH0
- AD1CHS0bits.CH0NA = 0; // MUXA -ve input selection (Vref-) for CH0
- //AD1PCFGH/AD1PCFGL: Port Configuration Register
- AD1PCFGL = 0xFFFF;
- AD1PCFGLbits.PCFG4 = 0; // AN4 as Analog Input
- IFS0bits.AD1IF = 0; // Clear the A/D interrupt flag bit
- IEC0bits.AD1IE = 0; // Do not Enable A/D interrupt
- AD1CON1bits.ADON = 0;
-
- // Timer 3 is setup to time-out every Ts secs. As a result, the module
- // will stop sampling and trigger a conversion on every Timer3 time-out Ts.
- // At that time, the conversion process starts and completes Tc=12*Tad periods later.
- // When the conversion completes, the module starts sampling again. However, since Timer3
- // is already on and counting, about (Ts-Tc)us later, Timer3 will expire again and trigger
- // next conversion.
- TMR3 = 0x0000; // Clear TMR3
- PR3 = SAMPPRD; // Load period value in PR3
- IFS0bits.T3IF = 0; // Clear Timer 3 Interrupt Flag
- IEC0bits.T3IE = 0; // Clear Timer 3 interrupt enable bit
- T3CONbits.TON = 0;
- }
- void dac1_init(void)
- {
- // Initiate DAC Clock
- ACLKCONbits.SELACLK = 0; // FRC w/ Pll as Clock Source
- ACLKCONbits.AOSCMD = 0; // Auxiliary Oscillator Disabled
- ACLKCONbits.ASRCSEL = 0; // Auxiliary Oscillator is the Clock Source
- ACLKCONbits.APSTSCLR = 7; // Fvco/1 = 158.5152 MHz/1 = 158.5152 MHz
-
- DAC1STATbits.RITYPE = 0; // Right Channel Interrupt if FIFO is not Full
- //DAC1STATbits.LITYPE = 0; // Left Channel Interrupt if FIFO is not Full
- DAC1STATbits.ROEN = 1; // Right Channel DAC Output Enabled
- DAC1STATbits.LOEN = 0; // Right Channel DAC Output Enabled
-
- DAC1DFLT = 0x000; // DAC Default value is the midpoint
- // Sampling Rate Fs = DACCLK / 256 = 16kHz
- DAC1CONbits.DACFDIV = 76; // DACCLK = ACLK/(DACFDIV + 1): 158.2 MHz/6 = 26.4 MHz
- DAC1CONbits.FORM = 1; // Data Format is signed integer
- DAC1CONbits.AMPON = 0; // Analog Output Amplifier is enabled during Sleep Mode/Stop-in Idle mode
- DAC1CONbits.DACEN = 0;
- IEC4bits.DAC1RIE = 0;
- IEC4bits.DAC1LIE = 0;
- }
- void dma_setadc(void)
- {
- DMA0CONbits.CHEN = 0; // Disable DMA channel
- IFS0bits.DMA0IF = 0; // Clear the DMA interrupt flag bit
- DMA0CONbits.AMODE = 0; // Register Indirect with Post Increment
- DMA0CONbits.MODE = 2; // Continuous Mode with Ping-Pong Enabled
- DMACS1bits.PPST0 = 0;
- DMA0CONbits.DIR = 0; // Peripheral-to-Ram Data Transfer
- DMA0PAD = (uint16_t)&ADC1BUF0; // Peripheral Address Register: ADC buffer
- DMA0CNT = G726A_FRAME_SIZE - 1; // DMA Transfer Count is (WB_SPEEX_ENCODER_INPUT_SIZE-1)
- DMA0REQ = 13; // ADC interrupt selected for DMA channel IRQ
- DMA0STA = __builtin_dmaoffset(samples_buf0); // DMA RAM Start Address A
- DMA0STB = __builtin_dmaoffset(samples_buf1); // DMA RAM Start Address B
- DSADR = 0;
- IEC0bits.DMA0IE = 1; // Set the DMA interrupt enable bit
- }
- void dma_setdac(void)
- {
- DMA0CONbits.CHEN = 0; // Disable DMA channel
- IFS0bits.DMA0IF = 0; // Clear the DMA interrupt flag bit
- DMA0CONbits.AMODE = 0; // Register Indirect with Post Increment
- DMA0CONbits.MODE = 2; // Continuous Mode with Ping-Pong Enabled
- DMACS1bits.PPST0 = 0;
- DMA0CONbits.DIR = 1; // Ram-to-Peripheral Data Transfer
- DMA0PAD = (uint16_t)&DAC1RDAT; // Point DMA to DAC1RDAT
- DMA0CNT = G726A_FRAME_SIZE - 1;
- DMA0REQ = 78; // Select DAC1RDAT as DMA Request Source
- DMA0STA = __builtin_dmaoffset(samples_buf0);
- DMA0STB = __builtin_dmaoffset(samples_buf1);
- DSADR = 0;
- IEC0bits.DMA0IE = 1; // Set the DMA interrupt enable bit
- }
- #define dma_start() (DMA0CONbits.CHEN = 1)
- #define dma_stop() (DMA0CONbits.CHEN = 0)
- #define dac_start() (DAC1CONbits.DACEN = 1)
- #define dac_stop() (DAC1CONbits.DACEN = 0)
- #define adc_start() do {AD1CON1bits.ADON = 1; T3CONbits.TON = 1; } while(0)
- #define adc_stop() do { AD1CON1bits.ADON = 0; T3CONbits.TON = 0; } while(0)
- void __attribute__((interrupt, no_auto_psv)) _DMA0Interrupt(void)
- {
- samples_buf_ready = 1;
- bufid ^= 1;
- IFS0bits.DMA0IF = 0;
- }
- void __attribute__((interrupt, no_auto_psv)) _T5Interrupt(void)
- {
- IFS1bits.T5IF = 0;
- if(!recording && !playing) {
- adc_stop();
- dma_setdac(); // No more carrier, playback
- dac_start();
- dma_start();
- playing = 1;
- page_samples_id = 0;
- packed_samples_num = 0;
- TRISB = 0x4c;
- }
- }
- void __attribute__((interrupt, no_auto_psv)) _CNInterrupt(void)
- {
- if(!recording && PORTBbits.RB3) {
- //if(!flag) {
- dac_stop();
- TRISB = 0x84c;
- dma_setadc(); // Carrier detected, listen
- adc_start();
- dma_start();
- page_samples_num = 0;
- packed_samples_num = 0;
- recording = 1;
- playing = 0;
- }
- else if(recording && !PORTBbits.RB3) {
- adc_stop();
- dma_stop();
- recording = 0;
- TMR5 = PR5 - 5;
- IFS1bits.T5IF = 0;
- playing = 0;
- }
- IFS1bits.CNIF = 0;
- }
- #include <stdlib.h>
- #include "data.h"
- int main(void)
- {
- //uint16_t i = 0, j;
- //uint8_t t, *p, *q;
- // Configure Oscillator to operate the device at ~39.6MIPS
- // Fosc= Fin * M / (N1*N2), Fcy = Fosc / 2
- // Fosc= 7.3728MHz * 43 / (2 * 2) = 79.2576Mhz
- PLLFBD = 41; // M = 43
- CLKDIVbits.PLLPOST = 0; // N1 = 2
- CLKDIVbits.PLLPRE = 0; // N2 = 2
- CLKDIVbits.FRCDIV = 0; // N2 = 2
- OSCTUN = 0; // Tune FRC oscillator
- // Disable Watch Dog Timer
- RCONbits.SWDTEN = 0;
-
- // Clock switching to incorporate PLL
- __builtin_write_OSCCONH(0x01); // Initiate Clock Switch to Primary
- // Oscillator with PLL (NOSC=0b011)
- __builtin_write_OSCCONL(0x01); // Start clock switching
- while(OSCCONbits.COSC != 0b001); // Wait for Clock switch to occur
- // Wait for PLL to lock
- while(OSCCONbits.LOCK != 1);
-
- G726AEncoderInit(encoder, G726A_32KBPS, G726A_FRAME_SIZE);
- G726ADecoderInit(decoder, G726A_32KBPS, G726A_FRAME_SIZE);
- //TRISA = 0;
- PORTBbits.RB11 = 0;
- TRISB = 0x84c;
- flash_init();
-
- // // OTP !!!!!!!!
- // // Power of 2 mode
- // spi1_begin();
- // spi1_write(0x3D);
- // spi1_write(0x2A);
- // spi1_write(0x80);
- // spi1_write(0xA6);
- // spi1_end();
- //
- // while(1);
-
- //PORTBbits.RB5 = flash_AT45DB041D_identify();
- adc1_init(); // Initialize the A/D converter to convert Channel 4
- dac1_init(); // Initialize the D/A converter
- //
- TMR4 = 0x0000;
- T4CONbits.TCKPS = 3;
- T4CONbits.TCS = 0;
- T4CONbits.T32 = 1;
- PR4 = 0;
- PR5 = 0x17;
- IFS1bits.T5IF = 0;
- IEC1bits.T5IE = 1;
- T4CONbits.TON = 1;
-
- //
- CNEN1bits.CN7IE = 1;
- IEC1bits.CNIE = 1;
-
-
- //page_samples_num = sizeof(test) >> 8;
-
- while(1) {
- while(!samples_buf_ready);
- samples_buf_ready = 0;
-
- if(recording) { // Encode the voice data
- if(!packed_samples_num)
- flash_sectorerase(page_samples_num);
- if(bufid)
- G726AEncode(encoder, (int*)samples_buf1, samples_encoded);
- else
- G726AEncode(encoder, (int*)samples_buf0, samples_encoded);
-
- G726APack(samples_encoded, samples_packed + (packed_samples_num << 7), G726A_FRAME_SIZE, G726A_32KBPS);
- // p = samples_encoded;
- // q = samples_packed + packed_samples_num * PACKED_FRAME_SIZE;
- // for(j = 0; j < PACKED_FRAME_SIZE; ++j) {
- // t = (*p++) & 0x3;
- // t |= ((*p++) << 2) & 0xc;
- // t |= ((*p++) << 4) & 0x30;
- // t |= ((*p++) << 6) & 0xc0;
- // *q++ = t;
- // }
-
- ++packed_samples_num;
- if(packed_samples_num & 0x20)
- packed_samples_num = 0;
- else if(packed_samples_num & 0x10)
- flash_pagewrite(page_samples_num++, samples_packed + ((packed_samples_num & 0xf) << 8));
- }
- else if(playing) { // Playback: decode the voice data
- if(!page_samples_num) {
- playing = 0;
- TRISB = 0x84c;
- continue;
- }
- flash_read(page_samples_id, (packed_samples_num << 7), samples_packed, 0x1 << 7);
-
- G726AUnpack(samples_packed, samples_encoded, G726A_FRAME_SIZE, G726A_32KBPS);
-
- // p = samples_encoded;
- // q = samples_packed + (i & 0x1) * PACKED_FRAME_SIZE;
- // for(j = 0; j < PACKED_FRAME_SIZE; ++j) {
- // t = *q++;
- // *p++ = t & 0x3;
- // *p++ = (t >> 2) & 0x3;
- // *p++ = (t >> 4) & 0x3;
- // *p++ = (t >> 6) & 0x3;
- // }
-
-
- //G726AUnpack(test + (page_samples_id << 7) + (packed_samples_num << 6), samples_encoded, G726A_FRAME_SIZE, G726A_32KBPS);
-
-
-
- if(bufid)
- G726ADecode(decoder, samples_encoded, (int*)samples_buf1);
- else
- G726ADecode(decoder, samples_encoded, (int*)samples_buf0);
- ++packed_samples_num;
- if(packed_samples_num & 0x2) {
- packed_samples_num = 0;
- if(++page_samples_id >= 0x4000)
- page_samples_id = 0;
- }
-
-
- if(page_samples_id == page_samples_num) {
- PR4 = 0;
- PR5 = 0x17;
- playing = 0;
- TRISB = 0x84c;
- dac_stop();
- dma_stop();
- }
- }
- }
- return 0;
- }
|