Created Wed, 11 Sep 2013 14:07:43 +0000 by ecolomato
Wed, 11 Sep 2013 14:07:43 +0000
Hi all,
I'm trying to talk to an I2S audio decoder with my uC32 board, but i get in trouble with timers. Could anyone help me with an example that works on MPIDE.
Thanks!
Thu, 12 Sep 2013 15:15:50 +0000
What is the trouble you're having with timers? What can't you do, or what doesn't do what you want to do?
Fri, 13 Sep 2013 07:05:45 +0000
The problem refers to me! I'm not an expert and don´t understand timers and OC configuration. Even reading the manual. So with an example, i could do some tests to understand them better.
Thank you very much!
Fri, 13 Sep 2013 07:21:09 +0000
Sorry!
I need a 44100Hz pulse, another 64 times faster, and another 256 times faster. And then output serial 16bit data at 44100Hz*64. One pin for each signal. But above all this, i need the processor not to be so busy doing that, because it has some other tasks to do.
Thanks again!
Fri, 13 Sep 2013 07:49:17 +0000
Ah, so what you want is to drive a CODEC chip then?
The PIC32 has hardware support for that built in to the SPI interface. You should check out the data sheet for the Serial Peripheral interface and look at framed mode.
The only thing it can't do is generate the 256x clock needed by most CODEC chips. You might be able to do it with a timer / OC pair, but getting that kind of clock accuracy at high frequencies may be tricky. 11289600Hz is an odd value to try and generate from an 80MHz base clock. Dividing by 7 (PS=1:1, PR=7 OC=3) yields 11428571.43Hz, which may be as close as you can get, and that won't be exactly 50% duty either. You may be better off with an external clock circuit to generate that signal.
Fri, 13 Sep 2013 19:44:10 +0000
Thank you very much! If there is no other way, i'll try external clock. I found out this code for MPLAB. It's supposed to drive a CODEC? If so, how could I export this code to MPIDE for some testing? Sorry for the large "paste":
/********************************************************************* *
PIC32MX Audio I2S Communication and Reference Clock Output
test_sine.c
MPLAB IDE v8+
The example generates 12.288MHz Reference Clock Output and
is configured for 48kHz sample rate 24-bit I2S stereo
communication. A sinusoid tone sampled at 48kHz is transmitted
over I2S output. REFOCLK, SS, SDO and SDI pins use the
Peripheral Pin Select functionality for flexible mapping of I2S
functionality on desired pins. The readme file states the pins
that can be probed to observe the I2S and Reference Clock Output
signals.
********************************************************************/ #include <plib.h>
#if defined (32MX360F512L) || (32MX460F512L) || (32MX795F512L) || (32MX430F064L) // Configuration Bit settings // SYSCLK = 80 MHz (8MHz Crystal / FPLLIDIV * FPLLMUL / FPLLODIV) // PBCLK = 80 MHz (SYSCLK / FPBDIV) // Primary Osc w/PLL (XT+,HS+,EC+PLL) // WDT OFF // Other options are don't care #pragma config FPLLMUL = MUL_20, FPLLIDIV = DIV_2, FPLLODIV = DIV_1, FWDTEN = OFF #pragma config POSCMOD = HS, FNOSC = PRIPLL, FPBDIV = DIV_1 #define SYS_FREQ (80000000L)
#elif defined (32MX220F032D) || (32MX250F128D) // Configuration Bit settings // SYSCLK = 48 MHz (8MHz Crystal / FPLLIDIV * FPLLMUL / FPLLODIV) // PBCLK = 48 MHz (SYSCLK / FPBDIV) // Primary Osc w/PLL (XT+,HS+,EC+PLL) // WDT OFF // Other options are don't care #pragma config FPLLMUL = MUL_24, FPLLIDIV = DIV_2, FPLLODIV = DIV_2, FWDTEN = OFF #pragma config POSCMOD = HS, FNOSC = PRIPLL, FPBDIV = DIV_1 #define SYS_FREQ (48000000L) #endif
//Definitions. #define SAMPLE_RATE 48000 #define FRAME_SIZE (SAMPLE_RATE/1000) #define RODIV 3 #define REFTRIM 464
//Stereo audio structure for 24-bit I2S data.
typedef union {
struct {
INT32 rightChannel;
INT32 leftChannel;
};
UINT64 audioWord;
} AudioStereo; AudioStereo* txBuffer;
/* Main entry function */ int main(void) { UINT spi_con1 = 0, spi_con2 = 0; UINT baud_rate = SAMPLE_RATE * 64; UINT mclk = SAMPLE_RATE * 256; extern AudioStereo test_sine[];
//Congigure MIPS, Prefetch Cache module.
SYSTEMConfig(SYS_FREQ, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);
INTEnableSystemMultiVectoredInt();
//Test tone vector sampled at 48kHz.
txBuffer = test_sine;
//Configure the direction of used pins and
//configure as digital pins.
#if defined (__32MX220F032D__) || defined (__32MX250F128D__)
PORTSetPinsDigitalOut(IOPORT_A, BIT_1);
PORTSetPinsDigitalOut(IOPORT_B, BIT_4);
PORTSetPinsDigitalIn(IOPORT_B, BIT_5);
PORTSetPinsDigitalOut(IOPORT_C, BIT_3);
#elif defined (__32MX430F064L__)
PORTSetPinsDigitalOut(IOPORT_D, BIT_9);
PORTSetPinsDigitalOut(IOPORT_D, BIT_15);
PORTSetPinsDigitalIn(IOPORT_D, BIT_3);
PORTSetPinsDigitalOut(IOPORT_D, BIT_4);
#endif
/*------------------------------------------------
Pin mapping for PIC32MX220F032D and PIC32MX250F128D:
--------------------------------------------------
Function PPS Pin# Test Point# : Comment
__________________________________________________________________________
REFOCLK(o) RPC3 (36) TP36 : Reference Clock Output
SCK1(o) - (14) TP14 : SPI-I2S SCLK Output
SS(o) RPB4 (33) TP33 : SPI-I2S LRCK Output
SDO(o) RPA1 (20) TP20 : SPI-I2S SDO Output
SDI(i) RPB5 (41) - : SPI-I2S SDI Input */
#if defined (__32MX220F032D__) || defined (__32MX250F128D__)
PPSOutput(3, RPC3, REFCLKO); //REFCLK0: RPC3 - Out
PPSInput(2, SDI1, RPB5); //SDI: RPB5 - In
PPSOutput(2, RPA1, SDO1); //SDO: RPA1 - Out
PPSOutput(1, RPB4, SS1); //SS: RPB4 - Out
/*------------------------------------------------
Pin mapping for PIC32MX430F064L:
--------------------------------------------------
Function PPS Pin# Test Point# : Comment
__________________________________________________________________________
REFOCLK(o) RPD9 (69) - : Reference Clock Output
SCK1(o) - (70) - : SPI-I2S SCLK Output
SS(o) RPD4 (81) - : SPI-I2S LRCK Output
SDO(o) RPD15 (48) - : SPI-I2S SDO Output
SDI(i) RPD3 (78) - : SPI-I2S SDI Input */
#elif defined (__32MX430F064L__)
PPSOutput(3, RPD9, REFCLKO); //REFCLK0: RPD9 - Out
PPSInput(1, SDI1, RPD3); //SDI: RPD3 - In
PPSOutput(2, RPD15, SDO1); //SDO: RPD15 - Out
PPSOutput(3, RPD4, SS1); //SS: RPD4 - Out
#endif
//Configure Reference Clock Output to 12.288MHz.
mOSCREFOTRIMSet(REFTRIM);
OSCREFConfig(OSC_REFOCON_USBPLL, //USB-PLL clock output used as REFCLKO source
OSC_REFOCON_OE | OSC_REFOCON_ON, //Enable and turn on the REFCLKO
RODIV);
//Configure SPI in I2S mode with 24-bit stereo audio.
spi_con1 = SPI_OPEN_MSTEN | //Master mode enable
SPI_OPEN_SSEN | //Enable slave select function
SPI_OPEN_CKP_HIGH | //Clock polarity Idle High Actie Low
SPI_OPEN_MODE16 | //Data mode: 24b
SPI_OPEN_MODE32 | //Data mode: 24b
SPI_OPEN_MCLKSEL | //Clock selected is reference clock
SPI_OPEN_FSP_HIGH; //Frame Sync Pulse is active high
spi_con2 = SPI_OPEN2_AUDEN | //Enable Audio mode
SPI_OPEN2_AUDMOD_I2S; //Enable I2S mode
//Configure and turn on the SPI1 module.
SpiChnOpenEx(SPI_CHANNEL1, spi_con1, spi_con2, (mclk / baud_rate));
//Enable SPI1 interrupt.
INTSetVectorPriority(INT_SPI_1_VECTOR, INT_PRIORITY_LEVEL_4);
INTSetVectorSubPriority(INT_SPI_1_VECTOR, INT_SUB_PRIORITY_LEVEL_0);
INTEnable(INT_SPI1, INT_ENABLED);
SpiChnPutC(SPI_CHANNEL1, 0); //Dummy write to start the SPI
//Idle.
while (1);
return 1;
}
/* SPI1 ISR */ void __ISR(_SPI_1_VECTOR, ipl4) SPI1InterruptHandler(void) { static UINT ptrIndex = 0; static BOOL toggleData = TRUE;
SpiChnPutC(SPI_CHANNEL1,
(toggleData ? txBuffer[ptrIndex].leftChannel : txBuffer[ptrIndex++].rightChannel));
toggleData = !toggleData;
if (ptrIndex >= FRAME_SIZE)
ptrIndex = 0;
INTClearFlag(INT_SPI1TX);
}
Fri, 13 Sep 2013 20:54:24 +0000
With great difficulty. All that code uses the Microchip Peripheral Libraries. I am not sure what of those is available in MPLAB, if any. I know there was a move away from plib a bit back.
Pretty much all the function calls do is modify the SFRs, so if you read through section 23 of the reference manuals you should be able to work out which registers it is setting in what way, and emulate that by directly manipulating those registers.
I have never used the reference clock - I am not sure which chips in the PIC32 family have it, but it might well be the way to go for the 256x oversampling clock.
Mon, 30 Sep 2013 19:06:19 +0000
Sorry for the delay...
Now i'm following your advice of using an external clock. I've learned a bit on SFR's manipulating... ;) But can't find the way counting an external pulses to obtain the 256x sync. There is only one timer a could use (Timer1) to be external triggered on UNO32 or uC32 (soldering wires, of course). There's no TxCK pin available!!!! After setting Timer1 for external clock and apply clock source, TMR1 register remains 0x0 forever and ever.
Is there any other way?
Thanks!
Wed, 02 Oct 2013 12:11:29 +0000
Now i'm working with SFR's, got to say that is better than working with libraries. That is the only way to know what to are exactly doing. And you can do it from MPIDE as well as MPLAB. I managed to synchronize UNO32 (master) with an audio codec (slave) connecting the codec MCLK out to the secondary oscilator crystal hole.
Thanks again!!!