Page 1 of 2

Using with Arduino Mega 2560

PostPosted: Fri Jan 27, 2012 8:26 am
by chipaudette
Hi All,

I received my Audio Code Shield a couple weeks ago. I'm now hooking it up to an Arduino Mega 2560. I downloaded the AudioCodec library for Arduino 1.0 and I'm using the Arduino 1.0 IDE (and yes, the IDE is set to Arduino Mega 2560). I compiled and uploaded sine_generator example program. I'm trying to listen to the line out (via a head phone amplifier). I'm getting nothing. I manipulate the knobs and I get nothing. No sound.

Bummer.

So, I begin to debug the code by starting a Serial link and using Serial.println commands to see what's happening. I created a counting variable (volatile long int defined as a global) and made it increment in the ISR each time the ISR is called. In the main loop, inside the while loop, I put my Serial.println(counter).

When I compile and run, the counter value stays at zero. It never increments. Bummer.

Is there something special about the Mega 2560 that is preventing this from running. Does anyone have any suggestions?

Thanks,

Chip

Re: Using with Arduino Mega 2560

PostPosted: Fri Jan 27, 2012 9:19 am
by guest
the arduino mega has a different pinout for its spi buss
in comparison to the uno and duemilinove
so some hacking is required to make them work together

we updated the website to reflect this a week or so ago

if youre interested in trying to hack them to work together
i can help out with information and code

Re: Using with Arduino Mega 2560

PostPosted: Tue Jan 31, 2012 10:23 am
by chipaudette
Thanks for the pointer about the SPI bus. Bummer. I can figure out the hack. It's just unfortunate that the hack will mess up the clean form factor of the shield. Flying leads over to the Mega's 50's pins is just unsightly. Bummer that the Arduino folks chose to wire the Mega differently from the Uno.

Chip

Re: Using with Arduino Mega 2560

PostPosted: Tue Jan 31, 2012 1:36 pm
by guest
yeah
im not sure why they did it that way
we were pretty bummed too when we realized it

then we took a look at the price point between the mega and the maple
and figured the maple would be a better high end platform anyways

Re: Using with Arduino Mega 2560

PostPosted: Sat Jul 21, 2012 1:29 pm
by guest
pinout differences between the Mega and Uno:

+5V - same
+3.3V - same
GND - same
MOD0 (Analog0) - same
MOD1 (Analog1) - same

I2C (SDA and SCL) - different (can be bit banged or rewired)
SPI (MISO, MOSI, SCK, SS) - different (needs to be rewired, except SS)
T1 - NOT PINNED OUT ON MEGA (moved to different timer)

mapping between pins that are different:

Code: Select all
UNO MEGA FUNCTION
--- ---- --------
A6  D20  I2C (SDA)
A7  D21  I2C (SCL)
D10 D53  SPI (SS)
D11 D51  SPI (MOSI)
D12 D50  SPI (MISO)
D13 D52  SPI (SCK)
D5  D47  T1 -> T5


NOTES:

1. the SS pin can essentially be any pin in master mode
which is what is being used here
so its probably best to just leave it where it is

2. the I2C can be bit banged rather than moving wires

3. be sure to set any unused pins to inputs
so there isnt any conflict on the lines

Re: Using with Arduino Mega 2560

PostPosted: Thu Nov 01, 2012 4:56 pm
by scott2
Hello -

I've been trying to get this port to work, but haven't had much luck. I've got the codec shield sitting on a breadboard to ensure there's no conflict. I've mapped everything appropriately (and kept SS on 10), and looked it over several times.

The following is only code modification I've made. The datasheet seems to indicate that the register codes should all hold over, but an extra pair of eyes might be useful here.

Do any of you have working Mega library code for this?

Any help appreciated, thanks!

Code: Select all
...
// setup timer1 for codec clock division 
TCCR5A = 0x00; // set to CTC mode
  TCCR5B = 0x0f; // set to CTC mode, external clock
  TCCR5C = 0x00; // not used
  TCNT5H = 0x00; // clear the counter
  TCNT5H = 0x00;
  #if SAMPLE_RATE == 88
    OCR5AH = 0x00; // set the counter top
    OCR5AL = 0x3f;
  #elif (SAMPLE_RATE == 44) || (SAMPLE_RATE == 22)
    OCR5AH = 0x00; // set the counter top
    OCR5AL = 0x7f;
  #elif SAMPLE_RATE == 8
    OCR5AH = 0x02; // set the counter top
    OCR5AL = 0xbf;
  #elif SAMPLE_RATE == 2
    OCR5AH = 0x04; // set the counter top
    OCR5AL = 0x7f;
  #endif
  TIMSK5 = 0x02; // turn on compare match interrupt
 
  // turn off all enabled interrupts (delay and wire)
  TIMSK0 = 0x00;
  TWCR = 0x00;

  sei(); // turn on interrupts
...

Re: Using with Arduino Mega 2560

PostPosted: Fri Nov 02, 2012 10:06 am
by scott2
Found some errors:
- TIMSK0 = 0x00 > TIMSK5 = 0x00;

And then corrected for ISR(TIMER0_COMPA_vect, ISR_NAKED) > ISR(TIMER5_COMPA_vect, ISR_NAKED) in the demo code.

Still no luck, though

Re: Using with Arduino Mega 2560

PostPosted: Fri Nov 02, 2012 10:49 am
by guest
the TIMSK0 is actually to turn off the delay() timer, so that is correct.
if you change that line back, the TIMER5 interrupt will work.

do you have an oscilloscope? if not, measure the dc voltage on the various I2C, SPI, and clock lines, to see if they are being toggled. if they are anything but 0V or 5V, then there is data going across them.

i will dig through the rest of the code to see if there are other bits missing.

Re: Using with Arduino Mega 2560

PostPosted: Fri Nov 02, 2012 10:57 am
by guest
at the beginning of the SPi setup, the SS pin will have to be changed here. so just change 10 to whatever pin you put SS on (should be 53).

Code: Select all
static inline void AudioCodec_init(void) {

  // setup spi peripheral
  digitalWrite(10, LOW); // set ss pin to output low
  pinMode (10, OUTPUT);
  SPI.begin();
  SPI.setBitOrder(MSBFIRST);
  SPI.setClockDivider(SPI_CLOCK_DIV2);
  SPI.setDataMode(SPI_MODE0);

Re: Using with Arduino Mega 2560

PostPosted: Fri Nov 02, 2012 11:00 am
by guest
in the data transfer function, reassign all instances of PORTB2 to PORTB0 (assuming ss on D53 again). there should only be 2 of them:

Code: Select all
// codec data transfer function
static inline void AudioCodec_data(int* _lin, int* _rin, int _lout, int _rout) {

  int _out_temp = _lout;
  PORTB |= (1<<PORTB2);  // toggle ss pina
  asm volatile ("out %0, %B1" : : "I" (_SFR_IO_ADDR(SPDR)), "r" (_out_temp) );
  PORTB &= ~(1<<PORTB2); // toggle ss pin
  while(!(SPSR & (1<<SPIF))){ // wait for data transfer to complete
  }
  asm volatile ("out %0, %A1" : : "I" (_SFR_IO_ADDR(SPDR)), "r" (_out_temp) );
  asm volatile ("in r3, %0" : : "I" (_SFR_IO_ADDR(SPDR)) );
  _out_temp = _rout;
  while(!(SPSR & (1<<SPIF))){ // wait for data transfer to complete
  }
  asm volatile ("out %0, %B1" : : "I" (_SFR_IO_ADDR(SPDR)), "r" (_out_temp) );
  asm volatile ("in r2, %0" : : "I" (_SFR_IO_ADDR(SPDR)) );
  asm volatile ("movw %0, r2" : "=r" (*_lin) : );
  while(!(SPSR & (1<<SPIF))){ // wait for data transfer to complete
  }
  asm volatile ("out %0, %A1" : : "I" (_SFR_IO_ADDR(SPDR)), "r" (_out_temp) );
  asm volatile ("in r3, %0" : : "I" (_SFR_IO_ADDR(SPDR)) );
  while(!(SPSR & (1<<SPIF))){ // wait for data transfer to complete
  }
  asm volatile ("in r2, %0" : : "I" (_SFR_IO_ADDR(SPDR)) );
  asm volatile ("movw %0, r2" : "=r" (*_rin) : : "r2", "r3");
}